bus_error2.c 2.95 KB
#include "cpusim.h"

extern void* __exception;
void __osException(void);
void exception(void), iram_stub(void);
#define saved_cause	(*(volatile int*)PHYS_TO_K1(INTERNAL_RAM_START))

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

int
main() {
    extern void __start(void), _end(void);
    int x;
    vu32 *p0, *p1;
    void (*f0)(void);

    test_preamble();

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

    setcp0reg(C0_SR, SR_CU0|SR_CU1);			/* turn off BEV */
    setcp0reg(C0_CONFIG, CONFIG_BE|CONFIG_NONCOHRNT);	/* KSEG0 uncached */

    init_ddr();
    initDCache();

    /* copy stub to ddr ram */
    p0 = (vu32*)exception;
    p1 = (vu32*)E_VEC;
    for(x = 0; x < 32; x++) *p1++ = *p0++;

    invalDCache((void*)PHYS_TO_K0(PI_BUFFER_BASE_REG), 16);
    IO_WRITE(MI_CTRL_REG, MI_CTRL_BUS_ERROR_BNM);
    (*f0)();
    failed("0");
    test_postamble();
    return 0;
}

void iram_stub(void) {
    int r;
    saved_cause = 0;
    IO_WRITE(PI_ACCESS_REG, 0xff);
    /* secure mode off */
    IO_WRITE(MI_SEC_MODE_REG, MI_SEC_MODE_IRAM_ACCESS|MI_SEC_MODE_BRAM_LO);
    /* generate a bus error with a cache fill */
    IO_WRITE(PI_BUFFER_BASE_REG, 0);
    IO_WRITE(PI_BUFFER_BASE_REG+4, 0);
    IO_WRITE(PI_BUFFER_BASE_REG+8, 0);
    IO_WRITE(PI_BUFFER_BASE_REG+16, 0);
    *(vu32*)PHYS_TO_K0(PI_BUFFER_BASE_REG); 
    //*(vu32*)PHYS_TO_K0(0+256); 
    r = 0x046fffe0;
    IDE_WRITE_NB(r, 't');
    IDE_WRITE_NB(r, 'e');
    IDE_WRITE_NB(r, 's');
    IDE_WRITE_NB(r, 't');
    IDE_WRITE_NB(r, ' ');
    IDE_WRITE_NB(r, 'b');
    IDE_WRITE_NB(r, 'u');
    IDE_WRITE_NB(r, 's');
    IDE_WRITE_NB(r, '_');
    IDE_WRITE_NB(r, 'e');
    IDE_WRITE_NB(r, 'r');
    IDE_WRITE_NB(r, 'r');
    IDE_WRITE_NB(r, 'o');
    IDE_WRITE_NB(r, 'r');
    IDE_WRITE_NB(r, '2');
    IDE_WRITE_NB(r, ' ');
    if ((saved_cause & CAUSE_EXCMASK) != EXC_DBE) {
	IDE_WRITE_NB(r, 'f');
	IDE_WRITE_NB(r, 'a');
	IDE_WRITE_NB(r, 'i');
	IDE_WRITE_NB(r, 'l');
	IDE_WRITE_NB(r, 'e');
	IDE_WRITE_NB(r, 'd');
	IDE_WRITE_NB(r, ' ');
	IDE_WRITE_NB(r, '1');
	IDE_WRITE_NB(r, '\n');
        DBG_JTAG_FAIL("Bus error test failed");
	test_postamble();
    } else {
	IDE_WRITE_NB(r, 'p');
	IDE_WRITE_NB(r, 'a');
	IDE_WRITE_NB(r, 's');
	IDE_WRITE_NB(r, 's');
	IDE_WRITE_NB(r, 'e');
	IDE_WRITE_NB(r, 'd');
	IDE_WRITE_NB(r, '\n');
        DBG_JTAG_PASS("Bus error test passed");
	test_postamble();
    }
}

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,$14\n\t"
			  "mfc0\t$26,$12\n\t"
			  "mtc0\t$0,$12\n\t"
			  "addiu $27,$27,4\n\t"
			  "mtc0\t$27,$14\n\t"
			  "mtc0\t$26,$12\n\t"
			  "nop\t\n"
			  "eret");
}