cacheun.c
2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "cpusim.h"
#define CMEM_WORD (*(vu32*)K0BASE)
#define UMEM_WORD (*(vu32*)K1BASE)
#define CMEM64_WORD (*(vu32*)PHYS_TO_K0(DDRRAM64_START))
#define UMEM64_WORD (*(vu32*)PHYS_TO_K1(DDRRAM64_START))
#define CNONMEM_WORD (*(vu32*)PHYS_TO_K0(PI_BUFFER_BASE_REG))
#define UNONMEM_WORD (*(vu32*)PHYS_TO_K1(PI_BUFFER_BASE_REG))
void
failed(const char* code) {
message("cached/uncached test failed (");
message(code);
message(")\n");
DBG_JTAG_FAIL(code);
test_postamble();
}
#define saved_cause (*(volatile int*)PHYS_TO_K1(INTERNAL_RAM_START))
/* run from the exception handler. don't use regular regs, or stack */
/*
* stash C0_CAUSE in saved_case and clear C0_CAUSE
* increment C0_EPC by 4 to skip instruction causing bus error, but
* temporarily set C0_SR to 0 to clear the EXL bit when writing C0_EPC
*/
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");
}
int
main() {
extern void *__exception;
test_preamble();
init_ddr();
#if 0
invalICache((void*)K0BASE, ICACHE_SIZE);
invalDCache((void*)K0BASE, DCACHE_SIZE);
#endif
initICache();
initDCache();
setcp0reg(C0_SR, SR_CU0|SR_CU1|SR_BEV);
setcp0reg(C0_CONFIG, CONFIG_BE|CONFIG_NONCOHRNT);
CMEM_WORD = 0xbabecafe;
*(&CMEM_WORD+1) = 0xfeedfade;
writebackDCache((void*)&CMEM_WORD, 8);
if (UMEM_WORD != 0xbabecafe || *(&UMEM_WORD+1) != 0xfeedfade)
failed("0");
if (UMEM64_WORD != 0xbabecafe || *(&UMEM64_WORD+2) != 0xfeedfade)
failed("1");
invalDCache((void*)&CMEM64_WORD, 4);
CMEM64_WORD = 0xb0bafad;
writebackDCache((void*)&CMEM64_WORD, 4);
if (UMEM64_WORD != 0xb0bafad)
failed("2");
CNONMEM_WORD = 0xdeadbeef;
writebackDCache((void*)&CNONMEM_WORD, 4);
IO_WRITE(MI_CTRL_REG, MI_CTRL_BUS_ERROR_BNM|MI_CTRL_WR_INTR_BNM);
/* generate write error interrupt on block write */
setcp0reg(C0_CAUSE, 0);
CNONMEM_WORD = 0xbad2dad;
writebackDCache((void*)&CNONMEM_WORD, 4);
if ((getcp0reg(C0_CAUSE) & CAUSE_IP6) != CAUSE_IP6)
failed("3");
if (IO_READ(MI_ERROR_ADDR_REG) != K0_TO_PHYS(&CNONMEM_WORD) ||
IO_READ(MI_ERROR_INFO_REG) != (MI_ERROR_INFO_ENABLE | MI_ERROR_INFO_TYPE_BLOCK | 1))
failed("4");
__exception = exception;
saved_cause = 0;
setcp0reg(C0_CAUSE, 0);
/* generate bus error on read */
(void)*(vu32*)(&CNONMEM_WORD+4);
IO_WRITE(PI_IDE0_BASE_REG, saved_cause);
if ((saved_cause & CAUSE_EXCMASK) != EXC_DBE)
failed("5");
message("cached/uncached test passed\n");
DBG_JTAG_PASS("cached/uncached test passed\n");
test_postamble();
return 0;
}