1 /*
2  * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef FIREWALL_H
9 #define FIREWALL_H
10 
11 #include <stdint.h>
12 
13 #define PE_CTRL_EN_OFF              0x1Fu
14      /*!< Protection Extenstion Control enable bit field offset */
15 #define PE_CTRL_EN_BYPASS_OFF       0x5u
16      /*!< Protection Extenstion Control bypass enable bit field offset */
17 #define PE_ST_EN_OFF                0x1Fu
18      /*!< Protection Extenstion Status enable bit field offset */
19 #define PE_BPS_BYPASS_ST_OFF        0x1u
20      /*!< Protection Extenstion Bypass status field offset */
21 
22 #define RWE_CTRL_RGN_INDX_OFF       0x0u
23   /*!< RWE Control Region Index offset */
24 #define RGN_EN_OFF                  0x0u
25   /*!< Region enable offset */
26 #define RGN_LCTRL_LOCK_OFF          0x0u
27   /*!< Region Lock Control lock offset */
28 #define RGN_MPE0_EN_OFF             0x1u
29   /*!< Region MPE0 enable offset */
30 #define RGN_MPE1_EN_OFF             0x2u
31   /*!< Region MPE1 enable offset */
32 #define RGN_MPE2_EN_OFF             0x3u
33   /*!< Region MPE2 enable offset */
34 #define RGN_MPE3_EN_OFF             0x4u
35   /*!< Region MPE3 enable offset */
36 #define RGN_SIZE_SIZE_OFF           0x0u
37   /*!< Region Size Size offset */
38 #define RGN_SIZE_MULnPO2_OFF        0x8u
39   /*!< Region Size MULnPO2 offset */
40 #define RGN_TCFG2_ADDR_TRANS_EN_OFF 0x11u
41   /*!< Region Translation Config 2 Address Translation enable offset */
42 #define RGN_TCFG2_MA_TRANS_EN_OFF   0x10u
43   /*!< Region Translation Config 2 Memory Attribute Translation enable offset */
44 #define RGN_TCFG2_INST_OFF          0xEu
45   /*!< Region Translation Config 2 Output txn instruction or data offset */
46 #define RGN_TCFG2_PRIV_OFF          0xCu
47   /*!< Region Translation Config 2 Output txn privileged level offset */
48 #define RGN_TCFG2_MA_OFF            0x4u
49   /*!< Region Translation Config 2 Output txn memory attribute offset */
50 #define RGN_TCFG2_SH_OFF            0x2u
51   /*!< Region Translation Config 2 Output txn shareability offset */
52 #define RGN_TCFG2_NS_OFF            0x0u
53   /*!< Region Translation Config 2 Output txn security offset */
54 #define RGN_MPL_ANY_MST_OFF         0xCu
55   /*!< Region Master Permission List Any Master ID offset */
56 #define RGN_MPL_SPX_OFF             0xBu
57   /*!< Region Master Permission List S privilege execute enable offset */
58 #define RGN_MPL_SPW_OFF             0xAu
59   /*!< Region Master Permission List S privilege write enable offset */
60 #define RGN_MPL_SPR_OFF             0x9u
61   /*!< Region Master Permission List S privilege read enable offset */
62 #define RGN_MPL_SUX_OFF             0x8u
63   /*!< Region Master Permission List S unprivileged execute enable offset */
64 #define RGN_MPL_SUW_OFF             0x7u
65   /*!< Region Master Permission List S unprivileged write enable offset */
66 #define RGN_MPL_SUR_OFF             0x6u
67   /*!< Region Master Permission List S unprivileged read enable offset */
68 #define RGN_MPL_NSPX_OFF            0x5u
69   /*!< Region Master Permission List NS privilege execute enable offset */
70 #define RGN_MPL_NSPW_OFF            0x4u
71   /*!< Region Master Permission List NS privilege write enable offset */
72 #define RGN_MPL_NSPR_OFF            0x3u
73   /*!< Region Master Permission List NS privilege read enable offset */
74 #define RGN_MPL_NSUX_OFF            0x2u
75   /*!< Region Master Permission List NS unprivileged execute enable offset */
76 #define RGN_MPL_NSUW_OFF            0x1u
77   /*!< Region Master Permission List NS unprivileged write enable offset */
78 #define RGN_MPL_NSUR_OFF            0x0u
79   /*!< Region Master Permission List NS unprivileged read enable offset */
80 
81 #define LD_CTRL_LOCK_OFF            0x0u
82 #define LD_CTRL_LDI_ST_OFF          0x2u
83 
84 /**
85  * \brief Firewall region size values
86  */
87 enum rgn_size_t {
88   RGN_SIZE_0B    = (0x00u),
89   RGN_SIZE_32B   = (0x05u),
90   RGN_SIZE_64B,
91   RGN_SIZE_128B,
92   RGN_SIZE_256B,
93   RGN_SIZE_512B,
94   RGN_SIZE_1KB,
95   RGN_SIZE_2KB,
96   RGN_SIZE_4KB,
97   RGN_SIZE_8KB,
98   RGN_SIZE_16KB,
99   RGN_SIZE_32KB,
100   RGN_SIZE_64KB,
101   RGN_SIZE_128KB,
102   RGN_SIZE_256KB,
103   RGN_SIZE_512KB,
104   RGN_SIZE_1MB,
105   RGN_SIZE_2MB,
106   RGN_SIZE_4MB,
107   RGN_SIZE_8MB,
108   RGN_SIZE_16MB,
109   RGN_SIZE_32MB,
110   RGN_SIZE_64MB,
111   RGN_SIZE_128MB,
112   RGN_SIZE_256MB,
113   RGN_SIZE_512MB,
114   RGN_SIZE_1GB,
115   RGN_SIZE_2GB,
116   RGN_SIZE_16EB  = (0x40u),
117 };
118 
119 enum rgn_mpe_t {
120   RGN_MPE0 = (0x1u << RGN_MPE0_EN_OFF),
121   RGN_MPE1 = (0x1u << RGN_MPE1_EN_OFF),
122   RGN_MPE2 = (0x1u << RGN_MPE2_EN_OFF),
123   RGN_MPE3 = (0x1u << RGN_MPE3_EN_OFF),
124 };
125 
126 enum rgn_mpl_t {
127   RGN_MPL_ANY_MST_MASK = (0x1u << RGN_MPL_ANY_MST_OFF),
128   RGN_MPL_SPX_MASK     = (0x1u << RGN_MPL_SPX_OFF),
129   RGN_MPL_SPW_MASK     = (0x1u << RGN_MPL_SPW_OFF),
130   RGN_MPL_SPR_MASK     = (0x1u << RGN_MPL_SPR_OFF),
131   RGN_MPL_SUX_MASK     = (0x1u << RGN_MPL_SUX_OFF),
132   RGN_MPL_SUW_MASK     = (0x1u << RGN_MPL_SUW_OFF),
133   RGN_MPL_SUR_MASK     = (0x1u << RGN_MPL_SUR_OFF),
134   RGN_MPL_NSPX_MASK    = (0x1u << RGN_MPL_NSPX_OFF),
135   RGN_MPL_NSPW_MASK    = (0x1u << RGN_MPL_NSPW_OFF),
136   RGN_MPL_NSPR_MASK    = (0x1u << RGN_MPL_NSPR_OFF),
137   RGN_MPL_NSUX_MASK    = (0x1u << RGN_MPL_NSUX_OFF),
138   RGN_MPL_NSUW_MASK    = (0x1u << RGN_MPL_NSUW_OFF),
139   RGN_MPL_NSUR_MASK    = (0x1u << RGN_MPL_NSUR_OFF),
140 };
141 
142 
143 #define RGN_MPL_SECURE_READ_MASK       (RGN_MPL_SUR_MASK | RGN_MPL_SPR_MASK)
144 #define RGN_MPL_SECURE_WRITE_MASK      (RGN_MPL_SUW_MASK | RGN_MPL_SPW_MASK)
145 #define RGN_MPL_SECURE_EXECUTE_MASK    (RGN_MPL_SUX_MASK | RGN_MPL_SPX_MASK)
146 
147 #define RGN_MPL_NONSECURE_READ_MASK    (RGN_MPL_NSUR_MASK | RGN_MPL_NSPR_MASK)
148 #define RGN_MPL_NONSECURE_WRITE_MASK   (RGN_MPL_NSUW_MASK | RGN_MPL_NSPW_MASK)
149 #define RGN_MPL_NONSECURE_EXECUTE_MASK (RGN_MPL_NSUX_MASK | RGN_MPL_NSPX_MASK)
150 
151 enum fw_lockdown_status_t {
152   FW_UNLOCKED = 0x0u,
153   FW_LOCKED   = 0x1u,
154 };
155 
156 enum fw_lockdown_state_t {
157   FW_OPEN_LOCKDOWN    = 0x0u,
158   FW_PARTIAL_LOCKDOWN = 0x2u,
159   FW_FULL_LOCKDOWN    = 0x3u,
160 };
161 
162 struct fw_dev_data_t {
163     void *base_addr;        /*!< Current FW base address */
164     uint32_t comp_id;       /*!< Current FC id */
165     void *cs_ptr;          /*!< Selected FC Control & Status address */
166     void *rwe_ptr;          /*!< Selected FC Region Window Entry address */
167 };
168 
169 /**
170  * \brief Selects a Firewall Component
171  */
172 void fc_select(void *base_addr, uint32_t comp_id);
173 
174 /**
175  * \brief Enables bypass in the selected Firewall Component
176  */
177 void fc_enable_bypass(void);
178 
179 /**
180  * \brief Disables bypass in the selected Firewall Component
181  */
182 void fc_disable_bypass(void);
183 
184 /**
185  * \brief Enables Protection Extenstion in the selected Firewall Component
186  */
187 void fc_pe_enable(void);
188 
189 /**
190  * \brief Disables Protection Extenstion in the selected Firewall Component
191  */
192 void fc_pe_disable(void);
193 
194 /**
195  * \brief Disables the error generation in response for transaction generating
196  *        a Configuration Access Error
197  */
198 void fc_disable_txn_term_error(void *base_addr);
199 
200 /**
201  * \brief Selects a region in the selected Firewall Component
202  */
203 void fc_select_region(uint32_t region_id);
204 
205 /**
206  * \brief Enables a region in the selected Firewall Component
207  */
208 void fc_enable_regions(void);
209 
210 /**
211  * \brief Disables a region in the selected Firewall Component
212  */
213 void fc_disable_regions(void);
214 
215 /**
216  * \brief Programs a region in the selected Firewall Component
217  */
218 void fc_prog_rgn(enum rgn_size_t size, uint32_t base_addr);
219 
220 /**
221  * \brief Programs the upper address in the selected Firewall Component
222  */
223 void fc_prog_rgn_upper_addr(uint32_t upper_addr);
224 
225 /**
226  * \brief Enables address translation in the selected Firewall Component
227  */
228 void fc_enable_addr_trans(void);
229 
230 /**
231  * \brief Disables address translation in the selected Firewall Component
232  */
233 void fc_disable_addr_trans(void);
234 
235 /**
236  * \brief Initializes the Master Permission List in selected Firewall Component
237  * \note Before enabling an MPE, it must:
238  *       1) Set the RGN_MPL fields with an UNKNOWN reset value to a known value.
239  *       2) Set either:
240  *          RGN_MID{0-3} to a known value.
241  *          RGN_MPL.ANY_MST to 0b1.
242  */
243 void fc_init_mpl(enum rgn_mpe_t mpe);
244 
245 /**
246  * \brief Enables Master Permission List in the selected Firewall Component
247  */
248 void fc_enable_mpl(enum rgn_mpe_t mpe, enum rgn_mpl_t mpl);
249 
250 /**
251  * \brief Reads Master Permission List in the selected Firewall Component
252  */
253 void fc_read_mpl(enum rgn_mpe_t mpe, enum rgn_mpl_t* mpl);
254 
255 /**
256  * \brief Disables Master Permission List in the selected Firewall Component
257  */
258 void fc_disable_mpl(enum rgn_mpe_t mpe, enum rgn_mpl_t mpl);
259 
260 /**
261  * \brief Programs Master ID in the given Master permission entry
262  */
263 void fc_prog_mid(enum rgn_mpe_t mpe, uint32_t mid);
264 
265 /**
266  * \brief Enables Master permission entry in the selected Firewall Component
267  */
268 void fc_enable_mpe(enum rgn_mpe_t mpe);
269 
270 /**
271  * \brief Disables Master permission entry in the selected Firewall Component
272  */
273 void fc_disable_mpe(enum rgn_mpe_t mpe);
274 
275 /**
276  * \brief Locks the selected region in the selected Firewall Component
277  */
278 void fc_rgn_lock(void);
279 
280 /**
281  * \brief Unlocks the selected region in the selected Firewall Component
282  */
283 void fc_rgn_unlock(void);
284 
285 /**
286  * \brief Returns the lockdown status of the Firewall IP
287  */
288 enum fw_lockdown_status_t fw_get_lockdown_status(void);
289 
290 /**
291  * \brief Locksdown the Firewall IP
292  */
293 void fw_lockdown(enum fw_lockdown_state_t lockdown_state);
294 
295 #endif /* FIREWALL_H */
296