patch-pre2.0.8 linux/arch/ppc/kernel/head.S
Next file: linux/arch/ppc/kernel/include/elf/ChangeLog
Previous file: linux/arch/ppc/kernel/Makefile
Back to the patch index
Back to the overall index
- Lines: 661
- Date:
Mon May 27 12:00:57 1996
- Orig file:
pre2.0.7/linux/arch/ppc/kernel/head.S
- Orig date:
Tue May 7 16:22:21 1996
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
@@ -1,5 +1,6 @@
#include "ppc_asm.tmpl"
#include "ppc_defs.h"
+#include <linux/errno.h>
#define SYNC() \
isync; \
@@ -14,7 +15,7 @@
* Increment a [64 bit] statistic counter
* Uses R2, R3
*/
-#define BUMP(ctr) /*\
+#define BUMP(ctr) \
lis r2,ctr@h; \
ori r2,r2,ctr@l; \
lwz r3,4(r2); \
@@ -22,10 +23,10 @@
stw r3,4(r2); \
lwz r3,0(r2); \
addze r3,r3; \
- stw r3,0(r2)*/
+ stw r3,0(r2)
/* The same as 'BUMP' but running unmapped (TLB code) */
-#define BUMP_UNMAPPED(ctr) /*\
+#define BUMP_UNMAPPED(ctr) \
mfspr r0,XER; \
lis r2,ctr@h; \
ori r2,r2,ctr@l; \
@@ -37,7 +38,7 @@
lwz r3,0(r2); \
addze r3,r3; \
mtspr XER,r0; \
- stw r3,0(r2)*/
+ 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 */
@@ -49,9 +50,9 @@
/* 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 */
+/* #define DO_TRAP_TRACE /* */
+/* #define DO_TLB_TRACE /* */
+/* #define DO_RFI_TRACE /* */
#ifdef DO_RFI_TRACE
#define DO_RFI_TRACE_UNMAPPED(mark) \
@@ -237,7 +238,7 @@
/* This instruction is not implemented on the PPC 603 */
#define tlbia \
- li r4,32; \
+ li r4,64; \
mtspr CTR,r4; \
lis r4,0x9000; \
0: tlbie r4; \
@@ -246,10 +247,10 @@
/* Validate kernel stack - check for overflow */
#define CHECK_STACK()
-#define _CHECK_STACK()\
+#define _CHECK_STACK() \
mtspr SPR0,r3; \
- lis r2,current@ha; \
- lwz r2,current@l(r2); \
+ lis r2,current_set@ha; \
+ lwz r2,current_set@l(r2); \
lwz r2,KERNEL_STACK_PAGE(r2); \
lis r3,sys_stack@h; \
ori r3,r3,sys_stack@l; \
@@ -308,7 +309,13 @@
stw r2,_DAR(r1); \
mfspr r2,DSISR; \
stw r2,_DSISR(r1); \
- mfspr r2,HASH1; \
+ mfspr r2,PVR; /* Check for 603/603e */ \
+ srwi r2,r2,16; \
+ cmpi 0,r2,3; /* 603 */ \
+ beq 22f; \
+ cmpi 0,r2,6; /* 603e */ \
+ bne 24f; \
+22: mfspr r2,HASH1; /* Note: these registers exist only on 603 */ \
stw r2,_HASH1(r1); \
mfspr r2,HASH2; \
stw r2,_HASH2(r1); \
@@ -319,7 +326,8 @@
mfspr r2,ICMP; \
stw r2,_ICMP(r1); \
mfspr r2,DCMP; \
- stw r2,_DCMP(r1)
+ stw r2,_DCMP(r1); \
+24:
#define SAVE_INT_REGS(mark) \
mtspr SPR0,r1; /* Save current stack pointer */ \
@@ -342,10 +350,15 @@
ori r2,r2,MSR_|MSR_DR|MSR_IR; \
mtspr SRR1,r2; \
rfi; \
-05: lis r2,current@ha; \
- lwz r2,current@l(r2); \
+05: lis r2,current_set@ha; \
+ lwz r2,current_set@l(r2); \
mfspr r1,SPR2; \
stw r1,TSS+LAST_PC(r2); \
+ mfspr r1,SPR0; \
+ stw r1,TSS+USER_STACK(r2); \
+ lwz r1,TSS+KSP(r2); \
+ subi r1,r1,INT_FRAME_SIZE; /* Make room for frame */ \
+ stw r1,TSS+PT_REGS(r2); /* Save regs pointer for 'ptrace' */ \
lwz r1,TSS+KSP(r2); \
b 20f; \
10: mfspr r2,SPR2; /* Restore CCR */ \
@@ -362,7 +375,7 @@
mtspr SRR1,r2; \
SYNC(); \
rfi; \
-20: SAVE_REGS(mark); \
+20: SAVE_REGS(mark); \
CHECK_STACK()
#define RETURN_FROM_INT(mark) \
@@ -370,8 +383,8 @@
li r4,0; \
ori r4,r4,MSR_EE; \
andc r0,r0,r4; \
+ sync; /* Some chip revs need this... */ \
mtmsr r0; \
- SYNC(); \
lis r2,intr_count@ha; /* Need to run 'bottom half' */ \
lwz r3,intr_count@l(r2); \
cmpi 0,r3,0; \
@@ -392,13 +405,13 @@
00: lwz r2,_MSR(r1); /* Returning to user mode? */ \
andi. r2,r2,MSR_PR; \
beq+ 10f; /* no - no need to mess with stack */ \
- lis r2,kernel_pages_are_copyback@ha; \
+/* lis r2,kernel_pages_are_copyback@ha; \
lwz r2,kernel_pages_are_copyback@l(r2); \
cmpi 0,r2,0; \
beq 05f; \
- bl _EXTERN(flush_instruction_cache); \
-05: lis r3,current@ha; /* need to save kernel stack pointer */ \
- lwz r3,current@l(r3); \
+ 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 */ \
stw r4,TSS+KSP(r3); \
lwz r4,STATE(r3); /* If state != 0, can't run */ \
@@ -444,14 +457,59 @@
rfi
_TEXT()
+/*
+ * This code may be executed by a bootstrap process. If so, the
+ * purpose is to relocate the loaded image to it's final location
+ * in memory.
+ * R3: End of image
+ * R4: Start of image - 0x400
+ * R11: Start of command line string
+ * R12: End of command line string
+ * R30: 'BeBx' if this is a BeBox
+ *
+ */
.globl _start
-_start:
- .globl _stext
+ .globl _stext
_stext:
+_start:
+ addi r4,r4,0x400 /* Point at start of image */
+ li r5,0 /* Load address */
+ subi r4,r4,4 /* Adjust for auto-increment */
+ subi r5,r5,4
+ subi r3,r3,4
+00: lwzu r0,4(r4) /* Fast move */
+ stwu r0,4(r5)
+ cmp 0,r3,r4
+ bne 00b
+ li r5,0x100 /* Actual code starts here */
+ mtlr r5
+ blr
hang:
ori r0,r0,0
b hang
+
+/*
+ * BeBox CPU #1 vector & code
+ */
+_ORG(0x0080)
+ .globl BeBox_CPU1_vector
+BeBox_CPU1_vector:
+ .long 0
+BeBox_CPU1_reset:
+ li r1,BeBox_CPU1_vector@l
+ li r2,0
+ stw r2,0(r1)
+00: lwz r2,0(r1)
+ cmpi 0,r2,0
+ bne 10f
+ li r2,10000
+ mtctr r2
+02: nop
+ bdnz 02b
+ b 00b
+10: mtlr r1
+ blr
_ORG(0x0100)
@@ -506,7 +564,8 @@
b SystemCall
_ORG(0x0D00)
-DEFAULT_TRAP(0x0D00)
+ b SingleStep
+
_ORG(0x0E00)
DEFAULT_TRAP(0x0E00)
_ORG(0x0F00)
@@ -649,7 +708,7 @@
* the only juncture [as far as the OS goes] where the data cache may
* contain instructions, e.g. after a disk read.
*/
-#define NUM_CACHE_LINES 128*2
+#define NUM_CACHE_LINES 128*4
#define CACHE_LINE_SIZE 32
cache_flush_buffer:
.space NUM_CACHE_LINES*CACHE_LINE_SIZE /* CAUTION! these need to match hardware */
@@ -658,12 +717,40 @@
_ORG(0x4000)
#endif
+
/*
* 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
+ * R30: 'BeBx' if this is a BeBox
*/
Reset:
lis r7,0xF000 /* To mask upper 4 bits */
+#define IS_BE_BOX 0x42654278 /* 'BeBx' */
+ lis r1,isBeBox@h
+ ori r1,r1,isBeBox@l
+ andc r1,r1,r7
+/* See if this is a CPU other than CPU#1 */
+/* This [currently] happens on the BeBox */
+ lwz r2,0(r1)
+ cmpi 0,r2,0
+ bne Reset_BeBox_CPU1
+/* Save machine type indicator */
+ li r2,0
+ lis r3,IS_BE_BOX>>16
+ ori r3,r3,IS_BE_BOX&0xFFFF
+ cmp 0,r30,r3
+ bne 00f
+ li r2,1
+ mr r11,r28
+ mr r12,r29
+ lis r5,BeBox_CPU1_vector@h
+ ori r5,r5,BeBox_CPU1_vector@l
+ 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)
@@ -723,6 +810,17 @@
lwz r0,4(r3)
mtspr IBAT2L,r0
mtspr DBAT2L,r0
+#if 0
+ lis r3,BAT3@h
+ ori r3,r3,BAT3@l
+ andc r3,r3,r7 /* make unmapped address */
+ lwz r0,0(r3)
+ mtspr IBAT3U,r0
+ mtspr DBAT3U,r0
+ lwz r0,4(r3)
+ mtspr IBAT3L,r0
+ mtspr DBAT3L,r0
+#endif
/* Now we can turn on the MMU */
mfmsr r3
ori r3,r3,MSR_DR|MSR_IR
@@ -736,7 +834,6 @@
10: bl _EXTERN(MMU_init) /* initialize MMU environment */
DO_RFI_TRACE_MAPPED(0xDEAD0100)
/* Withdraw BAT2->RAM mapping */
-#if 1
lis r7,0xF000 /* To mask upper 4 bits */
lis r3,20f@h
ori r3,r3,20f@l
@@ -750,7 +847,7 @@
DO_RFI_TRACE_MAPPED(0xDEAD0200)
SYNC
rfi
-20:
+20:
DO_RFI_TRACE_UNMAPPED(0xDEAD0400)
20: lis r3,BAT2@h
ori r3,r3,BAT2@l
@@ -761,8 +858,6 @@
lwz r0,4(r3)
mtspr IBAT2L,r0
mtspr DBAT2L,r0
-#endif
-
/* Load up the kernel context */
lis r2,init_task@h
ori r2,r2,init_task@l
@@ -818,7 +913,6 @@
SYNC
rfi /* enables MMU */
30:
-DO_RFI_TRACE_MAPPED(0xDEAD0600)
/* Turn on L1 Data Cache */
mfspr r3,HID0 /* Caches are controlled by this register */
ori r4,r3,(HID0_ICE|HID0_ICFI)
@@ -828,11 +922,81 @@
sync
mtspr HID0,r4
mtspr HID0,r3
-/* L1 cache enable */
- b _EXTERN(start_kernel) /* call main code */
+/* L1 cache enable */
+ mfspr r2,PVR /* Check for 603/603e */
+ srwi r2,r2,16
+ cmpi 0,r2,4 /* 604 */
+ bne 40f
+ mfspr r3,HID0 /* Turn on 604 specific features */
+ ori r3,r3,(HID0_SIED|HID0_BHTE)
+ mtspr HID0,r3
+40: b _EXTERN(start_kernel) /* call main code */
.long 0 # Illegal!
/*
+ * BeBox CPU #2 runs here
+ */
+Reset_BeBox_CPU1:
+ lis r1,CPU1_stack@h
+ ori r1,r1,CPU1_stack@l
+ li r2,0x0FFF /* Mask stack address down to page boundary */
+ andc r1,r1,r2
+ subi r1,r1,INT_FRAME_SIZE /* Padding for first frame */
+ lis r30,CPU1_trace@h
+ ori r30,r30,CPU1_trace@l
+ andc r30,r30,r7
+ li r5,1
+ stw r5,0(r30)
+ li r2,0 /* TOC pointer for nanokernel */
+ li r0,MSR_ /* Make sure FPU enabled */
+ mtmsr r0
+/* Initialize BAT registers */
+ lis r3,BAT0@h
+ ori r3,r3,BAT0@l
+ andc r3,r3,r7 /* make unmapped address */
+ lwz r0,0(r3)
+ mtspr IBAT0U,r0
+ mtspr DBAT0U,r0
+ lwz r0,4(r3)
+ mtspr IBAT0L,r0
+ mtspr DBAT0L,r0
+ lis r3,BAT1@h
+ ori r3,r3,BAT1@l
+ andc r3,r3,r7 /* make unmapped address */
+ lwz r0,0(r3)
+ mtspr IBAT1U,r0
+ mtspr DBAT1U,r0
+ lwz r0,4(r3)
+ mtspr IBAT1L,r0
+ mtspr DBAT1L,r0
+ lis r3,TMP_BAT2@h
+ ori r3,r3,TMP_BAT2@l
+ andc r3,r3,r7 /* make unmapped address */
+ lwz r0,0(r3)
+ mtspr IBAT2U,r0
+ mtspr DBAT2U,r0
+ lwz r0,4(r3)
+ mtspr IBAT2L,r0
+ mtspr DBAT2L,r0
+/* Now we can turn on the MMU */
+ mfmsr r3
+ ori r3,r3,MSR_DR|MSR_IR
+ mtspr SRR1,r3
+ lis r3,10f@h
+ ori r3,r3,10f@l
+ mtspr SRR0,r3
+ li r5,2
+ stw r5,0(r30)
+ SYNC
+ rfi /* enables MMU */
+10:
+ lis r30,CPU1_trace@h
+ ori r30,r30,CPU1_trace@l
+ li r5,3
+ stw r5,0(r30)
+ bl _EXTERN(BeBox_CPU1)
+
+/*
* Machine Check (Bus Errors, etc)
*/
MachineCheck:
@@ -846,25 +1010,30 @@
* Data Access exception
*/
DataAccess:
- TRACE_TRAP(0x0300)
+/* TRACE_TRAP(0x0300) */
SAVE_INT_REGS(0x0300)
SAVE_PAGE_FAULT_REGS(0x0300)
BUMP(__Data_Page_Faults)
mr r3,r1 /* Set pointer to saved regs */
bl _EXTERN(DataAccessException)
+#if 0
+ bl _EXTERN(flush_instruction_cache)
+#endif
RETURN_FROM_INT(0x0300)
/*
* Instruction Access Exception
*/
InstructionAccess:
- TRACE_TRAP(0x0400)
+/* TRACE_TRAP(0x0400) */
SAVE_INT_REGS(0x0400)
SAVE_PAGE_FAULT_REGS(0x0400)
BUMP(__Instruction_Page_Faults)
mr r3,r1 /* Set pointer to saved regs */
bl _EXTERN(InstructionAccessException)
+#if 0
bl _EXTERN(flush_instruction_cache)
+#endif
RETURN_FROM_INT(0x0400)
/*
@@ -898,6 +1067,19 @@
RETURN_FROM_INT(0x0700)
/*
+ * Single Step Exception
+ */
+SingleStep:
+ SAVE_INT_REGS(0x0D00)
+ SAVE_PAGE_FAULT_REGS(0x0D00)
+ mr r3,r1 /* Set pointer to saved regs */
+ bl _EXTERN(SingleStepException)
+#if 0
+ bl _EXTERN(flush_instruction_cache)
+#endif
+ RETURN_FROM_INT(0x0D00)
+
+/*
* Floating point [not available, etc]
*/
FloatingPointCheck:
@@ -909,8 +1091,9 @@
/*
* System Call exception
- */
+ */
SystemCall:
+/* TRACE_TRAP(0x0C00) */
SAVE_INT_REGS(0x0C00)
lwz r2,_CCR(r1) /* Clear SO bit in CR */
lis r9,0x1000
@@ -923,11 +1106,15 @@
cmpi 0,r3,0 /* Check for restarted system call */
bge 99f
b 20f
-10: lis r2,sys_call_table@h
+10: lis r2,current_set@ha
+ lwz r2,current_set@l(r2)
+ 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] */
-
mtlr r2
mr r9,r1
blrl /* Call handler */
@@ -935,11 +1122,56 @@
cmpi 0,r3,0
bge 30f
neg r3,r3
- lwz r2,_CCR(r1) /* Set SO bit in CR */
+ cmpi 0,r3,ERESTARTNOHAND
+ bne 22f
+ li r3,EINTR
+22: lwz r2,_CCR(r1) /* Set SO bit in CR */
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)
+ lwz r0,GPR0(r1) /* Restore original registers */
+ lwz r3,GPR3(r1)
+ lwz r4,GPR4(r1)
+ lwz r5,GPR5(r1)
+ lwz r6,GPR6(r1)
+ lwz r7,GPR7(r1)
+ lwz r8,GPR8(r1)
+ lwz r9,GPR9(r1)
+ 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] */
+ mtlr r2
+ mr r9,r1
+ blrl /* Call handler */
+ stw r3,RESULT(r1) /* Save result */
+ cmpi 0,r3,0
+ bge 60f
+ neg r3,r3
+ cmpi 0,r3,ERESTARTNOHAND
+ bne 52f
+ li r3,EINTR
+52: lwz r2,_CCR(r1) /* Set SO bit in CR */
+ oris r2,r2,0x1000
+ stw r2,_CCR(r1)
+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)
/*
@@ -1205,6 +1437,7 @@
xoris r0,r0,MSR_TGPR>>16
mtcrf 0x80,r3 /* Restore CR0 */
ori r0,r0,MSR_FP /* Need to keep FP enabled */
+ sync /* Some chip revs have problems here... */
mtmsr r0
b InstructionAccess
@@ -1233,6 +1466,7 @@
xoris r0,r0,MSR_TGPR>>16
mtcrf 0x80,r3 /* Restore CR0 */
ori r0,r0,MSR_FP /* Need to keep FP enabled */
+ sync /* Some chip revs have problems here... */
mtmsr r0
b DataAccess
@@ -1246,22 +1480,11 @@
mfspr r3,HID0 /* Caches are controlled by this register */
li r4,0
ori r4,r4,(HID0_ICE|HID0_ICFI)
+ or r3,r3,r4 /* Need to enable+invalidate to clear */
+ mtspr HID0,r3
andc r3,r3,r4
- isync
- mtspr HID0,r3 /* Disable cache */
- isync
- ori r3,r3,HID0_ICFI
- isync
- mtspr HID0,r3 /* Invalidate cache */
- isync
- andc r3,r3,r4
- isync
- mtspr HID0,r3 /* Invalidate (step 2) */
- isync
- ori r3,r3,HID0_ICE
- isync
- mtspr HID0,r3 /* Enable cache */
- isync
+ ori r3,r3,HID0_ICE /* Enable cache */
+ mtspr HID0,r3
mtlr r5
blr
@@ -1284,6 +1507,23 @@
addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
bdnz 00b
10: blr
+
+/*
+ * Flush a particular page from the DATA cache
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ * void flush_page(void *page)
+ */
+_GLOBAL(flush_page)
+ li r4,0x0FFF
+ andc r3,r3,r4 /* Get page base address */
+ li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
+ mtctr r4
+00: dcbf 0,r3 /* Clear line */
+ icbi 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 00b
+ blr
/*
* This routine switches between two different tasks. The process
@@ -1348,6 +1588,7 @@
mtsr SR15,r0
tlbia /* Invalidate entire TLB */
BUMP(__TLBIAs)
+ bl _EXTERN(flush_instruction_cache)
#ifdef TLB_STATS
/* TEMP */
lis r2,DataLoadTLB_trace_ptr@h
@@ -1368,8 +1609,10 @@
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)
@@ -1422,11 +1665,17 @@
sdata:
.space 2*4096
sys_stack:
+ .space 2*4096
+CPU1_stack:
.globl empty_zero_page
empty_zero_page:
.space 4096
+ .globl swapper_pg_dir
+swapper_pg_dir:
+ .space 4096
+
/*
* This space gets a copy of optional info passed to us by the bootstrap
* Used to pass parameters into the kernel like root=/dev/sda1, etc.
@@ -1495,3 +1744,4 @@
_RFI_ptr: .long _RFI_DATA
.text
#endif
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this