fmd.cpp
来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,511 行 · 第 1/4 页
CPP
1,511 行
//
// 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.
//
#include "fmd.h"
#include <ceddk.h>
#ifdef READ_FROM_REGISTRY
#include <ddkreg.h>
#endif
//wzw>> -
//#include <hwdefs.h>
#include "strata.h"
#define _SDNAND_
//=========================================================================================================
#include "xllp_ost.h"
#define NAND_BUSY_PORT (IoAddr+8)
#define NAND_CS_PORT (IoAddr+0xc)
typedef struct
{
volatile unsigned long osmr0; //OS timer match register 0
volatile unsigned long osmr1; //OS timer match register 1
volatile unsigned long osmr2; //OS timer match register 2
volatile unsigned long osmr3; //OS timer match register 3
volatile unsigned long oscr0; //OS timer counter register 0(compatible)
volatile unsigned long ossr; //OS timer status register
volatile unsigned long ower; //OS timer watchdog enable register
volatile unsigned long oier; //OS timer interrupt enable register
volatile unsigned long osnr; //OS timer snapshot register
volatile unsigned long reserved1[7];
volatile unsigned long oscr4; //OS timer counter register 4
volatile unsigned long oscr5; //OS timer counter register 5
volatile unsigned long oscr6; //OS timer counter register 6
volatile unsigned long oscr7; //OS timer counter register 7
volatile unsigned long oscr8; //OS timer counter register 8
volatile unsigned long oscr9; //OS timer counter register 9
volatile unsigned long oscr10; //OS timer counter register 10
volatile unsigned long oscr11; //OS timer counter register 11
volatile unsigned long reserved2[8];
volatile unsigned long osmr4; //OS timer match register 4
volatile unsigned long osmr5; //OS timer match register 5
volatile unsigned long osmr6; //OS timer match register 6
volatile unsigned long osmr7; //OS timer match register 7
volatile unsigned long osmr8; //OS timer match register 8
volatile unsigned long osmr9; //OS timer match register 9
volatile unsigned long osmr10; //OS timer match register 10
volatile unsigned long osmr11; //OS timer match register 11
volatile unsigned long reserved3[8];
volatile unsigned long omcr4; //OS timer match control register 4
volatile unsigned long omcr5; //OS timer match control register 5
volatile unsigned long omcr6; //OS timer match control register 6
volatile unsigned long omcr7; //OS timer match control register 7
volatile unsigned long omcr8; //OS timer match control register 8
volatile unsigned long omcr9; //OS timer match control register 9
volatile unsigned long omcr10; //OS timer match control register 10
volatile unsigned long omcr11; //OS timer match control register 11
} m_OST_T, *P_m_OST_T;
//=========================================================================================================
volatile ULONG NAND_CMD_PORT ;
volatile ULONG NAND_ADDR_PORT ;
volatile ULONG NAND_DATA_PORT ;
extern "C" PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
void *mg_pOSTRegs;
void *v_pNANDFlash;
//==============================================================================================
//1. adrress
//2. 8bit--->32bit
//3. delay
//==============================================================================================
//-------------------------------------------------------------
static void mmXllpOstDelayTicks(P_m_OST_T pOstRegs, unsigned long ticks)
{
unsigned long expireTime, time;
time = pOstRegs->oscr0;
expireTime = time + ticks;
if (expireTime < time) {
while (time < pOstRegs->oscr0);
}
while (pOstRegs->oscr0 <= expireTime);
return;
}
void mmXllpOstDelayMicroSeconds(P_m_OST_T pOstRegs, unsigned long microseconds)
{
unsigned long ticks;
ticks = microseconds * 3; ///XLLP_OST_TICKS_US; // approx. 3 ticks per microsecond.
mmXllpOstDelayTicks (pOstRegs, ticks);
}
//-------------------------------------------------------------
#if 0
BOOL FMD_MapVirtualAddress()
{
// RETAILMSG(1, (TEXT("wzw:FMD_MapVirtualAddress\r\n")));
// v_pNANDFlash=(ULONG *)VirtualAllocCopy(0x100,"nflash_addr",((PVOID)FPGA_REGS_BASE_U_VIRTUAL+0x400));
v_pNANDFlash=VirtualAllocCopy(0x100,"mapping nand",(LPVOID)(FPGA_REGS_BASE_U_VIRTUAL+0x400));
if (!v_pNANDFlash) {
if (v_pNANDFlash) {
VirtualFree((PVOID)v_pNANDFlash,0,FPGA_REGS_BASE_U_VIRTUAL);
v_pNANDFlash = NULL;
}
return FALSE;
}
// NAND_CMD_PORT = *v_pNANDFlash + 4;
// NAND_ADDR_PORT = *v_pNANDFlash + 8;
// NAND_DATA_PORT = *v_pNANDFlash + 0;
/*
nandAdrr = v_pNANDFlash + 4; //2; //1; //4 ;
nandCMD = v_pNANDFlash + 8; //1; //2; //8 ;
nandDATA = v_pNANDFlash + 0 ;
*/
//wzw>>
NAND_CMD_PORT = ((ULONG)v_pNANDFlash + 0x08); //0x408);
NAND_ADDR_PORT = ((ULONG)v_pNANDFlash + 0x04); //0x404);
NAND_DATA_PORT = ((ULONG)v_pNANDFlash + 0x0); //0x400);
return TRUE;
}
#endif
//==============================================================================================
BOOL FMD_MapVirtualAddress()
{
PHYSICAL_ADDRESS PA;
PHYSICAL_ADDRESS RegPA;
// v_pNANDFlash=VirtualAllocCopy(0x100,"mapping nand",(LPVOID)(FPGA_REGS_BASE_U_VIRTUAL+0x400));
PA.QuadPart = 0x08000000+0x400; ///MAINSTONEII_BASE_REG_PA_FPGA;
v_pNANDFlash = (void *) MmMapIoSpace(PA, 0x100, FALSE);
if (mg_pOSTRegs == NULL) {
RegPA.QuadPart = 0x40A00000; ///BULVERDE_BASE_REG_PA_OST;
mg_pOSTRegs = (void *) MmMapIoSpace(RegPA, 0x400, FALSE);
}
if (!v_pNANDFlash || !mg_pOSTRegs ) {
DEBUGMSG(1, (TEXT("ERROR: Failed to allocate touch panel resources (Error=%u).\r\n"), GetLastError()));
if (mg_pOSTRegs) {
VirtualFree((void *)mg_pOSTRegs, 0, MEM_RELEASE);
mg_pOSTRegs = NULL;
}
if (!v_pNANDFlash) {
VirtualFree((void *)v_pNANDFlash, 0, MEM_RELEASE);
v_pNANDFlash = NULL;
}
return(FALSE);
}
NAND_CMD_PORT = ((ULONG)v_pNANDFlash + 0x08); //0x408);
NAND_ADDR_PORT = ((ULONG)v_pNANDFlash + 0x04); //0x404);
NAND_DATA_PORT = ((ULONG)v_pNANDFlash + 0x0); //0x400);
return TRUE;
}
//==============================================================================================
// Flash Chip Capability
#define NUM_BLOCKS 4096
#define SECTOR_SIZE 2048
#define SPARE_SIZE 64
// NAND Flash Command. This appears to be generic across all NAND flash chips
#define CMD_READ 0x00 // Read
#define CMD_READ1 0x01 // Read1
#define CMD_READ2 0x50 // Read2
#define CMD_READID 0x90 // ReadID
#define CMD_READID2 0x91 // Read extended ID
#define CMD_WRITE 0x80 // Write phase 1
#define CMD_WRITE2 0x10 // Write phase 2
#define CMD_ERASE 0x60 // Erase phase 1
#define CMD_ERASE2 0xd0 // Erase phase 2
#define CMD_STATUS 0x70 // Status read
#define CMD_RESET 0xff // Reset
// Status bit pattern
#define STATUS_READY 0x40 // Ready
#define STATUS_ERROR 0x01 // Error
static BYTE ECC[8]; // Used to retrieve/store ECC information
#ifndef _ECC_H_
#define _ECC_H_
#include <windows.h>
//#include <windows.h>
#include <nkintr.h>
#define DATA_BLOCK_LEN 256
#define ECC_BUFF_LEN 6 // 3 bytes per 256 bytes of data
#define UNCORRECTABLE_ERROR 1
#define CORRECTABLE_ERROR 11
#ifdef __cplusplus
extern "C" {
#endif
//---------------------------- Structure Definitions -----------------------------
//------------------------------- Public Interface ------------------------------
BOOL ECC_ComputeECC(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pECC, DWORD dwECCBuffLen);
BOOL ECC_IsDataValid(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pExistingECC, DWORD dwECCBuffLen);
BOOL ECC_CorrectData(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pExistingECC, DWORD dwECCBuffLen);
//------------------------------ Helper Functions ------------------------------
UCHAR CountNumberOfOnes(UCHAR num);
#ifdef __cplusplus
}
#endif
#endif _ECC_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)
BOOL NEED_EXT_ADDR = TRUE;
static BOOL g_bXIPMode = FALSE;
static FMD_FLASH_INFO g_FMDInfo;
ULONG oldval;
// Function required by StrataFlash FMD - stub implementation.
DWORD SetKMode(DWORD fMode)
{
return(fMode);
}
// CheckStatus()
//
// Retrieve the status of the Chip. This function accept a loop number, which
// is used to do the loop if chip is not ready.
//
// dwLoops:
//
// 0: no loop
// 0xffffffff: loop forever
//
UCHAR CheckStatus(DWORD dwLoops)
{
BOOL bStop = (dwLoops != (DWORD) -1);
UCHAR usStatus,temp;
// Twb=200ns wait. generate 20 * 30ns wait
for (volatile int i=0;i<5;i++)
{
temp=*((volatile UCHAR *)(0x92000080));
}
return usStatus;
}
// GetStatus()
//
// Retrieve the status of the Chip. This function accept a loop number, which
// is used to do the loop if chip is not ready.
//
// dwLoops:
//
// 0: no loop
// 0xffffffff: loop forever
//
UCHAR GetStatus(DWORD dwLoops)
{
BOOL bStop = (dwLoops != (DWORD) -1);
UCHAR usStatus;
//wzw@@
// usWait(2); //
mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 2);
// Sleep(1);
// mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
// Issue read status command
*((volatile ULONG *)(NAND_CMD_PORT))=CMD_STATUS;
while(1) {
usStatus = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT)));
if( usStatus & STATUS_READY ) // Non-infinite loop and // we already pay our due
{
break;
}
dwLoops--;
}
// We need to reset the port back to read mode. Issuing a read (0x00)
// command
//FMD_WRITE_PORT_UCHAR((PUCHAR) NAND_CMD_PORT, (UCHAR) CMD_READ);
return usStatus;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: FMD_Init()
Description: Initializes the Flash memory device.
Returns: Boolean indicating success.
------------------------------------------------------------------------------*/
static DWORD ReadFlashID(void)
{
BYTE Mfg, Dev;
*((volatile ULONG *)(NAND_CMD_PORT ))=CMD_READID; // Send flash ID read command.
*((volatile ULONG *)(NAND_CMD_PORT ))=0; //
// Sleep(1); //wzw wait // Wait for flash to complete command.
// mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
// Sleep(1);
mmXllpOstDelayMicroSeconds((P_m_OST_T) mg_pOSTRegs, 1000);
Mfg = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); //
Dev = (UCHAR)(*((volatile ULONG *)(NAND_DATA_PORT))); //
return ((DWORD)Mfg*0x100+Dev);
}
BOOL ECC_ComputeECC(LPBYTE pData, DWORD dwDataBuffLen, LPBYTE pECC, DWORD dwECCBuffLen)
{
static UINT i, j, k;
static UCHAR evenParity[16] = {0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0}; // Look-up table (LUT)
static UCHAR dataXOR = 0;
static UCHAR bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7;
// Column parity terms. NOTE: p subscript denotes "prime" (i.e. P1p = P1')
static UCHAR P1, P2, P4, P1p, P2p, P4p;
// Row parity terms. NOTE: p subscript denotes "prime" (i.e. P8p = P8')
UCHAR P8, P8p, P16, P16p, P32, P32p, P64, P64p, P128, P128p,
P256, P256p, P512, P512p, P1024, P1024p;
// RETAILMSG(1, (TEXT("INFO:ECC_ComputeECC\r\n")));//+
//----- 1. Check to make sure the input buffers are legitimate... -----
if((pData == NULL) || (pECC == NULL) || (dwDataBuffLen < DATA_BLOCK_LEN) || (dwECCBuffLen < ECC_BUFF_LEN) )
{
DEBUGMSG(1, (TEXT("FMD:ECC_ComputeECC() - Input buffers are not legitimate!\r\n")));
return FALSE;
}
//----- 2. Segregrate the data buffer into 256 byte blocks and compute ECC info for each block -----
for(j=0,k=0; j<dwDataBuffLen; j+= DATA_BLOCK_LEN)
{
//----- 3. Initialize the ROW parity terms -----
dataXOR = 0;
P8=0; P8p=0; P16=0; P16p=0; P32=0; P32p=0; P64=0; P64p=0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?