blob: 991c6b5f68784f775eefde02c02e4db6946302c7 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// GEU_FuseWriteMethods.c
2//
3/******************************************************************************
4 *
5 * (C)Copyright 2022 ASR. All Rights Reserved.
6 *
7
8 ******************************************************************************/
9#include <Typedef.h>
10#include <predefines.h>
11#include <geu_interface.h>
12#include <Errors.h>
13#include <timer.h>
14#include <PMUA.h>
15#include <GEU.h>
16#include <platform_geu_fuse_internal.h>
17#include <GEU_FuseReadMethods.h>
18#include "GEU_Provisioning.h"
19
20static struct GEU_FuseGlobalData g_ActiveFuseData = {0xF /*ActiveFuseBlock*/ };
21struct GEU_FuseGlobalData *pActiveFuseData = &g_ActiveFuseData;
22static struct GEU_FuseBurnStatus g_FuseBurnStatus;
23struct GEU_FuseBurnStatus *pFuseBurnStatus = &g_FuseBurnStatus;
24
25UINT_T GEU_EnableFuseBurnPower()
26{
27 //UINT_T result = NoError;
28 UINT_T scratch, clock_divider;
29 static UINT_T check=0;
30
31 if (check == 0) {
32
33 scratch = (1 << 3) | 1;
34 //Enable clock
35 GEU_REG_WRITE(PMUA_AES_CLK_RES_CTRL, scratch);
36 }
37 check++;
38 return NoError;
39}
40
41UINT_T GEU_DisablePowerForFuseBurning()
42{
43 return NoError;
44}
45
46UINT_T GEU_SetActiveFuseBlock(UINT_T n)
47{
48 UINT_T scratch;
49
50 if (pActiveFuseData->ActiveFuseBlock != n)
51 {
52 // Clear the Fuse Burn Status Block
53 _geuClearFuseBurnStatus(pFuseBurnStatus);
54
55 // Clear the ActiveFuseData
56 _geuClearActiveFuseData(pActiveFuseData);
57
58 // Clear VAL1 & VAL2 register sets
59 _geuClearVal1Val2RegisterSets();
60
61 pActiveFuseData->ActiveFuseBlock = n;
62 pActiveFuseData->ActiveFuseBlockField = K_UNDEFINED_FUSEBLOCK_FIELD;
63 }//EndIf BlockNotActive
64 return 0;
65}//End Routine SetActiveFuseBlock
66
67UINT_T GEU_ReadActiveFuseBlockNumber()
68{
69 return (pActiveFuseData->ActiveFuseBlock);
70}
71
72UINT_T GEU_SetupApConfigFuseBits(UINT_T* pBuffer, UINT_T Size)
73{
74 UINT_T scratch;
75 UINT_T temp[3];
76 UINT_T read_back[3];
77
78 if (Size != K_AP_CONFIG_FUSE_SIZE)
79 {
80 return FUSE_BufferTooSmall;
81 }
82
83 // Confirm this fuseblock is active
84 if (g_ActiveFuseData.ActiveFuseBlock != K_AP_CONFIG_FUSEBLOCK)
85 {
86 return (FUSE_FuseBlockNotActive);
87 }
88
89 // Check and Set Active FuseBlock Field
90 if (!(pActiveFuseData->ActiveFuseBlockField & K_AP_FUSEBLOCK_FIELD))
91 {
92 pActiveFuseData->ActiveFuseBlockField |= K_AP_FUSEBLOCK_FIELD;
93 }
94
95 //Low16 bit is CP configs
96 temp[0] = (pBuffer[0] & 0xFFFF) << 16;
97 temp[1] = (pBuffer[0] >> 16) & 0xFFFF;
98 temp[1] |= (pBuffer[1] & 0xFFFF) << 16;
99 temp[2] = (pBuffer[1] >> 16) & 0xFFFF;
100 temp[2] |= (pBuffer[2] & 0xFFFF) << 16;
101
102 //Save the setup data to GEU_FUSE_PROG_VAL1/VAL2/VAL3
103 _geuUpdateRegister(GEU_FUSE_PROG_VAL1+0, temp[0], 0xFFFF0000); //bit 16-31 are AP config
104 _geuUpdateRegister(GEU_FUSE_PROG_VAL1+4, temp[1], 0xFFFFFFFF);
105 _geuUpdateRegister(GEU_FUSE_PROG_VAL1+8, temp[2], 0xFFFFFFFF);
106
107 //In case that AP config is not empty
108 GEU_ReadApConfigFuseBits(&read_back[0], K_APCP_CONFIG_FUSE_SIZE);
109
110 // Save to Active fuseblock for burn validation later
111 pActiveFuseData->ApConfigSave[0] = pBuffer[0] | read_back[0];
112 pActiveFuseData->ApConfigSave[1] = pBuffer[1] | read_back[1];
113 pActiveFuseData->ApConfigSave[2] = pBuffer[2] | read_back[2];
114
115 //Set Burn Request
116 pActiveFuseData->BurnRequest |= K_AP_CONFIG_BURN_REQUEST_MASK;
117
118 return 0;
119}
120
121UINT_T GEU_SetupCpConfigFuseBits(UINT_T* pBuffer, UINT_T Size)
122{
123 UINT_T scratch;
124 UINT_T temp;
125 UINT_T read_back;
126
127 if (Size != K_CP_CONFIG_FUSE_SIZE)
128 {
129 return FUSE_BufferTooSmall;
130 }
131
132 // Confirm this fuseblock is active
133 if (g_ActiveFuseData.ActiveFuseBlock != K_CP_CONFIG_FUSEBLOCK)
134 {
135 return (FUSE_FuseBlockNotActive);
136 }
137
138 // Check and Set Active FuseBlock Field
139 if (!(pActiveFuseData->ActiveFuseBlockField & K_CP_FUSEBLOCK_FIELD))
140 {
141 pActiveFuseData->ActiveFuseBlockField |= K_CP_FUSEBLOCK_FIELD;
142 }
143
144 // Clear Burn Data in the Active Fuse Data Structure
145 // JLC: _geuClearActiveFuseData();
146
147 //Low16 bit is CP configs
148 temp = pBuffer[0] & 0xFFFF;
149
150 //Save the setup data to GEU_FUSE_PROG_VAL1
151 _geuUpdateRegister(GEU_FUSE_PROG_VAL1+0, temp, 0x0000FFFF);
152
153 //In case that AP config is not empty
154 GEU_ReadCpConfigFuseBits(&read_back, K_CP_CONFIG_FUSE_SIZE);
155
156 // Save to Active fuseblock for burn validation later
157 pActiveFuseData->CpConfigSave[0] = pBuffer[0] | read_back;
158
159 //Set Burn Request
160 pActiveFuseData->BurnRequest |= K_CP_CONFIG_BURN_REQUEST_MASK;
161
162 return 0;
163}
164
165UINT_T GEU_SetupLifeCycleFuseBits(UINT_T* pBuffer, UINT_T Size)
166{
167 UINT_T lcs;
168 UINT_T read_back;
169
170 if (Size != K_LCS_FUSE_SIZE)
171 {
172 return FUSE_BufferTooSmall;
173 }
174
175 lcs = pBuffer[0];
176
177 // Confirm this fuseblock is active
178 if (g_ActiveFuseData.ActiveFuseBlock != K_LIFECYCLE_FUSEBLOCK)
179 {
180 return (FUSE_FuseBlockNotActive);
181 }
182
183 // Check and Set Active FuseBlock Field
184 if (!(pActiveFuseData->ActiveFuseBlockField & K_LIFECYCLE_FUSEBLOCK_FIELD))
185 {
186 pActiveFuseData->ActiveFuseBlockField |= K_LIFECYCLE_FUSEBLOCK_FIELD;
187 }
188
189 read_back = GEU_ReadLifeCycleState();
190 pActiveFuseData->LifeCycleSave = lcs | read_back;
191
192 //Save the setup data to GEU_FUSE_PROG_VAL1
193 _geuUpdateRegister(GEU_FUSE_PROG_VAL2+8, lcs, 0x0000FFFF);
194
195 //Set Burn Request
196 pActiveFuseData->BurnRequest |= K_LIFECYCLE_BURN_REQUEST_MASK;
197
198 return 0;
199}
200
201UINT_T GEU_SetupOemHashKeyFuseBits(UINT_T* pBuffer, UINT_T Size)
202{
203 UINT_T scratch;
204
205 if (Size != K_OEM_HASH_FUSE_SIZE)
206 {
207 return FUSE_InvalidBufferSize;
208 }
209 // Confirm this fuseblock is active
210 if (g_ActiveFuseData.ActiveFuseBlock != K_OEM_FUSEBLOCK)
211 {
212 return (FUSE_FuseBlockNotActive);
213 }
214
215 // Check and Set Active FuseBlock Field
216 if (!(pActiveFuseData->ActiveFuseBlockField & K_OEM0_FUSEBLOCK_FIELD))
217 {
218 pActiveFuseData->ActiveFuseBlockField |= K_OEM0_FUSEBLOCK_FIELD;
219 }
220
221 // Clear Burn Data in the Active Fuse Data Structure
222 // JLC: _geuClearActiveFuseData();
223
224 // Save to Active fuseblock for burn validation later
225 pActiveFuseData->FuseBlockSave[0] = pBuffer[0];
226 pActiveFuseData->FuseBlockSave[1] = pBuffer[1];
227 pActiveFuseData->FuseBlockSave[2] = pBuffer[2];
228 pActiveFuseData->FuseBlockSave[3] = pBuffer[3];
229 pActiveFuseData->FuseBlockSave[4] = pBuffer[4];
230 pActiveFuseData->FuseBlockSave[5] = pBuffer[5];
231 pActiveFuseData->FuseBlockSave[6] = pBuffer[6];
232 pActiveFuseData->FuseBlockSave[7] = pBuffer[7];
233
234 //Save the setup data to GEU_FUSE_PROG_VAL1/VAL2
235 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+0, pBuffer[0]);
236 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+4, pBuffer[1]);
237 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+8, pBuffer[2]);
238 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+12, pBuffer[3]);
239 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+0, pBuffer[4]);
240 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+4, pBuffer[5]);
241 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+8, pBuffer[6]);
242 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+12, pBuffer[7]);
243
244 //Set Burn Request
245 pActiveFuseData->BurnRequest |= K_OEM_KEY0_BURN_REQUEST_MASK;
246
247 return 0;
248}//End Routine GEU_SetupOemHashFuseBits
249
250UINT_T GEU_SetupRkekFuseBits(UINT_T* pBuffer, UINT_T Size)
251{
252 UINT_T scratch;
253
254 if (Size != K_RKEK_FUSE_SIZE)
255 {
256 return FUSE_InvalidBufferSize;
257 }
258 // Confirm this fuseblock is active
259 if (g_ActiveFuseData.ActiveFuseBlock != K_RKEK_FUSEBLOCK)
260 {
261 return (FUSE_FuseBlockNotActive);
262 }
263
264 // Check and Set Active FuseBlock Field
265 if (!(pActiveFuseData->ActiveFuseBlockField & K_RKEK_FUSEBLOCK_FIELD))
266 {
267 pActiveFuseData->ActiveFuseBlockField |= K_RKEK_FUSEBLOCK_FIELD;
268 }
269
270 // Clear Burn Data in the Active Fuse Data Structure
271 // JLC: _geuClearActiveFuseData();
272
273 // Save to Active fuseblock for burn validation later
274 pActiveFuseData->FuseBlockSave[0] = pBuffer[0];
275 pActiveFuseData->FuseBlockSave[1] = pBuffer[1];
276 pActiveFuseData->FuseBlockSave[2] = pBuffer[2];
277 pActiveFuseData->FuseBlockSave[3] = pBuffer[3];
278 pActiveFuseData->FuseBlockSave[4] = pBuffer[4];
279 pActiveFuseData->FuseBlockSave[5] = pBuffer[5];
280 pActiveFuseData->FuseBlockSave[6] = pBuffer[6];
281 pActiveFuseData->FuseBlockSave[7] = pBuffer[7];
282
283 //Save the setup data to GEU_FUSE_PROG_VAL1/VAL2
284 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+0, pBuffer[0]);
285 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+4, pBuffer[1]);
286 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+8, pBuffer[2]);
287 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1+12, pBuffer[3]);
288 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+0, pBuffer[4]);
289 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+4, pBuffer[5]);
290 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+8, pBuffer[6]);
291 GEU_REG_WRITE(GEU_FUSE_PROG_VAL2+12, pBuffer[7]);
292
293 //Set Burn Request
294 pActiveFuseData->BurnRequest |= K_RKEK_BURN_REQUEST_MASK;
295
296 return 0;
297}//End Routine GEU_SetupOemHashFuseBits
298
299UINT_T GEU_SetupPlatVersionFuseBits(UINT_T* pBuffer, UINT_T Size)
300{
301 UINT_T temp[2];
302 UINT_T read_back;
303
304 if (Size != K_PLAT_VERSION_FUSE_SIZE)
305 {
306 return FUSE_BufferTooSmall;
307 }
308
309 // Confirm this fuseblock is active
310 if (g_ActiveFuseData.ActiveFuseBlock != K_PLAT_VERSION_FUSEBLOCK)
311 {
312 return (FUSE_FuseBlockNotActive);
313 }
314
315 // Check and Set Active FuseBlock Field
316 if (!(pActiveFuseData->ActiveFuseBlockField & K_PLAT_VERSION_FUSEBLOCK_FIELD))
317 {
318 pActiveFuseData->ActiveFuseBlockField |= K_PLAT_VERSION_FUSEBLOCK_FIELD;
319 }
320
321 //Low16 bit is CP configs
322 temp[0] = (pBuffer[0] & 0xFFFF) << 16;
323 temp[1] = (pBuffer[0] >> 16) & 0xFFFF;
324
325 //Save the setup data to GEU_FUSE_PROG_VAL6/VAL7
326 _geuUpdateRegister(GEU_FUSE_PROG_VAL1+24, temp[0], 0xFFFF0000);
327 _geuUpdateRegister(GEU_FUSE_PROG_VAL1+28, temp[1], 0x0000FFFF);
328
329 //In case that AP config is not empty
330 read_back = GEU_ReadSoftwareVersion();
331
332 // Save to Active fuseblock for burn validation later
333 pActiveFuseData->SoftwareVersionSave[0] = pBuffer[0] | read_back;
334 pActiveFuseData->SoftwareVersionSave[1] = 0;
335
336 //Set Burn Request
337 pActiveFuseData->BurnRequest |= K_PLAT_VERSION_BURN_REQUEST_MASK;
338
339 return 0;
340}
341
342UINT_T GEU_BurnFuseBlock_OemHashKey(struct GEU_FuseBurnStatus * pUserFuseBurnStatus)
343{
344 UINT_T temp[8]; // temp buffer for fuse block compares
345 UINT_T status;
346
347 // Confirm this fuseblock is active
348 if (pActiveFuseData->ActiveFuseBlock != K_OEM_FUSEBLOCK)
349 {
350 return (FUSE_FuseBlockNotActive);
351 }
352
353 // Save the burn request in the FuseBurnStatus
354 pFuseBurnStatus->SavedBurnRequest = pActiveFuseData->BurnRequest;
355
356 if ((pActiveFuseData->BurnRequest & K_OEM_KEY0_BURN_REQUEST_MASK) == 0)
357 {
358 pFuseBurnStatus->FinalBurnStatus = FUSE_NoBurnRequest ;
359 return(_geuUpdateUserFuseBurnStatus(pUserFuseBurnStatus, pFuseBurnStatus));
360 }
361 // Burn Count = 0
362 pActiveFuseData->BurnCount = 0;
363
364 while (pActiveFuseData->BurnRequest)
365 {
366 //++ ****** Burn **********
367 status = _geuBurnFuse(K_OEM_FUSEBLOCK, 0); // Burn and NOT Lock OEM Key Hash
368 //-- ****** Burn **********
369 if (status != 0)
370 {
371 pFuseBurnStatus->DebugStatus = status;
372 }
373
374 // Burn Count++
375 pActiveFuseData->BurnCount++;
376 if (pActiveFuseData->BurnCount > 1)
377 {
378 pFuseBurnStatus->DebugStatus |= K_MULTIPLE_BURN_COUNT;
379 }
380
381 //********************************************************************
382 // Validate the OEM Hash Burn
383 //********************************************************************
384 if ((pActiveFuseData->BurnRequest & K_OEM_KEY0_BURN_REQUEST_MASK) != 0)
385 {
386 //Compare Burned value with Saved value
387 status = GEU_ReadOemHashKeyFuseBits(&temp[0], K_FUSEBLOCK_SIZE);
388 status = _geu_compare(&pActiveFuseData->FuseBlockSave[0],
389 &temp[0],
390 K_FUSEBLOCK_SIZE);
391 if (status == 0)
392 {
393 // AP Burn Good - Clear the Burn Request
394 pActiveFuseData->BurnRequest = pActiveFuseData->BurnRequest
395 & ~K_OEM_KEY0_BURN_REQUEST_MASK;
396 }
397 else
398 {
399 // If the BurnCount is 1, leave the burn request set
400 // for another try.
401 // Else
402 if (pActiveFuseData->BurnCount >= 2)
403 {
404 // Burn Failed two times - Clear the burn Request
405 pActiveFuseData->BurnRequest = pActiveFuseData->BurnRequest
406 & ~K_OEM_KEY0_BURN_REQUEST_MASK;
407 // Set the AP Raw Burn Status to indicate Failure
408 pFuseBurnStatus->RawBurnStatus = pFuseBurnStatus->RawBurnStatus |
409 K_OEM_KEY0_STATUS_BIT_MASK;
410 }
411 }//EndIfElse
412 }//Endif
413 }//End While
414
415 // Set status
416 pFuseBurnStatus->CorrectedBurnStatus = pFuseBurnStatus->RawBurnStatus;
417 pFuseBurnStatus->FinalBurnStatus = NoError;
418 if(pFuseBurnStatus->CorrectedBurnStatus != 0)
419 {
420 pFuseBurnStatus->FinalBurnStatus = FUSE_BurnError;
421 }
422 return(_geuUpdateUserFuseBurnStatus(pUserFuseBurnStatus, pFuseBurnStatus));
423}// End Routine GEU_BurnFuseBlock_OEM_Platform_Hash
424
425UINT_T GEU_BurnFuseBlock_RKEK(struct GEU_FuseBurnStatus * pUserFuseBurnStatus)
426{
427 UINT_T temp[8]; // temp buffer for fuse block compares
428 UINT_T status;
429
430 // Confirm this fuseblock is active
431 if (pActiveFuseData->ActiveFuseBlock != K_RKEK_FUSEBLOCK)
432 {
433 return (FUSE_FuseBlockNotActive);
434 }
435
436 // Save the burn request in the FuseBurnStatus
437 pFuseBurnStatus->SavedBurnRequest = pActiveFuseData->BurnRequest;
438
439 if ((pActiveFuseData->BurnRequest & K_RKEK_BURN_REQUEST_MASK) == 0)
440 {
441 pFuseBurnStatus->FinalBurnStatus = FUSE_NoBurnRequest ;
442 return(_geuUpdateUserFuseBurnStatus(pUserFuseBurnStatus, pFuseBurnStatus));
443 }
444 // Burn Count = 0
445 pActiveFuseData->BurnCount = 0;
446
447 while (pActiveFuseData->BurnRequest)
448 {
449 //++ ****** Burn **********
450 status = _geuBurnFuse(K_RKEK_FUSEBLOCK, 0); // Burn and NOT Lock OEM Key Hash
451 //-- ****** Burn **********
452 if (status != 0)
453 {
454 pFuseBurnStatus->DebugStatus = status;
455 }
456
457 // Burn Count++
458 pActiveFuseData->BurnCount++;
459 if (pActiveFuseData->BurnCount > 1)
460 {
461 pFuseBurnStatus->DebugStatus |= K_MULTIPLE_BURN_COUNT;
462 }
463
464 //********************************************************************
465 // Validate the OEM Hash Burn
466 //********************************************************************
467 if ((pActiveFuseData->BurnRequest & K_RKEK_BURN_REQUEST_MASK) != 0)
468 {
469 //Compare Burned value with Saved value
470 status = GEU_ReadRkekFuseBits(&temp[0], K_FUSEBLOCK_SIZE);
471 status = _geu_compare(&pActiveFuseData->FuseBlockSave[0],
472 &temp[0],
473 K_FUSEBLOCK_SIZE);
474 if (status == 0)
475 {
476 // AP Burn Good - Clear the Burn Request
477 pActiveFuseData->BurnRequest = pActiveFuseData->BurnRequest
478 & ~K_RKEK_BURN_REQUEST_MASK;
479 }
480 else
481 {
482 // If the BurnCount is 1, leave the burn request set
483 // for another try.
484 // Else
485 if (pActiveFuseData->BurnCount >= 2)
486 {
487 // Burn Failed two times - Clear the burn Request
488 pActiveFuseData->BurnRequest = pActiveFuseData->BurnRequest
489 & ~K_RKEK_BURN_REQUEST_MASK;
490 // Set the AP Raw Burn Status to indicate Failure
491 pFuseBurnStatus->RawBurnStatus = pFuseBurnStatus->RawBurnStatus |
492 K_RKEK_STATUS_BIT_MASK;
493 }
494 }//EndIfElse
495 }//Endif
496 }//End While
497
498 // Set status
499 pFuseBurnStatus->CorrectedBurnStatus = pFuseBurnStatus->RawBurnStatus;
500 pFuseBurnStatus->FinalBurnStatus = NoError;
501 if(pFuseBurnStatus->CorrectedBurnStatus != 0)
502 {
503 pFuseBurnStatus->FinalBurnStatus = FUSE_BurnError;
504 }
505 return(_geuUpdateUserFuseBurnStatus(pUserFuseBurnStatus, pFuseBurnStatus));
506}// End Routine GEU_BurnFuseBlock_OEM_Platform_Hash
507
508UINT_T GEU_BurnFuseBlock_SocConfig(struct GEU_FuseBurnStatus * pUserFuseBurnStatus)
509{
510 UINT_T temp[8]; // temp buffer for fuse block compares
511 UINT_T status;
512
513 // Confirm this fuseblock is active
514 if (pActiveFuseData->ActiveFuseBlock != K_SOC_CONFIG_FUSEBLOCK)
515 {
516 return (FUSE_FuseBlockNotActive);
517 }
518
519 // Confirm bandgap from USB PHY is enabled for the fuse power regulator
520 if( _geuConfirmPowerEnabledForFuseBurning() == 0)
521 {
522 pFuseBurnStatus->FinalBurnStatus = FUSE_FuseBurnPowerNotEnabled;
523 return(_geuUpdateUserFuseBurnStatus(pUserFuseBurnStatus, pFuseBurnStatus));
524 }
525
526 // Save the burn request in the FuseBurnStatus
527 pFuseBurnStatus->SavedBurnRequest = pActiveFuseData->BurnRequest;
528 if (pActiveFuseData->BurnRequest & K_SOC_COFNIG_BURN_REQUEST_MASK == 0)
529 {
530 pFuseBurnStatus->FinalBurnStatus = FUSE_IncompleteFuseFieldsSetup;
531 return(_geuUpdateUserFuseBurnStatus(pUserFuseBurnStatus, pFuseBurnStatus));
532 }
533
534 // Burn Count = 0
535 pActiveFuseData->BurnCount = 0;
536 while (pActiveFuseData->BurnRequest)
537 {
538 //++ ****** Burn **********
539 status = _geuBurnFuse(K_AP_CONFIG_FUSEBLOCK, 0);
540 //-- ****** Burn **********
541 if (status != 0)
542 {
543 pFuseBurnStatus->DebugStatus = status;
544 }
545 // Burn Count++
546 pActiveFuseData->BurnCount++;
547 if (pActiveFuseData->BurnCount > 1)
548 {
549 pFuseBurnStatus->DebugStatus |= K_MULTIPLE_BURN_COUNT;
550 }
551
552 //********************************************************************
553 // Validate the components burned (ones with a burn request)
554 //********************************************************************
555 // Validate Security CONFIG Burn Request
556 //********************************************************************
557 //++
558 if ((pActiveFuseData->BurnRequest & K_AP_CONFIG_BURN_REQUEST_MASK) != 0)
559 {
560 //Compare Burned Security with Saved Security Config Bits
561 status = GEU_ReadApConfigFuseBits(&temp[0],
562 K_AP_CONFIG_FUSE_SIZE);
563 // Ignore status - whatever we read, we read
564 status = _geu_compare(&pActiveFuseData->ApConfigSave[0],
565 &temp[0],
566 K_AP_CONFIG_FUSE_SIZE);
567 if (status == 0)
568 {
569 // Security Config Burn Good - Clear the Burn Request
570 pActiveFuseData->BurnRequest &= ~K_AP_CONFIG_BURN_REQUEST_MASK;
571
572 }
573 else
574 {
575 // If the BurnCount is 1, leave the burn request set
576 // for another try.
577 // Else
578 if (pActiveFuseData->BurnCount >= 2)
579 {
580 // Security Burn Failed two times - Clear the burn Request
581 pActiveFuseData->BurnRequest &= ~K_AP_CONFIG_BURN_REQUEST_MASK;
582 // Set the Security Raw Burn Status to indicate Failure
583 pFuseBurnStatus->RawBurnStatus |= K_AP_CONFIG_BURN_REQUEST_MASK;
584 }
585 }//EndIfElse
586 }//Endif
587 //-- Validate AP CONFIG Burn Request
588 if ((pActiveFuseData->BurnRequest & K_CP_CONFIG_BURN_REQUEST_MASK) != 0)
589 {
590 status = GEU_ReadCpConfigFuseBits(&temp[0],
591 K_CP_CONFIG_FUSE_SIZE);
592 // Ignore status - whatever we read, we read
593 status = _geu_compare(&pActiveFuseData->CpConfigSave[0],
594 &temp[0],
595 K_CP_CONFIG_FUSE_SIZE);
596 if (status == 0)
597 {
598 // CP Config Burn Good - Clear the Burn Request
599 pActiveFuseData->BurnRequest &= ~K_CP_CONFIG_BURN_REQUEST_MASK;
600
601 }
602 else
603 {
604 // If the BurnCount is 1, leave the burn request set
605 // for another try.
606 // Else
607 if (pActiveFuseData->BurnCount >= 2)
608 {
609 // Security Burn Failed two times - Clear the burn Request
610 pActiveFuseData->BurnRequest &= ~K_CP_CONFIG_BURN_REQUEST_MASK;
611 // Set the Security Raw Burn Status to indicate Failure
612 pFuseBurnStatus->RawBurnStatus |= K_CP_CONFIG_BURN_REQUEST_MASK;
613 }
614
615 }//EndIfElse
616
617 }//Endif
618 //-- Validate CP CONFIG Burn Request
619
620#if CLOSE_JTAG
621 if ((pActiveFuseData->BurnRequest & K_LIFECYCLE_BURN_REQUEST_MASK) != 0)
622 {
623 //Compare Burned Security with Saved Security Config Bits
624 temp[0] = GEU_ReadLifeCycleState();
625 // Ignore status - whatever we read, we read
626 status = _geu_compare(&pActiveFuseData->LifeCycleSave,
627 &temp[0],
628 K_LCS_FUSE_SIZE);
629 if (status == 0)
630 {
631 // LCS Burn Good - Clear the Burn Request
632 pActiveFuseData->BurnRequest &= ~K_LIFECYCLE_BURN_REQUEST_MASK;
633
634 }
635 else
636 {
637 // If the BurnCount is 1, leave the burn request set
638 // for another try.
639 // Else
640 if (pActiveFuseData->BurnCount >= 2)
641 {
642 // LCS Burn Failed two times - Clear the burn Request
643 pActiveFuseData->BurnRequest &= ~K_LIFECYCLE_BURN_REQUEST_MASK;
644 // Set the Raw Burn Status to indicate Failure
645 pFuseBurnStatus->RawBurnStatus |= K_LIFECYCLE_BURN_REQUEST_MASK;
646 }
647
648 }//EndIfElse
649
650 }//Endif
651 //-- Validate LCS Burn Request
652#endif //CLOSE_JTAG
653 if ((pActiveFuseData->BurnRequest & K_PLAT_VERSION_BURN_REQUEST_MASK) != 0 )
654 {
655 //Compare Burned Security with Saved Security Config Bits
656 temp[0] = GEU_ReadSoftwareVersion();
657 // Ignore status - whatever we read, we read
658 status = _geu_compare(&pActiveFuseData->SoftwareVersionSave[0],
659 &temp[0],
660 K_PLAT_VERSION_FUSE_SIZE);
661 if (status == 0)
662 {
663 pActiveFuseData->BurnRequest &= ~K_PLAT_VERSION_BURN_REQUEST_MASK;
664 }
665 else
666 {
667 if (pActiveFuseData->BurnCount >= 2)
668 {
669 // LCS Burn Failed two times - Clear the burn Request
670 pActiveFuseData->BurnRequest &= ~K_PLAT_VERSION_BURN_REQUEST_MASK;
671 // Set the Raw Burn Status to indicate Failure
672 pFuseBurnStatus->RawBurnStatus |= K_PLAT_VERSION_BURN_REQUEST_MASK;
673 }
674 }//EndIfElse
675 }//Endif
676 }
677 // Set status
678 pFuseBurnStatus->CorrectedBurnStatus = pFuseBurnStatus->RawBurnStatus;
679 if(pFuseBurnStatus->CorrectedBurnStatus != 0)
680 {
681 pFuseBurnStatus->FinalBurnStatus = FUSE_BurnError;
682 }
683 return(_geuUpdateUserFuseBurnStatus(pUserFuseBurnStatus, pFuseBurnStatus));
684}//End Routine GEU_BurnFuseBlock_SocConfig
685
686#if ENABLE_BITS_BURN
687UINT_T GEU_FuseBankBitBurn(UINT_T BankNum, UINT_T StartBit, UINT_T BitCouts)
688{
689 UINT_T result;
690 UINT_T status;
691 UINT_T BurnBuffer[8];
692 UINT_T ReadBuffer[8];
693
694 if (((StartBit + BitCouts) > 256) || (StartBit > 255) || (BitCouts == 0)) {
695 return FUSE_InvalidFuseBlockField;
696 }
697
698 /* make sure power supply required for fuse programming is enabled */
699 result = GEU_EnableFuseBurnPower();
700 if (result != NoError) {
701 return FUSE_FuseBurnPowerNotEnabled;
702 }
703
704 result = GEU_SetActiveFuseBlock(BankNum);
705 if (result != NoError) {
706 return result;
707 }
708
709 memset(BurnBuffer, 0, sizeof(BurnBuffer));
710
711 /* setup burn bits */
712 for (UINT_T i = StartBit; i < (StartBit + BitCouts); i++) {
713 BurnBuffer[i/32] |= (1 << (i%32));
714 }
715
716 for (UINT_T i = 0; i < 8; i++) {
717 GEU_REG_WRITE(GEU_FUSE_PROG_VAL1 + i*4, BurnBuffer[i]);
718 }
719
720 /* burn bits */
721 status = _geuBurnFuse(BankNum, 0);
722 if (status != 0) {
723 return FUSE_BurnError;
724 }
725
726 /* compare whether the burn is correct */
727 memset(ReadBuffer, 0, sizeof(ReadBuffer));
728 GEU_ReadFuseBank(ReadBuffer, BankNum);
729 for (UINT_T i = 0; i < 8; i++) {
730 if ((BurnBuffer[i] & ReadBuffer[i]) != BurnBuffer[i]) {
731 status = FUSE_BurnError;
732 break;
733 }
734 }
735
736 if (status == FUSE_BurnError) {
737 /* second burn bits */
738 status = _geuBurnFuse(BankNum, 0);
739 if (status != 0) {
740 return FUSE_BurnError;
741 }
742
743 /* compare whether the second burn is correct */
744 memset(ReadBuffer, 0, sizeof(ReadBuffer));
745 GEU_ReadFuseBank(ReadBuffer, BankNum);
746 for (UINT_T i = 0; i < 8; i++) {
747 if ((BurnBuffer[i] & ReadBuffer[i]) != BurnBuffer[i]) {
748 return FUSE_BurnError;
749 }
750 }
751 }
752
753 return NoError;
754}
755#endif