📄 cfiamd.c
字号:
for (ix = 0; ix < thisCFI->multiplier; ix++) cmdBuffer |= AMD_READ_ARRAY << (8 * ix); flashPtr[0x55 * thisCFI->multiplier] = cmdBuffer; return flOK; }#if 0/****************************************************************************** * cfiAmdLeftoverBytesWrite - Write trailing bytes from aligned write * * This is a helper routine to cfiAmdWrite(), which writes in chunks, 1, 2, and * 4 bytes wide. The trailing bytes are written from here bye reading 4 bytes * from flash and OR-ing in the data to be written. Note that when programming * flash, a 1 can be tuned to 0 but a 0 cannot be turned to 1. */LOCAL void cfiAmdLeftoverBytesWrite ( FLFlash vol, const void FAR1 *buffer, FlashPTR flashPtr, int length ) { /* data is a 1's mask, so we only try overwriting the * bytes we desire ie. written a 1 should not change * the state of an erase bit */ int byteCount; ULONG data = 0xffffffff; /* clear out the bytes we are going to overwrite */ for(byteCount = 0; byteCount<length; byteCount++) data &= ~(0xff << (byteCount*8)); /* set the bits we dont want to clear in our data */ data |= CFI_LONGSWAP(* (ULONG *) buffer); }#endif/****************************************************************************** * cfiAmdWrite - Write a block of bytes to Flash * * This routine will be registered as the MTD vol.write routine. Given a pointer * to a buffer that must be written, the write width determined from the * identification process is used the stepping stone to interate through the buffer. * * Parameters: * vol : Pointer identifying drive * address : Card address to write to * buffer : Address of data to write * length : Number of bytes to write * overwrite : TRUE if overwriting old Flash contents * FALSE if old contents are known to be erased * * Returns: * FLStatus : 0 on success, failed otherwise */LOCAL FLStatus cfiAmdWrite ( FLFlash vol, CardAddress address, const void FAR1 *buffer, int length, FLBoolean overwrite ) { /* Set timeout to 5 seconds from now */ unsigned long writeTimeout = flMsecCounter + 5000; int cLength; CardAddress cAddr = address; FlashPTR base; FlashPTR flashPtr; UINT32 unlock1 = 0; UINT32 unlock2 = 0; UINT32 setup_write = 0; UINT32 read_array = 0; int i; CFI_DWORD tmpDWord; CFI_WORD tmpWord;#define bFlashPtr flashPtr#define bBuffer ((const unsigned char FAR1 *) buffer)#define wFlashPtr ((FlashWPTR) flashPtr)#define wBuffer ((const unsigned short FAR1 *) buffer)#define dFlashPtr ((FlashDPTR) flashPtr)#define dBuffer ((const unsigned long FAR1 *) buffer) /* Setup the commands first */ for (i = 0; i < thisCFI->multiplier; i++) { unlock1 |= AMD_UNLOCK_1 << (i * 8); unlock2 |= AMD_UNLOCK_2 << (i * 8); setup_write |= AMD_SETUP_WRITE << (i * 8); read_array |= AMD_READ_ARRAY << (i * 8); } if (flWriteProtected(vol.socket)) return flWriteProtect; i = 0; while ((thisCFI->secInfo[i].sectorBaseAdrs <= address) && (i < thisCFI->sectorsInCFI)) i++; i--; base = (FlashPTR) vol.map(&vol, thisCFI->secInfo[i].sectorBaseAdrs, vol.interleaving * thisCFI->interleaveWidth); flashPtr = (FlashPTR) vol.map(&vol, address, vol.interleaving * thisCFI->interleaveWidth); cLength = length; if (vol.interleaving * thisCFI->interleaveWidth == 1) { while (cLength >= 1) { *(UCHAR *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1; *(UCHAR *)(base + (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2; *(UCHAR *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write; *bFlashPtr = *bBuffer; while (bFlashPtr[0] != bBuffer[0] && flMsecCounter < writeTimeout) { if ((bFlashPtr[0] & AMD_D5) && bFlashPtr[0] != bBuffer[0]) { bFlashPtr[0] = read_array;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif return flWriteFault; } } cLength--; cAddr++; buffer++; bFlashPtr++; } } else if (vol.interleaving * thisCFI->interleaveWidth == 2) { while (cLength >= 2) { *(USHORT *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1; *(USHORT *)(base + (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2; *(USHORT *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write; *wFlashPtr = *wBuffer; while ((wFlashPtr[0] != wBuffer[0]) && (flMsecCounter < writeTimeout)) { if (((wFlashPtr[0] & AMD_D5) && ((wFlashPtr[0] ^ wBuffer[0]) & 0xff)) || ((wFlashPtr[0] & (AMD_D5 * 0x100)) && ((wFlashPtr[0] ^ wBuffer[0]) & 0xff00))) { wFlashPtr[0] = read_array;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif return flWriteFault; } } cLength -= 2; cAddr += 2; buffer += 2; flashPtr += 2; } if (cLength > 0) { /* copy data from flash to tmpWord */ tmpWord.ushort = wFlashPtr[0]; /* now fill in the left over byte */ tmpWord.uchar[0] = *(char *)buffer; *(USHORT *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1; *(USHORT *)(base + (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2; *(USHORT *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write; *wFlashPtr = tmpWord.ushort; while ((wFlashPtr[0] != tmpWord.ushort) && (flMsecCounter < writeTimeout)) { if (((wFlashPtr[0] & AMD_D5) && ((wFlashPtr[0] ^ tmpWord.ushort) & 0xff)) || ((wFlashPtr[0] & (AMD_D5 * 0x100)) && ((wFlashPtr[0] ^ tmpWord.ushort) & 0xff00))) { wFlashPtr[0] = read_array;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif return flWriteFault; } } cAddr += cLength; buffer += cLength; flashPtr += cLength; cLength = 0; } /* cfiAmdLeftoverBytesWrite(&vol, buffer, flashPtr, cLength); */ } else /* if (vol.interleaving >= 4) */ { while (cLength >= 4) { *(UINT32 *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1; *(UINT32 *)(base + (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2; *(UINT32 *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write; *dFlashPtr = *dBuffer; while ((dFlashPtr[0] != dBuffer[0]) && (flMsecCounter < writeTimeout)) { if (thisCFI-> interleaveWidth == 1) { /* We have 4 8 bit devices */ if (((dFlashPtr[0] & AMD_D5) && ((dFlashPtr[0] ^ dBuffer[0]) & 0xff)) || ((dFlashPtr[0] & (AMD_D5 * 0x100)) && ((dFlashPtr[0] ^ dBuffer[0]) & 0xff00)) || ((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && ((dFlashPtr[0] ^ dBuffer[0]) & 0xff0000lu)) || ((dFlashPtr[0] & (AMD_D5 * 0x1000000lu)) && ((dFlashPtr[0] ^ dBuffer[0]) & 0xff000000lu))) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif dFlashPtr[0] = read_array; return flWriteFault; } } else { /* Here we assume that the only other option is 2 16 bit devices */ if (((dFlashPtr[0] & AMD_D5) && ((dFlashPtr[0] ^ dBuffer[0]) & 0x0000ffff)) || ((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && ((dFlashPtr[0] ^ dBuffer[0]) & 0xffff0000))) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug4-1: write failed in AMD MTD.\n");#endif dFlashPtr[0] = read_array; return flWriteFault; } } } cLength -= 4; cAddr += 4; buffer += 4; flashPtr += 4; } if (cLength > 0) { tmpDWord.uint32 = 0xffffffff; /* read trailing bytes in to temp dword */ for (i = 0; i < cLength; i++) tmpDWord.uchar[i] = *((char *)buffer + i); /* fill the rest from flash */ for ( ; i < 4; i++) tmpDWord.uchar[i] = *(flashPtr + i); *(UINT32 *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1; *(UINT32 *)(base + (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2; *(UINT32 *)(base + (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write; *dFlashPtr = tmpDWord.uint32; while ((dFlashPtr[0] != tmpDWord.uint32) && (flMsecCounter < writeTimeout)) { if (thisCFI-> interleaveWidth == 1) { /* We have 4 8 bit devices */ if (((dFlashPtr[0] & AMD_D5) && ((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff)) || ((dFlashPtr[0] & (AMD_D5 * 0x100)) && ((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff00)) || ((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && ((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff0000lu)) || ((dFlashPtr[0] & (AMD_D5 * 0x1000000lu)) && ((dFlashPtr[0] ^ tmpDWord.uint32) & 0xff000000lu))) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD.\n");#endif dFlashPtr[0] = read_array; return flWriteFault; } } else { /* Here we assume that the only other option is 16 devices */ if (((dFlashPtr[0] & AMD_D5) && ((dFlashPtr[0] ^ tmpDWord.uint32) & 0x0000ffff)) || ((dFlashPtr[0] & (AMD_D5 * 0x10000lu)) && ((dFlashPtr[0] ^ tmpDWord.uint32) & 0xffff0000))) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug4-2: write failed in AMD MTD.\n");#endif dFlashPtr[0] = read_array; return flWriteFault; } } } cAddr += cLength; buffer += cLength; flashPtr += cLength; cLength = 0; } /* cfiAmdLeftoverBytesWrite(&vol, buffer, flashPtr, cLength); */ } flashPtr -= length; buffer = (unsigned char *)buffer - length; /* bBuffer -= length; */ if (tffscmp((void FAR0 *) flashPtr,buffer,length)) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD on verification.\n");#endif return flWriteFault; } return flOK; }/******************************************************************************* * cfiAmdBootBlockErase - Erase sub blocks within boot block * * Use the boot block data discovered at CFI interrogation time and erase all * subsectors in the boot block. * * Parameters: * vol : Pointer identifying drive * firstErasableBlock : Sector number of start of boot block * * Returns: * FLStatus : 0 on success, failed otherwise */LOCAL FLStatus cfiAmdBootBlockErase ( FLFlash vol, int firstErasableBlock ) { int iBlock, i; UINT32 unlock1 = 0; UINT32 unlock2 = 0; UINT32 erase_setup = 0; UINT32 erase_sector = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -