1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "cmsis.h"
16 #include "cmsis_nvic.h"
17 #include "plat_addr_map.h"
18 #include "hal_chipid.h"
19
20 #include "hal_sec.h"
21
22 #include CHIP_SPECIFIC_HDR(reg_sec)
23 #include CHIP_SPECIFIC_HDR(reg_mpc_spy)
24
25 //these sec regs can only be accessed in security state
26 static struct HAL_SEC_T *const sec = (struct HAL_SEC_T *)TRUST_ZONE_BASE;
27
hal_sec_set_gdma_nonsec(bool nonsec)28 void hal_sec_set_gdma_nonsec(bool nonsec)
29 {
30 if (nonsec)
31 sec->REG_00C |= (SEC_CFG_NONSEC_GDMA1 | SEC_CFG_NONSEC_GDMA2);
32 else
33 sec->REG_00C &= ~(SEC_CFG_NONSEC_GDMA1 | SEC_CFG_NONSEC_GDMA2);
34 }
35
hal_sec_set_adma_nonsec(bool nonsec)36 void hal_sec_set_adma_nonsec(bool nonsec)
37 {
38 if (nonsec)
39 sec->REG_00C |= (SEC_CFG_NONSEC_ADMA1 | SEC_CFG_NONSEC_ADMA2);
40 else
41 sec->REG_00C &= ~(SEC_CFG_NONSEC_ADMA1 | SEC_CFG_NONSEC_ADMA2);
42 }
43
hal_sec_set_bcm_nonsec(bool nonsec)44 void hal_sec_set_bcm_nonsec(bool nonsec)
45 {
46 if (nonsec)
47 sec->REG_00C |= SEC_CFG_NONSEC_BCM;
48 else
49 sec->REG_00C &= ~SEC_CFG_NONSEC_BCM;
50 }
51
hal_sec_set_cksum_nonsec(bool nonsec)52 void hal_sec_set_cksum_nonsec(bool nonsec)
53 {
54 if (nonsec)
55 sec->REG_00C |= SEC_CFG_NONSEC_CKSUM;
56 else
57 sec->REG_00C &= ~SEC_CFG_NONSEC_CKSUM;
58 }
59
hal_sec_set_crc_nonsec(bool nonsec)60 void hal_sec_set_crc_nonsec(bool nonsec)
61 {
62 if (nonsec)
63 sec->REG_00C |= SEC_CFG_NONSEC_CRC;
64 else
65 sec->REG_00C &= ~SEC_CFG_NONSEC_CRC;
66 }
67
hal_sec_set_usb_nonsec(bool nonsec)68 void hal_sec_set_usb_nonsec(bool nonsec)
69 {
70 if (nonsec)
71 sec->REG_00C |= SEC_CFG_NONSEC_USB;
72 else
73 sec->REG_00C &= ~SEC_CFG_NONSEC_USB;
74 }
75
hal_sec_set_i2c_slv_nonsec(bool nonsec)76 void hal_sec_set_i2c_slv_nonsec(bool nonsec)
77 {
78 if (nonsec)
79 sec->REG_00C |= SEC_CFG_NONSEC_I2C_SLV;
80 else
81 sec->REG_00C &= ~SEC_CFG_NONSEC_I2C_SLV;
82 }
83
hal_sec_set_bt2mcu_nonsec(bool nonsec)84 void hal_sec_set_bt2mcu_nonsec(bool nonsec)
85 {
86 if (nonsec)
87 sec->REG_00C |= SEC_CFG_NONSEC_BT2MCU;
88 else
89 sec->REG_00C &= ~SEC_CFG_NONSEC_BT2MCU;
90 }
91
hal_sec_set_wf2mcu_nonsec(bool nonsec)92 void hal_sec_set_wf2mcu_nonsec(bool nonsec)
93 {
94 if (nonsec)
95 sec->REG_00C |= SEC_CFG_NONSEC_WF2MCU;
96 else
97 sec->REG_00C &= ~SEC_CFG_NONSEC_WF2MCU;
98 }
99
hal_mpc_spy_nonsec_bypass(uint32_t addr,bool bypass)100 void hal_mpc_spy_nonsec_bypass(uint32_t addr, bool bypass)
101 {
102 struct HAL_MPC_SPY_T *base = (struct HAL_MPC_SPY_T *)addr;
103 if (bypass)
104 base->REG_000 |= MPC_SPY_MPC_CFG_NONSEC_BYPASS;
105 else
106 base->REG_000 &= ~MPC_SPY_MPC_CFG_NONSEC_BYPASS;
107 }
108
hal_sec_set_flashctrl_nonsec(bool nonsec)109 void hal_sec_set_flashctrl_nonsec(bool nonsec)
110 {
111 sec->REG_010 &= ~(1 << (4 + SEC_CFG_NONSEC_BYPASS_PROT_AHB1_SHIFT));
112 if (nonsec) {
113 sec->REG_010 |= (1<<4);
114 } else {
115 sec->REG_010 &= ~(1<<4);
116 }
117 }
118
hal_page_spy_init()119 static void hal_page_spy_init()
120 {
121 uint32_t *vector_table = NVIC_GetVectorTab();
122 NVIC_SetVector(PAGESPY_IRQn, (uint32_t)vector_table[3]); //HardFault Handler
123 NVIC_SetPriority(PAGESPY_IRQn, IRQ_PRIORITY_REALTIME);
124 NVIC_ClearPendingIRQ(PAGESPY_IRQn);
125 NVIC_EnableIRQ(PAGESPY_IRQn);
126 }
127
hal_page_spy_set(uint32_t spy_base,uint32_t start_addr,uint32_t len,bool write,bool read)128 void hal_page_spy_set(uint32_t spy_base, uint32_t start_addr, uint32_t len, bool write, bool read)
129 {
130 struct HAL_MPC_SPY_T *base = (struct HAL_MPC_SPY_T *)spy_base;
131
132 hal_page_spy_init();
133
134 base->REG_008 = MPC_SPY_REG_STR_ADDR0(start_addr);
135 base->REG_00C = MPC_SPY_REG_STR_ADDR0(start_addr + len - 1);
136
137 base->REG_004 = MPC_SPY_REG_ENABLE0 | (read?MPC_SPY_REG_DETECT_READ0:0) | (write?MPC_SPY_REG_DETECT_WRITE0:0);
138 }
hal_sec_init()139 void hal_sec_init()
140 {
141 if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_4) {
142 #ifdef ARM_CMSE
143 //dr mode, dr non sec
144 sec->REG_00C &= ~(SEC_CFG_NONSEC_A7_AUTO | SEC_CFG_NONSEC_A7); //a7 non sec
145 sec->REG_00C &= ~(SEC_CFG_NONSEC_CP_AUTO | SEC_CFG_NONSEC_CP); //cp non sec
146 #else
147 //audo mode
148 sec->REG_00C |= (SEC_CFG_NONSEC_CP_AUTO | SEC_CFG_NONSEC_A7_AUTO);
149 #endif
150 }
151 }
152
hal_sec_idau_enable(bool enable)153 void hal_sec_idau_enable(bool enable)
154 {
155 if (enable) {
156 sec->REG_034 |= SEC_IDAUEN_CORE0;
157 } else {
158 sec->REG_034 &= ~SEC_IDAUEN_CORE0;
159 }
160 }
161