interrupt.c 3.88 KB
#include "cpusim.h"

#define saved_cause 	(*(volatile int*)PHYS_TO_K1(INTERNAL_RAM_START))
#define CNONMEM_WORD	(*(vu32*)PHYS_TO_K0(PI_BUFFER_BASE_REG))

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

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

/* run from the exception handler.  don't use regular regs, or stack */
/* stash away the cause register at 0xbfc40000, clear it, disable SR_IE */
void exception(void) {
    //saved_cause = getcp0reg(C0_CAUSE);
    //setcp0reg(C0_CAUSE, 0);
    __asm__ __volatile__ ("lui\t$26,0xbfc4\n\t"
			  "mfc0\t$27,$13\n\t"
			  "sw\t$27,0($26)\n\t"
			  "mtc0\t$0,$13\n\t"
			  "mfc0\t$27,$12\n\t"
			  "li\t$26,-2\n\t"
			  "and\t$27,$26\n\t"
			  "mtc0\t$27,$12\n\t"
			  "eret");
}

int
main() {
    extern void *__exception;
    /* check for nmi */
    if (getcp0reg(C0_SR) & SR_SR) {
	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))
	    passed();
        failed("7");
    }
    setcp0reg(C0_CONFIG, CONFIG_BE|CONFIG_NONCOHRNT);
    test_preamble();
    __exception = exception;
    init_ddr();
    saved_cause = 0;
    setcp0reg(C0_CAUSE, CAUSE_SW1);
    setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV|SR_IMASK|SR_IE);
    if ((saved_cause & CAUSE_SW1) != CAUSE_SW1)
	failed("0");
    saved_cause = 0;
    setcp0reg(C0_CAUSE, CAUSE_SW2);
    setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV|SR_IMASK|SR_IE);
    if ((saved_cause & CAUSE_SW2) != CAUSE_SW2)
	failed("1");
#if 1
    /* do an SI transfer to dram and generate an SI interrupt */
    saved_cause = 0;
    setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV|SR_IMASK|SR_IE);
    IO_WRITE(MI_INTR_MASK_REG, MI_INTR_MASK_SET_SI);
    IO_WRITE(SI_DRAM_ADDR_REG, RDRAM_START);
    IO_WRITE(SI_PIF_ADDR_WR64B_REG, 0);
    IO_READ(SI_STATUS_REG);
    IO_READ(SI_STATUS_REG);
    /* rcp interrupt */
    if ((saved_cause & CAUSE_IP3) != CAUSE_IP3)
	failed("2");
    IO_WRITE(SI_STATUS_REG, 0);
#endif
#if 1
    saved_cause = 0;
    setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV|SR_IMASK|SR_IE);
    /* bcp interrupt */
    /* make flash module disappear */
    IO_WRITE(MI_INTR_EMASK_REG, MI_INTR_MASK_SET_MD);
    IDE_WRITE_NB(BACKDOOR_MODULE, 1);
    IO_READ(PI_IDE0_BASE_REG); /* sleep a little */
    if ((saved_cause & CAUSE_IP4) != CAUSE_IP4 ||
	(IO_READ(MI_EINTR_REG) & (MI_INTR_MD|MI_EINTR_MD_STATUS)) != 
	    (MI_INTR_MD|MI_EINTR_MD_STATUS))
	failed("3");
    IDE_WRITE_NB(BACKDOOR_MODULE, 0);
    IO_READ(PI_IDE0_BASE_REG); /* sleep */
    IO_WRITE(MI_EINTR_REG, MI_INTR_MD);
    if ((IO_READ(MI_EINTR_REG) &
	(MI_INTR_MD|MI_EINTR_MD_STATUS)) != 0)
	failed("4");
#endif
#if 1
    saved_cause = 0;
    setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV|SR_IMASK|SR_IE);
    /* power off interrupt */
    IO_WRITE(MI_INTR_EMASK_REG, MI_INTR_MASK_SET_BUT);
    IDE_WRITE_NB(BACKDOOR_POWER, 1);
    IO_READ(PI_IDE0_BASE_REG); /* sleep a little */
    IO_READ(PI_IDE0_BASE_REG); /* sleep a little */
    if ((saved_cause & CAUSE_IP5) != CAUSE_IP5)
	failed("5");
    IO_WRITE(MI_INTR_EMASK_REG, MI_INTR_MASK_CLR_BUT);
#endif
#if 1
    /* system error interrupt */
    /* generate a cache writeback to a non-cacheable space */
    saved_cause = 0;
    setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV|SR_IMASK|SR_IE);
    IO_WRITE(MI_CTRL_REG, MI_CTRL_WR_INTR_BNM);
    initDCache();
    invalDCache((void*)&CNONMEM_WORD, 4);
    CNONMEM_WORD = 0xbad2dad;
    writebackDCache((void*)&CNONMEM_WORD, 4);
    IO_READ(MI_CTRL_REG);
    if ((saved_cause & CAUSE_IP6) != CAUSE_IP6)
	failed("6");
    IO_READ(MI_ERROR_ADDR_REG);
    IO_READ(MI_ERROR_INFO_REG);
#endif
#if 0
    /* gpio interrupt */
    saved_cause = 0;
    setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV|SR_IMASK|SR_IE);
    if ((saved_cause & CAUSE_IP7) != CAUSE_IP7)
	failed("7");
#endif
    passed();
    return 0;
}