📄 flash.c
字号:
{
switch (info.set)
{
#ifndef OAL_FLASH_NO_COMMAND_SET_1
case 1: // Intel/Sharp
case 3:
if (!EraseBlock1(&info, chip, blockStart))
{
goto cleanUp;
}
break;
#endif OAL_FLASH_NO_COMMAND_SET_1
#ifndef OAL_FLASH_NO_COMMAND_SET_2
case 2: // AMD
if (!EraseBlock2(&info, chip, blockStart))
{
goto cleanUp;
}
break;
#endif OAL_FLASH_NO_COMMAND_SET_2
default:
OALMSG(OAL_ERROR, (
L"ERROR: Flash type %d isn't supported\r\n", info.set
));
goto cleanUp;
}
}
// Move to next block
blockStart = blockEnd;
if (blockStart >= end) break;
if (++block >= info.aBlocks[region])
{
block = 0;
if (++region >= info.regions)
{
// Try read next chip info
if (!OALFlashInfo((VOID*)blockStart, &info)) break;
region = 0;
chip = blockStart;
}
}
}
rc = TRUE;
cleanUp:
OALMSG(OAL_FUNC, (L"-OALFlashErase(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
BOOL
OALFlashEraseStart(
VOID *pBase,
VOID *pStart,
UINT32 size
)
{
BOOL rc = FALSE;
OAL_FLASH_INFO info;
UINT32 base = (UINT32)pBase;
UINT32 start = (UINT32)pStart;
UINT32 end = start + size;
UINT32 chip, blockStart, blockEnd;
UINT32 region, block;
// There can be only one pending erase
if (s_erase.pending) goto cleanUp;
// First detect flash at base
if (!OALFlashInfo((VOID*)base, &info))
{
goto cleanUp;
}
// Find first block to be erased
region = block = 0;
blockStart = chip = base;
while (blockStart < end)
{
// Block end (+1)
blockEnd = blockStart + info.aBlockSize[region] * info.parallel;
// Should block be erased?
if (start < blockEnd && end >= blockStart) break;
// This should not happen...
if (blockEnd >= end) goto cleanUp;
// Move to next block
blockStart = blockEnd;
if (++block >= info.aBlocks[region])
{
block = 0;
if (++region >= info.regions)
{
// Try read next chip info
if (!OALFlashInfo((VOID*)block, &info)) goto cleanUp;
region = 0;
chip = block;
}
}
}
// Start erase
switch (info.set)
{
#ifndef OAL_FLASH_NO_COMMAND_SET_1
case 1: // Intel/Sharp
case 3:
if (!StartEraseBlock1(&info, chip, blockStart))
{
goto cleanUp;
}
break;
#endif OAL_FLASH_NO_COMMAND_SET_1
#ifndef OAL_FLASH_NO_COMMAND_SET_2
case 2: // AMD
if (!StartEraseBlock2(&info, chip, blockStart))
{
goto cleanUp;
}
break;
#endif OAL_FLASH_NO_COMMAND_SET_2
default:
goto cleanUp;
}
// Save context for continue...
s_erase.info = info;
s_erase.base = chip;
s_erase.end = end;
s_erase.pos = blockStart;
s_erase.region = region;
s_erase.block = block;
s_erase.pending = TRUE;
rc = TRUE;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
UINT32
OALFlashEraseContinue(
)
{
UINT32 rc = OAL_FLASH_ERASE_FAILED;
OAL_FLASH_INFO *pInfo = &s_erase.info;
// There must be pending erase
if (!s_erase.pending) goto cleanUp;
// Look if erase is done
switch (s_erase.info.set)
{
#ifndef OAL_FLASH_NO_COMMAND_SET_1
case 1: // Intel/Sharp
case 3:
rc = ContinueEraseBlock1(&s_erase.info, s_erase.base, s_erase.pos);
break;
#endif OAL_FLASH_NO_COMMAND_SET_1
#ifndef OAL_FLASH_NO_COMMAND_SET_2
case 2: // AMD
rc = ContinueEraseBlock2(&s_erase.info, s_erase.base, s_erase.pos);
break;
#endif OAL_FLASH_NO_COMMAND_SET_2
default:
goto cleanUp;
}
// If erase is pending or failed we are done
if (rc != OAL_FLASH_ERASE_DONE) goto cleanUp;
// Move to next block
s_erase.pos += pInfo->aBlockSize[s_erase.region] * pInfo->parallel;
// Are we done?
if (s_erase.pos >= s_erase.end) goto cleanUp;
// Is is next chip?
if (++s_erase.block >= pInfo->aBlocks[s_erase.region])
{
s_erase.block = 0;
if (++s_erase.region >= pInfo->regions)
{
s_erase.base = s_erase.pos;
// Try read next chip info
if (!OALFlashInfo((VOID*)s_erase.base, pInfo)) goto cleanUp;
s_erase.region = 0;
}
}
cleanUp:
if (rc != OAL_FLASH_ERASE_PENDING) s_erase.pending = FALSE;
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OALFlashWrite
//
// Note: please pass through Uncached Address (pBase, pStart)!
//
BOOL
OALFlashWrite(
VOID *pBase,
VOID *pStart,
UINT32 size,
VOID *pBuffer
)
{
BOOL rc = FALSE;
OAL_FLASH_INFO info;
DWORD base = (DWORD)pBase;
DWORD start = (DWORD)pStart;
DWORD end = start + size;
DWORD chipStart;
DWORD chipEnd;
DWORD pos, count;
UCHAR *pPos;
OALMSG(OAL_FUNC, (
L"+OALFlashWrite(0x%08x, 0x%08x, 0x%08x, 0x%08x)\r\n",
pBase, pStart, size, pBuffer
));
chipStart = base;
pPos = (UCHAR*)pBuffer;
// First read first chip info
while (TRUE)
{
if (!OALFlashInfo((VOID*)chipStart, &info))
{
OALMSG(OAL_ERROR, (
L"ERROR: OALFlashWrite - failed get flash info at 0x%08x\r\n",
chipStart
));
goto cleanUp;
}
chipEnd = chipStart + info.size * info.parallel;
// Is start address on this chip
if (start >= chipStart && start < chipEnd) break;
// Move to next chip
chipStart = chipEnd;
}
pos = start;
while (pos < end)
{
// How many data we can write
if (end > chipEnd)
{
count = chipEnd - pos;
}
else
{
count = end - pos;
}
// Program data chunk
switch (info.set)
{
#ifndef OAL_FLASH_NO_COMMAND_SET_1
case 1:
case 3:
count = WriteData1(&info, chipStart, pos, pPos);
break;
#endif OAL_FLASH_NO_COMMAND_SET_1
#ifndef OAL_FLASH_NO_COMMAND_SET_2
case 2:
count = WriteData2(&info, chipStart, pos, pPos);
break;
#endif OAL_FLASH_NO_COMMAND_SET_2
default:
OALMSG(OAL_ERROR, (
L"ERROR: Flash type %d isn't supported\r\n", info.set
));
goto cleanUp;
}
// If we write nothing something wrong 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;
// Break when we are done
if (pos >= end) break;
// If we run out of chip move to next one
if (pos > chipEnd)
{
switch(info.set) {
case 1:
case 3:
WriteCommand(&info, chipStart, 0, 0xFF);
break;
case 2:
WriteCommand(&info, chipStart, 0, 0xF0);
break;
}
chipStart = chipEnd;
if (!OALFlashInfo((VOID*)chipStart, &info)) break;
chipEnd = chipStart + info.size * info.parallel;
}
}
// Done
//rc = TRUE;
switch (info.set) {
case 1:
case 3:
WriteCommand(&info, chipStart, 0, 0xFF);
break;
case 2:
WriteCommand(&info, chipStart, 0, 0xF0);
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
OALFlashLockDown(
VOID *pBase,
VOID *pStart,
DWORD size
)
{
BOOL rc = FALSE;
OAL_FLASH_INFO info;
UINT32 base = (UINT32)pBase;
UINT32 start = (UINT32)pStart;
UINT32 end = start + size;
UINT32 chip, blockStart, blockEnd;
UINT32 region, block;
// Ther read first chip info
if (!OALFlashInfo((VOID*)base, &info))
{
goto cleanUp;
}
region = block = 0;
blockStart = chip = base;
while (blockStart < end)
{
// Block end (+1)
blockEnd = blockStart + info.aBlockSize[region] * info.parallel;
// Should block be erased?
if (start < blockEnd && end >= blockStart)
{
switch (info.set)
{
#ifndef OAL_FLASH_NO_COMMAND_SET_1
case 1: // Intel/Sharp
case 3:
if (!LockDownBlock1(&info, chip, blockStart))
{
goto cleanUp;
}
break;
#endif OAL_FLASH_NO_COMMAND_SET_1
#ifndef OAL_FLASH_NO_COMMAND_SET_2
case 2: // AMD
if (!LockDownBlock2(&info, chip, blockStart))
{
goto cleanUp;
}
break;
#endif OAL_FLASH_NO_COMMAND_SET_2
default:
goto cleanUp;
}
}
// Move to next block
blockStart = blockEnd;
if (blockStart >= end) break;
if (++block >= info.aBlocks[region])
{
block = 0;
if (++region >= info.regions)
{
// Try read next chip info
if (!OALFlashInfo((VOID*)block, &info)) break;
region = 0;
chip = block;
}
}
}
rc = TRUE;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -