|
|
1.1 ! root 1: /****************************************************************************** ! 2: * Copyright (c) 2004, 2008 IBM Corporation ! 3: * All rights reserved. ! 4: * This program and the accompanying materials ! 5: * are made available under the terms of the BSD License ! 6: * which accompanies this distribution, and is available at ! 7: * http://www.opensource.org/licenses/bsd-license.php ! 8: * ! 9: * Contributors: ! 10: * IBM Corporation - initial implementation ! 11: *****************************************************************************/ ! 12: ! 13: #include <rtas.h> ! 14: ! 15: /* ! 16: Function: ! 17: Input: ! 18: r3: Destination to copy rtas code to ! 19: r4: Configuration ! 20: Output: ! 21: r3: Entry point for rtas calls ! 22: Decription: Called by OpenFirmware to instantiate rtas, needs to copy ! 23: itself to destination, also do a relocations. ! 24: ! 25: */ ! 26: ! 27: .extern rtas_entry ! 28: .extern .stack ! 29: .extern _got ! 30: .extern _got_end ! 31: .extern __bss_start ! 32: .extern __bss_end ! 33: .extern rtas_config ! 34: ! 35: ! 36: .section ".rtasstart","ax"; ! 37: .align 3 ! 38: .globl _rtas_start ! 39: _rtas_start: ! 40: mflr r10 # save link register ! 41: bcl 20,31,.over # branch (always) to .over ! 42: ! 43: .base: ! 44: .align 3 ! 45: ! 46: /* Our Open Firmware needs to know the size of the RTAS binary and the ! 47: * size & address of the RTAS function jump table. SLOF always looks for this ! 48: * information in the following three quads here at the very beginning of the ! 49: * RTAS binary at offset 8. So DO NOT DELETE/MOVE them! */ ! 50: ! 51: ._rtas_size: .quad _rtas_end-_rtas_start ! 52: ._ptr_to_func_tab: .quad rtas_func_tab-_rtas_start ! 53: ._ptr_to_func_tab_size: .quad rtas_func_tab_size-_rtas_start ! 54: ! 55: /* The other variables are not accessed by SLOF anymore: */ ! 56: ! 57: ._rel_offset: .quad _reloc_table_start-_rtas_start ! 58: ._rel_end_offset: .quad _reloc_table_end-_rtas_start ! 59: ._bss_offset: .quad __bss_start-_rtas_start ! 60: ._bss_end_offset: .quad __bss_end-_rtas_start ! 61: ._rtas_entry_offset: .quad rtas_entry-_rtas_start ! 62: ._rtas_config_offset: .quad rtas_config-_rtas_start ! 63: ._rtas_stack: .quad .stack-_rtas_start+RTAS_STACKSIZE-0x60 ! 64: ._rtas_toc: .quad _got-_rtas_start+0x8000 ! 65: ! 66: .over: ! 67: mflr r8 # gpr 8 is the base ! 68: addi r8,r8,_rtas_start-.base # points to _rtas_start ! 69: mr r11,r4 # Save config value ! 70: ! 71: # Copy rtas code ! 72: ! 73: ld r5,._rtas_size-_rtas_start(r8) ! 74: mr r4,r8 # Start of rtas ! 75: addi r6,r3,-8 # Destination ! 76: addi r4,r4,-8 # Source ! 77: srdi r5,r5,3 # Count in quads ! 78: mtctr r5 ! 79: 0: ! 80: ldu r0,8(r4) ! 81: stdu r0,8(r6) ! 82: bdnz 0b ! 83: ! 84: # Clear bss ! 85: ! 86: ld r4,._bss_offset-_rtas_start(r8) ! 87: ld r5,._bss_end_offset-_rtas_start(r8) ! 88: li r0,0 ! 89: add r6,r3,r4 # Address bss in copied code ! 90: addi r6,r6,-8 ! 91: sub r5,r5,r4 # Calculate bss size ! 92: srdi r5,r5,3 # Count in quads ! 93: mtctr r5 ! 94: 0: ! 95: stdu r0,8(r6) ! 96: bdnz 0b ! 97: ! 98: # Relocate got ! 99: ! 100: ld r4, ._rel_offset-_rtas_start(r8) ! 101: ld r5, ._rel_end_offset-_rtas_start(r8) ! 102: sub r5, r5,r4 # Calculate reloc table size ! 103: cmpdi r5, 0 # No reloc table ? ! 104: beq 1f ! 105: ! 106: add r4, r4, r3 # Calculate reloc table address ! 107: addi r4, r4, -4 ! 108: srdi r5, r5, 2 # Count in words ! 109: mtctr r5 ! 110: 0: ! 111: lwzu r6, 4(r4) # Load offset out of reloc table ! 112: ldx r0, r6, r3 # Load value ! 113: add r0, r0, r3 # Add relocation offset = load address ! 114: stdx r0, r6, r3 ! 115: bdnz 0b ! 116: 1: ! 117: ! 118: # Save config data ! 119: ! 120: ld r5,._rtas_config_offset-_rtas_start(r8) ! 121: add r5,r5,r3 ! 122: std r11,0(r5) ! 123: ! 124: # Flush to memory ! 125: ! 126: mr r4,r3 # Destination address ! 127: ld r5,._rtas_size-_rtas_start(r8) ! 128: ! 129: add r5,r5,r4 ! 130: addi r5,r5,127 ! 131: rlwinm r4,r4,0,0,24 ! 132: rlwinm r5,r5,0,0,24 ! 133: sub r5,r5,r4 ! 134: srwi r5,r5,7 ! 135: mtctr r5 ! 136: 0: ! 137: dcbst 0,r4 ! 138: sync ! 139: icbi 0,r4 ! 140: sync ! 141: isync ! 142: addi r4,r4,128 ! 143: bdnz 0b ! 144: ! 145: # Call init function ! 146: mfmsr r11 # Switch to 64 bit mode ! 147: mr r7,r11 ! 148: rotldi r11,r11,1 ! 149: ori r11,r11,1 ! 150: rotldi r11,r11,63 ! 151: mtmsrd r11 ! 152: isync ! 153: mr r9,r1 # save old stack pointer ! 154: ld r1,._rtas_stack-_rtas_start(r8) # load new stack pointer ! 155: add r1,r1,r3 ! 156: std r9,0(r1) # save stack pointer ! 157: std r2,64(r1) # save toc ! 158: std r7,72(r1) # save old msr value ! 159: ! 160: ld r2,._rtas_toc-_rtas_start(r8) # load got pointer ! 161: add r2,r2,r3 ! 162: ! 163: bl save_regs_r3_r12 ! 164: bl .rtas_init ! 165: bl restore_regs_r3_r12 ! 166: ! 167: ld r11,72(r1) # restore msr value ! 168: ld r2,64(r1) # restore toc ! 169: ld r1,0(r1) # get old stack ! 170: ! 171: mtmsrd r11 # restore msr ! 172: isync ! 173: ! 174: ! 175: # Return rtas entry ! 176: ! 177: ld r4,._rtas_entry_offset-_rtas_start(r8) ! 178: add r3,r3,r4 ! 179: mtlr r10 ! 180: blr ! 181: ! 182: ! 183:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.