Skip to content

Commit 296f8cd

Browse files
authored
Refactor the ext_fetch_check_pc API. (#1226)
This makes it return just an option instead of also a possibly modified target address. The more general API was designed for an earlier CHERI model, but now the generality is not used. Addresses #1205.
1 parent 57a84bb commit 296f8cd

File tree

4 files changed

+66
-72
lines changed

4 files changed

+66
-72
lines changed

model/riscv_addr_checks.sail

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ type ext_fetch_addr_error = unit
1414
* start_pc: the PC at the start of the current fetch sequence
1515
* pc: the PC for the current granule
1616
*
17-
* returns: the *virtual* memory address to use for the fetch.
18-
* any address translation errors are reported for pc, not the returned value.
17+
* returns: an optional fetch error.
1918
*/
20-
function ext_fetch_check_pc(start_pc : xlenbits, pc : xlenbits) -> Ext_FetchAddr_Check(ext_fetch_addr_error) =
21-
Ext_FetchAddr_OK(Virtaddr(pc))
19+
function ext_fetch_check_pc(start_pc : xlenbits, pc : xlenbits) -> option(ext_fetch_addr_error) =
20+
None()
2221

2322
function ext_handle_fetch_check_error(err : ext_fetch_addr_error) -> unit =
2423
()

model/riscv_addr_checks_common.sail

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
* extensions would need to define their own functions to override them.
1515
*/
1616

17-
union Ext_FetchAddr_Check ('a : Type) = {
18-
Ext_FetchAddr_OK : virtaddr, /* PC value to use for the actual fetch */
19-
Ext_FetchAddr_Error : 'a
20-
}
21-
2217
union Ext_ControlAddr_Check ('a : Type) = {
2318
Ext_ControlAddr_OK : virtaddr, /* PC value to use for the target of the control operation */
2419
Ext_ControlAddr_Error : 'a

model/riscv_fetch.sail

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,47 @@ function fetch() -> FetchResult = {
1717
* but any exceptions use the untransformed PC.
1818
*/
1919
// TODO: Add a parameter to try_step() to allow forcing the fetch result and use that instead.
20+
2021
if get_config_rvfi()
2122
then return rvfi_fetch();
23+
2224
match ext_fetch_check_pc(PC, PC) {
23-
Ext_FetchAddr_Error(e) => F_Ext_Error(e),
24-
Ext_FetchAddr_OK(use_pc) => {
25-
let use_pc_bits = bits_of(use_pc);
26-
if (use_pc_bits[0] != bitzero | (use_pc_bits[1] != bitzero & not(currentlyEnabled(Ext_Zca))))
27-
then F_Error(E_Fetch_Addr_Align(), PC)
28-
else match translateAddr(use_pc, InstructionFetch()) {
29-
Err(e, _) => F_Error(e, PC),
30-
Ok(ppclo, _) => {
31-
/* split instruction fetch into 16-bit granules to handle RVC, as
32-
* well as to generate precise fault addresses in any fetch
33-
* exceptions.
34-
*/
35-
match mem_read(InstructionFetch(), ppclo, 2, false, false, false) {
36-
Err(e) => F_Error(e, PC),
37-
Ok(ilo) => {
38-
if isRVC(ilo)
39-
then F_RVC(ilo)
40-
else {
41-
/* fetch PC check for the next instruction granule */
42-
let PC_hi = PC + 2;
43-
match ext_fetch_check_pc(PC, PC_hi) {
44-
Ext_FetchAddr_Error(e) => F_Ext_Error(e),
45-
Ext_FetchAddr_OK(use_pc_hi) => {
46-
match translateAddr(use_pc_hi, InstructionFetch()) {
47-
Err(e, _) => F_Error(e, PC_hi),
48-
Ok(ppchi, _) => {
49-
match mem_read(InstructionFetch(), ppchi, 2, false, false, false) {
50-
Err(e) => F_Error(e, PC_hi),
51-
Ok(ihi) => F_Base(append(ihi, ilo))
52-
}
53-
}
54-
}
55-
}
25+
Some(e) => return F_Ext_Error(e),
26+
None() => (),
27+
};
28+
29+
if (PC[0] != bitzero | (PC[1] != bitzero & not(currentlyEnabled(Ext_Zca))))
30+
then return F_Error(E_Fetch_Addr_Align(), PC);
31+
32+
match translateAddr(Virtaddr(PC), InstructionFetch()) {
33+
Err(e, _) => F_Error(e, PC),
34+
Ok(ppclo, _) => {
35+
/* split instruction fetch into 16-bit granules to handle RVC, as
36+
* well as to generate precise fault addresses in any fetch
37+
* exceptions.
38+
*/
39+
match mem_read(InstructionFetch(), ppclo, 2, false, false, false) {
40+
Err(e) => F_Error(e, PC),
41+
Ok(ilo) =>
42+
if isRVC(ilo)
43+
then F_RVC(ilo)
44+
else {
45+
/* fetch PC check for the next instruction granule */
46+
let PC_hi = PC + 2;
47+
match ext_fetch_check_pc(PC, PC_hi) {
48+
Some(e) => return F_Ext_Error(e),
49+
None() => (),
50+
};
51+
52+
match translateAddr(Virtaddr(PC_hi), InstructionFetch()) {
53+
Err(e, _) => F_Error(e, PC_hi),
54+
Ok(ppchi, _) =>
55+
match mem_read(InstructionFetch(), ppchi, 2, false, false, false) {
56+
Err(e) => F_Error(e, PC_hi),
57+
Ok(ihi) => F_Base(append(ihi, ilo))
5658
}
57-
}
5859
}
5960
}
60-
}
6161
}
6262
}
6363
}

model/riscv_fetch_rvfi.sail

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,33 @@ function rvfi_fetch() -> FetchResult = {
1414

1515
/* First allow extensions to check pc */
1616
match ext_fetch_check_pc(PC, PC) {
17-
Ext_FetchAddr_Error(e) => F_Ext_Error(e),
18-
Ext_FetchAddr_OK(use_pc) => {
19-
/* then check PC alignment */
20-
let use_pc_bits = bits_of(use_pc);
21-
if (use_pc_bits[0] != bitzero | (use_pc_bits[1] != bitzero & not(currentlyEnabled(Ext_Zca))))
22-
then F_Error(E_Fetch_Addr_Align(), PC)
23-
else match translateAddr(use_pc, InstructionFetch()) {
24-
Err(e, _) => F_Error(e, PC),
25-
Ok(_, _) => {
26-
let i = rvfi_instruction[rvfi_insn];
27-
rvfi_inst_data[rvfi_insn] = zero_extend(i);
28-
if (i[1 .. 0] != 0b11)
29-
then F_RVC(i[15 .. 0])
30-
else {
31-
/* fetch PC check for the next instruction granule */
32-
let PC_hi = PC + 2;
33-
match ext_fetch_check_pc(PC, PC_hi) {
34-
Ext_FetchAddr_Error(e) => F_Ext_Error(e),
35-
Ext_FetchAddr_OK(use_pc_hi) =>
36-
match translateAddr(use_pc_hi, InstructionFetch()) {
37-
Err(e, _) => F_Error(e, PC),
38-
Ok(_, _) => F_Base(i)
39-
}
40-
}
41-
}
42-
}
43-
}
44-
}
17+
Some(e) => return F_Ext_Error(e),
18+
None() => (),
19+
};
20+
21+
/* Then check PC alignment */
22+
if (PC[0] != bitzero | (PC[1] != bitzero & not(currentlyEnabled(Ext_Zca))))
23+
then return F_Error(E_Fetch_Addr_Align(), PC);
24+
25+
match translateAddr(Virtaddr(PC), InstructionFetch()) {
26+
Err(e, _) => return F_Error(e, PC),
27+
Ok(_, _) => (),
28+
};
29+
30+
let i = rvfi_instruction[rvfi_insn];
31+
rvfi_inst_data[rvfi_insn] = zero_extend(i);
32+
if (i[1 .. 0] != 0b11)
33+
then return F_RVC(i[15 .. 0]);
34+
35+
/* fetch PC check for the next instruction granule */
36+
let PC_hi = PC + 2;
37+
match ext_fetch_check_pc(PC, PC_hi) {
38+
Some(e) => return F_Ext_Error(e),
39+
None() => (),
40+
};
41+
42+
match translateAddr(Virtaddr(PC_hi), InstructionFetch()) {
43+
Err(e, _) => F_Error(e, PC),
44+
Ok(_, _) => F_Base(i)
4545
}
4646
}

0 commit comments

Comments
 (0)