coreboot/src/cpu/ev6/start.inc
Eric W. Biederman 39b133810a Minor fixes
- Add IMB to the palcode in start.inc
- Reduce the heap to only 128K in alpha/ldscript.base
- In elfboot add checks to make certain we don't overwrite linuxBIOS...
2001-04-13 22:04:26 +00:00

488 lines
14 KiB
C++

#include <arch/cpu.h>
#include <arch/pal.h>
#include <arch/asm.h>
.set noat
.set noreorder
.text
#define PAL_EXCEPT(label,location) . = location ; label:
#define PAL_EXCEPT_DUMMY(location) . = location ; mb ; mb ; mb; hw_mfpr p7, EV6__EXC_ADDR ; bsr p0, __fatal_error_pal; mb ; mb ; mb
#define PAL_CALL_DUMMY(location) . = location ; mb ; mb ; mb ; mb ; bsr p0, __fatal_error_pal ; mb ; mb ; mb
#define va_48 0
#define mchk_en 1
#define tb_mb_en 0
#define EV6__I_STAT__W1C ((1 << EV6__I_STAT__TPE__S) | (1 << EV6__I_STAT__DPE__S))
#define EV6__DC_STAT__W1C ( \
(1 << EV6__DC_STAT__TPERR_P0__S) | \
(1 << EV6__DC_STAT__TPERR_P1__S) | \
(1 << EV6__DC_STAT__ECC_ERR_ST__S) | \
(1 << EV6__DC_STAT__ECC_ERR_LD__S) | \
(1 << EV6__DC_STAT__SEO__S))
#define EV6__I_CTL__INIT (\
(3 << EV6__I_CTL__IC_EN__S) | \
(2 << (EV6__I_CTL__SPE__S + va_48)) | \
(2 << EV6__I_CTL__SDE__S) | \
(3 << EV6__I_CTL__SBE__S) | \
(va_48 << EV6__I_CTL__VA_48__S) | \
(1 << EV6__I_CTL__CALL_PAL_R23__S) | \
(mchk_en << EV6__I_CTL__MCHK_EN__S) | \
(tb_mb_en << EV6__I_CTL__TB_MB_EN__S))
#define EV6__PCTX__INIT (1 << EV6__PCTX__FPE__S)
#define EV6__M_CTL__INIT (2 << (EV6__M_CTL__SPE__S+va_48))
#define EV6__IER__INIT 0
#define EV6__HW_INT_CLR__INIT ( \
(1 << (EV6__HW_INT_CLR__MCHK_D__S - EV6__HW_INT_CLR__MCHK_D__S)) | \
(3 << (EV6__HW_INT_CLR__PC__S - EV6__HW_INT_CLR__MCHK_D__S)) | \
(1 << (EV6__HW_INT_CLR__CR__S - EV6__HW_INT_CLR__MCHK_D__S)) | \
(1 << (EV6__HW_INT_CLR__SL__S - EV6__HW_INT_CLR__MCHK_D__S)))
#define EV6__VA_CTL__INIT (va_48 << EV6__VA_CTL__VA_48__S)
EntryPoint:
/* On startup
* R19 - Signature (0xDEC?????) likely (0xDECB001)
* R23 - Memory size in bytes.
* r22 - CPU speed in picoseconds.
* R25 - Chip revision.
* excAddr - Address of ICache flush code to execute in PALmode.
*/
/* Palcode switching entry point */
mb
bis a3, a3, a0 /* Signature */
bis t9, t9, a1 /* Memory size in bytes */
bis t8, t8, a2 /* CPU speed in picoseconds */
br zero, pal_mode_start
mb
mb
mb
PAL_EXCEPT_DUMMY(EV6__DTBM_DOUBLE_3_ENTRY)
PAL_EXCEPT_DUMMY(EV6__DTBM_DOUBLE_4_ENTRY)
PAL_EXCEPT_DUMMY(EV6__FEN_ENTRY)
PAL_EXCEPT_DUMMY(EV6__UNALIGN_ENTRY)
/* DTBM */
PAL_EXCEPT(DTBM_SINGLE, EV6__DTBM_SINGLE_ENTRY)
hw_mfpr p7, EV6__EXC_ADDR /* (0L,1) get exception address */
hw_mfpr p2, EV6__VA /* (4-7,1L,3) get original va */
lda p1, 0x3301(zero) /* all r/w enable */
srl p2, 13, p0 /* shift out the byte offset */
sll p0, EV6__DTB_PTE0__PFN__S, p0 /* get pfn into position */
bis p0, p1, p0 /* produce the pte */
FETCH_BLOCK_ALIGN
hw_mtpr p2, EV6__DTB_TAG0 /* (2&6,0L) write tag0 */
hw_mtpr p2, EV6__DTB_TAG1 /* (1&5,1L) write tag1 */
hw_mtpr p0, EV6__DTB_PTE0 /* (0,4,2,6) (0L) write pte0 */
hw_mtpr p0, EV6__DTB_PTE1 /* (3,7,1,5) (1L) write pte1 */
hw_mtpr zero, EV6__MM_STAT /* (4-7,0L) start outside IQ */
FETCH_BLOCK_ALIGN
hw_ret (p7) /* return with jmp */
br zero, .-4 /* stop predictor */
PAL_EXCEPT_DUMMY(EV6__DFAULT_ENTRY)
PAL_EXCEPT_DUMMY(EV6__OPCDEC_ENTRY)
PAL_EXCEPT_DUMMY(EV6__IACV_ENTRY)
PAL_EXCEPT_DUMMY(EV6__MCHK_ENTRY)
/* *ITBM* */
PAL_EXCEPT(ITB_MISS, EV6__ITB_MISS_ENTRY)
hw_mfpr p7, EV6__EXC_ADDR /* (0L,1) get exception address */
srl p7, 13, p2 /* shift out the byte offset */
lda p1, 0x301(zero) /* all read enable */
sll p2, EV6__ITB_PTE__PFN__S, p2 /* get pfn into position */
bis p2, p1, p2 /* produce the pte */
FETCH_BLOCK_ALIGN
hw_mtpr p7, EV6__ITB_TAG /* (2&6,0L) write tag0 */
hw_mtpr p2, EV6__ITB_PTE /* (0&4,0L) write pte0 */
FETCH_BLOCK_ALIGN
hw_ret/stall (p7) /* (0L) return */
br zero, .-4
PAL_EXCEPT_DUMMY(EV6__ARITH_ENTRY)
PAL_EXCEPT_DUMMY(EV6__INTERRUPT_ENTRY)
PAL_EXCEPT_DUMMY(EV6__MT_FPCR_ENTRY)
PAL_EXCEPT_DUMMY(EV6__RESET_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_00_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_01_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_02_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_03_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_04_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_05_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_06_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_07_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_08_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_09_ENTRY)
#if 0
PAL_CALL_DUMMY(EV6__CALL_PAL_0A_ENTRY)
#else
/* swppal */
PAL_EXCEPT(SWPPAL, EV6__CALL_PAL_0A_ENTRY)
#define OSF_P_MISC__SWITCH__S 62
/* new pal base is in a0 */
bis a0, a0, p1 /* base in p1 */
lda p0, 0x7fff(zero) /* check for pal base */
and p1, p0, p0 /* get low 15 bits */
cmpeq p0, 0, v0 /* check for non-zero bits */
blbc v0, call_pal__swppal_fail /* if not clear say unknown */
bis zero, 1, p0 /* get a '1' */
sll p0, OSF_P_MISC__SWITCH__S, p0 /* switch bit into position */
bis zero, p0, p6 /* mark switch */
bis zero, zero, v0 /* status success */
bis p1, 1, p1 /* set pal mode bit */
hw_ret (p1) /* go to it */
bis zero, zero, zero /* nop */
call_pal__swppal_fail:
bis zero, 1, v0 /* failure */
hw_ret (p7)
bis zero, zero, zero /* nop */
bis zero, zero, zero /* nop */
#endif
PAL_CALL_DUMMY(EV6__CALL_PAL_0B_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_0C_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_0D_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_0E_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_0F_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_10_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_11_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_12_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_13_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_14_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_15_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_16_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_17_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_18_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_19_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_1A_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_1B_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_1C_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_1D_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_1E_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_1F_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_20_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_21_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_22_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_23_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_24_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_25_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_26_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_27_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_28_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_29_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_2A_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_2B_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_2C_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_2D_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_2E_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_2F_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_30_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_31_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_32_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_33_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_34_ENTRY)
#if 0
PAL_CALL_DUMMY(EV6__CALL_PAL_35_ENTRY)
#else
/* swpipl */
PAL_EXCEPT(SWPIPL, EV6__CALL_PAL_35_ENTRY)
/* Fake the swpipl call just return the maximum ipl
* I'm not going to enable interrupts anyway.
*/
bis zero, 7, v0
hw_ret/stall(p7)
#endif
PAL_CALL_DUMMY(EV6__CALL_PAL_36_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_37_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_38_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_39_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_3A_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_3B_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_3C_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_3D_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_3E_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_3F_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_80_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_81_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_82_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_83_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_84_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_85_ENTRY)
#if 0
/* PAL_CALL_DUMMY(EV6__CALL_PAL_86_ENTRY) */
#else
/* imb */
PAL_EXCEPT(IMB, EV6__CALL_PAL_86_ENTRY)
mb
bis zero, zero, zero /* nop */
bis zero, zero, zero /* nop */
bis zero, zero, zero /* nop */
hw_mtpr zero, EV6__IC_FLUSH /* (4,0L) flush the icache
bne zero, . /* pvc #24 */
hw_ret/stall(p7) /* return with stall */
#endif
PAL_CALL_DUMMY(EV6__CALL_PAL_87_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_88_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_89_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_8A_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_8B_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_8C_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_8D_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_8E_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_8F_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_90_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_91_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_92_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_93_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_94_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_95_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_96_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_97_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_98_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_99_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_9A_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_9B_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_9C_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_9D_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_9E_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_9F_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A0_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A1_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A2_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A3_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A4_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A5_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A6_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A7_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A8_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_A9_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_AA_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_AB_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_AC_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_AD_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_AE_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_AF_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B0_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B1_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B2_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B3_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B4_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B5_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B6_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B7_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B8_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_B9_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_BA_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_BB_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_BC_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_BD_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_BE_ENTRY)
PAL_CALL_DUMMY(EV6__CALL_PAL_BF_ENTRY)
PAL_EXCEPT(dummy, EV6__CALL_PAL_BF_ENTRY + 0x80)
/* Data for pal_mode_start
* I can't use the magic linker gp magic here so roll my own.
* Note: The linker script ensures that EntryPoint _edata & _end
* are all 8 byte aligned.
*/
EntryPoint_addr:
.quad EntryPoint
_edata_addr:
.quad _edata
_end_addr:
.quad _end
kernel_mode_start_addr:
.quad kernel_mode_start
__fatal_error_non_pal_addr:
.quad __fatal_error_non_pal
pal_mode_start:
/* relocate to address zero */
/* The following move routine is not totally
* general. In particular it does not handle
* overlapping memory locations or moving to a higher
* address in memory.
*/
br pv, relocate
relocate:
lda t0,(EntryPoint - relocate)(pv)
ldq_p t1,(EntryPoint_addr - relocate)(pv)
ldq_p t2,(_edata_addr - relocate)(pv)
subq t2, t1, t2
br Mstart
/* Move the program */
Move: ldq_p t3, 0(t0)
subq t2, 8, t2
addq t0, 8, t0
stq_p t3, 0(t1)
addq t1, 8, t1
Mstart: bne t2, Move
/* set up pal_base register */
FETCH_BLOCK_ALIGN
ldq_p t0, (EntryPoint_addr - relocate)(pv)
hw_mtpr t0, EV6__PAL_BASE
/* flush ITB & DTB */
FETCH_BLOCK_ALIGN
hw_mtpr zero, EV6__ITB_IA
hw_mtpr zero, EV6__DTB_IA
/* flush I_CACHE */
FETCH_BLOCK_ALIGN
hw_mtpr zero, EV6__IC_FLUSH
/* clear i_stat & dc_stat */
LOAD_CONSTANT32(t0, EV6__I_STAT__W1C)
LOAD_CONSTANT16(t2, EV6__DC_STAT__W1C)
FETCH_BLOCK_ALIGN
hw_mtpr t0, EV6__I_STAT
hw_mtpr t2, EV6__DC_STAT
/* Initialize I_CTL */
LOAD_CONSTANT32(t0, EV6__I_CTL__INIT)
FETCH_BLOCK_ALIGN
hw_mtpr t0, EV6__I_CTL
/* Initialize pctx & m_ctl */
FETCH_BLOCK_ALIGN
LOAD_CONSTANT16(t0, EV6__PCTX__INIT)
LOAD_CONSTANT16(t2, EV6__M_CTL__INIT)
hw_mtpr t0, EV6__PCTX
hw_mtpr t2, EV6__M_CTL
/* Initialize ier_cm */
LOAD_CONSTANT32(t0, EV6__IER__INIT)
hw_mtpr t0, EV6__IER_CM
hw_mtpr zero, EV6__CC
/* Initialize SIRR */
bis zero, 1, t0
sll t0, 32, t0
hw_mtpr zero, EV6__SIRR
hw_mtpr $1, EV6__CC_CTL
/* Initialize int_clr */
LOAD_CONSTANT16(t0, EV6__HW_INT_CLR__INIT)
sll t0, EV6__HW_INT_CLR__MCHK_D__S, t0
hw_mtpr t0, EV6__HW_INT_CLR
hw_mtpr zero, EV6__DTB_ALT_MODE
/* set pctr_ctl & va_ctl */
hw_mtpr zero, EV6__PCTR_CTL
LOAD_CONSTANT16(t0, EV6__VA_CTL__INIT)
hw_mtpr t0, EV6__VA_CTL
FETCH_BLOCK_ALIGN
/* Clear the asn */
hw_mtpr zero, EV6__DTB_ASN0
hw_mtpr zero, EV6__DTB_ASN1
FETCH_BLOCK_ALIGN
/* write pctrl_ctl again to clear the 2nd stage overflow flag.
* and force other mtpr to retwir while we are at it.
*/
hw_mtpr zero, EV6__PCTR_CTL | 0xF0
FETCH_BLOCK_ALIGN
/* We need to write HW_INT_CLR to avoid a interrup that can occur
* the counters come up in an unpredictable state near overflow.
*/
lda t0, 3(zero)
sll t0, EV6__HW_INT_CLR__PC__S, t0
hw_mtpr t0, EV6__HW_INT_CLR
FETCH_BLOCK_ALIGN
hw_mtpr t0, EV6__HW_INT_CLR
FETCH_BLOCK_ALIGN
/* Clear the fpcr */
mt_fpcr $f31
#if 0
/* Setup 48 bit address space */
FETCH_BLOCK_ALIGN
bis zero, 2, t0
hw_mtpr t0, EV6__VA_CTL
bis zero, 8, t0
hw_mtpr t0, EV6__M_CTL
#else
/* Setup 40 bit address space */
FETCH_BLOCK_ALIGN
bis zero, 0, t0
hw_mtpr t0, EV6__VA_CTL
bis zero, 4, t0
hw_mtpr t0, EV6__M_CTL
#endif
FETCH_BLOCK_ALIGN
/* Enable special pal instructions in kernel mode */
hw_mfpr t0, EV6__I_CTL
lda t1, 1(zero)
sll t1, EV6__I_CTL__HWE__S, t1
bis t0, t1, t0
hw_mtpr t0, EV6__I_CTL
/* Now get out of palmode */
FETCH_BLOCK_ALIGN
ldq_p pv, (kernel_mode_start_addr - relocate)(pv)
hw_jmp (pv)
GLOBL(start)
br pv, __start
__start:
/* Some dummy parameters for debugging */
bis zero, zero, t8 /* CPU speed in picoseconds */
lda t9, 128*1024*1024 /* Memory size in bytes 128MB */
bis zero, zero, t11 /* Chip revision */
lda a0, (EntryPoint - __start)(pv)
call_pal PAL_swppal
br zero, .-4 /* spin in place */
/* __fatal_error_pal Called with:
* p0 - Exception handler that caught the exception
* p7 - Address where the exception occured.
* ra - Potentially valid return address from the code
* that took the exception.
*/
FETCH_BLOCK_ALIGN
__fatal_error_pal:
subq p0, 0x14, a0
bis p7, p7, a1
bis ra, ra, a2
bsr pv, __fatal_error_pal2
__fatal_error_pal2:
lda pv, (__fatal_error_non_pal - __fatal_error_pal2)(pv)
hw_ret (pv)