242 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			242 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/****************************************************************************
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
							 | 
						||
| 
								 | 
							
								 * be copied by any method or incorporated int32_to another program without
							 | 
						||
| 
								 | 
							
								 * the express written consent of Aerospace C.Power. This Information or any portion
							 | 
						||
| 
								 | 
							
								 * thereof remains the property of Aerospace C.Power. The Information contained herein
							 | 
						||
| 
								 | 
							
								 * is believed to be accurate and Aerospace C.Power assumes no responsibility or
							 | 
						||
| 
								 | 
							
								 * liability for its use in any way and conveys no license or title under
							 | 
						||
| 
								 | 
							
								 * any patent or copyright and makes no representation or warranty that this
							 | 
						||
| 
								 | 
							
								 * Information is free from patent or copyright infringement.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * ****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef _LIB_RISCV_PMP_H
							 | 
						||
| 
								 | 
							
								#define _LIB_RISCV_PMP_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "os_types.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct pmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Set of available PMP addressing modes
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								enum pmp_address_mode {
							 | 
						||
| 
								 | 
							
								    /*! @brief Disable the PMP region */
							 | 
						||
| 
								 | 
							
								    PMP_OFF = 0,
							 | 
						||
| 
								 | 
							
								    /*! @brief Use Top-of-Range mode */
							 | 
						||
| 
								 | 
							
								    PMP_TOR = 1,
							 | 
						||
| 
								 | 
							
								    /*! @brief Use naturally-aligned 4-byte region mode */
							 | 
						||
| 
								 | 
							
								    PMP_NA4 = 2,
							 | 
						||
| 
								 | 
							
								    /*! @brief Use naturally-aligned power-of-two mode */
							 | 
						||
| 
								 | 
							
								    PMP_NAPOT = 3
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum pmp_locked {
							 | 
						||
| 
								 | 
							
								    PMP_UNLOCKED = 0,
							 | 
						||
| 
								 | 
							
								    PMP_LOCKED = 1
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Configuration for a PMP region
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								struct pmp_config {
							 | 
						||
| 
								 | 
							
								    /*! @brief Sets whether reads to the PMP region succeed */
							 | 
						||
| 
								 | 
							
								    uint32_t R : 1;
							 | 
						||
| 
								 | 
							
								    /*! @brief Sets whether writes to the PMP region succeed */
							 | 
						||
| 
								 | 
							
								    uint32_t W : 1;
							 | 
						||
| 
								 | 
							
								    /*! @brief Sets whether the PMP region is executable */
							 | 
						||
| 
								 | 
							
								    uint32_t X : 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*! @brief Sets the addressing mode of the PMP region */
							 | 
						||
| 
								 | 
							
								    enum pmp_address_mode A : 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    uint32_t _pad : 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*! @brief Sets whether the PMP region is locked */
							 | 
						||
| 
								 | 
							
								    enum pmp_locked L : 1;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief A handle for the PMP device
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								struct pmp {
							 | 
						||
| 
								 | 
							
								    /* The minimum granularity of the PMP region. Set by pmp_init */
							 | 
						||
| 
								 | 
							
								    uintptr_t _granularity[3];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Get the PMP device handle
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								struct pmp *pmp_get_device(void);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Get the number of pmp regions for the hartid
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								uint32_t pmp_num_regions(int32_t hartid);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Initialize the PMP
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle to be initialized
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The PMP initialization routine is optional and may be called as many times
							 | 
						||
| 
								 | 
							
								 * as is desired. The effect of the initialization routine is to attempt to set
							 | 
						||
| 
								 | 
							
								 * all regions to unlocked and disabled, as well as to clear the X, W, and R
							 | 
						||
| 
								 | 
							
								 * bits. Only the pmp configuration of the hart which executes the routine will
							 | 
						||
| 
								 | 
							
								 * be affected.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * If any regions are fused to preset values by the implementation or locked,
							 | 
						||
| 
								 | 
							
								 * those PMP regions will silently remain uninitialized.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void pmp_init(struct pmp *pmp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Configure a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to configure
							 | 
						||
| 
								 | 
							
								 * @param config The desired configuration of the PMP region
							 | 
						||
| 
								 | 
							
								 * @param address The desired address of the PMP region
							 | 
						||
| 
								 | 
							
								 * @return 0 upon success
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_set_region(const struct pmp *pmp, uint32_t region,
							 | 
						||
| 
								 | 
							
								                         struct pmp_config config, size_t address);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Get the configuration for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to read
							 | 
						||
| 
								 | 
							
								 * @param config Variable to store the PMP region configuration
							 | 
						||
| 
								 | 
							
								 * @param address Variable to store the PMP region address
							 | 
						||
| 
								 | 
							
								 * @return 0 if the region is read successfully
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_get_region(const struct pmp *pmp, uint32_t region,
							 | 
						||
| 
								 | 
							
								                         struct pmp_config *config, size_t *address);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Lock a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to lock
							 | 
						||
| 
								 | 
							
								 * @return 0 if the region is successfully locked
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_lock(const struct pmp *pmp, uint32_t region);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Set the address for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to set
							 | 
						||
| 
								 | 
							
								 * @param address The desired address of the PMP region
							 | 
						||
| 
								 | 
							
								 * @return 0 if the address is successfully set
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_set_address(const struct pmp *pmp, uint32_t region,
							 | 
						||
| 
								 | 
							
								                          size_t address);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Get the address of a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to read
							 | 
						||
| 
								 | 
							
								 * @return The address of the PMP region, or 0 if the region could not be read
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								size_t pmp_get_address(const struct pmp *pmp, uint32_t region);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Set the addressing mode of a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to set
							 | 
						||
| 
								 | 
							
								 * @param mode The PMP addressing mode to set
							 | 
						||
| 
								 | 
							
								 * @return 0 if the addressing mode is successfully set
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_set_address_mode(const struct pmp *pmp, uint32_t region,
							 | 
						||
| 
								 | 
							
								                               enum pmp_address_mode mode);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Get the addressing mode of a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to read
							 | 
						||
| 
								 | 
							
								 * @return The address mode of the PMP region
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								enum pmp_address_mode pmp_get_address_mode(const struct pmp *pmp,
							 | 
						||
| 
								 | 
							
								                                                       uint32_t region);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Set the executable bit for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to set
							 | 
						||
| 
								 | 
							
								 * @param X The desired value of the executable bit
							 | 
						||
| 
								 | 
							
								 * @return 0 if the executable bit is successfully set
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_set_executable(const struct pmp *pmp, uint32_t region, int32_t X);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Get the executable bit for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to read
							 | 
						||
| 
								 | 
							
								 * @return the value of the executable bit
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_get_executable(const struct pmp *pmp, uint32_t region);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Set the writable bit for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to set
							 | 
						||
| 
								 | 
							
								 * @param W The desired value of the writable bit
							 | 
						||
| 
								 | 
							
								 * @return 0 if the writable bit is successfully set
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_set_writeable(const struct pmp *pmp, uint32_t region, int32_t W);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Get the writable bit for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to read
							 | 
						||
| 
								 | 
							
								 * @return the value of the writable bit
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_get_writeable(const struct pmp *pmp, uint32_t region);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Set the readable bit for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to set
							 | 
						||
| 
								 | 
							
								 * @param R The desired value of the readable bit
							 | 
						||
| 
								 | 
							
								 * @return 0 if the readable bit is successfully set
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_set_readable(const struct pmp *pmp, uint32_t region, int32_t R);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief Set the readable bit for a PMP region
							 | 
						||
| 
								 | 
							
								 * @param pmp The PMP device handle
							 | 
						||
| 
								 | 
							
								 * @param region The PMP region to read
							 | 
						||
| 
								 | 
							
								 * @return the value of the readable bit
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int32_t pmp_get_readable(const struct pmp *pmp, uint32_t region);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief reset the config of PMP region
							 | 
						||
| 
								 | 
							
								 * @param region: pmp region
							 | 
						||
| 
								 | 
							
								 * @return void
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void mmon_reset(uint32_t region);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief config pmp region
							 | 
						||
| 
								 | 
							
								 * @param region: pmp region
							 | 
						||
| 
								 | 
							
								 * @param start: start addr
							 | 
						||
| 
								 | 
							
								 * @param size: size
							 | 
						||
| 
								 | 
							
								 * @param privilege: privilege of this addr, 0x0:no privilege 0x1:read 0x2:write  0x4:execute
							 | 
						||
| 
								 | 
							
								 * @attention,read=0 && write=1 is reserved
							 | 
						||
| 
								 | 
							
								 * @return void
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void mmon_set(uint32_t region, uint32_t start, uint32_t size,
							 | 
						||
| 
								 | 
							
								    uint8_t privilege);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*!
							 | 
						||
| 
								 | 
							
								 * @brief read the config and addr of PMP region
							 | 
						||
| 
								 | 
							
								 * @param region: pmp region
							 | 
						||
| 
								 | 
							
								 * @param cfg:cfg
							 | 
						||
| 
								 | 
							
								 * @param addr:addr
							 | 
						||
| 
								 | 
							
								 * @return void
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void mmon_read(uint32_t region, uint32_t *cfg, uint32_t* addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //_LIB_RISCV_PMP_H
							 |