entry.s 2.68 KB
#include "sk.h"
	
.text
.align 2
.globl __start
.ent __start
__start:
        /*  Note below is only for dev code, since in real SK
	 *  we could never enter here unless an NMI was the source.
	 * XXX: we're going to use registers (t0, t1, ...) to 
	 *   determine if this is NMI or reset. But, since we could
         *   be entered from interrupt code, we must store
         *   these regs so they can be restored before returning.
         *   The stack ptr cannot be used since we don't yet
         *   know if it is valid. Thus, we'll need to choose
         *   some fixed place in SRAM for this purpose.
         */
	/* XXX: does continued assertion of NMI signal effectively
         * disable other interrups? YES
 	 */
	mfc0	t0,C0_SR
	li	t1,SR_SR
	and	t0,t0,t1
	beqz	t0,hardrst
	/* could be nmi. now must distinguish nmi from soft reset */
	lw	t0,MI_SEC_MODE_REG 
        and	t0,t0,MI_SEC_MODE_NMI
	beqz	t0,softrst
nmi:	
	/* setup sk stack and context switch */
	/* XXX:	 this switch is good for arriving by SK API.
	 *   more needs to be saved if arrive by timer since
	 *   we are interrupting unexpectedly
	mfc0	t0, C0_SR
	move	t1, sp	/* non-SK sp */
	li	t2, PHYS_TO_K0(SK_STACK_INIT_ADDR)
	subu	sp, t2, SK_API_CONTEXT_SIZE /* sk stack */
	sw	t1, SK_SP_SP(sp)
	sw	t0, SK_SP_SR(sp)  /* status register, still in t0 */
	sw	s0, SK_SP_S0(sp)
	sw	s1, SK_SP_S0(sp)
	sw	s2, SK_SP_S0(sp)
	sw	s3, SK_SP_S0(sp)
	sw	s4, SK_SP_S0(sp)
	sw	s5, SK_SP_S0(sp)
	sw	s6, SK_SP_S0(sp)
	sw	s7, SK_SP_S0(sp)
	sw	fp, SK_SP_GP(sp)
	sw	gp, SK_SP_FP(sp)
	sw	ra, SK_SP_RA(sp)
		
	/* call the appropriate handler */
	sll	t0, v0,2
	la	t1, sk_call_table
	addu	t1, t1,t0
	lw	t0, (t1) 
	jalr	t0

	/* restore status register */
	lw	t0, SK_SP_SR(sp)
	li	t1, SR_SR        /* unset soft-reset */
	not	t1
	and	t0, t0, t1
	li	t1, SR_BEV /* unset BEV (assumes not set pre-NMI) */
	not 	t1
	and 	t0, t0, t1
	mtc0    t0, C0_SR
	/* we assume SR_TS is 0, so we could not have entered here
	 * from a TLB exception.
 	 */

	/* restore regs and regular stack (context switch) */
	lw	s0, SK_SP_S0(sp)
	lw	s1, SK_SP_S0(sp)
	lw	s2, SK_SP_S0(sp)
	lw	s3, SK_SP_S0(sp)
	lw	s4, SK_SP_S0(sp)
	lw	s5, SK_SP_S0(sp)
	lw	s6, SK_SP_S0(sp)
	lw	s7, SK_SP_S0(sp)
	lw	fp, SK_SP_GP(sp)
	lw	gp, SK_SP_FP(sp)
	lw	ra, SK_SP_RA(sp)
	lw	sp, SK_SP_SP(sp) /* this must be last */
		
  	/* any secure cleanup or cache setup required */
	
	
        /* restore NMI_* registers */
	/* XXX */

	/* set mode (kernel or user), unless we assume kernel */

	/* clean icache and dcache if needed */

	/* must place eret and sw for MI_SEC_MODE_REG into icache */

	/* eret will clear C0_SR.ERL bit */
	sw	zero,MI_SEC_MODE_REG
	eret

	
hardrst:
softrst:
	lui	sp,0x8100
	jal	main
.end __start