secure.c 6.08 KB
#include "cpusim.h"

#define STATE	(*(volatile int*)PHYS_TO_K1(INTERNAL_RAM_START))

void
passed(void) {
    message("test secure passed\n");
    DBG_JTAG_PASS("test secure passed\n");
    test_postamble();
}

void
failed(const char* code) {
    message("test secure failed (");
    message(code);
    message(")\n");
    DBG_JTAG_FAIL(code);
    test_postamble();
}

int
main() {
    int x;
    extern void __stub(void), __stub2(void), __stub3(void), __stub4(void), __stub5(void);
    vu32 *p0, *p1;
    void (*f0)(void);
    /* check for nmi */
    if (getcp0reg(C0_SR) & SR_SR) {
	if (STATE == 0) {
	    /* check for app entry */
	    if (IO_READ(MI_SEC_MODE_REG) !=
		(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_APP|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_SECURE))
		failed("1");
            /* setup for timer entry */
            IO_WRITE(MI_SEC_TIMER_REG, (1<<16)|10);
	    STATE = 1;
	    f0 = (void*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    (*f0)();
	} else if (STATE == 1) {
	    /* check for timer entry */
	    if (IO_READ(MI_SEC_MODE_REG) !=
		(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_TIMER|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_SECURE))
		failed("2");
	    STATE = 2;

	    /* copy stub2 to internal ram */
	    p0 = (vu32*)__stub2;
	    p1 = (vu32*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    f0 = (void*)p1;
	    for(x = 0; x < 16; x++) *p1++ = *p0++;
	    f0 = (void*)PHYS_TO_K1(INTERNAL_RAM_START+4);

	    /* set up for module detect */
	    IO_WRITE(PI_ACCESS_REG, 0xff);
            IO_WRITE(MI_SEC_TIMER_REG, 0);

	    (*f0)();
        } else if (STATE == 2) {
	    /* check for module trap */
	    if (IO_READ(MI_SEC_MODE_REG) !=
		(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_MD_TRAP|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_SECURE|MI_SEC_MODE_MD_TRAP_EN))
		failed("3");
	    STATE = 3;

              /* Enable but interrupt */
            IO_WRITE(MI_INTR_EMASK_REG, MI_INTR_MASK_SET_BUT);

	    /* setup for button entry */
	    /* copy stub3 to internal ram */
	    p0 = (vu32*)__stub3;
	    p1 = (vu32*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    f0 = (void*)p1;
	    for(x = 0; x < 16; x++) *p1++ = *p0++;
	    f0 = (void*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    IO_WRITE(SI_CONFIG_REG, 0); /* speed up clock for timeout */
	    (*f0)();

	} else if (STATE == 3) {
	    /* check for button entry */
	    if (IO_READ(MI_SEC_MODE_REG) !=
		(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BUT_TRAP|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_SECURE|MI_SEC_MODE_BUT_TRAP_EN))
		failed("4");
	    STATE = 4;
	    /* set up for fatal */
	    /* copy stub4 to internal ram */
	    p0 = (vu32*)__stub4;
	    p1 = (vu32*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    f0 = (void*)p1;
	    for(x = 0; x < 16; x++) *p1++ = *p0++;
	    f0 = (void*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    IO_WRITE(PI_ERROR_REG, PI_ERROR_KERNEL_INTR);
	    (*f0)();
	} else if (STATE == 4) {
	    /* check for fatal */
	    if (IO_READ(MI_SEC_MODE_REG) !=
		(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_FATAL|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_SECURE))
		failed("5");
	    STATE = 5;
	    /* set up for emulation trap */
	    /* copy stub5 to internal ram */
	    p0 = (vu32*)__stub5;
	    p1 = (vu32*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    f0 = (void*)p1;
	    for(x = 0; x < 16; x++) *p1++ = *p0++;
	    f0 = (void*)PHYS_TO_K1(INTERNAL_RAM_START+4);
	    IO_WRITE(PI_ERROR_REG, 0);
	    IO_WRITE(MI_CTRL_REG, MI_CTRL_SK_TRAP_PIF);
	    (*f0)();
	} else if (STATE == 5) {
	    /* check for fatal */
	    if (IO_READ(MI_SEC_MODE_REG) !=
		(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_TRAP|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_SECURE))
		failed("6");
	    IO_WRITE(MI_SEC_MODE_REG, MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_SECURE);
	    passed();
	}
        failed("7");
    }
    test_preamble();

    /* copy stub to internal ram */
    p0 = (vu32*)__stub;
    p1 = (vu32*)PHYS_TO_K1(INTERNAL_RAM_START+4);
    f0 = (void*)p1;
    for(x = 0; x < 16; x++) *p1++ = *p0++;

    STATE = 0;
    /* jump to stub */
    (*f0)();
    failed("0");
    return 0;
}

void isram_stub(void) {
	__asm__ __volatile__(
	".set push\n"
	".set noreorder\n"
	".globl __stub\n__stub:\n"
	"la\t$27,%0\n\t"
	"la\t$26,%1\n\t"
	"sw\t$27,0($26)\n\t"
	"nop\n\t"
	"nop\n\t"
	"nop\n\t"
	"nop\n\t"
	"lw\t$27,0($26)\n\t"
	"nop\n\t"
	"1: b 1b\n\t"
	"nop\n\t"
	".set reorder\n"
	".set pop\n"
	: : "M"(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BROM_LO),
            "M"(PHYS_TO_K1(MI_SEC_MODE_REG)));
}

void isram_stub2(void) {
	__asm__ __volatile__(
	".set push\n"
	".set noreorder\n"
	".globl __stub2\n__stub2:\n"
	"la\t$27,%0\n\t"
	"la\t$26,%1\n\t"
	"sw\t$27,0($26)\n\t"
	"nop\n\t"
	"la\t$27,%2\n\t"
	"li\t$26,1\n\t"
	"sh\t$26,0($27)\n\t"
	"nop\n\t"
	"1: b 1b\n\t"
	"nop\n\t"
	".set reorder\n"
	".set pop\n"
	: : "M"(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_MD_TRAP_EN),
            "M"(PHYS_TO_K1(MI_SEC_MODE_REG)),
	    "M"(PHYS_TO_K1(BACKDOOR_MODULE)));
}

void isram_stub3(void) {
	__asm__ __volatile__(
	".set push\n"
	".set noreorder\n"
	".globl __stub3\n__stub3:\n"
	"la\t$27,%0\n\t"
	"la\t$26,%1\n\t"
	"sw\t$27,0($26)\n\t"
	"nop\n\t"
	"la\t$27,%2\n\t"
	"li\t$26,1\n\t"
	"sh\t$26,0($27)\n\t"
	"nop\n\t"
	"1: b 1b\n\t"
	"nop\n\t"
	".set reorder\n"
	".set pop\n"
	: : "M"(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BROM_LO|MI_SEC_MODE_BUT_TRAP_EN),
            "M"(PHYS_TO_K1(MI_SEC_MODE_REG)),
	    "M"(PHYS_TO_K1(BACKDOOR_POWER)));
}

void isram_stub4(void) {
	__asm__ __volatile__(
	".set push\n"
	".set noreorder\n"
	".globl __stub4\n__stub4:\n"
	"la\t$27,%0\n\t"
	"la\t$26,%1\n\t"
	"sw\t$27,0($26)\n\t"
	"nop\n\t"
	"la\t$27,%2\n\t"
	"li\t$26,1\n\t"
	"sw\t$26,0($27)\n\t"
	"nop\n\t"
	"1: b 1b\n\t"
	"nop\n\t"
	".set reorder\n"
	".set pop\n"
	: : "M"(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BROM_LO),
            "M"(PHYS_TO_K1(MI_SEC_MODE_REG)),
	    "M"(PHYS_TO_K1(PI_DOM1_ADDR1|4)));
}

void isram_stub5(void) {
	__asm__ __volatile__(
	".set push\n"
	".set noreorder\n"
	".globl __stub5\n__stub5:\n"
	"la\t$27,%0\n\t"
	"la\t$26,%1\n\t"
	"sw\t$27,0($26)\n\t"
	"nop\n\t"
	"la\t$27,%2\n\t"
	"li\t$26,1\n\t"
	"sw\t$26,0($27)\n\t"
	"nop\n\t"
	"1: b 1b\n\t"
	"nop\n\t"
	".set reorder\n"
	".set pop\n"
	: : "M"(MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BROM_LO),
            "M"(PHYS_TO_K1(MI_SEC_MODE_REG)),
	    "M"(PHYS_TO_K1(PIF_RAM_START)));
}