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 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 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 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 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 175 VOID FlashReset(UINT32 Base) 176 { 177 (VOID)PortWriteData(gIndex.InfIndex, Base, gFlashCommandReset[gIndex.ReIndex].ResetData); 178 (void)gBS->Stall(20000); 179 } 180 181 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 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 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 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 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 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 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 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 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