Skip to content

Commit

Permalink
New: Implement U-mode RTL
Browse files Browse the repository at this point in the history
  • Loading branch information
dpretet committed Sep 12, 2023
1 parent 90cc3e1 commit 217290d
Show file tree
Hide file tree
Showing 42 changed files with 5,843 additions and 65 deletions.
26 changes: 16 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,24 @@

FRISCV is a SystemVerilog implementation of the [RISCV ISA](https://riscv.org):

- Support RV32I & RV32E architecture
- Support Zifencei
- Support Zicsr
- Support Zicntr
- Support Zihpm
- Support M extension (multiply/divide)
- Machine-mode only
- Implement a 3-stage pipeline
- Support global and software interrupts
- Clint extension
- Built around a 3-stage pipeline
- In-order execution
- AXI4-lite for instruction and data bus
- Instruction & data cache units
- Privilege modes:
- Machine-mode only for simple embedded system
- User-mode for secure embedded system
- Physical memory protection (PMP)
- Physical memory attribute (PMA)
- External, software and timer interrupts
- Support multiple (optional) extensions:
- RV32I & RV32E architecture
- Zifencei
- Zicsr
- Zicntr
- Zihpm
- M extension (multiply/divide)
- Clint extension

The core is [compliant](./test/riscv-tests/README.md) with the official RISCV
testsuite.
Expand Down Expand Up @@ -62,6 +67,7 @@ More details of the architecture can be found in the:

The core is verified with several testsuites, present in [test](./test) folder:
- [White-Box Assembler testsuite](./test/wba_testsuite/README.md)
- [Privilege / Security testsuite](./test/priv_sec_testsuite/README.md)
- [RISCV Compliance testsuite](./test/riscv-tests/README.md)
- [C testsuite](./test/c_testsuite/README.md)
- [Apps testsuite](./test/apps/README.md)
Expand Down
66 changes: 35 additions & 31 deletions doc/privilege.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
# Privilege Modes Support

## Overview

FRISCV supports machine mode as default mode. it's always implemented as required by the
specification. The core can also support user, supervisor and hypervisor modes, activable
specification. The core can also support user, supervisor and hypervisor modes, activable
all by paramters, `USER_MODE`, `SUPERVISOR_MODE`, `HYPERVISOR_MODE`.

All modes use the same `XLEN` width. If `XLEN` = 32 bits, `MXLEN`, `SXLEN`, `UXLEN` and
All modes use the same `XLEN` width. If `XLEN` = 32 bits, `MXLEN`, `SXLEN`, `UXLEN` and
`HXLEN` will be setup to 32 bits.

The software navigates through the privilege levels with ECALL / xRET instructions

```
┌────────────────────────────────┐
│ MACHINE │
└────────────────────────────────┘
│ ▲
MRET │ │ ECALL
▼ │
┌────────────────────────────────┐
│ SUPERVISOR │
└────────────────────────────────┘
│ ▲
SRET │ │ ECALL
▼ │
┌────────────────────────────────┐
│ USER │
└────────────────────────────────┘
┌────────────────────────────────┐
│ MACHINE │
└────────────────────────────────┘
│ ▲
MRET │ │ ECALL
▼ │
┌────────────────────────────────┐
│ SUPERVISOR │
└────────────────────────────────┘
│ ▲
SRET │ │ ECALL
▼ │
┌────────────────────────────────┐
│ USER │
└────────────────────────────────┘
```

CSR registers address encodes inner attributes:

```
11/10 9/8 7/4 3/0
11/10 9/8 7/4 3/0
┌───────┬───────────┬───────────┬───────────┐
│ R/W │ Privilege │ Use │ Address │
└───────┴───────────┴───────────┴───────────┘
Expand All @@ -46,25 +48,19 @@ Bits [9:8]:
- `10`: Hypervisor
- `11`: Machine

The privilege modes support have been designed based on RISC-V ISA specification version 20211203

# TODO

Plan:
- 1. user mode + PMP
- 2. supervisor mode + virtual memory support
- 3. hypervisor mode
- 4. debug mode

1. User mode
# User Mode

- Implement MSTATUS based on latest spec
- Support U-mode:
- Support U-mode:
- Previous privilege mode interrupt is stored in xPP to support nested trap
- Ecall move to M-mode
- Mret move to U-mode
- Support exceptions
- M-mode instructions executed in U-mode must raise an illegal instruction exception
- Access to M-mode only registers must raise an illegal instruction exception
- ecall code when coming from U-mode in mcause
- Support PMP (Physical Memory Protection)
- Instruction read or data R/W access are checked against PMP to secure the hart
- Address is checked with CSRs pmpcfg
Expand All @@ -73,12 +69,16 @@ Plan:
- PMP checks are applied to all accesses whose effective privilege mode is S or U, including
instruction fetches and data accesses in S and U mode, and data accesses in M-mode when the
MPRV bit in mstatus is set and the MPP field in mstatus contains S or U (page 56)
- Study PMA (section 3.6)
- Study PMA (Physical Memory Attribute) (section 3.6)
- Replace existing IO_MAP by PMP & PMA
- Support cycle registers per mode


## Supervisor

2. Supervisor
- Support interrupts
- disable them for lower mode. If is SUPERVISOR, USER interrupts are disabled
- interrupts for higher mode are enabled, whatever xIE bit. If is SUPERVISOR,
- interrupts for higher mode are enabled, whatever xIE bit. If is SUPERVISOR,
HYPERVISOR interrupt are enabled
- previous privilege mode interrupt is stored in xPP to support nested trap
- medeleg & mideleg: delegate an trap to a mode means this mode can handle it. Traps never
Expand All @@ -88,3 +88,7 @@ Plan:
- Support priv mode in cache stages
- Support TW (section 3.1.6.5)
- V & F extensions support: XS, FS, VS fields

## Hypervisor

To be documented
10 changes: 7 additions & 3 deletions doc/project_mgt_hw.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# DOING

- [ ] Support U-mode
- [ ] Support PMP
- [ ] Support PMA


# BACKLOG
Expand Down Expand Up @@ -40,13 +43,13 @@ Cache Stages
Misc.

- [ ] Create a HW test platform
- [ ] Cloud
- [ ] Analogue pocket
- [C] Cloud
- [ ] Add registers to configure the core in platform
- [ ] Support completly a profile
- [ ] 64 bits support
- [ ] Atomic operations for single core
- [ ] Support privileged instructions, supervisor mode & user mode
- [ ] Support privileged instructions & supervisor mode
- voir les CSRs dans la privileged mode, implementer les compteurs par mode
- https://danielmangum.com/posts/risc-v-bytes-privilege-levels/
- https://mobile.twitter.com/hasheddan/status/1514581031092899843?s=12&t=MMNTY_iRC48CjykLQBdTkQ
Expand All @@ -66,9 +69,10 @@ Misc.
- [ ] Multi-core platform:
- [ ] Counters and timers should be reworked
- [ ] Nb core configurable
- [ ] Support PLIC
- [ ] PLIC controller
- [ ] Extended atomic operation support
- [ ] Implement a L2 cache stage
- [ ] Deactivate the core with WFI (clock gating)


AXI4 Infrastructure
Expand Down
51 changes: 42 additions & 9 deletions rtl/friscv_control.sv
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ module friscv_control
parameter XLEN = 32,
// Reduced RV32 arch
parameter RV32E = 0,
// Support hypervisor mode
parameter HYPERVISOR_MODE = 0,
// Support supervisor mode
parameter SUPERVISOR_MODE = 0,
// Support user mode
parameter USER_MODE = 0,
// Address bus width defined for both control and AXI4 address signals
parameter AXI_ADDR_W = ILEN,
// AXI ID width, setup by default to 8 and unused
Expand Down Expand Up @@ -193,11 +199,13 @@ module friscv_control
logic [XLEN -1:0] mtval_info;
logic load_misaligned;
logic store_misaligned;
logic illegal_instruction;
logic wfi_not_allowed;
logic trap_occuring;
logic sync_trap_occuring;
logic async_trap_occuring;

logic ecall_umode;
logic ecall_mmode;
logic [2 -1:0] priv_mode;

// Logger setup
Expand Down Expand Up @@ -524,7 +532,6 @@ module friscv_control

assign pc_val = pc_reg;

assign priv_mode = `MMODE;

assign flush_reqs = flush_pipe;

Expand All @@ -541,6 +548,7 @@ module friscv_control
arid <= {AXI_ID_W{1'b0}};
flush_blocks <= 1'b0;
flush_pipe <= 1'b0;
priv_mode <= `MMODE;
end else if (srst == 1'b1) begin
cfsm <= BOOT;
arvalid <= 1'b0;
Expand All @@ -552,6 +560,7 @@ module friscv_control
arid <= {AXI_ID_W{1'b0}};
flush_blocks <= 1'b0;
flush_pipe <= 1'b0;
priv_mode <= `MMODE;
end else begin

case (cfsm)
Expand All @@ -561,6 +570,7 @@ module friscv_control
///////////////////////////////////////////////////////////////
default: begin

priv_mode <= `MMODE;
arid <= AXI_ID_MASK;
araddr <= BOOT_ADDR;
pc_reg <= BOOT_ADDR;
Expand Down Expand Up @@ -699,6 +709,7 @@ module friscv_control
status[0] <= 1'b1;
flush_pipe <= 1'b1;
pc_reg <= mtvec;
if (USER_MODE) priv_mode <= `MMODE;

// Reach an EBREAK instruction, need to stall the core
end else if (sys[`IS_EBREAK]) begin
Expand All @@ -719,6 +730,7 @@ module friscv_control
status[2] <= 1'b1;
flush_pipe <= 1'b1;
pc_reg <= sb_mepc;
if (USER_MODE) priv_mode <= `UMODE;

// Reach a FENCE.i instruction, need to flush the cache
// the instruction pipeline
Expand Down Expand Up @@ -1074,6 +1086,24 @@ module friscv_control
assign load_misaligned = proc_exceptions[`LD_MA];
assign store_misaligned = proc_exceptions[`ST_MA];

assign inst_dec_error = dec_error & (cfsm==FETCH) & inst_ready;

generate
if (USER_MODE) begin: UMODE_EXPEC
assign illegal_instruction = (priv_mode==`MMODE) ? '0 :
(sys[`IS_MRET]) ? inst_ready :
(sys[`IS_CSR] && csr[9:8] != 2'b00) ? inst_ready :
// Check if WFI must be trapped or not
(sys[`IS_WFI] ) ? inst_ready :
'0;
end else begin : NO_UMODE
assign illegal_instruction = '0;
end
endgenerate

assign ecall_umode = (sys[`ECALL] && priv_mode==`UMODE);
assign ecall_mmode = (sys[`ECALL] && priv_mode==`MMODE);

///////////////////////////////////////////////////////////////////////////
//
// Asynchronous exceptions code:
Expand Down Expand Up @@ -1108,12 +1138,11 @@ module friscv_control
// Highest | 3 | Instruction address breakpoint
// ------------------------------------------------------------------------
// | 12 | Instruction page fault
// ------------------------------------------------------------------------
// | 1 | Instruction access fault
// ------------------------------------------------------------------------
// | 2 | Illegal instruction
// | 0 | Instruction address misaligned
// | 8,9,11 | Environment call (U/S/M modes)
// | 8,9,11 | Environment call from U/S/M modes
// | 3 | Environment break
// | 3 | Load/Store/AMO address breakpoint
// ------------------------------------------------------------------------
Expand All @@ -1135,10 +1164,12 @@ module friscv_control
(csr_sb[`MTIP]) ? {1'b1, {XLEN-5{1'b0}}, 4'h7} :
(csr_sb[`MEIP]) ? {1'b1, {XLEN-5{1'b0}}, 4'hB} :
// then follow sync exceptions
(inst_addr_misaligned) ? {XLEN{1'b0}} :
(csr_ro_wr) ? {{XLEN-4{1'b0}}, 4'h1} :
(illegal_instruction) ? {{XLEN-4{1'b0}}, 4'h2} :
(csr_ro_wr) ? {{XLEN-4{1'b0}}, 4'h2} :
(inst_dec_error) ? {{XLEN-4{1'b0}}, 4'h2} :
(sys[`IS_ECALL]) ? {{XLEN-4{1'b0}}, 4'hB} :
(inst_addr_misaligned) ? {XLEN{1'b0}} :
(ecall_umode) ? {{XLEN-4{1'b0}}, 4'h8} :
(ecall_mmode) ? {{XLEN-4{1'b0}}, 4'hB} :
(sys[`IS_EBREAK]) ? {{XLEN-4{1'b0}}, 4'h3} :
(store_misaligned) ? {{XLEN-4{1'b0}}, 4'h6} :
(load_misaligned) ? {{XLEN-4{1'b0}}, 4'h4} :
Expand All @@ -1147,6 +1178,8 @@ module friscv_control
// MTVAL: exception-specific information
assign mtval_info = (inst_dec_error) ? instruction :
(wfi_not_allowed) ? instruction :
(illegal_instruction) ? instruction :
(csr_ro_wr) ? instruction :
(inst_addr_misaligned) ? pc_reg :
(sys[`IS_ECALL]) ? pc_reg :
(sys[`IS_EBREAK]) ? pc_reg :
Expand All @@ -1161,13 +1194,13 @@ module friscv_control
assign sync_trap_occuring = csr_ro_wr |
inst_addr_misaligned |
load_misaligned |
// wfi_not_allowed |
// illegal_instruction |
store_misaligned |
inst_dec_error ;

assign trap_occuring = async_trap_occuring | sync_trap_occuring;

assign inst_dec_error = dec_error & (cfsm==FETCH) & inst_ready;

endmodule

`resetall
7 changes: 6 additions & 1 deletion rtl/friscv_csr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ module friscv_csr
logic sw_irq_sync;


///////////////////////////////////////////////////////////////////////////
// Build mstatus content
// @data: the new value to write into the CSR
// @returns the formatted register based on spec and extension supported
///////////////////////////////////////////////////////////////////////////
function automatic logic [XLEN-1:0] get_mstatus (
input logic [XLEN-1:0] data
);
Expand Down Expand Up @@ -274,7 +279,7 @@ module friscv_csr
logic [XLEN-1:0] mtval; // 0x343 MRW
logic [XLEN-1:0] mip; // 0x344 MRW

// Machine Memory Protection
// Physical Memory Protection (PMP)
// logic [XLEN-1:0] pmpcfg0; // 0x3A0 MRW (not implemented)
// logic [XLEN-1:0] pmpcfg1; // 0x3A1 MRW (not implemented)
// logic [XLEN-1:0] pmpcfg2; // 0x3A2 MRW (not implemented)
Expand Down
Loading

0 comments on commit 217290d

Please sign in to comment.