diff options
Diffstat (limited to 'arch/ppc/boot')
-rw-r--r-- | arch/ppc/boot/Makefile | 86 | ||||
-rw-r--r-- | arch/ppc/boot/head.S | 116 | ||||
-rw-r--r-- | arch/ppc/boot/kbd.c | 55 | ||||
-rw-r--r-- | arch/ppc/boot/mbxtty.c | 201 | ||||
-rw-r--r-- | arch/ppc/boot/misc.c | 695 | ||||
-rw-r--r-- | arch/ppc/boot/mkprep.c | 11 | ||||
-rw-r--r-- | arch/ppc/boot/of1275.c | 427 | ||||
-rw-r--r-- | arch/ppc/boot/of1275.h | 421 | ||||
-rw-r--r-- | arch/ppc/boot/piggyback.c | 64 |
9 files changed, 1294 insertions, 782 deletions
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index da4945fd7..5a83e79ee 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -14,7 +14,7 @@ .s.o: $(AS) -o $*.o $< .c.o: - $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $< + $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -c -o $*.o $< .S.s: $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $< .S.o: @@ -25,17 +25,14 @@ ZSZ = 0 IOFF = 0 ISZ = 0 -ifeq ($(CONFIG_ALL_PPC),y) -# yes, we want to build prep stuff -CONFIG_PREP = y -endif - -ifeq ($(CONFIG_MBX),y) -ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00100000 +ifeq ($(CONFIG_SMP),y) +TFTPIMAGE=/tftpboot/zImage.prep.smp else -ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00600000 +TFTPIMAGE=/tftpboot/zImage.prep endif +ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00800000 + GZIP_FLAGS = -v9 OBJECTS := head.o misc.o ../coffboot/zlib.o @@ -43,19 +40,13 @@ CFLAGS = -O2 -DSTDC_HEADERS -fno-builtin -I$(TOPDIR)/include OBJCOPY = $(CROSS_COMPILE)objcopy OBJCOPY_ARGS = -O elf32-powerpc -ifeq ($(CONFIG_MBX),y) -OBJECTS += mbxtty.o -CFLAGS += -DCONFIG_MBX -else -OBJECTS += vreset.o kbd.o +OBJECTS += vreset.o kbd.o of1275.o ifeq ($(CONFIG_SERIAL_CONSOLE),y) OBJECTS += ns16550.o endif -endif all: zImage -ifeq ($(CONFIG_PREP),y) zvmlinux.initrd: zvmlinux $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ @@ -66,54 +57,19 @@ zvmlinux.initrd: zvmlinux -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd initrd` \ -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd image` \ -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd image` \ - -DKERNELBASE=$(KERNELBASE) -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp $@ - rm zvmlinux.initrd.tmp -endif -ifeq ($(CONFIG_MBX),y) -zvmlinux.initrd: zvmlinux - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp zvmlinux.initrd - $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd initrd` \ - -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd initrd` \ - -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd image` \ - -DKERNELBASE=$(KERNELBASE) -c -o misc.o misc.c + -c -o misc.o misc.c $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ --add-section=initrd=ramdisk.image.gz \ --add-section=image=../coffboot/vmlinux.gz \ zvmlinux.initrd.tmp $@ rm zvmlinux.initrd.tmp -endif -ifeq ($(CONFIG_PREP),y) zImage: zvmlinux mkprep ./mkprep -pbp zvmlinux zImage -else -ifeq ($(CONFIG_MBX),y) -zImage: zvmlinux - ln -sf zvmlinux zImage -else -zImage: -endif -endif -ifeq ($(CONFIG_PREP),y) zImage.initrd: zvmlinux.initrd mkprep ./mkprep -pbp zvmlinux.initrd zImage.initrd -endif -ifeq ($(CONFIG_MBX),y) -zImage.initrd: zvmlinux.initrd - ln -sf zvmlinux.initrd zImage.initrd -endif zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz # @@ -128,7 +84,7 @@ zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz # $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` -DKERNELBASE=$(KERNELBASE) \ + -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \ -c -o misc.o misc.c $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ @@ -136,34 +92,16 @@ zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz rm zvmlinux.tmp floppy: $(TOPDIR)/vmlinux zImage -ifeq ($(CONFIG_PREP),y) dd if=zImage of=/dev/fd0H1440 bs=64b -endif -ifeq ($(CONFIG_PREP),y) mkprep : mkprep.c - $(HOSTCC) -DKERNELBASE=$(KERNELBASE) -o mkprep mkprep.c -endif + $(HOSTCC) -o mkprep mkprep.c -ifeq ($(CONFIG_PREP),y) znetboot : zImage - cp zImage /tftpboot/zImage.prep -else -ifeq ($(CONFIG_MBX),y) -znetboot : zImage - cp zImage /tftpboot/zImage.mbx -else -znetboot : -endif -endif + cp zImage $(TFTPIMAGE) znetboot.initrd : zImage.initrd -ifeq ($(CONFIG_PREP),y) - cp zImage.initrd /tftpboot/zImage.prep -endif -ifeq ($(CONFIG_MBX),y) - cp zImage.initrd /tftpboot/zImage.mbx -endif + cp zImage.initrd $(TFTPIMAGE) clean: rm -f vmlinux* zvmlinux* mkprep zImage* diff --git a/arch/ppc/boot/head.S b/arch/ppc/boot/head.S index 43facf7e2..552e82fa1 100644 --- a/arch/ppc/boot/head.S +++ b/arch/ppc/boot/head.S @@ -1,4 +1,3 @@ -#include <linux/config.h> #include "../kernel/ppc_defs.h" #include "../kernel/ppc_asm.tmpl" #include <asm/processor.h> @@ -7,43 +6,24 @@ .text /* - * $Id: head.S,v 1.26 1998/09/19 01:21:20 cort Exp $ + * $Id: head.S,v 1.31 1999/04/22 06:32:00 davem Exp $ * - * This code is loaded by the ROM loader at some arbitrary location. - * Move it to high memory so that it can load the kernel at 0x0000. - * - * The MBX EPPC-Bug understands ELF, so it loads us into the location - * specified in the header. This is a two step process. First, EPPC-Bug - * loads the file into the intermediate buffer memory location specified - * by the environment parameters. When it discovers this is an ELF - * binary, it relocates to the link address for us. Unfortunately, the - * header does not move with the file, so we have to find the - * intermediate load location and read the header from there. From - * information provided by Motorola (thank you), we know this intermediate - * location can be found from the NVRAM environment. - * All of these addresses must be somewhat carefully chosen to make sure - * we don't overlap the regions. I chose to load the kernel at 0, the - * compressed image loads at 0x00100000, and the MBX intermediate buffer - * was set to 0x00200000. Provided the loaded kernel image never grows - * over one megabyte (which I am going to ensure never happens :-), these - * will work fine. When we get called from EPPC-Bug, registers are: - * R1 - Stack pointer at a high memory address. - * R3 - Pointer to Board Information Block. - * R4 - Pointer to argument string. - * Interrupts masked, cache and MMU disabled. + * Boot loader philosophy: + * ROM loads us to some arbitrary location + * Move the boot code to the link address (8M) + * Call decompress_kernel() + * Relocate the initrd, zimage and residual data to 8M + * Decompress the kernel to 0 + * Jump to the kernel entry + * -- Cort */ - .globl start start: bl start_ start_: mr r11,r3 /* Save pointer to residual/board data */ - -#ifndef CONFIG_MBX - mfmsr r3 /* Turn off interrupts */ - li r4,0 - ori r4,r4,MSR_EE - andc r3,r3,r4 + mr r25,r5 /* Save OFW pointer */ + li r3,MSR_IP /* Establish default MSR value */ mtmsr r3 /* check if we need to relocate ourselves to the link addr or were we @@ -68,25 +48,6 @@ start_: mr r7,r5 b start_ldr 1010: -#if 0 -/* Copy relocation code down to location 0x0100 (where we hope it's safe!) */ - mflr r3 - addi r5,r3,start_ldr-start_ - addi r3,r3,relocate-start_ - li r4,0x0100 - mtctr r4 - subi r3,r3,4 - subi r4,r4,4 -00: lwzu r6,4(r3) - stwu r6,4(r4) - cmp 0,r3,r5 - bne 00b - mflr r21 - mfctr r22 - mtlr r21 - mtctr r22 - bctr /* Jump to code */ -#endif /* * no matter where we're loaded, move ourselves to -Ttext address */ @@ -96,13 +57,8 @@ relocate: mr r8,r3 lis r4,start@h ori r4,r4,start@l -#if 0 - lis r5,edata@h - ori r5,r5,edata@l -#else lis r5,end@h ori r5,r5,end@l -#endif addi r5,r5,3 /* Round up - just in case */ sub r5,r5,r4 /* Compute # longwords to move */ srwi r5,r5,2 @@ -120,7 +76,6 @@ relocate: mtlr r3 /* Easiest way to do an absolute jump */ blr start_ldr: -#endif /* ndef CONFIG_MBX */ /* Clear all of BSS */ lis r3,edata@h ori r3,r3,edata@l @@ -140,31 +95,11 @@ start_ldr: li r2,0x000F /* Mask pointer to 16-byte boundary */ andc r1,r1,r2 /* Run loader */ -#ifdef CONFIG_MBX - mr r3, r11 - mr r21, r11 - bl serial_init /* Init MBX serial port */ - - lis r8, 0xfa200000@h /* Disable Ethernet SCC */ - li r0, 0 - stw r0, 0x0a00(r8) - - mr r11, r21 - lis r8,start@h - ori r8,r8,start@l - li r9,end@h - ori r9,r9,end@l - sub r7,r8,r9 - srwi r7,r7,2 -#define ILAP_ADDRESS 0xfa000020 - lis r8, ILAP_ADDRESS@h - lwz r8, ILAP_ADDRESS@l(r8) - addis r8, r8, 1 /* Add 64K */ -#endif mr r3,r8 /* Load point */ mr r4,r7 /* Program length */ mr r5,r6 /* Checksum */ mr r6,r11 /* Residual data */ + mr r7,r25 /* OFW interfaces */ bl decompress_kernel /* changed to use r3 (as firmware does) for kernel @@ -193,12 +128,24 @@ start_ldr: li r9,0x0 lwz r9,0(r9) mtlr r9 -#ifndef CONFIG_MBX li r9,0 lis r10,0xdeadc0de@h ori r10,r10,0xdeadc0de@l stw r10,0(r9) -#endif +/* + * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2 + * so disable BATs before setting this to avoid a clash + */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT1U,r8 + mtspr DBAT2U,r8 + mtspr DBAT3U,r8 + mtspr IBAT0U,r8 + mtspr IBAT1U,r8 + mtspr IBAT2U,r8 + mtspr IBAT3U,r8 + blr hang: b hang @@ -269,7 +216,6 @@ _put_MSR: _GLOBAL(flush_instruction_cache) mflr r5 bl flush_data_cache -#ifndef CONFIG_MBX mfspr r3,HID0 /* Caches are controlled by this register */ li r4,0 ori r4,r4,(HID0_ICE|HID0_ICFI) @@ -278,18 +224,12 @@ _GLOBAL(flush_instruction_cache) andc r3,r3,r4 ori r3,r3,HID0_ICE /* Enable cache */ mtspr HID0,r3 -#endif mtlr r5 blr #define NUM_CACHE_LINES 128*8 #define CACHE_LINE_SIZE 32 -#if 0 -cache_flush_buffer: - .space NUM_CACHE_LINES*CACHE_LINE_SIZE /* CAUTION! these need to match hardware */ -#else #define cache_flush_buffer 0x1000 -#endif /* * Flush data cache @@ -300,11 +240,7 @@ _GLOBAL(flush_data_cache) ori r3,r3,cache_flush_buffer@l li r4,NUM_CACHE_LINES mtctr r4 -#if 0 -00: dcbz 0,r3 /* Flush cache line with minimal BUS traffic */ -#else 00: lwz r4,0(r3) -#endif addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ bdnz 00b 10: blr diff --git a/arch/ppc/boot/kbd.c b/arch/ppc/boot/kbd.c index 9f5cd330b..49a102e9c 100644 --- a/arch/ppc/boot/kbd.c +++ b/arch/ppc/boot/kbd.c @@ -1,7 +1,6 @@ - #include <linux/keyboard.h> -#include <../drivers/char/defkeymap.c> /* yeah I know it's bad */ +#include <../drivers/char/defkeymap.c> /* yeah I know it's bad -- Cort */ unsigned char shfts, ctls, alts, caps; @@ -119,7 +118,7 @@ enter: /* Wait for key up */ } break; } - if (brk) return (0); /* Ignore initial 'key up' codes */ + if (brk) return (-1); /* Ignore initial 'key up' codes */ goto loop; } @@ -128,6 +127,11 @@ static void kbdreset(void) unsigned char c; int i; + /* flush input queue */ + while ((inb(KBSTATP) & KBINRDY)) + { + (void)inb(KBDATAP); + } /* Send self-test */ while (inb(KBSTATP) & KBOUTRDY) ; outb(KBSTATP,0xAA); @@ -144,22 +148,63 @@ static void kbdreset(void) while (inb(KBSTATP) & KBOUTRDY) ; outb(KBDATAP,0x45); for (i = 0; i < 10000; i++) udelay(1); + + while (inb(KBSTATP) & KBOUTRDY) ; + outb(KBSTATP,0x20); + while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + if (! (inb(KBDATAP) & 0x40)) { + /* + * Quote from PS/2 System Reference Manual: + * + * "Address hex 0060 and address hex 0064 should be + * written only when the input-buffer-full bit and + * output-buffer-full bit in the Controller Status + * register are set 0." (KBINRDY and KBOUTRDY) + */ + + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + outb(KBDATAP,0xF0); + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + outb(KBDATAP,0x01); + } + while (inb(KBSTATP) & KBOUTRDY) ; outb(KBSTATP,0xAE); } +/* We have to actually read the keyboard when CRT_tstc is called, + * since the pending data might be a key release code, and therefore + * not valid data. In this case, kbd() will return -1, even though there's + * data to be read. Of course, we might actually read a valid key press, + * in which case it gets queued into key_pending for use by CRT_getc. + */ + static int kbd_reset = 0; +static int key_pending = -1; + int CRT_getc(void) { int c; if (!kbd_reset) {kbdreset(); kbd_reset++; } + + if (key_pending != -1) { + c = key_pending; + key_pending = -1; + return c; + } else { while ((c = kbd(0)) == 0) ; - return(c); + return c; + } } int CRT_tstc(void) { if (!kbd_reset) {kbdreset(); kbd_reset++; } - return ((inb(KBSTATP) & KBINRDY) != 0); + + while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) { + key_pending = kbd(1); + } + + return (key_pending != -1); } diff --git a/arch/ppc/boot/mbxtty.c b/arch/ppc/boot/mbxtty.c deleted file mode 100644 index e5566dc32..000000000 --- a/arch/ppc/boot/mbxtty.c +++ /dev/null @@ -1,201 +0,0 @@ - - -/* Minimal serial functions needed to send messages out the serial - * port on the MBX console. - * - * The MBX uxes SMC1 for the serial port. We reset the port and use - * only the first BD that EPPC-Bug set up as a character FIFO. - * - * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug - * use COM1 instead of SMC1 as the console port. This kinda sucks - * for the rest of the kernel, so here we force the use of SMC1 again. - * I f**ked around for a day trying to figure out how to make EPPC-Bug - * use SMC1, but gave up and decided to fix it here. - */ -#include <linux/config.h> -#include <linux/types.h> -#ifdef CONFIG_MBX -#include <asm/mbx.h> -#endif -#ifdef CONFIG_FADS -#include <asm/fads.h> -#endif -#include "../8xx_io/commproc.h" - -#ifdef CONFIG_MBX -#define MBX_CSR1 ((volatile u_char *)0xfa100000) -#define CSR1_COMEN (u_char)0x02 -#endif - -static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); - -void -serial_init(bd_t *bd) -{ - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8xx_t *cp; - uint dpaddr, memaddr; - - cp = cpmp; - sp = (smc_t*)&(cp->cp_smc[0]); - up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; - - /* Disable transmitter/receiver. - */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - -#ifdef CONFIG_MBX - if (*MBX_CSR1 & CSR1_COMEN) { - /* COM1 is enabled. Initialize SMC1 and use it for - * the console port. - */ - - /* Enable SDMA. - */ - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; - - /* Use Port B for SMCs instead of other functions. - */ - cp->cp_pbpar |= 0x00000cc0; - cp->cp_pbdir &= ~0x00000cc0; - cp->cp_pbodr &= ~0x00000cc0; - - /* Allocate space for two buffer descriptors in the DP ram. - * For now, this address seems OK, but it may have to - * change with newer versions of the firmware. - */ - dpaddr = 0x0800; - - /* Grab a few bytes from the top of memory. EPPC-Bug isn't - * running any more, so we can do this. - */ - memaddr = (bd->bi_memsize - 32) & ~15; - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; - rbdf->cbd_bufaddr = memaddr; - rbdf->cbd_sc = 0; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = memaddr+4; - tbdf->cbd_sc = 0; - - /* Set up the uart parameters in the parameter ram. - */ - up->smc_rbase = dpaddr; - up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Mask all interrupts and remove anything pending. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* Set up the baud rate generator. - * See 8xx_io/commproc.c for details. - */ - cp->cp_simode = 0x10000000; - cp->cp_brgc1 = - ((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN; - - /* Enable SMC1 for console output. - */ - *MBX_CSR1 &= ~CSR1_COMEN; - } - else { -#endif - /* SMC1 is used as console port. - */ - tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; - rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; - - /* Issue a stop transmit, and wait for it. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, - CPM_CR_STOP_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); -#ifdef CONFIG_MBX - } -#endif - - /* Make the first buffer the only buffer. - */ - tbdf->cbd_sc |= BD_SC_WRAP; - rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; - - /* Single character receive. - */ - up->smc_mrblr = 1; - up->smc_maxidl = 0; - - /* Initialize Tx/Rx parameters. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Enable transmitter/receiver. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -} - -void -serial_putchar(const char c) -{ - volatile cbd_t *tbdf; - volatile char *buf; - volatile smc_uart_t *up; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; - tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; - - /* Wait for last character to go. - */ - buf = (char *)tbdf->cbd_bufaddr; - while (tbdf->cbd_sc & BD_SC_READY); - - *buf = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; -} - -char -serial_getc() -{ - volatile cbd_t *rbdf; - volatile char *buf; - volatile smc_uart_t *up; - char c; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; - rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; - - /* Wait for character to show up. - */ - buf = (char *)rbdf->cbd_bufaddr; - while (rbdf->cbd_sc & BD_SC_EMPTY); - c = *buf; - rbdf->cbd_sc |= BD_SC_EMPTY; - - return(c); -} - -int -serial_tstc() -{ - volatile cbd_t *rbdf; - volatile smc_uart_t *up; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; - rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; - - return(!(rbdf->cbd_sc & BD_SC_EMPTY)); -} diff --git a/arch/ppc/boot/misc.c b/arch/ppc/boot/misc.c index 470e1e4a9..15d347df5 100644 --- a/arch/ppc/boot/misc.c +++ b/arch/ppc/boot/misc.c @@ -1,7 +1,7 @@ /* * misc.c * - * $Id: misc.c,v 1.53 1998/12/15 17:40:15 cort Exp $ + * $Id: misc.c,v 1.64 1999/04/30 05:52:46 cort Exp $ * * Adapted for PowerPC by Gary Thomas * @@ -17,13 +17,7 @@ #include <asm/page.h> #include <asm/processor.h> #include <asm/mmu.h> -#ifdef CONFIG_MBX -#include <asm/mbx.h> -#endif -#ifdef CONFIG_FADS -#include <asm/fads.h> -#endif -#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) +#if defined(CONFIG_SERIAL_CONSOLE) #include "ns16550.h" struct NS16550 *com_port; #endif /* CONFIG_SERIAL_CONSOLE */ @@ -37,30 +31,18 @@ struct NS16550 *com_port; */ char *avail_ram; char *end_avail; +extern char _end[]; -/* Because of the limited amount of memory on the MBX, it presents - * loading problems. The biggest is that we load this boot program - * into a relatively low memory address, and the Linux kernel Bss often - * extends into this space when it get loaded. When the kernel starts - * and zeros the BSS space, it also writes over the information we - * save here and pass to the kernel (command line and board info). - * On the MBX we grab some known memory holes to hold this information. - */ -char cmd_preset[] = "console=tty0 console=ttyS0,9600n8"; -char cmd_buf[256]; -char *cmd_line = cmd_buf; - -#if defined(CONFIG_MBX) || defined(CONFIG_FADS) -char *root_string = "root=/dev/nfs"; -char *nfsaddrs_string = "nfsaddrs="; -char *nfsroot_string = "nfsroot="; -char *defroot_string = "/sys/mbxroot"; -int do_ipaddrs(char **cmd_cp, int echo); -void do_nfsroot(char **cmd_cp, char *dp); -int strncmp(const char * cs,const char * ct,size_t count); -char *strrchr(const char * s, int c); +#ifdef CONFIG_CMDLINE +#define CMDLINE CONFIG_CMDLINE +#else +#define CMDLINE ""; #endif +char 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; @@ -78,6 +60,8 @@ 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() { @@ -90,7 +74,6 @@ void exit() while(1); } -#if !defined(CONFIG_MBX) && !defined(CONFIG_FADS) static void clear_screen() { int i, j; @@ -113,8 +96,11 @@ static void scroll() tstc(void) { -#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) - return (CRT_tstc() || NS16550_tstc(com_port)); +#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 */ @@ -123,10 +109,11 @@ tstc(void) getc(void) { while (1) { -#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) +#if defined(CONFIG_SERIAL_CONSOLE) if (NS16550_tstc(com_port)) return (NS16550_getc(com_port)); #endif /* CONFIG_SERIAL_CONSOLE */ - if (CRT_tstc()) return (CRT_getc()); + if (keyb_present) + if (CRT_tstc()) return (CRT_getc()); } } @@ -135,7 +122,7 @@ putc(const char c) { int x,y; -#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) +#if defined(CONFIG_SERIAL_CONSOLE) NS16550_putc(com_port, c); if ( c == '\n' ) NS16550_putc(com_port, '\r'); #endif /* CONFIG_SERIAL_CONSOLE */ @@ -149,6 +136,8 @@ putc(const char c) scroll(); y--; } + } else if (c == '\r') { + x = 0; } else if (c == '\b') { if (x > 0) { x--; @@ -179,7 +168,7 @@ void puts(const char *s) y = orig_y; while ( ( c = *s++ ) != '\0' ) { -#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) +#if defined(CONFIG_SERIAL_CONSOLE) NS16550_putc(com_port, c); if ( c == '\n' ) NS16550_putc(com_port, '\r'); #endif /* CONFIG_SERIAL_CONSOLE */ @@ -206,42 +195,11 @@ void puts(const char *s) } } + cursor(x, y); + orig_x = x; orig_y = y; } -#else -/* The MBX is just the serial port. -*/ -tstc(void) -{ - return (serial_tstc()); -} - -getc(void) -{ - while (1) { - if (serial_tstc()) return (serial_getc()); - } -} - -void -putc(const char c) -{ - serial_putchar(c); -} - -void puts(const char *s) -{ - char c; - - while ( ( c = *s++ ) != '\0' ) { - serial_putchar(c); - if ( c == '\n' ) - serial_putchar('\r'); - } -} - -#endif /* CONFIG_MBX */ void * memcpy(void * __dest, __const void * __src, int __n) @@ -354,7 +312,8 @@ void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) unsigned char sanity[0x2000]; unsigned long -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, RESIDUAL *residual) +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, + RESIDUAL *residual, void *OFW_interface) { int timer; extern unsigned long start; @@ -362,9 +321,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R unsigned long i; BATU *u; BATL *l; -#if defined(CONFIG_MBX) || defined(CONFIG_KB) - char *dp; -#endif + 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; @@ -372,7 +335,6 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R orig_y = 24; -#if !defined(CONFIG_MBX) && !defined(CONFIG_FADS) /* * IBM's have the MMU on, so we have to disable it or * things get really unhappy in the kernel when @@ -381,42 +343,79 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R */ flush_instruction_cache(); _put_HID0(_get_HID0() & ~0x0000C000); - _put_MSR(_get_MSR() & ~0x0030); - vga_init(0xC0000000); + _put_MSR((orig_MSR = _get_MSR()) & ~0x0030); -#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) +#if defined(CONFIG_SERIAL_CONSOLE) com_port = (struct NS16550 *)NS16550_init(0); #endif /* CONFIG_SERIAL_CONSOLE */ + vga_init(0xC0000000); if (residual) - memcpy(hold_residual,residual,sizeof(RESIDUAL)); -#else /* CONFIG_MBX */ - - /* Grab some space for the command line and board info. Since - * we no longer use the ELF header, but it was loaded, grab - * that space. - */ - cmd_line = (char *)(load_addr - 0x10000); - hold_residual = (RESIDUAL *)(cmd_line + sizeof(cmd_buf)); - /* copy board data */ - if (residual) - memcpy(hold_residual,residual,sizeof(bd_t)); -#endif /* CONFIG_MBX */ + { + /* Is this Motorola PPCBug? */ + if ((1 & residual->VitalProductData.FirmwareSupports) && + (1 == residual->VitalProductData.FirmwareSupplier)) { + board_type = inb(0x800) & 0xF0; - /* MBX/prep sometimes put the residual/board info at the end of mem - * assume 16M for now -- Cort - * To boot on standard MBX boards with 4M, we can't use initrd, - * and we have to assume less memory. -- Dan - */ - if ( INITRD_OFFSET ) - end_avail = (char *)0x01000000; - else - end_avail = (char *)0x00400000; + /* 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 == 0x9) || (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); + } - /* let residual data tell us it's higher */ - if ( (unsigned long)residual > 0x00800000 ) - end_avail = (char *)PAGE_ALIGN((unsigned long)residual); + /* 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 ) @@ -431,20 +430,12 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R { puts("board data at: "); puthex((unsigned long)residual); puts(" "); -#if defined(CONFIG_MBX) || defined(CONFIG_FADS) - puthex((unsigned long)((unsigned long)residual + sizeof(bd_t))); -#else puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL))); -#endif puts("\n"); puts("relocated to: "); puthex((unsigned long)hold_residual); puts(" "); -#if defined(CONFIG_MBX) || defined(CONFIG_FADS) - puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t))); -#else puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL))); -#endif puts("\n"); } @@ -460,33 +451,16 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R initrd_end = INITRD_SIZE + initrd_start; /* - * setup avail_ram - this is the first part of ram usable - * by the uncompress code. -- Cort + * Find a place to stick the zimage and initrd and + * relocate them if we have to. -- Cort */ - avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size); - if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram) - && (load_addr <= 0x01000000) ) - avail_ram = (char *)(load_addr+(num_words*4)); - if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram) - && (load_addr <= 0x01000000) ) - avail_ram = (char *)((unsigned long)&start+(num_words*4)); - - /* relocate zimage */ + avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); puts("zimage at: "); puthex((unsigned long)zimage_start); puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); - /* - * don't relocate the zimage if it was loaded above 16M since - * things get weird if we try to relocate -- Cort - * We don't relocate zimage on a base MBX board because of - * insufficient memory. In this case we don't have initrd either, - * so use that as an indicator. -- Dan - */ - if (( (unsigned long)zimage_start <= 0x01000000 ) && initrd_start) + if ( (unsigned long)zimage_start <= 0x00800000 ) { - memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-zimage_size), - (void *)zimage_start, zimage_size ); - zimage_start = (char *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-zimage_size); - end_avail = (char *)zimage_start; + memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size ); + zimage_start = (char *)avail_ram; puts("relocated to: "); puthex((unsigned long)zimage_start); puts(" "); puthex((unsigned long)zimage_size+(unsigned long)zimage_start); @@ -498,44 +472,24 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R { puts("initrd at: "); puthex(initrd_start); puts(" "); puthex(initrd_end); puts("\n"); - /* - * Memory is really tight on the MBX (we can assume 4M) - * so put the initrd at the TOP of ram, and set end_avail - * to right after that. - * - * I should do something like this for prep, too and keep - * a variable end_of_DRAM to keep track of what we think the - * max ram is. - * -- Cort - */ -#if 0 - memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE), - (void *)initrd_start, - INITRD_SIZE ); - initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE); +#ifdef OMIT + avail_ram = (char *)PAGE_ALIGN( + (unsigned long)zimage_size+(unsigned long)zimage_start); + memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE ); + initrd_start = (unsigned long)avail_ram; initrd_end = initrd_start + INITRD_SIZE; - end_avail = (char *)initrd_start; puts("relocated to: "); puthex(initrd_start); puts(" "); puthex(initrd_end); puts("\n"); -#endif +#endif } -#ifndef CONFIG_MBX - /* this is safe, just use it */ - /* I don't know why it didn't work for me on the MBX with 20 MB - * memory. I guess something was saved up there, but I can't - * figure it out......we are running on luck. -- Dan. - */ avail_ram = (char *)0x00400000; - end_avail = (char *)0x00600000; -#endif + end_avail = (char *)0x00800000; puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); puthex((unsigned long)end_avail); puts("\n"); - -#if !defined(CONFIG_MBX) && !defined(CONFIG_FADS) - CRT_tstc(); /* Forces keyboard to be initialized */ -#endif + if (keyb_present) + CRT_tstc(); /* Forces keyboard to be initialized */ puts("\nLinux/PPC load: "); timer = 0; @@ -550,13 +504,6 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R cp--; puts("\b \b"); } -#ifdef CONFIG_MBX - } else if (ch == '?') { - if (!do_ipaddrs(&cp, 1)) { - *cp++ = ch; - putc(ch); - } -#endif } else { *cp++ = ch; putc(ch); @@ -567,32 +514,6 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R udelay(1000); /* 1 msec */ } *cp = 0; -#ifdef CONFIG_MBX - /* The MBX does not currently have any default boot strategy. - * If the command line is not filled in, we will automatically - * create the default network boot. - */ - if (cmd_line[0] == 0) { - dp = root_string; - while (*dp != 0) - *cp++ = *dp++; - *cp++ = ' '; - - dp = nfsaddrs_string; - while (*dp != 0) - *cp++ = *dp++; - dp = cp; - do_ipaddrs(&cp, 0); - *cp++ = ' '; - - /* Add the server address to the root file system path. - */ - dp = strrchr(dp, ':'); - dp++; - do_nfsroot(&cp, dp); - *cp = 0; - } -#endif puts("\n"); /* mappings on early boot can only handle 16M */ @@ -611,150 +532,6 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R return (unsigned long)hold_residual; } -#ifdef CONFIG_MBX -int -do_ipaddrs(char **cmd_cp, int echo) -{ - char *cp, *ip, ch; - unsigned char ipd; - int i, j, retval; - - /* We need to create the string: - * <my_ip>:<serv_ip> - */ - cp = *cmd_cp; - retval = 0; - - if ((cp - 9) >= cmd_line) { - if (strncmp(cp - 9, "nfsaddrs=", 9) == 0) { - ip = (char *)0xfa000060; - retval = 1; - for (j=0; j<2; j++) { - for (i=0; i<4; i++) { - ipd = *ip++; - - ch = ipd/100; - if (ch) { - ch += '0'; - if (echo) - putc(ch); - *cp++ = ch; - ipd -= 100 * (ch - '0'); - } - - ch = ipd/10; - if (ch) { - ch += '0'; - if (echo) - putc(ch); - *cp++ = ch; - ipd -= 10 * (ch - '0'); - } - - ch = ipd + '0'; - if (echo) - putc(ch); - *cp++ = ch; - - ch = '.'; - if (echo) - putc(ch); - *cp++ = ch; - } - - /* At the end of the string, remove the - * '.' and replace it with a ':'. - */ - *(cp - 1) = ':'; - if (echo) { - putc('\b'); putc(':'); - } - } - - /* At the end of the second string, remove the - * '.' from both the command line and the - * screen. - */ - --cp; - putc('\b'); putc(' '); putc('\b'); - } - } - *cmd_cp = cp; - return(retval); -} - -void -do_nfsroot(char **cmd_cp, char *dp) -{ - char *cp, *rp, *ep; - - /* The boot argument (i.e /sys/mbxroot/zImage) is stored - * at offset 0x0078 in NVRAM. We use this path name to - * construct the root file system path. - */ - cp = *cmd_cp; - - /* build command string. - */ - rp = nfsroot_string; - while (*rp != 0) - *cp++ = *rp++; - - /* Add the server address to the path. - */ - while (*dp != ' ') - *cp++ = *dp++; - *cp++ = ':'; - - rp = (char *)0xfa000078; - ep = strrchr(rp, '/'); - - if (ep != 0) { - while (rp < ep) - *cp++ = *rp++; - } - else { - rp = defroot_string; - while (*rp != 0) - *cp++ = *rp++; - } - - *cmd_cp = cp; -} - -size_t strlen(const char * s) -{ - const char *sc; - - for (sc = s; *sc != '\0'; ++sc) - /* nothing */; - return sc - s; -} - -int strncmp(const char * cs,const char * ct,size_t count) -{ - register signed char __res = 0; - - while (count) { - if ((__res = *cs - *ct++) != 0 || !*cs++) - break; - count--; - } - - return __res; -} - -char * strrchr(const char * s, int c) -{ - const char *p = s + strlen(s); - do { - if (*p == (char)c) - return (char *)p; - } while (--p >= s); - return NULL; -} -#endif - void puthex(unsigned long val) { unsigned char buf[10]; @@ -802,3 +579,243 @@ _bcopy(char *src, char *dst, int len) { while (len--) *dst++ = *src++; } + + +#define FALSE 0 +#define TRUE 1 +#include <stdarg.h> + +int +strlen(char *s) +{ + int len = 0; + while (*s++) len++; + return len; +} + +_printk(char const *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = _vprintk(putc, fmt, ap); + va_end(ap); + return (ret); +} + +#define is_digit(c) ((c >= '0') && (c <= '9')) + +int +_vprintk(putc, fmt0, ap) +int (*putc)(); +const char *fmt0; +va_list ap; +{ + char c, sign, *cp; + int left_prec, right_prec, zero_fill, length, pad, pad_on_right; + char buf[32]; + long val; + while (c = *fmt0++) + { + if (c == '%') + { + c = *fmt0++; + left_prec = right_prec = pad_on_right = 0; + if (c == '-') + { + c = *fmt0++; + pad_on_right++; + } + if (c == '0') + { + zero_fill = TRUE; + c = *fmt0++; + } else + { + zero_fill = FALSE; + } + while (is_digit(c)) + { + left_prec = (left_prec * 10) + (c - '0'); + c = *fmt0++; + } + if (c == '.') + { + c = *fmt0++; + zero_fill++; + while (is_digit(c)) + { + right_prec = (right_prec * 10) + (c - '0'); + c = *fmt0++; + } + } else + { + right_prec = left_prec; + } + sign = '\0'; + switch (c) + { + case 'd': + case 'x': + case 'X': + val = va_arg(ap, long); + switch (c) + { + case 'd': + if (val < 0) + { + sign = '-'; + val = -val; + } + length = _cvt(val, buf, 10, "0123456789"); + break; + case 'x': + length = _cvt(val, buf, 16, "0123456789abcdef"); + break; + case 'X': + length = _cvt(val, buf, 16, "0123456789ABCDEF"); + break; + } + cp = buf; + break; + case 's': + cp = va_arg(ap, char *); + length = strlen(cp); + break; + case 'c': + c = va_arg(ap, long /*char*/); + (*putc)(c); + continue; + default: + (*putc)('?'); + } + pad = left_prec - length; + if (sign != '\0') + { + pad--; + } + if (zero_fill) + { + c = '0'; + if (sign != '\0') + { + (*putc)(sign); + sign = '\0'; + } + } else + { + c = ' '; + } + if (!pad_on_right) + { + while (pad-- > 0) + { + (*putc)(c); + } + } + if (sign != '\0') + { + (*putc)(sign); + } + while (length-- > 0) + { + (*putc)(c = *cp++); + if (c == '\n') + { + (*putc)('\r'); + } + } + if (pad_on_right) + { + while (pad-- > 0) + { + (*putc)(c); + } + } + } else + { + (*putc)(c); + if (c == '\n') + { + (*putc)('\r'); + } + } + } +} + +int _cvt(unsigned long val, char *buf, long radix, char *digits) +{ + char temp[80]; + char *cp = temp; + int length = 0; + if (val == 0) + { /* Special case */ + *cp++ = '0'; + } else + while (val) + { + *cp++ = digits[val % radix]; + val /= radix; + } + while (cp != temp) + { + *buf++ = *--cp; + length++; + } + *buf = '\0'; + return (length); +} + +_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) +{ + int i, c; + if ((unsigned int)s > (unsigned int)p) + { + s = (unsigned int)s - (unsigned int)p; + } + while (s > 0) + { + if (base) + { + _printk("%06X: ", (int)p - (int)base); + } else + { + _printk("%06X: ", p); + } + for (i = 0; i < 16; i++) + { + if (i < s) + { + _printk("%02X", p[i] & 0xFF); + } else + { + _printk(" "); + } + if ((i % 2) == 1) _printk(" "); + if ((i % 8) == 7) _printk(" "); + } + _printk(" |"); + for (i = 0; i < 16; i++) + { + if (i < s) + { + c = p[i] & 0xFF; + if ((c < 0x20) || (c >= 0x7F)) c = '.'; + } else + { + c = ' '; + } + _printk("%c", c); + } + _printk("|\n"); + s -= 16; + p += 16; + } +} + +_dump_buf(unsigned char *p, int s) +{ + _printk("\n"); + _dump_buf_with_offset(p, s, 0); +} diff --git a/arch/ppc/boot/mkprep.c b/arch/ppc/boot/mkprep.c index 7799c9acc..0a596b0ff 100644 --- a/arch/ppc/boot/mkprep.c +++ b/arch/ppc/boot/mkprep.c @@ -14,15 +14,8 @@ * Modified for x86 hosted builds by Matt Porter <porter@neta.com> */ -#ifdef linux -#include <linux/types.h> -/*#include <asm/stat.h>*/ -/*#include <asm/byteorder.h>*/ /* the byte swap funcs don't work here -- Cort */ -#else #include <unistd.h> -#endif #include <sys/stat.h> - #include <stdio.h> #include <errno.h> @@ -168,10 +161,10 @@ void write_prep_partition(int in, int out) /* set entry point and boot image size skipping over elf header */ #ifdef __i386__ *entry = 0x400/*+65536*/; - *length = info.st_size+0x400; + *length = info.st_size-elfhdr_size+0x400; #else *entry = cpu_to_le32(0x400/*+65536*/); - *length = cpu_to_le32(info.st_size+0x400); + *length = cpu_to_le32(info.st_size-elfhdr_size+0x400); #endif /* __i386__ */ /* sets magic number for msdos partition (used by linux) */ diff --git a/arch/ppc/boot/of1275.c b/arch/ppc/boot/of1275.c new file mode 100644 index 000000000..b82fa7a46 --- /dev/null +++ b/arch/ppc/boot/of1275.c @@ -0,0 +1,427 @@ +/* Open Firmware Client Interface */ + + +#include "of1275.h" + + +static int (*of_server)(void *) = (int(*)(void*))-1; + +void +of_init(void *handler) +{ + of_server = (int(*)(void*))handler; +} + + +/* 6.3.2.1 Client interface */ + + +int +of_test(const char *name, int *missing) +{ + int result; + static of_test_service s; + s.service = "test"; + s.n_args = 1; + s.n_returns = 1; + s.name = name; + result = of_server(&s); + *missing = s.missing; + return result; +} + + +/* 6.3.2.2 Device tree */ + + +int +of_peer(int phandle, int *sibling_phandle) +{ + int result; + static of_peer_service s; + s.service = "peer"; + s.n_args = 1; + s.n_returns = 1; + s.phandle = phandle; + result = of_server(&s); + *sibling_phandle = s.sibling_phandle; + return result; +} + +int +of_child(int phandle, int *child_phandle) +{ + int result; + static of_child_service s; + s.service = "child"; + s.n_args = 1; + s.n_returns = 1; + s.phandle = phandle; + result = of_server(&s); + *child_phandle = s.child_phandle; + return result; +} + +int +of_parent(int phandle, int *parent_phandle) +{ + int result; + static of_parent_service s; + s.service = "parent"; + s.n_args = 1; + s.n_returns = 1; + s.phandle = phandle; + result = of_server(&s); + *parent_phandle = s.parent_phandle; + return result; +} + +int +of_instance_to_package(int ihandle, int *phandle) +{ + int result; + static of_instance_to_package_service s; + s.service = "instance-to-package"; + s.n_args = 1; + s.n_returns = 1; + s.ihandle = ihandle; + result = of_server(&s); + *phandle = s.phandle; + return result; +} + +int +of_getproplen(int phandle, const char *name, int *proplen) +{ + int result; + static of_getproplen_service s; + s.service = "getproplen"; + s.n_args = 2; + s.n_returns = 1; + s.phandle = phandle; + s.name = name; + result = of_server(&s); + *proplen = s.proplen; + return result; +} + +int +of_getprop(int phandle, const char *name, void *buf, int buflen, int *size) +{ + int result; + static of_getprop_service s; + s.service = "getprop"; + s.n_args = 4; + s.n_returns = 1; + s.phandle = phandle; + s.name = name; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *size = s.size; + return result; +} + +int +of_nextprop(int phandle, const char *previous, void *buf, int *flag) +{ + int result; + static of_nextprop_service s; + s.service = "nextprop"; + s.n_args = 3; + s.n_returns = 1; + s.phandle = phandle; + s.previous = previous; + s.buf = buf; + result = of_server(&s); + *flag = s.flag; + return result; +} + +int +of_setprop(int phandle, const char *name, void *buf, int len, int *size) +{ + int result; + static of_setprop_service s; + s.service = "setprop"; + s.n_args = 4; + s.n_returns = 1; + s.phandle = phandle; + s.name = name; + s.buf = buf; + s.len = len; + result = of_server(&s); + *size = s.size; + return result; +} + +int +of_canon(const char *device_specifier, void *buf, int buflen, int *length) +{ + int result; + static of_canon_service s; + s.service = "canon"; + s.n_args = 3; + s.n_returns = 1; + s.device_specifier = device_specifier; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *length = s.length; + return result; +} + +int +of_finddevice(const char *device_specifier, int *phandle) +{ + int result; + static of_finddevice_service s; + s.service = "finddevice"; + s.n_args = 1; + s.n_returns = 1; + s.device_specifier = device_specifier; + result = of_server(&s); + *phandle = s.phandle; + return result; +} + +int +of_instance_to_path(int ihandle, void *buf, int buflen, int *length) +{ + int result; + static of_instance_to_path_service s; + s.service = "instance-to-path"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *length = s.length; + return result; +} + +int +of_package_to_path(int phandle, void *buf, int buflen, int *length) +{ + int result; + static of_package_to_path_service s; + s.service = "package-to-path"; + s.n_args = 3; + s.n_returns = 1; + s.phandle = phandle; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *length = s.length; + return result; +} + +/* int of_call_method(const char *method, int ihandle, ...); */ + + +/* 6.3.2.3 Device I/O */ + + +int +of_open(const char *device_specifier, int *ihandle) +{ + int result; + static of_open_service s; + s.service = "open"; + s.n_args = 1; + s.n_returns = 1; + s.device_specifier = device_specifier; + result = of_server(&s); + *ihandle = s.ihandle; + return result; +} + +int +of_close(int ihandle) +{ + int result; + static of_close_service s; + s.service = "close"; + s.n_args = 1; + s.n_returns = 0; + s.ihandle = ihandle; + result = of_server(&s); + return result; +} + +int +of_read(int ihandle, void *addr, int len, int *actual) +{ + int result; + static of_read_service s; + s.service = "read"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.addr = addr; + s.len = len; + result = of_server(&s); + *actual = s.actual; + return result; +} + +int +of_write(int ihandle, void *addr, int len, int *actual) +{ + int result; + static of_write_service s; + s.service = "write"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.addr = addr; + s.len = len; + result = of_server(&s); + *actual = s.actual; + return result; +} + +int +of_seek(int ihandle, int pos_hi, int pos_lo, int *status) +{ + int result; + static of_seek_service s; + s.service = "seek"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.pos_hi = pos_hi; + s.pos_lo = pos_lo; + result = of_server(&s); + *status = s.status; + return result; +} + + +/* 6.3.2.4 Memory */ + + +int +of_claim(void *virt, int size, int align, void **baseaddr) +{ + int result; + static of_claim_service s; + s.service = "claim"; + s.n_args = 3; + s.n_returns = 1; + s.virt = virt; + s.size = size; + s.align = align; + result = of_server(&s); + *baseaddr = s.baseaddr; + return result; +} + +int +of_release(void *virt, int size) +{ + int result; + static of_release_service s; + s.service = "release"; + s.n_args = 2; + s.n_returns = 0; + s.virt = virt; + s.size = size; + result = of_server(&s); + return result; +} + + +/* 6.3.2.5 Control transfer */ + + +int +of_boot(const char *bootspec) +{ + int result; + static of_boot_service s; + s.service = "boot"; + s.n_args = 1; + s.n_returns = 0; + s.bootspec = bootspec; + result = of_server(&s); + return result; +} + +int +of_enter(void) +{ + int result; + static of_enter_service s; + s.service = "enter"; + s.n_args = 0; + s.n_returns = 0; + result = of_server(&s); + return result; +} + +int +of_exit(void) +{ + int result; + static of_exit_service s; + s.service = "exit"; + s.n_args = 0; + s.n_returns = 0; + result = of_server(&s); + return result; +} + +/* int of_chain(void *virt, int size, void *entry, void *args, int len); */ + + +/* 6.3.2.6 User interface */ + + +/* int of_interpret(const char *arg, ...); */ + +int +of_set_callback(void *newfunc, void **oldfunc) +{ + int result; + static of_set_callback_service s; + s.service = "set-callback"; + s.n_args = 1; + s.n_returns = 1; + s.newfunc = newfunc; + result = of_server(&s); + *oldfunc = s.oldfunc; + return result; +} + +int +of_set_symbol_lookup(void *sym_to_value, void *value_to_sym) +{ + int result; + static of_set_symbol_lookup_service s; + s.service = "set-symbol-lookup"; + s.n_args = 2; + s.n_returns = 0; + s.sym_to_value = sym_to_value; + s.value_to_sym = s.value_to_sym; + result = of_server(&s); + return result; +} + + +/* 6.3.2.7 Time */ + + +int +of_milliseconds(int *ms) +{ + int result; + static of_milliseconds_service s; + s.service = "milliseconds"; + s.n_args = 0; + s.n_returns = 1; + result = of_server(&s); + *ms = s.ms; + return result; +} diff --git a/arch/ppc/boot/of1275.h b/arch/ppc/boot/of1275.h new file mode 100644 index 000000000..bc050d32b --- /dev/null +++ b/arch/ppc/boot/of1275.h @@ -0,0 +1,421 @@ +/* 6.3.2.1 Client interface */ + + +typedef struct _of_test_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *name; + /*out*/ + int missing; +} of_test_service; + +int of_test(const char *name, int *missing); + + +/* 6.3.2.2 Device tree */ + + +typedef struct _of_peer_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + /*out*/ + int sibling_phandle; +} of_peer_service; + +int of_peer(int phandle, int *sibling_phandle); + + +typedef struct _of_child_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + /*out*/ + int child_phandle; +} of_child_service; + +int of_child(int phandle, int *child_phandle); + + +typedef struct _of_parent_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + /*out*/ + int parent_phandle; +} of_parent_service; + +int of_child(int phandle, int *parent_phandle); + + +typedef struct _of_instance_to_package_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + /*out*/ + int phandle; +} of_instance_to_package_service; + +int of_instance_to_package(int ihandle, int *phandle); + + +typedef struct _of_getproplen_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *name; + /*out*/ + int proplen; +} of_getproplen_service; + +int of_getproplen(int phandle, const char *name, int *proplen); + + +typedef struct _of_getprop_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *name; + void *buf; + int buflen; + /*out*/ + int size; +} of_getprop_service; + +int of_getprop(int phandle, const char *name, void *buf, int buflen, + int *size); + + +typedef struct _of_nextprop_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *previous; + void *buf; + /*out*/ + int flag; +} of_nextprop_service; + +int of_nextprop(int phandle, const char *previous, void *buf, int *flag); + + +typedef struct _of_setprop_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *name; + void *buf; + int len; + /*out*/ + int size; +} of_setprop_service; + +int of_setprop(int phandle, const char *name, void *buf, int len, int *size); + + +typedef struct _of_canon_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *device_specifier; + void *buf; + int buflen; + /*out*/ + int length; +} of_canon_service; + +int of_canon(const char *device_specifier, void *buf, int buflen, int *length); + + +typedef struct _of_finddevice_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *device_specifier; + /*out*/ + int phandle; +} of_finddevice_service; + +int of_finddevice(const char *device_specifier, int *phandle); + + +typedef struct _of_instance_to_path_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + void *buf; + int buflen; + /*out*/ + int length; +} of_instance_to_path_service; + +int of_instance_to_path(int ihandle, void *buf, int buflen, int *length); + + +typedef struct _of_package_to_path_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + void *buf; + int buflen; + /*out*/ + int length; +} of_package_to_path_service; + +int of_package_to_path(int phandle, void *buf, int buflen, int *length); + + +typedef struct _of_call_method_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *method; + int ihandle; + /*...*/ + int args[0]; +} of_call_method_service; + +int of_call_method(const char *method, int ihandle, ...); + + +/* 6.3.2.3 Device I/O */ + + +typedef struct _of_open_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *device_specifier; + /*out*/ + int ihandle; +} of_open_service; + +int of_open(const char *device_specifier, + int *ihandle); + + +typedef struct _of_close_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + /*out*/ +} of_close_service; + +int of_close(int ihandle); + + +typedef struct _of_read_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + void *addr; + int len; + /*out*/ + int actual; +} of_read_service; + +int of_read(int ihandle, void *addr, int len, int *actual); + + +typedef struct _of_write_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + void *addr; + int len; + /*out*/ + int actual; +} of_write_service; + +int of_write(int ihandle, void *addr, int len, int *actual); + + +typedef struct _of_seek_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + int pos_hi; + int pos_lo; + /*out*/ + int status; +} of_seek_service; + +int of_seek(int ihandle, int pos_hi, int pos_lo, int *status); + + +/* 6.3.2.4 Memory */ + + +typedef struct _of_claim_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *virt; + int size; + int align; + /*out*/ + void *baseaddr; +} of_claim_service; + +int of_claim(void *virt, int size, int align, void **baseaddr); + + +typedef struct _of_release_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *virt; + int size; + int align; + /*out*/ +} of_release_service; + +int of_release(void *virt, int size); + + +/* 6.3.2.5 Control transfer */ + + +typedef struct _of_boot_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *bootspec; + /*out*/ +} of_boot_service; + +int of_boot(const char *bootspec); + + +typedef struct _of_enter_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + /*out*/ +} of_enter_service; + +int of_enter(void); + + +typedef struct _of_exit_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + /*out*/ +} of_exit_service; + +int of_exit(void); + + +typedef struct _of_chain_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *virt; + int size; + void *entry; + void *args; + int len; + /*out*/ +} of_chain_service; + +int of_chain(void *virt, int size, void *entry, void *args, int len); + + +/* 6.3.2.6 User interface */ + + +typedef struct _of_interpret_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *cmd; + int args[0]; + /*...*/ + /*out*/ + /*...*/ +} of_interpret_service; + +int of_interpret(const char *arg, ...); + + +typedef struct _of_set_callback_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *newfunc; + /*out*/ + void *oldfunc; +} of_set_callback_service; + +int of_set_callback(void *newfunc, void **oldfunc); + + +typedef struct _of_set_symbol_lookup_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *sym_to_value; + void *value_to_sym; + /*out*/ +} of_set_symbol_lookup_service; + +int of_set_symbol_lookup(void *sym_to_value, void *value_to_sym); + + +/* 6.3.2.7 Time */ + + +typedef struct _of_milliseconds_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + /*out*/ + int ms; +} of_milliseconds_service; + +int of_milliseconds(int *ms); diff --git a/arch/ppc/boot/piggyback.c b/arch/ppc/boot/piggyback.c deleted file mode 100644 index ca9fc2957..000000000 --- a/arch/ppc/boot/piggyback.c +++ /dev/null @@ -1,64 +0,0 @@ -#include <stdio.h> - -extern long ce_exec_config[]; - -main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - if (argc != 1) - { - fprintf(stderr, "usage: %s <in-file >out-file\n", argv[0]); - exit(1); - } - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl input_data\n"); - fprintf(stdout, "input_data:\n"); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl input_len\n"); - fprintf(stdout, "input_len:\t.long\t0x%x\n", pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - |