summaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
committer <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
commit19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch)
tree40b1cb534496a7f1ca0f5c314a523c69f1fee464 /arch/ppc/kernel
parent7206675c40394c78a90e74812bbdbf8cf3cca1be (diff)
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'arch/ppc/kernel')
-rw-r--r--arch/ppc/kernel/Makefile27
-rw-r--r--arch/ppc/kernel/head.S783
-rw-r--r--arch/ppc/kernel/include/elf/ChangeLog155
-rw-r--r--arch/ppc/kernel/include/elf/common.h232
-rw-r--r--arch/ppc/kernel/include/elf/dwarf.h314
-rw-r--r--arch/ppc/kernel/include/elf/external.h190
-rw-r--r--arch/ppc/kernel/include/elf/hppa.h90
-rw-r--r--arch/ppc/kernel/include/elf/internal.h173
-rw-r--r--arch/ppc/kernel/include/elf/mips.h267
-rw-r--r--arch/ppc/kernel/include/elf/ppc.h32
-rw-r--r--arch/ppc/kernel/irq.c383
-rw-r--r--arch/ppc/kernel/ksyms.c12
-rw-r--r--arch/ppc/kernel/ld.script-user75
-rw-r--r--arch/ppc/kernel/misc.S218
-rw-r--r--arch/ppc/kernel/mk_defs.c18
-rw-r--r--arch/ppc/kernel/pci.c38
-rw-r--r--arch/ppc/kernel/port_io.c6
-rw-r--r--arch/ppc/kernel/ppc_asm.tmpl2
-rw-r--r--arch/ppc/kernel/ppc_defs.h119
-rw-r--r--arch/ppc/kernel/process.c259
-rw-r--r--arch/ppc/kernel/ptrace.c124
-rw-r--r--arch/ppc/kernel/setup.c497
-rw-r--r--arch/ppc/kernel/signal.c126
-rw-r--r--arch/ppc/kernel/stubs.c63
-rw-r--r--arch/ppc/kernel/syscalls.c155
-rw-r--r--arch/ppc/kernel/time.c293
-rw-r--r--arch/ppc/kernel/traps.c77
-rw-r--r--arch/ppc/kernel/usercpy.c116
28 files changed, 1953 insertions, 2891 deletions
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 8a3a845f1..0bfb26c01 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -14,10 +14,8 @@
.c.o:
$(CC) $(CFLAGS) -c $<
.S.s:
-# $(CPP) $(CFLAGS) -D__ASSEMBLY__ -traditional $< -o $*.s
$(CPP) $(CFLAGS) -D__ASSEMBLY__ $< -o $*.s
.S.o:
-# $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
$(CPP) $(CFLAGS) -D__ASSEMBLY__ $< -o $*.s
$(AS) $(ASFLAGS) -o $*.o $*.s
rm $*.s
@@ -25,40 +23,25 @@
HOST_CC = gcc
OBJS = misc.o setup.o port_io.o irq.o pci.o traps.o stubs.o process.o \
- signal.o ksyms.o time.o syscalls.o \
- support.o ptrace.o # ramdisk_drvr.o
+ signal.o ksyms.o time.o syscalls.o usercpy.o\
+ support.o ptrace.o
-all: head.o kernel.o #no_ramdisk.o ramdisk.o
+all: head.o kernel.o
head.o: head.s
head.s: head.S $(TOPDIR)/include/linux/tasks.h ppc_defs.h
ppc_defs.h: mk_defs
-# simppc mk_defs -- $@
mk_defs $@
-#no_ramdisk.o: no_ramdisk.S
-
-#ramdisk.o: ramdisk.image mk_ramdisk
-# mk_ramdisk ramdisk.image $*.s
-# $(AS) -o $@ $*.s
-# rm $*.s
-
-#mk_ramdisk: mk_ramdisk.c
-# ${HOST_CC} -o mk_ramdisk mk_ramdisk.c
-
-mk_defs: mk_defs.c $(TOPDIR)/include/asm/mmu.h $(TOPDIR)/include/asm/processor.h $(TOPDIR)/include/asm/pgtable.h $(TOPDIR)/include/asm/ptrace.h
-# cc.ppc ${CFLAGS} -o mk_defs -T ld.script-user -Ttext 0x1000 mk_defs.c
- gcc.ppc ${CFLAGS} -o mk_defs mk_defs.c
+mk_defs: mk_defs.c
+ $(HOSTCC) $(CFLAGSINC) -Wl,-static ${CFLAGS} -o mk_defs mk_defs.c
kernel.o: $(OBJS)
$(LD) -r -o kernel.o $(OBJS)
sync
-#mkboot: mkboot.c
-# ${HOST_CC} -o $@ -Iinclude mkboot.c
-
dep:
$(CPP) -M *.c > .depend
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index bd6819c34..648c7bccf 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -1,16 +1,15 @@
#include "ppc_asm.tmpl"
#include "ppc_defs.h"
#include <linux/errno.h>
-#define NEWMM
+#include <linux/sys.h>
+#include <asm/ppc_machine.h>
+
+#define NEWMM 1
#define SYNC() \
isync; \
sync
-/* #define TLB_STATS */
-
-/* Keep track of low-level exceptions - rather crude, but informative */
#define STATS
-
/*
* Increment a [64 bit] statistic counter
* Uses R2, R3
@@ -40,179 +39,9 @@
mtspr XER,r0; \
stw r3,0(r2)
-/* These macros can be used to generate very raw traces of low-level */
-/* operations (where printf, etc. can't help). All they provide is */
-/* some after-the-fact documentation of what took place. Since [in */
-/* most instances] they have no registers to work with, they use the */
-/* hardware "special" registers SPRx for storage. Because of this, */
-/* defining more than one of them simultaneously will yield incorrect */
-/* results and a non-functional system. Note: the trick here is to */
-/* gather some data without disturbing anything - Heisenberg are you watching? */
-
-/* CAUTION! Don't turn on more than one of these at once! */
-/* #define DO_TRAP_TRACE */
-/* #define DO_TLB_TRACE */
-/* #define DO_RFI_TRACE */
-
-#ifdef DO_RFI_TRACE
-#define DO_RFI_TRACE_UNMAPPED(mark) \
- mtspr SPR0,r1; \
- mtspr SPR1,r2; \
- mtspr SPR2,r3; \
- mfcr r3; \
- mtspr SPR3,r3; \
- lis r1,_RFI_ptr@h; \
- ori r1,r1,_RFI_ptr@l; \
- lis r3,0xF000; \
- andc r1,r1,r3; \
- lwz r1,0(r1); \
- andc r1,r1,r3; \
- subi r1,r1,4; \
- lis r2,(mark>>16); \
- ori r2,r2,(mark&0xFFFF); \
- stwu r2,4(r1); \
- mfspr r2,SRR0; \
- stwu r2,4(r1); \
- mfspr r2,SRR1; \
- stwu r2,4(r1); \
- addi r1,r1,4+4; \
- lis r2,_RFI_ptr@h; \
- ori r2,r2,_RFI_ptr@l; \
- andc r2,r2,r3; \
- stw r1,0(r2); \
- mfspr r3,SPR3; \
- mtcrf 0xFF,r3; \
- mfspr r1,SPR0; \
- mfspr r2,SPR1; \
- mfspr r3,SPR2
-#define DO_RFI_TRACE_MAPPED(mark) \
- mtspr SPR0,r1; \
- mtspr SPR1,r2; \
- mtspr SPR2,r3; \
- mfcr r3; \
- mtspr SPR3,r3; \
- lis r1,_RFI_ptr@h; \
- ori r1,r1,_RFI_ptr@l; \
- lwz r1,0(r1); \
- lis r3,0x9000; \
- or r1,r1,r3; \
- subi r1,r1,4; \
- lis r2,(mark>>16); \
- ori r2,r2,(mark&0xFFFF); \
- stwu r2,4(r1); \
- mfspr r2,SRR0; \
- stwu r2,4(r1); \
- mfspr r2,SRR1; \
- stwu r2,4(r1); \
- addi r1,r1,4+4; \
- lis r2,_RFI_ptr@h; \
- ori r2,r2,_RFI_ptr@l; \
- stw r1,0(r2); \
- mfspr r3,SPR3; \
- mtcrf 0xFF,r3; \
- mfspr r1,SPR0; \
- mfspr r2,SPR1; \
- mfspr r3,SPR2
-#else
#define DO_RFI_TRACE_UNMAPPED(mark)
#define DO_RFI_TRACE_MAPPED(mark)
-#endif
-#ifdef DO_TRAP_TRACE
-#define DEFAULT_TRAP(offset) \
- mtspr SPR0,r1; \
- mtspr SPR1,r2; \
- mtspr SPR2,r3; \
- lis r1,_TRAP_ptr@h; \
- ori r1,r1,_TRAP_ptr@l; \
- lis r3,0xF000; \
- andc r1,r1,r3; \
- lwz r1,0(r1); \
- andc r1,r1,r3; \
- subi r1,r1,4; \
- lis r2,0xCACA; \
- ori r2,r2,offset; \
- stwu r2,4(r1); \
- mfspr r2,SRR0; \
- stwu r2,4(r1); \
- mfspr r2,SRR1; \
- stwu r2,4(r1); \
- mfspr r2,SPR0; \
- stwu r2,4(r1); \
- addi r1,r1,4; \
- lis r2,_TRAP_ptr@h; \
- ori r2,r2,_TRAP_ptr@l; \
- andc r2,r2,r3; \
- stw r1,0(r2); \
- mfspr r1,SPR0; \
- mfspr r2,SPR1; \
- mfspr r3,SPR2; \
- li r13,0; \
- ori r13,r13,HID0_ICE; \
- mtspr HID0,r13; \
- lis r13,0xFFF00000>>16; \
- ori r13,r13,offset; \
- mtlr r13; \
- b hang
-#define TRACE_TRAP(offset) \
- mtspr SPR0,r1; \
- mtspr SPR1,r2; \
- mtspr SPR2,r3; \
- mfcr r3; \
- mtspr SPR3,r3; \
- lis r1,_TRAP_ptr@h; \
- ori r1,r1,_TRAP_ptr@l; \
- lis r3,0xF000; \
- andc r1,r1,r3; \
- lwz r1,0(r1); \
- andc r1,r1,r3; \
- subi r1,r1,4; \
- lis r2,0xCABB; \
- ori r2,r2,offset; \
- stwu r2,4(r1); \
- dcbst 0,r1; \
- mfspr r2,SRR0; \
- stwu r2,4(r1); \
- dcbst 0,r1; \
- mfspr r2,SRR1; \
- stwu r2,4(r1); \
- dcbst 0,r1; \
- li r2,offset; \
- cmpi 0,r2,0x0C00; \
- beq 01f; \
- cmpi 0,r2,0x0300; \
- beq 00f; \
- cmpi 0,r2,0x0400; \
- beq 00f; \
- mfspr r2,SPR0; \
- b 02f; \
-00: mfspr r2,DAR; \
- b 02f; \
-01: mr r2,r0; \
-02: stwu r2,4(r1); \
- dcbst 0,r1; \
- addi r1,r1,4; \
- mflr r2; \
- stw r2,0(r1); \
- bl check_trace; \
- lwz r2,0(r1); \
- mtlr r2; \
-02: lis r2,_TRAP_ptr@h; \
- ori r2,r2,_TRAP_ptr@l; \
- oris r1,r1,0x9000; \
- cmp 0,r1,r2; \
- bne 00f; \
- lis r1,_TRAP_TRACE@h; \
- ori r1,r1,_TRAP_TRACE@l; \
-00: lis r3,0xF000; \
- andc r2,r2,r3; \
- stw r1,0(r2); \
- mfspr r1,SPR0; \
- mfspr r2,SPR1; \
- mfspr r3,SPR3; \
- mtcrf 0xFF,r3; \
- mfspr r3,SPR2
-#else
#define DEFAULT_TRAP(offset) \
li r13,0; \
ori r13,r13,HID0_ICE; \
@@ -222,7 +51,6 @@
mtlr r13; \
blr
#define TRACE_TRAP(offset)
-#endif
#define DATA_CACHE_OFF() \
mfspr r2,HID0; \
@@ -246,27 +74,147 @@
bdnz 0b
/* Validate kernel stack - check for overflow */
-#define CHECK_STACK()
+/* all regs are considered scratch since the C function will stomp them */
+#define CHECK_STACK() \
+ /*lis r3,current_set@ha; \
+ lwz r3,current_set@l(r3); \
+ bl _EXTERN(check_stack)*/
+#if 0
#define _CHECK_STACK() \
mtspr SPR0,r3; \
+ mtspr SPR1,r4; /* use r3,4 as scratch */ \
lis r2,current_set@ha; \
lwz r2,current_set@l(r2); \
lwz r2,KERNEL_STACK_PAGE(r2); \
- lis r3,sys_stack@h; \
+ /* if kernel stack is sys_stack skip check */ \
+ /*lis r3,sys_stack@h; \
ori r3,r3,sys_stack@l; \
- cmpl 0,r1,r3; \
- ble 02f; \
- li r3,0x0FFF; \
+ cmpl 0,r1,r3;*/ \
+ /* check for STACK_MAGIC on kernel stack page */ \
+ lis r3, 0xdead; /* STACK_MAGIC */ \
+ ori r3,r3,0xbeef; \
+ lwz r4,0(r2); /* get *kernel_stack_page */ \
+ cmpl 0,r4,r3; \
+ bne 01f; \
+ /* check that ksp is > kernel page */ \
+ /*li r3,0x0FFF; \
andc r2,r2,r3; \
andc r3,r1,r3; \
cmp 0,r3,r2; \
- beq 02f; \
- mr r3,r1; \
+ beq 02f;*/ \
+ /* check that ksp and kernel stack page are on same page */ \
+ cmp 0,r1,r2; \
+ bge 02f; \
+01: mr r6,r1; /* setup info for call to bad_stack() */ \
+ mr r5,r2; \
bl _EXTERN(bad_stack); \
-02: mfspr r3,SPR0
+02: mfspr r4,SPR1; \
+ mfspr r3,SPR0
+#endif
+
+/* save fp regs if fp is used */
+/* assumes that r1 contains ptr to regs of task and r2 is scratch
+ -- Cort */
+#define SAVE_FP_REGS() \
+ /* check if fp has been used by checking msr_fp bit */ \
+ lwz r2,_MSR(r1); \
+ andi. r2,r2,MSR_FP; \
+ bne 00f; \
+ /* floating point has been used -- save fp regs */ \
+ lis r2,current_set@h; \
+ ori r2,r2,current_set@l; \
+ addi r2,r2,TSS; \
+ /*mr r2,r1;*/ \
+ stfd fr0,TSS_FPR0(r2); \
+ stfd fr1,TSS_FPR1(r2); \
+ stfd fr2,TSS_FPR2(r2); \
+ stfd fr3,TSS_FPR3(r2); \
+ stfd fr4,TSS_FPR4(r2); \
+ stfd fr5,TSS_FPR5(r2); \
+ stfd fr6,TSS_FPR6(r2); \
+ stfd fr7,TSS_FPR7(r2); \
+ stfd fr8,TSS_FPR8(r2); \
+ stfd fr9,TSS_FPR9(r2); \
+ stfd fr10,TSS_FPR10(r2); \
+ stfd fr11,TSS_FPR11(r2); \
+ stfd fr12,TSS_FPR12(r2); \
+ stfd fr13,TSS_FPR13(r2); \
+ stfd fr14,TSS_FPR14(r2); \
+ stfd fr15,TSS_FPR15(r2); \
+ stfd fr16,TSS_FPR16(r2); \
+ stfd fr17,TSS_FPR17(r2); \
+ stfd fr18,TSS_FPR18(r2); \
+ stfd fr19,TSS_FPR19(r2); \
+ stfd fr20,TSS_FPR20(r2); \
+ stfd fr21,TSS_FPR21(r2); \
+ stfd fr22,TSS_FPR22(r2); \
+ stfd fr23,TSS_FPR23(r2); \
+ stfd fr24,TSS_FPR24(r2); \
+ stfd fr25,TSS_FPR25(r2); \
+ stfd fr26,TSS_FPR26(r2); \
+ stfd fr27,TSS_FPR27(r2); \
+ stfd fr28,TSS_FPR28(r2); \
+ stfd fr29,TSS_FPR29(r2); \
+ stfd fr30,TSS_FPR30(r2); \
+ stfd fr31,TSS_FPR31(r2); \
+00:
+
-/* Save all registers on kernel stack during an exception */
-#define SAVE_REGS(mark) \
+/* restores fp regs if fp has been used -- always restores fpscr */
+/* assumes that r1 contains ptr to regs, r2 is scratch and srr1 holds
+ what will become the msr when this process executes -- Cort*/
+#define RESTORE_FP_REGS(mark) \
+ /* check if restoring from _switch() */ \
+ li r2, mark; \
+ cmpi 0,r2,0x0f0f; \
+ bne 00f; /* only need to save if called from _switch() with 0x0f0f */\
+ /* check if fp has been used by checking msr_fp bit */ \
+ /* srr1 contains msr */ \
+ mfspr r2,SRR1; \
+ andi. r2,r2,MSR_FP; \
+ bne 00f; \
+ /* floating point has been used -- restore fp regs */ \
+ /* Hey, Rocky! Watch me pull fp regs from my stack! */ \
+ lis r2,current_set@h; \
+ ori r2,r2,current_set@l; \
+ addi r2,r2,TSS; \
+ /*mr r2,r1;*/\
+ lfd fr0,TSS_FPR0(r2); \
+ lfd fr1,TSS_FPR1(r2); \
+ lfd fr2,TSS_FPR2(r2); \
+ lfd fr3,TSS_FPR3(r2); \
+ lfd fr4,TSS_FPR4(r2); \
+ lfd fr5,TSS_FPR5(r2); \
+ lfd fr6,TSS_FPR6(r2); \
+ lfd fr7,TSS_FPR7(r2); \
+ lfd fr8,TSS_FPR8(r2); \
+ lfd fr9,TSS_FPR9(r2); \
+ lfd fr10,TSS_FPR10(r2); \
+ lfd fr11,TSS_FPR11(r2); \
+ lfd fr12,TSS_FPR12(r2); \
+ lfd fr13,TSS_FPR13(r2); \
+ lfd fr14,TSS_FPR14(r2); \
+ lfd fr15,TSS_FPR15(r2); \
+ lfd fr16,TSS_FPR16(r2); \
+ lfd fr17,TSS_FPR17(r2); \
+ lfd fr18,TSS_FPR18(r2); \
+ lfd fr19,TSS_FPR19(r2); \
+ lfd fr20,TSS_FPR20(r2); \
+ lfd fr21,TSS_FPR21(r2); \
+ lfd fr22,TSS_FPR22(r2); \
+ lfd fr23,TSS_FPR23(r2); \
+ lfd fr24,TSS_FPR24(r2); \
+ lfd fr25,TSS_FPR25(r2); \
+ lfd fr26,TSS_FPR26(r2); \
+ lfd fr27,TSS_FPR27(r2); \
+ lfd fr28,TSS_FPR28(r2); \
+ lfd fr29,TSS_FPR29(r2); \
+ lfd fr30,TSS_FPR30(r2); \
+ lfd fr31,TSS_FPR31(r2); \
+00:
+
+/* save all registers */
+#define SAVE_ALL_REGS(mark) \
subi r1,r1,INT_FRAME_SIZE; /* Make room for frame */ \
stmw r3,GPR3(r1); /* Save R3..R31 */ \
stw r3,ORIG_GPR3(r1); \
@@ -287,10 +235,6 @@
stw r2,_CCR(r1); \
mfspr r2,XER; \
stw r2,_XER(r1); \
- stfd fr0,FPR0(r1); \
- stfd fr1,FPR1(r1); \
- stfd fr2,FPR2(r1); \
- stfd fr3,FPR3(r1); \
mffs fr0; \
stfd fr0,FPCSR(r1); \
lis r2,_break_lwarx@h; \
@@ -304,9 +248,11 @@
li r2,0; \
stw r2,RESULT(r1)
+
+/* save registers clobbered by a page fault handler */
#define SAVE_PAGE_FAULT_REGS(offset) \
mfspr r2,DAR; \
- stw r2,_DAR(r1); \
+ stw r2,_DAR(r1); \
mfspr r2,DSISR; \
stw r2,_DSISR(r1); \
mfspr r2,PVR; /* Check for 603/603e */ \
@@ -328,7 +274,7 @@
mfspr r2,DCMP; \
stw r2,_DCMP(r1); \
24:
-
+
#define SAVE_INT_REGS(mark) \
mtspr SPR0,r1; /* Save current stack pointer */ \
mtspr SPR1,r2; /* Scratch */ \
@@ -375,7 +321,7 @@
mtspr SRR1,r2; \
SYNC(); \
rfi; \
-20: SAVE_REGS(mark); \
+20: SAVE_ALL_REGS(mark); \
CHECK_STACK()
#define RETURN_FROM_INT(mark) \
@@ -412,7 +358,10 @@
bl _EXTERN(flush_instruction_cache); */ \
05: lis r3,current_set@ha; /* need to save kernel stack pointer */ \
lwz r3,current_set@l(r3); \
- addi r4,r1,INT_FRAME_SIZE; /* size of frame */ \
+ /*addi r4,r1,INT_FRAME_SIZE*/; /* size of frame */ \
+ lwz r4, KERNEL_STACK_PAGE(r3); \
+ addi r4,r4,KERNEL_STACK_SIZE; /* reset stack pointer to top of stack page */ \
+ /* stack isn't 0'd so show_task():sched.c shows highwater of stack */ \
stw r4,TSS+KSP(r3); \
lwz r4,STATE(r3); /* If state != 0, can't run */ \
cmpi 0,r4,0; \
@@ -442,20 +391,18 @@
mtlr r2; \
lwz r2,_XER(r1); \
mtspr XER,r2; \
- lwz r2,_CCR(r1); \
- mtcrf 0xFF,r2; \
lfd fr0,FPCSR(r1); \
mtfsf 0xFF,fr0; \
- lfd fr0,FPR0(r1); \
- lfd fr1,FPR1(r1); \
- lfd fr2,FPR2(r1); \
- lfd fr3,FPR3(r1); \
+ RESTORE_FP_REGS(mark) ; \
+ lwz r2,_CCR(r1); \
+ mtcrf 0xFF,r2; \
lwz r0,GPR0(r1); \
lwz r2,GPR2(r1); \
lwz r1,GPR1(r1); \
SYNC(); \
rfi
+
_TEXT()
/*
* This code may be executed by a bootstrap process. If so, the
@@ -578,35 +525,6 @@ _ORG(0x1000)
/* Note: It is *unsafe* to use the TRACE TRAP macro here since there */
/* could be a 'trace' in progress when the TLB miss occurs. */
/* TRACE_TRAP(0x1000) */
-#ifdef TLB_STATS
- lis r2,DataLoadTLB_trace_ptr@h
- ori r2,r2,DataLoadTLB_trace_ptr@l
- lis r3,0xF000
- andc r2,r2,r3
- lwz r1,0(r2)
- andc r1,r1,r3
- li r0,0x1000
- stw r0,0(r1)
- mftbu r0
- stw r0,4(r1)
- mftb r0
- stw r0,8(r1)
- mfspr r0,IMISS
- mfspr r3,SRR1
- extrwi r3,r3,1,14
- or r0,r0,r3
- stw r0,12(r1)
- addi r1,r1,16
- mfcr r0
- cmpl 0,r1,r2
- blt 00f
- lis r1,DataLoadTLB_trace_buf@h
- ori r1,r1,DataLoadTLB_trace_buf@l
- lis r3,0xF000
- andc r1,r1,r3
-00: mtcrf 0xFF,r0
- stw r1,0(r2)
-#endif
b InstructionTLBMiss
/*
@@ -614,41 +532,6 @@ _ORG(0x1000)
*/
_ORG(0x1100)
/* TRACE_TRAP(0x1100) */
-#ifdef TLB_STATS
- lis r2,DataLoadTLB_trace_ptr@h
- ori r2,r2,DataLoadTLB_trace_ptr@l
- lis r3,0xF000
- andc r2,r2,r3
- lwz r1,0(r2)
- andc r1,r1,r3
- li r0,0x1100
- stw r0,0(r1)
- mftbu r0
- stw r0,4(r1)
- mftb r0
- stw r0,8(r1)
- mfspr r0,DMISS
- mfspr r3,SRR1
- extrwi r3,r3,1,14
- or r0,r0,r3
- stw r0,12(r1)
- addi r1,r1,16
- mfcr r0
- cmpl 0,r1,r2
- blt 00f
- lis r1,DataLoadTLB_trace_buf@h
- ori r1,r1,DataLoadTLB_trace_buf@l
- lis r3,0xF000
- andc r1,r1,r3
-00: mtcrf 0xFF,r0
- stw r1,0(r2)
- .data
-DataLoadTLB_trace_buf:
- .space 64*1024*4
-DataLoadTLB_trace_ptr:
- .long DataLoadTLB_trace_buf
- .text
-#endif
b DataLoadTLBMiss
/*
@@ -656,35 +539,6 @@ DataLoadTLB_trace_ptr:
*/
_ORG(0x1200)
/* TRACE_TRAP(0x1200) */
-#ifdef TLB_STATS
- lis r2,DataLoadTLB_trace_ptr@h
- ori r2,r2,DataLoadTLB_trace_ptr@l
- lis r3,0xF000
- andc r2,r2,r3
- lwz r1,0(r2)
- andc r1,r1,r3
- li r0,0x1200
- stw r0,0(r1)
- mftbu r0
- stw r0,4(r1)
- mftb r0
- stw r0,8(r1)
- mfspr r0,DMISS
- mfspr r3,SRR1
- extrwi r3,r3,1,14
- or r0,r0,r3
- stw r0,12(r1)
- addi r1,r1,16
- mfcr r0
- cmpl 0,r1,r2
- blt 00f
- lis r1,DataLoadTLB_trace_buf@h
- ori r1,r1,DataLoadTLB_trace_buf@l
- lis r3,0xF000
- andc r1,r1,r3
-00: mtcrf 0xFF,r0
- stw r1,0(r2)
-#endif
b DataStoreTLBMiss
_ORG(0x1300)
@@ -718,16 +572,40 @@ _ORG(0x4000)
#endif
+/* changed to use r3 as residual pointer (as firmware does), that's all -- Cort */
/*
* Hardware reset [actually from bootstrap]
* Initialize memory management & call secondary init
* Registers initialized by bootstrap:
* R11: Start of command line string
* R12: End of command line string
+ * R28: Residual data
+ * R29: Total Memory Size
* R30: 'BeBx' if this is a BeBox
*/
Reset:
lis r7,0xF000 /* To mask upper 4 bits */
+/* set pointer to residual data */
+ lis r1,resptr@h
+ ori r1,r1,resptr@l
+ andc r1,r1,r7
+/* changed to use r3 as residual pointer (as firmware does) -- Cort */
+/* this is only a ptr, the actual data is copied in mmu_init */
+ stw r3,0(r1)
+
+/* Copy argument string */
+ li r0,0 /* Null terminate string */
+ stb r0,0(r12)
+ lis r1,cmd_line@h
+ ori r1,r1,cmd_line@l
+ andc r1,r1,r7 /* No MMU yet - need unmapped address */
+ subi r1,r1,1
+ subi r11,r11,1
+00: lbzu r0,1(r11)
+ cmpi 0,r0,0
+ stbu r0,1(r1)
+ bne 00b
+
#define IS_BE_BOX 0x42654278 /* 'BeBx' */
lis r1,isBeBox@h
ori r1,r1,isBeBox@l
@@ -751,21 +629,19 @@ Reset:
andc r5,r5,r7 /* Tell CPU #1 where to go */
00: stw r2,0(r1)
stw r30,4(r1)
-/* Copy argument string */
- li r0,0 /* Null terminate string */
- stb r0,0(r12)
- lis r1,cmd_line@h
- ori r1,r1,cmd_line@l
- andc r1,r1,r7 /* No MMU yet - need unmapped address */
- subi r1,r1,1
- subi r11,r11,1
-00: lbzu r0,1(r11)
- cmpi 0,r0,0
- stbu r0,1(r1)
- bne 00b
+
+
+#if 0
lis r1,sys_stack@h
ori r1,r1,sys_stack@l
+#else
+ lis r1,init_kernel_stack@h
+ ori r1,r1,init_kernel_stack@l
+#endif
+ addi r1,r1,0x1000 /* top of stack */
+#if 0
li r2,0x0FFF /* Mask stack address down to page boundary */
+#endif
andc r1,r1,r2
subi r1,r1,INT_FRAME_SIZE /* Padding for first frame */
li r2,0 /* TOC pointer for nanokernel */
@@ -782,6 +658,13 @@ Reset:
00: stwu r0,4(r3)
cmp 0,r3,r4
blt 00b
+#if 0
+/* Save total memory size (passed from bootstrap) */
+ lis r3,_TotalMemory@h
+ ori r3,r3,_TotalMemory@l
+ andc r3,r3,r7 /* make unmapped address */
+ stw r29,0(r3)
+#endif
/* Initialize BAT registers */
lis r3,BAT0@h
ori r3,r3,BAT0@l
@@ -816,7 +699,7 @@ Reset:
lwz r0,4(r3)
mtspr IBAT2L,r0
mtspr DBAT2L,r0
-#if 0
+#if 1
lis r3,BAT3@h
ori r3,r3,BAT3@l
andc r3,r3,r7 /* make unmapped address */
@@ -837,7 +720,7 @@ Reset:
DO_RFI_TRACE_UNMAPPED(0xDEAD0000)
SYNC
rfi /* enables MMU */
-10: bl _EXTERN(MMU_init) /* initialize MMU environment */
+10: bl _EXTERN(MMU_init) /* initialize MMU environment */
DO_RFI_TRACE_MAPPED(0xDEAD0100)
/* Withdraw BAT2->RAM mapping */
lis r7,0xF000 /* To mask upper 4 bits */
@@ -1017,14 +900,17 @@ MachineCheck:
* Data Access exception
*/
DataAccess:
-/* TRACE_TRAP(0x0300) */
SAVE_INT_REGS(0x0300)
- SAVE_PAGE_FAULT_REGS(0x0300)
- BUMP(__Data_Page_Faults)
- mr r3,r1 /* Set pointer to saved regs */
+#if 1
+ mfspr r3, DAR
+ mfspr r4, DSISR
+ li r5, 0 /* not a text fault */
+ mr r6, r1
+ bl _EXTERN(new_page_fault)
+#else
+ SAVE_PAGE_FAULT_REGS(0x0D00)
+ mr r3,r1
bl _EXTERN(DataAccessException)
-#if 0
- bl _EXTERN(flush_instruction_cache)
#endif
RETURN_FROM_INT(0x0300)
@@ -1032,14 +918,17 @@ DataAccess:
* Instruction Access Exception
*/
InstructionAccess:
-/* TRACE_TRAP(0x0400) */
SAVE_INT_REGS(0x0400)
- SAVE_PAGE_FAULT_REGS(0x0400)
- BUMP(__Instruction_Page_Faults)
- mr r3,r1 /* Set pointer to saved regs */
+#if 1
+ mfspr r3, SPR2 /* srr0 was saved here */
+ mfspr r4, SPR3 /* srr1 was saved here */
+ li r5, 1 /* a text fault */
+ mr r6, r1
+ bl _EXTERN(new_page_fault)
+#else
+ SAVE_PAGE_FAULT_REGS(0x0D00)
+ mr r3,r1
bl _EXTERN(InstructionAccessException)
-#if 0
- bl _EXTERN(flush_instruction_cache)
#endif
RETURN_FROM_INT(0x0400)
@@ -1090,17 +979,18 @@ SingleStep:
* Floating point [not available, etc]
*/
FloatingPointCheck:
- TRACE_TRAP(0x0800)
SAVE_INT_REGS(0x0800)
mr r3,r1 /* Set pointer to saved regs */
bl _EXTERN(FloatingPointCheckException)
- RETURN_FROM_INT(0x0200)
+ cmpi 0,r3,MSR_FP /* check if fp was turned on by handler */
+ bne 00f
+ RETURN_FROM_INT(0x0f0f) /* 0xf0f tells to restore fp regs */
+00: RETURN_FROM_INT(0x0200)
/*
* System Call exception
*/
SystemCall:
-/* TRACE_TRAP(0x0C00) */
SAVE_INT_REGS(0x0C00)
lwz r2,_CCR(r1) /* Clear SO bit in CR */
lis r9,0x1000
@@ -1118,13 +1008,21 @@ SystemCall:
lwz r2,TASK_FLAGS(r2)
andi. r2,r2,PF_TRACESYS
bne 50f
+
lis r2,sys_call_table@h
ori r2,r2,sys_call_table@l
slwi r0,r0,2
lwzx r2,r2,r0 /* Fetch system call handler [ptr] */
+#if 1
+ cmpi 0,r2,0 /* make sure syscall handler not 0 */
+ beq 99f
+ cmpi 0,r0,NR_syscalls<<2 /* make sure syscallnum in bounds */
+ bgt 99f
+#endif
mtlr r2
mr r9,r1
blrl /* Call handler */
+
20: stw r3,RESULT(r1) /* Save result */
cmpi 0,r3,0
bge 30f
@@ -1136,10 +1034,6 @@ SystemCall:
oris r2,r2,0x1000
stw r2,_CCR(r1)
30: stw r3,GPR3(r1) /* Update return value */
-#if 0
- mr r3,r1
- bl _EXTERN(trace_syscall)
-#endif
b 99f
/* Traced system call support */
50: bl _EXTERN(syscall_trace)
@@ -1171,14 +1065,6 @@ SystemCall:
60: stw r3,GPR3(r1) /* Update return value */
bl _EXTERN(syscall_trace)
99:
-#if 0 /* This isn't needed here - already in RETURN_FROM_INT */
- lis r2,kernel_pages_are_copyback@ha
- lwz r2,kernel_pages_are_copyback@l(r2)
- cmpi 0,r2,0
- beq 00f
- bl _EXTERN(flush_instruction_cache) /* Ensure cache coherency */
-00:
-#endif
RETURN_FROM_INT(0x0C00)
/*
@@ -1186,36 +1072,6 @@ SystemCall:
*/
InstructionTLBMiss:
BUMP_UNMAPPED(__Instruction_TLB_Misses)
-#ifdef DO_TLB_TRACE
- lis r1,_TLB_ptr@h
- ori r1,r1,_TLB_ptr@l
- lis r2,0xF000
- andc r1,r1,r2
- lwz r1,0(r1)
- andc r1,r1,r2
- subi r1,r1,4
- lis r2,0xBEBE
- ori r2,r2,0x0100
- stwu r2,4(r1)
- mfspr r2,SRR0
- stwu r2,4(r1)
- mfspr r2,SRR1
- stwu r2,4(r1)
- mfspr r2,HASH1
- stwu r2,4(r1)
- mfspr r2,HASH2
- stwu r2,4(r1)
- mfspr r2,ICMP
- stwu r2,4(r1)
- mfspr r2,IMISS
- stwu r2,4(r1)
- addi r1,r1,4+(1*4)
- lis r3,_TLB_ptr@h
- ori r3,r3,_TLB_ptr@l
- lis r2,0xF000
- andc r3,r3,r2
- stw r1,0(r3)
-#endif
mfctr r0 /* Need to save this - CTR can't be touched! */
mfspr r2,HASH1 /* Get PTE pointer */
mfspr r3,ICMP /* Partial item compare value */
@@ -1256,37 +1112,6 @@ InstructionTLBMiss:
* Handle TLB miss for DATA Load operation
*/
DataLoadTLBMiss:
- BUMP_UNMAPPED(__DataLoad_TLB_Misses)
-#ifdef DO_TLB_TRACE
- lis r1,_TLB_ptr@h
- ori r1,r1,_TLB_ptr@l
- lis r2,0xF000
- andc r1,r1,r2
- lwz r1,0(r1)
- andc r1,r1,r2
- subi r1,r1,4
- lis r2,0xBEBE
- ori r2,r2,0x0200
- stwu r2,4(r1)
- mfspr r2,SRR0
- stwu r2,4(r1)
- mfspr r2,SRR1
- stwu r2,4(r1)
- mfspr r2,HASH1
- stwu r2,4(r1)
- mfspr r2,HASH2
- stwu r2,4(r1)
- mfspr r2,DCMP
- stwu r2,4(r1)
- mfspr r2,DMISS
- stwu r2,4(r1)
- addi r1,r1,4+(1*4)
- lis r3,_TLB_ptr@h
- ori r3,r3,_TLB_ptr@l
- lis r2,0xF000
- andc r3,r3,r2
- stw r1,0(r3)
-#endif
mfctr r0 /* Need to save this - CTR can't be touched! */
mfspr r2,HASH1 /* Get PTE pointer */
mfspr r3,DCMP /* Partial item compare value */
@@ -1325,36 +1150,6 @@ DataLoadTLBMiss:
*/
DataStoreTLBMiss:
BUMP_UNMAPPED(__DataStore_TLB_Misses)
-#ifdef DO_TLB_TRACE
- lis r1,_TLB_ptr@h
- ori r1,r1,_TLB_ptr@l
- lis r2,0xF000
- andc r1,r1,r2
- lwz r1,0(r1)
- andc r1,r1,r2
- subi r1,r1,4
- lis r2,0xBEBE
- ori r2,r2,0x0300
- stwu r2,4(r1)
- mfspr r2,SRR0
- stwu r2,4(r1)
- mfspr r2,SRR1
- stwu r2,4(r1)
- mfspr r2,HASH1
- stwu r2,4(r1)
- mfspr r2,HASH2
- stwu r2,4(r1)
- mfspr r2,DCMP
- stwu r2,4(r1)
- mfspr r2,DMISS
- stwu r2,4(r1)
- addi r1,r1,4+(1*4)
- lis r3,_TLB_ptr@h
- ori r3,r3,_TLB_ptr@l
- lis r2,0xF000
- andc r3,r3,r2
- stw r1,0(r3)
-#endif
mfctr r0 /* Need to save this - CTR can't be touched! */
mfspr r2,HASH1 /* Get PTE pointer */
mfspr r3,DCMP /* Partial item compare value */
@@ -1531,7 +1326,7 @@ _GLOBAL(flush_page)
addi r3,r3,CACHE_LINE_SIZE
bdnz 00b
blr
-
+
/*
* This routine switches between two different tasks. The process
* state of one is saved on its kernel stack. Then the state
@@ -1543,24 +1338,25 @@ _GLOBAL(flush_page)
* of this code; either by coming in via the entry (_switch)
* or via "fork" which must set up an environment equivalent
* to the "_switch" path. If you change this (or in particular, the
- * SAVE_REGS macro), you'll have to change the fork code also.
+ * SAVE_ALL_REGS macro), you'll have to change the fork code also.
*
* The code which creates the new task context is in 'copy_thread'
* in arch/ppc/kernel/process.c
*/
_GLOBAL(_switch)
- mtspr SPR0,r1 /* SAVE_REGS prologue */
+ mtspr SPR0,r1 /* SAVE_ALL_REGS prologue */
mtspr SPR1,r2
mflr r2 /* Return to switch caller */
mtspr SPR2,r2
mfmsr r2
mtspr SPR3,r2
- SAVE_REGS(0x0FF0)
+ SAVE_ALL_REGS(0x0FF0)
+ SAVE_FP_REGS()
+ CHECK_STACK()
SYNC()
stw r1,KSP(r3) /* Set old stack pointer */
BUMP(__Context_Switches)
lwz r1,KSP(r4) /* Load new stack pointer */
- CHECK_STACK()
lwz r0,MMU_SEG0(r4)
mtsr SR0,r0
lwz r0,MMU_SEG1(r4)
@@ -1577,6 +1373,8 @@ _GLOBAL(_switch)
mtsr SR6,r0
lwz r0,MMU_SEG7(r4)
mtsr SR7,r0
+#if 0
+ /* segs 8-15 are shared by everyone -- don't need to be changed */
lwz r0,MMU_SEG8(r4)
mtsr SR8,r0
lwz r0,MMU_SEG9(r4)
@@ -1593,34 +1391,22 @@ _GLOBAL(_switch)
mtsr SR14,r0
lwz r0,MMU_SEG15(r4)
mtsr SR15,r0
+#endif
+ /* no need to invalidate tlb since each process has a distinct
+ set of vsid's. -- Cort */
+#if 0
tlbia /* Invalidate entire TLB */
BUMP(__TLBIAs)
- bl _EXTERN(flush_instruction_cache)
-#ifdef TLB_STATS
-/* TEMP */
- lis r2,DataLoadTLB_trace_ptr@h
- ori r2,r2,DataLoadTLB_trace_ptr@l
- lis r3,0x9000
- lwz r4,0(r2)
- or r4,r4,r3
- li r0,0
- stw r0,0(r4)
- stw r0,4(r4)
- stw r0,8(r4)
- stw r0,12(r4)
- addi r4,r4,4
- cmpl 0,r4,r2
- blt 00f
- lis r4,DataLoadTLB_trace_buf@h
- ori r4,r4,DataLoadTLB_trace_buf@l
-00: stw r4,0(r2)
-/* TEMP */
-#endif
-#if 0
- lwz r2,_NIP(r1) /* Force TLB/MMU hit */
- lwz r2,0(r2)
#endif
- RETURN_FROM_INT(0xF000)
+ /* p5.2 603 users manual - with addr transl. enabled,
+ the memory access is performed under the control of
+ the page table entry. I interpret this to mean that
+ it is tagged with the vsid -- so no need to flush here
+ since each process has a distinct set of vsid's.
+ Of course, my intepretation may be wrong.
+ -- Cort */
+ /*bl _EXTERN(flush_instruction_cache)*/
+ RETURN_FROM_INT(0x0f0f)
/*
@@ -1629,50 +1415,16 @@ _GLOBAL(_switch)
_GLOBAL(__main)
blr
-#ifdef DO_TRAP_TRACE
-check_trace:
- sync /* Force all writes out */
- lwz r2,-8(r1)
- andi. r2,r2,MSR_PR
- bne 99f
- lwz r2,-32(r1)
- lwz r3,-16(r1)
- cmp 0,r2,r3
- bne 99f
- andi. r2,r2,0x7FFF
- cmpi 0,r2,0x0C00
- bge 99f
- lwz r2,-32+4(r1)
- lwz r3,-16+4(r1)
- cmp 0,r2,r3
- bne 99f
- lwz r2,-32+8(r1)
- lwz r3,-16+8(r1)
- cmp 0,r2,r3
- bne 99f
- lwz r2,-32(r1)
- lwz r3,-16(r1)
- cmp 0,r2,r3
- bne 99f
- andi. r2,r2,0x7FFF
- cmpi 0,r2,0x0600
- beq 00f
- lwz r2,-32+12(r1)
- lwz r3,-16+12(r1)
- cmp 0,r2,r3
- bne 99f
-00: li r2,0x7653
- stw r2,0(r1)
- b 00b
-99: blr
-#endif
-
.data
.globl sdata
sdata:
.space 2*4096
+
+#if 0
+_GLOBAL(sys_stack)
sys_stack:
- .space 2*4096
+ .space 4096
+#endif
CPU1_stack:
.globl empty_zero_page
@@ -1689,32 +1441,40 @@ swapper_pg_dir:
*/
.globl cmd_line
cmd_line:
- .space 512
-
+ .space 512
+
#ifdef STATS
/*
* Miscellaneous statistics - gathered just for performance info
*/
-
.globl _INTR_stats
_INTR_stats:
+ .globl __Instruction_TLB_Misses
__Instruction_TLB_Misses:
.long 0,0 /* Instruction TLB misses */
+ .globl __DataLoad_TLB_Misses
__DataLoad_TLB_Misses:
.long 0,0 /* Data [load] TLB misses */
+ .globl __DataStore_TLB_Misses
__DataStore_TLB_Misses:
.long 0,0 /* Data [store] TLB misses */
+ .globl __Instruction_Page_Faults
__Instruction_Page_Faults:
.long 0,0 /* Instruction page faults */
+ .globl __Data_Page_Faults
__Data_Page_Faults:
.long 0,0 /* Data page faults */
+ .globl __Cache_Flushes
__Cache_Flushes:
.long 0,0 /* Explicit cache flushes */
+ .globl __Context_Switches
__Context_Switches:
.long 0,0 /* Context switches */
+ .globl __Hardware_Interrupts
__Hardware_Interrupts:
.long 0,0 /* I/O interrupts (disk, timer, etc) */
.globl __TLBIAs
+ .globl __TLBIAs
__TLBIAs:
.long 0,0 /* TLB cache forceably flushed */
.globl __TLBIEs
@@ -1722,33 +1482,14 @@ __TLBIEs:
.long 0,0 /* Specific TLB entry flushed */
#endif
+ .globl _TotalMemory
+_TotalMemory:
+ .long 0,0
+
/*
* This location is used to break any outstanding "lock"s when
* changing contexts.
*/
_break_lwarx: .long 0
-
-/*
- * Various trace buffers
- */
-#ifdef DO_TRAP_TRACE
- .data
-_TRAP_TRACE: .space 32*1024
-_TRAP_ptr: .long _TRAP_TRACE
- .text
-#endif
-
-#ifdef DO_TLB_TRACE
- .data
-_TLB_TRACE: .space 128*1024
-_TLB_ptr: .long _TLB_TRACE
- .text
-#endif
-
-#ifdef DO_RFI_TRACE
- .data
-_RFI_DATA: .space 128*1024
-_RFI_ptr: .long _RFI_DATA
- .text
-#endif
+
diff --git a/arch/ppc/kernel/include/elf/ChangeLog b/arch/ppc/kernel/include/elf/ChangeLog
deleted file mode 100644
index b4e7bd3ad..000000000
--- a/arch/ppc/kernel/include/elf/ChangeLog
+++ /dev/null
@@ -1,155 +0,0 @@
-Tue Jun 20 10:18:28 1995 Jeff Law (law@snake.cs.utah.edu)
-
- * hppa.h (CPU_PA_RISC1_0): Protect from redefinitions.
- (CPU_PA_RISC1_1): Likewise.
-
-Wed Mar 8 18:14:37 1995 Michael Meissner <meissner@tiktok.cygnus.com>
-
- * ppc.h: New file for PowerPC support.
-
-Tue Feb 14 13:59:13 1995 Michael Meissner <meissner@tiktok.cygnus.com>
-
- * common.h (EM_PPC): Use official value of 20, not 17.
- (EM_PPC_OLD): Define this to be the old value of EM_PPC.
-
-
-Tue Jan 24 09:40:59 1995 Michael Meissner <meissner@tiktok.cygnus.com>
-
- * common.h (EM_PPC): New macro, PowerPC machine id.
-
-Tue Jan 17 10:51:38 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
-
- * mips.h (SHT_MIPS_MSYM, SHT_MIPS_DWARF, SHT_MIPS_EVENTS): Define.
-
-
-Mon Oct 17 13:43:59 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
-
- * internal.h (Elf_Internal_Shdr): Remove rawdata and size fields.
- Add bfd_section field.
-
-Tue May 24 16:11:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * mips.h (Elf32_External_gptab): Define.
-
-Mon May 16 13:22:04 1994 Jeff Law (law@snake.cs.utah.edu)
-
- * common.h (EM_HPPA): Delete.
- (EM_PARISC): Add.
- * hppa.h: New file.
-
-Mon May 9 13:27:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * common.h (SHN_LORESERVE): Rename from SHN_LORESERV.
- (ELF32_R_TYPE, ELF32_R_INFO): Don't rely on size of unsigned char.
- (ELF64_R_TYPE): Don't rely on size of unsigned long.
-
-Mon Apr 25 15:53:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * internal.h (Elf_Internal_Shdr): Use PTR, not void *.
-
-Fri Mar 11 00:34:59 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
-
- * mips.h (SHN_MIPS_TEXT, SHN_MIPS_DATA): Define.
-
-Sat Mar 5 14:08:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
-
- * internal.h: Remove Elf32_*, Elf64_* typedefs. These names
- cause conflicts with system headers, e.g. link.h in gdb/solib.c.
- Combine 32- and 64-bit versions of *_Internal_Dyn.
- * common.h: Replace uses of Elf64_Word, Elf64_Xword typedefs
- by their expansion.
- * mips.h: Replace uses of Elf32_Word, Elf32_Sword, Elf32_Addr
- typedefs by their expansion. Add DT_MIPS_RLD_MAP definition.
-
-Fri Feb 18 10:39:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * common.h (EM_CYGNUS_POWERPC): Define. This may be temporary,
- depending upon how quickly I can find a real PowerPC ABI.
-
-Mon Feb 7 08:27:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * internal.h: Change HOST_64_BIT to BFD_HOST_64_BIT.
-
-Wed Feb 2 14:12:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * common.h: Add comments regarding value of EM_HPPA and how to
- pick an unofficial value.
-
-Wed Nov 17 17:14:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * mips.h (SHT_MIPS_OPTIONS): Define.
-
-Mon Nov 8 17:57:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * mips.h: Added some more MIPS ABI macro definitions.
-
-Wed Nov 3 22:07:17 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
-
- * common.h (EM_MIPS_RS4_BE): New macro.
-
-Tue Oct 12 07:28:18 1993 Ian Lance Taylor (ian@cygnus.com)
-
- * mips.h: New file. MIPS ABI specific information.
-
-Mon Jun 21 13:13:43 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
-
- * internal.h: Combined 32- and 64-bit versions of all structures
- except *_Internal_Dyn. This will simply the assembler interface,
- and some bfd code.
-
-Tue May 25 02:00:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
-
- * external.h, internal.h, common.h: Added 64-bit versions of some
- structures and macros. Renamed old versions to put "32" in the
- name. Some are unchanged.
-
-Thu Apr 29 12:12:20 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
-
- * common.h (EM_HPPA, NT_VERSION, STN_UNDEF, DT_*): New macros.
- * external.h (Elf_External_Dyn): New type.
-
- * internal.h (Elf_Internal_Shdr): New field `size'.
- (Elf_Internal_Dyn): New type.
-
-Tue Apr 20 16:03:45 1993 Fred Fish (fnf@cygnus.com)
-
- * dwarf.h (LANG_CHILL): Change value to one randomly picked in
- the user defined range, to reduce probability of collisions.
-
-Sun Nov 15 09:34:02 1992 Fred Fish (fnf@cygnus.com)
-
- * dwarf.h (AT_src_coords): Whitespace change only.
- * dwarf.h (AT_body_begin, AT_body_end, LANG_MODULA2):
- Add from latest gcc.
- * dwarf.h (LANG_CHILL): Add as GNU extension.
-
-Sat Aug 1 13:46:53 1992 Fred Fish (fnf@cygnus.com)
-
- * dwarf.h: Replace with current version from gcc distribution.
-
-Fri Jun 19 19:05:09 1992 John Gilmore (gnu at cygnus.com)
-
- * internal.h: Add real struct tags to all the Type_Defs, so they
- can be used in prototypes where the Type_Defs are not known.
-
-Fri Apr 3 20:58:58 1992 Mark Eichin (eichin at cygnus.com)
-
- * common.h: added ELF_R_{SYM,TYPE,INFO} for handling relocation
- info
- added EM_MIPS, and corrected value of EM_860 based on System V ABI
- manual.
-
- * external.h: added Elf_External_{Rel,Rela}.
-
- * internal.h: added Elf_Internal_{Rel,Rela}.
- added rawdata to Elf_Internal_Shdr.
-
-Sat Nov 30 20:43:59 1991 Steve Chamberlain (sac at rtl.cygnus.com)
-
- * common.h, dwarf.h, external.h, internal.h, ChangeLog; moved from
- ../elf-<foo>
-
-
-Local Variables:
-version-control: never
-End:
diff --git a/arch/ppc/kernel/include/elf/common.h b/arch/ppc/kernel/include/elf/common.h
deleted file mode 100644
index a9bce87d6..000000000
--- a/arch/ppc/kernel/include/elf/common.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/* ELF support for BFD.
- Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
-
- Written by Fred Fish @ Cygnus Support, from information published
- in "UNIX System V Release 4, Programmers Guide: ANSI C and
- Programming Support Tools".
-
-This file is part of BFD, the Binary File Descriptor library.
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-/* This file is part of ELF support for BFD, and contains the portions
- that are common to both the internal and external representations.
- For example, ELFMAG0 is the byte 0x7F in both the internal (in-memory)
- and external (in-file) representations. */
-
-
-/* Fields in e_ident[] */
-
-#define EI_MAG0 0 /* File identification byte 0 index */
-#define ELFMAG0 0x7F /* Magic number byte 0 */
-
-#define EI_MAG1 1 /* File identification byte 1 index */
-#define ELFMAG1 'E' /* Magic number byte 1 */
-
-#define EI_MAG2 2 /* File identification byte 2 index */
-#define ELFMAG2 'L' /* Magic number byte 2 */
-
-#define EI_MAG3 3 /* File identification byte 3 index */
-#define ELFMAG3 'F' /* Magic number byte 3 */
-
-#define EI_CLASS 4 /* File class */
-#define ELFCLASSNONE 0 /* Invalid class */
-#define ELFCLASS32 1 /* 32-bit objects */
-#define ELFCLASS64 2 /* 64-bit objects */
-
-#define EI_DATA 5 /* Data encoding */
-#define ELFDATANONE 0 /* Invalid data encoding */
-#define ELFDATA2LSB 1 /* 2's complement, little endian */
-#define ELFDATA2MSB 2 /* 2's complement, big endian */
-
-#define EI_VERSION 6 /* File version */
-
-#define EI_PAD 7 /* Start of padding bytes */
-
-
-/* Values for e_type, which identifies the object file type */
-
-#define ET_NONE 0 /* No file type */
-#define ET_REL 1 /* Relocatable file */
-#define ET_EXEC 2 /* Executable file */
-#define ET_DYN 3 /* Shared object file */
-#define ET_CORE 4 /* Core file */
-#define ET_LOPROC 0xFF00 /* Processor-specific */
-#define ET_HIPROC 0xFFFF /* Processor-specific */
-
-/* Values for e_machine, which identifies the architecture */
-
-#define EM_NONE 0 /* No machine */
-#define EM_M32 1 /* AT&T WE 32100 */
-#define EM_SPARC 2 /* SUN SPARC */
-#define EM_386 3 /* Intel 80386 */
-#define EM_68K 4 /* Motorola m68k family */
-#define EM_88K 5 /* Motorola m88k family */
-#define EM_860 7 /* Intel 80860 */
-#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
-
-#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
-
-#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
-
-#define EM_PARISC 15 /* HPPA */
-#define EM_PPC 20 /* PowerPC */
-
-/* If it is necessary to assign new unofficial EM_* values, please pick large
- random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
- with official or non-GNU unofficial values. */
-
-/* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */
-#define EM_CYGNUS_POWERPC 0x9025
-
-/* Old version of PowerPC, this should be removed shortly. */
-#define EM_PPC_OLD 17
-
-
-/* Values for e_version */
-
-#define EV_NONE 0 /* Invalid ELF version */
-#define EV_CURRENT 1 /* Current version */
-
-/* Values for program header, p_type field */
-
-#define PT_NULL 0 /* Program header table entry unused */
-#define PT_LOAD 1 /* Loadable program segment */
-#define PT_DYNAMIC 2 /* Dynamic linking information */
-#define PT_INTERP 3 /* Program interpreter */
-#define PT_NOTE 4 /* Auxiliary information */
-#define PT_SHLIB 5 /* Reserved, unspecified semantics */
-#define PT_PHDR 6 /* Entry for header table itself */
-#define PT_LOPROC 0x70000000 /* Processor-specific */
-#define PT_HIPROC 0x7FFFFFFF /* Processor-specific */
-
-/* Program segment permissions, in program header p_flags field */
-
-#define PF_X (1 << 0) /* Segment is executable */
-#define PF_W (1 << 1) /* Segment is writable */
-#define PF_R (1 << 2) /* Segment is readable */
-#define PF_MASKPROC 0xF0000000 /* Processor-specific reserved bits */
-
-/* Values for section header, sh_type field */
-
-#define SHT_NULL 0 /* Section header table entry unused */
-#define SHT_PROGBITS 1 /* Program specific (private) data */
-#define SHT_SYMTAB 2 /* Link editing symbol table */
-#define SHT_STRTAB 3 /* A string table */
-#define SHT_RELA 4 /* Relocation entries with addends */
-#define SHT_HASH 5 /* A symbol hash table */
-#define SHT_DYNAMIC 6 /* Information for dynamic linking */
-#define SHT_NOTE 7 /* Information that marks file */
-#define SHT_NOBITS 8 /* Section occupies no space in file */
-#define SHT_REL 9 /* Relocation entries, no addends */
-#define SHT_SHLIB 10 /* Reserved, unspecified semantics */
-#define SHT_DYNSYM 11 /* Dynamic linking symbol table */
-#define SHT_LOPROC 0x70000000 /* Processor-specific semantics, lo */
-#define SHT_HIPROC 0x7FFFFFFF /* Processor-specific semantics, hi */
-#define SHT_LOUSER 0x80000000 /* Application-specific semantics */
-#define SHT_HIUSER 0x8FFFFFFF /* Application-specific semantics */
-
-/* Values for section header, sh_flags field */
-
-#define SHF_WRITE (1 << 0) /* Writable data during execution */
-#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
-#define SHF_EXECINSTR (1 << 2) /* Executable machine instructions */
-#define SHF_MASKPROC 0xF0000000 /* Processor-specific semantics */
-
-/* Values of note segment descriptor types for core files. */
-
-#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
-#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
-#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
-
-/* Values of note segment descriptor types for object files. */
-/* (Only for hppa right now. Should this be moved elsewhere?) */
-
-#define NT_VERSION 1 /* Contains a version string. */
-
-/* These three macros disassemble and assemble a symbol table st_info field,
- which contains the symbol binding and symbol type. The STB_ and STT_
- defines identify the binding and type. */
-
-#define ELF_ST_BIND(val) (((unsigned int)(val)) >> 4)
-#define ELF_ST_TYPE(val) ((val) & 0xF)
-#define ELF_ST_INFO(bind,type) (((bind) << 4) + ((type) & 0xF))
-
-#define STN_UNDEF 0 /* undefined symbol index */
-
-#define STB_LOCAL 0 /* Symbol not visible outside obj */
-#define STB_GLOBAL 1 /* Symbol visible outside obj */
-#define STB_WEAK 2 /* Like globals, lower precedence */
-#define STB_LOPROC 13 /* Application-specific semantics */
-#define STB_HIPROC 15 /* Application-specific semantics */
-
-#define STT_NOTYPE 0 /* Symbol type is unspecified */
-#define STT_OBJECT 1 /* Symbol is a data object */
-#define STT_FUNC 2 /* Symbol is a code object */
-#define STT_SECTION 3 /* Symbol associated with a section */
-#define STT_FILE 4 /* Symbol gives a file name */
-#define STT_LOPROC 13 /* Application-specific semantics */
-#define STT_HIPROC 15 /* Application-specific semantics */
-
-/* Special section indices, which may show up in st_shndx fields, among
- other places. */
-
-#define SHN_UNDEF 0 /* Undefined section reference */
-#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
-#define SHN_LOPROC 0xFF00 /* Begin range of appl-specific */
-#define SHN_HIPROC 0xFF1F /* End range of appl-specific */
-#define SHN_ABS 0xFFF1 /* Associated symbol is absolute */
-#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */
-#define SHN_HIRESERVE 0xFFFF /* End range of reserved indices */
-
-/* relocation info handling macros */
-
-#define ELF32_R_SYM(i) ((i) >> 8)
-#define ELF32_R_TYPE(i) ((i) & 0xff)
-#define ELF32_R_INFO(s,t) (((s) << 8) + ((t) & 0xff))
-
-#define ELF64_R_SYM(i) ((i) >> 32)
-#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
-#define ELF64_R_INFO(s,t) (((bfd_vma) (s) << 32) + (bfd_vma) (t))
-
-/* Dynamic section tags */
-
-#define DT_NULL 0
-#define DT_NEEDED 1
-#define DT_PLTRELSZ 2
-#define DT_PLTGOT 3
-#define DT_HASH 4
-#define DT_STRTAB 5
-#define DT_SYMTAB 6
-#define DT_RELA 7
-#define DT_RELASZ 8
-#define DT_RELAENT 9
-#define DT_STRSZ 10
-#define DT_SYMENT 11
-#define DT_INIT 12
-#define DT_FINI 13
-#define DT_SONAME 14
-#define DT_RPATH 15
-#define DT_SYMBOLIC 16
-#define DT_REL 17
-#define DT_RELSZ 18
-#define DT_RELENT 19
-#define DT_PLTREL 20
-#define DT_DEBUG 21
-#define DT_TEXTREL 22
-#define DT_JMPREL 23
-#define DT_LOPROC 0x70000000
-#define DT_HIPROC 0x7fffffff
diff --git a/arch/ppc/kernel/include/elf/dwarf.h b/arch/ppc/kernel/include/elf/dwarf.h
deleted file mode 100644
index bc9723ae0..000000000
--- a/arch/ppc/kernel/include/elf/dwarf.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/* Declarations and definitions of codes relating to the DWARF symbolic
- debugging information format.
-
- Written by Ron Guilmette (rfg@ncd.com)
-
-Copyright (C) 1992 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC 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, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* This file is derived from the DWARF specification (a public document)
- Revision 1.0.1 (April 8, 1992) developed by the UNIX International
- Programming Languages Special Interest Group (UI/PLSIG) and distributed
- by UNIX International. Copies of this specification are available from
- UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
-*/
-
-/* Tag names and codes. */
-
-enum dwarf_tag {
- TAG_padding = 0x0000,
- TAG_array_type = 0x0001,
- TAG_class_type = 0x0002,
- TAG_entry_point = 0x0003,
- TAG_enumeration_type = 0x0004,
- TAG_formal_parameter = 0x0005,
- TAG_global_subroutine = 0x0006,
- TAG_global_variable = 0x0007,
- /* 0x0008 -- reserved */
- /* 0x0009 -- reserved */
- TAG_label = 0x000a,
- TAG_lexical_block = 0x000b,
- TAG_local_variable = 0x000c,
- TAG_member = 0x000d,
- /* 0x000e -- reserved */
- TAG_pointer_type = 0x000f,
- TAG_reference_type = 0x0010,
- TAG_compile_unit = 0x0011,
- TAG_string_type = 0x0012,
- TAG_structure_type = 0x0013,
- TAG_subroutine = 0x0014,
- TAG_subroutine_type = 0x0015,
- TAG_typedef = 0x0016,
- TAG_union_type = 0x0017,
- TAG_unspecified_parameters = 0x0018,
- TAG_variant = 0x0019,
- TAG_common_block = 0x001a,
- TAG_common_inclusion = 0x001b,
- TAG_inheritance = 0x001c,
- TAG_inlined_subroutine = 0x001d,
- TAG_module = 0x001e,
- TAG_ptr_to_member_type = 0x001f,
- TAG_set_type = 0x0020,
- TAG_subrange_type = 0x0021,
- TAG_with_stmt = 0x0022,
-
- /* GNU extensions */
-
- TAG_format_label = 0x8000, /* for FORTRAN 77 and Fortran 90 */
- TAG_namelist = 0x8001, /* For Fortran 90 */
- TAG_function_template = 0x8002, /* for C++ */
- TAG_class_template = 0x8003 /* for C++ */
-};
-
-#define TAG_lo_user 0x8000 /* implementation-defined range start */
-#define TAG_hi_user 0xffff /* implementation-defined range end */
-#define TAG_source_file TAG_compile_unit /* for backward compatibility */
-
-/* Form names and codes. */
-
-enum dwarf_form {
- FORM_ADDR = 0x1,
- FORM_REF = 0x2,
- FORM_BLOCK2 = 0x3,
- FORM_BLOCK4 = 0x4,
- FORM_DATA2 = 0x5,
- FORM_DATA4 = 0x6,
- FORM_DATA8 = 0x7,
- FORM_STRING = 0x8
-};
-
-/* Attribute names and codes. */
-
-enum dwarf_attribute {
- AT_sibling = (0x0010|FORM_REF),
- AT_location = (0x0020|FORM_BLOCK2),
- AT_name = (0x0030|FORM_STRING),
- AT_fund_type = (0x0050|FORM_DATA2),
- AT_mod_fund_type = (0x0060|FORM_BLOCK2),
- AT_user_def_type = (0x0070|FORM_REF),
- AT_mod_u_d_type = (0x0080|FORM_BLOCK2),
- AT_ordering = (0x0090|FORM_DATA2),
- AT_subscr_data = (0x00a0|FORM_BLOCK2),
- AT_byte_size = (0x00b0|FORM_DATA4),
- AT_bit_offset = (0x00c0|FORM_DATA2),
- AT_bit_size = (0x00d0|FORM_DATA4),
- /* (0x00e0|FORM_xxxx) -- reserved */
- AT_element_list = (0x00f0|FORM_BLOCK4),
- AT_stmt_list = (0x0100|FORM_DATA4),
- AT_low_pc = (0x0110|FORM_ADDR),
- AT_high_pc = (0x0120|FORM_ADDR),
- AT_language = (0x0130|FORM_DATA4),
- AT_member = (0x0140|FORM_REF),
- AT_discr = (0x0150|FORM_REF),
- AT_discr_value = (0x0160|FORM_BLOCK2),
- /* (0x0170|FORM_xxxx) -- reserved */
- /* (0x0180|FORM_xxxx) -- reserved */
- AT_string_length = (0x0190|FORM_BLOCK2),
- AT_common_reference = (0x01a0|FORM_REF),
- AT_comp_dir = (0x01b0|FORM_STRING),
- AT_const_value_string = (0x01c0|FORM_STRING),
- AT_const_value_data2 = (0x01c0|FORM_DATA2),
- AT_const_value_data4 = (0x01c0|FORM_DATA4),
- AT_const_value_data8 = (0x01c0|FORM_DATA8),
- AT_const_value_block2 = (0x01c0|FORM_BLOCK2),
- AT_const_value_block4 = (0x01c0|FORM_BLOCK4),
- AT_containing_type = (0x01d0|FORM_REF),
- AT_default_value_addr = (0x01e0|FORM_ADDR),
- AT_default_value_data2 = (0x01e0|FORM_DATA2),
- AT_default_value_data4 = (0x01e0|FORM_DATA4),
- AT_default_value_data8 = (0x01e0|FORM_DATA8),
- AT_default_value_string = (0x01e0|FORM_STRING),
- AT_friends = (0x01f0|FORM_BLOCK2),
- AT_inline = (0x0200|FORM_STRING),
- AT_is_optional = (0x0210|FORM_STRING),
- AT_lower_bound_ref = (0x0220|FORM_REF),
- AT_lower_bound_data2 = (0x0220|FORM_DATA2),
- AT_lower_bound_data4 = (0x0220|FORM_DATA4),
- AT_lower_bound_data8 = (0x0220|FORM_DATA8),
- AT_private = (0x0240|FORM_STRING),
- AT_producer = (0x0250|FORM_STRING),
- AT_program = (0x0230|FORM_STRING),
- AT_protected = (0x0260|FORM_STRING),
- AT_prototyped = (0x0270|FORM_STRING),
- AT_public = (0x0280|FORM_STRING),
- AT_pure_virtual = (0x0290|FORM_STRING),
- AT_return_addr = (0x02a0|FORM_BLOCK2),
- AT_abstract_origin = (0x02b0|FORM_REF),
- AT_start_scope = (0x02c0|FORM_DATA4),
- AT_stride_size = (0x02e0|FORM_DATA4),
- AT_upper_bound_ref = (0x02f0|FORM_REF),
- AT_upper_bound_data2 = (0x02f0|FORM_DATA2),
- AT_upper_bound_data4 = (0x02f0|FORM_DATA4),
- AT_upper_bound_data8 = (0x02f0|FORM_DATA8),
- AT_virtual = (0x0300|FORM_STRING),
-
- /* GNU extensions. */
-
- AT_sf_names = (0x8000|FORM_DATA4),
- AT_src_info = (0x8010|FORM_DATA4),
- AT_mac_info = (0x8020|FORM_DATA4),
- AT_src_coords = (0x8030|FORM_DATA4),
- AT_body_begin = (0x8040|FORM_ADDR),
- AT_body_end = (0x8050|FORM_ADDR)
-};
-
-#define AT_lo_user 0x8000 /* implementation-defined range start */
-#define AT_hi_user 0xffff /* implementation-defined range end */
-
-/* Location atom names and codes. */
-
-enum dwarf_location_atom {
- OP_REG = 0x01,
- OP_BASEREG = 0x02,
- OP_ADDR = 0x03,
- OP_CONST = 0x04,
- OP_DEREF2 = 0x05,
- OP_DEREF4 = 0x06,
- OP_ADD = 0x07
-};
-
-#define OP_LO_USER 0x80 /* implementation-defined range start */
-#define OP_HI_USER 0xff /* implementation-defined range end */
-
-/* Fundamental type names and codes. */
-
-enum dwarf_fundamental_type {
- FT_char = 0x0001,
- FT_signed_char = 0x0002,
- FT_unsigned_char = 0x0003,
- FT_short = 0x0004,
- FT_signed_short = 0x0005,
- FT_unsigned_short = 0x0006,
- FT_integer = 0x0007,
- FT_signed_integer = 0x0008,
- FT_unsigned_integer = 0x0009,
- FT_long = 0x000a,
- FT_signed_long = 0x000b,
- FT_unsigned_long = 0x000c,
- FT_pointer = 0x000d, /* an alias for (void *) */
- FT_float = 0x000e,
- FT_dbl_prec_float = 0x000f,
- FT_ext_prec_float = 0x0010, /* breaks "classic" svr4 SDB */
- FT_complex = 0x0011, /* breaks "classic" svr4 SDB */
- FT_dbl_prec_complex = 0x0012, /* breaks "classic" svr4 SDB */
- /* 0x0013 -- reserved */
- FT_void = 0x0014,
- FT_boolean = 0x0015, /* breaks "classic" svr4 SDB */
- FT_ext_prec_complex = 0x0016, /* breaks "classic" svr4 SDB */
- FT_label = 0x0017,
-
- /* GNU extensions
- The low order byte must indicate the size (in bytes) for the type.
- All of these types will probably break "classic" svr4 SDB */
-
- FT_long_long = 0x8008,
- FT_signed_long_long = 0x8108,
- FT_unsigned_long_long = 0x8208,
-
- FT_int8 = 0x9001,
- FT_signed_int8 = 0x9101,
- FT_unsigned_int8 = 0x9201,
- FT_int16 = 0x9302,
- FT_signed_int16 = 0x9402,
- FT_unsigned_int16 = 0x9502,
- FT_int32 = 0x9604,
- FT_signed_int32 = 0x9704,
- FT_unsigned_int32 = 0x9804,
- FT_int64 = 0x9908,
- FT_signed_int64 = 0x9a08,
- FT_unsigned_int64 = 0x9b08,
-
- FT_real32 = 0xa004,
- FT_real64 = 0xa108,
- FT_real96 = 0xa20c,
- FT_real128 = 0xa310
-};
-
-#define FT_lo_user 0x8000 /* implementation-defined range start */
-#define FT_hi_user 0xffff /* implementation defined range end */
-
-/* Type modifier names and codes. */
-
-enum dwarf_type_modifier {
- MOD_pointer_to = 0x01,
- MOD_reference_to = 0x02,
- MOD_const = 0x03,
- MOD_volatile = 0x04
-};
-
-#define MOD_lo_user 0x80 /* implementation-defined range start */
-#define MOD_hi_user 0xff /* implementation-defined range end */
-
-/* Array ordering names and codes. */
-
-enum dwarf_array_dim_ordering {
- ORD_row_major = 0,
- ORD_col_major = 1
-};
-
-/* Array subscript format names and codes. */
-
-enum dwarf_subscr_data_formats {
- FMT_FT_C_C = 0x0,
- FMT_FT_C_X = 0x1,
- FMT_FT_X_C = 0x2,
- FMT_FT_X_X = 0x3,
- FMT_UT_C_C = 0x4,
- FMT_UT_C_X = 0x5,
- FMT_UT_X_C = 0x6,
- FMT_UT_X_X = 0x7,
- FMT_ET = 0x8
-};
-
-/* Derived from above for ease of use. */
-
-#define FMT_CODE(_FUNDAMENTAL_TYPE_P, _UB_CONST_P, _LB_CONST_P) \
- (((_FUNDAMENTAL_TYPE_P) ? 0 : 4) \
- | ((_UB_CONST_P) ? 0 : 2) \
- | ((_LB_CONST_P) ? 0 : 1))
-
-/* Source language names and codes. */
-
-enum dwarf_source_language {
- LANG_C89 = 0x00000001,
- LANG_C = 0x00000002,
- LANG_ADA83 = 0x00000003,
- LANG_C_PLUS_PLUS = 0x00000004,
- LANG_COBOL74 = 0x00000005,
- LANG_COBOL85 = 0x00000006,
- LANG_FORTRAN77 = 0x00000007,
- LANG_FORTRAN90 = 0x00000008,
- LANG_PASCAL83 = 0x00000009,
- LANG_MODULA2 = 0x0000000a,
-
- /* GNU extensions */
-
- LANG_CHILL = 0x00009af3 /* random value for GNU Chill */
-};
-
-#define LANG_lo_user 0x00008000 /* implementation-defined range start */
-#define LANG_hi_user 0x0000ffff /* implementation-defined range end */
-
-/* Names and codes for GNU "macinfo" extension. */
-
-enum dwarf_macinfo_record_type {
- MACINFO_start = 's',
- MACINFO_resume = 'r',
- MACINFO_define = 'd',
- MACINFO_undef = 'u'
-};
diff --git a/arch/ppc/kernel/include/elf/external.h b/arch/ppc/kernel/include/elf/external.h
deleted file mode 100644
index f2ab63e1e..000000000
--- a/arch/ppc/kernel/include/elf/external.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/* ELF support for BFD.
- Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-
- Written by Fred Fish @ Cygnus Support, from information published
- in "UNIX System V Release 4, Programmers Guide: ANSI C and
- Programming Support Tools".
-
-This file is part of BFD, the Binary File Descriptor library.
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-/* This file is part of ELF support for BFD, and contains the portions
- that describe how ELF is represented externally by the BFD library.
- I.E. it describes the in-file representation of ELF. It requires
- the elf-common.h file which contains the portions that are common to
- both the internal and external representations. */
-
-/* The 64-bit stuff is kind of random. Perhaps someone will publish a
- spec someday. */
-
-/* ELF Header (32-bit implementations) */
-
-typedef struct {
- unsigned char e_ident[16]; /* ELF "magic number" */
- unsigned char e_type[2]; /* Identifies object file type */
- unsigned char e_machine[2]; /* Specifies required architecture */
- unsigned char e_version[4]; /* Identifies object file version */
- unsigned char e_entry[4]; /* Entry point virtual address */
- unsigned char e_phoff[4]; /* Program header table file offset */
- unsigned char e_shoff[4]; /* Section header table file offset */
- unsigned char e_flags[4]; /* Processor-specific flags */
- unsigned char e_ehsize[2]; /* ELF header size in bytes */
- unsigned char e_phentsize[2]; /* Program header table entry size */
- unsigned char e_phnum[2]; /* Program header table entry count */
- unsigned char e_shentsize[2]; /* Section header table entry size */
- unsigned char e_shnum[2]; /* Section header table entry count */
- unsigned char e_shstrndx[2]; /* Section header string table index */
-} Elf32_External_Ehdr;
-
-typedef struct {
- unsigned char e_ident[16]; /* ELF "magic number" */
- unsigned char e_type[2]; /* Identifies object file type */
- unsigned char e_machine[2]; /* Specifies required architecture */
- unsigned char e_version[4]; /* Identifies object file version */
- unsigned char e_entry[8]; /* Entry point virtual address */
- unsigned char e_phoff[8]; /* Program header table file offset */
- unsigned char e_shoff[8]; /* Section header table file offset */
- unsigned char e_flags[4]; /* Processor-specific flags */
- unsigned char e_ehsize[2]; /* ELF header size in bytes */
- unsigned char e_phentsize[2]; /* Program header table entry size */
- unsigned char e_phnum[2]; /* Program header table entry count */
- unsigned char e_shentsize[2]; /* Section header table entry size */
- unsigned char e_shnum[2]; /* Section header table entry count */
- unsigned char e_shstrndx[2]; /* Section header string table index */
-} Elf64_External_Ehdr;
-
-/* Program header */
-
-typedef struct {
- unsigned char p_type[4]; /* Identifies program segment type */
- unsigned char p_offset[4]; /* Segment file offset */
- unsigned char p_vaddr[4]; /* Segment virtual address */
- unsigned char p_paddr[4]; /* Segment physical address */
- unsigned char p_filesz[4]; /* Segment size in file */
- unsigned char p_memsz[4]; /* Segment size in memory */
- unsigned char p_flags[4]; /* Segment flags */
- unsigned char p_align[4]; /* Segment alignment, file & memory */
-} Elf32_External_Phdr;
-
-typedef struct {
- unsigned char p_type[4]; /* Identifies program segment type */
- unsigned char p_flags[4]; /* Segment flags */
- unsigned char p_offset[8]; /* Segment file offset */
- unsigned char p_vaddr[8]; /* Segment virtual address */
- unsigned char p_paddr[8]; /* Segment physical address */
- unsigned char p_filesz[8]; /* Segment size in file */
- unsigned char p_memsz[8]; /* Segment size in memory */
- unsigned char p_align[8]; /* Segment alignment, file & memory */
-} Elf64_External_Phdr;
-
-/* Section header */
-
-typedef struct {
- unsigned char sh_name[4]; /* Section name, index in string tbl */
- unsigned char sh_type[4]; /* Type of section */
- unsigned char sh_flags[4]; /* Miscellaneous section attributes */
- unsigned char sh_addr[4]; /* Section virtual addr at execution */
- unsigned char sh_offset[4]; /* Section file offset */
- unsigned char sh_size[4]; /* Size of section in bytes */
- unsigned char sh_link[4]; /* Index of another section */
- unsigned char sh_info[4]; /* Additional section information */
- unsigned char sh_addralign[4]; /* Section alignment */
- unsigned char sh_entsize[4]; /* Entry size if section holds table */
-} Elf32_External_Shdr;
-
-typedef struct {
- unsigned char sh_name[4]; /* Section name, index in string tbl */
- unsigned char sh_type[4]; /* Type of section */
- unsigned char sh_flags[8]; /* Miscellaneous section attributes */
- unsigned char sh_addr[8]; /* Section virtual addr at execution */
- unsigned char sh_offset[8]; /* Section file offset */
- unsigned char sh_size[8]; /* Size of section in bytes */
- unsigned char sh_link[4]; /* Index of another section */
- unsigned char sh_info[4]; /* Additional section information */
- unsigned char sh_addralign[8]; /* Section alignment */
- unsigned char sh_entsize[8]; /* Entry size if section holds table */
-} Elf64_External_Shdr;
-
-/* Symbol table entry */
-
-typedef struct {
- unsigned char st_name[4]; /* Symbol name, index in string tbl */
- unsigned char st_value[4]; /* Value of the symbol */
- unsigned char st_size[4]; /* Associated symbol size */
- unsigned char st_info[1]; /* Type and binding attributes */
- unsigned char st_other[1]; /* No defined meaning, 0 */
- unsigned char st_shndx[2]; /* Associated section index */
-} Elf32_External_Sym;
-
-typedef struct {
- unsigned char st_name[4]; /* Symbol name, index in string tbl */
- unsigned char st_info[1]; /* Type and binding attributes */
- unsigned char st_other[1]; /* No defined meaning, 0 */
- unsigned char st_shndx[2]; /* Associated section index */
- unsigned char st_value[8]; /* Value of the symbol */
- unsigned char st_size[8]; /* Associated symbol size */
-} Elf64_External_Sym;
-
-/* Note segments */
-
-typedef struct {
- unsigned char namesz[4]; /* Size of entry's owner string */
- unsigned char descsz[4]; /* Size of the note descriptor */
- unsigned char type[4]; /* Interpretation of the descriptor */
- char name[1]; /* Start of the name+desc data */
-} Elf_External_Note;
-
-/* Relocation Entries */
-typedef struct {
- unsigned char r_offset[4]; /* Location at which to apply the action */
- unsigned char r_info[4]; /* index and type of relocation */
-} Elf32_External_Rel;
-
-typedef struct {
- unsigned char r_offset[4]; /* Location at which to apply the action */
- unsigned char r_info[4]; /* index and type of relocation */
- unsigned char r_addend[4]; /* Constant addend used to compute value */
-} Elf32_External_Rela;
-
-typedef struct {
- unsigned char r_offset[8]; /* Location at which to apply the action */
- unsigned char r_info[8]; /* index and type of relocation */
-} Elf64_External_Rel;
-
-typedef struct {
- unsigned char r_offset[8]; /* Location at which to apply the action */
- unsigned char r_info[8]; /* index and type of relocation */
- unsigned char r_addend[8]; /* Constant addend used to compute value */
-} Elf64_External_Rela;
-
-/* dynamic section structure */
-
-typedef struct {
- unsigned char d_tag[4]; /* entry tag value */
- union {
- unsigned char d_val[4];
- unsigned char d_ptr[4];
- } d_un;
-} Elf32_External_Dyn;
-
-typedef struct {
- unsigned char d_tag[8]; /* entry tag value */
- union {
- unsigned char d_val[8];
- unsigned char d_ptr[8];
- } d_un;
-} Elf64_External_Dyn;
diff --git a/arch/ppc/kernel/include/elf/hppa.h b/arch/ppc/kernel/include/elf/hppa.h
deleted file mode 100644
index e3f70d23d..000000000
--- a/arch/ppc/kernel/include/elf/hppa.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* HPPA ELF support for BFD.
- Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-
-This file is part of BFD, the Binary File Descriptor library.
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* This file holds definitions specific to the HPPA ELF ABI. Note
- that most of this is not actually implemented by BFD. */
-
-/* Processor specific flags for the ELF header e_flags field. */
-
-/* Target processor IDs to be placed in the low 16 bits of the flags
- field. Note these names are shared with SOM, and therefore do not
- follow ELF naming conventions. */
-
-/* PA 1.0 big endian. */
-#ifndef CPU_PA_RISC1_0
-#define CPU_PA_RISC1_0 0x0000020b
-#endif
-
-/* PA 1.1 big endian. */
-#ifndef CPU_PA_RISC1_1
-#define CPU_PA_RISC1_1 0x00000210
-#endif
-
-/* PA 1.0 little endian (unsupported) is 0x0000028b. */
-/* PA 1.1 little endian (unsupported) is 0x00000290. */
-
-/* Trap null address dereferences. */
-#define ELF_PARISC_TRAPNIL 0x00010000
-
-/* .PARISC.archext section is present. */
-#define EF_PARISC_EXT 0x00020000
-
-/* Processor specific section types. */
-
-/* Holds the global offset table, a table of pointers to external
- data. */
-#define SHT_PARISC_GOT SHT_LOPROC+0
-
-/* Nonloadable section containing information in architecture
- extensions used by the code. */
-#define SHT_PARISC_ARCH SHT_LOPROC+1
-
-/* Section in which $global$ is defined. */
-#define SHT_PARISC_GLOBAL SHT_LOPROC+2
-
-/* Section holding millicode routines (mul, div, rem, dyncall, etc. */
-#define SHT_PARISC_MILLI SHT_LOPROC+3
-
-/* Section holding unwind information for use by debuggers. */
-#define SHT_PARISC_UNWIND SHT_LOPROC+4
-
-/* Section holding the procedure linkage table. */
-#define SHT_PARISC_PLT SHT_LOPROC+5
-
-/* Short initialized and uninitialized data. */
-#define SHT_PARISC_SDATA SHT_LOPROC+6
-#define SHT_PARISC_SBSS SHT_LOPROC+7
-
-/* Optional section holding argument location/relocation info. */
-#define SHT_PARISC_SYMEXTN SHT_LOPROC+8
-
-/* Option section for linker stubs. */
-#define SHT_PARISC_STUBS SHT_LOPROC+9
-
-/* Processor specific section flags. */
-
-/* This section is near the global data pointer and thus allows short
- addressing modes to be used. */
-#define SHF_PARISC_SHORT 0x20000000
-
-/* Processor specific symbol types. */
-
-/* Millicode function entry point. */
-#define STT_PARISC_MILLICODE STT_LOPROC+0
-
diff --git a/arch/ppc/kernel/include/elf/internal.h b/arch/ppc/kernel/include/elf/internal.h
deleted file mode 100644
index fb6302937..000000000
--- a/arch/ppc/kernel/include/elf/internal.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* ELF support for BFD.
- Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
-
- Written by Fred Fish @ Cygnus Support, from information published
- in "UNIX System V Release 4, Programmers Guide: ANSI C and
- Programming Support Tools".
-
-This file is part of BFD, the Binary File Descriptor library.
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-/* This file is part of ELF support for BFD, and contains the portions
- that describe how ELF is represented internally in the BFD library.
- I.E. it describes the in-memory representation of ELF. It requires
- the elf-common.h file which contains the portions that are common to
- both the internal and external representations. */
-
-
-/* NOTE that these structures are not kept in the same order as they appear
- in the object file. In some cases they've been reordered for more optimal
- packing under various circumstances. */
-
-/* ELF Header */
-
-#define EI_NIDENT 16 /* Size of e_ident[] */
-
-typedef struct elf_internal_ehdr {
- unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
- bfd_vma e_entry; /* Entry point virtual address */
- bfd_signed_vma e_phoff; /* Program header table file offset */
- bfd_signed_vma e_shoff; /* Section header table file offset */
- unsigned long e_version; /* Identifies object file version */
- unsigned long e_flags; /* Processor-specific flags */
- unsigned short e_type; /* Identifies object file type */
- unsigned short e_machine; /* Specifies required architecture */
- unsigned short e_ehsize; /* ELF header size in bytes */
- unsigned short e_phentsize; /* Program header table entry size */
- unsigned short e_phnum; /* Program header table entry count */
- unsigned short e_shentsize; /* Section header table entry size */
- unsigned short e_shnum; /* Section header table entry count */
- unsigned short e_shstrndx; /* Section header string table index */
-} Elf_Internal_Ehdr;
-
-#define elf32_internal_ehdr elf_internal_ehdr
-#define Elf32_Internal_Ehdr Elf_Internal_Ehdr
-#define elf64_internal_ehdr elf_internal_ehdr
-#define Elf64_Internal_Ehdr Elf_Internal_Ehdr
-
-/* Program header */
-
-struct elf_internal_phdr {
- unsigned long p_type; /* Identifies program segment type */
- unsigned long p_flags; /* Segment flags */
- bfd_vma p_offset; /* Segment file offset */
- bfd_vma p_vaddr; /* Segment virtual address */
- bfd_vma p_paddr; /* Segment physical address */
- bfd_vma p_filesz; /* Segment size in file */
- bfd_vma p_memsz; /* Segment size in memory */
- bfd_vma p_align; /* Segment alignment, file & memory */
-};
-
-typedef struct elf_internal_phdr Elf_Internal_Phdr;
-#define elf32_internal_phdr elf_internal_phdr
-#define Elf32_Internal_Phdr Elf_Internal_Phdr
-#define elf64_internal_phdr elf_internal_phdr
-#define Elf64_Internal_Phdr Elf_Internal_Phdr
-
-/* Section header */
-
-typedef struct elf_internal_shdr {
- unsigned int sh_name; /* Section name, index in string tbl */
- unsigned int sh_type; /* Type of section */
- bfd_vma sh_flags; /* Miscellaneous section attributes */
- bfd_vma sh_addr; /* Section virtual addr at execution */
- bfd_size_type sh_size; /* Size of section in bytes */
- bfd_size_type sh_entsize; /* Entry size if section holds table */
- unsigned long sh_link; /* Index of another section */
- unsigned long sh_info; /* Additional section information */
- file_ptr sh_offset; /* Section file offset */
- unsigned int sh_addralign; /* Section alignment */
-
- /* The internal rep also has some cached info associated with it. */
- asection * bfd_section; /* Associated BFD section. */
- PTR contents; /* Section contents. */
-} Elf_Internal_Shdr;
-
-#define elf32_internal_shdr elf_internal_shdr
-#define Elf32_Internal_Shdr Elf_Internal_Shdr
-#define elf64_internal_shdr elf_internal_shdr
-#define Elf64_Internal_Shdr Elf_Internal_Shdr
-
-/* Symbol table entry */
-
-struct elf_internal_sym {
- bfd_vma st_value; /* Value of the symbol */
- bfd_vma st_size; /* Associated symbol size */
- unsigned long st_name; /* Symbol name, index in string tbl */
- unsigned char st_info; /* Type and binding attributes */
- unsigned char st_other; /* No defined meaning, 0 */
- unsigned short st_shndx; /* Associated section index */
-};
-
-typedef struct elf_internal_sym Elf_Internal_Sym;
-
-#define elf32_internal_sym elf_internal_sym
-#define elf64_internal_sym elf_internal_sym
-#define Elf32_Internal_Sym Elf_Internal_Sym
-#define Elf64_Internal_Sym Elf_Internal_Sym
-
-/* Note segments */
-
-typedef struct elf_internal_note {
- unsigned long namesz; /* Size of entry's owner string */
- unsigned long descsz; /* Size of the note descriptor */
- unsigned long type; /* Interpretation of the descriptor */
- char name[1]; /* Start of the name+desc data */
-} Elf_Internal_Note;
-#define Elf32_Internal_Note Elf_Internal_Note
-#define elf32_internal_note elf_internal_note
-
-/* Relocation Entries */
-
-typedef struct elf_internal_rel {
- bfd_vma r_offset; /* Location at which to apply the action */
- /* This needs to support 64-bit values in elf64. */
- bfd_vma r_info; /* index and type of relocation */
-} Elf_Internal_Rel;
-
-#define elf32_internal_rel elf_internal_rel
-#define Elf32_Internal_Rel Elf_Internal_Rel
-#define elf64_internal_rel elf_internal_rel
-#define Elf64_Internal_Rel Elf_Internal_Rel
-
-typedef struct elf_internal_rela {
- bfd_vma r_offset; /* Location at which to apply the action */
- bfd_vma r_info; /* Index and Type of relocation */
- bfd_signed_vma r_addend; /* Constant addend used to compute value */
-} Elf_Internal_Rela;
-
-#define elf32_internal_rela elf_internal_rela
-#define elf64_internal_rela elf_internal_rela
-#define Elf32_Internal_Rela Elf_Internal_Rela
-#define Elf64_Internal_Rela Elf_Internal_Rela
-
-/* dynamic section structure */
-
-typedef struct elf_internal_dyn {
- /* This needs to support 64-bit values in elf64. */
- bfd_vma d_tag; /* entry tag value */
- union {
- /* This needs to support 64-bit values in elf64. */
- bfd_vma d_val;
- bfd_vma d_ptr;
- } d_un;
-} Elf_Internal_Dyn;
-
-#define elf32_internal_dyn elf_internal_dyn
-#define elf64_internal_dyn elf_internal_dyn
-#define Elf32_Internal_Dyn Elf_Internal_Dyn
-#define Elf64_Internal_Dyn Elf_Internal_Dyn
diff --git a/arch/ppc/kernel/include/elf/mips.h b/arch/ppc/kernel/include/elf/mips.h
deleted file mode 100644
index f6beff71c..000000000
--- a/arch/ppc/kernel/include/elf/mips.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/* MIPS ELF support for BFD.
- Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-
- By Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>, from
- information in the System V Application Binary Interface, MIPS
- Processor Supplement.
-
-This file is part of BFD, the Binary File Descriptor library.
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* This file holds definitions specific to the MIPS ELF ABI. Note
- that most of this is not actually implemented by BFD. */
-
-/* Processor specific flags for the ELF header e_flags field. */
-
-/* At least one .noreorder directive appears in the source. */
-#define EF_MIPS_NOREORDER 0x00000001
-
-/* File contains position independent code. */
-#define EF_MIPS_PIC 0x00000002
-
-/* Code in file uses the standard calling sequence for calling
- position independent code. */
-#define EF_MIPS_CPIC 0x00000004
-
-/* Four bit MIPS architecture field. */
-#define EF_MIPS_ARCH 0xf0000000
-
-/* -mips1 code. */
-#define E_MIPS_ARCH_1 0x00000000
-
-/* -mips2 code. */
-#define E_MIPS_ARCH_2 0x10000000
-
-/* -mips3 code. */
-#define E_MIPS_ARCH_3 0x20000000
-
-/* Processor specific section indices. These sections do not actually
- exist. Symbols with a st_shndx field corresponding to one of these
- values have a special meaning. */
-
-/* Defined and allocated common symbol. Value is virtual address. If
- relocated, alignment must be preserved. */
-#define SHN_MIPS_ACOMMON 0xff00
-
-/* Defined and allocated text symbol. Value is virtual address.
- Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */
-#define SHN_MIPS_TEXT 0xff01
-
-/* Defined and allocated data symbol. Value is virtual address.
- Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */
-#define SHN_MIPS_DATA 0xff02
-
-/* Small common symbol. */
-#define SHN_MIPS_SCOMMON 0xff03
-
-/* Small undefined symbol. */
-#define SHN_MIPS_SUNDEFINED 0xff04
-
-/* Processor specific section types. */
-
-/* Section contains the set of dynamic shared objects used when
- statically linking. */
-#define SHT_MIPS_LIBLIST 0x70000000
-
-/* I'm not sure what this is, but it's used on Irix 5. */
-#define SHT_MIPS_MSYM 0x70000001
-
-/* Section contains list of symbols whose definitions conflict with
- symbols defined in shared objects. */
-#define SHT_MIPS_CONFLICT 0x70000002
-
-/* Section contains the global pointer table. */
-#define SHT_MIPS_GPTAB 0x70000003
-
-/* Section contains microcode information. The exact format is
- unspecified. */
-#define SHT_MIPS_UCODE 0x70000004
-
-/* Section contains some sort of debugging information. The exact
- format is unspecified. It's probably ECOFF symbols. */
-#define SHT_MIPS_DEBUG 0x70000005
-
-/* Section contains register usage information. */
-#define SHT_MIPS_REGINFO 0x70000006
-
-/* Section contains miscellaneous options (used on Irix). */
-#define SHT_MIPS_OPTIONS 0x7000000d
-
-/* DWARF debugging section (used on Irix 6). */
-#define SHT_MIPS_DWARF 0x7000001e
-
-/* Events section. This appears on Irix 6. I don't know what it
- means. */
-#define SHT_MIPS_EVENTS 0x70000021
-
-/* A section of type SHT_MIPS_LIBLIST contains an array of the
- following structure. The sh_link field is the section index of the
- string table. The sh_info field is the number of entries in the
- section. */
-typedef struct
-{
- /* String table index for name of shared object. */
- unsigned long l_name;
- /* Time stamp. */
- unsigned long l_time_stamp;
- /* Checksum of symbol names and common sizes. */
- unsigned long l_checksum;
- /* String table index for version. */
- unsigned long l_version;
- /* Flags. */
- unsigned long l_flags;
-} Elf32_Lib;
-
-/* The l_flags field of an Elf32_Lib structure may contain the
- following flags. */
-
-/* Require an exact match at runtime. */
-#define LL_EXACT_MATCH 0x00000001
-
-/* Ignore version incompatibilities at runtime. */
-#define LL_IGNORE_INT_VER 0x00000002
-
-/* A section of type SHT_MIPS_CONFLICT is an array of indices into the
- .dynsym section. Each element has the following type. */
-typedef unsigned long Elf32_Conflict;
-
-/* A section of type SHT_MIPS_GPTAB contains information about how
- much GP space would be required for different -G arguments. This
- information is only used so that the linker can provide informative
- suggestions as to the best -G value to use. The sh_info field is
- the index of the section for which this information applies. The
- contents of the section are an array of the following union. The
- first element uses the gt_header field. The remaining elements use
- the gt_entry field. */
-typedef union
-{
- struct
- {
- /* -G value actually used for this object file. */
- unsigned long gt_current_g_value;
- /* Unused. */
- unsigned long gt_unused;
- } gt_header;
- struct
- {
- /* If this -G argument has been used... */
- unsigned long gt_g_value;
- /* ...this many GP section bytes would be required. */
- unsigned long gt_bytes;
- } gt_entry;
-} Elf32_gptab;
-
-/* The external version of Elf32_gptab. */
-
-typedef union
-{
- struct
- {
- unsigned char gt_current_g_value[4];
- unsigned char gt_unused[4];
- } gt_header;
- struct
- {
- unsigned char gt_g_value[4];
- unsigned char gt_bytes[4];
- } gt_entry;
-} Elf32_External_gptab;
-
-/* A section of type SHT_MIPS_REGINFO contains the following
- structure. */
-typedef struct
-{
- /* Mask of general purpose registers used. */
- unsigned long ri_gprmask;
- /* Mask of co-processor registers used. */
- unsigned long ri_cprmask[4];
- /* GP register value for this object file. */
- long ri_gp_value;
-} Elf32_RegInfo;
-
-/* The external version of the Elf_RegInfo structure. */
-typedef struct
-{
- unsigned char ri_gprmask[4];
- unsigned char ri_cprmask[4][4];
- unsigned char ri_gp_value[4];
-} Elf32_External_RegInfo;
-
-/* MIPS ELF .reginfo swapping routines. */
-extern void bfd_mips_elf32_swap_reginfo_in
- PARAMS ((bfd *, const Elf32_External_RegInfo *, Elf32_RegInfo *));
-extern void bfd_mips_elf32_swap_reginfo_out
- PARAMS ((bfd *, const Elf32_RegInfo *, Elf32_External_RegInfo *));
-
-/* Processor specific section flags. */
-
-/* This section must be in the global data area. */
-#define SHF_MIPS_GPREL 0x10000000
-
-/* Processor specific program header types. */
-
-/* Register usage information. Identifies one .reginfo section. */
-#define PT_MIPS_REGINFO 0x70000000
-
-/* Processor specific dynamic array tags. */
-
-/* 32 bit version number for runtime linker interface. */
-#define DT_MIPS_RLD_VERSION 0x70000001
-
-/* Time stamp. */
-#define DT_MIPS_TIME_STAMP 0x70000002
-
-/* Checksum of external strings and common sizes. */
-#define DT_MIPS_ICHECKSUM 0x70000003
-
-/* Index of version string in string table. */
-#define DT_MIPS_IVERSION 0x70000004
-
-/* 32 bits of flags. */
-#define DT_MIPS_FLAGS 0x70000005
-
-/* Base address of the segment. */
-#define DT_MIPS_BASE_ADDRESS 0x70000006
-
-/* Address of .conflict section. */
-#define DT_MIPS_CONFLICT 0x70000008
-
-/* Address of .liblist section. */
-#define DT_MIPS_LIBLIST 0x70000009
-
-/* Number of local global offset table entries. */
-#define DT_MIPS_LOCAL_GOTNO 0x7000000a
-
-/* Number of entries in the .conflict section. */
-#define DT_MIPS_CONFLICTNO 0x7000000b
-
-/* Number of entries in the .liblist section. */
-#define DT_MIPS_LIBLISTNO 0x70000010
-
-/* Number of entries in the .dynsym section. */
-#define DT_MIPS_SYMTABNO 0x70000011
-
-/* Index of first external dynamic symbol not referenced locally. */
-#define DT_MIPS_UNREFEXTNO 0x70000012
-
-/* Index of first dynamic symbol in global offset table. */
-#define DT_MIPS_GOTSYM 0x70000013
-
-/* Number of page table entries in global offset table. */
-#define DT_MIPS_HIPAGENO 0x70000014
-
-/* Address of run time loader map, used for debugging. */
-#define DT_MIPS_RLD_MAP 0x70000016
diff --git a/arch/ppc/kernel/include/elf/ppc.h b/arch/ppc/kernel/include/elf/ppc.h
deleted file mode 100644
index b4907acb7..000000000
--- a/arch/ppc/kernel/include/elf/ppc.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* MIPS PPC support for BFD.
- Copyright (C) 1995 Free Software Foundation, Inc.
-
- By Michael Meissner, Cygnus Support, <meissner@cygnus.com>, from information
- in the System V Application Binary Interface, PowerPC Processor Supplement
- and the PowerPC Embedded Application Binary Interface (eabi).
-
-This file is part of BFD, the Binary File Descriptor library.
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* This file holds definitions specific to the PPC ELF ABI. Note
- that most of this is not actually implemented by BFD. */
-
-/* Processor specific flags for the ELF header e_flags field. */
-
-#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
-
- /* CYGNUS local bits below */
-#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag */
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index 27d146479..41d453186 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 1992 Linus Torvalds
* Adapted from arch/i386 by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
*
* This file contains the code used by various IRQ handling routines:
* asking for different IRQ's should be done through these routines
@@ -30,6 +31,24 @@
#include <asm/irq.h>
#include <asm/bitops.h>
+inline int get_irq_list(char *);
+void check_irq(void);
+void BeBox_CPU1(void);
+void BeBox_state(void);
+int BeBox_irq(void);
+void show_BeBox_state(void);
+void BeBox_enable_irq(int );
+void BeBox_disable_irq(int );
+void BeBox_init_IRQ(void);
+void _do_bottom_half(void);
+static _NOP(void);
+static _delay(void);
+void hard_disk_LED(int state);
+
+
+#define SHOW_IRQ
+#undef SHOW_IRQ
+
/*
* For the BeBox, interrupt numbers are 0..15 for 8259 PIC interrupts
* and 16..31 for other BeBox motherboard type interrupts.
@@ -52,7 +71,8 @@ void disable_irq(unsigned int irq_nr)
} else
{
mask = 1 << (irq_nr & 7);
- if (irq_nr < 8) {
+ if (irq_nr < 8)
+ {
cache_21 |= mask;
outb(cache_21,0x21);
} else
@@ -120,150 +140,202 @@ static struct irq_action irq_action[32] = {
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
};
-int get_irq_list(char *buf)
+
+inline int get_irq_list(char *buf)
{
- int i, len = 0;
- struct irq_action * action = irq_action;
-
- for (i = 0; i < 132; i++, action++) {
- if (!action->handler)
- continue;
- len += sprintf(buf+len, "%2d: %8d %c %s\n",
- i, kstat.interrupts[i],
- (action->flags & SA_INTERRUPT) ? '+' : ' ',
- action->name);
- }
- return len;
+ int i, len = 0;
+ struct irq_action * action = irq_action;
+
+ for (i = 0; i < 32; i++, action++) {
+ if (!action->handler)
+ continue;
+ len += sprintf(buf+len, "%2d: %8d %c %s\n",
+ i, kstat.interrupts[i],
+ (action->flags & SA_INTERRUPT) ? '+' : ' ',
+ action->name);
+ }
+ return len;
}
-asmlinkage void handle_IRQ(struct pt_regs *regs)
+inline void
+process_IRQ(int irq, int _irq, struct pt_regs *regs)
{
- int irq, _irq, s;
+ struct irq_action *action;
+ atomic_inc(&intr_count);
+ if (irq < 16)
+ {
+ /* Mask interrupt */
+ if (irq > 7)
+ {
+ cache_A1 |= (1<<(irq-8));
+ outb(cache_A1, 0xA1);
+ } else
+ {
+ cache_21 |= (1<<irq);
+ outb(cache_21, 0x21);
+ }
+ }
+ action = irq + irq_action;
+ kstat.interrupts[irq]++;
+ /* TEMP */
+ /* On the Nobis, the keyboard interrupt "edge" gets lost - why? */
+ if (irq == 0)
+ {
+ static int count;
+ if (++count == 500)
+ {
+ if (inb(0x64) & 0x01)
+ {
struct irq_action *action;
- intr_count++;
- if (!isBeBox[0] || ((irq = BeBox_irq()) < 16))
- {
- /* Figure out IRQ#, etc. */
- outb(0x0C, 0x20); /* Poll interrupt controller */
- irq = _irq = inb(0x20);
- irq &= 0x07; /* Caution! */
- if (irq == 2)
- { /* Cascaded interrupt -> IRQ8..IRQ15 */
- outb(0x0C, 0xA0);
- irq = (_irq = inb(0xA0)) & 0x07;
- irq += 8;
- }
- /* Mask interrupt & Issue EOI to interrupt controller */
- if (irq > 7)
- {
- cache_A1 |= (1<<(irq-8));
- outb(cache_A1, 0xA1);
-#if 0
- outb(0x20, 0xA0);
- /* Need to ack cascade controller as well */
- outb(0x20, 0x20);
-#else
- outb(0x60|(irq-8), 0xA0); /* Specific EOI */
- /* Need to ack cascade controller as well */
- outb(0x62, 0x20);
-#endif
- } else
- {
- cache_21 |= (1<<irq);
- outb(cache_21, 0x21);
- outb(0x20, 0x20);
- }
- }
- action = irq + irq_action;
- kstat.interrupts[irq]++;
- if (action->handler)
- {
- action->handler(irq, action->dev_id, regs);
- } else
- {
- printk("Bogus interrupt #%d/%x, PC: %x\n", irq, _irq, regs->nip);
- }
- if (_disable_interrupts() && !action->notified)
- {
- action->notified = 1;
- printk("*** WARNING! %s handler [IRQ %d] turned interrupts on!\n", action->name, irq);
- }
- if (irq < 16)
- {
- if (!(action->flags & SA_ONESHOT))
- {
- /* Re-enable interrupt */
- if (irq > 7)
- {
- cache_A1 &= ~(1<<(irq-8));
- outb(cache_A1, 0xA1);
- } else
- {
- cache_21 &= ~(1<<irq);
- outb(cache_21, 0x21);
- }
- }
- } else
+ action = irq_action + 1; /* Keyboard */
+ printk("Reset KBD, KBSTAT = %x, ELCR = %x/%x, MASK = %x/%x\n",
+ inb(0x64), inb(0x4D0), inb(0x4D1), cache_21, cache_A1);
+ action->handler(1, action->dev_id, regs);
+ }
+ count = 0;
+ }
+ }
+ if (action->handler)
+ {
+ action->handler(irq, action->dev_id, regs);
+ } else
+ {
+ printk("Bogus interrupt %d/%x, pc %x regs %x\n",
+ irq, _irq,regs->nip,regs);
+#if 0
+ printk("BeBox[] = %x/%x\n", isBeBox[0], isBeBox[1]);
+ show_BeBox_state();
+ cnpause();
+#endif
+ }
+ if (_disable_interrupts() && !action->notified)
+ {
+ action->notified = 1;
+ printk("*** WARNING! %s handler [IRQ %d] turned interrupts on!\n",
+ action->name, irq);
+ }
+ if (irq < 16)
+ {
+ /* Issue EOI to interrupt controller */
+ if (irq > 7)
+ {
+ outb(0xE0|(irq-8), 0xA0);
+ outb(0xE2, 0x20);
+ } else
+ {
+ outb(0xE0|irq, 0x20);
+ }
+ if (!(action->flags & SA_ONESHOT))
+ {
+ /* Re-enable interrupt */
+ if (irq > 7)
+ {
+ cache_A1 &= ~(1<<(irq-8));
+ outb(cache_A1, 0xA1);
+ } else
+ {
+ cache_21 &= ~(1<<irq);
+ outb(cache_21, 0x21);
+ }
+ }
+ } else
+ {
+ BeBox_enable_irq(irq);
+ }
+ atomic_dec(&intr_count);
+}
+
+asmlinkage inline void handle_IRQ(struct pt_regs *regs)
+{
+ int irq, _irq, s;
+ struct irq_action *action;
+ static int _ints;
+
+ if (!isBeBox[0] || ((irq = BeBox_irq()) < 16))
+ {
+ /* Figure out IRQ#, etc. */
+ outb(0x0C, 0x20); /* Poll interrupt controller */
+ irq = _irq = inb(0x20);
+ irq &= 0x07; /* Caution! */
+ if (irq == 2)
+ { /* Cascaded interrupt -> IRQ8..IRQ15 */
+ outb(0x0C, 0xA0);
+ irq = (_irq = inb(0xA0)) & 0x07;
+ irq += 8;
+ }
+ }
+ process_IRQ(irq, _irq, regs);
+
+ /* Sometimes, the cascaded IRQ controller get's "stuck" */
+ if ((irq == 0) && (_ints++ == 100))
+ {
+ _ints = 0;
+ outb(0x0A, 0xA0); _irq = inb(0xA0);
+ if (_irq & ~cache_A1)
+ { /* Figure out which IRQs are present */
+ _irq &= ~cache_A1;
+ for (irq = 0; irq < 7; irq++)
+ {
+ if (_irq & (1<<irq))
{
- BeBox_enable_irq(irq);
+#if 0
+ printk("Dropped IRQ #%d\n", irq+8);
+#endif
+ process_IRQ(irq+8, _irq, regs);
}
- intr_count--;
+ }
+ }
+ }
}
/*
- * This routine gets called when the SCSI times out on an operation.
- * I don't know why this happens, but every so often it does and it
- * seems to be a problem with the interrupt controller [state]. It
- * happens a lot when there is also network activity (both devices
- * are on the PCI bus with interrupts on the cascaded controller).
- * Re-initializing the interrupt controller [which might lose some
- * pending edge detected interrupts] seems to fix it.
+ * Display current IRQ state
*/
-check_irq()
+
+void
+show_irq_state(void)
+{
+ unsigned char state_21, state_A1;
+ outb(0x0A, 0x20); state_21 = inb(0x20);
+ outb(0x0A, 0xA0); state_A1 = inb(0xA0);
+ printk("IRQ State = %x/%x, Edge = %x/%x, Processor = %d\n", state_21, state_A1, inb(0x4D0), inb(0x4D1), _Processor);
+}
+
+/*
+ * Initialize interrupt controllers to a well-known state.
+ */
+
+static void
+reset_int_controllers(void)
{
- int s;
- unsigned char _a0, _a1, _20, _21;
- if (isBeBox[0])
- {
- return;
- }
- s = _disable_interrupts();
- _a1 = inb(0xA1);
- _21 = inb(0x21);
- outb(0x0C, 0x20); _20 = inb(0x20);
- outb(0x0C, 0xA0); _a0 = inb(0xA0);
-#if 0
- printk("IRQ 0x20 = %x, 0x21 = %x/%x, 0xA0 = %x, 0xA1 = %x/%x\n",
- _20, _21, cache_21, _a0, _a1, cache_A1);
-#endif
- /* Reset interrupt controller - see if this fixes it! */
/* Initialize interrupt controllers */
outb(0x11, 0x20); /* Start init sequence */
outb(0x40, 0x21); /* Vector base */
outb(0x04, 0x21); /* Cascade (slave) on IRQ2 */
outb(0x01, 0x21); /* Select 8086 mode */
outb(0xFF, 0x21); /* Mask all */
- outb(0x00, 0x4D0); /* All edge triggered */
outb(0x11, 0xA0); /* Start init sequence */
outb(0x48, 0xA1); /* Vector base */
outb(0x02, 0xA1); /* Cascade (slave) on IRQ2 */
outb(0x01, 0xA1); /* Select 8086 mode */
outb(0xFF, 0xA1); /* Mask all */
+#if 0
+ outb(0x00, 0x4D0); /* All edge triggered */
outb(0xCF, 0x4D1); /* Trigger mode */
+#endif
outb(cache_A1, 0xA1);
outb(cache_21, 0x21);
enable_irq(2); /* Enable cascade interrupt */
- _enable_interrupts(s);
}
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
- unsigned long irqflags, const char * devname, void *dev_id)
+ unsigned long irqflags, const char * devname, void *dev_id)
{
struct irq_action * action;
unsigned long flags;
-#if 0
-_printk("Request IRQ #%d, Handler: %x\n", irq, handler);
+#ifdef SHOW_IRQ
+if (irq) printk("Request IRQ #%d, Handler: %x\n", irq, handler);
#endif
if (irq > 15)
{
@@ -374,24 +446,33 @@ int probe_irq_off (unsigned long irqs)
void init_IRQ(void)
{
- int i;
-
- /* set the clock to 100 Hz */
- outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
- outb_p(LATCH & 0xff , 0x40); /* LSB */
- outb(LATCH >> 8 , 0x40); /* MSB */
- if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL))
- printk("Unable to get IRQ2 for cascade\n");
- request_region(0x20,0x20,"pic1");
- request_region(0xa0,0x20,"pic2");
-
- /* Set up PCI interrupts */
- route_PCI_interrupts();
-
- if (isBeBox[0])
- {
- BeBox_init_IRQ();
- }
+ int i;
+
+ if ((_get_PVR()>>16) == 1) /* PPC 601 */
+ { /* Nobis? */
+ reset_int_controllers();
+ }
+#define TIMER0_COUNT 0x40
+#define TIMER_CONTROL 0x43
+ /* set the clock to 100 Hz */
+ outb_p(0x34,TIMER_CONTROL); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , TIMER0_COUNT); /* LSB */
+ outb(LATCH >> 8 , TIMER0_COUNT); /* MSB */
+ if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL))
+ printk("Unable to get IRQ2 for cascade\n");
+ request_region(0x20,0x20,"pic1");
+ request_region(0xa0,0x20,"pic2");
+
+ /* Make sure IRQ2 (cascade) interrupt is "level" based */
+ outb(inb(0x4D0)|0x04, 0x4D0); /* IRQ2 level based */
+
+ /* Set up PCI interrupts */
+ route_PCI_interrupts();
+
+ if (isBeBox[0])
+ {
+ BeBox_init_IRQ();
+ }
}
/*
@@ -399,11 +480,18 @@ void init_IRQ(void)
* is called whenever an interrupt needs non-interrupt-time service.
*/
-_do_bottom_half()
+void _do_bottom_half(void)
{
- _enable_interrupts(1);
- do_bottom_half();
- _disable_interrupts();
+ _enable_interrupts(1);
+ do_bottom_half();
+ _disable_interrupts();
+}
+
+void hard_disk_LED(int state)
+{
+ if (_Processor == _PROC_IBM) {
+ outb(state, IBM_HDD_LED);
+ }
}
@@ -416,6 +504,11 @@ _do_bottom_half()
#define INT_SOURCE (volatile unsigned long *)(BeBox_IO_page+0x2F0)
#define CPU_RESET (volatile unsigned long *)(BeBox_IO_page+0x4F0)
+#define _CPU0_INT_MASK (volatile unsigned long *)(0xA0000000+0x0F0)
+#define _CPU1_INT_MASK (volatile unsigned long *)(0xA0000000+0x1F0)
+#define _INT_SOURCE (volatile unsigned long *)(0xA0000000+0x2F0)
+#define _CPU_RESET (volatile unsigned long *)(0xA0000000+0x4F0)
+
#define CPU_HRESET 0x20000000
#define CPU_SRESET 0x40000000
@@ -454,12 +547,12 @@ volatile int CPU1_alive;
volatile int CPU1_trace;
static
-_NOP()
+_NOP(void)
{
}
static
-_delay()
+_delay(void)
{
int i;
for (i = 0; i < 100; i++) _NOP();
@@ -486,12 +579,6 @@ printk("CPU #1 not there? - CPU Status: %x, Trace: %x\n", *CPU_RESET, CPU1_trace
_delay();
}
printk("CPU #1 running!\n");
-#if 0
-/* Temp - for SCSI */
- *(unsigned char *)0x81000038 = 0x00;
- *(unsigned char *)0x8080103C = 0xFF;
- *(unsigned char *)0x8080100D = 0x32;
-#endif
}
void
@@ -516,6 +603,16 @@ printk("/%x\n", *CPU0_INT_MASK);
_enable_interrupts(s);
}
+void
+show_BeBox_state(void)
+{
+ unsigned long cpu0_int_mask;
+ unsigned long int_state;
+ cpu0_int_mask = (*CPU0_INT_MASK & 0x0FFFFFFC) & ~INT_8259;
+ int_state = cpu0_int_mask & *INT_SOURCE;
+ printk("Ints[%x] = %x, Mask[%x] = %x/%x, State = %x\n", INT_SOURCE, *INT_SOURCE, CPU0_INT_MASK, *CPU0_INT_MASK, cpu0_int_mask, int_state);
+}
+
int
BeBox_irq(void)
{
@@ -542,12 +639,12 @@ printk("Can't find BeBox IRQ!\n");
return (0);
}
-BeBox_state()
+void BeBox_state(void)
{
printk("Int state = %x, CPU0 mask = %x, CPU1 mask = %x\n", *INT_SOURCE, *CPU0_INT_MASK, *CPU1_INT_MASK);
}
-BeBox_CPU1()
+void BeBox_CPU1(void)
{
CPU1_alive++;
while (1) ;
diff --git a/arch/ppc/kernel/ksyms.c b/arch/ppc/kernel/ksyms.c
index a0d3ec66e..b59b8964e 100644
--- a/arch/ppc/kernel/ksyms.c
+++ b/arch/ppc/kernel/ksyms.c
@@ -1,14 +1,4 @@
#include <linux/module.h>
#include <linux/smp.h>
-static struct symbol_table arch_symbol_table = {
-#include <linux/symtab_begin.h>
- /* platform dependent support */
-#include <linux/symtab_end.h>
-};
-
-void arch_syms_export(void)
-{
- register_symtab(&arch_symbol_table);
-}
-
+/* platform dependent support */
diff --git a/arch/ppc/kernel/ld.script-user b/arch/ppc/kernel/ld.script-user
deleted file mode 100644
index 910d34ad3..000000000
--- a/arch/ppc/kernel/ld.script-user
+++ /dev/null
@@ -1,75 +0,0 @@
-OUTPUT_ARCH(powerpc)
-SEARCH_DIR(libc); SEARCH_DIR(../sa_test/libc);
-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)
- }
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0
- .ctors : { *(.ctors) }
- .dtors : { *(.dtors) }
- .rodata : { *(.rodata) }
- .rodata1 : { *(.rodata1) }
- /* Read-write section, merged into data segment: */
-/* . = (. + 0x0FFF) & 0xFFFFF000; */
- .data :
- {
- *(.data)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* These are needed for ELF backends which have not yet been
- converted to the new style linker. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- /* These must appear regardless of . */
-}
-
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 7d84bdc89..e137e1171 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -3,9 +3,12 @@
* set of code at specific locations, based on function
*/
-#include <linux/sys.h>
#include "ppc_asm.tmpl"
-
+#include <linux/sys.h>
+#include <asm/errno.h>
+#include "ppc_defs.h"
+#include <asm/processor.h>
+
/* Keep track of low-level exceptions - rather crude, but informative */
#define STATS
@@ -23,6 +26,7 @@
addze r3,r3; \
stw r3,0(r2)
+/*#ifdef CONFIG_603*/
/* This instruction is not implemented on the PPC 603 */
#define tlbia \
li r4,64; \
@@ -31,9 +35,195 @@
0: tlbie r4; \
addi r4,r4,0x1000; \
bdnz 0b
+/*#endif*/ /* CONFIG_603*/
_TEXT()
+#define CPU_CTL 0x80000092
+_GLOBAL(hard_reset_now)
+ mfmsr r3 /* Disable interrupts */
+ li r4,0
+ ori r4,r4,MSR_EE
+ andc r3,r3,r4
+ ori r3,r3,MSR_IP /* Set FLASH/ROM interrupt handlers */
+ sync
+ mtmsr r3
+ lis r3,CPU_CTL>>16
+ ori r3,r3,(CPU_CTL&0xFFFF)
+ lbz r4,0(r3) /* Turn on SRESET */
+ li r5,1
+ andc r4,r4,r5 /* Make sure we go from 0->1 */
+ stb r4,0(r3)
+ ori r4,r4,1
+ stb r4,0(r3) /* This should do it! */
+99: nop
+ b 99b
+
+#if 0
+/*
+ unsigned short
+ le16_to_cpu(unsigned short val)
+*/
+_GLOBAL(le16_to_cpu)
+ lis r4,_le_scratch@h
+ ori r4,r4,_le_scratch@l
+ sth r3,0(r4)
+ li r5,0
+ lhbrx r3,r4,r5
+ blr
+_GLOBAL(le32_to_cpu)
+ lis r4,_le_scratch@h
+ ori r4,r4,_le_scratch@l
+ stw r3,0(r4)
+ li r5,0
+ lwbrx r3,r4,r5
+ blr
+_GLOBAL(_le_scratch)
+ .space 4
+#endif
+#if 1
+/*
+extern int __put_user_8(char, char *);
+extern int __put_user_16(short, short *);
+extern int __put_user_32(long, long *);
+*/
+_GLOBAL(__put_user_8)
+ /* setup exception stuff */
+ lis r2,current_set@ha
+ lwz r2,current_set@l(r2)
+ /* increment excount */
+ lwz r6,TSS+TSS_EXCOUNT(r2)
+ addi r6,r6,1
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ /* set expc */
+ lis r6,1f@h
+ ori r6,r6,1f@l
+ stw r6,TSS+TSS_EXPC(r2)
+
+ stb r3,0(r4)
+ li r3,0 /* successful return */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+1: li r3,-EFAULT /* bad access */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+
+_GLOBAL(__put_user_16)
+ /* setup exception stuff */
+ lis r2,current_set@ha
+ lwz r2,current_set@l(r2)
+ /* increment excount */
+ lwz r6,TSS+TSS_EXCOUNT(r2)
+ addi r6,r6,1
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ /* set expc */
+ lis r6,1f@h
+ ori r6,r6,1f@l
+ stw r6,TSS+TSS_EXPC(r2)
+
+ sth r3,0(r4)
+ li r3,0 /* successful return */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+1: li r3,-EFAULT /* bad access */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+
+_GLOBAL(__put_user_32)
+ /* setup exception stuff */
+ lis r2,current_set@ha
+ lwz r2,current_set@l(r2)
+ /* increment excount */
+ lwz r6,TSS+TSS_EXCOUNT(r2)
+ addi r6,r6,1
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ /* set expc */
+ lis r6,1f@h
+ ori r6,r6,1f@l
+ stw r6,TSS+TSS_EXPC(r2)
+
+ stw r3,0(r4)
+ li r3,0 /* successful return */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+1: li r3,-EFAULT /* bad access */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+
+_GLOBAL(__get_user_8)
+ /* setup exception stuff */
+ lis r2,current_set@ha
+ lwz r2,current_set@l(r2)
+ /* increment excount */
+ lwz r6,TSS+TSS_EXCOUNT(r2)
+ addi r6,r6,1
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ /* set expc */
+ lis r6,1f@h
+ ori r6,r6,1f@l
+ stw r6,TSS+TSS_EXPC(r2)
+
+ lbz r3,0(r4)
+ li r4,0 /* successful return */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+1: li r4,-EFAULT /* bad access */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+
+_GLOBAL(__get_user_16)
+ /* setup exception stuff */
+ lis r2,current_set@ha
+ lwz r2,current_set@l(r2)
+ /* increment excount */
+ lwz r6,TSS+TSS_EXCOUNT(r2)
+ addi r6,r6,1
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ /* set expc */
+ lis r6,1f@h
+ ori r6,r6,1f@l
+ stw r6,TSS+TSS_EXPC(r2)
+
+ lhz r3,0(r4)
+ li r4,0 /* successful return */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+1: li r4,-EFAULT /* bad access */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+
+_GLOBAL(__get_user_32)
+ /* setup exception stuff */
+ lis r2,current_set@ha
+ lwz r2,current_set@l(r2)
+ /* increment excount */
+ lwz r6,TSS+TSS_EXCOUNT(r2)
+ addi r6,r6,1
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ /* set expc */
+ lis r6,1f@h
+ ori r6,r6,1f@l
+ stw r6,TSS+TSS_EXPC(r2)
+ lwz r3,0(r4)
+ li r4,0 /* successful return */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+1: li r4,-EFAULT /* bad access */
+ li r6,0
+ stw r6,TSS+TSS_EXCOUNT(r2)
+ blr
+#endif
/*
* Disable interrupts
* rc = _disable_interrupts()
@@ -418,7 +608,9 @@ _GLOBAL(__ashldi3)
_GLOBAL(abort)
.long 0
-
+
+/* in include/asm/string.h now -- Cort */
+#if 0
_GLOBAL(bzero)
#define bufp r3
#define len r4
@@ -447,7 +639,9 @@ _GLOBAL(bzero)
20: stbu pat,1(bufp) /* Store value */
bdnz 20b /* Loop [based on counter] */
99: blr
+#endif
+
_GLOBAL(abs)
cmpi 0,r3,0
bge 10f
@@ -474,18 +668,22 @@ _GLOBAL(_get_PVR)
* Create a kernel thread
* __kernel_thread(flags, fn, arg)
*/
-#if 0
+#if 1
#define SYS_CLONE 120
_GLOBAL(__kernel_thread)
__kernel_thread:
li r0,SYS_CLONE
sc
- cmpi 0,r3,0
- bnelr
- mtlr r4
- mr r3,r5
+ cmpi 0,r3,0 /* parent or child? */
+ bnelr /* return if parent */
+ mtlr r4 /* fn addr in lr */
+ mr r3,r5 /* load arg and call fn */
blr
+ li 0, 1 /* exit after child exits */
+ li 3, 0
+ sc
#endif
+
/* Why isn't this a) automatic, b) written in 'C'? */
.data
.align 4
@@ -655,5 +853,7 @@ sys_call_table:
.long sys_sched_rr_get_interval
.long sys_nanosleep
.long sys_mremap
- .space (NR_syscalls-163)*4
+ .long SYMBOL_NAME(sys_setresuid)
+ .long SYMBOL_NAME(sys_getresuid)
+ .space (NR_syscalls-165)*4
diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c
index e63e5c04a..5e6789a1d 100644
--- a/arch/ppc/kernel/mk_defs.c
+++ b/arch/ppc/kernel/mk_defs.c
@@ -25,6 +25,8 @@ main(int argc, char *argv[])
FILE *out;
struct task_struct task;
struct thread_struct tss;
+ int i;
+ char s[256];
struct pt_regs regs;
if (!(out = fopen(argv[1], "w")))
{
@@ -62,6 +64,8 @@ main(int argc, char *argv[])
put_line(out, "MMU_SEG13", (int)&tss.segs[13]-(int)&tss);
put_line(out, "MMU_SEG14", (int)&tss.segs[14]-(int)&tss);
put_line(out, "MMU_SEG15", (int)&tss.segs[15]-(int)&tss);
+ put_line(out, "TSS_EXPC", (int)&tss.expc-(int)&tss);
+ put_line(out, "TSS_EXCOUNT", (int)&tss.excount-(int)&tss);
put_line(out, "TSS_FPR0", (int)&tss.fpr[0]-(int)&tss);
put_line(out, "TSS_FPR1", (int)&tss.fpr[1]-(int)&tss);
put_line(out, "TSS_FPR2", (int)&tss.fpr[2]-(int)&tss);
@@ -94,6 +98,7 @@ main(int argc, char *argv[])
put_line(out, "TSS_FPR29", (int)&tss.fpr[29]-(int)&tss);
put_line(out, "TSS_FPR30", (int)&tss.fpr[30]-(int)&tss);
put_line(out, "TSS_FPR31", (int)&tss.fpr[31]-(int)&tss);
+ put_line(out, "TSS_FP_USED", (int)&tss.fp_used-(int)&tss);
/* Interrupt register frame */
put_line(out, "INT_FRAME_SIZE", sizeof(regs));
put_line(out, "GPR0", (int)&regs.gpr[0]-(int)&regs);
@@ -128,14 +133,19 @@ main(int argc, char *argv[])
put_line(out, "GPR29", (int)&regs.gpr[29]-(int)&regs);
put_line(out, "GPR30", (int)&regs.gpr[30]-(int)&regs);
put_line(out, "GPR31", (int)&regs.gpr[31]-(int)&regs);
- put_line(out, "FPR0", (int)&regs.fpr[0]-(int)&regs);
- put_line(out, "FPR1", (int)&regs.fpr[1]-(int)&regs);
- put_line(out, "FPR2", (int)&regs.fpr[2]-(int)&regs);
- put_line(out, "FPR3", (int)&regs.fpr[3]-(int)&regs);
+#if 0
+ for ( i = 0 ; i <= 31 ; i++)
+ {
+ sprintf(s,"FPR%d",i);
+ put_line(out, s, (int)&regs.fpr[i]-(int)&regs);
+ }
+#endif
put_line(out, "FPCSR", (int)&regs.fpcsr-(int)&regs);
/* Note: these symbols include "_" because they overlap with special register names */
put_line(out, "_NIP", (int)&regs.nip-(int)&regs);
put_line(out, "_MSR", (int)&regs.msr-(int)&regs);
+ /* put_line(out, "_SRR1", (int)&regs.srr1-(int)&regs);
+ put_line(out, "_SRR0", (int)&regs.srr0-(int)&regs); */
put_line(out, "_CTR", (int)&regs.ctr-(int)&regs);
put_line(out, "_LINK", (int)&regs.link-(int)&regs);
put_line(out, "_CCR", (int)&regs.ccr-(int)&regs);
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index ff50a6c5e..74f796792 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -145,7 +145,38 @@ static char BeBox_pci_IRQ_routes[] =
15 /* Line 4 */
};
-/* #define PCI_DEBUG */
+/* IBM Nobis */
+static char Nobis_pci_IRQ_map[16] =
+ {
+ 0, /* Slot 0 - unused */
+ 0, /* Slot 1 - unused */
+ 0, /* Slot 2 - unused */
+ 0, /* Slot 3 - unused */
+ 0, /* Slot 4 - unused */
+ 0, /* Slot 5 - unused */
+ 0, /* Slot 6 - unused */
+ 0, /* Slot 7 - unused */
+ 0, /* Slot 8 - unused */
+ 0, /* Slot 9 - unused */
+ 0, /* Slot 10 - unused */
+ 0, /* Slot 11 - unused */
+ 3, /* Slot 12 - SCSI */
+ 0, /* Slot 13 - unused */
+ 0, /* Slot 14 - unused */
+ 0, /* Slot 15 - unused */
+ };
+
+static char Nobis_pci_IRQ_routes[] =
+ {
+ 0, /* Line 0 - Unused */
+ 13, /* Line 1 */
+ 13, /* Line 2 */
+ 13, /* Line 3 */
+ 13 /* Line 4 */
+ };
+
+#define PCI_DEBUG
+#undef PCI_DEBUG
#ifdef PCI_STATS
int PCI_conversions[2];
@@ -460,6 +491,11 @@ void route_PCI_interrupts(void)
Motherboard_map = BeBox_pci_IRQ_map;
Motherboard_routes = BeBox_pci_IRQ_routes;
} else
+ if ((_get_PVR()>>16) == 1)
+ { /* Nobis */
+ Motherboard_map = Nobis_pci_IRQ_map;
+ Motherboard_routes = Nobis_pci_IRQ_routes;
+ } else
{ /* Motorola hardware */
switch (inb(0x800) & 0xF0)
{
diff --git a/arch/ppc/kernel/port_io.c b/arch/ppc/kernel/port_io.c
index 3693112b2..e886705e1 100644
--- a/arch/ppc/kernel/port_io.c
+++ b/arch/ppc/kernel/port_io.c
@@ -141,3 +141,9 @@ unsigned char outb_p(unsigned char val,int port) { return (outb(val,port)); }
unsigned short outw_p(unsigned short val,int port) { return (outw(val,port)); }
unsigned long outl_p(unsigned long val,int port) { return (outl(val,port)); }
+
+/* makes writing to the ibm acorn power management stuff easier -- Cort */
+/* args in forn of PA.B as in tech spec for ibm carolina */
+void ibm_write(unsigned char val,unsigned int port)
+{
+}
diff --git a/arch/ppc/kernel/ppc_asm.tmpl b/arch/ppc/kernel/ppc_asm.tmpl
index b6fa91a3c..5d357be22 100644
--- a/arch/ppc/kernel/ppc_asm.tmpl
+++ b/arch/ppc/kernel/ppc_asm.tmpl
@@ -17,6 +17,8 @@ _EXTERN(n):
#else
#define _EXTERN(n) n
+#define SYMBOL_NAME(x) x
+
#define _GLOBAL(n)\
.globl n;\
n:
diff --git a/arch/ppc/kernel/ppc_defs.h b/arch/ppc/kernel/ppc_defs.h
deleted file mode 100644
index 1965f83e1..000000000
--- a/arch/ppc/kernel/ppc_defs.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * WARNING! This file is automatically generated - DO NOT EDIT!
- */
-#define STATE 0
-#define COUNTER 4
-#define BLOCKED 16
-#define SIGNAL 12
-#define KERNEL_STACK_PAGE 88
-#define TSS 528
-#define KSP 0
-#define LAST_PC 72
-#define USER_STACK 76
-#define PT_REGS 340
-#define PF_TRACESYS 32
-#define TASK_FLAGS 20
-#define MMU_SEG0 8
-#define MMU_SEG1 12
-#define MMU_SEG2 16
-#define MMU_SEG3 20
-#define MMU_SEG4 24
-#define MMU_SEG5 28
-#define MMU_SEG6 32
-#define MMU_SEG7 36
-#define MMU_SEG8 40
-#define MMU_SEG9 44
-#define MMU_SEG10 48
-#define MMU_SEG11 52
-#define MMU_SEG12 56
-#define MMU_SEG13 60
-#define MMU_SEG14 64
-#define MMU_SEG15 68
-#define TSS_FPR0 80
-#define TSS_FPR1 88
-#define TSS_FPR2 96
-#define TSS_FPR3 104
-#define TSS_FPR4 112
-#define TSS_FPR5 120
-#define TSS_FPR6 128
-#define TSS_FPR7 136
-#define TSS_FPR8 144
-#define TSS_FPR9 152
-#define TSS_FPR10 160
-#define TSS_FPR11 168
-#define TSS_FPR12 176
-#define TSS_FPR13 184
-#define TSS_FPR14 192
-#define TSS_FPR15 200
-#define TSS_FPR16 208
-#define TSS_FPR17 216
-#define TSS_FPR18 224
-#define TSS_FPR19 232
-#define TSS_FPR20 240
-#define TSS_FPR21 248
-#define TSS_FPR22 256
-#define TSS_FPR23 264
-#define TSS_FPR24 272
-#define TSS_FPR25 280
-#define TSS_FPR26 288
-#define TSS_FPR27 296
-#define TSS_FPR28 304
-#define TSS_FPR29 312
-#define TSS_FPR30 320
-#define TSS_FPR31 328
-#define INT_FRAME_SIZE 384
-#define GPR0 56
-#define GPR1 60
-#define GPR2 64
-#define GPR3 68
-#define GPR4 72
-#define GPR5 76
-#define GPR6 80
-#define GPR7 84
-#define GPR8 88
-#define GPR9 92
-#define GPR10 96
-#define GPR11 100
-#define GPR12 104
-#define GPR13 108
-#define GPR14 112
-#define GPR15 116
-#define GPR16 120
-#define GPR17 124
-#define GPR18 128
-#define GPR19 132
-#define GPR20 136
-#define GPR21 140
-#define GPR22 144
-#define GPR23 148
-#define GPR24 152
-#define GPR25 156
-#define GPR26 160
-#define GPR27 164
-#define GPR28 168
-#define GPR29 172
-#define GPR30 176
-#define GPR31 180
-#define FPR0 248
-#define FPR1 256
-#define FPR2 264
-#define FPR3 272
-#define FPCSR 280
-#define _NIP 184
-#define _MSR 188
-#define _CTR 192
-#define _LINK 196
-#define _CCR 200
-#define _XER 204
-#define _DAR 208
-#define _DSISR 212
-#define _HASH1 216
-#define _HASH2 220
-#define _IMISS 224
-#define _DMISS 228
-#define _ICMP 232
-#define _DCMP 236
-#define ORIG_GPR3 240
-#define RESULT 244
-#define TRAP 288
-#define MARKER 292
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 11ddb7678..8dc0e61ca 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 1995 Linus Torvalds
* Adapted for PowerPC by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
*/
/*
@@ -13,73 +14,157 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
-#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <asm/pgtable.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/ppc_machine.h>
+int dump_fpu(void);
+void hard_reset_now(void);
+void switch_to(struct task_struct *, struct task_struct *);
+void copy_thread(int,unsigned long,unsigned long,struct task_struct *,
+ struct pt_regs *);
+void print_backtrace(unsigned long *);
int
-dump_fpu()
+dump_fpu(void)
{
- return (1);
+ return (1);
}
+
+/* check to make sure the kernel stack is healthy */
+int check_stack(struct task_struct *tsk)
+{
+ extern unsigned long init_kernel_stack[PAGE_SIZE/sizeof(long)];
+ int ret = 0;
+ int i;
+
+ /* skip check in init_kernel_task -- swapper */
+ if ( tsk->kernel_stack_page == (unsigned long)&init_kernel_stack )
+ return;
+ /* check bounds on stack -- above/below kstack page */
+ if ( (tsk->tss.ksp-1 & KERNEL_STACK_MASK) != tsk->kernel_stack_page )
+ {
+ printk("check_stack(): not in bounds %s/%d ksp %x/%x\n",
+ tsk->comm,tsk->pid,tsk->tss.ksp,tsk->kernel_stack_page);
+ ret |= 1;
+ }
+
+ /* check for magic on kstack */
+ if ( *(unsigned long *)(tsk->kernel_stack_page) != STACK_MAGIC)
+ {
+ printk("check_stack(): no magic %s/%d ksp %x/%x magic %x\n",
+ tsk->comm,tsk->pid,tsk->tss.ksp,tsk->kernel_stack_page,
+ *(unsigned long *)(tsk->kernel_stack_page));
+ ret |= 2;
+ }
+
+#ifdef KERNEL_STACK_BUFFER
+ /* check extra padding page under kernel stack */
+ for ( i = PAGE_SIZE/sizeof(long) ; i >= 1; i--)
+ {
+ struct pt_regs *regs;
+
+ if ( *((unsigned long *)(tsk->kernel_stack_page)-1) )
+ {
+ printk("check_stack(): padding touched %s/%d ksp %x/%x value %x/%d\n",
+ tsk->comm,tsk->pid,tsk->tss.ksp,tsk->kernel_stack_page,
+ *(unsigned long *)(tsk->kernel_stack_page-i),i*sizeof(long));
+ regs = (struct pt_regs *)(tsk->kernel_stack_page-(i*sizeof(long)));
+ printk("marker %x trap %x\n", regs->marker,regs->trap);
+ print_backtrace((unsigned long *)(tsk->tss.ksp));
+
+ ret |= 4;
+ break;
+ }
+ }
+#endif
+
+#if 0
+ if (ret)
+ panic("bad stack");
+#endif
+ return(ret);
+}
+
+
void
switch_to(struct task_struct *prev, struct task_struct *new)
{
struct pt_regs *regs;
struct thread_struct *new_tss, *old_tss;
int s = _disable_interrupts();
- regs = new->tss.ksp;
+ regs = (struct pt_regs *)(new->tss.ksp);
+#if 1
+ check_stack(prev);
+ check_stack(new);
+#endif
+ /* if a process has used fp 15 times, then turn
+ on the fpu for good otherwise turn it on with the fp
+ exception handler as needed.
+ skip this for kernel tasks.
+ -- Cort */
+ if ( (regs->msr & MSR_FP)&&(regs->msr & MSR_PR)&&(new->tss.fp_used < 15) )
+ {
#if 0
- printk("Task %x(%d) -> %x(%d)", current, current->pid, new, new->pid);
- printk(" - IP: %x, SR: %x, SP: %x\n", regs->nip, regs->msr, regs);
+ printk("turning off fpu: %s/%d fp_used %d\n",
+ new->comm,new->pid,new->tss.fp_used);
+#endif
+ regs->msr = regs->msr & ~MSR_FP;
+ }
+#if 0
+ printk("%s/%d -> %s/%d\n",prev->comm,prev->pid,new->comm,new->pid);
#endif
new_tss = &new->tss;
old_tss = &current->tss;
- current_set[0] = new; /* FIX ME! */
+ current_set[0] = new;
_switch(old_tss, new_tss);
-#if 0
- printk("Back in task %x(%d)\n", current, current->pid);
-#endif
_enable_interrupts(s);
}
+asmlinkage int sys_debug(unsigned long r3)
+{
+ lock_kernel();
+ if (!strcmp(current->comm,"crashme"))
+ printk("sys_debug(): r3 (syscall) %d\n", r3);
+ unlock_kernel();
+ return 0;
+}
+
asmlinkage int sys_idle(void)
{
+ int ret = -EPERM;
+
+ lock_kernel();
if (current->pid != 0)
- return -EPERM;
+ goto out;
/* endless idle loop with no priority at all */
current->counter = -100;
for (;;) {
schedule();
}
-}
-
-void hard_reset_now(void)
-{
- halt();
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
void show_regs(struct pt_regs * regs)
{
- _panic("show_regs");
}
-/*
- * Free current thread data structures etc..
- */
void exit_thread(void)
{
}
@@ -96,30 +181,34 @@ release_thread(struct task_struct *t)
/*
* Copy a thread..
*/
-void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct task_struct * p, struct pt_regs * regs)
{
int i;
SEGREG *segs;
struct pt_regs * childregs;
-#if 0
-printk("copy thread - NR: %d, Flags: %x, USP: %x, Task: %x, Regs: %x\n", nr, clone_flags, usp, p, regs);
-#endif
+
/* Construct segment registers */
- segs = p->tss.segs;
+ segs = (SEGREG *)(p->tss.segs);
for (i = 0; i < 8; i++)
{
segs[i].ks = 0;
segs[i].kp = 1;
+#if 0
segs[i].vsid = i | (nr << 4);
+#else
+ segs[i].vsid = i | ((nr * 10000) << 4);
+#endif
}
if ((p->mm->context == 0) || (p->mm->count == 1))
{
- p->mm->context = (nr<<4);
-#if 0
-printk("Setting MM[%x] Context = %x Task = %x Current = %x/%x\n", p->mm, p->mm->context, p, current, current->mm);
+#if 0
+ p->mm->context = ((nr)<<4);
+#else
+ p->mm->context = ((nr*10000)<<4);
#endif
}
+
/* Last 8 are shared with kernel & everybody else... */
for (i = 8; i < 16; i++)
{
@@ -127,22 +216,23 @@ printk("Setting MM[%x] Context = %x Task = %x Current = %x/%x\n", p->mm, p->mm->
segs[i].kp = 1;
segs[i].vsid = i;
}
+
/* Copy registers */
-#ifdef STACK_HAS_TWO_PAGES
- childregs = ((struct pt_regs *) (p->kernel_stack_page + 2*PAGE_SIZE)) - 2;
-#else
- childregs = ((struct pt_regs *) (p->kernel_stack_page + 1*PAGE_SIZE)) - 2;
-#endif
+ childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 2;
+
*childregs = *regs; /* STRUCT COPY */
childregs->gpr[3] = 0; /* Result from fork() */
- p->tss.ksp = childregs;
+ p->tss.ksp = (unsigned long)(childregs);
if (usp >= (unsigned long)regs)
{ /* Stack is in kernel space - must adjust */
- childregs->gpr[1] = childregs+1;
+ childregs->gpr[1] = (long)(childregs+1);
} else
{ /* Provided stack is in user space */
childregs->gpr[1] = usp;
}
+ p->tss.fp_used = 0;
+
+ return 0;
}
/*
@@ -152,43 +242,17 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
{
}
-#if 0
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
-{
- regs->nip = eip;
- regs->gpr[1] = esp;
- regs->msr = MSR_USER;
-#if 0
-{
- int len;
- len = (unsigned long)0x80000000 - esp;
- if (len > 128) len = 128;
- printk("Start thread [%x] at PC: %x, SR: %x, SP: %x\n", regs, eip, regs->msr, esp);
- dump_buf(esp, len);
- dump_buf(eip, 0x80);
-}
-#endif
-}
-#endif
asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
{
- return do_fork(SIGCHLD, regs->gpr[1], regs);
+ int ret;
+
+ lock_kernel();
+ ret = do_fork(SIGCHLD, regs->gpr[1], regs);
+ unlock_kernel();
+ return ret;
}
-/*
- * sys_execve() executes a new program.
- *
- * This works due to the PowerPC calling sequence: the first 6 args
- * are gotten from registers, while the rest is on the stack, so
- * we get a0-a5 for free, and then magically find "struct pt_regs"
- * on the stack for us..
- *
- * Don't do this at home.
- */
asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs *regs)
@@ -196,12 +260,31 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
int error;
char * filename;
- error = getname((char *) a0, &filename);
- if (error)
+ lock_kernel();
+ /* getname does it's own verification of the address
+ when it calls get_max_filename() but
+ it will assume it's valid if get_fs() == KERNEL_DS
+ which is always true on the ppc so we check
+ it here
+
+ this doesn't completely check any of these data structures,
+ it just makes sure that the 1st long is in a good area
+ and from there we assume that it's safe then
+ -- Cort
+ */
+ /* works now since get_fs/set_fs work properly */
+#if 0
+ if ( verify_area(VERIFY_READ,(void *)a0,1)
+ && verify_area(VERIFY_READ,(void *)a1,1)
+ && verify_area(VERIFY_READ,(void *)a2,1)
+ )
{
-printk("Error getting EXEC name: %d\n", error);
- return error;
+ return -EFAULT;
}
+#endif
+ error = getname((char *) a0, &filename);
+ if (error)
+ goto out;
flush_instruction_cache();
error = do_execve(filename, (char **) a1, (char **) a2, regs);
#if 0
@@ -211,30 +294,32 @@ printk("EXECVE - file = '%s', error = %d\n", filename, error);
}
#endif
putname(filename);
+out:
+ unlock_kernel();
return error;
}
-/*
- * This doesn't actually work correctly like this: we need to do the
- * same stack setups that fork() does first.
- */
asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
{
unsigned long clone_flags = p1;
int res;
+
+ lock_kernel();
res = do_fork(clone_flags, regs->gpr[1], regs);
+ unlock_kernel();
return res;
}
void
print_backtrace(unsigned long *sp)
{
+#if 0
int cnt = 0;
printk("... Call backtrace:\n");
- while (*sp)
+ while (verify_area(VERIFY_READ,sp,sizeof(long)) && *sp)
{
printk("%08X ", sp[1]);
- sp = *sp;
+ sp = (unsigned long *)*sp;
if (++cnt == 8)
{
printk("\n");
@@ -242,17 +327,19 @@ print_backtrace(unsigned long *sp)
if (cnt > 32) break;
}
printk("\n");
+#endif
}
void
print_user_backtrace(unsigned long *sp)
{
+#if 0
int cnt = 0;
printk("... [User] Call backtrace:\n");
- while (valid_addr(sp) && *sp)
+ while (verify_area(VERIFY_READ,sp,sizeof(long)) && *sp)
{
printk("%08X ", sp[1]);
- sp = *sp;
+ sp = (unsigned long *)*sp;
if (++cnt == 8)
{
printk("\n");
@@ -260,11 +347,23 @@ print_user_backtrace(unsigned long *sp)
if (cnt > 16) break;
}
printk("\n");
+#endif
}
void
print_kernel_backtrace(void)
{
+#if 0
unsigned long *_get_SP(void);
print_backtrace(_get_SP());
+#endif
+}
+inline void start_thread(struct pt_regs * regs,
+ unsigned long eip, unsigned long esp)
+{
+ regs->nip = eip;
+ regs->gpr[1] = esp;
+ regs->msr = MSR_USER;
+ set_fs(USER_DS);
}
+
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
index dc4012f57..2d960c8cd 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/ppc/kernel/ptrace.c
@@ -7,6 +7,7 @@
*
* Adapted from 'linux/arch/m68k/kernel/ptrace.c'
* PowerPC version by Gary Thomas (gdt@linuxppc.org)
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file README.legal in the main directory of
@@ -17,6 +18,8 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
@@ -264,7 +267,7 @@ static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigne
struct vm_area_struct * vma;
addr &= PAGE_MASK;
- vma = find_vma(tsk,addr);
+ vma = find_vma(tsk->mm,addr);
if (!vma)
return NULL;
if (vma->vm_start <= addr)
@@ -375,34 +378,37 @@ static int write_long(struct task_struct * tsk, unsigned long addr,
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
- struct user * dummy;
-
- dummy = NULL;
+ struct user * dummy = NULL;
+ int ret = -EPERM;
+ lock_kernel();
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
if (current->flags & PF_PTRACED)
- return -EPERM;
+ goto out;
/* set the ptrace bit in the process flags. */
current->flags |= PF_PTRACED;
- return 0;
+ ret = 0;
+ goto out;
}
if (pid == 1) /* you may not mess with init */
- return -EPERM;
+ goto out;
+ ret = -ESRCH;
if (!(child = get_task(pid)))
- return -ESRCH;
+ goto out;
+ ret = -EPERM;
if (request == PTRACE_ATTACH) {
if (child == current)
- return -EPERM;
+ goto out;
if ((!child->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->gid)) && !suser())
- return -EPERM;
+ goto out;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
- return -EPERM;
+ goto out;
child->flags |= PF_PTRACED;
if (child->p_pptr != current) {
REMOVE_LINKS(child);
@@ -410,73 +416,75 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
SET_LINKS(child);
}
send_sig(SIGSTOP, child, 1);
- return 0;
+ ret = 0;
+ goto out;
}
+ ret = -ESRCH;
if (!(child->flags & PF_PTRACED))
- return -ESRCH;
+ goto out;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
- return -ESRCH;
+ goto out;
}
if (child->p_pptr != current)
- return -ESRCH;
+ goto out;
switch (request) {
/* If I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
unsigned long tmp;
- int res;
- res = read_long(child, addr, &tmp);
- if (res < 0)
- return res;
- res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
- if (!res)
+ ret = read_long(child, addr, &tmp);
+ if (ret < 0)
+ goto out;
+ ret = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
+ if (!ret)
put_user(tmp, (unsigned long *) data);
- return res;
+ goto out;
}
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp;
- int res;
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
return -EIO;
- res = verify_area(VERIFY_WRITE, (void *) data,
+ ret = verify_area(VERIFY_WRITE, (void *) data,
sizeof(long));
- if (res)
- return res;
+ if (ret)
+ goto out;
tmp = 0; /* Default return condition */
addr = addr >> 2; /* temporary hack. */
- if (addr < PT_FPR0) {
+ if (addr < PT_FPR0)
tmp = get_reg(child, addr);
- }
#if 0
else if (addr >= PT_FPR0 && addr < PT_FPR31)
tmp = child->tss.fpr[addr - PT_FPR0];
#endif
else
- return -EIO;
- put_user(tmp,(unsigned long *) data);
- return 0;
+ ret = -EIO;
+ if(!ret)
+ put_user(tmp,(unsigned long *) data);
+ goto out;
}
/* If I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
- return write_long(child,addr,data);
+ ret = write_long(child,addr,data);
+ goto out;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ ret = -EIO;
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
- return -EIO;
+ goto out;
addr = addr >> 2; /* temporary hack. */
if (addr == PT_ORIG_R3)
- return -EIO;
+ goto out;
#if 0 /* Let this check be in 'put_reg' */
if (addr == PT_SR) {
data &= SR_MASK;
@@ -486,22 +494,24 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
#endif
if (addr < PT_FPR0) {
if (put_reg(child, addr, data))
- return -EIO;
- return 0;
+ goto out;
+ ret = 0;
+ goto out;
}
#if 0
- if (addr >= 21 && addr < 48)
- {
+ if (addr >= 21 && addr < 48) {
child->tss.fp[addr - 21] = data;
- return 0;
+ ret = 0;
+ goto out;
}
#endif
- return -EIO;
+ goto out;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
+ ret = -EIO;
if ((unsigned long) data >= NSIG)
- return -EIO;
+ goto out;
if (request == PTRACE_SYSCALL)
child->flags |= PF_TRACESYS;
else
@@ -510,7 +520,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
wake_up_process(child);
/* make sure the single step bit is not set. */
clear_single_step(child);
- return 0;
+ ret = 0;
+ goto out;
}
/*
@@ -519,29 +530,33 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
* exit.
*/
case PTRACE_KILL: {
+ ret = 0;
if (child->state == TASK_ZOMBIE) /* already dead */
- return 0;
+ goto out;
wake_up_process(child);
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
clear_single_step(child);
- return 0;
+ goto out;
}
case PTRACE_SINGLESTEP: { /* set the trap flag. */
+ ret = -EIO;
if ((unsigned long) data >= NSIG)
- return -EIO;
+ goto out;
child->flags &= ~PF_TRACESYS;
set_single_step(child);
wake_up_process(child);
child->exit_code = data;
/* give it a chance to run. */
- return 0;
+ ret = 0;
+ goto out;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
+ ret = -EIO;
if ((unsigned long) data >= NSIG)
- return -EIO;
+ goto out;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
wake_up_process(child);
child->exit_code = data;
@@ -550,19 +565,25 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
SET_LINKS(child);
/* make sure the single step bit is not set. */
clear_single_step(child);
- return 0;
+ ret = 0;
+ goto out;
}
default:
- return -EIO;
+ ret = -EIO;
+ goto out;
}
+out:
+ unlock_kernel();
+ return ret;
}
asmlinkage void syscall_trace(void)
{
+ lock_kernel();
if ((current->flags & (PF_PTRACED|PF_TRACESYS))
!= (PF_PTRACED|PF_TRACESYS))
- return;
+ goto out;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
notify_parent(current);
@@ -575,5 +596,6 @@ asmlinkage void syscall_trace(void)
if (current->exit_code)
current->signal |= (1 << (current->exit_code - 1));
current->exit_code = 0;
- return;
+out:
+ unlock_kernel();
}
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 6f330b052..25f03cc11 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
*/
/*
@@ -17,23 +18,22 @@
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
-#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <linux/major.h>
-#define SIO_CONFIG_RA 0x398
-#define SIO_CONFIG_RD 0x399
-
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/residual.h>
+#include <asm/io.h>
#include <asm/pgtable.h>
extern unsigned long *end_of_DRAM;
extern PTE *Hash;
extern unsigned long Hash_size, Hash_mask;
-
-char sda_root[] = "root=/dev/sda1";
-extern int root_mountflags;
+extern int probingmem;
+unsigned long empty_zero_page[1024];
unsigned char aux_device_present;
#ifdef CONFIG_BLK_DEV_RAM
@@ -42,6 +42,14 @@ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
extern int rd_image_start; /* starting block # of image */
#endif
+#undef HASHSTATS
+
+extern unsigned long isBeBox[];
+
+/* copy of the residual data */
+RESIDUAL res;
+unsigned long resptr = 0; /* ptr to residual data from hw */
+
/*
* The format of "screen_info" is strange, and due to early
* i386-setup code. This is just enough to make the console
@@ -51,196 +59,351 @@ extern int rd_image_start; /* starting block # of image */
-- Cort
*/
struct screen_info screen_info = {
- 0, 25, /* orig-x, orig-y */
- { 0, 0 }, /* unused */
- 0, /* orig-video-page */
- 0, /* orig-video-mode */
- 80, /* orig-video-cols */
- 0,0,0, /* ega_ax, ega_bx, ega_cx */
- 25, /* orig-video-lines */
- 1, /* orig-video-isVGA */
- 16 /* orig-video-points */
+ 0, 25, /* orig-x, orig-y */
+ { 0, 0 }, /* unused */
+ 0, /* orig-video-page */
+ 0, /* orig-video-mode */
+ 80, /* orig-video-cols */
+ 0,0,0, /* ega_ax, ega_bx, ega_cx */
+ 25, /* orig-video-lines */
+ 1, /* orig-video-isVGA */
+ 16 /* orig-video-points */
};
unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
{
- return memory_start;
+ return memory_start;
}
-unsigned long find_end_of_memory(void)
+#ifdef HASHSTATS
+unsigned long *hashhits;
+#endif
+
+extern unsigned long _TotalMemory;
+/* find the physical size of RAM and setup hardware hash table */
+unsigned long *find_end_of_memory(void)
{
- unsigned char dram_size = inb(0x0804);
- unsigned long total;
- extern BAT BAT2;
-printk("DRAM Size = %x\n", dram_size);
-printk("Config registers = %x/%x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802), inb(0x0803));
- switch (dram_size & 0x07)
- {
- case 0:
- total = 0x08000000; /* 128M */
- break;
- case 1:
- total = 0x02000000; /* 32M */
- break;
- case 2:
- total = 0x00800000; /* 8M */
- break;
- case 3:
- total = 0x00400000; /* 4M - can't happen! */
- break;
- case 4:
- total = 0x10000000; /* 256M */
- break;
- case 5:
- total = 0x04000000; /* 64M */
- break;
- case 6:
- total = 0x01000000; /* 16M */
- break;
- case 7:
- total = 0x04000000; /* Can't happen */
- break;
- }
- switch ((dram_size>>4) & 0x07)
- {
- case 0:
- total += 0x08000000; /* 128M */
- break;
- case 1:
- total += 0x02000000; /* 32M */
- break;
- case 2:
- total += 0x00800000; /* 8M */
- break;
- case 3:
- total += 0x00000000; /* Module not present */
- break;
- case 4:
- total += 0x10000000; /* 256M */
- break;
- case 5:
- total += 0x04000000; /* 64M */
- break;
- case 6:
- total += 0x01000000; /* 16M */
- break;
- case 7:
- total += 0x00000000; /* Module not present */
- break;
- }
-/* TEMP */ total = 0x01000000;
-/* _cnpause(); */
-/* CAUTION!! This can be done more elegantly! */
- if (total < 0x01000000)
- {
- Hash_size = HASH_TABLE_SIZE_64K;
- Hash_mask = HASH_TABLE_MASK_64K;
- } else
- {
- Hash_size = HASH_TABLE_SIZE_128K;
- Hash_mask = HASH_TABLE_MASK_128K;
- }
- switch(total)
- {
- case 0x01000000:
-/* BAT2[0][1] = BL_16M;*/
- break;
- default:
- printk("WARNING: setup.c: find_end_of_memory() unknown total ram size %x\n", total);
- break;
- }
-
- Hash = (PTE *)((total-Hash_size)+KERNELBASE);
- bzero(Hash, Hash_size);
- return ((unsigned long)Hash);
+ extern BAT BAT2;
+ _TotalMemory = res.TotalMemory;
+
+ if (_TotalMemory == 0 )
+ {
+ printk("Ramsize from residual data was 0 -- Probing for value\n");
+ /* this needs be done differently since the bats actually map
+ addresses beyond physical memory! -- Cort */
+#if 0
+ probingmem = 1;
+ while ( probingmem )
+ {
+ _TotalMemory += 0x00800000; /* 8M */
+ *(unsigned long *)_TotalMemory+KERNELBASE;
+ }
+ _TotalMemory -= 0x00800000;
+#else
+ _TotalMemory = 0x03000000;
+#endif
+ printk("Ramsize probed to be %dM\n", _TotalMemory>>20);
+ }
+
+ /* setup BAT2 mapping so that it covers kernelbase to kernelbase+ramsize */
+ switch(_TotalMemory)
+ {
+ case 0x01000000: /* 16M */
+ BAT2.batu.bl = BL_16M;
+ Hash_size = HASH_TABLE_SIZE_128K;
+ Hash_mask = HASH_TABLE_MASK_128K;
+ break;
+ case 0x00800000: /* 8M */
+ BAT2.batu.bl = BL_8M;
+ Hash_size = HASH_TABLE_SIZE_64K;
+ Hash_mask = HASH_TABLE_MASK_64K;
+ break;
+ case 0x01800000: /* 24M */
+ case 0x02000000: /* 32M */
+ BAT2.batu.bl = BL_32M;
+ Hash_size = HASH_TABLE_SIZE_256K;
+ Hash_mask = HASH_TABLE_MASK_256K;
+ break;
+ case 0x03000000: /* 48M */
+ case 0x04000000: /* 64M */
+ BAT2.batu.bl = BL_64M;
+ Hash_size = HASH_TABLE_SIZE_512K;
+ Hash_mask = HASH_TABLE_MASK_512K;
+ break;
+ case 0x05000000: /* 80M */
+ BAT2.batu.bl = BL_128M;
+ Hash_size = HASH_TABLE_SIZE_1M;
+ Hash_mask = HASH_TABLE_MASK_1M;
+ break;
+ default:
+ printk("WARNING: setup.c: find_end_of_memory() unknown total ram size %x\n",
+ _TotalMemory);
+ break;
+ }
+
+ Hash = (PTE *)((_TotalMemory-Hash_size)+KERNELBASE);
+ bzero(Hash, Hash_size);
+
+
+#ifdef HASHSTATS
+ hashhits = (unsigned long *)Hash - (Hash_size/sizeof(struct _PTE))/2;
+ bzero(hashhits, (Hash_size/sizeof(struct _PTE))/2);
+ return ((unsigned long *)hashhits);
+#else
+ return ((unsigned long *)Hash);
+#endif
}
int size_memory;
-/* #define DEFAULT_ROOT_DEVICE 0x0200 /* fd0 */
-#define DEFAULT_ROOT_DEVICE 0x0801 /* sda1 */
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
+#ifdef CONFIG_APM
+#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
+#endif
+#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
+#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
+#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
+#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
+#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
+#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
+#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
+#define KERNEL_START (*(unsigned long *) (PARAM+0x214))
+#define INITRD_START (*(unsigned long *) (PARAM+0x218))
+#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
+#define COMMAND_LINE ((char *) (PARAM+2048))
+#define COMMAND_LINE_SIZE 256
+
+#define RAMDISK_IMAGE_START_MASK 0x07FF
+#define RAMDISK_PROMPT_FLAG 0x8000
+#define RAMDISK_LOAD_FLAG 0x4000
+
+static char command_line[COMMAND_LINE_SIZE] = { 0, };
+ char saved_command_line[COMMAND_LINE_SIZE];
-void setup_arch(char **cmdline_p,
- unsigned long * memory_start_p, unsigned long * memory_end_p)
+
+void
+setup_arch(char **cmdline_p, unsigned long * memory_start_p,
+ unsigned long * memory_end_p)
{
- extern int _end;
- extern char cmd_line[];
- unsigned char reg;
-
- /* Set up floppy in PS/2 mode */
- outb(0x09, SIO_CONFIG_RA);
- reg = inb(SIO_CONFIG_RD);
- reg = (reg & 0x3F) | 0x40;
- outb(reg, SIO_CONFIG_RD);
- outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */
- ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE);
- /*ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255);*/ /* nfs */
- aux_device_present = 0xaa;
+ extern int _end;
+ extern char cmd_line[];
+ unsigned char reg;
+ extern int panic_timeout;
+ char inf[512];
+ int i;
+
+ if (isBeBox[0])
+ _Processor = _PROC_Be;
+ else
+ {
+ if (strncmp(res.VitalProductData.PrintableModel,"IBM",3))
+ {
+ _Processor = _PROC_Motorola;
+ }
+ else
+ _Processor = _PROC_IBM;
+ }
+
+ get_cpuinfo(&inf);
+ printk("%s",inf);
+
+ /* Set up floppy in PS/2 mode */
+ outb(0x09, SIO_CONFIG_RA);
+ reg = inb(SIO_CONFIG_RD);
+ reg = (reg & 0x3F) | 0x40;
+ outb(reg, SIO_CONFIG_RD);
+ outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */
+
+ switch ( _Processor )
+ {
+ case _PROC_IBM:
+ ROOT_DEV = to_kdev_t(0x0301); /* hda1 */
+ break;
+ case _PROC_Motorola:
+ ROOT_DEV = to_kdev_t(0x0801); /* sda1 */
+ break;
+ }
+ aux_device_present = 0xaa;
+
+ panic_timeout = 300; /* reboot on panic */
+
+#if 0
+ /* get root via nfs from charon -- was only used for testing */
+ ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255); /* nfs */
/*nfsaddrs=myip:serverip:gateip:netmaskip:clientname*/
strcpy(cmd_line,
- "nfsaddrs=129.138.6.13:129.138.6.90:129.138.6.1:255.255.255.0:pandora");
- /* strcpy(cmd_line,"root=/dev/sda1");*/
- *cmdline_p = cmd_line;
- *memory_start_p = (unsigned long) &_end;
- *memory_end_p = (unsigned long *)end_of_DRAM;
- size_memory = *memory_end_p - KERNELBASE; /* Relative size of memory */
+ "nfsaddrs=129.138.6.101:129.138.6.90:129.138.6.1:255.255.255.0:gordito nfsroot=/joplin/ppc/root/");
+#endif
+ *cmdline_p = cmd_line;
+ *memory_start_p = (unsigned long) &_end;
+ (unsigned long *)*memory_end_p = (unsigned long *)end_of_DRAM;
+ size_memory = *memory_end_p - KERNELBASE; /* Relative size of memory */
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
- rd_prompt = 0;
- rd_doload = 0;
+#if 1
+ rd_prompt = 1;
+ rd_doload = 1;
rd_image_start = 0;
-#endif
+#endif
+#endif
+
+ /* Save unparsed command line copy for /proc/cmdline */
+ memcpy(saved_command_line, cmd_line,strlen(cmd_line)+1);
+ printk("Command line: %s\n", cmd_line);
}
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
{
- return -EIO;
+ return -EIO;
}
-#if 0
-extern char builtin_ramdisk_image;
-extern long builtin_ramdisk_size;
-void
-builtin_ramdisk_init(void)
-{
- if ((ROOT_DEV == to_kdev_t(DEFAULT_ROOT_DEVICE)) && (builtin_ramdisk_size != 0))
- {
- rd_preloaded_init(&builtin_ramdisk_image, builtin_ramdisk_size);
- } else
- { /* Not ramdisk - assume root needs to be mounted read only */
- root_mountflags |= MS_RDONLY;
- }
-}
-#endif
-#define MAJOR(n) (((n)&0xFF00)>>8)
-#define MINOR(n) ((n)&0x00FF)
int
get_cpuinfo(char *buffer)
{
- int pvr = _get_PVR();
- char *model;
- switch (pvr>>16)
- {
- case 3:
- model = "603";
- break;
- case 4:
- model = "604";
- break;
- case 6:
- model = "603e";
- break;
- case 7:
- model = "603ev";
- break;
- default:
- model = "unknown";
- break;
- }
- return sprintf(buffer, "PowerPC %s rev %d.%d\n", model, MAJOR(pvr), MINOR(pvr));
+ extern unsigned long loops_per_sec;
+ int i;
+ int pvr = _get_PVR();
+ int len;
+ char *model;
+ unsigned long full = 0, overflow = 0;
+ unsigned int ti;
+ PTE *ptr;
+
+ switch (pvr>>16)
+ {
+ case 3:
+ model = "603";
+ break;
+ case 4:
+ model = "604";
+ break;
+ case 6:
+ model = "603e";
+ break;
+ case 7:
+ model = "603ev";
+ break;
+ default:
+ model = "unknown";
+ break;
+ }
+
+#ifdef __SMP__
+#define CD(X) (cpu_data[n].X)
+#else
+#define CD(X) (X)
+#define CPUN 0
+#endif
+
+ len = sprintf(buffer, "PowerPC %s/%dMHz revision %d.%d %s\n",
+ model,
+ (res.VitalProductData.ProcessorHz > 1024) ?
+ res.VitalProductData.ProcessorHz>>20 :
+ res.VitalProductData.ProcessorHz,
+ MAJOR(pvr), MINOR(pvr),
+ (inb(IBM_EQUIP_PRESENT) & 2) ? "" : "upgrade");
+#if 1
+ if ( res.VitalProductData.PrintableModel[0] )
+ len += sprintf(buffer+len,"%s\n",res.VitalProductData.PrintableModel);
+
+ len += sprintf(buffer+len,"Bus %dMHz\n",
+ (res.VitalProductData.ProcessorBusHz > 1024) ?
+ res.VitalProductData.ProcessorBusHz>>20 :
+ res.VitalProductData.ProcessorBusHz);
+
+ /* make sure loops_per_sec has been setup -- ie not at boottime -- Cort */
+ if ( CD(loops_per_sec+2500)/500000 > 0)
+ len += sprintf(buffer+len,
+ "bogomips: %lu.%02lu\n",
+ CD(loops_per_sec+2500)/500000,
+ (CD(loops_per_sec+2500)/5000) % 100);
+
+
+ len += sprintf(buffer+len,"Total Ram: %dM Hash Table: %dkB (%dk buckets)\n",
+ _TotalMemory>>20, Hash_size>>10,
+ (Hash_size/(sizeof(PTE)*8)) >> 10);
+
+ for ( i = 0 ; (res.ActualNumMemories) && (i < MAX_MEMS) ; i++ )
+ {
+ if (i == 0)
+ len += sprintf(buffer+len,"SIMM Banks: ");
+ if ( res.Memories[i].SIMMSize != 0 )
+ len += sprintf(buffer+len,"%d:%dM ",i,
+ (res.Memories[i].SIMMSize > 1024) ?
+ res.Memories[i].SIMMSize>>20 :
+ res.Memories[i].SIMMSize);
+ if ( i == MAX_MEMS-1)
+ len += sprintf(buffer+len,"\n");
+ }
+
+ /* TLB */
+ len += sprintf(buffer+len,"TLB");
+ switch(res.VitalProductData.TLBAttrib)
+ {
+ case CombinedTLB:
+ len += sprintf(buffer+len,": %d entries\n",
+ res.VitalProductData.TLBSize);
+ break;
+ case SplitTLB:
+ len += sprintf(buffer+len,": (split I/D) %d/%d entries\n",
+ res.VitalProductData.I_TLBSize,
+ res.VitalProductData.D_TLBSize);
+ break;
+ case NoneTLB:
+ len += sprintf(buffer+len,": not present\n");
+ break;
+ }
+
+ /* L1 */
+ len += sprintf(buffer+len,"L1: ");
+ switch(res.VitalProductData.CacheAttrib)
+ {
+ case CombinedCAC:
+ len += sprintf(buffer+len,"%dkB LineSize\n",
+ res.VitalProductData.CacheSize,
+ res.VitalProductData.CacheLineSize);
+ break;
+ case SplitCAC:
+ len += sprintf(buffer+len,"(split I/D) %dkB/%dkB Linesize %dB/%dB\n",
+ res.VitalProductData.I_CacheSize,
+ res.VitalProductData.D_CacheSize,
+ res.VitalProductData.D_CacheLineSize,
+ res.VitalProductData.D_CacheLineSize);
+ break;
+ case NoneCAC:
+ len += sprintf(buffer+len,"not present\n");
+ break;
+ }
+
+ /* L2 */
+ if ( (inb(IBM_EQUIP_PRESENT) & 1) == 0) /* l2 present */
+ {
+ int size;
+
+ len += sprintf(buffer+len,"L2: %dkB %s\n",
+ ((inb(IBM_L2_STATUS) >> 5) & 1) ? 512 : 256,
+ (inb(IBM_SYS_CTL) & 64) ? "enabled" : "disabled");
+ }
+ else
+ {
+ len += sprintf(buffer+len,"L2: not present\n");
+ }
+#if 0
+ len+= sprintf(buffer+len,"Equip register %x\n",
+ inb(IBM_EQUIP_PRESENT));
+ len+= sprintf(buffer+len,"L2Status register %x\n",
+ inb(IBM_L2_STATUS));
+#endif
+#endif
+
+
+ return len;
}
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index 18a0a10d9..ba8864251 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -3,16 +3,20 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Adapted for PowerPC by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
*/
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
+#include <asm/uaccess.h>
#define _S(nr) (1<<((nr)-1))
@@ -26,7 +30,9 @@ asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
asmlinkage int sys_sigsuspend(unsigned long set, int p2, int p3, int p4, int p6, int p7, struct pt_regs *regs)
{
unsigned long mask;
+ int ret = -EINTR;
+ lock_kernel();
mask = current->blocked;
current->blocked = set & _BLOCKABLE;
regs->gpr[3] = -EINTR;
@@ -37,25 +43,32 @@ printk("Task: %x[%d] - SIGSUSPEND at %x, Mask: %x\n", current, current->pid, reg
current->state = TASK_INTERRUPTIBLE;
schedule();
if (do_signal(mask,regs))
- return -EINTR;
+ goto out;
}
+out:
+ unlock_kernel();
+ return ret;
}
-/*
- * This sets regs->esp even though we don't actually use sigstacks yet..
- */
asmlinkage int sys_sigreturn(struct pt_regs *regs)
{
struct sigcontext_struct *sc;
struct pt_regs *int_regs;
- int signo;
+ int signo, ret;
+
+ lock_kernel();
+#if 1
+ if (verify_area(VERIFY_READ, (void *) regs->gpr[1], sizeof(sc))
+ || (regs->gpr[1] >=KERNELBASE))
+ goto badframe;
+#endif
sc = (struct sigcontext_struct *)regs->gpr[1];
current->blocked = sc->oldmask & _BLOCKABLE;
int_regs = sc->regs;
signo = sc->signal;
sc++; /* Pop signal 'context' */
- if (sc == (struct sigcontext_struct *)(int_regs))
- { /* Last stacked signal */
+ if (sc == (struct sigcontext_struct *)(int_regs)) {
+ /* Last stacked signal */
#if 0
/* This doesn't work - it blows away the return address! */
memcpy(regs, int_regs, sizeof(*regs));
@@ -72,16 +85,24 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
regs->nip -= 4; /* Back up & retry system call */
regs->result = 0;
}
- return (regs->result);
- } else
- { /* More signals to go */
+ ret = (regs->result);
+ } else { /* More signals to go */
regs->gpr[1] = (unsigned long)sc;
regs->gpr[3] = sc->signal;
regs->gpr[4] = sc->regs;
regs->link = (unsigned long)((sc->regs)+1);
regs->nip = sc->handler;
- return (sc->signal);
+ ret = sc->signal;
}
+ goto out;
+
+badframe:
+ /*printk("sys_sigreturn(): badstack regs %x cur %s/%d\n",
+ regs,current->comm,current->pid);*/
+ do_exit(SIGSEGV);
+out:
+ unlock_kernel();
+ return ret;
}
@@ -96,27 +117,24 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
*/
asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
{
- unsigned long mask = ~current->blocked;
+ unsigned long mask;
unsigned long handler_signal = 0;
unsigned long *frame = NULL;
- unsigned long *trampoline;
- unsigned long *regs_ptr;
+ unsigned long *trampoline, *regs_ptr;
unsigned long nip = 0;
unsigned long signr;
- int bitno;
struct sigcontext_struct *sc;
struct sigaction * sa;
- int s = _disable_interrupts();
+ int bitno, s, ret;
+
+ lock_kernel();
+ mask = ~current->blocked;
while ((signr = current->signal & mask)) {
-#if 0
- signr = ffz(~signr); /* Compute bit # */
-#else
for (bitno = 0; bitno < 32; bitno++)
- {
- if (signr & (1<<bitno)) break;
- }
+ if (signr & (1<<bitno))
+ break;
signr = bitno;
-#endif
+
current->signal &= ~(1<<signr); /* Clear bit */
sa = current->sig->action + signr;
signr++;
@@ -157,7 +175,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
current->state = TASK_STOPPED;
current->exit_code = signr;
if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
- SA_NOCLDSTOP))
+ SA_NOCLDSTOP))
notify_parent(current);
schedule();
continue;
@@ -174,27 +192,33 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
do_exit(signr);
}
}
- /*
- * OK, we're invoking a handler
- */
+
+ /* handle signal */
if ((int)regs->orig_gpr3 >= 0) {
if ((int)regs->result == -ERESTARTNOHAND ||
- ((int)regs->result == -ERESTARTSYS && !(sa->sa_flags & SA_RESTART)))
+ ((int)regs->result == -ERESTARTSYS &&
+ !(sa->sa_flags & SA_RESTART)))
(int)regs->result = -EINTR;
}
handler_signal |= 1 << (signr-1);
mask &= ~sa->sa_mask;
}
+ ret = 0;
if (!handler_signal) /* no handler will be called - return 0 */
- {
- _enable_interrupts(s);
- return 0;
- }
+ goto out;
+
nip = regs->nip;
frame = (unsigned long *) regs->gpr[1];
+
/* Build trampoline code on stack */
frame -= 2;
trampoline = frame;
+#if 1
+ /* verify stack is valid for writing regs struct */
+ if (verify_area(VERIFY_WRITE,(void *)frame, sizeof(long)*2+sizeof(*regs))
+ || (frame >= KERNELBASE ))
+ goto badframe;
+#endif
trampoline[0] = 0x38007777; /* li r0,0x7777 */
trampoline[1] = 0x44000002; /* sc */
frame -= sizeof(*regs) / sizeof(long);
@@ -202,12 +226,19 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
memcpy(regs_ptr, regs, sizeof(*regs));
signr = 1;
sa = current->sig->action;
+
for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
if (mask > handler_signal)
break;
if (!(mask & handler_signal))
continue;
+
frame -= sizeof(struct sigcontext_struct) / sizeof(long);
+#if 1
+ if (verify_area(VERIFY_WRITE,(void *)frame,
+ sizeof(struct sigcontext_struct)/sizeof(long)))
+ goto badframe;
+#endif
sc = (struct sigcontext_struct *)frame;
nip = (unsigned long) sa->sa_handler;
#if 0 /* Old compiler */
@@ -226,14 +257,27 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
regs->link = (unsigned long)trampoline;
regs->nip = nip;
regs->gpr[1] = (unsigned long)sc;
- /* The DATA cache must be flushed here to insure coherency */
- /* between the DATA & INSTRUCTION caches. Since we just */
- /* created an instruction stream using the DATA [cache] space */
- /* and since the instruction cache will not look in the DATA */
- /* cache for new data, we have to force the data to go on to */
- /* memory and flush the instruction cache to force it to look */
- /* there. The following function performs this magic */
+
+ /* The DATA cache must be flushed here to insure coherency
+ * between the DATA & INSTRUCTION caches. Since we just
+ * created an instruction stream using the DATA [cache] space
+ * and since the instruction cache will not look in the DATA
+ * cache for new data, we have to force the data to go on to
+ * memory and flush the instruction cache to force it to look
+ * there. The following function performs this magic
+ */
flush_instruction_cache();
- _enable_interrupts(s);
- return 1;
+ ret = 1;
+ goto out;
+
+badframe:
+#if 0
+ printk("do_signal(): badstack signr %d frame %x regs %x cur %s/%d\n",
+ signr, frame, regs, current->comm, current->pid);
+#endif
+ do_exit(SIGSEGV);
+
+out:
+ unlock_kernel();
+ return ret;
}
diff --git a/arch/ppc/kernel/stubs.c b/arch/ppc/kernel/stubs.c
index b7af6dd44..30f028279 100644
--- a/arch/ppc/kernel/stubs.c
+++ b/arch/ppc/kernel/stubs.c
@@ -1,59 +1,58 @@
-#include <linux/in.h>
+/*#include <linux/in.h>*/
+#include <linux/autoconf.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
-void sys_iopl(void) { _panic("sys_iopl"); }
-void sys_vm86(void) { _panic("sys_vm86"); }
-void sys_modify_ldt(void) { _panic("sys_modify_ldt"); }
-
-void sys_ipc(void) {_panic("sys_ipc"); }
-void sys_newselect(void) {_panic("sys_newselect"); }
-
-halt()
-{
- printk("\n...Halt!\n");
- abort();
-}
-
-_panic(char *msg)
+void sys_iopl(void)
{
- printk("Panic: %s\n", msg);
- printk("Panic: %s\n", msg);
- abort();
+ lock_kernel();
+ panic("sys_iopl");
+ unlock_kernel();
}
-
-_warn(char *msg)
+void sys_vm86(void)
{
- printk("*** Warning: %s UNIMPLEMENTED!\n", msg);
+ lock_kernel();
+ panic("sys_vm86");
+ unlock_kernel();
}
-
-
-void
-saved_command_line(void)
+void sys_modify_ldt(void)
{
- panic("saved_command_line");
+ lock_kernel();
+ panic("sys_modify_ldt");
+ unlock_kernel();
}
-void
-KSTK_EIP(void)
+void sys_ipc(void)
{
- panic("KSTK_EIP");
+ lock_kernel();
+ panic("sys_ipc");
+ unlock_kernel();
}
-void
-KSTK_ESP(void)
+void sys_newselect(void)
{
- panic("KSTK_ESP");
+ lock_kernel();
+ panic("sys_newselect");
+ unlock_kernel();
}
+#ifndef CONFIG_MODULES
void
scsi_register_module(void)
{
+ lock_kernel();
panic("scsi_register_module");
+ unlock_kernel();
}
void
scsi_unregister_module(void)
{
+ lock_kernel();
panic("scsi_unregister_module");
+ unlock_kernel();
}
+#endif
+
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
index 7dd34510c..9d18c45ab 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -2,6 +2,7 @@
* linux/arch/ppc/kernel/sys_ppc.c
*
* Adapted from the i386 version by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
*
* This file contains various random system calls that
* have a non-standard calling sequence on the Linux/PPC
@@ -11,11 +12,14 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/stat.h>
#include <linux/mman.h>
+#include <asm/uaccess.h>
/*
* sys_pipe() is the normal C calling standard for creating
@@ -24,30 +28,35 @@
asmlinkage int sys_pipe(unsigned long * fildes)
{
int error;
+
+ lock_kernel();
error = verify_area(VERIFY_WRITE,fildes,8);
if (error)
- return error;
+ goto out;
error = do_pipe(fildes);
- if (error)
- return error;
- return 0;
+out:
+ unlock_kernel();
+ return error;
}
asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
int flags, int fd, off_t offset)
{
struct file * file = NULL;
+ int ret = -EBADF;
+ lock_kernel();
if (!(flags & MAP_ANONYMOUS)) {
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
+ goto out;
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
- return do_mmap(file, addr, len, prot, flags, offset);
+ ret = do_mmap(file, addr, len, prot, flags, offset);
+out:
+ unlock_kernel();
+ return ret;
}
-#if 0
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux/i386 didn't use to be able to handle more than
@@ -58,20 +67,30 @@ asmlinkage int old_mmap(unsigned long *buffer)
{
int error;
unsigned long flags;
+ long a,b,c,d,e;
struct file * file = NULL;
+ lock_kernel();
error = verify_area(VERIFY_READ, buffer, 6*sizeof(long));
if (error)
- return error;
- flags = get_user(buffer+3);
+ goto out;
+ get_user(flags,buffer+3);
if (!(flags & MAP_ANONYMOUS)) {
- unsigned long fd = get_user(buffer+4);
+ unsigned long fd;
+ get_user(fd,buffer+4);
+ error = -EBADF;
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- return -EBADF;
+ goto out;
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- return do_mmap(file, get_user(buffer), get_user(buffer+1),
- get_user(buffer+2), flags, get_user(buffer+5));
+ error = -EFAULT;
+ if ( get_user(a,buffer) || get_user(b,buffer+1) ||
+ get_user(c,buffer+2)||get_user(d,buffer+5) )
+ goto out;
+ error = do_mmap(file,a,b,c, flags, d);
+out:
+ unlock_kernel();
+ return error;
}
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
@@ -84,16 +103,21 @@ asmlinkage int old_select(unsigned long *buffer)
fd_set *exp;
struct timeval *tvp;
+ lock_kernel();
n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
if (n)
- return n;
- n = get_user(buffer);
- inp = (fd_set *) get_user(buffer+1);
- outp = (fd_set *) get_user(buffer+2);
- exp = (fd_set *) get_user(buffer+3);
- tvp = (struct timeval *) get_user(buffer+4);
- return sys_select(n, inp, outp, exp, tvp);
+ goto out;
+ get_user(n,buffer);
+ get_user(inp,buffer+1);
+ get_user(outp,buffer+2);
+ get_user(exp,buffer+3);
+ get_user(tvp,buffer+4);
+ n = sys_select(n, inp, outp, exp, tvp);
+out:
+ unlock_kernel();
+ return n;
}
+#if 0
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
@@ -102,57 +126,68 @@ asmlinkage int old_select(unsigned long *buffer)
*/
asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
{
- int version;
+ int version, ret;
+ lock_kernel();
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
if (call <= SEMCTL)
switch (call) {
case SEMOP:
- return sys_semop (first, (struct sembuf *)ptr, second);
+ ret = sys_semop (first, (struct sembuf *)ptr, second);
+ goto out;
case SEMGET:
- return sys_semget (first, second, third);
+ ret = sys_semget (first, second, third);
+ goto out;
case SEMCTL: {
union semun fourth;
- int err;
+ ret = -EINVAL;
if (!ptr)
- return -EINVAL;
- if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
- return err;
+ goto out;
+ if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long))))
+ goto out;
fourth.__pad = (void *) get_fs_long(ptr);
- return sys_semctl (first, second, third, fourth);
+ ret = sys_semctl (first, second, third, fourth);
+ goto out;
}
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (call <= MSGCTL)
switch (call) {
case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
+ ret = sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ goto out;
case MSGRCV:
switch (version) {
case 0: {
struct ipc_kludge tmp;
- int err;
+ ret = -EINVAL;
if (!ptr)
- return -EINVAL;
- if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
- return err;
+ goto out;
+ if ((ret = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
+ goto out;
memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
sizeof (tmp));
- return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
+ ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
+ goto out;
}
case 1: default:
- return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
+ ret = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
+ goto out;
}
case MSGGET:
- return sys_msgget ((key_t) first, second);
+ ret = sys_msgget ((key_t) first, second);
+ goto out;
case MSGCTL:
- return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+ ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
+ goto out;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (call <= SHMCTL)
switch (call) {
@@ -160,29 +195,39 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
switch (version) {
case 0: default: {
ulong raddr;
- int err;
- if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
- return err;
- err = sys_shmat (first, (char *) ptr, second, &raddr);
- if (err)
- return err;
+ if ((ret = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
+ goto out;
+ ret = sys_shmat (first, (char *) ptr, second, &raddr);
+ if (ret)
+ goto out;
put_fs_long (raddr, (ulong *) third);
- return 0;
+ ret = 0;
+ goto out;
}
case 1: /* iBCS2 emulator entry point */
+ ret = -EINVAL;
if (get_fs() != get_ds())
- return -EINVAL;
- return sys_shmat (first, (char *) ptr, second, (ulong *) third);
+ goto out;
+ ret = sys_shmat (first, (char *) ptr, second, (ulong *) third);
+ goto out;
}
case SHMDT:
- return sys_shmdt ((char *)ptr);
+ ret = sys_shmdt ((char *)ptr);
+ goto out;
case SHMGET:
- return sys_shmget (first, second, third);
+ ret = sys_shmget (first, second, third);
+ goto out;
case SHMCTL:
- return sys_shmctl (first, second, (struct shmid_ds *) ptr);
+ ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
+ goto out;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
- return -EINVAL;
+ else
+ ret = -EINVAL;
+out:
+ unlock_kernel();
+ return ret;
}
#endif
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index a0e2e0534..cdcad8204 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <asm/nvram.h>
#include <asm/mc146818rtc.h>
+#include <asm/processor.h>
#include <linux/timex.h>
#include <linux/config.h>
@@ -43,6 +44,13 @@ static inline int CMOS_READ(int addr)
return (inb(NVRAM_DATA));
}
+static inline int CMOS_WRITE(int addr, int val)
+{
+ outb(addr>>8, NVRAM_AS1);
+ outb(addr, NVRAM_AS0);
+ return (outb(val, NVRAM_DATA));
+}
+
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
*
@@ -138,9 +146,110 @@ void do_settimeofday(struct timeval *tv)
time_state = TIME_BAD;
time_maxerror = 0x70000000;
time_esterror = 0x70000000;
+ set_rtc(xtime.tv_sec);
sti();
}
+static int month_days[12] = {
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+#define FEBRUARY 2
+#define STARTOFTIME 1970
+#define SECDAY 86400L
+#define SECYR (SECDAY * 365)
+#define leapyear(year) ((year) % 4 == 0)
+#define days_in_year(a) (leapyear(a) ? 366 : 365)
+#define days_in_month(a) (month_days[(a) - 1])
+
+struct _tm
+{
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_day;
+ int tm_month;
+ int tm_year;
+};
+
+static _to_tm(int tim, struct _tm * tm)
+{
+ register int i;
+ register long hms, day;
+
+ day = tim / SECDAY;
+ hms = tim % SECDAY;
+
+ /* Hours, minutes, seconds are easy */
+ tm->tm_hour = hms / 3600;
+ tm->tm_min = (hms % 3600) / 60;
+ tm->tm_sec = (hms % 3600) % 60;
+
+ /* Number of years in days */
+ for (i = STARTOFTIME; day >= days_in_year(i); i++)
+ day -= days_in_year(i);
+ tm->tm_year = i;
+
+ /* Number of months in days left */
+ if (leapyear(tm->tm_year))
+ days_in_month(FEBRUARY) = 29;
+ for (i = 1; day >= days_in_month(i); i++)
+ day -= days_in_month(i);
+ days_in_month(FEBRUARY) = 28;
+ tm->tm_month = i;
+
+ /* Days are what is left over (+1) from all that. */
+ tm->tm_day = day + 1;
+}
+
+/*
+ * Set the time into the CMOS
+ */
+static void set_rtc(unsigned long nowtime)
+{
+ int retval = 0;
+ struct _tm tm;
+ unsigned char save_control, save_freq_select;
+
+ /*if (_Processor != _PROC_IBM) return;*/
+
+ _to_tm(nowtime, &tm);
+
+ /* tell the clock it's being set */
+ save_control = CMOS_MCRTC_READ(MCRTC_CONTROL);
+ CMOS_MCRTC_WRITE((save_control|MCRTC_SET), MCRTC_CONTROL);
+ /* stop and reset prescaler */
+ save_freq_select = CMOS_MCRTC_READ(MCRTC_FREQ_SELECT);
+ CMOS_MCRTC_WRITE((save_freq_select|MCRTC_DIV_RESET2), MCRTC_FREQ_SELECT);
+
+ printk("Set RTC H:M:S M/D/Y %d:%02d:%02d %d/%d/%d\n",
+ tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_month, tm.tm_day, tm.tm_year);
+ if (!(save_control & MCRTC_DM_BINARY) || MCRTC_ALWAYS_BCD) {
+ BIN_TO_BCD(tm.tm_sec);
+ BIN_TO_BCD(tm.tm_min);
+ BIN_TO_BCD(tm.tm_hour);
+ BIN_TO_BCD(tm.tm_month);
+ BIN_TO_BCD(tm.tm_day);
+ BIN_TO_BCD(tm.tm_year);
+ }
+
+ CMOS_MCRTC_WRITE(tm.tm_sec, MCRTC_SECONDS);
+ CMOS_MCRTC_WRITE(tm.tm_min, MCRTC_MINUTES);
+ CMOS_MCRTC_WRITE(tm.tm_hour, MCRTC_HOURS);
+ CMOS_MCRTC_WRITE(tm.tm_month, MCRTC_MONTH);
+ CMOS_MCRTC_WRITE(tm.tm_day, MCRTC_MINUTES);
+ CMOS_MCRTC_WRITE(tm.tm_year - 1900, MCRTC_MINUTES);
+
+ /* The following flags have to be released exactly in this order,
+ * otherwise the DS12887 (popular MC146818A clone with integrated
+ * battery and quartz) will not reset the oscillator and will not
+ * update precisely 500 ms later. You won't find this mentioned in
+ * the Dallas Semiconductor data sheets, but who believes data
+ * sheets anyway ... -- Markus Kuhn
+ */
+ CMOS_MCRTC_WRITE(save_control, MCRTC_CONTROL);
+ CMOS_MCRTC_WRITE(save_freq_select, MCRTC_FREQ_SELECT);
+}
/*
* In order to set the CMOS clock precisely, set_rtc_mmss has to be
@@ -156,17 +265,19 @@ static int set_rtc_mmss(unsigned long nowtime)
unsigned char save_control, save_freq_select;
#ifdef __powerpc__
+printk("%s: %d - set TOD\n", __FILE__, __LINE__);
return (-1); /* Not implemented */
#else
- save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
- CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+printk("%s: %d - set TOD\n", __FILE__, __LINE__);
+ save_control = CMOS_MCRTC_READ(MCRTC_CONTROL); /* tell the clock it's being set */
+ CMOS_MCRTC_WRITE((save_control|MCRTC_SET), MCRTC_CONTROL);
- save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
- CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+ save_freq_select = CMOS_MCRTC_READ(MCRTC_FREQ_SELECT); /* stop and reset prescaler */
+ CMOS_MCRTC_WRITE((save_freq_select|MCRTC_DIV_RESET2), MCRTC_FREQ_SELECT);
- cmos_minutes = CMOS_READ(RTC_MINUTES);
- if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+ cmos_minutes = CMOS_MCRTC_READ(MCRTC_MINUTES);
+ if (!(save_control & MCRTC_DM_BINARY) || MCRTC_ALWAYS_BCD)
BCD_TO_BIN(cmos_minutes);
/*
@@ -182,12 +293,12 @@ return (-1); /* Not implemented */
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
- if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ if (!(save_control & MCRTC_DM_BINARY) || MCRTC_ALWAYS_BCD) {
BIN_TO_BCD(real_seconds);
BIN_TO_BCD(real_minutes);
}
- CMOS_WRITE(real_seconds,RTC_SECONDS);
- CMOS_WRITE(real_minutes,RTC_MINUTES);
+ CMOS_MCRTC_WRITE(real_seconds,MCRTC_SECONDS);
+ CMOS_MCRTC_WRITE(real_minutes,MCRTC_MINUTES);
} else
retval = -1;
@@ -198,8 +309,8 @@ return (-1); /* Not implemented */
* the Dallas Semiconductor data sheets, but who believes data
* sheets anyway ... -- Markus Kuhn
*/
- CMOS_WRITE(save_control, RTC_CONTROL);
- CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ CMOS_MCRTC_WRITE(save_control, MCRTC_CONTROL);
+ CMOS_MCRTC_WRITE(save_freq_select, MCRTC_FREQ_SELECT);
return retval;
#endif
@@ -214,27 +325,42 @@ static long last_rtc_update = 0;
*/
static inline void timer_interrupt(int irq, void *dev, struct pt_regs * regs)
{
- do_timer(regs);
-
- /*
- * If we have an externally synchronized Linux clock, then update
- * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
- * called as close as possible to 500 ms before the new second starts.
- */
- if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
- xtime.tv_usec > 500000 - (tick >> 1) &&
- xtime.tv_usec < 500000 + (tick >> 1))
- if (set_rtc_mmss(xtime.tv_sec) == 0)
- last_rtc_update = xtime.tv_sec;
- else
- last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-#if 0
- /* As we return to user mode fire off the other CPU schedulers.. this is
- basically because we don't yet share IRQ's around. This message is
- rigged to be safe on the 386 - basically its a hack, so don't look
- closely for now.. */
- smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0);
-#endif
+ static int timeints = 0;
+
+ do_timer(regs);
+
+ /*
+ * If we have an externally synchronized Linux clock, then update
+ * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+ * called as close as possible to 500 ms before the new second starts.
+ */
+ if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec > 500000 - (tick >> 1) &&
+ xtime.tv_usec < 500000 + (tick >> 1))
+ if (set_rtc_mmss(xtime.tv_sec) == 0)
+ last_rtc_update = xtime.tv_sec;
+ else
+ last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+
+
+ /* use hard disk LED as a heartbeat instead -- much more useful
+ -- Cort */
+ switch(timeints)
+ {
+ /* act like an actual heart beat -- ie thump-thump-pause... */
+ case 0:
+ case 20:
+ hard_disk_LED(1);
+ break;
+ case 7:
+ case 27:
+ hard_disk_LED(0);
+ break;
+ case 100:
+ timeints = -1;
+ break;
+ }
+ timeints++;
}
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
@@ -270,49 +396,52 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
unsigned long get_cmos_time(void)
{
- unsigned int year, mon, day, hour, min, sec;
- int i;
-
- if (isBeBox[0])
- {
-#ifndef __powerpc__
- /* The Linux interpretation of the CMOS clock register contents:
- * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
- * RTC registers show the second which has precisely just started.
- * Let's hope other operating systems interpret the RTC the same way.
- */
- /* read RTC exactly on falling edge of update flag */
- for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
- break;
-#endif
- do { /* Isn't this overkill ? UIP above should guarantee consistency */
- sec = CMOS_MCRTC_READ(MCRTC_SECONDS);
- min = CMOS_MCRTC_READ(MCRTC_MINUTES);
- hour = CMOS_MCRTC_READ(MCRTC_HOURS);
- day = CMOS_MCRTC_READ(MCRTC_DAY_OF_MONTH);
- mon = CMOS_MCRTC_READ(MCRTC_MONTH);
- year = CMOS_MCRTC_READ(MCRTC_YEAR);
- } while (sec != CMOS_MCRTC_READ(MCRTC_SECONDS));
- } else
+ unsigned int year, mon, day, hour, min, sec;
+ int i;
+
+ if (_Processor == _PROC_IBM)
+ {
+ do { /* Isn't this overkill ? UIP above should guarantee consistency */
+ sec = CMOS_MCRTC_READ(MCRTC_SECONDS);
+ min = CMOS_MCRTC_READ(MCRTC_MINUTES);
+ hour = CMOS_MCRTC_READ(MCRTC_HOURS);
+ day = CMOS_MCRTC_READ(MCRTC_DAY_OF_MONTH);
+ mon = CMOS_MCRTC_READ(MCRTC_MONTH);
+ year = CMOS_MCRTC_READ(MCRTC_YEAR);
+ } while (sec != CMOS_MCRTC_READ(MCRTC_SECONDS));
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ } else
+ if (_Processor == _PROC_Be)
+ {
+ do { /* Isn't this overkill ? UIP above should guarantee consistency */
+ sec = CMOS_MCRTC_READ(MCRTC_SECONDS);
+ min = CMOS_MCRTC_READ(MCRTC_MINUTES);
+ hour = CMOS_MCRTC_READ(MCRTC_HOURS);
+ day = CMOS_MCRTC_READ(MCRTC_DAY_OF_MONTH);
+ mon = CMOS_MCRTC_READ(MCRTC_MONTH);
+ year = CMOS_MCRTC_READ(MCRTC_YEAR);
+ } while (sec != CMOS_MCRTC_READ(MCRTC_SECONDS));
+ } else
{ /* Motorola PowerStack etc. */
- do { /* Isn't this overkill ? UIP above should guarantee consistency */
- sec = CMOS_READ(RTC_SECONDS);
- min = CMOS_READ(RTC_MINUTES);
- hour = CMOS_READ(RTC_HOURS);
- day = CMOS_READ(RTC_DAY_OF_MONTH);
- mon = CMOS_READ(RTC_MONTH);
- year = CMOS_READ(RTC_YEAR);
- } while (sec != CMOS_READ(RTC_SECONDS));
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
+ do { /* Isn't this overkill ? UIP above should guarantee consistency */
+ sec = CMOS_READ(RTC_SECONDS);
+ min = CMOS_READ(RTC_MINUTES);
+ hour = CMOS_READ(RTC_HOURS);
+ day = CMOS_READ(RTC_DAY_OF_MONTH);
+ mon = CMOS_READ(RTC_MONTH);
+ year = CMOS_READ(RTC_YEAR);
+ } while (sec != CMOS_READ(RTC_SECONDS));
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
}
#if 0
printk("CMOS TOD - M/D/Y H:M:S = %d/%d/%d %d:%02d:%02d\n", mon, day, year, hour, min, sec);
@@ -324,13 +453,13 @@ printk("CMOS TOD - M/D/Y H:M:S = %d/%d/%d %d:%02d:%02d\n", mon, day, year, hour,
void time_init(void)
{
- void (*irq_handler)(int, struct pt_regs *);
- xtime.tv_sec = get_cmos_time();
- xtime.tv_usec = 0;
-
- /* If we have the CPU hardware time counters, use them */
- irq_handler = timer_interrupt;
- if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL) != 0)
- panic("Could not allocate timer IRQ!");
+ void (*irq_handler)(int, struct pt_regs *);
+ xtime.tv_sec = get_cmos_time();
+ xtime.tv_usec = 0;
+
+ /* If we have the CPU hardware time counters, use them */
+ irq_handler = timer_interrupt;
+ if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL) != 0)
+ panic("Could not allocate timer IRQ!");
}
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index e9f5e8e5b..a637e0acb 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 1995 Gary Thomas
* Adapted for PowerPC by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
*/
/*
@@ -17,7 +18,6 @@
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
-#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
@@ -40,44 +40,62 @@ trap_init(void)
void
_exception(int signr, struct pt_regs *regs)
{
-/* dump_regs(regs);*/
- force_sig(signr, current);
- if (!user_mode(regs))
- {
- printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
- while (1) ;
- }
+ /* dump_regs(regs);*/
+ force_sig(signr, current);
+ if (!user_mode(regs))
+ {
+ printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
+ while (1) ;
+ }
}
MachineCheckException(struct pt_regs *regs)
{
-/* printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
- _exception(SIGSEGV, regs);
+ printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+ _exception(SIGSEGV, regs);
}
ProgramCheckException(struct pt_regs *regs)
{
-/* printk("Program check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
- if (current->flags & PF_PTRACED)
- {
- _exception(SIGTRAP, regs);
- } else
- {
- _exception(SIGILL, regs);
- }
+#if 0
+ printk("Program check at PC: %x[%x], SR: %x\n",
+ regs->nip, va_to_phys(regs->nip), regs->msr);
+ #endif
+ if (current->flags & PF_PTRACED)
+ {
+ _exception(SIGTRAP, regs);
+ } else
+ {
+ _exception(SIGILL, regs);
+ }
}
SingleStepException(struct pt_regs *regs)
{
-/* printk("Single step at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
_exception(SIGTRAP, regs);
}
FloatingPointCheckException(struct pt_regs *regs)
{
-/* printk("Floating point check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
- _exception(SIGFPE, regs);
+ /* if fpu already on -- then exception was generated by an error */
+ if ( (unsigned long)(regs->msr) & (unsigned long)MSR_FP )
+ {
+ _exception(SIGFPE, regs);
+ return 0;
+ }
+
+#if 0
+ printk("fpu off -- turning on: %s pc %x fpscr %x msr %x ksp %x r1 %x\n",
+ current->comm,regs->nip,regs->fpcsr,regs->msr,regs,regs->gpr[1]);
+#endif
+
+ /* if the fpu is off then turn it on and return */
+ regs->msr |= MSR_FP;
+ current->tss.fp_used++;
+ /* tells return_from_int to restore fp regs since fp was turned on
+ see head.S -- Cort */
+ return MSR_FP;
}
AlignmentException(struct pt_regs *regs)
@@ -88,11 +106,20 @@ AlignmentException(struct pt_regs *regs)
_exception(SIGBUS, regs);
}
-bad_stack(struct pt_regs *regs)
+
+/* see CHECK_STACK macro in head.S for argument definitions */
+bad_stack(unsigned int r3, unsigned int r4, unsigned int r5, unsigned int r6)
{
-/* printk("Kernel stack overflow at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
- dump_regs(regs);*/
- while (1) ;
+ /* r6 (was r1) kernel stack pointer */
+ /* r5 (was r2) kernel stack page */
+ /* r4 kernel stack magic */
+ /* r3 stack magic or ksp masked to page boundary */
+ printk("bad_stack(): Kernel stack bad.\n");
+ printk("ksp %x kpage %x stack magic %x r3 %x\n",
+ r6,r5,r4,r3);
+ printk("current: %s/%d\n",
+ current->comm,current->pid);
+ while(1);
}
dump_regs(struct pt_regs *regs)
diff --git a/arch/ppc/kernel/usercpy.c b/arch/ppc/kernel/usercpy.c
new file mode 100644
index 000000000..7ef0f2280
--- /dev/null
+++ b/arch/ppc/kernel/usercpy.c
@@ -0,0 +1,116 @@
+#include <linux/types.h>
+#include <asm/string.h>
+#include <asm/errno.h>
+#include <linux/sched.h>
+
+/*
+ * bad data accesses from these functions should be handled specially
+ * since they are to user areas and may or may not be valid.
+ * on error -EFAULT should be returned. -- Cort
+ */
+int __copy_tofrom_user_failure(void)
+{
+ current->tss.excount = 0;
+ return -EFAULT;
+}
+
+int __copy_tofrom_user(unsigned long to, unsigned long from, int size)
+{
+ /* setup exception handling stuff */
+ current->tss.excount++;
+ current->tss.expc = (unsigned long )__copy_tofrom_user_failure;
+
+ if (memcpy( (void *)to, (void *)from, (size_t) size) == -EFAULT )
+ {
+ /* take down exception handler stuff */
+ current->tss.excount = 0;
+ return -EFAULT;
+ }
+ current->tss.excount = 0;
+ return 0; /* successful return */
+}
+
+/* Just like strncpy except in the return value:
+ *
+ * -EFAULT if an exception occurs before the terminator is copied.
+ * N if the buffer filled.
+ *
+ * Otherwise the length of the string is returned.
+ */
+asmlinkage int __strncpy_from_user_failure(void)
+{
+ current->tss.excount = 0;
+ return -EFAULT;
+}
+
+int __strncpy_from_user(unsigned long dest, unsigned long src, int count)
+{
+ int i = 0;
+ /* setup exception handling stuff */
+ current->tss.excount++;
+ current->tss.expc = (unsigned long )__strncpy_from_user_failure;
+
+ while ( i != count )
+ {
+ *(char *)(dest+i) = *(char *)(src+i);
+ if ( *(char *)(src+i) == 0 )
+ {
+ return i;
+ }
+ i++;
+ }
+ *(char *)(dest+i) = (char)0;
+ /* take down exception handler stuff */
+ current->tss.excount = 0;
+ return i;
+}
+
+int __clear_user_failure(void)
+{
+ current->tss.excount = 0;
+ return -EFAULT;
+}
+int __clear_user(unsigned long addr, int size)
+{
+ /* setup exception handling stuff */
+ current->tss.excount++;
+ current->tss.expc = (unsigned long )__clear_user_failure;
+
+ if ((int)memset((void *)addr,(int)0, (__kernel_size_t)size) == -EFAULT )
+ {
+ /* take down exception handler stuff */
+ current->tss.excount = 0;
+ return -EFAULT;
+ }
+ /* take down exception handler stuff */
+ current->tss.excount = 0;
+ return size;
+}
+
+/*
+ * Return the length of the string including the NUL terminator
+ * (strlen+1) or zero if an error occured.
+ */
+size_t strlen_user_failure(void)
+{
+ current->tss.excount = 0;
+ return -EFAULT;
+}
+size_t strlen_user(char * s)
+{
+ size_t i;
+ /* setup exception handling stuff */
+ current->tss.excount++;
+ current->tss.expc = (unsigned long )strlen_user_failure;
+
+ i = strlen(s)+1;
+
+ if ( i == -EFAULT)
+ return -EFAULT;
+
+ /* take down exception handler stuff */
+ current->tss.excount = 0;
+
+ return(i);
+}
+