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 9, 2023
1 parent 5cc9230 commit 7cdcabc
Show file tree
Hide file tree
Showing 5 changed files with 429 additions and 0 deletions.
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
124 changes: 124 additions & 0 deletions cpu/riscv_common/include/pmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* 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 <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 reg_num Register number
*/
void print_pmpcfg(int 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
Loading

0 comments on commit 7cdcabc

Please sign in to comment.