1*10465441SEvalZero#include <config.h> 2*10465441SEvalZero#include <asm/ppc_defs.h> 3*10465441SEvalZero 4*10465441SEvalZero/* #include <asm/cache.h> */ 5*10465441SEvalZero#include "cache.h" 6*10465441SEvalZero#include <asm/ppc4xx.h> 7*10465441SEvalZero 8*10465441SEvalZero#include "context.h" 9*10465441SEvalZero 10*10465441SEvalZero#define CONFIG_SYS_DCACHE_SACR_VALUE (0x00000000) 11*10465441SEvalZero#define CONFIG_SYS_ICACHE_SACR_VALUE \ 12*10465441SEvalZero (PPC_128MB_SACR_VALUE(CONFIG_SYS_SDRAM_BASE + ( 0 << 20)) | \ 13*10465441SEvalZero PPC_128MB_SACR_VALUE(CONFIG_SYS_SDRAM_BASE + (128 << 20)) | \ 14*10465441SEvalZero PPC_128MB_SACR_VALUE(CONFIG_SYS_FLASH_BASE)) 15*10465441SEvalZero 16*10465441SEvalZero#define function_prolog(func_name) .text; \ 17*10465441SEvalZero .align 2; \ 18*10465441SEvalZero .globl func_name; \ 19*10465441SEvalZero func_name: 20*10465441SEvalZero#define function_epilog(func_name) .type func_name,@function; \ 21*10465441SEvalZero .size func_name,.-func_name 22*10465441SEvalZero 23*10465441SEvalZero/* We don't want the MMU yet. 24*10465441SEvalZero*/ 25*10465441SEvalZero#undef MSR_KERNEL 26*10465441SEvalZero#define MSR_KERNEL ( MSR_ME ) /* Machine Check */ 27*10465441SEvalZero 28*10465441SEvalZero#define SYNC \ 29*10465441SEvalZero sync; \ 30*10465441SEvalZero isync 31*10465441SEvalZero 32*10465441SEvalZero/* 33*10465441SEvalZero * Macros for storing registers into and loading registers from 34*10465441SEvalZero * exception frames. 35*10465441SEvalZero */ 36*10465441SEvalZero#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base) 37*10465441SEvalZero#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) 38*10465441SEvalZero#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) 39*10465441SEvalZero#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) 40*10465441SEvalZero#define SAVE_10GPRS(n,base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) 41*10465441SEvalZero#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base) 42*10465441SEvalZero#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) 43*10465441SEvalZero#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) 44*10465441SEvalZero#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) 45*10465441SEvalZero#define REST_10GPRS(n,base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) 46*10465441SEvalZero 47*10465441SEvalZero/* 48*10465441SEvalZero * GCC sometimes accesses words at negative offsets from the stack 49*10465441SEvalZero * pointer, although the SysV ABI says it shouldn't. To cope with 50*10465441SEvalZero * this, we leave this much untouched space on the stack on exception 51*10465441SEvalZero * entry. 52*10465441SEvalZero */ 53*10465441SEvalZero#define STACK_UNDERHEAD 64 54*10465441SEvalZero 55*10465441SEvalZero/* 56*10465441SEvalZero * Exception entry code. This code runs with address translation 57*10465441SEvalZero * turned off, i.e. using physical addresses. 58*10465441SEvalZero * We assume sprg3 has the physical address of the current 59*10465441SEvalZero * task's thread_struct. 60*10465441SEvalZero */ 61*10465441SEvalZero /* Save: 62*10465441SEvalZero * CR, r0, r1 (sp), r2, r3, r4, r5, r6, r20, r21, r22, r23, 63*10465441SEvalZero * LR, CTR, XER, DAR, SRR0, SRR1 64*10465441SEvalZero */ 65*10465441SEvalZero#define EXCEPTION_PROLOG(reg1, reg2) \ 66*10465441SEvalZero mtspr SPRG0,r20; \ 67*10465441SEvalZero mtspr SPRG1,r21; \ 68*10465441SEvalZero mfcr r20; \ 69*10465441SEvalZero subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\ 70*10465441SEvalZero stw r20,_CCR(r21); /* save registers */ \ 71*10465441SEvalZero stw r22,GPR22(r21); \ 72*10465441SEvalZero stw r23,GPR23(r21); \ 73*10465441SEvalZero mfspr r20,SPRG0; \ 74*10465441SEvalZero stw r20,GPR20(r21); \ 75*10465441SEvalZero mfspr r22,SPRG1; \ 76*10465441SEvalZero stw r22,GPR21(r21); \ 77*10465441SEvalZero mflr r20; \ 78*10465441SEvalZero stw r20,_LINK(r21); \ 79*10465441SEvalZero mfctr r22; \ 80*10465441SEvalZero stw r22,_CTR(r21); \ 81*10465441SEvalZero mfspr r20,XER; \ 82*10465441SEvalZero stw r20,_XER(r21); \ 83*10465441SEvalZero mfspr r20, DAR_DEAR; \ 84*10465441SEvalZero stw r20,_DAR(r21); \ 85*10465441SEvalZero mfspr r22,reg1; \ 86*10465441SEvalZero mfspr r23,reg2; \ 87*10465441SEvalZero stw r0,GPR0(r21); \ 88*10465441SEvalZero stw r1,GPR1(r21); \ 89*10465441SEvalZero stw r2,GPR2(r21); \ 90*10465441SEvalZero stw r1,0(r21);/* back chain */ \ 91*10465441SEvalZero mr r1,r21;/* set new kernel sp */ \ 92*10465441SEvalZero SAVE_4GPRS(3, r21); 93*10465441SEvalZero/* 94*10465441SEvalZero * Note: code which follows this uses cr0.eq (set if from kernel), 95*10465441SEvalZero * r21, r22 (SRR0), and r23 (SRR1). 96*10465441SEvalZero */ 97*10465441SEvalZero 98*10465441SEvalZero/* 99*10465441SEvalZero * Exception vectors. 100*10465441SEvalZero * 101*10465441SEvalZero * The data words for `hdlr' and `int_return' are initialized with 102*10465441SEvalZero * OFFSET values only; they must be relocated first before they can 103*10465441SEvalZero * be used! 104*10465441SEvalZero */ 105*10465441SEvalZero#define STD_EXCEPTION(n, label, hdlr) \ 106*10465441SEvalZero . = n; \ 107*10465441SEvalZerolabel: \ 108*10465441SEvalZero EXCEPTION_PROLOG(SRR0, SRR1); \ 109*10465441SEvalZero lwz r3,GOT(transfer_to_handler); \ 110*10465441SEvalZero mtlr r3; \ 111*10465441SEvalZero addi r3,r1,STACK_FRAME_OVERHEAD; \ 112*10465441SEvalZero li r20,MSR_KERNEL; \ 113*10465441SEvalZero rlwimi r20,r23,0,25,25; \ 114*10465441SEvalZero blrl; \ 115*10465441SEvalZero.L_ ## label : \ 116*10465441SEvalZero .long hdlr - _start + _START_OFFSET; \ 117*10465441SEvalZero .long int_return - _start + _START_OFFSET 118*10465441SEvalZero 119*10465441SEvalZero#define CRIT_EXCEPTION(n, label, hdlr) \ 120*10465441SEvalZero . = n; \ 121*10465441SEvalZerolabel: \ 122*10465441SEvalZero EXCEPTION_PROLOG(CSRR0, CSRR1); \ 123*10465441SEvalZero lwz r3,GOT(transfer_to_handler); \ 124*10465441SEvalZero mtlr r3; \ 125*10465441SEvalZero addi r3,r1,STACK_FRAME_OVERHEAD; \ 126*10465441SEvalZero li r20,(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)); \ 127*10465441SEvalZero rlwimi r20,r23,0,25,25; \ 128*10465441SEvalZero blrl; \ 129*10465441SEvalZero.L_ ## label : \ 130*10465441SEvalZero .long hdlr - _start + _START_OFFSET; \ 131*10465441SEvalZero .long crit_return - _start + _START_OFFSET 132*10465441SEvalZero 133*10465441SEvalZero#define MCK_EXCEPTION(n, label, hdlr) \ 134*10465441SEvalZero . = n; \ 135*10465441SEvalZerolabel: \ 136*10465441SEvalZero EXCEPTION_PROLOG(MCSRR0, MCSRR1); \ 137*10465441SEvalZero lwz r3,GOT(transfer_to_handler); \ 138*10465441SEvalZero mtlr r3; \ 139*10465441SEvalZero addi r3,r1,STACK_FRAME_OVERHEAD; \ 140*10465441SEvalZero li r20,(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)); \ 141*10465441SEvalZero rlwimi r20,r23,0,25,25; \ 142*10465441SEvalZero blrl; \ 143*10465441SEvalZero.L_ ## label : \ 144*10465441SEvalZero .long hdlr - _start + _START_OFFSET; \ 145*10465441SEvalZero .long mck_return - _start + _START_OFFSET 146*10465441SEvalZero 147*10465441SEvalZero 148*10465441SEvalZero/*************************************************************************** 149*10465441SEvalZero * 150*10465441SEvalZero * These definitions simplify the ugly declarations necessary for GOT 151*10465441SEvalZero * definitions. 152*10465441SEvalZero * 153*10465441SEvalZero * Stolen from prepboot/bootldr.h, (C) 1998 Gabriel Paubert, [email protected] 154*10465441SEvalZero * 155*10465441SEvalZero * Uses r14 to access the GOT 156*10465441SEvalZero */ 157*10465441SEvalZero 158*10465441SEvalZero#define START_GOT \ 159*10465441SEvalZero .section ".got2","aw"; \ 160*10465441SEvalZero.LCTOC1 = .+32768 161*10465441SEvalZero 162*10465441SEvalZero#define END_GOT \ 163*10465441SEvalZero .text 164*10465441SEvalZero 165*10465441SEvalZero#define GET_GOT \ 166*10465441SEvalZero bl 1f ; \ 167*10465441SEvalZero .text 2 ; \ 168*10465441SEvalZero0: .long .LCTOC1-1f ; \ 169*10465441SEvalZero .text ; \ 170*10465441SEvalZero1: mflr r14 ; \ 171*10465441SEvalZero lwz r0,0b-1b(r14) ; \ 172*10465441SEvalZero add r14,r0,r14 ; 173*10465441SEvalZero 174*10465441SEvalZero#define GOT_ENTRY(NAME) .L_ ## NAME = . - .LCTOC1 ; .long NAME 175*10465441SEvalZero 176*10465441SEvalZero#define GOT(NAME) .L_ ## NAME (r14) 177*10465441SEvalZero 178*10465441SEvalZero/* 179*10465441SEvalZero * Set up GOT: Global Offset Table 180*10465441SEvalZero * 181*10465441SEvalZero * Use r14 to access the GOT 182*10465441SEvalZero */ 183*10465441SEvalZero START_GOT 184*10465441SEvalZero GOT_ENTRY(_GOT2_TABLE_) 185*10465441SEvalZero GOT_ENTRY(_FIXUP_TABLE_) 186*10465441SEvalZero 187*10465441SEvalZero GOT_ENTRY(_start) 188*10465441SEvalZero GOT_ENTRY(_start_of_vectors) 189*10465441SEvalZero GOT_ENTRY(_end_of_vectors) 190*10465441SEvalZero GOT_ENTRY(transfer_to_handler) 191*10465441SEvalZero 192*10465441SEvalZero GOT_ENTRY(__init_end) 193*10465441SEvalZero GOT_ENTRY(_end) 194*10465441SEvalZero GOT_ENTRY(__bss_start) 195*10465441SEvalZero END_GOT 196*10465441SEvalZero 197*10465441SEvalZero/* 198*10465441SEvalZero * r3 - 1st arg to board_init(): IMMP pointer 199*10465441SEvalZero * r4 - 2nd arg to board_init(): boot flag 200*10465441SEvalZero */ 201*10465441SEvalZero .text 202*10465441SEvalZeroversion_string: 203*10465441SEvalZero .ascii "RT-Thread 0.4.0" 204*10465441SEvalZero 205*10465441SEvalZero . = EXC_OFF_SYS_RESET 206*10465441SEvalZero_start_of_vectors: 207*10465441SEvalZero 208*10465441SEvalZero /* Critical input. */ 209*10465441SEvalZero CRIT_EXCEPTION(0x100, CritcalInput, UnknownException) 210*10465441SEvalZero CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException) 211*10465441SEvalZero /* Data Storage exception. */ 212*10465441SEvalZero STD_EXCEPTION(0x300, DataStorage, UnknownException) 213*10465441SEvalZero /* Instruction Storage exception. */ 214*10465441SEvalZero STD_EXCEPTION(0x400, InstStorage, UnknownException) 215*10465441SEvalZero 216*10465441SEvalZero . = 0x0500 217*10465441SEvalZeroExtInterrupt: 218*10465441SEvalZero /* save current thread stack */ 219*10465441SEvalZero subi r1, r1, STACK_FRAME_SIZE 220*10465441SEvalZero 221*10465441SEvalZero /* save registers */ 222*10465441SEvalZero stw r0,GPR0(r1) /* save general purpose registers 0 */ 223*10465441SEvalZero stmw r2,GPR2(r1) /* save general purpose registers 2-31 */ 224*10465441SEvalZero 225*10465441SEvalZero mfusprg0 r0 /* save usprg0 */ 226*10465441SEvalZero stw r0,USPRG0(r1) 227*10465441SEvalZero mfcr r0, /* save cr */ 228*10465441SEvalZero stw r0,CR(r1) 229*10465441SEvalZero mfxer r0 /* save xer */ 230*10465441SEvalZero stw r0,XER(r1) 231*10465441SEvalZero mfctr r0 /* save ctr */ 232*10465441SEvalZero stw r0,CTR(r1) 233*10465441SEvalZero mflr r0 /* save lr */ 234*10465441SEvalZero stw r0, LR(r1) 235*10465441SEvalZero 236*10465441SEvalZero mfsrr0 r0 /* save SRR0 and SRR1 */ 237*10465441SEvalZero stw r0,SRR0(r1) 238*10465441SEvalZero mfsrr1 r0 239*10465441SEvalZero stw r0,SRR1(r1) 240*10465441SEvalZero 241*10465441SEvalZero bl rt_interrupt_enter 242*10465441SEvalZero bl external_interrupt 243*10465441SEvalZero bl rt_interrupt_leave 244*10465441SEvalZero 245*10465441SEvalZero /* restore thread context */ 246*10465441SEvalZero lwz r0,SRR1(r1) /* restore SRR1 and SRR0 */ 247*10465441SEvalZero mtsrr1 r0 248*10465441SEvalZero lwz r0,SRR0(r1) 249*10465441SEvalZero mtsrr0 r0 250*10465441SEvalZero 251*10465441SEvalZero lwz r0,LR(r1) /* restore lr */ 252*10465441SEvalZero mtlr r0 253*10465441SEvalZero lwz r0,CTR(r1) /* restore ctr */ 254*10465441SEvalZero mtctr r0 255*10465441SEvalZero lwz r0,XER(r1) /* restore xer */ 256*10465441SEvalZero mtxer r0 257*10465441SEvalZero lwz r0,CR(r1) /* restore cr */ 258*10465441SEvalZero mtcr r0 259*10465441SEvalZero lwz r0,USPRG0(r1) /* restore usprg0 */ 260*10465441SEvalZero // mtusprg0 r0 261*10465441SEvalZero 262*10465441SEvalZero lmw r2, GPR2(r1) /* restore general register */ 263*10465441SEvalZero lwz r0,GPR0(r1) 264*10465441SEvalZero addi r1, r1, STACK_FRAME_SIZE 265*10465441SEvalZero b rt_hw_systemcall_entry 266*10465441SEvalZero 267*10465441SEvalZero/* Alignment exception. */ 268*10465441SEvalZero . = 0x600 269*10465441SEvalZeroAlignment: 270*10465441SEvalZero EXCEPTION_PROLOG(SRR0, SRR1) 271*10465441SEvalZero mfspr r4,DAR 272*10465441SEvalZero stw r4,_DAR(r21) 273*10465441SEvalZero mfspr r5,DSISR 274*10465441SEvalZero stw r5,_DSISR(r21) 275*10465441SEvalZero addi r3,r1,STACK_FRAME_OVERHEAD 276*10465441SEvalZero li r20,MSR_KERNEL 277*10465441SEvalZero rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ 278*10465441SEvalZero lwz r6,GOT(transfer_to_handler) 279*10465441SEvalZero mtlr r6 280*10465441SEvalZero blrl 281*10465441SEvalZero.L_Alignment: 282*10465441SEvalZero .long AlignmentException - _start + _START_OFFSET 283*10465441SEvalZero .long int_return - _start + _START_OFFSET 284*10465441SEvalZero 285*10465441SEvalZero/* Program check exception */ 286*10465441SEvalZero . = 0x700 287*10465441SEvalZeroProgramCheck: 288*10465441SEvalZero EXCEPTION_PROLOG(SRR0, SRR1) 289*10465441SEvalZero addi r3,r1,STACK_FRAME_OVERHEAD 290*10465441SEvalZero li r20,MSR_KERNEL 291*10465441SEvalZero rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ 292*10465441SEvalZero lwz r6,GOT(transfer_to_handler) 293*10465441SEvalZero mtlr r6 294*10465441SEvalZero blrl 295*10465441SEvalZero.L_ProgramCheck: 296*10465441SEvalZero .long ProgramCheckException - _start + _START_OFFSET 297*10465441SEvalZero .long int_return - _start + _START_OFFSET 298*10465441SEvalZero 299*10465441SEvalZero . = 0x0c00 300*10465441SEvalZeroSystemCall: 301*10465441SEvalZero b rt_hw_systemcall_entry 302*10465441SEvalZero 303*10465441SEvalZero . = 0x1000 304*10465441SEvalZeroPIT: 305*10465441SEvalZero /* save current thread stack */ 306*10465441SEvalZero subi r1, r1, STACK_FRAME_SIZE 307*10465441SEvalZero 308*10465441SEvalZero /* save registers */ 309*10465441SEvalZero stw r0,GPR0(r1) /* save general purpose registers 0 */ 310*10465441SEvalZero stmw r2,GPR2(r1) /* save general purpose registers 2-31 */ 311*10465441SEvalZero 312*10465441SEvalZero mfusprg0 r0 /* save usprg0 */ 313*10465441SEvalZero stw r0,USPRG0(r1) 314*10465441SEvalZero mfcr r0, /* save cr */ 315*10465441SEvalZero stw r0,CR(r1) 316*10465441SEvalZero mfxer r0 /* save xer */ 317*10465441SEvalZero stw r0,XER(r1) 318*10465441SEvalZero mfctr r0 /* save ctr */ 319*10465441SEvalZero stw r0,CTR(r1) 320*10465441SEvalZero mflr r0 /* save lr */ 321*10465441SEvalZero stw r0, LR(r1) 322*10465441SEvalZero 323*10465441SEvalZero mfsrr0 r0 /* save SRR0 and SRR1 */ 324*10465441SEvalZero stw r0,SRR0(r1) 325*10465441SEvalZero mfsrr1 r0 326*10465441SEvalZero stw r0,SRR1(r1) 327*10465441SEvalZero 328*10465441SEvalZero bl rt_interrupt_enter 329*10465441SEvalZero bl DecrementerPITException 330*10465441SEvalZero bl rt_interrupt_leave 331*10465441SEvalZero 332*10465441SEvalZero /* restore thread context */ 333*10465441SEvalZero lwz r0,SRR1(r1) /* restore SRR1 and SRR0 */ 334*10465441SEvalZero mtsrr1 r0 335*10465441SEvalZero lwz r0,SRR0(r1) 336*10465441SEvalZero mtsrr0 r0 337*10465441SEvalZero 338*10465441SEvalZero lwz r0,LR(r1) /* restore lr */ 339*10465441SEvalZero mtlr r0 340*10465441SEvalZero lwz r0,CTR(r1) /* restore ctr */ 341*10465441SEvalZero mtctr r0 342*10465441SEvalZero lwz r0,XER(r1) /* restore xer */ 343*10465441SEvalZero mtxer r0 344*10465441SEvalZero lwz r0,CR(r1) /* restore cr */ 345*10465441SEvalZero mtcr r0 346*10465441SEvalZero lwz r0,USPRG0(r1) /* restore usprg0 */ 347*10465441SEvalZero // mtusprg0 r0 348*10465441SEvalZero 349*10465441SEvalZero lmw r2, GPR2(r1) /* restore general register */ 350*10465441SEvalZero lwz r0,GPR0(r1) 351*10465441SEvalZero addi r1, r1, STACK_FRAME_SIZE 352*10465441SEvalZero b rt_hw_systemcall_entry 353*10465441SEvalZero 354*10465441SEvalZero STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) 355*10465441SEvalZero STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) 356*10465441SEvalZero 357*10465441SEvalZero CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException ) 358*10465441SEvalZero 359*10465441SEvalZero_end_of_vectors: 360*10465441SEvalZero . = _START_OFFSET 361*10465441SEvalZero 362*10465441SEvalZero /* 363*10465441SEvalZero * start and end addresses of the BSS section 364*10465441SEvalZero * they are taken from the linker script 365*10465441SEvalZero */ 366*10465441SEvalZero 367*10465441SEvalZero .set START_BSS, __bss_start 368*10465441SEvalZero .set END_BSS, __bss_end 369*10465441SEvalZero 370*10465441SEvalZero /* stack top address exported from linker script */ 371*10465441SEvalZero .set STACK_TOP, __stack_top 372*10465441SEvalZero 373*10465441SEvalZero_start: 374*10465441SEvalZero /*----------------------------------------------------------------------- */ 375*10465441SEvalZero /* Clear and set up some registers. */ 376*10465441SEvalZero /*----------------------------------------------------------------------- */ 377*10465441SEvalZero addi r4,r0,0x0000 378*10465441SEvalZero mtsgr r4 /* Configure guarded attribute for performance. */ 379*10465441SEvalZero mtsler r4 /* Configure endinanness */ 380*10465441SEvalZero mtsu0r r4 /* and compression. */ 381*10465441SEvalZero 382*10465441SEvalZero /*------------------------------------------------------------------------ 383*10465441SEvalZero * Initialize vector tables and other registers 384*10465441SEvalZero * set them all to 0. The Interrupt Handler implementation 385*10465441SEvalZero * has to set these registers later on 386*10465441SEvalZero *-----------------------------------------------------------------------*/ 387*10465441SEvalZero mtdcwr r4 388*10465441SEvalZero mtesr r4 /* clear Exception Syndrome Reg */ 389*10465441SEvalZero mttcr r4 /* clear Timer Control Reg */ 390*10465441SEvalZero mtxer r4 /* clear Fixed-Point Exception Reg */ 391*10465441SEvalZero mtevpr r4 /* clear Exception Vector Prefix Reg */ 392*10465441SEvalZero 393*10465441SEvalZero addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */ 394*10465441SEvalZero /* dbsr is cleared by setting bits to 1) */ 395*10465441SEvalZero mtdbsr r4 /* clear/reset the dbsr */ 396*10465441SEvalZero 397*10465441SEvalZero /* Invalidate the i- and d-caches. */ 398*10465441SEvalZero bl invalidate_icache 399*10465441SEvalZero bl invalidate_dcache 400*10465441SEvalZero 401*10465441SEvalZero /* Set-up icache cacheability. */ 402*10465441SEvalZero lis r4, CONFIG_SYS_ICACHE_SACR_VALUE@h 403*10465441SEvalZero ori r4, r4, CONFIG_SYS_ICACHE_SACR_VALUE@l 404*10465441SEvalZero mticcr r4 405*10465441SEvalZero isync 406*10465441SEvalZero 407*10465441SEvalZero /* Set-up dcache cacheability. */ 408*10465441SEvalZero lis r4, CONFIG_SYS_DCACHE_SACR_VALUE@h 409*10465441SEvalZero ori r4, r4, CONFIG_SYS_DCACHE_SACR_VALUE@l 410*10465441SEvalZero mtdccr r4 411*10465441SEvalZero 412*10465441SEvalZero /*----------------------------------------------------------------------- */ 413*10465441SEvalZero /* DMA Status, clear to come up clean */ 414*10465441SEvalZero /*----------------------------------------------------------------------- */ 415*10465441SEvalZero addis r3,r0, 0xFFFF /* Clear all existing DMA status */ 416*10465441SEvalZero ori r3,r3, 0xFFFF 417*10465441SEvalZero mtdcr dmasr, r3 418*10465441SEvalZero 419*10465441SEvalZero /* clear the BSS section */ 420*10465441SEvalZero lis r3,START_BSS@h // load start of BSS into r3 421*10465441SEvalZero ori r3,r3,START_BSS@l 422*10465441SEvalZero lis r4,END_BSS@h // load end of BSS into r4 423*10465441SEvalZero ori r4,r4,END_BSS@l 424*10465441SEvalZero sub r4,r4,r3 // calculate length of BSS 425*10465441SEvalZero srwi r4,r4,2 // convert byte-length to word-length 426*10465441SEvalZero li r5,0 // zero r5 427*10465441SEvalZero cmplw 0,r4,r5 // check to see whether length equals 0 428*10465441SEvalZero beql 0,2f // in case of length 0 we're already done 429*10465441SEvalZero subi r3,r3,4 // because of offset start 4 bytes lower 430*10465441SEvalZero mtctr r4 // use word-length of BSS section as counter 431*10465441SEvalZero1: /* bss clear start */ 432*10465441SEvalZero stwu r5,4(r3) // zero one word of BSS section 433*10465441SEvalZero bdnz 1b // keep going until BSS is entirely clean 434*10465441SEvalZero2: /* bss clear done */ 435*10465441SEvalZero 436*10465441SEvalZero /* Set up stack in the linker script defined RAM area */ 437*10465441SEvalZero lis r1, STACK_TOP@h 438*10465441SEvalZero ori r1, r1, STACK_TOP@l 439*10465441SEvalZero 440*10465441SEvalZero /* Set up a zeroized stack frame so that backtrace works right */ 441*10465441SEvalZero li r0, 0 442*10465441SEvalZero stwu r0, -4(r1) 443*10465441SEvalZero stwu r0, -4(r1) 444*10465441SEvalZero 445*10465441SEvalZero /* 446*10465441SEvalZero * Set up a dummy frame to store reset vector as return address. 447*10465441SEvalZero * this causes stack underflow to reset board. 448*10465441SEvalZero */ 449*10465441SEvalZero stwu r1, -8(r1) /* Save back chain and move SP */ 450*10465441SEvalZero lis r0, RESET_VECTOR@h /* Address of reset vector */ 451*10465441SEvalZero ori r0, r0, RESET_VECTOR@l 452*10465441SEvalZero stwu r1, -8(r1) /* Save back chain and move SP */ 453*10465441SEvalZero stw r0, +12(r1) /* Save return addr (underflow vect) */ 454*10465441SEvalZero 455*10465441SEvalZero GET_GOT /* initialize GOT access */ 456*10465441SEvalZero 457*10465441SEvalZero /* NEVER RETURNS! */ 458*10465441SEvalZero bl rtthread_startup 459*10465441SEvalZero 460*10465441SEvalZero/* 461*10465441SEvalZero * Note: code which follows this uses cr0.eq (set if from kernel), 462*10465441SEvalZero * r20(new MSR), r21(trap frame), r22 (SRR0), and r23 (SRR1). 463*10465441SEvalZero */ 464*10465441SEvalZero 465*10465441SEvalZero/* 466*10465441SEvalZero * This code finishes saving the registers to the exception frame 467*10465441SEvalZero * and jumps to the appropriate handler for the exception. 468*10465441SEvalZero * Register r21 is pointer into trap frame, r1 has new stack pointer. 469*10465441SEvalZero */ 470*10465441SEvalZerotransfer_to_handler: 471*10465441SEvalZero stw r22,_NIP(r21) 472*10465441SEvalZero lis r22,MSR_POW@h /* clear POW bit */ 473*10465441SEvalZero andc r23,r23,r22 /* use normal power management */ 474*10465441SEvalZero stw r23,_MSR(r21) /* MSC value when the exception returns */ 475*10465441SEvalZero SAVE_GPR(7, r21) 476*10465441SEvalZero SAVE_4GPRS(8, r21) 477*10465441SEvalZero SAVE_8GPRS(12, r21) 478*10465441SEvalZero SAVE_8GPRS(24, r21) 479*10465441SEvalZero mflr r23 /* hdlr/int_return addr immediately follows */ 480*10465441SEvalZero andi. r24,r23,0x3f00 /* get vector offset */ 481*10465441SEvalZero stw r24,TRAP(r21) /* vector address, such as 0x1000 for PIT */ 482*10465441SEvalZero li r22,0 483*10465441SEvalZero stw r22,RESULT(r21) /* clear the sc return value */ 484*10465441SEvalZero mtspr SPRG2,r22 /* r1 is now kernel sp */ 485*10465441SEvalZero lwz r24,0(r23) /* virtual address of hdlr */ 486*10465441SEvalZero lwz r23,4(r23) /* where to go when done */ 487*10465441SEvalZero mtspr SRR0,r24 /* hdlr */ 488*10465441SEvalZero mtspr SRR1,r20 /* MSR_KERNEL with ME enabled */ 489*10465441SEvalZero mtlr r23 /* call hdlr and then return to int_return */ 490*10465441SEvalZero SYNC /* note r3 has address for pt_regs on stack */ 491*10465441SEvalZero rfi /* jump to handler, enable ME */ 492*10465441SEvalZero 493*10465441SEvalZeroint_return: 494*10465441SEvalZero addi r3,r1,STACK_FRAME_OVERHEAD 495*10465441SEvalZero lwz r4,_MQ(r1) 496*10465441SEvalZero cmpwi r4, 0 497*10465441SEvalZero beq goon_return 498*10465441SEvalZeroswitch_stack: 499*10465441SEvalZero subi r1,r4,STACK_FRAME_OVERHEAD 500*10465441SEvalZerogoon_return: 501*10465441SEvalZero mfmsr r28 /* Disable interrupts */ 502*10465441SEvalZero li r4,0 503*10465441SEvalZero ori r4,r4,MSR_EE /* clear External Interrupt Enable */ 504*10465441SEvalZero ori r4,r4,MSR_DE /* clear Debug Interrupts Enable - 4xx */ 505*10465441SEvalZero andc r28,r28,r4 506*10465441SEvalZero SYNC /* Some chip revs need this... */ 507*10465441SEvalZero mtmsr r28 508*10465441SEvalZero SYNC 509*10465441SEvalZero lwz r2,_CTR(r1) 510*10465441SEvalZero lwz r0,_LINK(r1) 511*10465441SEvalZero mtctr r2 512*10465441SEvalZero mtlr r0 513*10465441SEvalZero lwz r2,_XER(r1) 514*10465441SEvalZero lwz r0,_CCR(r1) 515*10465441SEvalZero mtspr XER,r2 516*10465441SEvalZero mtcrf 0xFF,r0 517*10465441SEvalZero REST_10GPRS(3, r1) 518*10465441SEvalZero REST_10GPRS(13, r1) 519*10465441SEvalZero REST_8GPRS(23, r1) 520*10465441SEvalZero REST_GPR(31, r1) 521*10465441SEvalZero lwz r2,_NIP(r1) /* Restore environment */ 522*10465441SEvalZero lwz r0,_MSR(r1) 523*10465441SEvalZero mtspr SRR0,r2 524*10465441SEvalZero mtspr SRR1,r0 525*10465441SEvalZero lwz r0,GPR0(r1) 526*10465441SEvalZero lwz r2,GPR2(r1) 527*10465441SEvalZero lwz r1,GPR1(r1) 528*10465441SEvalZero SYNC 529*10465441SEvalZero rfi 530*10465441SEvalZero b . /* prevent prefetch past rfi */ 531*10465441SEvalZero 532*10465441SEvalZerocrit_return: 533*10465441SEvalZero mfmsr r28 /* Disable interrupts */ 534*10465441SEvalZero li r4,0 535*10465441SEvalZero ori r4,r4,MSR_EE 536*10465441SEvalZero andc r28,r28,r4 537*10465441SEvalZero SYNC /* Some chip revs need this... */ 538*10465441SEvalZero mtmsr r28 539*10465441SEvalZero SYNC 540*10465441SEvalZero lwz r2,_CTR(r1) 541*10465441SEvalZero lwz r0,_LINK(r1) 542*10465441SEvalZero mtctr r2 543*10465441SEvalZero mtlr r0 544*10465441SEvalZero lwz r2,_XER(r1) 545*10465441SEvalZero lwz r0,_CCR(r1) 546*10465441SEvalZero mtspr XER,r2 547*10465441SEvalZero mtcrf 0xFF,r0 548*10465441SEvalZero REST_10GPRS(3, r1) 549*10465441SEvalZero REST_10GPRS(13, r1) 550*10465441SEvalZero REST_8GPRS(23, r1) 551*10465441SEvalZero REST_GPR(31, r1) 552*10465441SEvalZero lwz r2,_NIP(r1) /* Restore environment */ 553*10465441SEvalZero lwz r0,_MSR(r1) 554*10465441SEvalZero mtspr SPRN_CSRR0,r2 555*10465441SEvalZero mtspr SPRN_CSRR1,r0 556*10465441SEvalZero lwz r0,GPR0(r1) 557*10465441SEvalZero lwz r2,GPR2(r1) 558*10465441SEvalZero lwz r1,GPR1(r1) 559*10465441SEvalZero SYNC 560*10465441SEvalZero rfci 561*10465441SEvalZero 562*10465441SEvalZeroget_pvr: 563*10465441SEvalZero mfspr r3, PVR 564*10465441SEvalZero blr 565