Skip to content

Commit

Permalink
cpu/riscv: Add PMP driver
Browse files Browse the repository at this point in the history
  • Loading branch information
Teufelchen1 committed Jun 28, 2023
1 parent 561e193 commit 49548f9
Show file tree
Hide file tree
Showing 17 changed files with 561 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ ifneq (,$(filter mpu_noexec_ram,$(USEMODULE)))
FEATURES_REQUIRED += cortexm_mpu
endif

ifneq (,$(filter pmp_noexec_ram,$(USEMODULE)))
FEATURES_REQUIRED += periph_pmp
endif

ifneq (,$(filter lwip_%,$(USEMODULE)))
USEPKG += lwip
endif
Expand Down
2 changes: 1 addition & 1 deletion core/lib/include/panic.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ typedef enum {
PANIC_HARD_REBOOT,
PANIC_ASSERT_FAIL,
PANIC_EXPECT_FAIL,
PANIC_MEM_MANAGE, /**< memory management fault */
#ifdef MODULE_CORTEXM_COMMON
PANIC_NMI_HANDLER, /**< non maskable interrupt */
PANIC_HARD_FAULT, /**< hard fault */
#if defined(CPU_CORE_CORTEX_M3) || defined(CPU_CORE_CORTEX_M33) || \
defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \
defined(CPU_CORE_CORTEX_M7)
PANIC_MEM_MANAGE, /**< memory controller interrupt */
PANIC_BUS_FAULT, /**< bus fault */
PANIC_USAGE_FAULT, /**< undefined instruction or unaligned access */
PANIC_DEBUG_MON, /**< debug interrupt */
Expand Down
1 change: 1 addition & 0 deletions cpu/fe310/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ config CPU_FAM_FE310
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_PM
select HAS_PERIPH_PMP
select HAS_PERIPH_PLIC
select HAS_PERIPH_RTT_OVERFLOW
select HAS_PERIPH_RTT_SET_COUNTER
Expand Down
1 change: 1 addition & 0 deletions cpu/fe310/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ CPU_CORE := rv32imac
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_pm
FEATURES_PROVIDED += periph_pmp
FEATURES_PROVIDED += periph_plic
FEATURES_PROVIDED += periph_rtt_overflow
FEATURES_PROVIDED += periph_rtt_set_counter
Expand Down
6 changes: 6 additions & 0 deletions cpu/fe310/include/cpu_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ extern "C" {
*/
#define PLIC_BASE_ADDR (PLIC_CTRL_ADDR)

/**
* @brief Number of available PMP regions
* Note, the upper 8 regions are hardwired to zero!
*/
#define NUM_PMP_ENTRIES 16

#ifdef __cplusplus
}
#endif
Expand Down
125 changes: 125 additions & 0 deletions cpu/riscv_common/include/pmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2023 Bennet Blischke <bennet.blischke@haw-hamburg.de>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/

/**
* @ingroup cpu_riscv_common
* @{
*
* @file
* @brief RISC-V PMP configuration options
*
* RISCV implementations using this peripheral must define the `NUM_PMP_ENTRIES`
* `NUM_PMP_ENTRIES` must be 16 or 64.
*
* @author Bennet Blischke
*/

#ifndef PMP_H
#define PMP_H

#include <assert.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @name Bit masks for the PMP configuration register
* @{
*/
#define PMP_NONE 0x00 /**< No access allowed at all */
#define PMP_R 0x01 /**< Allow read access */
#define PMP_W 0x02 /**< Allow write access */
#define PMP_X 0x04 /**< Allow execution */

#define PMP_A 0x18 /**< Addressing mode mask */
#define PMP_OFF 0x00 /**< Disable this pmp entry */
#define PMP_TOR 0x08 /**< Top-of-range addressing mode */
#define PMP_NA4 0x10 /**< Naturally aligned four-byte region */
#define PMP_NAPOT 0x18 /**< Naturally aligned power-of-two region, ≥8 bytes */

#define PMP_L 0x80 /**< Lock; read-only config & applies to machine-mode */
/** @} */

/**
* @brief Create a NAPOT formatted address
*
* @param addr Base address, must be aligned to the size of the region
* @param size Size of the region in bytes
*/
static inline uint32_t make_napot(uint32_t addr, uint32_t size)
{
assert(addr % size == 0);
return addr | ((size - 1) >> 1);
}

/**
* @brief Writes a complete pmpcfg register
*
* @param reg_num Register number
* @param value Value to write
*/
void write_pmpcfg(uint8_t reg_num, uint32_t value);

/**
* @brief Read a complete pmpcfg register
*
* @param[in] reg_num Register number
*
* @return Contents of the specified register
*/
uint32_t read_pmpcfg(uint8_t reg_num);

/**
* @brief Writes a complete pmpaddr register
*
* @param reg_num Register number
* @param value Value to write
*/
void write_pmpaddr(uint8_t reg_num, uint32_t value);

/**
* @brief Read a complete pmpaddr register
*
* @param[in] reg_num Register number
*
* @return Contents of the specified register
*/
uint32_t read_pmpaddr(uint8_t reg_num);

/**
* @brief Read a single pmpcfg sub-register
*
* @param[in] entry Sub-register number
*
* @return Contents of the specified sub-register
*/
uint8_t get_pmpcfg(uint8_t entry);

/**
* @brief Set's a single pmpcfg sub-register
*
* @param entry Sub-register number
* @param value Value to write
*/
void set_pmpcfg(uint8_t entry, uint8_t value);

/**
* @brief Prints a single pmpcfg sub-register human readable
*
* @param entry Register number to print
*/
void print_pmpcfg(uint8_t entry);

#ifdef __cplusplus
}
#endif

#endif /* PMP_H */
/** @} */
3 changes: 3 additions & 0 deletions cpu/riscv_common/include/vendor/riscv_csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@

#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)

#define CSR_PMPCFG0 0x3a0 // PMP configuration base register
#define CSR_PMPADDR0 0x3b0 // PMP address base register

#ifdef __riscv

#ifdef __riscv64
Expand Down
8 changes: 8 additions & 0 deletions cpu/riscv_common/irq_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ static void handle_trap(uword_t mcause)
write_csr(mepc, return_pc + 4);
break;
}
#ifdef MODULE_PERIPH_PMP
case CAUSE_FAULT_FETCH:
core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER (fetch)");
case CAUSE_FAULT_LOAD:
core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER (load)");
case CAUSE_FAULT_STORE:
core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER (store)");
#endif
default:
#ifdef DEVELHELP
printf("Unhandled trap:\n");
Expand Down
6 changes: 6 additions & 0 deletions cpu/riscv_common/periph/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ config MODULE_PERIPH_PLIC
help
Platform-Level interrupt controller driver.

config MODULE_PERIPH_PMP
bool
depends on HAS_PERIPH_PMP
help
Physical memory protection driver.

endif # MODULE_RISCV_COMMON_PERIPH
Loading

0 comments on commit 49548f9

Please sign in to comment.