📄 strata.c
字号:
//
// 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.
//
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//-----------------------------------------------------------------------------
//
// File: strata.c
//
// Low level driver for Intel Strata flash.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <ceddk.h>
#include "nor.h"
#include "strata.h"
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
// Local Functions
BOOL CheckStatus(BOOL bIsPaired, ULONG ulSectorAddress, BOOL fLockCmd);
//-----------------------------------------------------------------------------
// EXPORTED FUNCTIONS
//-----------------------------------------------------------------------------
// WARNING: for relocation purpose. Do not move!
void StrataX16_RelocateBegin(void)
{
}
//-----------------------------------------------------------------------------
//
// Function: StrataX16_IsFlashSupported
//
// Function performs check to see if flash is present and if device is
// supported. For 16bit mode flash devices.
//
// Parameters:
// pFlashDesc
// [in/out] pointer to NOR flash descriptor
//
// Returns:
// FALSE if device not supported/present
//
//-----------------------------------------------------------------------------
BOOL StrataX16_IsFlashSupported(NOR_FLASH_DESC *pFlashDesc)
{
ULONG ulFlashBase;
BOOL bIsPaired;
BOOL bSuccess;
DWORD i;
USHORT *pusSiID;
DWORD dwBusWidth;
ULONG id;
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("StrataX16_IsFlashSupported+\r\n")));
if (!pFlashDesc) {
DEBUGMSG(ZONE_HAL_ERROR,
(TEXT("StrataX16_IsFlashSupported: null param\r\n")));
return FALSE;
}
ulFlashBase = pFlashDesc->FlashBase;
bSuccess = TRUE;
bIsPaired = FALSE;
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_ARRAY_CMD);
// Check for manufacturer ID
// ********************************
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_IDENT_CMD);
id = RD_FLASH_INDEXED16(bIsPaired, ulFlashBase, READ_MFGCODE_ADDR);
DEBUGMSG(ZONE_HAL_INFO, (TEXT("Manufacturer code = 0x%08x\r\n"), id));
if (!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
READ_MFGCODE_ADDR, INTEL_MFG_ID)) {
// This isn't an Intel flash part.
DEBUGMSG(ZONE_HAL_ERROR,
(TEXT("INFO: No supported Intel flash detected\r\n")));
DEBUGMSG(ZONE_HAL_INFO, (TEXT("Manufacturer code = 0x%04x\r\n"),
(USHORT)RD_FLASH_INDEXED16(bIsPaired, ulFlashBase, READ_MFGCODE_ADDR)));
bSuccess = FALSE;
goto _exit;
}
// Look for a Common Flash Interface (CFI) device.
// ***********************************************
// Assume flash is paired
bIsPaired = TRUE;
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_ARRAY_CMD);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase,
CFI_QUERY_ADDR, CFI_QUERY_DATA);
if (!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_QRY_ID_Q, CFI_DATA_QUERY_ID_Q) ||
!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_QRY_ID_R, CFI_DATA_QUERY_ID_R) ||
!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_QRY_ID_Y, CFI_DATA_QUERY_ID_Y)) {
bIsPaired = FALSE;
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_ARRAY_CMD);
WR_FLASH_REG_INDEXED16(bIsPaired, ulFlashBase,
CFI_QUERY_ADDR, CFI_QUERY_DATA);
if (!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_QRY_ID_Q, CFI_DATA_QUERY_ID_Q) ||
!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_QRY_ID_R, CFI_DATA_QUERY_ID_R) ||
!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_QRY_ID_Y, CFI_DATA_QUERY_ID_Y)) {
// TODO - add JEDEC check & fake CFI info to support.
// This flash doesn't support CFI.
DEBUGMSG(ZONE_ERROR,
(TEXT("ERROR: Strata chip CFI not supported\r\n")));
bSuccess = FALSE;
goto _exit;
}
}
DEBUGMSG(ZONE_HAL_INFO,
(TEXT("INFO: CFI device detected at 0x%08x. Paired(%c)\r\n"),
ulFlashBase, bIsPaired? 'T':'F'));
// Use the CFI to collect information on it. Also, assume that both
// high and low word flash parts are the same if paired.
for (i = 0; i < sizeof(CFI_FLASH_QUERY_ID_STRING); i++) {
*((UCHAR *)&pFlashDesc->QryIDStr + i) =
(UCHAR)(RD_FLASH_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_QRY_ID + i) & 0xFF);
}
for (i = 0; i < sizeof(CFI_FLASH_SYSINTERFACE_INFO); i++) {
*((UCHAR *)&pFlashDesc->SysInt + i) =
(UCHAR)(RD_FLASH_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_SYSINTF + i) & 0xFF);
}
for (i = 0; i < sizeof(CFI_FLASH_GEOMETRY_INFO); i++) {
*((UCHAR *)&pFlashDesc->Geometry + i) =
(UCHAR)(RD_FLASH_INDEXED16(bIsPaired, ulFlashBase,
CFI_QS_OFFSET_DEVGEOM + i) & 0xFF);
}
// Get Primary extended table
if (pFlashDesc->QryIDStr.PriExtTableAddr != 0) {
INTEL_PET_QUERY_INFO pet;
for (i = 0; i < sizeof(INTEL_PET_QUERY_INFO); i++) {
*((UCHAR *)&pet + i) =
(UCHAR)((RD_FLASH_INDEXED16(bIsPaired, ulFlashBase,
pFlashDesc->QryIDStr.PriExtTableAddr + i)) & 0xFF);
}
if (!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
pFlashDesc->QryIDStr.PriExtTableAddr, CFI_DATA_PET_ID_P) ||
!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
pFlashDesc->QryIDStr.PriExtTableAddr+1, CFI_DATA_PET_ID_R) ||
!CHECK_FLASH_STATUS_INDEXED16(bIsPaired, ulFlashBase,
pFlashDesc->QryIDStr.PriExtTableAddr+2, CFI_DATA_PET_ID_I)) {
DEBUGMSG(ZONE_HAL_ERROR,
(TEXT("INFO: Invalid Primary vendor extended table data!\r\n")));
// TODO: do something if Pri ext table is needed.
}
}
// Put the Flash into a known state (READ_ARRAY mode with WRITE-ENABLE disabled).
// ******************************************************************************
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_ARRAY_CMD);
// Save manufacturer ID
// ********************************
pFlashDesc->FlashID.ManufacturerID = (USHORT)id;
// Get device ID
// *****************
for (i = 0; i < sizeof(NOR_FLASH_ID_DESC) / sizeof(ULONG); i++)
*((ULONG *)&pFlashDesc->FlashID + i) = 0;
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_IDENT_CMD);
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_ARRAY_CMD);
pFlashDesc->FlashID.DeviceID[0] =
(USHORT)RD_FLASH_INDEXED16(bIsPaired, ulFlashBase, READ_DEVCODE_ADDR);
DEBUGMSG(ZONE_HAL_INFO, (TEXT("Manufacturer: 0x%x Device: 0x%x Paired %c\r\n"),
pFlashDesc->FlashID.ManufacturerID, *(ULONG *)pFlashDesc->FlashID.DeviceID,
bIsPaired ? 'T' : 'F'));
// Check for device with supported interface
if (pFlashDesc->Geometry.DevInterface != CFI_DEV_INTF_x8x16_ASYNC &&
pFlashDesc->Geometry.DevInterface != CFI_DEV_INTF_x16_ASYNC &&
pFlashDesc->Geometry.DevInterface != CFI_DEV_INTF_x16x32_ASYNC ) {
DEBUGMSG(ZONE_HAL_INFO,
(TEXT("INFO: Unsupported device interface 0x%04x\r\n"),
pFlashDesc->Geometry.DevInterface));
bSuccess = FALSE;
goto _exit;
}
// Check for supported command set.
if (pFlashDesc->QryIDStr.PriOEMCmdSetID != 0x0001 &&
pFlashDesc->QryIDStr.PriOEMCmdSetID != 0x0003 ) {
DEBUGMSG(ZONE_HAL_INFO, (TEXT("Unsupported Pri Cmd Set: 0x%04x\r\n"),
pFlashDesc->QryIDStr.PriOEMCmdSetID));
bSuccess = FALSE;
goto _exit;
}
// TODO: Get device unique silicon ID
pusSiID = (USHORT *)(pFlashDesc->FlashID.SiliconID);
dwBusWidth = bIsPaired? sizeof(ULONG): sizeof(USHORT);
// Set device width
pFlashDesc->DeviceWidth = 16;
pFlashDesc->PairedFlash = bIsPaired;
_exit:
// Put the Flash into a known state (READ_ARRAY mode with WRITE-ENABLE disabled).
// ******************************************************************************
WR_FLASH_REG_16(bIsPaired, ulFlashBase, READ_ARRAY_CMD);
DEBUGMSG(ZONE_HAL_FUNCTION, (TEXT("StrataX16_IsFlashSupported-\r\n")));
return bSuccess;
}
//-----------------------------------------------------------------------------
//
// Function: StrataX16_Program
//
// Function performs programming of 16bit mode flash devices.
//
//
// Parameters:
// pFlashDesc
// [in] pointer to NOR flash descriptor
//
// ulProgramAddress
// [in] start address to start programming
//
// pData
// [in] ptr to data buffer
//
// ulLen
// [in] length of data
//
// bIgnore0to1
// [in] ignores writing 0 to 1 if true
// Returns:
// FALSE if programming failed
//
//-----------------------------------------------------------------------------
BOOL StrataX16_Program(NOR_FLASH_DESC *pFlashDesc, ULONG ulProgramAddress,
UCHAR *pData, ULONG ulLen, BOOL bIgnore0to1)
{
ULONG i;
ULONG j;
ULONG ulWriteBufferSize;
ULONG ulBufAlignBytes;
ULONG *pulData;
ULONG dwNumPages;
ULONG ulProgBytes;
ULONG ulDataToWrite;
ULONG ulDataWritten;
DWORD dwBusWidth;
ULONG ulFlashBase;
ULONG ulBufDatumSize;
BOOL bIsPaired;
BOOL bSuccess;
ULONG ulIgnoreBuffer[INTEL_BUF_PROG_MAX_DATUM];
DEBUGMSG(ZONE_HAL_FUNCTION,
(TEXT("StrataX16_Program+: 0x%08x 0x%08x 0x%08x\r\n"),
ulProgramAddress, pData, ulLen));
if (!pFlashDesc) {
DEBUGMSG(ZONE_HAL_ERROR, (TEXT("StrataX16_Program: null param\r\n")));
return FALSE;
}
ulFlashBase = pFlashDesc->FlashBase;
bIsPaired = pFlashDesc->PairedFlash;
ulWriteBufferSize = (pFlashDesc->Geometry.WriteBuffSize) ?
(bIsPaired ? ((1 << pFlashDesc->Geometry.WriteBuffSize) * 2) :
(1 << pFlashDesc->Geometry.WriteBuffSize)) : 0;
pulData = (ULONG *)pData;
dwNumPages = (ulWriteBufferSize) ? (ulLen / ulWriteBufferSize) : 0;
ulBufAlignBytes = (ulWriteBufferSize) ?
ulProgramAddress % ulWriteBufferSize : 0;
ulProgBytes = 0;
dwBusWidth = bIsPaired ? sizeof(ULONG) : sizeof(USHORT);
bSuccess = TRUE;
DEBUGMSG(ZONE_HAL_FUNCTION,
(TEXT("ulWriteBufferSize 0x%08x\r\n"), ulWriteBufferSize));
DEBUGMSG(ZONE_HAL_FUNCTION,
(TEXT("ulFlashBase 0x%08x bIsPaired %c dwBusWidth %d\r\n"),
ulFlashBase, bIsPaired? 'T' : 'F', dwBusWidth));
if (ulBufAlignBytes != 0 || dwNumPages == 0) {
ulProgBytes = (ulWriteBufferSize) ? ulBufAlignBytes : ulLen;
DEBUGMSG(ZONE_HAL_FUNCTION,
(TEXT("dwBufAlignBytes 0x%08x dwNumPages 0x%08x ulProgBytes 0x%08x\r\n"),
ulBufAlignBytes, dwNumPages, ulProgBytes));
for (i = 0; i < ulProgBytes; i += dwBusWidth) {
ulDataToWrite = bIsPaired ? *(ULONG *)pulData : *(USHORT *)pulData;
if (bIgnore0to1) {
ulDataWritten = bIsPaired ?
*(volatile ULONG *)ulProgramAddress :
*(volatile USHORT *)ulProgramAddress;
ulDataToWrite &= ulDataWritten;
}
WR_FLASH_REG_16(bIsPaired, ulProgramAddress, BYTEWORD_PROGRAM_CMD);
WR_FLASH_16(bIsPaired, ulProgramAddress, (*(ULONG *)pulData));
if (!CheckStatus(bIsPaired, ulProgramAddress, FALSE)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -