⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmd.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 = &pi;
    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 + -