LCOV - code coverage report
Current view: top level - zephyr/arch/xtensa - mpu.h Coverage Total Hit
Test: new.info Lines: 78.8 % 52 41
Test Date: 2025-03-11 06:50:38

            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 2.0-1