entry.h 7.13 KB
#ifndef __SK_ENTRY_CONSTANTS_HDR__
#define __SK_ENTRY_CONSTANTS_HDR__

/* define to enable stack checking via gaurdband */
#undef SK_STACK_CHECK
//#define SK_STACK_CHECK 1

#ifndef _LANGUAGE_C

#include <regdef.h>
#include <asm.h>
#include <PR/R4300.h>

#include <PR/bcp.h>

#define PTR        .word
#define PTRSIZE    4
#define PTRLOG     2

/* macros for switching execution between cached and uncached */
#define CACHED_EXECUTION_USING_T0     \
	la	t0, 1f;      \
	and	t0, ~K1BASE; \
	or	t0, K0BASE;  \
	jr	t0;          \
1:	                     

#define UNCACHED_EXECUTION_USING_T0   \
	la	t0, 1f;      \
	or	t0, K1BASE;  \
	jr	t0;          \
1:	                     

#define REG_TO_K1(_r)  or  _r, K1BASE
#define REG_TO_K0(_r)  and _r, ~K1BASE; or _r, K0BASE

/* hard-coded locations */
#define SK_STACK_SIZE        0x6000
#define SK_HEAP_SIZE         0x400

/* preserve space for initial C call from assembly. the
 * compiler may use this space to store a0..a3 and ra.
 * it is 8B aligned.
 */
#define SK_STACK_RESV_INIT_C 24

/* register saving for SK */
#define SK_SP_AT (SK_STACK_RESV_INIT_C +  0x00)
#define SK_SP_V0 (SK_STACK_RESV_INIT_C +  0x08)
#define SK_SP_V1 (SK_STACK_RESV_INIT_C +  0x10)
#define SK_SP_A0 (SK_STACK_RESV_INIT_C +  0x18)
#define SK_SP_A1 (SK_STACK_RESV_INIT_C +  0x20)
#define SK_SP_A2 (SK_STACK_RESV_INIT_C +  0x28)
#define SK_SP_A3 (SK_STACK_RESV_INIT_C +  0x30)
#define SK_SP_T0 (SK_STACK_RESV_INIT_C +  0x38)
#define SK_SP_T1 (SK_STACK_RESV_INIT_C +  0x40)
#define SK_SP_T2 (SK_STACK_RESV_INIT_C +  0x48)
#define SK_SP_T3 (SK_STACK_RESV_INIT_C +  0x50)
#define SK_SP_T4 (SK_STACK_RESV_INIT_C +  0x58)
#define SK_SP_T5 (SK_STACK_RESV_INIT_C +  0x60)
#define SK_SP_T6 (SK_STACK_RESV_INIT_C +  0x68)
#define SK_SP_T7 (SK_STACK_RESV_INIT_C +  0x70)
#define SK_SP_S0 (SK_STACK_RESV_INIT_C +  0x78)
#define SK_SP_S1 (SK_STACK_RESV_INIT_C +  0x80)
#define SK_SP_S2 (SK_STACK_RESV_INIT_C +  0x88)
#define SK_SP_S3 (SK_STACK_RESV_INIT_C +  0x90)
#define SK_SP_S4 (SK_STACK_RESV_INIT_C +  0x98)
#define SK_SP_S5 (SK_STACK_RESV_INIT_C +  0xa0)
#define SK_SP_S6 (SK_STACK_RESV_INIT_C +  0xa8)
#define SK_SP_S7 (SK_STACK_RESV_INIT_C +  0xb0)
#define SK_SP_T8 (SK_STACK_RESV_INIT_C +  0xb8)
#define SK_SP_T9 (SK_STACK_RESV_INIT_C +  0xc0)
#define SK_SP_K0 (SK_STACK_RESV_INIT_C +  0xc8)
#define SK_SP_K1 (SK_STACK_RESV_INIT_C +  0xd0)
#define SK_SP_GP (SK_STACK_RESV_INIT_C +  0xd8)
#define SK_SP_SP (SK_STACK_RESV_INIT_C +  0xe0)
#define SK_SP_S8 (SK_STACK_RESV_INIT_C +  0xe8)
#define SK_SP_RA (SK_STACK_RESV_INIT_C +  0xf0)
#define SK_SP_CP0_TAGLO (SK_STACK_RESV_INIT_C + 0x0f8)
#define SK_SP_CP0_TAGHI (SK_STACK_RESV_INIT_C + 0x100)
#define SK_SP_CP0_COUNT (SK_STACK_RESV_INIT_C + 0x108)
#define SK_SP_LO (SK_STACK_RESV_INIT_C + 0x110)
#define SK_SP_HI (SK_STACK_RESV_INIT_C + 0x118)

/* this number must include space for the total number of
 * SK_SP_ vals above (*8), and the initial stack the compiler
 * might use for the first "C" call.
 */
#define SK_CONTEXT_SIZE  (0x118 + 8 + SK_STACK_RESV_INIT_C) 

#define SK_STACK_SET \
 	la	sp, __stack + SK_STACK_SIZE; \
	subu    sp, SK_CONTEXT_SIZE

#define SK_STACK_SET_KSEG1 \
 	la	sp, (__stack + SK_STACK_SIZE) | K1BASE; \
	subu    sp, SK_CONTEXT_SIZE

#define SK_CONTEXT_SAVE_AT \
    .set push;             \
    .set noat;             \
    sd  AT, SK_SP_AT(sp);  \
    .set pop

#define SK_CONTEXT_REST_AT \
    .set push;             \
    .set noat;             \
    ld  AT, SK_SP_AT(sp);  \
    .set pop

#define SK_CONTEXT_SAVE_CP0_API(_r)   \
    mfc0     _r, C0_TAGLO;            \
    sd       _r, SK_SP_CP0_TAGLO(sp); \
    mfc0     _r, C0_TAGHI;            \
    sd       _r, SK_SP_CP0_TAGHI(sp); \
    mflo     _r;                      \
    sd       _r, SK_SP_LO(sp);        \
    mfhi     _r;                      \
    sd       _r, SK_SP_HI(sp)

#define SK_CONTEXT_SAVE_CP0(_r)       \
    SK_CONTEXT_SAVE_CP0_API(_r);      \
    mfc0     _r, C0_COUNT;            \
    sd       _r, SK_SP_CP0_COUNT(sp)

#define SK_CONTEXT_REST_CP0_API(_r)   \
    ld       _r, SK_SP_CP0_TAGLO(sp); \
    mtc0     _r, C0_TAGLO;            \
    ld       _r, SK_SP_CP0_TAGHI(sp); \
    mtc0     _r, C0_TAGHI;            \
    ld       _r, SK_SP_LO(sp);        \
    mtlo     _r;                      \
    ld       _r, SK_SP_HI(sp);        \
    mthi     _r

#define SK_CONTEXT_REST_CP0(_r)       \
    SK_CONTEXT_REST_CP0_API(_r);      \
    ld       _r, SK_SP_CP0_COUNT(sp); \
    mtc0     _r, C0_COUNT


#define SK_CONTEXT_SAVE_KX      \
    sw       k1, SK_SP_K0(sp);  \
    dsrl32   k1, 0;             \
    sw       k1, SK_SP_K1(sp)

#define SK_CONTEXT_SAVE_AX  \
    sd  a0, SK_SP_A0(sp);   \
    sd  a1, SK_SP_A1(sp);   \
    sd  a2, SK_SP_A2(sp);   \
    sd  a3, SK_SP_A3(sp)

#define SK_CONTEXT_REST_AX  \
    ld  a0, SK_SP_A0(sp);   \
    ld  a1, SK_SP_A1(sp);   \
    ld  a2, SK_SP_A2(sp);   \
    ld  a3, SK_SP_A3(sp)

#define SK_CONTEXT_SAVE_SX  \
    sd	s0, SK_SP_S0(sp);   \
    sd	s1, SK_SP_S1(sp);   \
    sd	s2, SK_SP_S2(sp);   \
    sd	s3, SK_SP_S3(sp);   \
    sd	s4, SK_SP_S4(sp);   \
    sd	s5, SK_SP_S5(sp);   \
    sd	s6, SK_SP_S6(sp);   \
    sd	s7, SK_SP_S7(sp);   \
    sd	s8, SK_SP_S8(sp)

#define SK_CONTEXT_REST_SX  \
    ld	s0, SK_SP_S0(sp);   \
    ld	s1, SK_SP_S1(sp);   \
    ld	s2, SK_SP_S2(sp);   \
    ld	s3, SK_SP_S3(sp);   \
    ld	s4, SK_SP_S4(sp);   \
    ld	s5, SK_SP_S5(sp);   \
    ld	s6, SK_SP_S6(sp);   \
    ld	s7, SK_SP_S7(sp);   \
    ld	s8, SK_SP_S8(sp)

#define SK_CONTEXT_SAVE_TX    \
    sd	t0, SK_SP_T0(sp);     \
    sd	t1, SK_SP_T1(sp);     \
    sd	t2, SK_SP_T2(sp);     \
    sd	t3, SK_SP_T3(sp);     \
    sd	t4, SK_SP_T4(sp);     \
    sd	t5, SK_SP_T5(sp);     \
    sd	t6, SK_SP_T6(sp);     \
    sd	t7, SK_SP_T7(sp);     \
    sd	t8, SK_SP_T8(sp);     \
    sd	t9, SK_SP_T9(sp)

#define SK_CONTEXT_REST_TX  \
    ld	t0, SK_SP_T0(sp);   \
    ld	t1, SK_SP_T1(sp);   \
    ld	t2, SK_SP_T2(sp);   \
    ld	t3, SK_SP_T3(sp);   \
    ld	t4, SK_SP_T4(sp);   \
    ld	t5, SK_SP_T5(sp);   \
    ld	t6, SK_SP_T6(sp);   \
    ld	t7, SK_SP_T7(sp);   \
    ld	t8, SK_SP_T8(sp);   \
    ld  t9, SK_SP_T9(sp)


/* NOTE: assuming k0 holds entry sp. */
#define SK_CONTEXT_SAVE_API   \
    SK_CONTEXT_SAVE_AT;       \
    SK_CONTEXT_SAVE_SX;       \
    sd  gp, SK_SP_GP(sp);     \
    sw  k0, SK_SP_SP(sp);     \
    sd  ra, SK_SP_RA(sp)

/* DO NOT restore sp here */
#define SK_CONTEXT_REST_API   \
    SK_CONTEXT_REST_AT;       \
    SK_CONTEXT_REST_SX;       \
    ld  gp, SK_SP_GP(sp);     \
    ld  ra, SK_SP_RA(sp)

/* save all regs assuming k0 holds entry sp, and k1 holds both k0 and k1. 
 * doing CP0 as soon as possible to catch C0_COUNT early.
 */
#define SK_CONTEXT_SAVE_ALL \
    SK_CONTEXT_SAVE_KX;     \
    SK_CONTEXT_SAVE_CP0(k1);\
    SK_CONTEXT_SAVE_API;    \
    SK_CONTEXT_SAVE_TX;     \
    sd  v0, SK_SP_V0(sp);   \
    sd  v1, SK_SP_V1(sp);   \
    SK_CONTEXT_SAVE_AX

/* restore all except k0, k1, and sp. doing CP0 as late as possible
 * so C0_COUNT changes as little as possible.
 */ 
#define SK_CONTEXT_REST_MOST   \
    SK_CONTEXT_REST_TX;        \
    SK_CONTEXT_REST_AX;        \
    ld  v0, SK_SP_V0(sp);      \
    SK_CONTEXT_REST_API;       \
    SK_CONTEXT_REST_CP0(v1);   \
    ld  v1, SK_SP_V1(sp);      \

#endif
#endif