⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btext.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * BK Id: %F% %I% %G% %U% %#% *//* * Procedures for drawing on the screen early on in the boot process. * * Benjamin Herrenschmidt <benh@kernel.crashing.org> */#include <linux/config.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/init.h>#include <linux/version.h>#include <asm/sections.h>#include <asm/bootx.h>#include <asm/btext.h>#include <asm/prom.h>#include <asm/page.h>#include <asm/mmu.h>#include <asm/pgtable.h>#include <asm/io.h>#include <asm/processor.h>#define NO_SCROLL#ifndef NO_SCROLLstatic void scrollscreen(void);#endifstatic void draw_byte(unsigned char c, long locX, long locY);static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);static int g_loc_X;static int g_loc_Y;static int g_max_loc_X;static int g_max_loc_Y;unsigned long disp_BAT[2] __initdata = {0, 0};#define cmapsz	(16*256)static unsigned char vga_font[cmapsz];int boot_text_mapped = 1;boot_infos_t *disp_bi;boot_infos_t fake_bi;extern char *klimit;/* * Powermac can use btext_* after boot for xmon, * chrp only uses it during early boot. */#ifdef CONFIG_XMON#define BTEXT	__pmac#define BTDATA	__pmacdata#else#define BTEXT	__init#define BTDATA	__initdata#endif /* CONFIG_XMON *//* * This is called only when we are booted via BootX. */void __initbtext_init(boot_infos_t *bi){	unsigned long offset = reloc_offset();	RELOC(g_loc_X) = 0;	RELOC(g_loc_Y) = 0;	RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;	RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;	RELOC(disp_bi) = PTRUNRELOC(bi);}void __initbtext_welcome(boot_infos_t* bi){	unsigned long offset = reloc_offset();	unsigned long flags;	unsigned long pvr;		btext_drawstring(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));	btext_drawstring(RELOC("\nlinked at        : 0x"));	btext_drawhex(KERNELBASE);	btext_drawstring(RELOC("\nframe buffer at  : 0x"));	btext_drawhex((unsigned long)bi->dispDeviceBase);	btext_drawstring(RELOC(" (phys), 0x"));	btext_drawhex((unsigned long)bi->logicalDisplayBase);	btext_drawstring(RELOC(" (log)"));	btext_drawstring(RELOC("\nklimit           : 0x"));	btext_drawhex((unsigned long)RELOC(klimit));	btext_drawstring(RELOC("\nMSR              : 0x"));	__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));	btext_drawhex(flags);	__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));	pvr >>= 16;	if (pvr > 1) {	    btext_drawstring(RELOC("\nHID0             : 0x"));	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));	    btext_drawhex(flags);	}	if (pvr == 8 || pvr == 12 || pvr == 0x800c) {	    btext_drawstring(RELOC("\nICTC             : 0x"));	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));	    btext_drawhex(flags);	}	btext_drawstring(RELOC("\n\n"));}/* Calc BAT values for mapping the display and store them * in disp_BAT.  Those values are then used from head.S to map * the display during identify_machine() and MMU_Init() *  * The display is mapped to virtual address 0xD0000000, rather * than 1:1, because some some CHRP machines put the frame buffer * in the region starting at 0xC0000000 (KERNELBASE). * This mapping is temporary and will disappear as soon as the * setup done by MMU_Init() is applied. *  * For now, we align the BAT and then map 8Mb on 601 and 16Mb * on other PPCs. This may cause trouble if the framebuffer * is really badly aligned, but I didn't encounter this case * yet. */void __initbtext_prepare_BAT(void){	unsigned long offset = reloc_offset();	boot_infos_t* bi = PTRRELOC(RELOC(disp_bi));	unsigned long vaddr = KERNELBASE + 0x10000000;	unsigned long addr;	unsigned long lowbits;	if (!RELOC(disp_bi)) {		RELOC(boot_text_mapped) = 0;		return;	}	addr = (unsigned long)bi->dispDeviceBase;	if (!addr) {		RELOC(boot_text_mapped) = 0;		return;	}	if (PVR_VER(mfspr(PVR)) != 1) {		/* 603, 604, G3, G4, ... */		lowbits = addr & ~0xFF000000UL;		addr &= 0xFF000000UL;		RELOC(disp_BAT[0]) = vaddr | (BL_16M<<2) | 2;		RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);			} else {		/* 601 */		lowbits = addr & ~0xFF800000UL;		addr &= 0xFF800000UL;		RELOC(disp_BAT[0]) = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;		RELOC(disp_BAT[1]) = addr | BL_8M | 0x40;	}	bi->logicalDisplayBase = (void *) (vaddr + lowbits);}/* This function will enable the early boot text when doing OF booting. This * way, xmon output should work too */void __initbtext_setup_display(int width, int height, int depth, int pitch,		    unsigned long address){	unsigned long offset = reloc_offset();	boot_infos_t* bi;	RELOC(disp_bi) = &fake_bi;	bi = PTRRELOC((&fake_bi));	RELOC(g_loc_X) = 0;	RELOC(g_loc_Y) = 0;	RELOC(g_max_loc_X) = width / 8;	RELOC(g_max_loc_Y) = height / 16;	bi->logicalDisplayBase = (unsigned char *)address;	bi->dispDeviceBase = (unsigned char *)address;	bi->dispDeviceRowBytes = pitch;	bi->dispDeviceDepth = depth;	bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;	bi->dispDeviceRect[2] = width;	bi->dispDeviceRect[3] = height;}/* Here's a small text engine to use during early boot * or for debugging purposes *  * todo: *  *  - build some kind of vgacon with it to enable early printk *  - move to a separate file *  - add a few video driver hooks to keep in sync with display *    changes. */void __openfirmwaremap_boot_text(void){	unsigned long base, offset, size;	if (disp_bi == 0)		return;	base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL;	offset = ((unsigned long) disp_bi->dispDeviceBase) - base;	size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset		+ disp_bi->dispDeviceRect[0];	disp_bi->logicalDisplayBase = ioremap(base, size);	if (disp_bi->logicalDisplayBase == 0)		return;	disp_bi->logicalDisplayBase += offset;	boot_text_mapped = 1;}/* Calc the base address of a given point (x,y) */static unsigned char * BTEXTcalc_base(boot_infos_t *bi, int x, int y){	unsigned char *base;	base = bi->logicalDisplayBase;	if (base == 0)		base = bi->dispDeviceBase;	base += (x + bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3);	base += (y + bi->dispDeviceRect[1]) * bi->dispDeviceRowBytes;	return base;}/* Adjust the display to a new resolution */voidbtext_update_display(unsigned long phys, int width, int height,		     int depth, int pitch){	if (disp_bi == 0)		return;	/* check it's the same frame buffer (within 256MB) */	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xf0000000)		return;	disp_bi->dispDeviceBase = (__u8 *) phys;	disp_bi->dispDeviceRect[0] = 0;	disp_bi->dispDeviceRect[1] = 0;	disp_bi->dispDeviceRect[2] = width;	disp_bi->dispDeviceRect[3] = height;	disp_bi->dispDeviceDepth = depth;	disp_bi->dispDeviceRowBytes = pitch;	if (boot_text_mapped) {		iounmap(disp_bi->logicalDisplayBase);		boot_text_mapped = 0;	}	map_boot_text();	g_loc_X = 0;	g_loc_Y = 0;	g_max_loc_X = width / 8;	g_max_loc_Y = height / 16;}void BTEXT btext_clearscreen(void){	unsigned long offset	= reloc_offset();	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *					(bi->dispDeviceDepth >> 3)) >> 2;	int i,j;		for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)	{		unsigned long *ptr = base;		for(j=width; j; --j)			*(ptr++) = 0;		base += (bi->dispDeviceRowBytes >> 2);	}}__inline__ void dcbst(const void* addr){	__asm__ __volatile__ ("dcbst 0,%0" :: "r" (addr));}void BTEXT btext_flushscreen(void){	unsigned long offset	= reloc_offset();	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *					(bi->dispDeviceDepth >> 3)) >> 2;	int i,j;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -