LOCAL FLStatus v28F128J3Write ( FLFlash vol, CardAddress address, const void FAR1 *buffer, int length, int overwrite ) { UINT8 *unaligned; UINT8 *buf = (UINT8 *)buffer; UINT32 left = length; UINT32 *aligned; UINT32 data, num; int i; if (flWriteProtected(vol.socket)) return flWriteProtect; /* calculate the program addr, make sure it's 32-bit aligned */ unaligned = (UINT8 *)vol.map (&vol, address, 0); num = (UINT32)unaligned & 0x3; aligned = (UINT32 *)((UINT32)unaligned - num); if (num != 0) { data = *aligned; for (i = num ; i < 4; i++) { data &= ~(0xFF << ((3 - i) * 8)); data |= ((*(buf + i - num)) << ((3 - i) * 8)); } if (v28F128J3Program(aligned, data) != flOK) return flWriteFault; buf += (4 - num); left -= (4 - num); aligned++; } while (left >= 4) { data = *(UINT32 *)buf; if (v28F128J3Program (aligned, data) != flOK) return flWriteFault; buf += 4; left -= 4; aligned++; } if (left > 0) { data = *aligned; for (i = 0 ; i < left; i++) { data &= ~(0xFF << ((3 - i) * 8)); data |= ((*(buf + i)) << ((3 - i) * 8)); } if (v28F128J3Program (aligned, data) != flOK) return flWriteFault; } if (tffscmp((void FAR0 *)unaligned, buffer, length)) { #ifdef DEBUG_PRINT DEBUG_PRINT("[v28F128J3Write]: data double check error @ 0x%08x ...\n", unaligned); #endif return flWriteFault; } return flOK; }
FLStatus check43Format(FLFlash *flash) { FLStatus status; byte FAR1* buf; /* If this is an alon */ if (flash->mediaType != DOC2000TSOP_TYPE) return flOK; buf = (flBufferOf(flSocketNoOf(flash->socket))->flData); if(flash->readBBT == NULL) { DFORMAT_PRINT(("ERROR : MTD read BBT routine was not initialized\r\n")); return flFeatureNotSupported; } status = flash->readBBT(flash,0,1,0,buf,FALSE); if (status == flBadBBT) { dword mediaSize = ((dword)flash->noOfChips*flash->chipSize); dword blockSize = 1<<flash->erasableBlockSizeBits; dword addr = 0; dword offset; word mediaHeaderBlock; /* ANAND unit number */ byte blocksPerUnit; /* Blocks per virtual unit */ byte blockShift; /* Bits to shift from block to unit */ CHECK_UNIT_WITH_ANAND: /* Either virgin or formated wih TrueFFS 4.3 */ for( ; addr < mediaSize ; addr += blockSize) { checkStatus(flash->read(flash,addr,buf,5,0)); if(tffscmp(buf,"ANAND",5) == 0) break; } if (addr == mediaSize) /* virgin card */ return flOK; DFORMAT_PRINT(("This DiskOnChip was formated with an NFTL format.\r\n")); /* Calculate block multiplier bits */ for (offset = addr + SECTOR_SIZE , status = flOK; (offset < addr + blockSize) && (status == flOK) ; offset += SECTOR_SIZE) { status = flash->read(flash,addr+offset,buf,512,EDC); } if(offset == addr + (SECTOR_SIZE<<1)) /* Bad EDC for NFTL unit header */ { DFORMAT_PRINT(("ERROR - Unit with ANAND was found, but the BBT has bad EDC.\r\n")); addr += blockSize; goto CHECK_UNIT_WITH_ANAND; /* Keep searching */ } offset = (offset - addr - (SECTOR_SIZE<<1)) << flash->erasableBlockSizeBits; for(blockShift = 0 ; offset < mediaSize ; blockShift++) { offset <<= 1; } blocksPerUnit = 1 << blockShift; mediaHeaderBlock = (word)(addr >> (flash->erasableBlockSizeBits + blockShift)); DFORMAT_PRINT(("Please wait while unformating is in progress...\r\n")); /* Read and write 512 blocks of the BBT (start from the end) */ for (offset = 0; offset < mediaSize>>(flash->erasableBlockSizeBits + blockShift); offset += SECTOR_SIZE) { word i; checkStatus(flash->read(flash,addr+offset+SECTOR_SIZE,buf,SECTOR_SIZE,EDC)); for(i=0;i<SECTOR_SIZE;i++) { if (i+offset == mediaHeaderBlock) continue; if (buf[i]==BBT_BAD_UNIT) /* A bad block */ { markUnitBad(flash , i+offset); } else /* A good block */ { status = flash->erase(flash,(word)(i+offset),blocksPerUnit); if (status != flOK) markUnitBad(flash , i+offset); } } } status = flash->erase(flash,mediaHeaderBlock,blocksPerUnit); if (status != flOK) markUnitBad(flash , mediaHeaderBlock); DFORMAT_PRINT(("Unformating of DiskOnChip 2000 tsop complete.\r\n")); }
FLStatus getExbInfo(Volume vol, void FAR1 * buf, dword bufLen, word exbFlags) { byte i; byte mediaType; ExbGlobalHeader FAR1* globalHeader = (ExbGlobalHeader FAR1*)buf; FirmwareHeader FAR1* firmwareHeader = (FirmwareHeader FAR1*) flAddLongToFarPointer(buf,sizeof(ExbGlobalHeader)); /* Make sure size given is big enough */ if (bufLen < sizeof(FirmwareHeader) * LE4(globalHeader->noOfFirmwares) + sizeof(ExbGlobalHeader)) { DFORMAT_PRINT(("ERROR - Buffer size not big enough.\r\n")); return flBadLength; } /* Make sure this is an M-systems EXB file */ if (tffscmp(globalHeader->mSysSign,SIGN_MSYS,SIGN_MSYS_SIZE) != 0) { DFORMAT_PRINT(("ERROR - Given file is not M-systems EXB file.\r\n")); return flBadParameter; } i = (exbFlags & FIRMWARE_NO_MASK) >> FIRMWARE_NO_SHIFT; if(i == 0) { /* Make sure this is the correct version of TrueFFS */ if (tffscmp(globalHeader->osakVer,TrueFFSVersion,SIGN_MSYS_SIZE) != 0) { DFORMAT_PRINT(("ERROR - Incorrect TrueFFS EXB file version.\r\n")); return flBadParameter; } /* Find the corrent firmware in the file */ /* Automatic firmware detection - by DiskOnChip type */ switch (vol.flash->mediaType) { case DOC_TYPE: case MDOC_TYPE: mediaType = DOC2000_FAMILY_FIRMWARE; break; case MDOCP_TYPE: case MDOCP_16_TYPE: mediaType = DOCPLUS_FAMILY_FIRMWARE; break; case DOC2000TSOP_TYPE: mediaType = DOC2300_FAMILY_FIRMWARE; break; default: DFORMAT_PRINT(("Unknown H/W - Try specifing the firmware manualy.\r\n")); return flFeatureNotSupported; } for (i=0;i<LE4(globalHeader->noOfFirmwares);i++,firmwareHeader++) { if (LE4(firmwareHeader->type) == mediaType) break; } } else /* Use given firmware */ { i--; /* 0 was used for automatic choose of firmware */ } if (i >= LE4(globalHeader->noOfFirmwares)) { DFORMAT_PRINT(("ERROR - The EXB file does not support the required firmware.\r\n")); return flBadParameter; } /* Initialize the volumes EXB fields */ firmwareHeader = (FirmwareHeader FAR1*)flAddLongToFarPointer(buf, (sizeof(ExbGlobalHeader) + (i * sizeof(FirmwareHeader)))); i = &vol - vols; /* Save firmware files statstics recieved from the files header */ exbs[i].firmwareStart = LE4(firmwareHeader->startOffset); exbs[i].firmwareEnd = LE4(firmwareHeader->endOffset); exbs[i].splStart = LE4(firmwareHeader->splStartOffset); exbs[i].splEnd = LE4(firmwareHeader->splEndOffset); exbs[i].exbFileEnd = LE4(globalHeader->fileSize); /* Calculate the binary partition size (good bytes) used to hold the EXB file. */ exbs[i].iplMod512 = (word)((exbs[i].splStart - exbs[i].firmwareStart) >> SECTOR_SIZE_BITS); switch (vol.flash->mediaType) { /* NFTL formated device - IPL is placed on the binary partition */ case DOC_TYPE: /* Size of EXB minus IPL which is placed in ROM */ vol.binaryLength = exbs[i].firmwareEnd - exbs[i].splStart + 0x4000; break; case MDOC_TYPE: /* Millennium 8, write data as is */ /* Size of entire EXB */ vol.binaryLength = exbs[i].firmwareEnd - exbs[i].firmwareStart; break; /* INFTL formated device - IPL is not placed on the binary partition, but on a dedicated flash area */ case DOC2000TSOP_TYPE: /* DOC2000 TSOP */ case MDOCP_TYPE: /* MDOC PLUS 32MB */ case MDOCP_16_TYPE: /* MDOC PLUS 16MB */ vol.binaryLength = exbs[i].firmwareEnd - exbs[i].splStart; break; default : DFORMAT_PRINT(("ERROR - Firmware formater reports A None DiskOnChip media.\r\n")); return flBadParameter; } return flOK; }
LOCAL FLStatus cfiAmdWrite ( FLFlash vol, /* Pointer identifying drive */ CardAddress address, /* Card address to write to */ const void FAR1 *buffer, /* Address of data to write */ int length, /* Number of bytes to write */ FLBoolean overwrite /* Mode: TRUE overwrite;FALSE erased */ ) { /* 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_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 >= 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] = read_array; #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD.\n"); #endif return flWriteFault; } } cLength -= 2; cAddr += 2; buffer = (const void FAR1 *)((UINT32)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] = read_array; #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: write failed in AMD MTD.\n"); #endif return flWriteFault; } } cAddr += cLength; buffer = (const void FAR1 *)((UINT32)buffer + cLength); flashPtr = 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; }