LCOV - code coverage report
Current view: top level - zephyr/arch/xtensa - mpu.h Hit Total Coverage
Test: new.info Lines: 41 52 78.8 %
Date: 2024-12-21 18:13:37

          Line data    Source code
       1           0 : /*
       2             :  * Copyright (c) 2023 Intel Corporation
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : #include <stdint.h>
       8             : 
       9             : #include <zephyr/toolchain.h>
      10             : #include <zephyr/sys/util_macro.h>
      11             : 
      12             : #include <xtensa/config/core-isa.h>
      13             : 
      14             : #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_MPU_H
      15             : #define ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_MPU_H
      16             : 
      17             : /**
      18             :  * @defgroup xtensa_mpu_apis Xtensa Memory Protection Unit (MPU) APIs
      19             :  * @ingroup xtensa_apis
      20             :  * @{
      21             :  */
      22             : 
      23             : /** Number of available entries in the MPU table. */
      24           1 : #define XTENSA_MPU_NUM_ENTRIES                  XCHAL_MPU_ENTRIES
      25             : 
      26             : /**
      27             :  * @name MPU memory region access rights.
      28             :  *
      29             :  * @note These are NOT bit masks, and must be used as whole value.
      30             :  *
      31             :  * @{
      32             :  */
      33             : 
      34             : /** Kernel and user modes no access. */
      35           1 : #define XTENSA_MPU_ACCESS_P_NA_U_NA                     (0)
      36             : 
      37             : /** Kernel mode execution only. */
      38           1 : #define XTENSA_MPU_ACCESS_P_X_U_NA                      (2)
      39             : 
      40             : /** User mode execution only. */
      41           1 : #define XTENSA_MPU_ACCESS_P_NA_U_X                      (3)
      42             : 
      43             : /** Kernel mode read only. */
      44           1 : #define XTENSA_MPU_ACCESS_P_RO_U_NA                     (4)
      45             : 
      46             : /** Kernel mode read and execution. */
      47           1 : #define XTENSA_MPU_ACCESS_P_RX_U_NA                     (5)
      48             : 
      49             : /** Kernel mode read and write. */
      50           1 : #define XTENSA_MPU_ACCESS_P_RW_U_NA                     (6)
      51             : 
      52             : /** Kernel mode read, write and execution. */
      53           1 : #define XTENSA_MPU_ACCESS_P_RWX_U_NA                    (7)
      54             : 
      55             : /** Kernel and user modes write only. */
      56           1 : #define XTENSA_MPU_ACCESS_P_WO_U_WO                     (8)
      57             : 
      58             : /** Kernel mode read, write. User mode read, write and execution. */
      59           1 : #define XTENSA_MPU_ACCESS_P_RW_U_RWX                    (9)
      60             : 
      61             : /** Kernel mode read and write. User mode read only. */
      62           1 : #define XTENSA_MPU_ACCESS_P_RW_U_RO                     (10)
      63             : 
      64             : /** Kernel mode read, write and execution. User mode read and execution. */
      65           1 : #define XTENSA_MPU_ACCESS_P_RWX_U_RX                    (11)
      66             : 
      67             : /** Kernel and user modes read only. */
      68           1 : #define XTENSA_MPU_ACCESS_P_RO_U_RO                     (12)
      69             : 
      70             : /** Kernel and user modes read and execution. */
      71           1 : #define XTENSA_MPU_ACCESS_P_RX_U_RX                     (13)
      72             : 
      73             : /** Kernel and user modes read and write. */
      74           1 : #define XTENSA_MPU_ACCESS_P_RW_U_RW                     (14)
      75             : 
      76             : /** Kernel and user modes read, write and execution. */
      77           1 : #define XTENSA_MPU_ACCESS_P_RWX_U_RWX                   (15)
      78             : 
      79             : /**
      80             :  * @}
      81             :  */
      82             : 
      83             : /**
      84             :  * @brief Foreground MPU Entry.
      85             :  *
      86             :  * This holds the as, at register values for one MPU entry which can be
      87             :  * used directly by WPTLB.
      88             :  */
      89           1 : struct xtensa_mpu_entry {
      90             :         /**
      91             :          * Content of as register for WPTLB.
      92             :          *
      93             :          * This contains the start address, the enable bit, and the lock bit.
      94             :          */
      95             :         union {
      96             :                 /** Raw value. */
      97           1 :                 uint32_t raw;
      98             : 
      99             :                 /** Individual parts. */
     100             :                 struct {
     101             :                         /**
     102             :                          * Enable bit for this entry.
     103             :                          *
     104             :                          * Modifying this will also modify the corresponding bit of
     105             :                          * the MPUENB register.
     106             :                          */
     107           1 :                         uint32_t enable:1;
     108             : 
     109             :                         /**
     110             :                          * Lock bit for this entry.
     111             :                          *
     112             :                          * Usable only if MPULOCKABLE parameter is enabled in
     113             :                          * processor configuration.
     114             :                          *
     115             :                          * Once set:
     116             :                          * - This cannot be cleared until reset.
     117             :                          * - This entry can no longer be modified.
     118             :                          * - The start address of the next entry also
     119             :                          *   cannot be modified.
     120             :                          */
     121           1 :                         uint32_t lock:1;
     122             : 
     123             :                         /** Must be zero. */
     124           1 :                         uint32_t mbz:3;
     125             : 
     126             :                         /**
     127             :                          * Start address of this MPU entry.
     128             :                          *
     129             :                          * Effective bits in this portion are affected by the minimum
     130             :                          * segment size of each MPU entry, ranging from 32 bytes to 4GB.
     131             :                          */
     132           1 :                         uint32_t start_addr:27;
     133           1 :                 } p;
     134           1 :         } as;
     135             : 
     136             :         /**
     137             :          * Content of at register for WPTLB.
     138             :          *
     139             :          * This contains the memory type, access rights, and the segment number.
     140             :          */
     141             :         union {
     142             :                 /** Raw value. */
     143             :                 uint32_t raw;
     144             : 
     145             :                 /** Individual parts. */
     146             :                 struct {
     147             :                         /** The segment number of this MPU entry. */
     148           1 :                         uint32_t segment:5;
     149             : 
     150             :                         /** Must be zero (part 1). */
     151           1 :                         uint32_t mbz1:3;
     152             : 
     153             :                         /**
     154             :                          * Access rights associated with this MPU entry.
     155             :                          *
     156             :                          * This dictates the access right from the start address of
     157             :                          * this entry, to the start address of next entry.
     158             :                          *
     159             :                          * Refer to XTENSA_MPU_ACCESS_* macros for available rights.
     160             :                          */
     161           1 :                         uint32_t access_rights:4;
     162             : 
     163             :                         /**
     164             :                          * Memory type associated with this MPU entry.
     165             :                          *
     166             :                          * This dictates the memory type from the start address of
     167             :                          * this entry, to the start address of next entry.
     168             :                          *
     169             :                          * This affects how the hardware treats the memory, for example,
     170             :                          * cacheable vs non-cacheable, shareable vs non-shareable.
     171             :                          * Refer to the Xtensa Instruction Set Architecture (ISA) manual
     172             :                          * for general description, and the processor manual for processor
     173             :                          * specific information.
     174             :                          */
     175           1 :                         uint32_t memory_type:9;
     176             : 
     177             :                         /** Must be zero (part 2). */
     178           1 :                         uint32_t mbz2:11;
     179           1 :                 } p;
     180           1 :         } at;
     181             : };
     182             : 
     183             : /**
     184             :  * @brief Struct to hold foreground MPU map and its entries.
     185             :  */
     186           1 : struct xtensa_mpu_map {
     187             :         /**
     188             :          * Array of MPU entries.
     189             :          */
     190           1 :         struct xtensa_mpu_entry entries[XTENSA_MPU_NUM_ENTRIES];
     191             : };
     192             : 
     193             : /**
     194             :  * @name Memory domain and partitions
     195             :  * @{
     196             :  */
     197             : 
     198             : typedef uint32_t k_mem_partition_attr_t;
     199             : 
     200           0 : static inline bool xtensa_mem_partition_is_executable(k_mem_partition_attr_t access_rights)
     201             : {
     202             :         bool is_exec;
     203             : 
     204             :         switch (access_rights) {
     205             :         case XTENSA_MPU_ACCESS_P_X_U_NA:
     206             :         case XTENSA_MPU_ACCESS_P_NA_U_X:
     207             :         case XTENSA_MPU_ACCESS_P_RX_U_NA:
     208             :         case XTENSA_MPU_ACCESS_P_RWX_U_NA:
     209             :         case XTENSA_MPU_ACCESS_P_RW_U_RWX:
     210             :         case XTENSA_MPU_ACCESS_P_RWX_U_RX:
     211             :         case XTENSA_MPU_ACCESS_P_RX_U_RX:
     212             :         case XTENSA_MPU_ACCESS_P_RWX_U_RWX:
     213             :                 is_exec = true;
     214             :                 break;
     215             :         default:
     216             :                 is_exec = false;
     217             :                 break;
     218             :         };
     219             : 
     220             :         return is_exec;
     221             : }
     222             : 
     223           0 : static inline bool xtensa_mem_partition_is_writable(k_mem_partition_attr_t access_rights)
     224             : {
     225             :         bool is_writable;
     226             : 
     227             :         switch (access_rights) {
     228             :         case XTENSA_MPU_ACCESS_P_RW_U_NA:
     229             :         case XTENSA_MPU_ACCESS_P_RWX_U_NA:
     230             :         case XTENSA_MPU_ACCESS_P_WO_U_WO:
     231             :         case XTENSA_MPU_ACCESS_P_RW_U_RWX:
     232             :         case XTENSA_MPU_ACCESS_P_RW_U_RO:
     233             :         case XTENSA_MPU_ACCESS_P_RWX_U_RX:
     234             :         case XTENSA_MPU_ACCESS_P_RW_U_RW:
     235             :         case XTENSA_MPU_ACCESS_P_RWX_U_RWX:
     236             :                 is_writable = true;
     237             :                 break;
     238             :         default:
     239             :                 is_writable = false;
     240             :                 break;
     241             :         };
     242             : 
     243             :         return is_writable;
     244             : }
     245             : 
     246           0 : #define K_MEM_PARTITION_IS_EXECUTABLE(access_rights) \
     247             :         (xtensa_mem_partition_is_executable(access_rights))
     248             : 
     249           0 : #define K_MEM_PARTITION_IS_WRITABLE(access_rights) \
     250             :         (xtensa_mem_partition_is_writable(access_rights))
     251             : 
     252             : /* Read-Write access permission attributes */
     253           0 : #define K_MEM_PARTITION_P_RW_U_RW \
     254             :         ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RW_U_RW})
     255           0 : #define K_MEM_PARTITION_P_RW_U_NA \
     256             :         ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RW_U_NA})
     257           0 : #define K_MEM_PARTITION_P_RO_U_RO \
     258             :         ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RO_U_RO})
     259           0 : #define K_MEM_PARTITION_P_RO_U_NA \
     260             :         ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RO_U_NA})
     261           0 : #define K_MEM_PARTITION_P_NA_U_NA \
     262             :         ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_NA_U_NA})
     263             : 
     264             : /* Execution-allowed attributes */
     265           0 : #define K_MEM_PARTITION_P_RX_U_RX \
     266             :         ((k_mem_partition_attr_t) {XTENSA_MPU_ACCESS_P_RX_U_RX})
     267             : 
     268             : /**
     269             :  * @}
     270             :  */
     271             : 
     272             : /**
     273             :  * Struct to describe a memory region [start, end).
     274             :  */
     275           1 : struct xtensa_mpu_range {
     276             :         /** Start address (inclusive) of the memory region. */
     277           1 :         const uintptr_t start;
     278             : 
     279             :         /**
     280             :          * End address (exclusive) of the memory region.
     281             :          *
     282             :          * Use 0xFFFFFFFF for the end of memory.
     283             :          */
     284           1 :         const uintptr_t end;
     285             : 
     286             :         /** Access rights for the memory region. */
     287           1 :         const uint8_t access_rights:4;
     288             : 
     289             :         /**
     290             :          * Memory type for the region.
     291             :          *
     292             :          * Refer to the Xtensa Instruction Set Architecture (ISA) manual
     293             :          * for general description, and the processor manual for processor
     294             :          * specific information.
     295             :          */
     296           1 :         const uint16_t memory_type:9;
     297             : } __packed;
     298             : 
     299             : /**
     300             :  * @brief Additional memory regions required by SoC.
     301             :  *
     302             :  * These memory regions will be setup by MPU initialization code at boot.
     303             :  *
     304             :  * Must be defined in the SoC layer.
     305             :  */
     306           1 : extern const struct xtensa_mpu_range xtensa_soc_mpu_ranges[];
     307             : 
     308             : /**
     309             :  * @brief Number of SoC additional memory regions.
     310             :  *
     311             :  * Must be defined in the SoC layer.
     312             :  */
     313           1 : extern const int xtensa_soc_mpu_ranges_num;
     314             : 
     315             : /**
     316             :  * @brief Initialize hardware MPU.
     317             :  *
     318             :  * This initializes the MPU hardware and setup the memory regions at boot.
     319             :  */
     320           1 : void xtensa_mpu_init(void);
     321             : 
     322             : /**
     323             :  * @}
     324             :  */
     325             : 
     326             : #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_MPU_H */

Generated by: LCOV version 1.14