Hazard3/test/sim/sw_testcases/csr_readable_umode.c

355 lines
9.4 KiB
C

#include "tb_cxxrtl_io.h"
#include "hazard3_csr.h"
// Check all implemented M-mode and D-mode CSRs are unreadable in U mode.
// Check that an M-mode trap taken from U mode is able to access the M-mode
// trap CSRs.
// These are new (priv-1.12) and may not be recognised by the toolchain:
#define mconfigptr 0xf15
#define mstatush 0x310
// Everything except for the U-mode counters should trap.
/*EXPECTED-OUTPUT***************************************************************
-> exception, mcause = 2, mpp = 0 // mvendorid
CSR was f11
-> exception, mcause = 2, mpp = 0 // marchid
CSR was f12
-> exception, mcause = 2, mpp = 0 // mimpid
CSR was f13
-> exception, mcause = 2, mpp = 0 // mhartid
CSR was f14
-> exception, mcause = 2, mpp = 0 // mconfigptr
CSR was f15
-> exception, mcause = 2, mpp = 0 // misa
CSR was 301
-> exception, mcause = 2, mpp = 0 // mstatus
CSR was 300
-> exception, mcause = 2, mpp = 0 // mstatush
CSR was 310
-> exception, mcause = 2, mpp = 0 // mie
CSR was 304
-> exception, mcause = 2, mpp = 0 // mip
CSR was 344
-> exception, mcause = 2, mpp = 0 // mtvec
CSR was 305
-> exception, mcause = 2, mpp = 0 // mscratch
CSR was 340
-> exception, mcause = 2, mpp = 0 // mepc
CSR was 341
-> exception, mcause = 2, mpp = 0 // mcause
CSR was 342
-> exception, mcause = 2, mpp = 0 // mtval
CSR was 343
-> exception, mcause = 2, mpp = 0 // mcounteren
CSR was 306
-> exception, mcause = 2, mpp = 0 // mcycle
CSR was b00
-> exception, mcause = 2, mpp = 0 // mcycleh
CSR was b80
-> exception, mcause = 2, mpp = 0 // minstret
CSR was b02
-> exception, mcause = 2, mpp = 0 // minstreth
CSR was b82
-> exception, mcause = 2, mpp = 0 // mphmcounter3
CSR was b03
-> exception, mcause = 2, mpp = 0 // ...
CSR was b04
-> exception, mcause = 2, mpp = 0
CSR was b05
-> exception, mcause = 2, mpp = 0
CSR was b06
-> exception, mcause = 2, mpp = 0
CSR was b07
-> exception, mcause = 2, mpp = 0
CSR was b08
-> exception, mcause = 2, mpp = 0
CSR was b09
-> exception, mcause = 2, mpp = 0
CSR was b0a
-> exception, mcause = 2, mpp = 0
CSR was b0b
-> exception, mcause = 2, mpp = 0
CSR was b0c
-> exception, mcause = 2, mpp = 0
CSR was b0d
-> exception, mcause = 2, mpp = 0
CSR was b0e
-> exception, mcause = 2, mpp = 0
CSR was b0f
-> exception, mcause = 2, mpp = 0
CSR was b10
-> exception, mcause = 2, mpp = 0
CSR was b11
-> exception, mcause = 2, mpp = 0
CSR was b12
-> exception, mcause = 2, mpp = 0
CSR was b13
-> exception, mcause = 2, mpp = 0
CSR was b14
-> exception, mcause = 2, mpp = 0
CSR was b15
-> exception, mcause = 2, mpp = 0
CSR was b16
-> exception, mcause = 2, mpp = 0
CSR was b17
-> exception, mcause = 2, mpp = 0
CSR was b18
-> exception, mcause = 2, mpp = 0
CSR was b19
-> exception, mcause = 2, mpp = 0
CSR was b1a
-> exception, mcause = 2, mpp = 0
CSR was b1b
-> exception, mcause = 2, mpp = 0
CSR was b1c
-> exception, mcause = 2, mpp = 0
CSR was b1d
-> exception, mcause = 2, mpp = 0
CSR was b1e
-> exception, mcause = 2, mpp = 0 // ... mhpmcounter31
CSR was b1f
-> exception, mcause = 2, mpp = 0 // mhpmcounter3h
CSR was b83
-> exception, mcause = 2, mpp = 0 // ...
CSR was b84
-> exception, mcause = 2, mpp = 0
CSR was b85
-> exception, mcause = 2, mpp = 0
CSR was b86
-> exception, mcause = 2, mpp = 0
CSR was b87
-> exception, mcause = 2, mpp = 0
CSR was b88
-> exception, mcause = 2, mpp = 0
CSR was b89
-> exception, mcause = 2, mpp = 0
CSR was b8a
-> exception, mcause = 2, mpp = 0
CSR was b8b
-> exception, mcause = 2, mpp = 0
CSR was b8c
-> exception, mcause = 2, mpp = 0
CSR was b8d
-> exception, mcause = 2, mpp = 0
CSR was b8e
-> exception, mcause = 2, mpp = 0
CSR was b8f
-> exception, mcause = 2, mpp = 0
CSR was b90
-> exception, mcause = 2, mpp = 0
CSR was b91
-> exception, mcause = 2, mpp = 0
CSR was b92
-> exception, mcause = 2, mpp = 0
CSR was b93
-> exception, mcause = 2, mpp = 0
CSR was b94
-> exception, mcause = 2, mpp = 0
CSR was b95
-> exception, mcause = 2, mpp = 0
CSR was b96
-> exception, mcause = 2, mpp = 0
CSR was b97
-> exception, mcause = 2, mpp = 0
CSR was b98
-> exception, mcause = 2, mpp = 0
CSR was b99
-> exception, mcause = 2, mpp = 0
CSR was b9a
-> exception, mcause = 2, mpp = 0
CSR was b9b
-> exception, mcause = 2, mpp = 0
CSR was b9c
-> exception, mcause = 2, mpp = 0
CSR was b9d
-> exception, mcause = 2, mpp = 0
CSR was b9e
-> exception, mcause = 2, mpp = 0 // ... mhpmcounter31h
CSR was b9f // followed by U-mode counters, which shouldn't trap...
-> exception, mcause = 2, mpp = 0 // mcountinhibit
CSR was 320
-> exception, mcause = 2, mpp = 0 // mhpmevent3
CSR was 323
-> exception, mcause = 2, mpp = 0 // tselect
CSR was 7a0
-> exception, mcause = 2, mpp = 0 // tdata1
CSR was 7a1
-> exception, mcause = 2, mpp = 0 // dcsr
CSR was 7b0
-> exception, mcause = 2, mpp = 0 // dpc
CSR was 7b1
-> exception, mcause = 2, mpp = 0 // dscratch0
CSR was 7b2
-> exception, mcause = 2, mpp = 0 // dscratch1
CSR was 7b3
-> exception, mcause = 2, mpp = 0 // hazard3_csr_dmdata0
CSR was bff
-> exception, mcause = 2, mpp = 0 // hazard3_csr_meiea
CSR was be0
-> exception, mcause = 2, mpp = 0 // hazard3_csr_meipa
CSR was be1
-> exception, mcause = 2, mpp = 0 // hazard3_csr_meifa
CSR was be2
-> exception, mcause = 2, mpp = 0 // hazard3_csr_meipr
CSR was be3
-> exception, mcause = 2, mpp = 0 // hazard3_csr_meinext
CSR was be4
-> exception, mcause = 2, mpp = 0 // hazard3_csr_meicontext
CSR was be5
-> exception, mcause = 3, mpp = 0 // This is the ebreak that ends the test
*******************************************************************************/
// This function is run in U mode. It returns to a trampoline that ebreaks to M mode.
void read_all_csrs() {
(void)read_csr(mvendorid);
(void)read_csr(marchid);
(void)read_csr(mimpid);
(void)read_csr(mhartid);
(void)read_csr(mconfigptr);
(void)read_csr(misa);
(void)read_csr(mstatus);
(void)read_csr(mstatush);
(void)read_csr(mie);
(void)read_csr(mip);
(void)read_csr(mtvec);
(void)read_csr(mscratch);
(void)read_csr(mepc);
(void)read_csr(mcause);
(void)read_csr(mtval);
(void)read_csr(mcounteren);
(void)read_csr(mcycle);
(void)read_csr(mcycleh);
(void)read_csr(minstret);
(void)read_csr(minstreth);
(void)read_csr(mhpmcounter3);
(void)read_csr(mhpmcounter4);
(void)read_csr(mhpmcounter5);
(void)read_csr(mhpmcounter6);
(void)read_csr(mhpmcounter7);
(void)read_csr(mhpmcounter8);
(void)read_csr(mhpmcounter9);
(void)read_csr(mhpmcounter10);
(void)read_csr(mhpmcounter11);
(void)read_csr(mhpmcounter12);
(void)read_csr(mhpmcounter13);
(void)read_csr(mhpmcounter14);
(void)read_csr(mhpmcounter15);
(void)read_csr(mhpmcounter16);
(void)read_csr(mhpmcounter17);
(void)read_csr(mhpmcounter18);
(void)read_csr(mhpmcounter19);
(void)read_csr(mhpmcounter20);
(void)read_csr(mhpmcounter21);
(void)read_csr(mhpmcounter22);
(void)read_csr(mhpmcounter23);
(void)read_csr(mhpmcounter24);
(void)read_csr(mhpmcounter25);
(void)read_csr(mhpmcounter26);
(void)read_csr(mhpmcounter27);
(void)read_csr(mhpmcounter28);
(void)read_csr(mhpmcounter29);
(void)read_csr(mhpmcounter30);
(void)read_csr(mhpmcounter31);
(void)read_csr(mhpmcounter3h);
(void)read_csr(mhpmcounter4h);
(void)read_csr(mhpmcounter5h);
(void)read_csr(mhpmcounter6h);
(void)read_csr(mhpmcounter7h);
(void)read_csr(mhpmcounter8h);
(void)read_csr(mhpmcounter9h);
(void)read_csr(mhpmcounter10h);
(void)read_csr(mhpmcounter11h);
(void)read_csr(mhpmcounter12h);
(void)read_csr(mhpmcounter13h);
(void)read_csr(mhpmcounter14h);
(void)read_csr(mhpmcounter15h);
(void)read_csr(mhpmcounter16h);
(void)read_csr(mhpmcounter17h);
(void)read_csr(mhpmcounter18h);
(void)read_csr(mhpmcounter19h);
(void)read_csr(mhpmcounter20h);
(void)read_csr(mhpmcounter21h);
(void)read_csr(mhpmcounter22h);
(void)read_csr(mhpmcounter23h);
(void)read_csr(mhpmcounter24h);
(void)read_csr(mhpmcounter25h);
(void)read_csr(mhpmcounter26h);
(void)read_csr(mhpmcounter27h);
(void)read_csr(mhpmcounter28h);
(void)read_csr(mhpmcounter29h);
(void)read_csr(mhpmcounter30h);
(void)read_csr(mhpmcounter31h);
(void)read_csr(cycle);
(void)read_csr(cycleh);
(void)read_csr(instret);
(void)read_csr(instreth);
(void)read_csr(mcountinhibit);
(void)read_csr(mhpmevent3);
(void)read_csr(tselect);
(void)read_csr(tdata1);
(void)read_csr(dcsr);
(void)read_csr(dpc);
(void)read_csr(dscratch0);
(void)read_csr(dscratch1);
(void)read_csr(hazard3_csr_dmdata0);
(void)read_csr(hazard3_csr_meiea);
(void)read_csr(hazard3_csr_meipa);
(void)read_csr(hazard3_csr_meifa);
(void)read_csr(hazard3_csr_meipr);
(void)read_csr(hazard3_csr_meinext);
(void)read_csr(hazard3_csr_meicontext);
}
void __attribute__((naked)) ebreak_trampoline() {
asm ("ebreak");
}
int main() {
// Make counters accessible to U mode
write_csr(mcounteren, -1u);
// Give U mode RWX permission on all of memory.
write_csr(pmpcfg0, 0x1fu);
write_csr(pmpaddr0, -1u);
// Enter function in U mode, return via ebreak trampoline
write_csr(mstatus, read_csr(mstatus) & ~0x1800u);
write_csr(mepc, &read_all_csrs);
asm (
"la ra, ebreak_trampoline\n"
"mret\n"
);
return 0;
}
void __attribute__((interrupt)) handle_exception() {
uint32_t mcause = read_csr(mcause);
tb_printf("-> exception, mcause = %u, mpp = %u\n", mcause, read_csr(mstatus) >> 11 & 0x3u);
write_csr(mcause, 0);
if (mcause == 3) {
// ebreak -> end of test
tb_exit(0);
}
uint32_t mepc = read_csr(mepc);
if ((*(uint16_t*)mepc & 0x3) == 0x3) {
tb_printf("CSR was %03x\n", *(uint16_t*)(mepc + 2) >> 4);
mepc += 4;
}
else {
tb_puts("Exception on 16-bit instruction?!\n");
tb_exit(-1);
}
write_csr(mepc, mepc);
}