Add test for readability of CSRs in U mode. Fix readback value of mstatus.mpp
This commit is contained in:
parent
ba81b533d2
commit
f033cde874
|
@ -495,22 +495,22 @@ always @ (*) begin
|
||||||
MSTATUS: if (CSR_M_MANDATORY || CSR_M_TRAP) begin
|
MSTATUS: if (CSR_M_MANDATORY || CSR_M_TRAP) begin
|
||||||
decode_match = match_mrw;
|
decode_match = match_mrw;
|
||||||
rdata = {
|
rdata = {
|
||||||
1'b0, // Never any dirty state besides GPRs
|
1'b0, // Never any dirty state besides GPRs
|
||||||
8'd0, // (WPRI)
|
8'd0, // (WPRI)
|
||||||
1'b0, // TSR (Trap SRET), tied 0 if no S mode.
|
1'b0, // TSR (Trap SRET), tied 0 if no S mode.
|
||||||
1'b0, // TW (Timeout Wait), tied 0 if only M mode.
|
1'b0, // TW (Timeout Wait), tied 0 if only M mode.
|
||||||
1'b0, // TVM (trap virtual memory), tied 0 if no S mode.
|
1'b0, // TVM (trap virtual memory), tied 0 if no S mode.
|
||||||
1'b0, // MXR (Make eXecutable Readable), tied 0 if not S mode.
|
1'b0, // MXR (Make eXecutable Readable), tied 0 if not S mode.
|
||||||
1'b0, // SUM, tied 0, we have no S or U mode
|
1'b0, // SUM, tied 0, we have no S or U mode
|
||||||
mstatus_mprv, // MPRV (modify privilege)
|
mstatus_mprv, // MPRV (modify privilege)
|
||||||
4'd0, // XS, FS always "off" (no extension state to clear!)
|
4'd0, // XS, FS always "off" (no extension state to clear!)
|
||||||
{2{m_mode}}, // MPP (M-mode previous privilege), only M and U supported
|
{2{mstatus_mpp}}, // MPP (M-mode previous privilege), only M and U supported
|
||||||
2'd0, // (WPRI)
|
2'd0, // (WPRI)
|
||||||
1'b0, // SPP, tied 0 if S mode not supported
|
1'b0, // SPP, tied 0 if S mode not supported
|
||||||
mstatus_mpie, // Previous interrupt enable
|
mstatus_mpie, // Previous interrupt enable
|
||||||
3'd0, // No S, U
|
3'd0, // No S, U
|
||||||
mstatus_mie, // Interrupt enable
|
mstatus_mie, // Interrupt enable
|
||||||
3'd0 // No S, U
|
3'd0 // No S, U
|
||||||
};
|
};
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,348 @@
|
||||||
|
#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
|
||||||
|
|
||||||
|
// Exceptions here are: medeleg, mideleg, tdata1, dcsr, dpc, dscratch1,
|
||||||
|
// dscratch0, dmdata0 (custom). medeleg/mideleg are just a couple of
|
||||||
|
// unimplemented registers sprinkled in for a sanity check, and the remainder
|
||||||
|
// are D-mode registers.
|
||||||
|
//
|
||||||
|
// Note we permit reads but not writes to tselect, to work around a logic
|
||||||
|
// error in openocd. Planning to implement triggers at some point, so this
|
||||||
|
// oddity will vanish.
|
||||||
|
|
||||||
|
/*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 dmdata0
|
||||||
|
CSR was bff
|
||||||
|
-> exception, mcause = 2, mpp = 0 // hazard3 meie0
|
||||||
|
CSR was be0
|
||||||
|
-> exception, mcause = 2, mpp = 0 // hazard3 meip0
|
||||||
|
CSR was fe0
|
||||||
|
-> exception, mcause = 2, mpp = 0 // hazard3 mlei
|
||||||
|
CSR was fe4
|
||||||
|
-> 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_meie0);
|
||||||
|
(void)read_csr(hazard3_csr_meip0);
|
||||||
|
(void)read_csr(hazard3_csr_mlei);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((naked)) ebreak_trampoline() {
|
||||||
|
asm ("ebreak");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Make counters accessible to U mode
|
||||||
|
write_csr(mcounteren, -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);
|
||||||
|
}
|
Loading…
Reference in New Issue