diff options
Diffstat (limited to 'qemu/roms/openbios/arch/sparc32/entry.S')
-rw-r--r-- | qemu/roms/openbios/arch/sparc32/entry.S | 532 |
1 files changed, 0 insertions, 532 deletions
diff --git a/qemu/roms/openbios/arch/sparc32/entry.S b/qemu/roms/openbios/arch/sparc32/entry.S deleted file mode 100644 index 72cb33863..000000000 --- a/qemu/roms/openbios/arch/sparc32/entry.S +++ /dev/null @@ -1,532 +0,0 @@ -/** - ** Standalone startup code for Linux PROM emulator. - ** Copyright 1999 Pete A. Zaitcev - ** This code is licensed under GNU General Public License. - **/ -/* - * $Id: head.S,v 1.12 2002/07/23 05:47:09 zaitcev Exp $ - */ - -#define __ASSEMBLY -#include "psr.h" -#include "asm/asi.h" -#include "asm/crs.h" -#define NO_QEMU_PROTOS -#define NO_OPENBIOS_PROTOS -#include "arch/common/fw_cfg.h" - -#define CFG_ADDR 0x00000510 -#define CFG_ASI 0x2d - -#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */ - -#define PHYS_SS10_INTR0 0xf1400000 - -#define PHYS_SS2_INTR0 0xf5000000 -#define SER_ADDR2 0xf1000004 - -#define PHYS_SS1000_SBI 0x02800000 -#define SER_ADDR1000 0x00200004 - -#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */ - - .globl entry, _entry - - .section ".text", "ax" - .align 8 - - /* Memory map: - * - * Top +-------------------------+ - * | SMP CPU table | - * | s + 0x1f00 ... 0x1f0f | - * | s + 0x1f0c valid | - * | s + 0x1f08 entry | - * | s + 0x1f04 ctxtbl | - * | s + 0x1f00 ctx | - * +-------------------------+ - * | Bootstrap | - * | MMU L3 tables 8 * 0x100 | - * | s + 0xa00 ... 0x11ff | - * +-------------------------+ - * | Bootstrap | - * | MMU L2 tables 2 * 0x100 | - * | s + 0x800 ... 0x9ff | - * +-------------------------+ - * | Bootstrap | - * | MMU L1 table 0x400 | - * | s + 0x400 ... 0x7ff | - * +-------------------------+ - * | Bootstrap | - * | MMU L0/ctx table 0x400 | - * | s + 0x000 ... 0x3ff | - * +-------------------------+ - * | | - * | ROM into RAM | - * | | - * +-------------------------+ - * : : - * Bottom - */ - -/* - * Entry point - * We start execution from here. - */ -_entry: -entry: - /* Switch to our main context. - * Main context is statically defined in C. - */ - - ! Check signature "QEMU" - set CFG_ADDR, %g5 - mov FW_CFG_SIGNATURE, %g2 - stha %g2, [%g5] CFG_ASI - add %g5, 2, %g5 - lduba [%g5] CFG_ASI, %g2 - cmp %g2, 'Q' - bne bad_conf - nop - lduba [%g5] CFG_ASI, %g2 - cmp %g2, 'E' - bne bad_conf - nop - lduba [%g5] CFG_ASI, %g2 - cmp %g2, 'M' - bne bad_conf - nop - lduba [%g5] CFG_ASI, %g2 - cmp %g2, 'U' - bne bad_conf - nop - - ! Get memory size from configuration device - ! NB: little endian format - mov FW_CFG_RAM_SIZE, %g2 - sub %g5, 2, %g5 - stha %g2, [%g5] CFG_ASI - add %g5, 2, %g5 - lduba [%g5] CFG_ASI, %g4 - - lduba [%g5] CFG_ASI, %g3 - sll %g3, 8, %g3 - or %g3, %g4, %g4 - - lduba [%g5] CFG_ASI, %g3 - sll %g3, 16, %g3 - or %g3, %g4, %g4 - - lduba [%g5] CFG_ASI, %g3 - sll %g3, 24, %g3 - or %g3, %g4, %g1 - ! %g1 contains end of memory - - ! Get kernel address from configuration device - ! NB: little endian format - mov FW_CFG_KERNEL_ADDR, %g2 - sub %g5, 2, %g5 - stha %g2, [%g5] CFG_ASI - add %g5, 2, %g5 - lduba [%g5] CFG_ASI, %g4 - - lduba [%g5] CFG_ASI, %g3 - sll %g3, 8, %g3 - or %g3, %g4, %g4 - - lduba [%g5] CFG_ASI, %g3 - sll %g3, 16, %g3 - or %g3, %g4, %g4 - - lduba [%g5] CFG_ASI, %g3 - sll %g3, 24, %g3 - or %g3, %g4, %g4 - - ! If kernel address is set, don't clear from base of RAM in order to - ! leave the kernel image intact - mov 0, %g6 - cmp %g4, 0 - beq clear_mem - nop - - ! Start from 16M - set 0x1000000, %g6 - -clear_mem: - sta %g0, [%g6] ASI_M_BYPASS - add %g6, 0x4, %g6 - cmp %g6, %g1 - bl clear_mem - nop - -clear_done: - ! Start of private memory in %g6 - set 0x2000, %g3 - sub %g1, %g3, %g6 - - ! Check if this is the boot CPU and skip SMP table check if yes - ! XXX: not all CPUs should have MXCC - set 0x1c00f00, %g2 - ldda [%g2] ASI_CONTROL, %g2 - srl %g3, 24, %g7 - sub %g7, 8, %g7 - tst %g7 - bz skip_table - nop - - ! Calculate SMP table location - set 0x1f0c, %g2 - add %g6, %g2, %g2 ! valid? - lda [%g2] ASI_M_BYPASS, %g7 - sta %g0, [%g2] ASI_M_BYPASS - -skip_table: - ! Get machine ID from configuration device - mov FW_CFG_MACHINE_ID, %g2 - sub %g5, 2, %g5 - stha %g2, [%g5] CFG_ASI - add %g5, 2, %g5 - lduba [%g5] CFG_ASI, %g4 - - lduba [%g5] CFG_ASI, %g3 - sll %g3, 8, %g3 - or %g3, %g4, %g4 - mov %g4, %y - - cmp %g4, 96 - bgeu ss1000 - cmp %g4, 64 - bgeu ss10 - cmp %g4, 32 - blu ss2 - nop - - ! Ok, this is SS-5 - - tst %g7 - bz first_cpu - nop - - ! Clear softints used for SMP CPU startup - set PHYS_JJ_INTR0 + 0x04, %g1 - sll %g2, 12, %g2 - add %g1, %g2, %g2 - set 0xffffffff, %g1 - sta %g1, [%g2] ASI_M_BYPASS ! clear softints - add %g2, 4, %g2 - sta %g0, [%g2] ASI_M_BYPASS ! clear softints - -load_ctx: - ! SMP init, jump to user specified address - set 0x1f04, %g5 - add %g6, %g5, %g5 ! ctxtbl - lda [%g5] ASI_M_BYPASS, %g2 - sta %g0, [%g5] ASI_M_BYPASS - set AC_M_CTPR, %g1 - sta %g2, [%g1] ASI_M_MMUREGS ! set ctx table ptr - set 0x1f00, %g5 - add %g6, %g5, %g5 ! ctx - lda [%g5] ASI_M_BYPASS, %g2 - sta %g0, [%g5] ASI_M_BYPASS - set AC_M_CXR, %g1 - sta %g2, [%g1] ASI_M_MMUREGS ! set context - set 0x1f08, %g5 - add %g6, %g5, %g5 ! entry - lda [%g5] ASI_M_BYPASS, %g2 - sta %g0, [%g5] ASI_M_BYPASS - set 1, %g1 - jmp %g2 ! jump to kernel - sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu - -ss10: - ! Ok, this is SS-10 or SS-600MP - tst %g7 - bz first_cpu - nop - - ! Clear softints used for SMP CPU startup - set PHYS_SS10_INTR0 + 0x04, %g1 - sll %g2, 12, %g2 - add %g1, %g2, %g2 - set 0xffffffff, %g1 - sta %g1, [%g2] ASI_M_CTL ! clear softints - add %g2, 4, %g2 - b load_ctx - sta %g0, [%g2] ASI_M_CTL ! clear softints - -ss2: - ! Ok, this is SS-2 - set ss2_error, %o2 - b ss2_ss1000_halt - nop - -ss1000: - ! Ok, this is SS-1000 or SS-2000 - set ss1000_error, %o2 - b ss2_ss1000_halt - nop - -first_cpu: - /* Create temporary page tables and map the ROM area to end of - RAM. This will be done properly in iommu.c later. */ - ! Calculate start of page tables etc. to %g6 - set 0x2000, %g4 - sub %g1, %g4, %g6 ! start of private memory - - mov %g6, %g2 ! ctx table at s+0x0 - add %g2, 0x400, %g3 ! l1 table at s+0x400 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 0x400, %g2 ! s+0x400 - add %g2, 0x400, %g3 ! l2 table for ram (00xxxxxx) at s+0x800 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 0x500, %g3 ! l2 table for rom (ffxxxxxx) at s+0x900 - add %g2, 0x3fc, %g2 ! s+0x7fc - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 0x4, %g2 ! s+0x800 -#if 0 - set 0x40, %g6 - set ((7 << 2) | 2), %g3 ! 7 = U: --- S: RWX (main memory) -1: sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 - deccc %g6 - bne 1b - nop -#else - add %g2, 0x100, %g2 -#endif - ! s+0x900 - add %g2, 0xa00 - 0x900, %g3 ! l3 table for rom at s+0xa00 - add %g2, 0x0d0, %g2 ! s+0x9d0 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 ! s+0x9d4 - add %g2, 0xb00 - 0x9d4, %g3 ! 2nd l3 table for rom at s+0xb00 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 ! s+0x9d8 - add %g2, 0xc00 - 0x9d8, %g3 ! 3rd l3 table for rom at s+0xc00 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 ! s+0x9dc - add %g2, 0xd00 - 0x9dc, %g3 ! 4th l3 table for rom at s+0xd00 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 ! s+0x9e0 - add %g2, 0xe00 - 0x9e0, %g3 ! 5th l3 table for rom at s+0xe00 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 ! s+0x9e4 - add %g2, 0xf00 - 0x9e4, %g3 ! 6th l3 table for rom at s+0xf00 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 ! s+0x9e8 - add %g2, 0x1000 - 0x9e8, %g3 ! 7th l3 table for rom at s+0x1000 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 ! s+0x9ec - add %g2, 0x1100 - 0x9ec, %g3 ! 8th l3 table for rom at s+0x1100 - srl %g3, 0x4, %g3 - or %g3, 0x1, %g3 - sta %g3, [%g2] ASI_M_BYPASS - add %g2, 0xa00-0x9ec, %g2 ! s+0xa00 - - /* Use end of ram for code, rodata, data, and bss - sections. SunOS wants to write to trap table... */ - set _end, %g6 - set _start, %g4 - sub %g6, %g4, %g6 - sub %g1, %g6, %g3 - set 0x1000, %g5 - sub %g3, %g5, %g3 - sub %g3, %g5, %g3 ! start of ROM copy - mov %g3, %g7 ! save in %g7 - srl %g6, 12, %g6 ! # of all pages -1: srl %g3, 0x4, %g4 - or %g4, ((7 << 2) | 2), %g4 ! 7 = U: --- S: RWX - sta %g4, [%g2] ASI_M_BYPASS - add %g2, 4, %g2 - add %g3, %g5, %g3 - deccc %g6 - bne 1b - nop - - mov %g1, %g6 ! %g6 = memory size - - /* Copy the code, rodata and data sections from ROM. */ - sub %g7, 4, %g3 - set _start - 4, %g4 ! First address of TEXT - 4 - set _bss, %g5 ! Last address of DATA - ba 2f - nop -1: - lda [%g4] ASI_M_KERNELTXT, %g1 - sta %g1, [%g3] ASI_M_BYPASS -2: - cmp %g4, %g5 - add %g3, 0x4, %g3 - bl 1b - add %g4, 0x4, %g4 - - set 0x2000, %g3 - sub %g6, %g3, %g7 ! ctx table at s+0x0 - set AC_M_CTPR, %g2 - srl %g7, 4, %g7 - sta %g7, [%g2] ASI_M_MMUREGS ! set ctx table ptr - set AC_M_CXR, %g2 - sta %g0, [%g2] ASI_M_MMUREGS ! context 0 - set highmem, %g2 - set 1, %g1 - jmp %g2 - sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu -highmem: - /* - * The code which enables traps is a simplified version of - * kernel head.S. - * - * We know number of windows as 8 so we do not calculate them. - * The deadwood is here for any case. - */ - - /* Turn on Supervisor, EnableFloating, and all the PIL bits. - * Also puts us in register window zero with traps off. - */ - set (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2 - wr %g2, 0x0, %psr - WRITE_PAUSE - - /* Zero out our BSS section. */ - set _bss - 4, %o0 ! First address of BSS - set _estack - 4, %o1 ! Last address of BSS - ba 2f - nop -1: - st %g0, [%o0] -2: - subcc %o0, %o1, %g0 - bl 1b - add %o0, 0x4, %o0 - - set trap_table, %g1 - wr %g1, 0x0, %tbr - - set qemu_mem_size, %g1 - st %g6, [%g1] - - set _end, %o0 ! Store va->pa conversion factor - set _start, %o2 - sub %o0, %o2, %o0 - sub %g6, %o0, %o0 - set 0x2000, %o1 - sub %o0, %o1, %o0 ! start of ROM copy - sub %o2, %o0, %o0 ! start of ROM copy - set va_shift, %g1 - st %o0, [%g1] - - set qemu_machine_type, %g1 - mov %y, %g2 - st %g2, [%g1] - - /* Compute NWINDOWS and stash it away. Now uses %wim trick explained - * in the V8 manual. Ok, this method seems to work, Sparc is cool... - * No, it doesn't work, have to play the save/readCWP/restore trick. - */ - - wr %g0, 0x0, %wim ! so we do not get a trap - WRITE_PAUSE - - save - - rd %psr, %g3 - - restore - - and %g3, 0x1f, %g3 - add %g3, 0x1, %g3 - - mov 2, %g1 - wr %g1, 0x0, %wim ! make window 1 invalid - WRITE_PAUSE - - cmp %g3, 0x7 - bne 1f - nop - - /* Adjust our window handling routines to - * do things correctly on 7 window Sparcs. - */ -#define PATCH_INSN(src, dest) \ - set src, %g5; \ - set dest, %g2; \ - ld [%g5], %g4; \ - st %g4, [%g2]; - - /* Patch for window spills... */ - PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) - PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) - - /* Patch for window fills... */ - PATCH_INSN(fnwin_patch1_7win, fnwin_patch1) - PATCH_INSN(fnwin_patch2_7win, fnwin_patch2) - -1: - /* Finally, turn on traps so that we can call c-code. */ - rd %psr, %g3 - wr %g3, 0x0, %psr - WRITE_PAUSE - - wr %g3, PSR_ET, %psr - WRITE_PAUSE - - set 0, %fp - call __switch_context_nosave - nop - - /* We get here when the main context switches back to - * the boot context. - * Return to previous bootloader. - */ - ret - nop - -ss2_ss1000_halt: - set SER_ADDR2, %o0 - set SER_ADDR1000, %o1 - mov 0x05, %o3 /* Reg 5, TXCTRL2 */ - stba %o3, [%o0] ASI_M_BYPASS - stba %o3, [%o1] ASI_M_CTL - mov 0x68, %o3 /* 8 bits, Tx enabled */ - stba %o3, [%o0] ASI_M_BYPASS - stba %o3, [%o1] ASI_M_CTL - add %o0, 2, %o0 - add %o1, 2, %o1 - -1: lduba [%o2] ASI_M_KERNELTXT, %o3 - cmp %o3, 0 - be 2f - nop - stba %o3, [%o0] ASI_M_BYPASS - stba %o3, [%o1] ASI_M_CTL - b 1b - inc %o2 -bad_conf: -2: b 2b - nop - - .section .rodata -ss2_error: - .string "Sun4c machines are not supported by OpenBIOS yet, freezing\r\n" -ss1000_error: - .string "Sun4d machines are not supported by OpenBIOS yet, freezing\r\n" |