1 /*
2  * =====================================================================================
3  *
4  *       Filename:  hal_efuse.c
5  *
6  *    Description:  efuse
7  *
8  *        Version:  1.0
9  *        Created:  2019-07-19
10  *       Revision:  none
11  *       Compiler:  gcc
12  *
13  *         Author:  wangwei
14  *   Organization:
15  *
16  * =====================================================================================
17  */
18 
19 #include <stdio.h>
20 #include <string.h>
21 #include <sunxi_hal_efuse.h>
22 #include <sunxi_hal_common.h>
23 #include <hal_osal.h>
24 
25 #include "platform_efuse.h"
26 #include "efuse.h"
27 
28 #define EFUSE_CHIPID_NAME            "chipid"
29 #define EFUSE_BROM_CONF_NAME         "brom_conf"
30 #define EFUSE_BROM_TRY_NAME          "brom_try"
31 #define EFUSE_THM_SENSOR_NAME        "thermal_sensor"
32 
33 #define EFUSE_FT_ZONE_NAME           "ft_zone"
34 #define EFUSE_TV_OUT_NAME            "tvout"
35 #define EFUSE_OEM_NAME               "oem"
36 #define EFUSE_OEM_SEC_NAME           "oem_secure"
37 #define EFUSE_EMAC_NAME              "emac"
38 
39 #define EFUSE_WR_PROTECT_NAME        "write_protect"
40 #define EFUSE_RD_PROTECT_NAME        "read_protect"
41 #define EFUSE_IN_NAME                "in"
42 #define EFUSE_ID_NAME                "id"
43 #define EFUSE_ROTPK_NAME             "rotpk"
44 #define EFUSE_SSK_NAME               "ssk"
45 #define EFUSE_RSSK_NAME              "rssk"
46 #define EFUSE_HDCP_HASH_NAME         "hdcp_hash"
47 #define EFUSE_HDCP_PKF_NAME          "hdcp_pkf"
48 #define EFUSE_HDCP_DUK_NAME          "hdcp_duk"
49 #define EFUSE_EK_HASH_NAME           "ek_hash"
50 #define EFUSE_SN_NAME                "sn"
51 #define EFUSE_NV1_NAME               "nv1"
52 #define EFUSE_NV2_NAME               "nv2"
53 #define EFUSE_BACKUP_KEY_NAME        "backup_key"
54 #define EFUSE_RSAKEY_HASH_NAME       "rsakey_hash"
55 #define EFUSE_RENEW_NAME             "renewability"
56 #define EFUSE_IPTV_MAC              "efusemac"
57 #define EFUSE_OPT_ID_NAME            "operator_id"
58 #define EFUSE_LIFE_CYCLE_NAME        "life_cycle"
59 #define EFUSE_JTAG_SECU_NAME         "jtag_security"
60 #define EFUSE_JTAG_ATTR_NAME         "jtag_attr"
61 #define EFUSE_CHIP_CONF_NAME         "chip_config"
62 #define EFUSE_RESERVED_NAME          "reserved"
63 #define EFUSE_RESERVED2_NAME         "reserved2"
64 #define EFUSE_HUK_NAME               "huk"
65 #define EFUSE_ANTI_BLUSH_NAME        "anti_blushing"
66 #define EFUSE_TVE_NAME               "tve"
67 
68 /* For KeyLadder */
69 #define EFUSE_KL_SCK0_NAME           "keyladder_sck0"
70 #define EFUSE_KL_KEY0_NAME           "keyladder_master_key0"
71 #define EFUSE_KL_SCK1_NAME           "keyladder_sck1"
72 #define EFUSE_KL_KEY1_NAME           "keyladder_master_key1"
73 
74 #define SUNXI_KEY_NAME_LEN  64
75 
76 
77 #if EFUSE_DBG_EN
78 #define EFUSE_DBG(fmt,args...)  hal_log_debug(fmt ,##args)
79 #define EFUSE_DBG_E   1
80 static unsigned int g_err_flg = 0;
81 #else
82 #define EFUSE_DBG_DUMP(...) do{} while(0);
83 #define EFUSE_DBG(...) do{} while(0);
84 #define EFUSE_DBG_E   0
85 #endif
86 
87 static hal_spinlock_t efuse_lock;
88 
89 int __efuse_acl_ck(efuse_key_map_new_t *key_map,int burn);
90 
91 
92 static efuse_key_map_new_t g_key_info[] = {
93 EFUSE_DEF_ITEM(EFUSE_CHIPID_NAME, 0x0, 128, -1, 0, EFUSE_RO),
94 EFUSE_DEF_ITEM(EFUSE_THM_SENSOR_NAME, EFUSE_THERMAL_SENSOR, 64, -1, 0, EFUSE_RO),
95 EFUSE_DEF_ITEM(EFUSE_FT_ZONE_NAME, EFUSE_TF_ZONE, 128, -1, 0, EFUSE_RO),
96 #ifdef EFUSE_ROTPK
97 EFUSE_DEF_ITEM(EFUSE_ROTPK_NAME, EFUSE_ROTPK, 256, -1, 12, EFUSE_RO),
98 #endif
99 #ifdef EFUSE_NV1
100 EFUSE_DEF_ITEM(EFUSE_NV1_NAME, EFUSE_NV1, 32, -1, 15, EFUSE_RO),
101 #endif
102 #ifdef EFUSE_PSENSOR
103 EFUSE_DEF_ITEM("psensor", EFUSE_PSENSOR, 32, -1, 15, EFUSE_RO),
104 #endif
105 #ifdef EFUSE_TVOUT
106 EFUSE_DEF_ITEM(EFUSE_TV_OUT_NAME, EFUSE_TVOUT, SID_TVOUT_SIZE, -1, -1, EFUSE_RO),
107 #endif
108 //EFUSE_DEF_ITEM("anti_blushing", EFUSE_ANTI_BLUSHING, 32, -1, 15, EFUSE_RO),
109 //EFUSE_DEF_ITEM(EFUSE_RESERVED_NAME, EFUSE_CLIENT_RESERVE, 256, -1, 12, EFUSE_RO),
110 EFUSE_DEF_ITEM("", 0, 0, 0, 0, EFUSE_PRIVATE),
111 };
112 
113 
_efuse_reg_read_key(uint key_index)114 static uint _efuse_reg_read_key(uint key_index)
115 {
116     uint reg_val;
117     uint32_t cpu_sr;
118 
119 //  taskENTER_CRITICAL(cpu_sr);
120     //rt_enter_critical();
121     cpu_sr = hal_spin_lock_irqsave(&efuse_lock);
122 
123     reg_val = hal_readl((unsigned long)SID_PRCTL);
124     reg_val &= ~((0x1ff<<16)|0x3);
125     reg_val |= key_index<<16;
126     hal_writel(reg_val, (unsigned long)SID_PRCTL);
127     reg_val &= ~((0xff<<8)|0x3);
128     reg_val |= (SID_OP_LOCK<<8) | 0x2;
129     hal_writel(reg_val, (unsigned long)SID_PRCTL);
130     while(hal_readl(SID_PRCTL)&0x2){};
131     reg_val &= ~((0x1ff<<16)|(0xff<<8)|0x3);
132     hal_writel(reg_val, (unsigned long)SID_PRCTL);
133     reg_val = hal_readl((unsigned long)SID_RDKEY);
134 
135     hal_spin_unlock_irqrestore(&efuse_lock, cpu_sr);
136     //rt_exit_critical();
137 //  taskEXIT_CRITICAL(cpu_sr);
138     return reg_val;
139 }
140 
141 
_efuse_program_key(uint key_index,uint key_value)142 static void _efuse_program_key(uint key_index, uint key_value)
143 {
144     uint reg_val;
145     uint32_t cpu_sr;
146 
147 //  taskENTER_CRITICAL(cpu_sr);
148     cpu_sr = hal_spin_lock_irqsave(&efuse_lock);
149 
150 #ifdef EFUSE_HV_SWITCH
151     hal_writel(0x1, (unsigned long)EFUSE_HV_SWITCH);
152 #endif
153     hal_writel(key_value, SID_PRKEY);
154     reg_val = hal_readl((unsigned long)SID_PRCTL);
155     reg_val &= ~((0x1ff<<16)|0x3);
156     reg_val |= key_index<<16;
157     hal_writel(reg_val, (unsigned long)SID_PRCTL);
158     reg_val &= ~((0xff<<8)|0x3);
159     reg_val |= (SID_OP_LOCK<<8) | 0x1;
160     hal_writel(reg_val, (unsigned long)SID_PRCTL);
161     while(hal_readl((unsigned long)SID_PRCTL)&0x1){};
162     reg_val &= ~((0x1ff<<16)|(0xff<<8)|0x3);
163     hal_writel(reg_val, (unsigned long)SID_PRCTL);
164 
165 #ifdef EFUSE_HV_SWITCH
166     hal_writel(0x0, (unsigned long)EFUSE_HV_SWITCH);
167 #endif
168     hal_spin_unlock_irqrestore(&efuse_lock, cpu_sr);
169 //  taskEXIT_CRITICAL(cpu_sr);
170     return ;
171 }
172 
_get_burned_flag(efuse_key_map_new_t * key_map)173 static int _get_burned_flag(efuse_key_map_new_t *key_map)
174 {
175     if(key_map->burned_flg_offset < 0)
176     {
177         EFUSE_DBG("_get_burned_flag offset:%d\n", key_map->burned_flg_offset);
178         return 0;
179     }
180     else
181     {
182         EFUSE_DBG("_get_burned_flag val:%d\n", _efuse_reg_read_key(EFUSE_WRITE_PROTECT));
183         return (_efuse_reg_read_key(EFUSE_WRITE_PROTECT)
184                >> (key_map->burned_flg_offset & EFUSE_BRUN_RD_OFFSET_MASK)) & 1;
185     }
186 }
187 
_sw_acl_ck(efuse_key_map_new_t * key_map,int burn)188 static int _sw_acl_ck(efuse_key_map_new_t *key_map,int burn)
189 {
190     if(key_map->sw_rule == EFUSE_PRIVATE)
191     {
192         EFUSE_DBG("\n[efuse]%s: PRIVATE\n",key_map->name);
193         return EFUSE_ERR_PRIVATE;
194     }
195     if(burn==0)
196     {
197         if(key_map->sw_rule == EFUSE_NACCESS)
198         {
199             EFUSE_DBG("\n[efuse]%s:NACCESS\n",key_map->name);
200             return EFUSE_ERR_NO_ACCESS;
201         }
202     }
203     else
204     {
205         /*If already burned:*/
206         if(_get_burned_flag(key_map))
207         {
208             EFUSE_DBG("\n[efuse]%s: already burned\n",key_map->name);
209             EFUSE_DBG("config reg:0x%x\n",efuse_sram_read_key(EFUSE_WRITE_PROTECT));
210             if(key_map->sw_rule == EFUSE_NACCESS)
211                 return EFUSE_ERR_NO_ACCESS;
212             return EFUSE_ERR_ALREADY_BURNED;
213         }
214         if(key_map->sw_rule == EFUSE_RW)
215         {
216             /*modify burned_flg_offset&&rd_fbd_offset in case of the config bits been burned*/
217             key_map->burned_flg_offset |= EFUSE_ACL_SET_BRUN_BIT;
218             key_map->rd_fbd_offset |= EFUSE_ACL_SET_RD_FORBID_BIT;
219         }
220         else if(key_map->sw_rule == EFUSE_RO)
221         {
222             /*modify rd_fbd_offset in case of the config bit been burned*/
223             key_map->rd_fbd_offset |= EFUSE_ACL_SET_RD_FORBID_BIT;
224         }
225     }
226     return 0;
227 }
228 
229 
efuse_sram_read_key(uint key_index)230 uint efuse_sram_read_key(uint key_index)
231 {
232     return hal_readl((unsigned long)EFUSE_SRAM + key_index);
233 }
234 
235 
236 /*Please reference 1728 spec page11 to know why to call _efuse_reg_read_key
237 * but efuse_sram_read_key
238 *burn efuse :efuse sram can not get the latest value
239 *unless via sid read or reboot.
240 */
efuse_uni_burn_key(uint key_index,uint key_value)241 int efuse_uni_burn_key(uint key_index, uint key_value)
242 {
243     #define EFUSE_BURN_MAX_TRY_CNT 3
244     uint key_burn_bitmask = ~(efuse_sram_read_key(key_index)) & key_value;
245     int fail = 0;
246 
247     while(key_burn_bitmask)
248     {
249         _efuse_program_key(key_index,key_burn_bitmask);
250 
251         if(fail > EFUSE_BURN_MAX_TRY_CNT)
252         {
253             EFUSE_DBG("%s: **failed **",
254             __func__);
255             #if EFUSE_DBG_E
256             g_err_flg++;
257             #endif
258             return -1;
259         }
260         key_burn_bitmask &= (~(_efuse_reg_read_key(key_index)));
261         fail++;
262     }
263     return 0;
264 }
265 
266 
efuse_set_cfg_flg(int efuse_cfg_base,int bit_offset)267 void efuse_set_cfg_flg(int efuse_cfg_base,int bit_offset)
268 {
269     if(efuse_uni_burn_key(efuse_cfg_base,(1<<bit_offset)))
270     {
271         EFUSE_DBG("[efuse] %s %d fatal err: **_set_cfg_flg [base:%d][offset:%d] **",
272         __FILE__,__LINE__,efuse_cfg_base,bit_offset);
273     }
274     return;
275 }
276 
277 
278 
279 /*Efuse access control rule check.*/
efuse_acl_ck(efuse_key_map_new_t * key_map,int burn)280 int efuse_acl_ck(efuse_key_map_new_t *key_map,int burn)
281 {
282     /*For normal solution only check EFUSE_PRIVATE,other will be seemed as EFUSE_RW */
283     if(hal_efuse_get_security_mode() == 0)
284     {
285         if(key_map->sw_rule == EFUSE_PRIVATE)
286         {
287             return EFUSE_ERR_PRIVATE;
288         }
289         return 0;
290     }
291 
292     int ret = _sw_acl_ck(key_map,burn);
293     if(ret)
294     {
295         EFUSE_DBG("[efuse]%s sw check failed\n",key_map->name);
296         return ret;
297     }
298     if(burn)
299     {
300         EFUSE_DBG("[efuse]burn %s burned bit check begin\n",key_map->name);
301         if(_get_burned_flag(key_map))
302         {
303             /*already burned*/
304             EFUSE_DBG("[efuse]%s:already burned\n",key_map->name);
305             EFUSE_DBG("config reg:0x%x\n",efuse_sram_read_key(EFUSE_WRITE_PROTECT));
306             return EFUSE_ERR_ALREADY_BURNED;
307         }
308         EFUSE_DBG("[efuse]burn %s burned bit check end\n",key_map->name);
309     }
310     else
311     {
312         if((key_map->rd_fbd_offset>=0)&&
313          ((efuse_sram_read_key(EFUSE_READ_PROTECT) >>
314            (key_map->rd_fbd_offset & EFUSE_BRUN_RD_OFFSET_MASK)) & 1))
315         {
316             /*Read is not allowed because of the read forbidden bit was set*/
317             EFUSE_DBG("[efuse]%s forbid bit set\n",key_map->name);
318             EFUSE_DBG("config reg:0x%x\n",efuse_sram_read_key(EFUSE_READ_PROTECT));
319             return EFUSE_ERR_READ_FORBID;
320         }
321 
322     }
323     return 0;
324 }
325 
efuse_search_key_by_name(const char * key_name)326 efuse_key_map_new_t *efuse_search_key_by_name(const char *key_name)
327 {
328     efuse_key_map_new_t *key_map = g_key_info;
329 
330     for (; key_map->size != 0; key_map++) {
331         if (strlen(key_map->name) != strlen(key_name)) {
332             continue;
333         }
334         if (!memcmp(key_name, key_map->name, strlen(key_map->name))) {
335             break;
336         }
337     }
338     return key_map;
339 }
340 
341