1 /******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation
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
10 * IBM Corporation - initial implementation
11 *****************************************************************************/
18 r3: Destination to copy rtas code to
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.
36 .section ".rtasstart","ax";
40 mflr r10 # save link register
41 bcl 20,31,.over # branch (always) to .over
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! */
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
55 /* The other variables are not accessed by SLOF anymore: */
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
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
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
86 ld r4,._bss_offset-_rtas_start(r8)
87 ld r5,._bss_end_offset-_rtas_start(r8)
89 add r6,r3,r4 # Address bss in copied code
91 sub r5,r5,r4 # Calculate bss size
92 srdi r5,r5,3 # Count in quads
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 ?
106 add r4, r4, r3 # Calculate reloc table address
108 srdi r5, r5, 2 # Count in words
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
120 ld r5,._rtas_config_offset-_rtas_start(r8)
126 mr r4,r3 # Destination address
127 ld r5,._rtas_size-_rtas_start(r8)
146 mfmsr r11 # Switch to 64 bit mode
153 mr r9,r1 # save old stack pointer
154 ld r1,._rtas_stack-_rtas_start(r8) # load new stack pointer
156 std r9,0(r1) # save stack pointer
157 std r2,64(r1) # save toc
158 std r7,72(r1) # save old msr value
160 ld r2,._rtas_toc-_rtas_start(r8) # load got pointer
165 bl restore_regs_r3_r12
167 ld r11,72(r1) # restore msr value
168 ld r2,64(r1) # restore toc
169 ld r1,0(r1) # get old stack
171 mtmsrd r11 # restore msr
177 ld r4,._rtas_entry_offset-_rtas_start(r8)