📄 misc.c
字号:
/* * misc.c * * $Id: misc.c,v 1.68 1999/10/20 22:08:08 cort Exp $ * * Adapted for PowerPC by Gary Thomas * * Rewritten by Cort Dougan (cort@cs.nmt.edu) * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort */#include <linux/types.h>#include "../coffboot/zlib.h"#include "asm/residual.h"#include <linux/elf.h>#include <linux/config.h>#include <asm/page.h>#include <asm/processor.h>#include <asm/bootinfo.h>#include <asm/mmu.h>#if defined(CONFIG_SERIAL_CONSOLE)#include "ns16550.h"struct NS16550 *com_port;#endif /* CONFIG_SERIAL_CONSOLE *//* * Please send me load/board info and such data for hardware not * listed here so I can keep track since things are getting tricky * with the different load addrs with different firmware. This will * help to avoid breaking the load/boot process. * -- Cort */char *avail_ram;char *end_avail;extern char _end[];#ifdef CONFIG_CMDLINE#define CMDLINE CONFIG_CMDLINE#else#define CMDLINE "";#endifchar cmd_preset[] = CMDLINE;char cmd_buf[256];char *cmd_line = cmd_buf;int keyb_present = 1; /* keyboard controller is present by default */RESIDUAL hold_resid_buf;RESIDUAL *hold_residual = &hold_resid_buf;unsigned long initrd_start = 0, initrd_end = 0;char *zimage_start;int zimage_size;char *vidmem = (char *)0xC00B8000;int lines, cols;int orig_x, orig_y;void puts(const char *);void putc(const char c);void puthex(unsigned long val);void _bcopy(char *src, char *dst, int len);void * memcpy(void * __dest, __const void * __src, int __n);void gunzip(void *, int, unsigned char *, int *);static int _cvt(unsigned long val, char *buf, long radix, char *digits);unsigned char inb(int);void pause(){ puts("pause\n");}void exit(){ puts("exit\n"); while(1); }static void clear_screen(){ int i, j; for (i = 0; i < lines; i++) { for (j = 0; j < cols; j++) { vidmem[((i*cols)+j)*2] = ' '; vidmem[((i*cols)+j)*2+1] = 0x07; } }}static void scroll(){ int i; memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) vidmem[i] = ' ';}tstc(void){#if defined(CONFIG_SERIAL_CONSOLE) if (keyb_present) return (CRT_tstc() || NS16550_tstc(com_port)); else NS16550_tstc(com_port);#else return (CRT_tstc() );#endif /* CONFIG_SERIAL_CONSOLE */}getc(void){ while (1) {#if defined(CONFIG_SERIAL_CONSOLE) if (NS16550_tstc(com_port)) return (NS16550_getc(com_port));#endif /* CONFIG_SERIAL_CONSOLE */ if (keyb_present) if (CRT_tstc()) return (CRT_getc()); }}void putc(const char c){ int x,y;#if defined(CONFIG_SERIAL_CONSOLE) NS16550_putc(com_port, c); if ( c == '\n' ) NS16550_putc(com_port, '\r');#endif /* CONFIG_SERIAL_CONSOLE */ x = orig_x; y = orig_y; if ( c == '\n' ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } else if (c == '\r') { x = 0; } else if (c == '\b') { if (x > 0) { x--; } } else { vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } } cursor(x, y); orig_x = x; orig_y = y;}void puts(const char *s){ int x,y; char c; x = orig_x; y = orig_y; while ( ( c = *s++ ) != '\0' ) {#if defined(CONFIG_SERIAL_CONSOLE) NS16550_putc(com_port, c); if ( c == '\n' ) NS16550_putc(com_port, '\r');#endif /* CONFIG_SERIAL_CONSOLE */ if ( c == '\n' ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } else if (c == '\b') { if (x > 0) { x--; } } else { vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } } } cursor(x, y); orig_x = x; orig_y = y;}void * memcpy(void * __dest, __const void * __src, int __n){ int i; char *d = (char *)__dest, *s = (char *)__src; for (i=0;i<__n;i++) d[i] = s[i];}int memcmp(__const void * __dest, __const void * __src, int __n){ int i; char *d = (char *)__dest, *s = (char *)__src; for (i=0;i<__n;i++, d++, s++) { if (*d != *s) { return (*s - *d); } } return (0);}void error(char *x){ puts("\n\n"); puts(x); puts("\n\n -- System halted"); while(1); /* Halt */}void *zalloc(void *x, unsigned items, unsigned size){ void *p = avail_ram; size *= items; size = (size + 7) & -8; avail_ram += size; if (avail_ram > end_avail) { puts("oops... out of memory\n"); pause(); } return p;}void zfree(void *x, void *addr, unsigned nb){}#define HEAD_CRC 2#define EXTRA_FIELD 4#define ORIG_NAME 8#define COMMENT 0x10#define RESERVED 0xe0#define DEFLATED 8void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp){ z_stream s; int r, i, flags; /* skip header */ i = 10; flags = src[3]; if (src[2] != DEFLATED || (flags & RESERVED) != 0) { puts("bad gzipped data\n"); exit(); } if ((flags & EXTRA_FIELD) != 0) i = 12 + src[10] + (src[11] << 8); if ((flags & ORIG_NAME) != 0) while (src[i++] != 0) ; if ((flags & COMMENT) != 0) while (src[i++] != 0) ; if ((flags & HEAD_CRC) != 0) i += 2; if (i >= *lenp) { puts("gunzip: ran out of data in header\n"); exit(); } s.zalloc = zalloc; s.zfree = zfree; r = inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { puts("inflateInit2 returned %d\n"); exit(); } s.next_in = src + i; s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; r = inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { puts("inflate returned %d\n"); exit(); } *lenp = s.next_out - (unsigned char *) dst; inflateEnd(&s);}unsigned longdecompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, RESIDUAL *residual, void *OFW_interface){ int timer; extern unsigned long start; char *cp, ch; unsigned long i; BATU *u; BATL *l; unsigned long TotalMemory; unsigned long orig_MSR; int dev_handle; int mem_info[2]; int res, size; unsigned char board_type; unsigned char base_mod; lines = 25; cols = 80; orig_x = 0; orig_y = 24; /* * IBM's have the MMU on, so we have to disable it or * things get really unhappy in the kernel when * trying to setup the BATs with the MMU on * -- Cort */ flush_instruction_cache(); _put_HID0(_get_HID0() & ~0x0000C000); _put_MSR((orig_MSR = _get_MSR()) & ~0x0030);#if defined(CONFIG_SERIAL_CONSOLE) com_port = (struct NS16550 *)NS16550_init(0);#endif /* CONFIG_SERIAL_CONSOLE */ vga_init(0xC0000000); if (residual) { /* Is this Motorola PPCBug? */ if ((1 & residual->VitalProductData.FirmwareSupports) && (1 == residual->VitalProductData.FirmwareSupplier)) { board_type = inb(0x800) & 0xF0; /* If this is genesis 2 board then check for no * keyboard controller and more than one processor. */ if (board_type == 0xe0) { base_mod = inb(0x803); /* if a MVME2300/2400 or a Sitka then no keyboard */ if((base_mod == 0xFA) || (base_mod == 0xF9) || (base_mod == 0xE1)) { keyb_present = 0; /* no keyboard */ } } } memcpy(hold_residual,residual,sizeof(RESIDUAL)); } else { /* Assume 32M in the absence of more info... */ TotalMemory = 0x02000000; /* * This is a 'best guess' check. We want to make sure * we don't try this on a PReP box without OF * -- Cort */ while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) ) { /* The MMU needs to be on when we call OFW */ _put_MSR(orig_MSR); of_init(OFW_interface); /* get handle to memory description */ res = of_finddevice("/memory@0", &dev_handle); // puthex(res); puts("\n"); if (res) break; /* get the info */ // puts("get info = "); res = of_getprop(dev_handle, "reg", mem_info, sizeof(mem_info), &size); // puthex(res); puts(", info = "); puthex(mem_info[0]); // puts(" "); puthex(mem_info[1]); puts("\n"); if (res) break; TotalMemory = mem_info[1]; break; } hold_residual->TotalMemory = TotalMemory; residual = hold_residual; /* Turn MMU back off */ _put_MSR(orig_MSR & ~0x0030); } /* assume the chunk below 8M is free */ end_avail = (char *)0x00800000; /* tell the user where we were loaded at and where we * were relocated to for debugging this process */ puts("loaded at: "); puthex(load_addr); puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); if ( (unsigned long)load_addr != (unsigned long)&start ) { puts("relocated to: "); puthex((unsigned long)&start); puts(" "); puthex((unsigned long)((unsigned long)&start + (4*num_words)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -