Esempio n. 1
0
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;
}
Esempio n. 2
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. 3
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;
}
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
}
Esempio n. 5
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;
}
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. 8
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. 9
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. 10
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;
}