2 ** Standalone startup code for Linux PROM emulator.
3 ** Copyright 1999 Pete A. Zaitcev
4 ** This code is licensed under GNU General Public License.
7 * $Id: head.S,v 1.12 2002/07/23 05:47:09 zaitcev Exp $
14 #define NO_QEMU_PROTOS
15 #define NO_OPENBIOS_PROTOS
16 #include "arch/common/fw_cfg.h"
18 #define PROM_ADDR 0x1fff0000000
19 #define CFG_ADDR 0x1fe02000510
20 #define HZ 1 * 1000 * 1000
21 #define TICK_INT_DIS 0x8000000000000000
25 .section ".text", "ax"
27 .register %g2, #scratch
28 .register %g3, #scratch
29 .register %g6, #scratch
30 .register %g7, #scratch
34 * We start execution from here.
39 wrpr %g0, PSTATE_PRIV, %pstate
43 ! Extract NWINDOWS from %ver
47 wrpr %g1, 0, %cleanwin
49 wrpr %g0, 0, %canrestore
50 wrpr %g0, 0, %otherwin
53 setx TICK_INT_DIS, %g2, %g1
56 ! Disable I/D MMUs and caches
57 stxa %g0, [%g0] ASI_LSU_CONTROL
59 ! Check signature "QEMU"
60 setx CFG_ADDR, %g2, %g5
61 mov FW_CFG_SIGNATURE, %g2
62 stha %g2, [%g5] ASI_PHYS_BYPASS_EC_E_L
64 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
68 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
72 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
76 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2
83 stxa %g0, [%g1] ASI_IMMU
84 stxa %g0, [%g1] ASI_DMMU
86 1: stxa %g0, [%g1] ASI_ITLB_DATA_ACCESS
87 subcc %g1, 1 << 3, %g1
93 1: stxa %g0, [%g1] ASI_DTLB_DATA_ACCESS
94 subcc %g1, 1 << 3, %g1
98 ! Get memory size from configuration device
99 ! NB: little endian format
100 mov FW_CFG_RAM_SIZE, %g2
102 stha %g2, [%g5] ASI_PHYS_BYPASS_EC_E_L
104 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g4
106 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
110 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
114 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
118 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
122 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
126 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
130 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g3
133 ! %g1 contains end of memory
141 sub %g1, %g2, %g2 ! %g2 = start of private memory
147 srlx %g5, 19, %g6 ! %g6 = # of 512k .bss pages
151 ! valid, 512k, locked, cacheable(I/E/C), priv, writable
153 1: stxa %g4, [%g7] ASI_DMMU ! vaddr = _data + N * 0x80000, ctx=0
155 ! paddr = start_mem + N * 0x80000
156 stxa %g5, [%g0] ASI_DTLB_DATA_IN
164 ! setup .rodata, also make .text readable
166 setx _start, %g7, %g4
168 srlx %g5, 19, %g6 ! %g6 = # of 512k .rodata pages
171 setx PROM_ADDR, %l1, %l2
172 1: stxa %g4, [%g7] ASI_DMMU ! vaddr = _rodata, ctx=0
177 ! valid, 512k, locked, cacheable(I/E/C), priv
178 ! paddr = _rodata + N * 0x10000
179 stxa %g3, [%g0] ASI_DTLB_DATA_IN
187 setx _start, %g7, %g4
188 setx _rodata, %g7, %g5
191 add %g5, %g7, %g5 ! round to 512k
192 srlx %g5, 19, %g6 ! %g6 = # of 512k .text pages
195 setx PROM_ADDR, %l1, %l2
196 1: stxa %g4, [%g7] ASI_IMMU ! vaddr = _start, ctx=0
201 ! valid, 512k, locked, cacheable(I/E/C), priv
202 ! paddr = _start + N * 0x80000
203 stxa %g3, [%g0] ASI_ITLB_DATA_IN
214 sta %g0, [%g2] ASI_DMMU ! set primary ctx=0
216 ! Enable I/D MMUs and caches
217 setx lowmem, %g2, %g1
218 set LSU_CONTROL_DM|LSU_CONTROL_IM|LSU_CONTROL_DC|LSU_CONTROL_IC, %g2
220 stxa %g2, [%g0] ASI_LSU_CONTROL
223 /* Copy the DATA section from ROM. */
224 setx _data - 8, %o7, %o0 ! First address of DATA
225 setx _bss, %o7, %o1 ! Last address of DATA
226 setx _start, %o7, %o2
227 sub %o0, %o2, %o2 ! _data - _start
228 setx PROM_ADDR, %o7, %o3
229 add %o3, %o2, %o2 ! PROM_ADDR + (_data - _start)
233 ldxa [%o2] ASI_PHYS_BYPASS_EC_E, %g1
241 /* Zero out our BSS section. */
242 setx _bss - 8, %o7, %o0 ! First address of BSS
243 setx _end - 8, %o7, %o1 ! Last address of BSS
253 setx trap_table, %g2, %g1
256 setx qemu_mem_size, %g7, %g1
259 setx _data, %g7, %g1 ! Store va->pa conversion factor
261 setx va_shift, %g7, %g1
264 /* Finally, turn on traps so that we can call c-code. */
265 wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
268 setx TICK_INT_DIS, %g2, %g1
273 wr %g1, 0, %tick_cmpr
275 /* Switch to our main context.
276 * Main context is statically defined in C.
279 call __switch_context_nosave
282 /* We get here when the main context switches back to