📄 flash.c
字号:
// Write Word Count Low. Decrement once since a count of 0 corresponds to a single write.
if (dwDWORDsLeft > dwFlashPageSize) dwCount = dwFlashPageSize;
else dwCount = dwDWORDsLeft;
if (bByteMode) { // byte mode, 4 devices require each command in byte line
do {
FlashWriteCommand(pdwSR, 0x70707070UL);
} while (!FlashSR1(pdwSR,0x80808080UL)); // status check
do {
FlashWriteCommand(pdwSR, 0xe8e8e8e8UL); // Write to Buffer command
} while (!FlashSR1(pdwSR,0x80808080UL));
FlashWriteCommand(pdwSR, // set byte count
(dwCount - 1) << 24 | (dwCount - 1) << 16 | (dwCount - 1) << 8 | dwCount - 1);
for (i = 0; i < dwCount; i++) *pdwFlash++ = *pdwFlashCache++;
FlashWriteCommand(pdwSR, 0xd0d0d0d0UL); // Program Buffer to Flash command
}
else { // word mode, 2 devices require each command in word line
FlashWriteCommand(pdwSR, 0x00700070UL);
while (!FlashSR1(pdwSR,0x00800080UL)); // status check
do {
FlashWriteCommand(pdwSR, 0x00e800e8UL); // Write to Buffer command
} while (!FlashSR1(pdwSR,0x00800080UL));
FlashWriteCommand(pdwSR, // set word count
(dwCount-1) << 16 | dwCount - 1);
for (i = 0; i < dwCount; i++) *pdwFlash++ = *pdwFlashCache++;
FlashWriteCommand(pdwSR, 0x00d000d0UL); // Program Buffer to Flash command
}
dwDWORDsLeft -= dwCount;
} // while there are still DWORDs to write to the page
if (bByteMode) {
FlashWriteCommand(pdwSR, 0x70707070UL); // Read Status Register command
while (!FlashSR1(pdwSR, 0x80808080UL)); // Wait until operation complete
}
else {
FlashWriteCommand(pdwSR, 0x00700070UL); // Read Status Register command
while (!FlashSR1(pdwSR, 0x00800080UL)); // Wait until operation complete
}
// Check for operation errors
if (FlashError_IntelStrata(pdwSR, ppszErrorMsg)) {
return 1;
}
return 0;
}
UINT16 FlashClose_IntelStrata(
DWORD dwPhysStart,
DWORD dwPhysLen,
char **ppszErrorMsg )
{
volatile DWORD *pdwSR;
DWORD dwStartBlock, dwEndBlock, dwCurBlock;
DWORD dwStartBank, dwEndBank, dwCurBank;
DWORD *pdwFlash, *pdwFlashCache;
DWORD i, j, k;
DWORD dwStart;
DWORD dwFlashAreaBase;
BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE; // See FlashPageWrite_IntelStrata().
dwFlashAreaBase = (dwPhysStart & 0x1C000000) | UNCACHED_BASE; // top of each area
// Compute starting and ending block numbers
dwStartBlock = (dwPhysStart & (0x04000000 - dwFlashBlockSize))
/ dwFlashBlockSize;
dwEndBlock = ((dwPhysStart + dwPhysLen) & (0x04000000 - dwFlashBlockSize))
/ dwFlashBlockSize;
EdbgOutputDebugString("Closing Out Flash Image at %X of length %X (Blocks %u to %u)\r\n",
dwPhysStart, dwPhysLen, dwStartBlock, dwEndBlock );
dwStart= OEMEthGetSecs();
while (OEMEthGetSecs() - dwStart < 3) ;
// Make sure that all the blocks have finished before letting them go on, otherwise you
// might get bad values out of it.
for (dwCurBlock = dwStartBlock; dwCurBlock <= dwEndBlock; dwCurBlock++) {
pdwSR = (DWORD*)(dwFlashAreaBase + dwCurBlock * dwFlashBlockSize);
// Wait for the page to indicate ready, meaning that everything has been written
if (bByteMode) {
FlashWriteCommand(pdwSR, 0x70707070UL); // Read Status Register command
while(!FlashSR1(pdwSR, 0x80808080UL));
}
else {
FlashWriteCommand(pdwSR, 0x00700070UL); // Read Status Register command
while(!FlashSR1(pdwSR, 0x00800080UL));
}
}
// Reset flash to read array mode
dwStartBank = dwStartBlock / (dwFlashBankSize / dwFlashBlockSize);
dwEndBank = dwEndBlock / (dwFlashBankSize / dwFlashBlockSize);
for (dwCurBank = dwStartBank; dwCurBank <= dwEndBank; dwCurBank++) {
pdwSR = (DWORD *)(dwFlashAreaBase + dwCurBank * dwFlashBankSize);
if (bByteMode) FlashWriteCommand(pdwSR, 0xFFFFFFFFUL);
else FlashWriteCommand(pdwSR, 0x00FF00FFUL);
}
// Do a compare against the FlashCache[] and see if it all looks right
pdwFlashCache = (LPDWORD)FLASH_CACHE;
EdbgOutputDebugString("Comparing Flash vs FlashCache...\r\n dwPhysStart=%Xh FLASH_CACHE=%Xh length=%Xh\r\n",
dwPhysStart,pdwFlashCache,dwPhysLen);
pdwFlash = (DWORD *)dwPhysStart;
for (i = 0; i < dwPhysLen/4; i++) {
j = *pdwFlash;
k = *pdwFlashCache;
if (j != k) {
EdbgOutputDebugString( "Beat!\r\n" );
EdbgOutputDebugString( "Flash - FlashCache\r\n" );
for (j = 0; j < 16; j++) {
EdbgOutputDebugString("%X : %X - %X : %X\r\n",
pdwFlash, *pdwFlash, pdwFlashCache, *pdwFlashCache );
pdwFlash++;
pdwFlashCache++;
}
*ppszErrorMsg = "Error Comparing Flash vs FlashCache";
return 1;
}
pdwFlash++;
pdwFlashCache++;
}
EdbgOutputDebugString( "Jammin'!\r\n" );
return 0;
}
UINT16 IsFlash( DWORD dwPhysStart, DWORD dwPhysLen )
{
volatile DWORD *pdwRIC;
DWORD dwPhysEnd = dwPhysStart + dwPhysLen - 1;
DWORD dwStartArea, dwEndArea;
DWORD dwStartBank, dwCurrBank, dwEndBank;
DWORD dwCurrOffset;
DWORD dwFlashAreaBase;
DWORD dwError = 0;
// Flash Code, initially set to 0.
gdwFlashCode = 0;
// Check the address range
dwFlashAreaBase = (dwPhysStart & 0x1C000000) | UNCACHED_BASE; // top of each area
dwStartArea = (dwPhysStart & 0x1C000000) >> 26;
dwEndArea = (dwPhysEnd & 0x1C000000) >> 26;
if (dwStartArea != dwEndArea) { // must in the same area
EdbgOutputDebugString("Error: Image exceeds the memory area boundary.\r\n");
while (1); // wait forever
}
// Initially these bank numbers are set to 0. (assuming 64MB for single bank)
dwStartBank = 0;
dwCurrBank = 0;
dwEndBank = 0;
dwCurrOffset = 0;
while (dwCurrBank <= dwEndBank) {
pdwRIC = (volatile DWORD*)(dwFlashAreaBase + dwCurrOffset);
// Read Identifier Code
FlashWriteCommand(pdwRIC, 0x90909090UL);
if (*(pdwRIC) == 0x00890089UL) { // Intel device in word mode
pdwRIC++; // proceed to next DWORD
// Read Identifier Code
FlashWriteCommand(pdwRIC, 0x90909090UL);
if (*(pdwRIC) == 0x00150015UL) {
dwFlashPageSize = 0x00000010; // 16 bytes per page
dwFlashBlockSize = 0x00040000; // 256kB per block
dwFlashBankSize = 0x01000000; // 16MB per bank
dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
if (dwCurrBank >= dwStartBank) { // when in actually-used bank
pdwRIC--; // back to the top of current bank
EdbgOutputDebugString("Area %d : Found Intel 28F640J5. [DUAL WORD: 0x%x - 0x%x]\r\n",
dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F640J5_DW) {
dwError = 1; // Other type flash memory is already detected.
break;
}
gdwFlashCode = FLASH_28F640J5_DW;
FlashWrite = FlashWrite_IntelStrata;
FlashError = FlashError_IntelStrata;
FlashClose = FlashClose_IntelStrata;
}
}
else if (*(pdwRIC) == 0x00170017UL) {
dwFlashPageSize = 0x00000010; // 16 bytes per page
dwFlashBlockSize = 0x00040000; // 256kB per block
dwFlashBankSize = 0x01000000; // 16MB per bank
dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
if (dwCurrBank >= dwStartBank) { // when in actrually-used bank
pdwRIC--; // back to the top of current bank
EdbgOutputDebugString("Area %d : Found Intel 28F640J3. [DUAL WORD: 0x%x - 0x%x]\r\n",
dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F640J3_DW) {
dwError = 1; // Other type flash memory is already detected.
break;
}
gdwFlashCode = FLASH_28F640J3_DW;
FlashWrite = FlashWrite_IntelStrata;
FlashError = FlashError_IntelStrata;
FlashClose = FlashClose_IntelStrata;
}
}
else {
EdbgOutputDebugString("Area %d : Found unknown or unsupported Intel device.\r\n");
dwError = 2;
break;
}
}
else if (*(pdwRIC) == 0x89898989) { // Intel device in byte mode
pdwRIC++; // proceed to next DWORD
pdwRIC++; // proceed to next DWORD
// When in byte mode, Identifier Code register is allocated
// at the 2 DWORD after the vendor code.
// Read Identifier Code
FlashWriteCommand(pdwRIC, 0x90909090UL);
if (*(pdwRIC) == 0x17171717UL) {
dwFlashPageSize = 0x00000020; // 32 bytes per page
dwFlashBlockSize = 0x00080000; // 512kB per block
dwFlashBankSize = 0x02000000; // 32MB per bank
dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
if (dwCurrBank >= dwStartBank) { // when in actrually-used bank
pdwRIC--; // back to the top of current bank
pdwRIC--;
EdbgOutputDebugString("Area %d : Found Intel 28F640J3. [QUAD BYTE: 0x%x - 0x%x]\r\n",
dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F640J3_QB) {
dwError = 1; // Other type flash memory is already detected.
break;
}
gdwFlashCode = FLASH_28F640J3_QB;
FlashWrite = FlashWrite_IntelStrata;
FlashError = FlashError_IntelStrata;
FlashClose = FlashClose_IntelStrata;
}
}
else if (*(pdwRIC) == 0x18181818UL) {
dwFlashPageSize = 0x00000020; // 32 bytes per page
dwFlashBlockSize = 0x00080000; // 512kB per block
dwFlashBankSize = 0x04000000; // 64MB per bank
dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // get actual start bank
dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // get actual end bank
if (dwCurrBank >= dwStartBank) { // when in actrually-used bank
pdwRIC--; // back to the top of current bank
pdwRIC--;
EdbgOutputDebugString("Area %d : Found Intel 28F128J3. [QUAD BYTE: 0x%x - 0x%x]\r\n",
dwStartArea, pdwRIC, (DWORD)pdwRIC + dwFlashBankSize - 1);
if (gdwFlashCode != 0 && gdwFlashCode != FLASH_28F128J3_QB) {
dwError = 1; // Other type flash memory is already detected.
break;
}
gdwFlashCode = FLASH_28F128J3_QB;
FlashWrite = FlashWrite_IntelStrata;
FlashError = FlashError_IntelStrata;
FlashClose = FlashClose_IntelStrata;
}
}
else {
EdbgOutputDebugString("Area %d : Found unknown or unsupported Intel device.\r\n");
dwError = 2;
break;
}
}
else if (*(pdwRIC) == 0x90909090UL) {
// Confirm this is actually RAM space.
*(pdwRIC ) = 0x00000000; // + 0
*(pdwRIC + 1) = 0x55555555; // + 4
*(pdwRIC + 2) = 0xAAAAAAAA; // + 8
*(pdwRIC + 3) = 0xFFFFFFFF; // + 12
if (*pdwRIC == 0x00000000 && *(pdwRIC + 1) == 0x55555555
&& *(pdwRIC + 2) == 0xAAAAAAAA && *(pdwRIC + 3) == 0xFFFFFFFF) {
// calculate address span for memory check (actually RAM, not flash)
dwFlashBankSize = 0x01000000; // not actual
dwStartBank = (dwPhysStart & 0x03000000) / dwFlashBankSize; // not actual
dwEndBank = (dwPhysEnd & 0x03000000) / dwFlashBankSize; // not actual
if (dwCurrBank >= dwStartBank) { // when in actrually-used RAM
EdbgOutputDebugString("Area %d : Found RAM at 0x%x.\r\n", dwStartArea, pdwRIC);
if (gdwFlashCode != 0) { // Previous addresses are flash but current is not.
dwError = 3;
break;
}
}
}
else { // unknown device or device not exist
dwError = 2;
break;
}
}
else { // unknown device or device not exist
dwError = 2;
break;
}
dwCurrOffset += dwFlashBankSize;
dwCurrBank = dwCurrOffset / dwFlashBankSize;
}
switch (dwError) {
case 0: // normal end, without error
if (gdwFlashCode == 0) return 0; // not flash (RAM)
else return 1; // flash
case 1: // Different flash memory is found.
EdbgOutputDebugString("Error: Different types of flash memories cannot be written together.\r\n");
PrintLED("Mem Fail");
while (1); // wait forever
case 2: // Failed to detect device.
EdbgOutputDebugString("Error: Failed to detect device.\r\n");
EdbgOutputDebugString("Addr %x Data %x %x %x %x.\r\n",
pdwRIC, *pdwRIC, *(pdwRIC + 1), *(pdwRIC + 2), *(pdwRIC + 3));
PrintLED("Mem Fail");
while (1); // wait forever
case 3: // Image exceeds flash memory space.
EdbgOutputDebugString("Error: Image exceeds flash memory space.\r\n");
PrintLED("Mem Fail");
while (1);
default: // What happened ?
EdbgOutputDebugString("Error: Unexpected state.\r\n");
PrintLED("Unhandle");
while (1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -