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

📄 perreg.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File: PerReg.c
//
//  This file implements persistent registry module for NOR flash memory.
//
#include <windows.h>
#include <oal_log.h>
#include <oal_memory.h>
#include <oal_flash.h>
#include <oal_perreg.h>

//------------------------------------------------------------------------------
//
//  External: pWriteRegistryToOEM/pReadRegistryFromOEM
//
//  This function pointers are expored by kernel as support for optional
//  persistent registry functionality.
//
extern BOOL (*pWriteRegistryToOEM)(UINT32 flags, UINT8 *pData, UINT32 size);
extern UINT32 (*pReadRegistryFromOEM)(UINT32 flags, UINT8 *pData, UINT32 size);

//------------------------------------------------------------------------------
//
//  Define: OAL_PERREG_MAX_REGIONS
//
//  This constant defines maximal supported number of regions. It is solved
//  in this way to avoid memory allocation which isn't supported at time
//  when OALPerRegInit is usally called.
//
#define OAL_PERREG_MAX_REGIONS          8

//------------------------------------------------------------------------------
//
//  Define: OAL_PERREG_SIGN
//
//  This constant is used as persistent registry signature in registry storage
//  header.
//
#define OAL_PERREG_SIGN                 'PREG'

//------------------------------------------------------------------------------
//
//  Type: OAL_PERREG_HEADER
//
//  This type defines registry storage header. Its size must be 32-bit word
//  allignment and it must be smaller than buffer size in OAL_PERREG_STATE
//  structure.
//
typedef struct {
    UINT32 signature;
    UINT32 size;
    UINT32 checkSum;
} OAL_PERREG_HEADER;

//------------------------------------------------------------------------------
//
//  Type: OAL_PERREG_STATE
//
//  The type encapsulating implementation internal status variables.
//
typedef struct {
    UINT32 regions;
    OAL_PERREG_REGION region[OAL_PERREG_MAX_REGIONS];
    
    UINT32 size;
    UINT32 checkSum;        
    
    UINT32 regionIdx;
    UINT32 regionPos;    
    
    UINT8  buffer[1024];
    UINT32 bufferPos;
} OAL_PERREG_STATE;

//------------------------------------------------------------------------------
//
//  Static: g_perRegState
//
//  Persistent registry implementation internal state.
//
static OAL_PERREG_STATE g_perRegState;

//------------------------------------------------------------------------------
// Local Functions 

static UINT32 CheckSum(VOID *pStart, UINT32 size);
static BOOL WriteBufferToFlash(BOOL skipHeader);
static BOOL ReadBufferFromFlash();
static BOOL EraseFlash();
static VOID ResetBuffer(BOOL write);
static BOOL CopyFromBuffer(VOID *pBuffer, UINT32 count);
static BOOL CopyToBuffer(VOID *pBuffer, UINT32 count);
static BOOL FlushBuffer(BOOL skipHeader);

//------------------------------------------------------------------------------
//
//  Function: OALPerRegInit
//
//  This function should be called from OAL to initalize persistent registry
//  functionality. When clean flag is set it also erase all regions. Function
//  make all regions flash memory block alignment.
//
BOOL OALPerRegInit(BOOL clean, OAL_PERREG_REGION aRegions[])
{
    UINT32 rc = FALSE;
    OAL_PERREG_REGION *pRegion;
    UINT32 i = 0;
    UINT32 offset; //, blockStart, blockSize;

    OALMSG(OAL_FLASH&&OAL_FUNC, (L"+OALPerRegInit(0x%08x)\r\n", aRegions));
    
    // Copy regions info to state variable
    g_perRegState.regions = 0;
    pRegion = &g_perRegState.region[0];
    while (aRegions[i].base != 0) {

#if 0
        // Verify, that there is flash memory
        if (!OALFlashBlockInfo(
            aRegions[i].pBase, aRegions[i].pStart, &blockStart, &blockSize
        )) {
            OALMSG(OAL_ERROR, (
                L"ERROR: There isn't flash memory at 0x%08x\r\n", 
                aRegions[i].pBase
            ));
            i++;
            continue;
        }

        // Get region offset in block
        offset = OALVAtoPA(aRegions[i].pStart) - blockStart;
        if (offset >= pRegion->size) {
            OALMSG(OAL_WARN, (
                L"WARN: Region %08x - %08x - %08x too small, ignored\r\n",
                aRegions[i].pBase, aRegions[i].pStart, aRegions[i].size
            ));
            i++;
            continue;
        }            
#else
        offset = 0;
#endif

        // Save region to state variable
        pRegion->base  = aRegions[i].base;
        pRegion->start = aRegions[i].start + offset;
        pRegion->size  = aRegions[i].size - offset;
        pRegion++;
        if (++g_perRegState.regions >= OAL_PERREG_MAX_REGIONS) break;
        
        i++;
    }

    // We was succesfull when at least one region was verified
    if (rc = (g_perRegState.regions > 0)) {
        pWriteRegistryToOEM = OALPerRegWrite;
        if (!clean) pReadRegistryFromOEM = OALPerRegRead;
    }        
    
    OALMSG(OAL_FLASH&&OAL_FUNC, (L"-OALPerRegInit(rc = %d)\r\n", rc));
    return rc;        
}

//------------------------------------------------------------------------------
//
//  Function: OALPerRegWrite
//
//  This function implements pWriteRegistryToOEM write function.
//
BOOL OALPerRegWrite(UINT32 flags, UINT8 *pData, UINT32 size)
{
    BOOL rc = FALSE;
    OAL_PERREG_HEADER header;


    OALMSG(OAL_FLASH&&OAL_FUNC, (
        L"+OALPerRegWrite(0x%08x, 0x%08x, 0x%08x)\r\n", flags, pData, size
    ));
    
    // Check if it is write start
    if ((flags & REG_WRITE_BYTES_START) != 0) {

        // First check if there are regions defined
        if (g_perRegState.regions <= 0) {
            OALMSG(OAL_ERROR, (
                L"ERROR: OALPerRegWrite: No valid flash regions defined\r\n"
            ));
            goto cleanUp;
        }

        RETAILMSG(TRUE, (L"INFO: OALPerRegWrite: Registry write start\r\n"));

        // Erase flash memory
        if (!EraseFlash()) goto cleanUp;
        
        // Initialize local state variables
        g_perRegState.size = 0;
        g_perRegState.checkSum = 0;
        memset(&header, 0xFF, sizeof(header));

        // Reset buffer & write temporary header
        ResetBuffer(TRUE);
        CopyToBuffer(&header, sizeof(header));
       
    }

    // While there are some data && place where to write
    if (size > 0) {

        if (!CopyToBuffer(pData, size)) {
            OALMSG(OAL_ERROR, (
                L"ERROR: OALPerRegWrite: CopyToBuffer failed\r\n"
            ));
            goto cleanUp;
        }
        g_perRegState.size += size;
        
    } else {

        // Flush buffer
        FlushBuffer(TRUE);

        // Prepare and write header
        header.signature = OAL_PERREG_SIGN;
        header.size = g_perRegState.size;
        header.checkSum = g_perRegState.checkSum;
        ResetBuffer(TRUE);
        CopyToBuffer(&header, sizeof(header));
        FlushBuffer(FALSE);

        RETAILMSG(TRUE, (L"INFO: OALPerRegWrite: Registry write done\r\n"));
    }
    
    rc = TRUE;
    
cleanUp:
    OALMSG(OAL_FLASH&&OAL_FUNC, (L"-OALPerRegWrite(rc = %d)", rc));
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function: OALPerRegRead
//
//  This function implements pReadRegistryFromOEM read function.
//
UINT32 OALPerRegRead(UINT32 flags, UINT8 *pData, UINT32 dataSize)
{
    UINT32 rc = 0;
    OAL_PERREG_HEADER header;
    UINT32 count, checkSum, chunk, buffer[32];
    UINT8 *pBase = pData;

    OALMSG(OAL_FLASH&&OAL_FUNC, (
        L"+OALPerRegRead(0x%08x, 0x%08x, 0x%08x)\r\n", flags, pData, dataSize
    ));

    if (flags & REG_READ_BYTES_START) {

        if (g_perRegState.regions <= 0) {
            OALMSG(OAL_ERROR, (
                L"ERROR: OALPerRegRead: No valid flash regions defined\r\n"
            ));
            rc = -1;
            goto cleanUp;
        }

        RETAILMSG(TRUE, (L"INFO: OALPerRegRead: Registry read start\r\n"));

        // Reset buffer and read header
        ResetBuffer(FALSE);
        CopyFromBuffer(&header, sizeof(header));

        if (header.signature != OAL_PERREG_SIGN) {
            OALMSG(OAL_WARN, (L"WARN: ReadRegistryFromOEM: Bad signature\r\n"));
            rc = -1;
            goto cleanUp;
        }

        // Calculate checksum
        count = (header.size + 3) & ~0x3;
        checkSum = 0;
        while (count > 0) {
            chunk = sizeof(buffer) < count ? sizeof(buffer) : count;
            CopyFromBuffer(buffer, chunk);
            checkSum += CheckSum(buffer, chunk);
            count -= chunk;
        }

        if (header.checkSum != checkSum) {
            OALMSG(OAL_WARN, (
                L"WARN: ReadRegistryFromOEM: Invalid checksum\r\n"
            ));
            rc = -1;
            goto cleanUp;
        }            

        // Reset buffer and read header
        ResetBuffer(FALSE);
        CopyFromBuffer(&header, sizeof(header));
        g_perRegState.size = header.size;
        
    }

    if (g_perRegState.size >= dataSize) {
        CopyFromBuffer(pData, dataSize);
        g_perRegState.size -= dataSize;
        rc = dataSize;
    }

    RETAILMSG(rc == 0, (
        L"INFO: OALPerRegRead: Registry read done (%d)\r\n", g_perRegState.size
    ));

cleanUp:
    OALMSG(OAL_FLASH&&OAL_FUNC, (L"-OALPerRegRead(rc = %d)", rc));
    return rc;
}

//------------------------------------------------------------------------------

static UINT32 CheckSum(VOID *pStart, UINT32 size)
{
    UINT32 sum = 0;
    UINT32 *p;

    for (p = pStart; size > sizeof(UINT32) - 1; size -= sizeof(UINT32)) {
        sum += *p++;
    }
    return sum;
}

//------------------------------------------------------------------------------

static BOOL EraseFlash()
{
    BOOL rc = FALSE;
    OAL_PERREG_REGION *pRegion;
    UINT32 i;
    
    // Erase all regions...
    RETAILMSG(TRUE, (L"INFO: OALPerRegWrite: Registry store erase start\r\n"));
    pRegion = g_perRegState.region;
    for (i = 0; i < g_perRegState.regions; i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -