From 3201b410776d78f502ea076090618516b7240c57 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Mon, 25 Nov 2024 13:19:06 +0100 Subject: [PATCH] Add doc about privileges --- source/VexiiRiscv/Execute/plugins.rst | 50 ++------- source/VexiiRiscv/Memory/index.rst | 8 +- source/VexiiRiscv/Privileges/index.rst | 118 +++++++++++++++++++++ source/asset/miaou.drawio | 141 ++++++++++++++++--------- source/asset/picture/privileges.png | Bin 0 -> 27625 bytes source/conf.py | 3 + source/index.rst | 1 + 7 files changed, 223 insertions(+), 98 deletions(-) create mode 100644 source/VexiiRiscv/Privileges/index.rst create mode 100644 source/asset/picture/privileges.png diff --git a/source/VexiiRiscv/Execute/plugins.rst b/source/VexiiRiscv/Execute/plugins.rst index 3052ac7..452a868 100644 --- a/source/VexiiRiscv/Execute/plugins.rst +++ b/source/VexiiRiscv/Execute/plugins.rst @@ -125,53 +125,17 @@ Implement load / store through a l1 cache. More information in the :ref:`lsu` chapter - -Special -------- - -Some implement CSR, privileges and special instructions - CsrAccessPlugin ^^^^^^^^^^^^^^^ -- Implement the CSR read and write instruction -- Provide an API for other plugins to specify its hardware mapping - -CsrRamPlugin -^^^^^^^^^^^^ +- Implement the CSR read and write instruction in the execute pipeline +- Provide an API for other plugins to specify the mapping between the CSR registers and the CSR instruction -- Implement a shared on chip ram -- Provide an API which allows to statically allocate space on it -- Provide an API to create read / write ports on it -- Used by various plugins to store the CSR contents in a FPGA efficient way - -PrivilegedPlugin -^^^^^^^^^^^^^^^^ - -- Implement the RISC-V privileged spec -- Use the CsrRamPlugin to implement various CSR as MTVAL, MTVEC, MEPC, MSCRATCH, ... - -TrapPlugin -^^^^^^^^^^^ - -- Implement the trap buffer / FSM -- The FSM implement the core logic of many special instructions (MRET, SRET, ECALL, EBREAK, FENCE.I, WFI, ...) -- Also allows the CPU pipeline to emit hardware traps to re-execute (REDO) the current instruction - or to jump to the next one after a full pipeline flush (NEXT). -- the REDO hardware trap is used by I$ D$ miss, the DecodePlugin when it detect a illegal branch prediction -- the NEXT hardware trap is used by the CsrAccessPlugin when a state change require a full CPU flush - -PerformanceCounterPlugin -^^^^^^^^^^^^^^^^^^^^^^^^ - -Implement the privileged performance counters in a FPGA friendly way : - -- Use the CsrRamPlugin to store 57 bits for each performance counter -- Use a dedicated 7 bits hardware register per counter -- Once that 7 bits register MSB is set, a FSM will flush it into the CsrRamPlugin +See the :ref:`privileges` chapter for more informations. EnvPlugin -^^^^^^^^^ +^^^^^^^^^^^^^^^ + +See the :ref:`privileges` chapter for more informations. -- Implement a few instructions as MRET, SRET, ECALL, EBREAK, FENCE.I, WFI by producing hardware traps -- Those hardware trap are then handled in the TrapPlugin FSM +- Implement a few instructions as MRET, SRET, ECALL, EBREAK, FENCE.I, WFI by producing hardware traps \ No newline at end of file diff --git a/source/VexiiRiscv/Memory/index.rst b/source/VexiiRiscv/Memory/index.rst index 2dc9fc1..06f7052 100644 --- a/source/VexiiRiscv/Memory/index.rst +++ b/source/VexiiRiscv/Memory/index.rst @@ -177,11 +177,11 @@ Without it, the CPU software would have to manualy flush/invalidate their L1 cac There is mostly 2 kinds of hardware memory coherency architecture : - By invalidation : When a CPU/DMA write some memory, it notifies the other CPU caches that they should invalidate any -old copy that they have of the written memory locations. This is generaly used for write-through L1 caches. -This isn't what VexiiRiscv implements. + old copy that they have of the written memory locations. This is generaly used for write-through L1 caches. + This isn't what VexiiRiscv implements. - By permition : Memory blocks copies (typicaly 64 aligned bytes blocks which resides in L1 cache lines) can have multiple states. -Some of which provide read only accesses, while others provide read/write accesses. This is generaly used in write-back L1 caches, -and this is what VexiiRiscv uses. + Some of which provide read only accesses, while others provide read/write accesses. This is generaly used in write-back L1 caches, + and this is what VexiiRiscv uses. In VexiiRiscv, the hardware memory coherency (L1) with other memory agents (CPU, DMA, L2, ..) is supported though a MESI implementation which can be bridged to a tilelink memory bus. diff --git a/source/VexiiRiscv/Privileges/index.rst b/source/VexiiRiscv/Privileges/index.rst new file mode 100644 index 0000000..e149c76 --- /dev/null +++ b/source/VexiiRiscv/Privileges/index.rst @@ -0,0 +1,118 @@ +.. _privileges: + +Privileges +################### + +RISC-V specifies in "Volume 2, Privileged Specification" most of its special registers (CSR) which allows to handle things as : + +- Traps (interrupts + exceptions) +- Memory protections (MMU, PMP) +- Privilege modes (Machine, Superivisor, User) + +A microcontroller will typicaly only need Machine mode, maybe User mode, while a Linux capable CPU will normaly need them all. + +- Machine mode : Baremetal / Bootloader / BIOS / OpenSBI / RTOS +- Supervisor mode : Kernel / Linux +- User mode : Applications running on the top of linux + +Those are handled in VexiiRiscv via a sets of plugins. + +.. image:: /asset/picture/privileges.png + +CsrAccessPlugin +^^^^^^^^^^^^^^^ + +- Implement the CSR read and write instruction in the execute pipeline +- Provide an API for other plugins to specify the mapping between the CSR registers and the CSR instruction + +For instance, when another plugin want to add a custom CSR, it can do as follow : + +.. code-block:: scala + + class CustomPlugin() extends FiberPlugin { + val logic = during setup new Area{ + val cp = host[CsrService] // CsrAccessPlugin is an implementation of CsrService + val buildBefore = retains(cp.csrLock) // This ensure that the CsrService hold one until we are finished with the API usages + awaitBuild() + + // Define a few registers + val regX = Reg(UInt(8 bits)) init(0) + val regY = Reg(UInt(8 bits)) init(0) + + // Map those registers in the RISC-V CSRs at address 0xFF0. + // - Bits 17:10 will be regX + // - Bits 27:20 will be regY + cp.readWrite(0xFF0, 10 -> regX, 20 -> regY) + + // Now that we are with the csr API, we allows it to elaborate + buildBefore.release() + } + } + +PrivilegedPlugin +---------------- + +- Implement the RISC-V privileged spec, mostly by using the CsrAccessPlugin API +- Use the CsrRamPlugin to implement various CSR as MTVAL, MTVEC, MEPC, MSCRATCH, ... +- By default only the machine mode is enabled. +- You can use `--with-supervisor` and --with-user` to enable the corresponding privileged modes + +CsrRamPlugin +------------ + +- Provide an API which allows to statically allocate space on it +- Provide an API to create read / write ports on it +- Used by various plugins to store the CSR contents in a FPGA efficient way + + +TrapPlugin +----------- + +- Implement the trap buffer / FSM +- The FSM implement the core logic of many special instructions (MRET, SRET, ECALL, EBREAK, FENCE.I, WFI, ...) +- Also allows the CPU pipeline to emit hardware traps to re-execute (REDO) the current instruction + or to jump to the next one after a full pipeline flush (NEXT). +- the REDO hardware trap is used by I$ D$ miss, the DecodePlugin when it detect a illegal branch prediction +- the NEXT hardware trap is used by the CsrAccessPlugin when a state change require a full CPU flush + +PerformanceCounterPlugin +------------------------ + +Implement the privileged performance counters in a FPGA friendly way : + +- Use the CsrRamPlugin to store 57 bits for each performance counter +- Use a dedicated 7 bits hardware register per counter +- Once that 7 bits register MSB is set, a FSM will flush it into the CsrRamPlugin +- By default, this plugins is disabled, to enable it, you can use, for instance, `--performance-counters 9` + +EnvPlugin +--------- + +- Implement a few instructions as MRET, SRET, ECALL, EBREAK, FENCE.I, WFI by producing hardware traps +- Those hardware trap are then handled in the TrapPlugin FSM + +MmuPlugin +--------- + +- Implements supervisor mode memory protections +- Include a hardware page walker +- Has a TLB to store the page walker results +- TLB are stored in multiples directly mapped memories. Typicaly 2 way x 32 TLB for 4KB pages + 1 way x 32 TLB for mega pages +- Map very well with FPGA which supports asyncronous read memory (LUT based RAM) +- Can be configured to work with syncronous read memory (block ram), but will likely be your critical path for timings + +This plugin is enabled via `--with-mmu` or `--with-supervisor` + +PmpPlugin +---------- + +- Allows the machine mode to restrict memory accesses of the supervisor/user mode to specific ranges (Physical Memory Protection) +- Quite expensive in resources and timings. +- Support NAPOT (aligned power of 2 sized regions) +- Support TOR (unrestricted region address/size) +- You can disable the RISC-V TOR support to help with area and timings +- You can set the granularity of the memory regions (to improve timings and area usage). This throw away some of the address LSB bits. + By default, the granularity is 4KB (--pmp-granularity=4096). Minimum allowed is 4. +- By default, the PmpPlugin is disabled, but you can enable it via, for instance, `--pmp-size=4`, + which will enable 4 hardware PMP registres, allowing you to set up to 4 memory regions. + diff --git a/source/asset/miaou.drawio b/source/asset/miaou.drawio index ac8a9c8..f409c1c 100644 --- a/source/asset/miaou.drawio +++ b/source/asset/miaou.drawio @@ -1,6 +1,6 @@ - + - + @@ -3284,7 +3284,7 @@ - + @@ -3609,222 +3609,261 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/asset/picture/privileges.png b/source/asset/picture/privileges.png new file mode 100644 index 0000000000000000000000000000000000000000..0dd3abaacc9ada5790b0f11b370306106cfea110 GIT binary patch literal 27625 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 literal 0 HcmV?d00001 diff --git a/source/conf.py b/source/conf.py index 8cf23d0..eba5c96 100644 --- a/source/conf.py +++ b/source/conf.py @@ -236,6 +236,9 @@ # Whitelist pattern for tags (set to None to ignore all tags) smv_tag_whitelist = r'^.*$' +smartquotes = False +html_use_smartypants = False + # The branch called "latest" is not a real branch/tag, it is aliased by the document # build process to the most recent stable release. # Whitelist pattern for branches (set to None to ignore all branches) diff --git a/source/index.rst b/source/index.rst index f949a11..35c6592 100644 --- a/source/index.rst +++ b/source/index.rst @@ -14,6 +14,7 @@ Welcome to VexiiRiscv's documentation! VexiiRiscv/Execute/index VexiiRiscv/BranchPrediction/index VexiiRiscv/Memory/index + VexiiRiscv/Privileges/index VexiiRiscv/Debug/index VexiiRiscv/HowToUse/index VexiiRiscv/Performance/index