📄 fmd.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: fmd.cpp
//
// This file implements a flash media PDD for DOC.
// It is a wrapper for M-Systems SDK accesses. The DOC is treated
// as one sector per block NOR device. This allows bootpart to
// use the MDOC as FMD.
//
// Note: The M-Systems SDK uses the terms "IPL" and "MDOCIPL" for what
// the rest of the BSP calls "MDOCLDR". In this file and in g3_startup.s
// "IPL" is used when interfacing with the M-Systems SDK, "MDOCLDR"
// or "LDR" are used when interfacing with all other code. This should
// explain why flWriteIPL is being called from WriteMDOCLDR.
//
#include <windows.h>
#include <bootpart.h>
#include <fmd.h>
#include <oal.h>
#include <bsp_mdoc_cfg.h>
#include <eboot_fmd.h>
#include <image_cfg.h>
#include <blockdev.h>
/* Number of translation layer partitions
*
* Defines Maximum Number of Traslation layer partitons on a physical device
*
* The actual number of partitions depends on the format placed on each device.
*/
#define FL_MAX_TL_PARTITIONS 6
#define USER_PASS_1 "12345678"
//------------------------------------------------------------------------------
// Geometry info structure
typedef struct {
UINT8 manufacturerId;
UINT8 deviceId;
UINT32 blocks;
UINT32 sectorsPerBlock;
UINT32 sectorSize;
BYTE mdocType;
UINT32 eraseUnitSize;
UINT32 handle;
} MDOC_INFO;
//------------------------------------------------------------------------------
// Local Variable
static struct {
MDOC_INFO *pMDOCInfo;
} g_fmd;
static struct {
BDKStruct bdkstr;
DWORD handle;
} g_bdkFmd;
static MDOC_INFO mdocInfo;
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
//
// Function: InsertProtectionKey
//
// This function is called to un-protect/unlock the flash
//
static BOOL InsertProtectionKey()
{
FLStatus flstatus;
IOreq ioreq;
// We are using here '0' as the handle since we use one DPS for
// all the sectors/partitions together.
ioreq.irHandle = 0;
ioreq.irData=(void*)USER_PASS_1;
flstatus = flInsertProtectionKey(&ioreq);
if (flstatus == flNotProtected)
{
OALMSG(OAL_WARN, (L"InsertProtectionKey: Warning: DiskOnChip is not "
L"protected\r\n"));
}
else if (flstatus != flOK)
{
OALMSG(OAL_WARN, (L"InsertProtectionKey: Error %d in "
L"flInsertProtectionKey\r\n", flstatus));
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: RemoveProtectionKey
//
// This function is called to write-protect/lock the flash
//
static BOOL RemoveProtectionKey()
{
FLStatus flstatus;
IOreq ioreq;
// We are using here '0' as the handle since we use one DPS for
// all the sectors/partitions together.
ioreq.irHandle=0;
flstatus = flRemoveProtectionKey(&ioreq);
if( flstatus == flNotProtected )
{
OALMSG(OAL_WARN, (L"RemoveProtectionKey: Warning: DiskOnChip is not "
L"protected\r\n"));
}
else if (flstatus != flOK)
{
OALMSG(OAL_WARN, (L"RemoveProtectionKey: Error %d in "
L"flRemoveProtectionKey\r\n", flstatus));
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: MountMDOC
//
// This function is called to mount the currrent DiskOnChip partitiion as
// specified in FMD_Init.
//
static BOOL MountMDOC()
{
FLStatus flstatus;
IOreq ioreq;
ioreq.irHandle = g_fmd.pMDOCInfo->handle;
flstatus = flAbsMountVolume(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_WARN, (L" FMD_OEMIoControl: Error %d in "
L"flAbsMountVolume\r\n", flstatus));
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: FMD_bdkInit
//
// This function is called to initialize bdk flash subsystem.
//
PVOID FMD_bdkInit(DWORD handle, PCHAR sig, DWORD dwLength, BOOL bRead)
{
IOreq ioreq;
FLStatus flstatus;
ioreq.irHandle = handle;
ioreq.irData = &g_bdkFmd.bdkstr;
g_bdkFmd.bdkstr.length = dwLength;
g_bdkFmd.bdkstr.flags = bRead ? 0 : BDK_COMPLETE_IMAGE_UPDATE;
g_bdkFmd.bdkstr.oldSign[0] = sig[0];
g_bdkFmd.bdkstr.oldSign[1] = sig[1];
g_bdkFmd.bdkstr.oldSign[2] = sig[2];
g_bdkFmd.bdkstr.oldSign[3] = sig[3];
g_bdkFmd.bdkstr.startingBlock = 0;
g_bdkFmd.bdkstr.signOffset = 8;
g_bdkFmd.handle = handle;
flstatus = bRead ? bdkReadInit(&ioreq) : bdkWriteInit(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_ERROR, (L"ReadFlashLDR: Error %d in bdkReadInit\r\n",
flstatus));
return NULL;
}
return &g_bdkFmd;
}
//------------------------------------------------------------------------------
//
// Function: FMD_BDK_Deinit
//
BOOL FMD_bdkDeinit(VOID *pContext)
{
memset (&g_bdkFmd, 0, sizeof(g_bdkFmd));
return TRUE;
}
BOOL FMD_bdkGetInfo(FlashInfo *pFlashInfo)
{
memset (pFlashInfo, 0, sizeof(*pFlashInfo));
pFlashInfo->flashType = NOR;
pFlashInfo->wDataBytesPerSector = FL_SECTOR_SIZE;
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: FMD_bdkWriteBlock
// Write the content of the sector.
//
BOOL FMD_bdkWriteSector(SECTOR_ADDR sector, UCHAR *pBuffer,
SectorInfo *pSectorInfo, DWORD sectors)
{
IOreq ioreq;
FLStatus flstatus;
ioreq.irHandle = g_bdkFmd.handle;
ioreq.irData = &g_bdkFmd.bdkstr;
g_bdkFmd.bdkstr.bdkBuffer = pBuffer;
g_bdkFmd.bdkstr.length = sectors*FL_SECTOR_SIZE;
g_bdkFmd.bdkstr.flags = ERASE_BEFORE_WRITE;
flstatus = bdkWriteBlock(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_ERROR, (L"\r\nFMD_bdkWriteSector: "
L"Error %d in bdkWriteBlock\r\n", flstatus));
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: FMD_bdkReadSector
// Write the content of the sector.
//
BOOL FMD_bdkReadSector(SECTOR_ADDR sector, UCHAR *pBuffer,
SectorInfo *pSectorInfo, DWORD sectors)
{
IOreq ioreq;
FLStatus flstatus;
ioreq.irHandle = g_bdkFmd.handle;
ioreq.irData = &g_bdkFmd.bdkstr;
g_bdkFmd.bdkstr.bdkBuffer = pBuffer;
g_bdkFmd.bdkstr.length = sectors*FL_SECTOR_SIZE;
g_bdkFmd.bdkstr.flags = ERASE_BEFORE_WRITE;
flstatus = bdkReadBlock(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_ERROR, (L"\r\nFMD_bdkReadSector: "
L"Error %d in bdkWriteBlock\r\n", flstatus));
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: FMD_Init
//
// This function is called to initialize flash subsystem.
//
PVOID FMD_Init(LPCTSTR pActive, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{
HANDLE hFMD = NULL;
FLStatus flstatus;
IOreq ioreq;
PhysicalInfo pi;
DWORD handle = (DWORD)pActive & 0xff;
OALMSG(OAL_INFO, (L"FMD_Init (DiskOnChip, partition %d)\r\n", handle >> 4));
// Mount DiskOnChip Partition
ioreq.irHandle = handle;
flstatus = flAbsMountVolume(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_WARN, (L"FMD_Init: Error %d in flAbsMountVolume partition."
L"\r\n", flstatus));
goto cleanUp;
}
// Get physical data.
ioreq.irHandle = 0; // Must be '0'!!
ioreq.irData = π
flstatus = flGetPhysicalInfo(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_WARN, (L"FMD_Init: Error %d in flGetPhysicalInfo\r\n",
flstatus));
flDismountVolume(&ioreq);
goto cleanUp;
}
ioreq.irHandle = handle;
flstatus = flSectorsInVolume(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_WARN, (L"FMD_Init: Error %d in flSectorsInVolume\r\n",
flstatus));
flDismountVolume(&ioreq);
goto cleanUp;
}
g_fmd.pMDOCInfo = &mdocInfo;
g_fmd.pMDOCInfo->manufacturerId = (pi.type>>8)&0xff;
g_fmd.pMDOCInfo->deviceId = pi.type&0xff;
g_fmd.pMDOCInfo->sectorsPerBlock = 128;
g_fmd.pMDOCInfo->blocks = ioreq.irLength/g_fmd.pMDOCInfo->sectorsPerBlock;
g_fmd.pMDOCInfo->sectorSize = FL_SECTOR_SIZE;
g_fmd.pMDOCInfo->mdocType = pi.mediaType;
g_fmd.pMDOCInfo->eraseUnitSize = pi.unitSize;
g_fmd.pMDOCInfo->handle = handle;
// We are done
hFMD = &g_fmd;
cleanUp:
return hFMD;
}
//------------------------------------------------------------------------------
//
// Function: FMD_Deinit
//
BOOL FMD_Deinit(VOID *pContext)
{
FLStatus flstatus = flOK;
IOreq ioreq;
// Dismount the partition
flstatus = flOK;
ioreq.irHandle = g_fmd.pMDOCInfo->handle ;
while (flstatus == flOK)
flstatus = flDismountVolume(&ioreq);
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: FMD_GetInfo
//
// This function is call to get flash information
//
BOOL FMD_GetInfo(FlashInfo *pFlashInfo)
{
BOOL rc = FALSE;
// If we don't support NAND, fail...
if (!g_fmd.pMDOCInfo)
goto cleanUp;
// DiskOnChip is NAND. To get rid of bootpart verification we report NOR.
pFlashInfo->flashType = NOR;
pFlashInfo->dwNumBlocks = g_fmd.pMDOCInfo->blocks;
pFlashInfo->wSectorsPerBlock = g_fmd.pMDOCInfo->sectorsPerBlock;
pFlashInfo->wDataBytesPerSector = g_fmd.pMDOCInfo->sectorSize;
pFlashInfo->dwBytesPerBlock =
g_fmd.pMDOCInfo->sectorSize * g_fmd.pMDOCInfo->sectorsPerBlock;
// Done
rc = TRUE;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
//
// Function: FMD_ReadSector
//
// Read the content of the sector.
//
BOOL FMD_ReadSector(SECTOR_ADDR sector, UCHAR *pBuffer,
SectorInfo *pSectorInfo, DWORD sectors)
{
BOOL rc = FALSE;
FLStatus flstatus;
IOreq ioreq;
// There isn't clear semantic how to read more than one sector
if (sectors > 1 || !g_fmd.pMDOCInfo)
goto cleanUp;
// Read one sector.
if (pBuffer)
{
ioreq.irHandle = g_fmd.pMDOCInfo->handle;
ioreq.irData = pBuffer;
ioreq.irSectorNo = sector;
ioreq.irSectorCount = 1;
flstatus = flAbsRead(&ioreq);
if (flstatus != flOK)
{
OALMSG(OAL_WARN, (L"FMD_ReadSector: Error %d in call to flAbsRead\r\n",
flstatus));
goto cleanUp;
}
}
// Copy sector info
if (pSectorInfo)
{
pSectorInfo->bBadBlock = 0;
pSectorInfo->bOEMReserved = 0;
pSectorInfo->dwReserved1 = 0;
pSectorInfo->wReserved2 = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -