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 CFG_ADDR 0x00000510
21 #define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
23 #define PHYS_SS10_INTR0 0xf1400000
25 #define PHYS_SS2_INTR0 0xf5000000
26 #define SER_ADDR2 0xf1000004
28 #define PHYS_SS1000_SBI 0x02800000
29 #define SER_ADDR1000 0x00200004
31 #define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
35 .section ".text", "ax"
40 * Top +-------------------------+
42 * | s + 0x1f00 ... 0x1f0f |
43 * | s + 0x1f0c valid |
44 * | s + 0x1f08 entry |
45 * | s + 0x1f04 ctxtbl |
47 * +-------------------------+
49 * | MMU L3 tables 8 * 0x100 |
50 * | s + 0xa00 ... 0x11ff |
51 * +-------------------------+
53 * | MMU L2 tables 2 * 0x100 |
54 * | s + 0x800 ... 0x9ff |
55 * +-------------------------+
57 * | MMU L1 table 0x400 |
58 * | s + 0x400 ... 0x7ff |
59 * +-------------------------+
61 * | MMU L0/ctx table 0x400 |
62 * | s + 0x000 ... 0x3ff |
63 * +-------------------------+
67 * +-------------------------+
74 * We start execution from here.
78 /* Switch to our main context.
79 * Main context is statically defined in C.
82 ! Check signature "QEMU"
84 mov FW_CFG_SIGNATURE, %g2
85 stha %g2, [%g5] CFG_ASI
87 lduba [%g5] CFG_ASI, %g2
91 lduba [%g5] CFG_ASI, %g2
95 lduba [%g5] CFG_ASI, %g2
99 lduba [%g5] CFG_ASI, %g2
104 ! Get memory size from configuration device
105 ! NB: little endian format
106 mov FW_CFG_RAM_SIZE, %g2
108 stha %g2, [%g5] CFG_ASI
110 lduba [%g5] CFG_ASI, %g4
112 lduba [%g5] CFG_ASI, %g3
116 lduba [%g5] CFG_ASI, %g3
120 lduba [%g5] CFG_ASI, %g3
123 ! %g1 contains end of memory
125 ! Get kernel address from configuration device
126 ! NB: little endian format
127 mov FW_CFG_KERNEL_ADDR, %g2
129 stha %g2, [%g5] CFG_ASI
131 lduba [%g5] CFG_ASI, %g4
133 lduba [%g5] CFG_ASI, %g3
137 lduba [%g5] CFG_ASI, %g3
141 lduba [%g5] CFG_ASI, %g3
145 ! If kernel address is set, don't clear from base of RAM in order to
146 ! leave the kernel image intact
156 sta %g0, [%g6] ASI_M_BYPASS
163 ! Start of private memory in %g6
167 ! Check if this is the boot CPU and skip SMP table check if yes
168 ! XXX: not all CPUs should have MXCC
170 ldda [%g2] ASI_CONTROL, %g2
177 ! Calculate SMP table location
179 add %g6, %g2, %g2 ! valid?
180 lda [%g2] ASI_M_BYPASS, %g7
181 sta %g0, [%g2] ASI_M_BYPASS
184 ! Get machine ID from configuration device
185 mov FW_CFG_MACHINE_ID, %g2
187 stha %g2, [%g5] CFG_ASI
189 lduba [%g5] CFG_ASI, %g4
191 lduba [%g5] CFG_ASI, %g3
210 ! Clear softints used for SMP CPU startup
211 set PHYS_JJ_INTR0 + 0x04, %g1
215 sta %g1, [%g2] ASI_M_BYPASS ! clear softints
217 sta %g0, [%g2] ASI_M_BYPASS ! clear softints
220 ! SMP init, jump to user specified address
222 add %g6, %g5, %g5 ! ctxtbl
223 lda [%g5] ASI_M_BYPASS, %g2
224 sta %g0, [%g5] ASI_M_BYPASS
226 sta %g2, [%g1] ASI_M_MMUREGS ! set ctx table ptr
228 add %g6, %g5, %g5 ! ctx
229 lda [%g5] ASI_M_BYPASS, %g2
230 sta %g0, [%g5] ASI_M_BYPASS
232 sta %g2, [%g1] ASI_M_MMUREGS ! set context
234 add %g6, %g5, %g5 ! entry
235 lda [%g5] ASI_M_BYPASS, %g2
236 sta %g0, [%g5] ASI_M_BYPASS
238 jmp %g2 ! jump to kernel
239 sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
242 ! Ok, this is SS-10 or SS-600MP
247 ! Clear softints used for SMP CPU startup
248 set PHYS_SS10_INTR0 + 0x04, %g1
252 sta %g1, [%g2] ASI_M_CTL ! clear softints
255 sta %g0, [%g2] ASI_M_CTL ! clear softints
264 ! Ok, this is SS-1000 or SS-2000
265 set ss1000_error, %o2
270 /* Create temporary page tables and map the ROM area to end of
271 RAM. This will be done properly in iommu.c later. */
272 ! Calculate start of page tables etc. to %g6
274 sub %g1, %g4, %g6 ! start of private memory
276 mov %g6, %g2 ! ctx table at s+0x0
277 add %g2, 0x400, %g3 ! l1 table at s+0x400
280 sta %g3, [%g2] ASI_M_BYPASS
281 add %g2, 0x400, %g2 ! s+0x400
282 add %g2, 0x400, %g3 ! l2 table for ram (00xxxxxx) at s+0x800
285 sta %g3, [%g2] ASI_M_BYPASS
286 add %g2, 0x500, %g3 ! l2 table for rom (ffxxxxxx) at s+0x900
287 add %g2, 0x3fc, %g2 ! s+0x7fc
290 sta %g3, [%g2] ASI_M_BYPASS
291 add %g2, 0x4, %g2 ! s+0x800
294 set ((7 << 2) | 2), %g3 ! 7 = U: --- S: RWX (main memory)
295 1: sta %g3, [%g2] ASI_M_BYPASS
304 add %g2, 0xa00 - 0x900, %g3 ! l3 table for rom at s+0xa00
305 add %g2, 0x0d0, %g2 ! s+0x9d0
308 sta %g3, [%g2] ASI_M_BYPASS
309 add %g2, 4, %g2 ! s+0x9d4
310 add %g2, 0xb00 - 0x9d4, %g3 ! 2nd l3 table for rom at s+0xb00
313 sta %g3, [%g2] ASI_M_BYPASS
314 add %g2, 4, %g2 ! s+0x9d8
315 add %g2, 0xc00 - 0x9d8, %g3 ! 3rd l3 table for rom at s+0xc00
318 sta %g3, [%g2] ASI_M_BYPASS
319 add %g2, 4, %g2 ! s+0x9dc
320 add %g2, 0xd00 - 0x9dc, %g3 ! 4th l3 table for rom at s+0xd00
323 sta %g3, [%g2] ASI_M_BYPASS
324 add %g2, 4, %g2 ! s+0x9e0
325 add %g2, 0xe00 - 0x9e0, %g3 ! 5th l3 table for rom at s+0xe00
328 sta %g3, [%g2] ASI_M_BYPASS
329 add %g2, 4, %g2 ! s+0x9e4
330 add %g2, 0xf00 - 0x9e4, %g3 ! 6th l3 table for rom at s+0xf00
333 sta %g3, [%g2] ASI_M_BYPASS
334 add %g2, 4, %g2 ! s+0x9e8
335 add %g2, 0x1000 - 0x9e8, %g3 ! 7th l3 table for rom at s+0x1000
338 sta %g3, [%g2] ASI_M_BYPASS
339 add %g2, 4, %g2 ! s+0x9ec
340 add %g2, 0x1100 - 0x9ec, %g3 ! 8th l3 table for rom at s+0x1100
343 sta %g3, [%g2] ASI_M_BYPASS
344 add %g2, 0xa00-0x9ec, %g2 ! s+0xa00
346 /* Use end of ram for code, rodata, data, and bss
347 sections. SunOS wants to write to trap table... */
354 sub %g3, %g5, %g3 ! start of ROM copy
355 mov %g3, %g7 ! save in %g7
356 srl %g6, 12, %g6 ! # of all pages
358 or %g4, ((7 << 2) | 2), %g4 ! 7 = U: --- S: RWX
359 sta %g4, [%g2] ASI_M_BYPASS
366 mov %g1, %g6 ! %g6 = memory size
368 /* Copy the code, rodata and data sections from ROM. */
370 set _start - 4, %g4 ! First address of TEXT - 4
371 set _bss, %g5 ! Last address of DATA
375 lda [%g4] ASI_M_KERNELTXT, %g1
376 sta %g1, [%g3] ASI_M_BYPASS
384 sub %g6, %g3, %g7 ! ctx table at s+0x0
387 sta %g7, [%g2] ASI_M_MMUREGS ! set ctx table ptr
389 sta %g0, [%g2] ASI_M_MMUREGS ! context 0
393 sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
396 * The code which enables traps is a simplified version of
399 * We know number of windows as 8 so we do not calculate them.
400 * The deadwood is here for any case.
403 /* Turn on Supervisor, EnableFloating, and all the PIL bits.
404 * Also puts us in register window zero with traps off.
406 set (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2
410 /* Zero out our BSS section. */
411 set _bss - 4, %o0 ! First address of BSS
412 set _estack - 4, %o1 ! Last address of BSS
425 set qemu_mem_size, %g1
428 set _end, %o0 ! Store va->pa conversion factor
433 sub %o0, %o1, %o0 ! start of ROM copy
434 sub %o2, %o0, %o0 ! start of ROM copy
438 set qemu_machine_type, %g1
442 /* Compute NWINDOWS and stash it away. Now uses %wim trick explained
443 * in the V8 manual. Ok, this method seems to work, Sparc is cool...
444 * No, it doesn't work, have to play the save/readCWP/restore trick.
447 wr %g0, 0x0, %wim ! so we do not get a trap
460 wr %g1, 0x0, %wim ! make window 1 invalid
467 /* Adjust our window handling routines to
468 * do things correctly on 7 window Sparcs.
470 #define PATCH_INSN(src, dest) \
476 /* Patch for window spills... */
477 PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
478 PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
480 /* Patch for window fills... */
481 PATCH_INSN(fnwin_patch1_7win, fnwin_patch1)
482 PATCH_INSN(fnwin_patch2_7win, fnwin_patch2)
485 /* Finally, turn on traps so that we can call c-code. */
494 call __switch_context_nosave
497 /* We get here when the main context switches back to
499 * Return to previous bootloader.
506 set SER_ADDR1000, %o1
507 mov 0x05, %o3 /* Reg 5, TXCTRL2 */
508 stba %o3, [%o0] ASI_M_BYPASS
509 stba %o3, [%o1] ASI_M_CTL
510 mov 0x68, %o3 /* 8 bits, Tx enabled */
511 stba %o3, [%o0] ASI_M_BYPASS
512 stba %o3, [%o1] ASI_M_CTL
516 1: lduba [%o2] ASI_M_KERNELTXT, %o3
520 stba %o3, [%o0] ASI_M_BYPASS
521 stba %o3, [%o1] ASI_M_CTL
530 .string "Sun4c machines are not supported by OpenBIOS yet, freezing\r\n"
532 .string "Sun4d machines are not supported by OpenBIOS yet, freezing\r\n"