Esempio n. 1
0
VOID SetBadBlock(OAL_BLMENU_ITEM *pMenu)
{
    HANDLE hFMD = NULL;
    PCI_REG_INFO regInfo;
    FlashInfo flashInfo;
    BLOCK_ID blockId;
    WCHAR szInputLine[16];

    UNREFERENCED_PARAMETER(pMenu);

    // Open FMD
    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    hFMD = FMD_Init(NULL, &regInfo, 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;
        }

    OALLog(L"\r\n Block Number: ");

    if (OALBLMenuReadLine(szInputLine, dimof(szInputLine)) == 0) 
        {
        goto cleanUp;
        }

    // Get sector number
    blockId = OALStringToUINT32(szInputLine);

    // Check sector number
    if (blockId >= flashInfo.dwNumBlocks) 
        {
        OALLog(L" Oops, too big block number\r\n");
        goto cleanUp;
        }

    FMD_SetBlockStatus(blockId, BLOCK_STATUS_BAD);

    OALLog(L"\r\n Done\r\n");

cleanUp:
    if (hFMD != NULL) 
        {
        FMD_Deinit(hFMD);
        }

    return;
}
BOOL BLConfigureFlashPartitions(BOOL bForceEnable)
{
    BOOL rc = FALSE;
    HANDLE hFMD;
    PCI_REG_INFO regInfo;
    FlashInfo flashInfo;
    HANDLE hPartition;
    PPARTENTRY pPartitionEntry;
    DWORD dwBootPartitionSectorCount;

#ifdef IMGMULTIXIP
    // Variable for sector count for the new BinFS region (EXT) 
    DWORD dwExtPartitionSectorCount;
#endif

    memset(&regInfo, 0, sizeof(PCI_REG_INFO));
    regInfo.MemBase.Num    = 1;
    regInfo.MemLen.Num     = 1;
    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    
    // Get flash info
    hFMD = FMD_Init(NULL, &regInfo, NULL);
    if (hFMD == NULL)
        goto cleanUp;

    if (!FMD_GetInfo(&flashInfo))
        goto cleanUp;
    
    FMD_Deinit(hFMD);
    
    // Initialize boot partition library
    if (!BP_Init((LPBYTE)g_ulBPartBase, g_ulBPartLengthBytes, NULL, &regInfo, NULL))
    {
        OALLog(L"BLConfigureFlashPartitions: Error initializing bootpart library!!\r\n");
        goto cleanUp;
    }
    
    // Get boot partition size
    // Ensure boot partition uses entire blocks with no space left over
    // Round up to an even block size
    dwBootPartitionSectorCount = ((g_bootCfg.osPartitionSize + (flashInfo.dwBytesPerBlock - 1))/ flashInfo.dwBytesPerBlock) * flashInfo.wSectorsPerBlock;

    // Reduce by one to account for MBR, which will be the first sector in non reserved area.
    // This causes boot partition to end on a block boundary
    dwBootPartitionSectorCount -= 1;
	
#ifdef IMGMULTIXIP
    // Calculation of the size for the EXT region
    dwExtPartitionSectorCount = ((IMAGE_WINCE_EXT_SIZE + (flashInfo.dwBytesPerBlock - 1))/ flashInfo.dwBytesPerBlock) * flashInfo.wSectorsPerBlock;

    dwExtPartitionSectorCount -= 1;
#endif	

    // Check for existence and size of OS boot partition
    hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_BOOTSECTION, FALSE, PART_OPEN_EXISTING);
    if (hPartition == INVALID_HANDLE_VALUE)
        OALLog(L"OS partition does not exist!!\r\n");
    else
    {
        pPartitionEntry = BP_GetPartitionInfo(hPartition);
        if (dwBootPartitionSectorCount != pPartitionEntry->Part_TotalSectors)
        {
            OALLog(L"OS partition does not match configured size!!  Sector count expected: 0x%x, actual 0x%x\r\n", dwBootPartitionSectorCount, pPartitionEntry->Part_TotalSectors);
            // Mark handle invalid to kick us into formatting code
            hPartition = INVALID_HANDLE_VALUE;
        }
    }
        
    if ((hPartition == INVALID_HANDLE_VALUE) || (bForceEnable == TRUE))
    {
        // OS binary partition either does not exist or does not match configured size
        OALLog(L"Formatting flash...\r\n");
        // Create a new partion
        // Can't just call BP_OpenPartition with PART_OPEN_ALWAYS because it will erase reserved 
        // blocks (bootloader) if MBR doesn't exist.  Also, we want to ensure the boot partition
        // is actually the first partition on the flash.  So do low level format here (note that 
        // this destroys all other partitions on the device)
        // Note, we're skipping the block check for speed reasons. Might not want this in a production device...
        BP_LowLevelFormat (0, flashInfo.dwNumBlocks, FORMAT_SKIP_RESERVED|FORMAT_SKIP_BLOCK_CHECK);
        // Create the OS partition
        hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, dwBootPartitionSectorCount, PART_BOOTSECTION, FALSE, PART_CREATE_NEW);
        if (hPartition == INVALID_HANDLE_VALUE)
        {
            OALLog(L"Error creating OS partition!!\r\n");
            goto cleanUp;
        }
        OALLog(L"NK partition created\r\n");
		
#ifdef IMGMULTIXIP

       // Creation of the BinFS partition
       hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, dwExtPartitionSectorCount, PART_BINFS, FALSE, PART_CREATE_NEW);
       if (hPartition == INVALID_HANDLE_VALUE)
       {
           OALLog(L"Error creating OS partition!!\r\n");
           goto cleanUp;
       }
       OALLog(L"EXT partition created\r\n");
#endif

        // Create FAT partition on remaining flash (can be automatically mounted)
        hPartition = BP_OpenPartition((DWORD)NEXT_FREE_LOC, (DWORD)USE_REMAINING_SPACE, PART_DOS32, FALSE, PART_CREATE_NEW);
        if (hPartition == INVALID_HANDLE_VALUE)
        {
            OALLog(L"Error creating file partition!!\r\n");
            goto cleanUp;
        }
        OALLog(L"Flash format complete!\r\n");
    }
    
    // Done
    rc = TRUE;

cleanUp:
    return rc;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
//------------------------------------------------------------------------------
//
//  Function:  DFT_IOControl
//
//  This function sends a command to a device.
//
BOOL DFT_IOControl(
    DWORD context, DWORD dwCode,
    BYTE *pInBuffer, DWORD inSize,
    BYTE *pOutBuffer, DWORD outSize, DWORD *pOutSize)
{
    NANDTEST_CONTEXT *pContext = (NANDTEST_CONTEXT *)context;
    HANDLE hFMD;
    PCI_REG_INFO regInfo;
    FlashInfo flashInfo;
    DWORD sector,block; 
    BOOL rc=FALSE;
    UCHAR p_goodata[SECTOR_SIZE*2];

    UNREFERENCED_PARAMETER(pOutSize); 

    DEBUGMSG(ZONE_FUNCTION,
             (L"+DFT_IOControl(0x%08x, 0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x)\r\n",
              context, dwCode, pInBuffer, inSize, pOutBuffer, outSize, pOutSize));

    regInfo.MemBase.Reg[0] = OMAP_GPMC_REGS_PA;
    regInfo.MemLen.Reg[0] = 0x00001000;
    regInfo.MemBase.Reg[1] = BSP_NAND_REGS_PA;
    regInfo.MemLen.Reg[1] = 0x00001000;
	
    hFMD  = FMD_Init(NULL, &regInfo, NULL);
    if (hFMD  == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: FMD_Init call failed!\r\n"));
        goto cleanUp;
    }

    switch (dwCode)
    {
        case NAND_SET_SECTOR:
            // Checking parameter
            if (pInBuffer == NULL || inSize < sizeof(DWORD))
            {
                DEBUGMSG(ZONE_ERROR, (L"+DFT_IOControl(%d): ERROR - invalid parameters\r\n", dwCode));
                goto cleanUp;
            }
            // Get flash info
            if (!FMD_GetInfo(&flashInfo))
            {
                DEBUGMSG(ZONE_ERROR,  (L"ERROR: FMD_GetInfo call failed!\r\n"));
                goto cleanUp;
            }

            pContext->test_sector = *(DWORD*)pInBuffer;
            block  =     pContext->test_sector / flashInfo.wSectorsPerBlock;
            sector = 	pContext->test_sector % flashInfo.wSectorsPerBlock;

            DEBUGMSG(ZONE_ERROR,  (L"Test section info: block=%d sector=%d !\r\n", block, sector));

	     if(block >= flashInfo.dwNumBlocks)
            {
                DEBUGMSG(ZONE_ERROR,  (L"ERROR: invalid sector!\r\n"));
                goto cleanUp;
            }
            if(FMD_GetBlockStatus(block) & 
				(BLOCK_STATUS_BAD |BLOCK_STATUS_RESERVED |BLOCK_STATUS_READONLY))		

            {
                DEBUGMSG(ZONE_ERROR,  (L"ERROR: invalid sector status:%x!\r\n", FMD_GetBlockStatus(block) ));
                goto cleanUp;
            }
			
            rc = TRUE;
			
	     break;
			
        case NAND_ECC_CORRECTION:
            /* Expecting 2 * 2K data, first 2K is good data, 
			                             second 2K is bad data needs correction */
            // Checking parameter
            if (pInBuffer == NULL || inSize != SECTOR_SIZE *2)
            {
                DEBUGMSG(ZONE_ERROR, (L"+DFT_IOControl(%d): ERROR - invalid in parameters\r\n", dwCode));
                goto cleanUp;
            }
            memcpy(p_goodata, pInBuffer, SECTOR_SIZE * 2);
			
            if (pOutBuffer == NULL || outSize != SECTOR_SIZE)
            {
                DEBUGMSG(ZONE_ERROR, (L"+DFT_IOControl(%d): ERROR - invalid out parameters\r\n", dwCode));
                goto cleanUp;
            }

            /* Call ECC test routine */
            rc = nand_ecc_test(context, p_goodata, pOutBuffer);
	     break;
			
	 default:
	     break;
    }
	
cleanUp:
    if (hFMD  != NULL) FMD_Deinit(hFMD);
	
    return rc;
}
Esempio n. 5
0
BOOL WriteFlashNK(UINT32 address, UINT32 size)
{
    BOOL rc = FALSE;
    HANDLE hFMD;
    FlashInfo flashInfo;
    SectorInfo sectorInfo;
    BOOL ok = FALSE;
    BLOCK_ID block;
    //ROMHDR *pTOC;
    UINT32 *pInfo, count, sector;
    UINT32 blockSize, sectorSize, sectorsPerBlock;
    UINT8 *pData;


    OALMSG(OAL_INFO, (L"OEMWriteFlash: Writing NK image to flash\r\n"));

    // We need to know sector/block size
    if ((hFMD = FMD_Init(NULL, NULL, NULL)) == NULL) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"FMD_Init call failed\r\n"
        ));
        goto cleanUp;
    }

    // Get flash info
    if (!FMD_GetInfo(&flashInfo)) {
        OALMSG(OAL_ERROR, (L"ERROR: EBOOT!OEMWriteFlash: "
            L"FMD_GetInfo call failed!\r\n"
        ));
        FMD_Deinit(hFMD);
        goto cleanUp;
    }

    // We don't need access to FMD library
    FMD_Deinit(hFMD);

    OALMSG(OAL_INFO, (L"OEMWriteFlash: "
        L"Flash has %d blocks, %d bytes/block, %d sectors/block\r\n",
        flashInfo.dwNumBlocks, flashInfo.dwBytesPerBlock,
        flashInfo.wSectorsPerBlock
    ));

    // Make block & sector size ready
    blockSize = flashInfo.dwBytesPerBlock;
    sectorSize = flashInfo.wDataBytesPerSector;
    sectorsPerBlock = flashInfo.wSectorsPerBlock;

    // Get data location
    pData = OEMMapMemAddr(address, address);

    // Verify that we get CE image.
    pInfo = (UINT32*)(pData + ROM_SIGNATURE_OFFSET);
    if (*pInfo++ != ROM_SIGNATURE) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"Image Signature not found\r\n"
        ));
        goto cleanUp;
    }
    pInfo++;

    // Skip reserved blocks
    block = 0;
    while (block < flashInfo.dwNumBlocks) {
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Skip bad block %d\r\n", block
            ));
            block++;
            continue;
        }
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_RESERVED) == 0) break;
        block++;
    }

    OALMSG(OAL_INFO, (L"OEMWriteFlash: "
        L"NK image starts at block %d\r\n",  block
    ));

    // Write image
    count = 0;
    while (count < size && block < flashInfo.dwNumBlocks) {

        // If block is bad, we have to offset it
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Skip bad block %d\r\n", block
            ));
            continue;
        }

        // Erase block
        if (!EraseBlock(block)) {
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Block %d erase failed, mark block as bad\r\n", block
            ));
            continue;
        }

        // Now write sectors
        sector = 0;
        while (sector < sectorsPerBlock && count < size) {

            // Prepare sector info
            memset(&sectorInfo, 0xFF, sizeof(sectorInfo));
            sectorInfo.dwReserved1 = 0;
            sectorInfo.wReserved2 = 0;

            // Write sector
            if (!(ok = WriteSector(
                block * sectorsPerBlock + sector, pData + count, &sectorInfo
            ))) break;

            // Move to next sector
            count += sectorSize;
            sector++;
        }

        // When sector write failed, mark block as bad and move back
        if (!ok) {
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Block %d sector %d write failed, mark block as bad\r\n", 
                block, sector
            ));
            // First move back
            count -= sector * flashInfo.wDataBytesPerSector;
            // Mark block as bad
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
        }

        // We are done with block
        block++;
    }

    // Erase rest of media
    while (block < flashInfo.dwNumBlocks) {

        // If block is bad, we have to offset it
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Skip bad block %d\r\n", block
            ));
            continue;
        }

        // When erase failed, mark block as bad and skip it
        if (!EraseBlock(block)) {
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Block %d erase failed, mark block as bad\r\n", block
            ));
            continue;
        }

        // Move to next block
        block++;
    }

    // Close FMD driver
    FMD_Deinit(hFMD);
    hFMD = NULL;

    OALMSG(OAL_INFO, (L"OEMWriteFlash: NK written\r\n"));

    // Done
    rc = TRUE;

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return rc;
}
Esempio n. 6
0
static UINT32 ReadFlashNK()
{
    UINT32 rc = BL_ERROR;
    HANDLE hFMD = NULL;
    FlashInfo flashInfo;
    ROMHDR *pTOC;
    UINT32 offset, size, toc;
    UINT32 blockSize, sectorSize, sectorsPerBlock;
    SectorInfo sectorInfo;
    SECTOR_ADDR sector;
    BLOCK_ID block;
    UINT8 *pImage;

    // Check if there is a valid image
    OALMSG(OAL_INFO, (L"\r\nLoad NK image from flash memory\r\n"));

    // Open FMD to access NAND
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL) {
        OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
            L"FMD_Init call failed\r\n"
        ));
        goto cleanUp;
    }

    // Get flash info
    if (!FMD_GetInfo(&flashInfo)) {
        OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
            L"FMD_GetInfo call failed\r\n"
        ));
        goto cleanUp;
    }

    // Make block & sector size ready
    blockSize = flashInfo.dwBytesPerBlock;
    sectorSize = flashInfo.wDataBytesPerSector;
    sectorsPerBlock = flashInfo.wSectorsPerBlock;

    // Skip reserved blocks
    block = 0;
    while (block < flashInfo.dwNumBlocks) {
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            OALMSG(OAL_WARN, (L"WARN: EBOOT!FMD_GetBlockStatus: "
                L"Skip bad block %d\r\n", block
            ));
            block++;
            continue;
        }
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_RESERVED) == 0) break;
        block++;
    }

    // Set address where to place image
    pImage = (UINT8*)IMAGE_WINCE_CODE_PA;
    size = IMAGE_WINCE_CODE_SIZE;

    // Read image to memory
    offset = 0;
    toc = 0;
    pTOC = NULL;
    while (offset < size && block < flashInfo.dwNumBlocks) {

        // Skip bad blocks
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            sector += flashInfo.wSectorsPerBlock;
            continue;
        }

        // Read sectors in block
        sector = 0;
        while (sector < sectorsPerBlock && offset < size) {
            // When block read fail, there isn't what we can do more
		    
			RETAILMSG(1, (TEXT("0x%x 0x%x \r\n"), block * sectorsPerBlock + sector, pImage + offset));

            if (!FMD_ReadSector(
                block * sectorsPerBlock + sector, pImage + offset, 
                &sectorInfo, 1
            )) {
                OALMSG(OAL_ERROR, (L"\r\nERROR: BLFlashDownload: "
                    L"Failed read sector %d from flash\r\n", sector
                ));
                goto cleanUp;
            }
            // Move to next sector
            sector++;
            offset += sectorSize;
        }

        // Move to next block
        block++;
    }

	g_pTOC->id[g_dwTocEntry].dwJumpAddress = IMAGE_WINCE_CODE_PA;
    rc = BL_JUMP;

cleanUp:
    return rc;
}
Esempio n. 7
0
static UINT32 ReadFlashIPL()
{
    UINT32 rc = BL_ERROR;
    HANDLE hFMD = NULL;
    FlashInfo flashInfo;
    UINT32 offset;
    SectorInfo sectorInfo;
    SECTOR_ADDR sector;
    BLOCK_ID block;
    UINT8 *pImage;
    UINT32 *pInfo;


    // Check if there is a valid image
    OALMSG(OAL_INFO, (L"\r\nLoad IPL Image from flash memory\r\n"));

    // Open FMD to access NAND
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL) {
        OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
            L"FMD_Init call failed\r\n"
        ));
        goto cleanUp;
    }

    // Get flash info
    if (!FMD_GetInfo(&flashInfo)) {
        OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
            L"FMD_GetInfo call failed\r\n"
        ));
        goto cleanUp;
    }

    // Start from NAND start
    block  = 0;
    sector = 8;
    offset = 0;

    // Set address where to place image
    pImage = (UINT8*)(IMAGE_IPL_ADDR_VA);

    // Read image to memory
    while (offset < IMAGE_IPL_SIZE && block < flashInfo.dwNumBlocks) {

        // Read sectors in block
        while ( offset < IMAGE_IPL_SIZE ) {
            // When block read fail, there isn't what we can do more
            if (!FMD_ReadSector(sector, pImage, &sectorInfo, 1)) {
                OALMSG(OAL_ERROR, (L"\r\nERROR: BLFlashDownload: "
                    L"Failed read sector %d from flash\r\n", sector
                ));
                goto cleanUp;
            }

            // Move to next sector
            sector++;
            pImage += flashInfo.wDataBytesPerSector;
            offset += flashInfo.wDataBytesPerSector;
//            OALMSG(OAL_INFO, (L"."));
        }

        // Move to next block
        block++;
    }

    OALMSG(OAL_INFO, (L"\r\n"));

    // Check if IPL is image and dump its content
    pInfo = (UINT32*)(IMAGE_IPL_ADDR_VA + ROM_SIGNATURE_OFFSET);
    if (*pInfo != ROM_SIGNATURE) {
        OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
            L"IPL image doesn't have ROM signature at 0x%08x\r\n", pInfo
        ));
        goto cleanUp;
    }

    g_pTOC->id[g_dwTocEntry].dwJumpAddress = IMAGE_IPL_ADDR_VA;
    rc = BL_JUMP;

cleanUp:
    return rc;
}
BOOL
BLReserveBootBlocks(
    BOOT_CFG *pBootCfg
    )
{
#ifndef BSP_NO_NAND_IN_SDBOOT
    BOOL rc = FALSE;
    HANDLE hFMD;
    PCI_REG_INFO regInfo;
    FlashInfo flashInfo;
    UINT32 size;
    BLOCK_ID firstblock, lastblock;
    UINT32 status;
    
    UNREFERENCED_PARAMETER(pBootCfg);

    // Automatically mark the bootloader blocks as read-only/reserved
    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    hFMD = FMD_Init(NULL, &regInfo, 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;
        }


    //  Loop thru the bootloader blocks to ensure they are marked reserved
    firstblock = 0;
    size = IMAGE_BOOTLOADER_NAND_SIZE;
    lastblock = ((size -1) / flashInfo.dwBytesPerBlock) + 1;

    OALLog(L"Checking bootloader blocks are marked as reserved (Num = %d)\r\n", lastblock-firstblock);

    while (firstblock < lastblock)
        {

        // If block is bad, we have to offset it
        status = FMD_GetBlockStatus(firstblock);

        // Skip bad blocks
        if ((status & BLOCK_STATUS_BAD) != 0) 
            {
            OALLog(L" Skip bad block %d\r\n", firstblock);
            // blocks marked bad would not have been written either, so don't include this 
            // in the count of blocks that are reserved.
            firstblock++;
            lastblock++;
            continue;
            }

        // Skip already reserved blocks
        if ((status & BLOCK_STATUS_RESERVED) != 0) 
            {
            firstblock++;
            continue;
            }

        // Mark block as read-only & reserved
        if (!FMD_SetBlockStatus(firstblock, BLOCK_STATUS_READONLY|BLOCK_STATUS_RESERVED)) 
            {
            OALLog(L" Oops, can't mark block %d - as reserved\r\n", firstblock);
            }

        firstblock++;
        OALLog(L".");
        }

    // Done    
    rc = TRUE;

    OALLog(L"\r\n");

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return rc;
	
#else
    UNREFERENCED_PARAMETER(pBootCfg);
    // Nothing to do...
    return TRUE;

#endif
}
BOOL
BLReadBootCfg(
    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;
    UINT8 buffer[2048];
    
    // EBOOT configuration is placed in last sector of EBOOT image
    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    hFMD = FMD_Init(NULL, &regInfo, 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 < 2048 bytes
    if (flashInfo.wDataBytesPerSector > sizeof(buffer))
        {
        OALMSG(OAL_ERROR, (L"ERROR: "
            L"Flash sector size %d bytes bigger than supported %d bytes\r\n",
            flashInfo.wDataBytesPerSector, sizeof(buffer)    
            ));
        goto cleanUp;
        }

    // Configuration is located in last sector of EBOOT image
    offset = IMAGE_XLDR_BOOTSEC_NAND_SIZE + IMAGE_EBOOT_BOOTSEC_NAND_SIZE;
    
    // Start from beginning
    block  = 0;
    sector = 0;

    // Skip X-Loader & EBOOT code & bad blocks
    // Note that we also check the last eboot block in order to ensure it is good
    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--;

    //  Compute sector within the block where config lies
    sector = block * flashInfo.wSectorsPerBlock;
    sector += flashInfo.wSectorsPerBlock - 1;

    // Read sector to buffer
    if (!FMD_ReadSector(sector, buffer, &sectorInfo, 1)) {
        OALMSG(OAL_ERROR, (L"ERROR: EBOOT!BLReadBootCfg: "
            L"Flash sector %d read failed\r\n", sector
        ));
            goto cleanUp;
    }

    // Copy data to BOOT_CFG structure
    memcpy(pBootCfg, buffer, sizeof(BOOT_CFG));        

    // Done    
    rc = TRUE;

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
#else
    UNREFERENCED_PARAMETER(pBootCfg);
#endif
    return rc;
}
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, &regInfo, 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, &sectorInfo, 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(&sectorInfo, 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, &sectorInfo, 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;
}
Esempio n. 11
0
VOID DumpFlash(OAL_BLMENU_ITEM *pMenu)
{
    HANDLE hFMD = NULL;
    PCI_REG_INFO regInfo;
    FlashInfo flashInfo;
    SectorInfo sectorInfo;
    SECTOR_ADDR sector;
    WCHAR szInputLine[16];
    UINT8 buffer[2048], pOob[64];
    UINT32 i, j;

    UNREFERENCED_PARAMETER(pMenu);


    // Open FMD
    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    hFMD = FMD_Init(NULL, &regInfo, 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 (flashInfo.wDataBytesPerSector > sizeof(buffer)) 
        {
        OALLog(L" Oops, sector size larger than my buffer\r\n");
        goto cleanUp;
        }

        for(;;)
        {

        OALLog(L"\r\n Sector Number: ");

        if (OALBLMenuReadLine(szInputLine, dimof(szInputLine)) == 0) 
            {
            break;
            }

        // Get sector number
        sector = OALStringToUINT32(szInputLine);

        // Check sector number
        if (sector > flashInfo.dwNumBlocks * flashInfo.wSectorsPerBlock) 
            {
            OALLog(L" Oops, too big sector number\r\n");
            continue;
            }

        if (!FMD_ReadSector(sector, buffer, &sectorInfo, 1)) 
            {
            OALLog(L" Oops, sector read failed\r\n");
            continue;
            }

        OALLog(
            L"\r\nSector %d (sector %d in block %d)\r\n", sector,
            sector%flashInfo.wSectorsPerBlock, sector/flashInfo.wSectorsPerBlock
        );
        OALLog(
            L"Reserved1: %08x OEMReserved: %02x Bad: %02x Reserved2: %04x\r\n",
            sectorInfo.dwReserved1, sectorInfo.bOEMReserved,
            sectorInfo.bBadBlock, sectorInfo.wReserved2
        );

        for (i = 0; i < flashInfo.wDataBytesPerSector; i += 16) 
            {
            OALLog(L"%04x ", i);
            for (j = i; j < i + 16 && j < flashInfo.wDataBytesPerSector; j++) 
                {
                OALLog(L" %02x", buffer[j]);
                }
            OALLog(L"  ");
            for (j = i; j < i + 16 && j < flashInfo.wDataBytesPerSector; j++) 
                {
                if (buffer[j] >= ' ' && buffer[j] < 127) 
                    {
                    OALLog(L"%c", buffer[j]);
                    } 
                else 
                    {
                    OALLog(L".");
                    }
                }
            OALLog(L"\r\n");
            }
	//dump OOB data
        if (!FMD_ReadSectorOOB(sector, pOob)) 
            {
            OALLog(L" Oops, sector read failed\r\n");
            continue;
            }
        for (i = 0; i < 64; i += 16) 
            {
            OALLog(L"%04x ", i);
            for (j = i; j < i + 16 && j < 64; j++) 
                {
                OALLog(L" %02x", pOob[j]);
                }
                
            OALLog(L"\r\n");
            }

        }

cleanUp:

    if (hFMD != NULL) 
        {
        FMD_Deinit(hFMD);
        }

    return;
}
Esempio n. 12
0
VOID ReserveBlock(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, &regInfo, 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 mark as reserved 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);

        // Skip bad blocks
        if ((status & BLOCK_STATUS_BAD) != 0) 
            {
            OALLog(L" Skip bad block %d\r\n", firstblock);
            // NOTE - this will cause a smaller number of blocks to actually be reserved...
            firstblock++;
            continue;
            }

        // Skip already reserved blocks
        if ((status & BLOCK_STATUS_RESERVED) != 0) 
            {
            OALLog(L" Skip reserved block %d\r\n", firstblock);
            firstblock++;
            continue;
            }

        // Mark block as read-only & reserved
        if (!FMD_SetBlockStatus(firstblock, BLOCK_STATUS_READONLY|BLOCK_STATUS_RESERVED)) 
            {
            OALLog(L" Oops, can't mark block %d - as reserved\r\n", firstblock);
            }

        firstblock++;
        OALLog(L".");
        }

    OALLog(L" Done\r\n");

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return;
}
Esempio n. 13
0
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, &regInfo, 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;
}
Esempio n. 14
0
VOID 
ShowFlashGeometry(OAL_BLMENU_ITEM *pMenu)
{
    HANDLE hFMD;
    PCI_REG_INFO regInfo;
    FlashInfo flashInfo;
    LPCWSTR pszType;
    BLOCK_ID block;
    UINT32 status;
    UINT32 listmode=0;

    UNREFERENCED_PARAMETER(pMenu);

    regInfo.MemBase.Reg[0] = g_ulFlashBase;
    hFMD = FMD_Init(NULL, &regInfo, 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;
        }

    switch (flashInfo.flashType) 
        {
        case NAND:
            pszType = L"NAND";
            break;
        case NOR:
            pszType = L"NOR";
            break;
        default:
            pszType = L"Unknown";
        }

    OALLog(L"\r\n");
    OALLog(L" Flash Type:    %s\r\n", pszType);
    OALLog(L" Blocks:        %d\r\n", flashInfo.dwNumBlocks);
    OALLog(L" Bytes/block:   %d\r\n", flashInfo.dwBytesPerBlock);
    OALLog(L" Sectors/block: %d\r\n", flashInfo.wSectorsPerBlock);
    OALLog(L" Bytes/sector:  %d\r\n", flashInfo.wDataBytesPerSector);
	
    switch (g_bootCfg.ECCtype) 
        {
        case 0:
            pszType = L"Hamming 1bit ECC";
            break;
        case 1:
            pszType = L"BCH 4bit ECC";
            break;
        case 2:
            pszType = L"BCH 8bit ECC";
            break;
			
        default:
            pszType = L"Unknown";
        }
	
    OALLog(L" ECC mode:  %s\r\n", pszType);

    // now list bad/reserved sectors

    // First offset given
    block = 0;
    while (block < flashInfo.dwNumBlocks) 
        {

        // If block is bad, we have to offset it
        status = FMD_GetBlockStatus(block);

        // bad block
        if ((status & BLOCK_STATUS_BAD) != 0) 
            {
            if (listmode!=1)
                {
                OALLog(L"\r\n[bad]     ");
                listmode=1;
                }

            OALLog(L" %d", block);

            block++;
            continue;
            }

        // reserved block
        if ((status & BLOCK_STATUS_RESERVED) != 0) 
            {
            if (listmode!=2)
                {
                OALLog(L"\r\n[reserved]");
                listmode=2;
                }

            OALLog(L" %d", block);

            block++;
            continue;
            }

        block++;
    }

    OALLog(L" Done\r\n");

cleanUp:
    if (hFMD != NULL) 
        {
        FMD_Deinit(hFMD);
        }
    return;
}