📄 flash.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//*****************************************************************************
//* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2005 *
//------------------------------------------------------------------------------
//
// File: flash.c
//
// Flash routines for the PLATO bootloader.
//
#include <windows.h>
#include <plato.h>
#include <oal_memory.h>
#include <fmd.h>
#include <bsp_mdoc_cfg.h>
#include "eboot_fmd.h"
#include "loader.h"
#include "flash.h"
// Global variables.
//
extern IMAGE_TYPE g_ImageType;
extern BOOL g_FormatFlash;
// External function prorotypes.
//
extern void DisplayDebugString(CHAR * str);
// Flash base Address for tffslib
//
DWORD flDocBaseAddress = 0xAA700000; // uncached address
#ifdef DEBUG
void DumpTOC(ROMHDR *pTOC);
#endif
//------------------------------------------------------------------------------
//
// Function: OEMIsFlashAddr
//
// Checks the address provided and determines if it's a flash address or not.
//
BOOL OEMIsFlashAddr(DWORD dwAddr)
{
DWORD dwVirtFlashStart = (DWORD) OALPAtoVA(PLATO_BASE_PA_BOOT_FLASH, FALSE);
DWORD dwCachedVirtFlashStart = (DWORD) OALPAtoVA(PLATO_BASE_PA_BOOT_FLASH, TRUE);
if ((dwAddr >= dwVirtFlashStart) && (dwAddr <= (dwVirtFlashStart + PLATO_SIZE_BOOT_FLASH)))
{
return(TRUE);
}
if ((dwAddr >= dwCachedVirtFlashStart) && (dwAddr <= (dwCachedVirtFlashStart + PLATO_SIZE_BOOT_FLASH)))
{
return(TRUE);
}
return(FALSE);
}
//------------------------------------------------------------------------------
//
// Function: OEMMapMemAddr
//
// Maps a flash address to a RAM address (used when temporarily caching a
// flash-destined download image to RAM).
//
LPBYTE OEMMapMemAddr (DWORD dwImageStart, DWORD dwAddr)
{
if (OEMIsFlashAddr(dwAddr))
{
// The image being downloaded is a flash image - temporarily
// cache the image in RAM until it's completely downloaded.
//
dwAddr -= dwImageStart;
dwAddr += EBOOT_FLASHBLOCK_CACHE_START;
}
return((LPBYTE) (dwAddr));
}
//------------------------------------------------------------------------------
//
// Function: OEMStartEraseFlash
//
// Begins the flash erase procedure.
//
BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: main
//
// Continues the flash erase procedure (erases are incrementally done during
// download to speed up the overall flash operation from the user's perspective).
//
void OEMContinueEraseFlash(void)
{
}
//------------------------------------------------------------------------------
//
// Function: OEMFinishEraseFlash
//
// Finished the flash erase procedure.
//
BOOL OEMFinishEraseFlash(void)
{
return(TRUE);
}
BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)
{
BOOL retVal = FALSE;
switch(g_ImageType)
{
case IMAGE_TYPE_MDOCLDR:
DisplayDebugString("MDOCLDR flash in progress");
retVal = WriteFlashMDOCLDR(dwImageStart, dwImageLength);
if (retVal)
{
KITLOutputDebugString("\r\nINFO: MDOCLDR flashed successfully.\r\n");
DisplayDebugString("MDOCLDR flash: success");
}
break;
case IMAGE_TYPE_BOOTLOADER:
DisplayDebugString("EBOOT flash in progress");
retVal = WriteFlashEBOOT(dwImageStart, dwImageLength);
if (retVal)
{
KITLOutputDebugString("\r\nINFO: EBOOT flashed successfully.\r\n");
DisplayDebugString("EBOOT flash: success");
}
break;
case IMAGE_TYPE_FLASHIMAGE:
DisplayDebugString("OS Image flash in progress");
retVal = WriteFlashNK(dwImageStart, dwImageLength);
if (retVal)
{
KITLOutputDebugString("\r\nINFO: OS Image flashed successfully.\r\n");
DisplayDebugString("OS Image flash: success");
}
break;
default:
KITLOutputDebugString("\r\nERROR: OEMWriteFlash:Unknown Image type.");
DisplayDebugString("ERROR: Unknown Image type.");
SpinForever();
}
// The system should be re-started for a bootloader or LDR flash
// If we hit an error, inform the user and halt.
//
if (g_ImageType != IMAGE_TYPE_FLASHIMAGE) {
if (retVal) { // Don't overwrite any error messages on the display
DisplayDebugString("Please reboot the device.");
} else {
g_pOEMReportError(BLERR_FLASH_WRITE, 0);
}
KITLOutputDebugString("Reboot the device manually. ");
SpinForever();
}
return(retVal);
}
BOOL GetMacAddress(UINT16 RNDISMac[3])
{
BOOL rc = FALSE;
UINT8 i=0;
UCHAR FlashUniqueID[16] = {0};
DWORD dwLenOut = 0;
HANDLE hFMD = NULL;
UCHAR MacAddress[6] = { 0x00, 0x50, 0x00, 0x00, 0x00, 0x00 }; // the last 4 bytes will be filled from the unique ID
// Get the unique ID of the flash chip
if (!FMD_OEMIoControl(IOCTL_DOC_GET_UNIQUE_ID, NULL, 0, FlashUniqueID, sizeof(FlashUniqueID), &dwLenOut))
{
KITLOutputDebugString("GetMacAddress: FMD_OEMIoControl failed.\r\n");
return FALSE;
}
for (i=0; i<8; i++)
{
MacAddress[2] += FlashUniqueID[i]; // sum of first 8 bytes of Unique ID
MacAddress[3] += FlashUniqueID[i + 8]; // sum of last 8 bytes of Unique ID
}
for (i=0; i<4; i++)
{
MacAddress[4] += FlashUniqueID[i+8]; // sum of bytes 8 thru 11 of Unique ID
MacAddress[5] += FlashUniqueID[i+12]; // sum of bytes 12 thru 15 of Unique ID
}
memcpy(RNDISMac, MacAddress, sizeof(MacAddress));
KITLOutputDebugString ( "GetMacAddress returning MAC: %x-%x-%x-%x-%x-%x\r\n",(UCHAR) RNDISMac[0],
(UCHAR) (RNDISMac[0]>>8),
(UCHAR)RNDISMac[1],
(UCHAR)(RNDISMac[1]>>8),
(UCHAR)RNDISMac[2],
(UCHAR)(RNDISMac[2]>>8));
return TRUE;
}
BOOL FlashLoadEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
BOOL rc = FALSE;
DWORD bufferIndex = 0;
DWORD bytesRemaining = 0;
DWORD readCount = 0;
HANDLE hFMD = NULL;
FlashInfo flashInfo;
SectorInfo sectorInfo;
SECTOR_ADDR sector;
unsigned char ucFlashSectorBuffer[BSP_SECTOR_SIZE];
// Initialize EBOOT_CFG_PARTITION for read
//
hFMD = FMD_Init((LPCTSTR)BSP_MDOC_EBOOT_CFG_PARTITION_HANDLE, NULL, NULL);
if (!hFMD)
{
KITLOutputDebugString("ERROR: FlashReadBootCfg: FMD_Init call failed\r\n");
goto cleanUp;
}
// Get flash info
if (!FMD_GetInfo(&flashInfo))
{
KITLOutputDebugString("ERROR: FMD_GetInfo call failed\r\n");
goto cleanUp;
}
// Read sectors and copy to EBOOT_CFG
//
bufferIndex = 0;
sector = 0;
bytesRemaining = cbBootCfgSize;
while (bytesRemaining > 0)
{
// Read config data one sector at a time
if (!FMD_ReadSector(sector, ucFlashSectorBuffer, §orInfo, 1) )
{
KITLOutputDebugString("\r\nERROR: Failed read sector %d from flash\r\n", sector);
goto cleanUp;
}
readCount = (bytesRemaining < flashInfo.wDataBytesPerSector) ? bytesRemaining : flashInfo.wDataBytesPerSector;
memcpy(pBootCfg + bufferIndex, ucFlashSectorBuffer, readCount);
bufferIndex += readCount;
bytesRemaining -= readCount;
sector++;
}
// Done
rc = TRUE;
cleanUp:
// Close FMD driver
if (hFMD)
{
FMD_Deinit(hFMD);
}
return rc;
}
//------------------------------------------------------------------------------
BOOL FlashStoreEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
BOOL rc = FALSE;
HANDLE hFMD = NULL;
FlashInfo flashInfo;
SectorInfo sectorInfo;
SECTOR_ADDR sector;
DWORD bufferIndex = 0;
DWORD bytesRemaining = 0;
DWORD writeCount = 0;
unsigned char ucFlashSectorBuffer[BSP_SECTOR_SIZE];
// Initialize EBOOT_CFG_PARTITION for write
//
hFMD = FMD_Init((LPCTSTR)BSP_MDOC_EBOOT_CFG_PARTITION_HANDLE, NULL, NULL);
if (!hFMD)
{
KITLOutputDebugString("ERROR: FlashStoreEBootCFG: FMD_Init call failed\r\n");
goto cleanUp;
}
// Get flash info
if (!FMD_GetInfo(&flashInfo))
{
KITLOutputDebugString("ERROR: FMD_GetInfo call failed\r\n");
goto cleanUp;
}
// Write EBOOT_CFG to sectors
//
bufferIndex = 0;
sector = 0;
bytesRemaining = cbBootCfgSize;
while (bytesRemaining > 0)
{
writeCount = (bytesRemaining < flashInfo.wDataBytesPerSector) ? bytesRemaining : flashInfo.wDataBytesPerSector;
memset(ucFlashSectorBuffer, 0, sizeof(ucFlashSectorBuffer));
memcpy(ucFlashSectorBuffer, pBootCfg + bufferIndex, writeCount);
// Write config data one sector at a time
if (!FMD_WriteSector(sector, ucFlashSectorBuffer, §orInfo, 1) )
{
KITLOutputDebugString("\r\nERROR: Failed write sector %d to flash\r\n", sector);
goto cleanUp;
}
bufferIndex += writeCount;
bytesRemaining -= writeCount;
sector++;
}
// Done
rc = TRUE;
cleanUp:
// Close FMD driver
if (hFMD)
{
FMD_Deinit(hFMD);
}
return rc;
}
//------------------------------------------------------------------------------
//
// Function: ReadFlashNK
//
// This function downloads image from flash memory to RAM.
//
UINT32 ReadFlashNK()
{
UINT32 rc = BL_ERROR;
ROMHDR *pTOC;
ULONG offsetTOC = 0;
ULONG endTOC = 0;
UINT8* pImage;
DWORD bytesImageCopied = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -