Skip to content

Commit

Permalink
🔒 restrict access to IO modules to privileged (machine-mode) software (…
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting authored Jul 21, 2024
2 parents 3ada741 + 88fea03 commit 9f21272
Show file tree
Hide file tree
Showing 31 changed files with 152 additions and 83 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 21.07.2024 | 1.10.1.8 | :lock: restrict IO access to privileged (machine-mode) software | [#958](https://github.com/stnolting/neorv32/pull/958) |
| 20.07.2024 | 1.10.1.7 | :bug: fix bug in `sbrk` newlib system call (causing `malloc` to provide infinite memory until heap and stack collide) | [#957](https://github.com/stnolting/neorv32/pull/957) |
| 20.07.2024 | 1.10.1.6 | SDI: remove explicit "RX clear flag"; add new flag to check the current state of the chip-select input | [#955](https://github.com/stnolting/neorv32/pull/955) |
| 19.07.2024 | 1.10.1.5 | :sparkles: add "programmable" chip-select enable/disable functionality to SPI module | [#954](https://github.com/stnolting/neorv32/pull/954) |
Expand Down
29 changes: 20 additions & 9 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ table (the channel number also corresponds to the according FIRQ priority: 0 = h
As a 32-bit architecture the NEORV32 can access a 4GB physical address space. By default, this address space is
split into six main regions. Each region provides specific _physical memory attributes_ ("PMAs") that define
the access capabilities (`rwxac`; `r` = read permission, `w` = write permission, `x` - execute permission,
`a` = atomic access support, `c` = cached CPU access).
`a` = atomic access support, `c` = cached CPU access, `p` = privileged access only).

.NEORV32 Processor Address Space (Default Configuration)
image::address_space.png[900]
Expand All @@ -475,17 +475,23 @@ raise a bus error exception.
[options="header",grid="rows"]
|=======================
| # | Region | PMAs | Description
| 1 | Internal IMEM address space | `rwxac` | For instructions (=code) and constants; mapped to the internal <<_instruction_memory_imem>>.
| 2 | Internal DMEM address space | `rwxac` | For application runtime data (heap, stack, etc.); mapped to the internal <<_data_memory_dmem>>).
| 3 | Memory-mapped XIP flash | `r-xac` | Memory-mapped access to the <<_execute_in_place_module_xip>> SPI flash.
| 4 | Bootloader address space | `r-xa-` | Read-only memory for the internal <<_bootloader_rom_bootrom>> containing the default <<_bootloader>>.
| 5 | IO/peripheral address space | `rwxa-` | Processor-internal peripherals / IO devices.
| 6 | The "**void**" | `rwxac` | Unmapped address space. All accesses to this region(s) are redirected to the <<_processor_external_bus_interface_xbus>> (if implemented).
| 1 | Internal IMEM address space | `rwxac-` | For instructions (=code) and constants; mapped to the internal <<_instruction_memory_imem>>.
| 2 | Internal DMEM address space | `rwxac-` | For application runtime data (heap, stack, etc.); mapped to the internal <<_data_memory_dmem>>).
| 3 | Memory-mapped XIP flash | `r-xac-` | Memory-mapped access to the <<_execute_in_place_module_xip>> SPI flash.
| 4 | Bootloader address space | `r-xa-p` | Read-only memory for the internal <<_bootloader_rom_bootrom>> containing the default <<_bootloader>>.
| 5 | IO/peripheral address space | `rwxa-p` | Processor-internal peripherals / IO devices.
| 6 | The "**void**" | `rwxac-` | Unmapped address space. All accesses to this region(s) are redirected to the <<_processor_external_bus_interface_xbus>> (if implemented).
|=======================

.Privileged IO and BOOTROM Access Only
[IMPORTANT]
Only privileged accesses (M-mode) to the IO/peripheral and bootloader address spaces are allowed.
If an unprivileged application tries to access this address space a bus access error exception is raised.

.Custom PMAs
[NOTE]
Physical memory attributes can be customized (constrained) using the CPU's <<_smpmp_isa_extension>>.
[TIP]
Custom physical memory attributes enforced by the CPU's _physcial memory protection_ (<<_smpmp_isa_extension>>)
can be used to further constrain the physical memory attributes.


:sectnums:
Expand Down Expand Up @@ -689,6 +695,11 @@ providing an initialized external memory that contains the actual application to
:sectnums:
=== Processor-Internal Modules

.Privileged IO Access Only
[IMPORTANT]
Only privileged accesses (M-mode) to the IO/peripheral modules are allowed. If an unprivileged application
tries to access this address space a bus access error exception is raised.

.Full-Word Write Accesses Only
[NOTE]
All peripheral/IO devices should only be written in full-word mode (i.e. 32-bit). Byte or half-word (8/16-bit) write accesses
Expand Down
12 changes: 8 additions & 4 deletions docs/datasheet/soc_bootrom.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files: | neorv32_boot_rom.vhd |
| Software driver files: | none |
| Top entity ports: | none |
| Hardware source files: | neorv32_boot_rom.vhd |
| Software driver files: | none |
| Top entity ports: | none |
| Configuration generics: | `INT_BOOTLOADER_EN` | implement processor-internal bootloader when `true`
| CPU interrupts: | none |
| CPU interrupts: | none |
| Access restrictions: 2+| privileged access only, read-only
|=======================


**Overview**

This boot ROM module provides a read-only memory that contain the executable image of the default NEORV32
<<_bootloader>>. If the internal bootloader is enabled via the `INT_BOOTLOADER_EN` generic the CPU's boot address
is automatically set to the beginning of the bootloader ROM. See sections <<_address_space>> and
Expand Down
5 changes: 3 additions & 2 deletions docs/datasheet/soc_cfs.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files: | neorv32_cfs.vhd |
| Hardware source files: | neorv32_cfs.vhd |
| Software driver files: | neorv32_cfs.c |
| | neorv32_cfs.h |
| Top entity ports: | `cfs_in_i` | custom input conduit
Expand All @@ -15,10 +15,11 @@
| | `IO_CFS_IN_SIZE` | size of `cfs_in_i`
| | `IO_CFS_OUT_SIZE` | size of `cfs_out_o`
| CPU interrupts: | fast IRQ channel 1 | CFS interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


**Theory of Operation**
**Overview**

The custom functions subsystem is meant for implementing custom tightly-coupled co-processors or interfaces.
IT provides up to 64 32-bit memory-mapped read/write registers (`REG`, see register map below) that can be
Expand Down
5 changes: 3 additions & 2 deletions docs/datasheet/soc_crc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
| | neorv32_crc.h |
| Top entity ports: | none |
| Configuration generics: | `IO_CRC_EN` | implement CRC module when `true`
| CPU interrupts: | none |
| CPU interrupts: | none |
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand All @@ -20,7 +21,7 @@ The cyclic redundancy check unit provides a programmable checksum computation mo
single bytes and can either compute CRC8, CRC16 or CRC32 checksums based on an arbitrary polynomial and
start value.

.DMA Demo Program
.CRC Demo Program
[TIP]
A CRC example program (also using CPU-independent DMA transfers) can be found in `sw/example/crc_dma`.

Expand Down
4 changes: 4 additions & 0 deletions docs/datasheet/soc_dcache.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
| | `DCACHE_NUM_BLOCKS` | number of cache blocks (pages/lines)
| | `DCACHE_BLOCK_SIZE` | size of a cache block in bytes
| CPU interrupts: | none |
| Access restrictions: 2+| none
|=======================


**Overview**

The processor features an optional data cache to improve performance when using memories with high
access latencies. The cache is connected directly to the CPU's data access interface and provides
full-transparent accesses. The cache is direct-mapped and uses "write-allocate" and "write-back" strategies.
Expand Down
3 changes: 2 additions & 1 deletion docs/datasheet/soc_dma.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
| Top entity ports: | none |
| Configuration generics: | `IO_DMA_EN` | implement DMA when `true`
| CPU interrupts: | fast IRQ channel 10 | DMA transfer done (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down Expand Up @@ -61,7 +62,7 @@ automatically cleared when writing the `CTRL` register.
.DMA Access Privilege Level
[WARNING]
Transactions performed by the DMA are executed as bus transactions with elevated **machine-mode** privilege level.
Additionally, all physical memory protection rules (<<_smpmp_isa_extension>>) defined by the CPU are **bypassed**.
Note that any physical memory protection rules (<<_smpmp_isa_extension>>) are not applied to DMA transfers.


**Transfer Configuration**
Expand Down
8 changes: 6 additions & 2 deletions docs/datasheet/soc_dmem.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
| | mem/neorv32_dmem.default.vhd | default _platform-agnostic_ memory architecture
| | mem/neorv32_dmem.legacy.vhd | alternative legacy-style memory architecture
| Software driver files: | none | _implicitly used_
| Top entity ports: | none |
| Top entity ports: | none |
| Configuration generics: | `MEM_INT_DMEM_EN` | implement processor-internal DMEM when `true`
| | `MEM_INT_DMEM_SIZE` | DMEM size in bytes (use a power of 2)
| CPU interrupts: | none |
| CPU interrupts: | none |
| Access restrictions: 2+| none
|=======================


**Overview**

Implementation of the processor-internal data memory is enabled by the processor's `MEM_INT_DMEM_EN`
generic. The total memory size in bytes is defined via the `MEM_INT_DMEM_SIZE` generic. Note that this
size should be a power of two to optimize physical implementation. If the DMEM is implemented,
Expand Down
4 changes: 4 additions & 0 deletions docs/datasheet/soc_gpio.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
| | `gpio_i` | 64-bit parallel input port
| Configuration generics: | `IO_GPIO_NUM` | number of input/output pairs to implement (0..64)
| CPU interrupts: | none |
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


**Overview**

The general purpose parallel IO unit provides a simple parallel input and output port. These ports can be used
chip-externally (for example to drive status LEDs, connect buttons, etc.) or chip-internally to provide control
signals for other IP modules.
Expand Down
3 changes: 2 additions & 1 deletion docs/datasheet/soc_gptmr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
| Top entity ports: | none |
| Configuration generics: | `IO_GPTMR_EN` | implement general purpose timer when `true`
| CPU interrupts: | fast IRQ channel 12 | timer interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


**Overview**

The general purpose timer module implements a simple yet universal 32-bit timer. It is implemented if the processor's
`IO_GPTMR_EN` top generic is set `true`. The timer provides a pre-scaled counter register that can trigger an interrupt
when reaching a programmable threshold value.l.
when reaching a programmable threshold value.

The GPTMR provides three interface registers : a control register (`CTRL`), a 32-bit counter register (`COUNT`) and a
32-bit threshold register (`THRES`). The timer is globally enabled by setting the `GPTMR_CTRL_EN` bit in the module's
Expand Down
4 changes: 4 additions & 0 deletions docs/datasheet/soc_icache.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
| | `ICACHE_NUM_BLOCKS` | number of cache blocks (pages/lines)
| | `ICACHE_BLOCK_SIZE` | size of a cache block in bytes
| CPU interrupts: | none |
| Access restrictions: 2+| none
|=======================


**Overview**

The processor features an optional instruction cache to improve performance when using memories with high
access latencies. The cache is connected directly to the CPU's instruction fetch interface and provides
full-transparent accesses. The cache is direct-mapped and read-only.
Expand Down
4 changes: 4 additions & 0 deletions docs/datasheet/soc_imem.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
| | `MEM_INT_IMEM_SIZE` | IMEM size in bytes (use a power of 2)
| | `INT_BOOTLOADER_EN` | use internal bootloader when `true` (implements IMEM as _uninitialized_ RAM, otherwise the IMEM is implemented an _pre-intialized_ ROM)
| CPU interrupts: | none |
| Access restrictions: 2+| none / read-only if `INT_BOOTLOADER_EN = true`
|=======================


**Overview**

Implementation of the processor-internal instruction memory is enabled by the processor's
`MEM_INT_IMEM_EN` generic. The total memory size in bytes is defined via the `MEM_INT_IMEM_SIZE` generic.
Note that this size should be a power of two to optimize physical implementation. If the IMEM is implemented,
Expand Down
9 changes: 7 additions & 2 deletions docs/datasheet/soc_mtime.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@
| | `mtime_time_o` | Current system time (`TIME` register)
| Configuration generics: | `IO_MTIME_EN` | implement machine timer when `true`
| CPU interrupts: | `MTI` | machine timer interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


**Overview**

The MTIME module implements a memory-mapped machine system timer that is compatible to the RISC-V
privileged specifications. The 64-bit system time is accessed via individual `TIME_LO` and
`TIME_HI` registers. A 64-bit time compare register, which is accessible via individual `TIMECMP_LO`
and `TIMECMP_HI` registers, can be used to configure the CPU's machine timer interrupt (`MTI`)). The interrupt
is triggered whenever `TIME` (high & low part) is greater than or equal to `TIMECMP` (high & low part).
and `TIMECMP_HI` registers, can be used to configure the CPU's machine timer interrupt (`MTI`)).

The interrupt is triggered whenever `TIME` (high & low part) is greater than or equal to `TIMECMP` (high & low part).
The interrupt remains active (=pending) until `TIME` becomes less than `TIMECMP` again (either by modifying
`TIME` or `TIMECMP`). The current system time is available for other SoC modules via the top's `mtime_time_o` signal.

Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/soc_neoled.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
| Configuration generics: | `IO_NEOLED_EN` | implement NEOLED controller when `true`
| | `IO_NEOLED_TX_FIFO` | TX FIFO depth, has to be a power of 2, min 1
| CPU interrupts: | fast IRQ channel 9 | configurable NEOLED data FIFO interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/soc_onewire.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
| | `onewire_o` | 1-bit 1-wire bus output (pull low only)
| Configuration generics: | `IO_ONEWIRE_EN` | implement ONEWIRE interface controller when `true`
| CPU interrupts: | fast IRQ channel 13 | operation done interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down
6 changes: 3 additions & 3 deletions docs/datasheet/soc_pwm.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files: | neorv32_pwm.vhd |
| Hardware source files: | neorv32_pwm.vhd |
| Software driver files: | neorv32_pwm.c |
| | neorv32_pwm.h |
| Top entity ports: | `pwm_o` | PWM output channels (12-bit)
| Configuration generics: | `IO_PWM_NUM_CH` | number of PWM channels to implement (0..12)
| CPU interrupts: | none |
| CPU interrupts: | none |
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


**Overview**
**Overview**

The PWM module implements a pulse-width modulation controller with up to 12 independent channels providing
Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/soc_sdi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
| Configuration generics: | `IO_SDI_EN` | implement SDI controller when `true`
| | `IO_SDI_FIFO` | data FIFO size, has to a power of two, min 1
| CPU interrupts: | fast IRQ channel 11 | configurable SDI interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/soc_slink.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
| | `IO_SLINK_TX_FIFO` | TX FIFO depth (1..32k), has to be a power of two, min 1
| CPU interrupts: | fast IRQ channel 14 | RX SLINK IRQ (see <<_processor_interrupts>>)
| | fast IRQ channel 15 | TX SLINK IRQ (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down
7 changes: 4 additions & 3 deletions docs/datasheet/soc_spi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
| Configuration generics: | `IO_SPI_EN` | implement SPI controller when `true`
| | `IO_SPI_FIFO` | FIFO depth, has to be a power of two, min 1
| CPU interrupts: | fast IRQ channel 6 | configurable SPI interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand All @@ -26,15 +27,15 @@ SPI clock generator and provides up to 8 dedicated chip select signals via the t
An optional receive/transmit ring-buffer/FIFO can be configured via the `IO_SPI_FIFO` generic to support block-based
transmissions without CPU interaction.

The SPI module provides a single control register `CTRL` to configure the module and to check it's status
and a single data register `DATA` for receiving/transmitting data.

.Host-Mode Only
[NOTE]
The NEORV32 SPI module only supports _host mode_. Transmission are initiated only by the processor's SPI module
and not by an external SPI module. If you are looking for a _device-mode_ serial peripheral interface (transactions
initiated by an external host) check out the <<_serial_data_interface_controller_sdi>>.

The SPI module provides a single control register `CTRL` to configure the module and to check it's status
and a single data register `DATA` for receiving/transmitting data.


**Theory of Operation**

Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/soc_sysinfo.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
| Top entity ports: | none |
| Configuration generics: | * | most of the top's configuration generics
| CPU interrupts: | none |
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/soc_trng.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
| Configuration generics: | `IO_TRNG_EN` | implement TRNG when `true`
| | `IO_TRNG_FIFO` | data FIFO depth, min 1, has to be a power of two
| CPU interrupts: | fast IRQ channel 0 | TRNG data available interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down
1 change: 1 addition & 0 deletions docs/datasheet/soc_twi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
| Configuration generics: | `IO_TWI_EN` | implement TWI controller when `true`
| | `IO_TWI_FIFO` | FIFO depth, has to be a power of two, min 1
| CPU interrupts: | fast IRQ channel 7 | FIFO empty and module idle interrupt (see <<_processor_interrupts>>)
| Access restrictions: 2+| privileged access only, non-32-bit write accesses are ignored
|=======================


Expand Down
Loading

0 comments on commit 9f21272

Please sign in to comment.