summaryrefslogtreecommitdiffstats
path: root/arch/ppc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
commit33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch)
tree2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /arch/ppc
parent216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff)
Merge with Linux 2.3.32.
Diffstat (limited to 'arch/ppc')
-rw-r--r--arch/ppc/8xx_io/commproc.c1
-rw-r--r--arch/ppc/8xx_io/commproc.h1
-rw-r--r--arch/ppc/8xx_io/enet.c1
-rw-r--r--arch/ppc/8xx_io/fec.c1
-rw-r--r--arch/ppc/Makefile74
-rw-r--r--arch/ppc/amiga/ints.c1
-rw-r--r--arch/ppc/boot/Makefile2
-rw-r--r--arch/ppc/boot/head.S8
-rw-r--r--arch/ppc/boot/misc.c39
-rw-r--r--arch/ppc/chrpboot/main.c28
-rw-r--r--arch/ppc/chrpboot/string.S206
-rw-r--r--arch/ppc/coffboot/Makefile67
-rw-r--r--arch/ppc/coffboot/chrpmain.c241
-rw-r--r--arch/ppc/coffboot/coffcrt0.S24
-rw-r--r--arch/ppc/coffboot/coffmain.c189
-rw-r--r--arch/ppc/coffboot/crt0.S4
-rw-r--r--arch/ppc/coffboot/main.c33
-rw-r--r--arch/ppc/coffboot/misc.S35
-rw-r--r--arch/ppc/coffboot/mknote.c43
-rw-r--r--arch/ppc/coffboot/no_initrd.c2
-rw-r--r--arch/ppc/coffboot/piggyback.c65
-rw-r--r--arch/ppc/coffboot/start.c56
-rw-r--r--arch/ppc/config.in82
-rw-r--r--arch/ppc/configs/apus_defconfig (renamed from arch/ppc/apus_defconfig)0
-rw-r--r--arch/ppc/configs/chrp_defconfig (renamed from arch/ppc/chrp_defconfig)0
-rw-r--r--arch/ppc/configs/common_defconfig (renamed from arch/ppc/common_defconfig)108
-rw-r--r--arch/ppc/configs/gemini_defconfig (renamed from arch/ppc/gemini_defconfig)91
-rw-r--r--arch/ppc/configs/mbx_defconfig (renamed from arch/ppc/mbx_defconfig)0
-rw-r--r--arch/ppc/configs/oak_defconfig293
-rw-r--r--arch/ppc/configs/pmac_defconfig (renamed from arch/ppc/pmac_defconfig)0
-rw-r--r--arch/ppc/configs/prep_defconfig (renamed from arch/ppc/prep_defconfig)0
-rw-r--r--arch/ppc/configs/walnut_defconfig293
-rw-r--r--arch/ppc/defconfig108
-rw-r--r--arch/ppc/kernel/Makefile72
-rw-r--r--arch/ppc/kernel/align.c52
-rw-r--r--arch/ppc/kernel/entry.S6
-rw-r--r--arch/ppc/kernel/gemini_prom.S1
-rw-r--r--arch/ppc/kernel/gemini_setup.c58
-rw-r--r--arch/ppc/kernel/head.S83
-rw-r--r--arch/ppc/kernel/head_4xx.S600
-rw-r--r--arch/ppc/kernel/misc.S49
-rw-r--r--arch/ppc/kernel/mk_defs.c10
-rw-r--r--arch/ppc/kernel/oak_setup.c84
-rw-r--r--arch/ppc/kernel/oak_setup.h32
-rw-r--r--arch/ppc/kernel/open_pic.c18
-rw-r--r--arch/ppc/kernel/open_pic.h1
-rw-r--r--arch/ppc/kernel/pci.c46
-rw-r--r--arch/ppc/kernel/pmac_nvram.c (renamed from arch/ppc/kernel/pmac_support.c)7
-rw-r--r--arch/ppc/kernel/pmac_pci.c25
-rw-r--r--arch/ppc/kernel/ppc8xx_pic.c2
-rw-r--r--arch/ppc/kernel/ppc8xx_pic.h2
-rw-r--r--arch/ppc/kernel/ppc_asm.h23
-rw-r--r--arch/ppc/kernel/ppc_asm.tmpl18
-rw-r--r--arch/ppc/kernel/ppc_htab.c19
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c16
-rw-r--r--arch/ppc/kernel/prep_setup.c16
-rw-r--r--arch/ppc/kernel/process.c10
-rw-r--r--arch/ppc/kernel/prom.c5
-rw-r--r--arch/ppc/kernel/qspan_pci.c1
-rw-r--r--arch/ppc/kernel/setup.c176
-rw-r--r--arch/ppc/kernel/signal.c1
-rw-r--r--arch/ppc/kernel/smp.c8
-rw-r--r--arch/ppc/kernel/traps.c17
-rw-r--r--arch/ppc/lib/checksum.S7
-rw-r--r--arch/ppc/mm/Makefile6
-rw-r--r--arch/ppc/mm/fault.c34
-rw-r--r--arch/ppc/mm/init.c337
-rw-r--r--arch/ppc/mm/mem_pieces.c224
-rw-r--r--arch/ppc/mm/mem_pieces.h61
-rw-r--r--arch/ppc/treeboot/Makefile62
-rw-r--r--arch/ppc/treeboot/crt0.S70
-rw-r--r--arch/ppc/treeboot/elf.pl33
-rw-r--r--arch/ppc/treeboot/irSect.c36
-rw-r--r--arch/ppc/treeboot/irSect.h32
-rw-r--r--arch/ppc/treeboot/ld.script68
-rw-r--r--arch/ppc/treeboot/main.c209
-rw-r--r--arch/ppc/treeboot/misc.S28
-rw-r--r--arch/ppc/treeboot/mkevimg437
-rw-r--r--arch/ppc/treeboot/mkirimg367
-rw-r--r--arch/ppc/xmon/ppc-opc.c3
-rw-r--r--arch/ppc/xmon/privinst.h9
-rw-r--r--arch/ppc/xmon/start.c4
-rw-r--r--arch/ppc/xmon/xmon.c29
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)
{