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

📄 intel-p3c3.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//**********************************************************************
//                                                                      
// Filename: intel-c3.cpp
//                                                                      
// Description: FLASH Media Driver Interface for Intel C3 style StrataFlash 
//              Chip
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus 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 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//                                                                      
//**********************************************************************

#include <fmd.h>
#include <ceddk.h>
#ifdef READ_FROM_REGISTRY
#include <ddkreg.h>
#endif    // READ_FROM_REGISTRY.
#include <hwdefs.h>
#include "strata.h"

/*----------------------------------------------------------------------------------------------------*/
static BOOL g_bPairedFlash = TRUE;        // Indicates whether or not two flash parts are paired to create a 32-bit data interface.

#define MIN(a, b) (a < b ? a : b) 

static BOOL g_bXIPMode = FALSE;
static SysRegionInfo_t        g_FlashRegion[IntelRegionNUM];
unsigned long oldval;

/*---------------------------------------------------------------------------------------------------*/
BOOLEAN InitializeFlash(volatile ULONG * pChipBaseAddress, ULONG ChipFlashLength,volatile ULONG * pBaseAddress, ULONG FlashLength);

DWORD DoBufferedWrite(volatile ULONG ulBlockAddress,
                      volatile SECTOR_ADDR physicalSectorAddr,
                      PUCHAR pBuffer,
                      USHORT NumWriteBytes);

/*--------------------------------------------------------------------------------------------------*/

BOOL  GetEraseFlashSectorIndex(ULONG dwStartAddr)
{
	DWORD i,j,dwEraseLen;

	dwEraseLen = dwStartAddr;
	if(dwEraseLen==0)
	{
		return TRUE;
	}

	for(i = 0; i <g_FMDInfo.Geometry.NumEraseBlocks; i++) 
	{
		for(j = 0; j< g_FlashRegion[i].blocks; j++) 
		{
            if(dwEraseLen > g_FlashRegion[i].block_size) 
			{
                dwEraseLen = dwEraseLen - g_FlashRegion[i].block_size;
            } 
			else if(dwEraseLen ==g_FlashRegion[i].block_size)
			{
				g_FMDInfo.gdwCurEraseRegion = i;
				g_FMDInfo.gdwCurEraseBlock   = j;
				//RETAILMSG(ZONE_TEST, (TEXT(" = block_size =%x.i=%x,j=%x\r\n"),g_FlashRegion[i].block_size,i,j));
				return TRUE;
			}
			else 
			{
				g_FMDInfo.gdwCurEraseRegion = i;
				g_FMDInfo.gdwCurEraseBlock   = j;
				RETAILMSG(ZONE_TEST, (TEXT(" < block_size =%x.i=%x,j=%x\r\n"),g_FlashRegion[i].block_size,i,j));
				return FALSE;
			}
		}
	}
   return FALSE;
}

/*--------------------------------------------------------------------------------------------------*/

void SetWriteProtect(BOOL bprotect)
{
    volatile unsigned long val;
    if(bprotect)
    {
        val = oldval;
    }
    else
    {
        oldval = *FLASH_SMC;
        val = oldval & ~SMCBCR_WP ;     // Enable Bit WP
    }
    *FLASH_SMC  = val;
}



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_Init()

Description:    Initializes the Flash memory device.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
PVOID FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{
    volatile ULONG * pBaseAddress = NULL;
	volatile ULONG * pChipBaseAddress = NULL;
    ULONG FlashLength = 0,ChipFlashLength=0;

    BOOL bLastMode;
    RETAILMSG(1, (TEXT("INFO: FMD_Init. intel C3 like\r\n")));
	
#ifdef READ_FROM_REGISTRY
    if (lpActiveReg != NULL)
    {
        DDKWINDOWINFO dwi;
        HKEY hConfig;

        // Get flash information from the registry.
        hConfig = OpenDeviceKey((LPCTSTR)lpActiveReg);        
        if (hConfig == NULL)
        {
            RETAILMSG(ZONE_TEST, (TEXT("ERROR: FMD_Init: OpenDeviceKey failed.\r\n")));
            return(NULL);
        }
        dwi.cbSize = sizeof(dwi);
        if (DDKReg_GetWindowInfo(hConfig, &dwi) != ERROR_SUCCESS)
        {
            RETAILMSG(ZONE_TEST, (TEXT("ERROR: FMD_Init: DDKReg_GetWindowInfo() failed.\r\n")));
            return(NULL);
        }
        // The first memory window contains the base address and length of our flash part.
        if (dwi.dwNumMemWindows)
        {
            pBaseAddress = (volatile ULONG *)(dwi.memWindows[1].dwBase);
            FlashLength  = (ULONG)(dwi.memWindows[1].dwLen);

            pChipBaseAddress = (volatile ULONG *)(dwi.memWindows[0].dwBase);
            ChipFlashLength  = (ULONG)(dwi.memWindows[0].dwLen);
        }
    }
#else
    // Get flash base address and length from caller.
    if (!pRegIn || !pRegIn->MemBase.Num || !pRegIn->MemLen.Num)
    {
        RETAILMSG(ZONE_TEST, (TEXT("ERROR: FMD_Init: invalid flash memory base and/or length specified by caller.\r\n")));
        return(NULL);
    }
    else
    {
        pBaseAddress = (volatile ULONG *)pRegIn->MemBase.Reg[1];
        FlashLength  = pRegIn->MemLen.Reg[1];

        pChipBaseAddress = (volatile ULONG *)pRegIn->MemBase.Reg[0];
        ChipFlashLength  = pRegIn->MemLen.Reg[0];
    }
#endif    // READ_FROM_REGISTRY.

    // Run in kernel mode.
    bLastMode = SetKMode(TRUE);

//resetting the smc interface

    // Identify the flash part and collect device information.
    //
    SetWriteProtect(FALSE);
    if (!InitializeFlash(pChipBaseAddress,ChipFlashLength,pBaseAddress, FlashLength))
    {
        RETAILMSG(ZONE_TEST, (TEXT("ERROR: FMD_Init: Failed to initialize flash.\r\n")));
        SetKMode(bLastMode);
        return(NULL);
    }
    SetWriteProtect(TRUE);

    RETAILMSG(ZONE_TEST, (TEXT("INFO: FMD_Init: Flash Address=0x%x  Length=0x%x.\r\n"), (ULONG)pBaseAddress, FlashLength));

    SetKMode(bLastMode);
    return((PVOID)pBaseAddress);
}

/*
    @func   BOOLEAN | UnlockBlock | Unlocks the specified flash block.
    @rdesc  TRUE returned on success, FALSE on failure.
    @comm    
    @xref   
*/
BOOLEAN SetBlockLock(BLOCK_ID blockID, ULONG NumBlocks, BOOL bLock)
{
    ULONG ulStatus = 0;
    volatile ULONG ulBlockAddress = 0;
    BOOL bLastMode = SetKMode(TRUE);
    UINT j;

	RETAILMSG(ZONE_TEST, (TEXT("SetBlockLock ID =%x num=%x).\r\n"),blockID,NumBlocks));

    SetWriteProtect(FALSE);

    while (NumBlocks--)
    {
        // Compute the block address.
        ulBlockAddress  =  g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);

		if(GetEraseFlashSectorIndex(ulBlockAddress-g_FMDInfo.ChipBaseAddress)==FALSE)
		{
			  RETAILMSG(ZONE_TEST, (TEXT("ERASE Block error,not aligned\r\n")));
			return FALSE;
		}
		if(g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize)
		{  
			// Clear the status register.
			//WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);
			WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
			// Set or Clear the block lock bit and confirm.
			WRITE_COMMAND(ulBlockAddress, BLOCK_LOCK_CMD);
			
			if (bLock)
			{
				WRITE_COMMAND(ulBlockAddress, BLOCK_SETLOCK_CMD);
			}
			else
			{
				WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
			}

			// Wait for status...
			WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
			do
			{
				//WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
			}
			while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK));			
			WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);

			WRITE_COMMAND(ulBlockAddress, READ_ARRAY_CMD);
		}
		else
		{
			for(j = g_FMDInfo.gdwCurEraseBlock; j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++) 
			{
	        // Clear the status register.
		        WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);

		        // Set or Clear the block lock bit and confirm.
		        WRITE_COMMAND(ulBlockAddress, BLOCK_LOCK_CMD);
		        if (bLock)
		        {
		            WRITE_COMMAND(ulBlockAddress, BLOCK_SETLOCK_CMD);
		        }
		        else
		        {
		            WRITE_COMMAND(ulBlockAddress, BLOCK_PROCEED_CMD);
		        }

		        // Wait for status...
		        do
		        {
		            WRITE_COMMAND(ulBlockAddress, READ_STATUS_CMD);
		        }
		        while (!CHECK_STATUS(ulBlockAddress, STATUS_READY_MASK));
				WRITE_COMMAND(ulBlockAddress, CLEAR_STATUS_CMD);	

				ulBlockAddress = ulBlockAddress +g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size;
			}
		}
        ++blockID;
	}
	
    SetWriteProtect(TRUE);

    SetKMode(bLastMode);

	RETAILMSG(ZONE_TEST, (TEXT("SetBlockLock --over ID =%x num=%x).\r\n"),blockID,NumBlocks));
    return(TRUE);
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_ReadSector()

Description:    Reads the requested sector data and/or sector metadata from the
                Flash media.

Notes:          Notice that although each byte of a NOR Flash block is individually
                addressable, the media is still logically broken up into sectors.  
                Thus, for each sector request, we must determine where this data
                resides in the respective Flash block (see note above).

                By default, the NOR Flash is configured in READ ARRAY MODE so there
                is no need to set any control lines to access the media.  The data
                can just be read directly from the media (like RAM).
                
Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL  FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    volatile SECTOR_ADDR  physicalSectorAddr = 0;
    volatile ULONG ulBlockAddress = 0;
    BLOCK_ID blockID = 0;
    DWORD i = 0;
    UINT j;
    BOOL bLastMode;

	RETAILMSG(ZONE_TEST, (TEXT("FMD_ReadSector: (startAdd =%x num=%x) sectot_addr=%x,sector_info %x.\r\n"),startSectorAddr,dwNumSectors,
									pSectorBuff,pSectorInfoBuff));

    //----- 1. Check the input parameters -----
    //         NOTE: The FAL insures that the starting sector address is in the allowable range.
    if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
    {
        return(FALSE);
    }
    //----- 2. Process the read request(s)... -----
    bLastMode = SetKMode(TRUE);
    SetWriteProtect(FALSE);
    
    for(i = startSectorAddr ; i < (startSectorAddr + dwNumSectors) ; i++)
    {
        //----- Determine the block this physical sector resides in -----
        blockID = (i / g_FMDInfo.SectorsPerBlock);

        //----- Compute the physical address for the requested -----
        // Note we do this differently based on whether the caller wants us to read the sector information structure as well.  Since we're
        // dealing with a NOR flash which is XIP-able, one might want to use this function to read from an XIP region (i.e., no sector information
        // structures in flash).
        //
        if (!g_bXIPMode)
            physicalSectorAddr = g_FMDInfo.BaseAddress + i*(SECTOR_SIZE + sizeof(SectorInfo)) + (blockID * g_FMDInfo.UnusedBytesPerBlock);
        else

⌨️ 快捷键说明

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