diff -urN linux/arch/ppc/chrpboot/Makefile bk/arch/ppc/chrpboot/Makefile --- linux/arch/ppc/chrpboot/Makefile Tue Jun 27 14:52:22 2000 +++ bk/arch/ppc/chrpboot/Makefile Tue Aug 15 16:16:12 2000 @@ -67,11 +67,13 @@ zImage: $(OBJS) no_initrd.o addnote $(LD) $(LD_ARGS) -o $@ $(OBJS) no_initrd.o $(LIBS) - ./addnote $@ + cp $@ $@.rs6k + ./addnote $@.rs6k zImage.initrd: $(OBJS) initrd.o addnote $(LD) $(LD_ARGS) -o $@ $(OBJS) initrd.o $(LIBS) - ./addnote $@ + cp $@ $@.rs6k + ./addnote $@.rs6k else znetboot: diff -urN linux/arch/ppc/chrpboot/addnote.c bk/arch/ppc/chrpboot/addnote.c --- linux/arch/ppc/chrpboot/addnote.c Tue Jun 27 14:52:22 2000 +++ bk/arch/ppc/chrpboot/addnote.c Tue Aug 22 09:45:16 2000 @@ -22,12 +22,23 @@ #define N_DESCR 6 unsigned int descr[N_DESCR] = { +#if 1 + /* values for IBM RS/6000 machines */ 0xffffffff, /* real-mode = true */ 0x00c00000, /* real-base, i.e. where we expect OF to be */ 0xffffffff, /* real-size */ 0xffffffff, /* virt-base */ 0xffffffff, /* virt-size */ 0x4000, /* load-base */ +#else + /* values for longtrail CHRP */ + 0, /* real-mode = false */ + 0xffffffff, /* real-base */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x00600000, /* load-base */ +#endif }; unsigned char buf[512]; @@ -63,7 +74,7 @@ unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; -main(int ac, char **av) +int main(int ac, char **av) { int fd, n, i; int ph, ps, np; diff -urN linux/arch/ppc/coffboot/chrpmain.c bk/arch/ppc/coffboot/chrpmain.c --- linux/arch/ppc/coffboot/chrpmain.c Thu Feb 10 14:43:47 2000 +++ bk/arch/ppc/coffboot/chrpmain.c Tue Aug 15 16:16:12 2000 @@ -63,9 +63,9 @@ claim(PROG_START, 3 << 20, 0); dst = (void *) PROG_START; if (im[0] == 0x1f && im[1] == 0x8b) { - /* claim 512kB for scratch space */ - avail_ram = (char *) claim(0, 512 << 10, 0x10); - end_avail = avail_ram + (512 << 10); + /* claim 1024kB for scratch space */ + avail_ram = (char *) claim(0, 1024 << 10, 0x10); + end_avail = avail_ram + (1024 << 10); printf("avail_ram = %x\n", avail_ram); printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); gunzip(dst, 3 << 20, im, &len); diff -urN linux/arch/ppc/kernel/chrp_pci.c bk/arch/ppc/kernel/chrp_pci.c --- linux/arch/ppc/kernel/chrp_pci.c Fri Jul 14 14:41:35 2000 +++ bk/arch/ppc/kernel/chrp_pci.c Tue Aug 15 16:16:12 2000 @@ -284,13 +284,38 @@ return 1; } +#ifdef CONFIG_POWER4 +static void +power4_fixup_dev(struct pci_dev *dev) +{ + int i; + unsigned long offset; + + for (i = 0; i < 6; ++i) { + if (dev->resource[i].start == 0) + continue; + offset = pci_address_offset(dev->bus->number, + dev->resource[i].flags); + if (offset) { + dev->resource[i].start += offset; + dev->resource[i].end += offset; + printk("device %x.%x[%d] now [%lx..%lx]\n", + dev->bus->number, dev->devfn, i, + dev->resource[i].start, + dev->resource[i].end); + } + /* zap the 2nd function of the winbond chip */ + if (dev->resource[i].flags & IORESOURCE_IO + && dev->bus->number == 0 && dev->devfn == 0x81) + dev->resource[i].flags &= ~IORESOURCE_IO; + } +} +#endif /* CONFIG_POWER4 */ + void __init chrp_pcibios_fixup(void) { struct pci_dev *dev; -#ifdef CONFIG_POWER4 - int i; -#endif int *brp; struct device_node *np; extern struct pci_ops generic_pci_ops; @@ -316,10 +341,8 @@ /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { np = find_pci_device_OFnode(dev->bus->number, dev->devfn); - if ( (np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) + if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) dev->irq = np->intrs[0].line; - if ( dev->irq ) - dev->irq = openpic_to_irq( dev->irq ); /* these need to be absolute addrs for OF and Matrox FB -- Cort */ if ( dev->vendor == PCI_VENDOR_ID_MATROX ) { @@ -337,25 +360,7 @@ dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); } #ifdef CONFIG_POWER4 - for (i = 0; i < 6; ++i) { - unsigned long offset; - if (dev->resource[i].start == 0) - continue; - offset = pci_address_offset(dev->bus->number, - dev->resource[i].flags); - if (offset) { - dev->resource[i].start += offset; - dev->resource[i].end += offset; - printk("device %x.%x[%d] now [%lx..%lx]\n", - dev->bus->number, dev->devfn, i, - dev->resource[i].start, - dev->resource[i].end); - } - /* zap the 2nd function of the winbond chip */ - if (dev->resource[i].flags & IORESOURCE_IO - && dev->bus->number == 0 && dev->devfn == 0x81) - dev->resource[i].flags &= ~IORESOURCE_IO; - } + power4_fixup_dev(dev); #else if (dev->bus->number > 0 && python_busnr > 0) dev->resource[0].start += dev->bus->number*0x01000000; diff -urN linux/arch/ppc/kernel/chrp_setup.c bk/arch/ppc/kernel/chrp_setup.c --- linux/arch/ppc/kernel/chrp_setup.c Fri Jul 14 14:41:35 2000 +++ bk/arch/ppc/kernel/chrp_setup.c Tue Aug 22 09:45:16 2000 @@ -65,8 +65,10 @@ void chrp_time_init(void); void chrp_setup_pci_ptrs(void); -extern void chrp_progress(char *, unsigned short); void chrp_event_scan(void); +void rtas_display_progress(char *, unsigned short); +void rtas_indicator_progress(char *, unsigned short); +void bootx_text_progress(char *, unsigned short); extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int pckbd_getkeycode(unsigned int scancode); @@ -91,6 +93,8 @@ extern unsigned long Hash_size, Hash_mask; extern int probingmem; extern unsigned long loops_per_sec; +extern int bootx_text_mapped; +static int max_width; unsigned long empty_zero_page[1024]; @@ -252,13 +256,6 @@ #endif ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ printk("Boot arguments: %s\n", cmd_line); - - request_region(0x20,0x20,"pic1"); - request_region(0xa0,0x20,"pic2"); - request_region(0x00,0x20,"dma1"); - request_region(0x40,0x20,"timer"); - request_region(0x80,0x10,"dma page reg"); - request_region(0xc0,0x20,"dma2"); #ifndef CONFIG_PPC64BRIDGE /* PCI bridge config space access area - @@ -446,11 +443,43 @@ void __init chrp_init2(void) { +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) + struct device_node *kbd; +#endif #ifdef CONFIG_NVRAM pmac_nvram_init(); #endif + + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + if (ppc_md.progress) ppc_md.progress(" Have fun! ", 0x7777); + +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) { + ppc_md.kbd_setkeycode = mackbd_setkeycode; + ppc_md.kbd_getkeycode = mackbd_getkeycode; + ppc_md.kbd_translate = mackbd_translate; + ppc_md.kbd_unexpected_up = mackbd_unexpected_up; + ppc_md.kbd_leds = mackbd_leds; + ppc_md.kbd_init_hw = mackbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; + SYSRQ_KEY = 0x69; +#endif /* CONFIG_MAGIC_SYSRQ */ + } +#endif /* CONFIG_VT && CONFIG_ADB_KEYBOARD */ } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) @@ -598,40 +627,40 @@ ppc_md.calibrate_decr = chrp_calibrate_decr; #ifdef CONFIG_VT -#ifdef CONFIG_MAC_KEYBOARD - if (adb_driver == NULL) - { -#endif /* CONFIG_MAC_KEYBOAD */ - ppc_md.kbd_setkeycode = pckbd_setkeycode; - ppc_md.kbd_getkeycode = pckbd_getkeycode; - ppc_md.kbd_translate = pckbd_translate; - ppc_md.kbd_unexpected_up = pckbd_unexpected_up; - ppc_md.kbd_leds = pckbd_leds; - ppc_md.kbd_init_hw = pckbd_init_hw; -#ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; - SYSRQ_KEY = 0x54; -#endif /* CONFIG_MAGIC_SYSRQ */ -#ifdef CONFIG_MAC_KEYBOARD - } - else - { - ppc_md.kbd_setkeycode = mackbd_setkeycode; - ppc_md.kbd_getkeycode = mackbd_getkeycode; - ppc_md.kbd_translate = mackbd_translate; - ppc_md.kbd_unexpected_up = mackbd_unexpected_up; - ppc_md.kbd_leds = mackbd_leds; - ppc_md.kbd_init_hw = mackbd_init_hw; + /* these are adjusted in chrp_init2 if we have an ADB keyboard */ + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; #ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; - SYSRQ_KEY = 0x69; + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; #endif /* CONFIG_MAGIC_SYSRQ */ - } -#endif /* CONFIG_MAC_KEYBOARD */ #endif /* CONFIG_VT */ - if ( rtas_data ) - ppc_md.progress = chrp_progress; - + + if (rtas_data) { + struct device_node *rtas; + unsigned int *p; + + rtas = find_devices("rtas"); + if (rtas != NULL) { + if (get_property(rtas, "display-character", NULL)) { + ppc_md.progress = rtas_display_progress; + p = (unsigned int *) get_property + (rtas, "ibm,display-line-length", NULL); + if (p) + max_width = *p; + } else if (get_property(rtas, "set-indicator", NULL)) + ppc_md.progress = rtas_indicator_progress; + } + } +#ifdef CONFIG_BOOTX_TEXT + if (ppc_md.progress == NULL && bootx_text_mapped) + ppc_md.progress = bootx_text_progress; +#endif + #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.insw = chrp_ide_insw; ppc_ide_md.outsw = chrp_ide_outsw; @@ -653,30 +682,13 @@ } void __chrp -chrp_progress(char *s, unsigned short hex) +rtas_display_progress(char *s, unsigned short hex) { - extern unsigned int rtas_data; - int max_width, width; - struct device_node *root; + int width; char *os = s; - unsigned long *p; - if ( (root = find_path_device("/rtas")) && - (p = (unsigned long *)get_property(root, - "ibm,display-line-length", - NULL)) ) - max_width = *p; - else - max_width = 0x10; - - if ( (_machine != _MACH_chrp) || !rtas_data ) - return; if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) ) - { - /* assume no display-character RTAS method - use hex display */ - call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex); return; - } width = max_width; while ( *os ) @@ -696,3 +708,17 @@ call_rtas( "display-character", 1, 1, NULL, ' ' ); } +void __chrp +rtas_indicator_progress(char *s, unsigned short hex) +{ + call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex); +} + +#ifdef CONFIG_BOOTX_TEXT +void +bootx_text_progress(char *s, unsigned short hex) +{ + prom_print(s); + prom_print("\n"); +} +#endif /* CONFIG_BOOTX_TEXT */ diff -urN linux/arch/ppc/kernel/prom.c bk/arch/ppc/kernel/prom.c --- linux/arch/ppc/kernel/prom.c Fri Jul 14 14:41:36 2000 +++ bk/arch/ppc/kernel/prom.c Tue Aug 29 09:48:33 2000 @@ -140,8 +140,7 @@ static long g_max_loc_X = 0; static long g_max_loc_Y = 0; -unsigned long disp_BATL = 0; -unsigned long disp_BATU = 0; +unsigned long disp_BAT[2] = {0, 0}; #define cmapsz (16*256) @@ -276,8 +275,7 @@ prom_drawstring(msg); #endif return; - } - + } for (p = msg; *p != 0; p = q) { for (q = p; *q != 0 && *q != '\n'; ++q) @@ -362,7 +360,7 @@ /* copy the holding pattern code to someplace safe (0) */ /* the holding pattern is now within the first 0x100 bytes of the kernel image -- paulus */ - memcpy((void *)0, KERNELBASE + offset, 0x100); + memcpy((void *)0, (void *)(KERNELBASE + offset), 0x100); flush_icache_range(0, 0x100); /* look for cpus */ @@ -737,7 +735,7 @@ /* We assume the phys. address size is 3 cells */ if (prom_args.args[nargs] != 0) - prom_print(RELOC(" (translate failed) ")); + prom_print(RELOC(" (translate failed)\n")); else phys = (unsigned long)prom_args.args[nargs+3]; } @@ -752,8 +750,6 @@ if (prom_version >= 3) { prom_print(RELOC("Calling quiesce ...\n")); call_prom(RELOC("quiesce"), 0, 0); - offset = reloc_offset(); - phys = offset + KERNELBASE; } #ifdef CONFIG_BOOTX_TEXT @@ -769,7 +765,9 @@ } #endif - prom_print(RELOC("returning from prom_init\n")); + prom_print(RELOC("returning ")); + prom_print_hex(phys); + prom_print(RELOC(" from prom_init\n")); RELOC(prom_stdout) = 0; return phys; } @@ -836,9 +834,8 @@ } /* Calc BAT values for mapping the display and store them - * in disp_BATH and disp_BATL. Those values are then used - * from head.S to map the display during identify_machine() - * and MMU_Init() + * in disp_BAT. Those values are then used from head.S to map + * the display during identify_machine() and MMU_Init() * * For now, the display is mapped in place (1:1). This should * be changed if the display physical address overlaps @@ -862,13 +859,13 @@ if ((_get_PVR() >> 16) != 1) { /* 603, 604, G3, G4, ... */ addr &= 0xFF000000UL; - RELOC(disp_BATU) = addr | (BL_16M<<2) | 2; - RELOC(disp_BATL) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); + RELOC(disp_BAT[0]) = addr | (BL_16M<<2) | 2; + RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); } else { /* 601 */ addr &= 0xFF800000UL; - RELOC(disp_BATU) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4; - RELOC(disp_BATL) = addr | BL_8M | 0x40; + RELOC(disp_BAT[0]) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4; + RELOC(disp_BAT[1]) = addr | BL_8M | 0x40; } bi->logicalDisplayBase = bi->dispDeviceBase; } @@ -1003,34 +1000,50 @@ unsigned address; boot_infos_t* bi; unsigned long offset = reloc_offset(); - + struct pci_reg_property addrs[8]; + int i, naddrs; + char name[32]; + char *getprop = RELOC("getprop"); + prom_print(RELOC("Initializing fake screen\n")); - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"), - &width, sizeof(width)); - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"), - &height, sizeof(height)); - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"), - &depth, sizeof(depth)); + memset(name, 0, sizeof(name)); + call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name)); + name[sizeof(name)-1] = 0; + call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width)); + call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height)); + call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth)); pitch = width * ((depth + 7) / 8); - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"), + call_prom(getprop, 4, 1, dp, RELOC("linebytes"), &pitch, sizeof(pitch)); - address = 0; - if (pitch == 1) { - address = 0xfa000000; + if (pitch == 1) pitch = 0x1000; /* for strange IBM display */ - } - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"), + address = 0; + call_prom(getprop, 4, 1, dp, RELOC("address"), &address, sizeof(address)); if (address == 0) { - prom_print(RELOC("Failed to get address\n")); - return; + /* look for an assigned address with a size of >= 1MB */ + naddrs = (int) call_prom(getprop, 4, 1, dp, + RELOC("assigned-addresses"), + addrs, sizeof(addrs)); + naddrs /= sizeof(struct pci_reg_property); + for (i = 0; i < naddrs; ++i) { + if (addrs[i].size_lo >= (1 << 20)) { + address = addrs[i].addr.a_lo; + /* kludge for control */ + if (strcmp(name, RELOC("control")) == 0) + address += 0x800000; + break; + } + } + if (address == 0) { + prom_print(RELOC("Failed to get address\n")); + return; + } } -#if 0 /* kludge for valkyrie */ - if (strcmp(dp->name, "valkyrie") == 0) - address += 0x1000; -#endif + if (strcmp(name, RELOC("valkyrie")) == 0) + address += 0x1000; RELOC(disp_bi) = &fake_bi; bi = PTRRELOC((&fake_bi)); @@ -1334,11 +1347,19 @@ */ if (get_property(node, "interrupt-controller", &l)) { int i,j; + int cvt_irq; + + /* XXX on chrp, offset interrupt numbers for the + 8259 by 0, those for the openpic by 16 */ + cvt_irq = _machine == _MACH_chrp + && get_property(node, "interrupt-parent", NULL) == 0; np->intrs = (struct interrupt_info *) mem_start; np->n_intrs = ipsize / isize; mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *interrupts++; + if (cvt_irq) + np->intrs[i].line = openpic_to_irq(np->intrs[i].line); np->intrs[i].sense = 0; if (isize > 1) np->intrs[i].sense = *interrupts++; diff -urN linux/arch/ppc/kernel/setup.c bk/arch/ppc/kernel/setup.c --- linux/arch/ppc/kernel/setup.c Fri Jul 14 14:41:36 2000 +++ bk/arch/ppc/kernel/setup.c Tue Aug 15 16:16:13 2000 @@ -683,6 +683,9 @@ extern char *klimit; extern void do_init_bootmem(void); + /* so udelay does something sensible, assume <= 1000 bogomips */ + loops_per_sec = 500000000; + #ifdef CONFIG_ALL_PPC feature_init(); #endif