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

📄 strata.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 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.
//
//-----------------------------------------------------------------------------
//
// 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 + -