1 /*******************************************************************************
2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * MPFS HAL Embedded Software
7 *
8 */
9 /*******************************************************************************
10 * @file mss_mpu.h
11 * @author Microchip-FPGA Embedded Systems Solutions
12 * @brief PolarFire SoC MSS MPU driver APIs for configuring access regions for
13 * the external masters.
14 *
15 */
16 /*=========================================================================*//**
17
18 *//*=========================================================================*/
19 #ifndef MSS_MPU_H
20 #define MSS_MPU_H
21
22 #include <stdint.h>
23
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 #ifndef SIFIVE_HIFIVE_UNLEASHED
30
31 /***************************************************************************//**
32
33 */
34 #define MPU_MODE_READ_ACCESS (1U << 0U)
35 #define MPU_MODE_WRITE_ACCESS (1U << 1U)
36 #define MPU_MODE_EXEC_ACCESS (1U << 2U)
37
38 typedef enum {
39 MSS_MPU_FIC0 = 0x00,
40 MSS_MPU_FIC1,
41 MSS_MPU_FIC2,
42 MSS_MPU_CRYPTO,
43 MSS_MPU_GEM0,
44 MSS_MPU_GEM1,
45 MSS_MPU_USB,
46 MSS_MPU_MMC,
47 MSS_MPU_SCB,
48 MSS_MPU_TRACE,
49 MSS_MPU_SEG0,
50 MSS_MPU_SEG1,
51 } mss_mpu_mport_t;
52
53 typedef enum {
54 MSS_MPU_AM_OFF = 0x00U,
55 MSS_MPU_AM_NAPOT = 0x03U,
56 } mss_mpu_addrm_t;
57
58 typedef enum {
59 MSS_MPU_PMP_REGION0 = 0x00,
60 MSS_MPU_PMP_REGION1,
61 MSS_MPU_PMP_REGION2,
62 MSS_MPU_PMP_REGION3,
63 MSS_MPU_PMP_REGION4,
64 MSS_MPU_PMP_REGION5,
65 MSS_MPU_PMP_REGION6,
66 MSS_MPU_PMP_REGION7,
67 MSS_MPU_PMP_REGION8,
68 MSS_MPU_PMP_REGION9,
69 MSS_MPU_PMP_REGION10,
70 MSS_MPU_PMP_REGION11,
71 MSS_MPU_PMP_REGION12,
72 MSS_MPU_PMP_REGION13,
73 MSS_MPU_PMP_REGION14,
74 MSS_MPU_PMP_REGION15,
75 } mss_mpu_pmp_region_t;
76
77 extern uint8_t num_pmp_lut[10];
78
79 #ifndef __I
80 #define __I const volatile
81 #endif
82 #ifndef __IO
83 #define __IO volatile
84 #endif
85 #ifndef __O
86 #define __O volatile
87 #endif
88
89
90 typedef struct {
91 union {
92 struct
93 {
94 __IO uint64_t pmp : 38;
95 __IO uint64_t rsrvd : 18;
96 __IO uint64_t mode : 8;
97 } MPUCFG_TypeDef;
98 uint64_t raw;
99 };
100 } MPU_CFG;
101
102 typedef struct
103 {
104 __IO uint64_t addr : 38;
105 __IO uint64_t rw : 1;
106 __IO uint64_t id : 4;
107 __IO uint64_t failed : 1;
108 __IO uint64_t padding : (64-44);
109 } MPU_FailStatus_TypeDef;
110
111 typedef struct
112 {
113 MPU_CFG PMPCFG[16U];
114 __IO MPU_FailStatus_TypeDef STATUS;
115 } MPU_TypeDef;
116
117
118
119 #define MSS_MPU(master) ( (MPU_TypeDef*) (0x20005000UL + ((master) << 8U)))
120
121
122 uint8_t mpu_configure(void);
123
124
125 uint8_t MSS_MPU_configure(mss_mpu_mport_t master_port,
126 mss_mpu_pmp_region_t pmp_region,
127 uint64_t base,
128 uint64_t size,
129 uint8_t permission,
130 mss_mpu_addrm_t matching_mode,
131 uint8_t lock_en);
132
133 uint8_t MSS_MPU_get_config(mss_mpu_mport_t master_port,
134 mss_mpu_pmp_region_t pmp_region,
135 uint64_t* base,
136 uint64_t* size,
137 uint8_t* permission,
138 mss_mpu_addrm_t* matching_mode,
139 uint8_t* lock_en);
140
MSS_MPU_lock_region(mss_mpu_mport_t master_port,mss_mpu_pmp_region_t pmp_region)141 static inline uint8_t MSS_MPU_lock_region(mss_mpu_mport_t master_port,
142 mss_mpu_pmp_region_t pmp_region)
143 {
144 if(pmp_region < num_pmp_lut[master_port])
145 {
146 MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= (0x1U << 7U);
147 return (0U);
148 }
149 else
150 {
151 return (1U);
152 }
153 }
154
155 /*permission value could be bitwise or of:
156 * MPU_MODE_READ_ACCESS
157 * MPU_MODE_WRITE_ACCESS
158 * MPU_MODE_EXEC_ACCESS
159 *
160 * */
MSS_MPU_set_permission(mss_mpu_mport_t master_port,mss_mpu_pmp_region_t pmp_region,uint8_t permission)161 static inline uint8_t MSS_MPU_set_permission(mss_mpu_mport_t master_port,
162 mss_mpu_pmp_region_t pmp_region,
163 uint8_t permission)
164 {
165 if(pmp_region < num_pmp_lut[master_port])
166 {
167 MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= permission;
168 return (0U);
169 }
170 else
171 {
172 return (1U);
173 }
174 }
175
MSS_MPU_get_permission(mss_mpu_mport_t master_port,mss_mpu_pmp_region_t pmp_region,uint8_t * permission)176 static inline uint8_t MSS_MPU_get_permission(mss_mpu_mport_t master_port,
177 mss_mpu_pmp_region_t pmp_region,
178 uint8_t* permission)
179 {
180 if(pmp_region < num_pmp_lut[master_port])
181 {
182 *permission = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode & 0x7U;
183 return (0U);
184 }
185 else
186 {
187 return (1U);
188 }
189 }
190
191 /*read the Fail status register when there is a MPU access failure.
192 See the return type MPU_FailStatus_TypeDef for the details of the STATUS bitfield.
193 The status failed bit(offset 42) needs to be reset using the corresponding bit
194 in SYSREG->mpu_violation_sr
195 */
MSS_MPU_get_failstatus(mss_mpu_mport_t master_port)196 static inline MPU_FailStatus_TypeDef MSS_MPU_get_failstatus(mss_mpu_mport_t master_port)
197 {
198 return (MSS_MPU(master_port)->STATUS);
199 }
200
201 #endif /* ! SIFIVE_HIFIVE_UNLEASHED */
202
203 #ifdef __cplusplus
204 }
205 #endif
206
207
208 #endif /* MSS_MPU_H */
209