?? fbcon-sti.c
字號:
/* * linux/drivers/video/fbcon-sti.c -- Low level frame buffer * operations for generic HP video boards using STI (standard * text interface) firmware * * Based on linux/drivers/video/fbcon-artist.c * Created 5 Apr 1997 by Geert Uytterhoeven * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive for * more details. */#include <linux/module.h>#include <linux/tty.h>#include <linux/console.h>#include <linux/string.h>#include <linux/fb.h>#include <linux/delay.h>#include <asm/types.h>#include <video/fbcon.h>#include <video/fbcon-mfb.h>#include "sti.h"/* Translate an address as it would be found in a 2048x2048x1 bit frame * buffer into a logical address Artist actually expects. Addresses fed * into Artist look like this: * fixed Y X * FFFF FFFF LLLL LLLL LLLC CCCC CCCC CC00 * * our "RAM" addresses look like this: * * FFFF FFFF 0000 0LLL LLLL LLLL CCCC CCCC [CCC] * * */static inline u32ram2log(void * addr){ u32 a = (unsigned long) addr; u32 r;#if 0 r = a & 0xff000000; /* fixed part */ r += ((a & 0x000000ff) << 5); r += ((a & 0x00ffff00) << 3);#else r = a & 0xff000000; /* fixed part */ r += ((a & 0x000000ff) << 5); r += ((a & 0x0007ff00) << 5);#endif return r;}/* All those functions need better names. */static voidmemcpy_fromhp_tohp(void *dest, void *src, int count){ unsigned long d = ram2log(dest); unsigned long s = ram2log(src); count += 3; count &= ~3; /* XXX */ while(count) { count --; gsc_writel(~gsc_readl(s), d); d += 32*4; s += 32*4; }}static voidmemcpy_tohp(void *dest, void *src, int count){ unsigned long d = (unsigned long) dest; u32 *s = (u32 *)src; count += 3; count &= ~3; /* XXX */ d = ram2log(dest); while(count) { count--; gsc_writel(*s++, d); d += 32*4; }}static voidmemcopy_fromhp(void *dest, void *src, int count){ /* FIXME */ printk("uhm ...\n");}static voidmemset_tohp(void *dest, u32 word, int count){ unsigned long d = ram2log(dest); count += 3; count &= ~3; while(count) { count--; gsc_writel(word, d); d += 32; }}static u8readb_hp(void *src){ unsigned long s = ram2log(src); return ~gsc_readb(s);}static voidwriteb_hp(u8 b, void *dst){ unsigned long d = ram2log(dst); if((d&0xf0000000) != 0xf0000000) { printk("writeb_hp %02x %p (%08lx) (%p)\n", b, dst, d, __builtin_return_address(0)); return; } gsc_writeb(b, d);}static voidfbcon_sti_setup(struct display *p){ if (p->line_length) p->next_line = p->line_length; else p->next_line = p->var.xres_virtual>>3; p->next_plane = 0;}static voidfbcon_sti_bmove(struct display *p, int sy, int sx, int dy, int dx, int height, int width){#if 0 /* Unfortunately, still broken */ sti_bmove(&default_sti /* FIXME */, sy, sx, dy, dx, height, width);#else u8 *src, *dest; u_int rows; if (sx == 0 && dx == 0 && width == p->next_line) { src = p->screen_base+sy*fontheight(p)*width; dest = p->screen_base+dy*fontheight(p)*width; memcpy_fromhp_tohp(dest, src, height*fontheight(p)*width); } else if (dy <= sy) { src = p->screen_base+sy*fontheight(p)*p->next_line+sx; dest = p->screen_base+dy*fontheight(p)*p->next_line+dx; for (rows = height*fontheight(p); rows--;) { memcpy_fromhp_tohp(dest, src, width); src += p->next_line; dest += p->next_line; } } else { src = p->screen_base+((sy+height)*fontheight(p)-1)*p->next_line+sx; dest = p->screen_base+((dy+height)*fontheight(p)-1)*p->next_line+dx; for (rows = height*fontheight(p); rows--;) { memcpy_fromhp_tohp(dest, src, width); src -= p->next_line; dest -= p->next_line; } }#endif}static voidfbcon_sti_clear(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width){ u8 *dest; u_int rows; int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0; dest = p->screen_base+sy*fontheight(p)*p->next_line+sx; if (sx == 0 && width == p->next_line) { if (inverse) memset_tohp(dest, ~0, height*fontheight(p)*width); else memset_tohp(dest, 0, height*fontheight(p)*width); } else for (rows = height*fontheight(p); rows--; dest += p->next_line) if (inverse) memset_tohp(dest, 0xffffffff, width); else memset_tohp(dest, 0x00000000, width);}static void fbcon_sti_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx){ u8 *dest, *cdat; u_int rows, bold, revs, underl; u8 d; dest = p->screen_base+yy*fontheight(p)*p->next_line+xx; cdat = p->fontdata+(c&p->charmask)*fontheight(p); bold = attr_bold(p,c); revs = attr_reverse(p,c); underl = attr_underline(p,c); for (rows = fontheight(p); rows--; dest += p->next_line) { d = *cdat++; if (underl && !rows) d = 0xff; else if (bold) d |= d>>1; if (revs) d = ~d; writeb_hp (d, dest); }}static void fbcon_sti_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx){ u8 *dest, *dest0, *cdat; u_int rows, bold, revs, underl; u8 d; u16 c; if(((unsigned)xx > 200) || ((unsigned) yy > 200)) { printk("refusing to putcs %p %p %p %d %d %d (%p)\n", conp, p, s, count, yy, xx, __builtin_return_address(0)); return; } dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx; if(((u32)dest0&0xf0000000)!=0xf0000000) { printk("refusing to putcs %p %p %p %d %d %d (%p) %p = %p + %d * %d * %ld + %d\n", conp, p, s, count, yy, xx, __builtin_return_address(0), dest0, p->screen_base, yy, fontheight(p), p->next_line, xx); return; } c = scr_readw(s); bold = attr_bold(p, c); revs = attr_reverse(p, c); underl = attr_underline(p, c); while (count--) { c = scr_readw(s++) & p->charmask; dest = dest0++; cdat = p->fontdata+c*fontheight(p); for (rows = fontheight(p); rows--; dest += p->next_line) { d = *cdat++; if (0 && underl && !rows) d = 0xff; else if (0 && bold) d |= d>>1; if (revs) d = ~d; writeb_hp (d, dest); } }}static void fbcon_sti_revc(struct display *p, int xx, int yy){ u8 *dest, d; u_int rows; dest = p->screen_base+yy*fontheight(p)*p->next_line+xx; for (rows = fontheight(p); rows--; dest += p->next_line) { d = readb_hp(dest); writeb_hp (~d, dest); }}static voidfbcon_sti_clear_margins(struct vc_data *conp, struct display *p, int bottom_only){ u8 *dest; int height, bottom; int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0; /* XXX Need to handle right margin? */ height = p->var.yres - conp->vc_rows * fontheight(p); if (!height) return; bottom = conp->vc_rows + p->yscroll; if (bottom >= p->vrows) bottom -= p->vrows; dest = p->screen_base + bottom * fontheight(p) * p->next_line; if (inverse) memset_tohp(dest, 0xffffffff, height * p->next_line); else memset_tohp(dest, 0x00000000, height * p->next_line);} /* * `switch' for the low level operations */struct display_switch fbcon_sti = { setup: fbcon_sti_setup, bmove: fbcon_sti_bmove, clear: fbcon_sti_clear, putc: fbcon_sti_putc, putcs: fbcon_sti_putcs, revc: fbcon_sti_revc, clear_margins: fbcon_sti_clear_margins, fontwidthmask: FONTWIDTH(8)};MODULE_LICENSE("GPL");
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -