|
|
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.