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

📄 nor.c

📁 Freescale ARM9系列CPU MX27的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 2 页
字号:

    // Just to avoid possible problems
    memset(pInfo, 0, sizeof(*pInfo));

    // Make sure that we talk to uncached address
    base = (UINT32)OALCAtoUA(pBase);
    
    // Try 32-bit geometry
    //OUTREG32((UINT32*)(base + 4 * 0x5555), 0xAAAAAAAA);
    //OUTREG32((UINT32*)(base + 4 * 0x2AAA), 0x55555555);
    OUTREG32((UINT32*)(base + 4 * 0x5555), 0x98989898);
    code1 = INREG32((UINT32*)(base + 4 * 0x10));
    code2 = INREG32((UINT32*)(base + 4 * 0x11));
    code3 = INREG32((UINT32*)(base + 4 * 0x12));
    if (code1 == 'QQQQ' && code2 == 'RRRR' && code3 == 'YYYY') {
        pInfo->width = 4;
        pInfo->parallel = 4;
    } else if (code1 == 'Q\0Q\0' && code2 == 'R\0R\0' && code3 == 'Y\0Y\0') {
        pInfo->width = 4;
        pInfo->parallel = 2;
    } else if (code1 == 'Q\0\0\0' && code2 == 'R\0\0\0' && code3 == 'Y\0\0\0') {
        pInfo->width = 4;
        pInfo->parallel = 1;
    } else {
        // Now try luck with 16-bit geometry
        //OUTREG16((UINT16*)(base + 2 * 0x5555), 0xAAAA);
        //OUTREG16((UINT16*)(base + 2 * 0x2AAA), 0x5555);
        OUTREG16((UINT16*)(base + 2 * 0x5555), 0x9898);
        code1 = INREG16((UINT16*)(base + 2 * 0x10));
        code2 = INREG16((UINT16*)(base + 2 * 0x11));
        code3 = INREG16((UINT16*)(base + 2 * 0x12));
        if (code1 == 'QQ' && code2 == 'RR' && code3 == 'YY') {
            pInfo->width = 2;
            pInfo->parallel = 2;
        } else if (code1 == '\0Q' && code2 == '\0R' && code3 == '\0Y') {
            pInfo->width = 2;
            pInfo->parallel = 1;
        } else {
            // So last oppurtinity is 8-bit mode
            //OUTREG8((UINT8*)(base + 0x5555), 0xAA);
            //OUTREG8((UINT8*)(base + 0x2AAA), 0x55);
            OUTREG8((UINT8*)(base + 0x5555), 0x98);
            code1 = INREG8((UINT8*)(base + 0x10));
            code2 = INREG8((UINT8*)(base + 0x11));
            code3 = INREG8((UINT8*)(base + 0x12));
            if (code1 == 'Q' && code2 == 'R' && code3 == 'Y') {
                pInfo->width = 1;
                pInfo->parallel = 1;
            } else {
                goto cleanUp;
            }                
        }
    }        

    // Read primary command set, size, burst size and number of regions
    pInfo->set = ReadInfo(base, 0x13, 2, pInfo->width);
    pInfo->size = 1 << ReadInfo(base, 0x27, 1, pInfo->width);
    pInfo->burst = 1 << ReadInfo(base, 0x2A, 1, pInfo->width);
    pInfo->regions = ReadInfo(base, 0x2C, 1, pInfo->width);

    // If there is more regions than expected
    if (pInfo->regions > 8) goto cleanUp;
   
    // Read region info
    for (i = 0; i < pInfo->regions; i++) {
        code1 = ReadInfo(base, 0x2d + (i << 2), 4, pInfo->width);
        pInfo->aBlocks[i] = (code1 & 0xFFFF) + 1;
        pInfo->aBlockSize[i] = (code1 >> 8) & 0x00FFFF00;
        if (pInfo->aBlockSize[i] == 0) pInfo->aBlockSize[i] = 128;
    }

    // Switch back to read mode
    switch (pInfo->set) {
    case 1:  // Intel/Sharp
    case 3: // New Intel parts
        WriteCommand(base, 0, 0xFF, pInfo->width, pInfo->parallel);
        break;
    case 2:  // AMD/Fujitsu
    case 0x0701: // SST
        WriteCommand(base, 0, 0xF0,  pInfo->width, pInfo->parallel);
        break;
    }      

    rc = TRUE;

cleanUp:
    OALMSG(OAL_FUNC, (L"-OALFlashInfo(rc = %d)\r\n", rc));
    return rc;
}

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

BOOL OALFlashErase(VOID *pBase, VOID *pStart, UINT32 size)
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    UINT32 base, start, end, chip, block;
    UINT32 ixReg, ixBlock;

    OALMSG(OAL_FUNC, (
        L"+OALFlashErase(0x%08x, 0x%08x, 0x%08x)\r\n", pBase, pStart, size
    ));


    // Erase must work from uncached memory
    base = (UINT32)OALCAtoUA(pBase);
    start = (UINT32)OALCAtoUA(pStart);
    
    // First get end address
    end = start + size;
   
    // Ther read first chip info
    if (!OALFlashInfo((VOID*)base, &info)) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OALFlashErase failed get flash memory info\r\n"
        ));
        goto cleanUp;
    }

    ixReg = ixBlock = 0;
    block = chip = base;
    while (block < end) {

        // Should block be erased?
        if (
            start < (block + info.aBlockSize[ixReg] * info.parallel) && 
            end >=  block
            ) {
            switch (info.set) {
            case 1: // Intel/Sharp
            case 3: // New Intel parts
                if (!UnlockBlock1(chip, block, &info)) {
                    goto cleanUp;
                }
                if (!EraseBlock1(chip, block, &info)) {
                    goto cleanUp;
                }
                break;
            case 2: // AMD
            case 0x0701: // SST
                if (!EraseBlock2(chip, block, &info)) {
                    goto cleanUp;
                }                    
                break;
            default:
                OALMSG(OAL_ERROR, (
                    L"ERROR: Flash type %d isn't supported\r\n", info.set
                    ));
                goto cleanUp;
            }
        }         

        // Move to next block
        block += info.aBlockSize[ixReg] * info.parallel;
        if (block >= end) break;
        if (++ixBlock >= info.aBlocks[ixReg]) {
            ixBlock = 0;
            if (++ixReg >= info.regions) {
                // Try read next chip info
                if (!OALFlashInfo((VOID*)block, &info)) break;
                ixReg = 0;
                chip = block;
            }
        }
    }

    rc = TRUE;
   
cleanUp:
    OALMSG(OAL_FUNC, (L"-OALFlashErase(rc = %d)\r\n", rc));
    return rc;
}

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

BOOL OALFlashWrite(VOID *pBase, VOID *pStart, UINT32 size, VOID *pBuffer)
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    UINT32 base, start, end, chip, pos, count;
    UINT8 *pPos;

    OALMSG(OAL_FUNC, (
        L"+OALFlashWrite(0x%08x, 0x%08x, 0x%08x, 0x%08x)\r\n", 
        pBase, pStart, size, pBuffer
    ));

    // Flash must work from uncached memory
    base = (UINT32)OALCAtoUA(pBase);
    start = (UINT32)OALCAtoUA(pStart);

    // First get end address
    end = start + size;
    chip = base;
    pPos = (UINT8*)pBuffer;

    // First read first chip info
    while (TRUE) {
        if (!OALFlashInfo((VOID*)chip, &info)) {
            OALMSG(OAL_ERROR, (
                L"ERROR: OALFlashWrite - failed get flash info at 0x%08x\r\n",
                chip
            ));
            goto cleanUp;
        }
        // Is start address on this chip
        if (start >= chip && start < (chip + info.size * info.parallel)) break;
        // Move to next chip
        chip += info.size * info.parallel;
    }
   
    pos = start;
    while (pos < end) {

        // Program data chunk
        switch (info.set) {
        case 1:
        case 3:
            count = WriteData1(chip, pos, &info, pPos);
            break;
        case 2:
        case 0x0701: // SST
            count = WriteData2(chip, pos, &info, pPos);
            break;
        default:
            OALMSG(OAL_ERROR, (
                L"ERROR: Flash type %d isn't supported\r\n", info.set
            ));
            goto cleanUp;
        }

        // If we write nothing some problem happen
        if (count == 0) {
            rc = FALSE;
            OALMSG(OAL_ERROR, (
                L"ERROR: Flash write at 0x%08x failed\r\n", pos
            ));
            goto cleanUp;
        }
      
        // Move position
        pos += count;
        pPos += count;

        // If we run out of chip move to next one
        if (pos > (chip + info.size * info.parallel)) {
            switch (info.set) {
            case 1:
            case 3:
                WriteCommand(chip, 0, 0xFF, info.width, info.parallel);
                break;
            case 2:
                WriteCommand(chip, 0, 0xF0, info.width, info.parallel);
                break;
            }
            chip += info.size * info.parallel;
            if (!OALFlashInfo((VOID*)chip, &info)) break;
        }         
    }

    switch (info.set) {
    case 1:
    case 3:
        WriteCommand(chip, 0, 0xFF, info.width, info.parallel);
        break;
    case 2:
    case 0x0701: // SST
        WriteCommand(chip, 0, 0xF0, info.width, info.parallel);
        break;
    }

    // Do final check
    pPos = (UINT8*)pBuffer;
    for (pos = start; pos < end - sizeof(UINT32) + 1; pos += sizeof(UINT32)) {
        if (*(UINT32*)pPos != *(UINT32*)pos) break;
        pPos += sizeof(UINT32);
    }

    // If we reach end, all is ok
    rc = (pos >= end - sizeof(UINT32) + 1);
    OALMSG(!rc&&OAL_ERROR, (
        L"ERROR: Flash failed at 0x%08x -- write 0x%08x, but read 0x%08x\r\n",
        pos, *(UINT32*)pPos, *(UINT32*)pos
    ));
    
cleanUp:
    OALMSG(OAL_FUNC, (L"-OALFlashWrite(rc = %d)", rc));
    return rc;
}

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

BOOL OALFlashIdentifier(VOID *pBase, BYTE* pIdent, DWORD* pdwSize)
{
    BOOL rc = FALSE;
    OAL_FLASH_INFO info;
    UINT32 base;

    OALMSG(OAL_FUNC, (L"+OALFlashIdentifier(0x%08x, ...)\r\n", pBase));

    if (pdwSize == NULL || *pdwSize == 0)
    {
        goto cleanUp;
    }

    // Make sure that we talk to uncached address
    base = (UINT32)OALCAtoUA(pBase);
    
    if (pIdent == NULL)
        goto cleanUp;

    if (!OALFlashInfo((VOID*)base, &info)) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OALFlashIdentifier - failed get flash info at 0x%08x\r\n",
            base
        ));
        goto cleanUp;
    }

    // TODO: This works for Intel parts. How about others?
    switch (info.set) {
    case 1:        
    case 3:
        if (*pdwSize < 8 * info.parallel)
            goto cleanUp;
        *pdwSize = 8 * info.parallel;
        // read 8 bytes of protection register from each chip into pIdent buffer
        rc = ReadIdent1(base, base, &info, pIdent, *pdwSize);
        break;
    case 2:
        *pdwSize = 0; // I'm unaware of any chips with set=2 which have an ident
        break;
    default:
        rc = FALSE;
    }


cleanUp:
    OALMSG(OAL_FUNC, (L"-OALFlashIdentifier(rc = %d)\r\n", rc));
    return rc;
}


//------------------------------------------------------------------------------
//
//  Function:  NORLoadEBootCFG
//
//  Retrieves bootloader configuration information (menu settings, etc.) from 
//  the NOR flash.
//
//  Parameters:
//      eBootCFG 
//          [out] Points to bootloader configuration that will be filled with
//          loaded data. 
//
//      cbBootCfgSize
//          [in] Size in bytes of the bootloader configuration.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NORLoadEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
    VOID *pStart = (VOID *) OALPAtoUA(IMAGE_BOOT_BOOTCFG_NOR_PA_START);

    KITLOutputDebugString("INFO:  Reading boot configuaration in NOR flash (addr = 0x%x, size = 0x%x)\r\n", 
        pStart, cbBootCfgSize);

    if (!pBootCfg) return FALSE;

    memcpy((VOID *) pBootCfg, pStart, cbBootCfgSize);

    KITLOutputDebugString("INORLoadEBootCFG end!\r\n");

    return TRUE;
}


//------------------------------------------------------------------------------
//
//  Function:  NORStoreEBootCFG
//
//  Stores bootloader configuration information (menu settings, etc.) to 
//  the NOR flash.
//
//  Parameters:
//      eBootCFG 
//          [out] Points to bootloader configuration that will be stored.
//
//      cbBootCfgSize
//          [in] Size in bytes of the bootloader configuration.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NORStoreEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
    BOOL rc = FALSE;
    VOID *pFlashBase = (VOID *) OALPAtoUA(IMAGE_BOOT_NOR_PA_START);
    VOID *pStart = (VOID *) OALPAtoUA(IMAGE_BOOT_BOOTCFG_NOR_PA_START);

    KITLOutputDebugString("INFO:  Storing boot configuaration in NOR flash (addr = 0x%x, size = 0x%x)\r\n", 
        pStart, cbBootCfgSize);

    if (!OALFlashErase(pFlashBase, pStart, cbBootCfgSize))
    {
        KITLOutputDebugString("ERROR:  OEMWriteErase failed!\r\n");
        goto cleanUp;
    }

    if (!OALFlashWrite(pFlashBase, pStart, cbBootCfgSize, (VOID *) pBootCfg))
    {
        KITLOutputDebugString("ERROR:  OALFlashWrite failed!\r\n");
        goto cleanUp;
    }        

    KITLOutputDebugString("INFO:  Boot configuration successfully stored.\r\n");

    rc = TRUE;

cleanUp:
    return  rc;
}


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

⌨️ 快捷键说明

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