BOOL EraseBlock(BLOCK_ID block) { BOOL rc; UINT32 retry = 4; // Erase block do { rc = FMD_EraseBlock(block); } while (!rc && --retry > 0); return rc; }
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { DWORD dwBlock = 0; DWORD dwNumBlocks = 0; LPBYTE pbBuffer; SectorInfo si; //unsigned int sectorchk; unsigned int sectorcnt = 0; unsigned int areachange = 0; OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n"))); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if(dwLaunchAddr==0x10) { dwBlock = LOGO_BLOCK; //dwImageLength = UPLDR_RAM_IMAGE_SIZE; g_ImageType=IMAGE_TYPE_RAWBIN; }else{ if (g_ImageType == IMAGE_TYPE_LOADER) { dwBlock = EBOOT_BLOCK; if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: INVALID_TOC\r\n"))); if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n"))); return(FALSE); } } } else if (g_ImageType == IMAGE_TYPE_STEPLDR) { dwBlock = STEPLDR_BLOCK; dwImageStart += dwLaunchAddr; //dwImageLength = 0x2050; //step loader can support 8k bytes. //dwImageLength = STEPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } else if (g_ImageType == IMAGE_TYPE_DIONB0) { dwBlock = DIONB0_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength -= (dwImageLength / (g_FlashInfo.wDataBytesPerSector + 8))*8; } else if (g_ImageType == IMAGE_TYPE_UPLDR) { dwBlock = UPLDR_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength = UPLDR_RAM_IMAGE_SIZE; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } else if (g_ImageType == IMAGE_TYPE_FLASHBIN) { dwBlock = FLASHBIN_BLOCK; // dwImageStart += dwLaunchAddr; // dwImageLength = dwImageLength; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block } } if(dwLaunchAddr==0x10) pbBuffer=(LPBYTE)dwImageStart; else pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart); // Compute number of blocks. dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength)); OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks)); while (dwNumBlocks--) { // If the block is marked bad, skip to next block. Note that the assumption in our error checking // is that any truely bad block will be marked either by the factory during production or will be marked // during the erase and write verification phases. If anything other than a bad block fails ECC correction // in this routine, it's fatal. OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); if (!FMD_EraseBlock(dwBlock)) { OALMSG(TRUE, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } // FMD_GetBlockStatus(dwBlock); if ((FMD_GetBlockStatus(dwBlock) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))&&dwBlock!=0) { OALMSG(TRUE, (TEXT("FMD_GetBlockStatus Error \r\n"))); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } //FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1); if (!FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1)) { OALMSG(TRUE, (TEXT("FMD_ReadSector : Failed to get block(0x%x)'s sector info.\r\n"), dwBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=0xfc )&&dwBlock!=0) { OALMSG(TRUE, (TEXT("si.bBadBlock failed, si.bOEMReserved %x,si.bBadBlock %x.\r\n"),si.bOEMReserved, si.bBadBlock)); ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) { OALMSG(TRUE, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock)); return(FALSE); } if (g_ImageType == IMAGE_TYPE_DIONB0) { for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ ) { if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8); } ++dwBlock; } else if (g_ImageType == IMAGE_TYPE_FLASHBIN) { for ( int iSector = 0; iSector < g_FlashInfo.wSectorsPerBlock; iSector ++ ) { //RETAILMSG(1, (TEXT("WriteData: (0x%x)(0x%x,0x%x,0x%x).\r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, g_pSectorInfoBuf->dwReserved1, g_pSectorInfoBuf->bOEMReserved, g_pSectorInfoBuf->wReserved2)); if (!WritePage(dwBlock*g_FlashInfo.wSectorsPerBlock + iSector, pbBuffer, (PSectorInfo)(pbBuffer+g_FlashInfo.wDataBytesPerSector) )) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); #ifdef IROMBOOT FMD_EraseBlock(dwBlock); // this block is actually considered to bad block. // because it may be erased initial bad block information. si.bOEMReserved = 0xff; si.bBadBlock = BADBLOCKMARK; si.dwReserved1 = 0xffffffff; si.wReserved2 = 0xffff; FMD_WriteSector(BLOCK_TO_SECTOR(dwBlock), NULL, &si, 1); pbBuffer -= (g_FlashInfo.wDataBytesPerSector + 8)*iSector; iSector = 0; break; #else return(FALSE); #endif // !IROMBOOT } pbBuffer += (g_FlashInfo.wDataBytesPerSector + 8); } ++dwBlock; } else { OALMSG(TRUE, (TEXT(" Write Reserved Area \n"))); if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) { OALMSG(TRUE, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } ++dwBlock; OALMSG(TRUE, (TEXT("pbBuffer + %x .\r\n"), SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK)); #ifdef IROMBOOT pbBuffer += (SECTOR_SIZE/*SECTORS_PER_PAGE*/*PAGES_PER_BLOCK); #else pbBuffer += 0x4000; #endif // !IROMBOOT } } if (g_ImageType == IMAGE_TYPE_LOADER) { g_pTOC->id[0].dwLoadAddress = dwImageStart; g_pTOC->id[0].dwJumpAddress = 0; g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength); g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK); g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors; } OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n"))); return TRUE; }
// // Store TOC to Nand // BUGBUG: only uses 1 sector for now. // BOOL TOC_Write(void) { SectorInfo si, si2; EdbgOutputDebugString("+TOC_Write\r\n"); if ( !g_bBootMediaExist ) { EdbgOutputDebugString("TOC_Write WARN: no boot media\r\n"); return FALSE; } // is it a valid TOC? if ( !VALID_TOC(g_pTOC) ) { EdbgOutputDebugString("TOC_Write ERROR: INVALID_TOC Signature: 0x%x\r\n", g_pTOC->dwSignature); // return FALSE; } // is it a valid image descriptor? if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) { EdbgOutputDebugString("TOC_Write ERROR: INVALID_IMAGE[%u] Signature: 0x%x\r\n", g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwSignature); //return FALSE; } // in order to write a sector we must erase the entire block first // !! BUGBUG: must cache the TOC first so we don't trash other image descriptors !! if ( !FMD_EraseBlock(TOC_BLOCK) ) { RETAILMSG(1, (TEXT("TOC_Write ERROR: EraseBlock[%d] \r\n"), TOC_BLOCK)); return FALSE; } // setup our metadata so filesys won't stomp us si.dwReserved1 = 0; si.bOEMReserved = OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY; si.bBadBlock = BADBLOCKMARK; si.wReserved2 = 0; // write the sector & metadata if ( !FMD_WriteSector(TOC_SECTOR, (PUCHAR)&g_TOC, &si, 1) ) { EdbgOutputDebugString("TOC_Write ERROR: Unable to save TOC\r\n"); return FALSE; } // read it back & verify both data & metadata if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)&toc, &si2, 1) ) { EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOC\r\n"); return FALSE; } if ( 0 != memcmp(&g_TOC, &toc, SECTOR_SIZE) ) { EdbgOutputDebugString("TOC_Write ERROR: TOC verify failed\r\n"); return FALSE; } if ( 0 != memcmp(&si, &si2, sizeof(si)) ) { EdbgOutputDebugString("TOC_Write ERROR: SectorInfo verify failed: %x %x %x %x\r\n", si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2); return FALSE; } EdbgOutputDebugString("-TOC_Write\r\n"); return TRUE; }
BOOL nand_ecc_test( DWORD Context, UCHAR *pInBuffer, UCHAR *p_outbuf) { NANDTEST_CONTEXT *pContext = (NANDTEST_CONTEXT *)Context; BOOL rc = FALSE; DWORD block; FlashInfo flashInfo; UCHAR outBuf[SECTOR_SIZE]; SectorInfo secInfo; UCHAR *p_gooddata, *p_baddata; /* NAND ECC test sector: pContext.test_sector data: p_gooddata, p_baddata */ p_gooddata = pInBuffer; p_baddata = pInBuffer + SECTOR_SIZE; DEBUGMSG(ZONE_FUNCTION, (L"+nand_ecc_test: p_gooddata=%x, p_baddata=%x\r\n", p_gooddata, p_baddata)); /* Step 0: Erase block */ if (!FMD_GetInfo(&flashInfo)) { DEBUGMSG(ZONE_ERROR, (L"ERROR: FMD_GetInfo call failed!\r\n")); goto cleanUp; } block = pContext->test_sector / flashInfo.wSectorsPerBlock; rc = FMD_EraseBlock(block); if(!rc) { DEBUGMSG(ZONE_ERROR, (L"ERROR: nand_ecc_test ERASE block(%d) failed!\r\n", block)); goto cleanUp; } /* Step 1: flash the NAND with Good data */ rc = FMD_WriteSector(pContext->test_sector, p_gooddata, NULL, 1); if( !rc ) { DEBUGMSG(ZONE_ERROR, (L"ERROR: nand_ecc_test WRITE good data in sector(%d) failed!\r\n", pContext->test_sector)); goto cleanUp; } /* Step 2: read back to see if there are errors */ rc = FMD_ReadSector(pContext->test_sector, outBuf, NULL, 1); if( !rc ) { DEBUGMSG(ZONE_ERROR, (L"ERROR: nand_ecc_test READ good data in sector(%d) failed!\r\n", pContext->test_sector)); goto cleanUp; } if(memcmp(outBuf, p_gooddata, SECTOR_SIZE)) { DEBUGMSG(ZONE_ERROR, (L"ERROR: nand_ecc_test READ data does not match good data in sector(%d) failed!\r\n", pContext->test_sector)); goto cleanUp; } /* Step 3: flash the NAND with Bad data WITHOUT UPDATING ecc*/ memset (&secInfo, 0, sizeof(secInfo)); secInfo.bOEMReserved = SKIP_ECC_WRITE_MAGIC_NUMBER; rc = FMD_WriteSector(pContext->test_sector, p_baddata, &secInfo, 1); if( !rc ) { DEBUGMSG(ZONE_ERROR, (L"ERROR: nand_ecc_test WRITE bad data in sector(%d) failed!\r\n", pContext->test_sector)); goto cleanUp; } /* Step 4: read back to see if there are errors */ rc = FMD_ReadSector(pContext->test_sector, outBuf, NULL, 1); if( !rc ) { DEBUGMSG(ZONE_ERROR, (L"ERROR: nand_ecc_test READ good data in sector(%d) failed!\r\n", pContext->test_sector)); goto cleanUp; } if(memcmp(outBuf, p_gooddata, SECTOR_SIZE)) { RETAILMSG(TRUE, (L"ERROR: nand_ecc_test READ data after correction does not match good data in sector(%d) failed!\r\n", pContext->test_sector)); goto cleanUp; } rc = TRUE; cleanUp: memcpy(p_outbuf, outBuf, SECTOR_SIZE ); return rc; }
BOOL WriteRawImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) { DWORD dwBlock,dwNumBlocks; LPBYTE pbBuffer; SectorInfo si; OALMSG(OAL_FUNC, (TEXT("+WriteRawImageToBootMedia\r\n"))); if ( !g_bBootMediaExist ) { OALMSG(OAL_ERROR, (TEXT("ERROR: WriteRawImageToBootMedia: device doesn't exist.\r\n"))); return(FALSE); } if (g_ImageType == IMAGE_TYPE_LOADER) { dwBlock = EBOOT_BLOCK; if ( !VALID_TOC(g_pTOC) ) { OALMSG(OAL_WARN, (TEXT("WARN: WriteRawImageToBootMedia: INVALID_TOC\r\n"))); if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) { OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n"))); return(FALSE); } } } else if (g_ImageType == IMAGE_TYPE_STEPLDR) { dwBlock = NBOOT_BLOCK; dwImageStart += dwLaunchAddr; dwImageLength = STEPPINGSTONE_SIZE; //step loader can support 8k bytes. } pbBuffer = OEMMapMemAddr(dwImageStart, dwImageStart); // Compute number of blocks. //dwNumBlocks = (dwImageLength / 0x4000) + 1; dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) + (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0); OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength)); OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks)); while (dwNumBlocks--) { // If the block is marked bad, skip to next block. Note that the assumption in our error checking // is that any truely bad block will be marked either by the factory during production or will be marked // during the erase and write verification phases. If anything other than a bad block fails ECC correction // in this routine, it's fatal. OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock)); OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock)); OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock)); FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1); // Stepldr & Eboot image in nand flash // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD if ((si.bBadBlock == BADBLOCKMARK) && (si.bOEMReserved != 0xFC )) { ++dwBlock; ++dwNumBlocks; // Compensate for fact that we didn't write any blocks. continue; } if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock)); return(FALSE); } if (!FMD_EraseBlock(dwBlock)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock)); return FALSE; } if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)) { OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock)); return(FALSE); } ++dwBlock; pbBuffer += g_FlashInfo.dwBytesPerBlock; //c ksk 20060311 OALMSG(TRUE, (TEXT("dwBytesPerBlock : %d\r\n"), g_FlashInfo.dwBytesPerBlock)); } if (g_ImageType == IMAGE_TYPE_LOADER) { g_pTOC->id[0].dwLoadAddress = dwImageStart; g_pTOC->id[0].dwJumpAddress = 0; g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength); g_pTOC->id[0].sgList[0].dwSector = BLOCK_TO_SECTOR(EBOOT_BLOCK); g_pTOC->id[0].sgList[0].dwLength = g_pTOC->id[0].dwTtlSectors; } OALMSG(OAL_FUNC, (TEXT("_WriteRawImageToBootMedia\r\n"))); return TRUE; }
BOOL BLWriteBootCfg( BOOT_CFG *pBootCfg ) { BOOL rc = FALSE; #ifndef BSP_NO_NAND_IN_SDBOOT HANDLE hFMD; PCI_REG_INFO regInfo; FlashInfo flashInfo; SectorInfo sectorInfo; SECTOR_ADDR sector; BLOCK_ID block; UINT32 count, offset, length; UINT8 buffer[2048]; UINT8 *pEBOOT; // EBOOT configuration is placed in last sector of image regInfo.MemBase.Reg[0] = g_ulFlashBase; hFMD = FMD_Init(NULL, ®Info, NULL); if (hFMD == NULL) { OALMSG(OAL_ERROR, (L"ERROR: FMD_Init call failed!\r\n")); goto cleanUp; } // Get flash info if (!FMD_GetInfo(&flashInfo)) { OALMSG(OAL_ERROR, (L"ERROR: FMD_GetInfo call failed!\r\n")); goto cleanUp; } // We can support only flash with sector size which fit to our buffer if (flashInfo.wDataBytesPerSector > sizeof(buffer)) { OALMSG(OAL_ERROR, (L"ERROR: " L"Flash sector size %d bytes bigger that supported %d bytes\r\n", flashInfo.wDataBytesPerSector, sizeof(buffer) )); goto cleanUp; } // Configuration is located in last sector of last EBOOT block offset = IMAGE_XLDR_BOOTSEC_NAND_SIZE + IMAGE_EBOOT_BOOTSEC_NAND_SIZE; // Skip X-Loader & EBOOT code & bad blocks // Note that we also check the last eboot block in order to ensure it is good block = 0; count = 0; while ((count < offset) && (block < flashInfo.dwNumBlocks)) { if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) == 0) { count += flashInfo.dwBytesPerBlock; } block++; } // We've incremented past the last eboot block in order to check it too // Back up now, the previous block is the last one containing eboot and is good block--; // Need to copy off the block contents to RAM (minus the config sector) pEBOOT = (UINT8*)IMAGE_WINCE_CODE_CA; length = flashInfo.dwBytesPerBlock - flashInfo.wDataBytesPerSector; memset((VOID*)pEBOOT, 0xFF, flashInfo.dwBytesPerBlock); sector = block * flashInfo.wSectorsPerBlock; offset = 0; while (offset < length) { // When block read fail, there isn't what we can do more if (!FMD_ReadSector(sector, pEBOOT + offset, §orInfo, 1)) { OALMSG(OAL_ERROR, (L"\r\nERROR: EBOOT!BLWriteBootCfg: " L"Failed read sector %d from flash\r\n", sector )); goto cleanUp; } // Move to next sector sector++; offset += flashInfo.wDataBytesPerSector; } // Copy the config info into last sector of saved block in RAM memcpy(pEBOOT + offset, pBootCfg, sizeof(BOOT_CFG)); // Erase block if (!FMD_EraseBlock(block)) { OALMSG(OAL_ERROR, (L"ERROR: EBOOT!BLWriteBootCfg: " L"Flash block %d erase failed\r\n", block )); goto cleanUp; } // Write contents of the save block + config sector back to flash pEBOOT = (UINT8*)IMAGE_WINCE_CODE_CA; length = flashInfo.dwBytesPerBlock; sector = block * flashInfo.wSectorsPerBlock; offset = 0; while (offset < length) { // Prepare sector info memset(§orInfo, 0xFF, sizeof(sectorInfo)); sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED); sectorInfo.dwReserved1 = 0; sectorInfo.wReserved2 = 0; // Write sector if (!FMD_WriteSector(sector, pEBOOT + offset, §orInfo, 1)) { OALMSG(OAL_ERROR, (L"ERROR: EBOOT!BLWriteBootCfg: " L"Flash sector %d write failed\r\n", sector )); goto cleanUp; } // Move to next sector sector++; offset += flashInfo.wDataBytesPerSector; } // Done rc = TRUE; cleanUp: if (hFMD != NULL) FMD_Deinit(hFMD); #else UNREFERENCED_PARAMETER(pBootCfg); #endif return rc; }
VOID EraseBlock(OAL_BLMENU_ITEM *pMenu) { WCHAR key; HANDLE hFMD = NULL; PCI_REG_INFO regInfo; FlashInfo flashInfo; BLOCK_ID firstblock, lastblock=0; WCHAR szInputLine[16]; UINT32 status; UNREFERENCED_PARAMETER(pMenu); OALLog(L"\r\n First Block Number: "); if (OALBLMenuReadLine(szInputLine, dimof(szInputLine)) == 0) { goto cleanUp; } // Get block number firstblock = OALStringToUINT32(szInputLine); OALLog(L"\r\n Last Block Number: "); if (OALBLMenuReadLine(szInputLine, dimof(szInputLine)) != 0) { // Get block number lastblock = OALStringToUINT32(szInputLine); } if (lastblock < firstblock) { lastblock=firstblock; } // Open FMD regInfo.MemBase.Reg[0] = g_ulFlashBase; hFMD = FMD_Init(NULL, ®Info, NULL); if (hFMD == NULL) { OALLog(L" Oops, can't open FMD driver\r\n"); goto cleanUp; } if (!FMD_GetInfo(&flashInfo)) { OALLog(L" Oops, can't get flash geometry info\r\n"); goto cleanUp; } if (lastblock >= flashInfo.dwNumBlocks) { OALLog(L" Oops, too big block number\r\n"); goto cleanUp; } OALLog(L" Do you want erase block %d-%d [-/y]? ", firstblock, lastblock); // Get key key = OALBLMenuReadKey(TRUE); OALLog(L"%c\r\n", key); // Depending on result if (key != L'y' && key != L'Y') { goto cleanUp; } while (firstblock<=lastblock) { // If block is bad, we have to offset it status = FMD_GetBlockStatus(firstblock); // ask before erasing reserved blocks if ((status & BLOCK_STATUS_RESERVED) != 0) { OALLog(L" Do you want to erase reserved block %d [-/y]? ", firstblock); // Get key key = OALBLMenuReadKey(TRUE); OALLog(L"%c\r\n", key); // Depending on result if (key != L'y' && key != L'Y') { firstblock++; continue; } } // ask before erasing bad blocks if ((status & BLOCK_STATUS_BAD) != 0) { OALLog(L" Do you want to erase bad block %d [-/y]? ", firstblock); // Get key key = OALBLMenuReadKey(TRUE); OALLog(L"%c\r\n", key); // Depending on result if (key != L'y' && key != L'Y') { firstblock++; continue; } } // Erase block if (!FMD_EraseBlock(firstblock)) { OALLog(L" Oops, can't erase block %d - mark as bad\r\n", firstblock); FMD_SetBlockStatus(firstblock, BLOCK_STATUS_BAD); } firstblock++; OALLog(L"."); } OALLog(L" Done\r\n"); cleanUp: if (hFMD != NULL) FMD_Deinit(hFMD); return; }
VOID EraseFlash(OAL_BLMENU_ITEM *pMenu) { WCHAR key; HANDLE hFMD = NULL; PCI_REG_INFO regInfo; FlashInfo flashInfo; BLOCK_ID block; UINT32 status; UNREFERENCED_PARAMETER(pMenu); OALLog(L" Do you want to erase unreserved blocks [-/y]? "); // Get key key = OALBLMenuReadKey(TRUE); OALLog(L"%c\r\n", key); // Depending on result if (key != L'y' && key != L'Y') goto cleanUp; // Open FMD regInfo.MemBase.Reg[0] = g_ulFlashBase; hFMD = FMD_Init(NULL, ®Info, NULL); if (hFMD == NULL) { OALLog(L" Oops, can't open FMD driver\r\n"); goto cleanUp; } if (!FMD_GetInfo(&flashInfo)) { OALLog(L" Oops, can't get flash geometry info\r\n"); goto cleanUp; } // First offset given block = 0; while (block < flashInfo.dwNumBlocks) { // If block is bad, we have to offset it status = FMD_GetBlockStatus(block); // Skip bad blocks if ((status & BLOCK_STATUS_BAD) != 0) { OALLog(L" Skip bad block %d\r\n", block); block++; continue; } // Skip reserved blocks if ((status & BLOCK_STATUS_RESERVED) != 0) { OALLog(L" Skip reserved block %d\r\n", block); block++; continue; } // Erase block if (!FMD_EraseBlock(block)) { OALLog(L" Oops, can't erase block %d - mark as bad\r\n", block); FMD_SetBlockStatus(block, BLOCK_STATUS_BAD); } block++; } OALLog(L" Done\r\n"); // Block until a keypress OALBLMenuReadKey(TRUE); cleanUp: if (hFMD != NULL) FMD_Deinit(hFMD); return; }