diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
commit | 33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch) | |
tree | 2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /arch/ppc | |
parent | 216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff) |
Merge with Linux 2.3.32.
Diffstat (limited to 'arch/ppc')
83 files changed, 4575 insertions, 1035 deletions
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index acdc7c11d..c975513f0 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c @@ -21,7 +21,6 @@ * applications that require more DP ram, we can expand the boundaries * but then we have to be careful of any downloaded microcode. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/ppc/8xx_io/commproc.h b/arch/ppc/8xx_io/commproc.h index 373db5fef..7e7e9896d 100644 --- a/arch/ppc/8xx_io/commproc.h +++ b/arch/ppc/8xx_io/commproc.h @@ -18,6 +18,7 @@ #ifndef __CPM_8XX__ #define __CPM_8XX__ +#include <linux/config.h> #include <asm/8xx_immap.h> /* CPM Command register. diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 879b326a7..26beffc40 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -22,6 +22,7 @@ * small packets. * */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index aa45d4d27..f0036981e 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -16,6 +16,7 @@ * small packets. * */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 82bdb59ed..8a6db08e2 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -21,11 +21,15 @@ endif ASFLAGS = LINKFLAGS = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic CFLAGSINC = -D__KERNEL__ -I$(TOPDIR)/include -D__powerpc__ -CFLAGS := $(CFLAGS) -I$(HPATH) -D__powerpc__ -fsigned-char -msoft-float \ - -pipe -fno-builtin -ffixed-r2 -Wno-uninitialized -mmultiple \ - -mstring +CFLAGS := $(CFLAGS) -I$(HPATH) -D__powerpc__ -fsigned-char \ + -msoft-float -pipe -fno-builtin -ffixed-r2 -Wno-uninitialized \ + -mmultiple -mstring CPP = $(CC) -E $(CFLAGS) +ifdef CONFIG_4xx +CFLAGS := $(CFLAGS) -mcpu=403 +endif + ifdef CONFIG_8xx CFLAGS := $(CFLAGS) -mcpu=860 -I../8xx_io endif @@ -34,10 +38,14 @@ ifdef CONFIG_PPC64 CFLAGS := $(CFLAGS) -Wa,-mppc64bridge #-mpowerpc64 endif -ifndef CONFIG_8xx -HEAD := arch/ppc/kernel/head.o +ifdef CONFIG_4xx + HEAD := arch/ppc/kernel/head_4xx.o else -HEAD := arch/ppc/kernel/head_8xx.o + ifdef CONFIG_8xx + HEAD := arch/ppc/kernel/head_8xx.o + else + HEAD := arch/ppc/kernel/head.o + endif endif ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm arch/ppc/lib @@ -60,6 +68,7 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot MAKECOFFBOOT = $(MAKE) -C arch/$(ARCH)/coffboot MAKECHRPBOOT = $(MAKE) -C arch/$(ARCH)/chrpboot MAKEMBXBOOT = $(MAKE) -C arch/$(ARCH)/mbxboot +MAKETREEBOOT = $(MAKE) -C arch/$(ARCH)/treeboot ifdef CONFIG_8xx SUBDIRS += arch/ppc/8xx_io @@ -77,11 +86,18 @@ checks: BOOT_TARGETS = zImage znetboot.initrd zImage.initrd +ifdef CONFIG_4xx +$(BOOT_TARGETS): $(CHECKS) vmlinux + @$(MAKETREEBOOT) $@ +endif + ifdef CONFIG_8xx $(BOOT_TARGETS): $(CHECKS) vmlinux @$(MAKECOFFBOOT) $@ @$(MAKEMBXBOOT) $@ -else +endif + +ifdef CONFIG_6xx $(BOOT_TARGETS): $(CHECKS) vmlinux @$(MAKECOFFBOOT) $@ @$(MAKEBOOT) $@ @@ -108,33 +124,36 @@ endif @$(MAKECHRPBOOT) $@ endif -gemini_config: +.PHONY: clean_config +clean_config: rm -f .config arch/ppc/defconfig - ln -s gemini_defconfig arch/ppc/defconfig -pmac_config: - rm -f .config arch/ppc/defconfig - ln -s pmac_defconfig arch/ppc/defconfig +gemini_config: clean_config + ln -s configs/gemini_defconfig arch/ppc/defconfig -prep_config: - rm -f .config arch/ppc/defconfig - ln -s prep_defconfig arch/ppc/defconfig +pmac_config: clean_config + ln -s configs/pmac_defconfig arch/ppc/defconfig -chrp_config: - rm -f .config arch/ppc/defconfig - ln -s chrp_defconfig arch/ppc/defconfig +prep_config: clean_config + ln -s configs/prep_defconfig arch/ppc/defconfig -common_config: - rm -f .config arch/ppc/defconfig - ln -s common_defconfig arch/ppc/defconfig +chrp_config: clean_config + ln -s configs/chrp_defconfig arch/ppc/defconfig -mbx_config: - rm -f .config arch/ppc/defconfig - ln -s mbx_defconfig arch/ppc/defconfig +common_config: clean_config + ln -s configs/common_defconfig arch/ppc/defconfig -apus_config: - rm -f .config arch/ppc/defconfig - ln -s apus_defconfig arch/ppc/defconfig +mbx_config: clean_config + ln -s configs/mbx_defconfig arch/ppc/defconfig + +apus_config: clean_config + ln -s configs/apus_defconfig arch/ppc/defconfig + +oak_config: clean_config + ln -s configs/oak_defconfig arch/ppc/defconfig + +walnut_config: clean_config + ln -s configs/walnut_defconfig arch/ppc/defconfig tags: etags */*.c include/{asm,linux}/*.h arch/ppc/kernel/*.{c,h} @@ -145,6 +164,7 @@ archclean: @$(MAKEBOOT) clean @$(MAKECHRPBOOT) clean @$(MAKEMBXBOOT) clean + @$(MAKETREEBOOT) clean archmrproper: diff --git a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c index 80c63f7ab..938476267 100644 --- a/arch/ppc/amiga/ints.c +++ b/arch/ppc/amiga/ints.c @@ -5,7 +5,6 @@ * Needed to drive the m68k emulating IRQ hardware on the PowerUp boards. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/sched.h> #include <linux/kernel_stat.h> diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 41a8a915f..96b6ba306 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -134,7 +134,7 @@ znetboot.initrd : zImage.initrd cp zImage.initrd $(TFTPIMAGE) clean: - rm -f vmlinux* zvmlinux* mkprep zImage* + rm -f vmlinux* zvmlinux* mkprep zImage* sImage* fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend diff --git a/arch/ppc/boot/head.S b/arch/ppc/boot/head.S index 79377a2ac..cc9339c8e 100644 --- a/arch/ppc/boot/head.S +++ b/arch/ppc/boot/head.S @@ -112,14 +112,6 @@ start_ldr: cmpi 0,r2,0 bne 00b - /* r4,r5 have initrd_start, size */ - lis r2,initrd_start@h - ori r2,r2,initrd_start@l - lwz r4,0(r2) - lis r2,initrd_end@h - ori r2,r2,initrd_end@l - lwz r5,0(r2) - /* tell kernel we're prep */ /* * get start address of kernel code which is stored as a coff diff --git a/arch/ppc/boot/misc.c b/arch/ppc/boot/misc.c index 6724a8130..d25f732b8 100644 --- a/arch/ppc/boot/misc.c +++ b/arch/ppc/boot/misc.c @@ -16,6 +16,7 @@ #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" @@ -518,17 +519,39 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, *cp = 0; puts("\n"); - /* mappings on early boot can only handle 16M */ - if ( (int)(cmd_line[0]) > (16<<20)) - puts("cmd_line located > 16M\n"); - if ( (int)hold_residual > (16<<20)) - puts("hold_residual located > 16M\n"); - if ( initrd_start > (16<<20)) - puts("initrd_start located > 16M\n"); - puts("Uncompressing Linux..."); gunzip(0, 0x400000, zimage_start, &zimage_size); puts("done.\n"); + + { + struct bi_record *rec; + + rec = (struct bi_record *)PAGE_ALIGN(zimage_size); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + memcpy( (void *)rec->data, "prepboot", 9); + rec->size = sizeof(struct bi_record) + 8 + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_prep; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_CMD_LINE; + memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); + rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; + rec = (struct bi_record *)((ulong)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } puts("Now booting the kernel\n"); return (unsigned long)hold_residual; } diff --git a/arch/ppc/chrpboot/main.c b/arch/ppc/chrpboot/main.c index 80db69a7b..bf506552a 100644 --- a/arch/ppc/chrpboot/main.c +++ b/arch/ppc/chrpboot/main.c @@ -8,6 +8,10 @@ */ #include "../coffboot/nonstdio.h" #include "../coffboot/zlib.h" +#include <asm/bootinfo.h> +#include <asm/processor.h> +#define __KERNEL__ +#include <asm/page.h> extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); @@ -71,6 +75,30 @@ chrpboot(int a1, int a2, void *prom) sa = (unsigned long)PROG_START; printf("start address = 0x%x\n\r", sa); + { + struct bi_record *rec; + + rec = (struct bi_record *)PAGE_ALIGN((unsigned long)dst+len); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, "chrpboot"); + rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_chrp; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } (*(void (*)())sa)(0, 0, prom, a1, a2); printf("returned?\n\r"); diff --git a/arch/ppc/chrpboot/string.S b/arch/ppc/chrpboot/string.S deleted file mode 100644 index ba83591b7..000000000 --- a/arch/ppc/chrpboot/string.S +++ /dev/null @@ -1,206 +0,0 @@ -/* - * String handling functions for PowerPC. - * - * Copyright (C) 1996 Paul Mackerras. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#define r0 0 -#define r3 3 -#define r4 4 -#define r5 5 -#define r6 6 -#define r7 7 -#define r8 8 - - .globl strcpy -strcpy: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r5) - bne 1b - blr - - .globl strncpy -strncpy: - cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r6,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r6) - bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ - blr - - .globl strcat -strcat: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r5) - cmpwi 0,r0,0 - bne 1b - addi r5,r5,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r5) - bne 1b - blr - - .globl strcmp -strcmp: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r3,1(r5) - cmpwi 1,r3,0 - lbzu r0,1(r4) - subf. r3,r0,r3 - beqlr 1 - beq 1b - blr - - .globl strlen -strlen: - addi r4,r3,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - bne 1b - subf r3,r3,r4 - blr - - .globl memset -memset: - rlwimi r4,r4,8,16,23 - rlwimi r4,r4,16,0,15 - addi r6,r3,-4 - cmplwi 0,r5,4 - blt 7f - stwu r4,4(r6) - beqlr - andi. r0,r6,3 - add r5,r0,r5 - subf r6,r0,r6 - rlwinm r0,r5,32-2,2,31 - mtctr r0 - bdz 6f -1: stwu r4,4(r6) - bdnz 1b -6: andi. r5,r5,3 -7: cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r6,r6,3 -8: stbu r4,1(r6) - bdnz 8b - blr - - .globl bcopy -bcopy: - mr r6,r3 - mr r3,r4 - mr r4,r6 - b memcpy - - .globl memmove -memmove: - cmplw 0,r3,r4 - bgt backwards_memcpy - /* fall through */ - - .globl memcpy -memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ - addi r6,r3,-4 - addi r4,r4,-4 - beq 2f /* if less than 8 bytes to do */ - andi. r0,r6,3 /* get dest word aligned */ - mtctr r7 - bne 5f -1: lwz r7,4(r4) - lwzu r8,8(r4) - stw r7,4(r6) - stwu r8,8(r6) - bdnz 1b - andi. r5,r5,7 -2: cmplwi 0,r5,4 - blt 3f - lwzu r0,4(r4) - addi r5,r5,-4 - stwu r0,4(r6) -3: cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r4,r4,3 - addi r6,r6,3 -4: lbzu r0,1(r4) - stbu r0,1(r6) - bdnz 4b - blr -5: subfic r0,r0,4 - mtctr r0 -6: lbz r7,4(r4) - addi r4,r4,1 - stb r7,4(r6) - addi r6,r6,1 - bdnz 6b - subf r5,r0,r5 - rlwinm. r7,r5,32-3,3,31 - beq 2b - mtctr r7 - b 1b - - .globl backwards_memcpy -backwards_memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ - add r6,r3,r5 - add r4,r4,r5 - beq 2f - andi. r0,r6,3 - mtctr r7 - bne 5f -1: lwz r7,-4(r4) - lwzu r8,-8(r4) - stw r7,-4(r6) - stwu r8,-8(r6) - bdnz 1b - andi. r5,r5,7 -2: cmplwi 0,r5,4 - blt 3f - lwzu r0,-4(r4) - subi r5,r5,4 - stwu r0,-4(r6) -3: cmpwi 0,r5,0 - beqlr - mtctr r5 -4: lbzu r0,-1(r4) - stbu r0,-1(r6) - bdnz 4b - blr -5: mtctr r0 -6: lbzu r7,-1(r4) - stbu r7,-1(r6) - bdnz 6b - subf r5,r0,r5 - rlwinm. r7,r5,32-3,3,31 - beq 2b - mtctr r7 - b 1b - - .globl memcmp -memcmp: - cmpwi 0,r5,0 - blelr - mtctr r5 - addi r6,r3,-1 - addi r4,r4,-1 -1: lbzu r3,1(r6) - lbzu r0,1(r4) - subf. r3,r0,r3 - bdnzt 2,1b - blr diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile index 81e21f3e3..a7ed94074 100644 --- a/arch/ppc/coffboot/Makefile +++ b/arch/ppc/coffboot/Makefile @@ -9,25 +9,26 @@ CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld CFLAGS = -O -fno-builtin -I$(TOPDIR)/include OBJCOPY = $(CROSS_COMPILE)objcopy -OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment \ - --add-section=image=vmlinux.gz -LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic +OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment +COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic +CHRP_LD_ARGS = -Ttext 0x00400000 GZ = gzip -9 -OBJS = crt0.o start.o main.o misc.o string.o zlib.o +COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o +CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o LIBS = $(TOPDIR)/lib/lib.a -ifeq ($(CONFIG_ALL_PPC),y) -# yes, we want to build pmac stuff -CONFIG_PMAC = y -endif - ifeq ($(CONFIG_PPC64),y) MSIZE=.64 else MSIZE= endif +ifeq ($(CONFIG_ALL_PPC),y) +# yes, we want to build pmac stuff +CONFIG_PMAC = y +endif + ifeq ($(CONFIG_SMP),y) TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE) else @@ -38,34 +39,58 @@ ifeq ($(CONFIG_PMAC),y) hack-coff: hack-coff.c $(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c +znetboot: vmlinux.coff zImage + cp vmlinux.coff $(TFTPIMAGE) + +znetboot.initrd: vmlinux.coff.initrd + cp vmlinux.coff.initrd $(TFTPIMAGE) + floppy: zImage # mount -t hfs /dev/fd0 /mnt # cp vmlinux.coff /mnt # umount /mnt -znetboot: vmlinux.coff - cp vmlinux.coff $(TFTPIMAGE) +coffboot: $(COFFOBJS) no_initrd.o ld.script + $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) no_initrd.o $(LIBS) -znetboot.initrd: vmlinux.coff.initrd - cp vmlinux.coff.initrd $(TFTPIMAGE) +coffboot.initrd: $(COFFOBJS) initrd.o ld.script + $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS) -coffboot: $(OBJS) ld.script - $(LD) -o coffboot $(LD_ARGS) $(OBJS) $(LIBS) +piggyback: piggyback.c + $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c -zImage: vmlinux.coff +mknote: mknote.c + $(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c -zImage.initrd: vmlinux.coff.initrd +image.o: piggyback vmlinux.gz + ./piggyback image < vmlinux.gz | $(AS) -o image.o -vmlinux.coff: coffboot hack-coff vmlinux.gz +initrd.o: ramdisk.image.gz piggyback + ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o + +vmlinux.coff: coffboot hack-coff $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@ ./hack-coff $@ ln -sf vmlinux.coff zImage -vmlinux.coff.initrd: coffboot hack-coff vmlinux.gz ramdisk.image.gz - $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz \ - coffboot $@ +vmlinux.coff.initrd: coffboot.initrd hack-coff + $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@ ./hack-coff $@ +vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote + $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS) + ./mknote > note + $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment + +vmlinux.elf.initrd: $(CHRPOBJS) initrd.o mknote + $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) initrd.o $(LIBS) + ./mknote > note + $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment + +zImage: vmlinux.coff vmlinux.elf + +zImage.initrd: vmlinux.coff.initrd vmlinux.elf.initrd + else znetboot: vmlinux.gz diff --git a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c new file mode 100644 index 000000000..fc5648944 --- /dev/null +++ b/arch/ppc/coffboot/chrpmain.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include "nonstdio.h" +#include "zlib.h" +#include <asm/bootinfo.h> +#include <asm/processor.h> +#define __KERNEL__ +#include <asm/page.h> + +extern void *finddevice(const char *); +extern int getprop(void *, const char *, void *, int); +void make_bi_recs(unsigned long); +void gunzip(void *, int, unsigned char *, int *); +void stop_imac_ethernet(void); +void stop_imac_usb(void); + +#define get_16be(x) (*(unsigned short *)(x)) +#define get_32be(x) (*(unsigned *)(x)) + +#define RAM_START 0x00000000 +#define RAM_END (8<<20) + +#define PROG_START 0x00010000 + +char *avail_ram; +char *end_avail; + +extern char _end[]; +extern char image_data[]; +extern int image_len; +extern char initrd_data[]; +extern int initrd_len; + + +boot(int a1, int a2, void *prom) +{ + int ns, oh, i; + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned initrd_start, initrd_size; + extern char _start; + + printf("chrpboot starting: loaded at 0x%x\n", &_start); + if (initrd_len) { + initrd_size = initrd_len; + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; + claim(initrd_start, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start, + initrd_data,initrd_size); + memcpy((char *)initrd_start, initrd_data, initrd_size); + } + im = image_data; + len = image_len; + /* claim 3MB starting at PROG_START */ + 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); + 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); + printf("done %u bytes\n", len); + } else { + memmove(dst, im, len); + } + + flush_cache(dst, len); + stop_imac_ethernet(); + stop_imac_usb(); + make_bi_recs((unsigned long) dst + len); + + sa = (unsigned long)PROG_START; + printf("start address = 0x%x\n", sa); + + (*(void (*)())sa)(0, 0, prom, a1, a2); + + printf("returned?\n"); + + pause(); +} + +void make_bi_recs(unsigned long addr) +{ + struct bi_record *rec; + + rec = (struct bi_record *)PAGE_ALIGN(addr); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, "coffboot"); + rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_Pmac; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); +} + +#define eieio() asm volatile("eieio"); + +void stop_imac_ethernet(void) +{ + void *macio, *enet; + unsigned int macio_addr[5], enet_reg[6]; + int len; + volatile unsigned int *dbdma; + + macio = finddevice("/pci/mac-io"); + enet = finddevice("/pci/mac-io/ethernet"); + if (macio == NULL || enet == NULL) + return; + len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr)); + if (len != sizeof(macio_addr)) + return; + len = getprop(enet, "reg", enet_reg, sizeof(enet_reg)); + if (len != sizeof(enet_reg)) + return; + printf("macio base %x, dma at %x & %x\n", + macio_addr[2], enet_reg[2], enet_reg[4]); + + /* hope this is mapped... */ + dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]); + *dbdma = 0x80; /* clear the RUN bit */ + eieio(); + dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]); + *dbdma = 0x80; /* clear the RUN bit */ + eieio(); +} + +void stop_imac_usb(void) +{ + void *usb; + unsigned int usb_addr[5]; + int len; + volatile unsigned int *usb_ctrl; + + usb = finddevice("/pci/usb"); + if (usb == NULL) + return; + len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr)); + if (len != sizeof(usb_addr)) + return; + printf("usb base %x\n", usb_addr[2]); + + usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8); + *usb_ctrl = 0x01000000; /* cpu_to_le32(1) */ + eieio(); +} + +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) { + printf("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 8 + +void 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) { + printf("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) { + printf("gunzip: ran out of data in header\n"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n", r); + 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) { + printf("inflate returned %d msg: %s\n", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} diff --git a/arch/ppc/coffboot/coffcrt0.S b/arch/ppc/coffboot/coffcrt0.S new file mode 100644 index 000000000..43ae4e0ec --- /dev/null +++ b/arch/ppc/coffboot/coffcrt0.S @@ -0,0 +1,24 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + .text + .globl _start +_start: + .long __start,0,0 + + .globl __start +__start: + lis 9,_start@h + lis 8,_etext@ha + addi 8,8,_etext@l +1: dcbf 0,9 + icbi 0,9 + addi 9,9,0x20 + cmplwi 0,9,8 + blt 1b + b start diff --git a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c new file mode 100644 index 000000000..2bb4ea31d --- /dev/null +++ b/arch/ppc/coffboot/coffmain.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include "nonstdio.h" +#include "zlib.h" +#include <asm/bootinfo.h> +#include <asm/processor.h> +#define __KERNEL__ +#include <asm/page.h> + +extern void *finddevice(const char *); +extern int getprop(void *, const char *, void *, int); +extern char *claim(unsigned, unsigned, unsigned); +void make_bi_recs(unsigned long); +void gunzip(void *, int, unsigned char *, int *); + +#define get_16be(x) (*(unsigned short *)(x)) +#define get_32be(x) (*(unsigned *)(x)) + +#define RAM_START 0xc0000000 +#define PROG_START RAM_START +#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ + +char *avail_ram; +char *end_avail; + +extern char _start[], _end[]; +extern char image_data[]; +extern int image_len; +extern char initrd_data[]; +extern int initrd_len; + + +boot(int a1, int a2, void *prom) +{ + int ns, oh, i; + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned initrd_start, initrd_size; + + printf("coffboot starting: loaded at 0x%x\n", _start); + setup_bats(RAM_START); + if (initrd_len) { + initrd_size = initrd_len; + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; + claim(initrd_start - RAM_START, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", + initrd_start, initrd_data, initrd_size); + memcpy((char *)initrd_start, initrd_data, initrd_size); + } + im = image_data; + len = image_len; + /* claim 3MB starting at 0 */ + claim(0, 3 << 20, 0); + dst = (void *) RAM_START; + if (im[0] == 0x1f && im[1] == 0x8b) { + /* claim 512kB for scratch space */ + avail_ram = claim(0, 512 << 10, 0x10) + RAM_START; + end_avail = avail_ram + (512 << 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); + printf("done %u bytes\n", len); + } else { + memmove(dst, im, len); + } + + flush_cache(dst, len); + make_bi_recs((unsigned long)dst + len); + + sa = (unsigned long)PROG_START; + printf("start address = 0x%x\n", sa); + +#if 0 + pause(); +#endif + (*(void (*)())sa)(a1, a2, prom); + + printf("returned?\n"); + + pause(); +} + +void make_bi_recs(unsigned long addr) +{ + struct bi_record *rec; + + rec = (struct bi_record *)PAGE_ALIGN(addr); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, "coffboot"); + rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_Pmac; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); +} + +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) { + printf("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 8 + +void 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) { + printf("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) { + printf("gunzip: ran out of data in header\n"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n", r); + 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) { + printf("inflate returned %d msg: %s\n", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} diff --git a/arch/ppc/coffboot/crt0.S b/arch/ppc/coffboot/crt0.S index 43ae4e0ec..c43340594 100644 --- a/arch/ppc/coffboot/crt0.S +++ b/arch/ppc/coffboot/crt0.S @@ -9,10 +9,6 @@ .text .globl _start _start: - .long __start,0,0 - - .globl __start -__start: lis 9,_start@h lis 8,_etext@ha addi 8,8,_etext@l diff --git a/arch/ppc/coffboot/main.c b/arch/ppc/coffboot/main.c index b3a310e17..56d29b84f 100644 --- a/arch/ppc/coffboot/main.c +++ b/arch/ppc/coffboot/main.c @@ -9,6 +9,10 @@ #include "nonstdio.h" #include "rs6000.h" #include "zlib.h" +#include <asm/bootinfo.h> +#include <asm/processor.h> +#define __KERNEL__ +#include <asm/page.h> extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); @@ -106,6 +110,31 @@ coffboot(int a1, int a2, void *prom) #if 0 pause(); #endif + { + struct bi_record *rec; + + rec = (struct bi_record *)PAGE_ALIGN((unsigned long)dst+len); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, "coffboot"); + rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_Pmac; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); @@ -165,7 +194,6 @@ void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) printf("gunzip: ran out of data in header\n"); exit(); } -printf("done 1\n"); s.zalloc = zalloc; s.zfree = zfree; r = inflateInit2(&s, -MAX_WBITS); @@ -177,14 +205,11 @@ printf("done 1\n"); s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; -printf("doing inflate\n"); r = inflate(&s, Z_FINISH); -printf("done inflate\n"); if (r != Z_OK && r != Z_STREAM_END) { printf("inflate returned %d\n", r); exit(); } *lenp = s.next_out - (unsigned char *) dst; -printf("doing end\n"); inflateEnd(&s); } diff --git a/arch/ppc/coffboot/misc.S b/arch/ppc/coffboot/misc.S index df542a522..7defc69e8 100644 --- a/arch/ppc/coffboot/misc.S +++ b/arch/ppc/coffboot/misc.S @@ -14,23 +14,26 @@ */ .globl setup_bats setup_bats: - mr 4,3 - mfpvr 3 - rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */ - cmpi 0,3,1 + mfpvr 5 + rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ + cmpi 0,5,1 + li 0,0 bne 4f - ori 4,4,4 /* set up BAT registers for 601 */ - li 5,0x7f - mtibatu 3,4 - mtibatl 3,5 - isync - blr -4: ori 4,4,0xfe /* set up BAT registers for 604 */ - li 5,2 - mtdbatl 3,5 - mtdbatu 3,4 - mtibatl 3,5 - mtibatu 3,4 + mtibatl 3,0 /* invalidate BAT first */ + ori 3,3,4 /* set up BAT registers for 601 */ + li 4,0x7f + mtibatu 3,3 + mtibatl 3,4 + b 5f +4: mtdbatu 3,0 /* invalidate BATs first */ + mtibatu 3,0 + ori 3,3,0xff /* set up BAT registers for 604 */ + li 4,2 + mtdbatl 3,4 + mtdbatu 3,3 + mtibatl 3,4 + mtibatu 3,3 +5: sync isync blr diff --git a/arch/ppc/coffboot/mknote.c b/arch/ppc/coffboot/mknote.c new file mode 100644 index 000000000..120cc1d89 --- /dev/null +++ b/arch/ppc/coffboot/mknote.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) Cort Dougan 1999. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Generate a note section as per the CHRP specification. + * + */ + +#include <stdio.h> + +#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); + +int main(void) +{ +/* header */ + /* namesz */ + PL(strlen("PowerPC")+1); + /* descrsz */ + PL(6*4); + /* type */ + PL(0x1275); + /* name */ + printf("PowerPC"); printf("%c", 0); + +/* descriptor */ + /* real-mode */ + PL(0xffffffff); + /* real-base */ + PL(0x00c00000); + /* real-size */ + PL(0xffffffff); + /* virt-base */ + PL(0xffffffff); + /* virt-size */ + PL(0xffffffff); + /* load-base */ + PL(0x4000); + return 0; +} diff --git a/arch/ppc/coffboot/no_initrd.c b/arch/ppc/coffboot/no_initrd.c new file mode 100644 index 000000000..ed5dcdb1f --- /dev/null +++ b/arch/ppc/coffboot/no_initrd.c @@ -0,0 +1,2 @@ +char initrd_data[1]; +int initrd_len = 0; diff --git a/arch/ppc/coffboot/piggyback.c b/arch/ppc/coffboot/piggyback.c new file mode 100644 index 000000000..172025802 --- /dev/null +++ b/arch/ppc/coffboot/piggyback.c @@ -0,0 +1,65 @@ +#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 != 2) + { + fprintf(stderr, "usage: %s name <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 %s_data\n", argv[1]); + fprintf(stdout, "%s_data:\n", argv[1]); + 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 %s_len\n", argv[1]); + fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos); + fflush(stdout); + fclose(stdout); + fprintf(stderr, "cksum = %x\n", cksum); + exit(0); +} + diff --git a/arch/ppc/coffboot/start.c b/arch/ppc/coffboot/start.c index 1f11edbec..6fc1fc1fb 100644 --- a/arch/ppc/coffboot/start.c +++ b/arch/ppc/coffboot/start.c @@ -33,7 +33,7 @@ start(int a1, int a2, void *promptr) if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) exit(); - coffboot(a1, a2, promptr); + boot(a1, a2, promptr); for (;;) exit(); } @@ -62,6 +62,25 @@ write(void *handle, void *ptr, int nb) return args.actual; } +int writestring(void *f, char *ptr, int nb) +{ + int w = 0, i; + char *ret = "\r"; + + for (i = 0; i < nb; ++i) { + if (ptr[i] == '\n') { + if (i > w) { + write(f, ptr + w, i - w); + w = i; + } + write(f, ret, 1); + } + } + if (w < nb) + write(f, ptr + w, nb - w); + return nb; +} + int read(void *handle, void *ptr, int nb) { @@ -130,6 +149,29 @@ finddevice(const char *name) return args.phandle; } +void * +claim(unsigned int virt, unsigned int size, unsigned int align) +{ + struct prom_args { + char *service; + int nargs; + int nret; + unsigned int virt; + unsigned int size; + unsigned int align; + void *ret; + } args; + + args.service = "claim"; + args.nargs = 3; + args.nret = 1; + args.virt = virt; + args.size = size; + args.align = align; + (*prom)(&args); + return args.ret; +} + int getprop(void *phandle, const char *name, void *buf, int buflen) { @@ -161,9 +203,7 @@ putc(int c, void *f) { char ch = c; - if (c == '\n') - putc('\r', f); - return write(f, &ch, 1) == 1? c: -1; + return writestring(f, &ch, 1) == 1? c: -1; } int @@ -177,7 +217,7 @@ fputs(char *str, void *f) { int n = strlen(str); - return write(f, str, n) == n? 0: -1; + return writestring(f, str, n) == n? 0: -1; } int @@ -190,7 +230,7 @@ readchar() case 1: return ch; case -1: - printk("read(stdin) returned -1\r\n"); + printk("read(stdin) returned -1\n"); return -1; } } @@ -264,7 +304,7 @@ printk(char *fmt, ...) va_start(args, fmt); n = vsprintf(sprint_buf, fmt, args); va_end(args); - write(stdout, sprint_buf, n); + writestring(stdout, sprint_buf, n); } int @@ -276,6 +316,6 @@ printf(char *fmt, ...) va_start(args, fmt); n = vsprintf(sprint_buf, fmt, args); va_end(args); - write(stdout, sprint_buf, n); + writestring(stdout, sprint_buf, n); return n; } diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 325935ffe..279d81438 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -12,35 +12,49 @@ endmenu mainmenu_option next_comment comment 'Platform support' define_bool CONFIG_PPC y -choice 'Processor type' \ - "6xx/7xx CONFIG_6xx \ - 630/Power3(64-Bit) CONFIG_PPC64 \ - 82xx CONFIG_82xx \ - 8xx CONFIG_8xx" 6xx/7xx +choice 'Processor Type' \ + "6xx/7xx CONFIG_6xx \ + 4xx CONFIG_4xx \ + 630/Power3(64-Bit) CONFIG_PPC64 \ + 82xx CONFIG_82xx \ + 8xx CONFIG_8xx" 6xx/7xx + +if [ "$CONFIG_4xx" = "y" ]; then + choice 'Machine Type' \ + "Oak CONFIG_OAK \ + Walnut CONFIG_WALNUT" Oak +fi if [ "$CONFIG_8xx" = "y" ]; then - choice 'Processor Model' \ - "821 CONFIG_MPC821 \ - 823 CONFIG_MPC823 \ - 850 CONFIG_MPC850 \ - 855 CONFIG_MPC855 \ - 860 CONFIG_MPC860 \ - 860T CONFIG_MPC860T" 860 define_bool CONFIG_SERIAL_CONSOLE y - choice 'Machine Type' \ - "RPX-Lite CONFIG_RPXLITE \ - RPX-Classic CONFIG_RPXCLASSIC \ - BSE-IP CONFIG_BSEIP \ - MBX CONFIG_MBX \ - WinCept CONFIG_WINCEPT" RPX-Lite -else - choice 'Machine Type' \ - "PowerMac CONFIG_PMAC \ - PReP/MTX CONFIG_PREP \ - CHRP CONFIG_CHRP \ - PowerMac/PReP/CHRP CONFIG_ALL_PPC \ - Gemini CONFIG_GEMINI \ - APUS CONFIG_APUS" PowerMac + + choice 'Processor Model' \ + "821 CONFIG_MPC821 \ + 823 CONFIG_MPC823 \ + 850 CONFIG_MPC850 \ + 855 CONFIG_MPC855 \ + 860 CONFIG_MPC860 \ + 860T CONFIG_MPC860T" 860 + + choice 'Machine Type' \ + "RPX-Lite CONFIG_RPXLITE \ + RPX-Classic CONFIG_RPXCLASSIC \ + BSE-IP CONFIG_BSEIP \ + MBX CONFIG_MBX \ + WinCept CONFIG_WINCEPT" RPX-Lite +fi +if [ "$CONFIG_6xx" = "y" ]; then + choice 'Machine Type' \ + "PowerMac CONFIG_PMAC \ + PReP/MTX CONFIG_PREP \ + CHRP CONFIG_CHRP \ + PowerMac/PReP/CHRP CONFIG_ALL_PPC \ + Gemini CONFIG_GEMINI \ + APUS CONFIG_APUS" PowerMac +fi + +if [ "$CONFIG_PPC64" = "y" ]; then + define_bool CONFIG_ALL_PPC y fi bool 'Symmetric multi-processing support' CONFIG_SMP @@ -52,12 +66,8 @@ if [ "$CONFIG_ALL_PPC" != "y" ];then define_bool CONFIG_MACH_SPECIFIC y fi -if [ "$CONFIG_8xx" = "y" ]; then +if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then bool 'Math emulation' CONFIG_MATH_EMULATION -else - if [ "$CONFIG_PPC64" != "y" ];then - define_bool CONFIG_6xx y - fi fi endmenu @@ -75,12 +85,12 @@ comment 'General setup' if [ "$CONFIG_APUS" = "y" ]; then define_bool CONFIG_PCI n -else - if [ "$CONFIG_8xx" = "y" ]; then +else if [ "$CONFIG_OAK" = "y" ]; then + define_bool CONFIG_PCI n +else if [ "$CONFIG_8xx" = "y" ]; then bool 'QSpan PCI' CONFIG_PCI - else +else define_bool CONFIG_PCI y - fi fi bool 'Networking support' CONFIG_NET @@ -96,6 +106,8 @@ define_bool CONFIG_BINFMT_ELF y define_bool CONFIG_KERNEL_ELF y tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +source drivers/pci/Config.in + source drivers/pcmcia/Config.in source drivers/parport/Config.in diff --git a/arch/ppc/apus_defconfig b/arch/ppc/configs/apus_defconfig index f86dbd55e..f86dbd55e 100644 --- a/arch/ppc/apus_defconfig +++ b/arch/ppc/configs/apus_defconfig diff --git a/arch/ppc/chrp_defconfig b/arch/ppc/configs/chrp_defconfig index 48e305f44..48e305f44 100644 --- a/arch/ppc/chrp_defconfig +++ b/arch/ppc/configs/chrp_defconfig diff --git a/arch/ppc/common_defconfig b/arch/ppc/configs/common_defconfig index 8b232d723..977626274 100644 --- a/arch/ppc/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y # CONFIG_PPC=y CONFIG_6xx=y +# CONFIG_4xx is not set # CONFIG_PPC64 is not set # CONFIG_82xx is not set # CONFIG_8xx is not set @@ -22,7 +23,7 @@ CONFIG_ALL_PPC=y # CONFIG_GEMINI is not set # CONFIG_APUS is not set # CONFIG_SMP is not set -CONFIG_6xx=y +# CONFIG_ALTIVEC is not set # # Loadable module support @@ -34,11 +35,13 @@ CONFIG_KMOD=y # # General setup # +# CONFIG_PCI is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set @@ -271,9 +274,7 @@ CONFIG_BMAC=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_YELLOWFIN is not set # CONFIG_RTL8139 is not set -# CONFIG_SIS900 is not set # CONFIG_DM9102 is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set @@ -281,7 +282,6 @@ CONFIG_BMAC=y CONFIG_NET_EISA=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_ACENIC is not set # CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set @@ -292,12 +292,20 @@ CONFIG_DE4X5=y # CONFIG_LNE390 is not set # CONFIG_NE3210 is not set # CONFIG_NE2K_PCI is not set +# CONFIG_SIS900 is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_ES3210 is not set # CONFIG_EPIC100 is not set # CONFIG_ZNET is not set # CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -356,6 +364,7 @@ CONFIG_PPP=y # CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set CONFIG_FB_OF=y @@ -367,13 +376,13 @@ CONFIG_FB_CT65550=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set CONFIG_FB_MATROX=y -# CONFIG_FB_MATROX_MILLENIUM is not set +CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G100=y # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_3DFX is not set +CONFIG_FB_ATY128=y +CONFIG_FB_3DFX=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -414,6 +423,10 @@ CONFIG_PSMOUSE=y # CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set # CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set CONFIG_NVRAM=y # CONFIG_RTC is not set @@ -438,9 +451,40 @@ CONFIG_NVRAM=y # CONFIG_DRM is not set # -# USB drivers - not for the faint of heart +# Support for USB +# +CONFIG_USB=y + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +CONFIG_USB_OHCI=y +CONFIG_USB_OHCI_DEBUG=y +# CONFIG_USB_OHCI_HCD is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEBUG_ISOC=y +CONFIG_USB_PROC=y +# CONFIG_USB_EZUSB is not set + +# +# USB Devices # -# CONFIG_USB is not set +CONFIG_USB_HUB=y +CONFIG_USB_MOUSE=y +CONFIG_USB_HP_SCANNER=m +CONFIG_USB_KBD=y +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_CPIA is not set +# CONFIG_USB_DC2XX is not set +CONFIG_USB_SCSI=m +CONFIG_USB_SCSI_DEBUG=y # # Filesystems @@ -449,11 +493,9 @@ CONFIG_NVRAM=y CONFIG_AUTOFS_FS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=y -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set # CONFIG_EFS_FS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -466,7 +508,6 @@ CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y -# CONFIG_BFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set @@ -488,44 +529,9 @@ CONFIG_LOCKD=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set # CONFIG_SUN_PARTITION is not set -CONFIG_NLS=y - -# -# Native Language Support -# -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS is not set # # Sound diff --git a/arch/ppc/gemini_defconfig b/arch/ppc/configs/gemini_defconfig index cebd77dfe..b3129c7a5 100644 --- a/arch/ppc/gemini_defconfig +++ b/arch/ppc/configs/gemini_defconfig @@ -3,24 +3,19 @@ # # +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# # Platform support # CONFIG_PPC=y CONFIG_6xx=y +# CONFIG_4xx is not set # CONFIG_PPC64 is not set # CONFIG_82xx is not set # CONFIG_8xx is not set -# CONFIG_MPC821 is not set -# CONFIG_MPC823 is not set -# CONFIG_MPC850 is not set -# CONFIG_MPC855 is not set -# CONFIG_MPC860 is not set -# CONFIG_MPC860T is not set -# CONFIG_RPXLITE is not set -# CONFIG_RPXCLASSIC is not set -# CONFIG_BSEIP is not set -# CONFIG_MBX is not set -# CONFIG_WINCEPT is not set # CONFIG_PMAC is not set # CONFIG_PREP is not set # CONFIG_CHRP is not set @@ -28,24 +23,34 @@ CONFIG_6xx=y CONFIG_GEMINI=y # CONFIG_APUS is not set # CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set CONFIG_MACH_SPECIFIC=y -CONFIG_6xx=y # -# General setup +# Loadable module support # -CONFIG_EXPERIMENTAL=y CONFIG_MODULES=y CONFIG_MODVERSIONS=y CONFIG_KMOD=y + +# +# General setup +# +# CONFIG_PCI is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set # CONFIG_PARPORT is not set # CONFIG_VGA_CONSOLE is not set # CONFIG_FB is not set @@ -83,6 +88,7 @@ CONFIG_KERNEL_ELF=y # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_DAC960 is not set CONFIG_PARIDE_PARPORT=y # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_IDE_MODES is not set @@ -181,12 +187,11 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_G_NCR5380_PORT is not set -# CONFIG_SCSI_G_NCR5380_MEM is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set CONFIG_SCSI_SYM53C8XX=y @@ -238,10 +243,11 @@ CONFIG_NCR885E=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_RTL8139 is not set -# CONFIG_SIS900 is not set # CONFIG_YELLOWFIN is not set -# CONFIG_ACENIC is not set +# CONFIG_RTL8139 is not set +# CONFIG_DM9102 is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set # CONFIG_NET_ISA is not set # CONFIG_NET_EISA is not set # CONFIG_NET_POCKET is not set @@ -249,10 +255,14 @@ CONFIG_NCR885E=y # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# # CONFIG_NET_RADIO is not set # -# Token ring devices +# Token Ring driver support # # CONFIG_TR is not set # CONFIG_NET_FC is not set @@ -262,10 +272,7 @@ CONFIG_NCR885E=y # # Wan interfaces # -# CONFIG_HOSTESS_SV11 is not set -# CONFIG_COSA is not set -# CONFIG_SEALEVEL_4021 is not set -# CONFIG_DLCI is not set +# CONFIG_WAN is not set # # Amateur Radio support @@ -287,10 +294,14 @@ CONFIG_NCR885E=y # # +# Frame-buffer support +# +# CONFIG_FB is not set + +# # Character devices # -CONFIG_VT=y -CONFIG_VT_CONSOLE=y +# CONFIG_VT is not set CONFIG_SERIAL=y CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set @@ -301,15 +312,13 @@ CONFIG_UNIX98_PTY_COUNT=256 # # Mice # -CONFIG_BUSMOUSE=y -# CONFIG_ATIXL_BUSMOUSE is not set -# CONFIG_LOGIBUSMOUSE is not set -# CONFIG_MS_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set # CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -331,18 +340,10 @@ CONFIG_PSMOUSE=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_FT_NORMAL_DEBUG is not set -# CONFIG_FT_FULL_DEBUG is not set -# CONFIG_FT_NO_TRACE is not set -# CONFIG_FT_NO_TRACE_AT_ALL is not set -# CONFIG_FT_STD_FDC is not set -# CONFIG_FT_MACH2 is not set -# CONFIG_FT_PROBE_FC10 is not set -# CONFIG_FT_ALT_FDC is not set # CONFIG_DRM is not set # -# USB drivers - not for the faint of heart +# Support for USB # # CONFIG_USB is not set @@ -354,6 +355,7 @@ CONFIG_PSMOUSE=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set # CONFIG_FAT_FS is not set # CONFIG_EFS_FS is not set CONFIG_ISO9660_FS=y @@ -387,9 +389,6 @@ CONFIG_EXT2_FS=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set # CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set diff --git a/arch/ppc/mbx_defconfig b/arch/ppc/configs/mbx_defconfig index 7080efb3e..7080efb3e 100644 --- a/arch/ppc/mbx_defconfig +++ b/arch/ppc/configs/mbx_defconfig diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig new file mode 100644 index 000000000..1c2daf125 --- /dev/null +++ b/arch/ppc/configs/oak_defconfig @@ -0,0 +1,293 @@ +# +# Default configuration for the IBM PowerPC 403 "Oak" evaluation boards. +# + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_4xx=y +# CONFIG_6xx is not set +# CONFIG_PPC64 is not set +# CONFIG_82xx is not set +# CONFIG_8xx is not set +CONFIG_403=y +# CONFIG_405 is not set +CONFIG_OAK=y +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +# CONFIG_MATH_EMULATION is not set + +# +# General setup +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set +# CONFIG_PARPORT is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_FB is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set +# CONFIG_ADB is not set +# CONFIG_PROC_DEVICETREE is not set +# CONFIG_TOTALMP is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_MOTOROLA_HOTSWAP is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_IDE is not set + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_CPQ_DA is not set + +# +# Additional Block Devices +# +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_PARIDE_PARPORT=y +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_ALIAS=y +CONFIG_SYN_COOKIES=y + +# +# (it is safe to leave these untouched) +# +# CONFIG_SKB_LARGE is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_EISA is not set +# CONFIG_NET_POCKET is not set +# CONFIG_FDDI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring driver support +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set + +# +# Joystick support +# +# CONFIG_JOYSTICK is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set + +# +# USB drivers - not for the faint of heart +# +# CONFIG_USB is not set + +# +# Filesystems +# +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_UDF_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_ROMFS_FS=y +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_SGI_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/pmac_defconfig b/arch/ppc/configs/pmac_defconfig index 514843d00..514843d00 100644 --- a/arch/ppc/pmac_defconfig +++ b/arch/ppc/configs/pmac_defconfig diff --git a/arch/ppc/prep_defconfig b/arch/ppc/configs/prep_defconfig index 01c314cb3..01c314cb3 100644 --- a/arch/ppc/prep_defconfig +++ b/arch/ppc/configs/prep_defconfig diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig new file mode 100644 index 000000000..66edd11b6 --- /dev/null +++ b/arch/ppc/configs/walnut_defconfig @@ -0,0 +1,293 @@ +# +# Default configuration for the IBM PowerPC 405GP "Walnut" evaluation board. +# + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_4xx=y +# CONFIG_6xx is not set +# CONFIG_PPC64 is not set +# CONFIG_82xx is not set +# CONFIG_8xx is not set +CONFIG_403=y +# CONFIG_405 is not set +CONFIG_OAK=y +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +# CONFIG_MATH_EMULATION is not set + +# +# General setup +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set +# CONFIG_PARPORT is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_FB is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set +# CONFIG_ADB is not set +# CONFIG_PROC_DEVICETREE is not set +# CONFIG_TOTALMP is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_MOTOROLA_HOTSWAP is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_IDE is not set + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_CPQ_DA is not set + +# +# Additional Block Devices +# +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_PARIDE_PARPORT=y +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_ALIAS=y +CONFIG_SYN_COOKIES=y + +# +# (it is safe to leave these untouched) +# +# CONFIG_SKB_LARGE is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_EISA is not set +# CONFIG_NET_POCKET is not set +# CONFIG_FDDI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring driver support +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set + +# +# Joystick support +# +# CONFIG_JOYSTICK is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set + +# +# USB drivers - not for the faint of heart +# +# CONFIG_USB is not set + +# +# Filesystems +# +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_UDF_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_ROMFS_FS=y +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_SGI_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 8b232d723..2a3aac0f7 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y # CONFIG_PPC=y CONFIG_6xx=y +# CONFIG_4xx is not set # CONFIG_PPC64 is not set # CONFIG_82xx is not set # CONFIG_8xx is not set @@ -22,7 +23,7 @@ CONFIG_ALL_PPC=y # CONFIG_GEMINI is not set # CONFIG_APUS is not set # CONFIG_SMP is not set -CONFIG_6xx=y +# CONFIG_ALTIVEC is not set # # Loadable module support @@ -35,10 +36,12 @@ CONFIG_KMOD=y # General setup # CONFIG_PCI=y +CONFIG_PCI_NAMES=y CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set @@ -271,9 +274,7 @@ CONFIG_BMAC=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_YELLOWFIN is not set # CONFIG_RTL8139 is not set -# CONFIG_SIS900 is not set # CONFIG_DM9102 is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set @@ -281,7 +282,6 @@ CONFIG_BMAC=y CONFIG_NET_EISA=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_ACENIC is not set # CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set @@ -292,12 +292,20 @@ CONFIG_DE4X5=y # CONFIG_LNE390 is not set # CONFIG_NE3210 is not set # CONFIG_NE2K_PCI is not set +# CONFIG_SIS900 is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_ES3210 is not set # CONFIG_EPIC100 is not set # CONFIG_ZNET is not set # CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -356,6 +364,7 @@ CONFIG_PPP=y # CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set CONFIG_FB_OF=y @@ -367,13 +376,13 @@ CONFIG_FB_CT65550=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set CONFIG_FB_MATROX=y -# CONFIG_FB_MATROX_MILLENIUM is not set +CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G100=y # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_3DFX is not set +CONFIG_FB_ATY128=y +CONFIG_FB_3DFX=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -414,6 +423,10 @@ CONFIG_PSMOUSE=y # CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set # CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set CONFIG_NVRAM=y # CONFIG_RTC is not set @@ -438,9 +451,40 @@ CONFIG_NVRAM=y # CONFIG_DRM is not set # -# USB drivers - not for the faint of heart +# Support for USB +# +CONFIG_USB=y + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +CONFIG_USB_OHCI=y +CONFIG_USB_OHCI_DEBUG=y +# CONFIG_USB_OHCI_HCD is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEBUG_ISOC=y +CONFIG_USB_PROC=y +# CONFIG_USB_EZUSB is not set + +# +# USB Devices # -# CONFIG_USB is not set +CONFIG_USB_HUB=y +CONFIG_USB_MOUSE=y +CONFIG_USB_HP_SCANNER=m +CONFIG_USB_KBD=y +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_CPIA is not set +# CONFIG_USB_DC2XX is not set +CONFIG_USB_SCSI=m +CONFIG_USB_SCSI_DEBUG=y # # Filesystems @@ -449,11 +493,9 @@ CONFIG_NVRAM=y CONFIG_AUTOFS_FS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=y -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set # CONFIG_EFS_FS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -466,7 +508,6 @@ CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y -# CONFIG_BFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set @@ -488,44 +529,9 @@ CONFIG_LOCKD=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set # CONFIG_SUN_PARTITION is not set -CONFIG_NLS=y - -# -# Native Language Support -# -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS is not set # # Sound diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 3677276b5..a41473fa5 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -12,7 +12,17 @@ O_TARGET := kernel.o OX_OBJS := ppc_ksyms.o setup.o -KHEAD := head.o + + +ifeq ($(CONFIG_4xx),y) + KHEAD := head_4xx.o +else + ifeq ($(CONFIG_8xx),y) + KHEAD := head_8xx.o + else + KHEAD := head.o + endif +endif ifdef CONFIG_ALL_PPC CONFIG_PMAC=y @@ -47,48 +57,50 @@ ifdef CONFIG_SMP O_OBJS += smp.o endif -ifeq ($(CONFIG_8xx),y) -KHEAD := head_8xx.o -O_OBJS += m8xx_setup.o ppc8xx_pic.o -ifndef CONFIG_MATH_EMULATION -O_OBJS += softemu8xx.o -endif -ifdef CONFIG_PCI -O_OBJS += qspan_pci.c +ifeq ($(CONFIG_OAK),y) + O_OBJS += oak_setup.o endif -ifdef CONFIG_MBX -O_OBJS += i8259.o + +ifeq ($(CONFIG_8xx),y) + O_OBJS += m8xx_setup.o ppc8xx_pic.o + ifndef CONFIG_MATH_EMULATION + O_OBJS += softemu8xx.o + endif + ifdef CONFIG_PCI + O_OBJS += qspan_pci.c + endif + ifdef CONFIG_MBX + O_OBJS += i8259.o + endif endif -else -O_OBJS += chrp_setup.o chrp_pci.o chrp_time.o \ - pmac_time.o pmac_pci.o pmac_setup.o \ - prom.o open_pic.o feature.o \ - i8259.o pmac_pic.o indirect_pci.o \ - gemini_pci.o gemini_prom.o gemini_setup.o ifeq ($(CONFIG_NVRAM),y) -O_OBJS += pmac_support.o + O_OBJS += pmac_nvram.o endif - -ifeq ($(CONFIG_PREP), y) -O_OBJS += prep_pci.o prep_setup.o prep_nvram.o prep_time.o residual.o +ifeq ($(CONFIG_6xx),y) + O_OBJS += open_pic.o indirect_pci.o endif - -ifeq ($(CONFIG_PMAC), y) +ifeq ($(CONFIG_APUS),y) + O_OBJS += apus_setup.o endif - -ifeq ($(CONFIG_PMAC), y) +ifeq ($(CONFIG_PMAC),y) + O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o endif - -ifdef CONFIG_APUS -O_OBJS += apus_setup.o +ifeq ($(CONFIG_CHRP),y) + O_OBJS += chrp_pci.o pmac_pci.o chrp_setup.o i8259.o \ + chrp_time.o pmac_time.o prom.o endif +ifeq ($(CONFIG_PREP),y) + O_OBJS += prep_pci.o i8259.o prep_setup.o prep_nvram.o prep_time.o residual.o +endif +ifeq ($(CONFIG_GEMINI),y) + O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o endif all: $(KHEAD) kernel.o head.o: head.S ppc_defs.h - +head_4xx.o: head_4xx.S ppc_defs.h head_8xx.o: head_8xx.S ppc_defs.h ppc_defs.h: mk_defs.c ppc_defs.head \ @@ -98,7 +110,7 @@ ppc_defs.h: mk_defs.c ppc_defs.head \ $(TOPDIR)/include/asm/ptrace.h $(CC) $(CFLAGS) -S mk_defs.c cp ppc_defs.head ppc_defs.h - grep '^#define' mk_defs.s >>ppc_defs.h + grep '^#define' mk_defs.s >> ppc_defs.h rm mk_defs.s find_name : find_name.c diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c index 6a20863c5..7f6340261 100644 --- a/arch/ppc/kernel/align.c +++ b/arch/ppc/kernel/align.c @@ -1,9 +1,13 @@ /* * align.c - handle alignment exceptions for the Power PC. * - * Paul Mackerras August 1996. - * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au). + * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> + * Copyright (c) 1998-1999 TiVo, Inc. + * PowerPC 403GCX modifications. + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * PowerPC 403GCX/405GP modifications. */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/mm.h> #include <asm/ptrace.h> @@ -16,6 +20,13 @@ struct aligninfo { unsigned char flags; }; +#if defined(CONFIG_4xx) +#define OPCD(inst) (((inst) & 0xFC000000) >> 26) +#define RS(inst) (((inst) & 0x03E00000) >> 21) +#define RA(inst) (((inst) & 0x001F0000) >> 16) +#define IS_DFORM(code) ((code) >= 32 && (code) <= 47) +#endif + #define INVALID { 0, 0 } #define LD 1 /* load */ @@ -170,6 +181,9 @@ int fix_alignment(struct pt_regs *regs) { int instr, nb, flags; +#if defined(CONFIG_4xx) + int opcode, f1, f2, f3; +#endif int i, t; int reg, areg; unsigned char *addr; @@ -180,13 +194,42 @@ fix_alignment(struct pt_regs *regs) unsigned char v[8]; } data; +#if defined(CONFIG_4xx) + /* The 4xx-family processors have no DSISR register, + * so we emulate it. + */ + + instr = *((unsigned int *)regs->nip); + opcode = OPCD(instr); + reg = RS(instr); + areg = RA(instr); + + if (IS_DFORM(opcode)) { + f1 = 0; + f2 = (instr & 0x04000000) >> 26; + f3 = (instr & 0x78000000) >> 27; + } else { + f1 = (instr & 0x00000006) >> 1; + f2 = (instr & 0x00000040) >> 6; + f3 = (instr & 0x00000780) >> 7; + } + + instr = ((f1 << 5) | (f2 << 4) | f3); +#else + reg = (regs->dsisr >> 5) & 0x1f; /* source/dest register */ + areg = regs->dsisr & 0x1f; /* register to update */ instr = (regs->dsisr >> 10) & 0x7f; +#endif nb = aligninfo[instr].len; if (nb == 0) return 0; /* too hard or invalid instruction bits */ flags = aligninfo[instr].flags; - addr = (unsigned char *) regs->dar; - reg = (regs->dsisr >> 5) & 0x1f; /* source/dest register */ + + /* For the 4xx-family processors, the 'dar' field of the + * pt_regs structure is overloaded and is really from the DEAR. + */ + + addr = (unsigned char *)regs->dar; /* Verify the address of the operand */ if (user_mode(regs)) { @@ -280,7 +323,6 @@ fix_alignment(struct pt_regs *regs) } if (flags & U) { - areg = regs->dsisr & 0x1f; /* register to update */ regs->gpr[areg] = regs->dar; } diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 6133f32ca..5ed04344e 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -386,13 +386,13 @@ _GLOBAL(fake_interrupt) mtlr r0 blr -#ifndef CONFIG_8xx + /* * PROM code for specific machines follows. Put it * here so it's easy to add arch-specific sections later. * -- Cort */ - +#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) /* * On CHRP, the Run-Time Abstraction Services (RTAS) have to be * called with the MMU off. @@ -432,4 +432,4 @@ enter_rtas: mtspr SRR0,r8 mtspr SRR1,r9 rfi /* return to caller */ -#endif /* CONFIG_8xx */ +#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */ diff --git a/arch/ppc/kernel/gemini_prom.S b/arch/ppc/kernel/gemini_prom.S index 095f50e8f..f91e992f4 100644 --- a/arch/ppc/kernel/gemini_prom.S +++ b/arch/ppc/kernel/gemini_prom.S @@ -23,6 +23,7 @@ * */ +_GLOBAL(prom_init) _GLOBAL(gemini_prom_init) #ifdef __SMP__ /* Since the MMU's on, get stuff in rom space that we'll need */ diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index aee01f105..57ea34687 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -36,7 +36,6 @@ void gemini_setup_pci_ptrs(void); -static int l2_printed = 0; static unsigned char gemini_switch_map = 0; static char *gemini_board_families[] = { "VGM", "VSS", "KGM", "VGR", "KSS" @@ -178,10 +177,8 @@ void __init gemini_setup_arch(void) /* take special pains to map the MPIC, since it isn't mapped yet */ gemini_openpic_init(); - /* start the L2 */ gemini_init_l2(); - } @@ -219,7 +216,6 @@ gemini_get_clock_speed(void) return clock; } - #define L2CR_PIPE_LATEWR (0x01800000) /* late-write SRAM */ #define L2CR_L2CTL (0x00100000) /* RAM control */ #define L2CR_INST_DISABLE (0x00400000) /* disable for insn's */ @@ -259,18 +255,17 @@ void __init gemini_init_l2(void) probably always going to be late-write". --Dan */ if (reg & 0xc0) { - if (!l2_printed) { - printk("Enabling 750 L2 cache: %dKb\n", - (128 << ((reg & 0xc0)>>6))); - l2_printed=1; - } - + printk("Enabling 750 L2 cache: %dKb\n", + (128 << ((reg & 0xc0)>>6))); /* take the size given */ cache = (((reg>>6) & 0x3)<<28); } else + { + printk("Enabling 750 L2 cache: 1M\n"); /* default of 1Mb */ cache = 0x3<<28; + } reg &= 0x3; @@ -278,6 +273,7 @@ void __init gemini_init_l2(void) things. If found, tune it down to 1:1.5. -- Dan */ if (!reg) { +printk("3\n"); speed = gemini_get_clock_speed(); if (speed >= 300) { @@ -297,7 +293,10 @@ void __init gemini_init_l2(void) write-through. This is fixed in IBM's 3.1 rev (I'm told), but for now, always make 2.x versions use L2 write-through. --Dan */ if (((_get_PVR()>>8) & 0xf) <= 2) + { cache |= L2CR_L2WT; + printk("L2 cache: Enabling Write-Through due to 750 Errata.\n"); + } #endif cache |= L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE; _set_L2CR(0); @@ -332,7 +331,7 @@ void __init gemini_init_IRQ(void) /* gemini has no 8259 */ open_pic.irq_offset = 0; - for( i=0; i < OPENPIC_VEC_SPURIOUS; i++ ) + for( i=0; i < NR_IRQS; i++ ) irq_desc[i].ctl = &open_pic; openpic_init(1); #ifdef __SMP__ @@ -480,6 +479,39 @@ void __init gemini_calibrate_decr(void) count_period_den = freq / 1000000; } +int gemini_get_irq( struct pt_regs *regs ) +{ + int irq; + + irq = openpic_irq( smp_processor_id() ); + if (irq == OPENPIC_VEC_SPURIOUS) + /* + * Spurious interrupts should never be + * acknowledged + */ + irq = -1; + /* + * I would like to openpic_eoi here but there seem to be timing problems + * between the openpic ack and the openpic eoi. + * -- Cort + */ + return irq; +} + +void gemini_post_irq(int irq) +{ + /* + * If it's an i8259 irq then we've already done the + * openpic irq. So we just check to make sure the controller + * is an openpic and if it is then eoi + * + * We do it this way since our irq_desc[irq].ctl can change + * with RTL and no longer be open_pic -- Cort + */ + if ( irq >= open_pic.irq_offset) + openpic_eoi( smp_processor_id() ); +} + void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) @@ -506,8 +538,8 @@ void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_cpuinfo = gemini_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = gemini_init_IRQ; - ppc_md.get_irq = chrp_get_irq; - ppc_md.post_irq = chrp_post_irq; + ppc_md.get_irq = gemini_get_irq; + ppc_md.post_irq = gemini_post_irq; ppc_md.init = NULL; ppc_md.restart = gemini_restart; diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 57ff53992..451a1cad4 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -137,7 +137,7 @@ __start: #endif /* * We have to do any OF calls before we map ourselves to KERNELBASE, - * because OF may have I/O devices mapped in in that area + * because OF may have I/O devices mapped into that area * (particularly on CHRP). */ mr r31,r3 /* save parameters */ @@ -444,7 +444,9 @@ SystemCall: STD_EXCEPTION(0xd00, SingleStep, SingleStepException) STD_EXCEPTION(0xe00, Trap_0e, UnknownException) +#ifdef CONFIG_ALTIVEC STD_EXCEPTION(0xf20, AltiVec, AltiVecUnavailable) +#endif /* CONFIG_ALTIVEC */ /* * Handle TLB miss for instruction on 603/603e. @@ -1166,7 +1168,6 @@ __secondary_start: mtspr SRR0,r3 mtspr SRR1,r4 rfi - #endif /* CONFIG_SMP */ /* @@ -1351,6 +1352,42 @@ _GLOBAL(set_context) SYNC blr +/* + * An undocumented "feature" of 604e requires that the v bit + * be cleared before changing BAT values. + * + * Also, newer IBM firmware does not clear bat3 and 4 so + * this makes sure it's done. + * -- Cort + */ +clear_bats: +#if !defined(CONFIG_GEMINI) + li r20,0 + mfspr r9,PVR + rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ + cmpwi r9, 1 + beq 1f + + mtspr DBAT0U,r20 + mtspr DBAT0L,r20 + mtspr DBAT1U,r20 + mtspr DBAT1L,r20 + mtspr DBAT2U,r20 + mtspr DBAT2L,r20 + mtspr DBAT3U,r20 + mtspr DBAT3L,r20 +1: + mtspr IBAT0U,r20 + mtspr IBAT0L,r20 + mtspr IBAT1U,r20 + mtspr IBAT1L,r20 + mtspr IBAT2U,r20 + mtspr IBAT2L,r20 + mtspr IBAT3U,r20 + mtspr IBAT3L,r20 +#endif /* !defined(CONFIG_GEMINI) */ + blr + /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the data segment, @@ -1374,45 +1411,3 @@ swapper_pg_dir: .globl cmd_line cmd_line: .space 512 - -/* - * An undocumented "feature" of 604e requires that the v bit - * be cleared before changing BAT values. - * - * Also, newer IBM firmware does not clear bat3 and 4 so - * this makes sure it's done. - * -- Cort - */ -clear_bats: - mfmsr r20 - andi. r19,r20,MSR_DR - beqlr - - li r20,0 - - mtspr DBAT0U,r20 - mtspr DBAT0L,r20 - mtspr IBAT0U,r20 - mtspr IBAT0L,r20 - sync - isync - - mtspr DBAT1U,r20 - mtspr DBAT1L,r20 - mtspr IBAT1U,r20 - mtspr IBAT1L,r20 - sync - isync - - mtspr DBAT2U,r20 - mtspr DBAT2L,r20 - mtspr IBAT2U,r20 - mtspr IBAT2L,r20 - - mtspr DBAT3U,r20 - mtspr DBAT3L,r20 - mtspr IBAT3U,r20 - mtspr IBAT3L,r20 - - blr - diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S new file mode 100644 index 000000000..abc651218 --- /dev/null +++ b/arch/ppc/kernel/head_4xx.S @@ -0,0 +1,600 @@ +/* + * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> + * Initial PowerPC version. + * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu> + * Rewritten for PReP + * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> + * Low-level exception handers, MMU support, and rewrite. + * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> + * PowerPC 8xx modifications. + * Copyright (c) 1998-1999 TiVo, Inc. + * PowerPC 403GCX modifications. + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * PowerPC 403GCX/405GP modifications. + * + * Module name: head_4xx.S + * + * Description: + * Kernel execution entry point code. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <linux/config.h> + +#include <asm/processor.h> +#include <asm/4xx.h> +#include <asm/403gcx.h> +#include <asm/405gp.h> +#include <asm/page.h> +#include <asm/mmu.h> + +#include "ppc_asm.h" + + +/* Preprocessor Defines */ + +#define STND_EXC 0 +#define CRIT_EXC 1 + +### +### Check to make sure the right processor has been defined. +### + +#if !defined(CONFIG_4xx) +#error "This file is only appropriate for kernels supporting the PPC4xx." +#endif + +### +### Execution entry point. +### + +### +### As with the other PowerPC ports, it is expected that when code +### execution begins here, the following registers contain valid, yet +### optional, information: +### +### r3 - ??? +### r4 - Starting address of the init RAM disk +### r5 - Ending address of the init RAM disk +### r6 - Start of kernel command line string (e.g. "mem=96m") +### r7 - End of kernel command line string +### + + .text +_GLOBAL(_stext) +_GLOBAL(_start) + ## Save residual data, init RAM disk, and command line parameters + + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + + ## Set the ID for this CPU + + li r24,0 + + ## Establish exception vector base + + lis r0,KERNELBASE@h + mtspr SPRN_EVPR,r0 + + ## Jump to the main PowerPC kernel start-up code + +1: lis r7,start_here@ha + addi r7,r7,start_here@l + mtlr r7 + blr + +### +### Exception vector entry code. This code runs with address translation +### turned off (i.e. using physical addresses). We assume SPRG3 has the +### physical address of the current task thread_struct. +### + + ## Common exception code for all exception types. + +#define COMMON_PROLOG \ +0: mtspr SPRN_SPRG0,r20; /* We need r20, move it to SPRG0 */\ + mtspr SPRN_SPRG1,r21; /* We need r21, move it to SPRG1 */\ + mfcr r20; /* We need the CR, move it to r20 */\ + mfspr r21,SPRN_SPRG2; /* Exception stack to use */\ + cmpwi cr0,r21,0; /* From user mode or RTAS? */\ + bne 1f; /* Not RTAS, branch */\ + tophys(r21, r1); /* Convert vka in r1 to pka in r21 */\ + subi r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame */\ +1: stw r20,_CCR(r21); /* Save CR on the stack */\ + stw r22,GPR22(r21); /* Save r22 on the stack */\ + stw r23,GPR23(r21); /* r23 Save on the stack */\ + mfspr r20,SPRN_SPRG0; /* Get r20 back out of SPRG0 */\ + stw r20,GPR20(r21); /* Save r20 on the stack */\ + mfspr r22,SPRN_SPRG1; /* Get r21 back out of SPRG0 */\ + stw r22,GPR21(r21); /* Save r21 on the stack */\ + mflr r20; \ + stw r20,_LINK(r21); /* Save LR on the stack */\ + mfctr r22; \ + stw r22,_CTR(r21); /* Save CTR on the stack */\ + mfspr r20,XER; \ + stw r20,_XER(r21); /* Save XER on the stack */ + +#define COMMON_EPILOG \ + stw r0,GPR0(r21); /* Save r0 on the stack */\ + stw r1,GPR1(r21); /* Save r1 on the stack */\ + stw r2,GPR2(r21); /* Save r2 on the stack */\ + stw r1,0(r21); \ + tovirt(r1,r21); /* Set-up new kernel stack pointer */\ + SAVE_4GPRS(3, r21); /* Save r3 through r6 on the stack */ + + ## Common exception code for standard (non-critical) exceptions. + +#define STND_EXCEPTION_PROLOG \ + COMMON_PROLOG; \ + mfspr r22,SPRN_SRR0; /* Faulting instruction address */\ + mfspr r23,SPRN_SRR1; /* MSR at the time of fault */\ + COMMON_EPILOG; + + ## Common exception code for critical exceptions. + +#define CRIT_EXCEPTION_PROLOG \ + COMMON_PROLOG; \ + mfspr r22,SPRN_SRR2; /* Faulting instruction address */\ + mfspr r23,SPRN_SRR3; /* MSR at the time of fault */\ + COMMON_EPILOG; + +### +### Macros for specific exception types +### + +#define START_EXCEPTION(n, label) \ + . = n; \ +label: + + +#define FINISH_EXCEPTION(func) \ + bl transfer_to_handler; \ + .long func; \ + .long ret_from_except + + +#define STND_EXCEPTION(n, label, func) \ + START_EXCEPTION(n, label); \ + STND_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + li r0,STND_EXC; \ + li r20,MSR_KERNEL; \ + FINISH_EXCEPTION(func) + + +#define CRIT_EXCEPTION(n, label, func) \ + START_EXCEPTION(n, label); \ + CRIT_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + li r0,CRIT_EXC; \ + li r20,MSR_KERNEL; \ + FINISH_EXCEPTION(func) + + +#define INTR_EXCEPTION(n, label, func) \ + START_EXCEPTION(n, label); \ + STND_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + li r0,STND_EXC; \ + li r20,MSR_KERNEL; \ + li r4,0; \ + bl transfer_to_handler; \ +_GLOBAL(do_IRQ_intercept); \ + .long func; \ + .long ret_from_except + + +### +### Exception vectors. +### + +### 0x0100 - Critical Interrupt Exception + + CRIT_EXCEPTION(0x0100, CriticalInterrupt, UnknownException) + +### 0x0200 - Machine Check Exception + + CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + +### 0x0300 - Data Storage Exception + + START_EXCEPTION(0x0300, DataAccess) + STND_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR # Grab the ESR, save it, pass as arg3 + stw r5,_ESR(r21) + mfspr r4,SPRN_DEAR # Grab the DEAR, save it, pass as arg2 + stw r4,_DEAR(r21) + addi r3,r1,STACK_FRAME_OVERHEAD + li r0,STND_EXC # This is a standard exception + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, ESR, DEAR) + +### 0x0400 - Instruction Storage Exception + + START_EXCEPTION(0x0400, InstructionAccess) + STND_EXCEPTION_PROLOG + mr r4,r22 # Pass SRR0 as arg2 + mr r5,r23 # Pass SRR1 as arg3 + addi r3,r1,STACK_FRAME_OVERHEAD + li r0,STND_EXC # This is a standard exception + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, SRR0, SRR1) + +### 0x0500 - External Interrupt Exception + + INTR_EXCEPTION(0x0500, HardwareInterrupt, do_IRQ) + +### 0x0600 - Alignment Exception + + START_EXCEPTION(0x0600, Alignment) + STND_EXCEPTION_PROLOG + mfspr r4,SPRN_DEAR # Grab the DEAR and save it + stw r4,_DEAR(r21) + addi r3,r1,STACK_FRAME_OVERHEAD + li r0,STND_EXC # This is a standard exception + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + FINISH_EXCEPTION(AlignmentException) + +### 0x0700 - Program Exception + + START_EXCEPTION(0x0700, ProgramCheck) + STND_EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + li r0,STND_EXC # This is a standard exception + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + FINISH_EXCEPTION(ProgramCheckException) + + STND_EXCEPTION(0x0800, Trap_08, UnknownException) + STND_EXCEPTION(0x0900, Trap_09, UnknownException) + STND_EXCEPTION(0x0A00, Trap_0A, UnknownException) + STND_EXCEPTION(0x0B00, Trap_0B, UnknownException) +### 0x0C00 - System Call Exception + + START_EXCEPTION(0x0C00, SystemCall) + STND_EXCEPTION_PROLOG + stw r3,ORIG_GPR3(r21) + li r0,STND_EXC # This is a standard exception + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + FINISH_EXCEPTION(DoSyscall) + + STND_EXCEPTION(0x0D00, Trap_0D, UnknownException) + STND_EXCEPTION(0x0E00, Trap_0E, UnknownException) + STND_EXCEPTION(0x0F00, Trap_0F, UnknownException) + +#if 0 +### 0x1000 - Programmable Interval Timer (PIT) Exception + + STND_EXCEPTION(0x1000, PITException, UnknownException) + +### 0x1010 - Fixed Interval Timer (FIT) Exception + + STND_EXCEPTION(0x1010, FITException, UnknownException) + +### 0x1020 - Watchdog Timer (WDT) Exception + + CRIT_EXCEPTION(0x1020, WDTException, UnknownException) +#endif + +### 0x1100 - Data TLB Miss Exception + + START_EXCEPTION(0x1100, DTLBMiss) + STND_EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + li r0,STND_EXC + li r20,MSR_KERNEL + FINISH_EXCEPTION(UnknownException) + +### 0x1200 - Instruction TLB Miss Exception + + START_EXCEPTION(0x1200, ITLBMiss) + STND_EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + li r0,STND_EXC + li r20,MSR_KERNEL + FINISH_EXCEPTION(UnknownException) + + STND_EXCEPTION(0x1300, Trap_13, UnknownException) + STND_EXCEPTION(0x1400, Trap_14, UnknownException) + STND_EXCEPTION(0x1500, Trap_15, UnknownException) + STND_EXCEPTION(0x1600, Trap_16, UnknownException) + STND_EXCEPTION(0x1700, Trap_17, UnknownException) + STND_EXCEPTION(0x1800, Trap_18, UnknownException) + STND_EXCEPTION(0x1900, Trap_19, UnknownException) + STND_EXCEPTION(0x1A00, Trap_1A, UnknownException) + STND_EXCEPTION(0x1B00, Trap_1B, UnknownException) + STND_EXCEPTION(0x1C00, Trap_1C, UnknownException) + STND_EXCEPTION(0x1D00, Trap_1D, UnknownException) + STND_EXCEPTION(0x1E00, Trap_1E, UnknownException) + STND_EXCEPTION(0x1F00, Trap_1F, UnknownException) + +### 0x2000 - Debug Exception + + CRIT_EXCEPTION(0x2000, DebugTrap, UnknownException) + +### +### Other PowerPC processors, namely those derived from the 6xx-series +### have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. +### However, for the 4xx-series processors these are neither defined nor +### reserved. +### + +### +### This code finishes saving the registers to the exception frame +### and jumps to the appropriate handler for the exception, turning +### on address translation. +### + +_GLOBAL(transfer_to_handler) + stw r22,_NIP(r21) # Save the faulting IP on the stack + stw r23,_MSR(r21) # Save the exception MSR on the stack + SAVE_GPR(7, r21) # Save r7 on the stack + SAVE_4GPRS(8, r21) # Save r8 through r11 on the stack + SAVE_8GPRS(12, r21) # Save r12 through r19 on the stack + SAVE_8GPRS(24, r21) # Save r24 through r31 on the stack + andi. r23,r23,MSR_PR # Is this from user space? + mfspr r23,SPRN_SPRG3 # If from user, fix up THREAD.regs + beq 2f # No, it is from the kernel; branch. + addi r24,r1,STACK_FRAME_OVERHEAD + stw r24,PT_REGS(r23) # +2: addi r2,r23,-THREAD # Set r2 to current thread + tovirt(r2,r2) + mflr r23 + andi. r24,r23,0x3f00 # Get vector offset + stw r24,TRAP(r21) + li r22,RESULT + stwcx. r22,r22,r21 # Clear the reservation + li r22,0 + stw r22,RESULT(r21) + mtspr SPRN_SPRG2,r22 # r1 is now the kernel stack pointer + addi r24,r2,TASK_STRUCT_SIZE # Check for kernel stack overflow + cmplw cr0,r1,r2 + cmplw cr1,r1,r24 + crand cr1,cr1,cr4 + bgt- stack_ovf # If r2 < r1 < r2 + TASK_STRUCT_SIZE + lwz r24,0(r23) # Virtual address of the handler + lwz r23,4(r23) # Handler return pointer + cmpwi cr0,r0,STND_EXC # What type of exception is this? + bne 3f # It is a critical exception... + + ## Standard exception jump path + + mtspr SPRN_SRR0,r24 # Set up the instruction pointer + mtspr SPRN_SRR1,r20 # Set up the machine state register + mtlr r23 # Set up the return pointer + SYNC + rfi # Enable the MMU, jump to the handler + + ## Critical exception jump path + +3: mtspr SPRN_SRR2,r24 # Set up the instruction pointer + mtspr SPRN_SRR3,r20 # Set up the machine state register + mtlr r23 # Set up the return pointer + SYNC + rfci # Enable the MMU, jump to the handler + +### +### On kernel stack overlow, load up an initial stack pointer and call +### StackOverflow(regs), which should NOT return. +### + +stack_ovf: + addi r3,r1,STACK_FRAME_OVERHEAD + lis r1,init_task_union@ha + addi r1,r1,init_task_union@l + addi r1,r1,TASK_UNION_SIZE - STACK_FRAME_OVERHEAD + lis r24,StackOverflow@ha + addi r24,r24,StackOverflow@l + li r20,MSR_KERNEL + mtspr SPRN_SRR0,r24 # Set up the instruction pointer + mtspr SPRN_SRR1,r20 # Set up the machine state register + SYNC + rfi # Enable the MMU, jump to StackOverflow + +### +### extern void giveup_altivec(struct task_struct *prev) +### +### The PowerPC 4xx family of processors do not have AltiVec capabilities, so +### this just returns. +### + +_GLOBAL(giveup_altivec) + blr + +### +### extern void giveup_fpu(struct task_struct *prev) +### +### The PowerPC 4xx family of processors do not have an FPU, so this just +### returns. +### + +_GLOBAL(giveup_fpu) + blr + +### +### extern void abort(void) +### +### At present, this routine just applies a system reset. +### + +_GLOBAL(abort) + mfspr r13,SPRN_DBCR + ori r13,r13,DBCR_RST(SYSTEM)@h + mtspr SPRN_DBCR,r13 + + +### +### This code is jumped-to from the startup code. It copies the kernel +### image from wherever it happens to be currently running at in physical +### address space to physical address 0. +### +### In general, for a running Linux/PPC system: +### Kernel Physical Address (KPA) = 0x00000000 +### Kernel Virtual Address (KVA) = 0xC0000000 +### + +#if 0 +relocate_kernel: + lis r9,0x426f /* if booted from BootX, don't */ + addi r9,r9,0x6f58 /* translate source addr */ + cmpw r31,r9 /* (we have to on chrp) */ + beq 7f + rlwinm r4,r4,0,8,31 /* translate source address */ + add r4,r4,r3 /* to region mapped with BATs */ +7: addis r9,r26,klimit@ha /* fetch klimit */ + lwz r25,klimit@l(r9) + addis r25,r25,-KERNELBASE@h + li r6,0 /* Destination offset */ + li r5,0x4000 /* # bytes of memory to copy */ + bl copy_and_flush /* copy the first 0x4000 bytes */ + addi r0,r3,4f@l /* jump to the address of 4f */ + mtctr r0 /* in copy and do the rest. */ + bctr /* jump to the copy */ +4: mr r5,r25 + bl copy_and_flush /* copy the rest */ + b turn_on_mmu + +/* + * Copy routine used to copy the kernel to start at physical address 0 + * and flush and invalidate the caches as needed. + * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset + * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5. + */ +copy_and_flush: + addi r5,r5,-4 + addi r6,r6,-4 +4: li r0,8 + mtctr r0 +3: addi r6,r6,4 /* copy a cache line */ + lwzx r0,r6,r4 + stwx r0,r6,r3 + bdnz 3b + dcbst r6,r3 /* write it to memory */ + sync + icbi r6,r3 /* flush the icache line */ + cmplw 0,r6,r5 + blt 4b + isync + addi r5,r5,4 + addi r6,r6,4 + blr +#endif + +### +### This is where the main kernel code starts. +### + +start_here: + ## Establish a pointer to the current task + + lis r2,init_task_union@h + ori r2,r2,init_task_union@l + + ## Clear out the BSS as per ANSI C requirements + + lis r7,_end@ha + addi r7,r7,_end@l + lis r8,__bss_start@ha + addi r8,r8,__bss_start@l + subf r7,r8,r7 + addi r7,r7,3 + srwi. r7,r7,2 + beq 2f + addi r8,r8,-4 + mtctr r7 + li r0,0 +3: stwu r0,4(r8) + bdnz 3b + + ## Stack + +2: addi r1,r2,TASK_UNION_SIZE + li r0,0 + stwu r0,-STACK_FRAME_OVERHEAD(r1) + + ## Determine what type of platform this is. + + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl identify_machine + + ## Initialize the memory management unit. + + bl MMU_init + + ## Go back to running unmapped so that we can change to our + ## exception vectors. + + lis r4,2f@h + ori r4,r4,2f@l + tophys(r4,r4) + li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR) + mtspr SPRN_SRR0,r4 # Set up the instruction pointer + mtspr SPRN_SRR1,r3 # Set up the machine state register + rfi + + ## Load up the kernel context + +2: SYNC # Force all PTE updates to finish +# tlbia # Clear all TLB entries +# sync # Wait for tlbia to finish... + + ## Set up for using our exception vectors + + tophys(r4,r2) # Pointer to physical current thread + addi r4,r4,THREAD # The init task thread + mtspr SPRN_SPRG3,r4 # Save it for exceptions later + li r3,0 # + mtspr SPRN_SPRG2,r3 # 0 implies r1 has kernel stack pointer + + ## Really turn on the MMU and jump into the kernel + + lis r4,MSR_KERNEL@h + ori r4,r4,MSR_KERNEL@l + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SPRN_SRR0,r3 # Set up the instruction pointer + mtspr SPRN_SRR1,r4 # Set up the machine state register + rfi # Enable the MMU, jump to the kernel + +_GLOBAL(set_context) + mtspr SPRN_PID,r3 + tlbia + SYNC + blr + +### +### We put a few things here that have to be page-aligned. This stuff +### goes at the beginning of the data segment, which is page-aligned. +### + + .data +_GLOBAL(sdata) +_GLOBAL(empty_zero_page) + .space 4096 +_GLOBAL(swapper_pg_dir) + .space 4096 + +### +### This space gets a copy of optional info passed to us by the bootstrap +### which is used to pass parameters into the kernel like root=/dev/sda1, etc. +### + +_GLOBAL(cmd_line) + .space 512 diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 89994881b..444654ec6 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -103,8 +103,7 @@ _GLOBAL(__no_use_sti) * We were about to enable interrupts but we have to simulate * some interrupts that were lost by enable_irq first. */ - .globl do_lost_interrupts -do_lost_interrupts: +_GLOBAL(do_lost_interrupts) stwu r1,-16(r1) mflr r0 stw r0,20(r1) @@ -405,8 +404,10 @@ _GLOBAL(atomic_set_mask) * The *_ns versions don't do byte-swapping. */ _GLOBAL(_insb) + cmpw 0,r5,0 mtctr r5 subi r4,r4,1 + blelr- 00: lbz r5,0(r3) eieio stbu r5,1(r4) @@ -414,8 +415,10 @@ _GLOBAL(_insb) blr _GLOBAL(_outsb) + cmpw 0,r5,0 mtctr r5 subi r4,r4,1 + blelr- 00: lbzu r5,1(r4) stb r5,0(r3) eieio @@ -423,8 +426,10 @@ _GLOBAL(_outsb) blr _GLOBAL(_insw) + cmpw 0,r5,0 mtctr r5 subi r4,r4,2 + blelr- 00: lhbrx r5,0,r3 eieio sthu r5,2(r4) @@ -432,8 +437,10 @@ _GLOBAL(_insw) blr _GLOBAL(_outsw) + cmpw 0,r5,0 mtctr r5 subi r4,r4,2 + blelr- 00: lhzu r5,2(r4) eieio sthbrx r5,0,r3 @@ -441,8 +448,10 @@ _GLOBAL(_outsw) blr _GLOBAL(_insl) + cmpw 0,r5,0 mtctr r5 subi r4,r4,4 + blelr- 00: lwbrx r5,0,r3 eieio stwu r5,4(r4) @@ -450,8 +459,10 @@ _GLOBAL(_insl) blr _GLOBAL(_outsl) + cmpw 0,r5,0 mtctr r5 subi r4,r4,4 + blelr- 00: lwzu r5,4(r4) stwbrx r5,0,r3 eieio @@ -460,8 +471,10 @@ _GLOBAL(_outsl) _GLOBAL(ide_insw) _GLOBAL(_insw_ns) + cmpw 0,r5,0 mtctr r5 subi r4,r4,2 + blelr- 00: lhz r5,0(r3) eieio sthu r5,2(r4) @@ -470,8 +483,10 @@ _GLOBAL(_insw_ns) _GLOBAL(ide_outsw) _GLOBAL(_outsw_ns) + cmpw 0,r5,0 mtctr r5 subi r4,r4,2 + blelr- 00: lhzu r5,2(r4) sth r5,0(r3) eieio @@ -479,8 +494,10 @@ _GLOBAL(_outsw_ns) blr _GLOBAL(_insl_ns) + cmpw 0,r5,0 mtctr r5 subi r4,r4,4 + blelr- 00: lwz r5,0(r3) eieio stwu r5,4(r4) @@ -488,8 +505,10 @@ _GLOBAL(_insl_ns) blr _GLOBAL(_outsl_ns) + cmpw 0,r5,0 mtctr r5 subi r4,r4,4 + blelr- 00: lwzu r5,4(r4) stw r5,0(r3) eieio @@ -758,8 +777,19 @@ _GLOBAL(_set_L2CR) * We restore and save the fpscr so the task gets the same result * and exceptions as if the cpu had performed the load or store. */ + +#if defined(CONFIG_4xx) +_GLOBAL(cvt_fd) + lfs 0,0(r3) + stfd 0,0(r4) + blr + +_GLOBAL(cvt_df) + lfd 0,0(r3) + stfs 0,0(r4) + blr +#else _GLOBAL(cvt_fd) -cvt_fd: lfd 0,-4(r5) /* load up fpscr value */ mtfsf 0xff,0 lfs 0,0(r3) @@ -769,7 +799,6 @@ cvt_fd: blr _GLOBAL(cvt_df) -cvt_df: lfd 0,-4(r5) /* load up fpscr value */ mtfsf 0xff,0 lfd 0,0(r3) @@ -777,9 +806,9 @@ cvt_df: mffs 0 /* save new fpscr value */ stfd 0,-4(r5) blr +#endif - .globl __clear_msr_me -__clear_msr_me: +_GLOBAL(__clear_msr_me) mfmsr r0 /* Get current interrupt state */ lis r3,0 ori r3,r3,MSR_ME @@ -843,8 +872,7 @@ SYSCALL(read) /* Why isn't this a) automatic, b) written in 'C'? */ .data .align 4 - .globl sys_call_table -sys_call_table: +_GLOBAL(sys_call_table) .long sys_ni_syscall /* 0 - old "setup()" system call */ .long sys_exit .long sys_fork @@ -921,7 +949,7 @@ sys_call_table: .long sys_sigpending .long sys_sethostname .long sys_setrlimit /* 75 */ - .long sys_getrlimit + .long sys_old_getrlimit .long sys_getrusage .long sys_gettimeofday .long sys_settimeofday @@ -1039,4 +1067,5 @@ sys_call_table: .long sys_ni_syscall /* streams1 */ .long sys_ni_syscall /* streams2 */ .long sys_vfork - .space (NR_syscalls-183)*4 + .long sys_getrlimit /* 190 */ + .space (NR_syscalls-190)*4 diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c index 849e268fe..34682bd2a 100644 --- a/arch/ppc/kernel/mk_defs.c +++ b/arch/ppc/kernel/mk_defs.c @@ -88,7 +88,9 @@ main(void) DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29])); DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30])); DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31])); - /* Note: these symbols include _ because they overlap with special register names */ + /* Note: these symbols include _ because they overlap with special + * register names + */ DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip)); DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr)); DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr)); @@ -97,6 +99,12 @@ main(void) DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer)); DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar)); DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); + /* The PowerPC 400-class processors have neither the DAR nor the DSISR + * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs + * for such processors. + */ + DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar)); + DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr)); DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3)); DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result)); DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); diff --git a/arch/ppc/kernel/oak_setup.c b/arch/ppc/kernel/oak_setup.c new file mode 100644 index 000000000..a9c9137a0 --- /dev/null +++ b/arch/ppc/kernel/oak_setup.c @@ -0,0 +1,84 @@ +/* + * + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: oak_setup.c + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original + * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek + * <dmalek@jlc.net>. + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/string.h> + +#include <asm/machdep.h> +#include <asm/page.h> + +#include "oak_setup.h" + + +void __init +oak_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ +#if 0 +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured in, and there's a valid + * starting address for it, set it up. + */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } +#endif /* 0 */ + + ppc_md.setup_arch = oak_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = NULL; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = NULL; + ppc_md.get_irq = NULL; + ppc_md.init = NULL; + + ppc_md.restart = NULL; + ppc_md.power_off = NULL; + ppc_md.halt = NULL; + + ppc_md.time_init = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.calibrate_decr = NULL; + + ppc_md.kbd_setkeycode = NULL; + ppc_md.kbd_getkeycode = NULL; + ppc_md.kbd_translate = NULL; + ppc_md.kbd_unexpected_up = NULL; + ppc_md.kbd_leds = NULL; + ppc_md.kbd_init_hw = NULL; + +#if defined(CONFIG_MAGIC_SYSRQ) + ppc_md.kbd_sysrq_xlate = NULL; +#endif + + return; +} + +void __init +oak_setup_arch(void) +{ + +} diff --git a/arch/ppc/kernel/oak_setup.h b/arch/ppc/kernel/oak_setup.h new file mode 100644 index 000000000..10f7d7354 --- /dev/null +++ b/arch/ppc/kernel/oak_setup.h @@ -0,0 +1,32 @@ +/* + * + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: oak_setup.c + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original + * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek + * <dmalek@jlc.net>. + * + */ + +#ifndef __OAK_SETUP_H__ +#define __OAK_SETUP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void oak_init(unsigned long r3, + unsigned long ird_start, unsigned long ird_end, + unsigned long cline_start, unsigned long cline_end); +extern void oak_setup_arch(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __OAK_SETUP_H__ */ diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 9f3f58a38..4b0375433 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -63,9 +63,15 @@ struct hw_interrupt_type open_pic = { #define check_arg_pri(pri) \ if (pri < 0 || pri >= OPENPIC_NUM_PRI) \ printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri); -#define check_arg_irq(irq) \ +/* + * Turned this check off since the IPI's are treated as irqs + * but they're above NumSources -- Cort + */ +#define check_arg_irq(irq) +#if 0 if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \ printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq); +#endif #define check_arg_cpu(cpu) \ if (cpu < 0 || cpu >= NumProcessors) \ printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu); @@ -201,15 +207,12 @@ void __init openpic_init(int main_pic) /* Initialize IPI interrupts */ if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb); for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 0 */ - openpic_initipi(i, 0, OPENPIC_VEC_IPI+i); + /* Disabled, Priority 8 */ + openpic_initipi(i, 8, OPENPIC_VEC_IPI+i); } /* Initialize external interrupts */ if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc); - /* SIOint (8259 cascade) is special */ - openpic_initirq(0, 8, open_pic.irq_offset, 1, 1); - openpic_mapirq(0, 1<<0); for (i = 1; i < NumSources; i++) { /* Enabled, Priority 8 */ openpic_initirq(i, 8, open_pic.irq_offset+i, 0, @@ -223,6 +226,9 @@ void __init openpic_init(int main_pic) openpic_set_spurious(OPENPIC_VEC_SPURIOUS); if ( _machine != _MACH_gemini ) { + /* SIOint (8259 cascade) is special */ + openpic_initirq(0, 8, open_pic.irq_offset, 1, 1); + openpic_mapirq(0, 1<<0); if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, "82c59 cascade", NULL)) printk("Unable to get OpenPIC IRQ 0 for cascade\n"); diff --git a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h index ace8590bb..1097c70bf 100644 --- a/arch/ppc/kernel/open_pic.h +++ b/arch/ppc/kernel/open_pic.h @@ -4,5 +4,6 @@ extern struct hw_interrupt_type open_pic; void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); +void openpic_enable_IPI(u_int ipi); #endif /* _PPC_KERNEL_OPEN_PIC_H */ diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 0d07c289d..054eee918 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -8,7 +8,6 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/config.h> #include <linux/openpic.h> #include <asm/processor.h> @@ -77,6 +76,21 @@ void __init pcibios_init(void) ppc_md.pcibios_fixup(); } +void __init +pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges) +{ + ranges->io_start -= bus->resource[0]->start; + ranges->io_end -= bus->resource[0]->start; + ranges->mem_start -= bus->resource[1]->start; + ranges->mem_end -= bus->resource[1]->start; +} + +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, + unsigned long start, unsigned long size) +{ + return start; +} + static void __init pcibios_claim_resources(struct pci_bus *bus) { struct pci_dev *dev; @@ -117,31 +131,6 @@ char __init *pcibios_setup(char *str) return str; } -#ifndef CONFIG_8xx -/* Recursively searches any node that is of type PCI-PCI bridge. Without - * this, the old code would miss children of P2P bridges and hence not - * fix IRQ's for cards located behind P2P bridges. - * - Ranjit Deshpande, 01/20/99 - */ -void __init fix_intr(struct device_node *node, struct pci_dev *dev) -{ - unsigned int *reg, *class_code; - - for (; node != 0;node = node->sibling) { - class_code = (unsigned int *) get_property(node, "class-code", 0); - if((*class_code >> 8) == PCI_CLASS_BRIDGE_PCI) - fix_intr(node->child, dev); - reg = (unsigned int *) get_property(node, "reg", 0); - if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn) - continue; - /* this is the node, see if it has interrupts */ - if (node->n_intrs > 0) - dev->irq = node->intrs[0].line; - break; - } -} -#endif - int pcibios_assign_resource(struct pci_dev *pdev, int resource) { return 0; @@ -168,3 +157,8 @@ pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); /* XXX FIXME - update OF device tree node interrupt property */ } + +void __init +pcibios_align_resource(void *data, struct resource *res, unsigned long size) +{ +} diff --git a/arch/ppc/kernel/pmac_support.c b/arch/ppc/kernel/pmac_nvram.c index cf3d1711a..99bfa4f8b 100644 --- a/arch/ppc/kernel/pmac_support.c +++ b/arch/ppc/kernel/pmac_nvram.c @@ -1,15 +1,13 @@ /* * Miscellaneous procedures for dealing with the PowerMac hardware. */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/stddef.h> -#include <linux/reboot.h> #include <linux/nvram.h> #include <linux/init.h> #include <asm/init.h> -#include <asm/ptrace.h> #include <asm/io.h> -#include <asm/pgtable.h> #include <asm/system.h> #include <asm/prom.h> #include <linux/adb.h> @@ -25,7 +23,6 @@ static int nvram_mult; #define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ - __init void pmac_nvram_init(void) { @@ -55,6 +52,7 @@ void pmac_nvram_init(void) } } +__openfirmware unsigned char nvram_read_byte(int addr) { struct adb_request req; @@ -79,6 +77,7 @@ unsigned char nvram_read_byte(int addr) return 0; } +__openfirmware void nvram_write_byte(unsigned char val, int addr) { struct adb_request req; diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 62161f68a..a9166da34 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -21,7 +21,6 @@ #include <asm/init.h> #include <asm/io.h> -#include <asm/pgtable.h> #include <asm/prom.h> #include <asm/pci-bridge.h> #include <asm/machdep.h> @@ -442,6 +441,30 @@ static void __init add_bridges(struct device_node *dev) } } +/* Recursively searches any node that is of type PCI-PCI bridge. Without + * this, the old code would miss children of P2P bridges and hence not + * fix IRQ's for cards located behind P2P bridges. + * - Ranjit Deshpande, 01/20/99 + */ +void __init +fix_intr(struct device_node *node, struct pci_dev *dev) +{ + unsigned int *reg, *class_code; + + for (; node != 0;node = node->sibling) { + class_code = (unsigned int *) get_property(node, "class-code", 0); + if((*class_code >> 8) == PCI_CLASS_BRIDGE_PCI) + fix_intr(node->child, dev); + reg = (unsigned int *) get_property(node, "reg", 0); + if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn) + continue; + /* this is the node, see if it has interrupts */ + if (node->n_intrs > 0) + dev->irq = node->intrs[0].line; + break; + } +} + void __init pmac_pcibios_fixup(void) { diff --git a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c index 96c1e7260..afcda088b 100644 --- a/arch/ppc/kernel/ppc8xx_pic.c +++ b/arch/ppc/kernel/ppc8xx_pic.c @@ -1,4 +1,4 @@ - +#include <linux/config.h> #include <linux/stddef.h> #include <linux/init.h> #include <linux/sched.h> diff --git a/arch/ppc/kernel/ppc8xx_pic.h b/arch/ppc/kernel/ppc8xx_pic.h index c4de8f12e..13518bb06 100644 --- a/arch/ppc/kernel/ppc8xx_pic.h +++ b/arch/ppc/kernel/ppc8xx_pic.h @@ -1,7 +1,7 @@ - #ifndef _PPC_KERNEL_PPC8xx_H #define _PPC_KERNEL_PPC8xx_H +#include <linux/config.h> #include "local_irq.h" extern struct hw_interrupt_type ppc8xx_pic; diff --git a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h index 10be7ceab..2b999ab36 100644 --- a/arch/ppc/kernel/ppc_asm.h +++ b/arch/ppc/kernel/ppc_asm.h @@ -10,6 +10,9 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + +#include <linux/config.h> + #include "ppc_asm.tmpl" #include "ppc_defs.h" @@ -45,14 +48,20 @@ sync; \ isync -/* This instruction is not implemented on the PPC 603 or 601 */ -#define tlbia \ - li r4,128; \ - mtctr r4; \ - lis r4,KERNELBASE@h; \ -0: tlbie r4; \ - addi r4,r4,0x1000; \ +/* + * This instruction is not implemented on the PPC 603 or 601; however, on + * the 403GCX and 405GP tlbia IS defined and tlbie is not. + */ + +#if !defined(CONFIG_4xx) +#define tlbia \ + li r4,128; \ + mtctr r4; \ + lis r4,KERNELBASE@h; \ +0: tlbie r4; \ + addi r4,r4,0x1000; \ bdnz 0b +#endif /* * On APUS (Amiga PowerPC cpu upgrade board), we don't know the diff --git a/arch/ppc/kernel/ppc_asm.tmpl b/arch/ppc/kernel/ppc_asm.tmpl index e3004c8f6..94a5bd74c 100644 --- a/arch/ppc/kernel/ppc_asm.tmpl +++ b/arch/ppc/kernel/ppc_asm.tmpl @@ -1,4 +1,17 @@ -/* Register names */ +/* Condition Register Bit Fields */ + +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + + +/* General Purpose Registers (GPRs) */ + #define r0 0 #define r1 1 #define r2 2 @@ -32,6 +45,9 @@ #define r30 30 #define r31 31 + +/* Floating Point Registers (FPRs) */ + #define fr0 0 #define fr1 1 #define fr2 2 diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c index 0b7c77683..b90fa7a2c 100644 --- a/arch/ppc/kernel/ppc_htab.c +++ b/arch/ppc/kernel/ppc_htab.c @@ -63,25 +63,6 @@ static struct file_operations ppc_htab_operations = { */ struct inode_operations proc_ppc_htab_inode_operations = { &ppc_htab_operations, /* default proc file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ }; /* these will go into processor.h when I'm done debugging -- Cort */ diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 7bd21c277..11d2cd114 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -76,7 +76,7 @@ EXPORT_SYMBOL(ppc_local_bh_count); EXPORT_SYMBOL(kernel_flag); #endif /* __SMP__ */ -#ifndef CONFIG_8xx +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) EXPORT_SYMBOL(isa_io_base); EXPORT_SYMBOL(isa_mem_base); EXPORT_SYMBOL(pci_dram_offset); @@ -219,21 +219,22 @@ EXPORT_SYMBOL(pmu_register_sleep_notifier); EXPORT_SYMBOL(pmu_unregister_sleep_notifier); EXPORT_SYMBOL(pmu_enable_irled); #endif CONFIG_PMAC_PBOOK -EXPORT_SYMBOL(abort); -#ifndef CONFIG_8xx +#if defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); EXPORT_SYMBOL(find_compatible_devices); EXPORT_SYMBOL(find_path_device); EXPORT_SYMBOL(find_phandle); +EXPORT_SYMBOL(device_is_compatible); +EXPORT_SYMBOL(machine_is_compatible); EXPORT_SYMBOL(get_property); EXPORT_SYMBOL(pci_io_base); EXPORT_SYMBOL(pci_device_loc); EXPORT_SYMBOL(feature_set); EXPORT_SYMBOL(feature_clear); EXPORT_SYMBOL(feature_test); -#endif -#ifdef CONFIG_SCSI +#endif /* defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) */ +#if defined(CONFIG_SCSI) && (defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)) EXPORT_SYMBOL(note_scsi_host); #endif EXPORT_SYMBOL(kd_mksound); @@ -251,17 +252,16 @@ EXPORT_SYMBOL_NOVERS(memscan); EXPORT_SYMBOL_NOVERS(memcmp); EXPORT_SYMBOL(abs); -#ifndef CONFIG_8xx -EXPORT_SYMBOL(device_is_compatible); -#endif #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif EXPORT_SYMBOL(int_control); +#if !defined(CONFIG_4xx) EXPORT_SYMBOL(timer_interrupt_intercept); EXPORT_SYMBOL(timer_interrupt); +#endif extern unsigned long do_IRQ_intercept; EXPORT_SYMBOL(do_IRQ_intercept); EXPORT_SYMBOL(irq_desc); diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index 1bfc63c63..e7f62c429 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -760,22 +760,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, prep_setup_pci_ptrs(); -#ifdef CONFIG_BLK_DEV_INITRD - /* take care of initrd if we have one */ - if ( r4 ) - { - initrd_start = r4 + KERNELBASE; - initrd_end = r5 + KERNELBASE; - } -#endif /* CONFIG_BLK_DEV_INITRD */ - - /* take care of cmd line */ - if ( r6 && (((char *) r6) != '\0')) - { - *(char *)(r7+KERNELBASE) = 0; - strcpy(cmd_line, (char *)(r6+KERNELBASE)); - } - ppc_md.setup_arch = prep_setup_arch; ppc_md.setup_residual = prep_setup_residual; ppc_md.get_cpuinfo = prep_get_cpuinfo; diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index adeeefe33..403213883 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -204,9 +204,15 @@ _switch_to(struct task_struct *prev, struct task_struct *new, if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) && prev->thread.vrsave ) giveup_altivec(prev); - if ( (new->last_processor != NO_PROC_ID) && + /* + * The 750 doesn't broadcast invalidates with tlbie's + * so flush every processor switch. + * -- Cort + */ + if ( ((_get_PVR()>>16) == 8) && + (new->last_processor != NO_PROC_ID) && (new->last_processor != new->processor) && new->mm ) - flush_tlb_mm(new->mm); + flush_tlb_mm(new->mm); prev->last_processor = prev->processor; current_set[smp_processor_id()] = new; #endif /* __SMP__ */ diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index 22dcf8cbe..049cde10f 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -283,11 +283,6 @@ prom_init(int r3, int r4, prom_entry pp) int l; char *p, *d; -#ifdef CONFIG_GEMINI - gemini_prom_init(); - return; -#endif /* CONFIG_GEMINI */ - /* check if we're apus, return if we are */ if ( r3 == 0x61707573 ) return; diff --git a/arch/ppc/kernel/qspan_pci.c b/arch/ppc/kernel/qspan_pci.c index 6d331b2b4..860f4f0cc 100644 --- a/arch/ppc/kernel/qspan_pci.c +++ b/arch/ppc/kernel/qspan_pci.c @@ -15,6 +15,7 @@ * we have switched the chip select. */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/delay.h> diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 2cf9ee714..caffdcf99 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -30,6 +30,8 @@ #include <asm/bootx.h> #include <asm/machdep.h> +#include "oak_setup.h" + extern void pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, @@ -67,11 +69,11 @@ extern void gemini_init(unsigned long r3, unsigned long r7); extern boot_infos_t *boot_infos; -extern char cmd_line[512]; char saved_command_line[256]; unsigned char aux_device_present; struct int_control_struct int_control; struct ide_machdep_calls ppc_ide_md; +int parse_bootinfo(void); unsigned long ISA_DMA_THRESHOLD; unsigned long DMA_MODE_READ, DMA_MODE_WRITE; @@ -84,14 +86,9 @@ int have_of = 0; #ifdef CONFIG_MAGIC_SYSRQ unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ -/* For MTX/MVME boards.. with Raven/Falcon Chipset - Real close to CHRP, but boot like PReP (via PPCbug) - There's probably a nicer way to do this.. --Troy */ -int is_powerplus = 0; struct machdep_calls ppc_md; - /* copy of the residual data */ #ifndef CONFIG_8xx extern unsigned char __res[sizeof(RESIDUAL)]; @@ -196,6 +193,7 @@ int get_cpuinfo(char *buffer) unsigned long len = 0; unsigned long bogosum = 0; unsigned long i; + unsigned short maj, min; #ifdef __SMP__ #define CPU_PRESENT(x) (cpu_callin_map[(x)]) @@ -215,8 +213,8 @@ int get_cpuinfo(char *buffer) if ( i ) len += sprintf(len+buffer,"\n"); len += sprintf(len+buffer,"processor\t: %lu\n",i); - len += sprintf(len+buffer,"cpu\t\t: "); - + len += sprintf(len+buffer,"cpu\t\t: "); + switch (GET_PVR >> 16) { case 1: @@ -254,7 +252,7 @@ int get_cpuinfo(char *buffer) len += sprintf(len+buffer, "860\n"); break; default: - len += sprintf(len+buffer, "unknown (%lu)\n", + len += sprintf(len+buffer, "unknown (%lx)\n", GET_PVR>>16); break; } @@ -294,8 +292,7 @@ int get_cpuinfo(char *buffer) len += ppc_md.setup_residual(buffer + len); } - len += sprintf(len+buffer, "revision\t: %ld.%ld\n", - (GET_PVR & 0xff00) >> 8, GET_PVR & 0xff); + len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min); len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n", (CD(loops_per_sec)+2500)/500000, @@ -333,6 +330,30 @@ int get_cpuinfo(char *buffer) return len; } +#ifndef CONFIG_MACH_SPECIFIC +void __init +intuit_machine_type(void) +{ + char *model; + struct device_node *root; + + /* ask the OF info if we're a chrp or pmac */ + root = find_path_device("/"); + if (root != 0) { + /* assume pmac unless proven to be chrp -- Cort */ + _machine = _MACH_Pmac; + model = get_property(root, "device_type", NULL); + if (model && !strncmp("chrp", model, 4)) + _machine = _MACH_chrp; + else { + model = get_property(root, "model", NULL); + if (model && !strncmp(model, "IBM", 3)) + _machine = _MACH_chrp; + } + } +} +#endif /* CONFIG_MACH_SPECIFIC */ + /* * Find out what kind of machine we're on and save any data we need * from the early boot process (devtree is copied on pmac by prom_init() ) @@ -341,49 +362,31 @@ unsigned long __init identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + int_control.int_sti = __no_use_sti; + int_control.int_cli = __no_use_cli; + int_control.int_save_flags = __no_use_save_flags; + int_control.int_restore_flags = __no_use_restore_flags; -#ifndef CONFIG_8xx - if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100); + parse_bootinfo(); + if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100); +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) #ifndef CONFIG_MACH_SPECIFIC - /* boot loader will tell us if we're APUS */ - if ( r3 == 0x61707573 ) + /* if we didn't get any bootinfo telling us what we are... */ + if ( _machine == 0 ) { - _machine = _MACH_apus; - r3 = 0; - } - /* prep boot loader tells us if we're prep or not */ - else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) - { - _machine = _MACH_prep; - } else - { - char *model; - struct device_node *root; - - have_of = 1; - - /* prom_init has already been called from __start */ - if (boot_infos) - relocate_nodes(); - - /* ask the OF info if we're a chrp or pmac */ - /* we need to set _machine before calling finish_device_tree */ - root = find_path_device("/"); - if (root != 0) { - /* assume pmac unless proven to be chrp -- Cort */ - _machine = _MACH_Pmac; - model = get_property(root, "device_type", NULL); - if (model && !strncmp("chrp", model, 4)) - _machine = _MACH_chrp; - else { - model = get_property(root, "model", NULL); - if (model && !strncmp(model, "IBM", 3)) - _machine = _MACH_chrp; - } + /* boot loader will tell us if we're APUS */ + if ( r3 == 0x61707573 ) + { + _machine = _MACH_apus; + r3 = 0; } - - finish_device_tree(); + /* prep boot loader tells us if we're prep or not */ + else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) + { + _machine = _MACH_prep; + } else + have_of = 1; } #endif /* CONFIG_MACH_SPECIFIC */ @@ -392,7 +395,13 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, /* prom_init has already been called from __start */ if (boot_infos) relocate_nodes(); +#ifndef CONFIG_MACH_SPECIFIC + /* we need to set _machine before calling finish_device_tree */ + if (_machine == 0) + intuit_machine_type(); +#endif /* CONFIG_MACH_SPECIFIC */ finish_device_tree(); + /* * If we were booted via quik, r3 points to the physical * address of the command-line parameters. @@ -444,11 +453,6 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, cmd_line[sizeof(cmd_line) - 1] = 0; } - int_control.int_sti = __no_use_sti; - int_control.int_cli = __no_use_cli; - int_control.int_save_flags = __no_use_save_flags; - int_control.int_restore_flags = __no_use_restore_flags; - switch (_machine) { case _MACH_Pmac: @@ -469,7 +473,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, case _MACH_gemini: gemini_init(r3, r4, r5, r6, r7); break; -#endif +#endif default: printk("Unknown machine type in identify_machine!\n"); } @@ -478,14 +482,15 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, extern int __map_without_bats; __map_without_bats = 1; } -#else /* CONFIG_8xx */ - int_control.int_sti = __no_use_sti; - int_control.int_cli = __no_use_cli; - int_control.int_save_flags = __no_use_save_flags; - int_control.int_restore_flags = __no_use_restore_flags; - +#else +#if defined(CONFIG_4xx) + oak_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_8xx) m8xx_init(r3, r4, r5, r6, r7); -#endif +#else +#error "No board type has been defined for identify_machine()!" +#endif /* CONFIG_4xx */ +#endif /* !CONFIG_4xx && !CONFIG_8xx */ /* Look for mem= option on command line */ if (strstr(cmd_line, "mem=")) { @@ -513,6 +518,53 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.ppc_machine = _machine; if ( ppc_md.progress ) ppc_md.progress("id mach(): done", 0x200); + + return 0; +} + +int parse_bootinfo(void) +{ + struct bi_record *rec; + extern char _end[]; + + rec = (struct bi_record *)PAGE_ALIGN((ulong)_end); + if ( rec->tag != BI_FIRST ) + { + /* + * This 0x10000 offset is a terrible hack but it will go away when + * we have the bootloader handle all the relocation and + * prom calls -- Cort + */ + rec = (struct bi_record *)PAGE_ALIGN((ulong)_end+0x10000); + if ( rec->tag != BI_FIRST ) + return -1; + } + + for ( ; rec->tag != BI_LAST ; + rec = (struct bi_record *)((ulong)rec + rec->size) ) + { + ulong *data = rec->data; + switch (rec->tag) + { + case BI_CMD_LINE: + memcpy(cmd_line, (void *)data, rec->size); + break; +#ifdef CONFIG_BLK_DEV_INITRD + case BI_INITRD: + initrd_start = data[0]; + initrd_end = data[0] + rec->size; + break; +#endif /* CONFIG_BLK_DEV_INITRD */ +#ifndef CONFIG_MACH_SPECIFIC + case BI_MACHTYPE: + _machine = data[0]; + have_of = data[1]; + break; +#endif /* CONFIG_MACH_SPECIFIC */ + + } + } + return 0; } diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 0d55bcefc..1ca3a65f8 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -444,6 +444,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) case SIGQUIT: case SIGILL: case SIGTRAP: case SIGABRT: case SIGFPE: case SIGSEGV: + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: if (do_coredump(signr, regs)) exit_code |= 0x80; /* FALLTHRU */ diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index a21361340..fad7c7c1d 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -39,6 +39,7 @@ #include <asm/gemini.h> #include "time.h" +#include "open_pic.h" int smp_threads_ready = 0; volatile int smp_commenced = 0; int smp_num_cpus = 1; @@ -160,14 +161,15 @@ void smp_message_recv(void) void smp_send_reschedule(int cpu) { /* + * This is only used if `cpu' is running an idle task, + * so it will reschedule itself anyway... + * * This isn't the case anymore since the other CPU could be * sleeping and won't reschedule until the next interrupt (such * as the timer). * -- Cort */ - /* This is only used if `cpu' is running an idle task, - so it will reschedule itself anyway... */ - /*smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);*/ + smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0); } void smp_send_stop(void) diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 07e45db6b..47fef50d4 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -128,6 +128,7 @@ MachineCheckException(struct pt_regs *regs) _exception(SIGSEGV, regs); } +#if defined(CONFIG_ALTIVEC) void AltiVecUnavailable(struct pt_regs *regs) { @@ -163,6 +164,7 @@ AltiVecUnavailable(struct pt_regs *regs) /* enable altivec for the task on return */ regs->msr |= MSR_VEC; } +#endif /* CONFIG_ALTIVEC */ void UnknownException(struct pt_regs *regs) @@ -191,6 +193,20 @@ RunModeException(struct pt_regs *regs) void ProgramCheckException(struct pt_regs *regs) { +#if defined(CONFIG_4xx) + unsigned int instr; + unsigned int esr = mfspr(SPRN_ESR); + + if (esr & ESR_PTR) { +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) + if (debugger_bpt(regs)) + return; +#endif + _exception(SIGTRAP, regs); + } else { + _exception(SIGILL, regs); + } +#else if (regs->msr & 0x100000) { /* IEEE FP exception */ _exception(SIGFPE, regs); @@ -204,6 +220,7 @@ ProgramCheckException(struct pt_regs *regs) } else { _exception(SIGILL, regs); } +#endif } void diff --git a/arch/ppc/lib/checksum.S b/arch/ppc/lib/checksum.S index 5eb60537c..40741dac4 100644 --- a/arch/ppc/lib/checksum.S +++ b/arch/ppc/lib/checksum.S @@ -24,13 +24,12 @@ * len is in words and is always >= 5. */ _GLOBAL(ip_fast_csum) - cmpi 0,r4,0 - beq 10f lwz r0,0(r3) lwzu r5,4(r3) - addi r4,r4,-2 + addic. r4,r4,-2 addc r0,r0,r5 mtctr r4 + blelr- 1: lwzu r4,4(r3) adde r0,r0,r4 bdnz 1b @@ -40,8 +39,6 @@ _GLOBAL(ip_fast_csum) not r3,r3 srwi r3,r3,16 blr -10: li r3,0 - blr /* * Compute checksum of TCP or UDP pseudo-header: diff --git a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile index 2b07c7227..43f53ef4d 100644 --- a/arch/ppc/mm/Makefile +++ b/arch/ppc/mm/Makefile @@ -8,6 +8,10 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := mm.o -O_OBJS = fault.o init.o extable.o +O_OBJS = fault.o init.o mem_pieces.o extable.o + +ifeq ($(CONFIG_4xx),y) +O_OBJS += 4xx_tlb.o +endif include $(TOPDIR)/Rules.make diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index aa4f97acd..0427f2166 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -52,36 +52,36 @@ void bad_page_fault(struct pt_regs *, unsigned long); void do_page_fault(struct pt_regs *, unsigned long, unsigned long); /* - * The error_code parameter is DSISR for a data fault, SRR1 for - * an instruction fault. + * For 600- and 800-family processors, the error_code parameter is DSISR + * for a data fault, SRR1 for an instruction fault. For 400-family processors + * the error_code parameter is ESR for a data fault, 0 for an instruction + * fault. */ void do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code) { struct vm_area_struct * vma; struct mm_struct *mm = current->mm; +#if defined(CONFIG_4xx) + int is_write = error_code & ESR_DST; +#else + int is_write = error_code & 0x02000000; +#endif /* CONFIG_4xx */ - /*printk("address: %08lx nip:%08lx code: %08lx %s%s%s%s%s%s\n", - address,regs->nip,error_code, - (error_code&0x40000000)?"604 tlb&htab miss ":"", - (error_code&0x20000000)?"603 tlbmiss ":"", - (error_code&0x02000000)?"write ":"", - (error_code&0x08000000)?"prot ":"", - (error_code&0x80000000)?"I/O ":"", - (regs->trap == 0x400)?"instr":"data" - );*/ - #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_fault_handler && regs->trap == 0x300) { debugger_fault_handler(regs); return; } +#if !defined(CONFIG_4xx) if (error_code & 0x00400000) { /* DABR match */ if (debugger_dabr_match(regs)) return; } -#endif +#endif /* !CONFIG_4xx */ +#endif /* CONFIG_XMON || CONFIG_KGDB */ + if (in_interrupt()) { static int complained; if (complained < 20) { @@ -107,12 +107,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, goto bad_area; good_area: -#ifdef CONFIG_6xx +#if defined(CONFIG_6xx) if (error_code & 0x95700000) /* an error such as lwarx to I/O controller space, address matching DABR, eciwx, etc. */ #endif /* CONFIG_6xx */ -#ifdef CONFIG_8xx +#if defined(CONFIG_8xx) /* The MPC8xx seems to always set 0x80000000, which is * "undefined". Of those that can be set, this is the only * one which seems bad. @@ -124,7 +124,7 @@ good_area: /* a write */ - if (error_code & 0x02000000) { + if (is_write) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; /* a read */ @@ -135,7 +135,7 @@ good_area: if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } - if (!handle_mm_fault(current, vma, address, error_code & 0x02000000)) + if (!handle_mm_fault(current, vma, address, is_write)) goto bad_area; up(&mm->mmap_sem); /* diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 025145d71..397083aca 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -40,6 +40,7 @@ #include <linux/blk.h> /* for initrd_* */ #endif +#include <asm/pgalloc.h> #include <asm/prom.h> #include <asm/io.h> #include <asm/mmu_context.h> @@ -56,6 +57,10 @@ #include <asm/amigahw.h> #include <asm/gemini.h> +#include "mem_pieces.h" + +#define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10) + int prom_trashed; atomic_t next_mmu_context; unsigned long *end_of_DRAM; @@ -71,7 +76,6 @@ extern char __prep_begin, __prep_end; extern char __pmac_begin, __pmac_end; extern char __apus_begin, __apus_end; extern char __openfirmware_begin, __openfirmware_end; -char *klimit = _end; struct device_node *memory_node; unsigned long ioremap_base; unsigned long ioremap_bot; @@ -98,34 +102,13 @@ void map_page(unsigned long va, unsigned long pa, int flags); extern void die_if_kernel(char *,struct pt_regs *,long); extern void show_net_buffers(void); - -/* - * The following stuff defines a data structure for representing - * areas of memory as an array of (address, length) pairs, and - * procedures for manipulating them. - */ -#define MAX_MEM_REGIONS 32 - -struct mem_pieces { - int n_regions; - struct reg_property regions[MAX_MEM_REGIONS]; -}; struct mem_pieces phys_mem; -struct mem_pieces phys_avail; - -static void remove_mem_piece(struct mem_pieces *, unsigned, unsigned, int); -static void set_phys_avail(void); -void *find_mem_piece(unsigned, unsigned); -static void print_mem_pieces(struct mem_pieces *); -#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC) -static void append_mem_piece(struct mem_pieces *, unsigned, unsigned); -#endif extern struct task_struct *current_set[NR_CPUS]; PTE *Hash, *Hash_end; unsigned long Hash_size, Hash_mask; -#ifndef CONFIG_8xx +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) #ifdef CONFIG_PPC64 unsigned long long _SDR1; #else @@ -174,12 +157,10 @@ static inline unsigned long p_mapped_by_bats(unsigned long pa) return 0; } -#else /* CONFIG_8xx */ - -/* 8xx doesn't have BATs */ +#else /* CONFIG_4xx || CONFIG_8xx */ #define v_mapped_by_bats(x) (0UL) #define p_mapped_by_bats(x) (0UL) -#endif /* CONFIG_8xx */ +#endif /* !CONFIG_4xx && !CONFIG_8xx */ /* * this tells the system to map all of ram with the segregs @@ -343,24 +324,23 @@ void show_mem(void) void si_meminfo(struct sysinfo *val) { - int i; + int i, c; i = max_mapnr; - val->totalram = 0; - val->sharedram = 0; + val->totalram = totalram_pages; val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); + val->sharedram = 0; while (i-- > 0) { if (PageReserved(mem_map+i)) continue; - val->totalram++; - if (!atomic_read(&mem_map[i].count)) - continue; - val->sharedram += atomic_read(&mem_map[i].count) - 1; + c = atomic_read(&mem_map[i].count); + if (c > 1) + val->sharedram += c - 1; } - val->totalram <<= PAGE_SHIFT; - val->sharedram <<= PAGE_SHIFT; - return; + val->totalhigh = 0; + val->freehigh = 0; + val->mem_unit = PAGE_SIZE; } void * @@ -422,7 +402,7 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) if (mem_init_done) { struct vm_struct *area; - area = get_vm_area(size); + area = get_vm_area(size, VM_IOREMAP); if (area == 0) return NULL; v = VMALLOC_VMADDR(area->addr); @@ -593,191 +573,8 @@ mmu_context_overflow(void) } #endif /* CONFIG_8xx */ -/* - * Set phys_avail to phys_mem less the kernel text/data/bss. - */ -static void __init set_phys_avail(void) -{ - unsigned long kstart, ksize; - - /* we can't call the prom any more at this stage, so - all of memory is available (after klimit) */ - phys_avail = phys_mem; - - /* - * phys_avail records memory we can use. - * Make sure the kernel text/data/bss is not in it. - */ - kstart = __pa(_stext); /* should be 0 */ - ksize = PAGE_ALIGN(klimit - _stext); - remove_mem_piece(&phys_avail, kstart, ksize, 0); - remove_mem_piece(&phys_avail, 0, 0x4000, 0); - -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) { - /* - * Remove the initialized ramdisk from the available memory. - */ - remove_mem_piece(&phys_avail, __pa(initrd_start), - initrd_end - initrd_start, 1); - } -#endif /* CONFIG_BLK_DEV_INITRD */ -} - -/* - * Scan a region for a piece of a given size with the required alignment. - */ -void __init *find_mem_piece(unsigned size, unsigned align) -{ - int i; - unsigned a, e; - struct mem_pieces *mp = &phys_avail; - - for (i = 0; i < mp->n_regions; ++i) { - a = mp->regions[i].address; - e = a + mp->regions[i].size; - a = (a + align - 1) & -align; - if (a + size <= e) { - remove_mem_piece(mp, a, size, 1); - return __va(a); - } - } - printk("Couldn't find %u bytes at %u alignment\n", size, align); - abort(); - return NULL; -} - -/* - * Remove some memory from an array of pieces - */ -static void __init -remove_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size, - int must_exist) -{ - int i, j; - unsigned end, rs, re; - struct reg_property *rp; - - end = start + size; - for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) { - if (end > rp->address && start < rp->address + rp->size) - break; - } - if (i >= mp->n_regions) { - if (must_exist) - printk("remove_mem_piece: [%x,%x) not in any region\n", - start, end); - return; - } - for (; i < mp->n_regions && end > rp->address; ++i, ++rp) { - rs = rp->address; - re = rs + rp->size; - if (must_exist && (start < rs || end > re)) { - printk("remove_mem_piece: bad overlap [%x,%x) with", - start, end); - print_mem_pieces(mp); - must_exist = 0; - } - if (start > rs) { - rp->size = start - rs; - if (end < re) { - /* need to split this entry */ - if (mp->n_regions >= MAX_MEM_REGIONS) - panic("eek... mem_pieces overflow"); - for (j = mp->n_regions; j > i + 1; --j) - mp->regions[j] = mp->regions[j-1]; - ++mp->n_regions; - rp[1].address = end; - rp[1].size = re - end; - } - } else { - if (end < re) { - rp->address = end; - rp->size = re - end; - } else { - /* need to delete this entry */ - for (j = i; j < mp->n_regions - 1; ++j) - mp->regions[j] = mp->regions[j+1]; - --mp->n_regions; - --i; - --rp; - } - } - } -} - -static void __init print_mem_pieces(struct mem_pieces *mp) -{ - int i; - - for (i = 0; i < mp->n_regions; ++i) - printk(" [%x, %x)", mp->regions[i].address, - mp->regions[i].address + mp->regions[i].size); - printk("\n"); -} - -#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC) -/* - * Add some memory to an array of pieces - */ -static void __init -append_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size) -{ - struct reg_property *rp; - - if (mp->n_regions >= MAX_MEM_REGIONS) - return; - rp = &mp->regions[mp->n_regions++]; - rp->address = start; - rp->size = size; -} -#endif - -#ifndef CONFIG_8xx -static void hash_init(void); +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) static void get_mem_prop(char *, struct mem_pieces *); -static void sort_mem_pieces(struct mem_pieces *); -static void coalesce_mem_pieces(struct mem_pieces *); - -static void __init sort_mem_pieces(struct mem_pieces *mp) -{ - unsigned long a, s; - int i, j; - - for (i = 1; i < mp->n_regions; ++i) { - a = mp->regions[i].address; - s = mp->regions[i].size; - for (j = i - 1; j >= 0; --j) { - if (a >= mp->regions[j].address) - break; - mp->regions[j+1] = mp->regions[j]; - } - mp->regions[j+1].address = a; - mp->regions[j+1].size = s; - } -} - -static void __init coalesce_mem_pieces(struct mem_pieces *mp) -{ - unsigned long a, s, ns; - int i, j, d; - - d = 0; - for (i = 0; i < mp->n_regions; i = j) { - a = mp->regions[i].address; - s = mp->regions[i].size; - for (j = i + 1; j < mp->n_regions - && mp->regions[j].address - a <= s; ++j) { - ns = mp->regions[j].address + mp->regions[j].size - a; - if (ns > s) - s = ns; - } - mp->regions[d].address = a; - mp->regions[d].size = s; - ++d; - } - mp->n_regions = d; -} #if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) /* @@ -799,8 +596,8 @@ static void __init get_mem_prop(char *name, struct mem_pieces *mp) memcpy(mp->regions, rp, s); /* Make sure the pieces are sorted. */ - sort_mem_pieces(mp); - coalesce_mem_pieces(mp); + mem_pieces_sort(mp); + mem_pieces_coalesce(mp); } #endif /* CONFIG_PMAC || CONFIG_CHRP || CONFIG_ALL_PPC */ @@ -918,7 +715,7 @@ static void __init mapin_ram(void) f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #ifndef CONFIG_8xx else - /* On the powerpc (not 8xx), no user access + /* On the powerpc, denying user access forces R/W kernel access */ f |= _PAGE_USER; #endif /* CONFIG_8xx */ @@ -939,7 +736,7 @@ static void __init *MMU_get_page(void) } else if (init_bootmem_done) { p = alloc_bootmem_pages(PAGE_SIZE); } else { - p = find_mem_piece(PAGE_SIZE, PAGE_SIZE); + p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE); } if (p == 0) panic("couldn't get a page in MMU_get_page"); @@ -1000,18 +797,32 @@ void __init free_initmem(void) num_openfirmware_pages ); printk ("Freeing unused kernel memory: %ldk init", - (num_freed_pages * PAGE_SIZE) >> 10); + PGTOKB(num_freed_pages)); + if ( num_prep_pages ) - printk(" %ldk prep",(num_prep_pages*PAGE_SIZE)>>10); + printk(" %ldk prep", PGTOKB(num_prep_pages)); if ( num_pmac_pages ) - printk(" %ldk pmac",(num_pmac_pages*PAGE_SIZE)>>10); + printk(" %ldk pmac", PGTOKB(num_pmac_pages)); if ( num_openfirmware_pages ) - printk(" %ldk open firmware",(num_openfirmware_pages*PAGE_SIZE)>>10); + printk(" %ldk open firmware", PGTOKB(num_openfirmware_pages)); if ( num_apus_pages ) - printk(" %ldk apus",(num_apus_pages*PAGE_SIZE)>>10); + printk(" %ldk apus", PGTOKB(num_apus_pages)); printk("\n"); } +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(mem_map + MAP_NR(start)); + set_page_count(mem_map+MAP_NR(start), 1); + free_page(start); + totalram_pages++; + } + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); +} +#endif + /* * Do very early mm setup such as finding the size of memory * and setting up the hash table. @@ -1063,7 +874,7 @@ void __init MMU_init(void) setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); break; case _MACH_Pmac: -#if 0 +#if 1 { unsigned long base = 0xf3000000; struct device_node *macio = find_devices("mac-io"); @@ -1155,7 +966,8 @@ void __init do_init_bootmem(void) __pa(end_of_DRAM) >> PAGE_SHIFT); /* remove the bootmem bitmap from the available memory */ - remove_mem_piece(&phys_avail, start, boot_mapsize, 1); + mem_pieces_remove(&phys_avail, start, boot_mapsize, 1); + /* add everything in phys_avail into the bootmem map */ for (i = 0; i < phys_avail.n_regions; ++i) free_bootmem(phys_avail.regions[i].address, @@ -1215,6 +1027,24 @@ void __init paging_init(void) */ empty_bad_page = alloc_bootmem_pages(PAGE_SIZE); empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE); + { + unsigned int zones_size[MAX_NR_ZONES], i; + /* + * All pages are DMA-able so this is wrong - the zone code is + * assuming both regions have a value so this is necessary for + * now. + * -- Cort + */ +#if 1 + for ( i = 1; i < MAX_NR_ZONES; i++ ) + zones_size[i] = 1<<MAX_ORDER; + zones_size[0] = (virt_to_phys(end_of_DRAM) >> PAGE_SHIFT) - + ((MAX_NR_ZONES-1)*(1<<MAX_ORDER)); +#else + zones_size[0] = virt_to_phys(end_of_DRAM) >> PAGE_SHIFT; +#endif + free_area_init(zones_size); + } } void __init mem_init(void) @@ -1223,8 +1053,9 @@ void __init mem_init(void) int codepages = 0; int datapages = 0; int initpages = 0; +#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) extern unsigned int rtas_data, rtas_size; - +#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */ max_mapnr = max_low_pfn; high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); num_physpages = max_mapnr; /* RAM is assumed contiguous */ @@ -1239,6 +1070,14 @@ void __init mem_init(void) clear_bit(PG_reserved, &mem_map[MAP_NR(addr)].flags); } #endif /* CONFIG_BLK_DEV_INITRD */ + +#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) + /* mark the RTAS pages as reserved */ + if ( rtas_data ) + for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ; + addr += PAGE_SIZE) + SetPageReserved(mem_map + MAP_NR(addr)); +#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */ for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM; addr += PAGE_SIZE) { @@ -1249,12 +1088,12 @@ void __init mem_init(void) else if (addr >= (unsigned long)&__init_begin && addr < (unsigned long)&__init_end) initpages++; - else if (addr < (ulong) klimit) + else datapages++; } printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n", - (unsigned long) nr_free_pages << (PAGE_SHIFT-10), + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10), @@ -1262,7 +1101,7 @@ void __init mem_init(void) mem_init_done = 1; } -#ifndef CONFIG_8xx +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) #if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) /* * On systems with Open Firmware, collect information about @@ -1324,7 +1163,7 @@ unsigned long __init *pmac_find_end_of_memory(void) phys_mem.n_regions = 1; } - set_phys_avail(); + set_phys_avail(&phys_mem); #undef RAM_LIMIT return __va(total); @@ -1353,8 +1192,8 @@ unsigned long __init *prep_find_end_of_memory(void) total = 0x02000000; printk("Ramsize default to be %ldM\n", total>>20); } - append_mem_piece(&phys_mem, 0, total); - set_phys_avail(); + mem_pieces_append(&phys_mem, 0, total); + set_phys_avail(&phys_mem); return (__va(total)); } @@ -1376,7 +1215,7 @@ unsigned long __init *gemini_find_end_of_memory(void) phys_mem.n_regions = 1; ret = __va(phys_mem.regions[0].size); - set_phys_avail(); + set_phys_avail(&phys_mem); return ret; } #endif /* defined(CONFIG_GEMINI) */ @@ -1412,8 +1251,8 @@ unsigned long __init *apus_find_end_of_memory(void) } /* Now register the memory block. */ - append_mem_piece(&phys_mem, memory[0].addr, memory[0].size); - set_phys_avail(); + mem_pieces_append(&phys_mem, memory[0].addr, memory[0].size); + set_phys_avail(&phys_mem); /* Remove the memory chunks that are controlled by special Phase5 hardware. */ @@ -1427,8 +1266,8 @@ unsigned long __init *apus_find_end_of_memory(void) if (shadow) { top -= HARDWARE_MAPPED_SIZE; - remove_mem_piece(&phys_avail, top, - HARDWARE_MAPPED_SIZE, 0); + mem_pieces_remove(&phys_avail, top, + HARDWARE_MAPPED_SIZE, 0); } /* Remove the upper 512KB where the PPC exception @@ -1436,9 +1275,9 @@ unsigned long __init *apus_find_end_of_memory(void) top -= HARDWARE_MAPPED_SIZE; #if 0 /* This would be neat, but it breaks on A3000 machines!? */ - remove_mem_piece(&phys_avail, top, 16384, 0); + mem_pieces_remove(&phys_avail, top, 16384, 0); #else - remove_mem_piece(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0); + mem_pieces_remove(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0); #endif } @@ -1497,7 +1336,7 @@ static void __init hash_init(void) if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322); /* Find some memory for the hash table. */ if ( Hash_size ) - Hash = find_mem_piece(Hash_size, Hash_size); + Hash = mem_pieces_find(Hash_size, Hash_size); else Hash = 0; @@ -1575,7 +1414,7 @@ unsigned long __init *m8xx_find_end_of_memory(void) ret = __va(phys_mem.regions[0].address+ phys_mem.regions[0].size); - set_phys_avail(); + set_phys_avail(&phys_mem); return ret; } #endif /* ndef CONFIG_8xx */ diff --git a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c new file mode 100644 index 000000000..138b2a40f --- /dev/null +++ b/arch/ppc/mm/mem_pieces.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> + * Changes to accomodate Power Macintoshes. + * Cort Dougan <cort@cs.nmt.edu> + * Rewrites. + * Grant Erickson <grant@lcse.umn.edu> + * General rework and split from mm/init.c. + * + * Module name: mem_pieces.c + * + * Description: + * Routines and data structures for manipulating and representing + * phyiscal memory extents (i.e. address/length pairs). + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/stddef.h> +#include <linux/blk.h> + +#include <asm/page.h> +#include <asm/prom.h> + +#include "mem_pieces.h" + +extern char _start[], _end[]; +extern char _stext[], etext[]; + +char *klimit = _end; + +struct mem_pieces phys_avail; + +static void mem_pieces_print(struct mem_pieces *); + +/* + * Scan a region for a piece of a given size with the required alignment. + */ +void __init * +mem_pieces_find(unsigned int size, unsigned int align) +{ + int i; + unsigned a, e; + struct mem_pieces *mp = &phys_avail; + + for (i = 0; i < mp->n_regions; ++i) { + a = mp->regions[i].address; + e = a + mp->regions[i].size; + a = (a + align - 1) & -align; + if (a + size <= e) { + mem_pieces_remove(mp, a, size, 1); + return __va(a); + } + } + panic("Couldn't find %u bytes at %u alignment\n", size, align); + + return NULL; +} + +/* + * Remove some memory from an array of pieces + */ +void __init +mem_pieces_remove(struct mem_pieces *mp, unsigned int start, unsigned int size, + int must_exist) +{ + int i, j; + unsigned int end, rs, re; + struct reg_property *rp; + + end = start + size; + for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) { + if (end > rp->address && start < rp->address + rp->size) + break; + } + if (i >= mp->n_regions) { + if (must_exist) + printk("mem_pieces_remove: [%x,%x) not in any region\n", + start, end); + return; + } + for (; i < mp->n_regions && end > rp->address; ++i, ++rp) { + rs = rp->address; + re = rs + rp->size; + if (must_exist && (start < rs || end > re)) { + printk("mem_pieces_remove: bad overlap [%x,%x) with", + start, end); + mem_pieces_print(mp); + must_exist = 0; + } + if (start > rs) { + rp->size = start - rs; + if (end < re) { + /* need to split this entry */ + if (mp->n_regions >= MEM_PIECES_MAX) + panic("eek... mem_pieces overflow"); + for (j = mp->n_regions; j > i + 1; --j) + mp->regions[j] = mp->regions[j-1]; + ++mp->n_regions; + rp[1].address = end; + rp[1].size = re - end; + } + } else { + if (end < re) { + rp->address = end; + rp->size = re - end; + } else { + /* need to delete this entry */ + for (j = i; j < mp->n_regions - 1; ++j) + mp->regions[j] = mp->regions[j+1]; + --mp->n_regions; + --i; + --rp; + } + } + } +} + +static void __init +mem_pieces_print(struct mem_pieces *mp) +{ + int i; + + for (i = 0; i < mp->n_regions; ++i) + printk(" [%x, %x)", mp->regions[i].address, + mp->regions[i].address + mp->regions[i].size); + printk("\n"); +} + +#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC) +/* + * Add some memory to an array of pieces + */ +void __init +mem_pieces_append(struct mem_pieces *mp, unsigned int start, unsigned int size) +{ + struct reg_property *rp; + + if (mp->n_regions >= MEM_PIECES_MAX) + return; + rp = &mp->regions[mp->n_regions++]; + rp->address = start; + rp->size = size; +} +#endif + +void __init +mem_pieces_sort(struct mem_pieces *mp) +{ + unsigned long a, s; + int i, j; + + for (i = 1; i < mp->n_regions; ++i) { + a = mp->regions[i].address; + s = mp->regions[i].size; + for (j = i - 1; j >= 0; --j) { + if (a >= mp->regions[j].address) + break; + mp->regions[j+1] = mp->regions[j]; + } + mp->regions[j+1].address = a; + mp->regions[j+1].size = s; + } +} + +void __init +mem_pieces_coalesce(struct mem_pieces *mp) +{ + unsigned long a, s, ns; + int i, j, d; + + d = 0; + for (i = 0; i < mp->n_regions; i = j) { + a = mp->regions[i].address; + s = mp->regions[i].size; + for (j = i + 1; j < mp->n_regions + && mp->regions[j].address - a <= s; ++j) { + ns = mp->regions[j].address + mp->regions[j].size - a; + if (ns > s) + s = ns; + } + mp->regions[d].address = a; + mp->regions[d].size = s; + ++d; + } + mp->n_regions = d; +} + +/* + * Set phys_avail to phys_mem less the kernel text/data/bss. + */ +void __init +set_phys_avail(struct mem_pieces *mp) +{ + unsigned long kstart, ksize; + + /* + * Initially, available phyiscal memory is equivalent to all + * physical memory. + */ + + phys_avail = *mp; + + /* + * Map out the kernel text/data/bss from the available physical + * memory. + */ + + kstart = __pa(_stext); /* should be 0 */ + ksize = PAGE_ALIGN(klimit - _stext); + + printk("kstart = 0x%08lx, ksize = 0x%08lx\n", kstart, ksize); + + mem_pieces_remove(&phys_avail, kstart, ksize, 0); + mem_pieces_remove(&phys_avail, 0, 0x4000, 0); + +#if defined(CONFIG_BLK_DEV_INITRD) + /* Remove the init RAM disk from the available memory. */ + if (initrd_start) { + mem_pieces_remove(&phys_avail, __pa(initrd_start), + initrd_end - initrd_start, 1); + } +#endif /* CONFIG_BLK_DEV_INITRD */ +} diff --git a/arch/ppc/mm/mem_pieces.h b/arch/ppc/mm/mem_pieces.h new file mode 100644 index 000000000..6dbe045da --- /dev/null +++ b/arch/ppc/mm/mem_pieces.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> + * Changes to accomodate Power Macintoshes. + * Cort Dougan <cort@cs.nmt.edu> + * Rewrites. + * Grant Erickson <grant@lcse.umn.edu> + * General rework and split from mm/init.c. + * + * Module name: mem_pieces.h + * + * Description: + * Routines and data structures for manipulating and representing + * phyiscal memory extents (i.e. address/length pairs). + * + */ + +#ifndef __MEM_PIECES_H__ +#define __MEM_PIECES_H__ + +#include <linux/init.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Type Definitions */ + +#define MEM_PIECES_MAX 32 + +struct mem_pieces { + int n_regions; + struct reg_property regions[MEM_PIECES_MAX]; +}; + + +/* Global Variables */ + +extern char *klimit; +extern struct mem_pieces phys_avail; + + +/* Function Prototypes */ + +extern void *mem_pieces_find(unsigned int size, unsigned int align); +extern void mem_pieces_remove(struct mem_pieces *mp, unsigned int start, + unsigned int size, int must_exist); +extern void mem_pieces_append(struct mem_pieces *mp, unsigned int start, + unsigned int size); +extern void mem_pieces_coalesce(struct mem_pieces *mp); +extern void mem_pieces_sort(struct mem_pieces *mp); + +extern void set_phys_avail(struct mem_pieces *mp); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MEM_PIECES_H__ */ diff --git a/arch/ppc/treeboot/Makefile b/arch/ppc/treeboot/Makefile new file mode 100644 index 000000000..405634214 --- /dev/null +++ b/arch/ppc/treeboot/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> +# +# Module name: Makefile +# +# Description: +# Makefile for the IBM "tree" evaluation board Linux kernel +# boot loaders. +# + +HOSTCFLAGS = -O -I$(TOPDIR)/include + +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)ld +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump + +GZIP = gzip -vf9 +RM = rm -f +MKEVIMG = mkevimg -l +MKIRIMG = mkirimg + +CFLAGS = -O -fno-builtin -I$(TOPDIR)/include +LD_ARGS = -e _start -T ld.script -Ttext 80200000 -Bstatic + +OBJS = crt0.o main.o misc.o string.o zlib.o irSect.o +LIBS = + +treeboot: $(OBJS) ld.script + $(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS) + +zImage: vmlinux.img + +zImage.initrd: vmlinux.initrd.img + +treeboot.image: treeboot vmlinux.gz + $(OBJCOPY) --add-section=image=vmlinux.gz treeboot $@ + +treeboot.initrd: treeboot.image ramdisk.image.gz + $(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@ + +vmlinux.img: treeboot.image + $(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt + $(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt + $(MKEVIMG) treeboot.image.out $@ + $(RM) treeboot.image treeboot.image.out irSectStart.txt + +vmlinux.initrd.img: treeboot.initrd + $(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt + $(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt + $(MKEVIMG) treeboot.initrd.out $@ + $(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt + +vmlinux.gz: $(TOPDIR)/vmlinux + $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux + $(GZIP) vmlinux + +clean: + rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.* *.o + +fastdep: + diff --git a/arch/ppc/treeboot/crt0.S b/arch/ppc/treeboot/crt0.S new file mode 100644 index 000000000..1f2c1c094 --- /dev/null +++ b/arch/ppc/treeboot/crt0.S @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au> + * Initial Power Macintosh COFF version. + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * Modifications for IBM PowerPC 400-class processor evaluation + * boards. + * + * Module name: crt0.S + * + * Description: + * Boot loader execution entry point. Clears out .bss section as per + * ANSI C requirements. Invalidates and flushes the caches over the + * range covered by the boot loader's .text section. Sets up a stack + * below the .text section entry point. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include "../kernel/ppc_asm.h" + + .text + + .globl _start +_start: + ## Clear out the BSS as per ANSI C requirements + + lis r7,_end@ha # + addi r7,r7,_end@l # r7 = &_end + lis r8,__bss_start@ha # + addi r8,r8,__bss_start@l # r8 = &_bss_start + + ## Determine how large an area, in number of words, to clear + + subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 + addi r7,r7,3 # r7 += 3 + srwi. r7,r7,2 # r7 = size in words. + beq 2f # If the size is zero, do not bother + addi r8,r8,-4 # r8 -= 4 + mtctr r7 # SPRN_CTR = number of words to clear + li r0,0 # r0 = 0 +1: stwu r0,4(r8) # Clear out a word + bdnz 1b # If we are not done yet, keep clearing + + ## Flush and invalidate the caches for the range in memory covering + ## the .text section of the boot loader + +2: lis r9,_start@h # r9 = &_start + lis r8,_etext@ha # + addi r8,r8,_etext@l # r8 = &_etext +3: dcbf r0,r9 # Flush the data cache + icbi r0,r9 # Invalidate the instruction cache + addi r9,r9,0x10 # Increment by one cache line + cmplwi cr0,r9,r8 # Are we at the end yet? + blt 3b # No, keep flushing and invalidating + + ## Set up the stack + + lis r9,_start@h # r9 = &_start (text section entry) + addi r9,r9,_start@l + subi r1,r9,64 # Start the stack 64 bytes below _start + clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes. + li r0,0 + stwu r0,-16(r1) + mtlr r9 + + b start # All done, start the real work. diff --git a/arch/ppc/treeboot/elf.pl b/arch/ppc/treeboot/elf.pl new file mode 100644 index 000000000..d3e9d9d5b --- /dev/null +++ b/arch/ppc/treeboot/elf.pl @@ -0,0 +1,33 @@ +# +# ELF header field numbers +# + +$e_ident = 0; # Identification bytes / magic number +$e_type = 1; # ELF file type +$e_machine = 2; # Target machine type +$e_version = 3; # File version +$e_entry = 4; # Start address +$e_phoff = 5; # Program header file offset +$e_shoff = 6; # Section header file offset +$e_flags = 7; # File flags +$e_ehsize = 8; # Size of ELF header +$e_phentsize = 9; # Size of program header +$e_phnum = 10; # Number of program header entries +$e_shentsize = 11; # Size of section header +$e_shnum = 12; # Number of section header entries +$e_shstrndx = 13; # Section header table string index + +# +# Section header field numbers +# + +$sh_name = 0; # Section name +$sh_type = 1; # Section header type +$sh_flags = 2; # Section header flags +$sh_addr = 3; # Virtual address +$sh_offset = 4; # File offset +$sh_size = 5; # Section size +$sh_link = 6; # Miscellaneous info +$sh_info = 7; # More miscellaneous info +$sh_addralign = 8; # Memory alignment +$sh_entsize = 9; # Entry size if this is a table diff --git a/arch/ppc/treeboot/irSect.c b/arch/ppc/treeboot/irSect.c new file mode 100644 index 000000000..7f4c7f6ab --- /dev/null +++ b/arch/ppc/treeboot/irSect.c @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: irSect.c + * + * Description: + * Defines variables to hold the absolute starting address and size + * of the Linux kernel "image" and the initial RAM disk "initrd" + * sections within the boot loader. + * + */ + +#include "irSect.h" + + +/* + * The order of globals below must not change. If more globals are added, + * you must change the script 'mkirimg' accordingly. + * + */ + +/* + * irSectStart must be at beginning of file + */ +unsigned int irSectStart = 0xdeadbeaf; + +unsigned int imageSect_start = 0; +unsigned int imageSect_size = 0; +unsigned int initrdSect_start = 0; +unsigned int initrdSect_size = 0; + +/* + * irSectEnd must be at end of file + */ +unsigned int irSectEnd = 0xdeadbeaf; diff --git a/arch/ppc/treeboot/irSect.h b/arch/ppc/treeboot/irSect.h new file mode 100644 index 000000000..801c3b42e --- /dev/null +++ b/arch/ppc/treeboot/irSect.h @@ -0,0 +1,32 @@ +/* + * + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: irSect.h + * + * Description: + * Defines variables to hold the absolute starting address and size + * of the Linux kernel "image" and the initial RAM disk "initrd" + * sections within the boot loader. + * + */ + +#ifndef __IRSECT_H__ +#define __IRSECT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern unsigned int imageSect_start; +extern unsigned int imageSect_size; + +extern unsigned int initrdSect_start; +extern unsigned int initrdSect_size; + + +#ifdef __cplusplus +} +#endif + +#endif /* __IRSECT_H__ */ diff --git a/arch/ppc/treeboot/ld.script b/arch/ppc/treeboot/ld.script new file mode 100644 index 000000000..2469ed65d --- /dev/null +++ b/arch/ppc/treeboot/ld.script @@ -0,0 +1,68 @@ +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0 + .plt : { *(.plt) } + .text : + { + *(.text) + *(.rodata) + *(.rodata1) + *(.got1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + _etext = .; + PROVIDE (etext = .); + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} + diff --git a/arch/ppc/treeboot/main.c b/arch/ppc/treeboot/main.c new file mode 100644 index 000000000..1b5ef3805 --- /dev/null +++ b/arch/ppc/treeboot/main.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au> + * Initial Power Macintosh COFF version. + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * Modifications for an ELF-based IBM evaluation board version. + * + * Module name: main.c + * + * Description: + * This module does most of the real work for the boot loader. It + * checks the variables holding the absolute start address and size + * of the Linux kernel "image" and initial RAM disk "initrd" sections + * and if they are present, moves them to their "proper" locations. + * + * For the Linux kernel, "proper" is physical address 0x00000000. + * For the RAM disk, "proper" is the image's size below the top + * of physical memory. The Linux kernel may be in either raw + * binary form or compressed with GNU zip (aka gzip). + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include "nonstdio.h" +#include "zlib.h" +#include "irSect.h" + + +/* Preprocessor Defines */ + +#define RAM_SIZE (4 * 1024 * 1024) + +#define RAM_PBASE 0x00000000 +#define RAM_PEND (RAM_PBASE + RAM_SIZE) + +#define RAM_VBASE 0xC0000000 +#define RAM_VEND (RAM_VBASE + RAM_SIZE) + +#define RAM_START RAM_PBASE +#define RAM_END RAM_PEND +#define RAM_FREE (imageSect_start + imageSect_size + initrdSect_size) + +#define PROG_START RAM_START + + +/* Function Macros */ + +#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) + + +/* Global Variables */ + +/* Needed by zalloc and zfree for allocating memory */ + +char *avail_ram; /* Indicates start of RAM available for heap */ +char *end_avail; /* Indicates end of RAM available for heap */ + + +/* Function Prototypes */ + +void *zalloc(void *x, unsigned items, unsigned size); +void zfree(void *x, void *addr, unsigned nb); + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); + +void printf () {} +void pause () {} +void exit () {} + + +void start(void) +{ + void *options; + int ns, oh, i; + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned initrd_start, initrd_size; + + /* setup_bats(RAM_START); */ + + /* Init RAM disk (initrd) section */ + + if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) { + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + + printf("Initial RAM disk at 0x%08x (%u bytes)\n", + initrd_start, initrd_size); + + memcpy((char *)initrd_start, + (char *)(initrdSect_start), + initrdSect_size); + + end_avail = (char *)initrd_start; + } else { + end_avail = (char *)RAM_END; + } + + /* Linux kernel image section */ + + im = (unsigned char *)(imageSect_start); + len = imageSect_size; + dst = (void *)PROG_START; + + /* Check for the gzip archive magic numbers */ + + if (im[0] == 0x1f && im[1] == 0x8b) { + + /* The gunzip routine needs everything nice and aligned */ + + void *cp = (void *)ALIGN_UP(RAM_FREE, 8); + avail_ram = (void *)(cp + ALIGN_UP(len, 8)); + memcpy(cp, im, len); + + /* I'm not sure what the 0x200000 parameter is for, but it works. */ + + gunzip(dst, 0x200000, cp, &len); + } else { + memmove(dst, im, len); + } + + /* flush_cache(dst, len); */ + + sa = (unsigned long)dst; + + (*(void (*)())sa)(); + + pause(); +} + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p = avail_ram; + + size *= items; + size = ALIGN_UP(size, 8); + avail_ram += size; + if (avail_ram > end_avail) { + printf("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 8 + +void 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) { + printf("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) { + printf("gunzip: ran out of data in header\n"); + exit(); + } + printf("done 1\n"); + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + printf("doing inflate\n"); + r = inflate(&s, Z_FINISH); + printf("done inflate\n"); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d\n", r); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + printf("doing end\n"); + inflateEnd(&s); +} diff --git a/arch/ppc/treeboot/misc.S b/arch/ppc/treeboot/misc.S new file mode 100644 index 000000000..27417563f --- /dev/null +++ b/arch/ppc/treeboot/misc.S @@ -0,0 +1,28 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + .text + +/* + * Flush the dcache and invalidate the icache for a range of addresses. + * + * flush_cache(addr, len) + */ + .global flush_cache +flush_cache: + addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ + rlwinm. 4,4,27,5,31 + mtctr 4 + beqlr +1: dcbf 0,3 + icbi 0,3 + addi 3,3,0x20 + bdnz 1b + sync + isync + blr diff --git a/arch/ppc/treeboot/mkevimg b/arch/ppc/treeboot/mkevimg new file mode 100644 index 000000000..76f849bb7 --- /dev/null +++ b/arch/ppc/treeboot/mkevimg @@ -0,0 +1,437 @@ +#!/usr/local/bin/perl + +# +# Copyright (c) 1998-1999 TiVo, Inc. +# All rights reserved. +# +# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> +# Major syntactic and usability rework. +# +# Module name: mkevimg +# +# Description: +# Converts an ELF output file from the linker into the format used by +# the IBM evaluation board ROM Monitor to load programs from a host +# onto the evaluation board. The ELF file must be an otherwise execut- +# able file (with the text and data addresses bound at link time) and +# have space reserved after the entry point for the load information +# block: +# +# typedef struct boot_block { +# unsigned long magic; 0x0052504F +# unsigned long dest; Target address of the image +# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks +# unsigned long debug_flag; Run the debugger or image after load +# unsigned long entry_point; The image address to jump to after load +# unsigned long reserved[3]; +# } boot_block_t; +# +# + +use File::Basename; +use Getopt::Std; + +# +# usage() +# +# Description: +# This routine prints out the proper command line usage for this program +# +# Input(s): +# status - Flag determining what usage information will be printed and what +# the exit status of the program will be after the information is +# printed. +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub usage { + my($status); + $status = $_[0]; + + printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n", + $program); + + if ($status != 0) { + printf("Try `%s -h' for more information.\n", $program); + } + + if ($status != 1) { + print(" -h Print out this message and exit.\n"); + print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n"); + print(" -v Verbose. Print out lots of ELF information.\n"); + print(" -V Print out version information and exit.\n"); + } + + exit($status); +} + +# +# version() +# +# Description: +# This routine prints out program version information +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub version { + print("mkevimg Version 1.1.0\n"); + print("Copyright (c) 1998-1999 TiVo, Inc.\n"); + print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n"); + + exit (0); +} + +# +# file_check() +# +# Description: +# This routine checks an input file to ensure that it exists, is a +# regular file, and is readable. +# +# Input(s): +# file - Input file to be checked. +# +# Output(s): +# N/A +# +# Returns: +# 0 if the file exists, is a regular file, and is readable, otherwise -1. +# + +sub file_check { + my($file); + $file = $_[0]; + + if (!(-e $file)) { + printf("The file \"%s\" does not exist.\n", $file); + return (-1); + } elsif (!(-f $file)) { + printf("The file \"%s\" is not a regular file.\n", $file); + return (-1); + } elsif (!(-r $file)) { + printf("The file \"%s\" is not readable.\n", $file); + return (-1); + } + + return (0); +} + +# +# decode_options() +# +# Description: +# This routine steps through the command-line arguments, parsing out +# recognzied options. +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# N/A +# + +sub decode_options { + + if (!getopts("hlvV")) { + usage(1); + } + + if ($opt_h) { + usage(0); + } + + if ($opt_l) { + $linux = 1; + } + + if ($opt_V) { + version(); + exit (0); + } + + if ($opt_v) { + $verbose = 1; + } + + if (!($ifile = shift(@ARGV))) { + usage(1); + } + + if (!($ofile = shift(@ARGV))) { + usage (1); + } + + if (file_check($ifile)) { + exit(1); + } + +} + +# +# ELF file and section header field numbers +# + +require 'elf.pl'; + +# +# Main program body +# + +{ + $program = basename($0); + + decode_options(); + + open(ELF, "<$ifile") || die "Cannot open input file"; + + $ifilesize = (-s $ifile); + + if ($verbose) { + print("Output file: $ofile\n"); + print("Input file: $ifile, $ifilesize bytes.\n"); + } + + if (read(ELF, $ibuf, $ifilesize) != $ifilesize) { + print("Failed to read input file!\n"); + exit(1); + } + + # + # Parse ELF header + # + + @eh = unpack("a16n2N5n6", $ibuf); + + # + # Make sure this is actually a PowerPC ELF file. + # + + if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { + printf("The file \"%s\" is not an ELF file.\n", $ifile); + exit (1); + } elsif ($eh[$e_machine] != 20) { + printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile); + exit (1); + } + + if ($verbose) { + print("File header:\n"); + printf(" Identifier: %s\n", $eh[$e_ident]); + printf(" Type: %d\n", $eh[$e_type]); + printf(" Machine: %d\n", $eh[$e_machine]); + printf(" Version: %d\n", $eh[$e_version]); + printf(" Entry point: 0x%08x\n", $eh[$e_entry]); + printf(" Program header offset: 0x%x\n", $eh[$e_phoff]); + printf(" Section header offset: 0x%x\n", $eh[$e_shoff]); + printf(" Flags: 0x%08x\n", $eh[$e_flags]); + printf(" Header size: %d\n", $eh[$e_ehsize]); + printf(" Program entry size: %d\n", $eh[$e_phentsize]); + printf(" Program table entries: %d\n", $eh[$e_phnum]); + printf(" Section header size: %d\n", $eh[$e_shentsize]); + printf(" Section table entries: %d\n", $eh[$e_shnum]); + printf(" String table section: %d\n", $eh[$e_shstrndx]); + } + + # + # Find the section header for the string table. + # + + $strtable_section_offset = $eh[$e_shoff] + + $eh[$e_shstrndx] * $eh[$e_shentsize]; + + if ($verbose) { + printf("String table section header offset: 0x%x\n", + $strtable_section_offset); + } + + # + # Find the start of the string table. + # + + @strh = unpack("N10", substr($ibuf, $strtable_section_offset, + $eh[$e_shentsize])); + + if ($verbose) { + printf("Section name strings start at: 0x%x, %d bytes.\n", + $strh[$sh_offset], $strh[$sh_size]); + } + + $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); + + # Grab each section header and find '.text' and '.bss' sections in + # particular. + + if ($verbose) { + print("Section headers:\n"); + print("Idx Name Size Address File off Algn\n"); + print("--- ------------------------ -------- -------- -------- ----\n"); + } + + $off = $eh[$e_shoff]; + + for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { + @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); + + # Take the first section name from the array returned by split. + + ($name) = split(/\000/, substr($names, $sh[$sh_name])); + + if ($verbose) { + printf("%3d %-24s %8x %08x %08x %4d\n", + $i, $name, $sh[$sh_size], $sh[$sh_addr], + $sh[$sh_offset], $sh[$sh_addralign]); + } + + # Attempt to find the .text and .bss sections + + if ($name =~ /^\.bss$/) { + ($bss_addr, $bss_offset, $bss_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($name =~ /^\.text$/) { + ($text_addr, $text_offset, $text_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($linux && ($name =~ /^\image$/)) { + $image_found = 1; + + ($image_addr, $image_offset, $image_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($linux && ($name =~ /^\initrd$/)) { + $initrd_found = 1; + + ($initrd_addr, $initrd_offset, $initrd_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } + } + + printf("Text section - Address: 0x%08x, Size: 0x%08x\n", + $text_addr, $text_size); + printf("Bss section - Address: 0x%08x, Size: 0x%08x\n", + $bss_addr, $bss_size); + + if ($linux) { + if ($image_found) { + printf("Image section - Address: 0x%08x, Size: 0x%08x\n", + $image_addr, $image_size); + } + + if ($initrd_found) { + printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", + $initrd_addr, $initrd_size); + } + } + + # + # Open output file + # + + open(BOOT, ">$ofile") || die "Cannot open output file"; + + # + # Compute image size + # + + $output_size = $bss_offset - $text_offset + $bss_size; + + if ($linux && $image_found) { + $output_size += $image_size; + } + + if ($linux && $initrd_found) { + $output_size += $initrd_size; + } + + $num_blocks = $output_size / 512 + 1; + + # + # Write IBM PowerPC evaluation board boot_block_t header + # + + $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0, + $text_addr, 0, 0, 0); + + $bytes = length($header); + + if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) { + die("Could not write boot image header to output file."); + } + + printf("Entry point = 0x%08x\n", $text_addr); + printf("Image size = 0x%08x (%d bytes) (%d blocks).\n", + $output_size, $output_size, $num_blocks); + + # + # Write image starting after ELF and program headers and + # continuing to beginning of bss + # + + $bytes = $bss_offset - $text_offset + $bss_size; + + if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) { + die("Could not write boot image to output file.\n"); + } + + # + # If configured, write out the image and initrd sections as well + # + + if ($linux) { + if ($image_found) { + $bytes = $image_size; + if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) { + die("Could not write boot image to output file.\n"); + } + } + + if ($initrd_found) { + $bytes = $initrd_size; + if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) { + die("Could not write boot image to output file.\n"); + } + } + } + + # + # Pad to a multiple of 512 bytes + # + + $pad_size = 512 - (length($header) + $output_size) % 512; + + if ($verbose) { + print("Padding boot image by an additional $pad_size bytes.\n"); + } + + $pad_string = pack(("H8","deadbeef") x 128); + + syswrite(BOOT, $pad_string, $pad_size) or + die "Could not pad boot image in output file.\n"; + + # + # Clean-up and leave + # + + close(BOOT); + + print("\nBoot image file \"$ofile\" built successfuly.\n\n"); + + exit(0); +} diff --git a/arch/ppc/treeboot/mkirimg b/arch/ppc/treeboot/mkirimg new file mode 100644 index 000000000..e8aa24e3d --- /dev/null +++ b/arch/ppc/treeboot/mkirimg @@ -0,0 +1,367 @@ +#!/usr/local/bin/perl +# +# Copyright (c) 1998-1999 TiVo, Inc. +# Original ELF parsing code. +# +# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> +# Original code from 'mkevimg'. +# +# Module name: mkirimg +# +# Description: +# Reads an ELF file and assigns global variables 'imageSect_start', +# 'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from +# the "image" and "initrd" section header information. It then +# rewrites the input ELF file with assigned globals to an output +# file. +# +# An input file, "irSectStart.txt" has the memory address of +# 'irSectStart'. The irSectStart memory address is used to find +# the global variables in the ".data" section of the ELF file. +# The 'irSectStart' and the above global variables are defined +# in "irSect.c". +# +# + +use File::Basename; +use Getopt::Std; + +# +# usage() +# +# Description: +# This routine prints out the proper command line usage for this program +# +# Input(s): +# status - Flag determining what usage information will be printed and what +# the exit status of the program will be after the information is +# printed. +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub usage { + my($status); + $status = $_[0]; + + printf("Usage: %s [-hvV] <ELF input file> <Evaluation board output file> <irSectStart.txt file>\n", + $program); + + if ($status != 0) { + printf("Try `%s -h' for more information.\n", $program); + } + + if ($status != 1) { + print(" -h Print out this message and exit.\n"); + print(" -v Verbose. Print out lots of ELF information.\n"); + print(" -V Print out version information and exit.\n"); + } + + exit($status); +} + +# +# version() +# +# Description: +# This routine prints out program version information +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub version { + print("mkirimg Version 1.1.0\n"); + print("Copyright (c) 1998-1999 TiVo, Inc.\n"); + print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n"); + + exit (0); +} + +# +# file_check() +# +# Description: +# This routine checks an input file to ensure that it exists, is a +# regular file, and is readable. +# +# Input(s): +# file - Input file to be checked. +# +# Output(s): +# N/A +# +# Returns: +# 0 if the file exists, is a regular file, and is readable, otherwise -1. +# + +sub file_check { + my($file); + $file = $_[0]; + + if (!(-e $file)) { + printf("The file \"%s\" does not exist.\n", $file); + return (-1); + } elsif (!(-f $file)) { + printf("The file \"%s\" is not a regular file.\n", $file); + return (-1); + } elsif (!(-r $file)) { + printf("The file \"%s\" is not readable.\n", $file); + return (-1); + } + + return (0); +} + +# +# decode_options() +# +# Description: +# This routine steps through the command-line arguments, parsing out +# recognzied options. +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# N/A +# + +sub decode_options { + + if (!getopts("hvV")) { + usage(1); + } + + if ($opt_h) { + usage(0); + } + + if ($opt_V) { + version(); + exit (0); + } + + if ($opt_v) { + $verbose = 1; + } + + if (!($ElfFile = shift(@ARGV))) { + usage(1); + } + + if (!($OutputFile = shift(@ARGV))) { + usage (1); + } + + if (!($IrFile = shift(@ARGV))) { + usage (1); + } + + if (file_check($ElfFile)) { + exit(1); + } + + if (file_check($IrFile)) { + exit(1); + } +} + +# +# ELF file and section header field numbers +# + +require 'elf.pl'; + +# +# Main program body +# + +{ + $program = basename($0); + decode_options(); + + open(ELF, "<$ElfFile") || die "Cannot open input file"; + open(OUTPUT, ">$OutputFile") || die "Cannot open output file"; + open(IR, "$IrFile") || die "Cannot open input file"; + + $ElfFilesize = (-s $ElfFile); + + if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) { + print("Failed to read ELF input file!\n"); + exit(1); + } + + if (read(IR, $irbuf, 8) != 8) { + print("Failed to read Ir input file!\n"); + exit(1); + } + + # + # Parse ELF header + # + + @eh = unpack("a16n2N5n6", $ibuf); + + # + # Make sure this is actually a PowerPC ELF file. + # + + if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { + printf("The file \"%s\" is not an ELF file.\n", $ElfFile); + exit (1); + } elsif ($eh[$e_machine] != 20) { + printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile); + exit (1); + } + + # + # Find the section header for the string table. + # + + $strtable_section_offset = $eh[$e_shoff] + + + $eh[$e_shstrndx] * $eh[$e_shentsize]; + + if ($verbose) { + printf("String table section header offset: 0x%x\n", + $strtable_section_offset); + } + + # + # Find the start of the string table. + # + + @strh = unpack("N10", substr($ibuf, $strtable_section_offset, + $eh[$e_shentsize])); + + if ($verbose) { + printf("Section name strings start at: 0x%x, %d bytes.\n", + $strh[$sh_offset], $strh[$sh_size]); + } + + $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); + + # Grab each section header and find '.data', 'image', and + # 'initrd' sections in particular. + + $off = $eh[$e_shoff]; + $imageFound = 0; + $initrdFound = 0; + + for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { + @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); + + # Take the first section name from the array returned by split. + + ($name) = split(/\000/, substr($names, $sh[$sh_name])); + + # Attempt to find the .data, image, and initrd sections + + if ($name =~ /^\image$/) { + ($image_addr, $image_offset, $image_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + $imageFound = 1; + + } elsif ($name =~ /^\initrd$/) { + ($initrd_addr, $initrd_offset, $initrd_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + $initrdFound = 1; + + } elsif ($name =~ /^\.data$/) { + ($data_addr, $data_offset, $data_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($name =~ /^\.bss$/) { + ($bss_addr, $bss_offset, $bss_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } + } + + if ($verbose) { + printf("Data section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", + $data_addr, $data_size, $data_offset); + printf("Bss section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", + $bss_addr, $bss_size, $bss_offset); + } + + if ($verbose) { + if ($imageFound) { + printf("Image section - Address: 0x%08x, Size: 0x%08x\n", + $image_addr, $image_size); + } else { + printf("Image section not found in file: $ElfFile\n"); + } + + if ($initrdFound) { + printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", + $initrd_addr, $initrd_size); + } else { + printf("Initrd section not found in file: $ElfFile\n"); + } + } + + # get file offset of irSectStart + + $irSectStartoffset = hex ($irbuf); + + if ($verbose) { + printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset); + } + + # get the offset of global variables + + $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4; + + # write modified values to OUTPUT file + + syswrite(OUTPUT, $ibuf, $initialOffset); + + if ($imageFound) { + $testN = pack ("I2", $bss_addr + $bss_size, $image_size); + syswrite(OUTPUT, $testN, length($testN)); + printf("Updated symbol \"imageSect_start\" to 0x%08x\n", + $bss_addr + $bss_size); + printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size); + } else { + syswrite(OUTPUT, $ibuf, 8, $initialOffset); + } + + if ($initrdFound) { + $testN = pack ("I2", $bss_addr + $bss_size + $image_size, $initrd_size); + syswrite(OUTPUT, $testN, length($testN)); + printf("Updated symbol \"initrdSect_start\" to 0x%08x\n", + $bss_addr + $bss_size + $image_size); + printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size); + } else { + syswrite(OUTPUT, $ibuf,8, $initialOffset + 8); + } + + syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16), + $initialOffset + 16); + + # + # Clean-up and leave + # + + close (ELF); + close (OUTPUT); + close (IR); + + exit (0); +} + diff --git a/arch/ppc/xmon/ppc-opc.c b/arch/ppc/xmon/ppc-opc.c index b3566863d..5e838d924 100644 --- a/arch/ppc/xmon/ppc-opc.c +++ b/arch/ppc/xmon/ppc-opc.c @@ -533,8 +533,7 @@ extract_bdp (insn, invalid) /* Check for legal values of a BO field. */ static int -valid_bo (value) - long value; +valid_bo (long value) { /* Certain encodings have bits that are required to be zero. These are (z must be zero, y may be anything): diff --git a/arch/ppc/xmon/privinst.h b/arch/ppc/xmon/privinst.h index 9a46f1aee..ec281a154 100644 --- a/arch/ppc/xmon/privinst.h +++ b/arch/ppc/xmon/privinst.h @@ -70,4 +70,13 @@ static inline void store_inst(void *p) asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); } +static inline void cflush(void *p) +{ + asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); +} + +static inline void cinval(void *p) +{ + asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); +} diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index 1b0fffd71..9fc97b5a9 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c @@ -6,11 +6,11 @@ #include <asm/machdep.h> #include <asm/io.h> #include <asm/page.h> -#include <asm/pgtable.h> #include <linux/adb.h> #include <linux/pmu.h> #include <asm/prom.h> #include <asm/bootx.h> +#include <asm/processor.h> static volatile unsigned char *sccc, *sccd; unsigned long TXRDY, RXRDY; @@ -41,7 +41,7 @@ xmon_map_scc(void) #ifdef CONFIG_BOOTX_TEXT if (boot_infos != 0 && find_via_pmu()) { - printk(KERN_INFO "xmon uses screen and keyboard\n"); + printk("xmon uses screen and keyboard\n"); use_screen = 1; map_bootx_text(); return; diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index b07d7fc99..f5a42cc29 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -79,6 +79,7 @@ static void remove_bpts(void); static void insert_bpts(void); static struct bpt *at_breakpoint(unsigned pc); static void bpt_cmds(void); +static void cacheflush(void); extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned); extern void printf(const char *fmt, ...); @@ -342,11 +343,9 @@ cmds(struct pt_regs *excp) case 't': backtrace(excp); break; -#if 0 case 'f': - openforth(); + cacheflush(); break; -#endif case 'h': dump_hash_table(); break; @@ -541,6 +540,30 @@ prregs(struct pt_regs *fp) fp->ctr, fp->xer, fp->trap); } +void +cacheflush(void) +{ + int cmd; + unsigned nflush; + + cmd = inchar(); + if (cmd != 'i') + termch = cmd; + scanhex(&adrs); + if (termch != '\n') + termch = 0; + nflush = 1; + scanhex(&nflush); + nflush = (nflush + 31) / 32; + if (cmd != 'i') { + for (; nflush > 0; --nflush, adrs += 0x20) + cflush((void *) adrs); + } else { + for (; nflush > 0; --nflush, adrs += 0x20) + cinval((void *) adrs); + } +} + unsigned int read_spr(int n) { |