1 /*
2  * SPDX-FileCopyrightText: 2019-2025 SiFli Technologies(Nanjing) Co., Ltd
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "bf0_hal.h"
8 
9 /** @addtogroup BF0_HAL_Driver
10   * @{
11   */
12 
13 /** @defgroup SECU Security
14   * @brief Security HAL module driver
15   * @{
16   */
17 
18 #if defined(HAL_SECU_MODULE_ENABLED)||defined(_SIFLI_DOXYGEN_)
19 
20 typedef struct
21 {
22     uint8_t  memory_type;
23     uint8_t  secu_flag;
24     uint8_t  reg_cnt;
25     uint8_t  reserved;
26     uint32_t *reg_addr;
27 } MemRegInfo;
28 
29 static const MemRegInfo MemRegList[] =
30 {
31     {SECU_MEM_MPI1, SECU_FLAG_PRIV, 2, 0, (uint32_t *) &hwp_secu1->MPI1_PRIV_CFG0},
32     {SECU_MEM_MPI1, SECU_FLAG_SECU, 2, 0, (uint32_t *) &hwp_secu1->MPI1_SEC_CFG0},
33     {SECU_MEM_MPI2, SECU_FLAG_PRIV, 2, 0, (uint32_t *) &hwp_secu1->MPI2_PRIV_CFG0},
34     {SECU_MEM_MPI2, SECU_FLAG_SECU, 2, 0, (uint32_t *) &hwp_secu1->MPI2_SEC_CFG0},
35     {SECU_MEM_HPSYS_RAM0, SECU_FLAG_PRIV, 1, 0, (uint32_t *) &hwp_secu1->RAM0_PRIV_CFG0},
36     {SECU_MEM_HPSYS_RAM0, SECU_FLAG_SECU, 1, 0, (uint32_t *) &hwp_secu1->RAM0_SEC_CFG0},
37     {SECU_MEM_HPSYS_RAM1, SECU_FLAG_PRIV, 1, 0, (uint32_t *) &hwp_secu1->RAM1_PRIV_CFG0},
38     {SECU_MEM_HPSYS_RAM1, SECU_FLAG_SECU, 1, 0, (uint32_t *) &hwp_secu1->RAM1_SEC_CFG0},
39     {SECU_MEM_HPSYS_RAM2, SECU_FLAG_PRIV, 1, 0, (uint32_t *) &hwp_secu1->RAM2_PRIV_CFG0},
40     {SECU_MEM_HPSYS_RAM2, SECU_FLAG_SECU, 1, 0, (uint32_t *) &hwp_secu1->RAM2_SEC_CFG0},
41 
42     {SECU_MEM_LPSYS_RAM0, SECU_FLAG_PRIV, 1, 0, (uint32_t *) &hwp_secu2->RAM0_PRIV_CFG0},
43     {SECU_MEM_LPSYS_RAM0, SECU_FLAG_SECU, 1, 0, (uint32_t *) &hwp_secu2->RAM0_SEC_CFG0},
44     {SECU_MEM_LPSYS_RAM1, SECU_FLAG_PRIV, 1, 0, (uint32_t *) &hwp_secu2->RAM1_PRIV_CFG0},
45     {SECU_MEM_LPSYS_RAM1, SECU_FLAG_SECU, 1, 0, (uint32_t *) &hwp_secu2->RAM1_SEC_CFG0}
46 };
47 
HAL_SECU_SetAttr(SECU_MODULE_TYPE module,uint32_t role,uint32_t flag)48 HAL_StatusTypeDef HAL_SECU_SetAttr(SECU_MODULE_TYPE module, uint32_t role, uint32_t flag)
49 {
50     volatile uint32_t *p_reg;
51     uint32_t bit_n, tmp;
52     if (role & SECU_ROLE_MASTER)
53     {
54         switch (module)
55         {
56         /*SECU1*/
57         case SECU_MOD_PTC1:
58             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
59             bit_n = SECU1_HPMST_ATTR_CFG_PTC1_SEC_Pos;
60             break;
61         case SECU_MOD_DMAC1:
62             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
63             bit_n = SECU1_HPMST_ATTR_CFG_DMAC1_SEC_Pos;
64             break;
65         case SECU_MOD_USBC:
66             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
67             bit_n = SECU1_HPMST_ATTR_CFG_USB_SEC_Pos;
68             break;
69         case SECU_MOD_AES:
70             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
71             bit_n = SECU1_HPMST_ATTR_CFG_AES_SEC_Pos;
72             break;
73         case SECU_MOD_LCDC1:
74             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
75             bit_n = SECU1_HPMST_ATTR_CFG_LCDC_SEC_Pos;
76             break;
77         case SECU_MOD_EPIC:
78             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
79             bit_n = SECU1_HPMST_ATTR_CFG_EPIC_SEC_Pos;
80             break;
81         case SECU_MOD_EXTDMA:
82             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
83             bit_n = SECU1_HPMST_ATTR_CFG_EXTDMA_SEC_Pos;
84             break;
85         case SECU_MOD_HCPU:
86             p_reg = &(hwp_secu1->HPMST_ATTR_CFG);
87             bit_n = SECU1_HPMST_ATTR_CFG_HCPU_SEC_Pos;
88             break;
89 
90 
91 
92         /*SECU2*/
93         case SECU_MOD_LCPU:
94             p_reg = &(hwp_secu2->LPMST_ATTR_CFG);
95             bit_n = SECU2_LPMST_ATTR_CFG_LCPU_SEC_Pos;
96             break;
97         case SECU_MOD_PTC2:
98             p_reg = &(hwp_secu2->LPMST_ATTR_CFG);
99             bit_n = SECU2_LPMST_ATTR_CFG_PTC2_SEC_Pos;
100             break;
101         case SECU_MOD_DMAC2:
102             p_reg = &(hwp_secu2->LPMST_ATTR_CFG);
103             bit_n = SECU2_LPMST_ATTR_CFG_DMAC2_SEC_Pos;
104             break;
105 
106         default:
107             HAL_ASSERT(0);
108             return HAL_ERROR;
109         }
110 
111         tmp = *p_reg;
112         if ((module != SECU_MOD_HCPU) && (module != SECU_MOD_LCPU)) //No privilege bit for HCPU&LCPU
113         {
114             tmp |= 1 << (bit_n + 3); //set xxx_priv_use
115             if (flag & SECU_FLAG_PRIV)
116             {
117                 tmp |= 1 << (bit_n + 1); //set xxx_priv
118             }
119             else
120             {
121                 tmp &= ~(1 << (bit_n + 1)); //clear xxx_priv
122             }
123         }
124 
125         tmp |= 1 << (bit_n + 2); //set xxx_sec_use
126         if (flag & SECU_FLAG_SECU)
127         {
128             tmp |= 1 << (bit_n + 0); //set xxx_sec
129         }
130         else
131         {
132             tmp &= ~(1 << (bit_n + 0)); //clear xxx_sec
133         }
134 
135         *p_reg = tmp;
136 
137     }
138 
139 
140     if (role & SECU_ROLE_SLAVE)
141     {
142         switch (module)
143         {
144         /*SECU1*/
145         case SECU_MOD_PTC1:
146             p_reg = &(hwp_secu1->HPSLV_ATTR_CFG);
147             bit_n = SECU1_HPSLV_ATTR_CFG_PTC1_SEC_Pos;
148             break;
149         case SECU_MOD_DMAC1:
150             p_reg = &(hwp_secu1->HPSLV_ATTR_CFG);
151             bit_n = SECU1_HPSLV_ATTR_CFG_DMAC1_SEC_Pos;
152             break;
153         case SECU_MOD_AES:
154             p_reg = &(hwp_secu1->HPSLV_ATTR_CFG);
155             bit_n = SECU1_HPSLV_ATTR_CFG_AES_SEC_Pos;
156             break;
157         case SECU_MOD_TRNG:
158             p_reg = &(hwp_secu1->HPSLV_ATTR_CFG);
159             bit_n = SECU1_HPSLV_ATTR_CFG_TRNG_SEC_Pos;
160             break;
161         case SECU_MOD_EFUSE:
162             p_reg = &(hwp_secu1->HPSLV_ATTR_CFG);
163             bit_n = SECU1_HPSLV_ATTR_CFG_EFUSE_SEC_Pos;
164             break;
165 
166 
167         /*SECU2*/
168         case SECU_MOD_PTC2:
169             p_reg = &(hwp_secu2->LPSLV_ATTR_CFG);
170             bit_n = SECU2_LPSLV_ATTR_CFG_PTC2_SEC_Pos;
171             break;
172         case SECU_MOD_DMAC2:
173             p_reg = &(hwp_secu2->LPSLV_ATTR_CFG);
174             bit_n = SECU2_LPSLV_ATTR_CFG_DMAC2_SEC_Pos;
175             break;
176 
177         default:
178             HAL_ASSERT(0);
179             return HAL_ERROR;
180         }
181 
182         tmp = *p_reg;
183 
184         if (flag & SECU_FLAG_PRIV)
185         {
186             tmp |= 1 << (bit_n + 1); //set xxx_priv
187         }
188         else
189         {
190             tmp &= ~(1 << (bit_n + 1)); //clear xxx_priv
191         }
192 
193         if (flag & SECU_FLAG_SECU)
194         {
195             tmp |= 1 << (bit_n + 0); //set xxx_sec
196         }
197         else
198         {
199             tmp &= ~(1 << (bit_n + 0)); //clear xxx_sec
200         }
201 
202         *p_reg = tmp;
203 
204     }
205 
206     return HAL_OK;
207 }
208 
209 /*Treat S-bus C-bus access as same address*/
210 #define SECU_MEM_ADDR(addr) ((addr) & 0x0FFFFFFF)
211 #define SECU_HPMEM_ADDR(addr) ((addr) & 0x00FFFFFF)
212 
HAL_SECU_SetMemoryAttr(SECU_MEM_TYPE memory_type,const SECU_MemAttr_Type * attrs,uint32_t attrs_cnt)213 HAL_StatusTypeDef HAL_SECU_SetMemoryAttr(SECU_MEM_TYPE memory_type, const SECU_MemAttr_Type *attrs, uint32_t attrs_cnt)
214 {
215     uint32_t i, j, k;
216     for (i = 0; i < attrs_cnt; i++)
217     {
218         if ((SECU_MEMRange_ALIGN(attrs[i].start) != attrs[i].start)
219                 || (SECU_MEMRange_ALIGN(attrs[i].end) != attrs[i].end))
220         {
221             return HAL_ERROR; //Address not aligned.
222         }
223 
224         if (attrs[i].start >= attrs[i].end)
225         {
226             return HAL_ERROR;//end address must larger than start addr.
227         }
228 
229         for (j = 0; j < sizeof(MemRegList) / sizeof(MemRegList[0]); j++)
230         {
231             if ((MemRegList[j].memory_type == memory_type) && (MemRegList[j].secu_flag == attrs[i].flag))
232             {
233                 volatile uint32_t *start_addr, *end_addr;
234 
235                 start_addr = MemRegList[j].reg_addr;
236                 end_addr   = start_addr + 1;
237                 for (k = 0; k < MemRegList[j].reg_cnt; k++)
238                 {
239 
240                     if (*start_addr > *end_addr)
241                     {
242                         if ((SECU_MEM_HPSYS_RAM0 == memory_type)
243                                 || (SECU_MEM_HPSYS_RAM1 == memory_type)
244                                 || (SECU_MEM_HPSYS_RAM2 == memory_type))
245                         {
246                             *start_addr = SECU_HPMEM_ADDR(attrs[i].start);
247                             *end_addr   = SECU_HPMEM_ADDR(attrs[i].end - SECU_MEM_MIN_BLOCK);
248                         }
249                         else
250                         {
251                             *start_addr = SECU_MEM_ADDR(attrs[i].start) ;
252                             *end_addr   = SECU_MEM_ADDR(attrs[i].end - SECU_MEM_MIN_BLOCK);
253                         }
254 
255                         break; //Write attrs[i] success
256                     }
257 
258                     //Move to next range registers
259                     start_addr += 2;
260                     end_addr   += 2;
261                 }
262 
263                 if (MemRegList[j].reg_cnt == k)
264                 {
265                     return HAL_ERROR; //None available memory register
266                 }
267 
268                 break; //Write attrs[i] success
269             }
270         }
271 
272 
273         if (sizeof(MemRegList) / sizeof(MemRegList[0]) == j)
274         {
275             return HAL_ERROR; //Can't find matched record in MemRegList
276         }
277     }
278 
279 
280     return HAL_OK;
281 }
282 
283 
HAL_SECU_ApplyAndLock(SECU_GROUP_TYPE group)284 HAL_StatusTypeDef HAL_SECU_ApplyAndLock(SECU_GROUP_TYPE group)
285 {
286     switch (group)
287     {
288     case SECU_GROUP_HPMST:
289         hwp_secu1->SECU_CTRL = SECU1_SECU_CTRL_HPMST_ATTR_UPDATE | SECU1_SECU_CTRL_HPMST_LOCK;
290         break;
291     case SECU_GROUP_HPSLV:
292         hwp_secu1->SECU_CTRL = SECU1_SECU_CTRL_HPSLV_LOCK;
293         break;
294     case SECU_GROUP_HPMPI1:
295         hwp_secu1->SECU_CTRL = SECU1_SECU_CTRL_MPI1_LOCK;
296         break;
297     case SECU_GROUP_HPMPI2:
298         hwp_secu1->SECU_CTRL = SECU1_SECU_CTRL_MPI2_LOCK;
299         break;
300     case SECU_GROUP_HPRAM:
301         hwp_secu1->SECU_CTRL = SECU1_SECU_CTRL_RAM_LOCK;
302         break;
303 
304     case SECU_GROUP_LPMST:
305         hwp_secu2->SECU_CTRL = SECU2_SECU_CTRL_LPMST_ATTR_UPDATE | SECU2_SECU_CTRL_LPMST_LOCK;
306         break;
307     case SECU_GROUP_LPSLV:
308         hwp_secu2->SECU_CTRL = SECU2_SECU_CTRL_LPSLV_LOCK;
309         break;
310     case SECU_GROUP_LPRAM:
311         hwp_secu2->SECU_CTRL = SECU2_SECU_CTRL_RAM_LOCK;
312         break;
313     default:
314         return HAL_ERROR;
315     }
316 
317     return HAL_OK;
318 }
319 
320 
HAL_SECU_Apply(SECU_GROUP_TYPE group)321 HAL_StatusTypeDef HAL_SECU_Apply(SECU_GROUP_TYPE group)
322 {
323     switch (group)
324     {
325     case SECU_GROUP_HPMST:
326         hwp_secu1->SECU_CTRL = SECU1_SECU_CTRL_HPMST_ATTR_UPDATE;
327         break;
328 
329     case SECU_GROUP_LPMST:
330         hwp_secu2->SECU_CTRL = SECU2_SECU_CTRL_LPMST_ATTR_UPDATE;
331         break;
332 
333     default:
334         return HAL_ERROR;
335     }
336 
337     return HAL_OK;
338 }
339 
340 
341 
342 #endif /* HAL_SECU_MODULE_ENABLED */
343 /**
344   * @}
345   */
346 
347 /**
348   * @}
349   */