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