zephyr/arch/riscv/include/core_pmp.h

143 lines
3.7 KiB
C

/*
* Copyright (c) 2020 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef CORE_PMP_H_
#define CORE_PMP_H_
/* Configuration register flags (cfg_val)*/
#define PMP_R 0x01 /* Allow read */
#define PMP_W 0x02 /* Allow write */
#define PMP_X 0x04 /* Allow execute */
#define PMP_A 0x18 /* Address-matching mode field */
#define PMP_L 0x80 /* PMP entry is locked */
#define PMP_OFF 0x00 /* Null region */
#define PMP_TOR 0x08 /* Top of range */
#define PMP_NA4 0x10 /* Naturally aligned four-byte region */
#define PMP_NAPOT 0x18 /* Naturally aligned power-of-two region */
#define PMP_SHIFT_ADDR 2
#define PMP_TYPE_MASK 0x18
#define TO_PMP_ADDR(addr) ((addr) >> PMP_SHIFT_ADDR)
#define FROM_PMP_ADDR(addr) ((addr) << PMP_SHIFT_ADDR)
#define TO_NAPOT_RANGE(size) (((size) - 1) >> 1)
#define TO_PMP_NAPOT(addr, size) TO_PMP_ADDR(addr | \
TO_NAPOT_RANGE(size))
#ifdef CONFIG_PMP_STACK_GUARD
#define PMP_GUARD_ALIGN_AND_SIZE CONFIG_PMP_STACK_GUARD_MIN_SIZE
#else
#define PMP_GUARD_ALIGN_AND_SIZE 0
#endif /* CONFIG_PMP_STACK_GUARD */
#ifdef CONFIG_RISCV_PMP
/*
* @brief Set a Physical Memory Protection slot
*
* Configure a memory region to be secured by one of the 16 PMP entries.
*
* @param index Number of the targeted PMP entrie (0 to 15 only).
* @param cfg_val Configuration value (cf datasheet or defined flags)
* @param addr_val Address register value
*
* This function shall only be called from Secure state.
*
* @return -1 if bad argument, 0 otherwise.
*/
int z_riscv_pmp_set(unsigned int index, ulong_t cfg_val, ulong_t addr_val);
/*
* @brief Reset to 0 all PMP setup registers
*/
void z_riscv_pmp_clear_config(void);
/*
* @brief Print PMP setup register for info/debug
*/
void z_riscv_pmp_print(unsigned int index);
#endif /* CONFIG_RISCV_PMP */
#if defined(CONFIG_USERSPACE)
/*
* @brief Configure RISCV user thread access to the stack
*
* Determine and save allow access setup in thread structure.
*
* @param thread Thread info data pointer.
*/
void z_riscv_init_user_accesses(struct k_thread *thread);
/*
* @brief Apply RISCV user thread access to the stack
*
* Write user access setup saved in this thread structure.
*
* @param thread Thread info data pointer.
*/
void z_riscv_configure_user_allowed_stack(struct k_thread *thread);
/*
* @brief Add a new RISCV stack access
*
* Add a new memory permission area in the existing
* pmp setup of the thread.
*
* @param thread Thread info data pointer.
* @param addr Start address of the memory area.
* @param size Size of the memory area.
* @param flags Pemissions: PMP_R, PMP_W, PMP_X, PMP_L
*/
void z_riscv_pmp_add_dynamic(struct k_thread *thread,
ulong_t addr,
ulong_t size,
unsigned char flags);
#endif /* CONFIG_USERSPACE */
#ifdef CONFIG_PMP_STACK_GUARD
/*
* @brief Configure RISCV stack guard for interrupt stack
*
* Write PMP registers to prevent RWX access from all privilege mode.
*/
void z_riscv_configure_interrupt_stack_guard(void);
/*
* @brief Configure RISCV stack guard
*
* Determine and save stack guard setup in thread structure.
*
* @param thread Thread info data pointer.
*/
void z_riscv_init_stack_guard(struct k_thread *thread);
/*
* @brief Apply RISCV stack guard
*
* Write stack guard setup saved in this thread structure.
*
* @param thread Thread info data pointer.
*/
void z_riscv_configure_stack_guard(struct k_thread *thread);
#endif /* CONFIG_PMP_STACK_GUARD */
#if defined(CONFIG_PMP_STACK_GUARD) || defined(CONFIG_USERSPACE)
/*
* @brief Initialize thread PMP setup value to 0
*
* @param thread Thread info data pointer.
*/
void z_riscv_pmp_init_thread(struct k_thread *thread);
#endif /* CONFIG_PMP_STACK_GUARD || CONFIG_USERSPACE */
#endif /* CORE_PMP_H_ */