Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

527 lines
20 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/FLFLASH.C_V $
  3. *
  4. * Rev 1.12 Apr 15 2002 07:36:38 oris
  5. * Bug fix - do not initialize access routines in case of user defined routines - as a result docsys must be included.
  6. *
  7. * Rev 1.11 Jan 28 2002 21:24:38 oris
  8. * Changed memWinowSize to memWindowSize.
  9. *
  10. * Rev 1.10 Jan 17 2002 23:09:30 oris
  11. * Added flFlashOf() routine to allow the use of a single FLFlash record per socket .
  12. * Added memory access routines initialization for FLFlash.
  13. * Bug fix - if M+ device was registered after 8-bit DiskOnChip and the M+ had a bad download problem , the error would not be reported, but only flUnknown media.
  14. *
  15. * Rev 1.9 Sep 15 2001 23:46:00 oris
  16. * Changed erase routine to support up to 64K erase blocks.
  17. *
  18. * Rev 1.8 Jul 13 2001 01:04:38 oris
  19. * Added new field initialization in FLFlash record - Max Erase Cycles of the flash.
  20. *
  21. * Rev 1.7 May 16 2001 21:18:24 oris
  22. * Removed warnings.
  23. *
  24. * Rev 1.6 May 02 2001 06:41:26 oris
  25. * Removed the lastUsableBlock variable.
  26. *
  27. * Rev 1.5 Apr 24 2001 17:07:52 oris
  28. * Bug fix - missing NULL initialization for several compilation flags.
  29. * Added lastUsableBlock field defualt initialization.
  30. *
  31. * Rev 1.4 Apr 16 2001 13:39:14 oris
  32. * Bug fix read and write default routines were not initialized.
  33. * Initialize the firstUsableBlock.
  34. * Removed warrnings.
  35. *
  36. * Rev 1.3 Apr 12 2001 06:50:22 oris
  37. * Added initialization of download routine pointer.
  38. *
  39. * Rev 1.2 Apr 09 2001 15:09:04 oris
  40. * End with an empty line.
  41. *
  42. * Rev 1.1 Apr 01 2001 07:54:08 oris
  43. * copywrite notice.
  44. * Changed prototype of :flashRead.
  45. * Removed interface b initialization (experimental MTD interface for mdocp).
  46. * Spelling mistake "changableProtectedAreas".
  47. * Added check for bad download in flash recognition.
  48. *
  49. * Rev 1.0 Feb 04 2001 11:21:16 oris
  50. * Initial revision.
  51. *
  52. */
  53. /***********************************************************************************/
  54. /* M-Systems Confidential */
  55. /* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
  56. /* All Rights Reserved */
  57. /***********************************************************************************/
  58. /* NOTICE OF M-SYSTEMS OEM */
  59. /* SOFTWARE LICENSE AGREEMENT */
  60. /* */
  61. /* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
  62. /* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
  63. /* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
  64. /* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
  65. /* E-MAIL = [email protected] */
  66. /***********************************************************************************/
  67. #include "flflash.h"
  68. #include "docsys.h"
  69. #define READ_ID 0x90
  70. #define INTEL_READ_ARRAY 0xff
  71. #define AMD_READ_ARRAY 0xf0
  72. /* MTD registration information */
  73. int noOfMTDs = 0;
  74. MTDidentifyRoutine mtdTable[MTDS];
  75. static FLFlash vols[SOCKETS];
  76. FLStatus dataErrorObject;
  77. /*----------------------------------------------------------------------*/
  78. /* f l F l a s h O f */
  79. /* */
  80. /* Gets the flash connected to a volume no. */
  81. /* */
  82. /* Parameters: */
  83. /* volNo : Volume no. for which to get flash */
  84. /* */
  85. /* Returns: */
  86. /* flash of volume no. */
  87. /*----------------------------------------------------------------------*/
  88. FLFlash *flFlashOf(unsigned volNo)
  89. {
  90. return &vols[volNo];
  91. }
  92. /*----------------------------------------------------------------------*/
  93. /* f l a s h M a p */
  94. /* */
  95. /* Default flash map method: Map through socket window. */
  96. /* This method is applicable for all NOR Flash */
  97. /* */
  98. /* Parameters: */
  99. /* vol : Pointer identifying drive */
  100. /* address : Card address to map */
  101. /* length : Length to map (irrelevant here) */
  102. /* */
  103. /* Returns: */
  104. /* Pointer to required card address */
  105. /*----------------------------------------------------------------------*/
  106. static void FAR0 *flashMap(FLFlash vol, CardAddress address, int length)
  107. {
  108. return flMap(vol.socket,address);
  109. }
  110. /*----------------------------------------------------------------------*/
  111. /* f l a s h R e a d */
  112. /* */
  113. /* Default flash read method: Read by copying from mapped address */
  114. /* */
  115. /* Parameters: */
  116. /* vol : Pointer identifying drive */
  117. /* address : Card address to read */
  118. /* buffer : Area to read into */
  119. /* length : Length to read */
  120. /* */
  121. /*----------------------------------------------------------------------*/
  122. static FLStatus flashRead(FLFlash vol,
  123. CardAddress address,
  124. void FAR1 *buffer,
  125. dword length,
  126. word mode)
  127. {
  128. tffscpy(buffer,vol.map(&vol,address,(word)length),(word)length);
  129. return flOK;
  130. }
  131. /*----------------------------------------------------------------------*/
  132. /* f l a s h N o W r i t e */
  133. /* */
  134. /* Default flash write method: Write not allowed (read-only mode) */
  135. /* */
  136. /* Parameters: */
  137. /* vol : Pointer identifying drive */
  138. /* address : Card address to write */
  139. /* buffer : Area to write from */
  140. /* length : Length to write */
  141. /* */
  142. /* Returns: */
  143. /* Write-protect error */
  144. /*----------------------------------------------------------------------*/
  145. static FLStatus flashNoWrite(FLFlash vol,
  146. CardAddress address,
  147. const void FAR1 *from,
  148. dword length,
  149. word mode)
  150. {
  151. return flWriteProtect;
  152. }
  153. /*----------------------------------------------------------------------*/
  154. /* f l a s h N o E r a s e */
  155. /* */
  156. /* Default flash erase method: Erase not allowed (read-only mode) */
  157. /* */
  158. /* Parameters: */
  159. /* vol : Pointer identifying drive */
  160. /* firstBlock : No. of first erase block */
  161. /* noOfBlocks : No. of contiguous blocks to erase */
  162. /* */
  163. /* Returns: */
  164. /* Write-protect error */
  165. /*----------------------------------------------------------------------*/
  166. static FLStatus flashNoErase(FLFlash vol,
  167. word firstBlock,
  168. word noOfBlocks)
  169. {
  170. return flWriteProtect;
  171. }
  172. /*----------------------------------------------------------------------*/
  173. /* s e t N o C a l l b a c k */
  174. /* */
  175. /* Register power on callback routine. Default: no routine is */
  176. /* registered. */
  177. /* */
  178. /* Parameters: */
  179. /* vol : Pointer identifying drive */
  180. /* */
  181. /*----------------------------------------------------------------------*/
  182. static void setNoCallback(FLFlash vol)
  183. {
  184. flSetPowerOnCallback(vol.socket,NULL,NULL);
  185. }
  186. /*----------------------------------------------------------------------*/
  187. /* f l I n t e l I d e n t i f y */
  188. /* */
  189. /* Identify the Flash type and interleaving for Intel-style Flash. */
  190. /* Sets the value of vol.type (JEDEC id) & vol.interleaving. */
  191. /* */
  192. /* Parameters: */
  193. /* vol : Pointer identifying drive */
  194. /* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at */
  195. /* a specific location. If null, Intel procedure */
  196. /* is used. */
  197. /* idOffset : Chip offset to use for identification */
  198. /* */
  199. /* Returns: */
  200. /* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*/
  201. /*----------------------------------------------------------------------*/
  202. void flIntelIdentify(FLFlash vol,
  203. void (*amdCmdRoutine)(FLFlash vol, CardAddress,
  204. unsigned char, FlashPTR),
  205. CardAddress idOffset)
  206. {
  207. int inlv;
  208. unsigned char vendorId = 0;
  209. FlashPTR flashPtr = (FlashPTR) flMap(vol.socket,idOffset);
  210. unsigned char firstByte = 0;
  211. unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY;
  212. for (inlv = 0; inlv < 15; inlv++) { /* Increase interleaving until failure */
  213. flashPtr[inlv] = resetCmd; /* Reset the chip */
  214. flashPtr[inlv] = resetCmd; /* Once again for luck */
  215. if (inlv == 0)
  216. firstByte = flashPtr[0]; /* Remember byte on 1st chip */
  217. if (amdCmdRoutine) /* AMD: use unlock sequence */
  218. amdCmdRoutine(&vol,idOffset + inlv, READ_ID, flashPtr);
  219. else
  220. flashPtr[inlv] = READ_ID; /* Read chip id */
  221. if (inlv == 0)
  222. vendorId = flashPtr[0]; /* Assume first chip responded */
  223. else if (flashPtr[inlv] != vendorId || firstByte != flashPtr[0]) {
  224. /* All chips should respond in the same way. We know interleaving = n */
  225. /* when writing to chip n affects chip 0. */
  226. /* Get full JEDEC id signature */
  227. vol.type = (FlashType) ((vendorId << 8) | flashPtr[inlv]);
  228. flashPtr[inlv] = resetCmd;
  229. break;
  230. }
  231. flashPtr[inlv] = resetCmd;
  232. }
  233. if (inlv & (inlv - 1))
  234. vol.type = NOT_FLASH; /* not a power of 2, no way ! */
  235. else
  236. #ifndef NT5PORT
  237. vol.interleaving = inlv;
  238. #else
  239. vol.interleaving = (Sword)inlv;
  240. #endif /*NT5PORT*/
  241. }
  242. /*----------------------------------------------------------------------*/
  243. /* i n t e l S i z e */
  244. /* */
  245. /* Identify the card size for Intel-style Flash. */
  246. /* Sets the value of vol.noOfChips. */
  247. /* */
  248. /* Parameters: */
  249. /* vol : Pointer identifying drive */
  250. /* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at */
  251. /* a specific location. If null, Intel procedure */
  252. /* is used. */
  253. /* idOffset : Chip offset to use for identification */
  254. /* */
  255. /* Returns: */
  256. /* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*/
  257. /*----------------------------------------------------------------------*/
  258. FLStatus flIntelSize(FLFlash vol,
  259. void (*amdCmdRoutine)(FLFlash vol, CardAddress,
  260. unsigned char, FlashPTR),
  261. CardAddress idOffset)
  262. {
  263. unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY;
  264. FlashPTR flashPtr = (FlashPTR) vol.map(&vol,idOffset,0);
  265. if (amdCmdRoutine) /* AMD: use unlock sequence */
  266. amdCmdRoutine(&vol,0,READ_ID, flashPtr);
  267. else
  268. flashPtr[0] = READ_ID;
  269. /* We leave the first chip in Read ID mode, so that we can */
  270. /* discover an address wraparound. */
  271. for (vol.noOfChips = 0; /* Scan the chips */
  272. vol.noOfChips < 2000; /* Big enough ? */
  273. vol.noOfChips += vol.interleaving) {
  274. int i;
  275. flashPtr = (FlashPTR) vol.map(&vol,vol.noOfChips * vol.chipSize + idOffset,0);
  276. /* Check for address wraparound to the first chip */
  277. if (vol.noOfChips > 0 &&
  278. (FlashType) ((flashPtr[0] << 8) | flashPtr[vol.interleaving]) == vol.type)
  279. goto noMoreChips; /* wraparound */
  280. /* Check if chip displays the same JEDEC id and interleaving */
  281. for (i = (vol.noOfChips ? 0 : 1); i < vol.interleaving; i++) {
  282. if (amdCmdRoutine) /* AMD: use unlock sequence */
  283. amdCmdRoutine(&vol,vol.noOfChips * vol.chipSize + idOffset + i,
  284. READ_ID, flashPtr);
  285. else
  286. flashPtr[i] = READ_ID;
  287. if ((FlashType) ((flashPtr[i] << 8) | flashPtr[i + vol.interleaving]) !=
  288. vol.type)
  289. goto noMoreChips; /* This "chip" doesn't respond correctly, so we're done */
  290. flashPtr[i] = resetCmd;
  291. }
  292. }
  293. noMoreChips:
  294. flashPtr = (FlashPTR) vol.map(&vol,idOffset,0);
  295. flashPtr[0] = resetCmd; /* reset the original chip */
  296. return (vol.noOfChips == 0) ? flUnknownMedia : flOK;
  297. }
  298. /*----------------------------------------------------------------------*/
  299. /* i s R A M */
  300. /* */
  301. /* Checks if the card memory behaves like RAM */
  302. /* */
  303. /* Parameters: */
  304. /* vol : Pointer identifying drive */
  305. /* */
  306. /* Returns: */
  307. /* 0 = not RAM-like, other = memory is apparently RAM */
  308. /*----------------------------------------------------------------------*/
  309. static FLBoolean isRAM(FLFlash vol)
  310. {
  311. #ifndef NT5PORT
  312. FlashPTR flashPtr = (FlashPTR) flMap(vol.socket,0);
  313. unsigned char firstByte = flashPtr[0];
  314. char writeChar = (firstByte != 0) ? 0 : 0xff;
  315. volatile int zero=0;
  316. #else
  317. FlashPTR flashPtr = (FlashPTR) flMap(vol.socket,0);
  318. unsigned char firstByte;
  319. char writeChar;
  320. volatile int zero=0;
  321. if(flashPtr == NULL){
  322. DEBUG_PRINT(("Debug:isRAM(): NULL Pointer.\n"));
  323. }
  324. firstByte = flashPtr[0];
  325. writeChar = (firstByte != 0) ? 0 : 0xff;
  326. #endif //NT5PORT
  327. flashPtr[zero] = writeChar; /* Write something different */
  328. if (flashPtr[zero] == writeChar) { /* Was it written ? */
  329. flashPtr[zero] = firstByte; /* must be RAM, undo the damage */
  330. DEBUG_PRINT(("Debug: error, socket window looks like RAM.\r\n"));
  331. return TRUE;
  332. }
  333. return FALSE;
  334. }
  335. /*----------------------------------------------------------------------*/
  336. /* f l I d e n t i f y F l a s h */
  337. /* */
  338. /* Identify the current Flash medium and select an MTD for it */
  339. /* */
  340. /* Parameters: */
  341. /* socket : Socket of flash */
  342. /* vol : New volume pointer */
  343. /* */
  344. /* Returns: */
  345. /* FLStatus : 0 = Flash was identified */
  346. /* other = identification failed */
  347. /*----------------------------------------------------------------------*/
  348. FLStatus flIdentifyFlash(FLSocket *socket, FLFlash vol)
  349. {
  350. FLStatus status = flUnknownMedia;
  351. int iMTD;
  352. dword blockSize;
  353. vol.socket = socket;
  354. #ifndef FIXED_MEDIA
  355. /* Check that we have a media */
  356. flResetCardChanged(vol.socket); /* we're mounting anyway */
  357. checkStatus(flMediaCheck(vol.socket));
  358. #endif
  359. #ifdef ENVIRONMENT_VARS
  360. if(flUseisRAM==1)
  361. {
  362. #endif
  363. if ( isRAM(&vol))
  364. return flUnknownMedia; /* if it looks like RAM, leave immediately */
  365. #ifdef ENVIRONMENT_VARS
  366. }
  367. #endif
  368. /* Install default methods */
  369. vol.type = NOT_FLASH;
  370. vol.mediaType = NOT_DOC_TYPE;
  371. vol.pageSize = 0;
  372. vol.flags = 0;
  373. vol.map = flashMap;
  374. vol.read = flashRead;
  375. vol.setPowerOnCallback = setNoCallback;
  376. vol.erase = flashNoErase;
  377. vol.write = flashNoWrite;
  378. vol.readBBT = NULL;
  379. vol.writeIPL = NULL;
  380. vol.readIPL = NULL;
  381. #ifdef HW_OTP
  382. vol.otpSize = NULL;
  383. vol.readOTP = NULL;
  384. vol.writeOTP = NULL;
  385. vol.getUniqueId = NULL;
  386. #endif /* HW_OTP */
  387. #ifdef HW_PROTECTION
  388. vol.protectionBoundries = NULL;
  389. vol.protectionKeyInsert = NULL;
  390. vol.protectionKeyRemove = NULL;
  391. vol.protectionType = NULL;
  392. vol.protectionSet = NULL;
  393. #endif /* HW_PROTECTION */
  394. vol.download = NULL;
  395. vol.enterDeepPowerDownMode = NULL;
  396. #ifndef FL_NO_USE_FUNC
  397. if(flBusConfig[flSocketNoOf(socket)] != FL_ACCESS_USER_DEFINED);
  398. {
  399. vol.memRead = NULL;
  400. vol.memWrite = NULL;
  401. vol.memSet = NULL;
  402. vol.memRead8bit = NULL;
  403. vol.memWrite8bit = NULL;
  404. vol.memRead16bit = NULL;
  405. vol.memWrite16bit = NULL;
  406. vol.memWindowSize = NULL;
  407. }
  408. #endif /* FL_NO_USE_FUNC */
  409. /* Setup arbitrary parameters for read-only mount */
  410. vol.chipSize = 0x100000L;
  411. vol.erasableBlockSize = 0x1000L;
  412. vol.noOfChips = 1;
  413. vol.interleaving = 1;
  414. vol.noOfFloors = 1;
  415. vol.totalProtectedAreas = 0;
  416. vol.changeableProtectedAreas = 0;
  417. vol.ppp = 5;
  418. vol.firstUsableBlock = 0;
  419. vol.maxEraseCycles = 100000L; /* Defaul for NOR */
  420. #ifdef NT5PORT
  421. vol.readBufferSize = 0;
  422. vol.readBuffer = NULL;
  423. #endif /*NT5PORT*/
  424. /* Attempt all MTD's */
  425. for (iMTD = 0; (iMTD < noOfMTDs) && (status != flOK) &&
  426. (status != flBadDownload); iMTD++)
  427. status = mtdTable[iMTD](&vol);
  428. if (status == flBadDownload)
  429. {
  430. DEBUG_PRINT(("Debug: Flash media reported bad download error.\r\n"));
  431. return flBadDownload;
  432. }
  433. if (status != flOK) /* No MTD recognition */
  434. {
  435. DEBUG_PRINT(("Debug: did not identify flash media.\r\n"));
  436. return flUnknownMedia;
  437. }
  438. /* Calculate erasable Block Size Bits */
  439. for(blockSize = vol.erasableBlockSize>>1,vol.erasableBlockSizeBits = 0;
  440. blockSize>0; vol.erasableBlockSizeBits++,blockSize = blockSize >> 1);
  441. return flOK;
  442. }
  443. #ifdef NT5PORT
  444. VOID * mapThroughBuffer(FLFlash vol, CardAddress address, LONG length)
  445. {
  446. if ((ULONG) length > vol.readBufferSize) {
  447. vol.readBufferSize = 0;
  448. if (vol.readBuffer) {
  449. FREE(vol.readBuffer);
  450. }
  451. vol.readBuffer = MALLOC(length);
  452. if (vol.readBuffer == NULL) {
  453. return vol.readBuffer;
  454. }
  455. vol.readBufferSize = length;
  456. }
  457. vol.read(&vol,address,vol.readBuffer,length,0);
  458. return vol.readBuffer;
  459. }
  460. #endif /* NT5PORT */