1 /** @file
2 *
3 * Copyright (c) 2015, Hisilicon Limited. All rights reserved.
4 * Copyright (c) 2015, Linaro Limited. All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-2-Clause-Patent
7 *
8 **/
9
10 #include <PiDxe.h>
11 #include <Library/DebugLib.h>
12 #include <Library/UefiBootServicesTableLib.h>
13 #include <Library/IoLib.h>
14 #include "NorFlashHw.h"
15
16
17 BOOLEAN gFlashBusy = FALSE;
18 FLASH_INDEX gIndex = {
19 0,
20 0,
21 0,
22 0,
23 0,
24 0
25 };
26
27
PortReadData(UINT32 Index,UINT32 FlashAddr)28 UINT32 PortReadData (
29 UINT32 Index,
30 UINT32 FlashAddr
31 )
32 {
33
34 switch (gFlashInfo[Index].ParallelNum)
35 {
36 case 2:
37 return MmioRead32 (FlashAddr);
38 case 1:
39 return MmioRead16 (FlashAddr);
40
41 default:
42 DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:illegal PortWidth!\n", __FUNCTION__,__LINE__));
43 return 0xffffffff;
44 }
45 }
46
47 EFI_STATUS
PortWriteData(UINT32 Index,UINT32 FlashAddr,UINT32 InputData)48 PortWriteData (
49 UINT32 Index,
50 UINT32 FlashAddr,
51 UINT32 InputData
52 )
53 {
54
55 switch (gFlashInfo[Index].ParallelNum)
56 {
57 case 2:
58 MmioWrite32 (FlashAddr, InputData);
59 break;
60 case 1:
61 MmioWrite16 (FlashAddr, InputData);
62 break;
63 default:
64 DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:illegal PortWidth!\n", __FUNCTION__,__LINE__));
65 return EFI_DEVICE_ERROR;
66 }
67 return EFI_SUCCESS;
68 }
69
PortAdjustData(UINT32 Index,UINT32 ulInputData)70 UINT32 PortAdjustData(
71 UINT32 Index,
72 UINT32 ulInputData
73 )
74 {
75
76 switch (gFlashInfo[Index].ParallelNum)
77 {
78 case 2:
79 return ulInputData;
80 case 1:
81 return (0x0000ffff & ulInputData );
82 default:
83 DEBUG((EFI_D_ERROR,"[FLASH_S29GL256N_PortAdjustData]: Error--illegal g_ulFlashS29Gl256NPortWidth!\n\r"));
84 return 0xffffffff;
85 }
86 }
87
88
GetCommandIndex(UINT32 Index)89 EFI_STATUS GetCommandIndex(
90 UINT32 Index
91 )
92 {
93 UINT32 CommandCount = 0;
94 UINT32 i;
95 UINT8 Flag = 1;
96
97 CommandCount = sizeof(gFlashCommandReset) / sizeof(FLASH_COMMAND_RESET);
98 for(i = 0;i < CommandCount; i ++ )
99 {
100 if(gFlashInfo[Index].CommandType & gFlashCommandReset[i].CommandType)
101 {
102 Flag = 0;
103 gIndex.ReIndex = i;
104 break;
105 }
106 }
107
108 if(Flag)
109 {
110 DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get Reset Command!\n", __FUNCTION__,__LINE__));
111 return EFI_DEVICE_ERROR;
112 }
113
114 CommandCount = sizeof(gFlashCommandId) / sizeof(FLASH_COMMAND_ID);
115 for(Flag = 1,i = 0;i < CommandCount; i ++ )
116 {
117 if(gFlashInfo[Index].CommandType & gFlashCommandId[i].CommandType)
118 {
119 Flag = 0;
120 gIndex.IdIndex = i;
121 break;
122 }
123 }
124
125 if(Flag)
126 {
127 DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get ID Command!\n", __FUNCTION__,__LINE__));
128 return EFI_DEVICE_ERROR;
129 }
130
131 CommandCount = sizeof(gFlashCommandWrite) / sizeof(FLASH_COMMAND_WRITE);
132 for(Flag = 1, i = 0;i < CommandCount; i ++ )
133 {
134 if(gFlashInfo[Index].CommandType & gFlashCommandWrite[i].CommandType)
135 {
136 Flag = 0;
137 gIndex.WIndex = i;
138 break;
139 }
140 }
141
142 if(Flag)
143 {
144 DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get Write Command!\n", __FUNCTION__,__LINE__));
145 return EFI_DEVICE_ERROR;
146 }
147
148 CommandCount = sizeof(gFlashCommandErase) / sizeof(FLASH_COMMAND_ERASE);
149 for(Flag = 1, i = 0;i < CommandCount; i ++ )
150 {
151 if(gFlashInfo[Index].CommandType & gFlashCommandErase[i].CommandType)
152 {
153 Flag = 0;
154 gIndex.WIndex = i;
155 break;
156 }
157 }
158
159 if(Flag)
160 {
161 DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Can not Get Erase Command!\n", __FUNCTION__,__LINE__));
162 return EFI_DEVICE_ERROR;
163 }
164
165 return EFI_SUCCESS;
166 }
167
168
FlashReset(UINT32 Base)169 VOID FlashReset(UINT32 Base)
170 {
171 (VOID)PortWriteData(gIndex.InfIndex, Base, gFlashCommandReset[gIndex.ReIndex].ResetData);
172 (void)gBS->Stall(20000);
173 }
174
175
GetManufacturerID(UINT32 Index,UINT32 Base,UINT8 * pbyData)176 void GetManufacturerID(UINT32 Index, UINT32 Base, UINT8 *pbyData)
177 {
178
179 UINT32 dwAddr;
180
181 FlashReset(Base);
182
183 dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep1 << gFlashInfo[Index].ParallelNum);
184 (VOID)PortWriteData(Index, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep1);
185
186 dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep2 << gFlashInfo[Index].ParallelNum);
187 (VOID)PortWriteData(Index, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep2);
188
189 dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep3 << gFlashInfo[Index].ParallelNum);
190 (VOID)PortWriteData(Index, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep3);
191
192 *pbyData = (UINT8)PortReadData(Index, Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddress << gFlashInfo[Index].ParallelNum));
193
194 FlashReset(Base); //must reset to return to the read mode
195 }
196
197
FlashInit(UINT32 Base)198 EFI_STATUS FlashInit(UINT32 Base)
199 {
200 UINT32 FlashCount = 0;
201 UINT32 i = 0;
202 EFI_STATUS Status;
203 UINT8 Flag = 1;
204 UINT32 TempData = 0;
205 UINT32 TempDev1 = 0;
206 UINT32 TempDev2 = 0;
207 UINT32 TempDev3 = 0;
208 UINT32 dwAddr;
209
210 FlashCount = sizeof(gFlashInfo) / sizeof(NOR_FLASH_INFO_TABLE);
211 for(;i < FlashCount; i ++ )
212 {
213
214 Status = GetCommandIndex(i);
215 if (EFI_ERROR(Status))
216 {
217 DEBUG ((EFI_D_ERROR, "[%a]:[%dL]:Get Command Index %r!\n", __FUNCTION__,__LINE__, Status));
218 return Status;
219 }
220
221 FlashReset(Base);
222
223 dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep1 << gFlashInfo[i].ParallelNum);
224 (VOID)PortWriteData(i, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep1);
225
226 dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep2 << gFlashInfo[i].ParallelNum);
227 (VOID)PortWriteData(i, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep2);
228
229 dwAddr = Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddressStep3 << gFlashInfo[i].ParallelNum);
230 (VOID)PortWriteData(i, dwAddr, gFlashCommandId[gIndex.IdIndex].ManuIDDataStep3);
231 //Get manufacture ID
232 TempData = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].ManuIDAddress << gFlashInfo[i].ParallelNum));
233
234 //Get Device Id
235 TempDev1 = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].DeviceIDAddress1 << gFlashInfo[i].ParallelNum));
236 TempDev2 = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].DeviceIDAddress2 << gFlashInfo[i].ParallelNum));
237 TempDev3 = PortReadData(i, Base + (gFlashCommandId[gIndex.IdIndex].DeviceIDAddress3 << gFlashInfo[i].ParallelNum));
238 DEBUG ((EFI_D_ERROR, "[cdtest]manufactor ID 0x%x!\n",TempData));
239 DEBUG ((EFI_D_ERROR, "[cdtest]Device ID 1 0x%x!\n",TempDev1));
240 DEBUG ((EFI_D_ERROR, "[cdtest]Device ID 2 0x%x!\n",TempDev2));
241 DEBUG ((EFI_D_ERROR, "[cdtest]Device ID 3 0x%x!\n",TempDev3));
242
243 FlashReset(Base);
244
245
246 if((0xffffffff != TempData)
247 && (PortAdjustData(i, gFlashInfo[i].ManufacturerID) == TempData))
248 {
249 if((0xffffffff != TempDev1)
250 && (PortAdjustData(i, gFlashInfo[i].DeviceID1) == TempDev1))
251 {
252 if((0xffffffff != TempDev2)
253 && (PortAdjustData(i, gFlashInfo[i].DeviceID2) == TempDev2))
254 {
255 if((0xffffffff != TempDev3)
256 && (PortAdjustData(i, gFlashInfo[i].DeviceID3) == TempDev3))
257 {
258 Flag = 0;
259 gIndex.InfIndex = i;
260 break;
261 }
262 }
263 }
264 }
265 }
266
267 if(Flag)
268 {
269 return EFI_DEVICE_ERROR;
270 }
271
272 return EFI_SUCCESS;
273 }
274
275
width8IsAll(const UINT64 Base,const UINT64 Offset,const UINT64 Length,const UINT8 Value)276 static BOOLEAN width8IsAll(
277 const UINT64 Base,
278 const UINT64 Offset,
279 const UINT64 Length,
280 const UINT8 Value
281 )
282 {
283 UINT64 NewAddr = Base + Offset;
284 UINT64 NewLength = Length;
285 while (NewLength --)
286 {
287 if (*(UINT8 *)(UINTN)NewAddr == Value)
288 {
289 NewAddr ++;
290 continue;
291 }
292 else
293 {
294 return FALSE;
295 }
296 }
297 return TRUE;
298 }
299
300
301
BufferWriteCommand(UINTN Base,UINTN Offset,void * pData)302 EFI_STATUS BufferWriteCommand(UINTN Base, UINTN Offset, void *pData)
303 {
304 UINT32 dwCommAddr;
305 UINT32 *pdwData;
306 UINT16 *pwData;
307 UINT32 dwLoop;
308 UINT32 ulWriteWordCount;
309 UINT32 dwAddr;
310
311 if(gFlashBusy)
312 {
313 DEBUG((EFI_D_ERROR, "[%a]:[%dL]:Flash is busy!\n", __FUNCTION__,__LINE__));
314 return EFI_NOT_READY;
315 }
316 gFlashBusy = TRUE;
317
318 if(2 == gFlashInfo[gIndex.InfIndex].ParallelNum)
319 {
320 pdwData = (UINT32 *)pData;
321
322 dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep1 << gFlashInfo[gIndex.InfIndex].ParallelNum);
323 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep1);
324
325 dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep2 << gFlashInfo[gIndex.InfIndex].ParallelNum);
326 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep2);
327
328 //dwAddr = Base + (Offset << gFlashInfo[gIndex.InfIndex].ParallelNum);
329 dwAddr = (UINT32)Base + Offset;
330 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep3);
331
332
333 ulWriteWordCount = ((gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1) << 16) | (gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1);
334 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, ulWriteWordCount);
335
336
337 for (dwLoop = 0; dwLoop < gFlashInfo[gIndex.InfIndex].BufferProgramSize; dwLoop ++)
338 {
339 dwCommAddr = (UINT32)Base + (UINT32)Offset + (dwLoop << gFlashInfo[gIndex.InfIndex].ParallelNum);
340 MmioWrite32 (dwCommAddr, *pdwData);
341 pdwData ++;
342 }
343
344 dwAddr = (UINT32)Base + (UINT32)Offset + ((gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1) << gFlashInfo[gIndex.InfIndex].ParallelNum);
345 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramtoFlash);
346
347
348
349 }
350 else
351 {
352 pwData = (UINT16 *)pData;
353
354 dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep1 << gFlashInfo[gIndex.InfIndex].ParallelNum);
355 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep1);
356
357 dwAddr = (UINT32)Base + (gFlashCommandWrite[gIndex.WIndex].BufferProgramAddressStep2 << gFlashInfo[gIndex.InfIndex].ParallelNum);
358 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep2);
359
360 //dwAddr = Base + (Offset << gFlashInfo[gIndex.InfIndex].ParallelNum);
361 dwAddr = (UINT32)Base + Offset;
362 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramDataStep3);
363
364
365 ulWriteWordCount = gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1;
366 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, ulWriteWordCount);
367
368
369 for (dwLoop = 0; dwLoop < gFlashInfo[gIndex.InfIndex].BufferProgramSize; dwLoop ++)
370 {
371 dwCommAddr = (UINT32)Base + (UINT32)Offset + (dwLoop << gFlashInfo[gIndex.InfIndex].ParallelNum);
372 MmioWrite16 (dwCommAddr, *pwData);
373 pwData ++;
374 }
375
376 dwAddr = (UINT32)Base + (UINT32)Offset + ((gFlashInfo[gIndex.InfIndex].BufferProgramSize - 1) << gFlashInfo[gIndex.InfIndex].ParallelNum);
377 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandWrite[gIndex.WIndex].BufferProgramtoFlash);
378
379 }
380
381 (void)gBS->Stall(200);
382
383 gFlashBusy = FALSE;
384 return EFI_SUCCESS;
385
386 }
387
388
SectorEraseCommand(UINTN Base,UINTN Offset)389 EFI_STATUS SectorEraseCommand(UINTN Base, UINTN Offset)
390 {
391 UINT32 dwAddr;
392
393 if(gFlashBusy)
394 {
395 DEBUG((EFI_D_ERROR, "[%a]:[%dL]:Flash is busy!\n", __FUNCTION__,__LINE__));
396 return EFI_NOT_READY;
397 }
398
399 gFlashBusy = TRUE;
400
401 dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep1 << gFlashInfo[gIndex.InfIndex].ParallelNum);
402 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep1);
403
404 dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep2 << gFlashInfo[gIndex.InfIndex].ParallelNum);
405 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep2);
406
407 dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep3 << gFlashInfo[gIndex.InfIndex].ParallelNum);
408 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep3);
409
410 dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep4 << gFlashInfo[gIndex.InfIndex].ParallelNum);
411 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep4);
412
413 dwAddr = (UINT32)Base + (gFlashCommandErase[gIndex.EIndex].SectorEraseAddressStep5 << gFlashInfo[gIndex.InfIndex].ParallelNum);
414 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep5);
415
416 dwAddr = (UINT32)Base + Offset;
417 (VOID)PortWriteData(gIndex.InfIndex, dwAddr, gFlashCommandErase[gIndex.EIndex].SectorEraseDataStep6);
418
419 (void)gBS->Stall(500000);
420
421 gFlashBusy = FALSE;
422 return EFI_SUCCESS;
423 }
424
425
CompleteCheck(UINT32 Base,UINT32 Offset,void * pData,UINT32 Length)426 EFI_STATUS CompleteCheck(UINT32 Base, UINT32 Offset, void *pData, UINT32 Length)
427 {
428 UINT32 dwTestAddr;
429 UINT32 dwTestData;
430 UINT32 dwTemp = 0;
431 UINT32 dwTemp1 = 0;
432 UINT32 i;
433 UINT32 dwTimeOut = 3000000;
434
435 if(gFlashBusy)
436 {
437 DEBUG((EFI_D_ERROR, "[%a]:[%dL]:Flash is busy!\n", __FUNCTION__,__LINE__));
438 return EFI_NOT_READY;
439 }
440 gFlashBusy = TRUE;
441
442 if(2 == gFlashInfo[gIndex.InfIndex].ParallelNum)
443 {
444 dwTestAddr = Base + Offset + Length - sizeof(UINT32);
445 dwTestData = *((UINT32 *)((UINT8 *)pData + Length - sizeof(UINT32)));
446
447 while(dwTimeOut--)
448 {
449 dwTemp1 = MmioRead32 (dwTestAddr);
450 if (dwTestData == dwTemp1)
451 {
452 dwTemp = MmioRead32 (dwTestAddr);
453 dwTemp1 = MmioRead32 (dwTestAddr);
454 if ((dwTemp == dwTemp1) && (dwTestData == dwTemp1))
455 {
456 gFlashBusy = FALSE;
457 return EFI_SUCCESS;
458 }
459 }
460
461 (void)gBS->Stall(1);
462 }
463
464 if((UINT16)(dwTemp1 >> 16) != (UINT16)(dwTestData >> 16))
465 {
466 DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: chip1 address %x, buffer %x, flash %x!\n", Offset, dwTestData, dwTemp1));
467 }
468 if((UINT16)(dwTemp1) != (UINT16)(dwTestData))
469 {
470 DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: chip2 address %x, buffer %x, flash %x!\n", Offset, dwTestData, dwTemp1));
471 }
472 }
473 else
474 {
475 dwTestAddr = Base + Offset + Length - sizeof(UINT16);
476 dwTestData = *((UINT16 *)((UINT8 *)pData + Length - sizeof(UINT16)));
477
478 while(dwTimeOut--)
479 {
480 dwTemp1 = MmioRead16 (dwTestAddr);
481 if (dwTestData == dwTemp1)
482 {
483 dwTemp = MmioRead16 (dwTestAddr);
484 dwTemp1 = MmioRead16 (dwTestAddr);
485 if ((dwTemp == dwTemp1) && (dwTestData == dwTemp1))
486 {
487 gFlashBusy = FALSE;
488 return EFI_SUCCESS;
489 }
490 }
491
492 (void)gBS->Stall(1);
493 }
494 }
495
496 for(i = 0; i < 5; i ++)
497 {
498 DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: flash %x\n",PortReadData(gIndex.InfIndex, dwTestAddr)));
499 }
500
501 FlashReset(Base);
502
503 gFlashBusy = FALSE;
504 DEBUG((EFI_D_ERROR, "CompleteCheck ERROR: timeout address %x, buffer %x, flash %x\n", Offset, dwTestData, dwTemp1));
505 return EFI_TIMEOUT;
506 }
507
IsNeedToWrite(IN UINT32 Base,IN UINT32 Offset,IN UINT8 * Buffer,IN UINT32 Length)508 EFI_STATUS IsNeedToWrite(
509 IN UINT32 Base,
510 IN UINT32 Offset,
511 IN UINT8 *Buffer,
512 IN UINT32 Length
513 )
514 {
515 UINTN NewAddr = Base + Offset;
516 UINT8 FlashData = 0;
517 UINT8 BufferData = 0;
518
519 for(; Length > 0; Length --)
520 {
521 BufferData = *Buffer;
522 //lint -epn -e511
523 FlashData = *(UINT8 *)NewAddr;
524 if (BufferData != FlashData)
525 {
526 return TRUE;
527 }
528 NewAddr ++;
529 Buffer ++;
530 }
531
532 return FALSE;
533 }
534
535
BufferWrite(UINT32 Offset,void * pData,UINT32 Length)536 EFI_STATUS BufferWrite(UINT32 Offset, void *pData, UINT32 Length)
537 {
538 EFI_STATUS Status;
539 UINT32 dwLoop;
540 UINT32 Retry = 3;
541
542 if (FALSE == IsNeedToWrite(gIndex.Base, Offset, (UINT8 *)pData, Length))
543 {
544 return EFI_SUCCESS;
545 }
546
547 do
548 {
549 (void)BufferWriteCommand(gIndex.Base, Offset, pData);
550 Status = CompleteCheck(gIndex.Base, Offset, pData, Length);
551
552
553 if (EFI_SUCCESS == Status)
554 {
555 for (dwLoop = 0; dwLoop < Length; dwLoop ++)
556 {
557 if (*(UINT8 *)(UINTN)(gIndex.Base + Offset + dwLoop) != *((UINT8 *)pData + dwLoop))
558 {
559 DEBUG((EFI_D_ERROR, "Flash_WriteUnit ERROR: address %x, buffer %x, flash %x\n", Offset, *((UINT8 *)pData + dwLoop), *(UINT8 *)(UINTN)(gIndex.Base + Offset + dwLoop)));
560 Status = EFI_ABORTED;
561 continue;
562 }
563 }
564 }
565 else
566 {
567 DEBUG((EFI_D_ERROR, "Flash_WriteUnit ERROR: complete check failed, %r\n", Status));
568 continue;
569 }
570 } while ((Retry--) && EFI_ERROR(Status));
571
572 return Status;
573 }
574
575
SectorErase(UINT32 Base,UINT32 Offset)576 EFI_STATUS SectorErase(UINT32 Base, UINT32 Offset)
577 {
578 UINT8 gTemp[FLASH_MAX_UNIT];
579 UINT64 dwLoop = FLASH_MAX_UNIT - 1;
580 UINT32 Retry = 3;
581 EFI_STATUS Status;
582
583 do
584 {
585 gTemp[dwLoop] = 0xFF;
586 }while (dwLoop --);
587
588 do
589 {
590 (void)SectorEraseCommand(Base, Offset);
591 Status = CompleteCheck(Base, Offset, (void *)gTemp, FLASH_MAX_UNIT);
592
593
594 if (EFI_SUCCESS == Status)
595 {
596
597 if (width8IsAll(Base,Offset - (Offset % gFlashInfo[gIndex.InfIndex].BlockSize), gFlashInfo[gIndex.InfIndex].BlockSize, 0xFF))
598 {
599 return EFI_SUCCESS;
600 }
601 else
602 {
603 DEBUG((EFI_D_ERROR, "Flash_SectorErase ERROR: not all address equal 0xFF\n"));
604
605 Status = EFI_ABORTED;
606 continue;
607 }
608 }
609 else
610 {
611 DEBUG((EFI_D_ERROR, "Flash_SectorErase ERROR: complete check failed, %r\n", Status));
612 continue;
613 }
614 }while ((Retry--) && EFI_ERROR(Status));
615
616 if(Retry)
617 {
618 //do nothing for pclint
619 }
620
621 return Status;
622 }
623