|
|
1.1 ! root 1: /* ! 2: * Creation Date: <2001/06/16 21:30:18 samuel> ! 3: * Time-stamp: <2003/04/04 16:32:06 samuel> ! 4: * ! 5: * <init.S> ! 6: * ! 7: * Asm glue for ELF images run inside MOL ! 8: * ! 9: * Copyright (C) 2001, 2002, 2003 Samuel Rydh ([email protected]) ! 10: * ! 11: * This program is free software; you can redistribute it and/or ! 12: * modify it under the terms of the GNU General Public License ! 13: * as published by the Free Software Foundation ! 14: * ! 15: */ ! 16: ! 17: #include "asm/asmdefs.h" ! 18: #include "asm/processor.h" ! 19: #include "osi.h" ! 20: ! 21: /************************************************************************/ ! 22: /* Macros */ ! 23: /************************************************************************/ ! 24: ! 25: #define ILLEGAL_VECTOR( v ) .org __vectors + v ; bl trap_error ; ! 26: #define VECTOR( v, dummystr ) .org __vectors + v ; vector__##v ! 27: ! 28: #define EXCEPTION_PREAMBLE \ ! 29: mtsprg1 r1 ; /* scratch */ \ ! 30: mfsprg0 r1 ; /* exception stack in sprg0 */ \ ! 31: addi r1,r1,-80 ; /* push exception frame */ \ ! 32: \ ! 33: stw r0,0(r1) ; /* save r0 */ \ ! 34: mfsprg1 r0 ; \ ! 35: stw r0,4(r1) ; /* save r1 */ \ ! 36: stw r2,8(r1) ; /* save r2 */ \ ! 37: stw r3,12(r1) ; /* save r3 */ \ ! 38: stw r4,16(r1) ; \ ! 39: stw r5,20(r1) ; \ ! 40: stw r6,24(r1) ; \ ! 41: stw r7,28(r1) ; \ ! 42: stw r8,32(r1) ; \ ! 43: stw r9,36(r1) ; \ ! 44: stw r10,40(r1) ; \ ! 45: stw r11,44(r1) ; \ ! 46: stw r12,48(r1) ; \ ! 47: \ ! 48: mflr r0 ; \ ! 49: stw r0,52(r1) ; \ ! 50: mfcr r0 ; \ ! 51: stw r0,56(r1) ; \ ! 52: mfctr r0 ; \ ! 53: stw r0,60(r1) ; \ ! 54: mfxer r0 ; \ ! 55: stw r0,64(r1) ; \ ! 56: \ ! 57: /* 76(r1) unused */ \ ! 58: addi r1,r1,-16 ; /* call conventions uses 0(r1) and 4(r1)... */ ! 59: ! 60: ! 61: /************************************************************************/ ! 62: /* stack space */ ! 63: /************************************************************************/ ! 64: ! 65: .section .bss ! 66: .balign 32 ! 67: .space 32*1024 // 32 K client stack ! 68: client_stack: ! 69: .space 128 ! 70: ! 71: .space 64*1024 // 64 K stack ! 72: stack: .space 64 ! 73: ! 74: .space 32*1024 // 32 K exception stack ! 75: estack: .space 128 ! 76: ! 77: ! 78: /************************************************************************/ ! 79: /* entry */ ! 80: /************************************************************************/ ! 81: ! 82: .text ! 83: GLOBL(_start): ! 84: li r0,0 ! 85: mtmsr r0 ! 86: ! 87: lis r1,HA(estack) ! 88: addi r1,r1,LO(estack) ! 89: mtsprg0 r1 // setup exception stack ! 90: lis r1,HA(stack) ! 91: addi r1,r1,LO(stack) ! 92: ! 93: // copy exception vectors ! 94: lis r3,HA(__vectors) ! 95: addi r3,r3,LO(__vectors) ! 96: li r4,0 ! 97: li r5,__vectors_end - __vectors + 16 ! 98: rlwinm r5,r5,0,0,28 ! 99: 1: lwz r6,0(r3) ! 100: lwz r7,4(r3) ! 101: lwz r8,8(r3) ! 102: lwz r9,12(r3) ! 103: stw r6,0(r4) ! 104: stw r7,4(r4) ! 105: stw r8,8(r4) ! 106: stw r9,12(r4) ! 107: dcbst 0,r4 ! 108: sync ! 109: icbi 0,r4 ! 110: sync ! 111: addi r5,r5,-16 ! 112: addi r3,r3,16 ! 113: addi r4,r4,16 ! 114: cmpwi r5,0 ! 115: bgt 1b ! 116: isync ! 117: ! 118: bl setup_mmu ! 119: bl entry ! 120: 1: nop ! 121: b 1b ! 122: ! 123: ! 124: /* According to IEEE 1275, PPC bindings: ! 125: * ! 126: * MSR = FP, ME + (DR|IR) ! 127: * r1 = stack (32 K + 32 bytes link area above) ! 128: * r5 = clint interface handler ! 129: * r6 = address of client program arguments (unused) ! 130: * r7 = length of client program arguments (unsed) ! 131: */ ! 132: saved_stack: ! 133: .long 0 ! 134: /* void call_elf( entry ) */ ! 135: GLOBL(call_elf): ! 136: mflr r0 ! 137: stwu r1,-16(r1) ! 138: stw r0,20(r1) ! 139: mtlr r3 ! 140: lis r8,HA(saved_stack) ! 141: addi r8,r8,LO(saved_stack) // save our stack pointer ! 142: stw r1,0(r8) ! 143: lis r1,HA(client_stack) ! 144: addi r1,r1,LO(client_stack) ! 145: lis r5,HA(of_client_callback) ! 146: addi r5,r5,LO(of_client_callback) // r5 = callback ! 147: li r6,0 // r6 = address of client program arguments (unused) ! 148: li r7,0 // r7 = length of client program arguments (unused) ! 149: li r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR ! 150: mtmsr r0 ! 151: blrl ! 152: ! 153: lis r8,HA(saved_stack) ! 154: addi r8,r8,LO(saved_stack) // restore stack pointer ! 155: mr r1,r8 ! 156: lwz r0,20(r1) ! 157: mtlr r0 ! 158: addi r1,r1,16 ! 159: // XXX: should restore r12-r31 etc.. ! 160: // we should not really come here though ! 161: blr ! 162: ! 163: GLOBL(of_client_callback): ! 164: lis r4,HA(saved_stack) ! 165: addi r4,r4,LO(saved_stack) ! 166: lwz r4,0(r4) ! 167: stwu r4,-32(r4) ! 168: mflr r5 ! 169: stw r5,32+4(r4) ! 170: stw r1,8(r4) // save caller stack ! 171: mr r1,r4 ! 172: stw r2,12(r1) ! 173: stw r0,16(r1) ! 174: mfctr r2 ! 175: stw r2,20(r1) ! 176: mfcr r2 ! 177: stw r2,24(r1) ! 178: mfxer r2 ! 179: stw r2,28(r1) ! 180: // do we need to save more registers? ! 181: bl of_client_interface ! 182: lwz r4,32+4(r1) ! 183: mtlr r4 ! 184: lwz r2,20(r1) ! 185: mtctr r2 ! 186: lwz r2,24(r1) ! 187: mtcr r2 ! 188: lwz r2,28(r1) ! 189: mtxer r2 ! 190: lwz r2,12(r1) ! 191: lwz r0,16(r1) ! 192: lwz r1,8(r1) // restore caller stack ! 193: blr ! 194: ! 195: /* rtas glue (must be reloctable) */ ! 196: GLOBL(of_rtas_start): ! 197: /* r3 = argument buffer, r4 = of_rtas_start */ ! 198: /* according to the CHRP standard, cr must be preserved (cr0/cr1 too?) */ ! 199: mr r6,r3 ! 200: lis r3,HA(OSI_SC_MAGIC_R3) ! 201: addi r3,r3,LO(OSI_SC_MAGIC_R3) ! 202: lis r4,HA(OSI_SC_MAGIC_R4) ! 203: addi r4,r4,LO(OSI_SC_MAGIC_R4) ! 204: li r5,OSI_OF_RTAS ! 205: sc ! 206: blr ! 207: GLOBL(of_rtas_end): ! 208: ! 209: ! 210: /* used in a hack to the newworld calibration */ ! 211: GLOBL(nw_dec_calibration): ! 212: .long 0 ! 213: GLOBL(timer_calib_start): ! 214: lis r3,HA(nw_dec_calibration) ! 215: addi r3,r3,LO(nw_dec_calibration) ! 216: lwz r3,0(r3) ! 217: blr ! 218: GLOBL(timer_calib_end): ! 219: ! 220: ! 221: /************************************************************************/ ! 222: /* vectors */ ! 223: /************************************************************************/ ! 224: ! 225: GLOBL(__vectors): ! 226: nop // NULL-jmp trap ! 227: 1: nop // ! 228: b 1b ! 229: ! 230: exception_return: ! 231: addi r1,r1,16 // pop ABI frame ! 232: ! 233: lwz r0,52(r1) ! 234: mtlr r0 ! 235: lwz r0,56(r1) ! 236: mtcr r0 ! 237: lwz r0,60(r1) ! 238: mtctr r0 ! 239: lwz r0,64(r1) ! 240: mtxer r0 ! 241: ! 242: lwz r0,0(r1) // restore r0 ! 243: lwz r2,8(r1) // restore r2 ! 244: lwz r3,12(r1) // restore r3 ! 245: lwz r4,16(r1) ! 246: lwz r5,20(r1) ! 247: lwz r6,24(r1) ! 248: lwz r7,28(r1) ! 249: lwz r8,32(r1) ! 250: lwz r9,36(r1) ! 251: lwz r10,40(r1) ! 252: lwz r11,44(r1) ! 253: lwz r12,48(r1) ! 254: lwz r1,4(r1) // restore r1 ! 255: rfi ! 256: ! 257: trap_error: ! 258: mflr r3 ! 259: b unexpected_excep ! 260: ! 261: ILLEGAL_VECTOR( 0x100 ) ! 262: ILLEGAL_VECTOR( 0x200 ) ! 263: ! 264: VECTOR( 0x300, "DSI" ): ! 265: EXCEPTION_PREAMBLE ! 266: lis r3,HA(dsi_exception) ! 267: addi r3,r3,LO(dsi_exception) ! 268: mtctr r3 ! 269: bctrl ! 270: b exception_return ! 271: ! 272: VECTOR( 0x400, "ISI" ): ! 273: EXCEPTION_PREAMBLE ! 274: lis r3,HA(isi_exception) ! 275: addi r3,r3,LO(isi_exception) ! 276: mtctr r3 ! 277: bctrl ! 278: b exception_return ! 279: ! 280: ILLEGAL_VECTOR( 0x500 ) ! 281: ILLEGAL_VECTOR( 0x600 ) ! 282: ILLEGAL_VECTOR( 0x700 ) ! 283: ! 284: VECTOR( 0x800, "FPU" ): ! 285: mtsprg1 r3 ! 286: mfsrr1 r3 ! 287: ori r3,r3,0x2000 ! 288: mtsrr1 r3 ! 289: mfsprg1 r3 ! 290: rfi ! 291: ! 292: ILLEGAL_VECTOR( 0x900 ) ! 293: ILLEGAL_VECTOR( 0xa00 ) ! 294: ILLEGAL_VECTOR( 0xb00 ) ! 295: ILLEGAL_VECTOR( 0xc00 ) ! 296: ILLEGAL_VECTOR( 0xd00 ) ! 297: ILLEGAL_VECTOR( 0xe00 ) ! 298: ILLEGAL_VECTOR( 0xf00 ) ! 299: ILLEGAL_VECTOR( 0xf20 ) ! 300: ILLEGAL_VECTOR( 0x1000 ) ! 301: ILLEGAL_VECTOR( 0x1100 ) ! 302: ILLEGAL_VECTOR( 0x1200 ) ! 303: ILLEGAL_VECTOR( 0x1300 ) ! 304: ILLEGAL_VECTOR( 0x1400 ) ! 305: ILLEGAL_VECTOR( 0x1500 ) ! 306: ILLEGAL_VECTOR( 0x1600 ) ! 307: ILLEGAL_VECTOR( 0x1700 ) ! 308: ! 309: GLOBL(__vectors_end): ! 310: ! 311: ! 312: #define CACHE_LINE_SIZE 32 ! 313: #define LG_CACHE_LINE_SIZE 5 ! 314: ! 315: /* flush_icache_range( unsigned long start, unsigned long stop) */ ! 316: GLOBL(flush_icache_range): ! 317: li r5,CACHE_LINE_SIZE-1 ! 318: andc r3,r3,r5 ! 319: subf r4,r3,r4 ! 320: add r4,r4,r5 ! 321: srwi. r4,r4,LG_CACHE_LINE_SIZE ! 322: beqlr ! 323: mtctr r4 ! 324: mr r6,r3 ! 325: 1: dcbst 0,r3 ! 326: addi r3,r3,CACHE_LINE_SIZE ! 327: bdnz 1b ! 328: sync /* wait for dcbst's to get to ram */ ! 329: mtctr r4 ! 330: 2: icbi 0,r6 ! 331: addi r6,r6,CACHE_LINE_SIZE ! 332: bdnz 2b ! 333: sync /* additional sync needed on g4 */ ! 334: isync ! 335: blr
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.