Skip to content

Commit 855f527

Browse files
authored
Smrnmi/Smdbltrp extensions fixes (#472)
* Smrnmi/Smdbltrp extensions fixes Signed-off-by: Albert Yosher <[email protected]> * Smrnmi extension: should be priviledged as describe in vol.2 section 8. Signed-off-by: Albert Yosher <[email protected]> * Smrnmi extension: Fix mnepc CSR logic and reset value for mnepc and mnscratch CSRs Signed-off-by: Albert Yosher <[email protected]> --------- Signed-off-by: Albert Yosher <[email protected]>
1 parent f5d2201 commit 855f527

File tree

7 files changed

+191
-1
lines changed

7 files changed

+191
-1
lines changed

arch/csr/Smrnmi/mnepc.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# yaml-language-server: $schema=../../schemas/csr_schema.json
2+
3+
$schema: "csr_schema.json#"
4+
kind: csr
5+
name: mnepc
6+
long_name: Machine Exception Program Counter
7+
address: 0x741
8+
priv_mode: M
9+
length: MXLEN
10+
description: |
11+
Written with the PC of an instruction on an exception or interrupt taken in M-mode.
12+
13+
Also controls where the hart jumps on an exception return from M-mode.
14+
definedBy: Sm
15+
fields:
16+
PC:
17+
location_rv32: 31-0
18+
location_rv64: 63-0
19+
description: |
20+
When a NMI / double trap is taken into M-mode, `mnepc.PC` is written with the virtual address of the
21+
instruction that was interrupted or that encountered the exception.
22+
Otherwise, `mnepc.PC` is never written by the implementation, though it may be explicitly written
23+
by software.
24+
25+
On an exception return from M-mode NMI / double trap (from the MNRET instruction),
26+
control transfers to the virtual address read out of `mnepc.PC`.
27+
28+
[when,"ext?(:C)"]
29+
Because PCs are always halfword-aligned, bit 0 of `mnepc.PC` is always
30+
read-only 0.
31+
32+
[when,"!ext?(:C)"]
33+
Because PCs are always word-aligned, bits 1:0 of `mnepc.PC` are always
34+
read-only 0.
35+
36+
[when,"ext?(:C) && MUTABLE_MISA_C == true"]
37+
When `misa.C` is clear, bit 1 is masked to zero. Writes to bit 1 are still captured, and
38+
may be visible on the next read with `misa.C` is set.
39+
type: RW-RH
40+
sw_write(csr_value): |
41+
return csr_value.PC & ~64'b1;
42+
reset_value: UNDEFINED_LEGAL
43+
sw_read(): |
44+
if (implemented?(ExtensionName::C) && CSR[misa].C == 1'b1) {
45+
return CSR[mnepc].PC & ~64'b1;
46+
} else {
47+
return CSR[mnepc].PC & ~64'b11;
48+
}

arch/csr/Smrnmi/mnscratch.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# yaml-language-server: $schema=../../schemas/csr_schema.json
2+
3+
$schema: "csr_schema.json#"
4+
kind: csr
5+
name: mnscratch
6+
long_name: Machine Scratch Register
7+
address: 0x740
8+
priv_mode: M
9+
length: MXLEN
10+
description: Scratch register for software use in NMI / double trap. Bits are not interpreted by hardware.
11+
definedBy: Smrnmi
12+
fields:
13+
SCRATCH:
14+
location_rv32: 31-0
15+
location_rv64: 63-0
16+
description: Scratch value
17+
type: RW
18+
reset_value: UNDEFINED_LEGAL

arch/csr/Smrnmi/mnstatus.yaml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# yaml-language-server: $schema=../../schemas/csr_schema.json
2+
3+
$schema: "csr_schema.json#"
4+
kind: csr
5+
name: mnstatus
6+
long_name: Machine NMI Status
7+
address: 0x744
8+
priv_mode: M
9+
10+
# length is MXLEN-bit
11+
length: MXLEN
12+
description: The mnstatus register tracks and controls the hart's current NMI operating state.
13+
definedBy: Smrnmi
14+
fields:
15+
MNPP:
16+
location: 12-11
17+
description: |
18+
M-mode NMI Previous Privilege.
19+
20+
Written by hardware in two cases:
21+
22+
* Written with the prior nominal privilege level when entering M-mode NMI from an exception/interrupt.
23+
* Written with 0 when executing an `mnret` instruction to return from a double exception / NMI in M-mode.
24+
25+
Can also be written by software without immediate side-effect.
26+
27+
Affects execution in two cases:
28+
29+
* On a return from a double exception / NMI from M-mode, the machine will
30+
enter the privilege level stored in MNPP before clearing the field.
31+
* When `mnstatus.MNPRV` is set, loads and stores behave as if the current privilege level were MNPP.
32+
type: RW-H
33+
reset_value: UNDEFINED_LEGAL
34+
sw_write(csr_value): |
35+
if (csr_value.MNPP == 2'b01 && !implemented?(ExtensionName::S)) {
36+
return UNDEFINED_LEGAL_DETERMINISTIC;
37+
} else if (csr_value.MNPP == 2'b00 && !implemented?(ExtensionName::U)) {
38+
return UNDEFINED_LEGAL_DETERMINISTIC;
39+
} else if (csr_value.MNPP == 2'b10) {
40+
# never a valid value
41+
return UNDEFINED_LEGAL_DETERMINISTIC;
42+
} else {
43+
return csr_value.MNPP;
44+
}
45+
legal?(csr_value): |
46+
if (csr_value.MNPP == 2'b01 && !implemented?(ExtensionName::S)) {
47+
return false;
48+
} else if (csr_value.MNPP == 2'b00 && !implemented?(ExtensionName::U)) {
49+
return false;
50+
} else if (csr_value.MNPP == 2'b10) {
51+
# never a valid value
52+
return false;
53+
} else {
54+
return true;
55+
}
56+
MNPV:
57+
location: 7
58+
description: |
59+
*Machine Previous NMI Virtualization mode*
60+
61+
Written with the prior virtualization mode when entering M-mode from an exception/interrupt.
62+
When returning via an MRET instruction, the virtualization mode becomes the value of MPV unless MPP=3, in which case the virtualization mode is always 0.
63+
Can also be written by software.
64+
type: RW-H
65+
reset_value: UNDEFINED_LEGAL
66+
definedBy: H
67+
NMIE:
68+
location: 3
69+
description: |
70+
*M-mode NMI Enable*
71+
72+
Written by hardware in two cases:
73+
74+
* Written with the value 0 when entering M-mode NMI.
75+
* Written with the value 0 when entering M-mode double trap.
76+
77+
Written by software in one case only:
78+
79+
* The NMIE is 0 on reset for boot code to initialize system to service NMIs. Once SW writes NMIE to 1, it cannot be changed anymore by SW.
80+
81+
Affects execution by:
82+
83+
* When 0, all non-maskable interrupts and exceptions are disabled when the current privilege level is M.
84+
* When 1, NMI or double trap is possible.
85+
86+
type: RW-H
87+
reset_value: 0

arch/csr/mstatus.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ fields:
4646
return UNDEFINED_LEGAL;
4747
}
4848
49+
MDT:
50+
location: 42
51+
base: 64
52+
description: |
53+
*Machine Disable Trap*
54+
55+
Written to 1 when entering M-mode from an exception/interrupt.
56+
When returning via an MRET instruction, the bit is written to 0.
57+
On reset in set to 1, and software should write it to 0 when boot sequence is done.
58+
When mstatus.MDT=1, direct write by CSR instruction cannot set mstatus.MIE to 1, if not written together.
59+
definedBy: Smdbltrp
60+
type: RW-H
61+
reset_value: UNDEFINED_LEGAL
4962
MPV:
5063
location: 39
5164
base: 64

arch/csr/mstatush.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ definedBy:
1313
name: Sm
1414
version: ">= 1.12"
1515
fields:
16+
MDT:
17+
location: 10
18+
description: |
19+
*Machine Disable Trap*
20+
21+
Written to 1 when entering M-mode from an exception/interrupt.
22+
When returning via an MRET instruction, the bit is written to 0.
23+
On reset in set to 1, and software should write it to 0 when boot sequence is done.
24+
When mstatush.MDT=1, direct write by CSR instruction cannot set mstatus.MIE to 1.
25+
definedBy: Smdbltrp
26+
type: RW-H
27+
reset_value: UNDEFINED_LEGAL
1628
MPV:
1729
location: 7
1830
description: |

arch/ext/Smrnmi.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ description: |
1414
The `Smrnmi` extension adds support for resumable non-maskable interrupts (RNMIs) to RISC-V.
1515
The extension adds four new CSRs (`mnepc`, `mncause`, `mnstatus`, and `mnscratch`) to hold the
1616
interrupted state, and one new instruction, `mnret`, to resume from the RNMI handler.
17-
type: unprivileged
17+
type: privileged
1818
versions:
1919
- version: "1.0.0"
2020
state: ratified

arch/inst/Smrnmi/mnret.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,15 @@ access:
1818
vu: always
1919
data_independent_timing: false
2020
operation(): |
21+
if (implemented?(ExtensionName::S) && CSR[mstatus].MPP != 2'b11) {
22+
CSR[mstatus].MPRV = 0;
23+
}
24+
if (CSR[mnstatus].MNPP == 2'b00) {
25+
set_mode(PrivilegeMode::U);
26+
} else if (CSR[mnstatus].MNPP == 2'b01) {
27+
set_mode(PrivilegeMode::S);
28+
} else if (CSR[mnstatus].MNPP == 2'b11) {
29+
set_mode(PrivilegeMode::M);
30+
}
31+
CSR[mnstatus].MNPP = implemented?(ExtensionName::U) ? 2'b00 : 2'b11;
32+
$pc = $bits(CSR[mnepc]);

0 commit comments

Comments
 (0)