cfi.c
上传用户:fy98168
上传日期:2015-06-26
资源大小:13771k
文件大小:58k
源码类别:

DVD

开发平台:

C/C++

  1. #include "gendef.h"
  2. #include "cfi.h"
  3. #include "osp.h"
  4. #ifndef SUCCESS
  5. #define SUCCESS RETOK
  6. #endif
  7. #ifndef FAILURE
  8. #define FAILURE RETFIAL1
  9. #endif
  10. #define WORDREG volatile UINT16 * 
  11. #define BYTEREG volatile UINT8 * 
  12. #define CFI_COMMAND_PREAMBLE_1  (0x5555)
  13. #define CFI_COMMAND_PREAMBLE_2  (0x2AAA)
  14. #define CFI_COMMAND_TYPE        (0x5555)
  15. #define CFI_COMMAND_PREAMBLE_1_DATA  (0xAA)
  16. #define CFI_COMMAND_PREAMBLE_2_DATA  (0x55)
  17. #define CFI_IDENTIFIER_CODES_ADDRESS  (0x5555)
  18. #define CFI_IDENTIFIER_CODES_COMMAND  (0x90)
  19. #define CFI_MANUF_ID            (0x0)
  20. #define CFI_DEVICE_ID           (0x1)
  21. #define CFI_SECTOR_PROTECT      (0x2)
  22. #define CFI_QUERY_ADDRESS  (0x55)
  23. #define CFI_QUERY_COMMAND  (0x98)
  24. #define CFI_QUERY_Q                     (0x10)
  25. #define CFI_QUERY_R                     (0x11)
  26. #define CFI_QUERY_Y                     (0x12)
  27. #define CFI_VENDOR_COMMAND_SET          (0x13)
  28. #define CFI_EXT_QUERY_TABLE_ADDRESS     (0x15)
  29. #define CFI_ALT_VENDOR_COMMAND_SET      (0x17)
  30. #define CFI_ALT_EXT_QUERY_TABLE_ADDRESS (0x19)
  31. #define CFI_2N_DEVICE_SIZE          (0x27)
  32. #define CFI_INTERFACE_CODE          (0x28)
  33. #define CFI_2N_MAX_BUFFER_BYTES     (0x2A)
  34. #define CFI_NUM_ERASE_BLOCK_REGIONS (0x2C)
  35. #define CFI_ERASE_BLOCK_REGION_INFO (0x2D)
  36. #define CFI_NUM_BLOCKS_IN_REGION_LO (0x0)
  37. #define CFI_NUM_BLOCKS_IN_REGION_HI (0x1)
  38. #define CFI_256X_BLOCK_SIZE_LO    (0x2)
  39. #define CFI_256X_BLOCK_SIZE_HI    (0x3)
  40. #define CFI_BOOT_SECTOR_FLAG        (0x4F)
  41. #define CFI_BOTTOM_BOOT             (0x02)
  42. #define CFI_TOP_BOOT                (0x03)
  43. #define CFI_NO_COMMAND_SET             (0)
  44. #define CFI_INTEL_EXTENDED_COMMAND_SET (1)
  45. #define CFI_AMD_STANDARD_COMMAND_SET   (2)
  46. #define CFI_INTEL_STANDARD_COMMAND_SET (3)
  47. #define CFI_AMD_EXTENDED_COMMAND_SET   (4)
  48. #define CFI_SST_COMMAND_SET            (0x0701)
  49. #define CFI_INTEL_ERASE_COMMAND_SETUP   (0x20)
  50. #define CFI_INTEL_ERASE_COMMAND_CONFIRM (0xD0)
  51. #define CFI_INTEL_STATUS_BUSY           (0x80)
  52. #define CFI_INTEL_RESET_TO_READ         (0xFF)
  53. #define CFI_INTEL_READ_STATUS           (0x70)
  54. #define CFI_INTEL_CLEAR_STATUS          (0x50)
  55. #define CFI_INTEL_COMMAND_ERROR         (0x30)
  56. #define CFI_INTEL_WRITE_WORD            (0x40)
  57. #define CFI_INTEL_WRITE_BUFFER_SETUP    (0xE8)
  58. #define CFI_INTEL_WRITE_CONFIRM         (0xD0)
  59. #define CFI_INTEL_READ_IDENTIFIER_CODES (0x90)
  60. #define CFI_AMD_COMMAND_PROGRAM       (0xA0)
  61. #define CFI_AMD_COMMAND_UNLOCK_BYPASS (0x20)
  62. #define CFI_AMD_COMMAND_ERASE         (0x80)
  63. #define CFI_AMD_UNLOCK_BYPASS_RESET_1 (0x90)
  64. #define CFI_AMD_UNLOCK_BYPASS_RESET_2 (0x00)
  65. #define CFI_AMD_ERASE_COMMAND_CHIP    (0x10)
  66. #define CFI_AMD_ERASE_COMMAND_SECTOR  (0x30)
  67. #define CFI_AMD_DQ7_BIT_MASK          (0x80)
  68. #define CFI_AMD_TOGGLE_BIT_MASK       (0x40)
  69. #define CFI_AMD_TIMEOUT_BIT_MASK      (0x20)
  70. INT32 CFIAMDBusy(T_CFIRomDevice *this);
  71. INT32 CFIAMDEraseChip(T_CFIRomDevice *this, UINT32 blocking);
  72. INT32 CFIAMDEraseSector(T_CFIRomDevice *this, UINT16 *targetAddress,
  73.                         UINT32 blocking);
  74. INT32 CFIAMDExtendedProgram(T_CFIRomDevice *this, UINT16 *targetAddress,
  75.                             UINT8 *sourceData, UINT32 numBytes);
  76. INT32 CFIAMDExtendedProgram(T_CFIRomDevice *this, UINT16 *targetAddress,
  77.                             UINT8 *sourceData, UINT32 numBytes);
  78. void  CFIAMDIDCodesEntry(T_CFIRomDevice *this);
  79. INT32 CFIAMDProgram(T_CFIRomDevice *this, UINT16 *targetAddress,
  80.                     UINT8 *sourceData, UINT32 numBytes);
  81. void  CFIAMDReset(T_CFIRomDevice *this);
  82. INT32 CFIIntelBusy(T_CFIRomDevice *this);
  83. INT32 CFIIntelEraseSector(T_CFIRomDevice *this, UINT16 *targetAddress,
  84.                           UINT32 block);
  85. INT32 CFIIntelExtendedProgram(T_CFIRomDevice *this, UINT16 *targetAddress,
  86.                               UINT8 *sourceData, UINT32 numBytes);
  87. void  CFIIntelIDCodesEntry(T_CFIRomDevice *this);
  88. INT32 CFIIntelProgram(T_CFIRomDevice *this, UINT16 *targetAddress,
  89.                       UINT8 *sourceData, UINT32 numBytes);
  90. void  CFIIntelReset(T_CFIRomDevice *this);
  91. UINT16 CFISetEndian(UINT16 value);
  92. static UINT32 EXCStartCriticalSection(void)
  93. {
  94. KB_OSPTaskDelay(1);
  95. return 0;
  96. }
  97. static void EXCEndCriticalSection(UINT32 State)
  98. {
  99. State = State;
  100. KB_OSPTaskDelay(1);
  101. }
  102. /****************************************************************************
  103. ** Functions
  104. ****************************************************************************/
  105. INT32 CFIIdentify(UINT16 *intRomAddress, T_CFIRomDevice *romDevice)
  106. {
  107. UINT32 numEraseBlockRegions;
  108. UINT32 index;
  109. UINT32 whichSector, numSectors, sectorSize;
  110. UINT32 sectorBaseAddress;
  111. UINT32 boolInvertGeometry;
  112. UINT32 bootSectorFlag;
  113. UINT32 irqState;
  114. irqState = EXCStartCriticalSection();
  115. /*
  116. ** Issue CFI Query command by writing 0x98 to address 0x55
  117. */
  118. ((WORDREG)intRomAddress)[CFI_QUERY_ADDRESS] = CFI_QUERY_COMMAND;
  119. if (((((WORDREG)intRomAddress)[CFI_QUERY_Q] & 0xFF) != 'Q') ||
  120. ((((WORDREG)intRomAddress)[CFI_QUERY_R] & 0xFF) != 'R') ||
  121. ((((WORDREG)intRomAddress)[CFI_QUERY_Y] & 0xFF) != 'Y'))
  122. {
  123. /*
  124. ** This doesn't appear to be a CFI ROM. However, there is a
  125. ** chance that we have an SST device. SST devices implement the CFI
  126. ** standard in a proprietary way. Test for this first before
  127. ** we give up.
  128. */
  129. ((WORDREG)intRomAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  130. ((WORDREG)intRomAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  131. ((WORDREG)intRomAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_QUERY_COMMAND;
  132. if (((((WORDREG)intRomAddress)[CFI_QUERY_Q] & 0xFF) != 'Q') ||
  133. ((((WORDREG)intRomAddress)[CFI_QUERY_R] & 0xFF) != 'R') ||
  134. ((((WORDREG)intRomAddress)[CFI_QUERY_Y] & 0xFF) != 'Y'))
  135. {    
  136. /*
  137. ** Not a CFI ROM, so return.
  138. */
  139. romDevice->baseAddress = 0;
  140. EXCEndCriticalSection(irqState);
  141. return FAILURE;
  142. }
  143. }
  144. /*
  145. ** Read the rom size.
  146. */  
  147. romDevice->romSize = (1 << ((WORDREG)intRomAddress)[CFI_2N_DEVICE_SIZE]);
  148. /*
  149. ** The rom base address mask will be the same as the
  150. ** inversion of the rom size -1. E.g. A 64 MBit rom
  151. ** will have a rom size of 0x800000, this makes the
  152. ** base address mask 0xFF800000.
  153. */
  154. romDevice->romBaseMask = ~(romDevice->romSize - 1);
  155. /*
  156. ** We should already have the ROM base address, but calculate
  157. ** it anyway.
  158. */
  159. romDevice->baseAddress = ((UINT32)intRomAddress & romDevice->romBaseMask);
  160. /*  
  161. ** Find the supported command set.
  162. */
  163. romDevice->commandSet = (0xFF & ((WORDREG)romDevice->baseAddress)[CFI_VENDOR_COMMAND_SET]);
  164. romDevice->commandSet |= (0xFF & ((WORDREG)romDevice->baseAddress)[CFI_VENDOR_COMMAND_SET+1]) << 8;
  165. /*
  166. ** Read the number of erase block regions.
  167. */
  168. numEraseBlockRegions = ((WORDREG)(romDevice->baseAddress))[CFI_NUM_ERASE_BLOCK_REGIONS];
  169. /*
  170. ** For each erase block region read the details on the sectors (blocks)
  171. ** contained in it and expand to fill the romDevice structure.
  172. */
  173. whichSector = 0;
  174. for(index=0; index < numEraseBlockRegions; index++)
  175. {
  176. numSectors = (0xFF & ((WORDREG)(romDevice->baseAddress))[CFI_ERASE_BLOCK_REGION_INFO + (4 * index) + CFI_NUM_BLOCKS_IN_REGION_LO]);
  177. numSectors |= (0xFF & ((WORDREG)(romDevice->baseAddress))[CFI_ERASE_BLOCK_REGION_INFO + (4 * index) + CFI_NUM_BLOCKS_IN_REGION_HI]) << 8;
  178. numSectors++;
  179. sectorSize = (0xFF & ((WORDREG)(romDevice->baseAddress))[CFI_ERASE_BLOCK_REGION_INFO + (4 * index) + CFI_256X_BLOCK_SIZE_LO]);
  180. sectorSize |= (0xFF & ((WORDREG)(romDevice->baseAddress))[CFI_ERASE_BLOCK_REGION_INFO + (4 * index) + CFI_256X_BLOCK_SIZE_HI]) << 8;
  181. sectorSize *= 256;
  182. do
  183. {
  184. romDevice->sectorSize[whichSector++] = sectorSize;
  185. numSectors--;
  186. }
  187. while(numSectors > 0 );
  188. }
  189. romDevice->numSectors = whichSector;  
  190. /*
  191. ** AMD and Fujitsu always list the device geometry for bottom boot devices.
  192. ** This then has to be inverted for top boot devices. Knowing if a device
  193. ** is top boot is an issue. For some devices you can read a CFI register,
  194. ** for others it has to be determined based on the device ID.
  195. */
  196. bootSectorFlag = ((WORDREG)(romDevice->baseAddress))[CFI_BOOT_SECTOR_FLAG];
  197. boolInvertGeometry = (bootSectorFlag == CFI_TOP_BOOT);
  198. /*
  199. ** Read max write buffer size.
  200. */
  201. romDevice->writeBufferDepth = (1 << ((WORDREG)(romDevice->baseAddress))[CFI_2N_MAX_BUFFER_BYTES]);
  202. /*
  203. ** Determine the programming algorithms to use and write the
  204. ** relevant function pointers to the romDevice structure.
  205. */  
  206. switch (romDevice->commandSet)
  207. {
  208.     case CFI_INTEL_EXTENDED_COMMAND_SET:
  209. romDevice->Busy = CFIIntelBusy;
  210. romDevice->Reset = CFIIntelReset;
  211. romDevice->IDCodesEntry = CFIIntelIDCodesEntry;
  212. romDevice->Program = CFIIntelExtendedProgram;
  213. romDevice->EraseSector = CFIIntelEraseSector;
  214. break;
  215.     case CFI_INTEL_STANDARD_COMMAND_SET:
  216. romDevice->Busy = CFIIntelBusy;
  217. romDevice->Reset = CFIIntelReset;
  218. romDevice->IDCodesEntry = CFIIntelIDCodesEntry;
  219. romDevice->Program = CFIIntelProgram;
  220. romDevice->EraseSector = CFIIntelEraseSector;
  221. break;
  222.     case CFI_AMD_STANDARD_COMMAND_SET:
  223. romDevice->Busy = CFIAMDBusy;
  224. romDevice->Reset = CFIAMDReset;
  225. romDevice->IDCodesEntry = CFIAMDIDCodesEntry;
  226. romDevice->Program = CFIAMDProgram;
  227. romDevice->EraseSector = CFIAMDEraseSector;
  228. break;
  229.     case CFI_AMD_EXTENDED_COMMAND_SET:
  230.     case CFI_SST_COMMAND_SET:
  231. romDevice->Busy = CFIAMDBusy;
  232. romDevice->Reset = CFIAMDReset;
  233. romDevice->IDCodesEntry = CFIAMDIDCodesEntry;
  234. romDevice->Program = CFIAMDExtendedProgram;
  235. romDevice->EraseSector = CFIAMDEraseSector;
  236. break;
  237.     default:
  238. /*      {
  239. UINT8 string[9];
  240. SUIPutMessage("nbaseAddress: 0x");
  241. APPIntToHexString(romDevice->baseAddress, string);
  242. SUIPutMessage(string);
  243. SUIPutMessage("tromSize: 0x");
  244. APPIntToHexString(romDevice->romSize, string);
  245. SUIPutMessage(string);
  246. SUIPutMessage("ncommandSet: 0x");
  247. APPIntToHexString(romDevice->commandSet, string);
  248. SUIPutMessage(string);
  249. SUIPutMessage("nnumSectors: 0x");
  250. APPIntToHexString(romDevice->numSectors, string);
  251. SUIPutMessage(string);
  252. SUIPutMessage("n0x13: 0x");
  253. APPIntToHexString(((WORDREG)romDevice->baseAddress)[CFI_VENDOR_COMMAND_SET], string);
  254. SUIPutMessage(string);
  255. SUIPutMessage("t0x14: 0x");
  256. APPIntToHexString(((WORDREG)romDevice->baseAddress)[CFI_VENDOR_COMMAND_SET + 1], string);
  257. SUIPutMessage(string);
  258. } */
  259. /*
  260. ** Put the ROM back into read array mode and return.
  261. */
  262. CFIAMDReset(romDevice);
  263. CFIIntelReset(romDevice);
  264. EXCEndCriticalSection(irqState);
  265. return(FAILURE);
  266. }
  267. /*
  268. ** Issue the read identifier codes command.
  269. */
  270. romDevice->Reset(romDevice);
  271. romDevice->IDCodesEntry(romDevice);
  272.     
  273. /*
  274. ** Read the manufacturer and device id.
  275. */
  276. romDevice->manufacturerID = ((WORDREG)(romDevice->baseAddress))[CFI_MANUF_ID];
  277. romDevice->deviceID = ((WORDREG)(romDevice->baseAddress))[CFI_DEVICE_ID];
  278. /*
  279. ** Set the name parameter of the ROM.
  280. **
  281. ** We also use this point to catch the special case for AMD top boot
  282. ** ROMs where the device geometry has to be inverted.
  283. */
  284. switch (romDevice->manufacturerID)
  285. {
  286. case CFI_MANUF_AMD:
  287. switch (romDevice->deviceID)
  288. {    
  289. case CFI_DEVICE_AM29LV400BT:
  290. romDevice->name = "AMD AM29LV400BT";
  291. break;
  292. case CFI_DEVICE_AM29LV400BB:
  293. romDevice->name = "AMD AM29LV400BB";
  294. break;
  295. case CFI_DEVICE_AM29LV800BT:
  296. romDevice->name = "AMD AM29LV800BT";
  297. break;
  298. case CFI_DEVICE_AM29LV800BB:
  299. romDevice->name = "AMD AM29LV800BB";
  300. break;
  301. case CFI_DEVICE_AM29LV160DB:
  302. romDevice->name = "AMD AM29LV160DB";
  303. break;
  304. case CFI_DEVICE_AM29LV160DT:
  305. romDevice->name = "AMD AM29LV160DT";
  306. boolInvertGeometry = TRUE; /* Special case */
  307. break;
  308. case CFI_DEVICE_AM29LV320DT:
  309. romDevice->name = "AMD AM29LV320DT";
  310. break;
  311. case CFI_DEVICE_AM29LV320DB:
  312. romDevice->name = "AMD AM29LV320DB";
  313. break;
  314. case CFI_DEVICE_AM29LV640DU:
  315. romDevice->name = "AMD AM29LV640DU";
  316. break;
  317. case CFI_DEVICE_AM29DL322DT:
  318. romDevice->name = "AMD AM29DL322DT";
  319. break;
  320. case CFI_DEVICE_AM29DL322DB:
  321. romDevice->name = "AMD AM29DL322DB";
  322. break;
  323. case CFI_DEVICE_AM29DL323DT:
  324. romDevice->name = "AMD AM29DL323DT";
  325. break;
  326. case CFI_DEVICE_AM29DL323DB:
  327. romDevice->name = "AMD AM29DL323DB";
  328. break;
  329. case CFI_DEVICE_AM29DL324DT:
  330. romDevice->name = "AMD AM29DL324DT";
  331. break;
  332. case CFI_DEVICE_AM29DL324DB:
  333. romDevice->name = "AMD AM29DL324DB";
  334. break;
  335. default:
  336. romDevice->name = "Unknown AMD";
  337. break;
  338. }                     
  339. break;
  340. case CFI_MANUF_FUJITSU:
  341. switch (romDevice->deviceID)
  342. {    
  343. case CFI_DEVICE_MBM29LV160BE:
  344. romDevice->name = "Fujitsu MBM29LV160BE";
  345. break;
  346. case CFI_DEVICE_MBM29LV160TE:
  347. romDevice->name = "Fujitsu MBM29LV160TE";
  348. boolInvertGeometry = TRUE; /* Special case */
  349. break;
  350. case CFI_DEVICE_MBM29DL32TF_BF:
  351. if(boolInvertGeometry)
  352. {
  353. romDevice->name = "Fujitsu MBM29DL32TF";
  354. }
  355. else
  356. {
  357. romDevice->name = "Fujitsu MBM29DL32BF";
  358. }
  359. break;
  360. default:
  361. romDevice->name = "Unknown Fujitsu";
  362. break;
  363. }
  364. break;
  365. case CFI_MANUF_INTEL:
  366. switch (romDevice->deviceID)
  367. {    
  368. case CFI_DEVICE_28F800C3T:
  369. romDevice->name = "Intel 28F800C3-T";
  370. break;
  371. case CFI_DEVICE_28F800C3B:
  372. romDevice->name = "Intel 28F800C3-B";
  373. break;
  374. case CFI_DEVICE_28F160C3T:
  375. romDevice->name = "Intel 28F160C3-T";
  376. break;
  377. case CFI_DEVICE_28F160C3B:
  378. romDevice->name = "Intel 28F160C3-B";
  379. break;
  380. case CFI_DEVICE_28F320C3T:
  381. romDevice->name = "Intel 28F320C3-T";
  382. break;
  383. case CFI_DEVICE_28F320C3B:
  384. romDevice->name = "Intel 28F320C3-B";
  385. break;
  386. case CFI_DEVICE_28F640C3T:
  387. romDevice->name = "Intel 28F640C3-T";
  388. break;
  389. case CFI_DEVICE_28F640C3B:
  390. romDevice->name = "Intel 28F640C3-B";
  391. break;
  392. case CFI_DEVICE_28F128J3A:
  393. romDevice->name = "Intel 28F128J3A";
  394. break;
  395. case CFI_DEVICE_28F320J3A:
  396. romDevice->name = "Intel 28F320J3A";
  397. break;
  398. case CFI_DEVICE_28F640J3A:
  399. romDevice->name = "Intel 28F640J3A";
  400. break;
  401. default:
  402. romDevice->name = "Unknown Intel";
  403. break;
  404. }
  405. break;
  406. case CFI_MANUF_SHARP:
  407. switch (romDevice->deviceID)
  408. {    
  409. case CFI_DEVICE_LH28F800BJ:
  410. romDevice->name = "Sharp LH28F800BJ";
  411. break;
  412. case CFI_DEVICE_LH28F160BJ:
  413. romDevice->name = "Sharp LH28F160BJ";
  414. break;
  415. case CFI_DEVICE_LH28F320BJ:
  416. romDevice->name = "Sharp LH28F320BJ";
  417. break;
  418. case CFI_DEVICE_LH28F160S3:
  419. romDevice->name = "Sharp LH28F160S3";
  420. break;
  421. default:
  422. romDevice->name = "Unknown Sharp";
  423. break;
  424. }
  425. break;
  426. case CFI_MANUF_ST:
  427. switch (romDevice->deviceID)
  428. {    
  429. case CFI_DEVICE_M29W160DT:
  430. romDevice->name = "ST M29W160DT";
  431. break;
  432. case CFI_DEVICE_M29W160DB:
  433. romDevice->name = "ST M29W160DB";
  434. break;
  435. case CFI_DEVICE_M29W320DT:
  436. romDevice->name = "ST M29W320DT";
  437. break;
  438. case CFI_DEVICE_M29W320DB:
  439. romDevice->name = "ST M29W320DB";
  440. break;
  441. case CFI_DEVICE_M29W640FT:
  442. romDevice->name = "ST M29W640FT";
  443. break;
  444. default:
  445. romDevice->name = "Unknown ST";
  446. break;
  447. }
  448. break;
  449. case CFI_MANUF_SST:
  450. switch (romDevice->deviceID)
  451. {    
  452. case CFI_DEVICE_SST39xF200A:
  453. romDevice->name = "SST SST39LF200/SST39VF200";
  454. break;
  455. case CFI_DEVICE_SST39xF400A:
  456. romDevice->name = "SST SST39LF400/SST39VF400";
  457. break;
  458. case CFI_DEVICE_SST39xF800A:
  459. romDevice->name = "SST SST39LF800/SST39VF800";
  460. break;
  461. case CFI_DEVICE_SST39xF160:
  462. romDevice->name = "SST SST39LF160/SST39VF160";
  463. break;
  464. default:
  465. romDevice->name = "Unknown SST";
  466. break;
  467. }
  468. break;
  469. case CFI_MANUF_TOSHIBA:
  470. switch (romDevice->deviceID)
  471. {    
  472. case CFI_DEVICE_TC58FVT160:
  473. romDevice->name = "Toshiba TC58FVT160";
  474. break;
  475. case CFI_DEVICE_TC58FVB160:
  476. romDevice->name = "Toshiba TC58FVB160";
  477. break;
  478. case CFI_DEVICE_TC58FVT321:
  479. romDevice->name = "Toshiba TC58FVT321";
  480. break;
  481. case CFI_DEVICE_TC58FVB321:
  482. romDevice->name = "Toshiba TC58FVB321";
  483. break;
  484. case CFI_DEVICE_TC58FVT641:
  485. romDevice->name = "Toshiba TC58FVT641";
  486. break;
  487. case CFI_DEVICE_TC58FVB641:
  488. romDevice->name = "Toshiba TC58FVB641";
  489. break;
  490. default:
  491. romDevice->name = "Unknown Toshiba";
  492. break;
  493. }
  494. break;
  495. default:
  496. romDevice->name = "Unknown Manufacturer";
  497. break;
  498. }
  499.   
  500. /*
  501. ** Specifically for AMD and Fujitsu ROMs invert the device geometry
  502. ** if required.
  503. */ 
  504. if (((romDevice->manufacturerID == CFI_MANUF_AMD) || (romDevice->manufacturerID == CFI_MANUF_FUJITSU)) && (boolInvertGeometry != FALSE))
  505. for(index=0; index < ((romDevice->numSectors - 1) / 2); index++)
  506. {
  507. sectorSize = romDevice->sectorSize[index];
  508. romDevice->sectorSize[index] = romDevice->sectorSize[romDevice->numSectors - index - 1];
  509. romDevice->sectorSize[romDevice->numSectors - index - 1] = sectorSize;
  510. }
  511. }
  512.   
  513. /*
  514. ** Determine what sectors are protected and get each sector base address.
  515. */
  516. sectorBaseAddress = romDevice->baseAddress;
  517. for (index=0; index < (romDevice->numSectors) ; index++)
  518. {
  519. romDevice->sector[index] = ((WORDREG)sectorBaseAddress)[CFI_SECTOR_PROTECT] & 0x1;
  520. romDevice->sectorAddr[index] = sectorBaseAddress;
  521. sectorBaseAddress += romDevice->sectorSize[index];
  522. }
  523.   
  524. /*
  525. ** Put the ROM back into read array mode and return.
  526. */
  527. romDevice->Reset(romDevice);
  528. EXCEndCriticalSection(irqState);
  529. return(SUCCESS);  
  530. }
  531. /****************************************************************************
  532. ** Function CFIAMDBusy(): This function tests to see if a FLASH ROM command is
  533. ** currently being executed. It will also test if a command has failed.
  534. **
  535. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  536. **
  537. ** Outputs:     None
  538. **
  539. ** Returns:     TRUE if the ROM is busy.
  540. **              FALSE if the ROM is not busy.
  541. **              FAILURE if the command failed.
  542. ****************************************************************************/
  543. INT32 CFIAMDBusy(T_CFIRomDevice *this)
  544. {
  545. UINT16 toggleOdd, toggleEven;
  546. INT32 nret;
  547. UINT32 irqState;
  548. irqState = EXCStartCriticalSection();
  549. /*
  550. ** If the toggle bit is still toggling then the ROM is still
  551. ** attempting to execute a command.
  552. */
  553. toggleOdd = (*((WORDREG)this->baseAddress) & CFI_AMD_TOGGLE_BIT_MASK);
  554. toggleEven = (*((WORDREG)this->baseAddress) & CFI_AMD_TOGGLE_BIT_MASK); 
  555. if (toggleOdd != toggleEven)
  556. {  
  557. /*
  558. ** The ROM is busy so set the return value to TRUE.
  559. ** This will change if the command has timed out..
  560. */
  561. nret = TRUE;
  562. /*
  563. ** Test to see if the command has timed out.
  564. */
  565. if ((*((WORDREG)this->baseAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  566. {
  567. /*
  568. ** Just because the operation has timed out
  569. ** does not necessarily mean that it has failed.
  570. ** Test to see if it has succeeded before returning.
  571. ** If the toggle bit is still toggling then it has failed.
  572. */
  573. toggleOdd = (*((WORDREG)this->baseAddress) & CFI_AMD_TOGGLE_BIT_MASK);
  574. toggleEven = (*((WORDREG)this->baseAddress) & CFI_AMD_TOGGLE_BIT_MASK); 
  575. if (toggleOdd != toggleEven)
  576. {
  577. /*
  578. ** Put the ROM back into normal read mode.
  579. */
  580. CFIAMDReset(this);
  581. /*
  582. ** Return FAILURE.
  583. */
  584. nret = FAILURE;
  585. }
  586. else
  587. {
  588. /*
  589. ** Return FALSE as the ROM is no longer busy.
  590. */
  591. nret = FALSE;
  592. }
  593. }
  594. }
  595. else
  596. {
  597. /*
  598. ** Return FALSE as the ROM is no longer busy.
  599. */
  600. nret = FALSE;
  601. }
  602. EXCEndCriticalSection(irqState);
  603. return nret;
  604. }
  605. /****************************************************************************
  606. ** Function CFIAMDEraseChip(): This function will erase all unprotected sectors
  607. ** of the specified AMD FLASH ROM. This is function can be either blocking
  608. ** or non-blocking. If the blocking mode is used then this function will not
  609. ** return control until either the ROM is erased or an error occurs. If a 
  610. ** non-blocking mode is used then the CFIAMDBusy() should be used to poll for
  611. ** completion.
  612. **
  613. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  614. **              block, CFI_BLOCKING if this function should block waiting
  615. **               for completion, or CFI_NON_BLOCKING if this function should
  616. **               return immediately after initiating the command.
  617. **
  618. ** Outputs:     None
  619. **
  620. ** Returns:     SUCCESS if the ROM is successfully erased.
  621. **              FAILURE if this function is not running in RAM, or the
  622. **               erase failed.
  623. ****************************************************************************/
  624. INT32 CFIAMDEraseChip(T_CFIRomDevice *this, UINT32 blocking)
  625. {
  626. INT32 nret;
  627. INT32 busy;
  628. UINT32 irqState;
  629. irqState = EXCStartCriticalSection();
  630. /*
  631. ** Enter the chip erase command.
  632. ** Pre-amble first, then erase command, then pre-amble again,
  633. ** then chip erase command.
  634. */
  635. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  636. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  637. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_ERASE;
  638. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  639. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  640. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_ERASE_COMMAND_CHIP;
  641. /*
  642. ** If this function was called in the non-blocking mode then
  643. ** return immediately, otherwise wait for the erase command
  644. ** to be completed.
  645. */
  646. if (blocking == CFI_BLOCKING)
  647. {
  648. /*
  649. ** Wait for the erase command to complete. CFIAMDBusy() will
  650. ** also report if the operation failed.
  651. */
  652. while ((busy = CFIAMDBusy(this)) == TRUE);
  653. if (busy == FAILURE)
  654. {
  655. nret = FAILURE;
  656. }
  657. else
  658. {
  659. nret = SUCCESS;
  660. }
  661. }
  662. else
  663. {
  664. nret = SUCCESS;
  665. }
  666. EXCEndCriticalSection(irqState);
  667. return nret;
  668. }
  669. /****************************************************************************
  670. ** Function CFIAMDEraseSector(): This function will erase the specified sector
  671. ** of an AMD FLASH ROM. This is function can be either blocking or
  672. ** non-blocking. If the blocking mode is used then this function will not
  673. ** return control until either the sector is erased or an error occurs. If a 
  674. ** non-blocking mode is used then the CFIAMDBusy() should be used to poll for
  675. ** completion.
  676. **
  677. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  678. **              targetAddress, an address inside the sector to be erased.
  679. **              blocking, CFI_BLOCKING or CFI_NON_BLOCKING
  680. **
  681. ** Outputs:     None
  682. **
  683. ** Returns:     SUCCESS if the ROM is successfully erased.
  684. **              FAILURE if this function is not running in RAM, or the
  685. **               erase failed.
  686. ****************************************************************************/
  687. INT32 CFIAMDEraseSector(T_CFIRomDevice *this, UINT16 *targetAddress,
  688.                         UINT32 blocking)
  689. {
  690. INT32 nret;
  691. INT32 busy;
  692. UINT32 irqState;
  693. irqState = EXCStartCriticalSection();
  694. /*
  695. ** Enter sector erase mode.
  696. ** Pre-amble first, then erase command, then pre-amble again,
  697. ** then sector to erase.
  698. */
  699. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  700. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  701. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_ERASE;
  702. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  703. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  704. *((WORDREG)targetAddress) = CFI_AMD_ERASE_COMMAND_SECTOR;
  705. /*
  706. ** If this function was called in the non-blocking mode then
  707. ** return immediately, otherwise wait for the erase command
  708. ** to be completed.
  709. */
  710. if (blocking == CFI_BLOCKING)
  711. {
  712. /*
  713. ** Wait for the erase command to complete. CFIAMDBusy() will
  714. ** also report if the operation failed.
  715. */
  716. while ((busy = CFIAMDBusy(this)) == TRUE);
  717. if (busy == FAILURE)
  718. {
  719. nret = FAILURE;
  720. }
  721. else
  722. {
  723. nret = SUCCESS;
  724. }
  725. }
  726. else
  727. {
  728. nret = SUCCESS;
  729. }
  730. EXCEndCriticalSection(irqState);
  731. return nret;
  732. }
  733. /****************************************************************************
  734. ** Function CFIAMDExtendedProgram(): This function will program the
  735. ** specified area of an AMD FLASH ROM. This is a blocking function and will
  736. ** not return control until either the programming is complete or an error
  737. ** occurs.
  738. **
  739. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  740. **              targetAddress, the start address to program to in the ROM.
  741. **              sourceData, a pointer to the start of the data to be
  742. **               programmed.
  743. **              numBytes, the number of bytes to be programmed.
  744. **
  745. ** Outputs:     None
  746. **
  747. ** Returns:     SUCCESS if the programming is successful.
  748. **              FAILURE if this function is not running in RAM, or the
  749. **               programming failed. The programming is likely to fail
  750. **               if an attempt is made to program an area of memory that
  751. **               has not been erased. Specifically if an attempt is made
  752. **               to change a 0 to a 1.
  753. ****************************************************************************/
  754. INT32 CFIAMDExtendedProgram(T_CFIRomDevice *this, UINT16 *targetAddress,
  755.                             UINT8 *sourceData, UINT32 numBytes)
  756. {
  757. UINT32 i=0;
  758. UINT16 tempWord;
  759. UINT16 *writeAddress;
  760. UINT32 irqState;
  761. irqState = EXCStartCriticalSection();
  762. /************************************************************************
  763. ** Mis-aligned write detection and handling.
  764. ************************************************************************/
  765. /*
  766. ** Our FLASH ROM is a 16-bit device, however we may be asked to write an
  767. ** odd number of bytes, or the target address may not be on a 16-bit
  768. ** boundary. If this is the case write use read/modify/write cycles to
  769. ** write the misaligned data.
  770. */
  771. /*
  772. ** If the start address is mis-aligned, write the first
  773. ** byte to align the start address.
  774. */
  775. if (((UINT32)targetAddress & 1) != 0)
  776. {
  777. /*
  778. ** Calculate what to write to where, i.e. do the read and modify.
  779. ** The function parameters will also be adapted ready for the
  780. ** main body of this function.
  781. */
  782. targetAddress = (UINT16 *)((UINT32)targetAddress & ~1);
  783. tempWord = targetAddress[0] & CFISetEndian(0xFF00); // We are masking off the lowest addressed byte which is a different part of the 16-bit word on big and little endian machines.
  784. tempWord |= CFISetEndian((UINT16)sourceData[0]);
  785. writeAddress = targetAddress;
  786. targetAddress++;
  787. numBytes--;
  788. sourceData++;
  789. /*
  790. ** Write the data.
  791. */
  792. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  793. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  794. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_PROGRAM;
  795. *((WORDREG)writeAddress) = tempWord;
  796. /*
  797. ** Poll for the programming completion.
  798. */
  799. while ( (*((WORDREG)writeAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  800. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  801. {
  802. /*
  803. ** Test to see if the programming operation
  804. ** has timed out.
  805. */
  806. if ((*((WORDREG)targetAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  807. {
  808. /*
  809. ** Just because the programming operation has timed
  810. ** out does not necessarily mean that it has failed.
  811. ** If DQ7 (data bit 7) is still the inverse of the data
  812. ** being programmed then the operation has failed.
  813. */
  814. if ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  815. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  816. {
  817. /*
  818. ** Reset the FLASH ROM back to read mode.
  819. */
  820. CFIAMDReset(this);
  821. /*
  822. ** Test to see if the word actually programmed.
  823. */
  824. if(*((WORDREG)writeAddress) == tempWord)
  825. {
  826. break;
  827. }
  828. /*
  829. ** Return FAILURE, as the programming failed.
  830. ** The most likely reason being that an attempt
  831. ** was made to program a '0' to a '1'.
  832. */
  833. EXCEndCriticalSection(irqState);
  834. return FAILURE;
  835. }
  836. }
  837. }
  838. }
  839. /*
  840. ** If there is now an odd number of bytes to write, the last
  841. ** byte has to be written to align the data length.
  842. */
  843. if ((numBytes & 1) != 0)
  844. {
  845. tempWord = targetAddress[((numBytes-1) >> 1)] & CFISetEndian(0x00FF);
  846. tempWord |= CFISetEndian((UINT16)(sourceData[(numBytes-1)] << 8));
  847. writeAddress = &(targetAddress[((numBytes-1) >> 1)]);
  848. numBytes--;
  849. /*
  850. ** Write the data.
  851. */
  852. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  853. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  854. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_PROGRAM;
  855. *((WORDREG)writeAddress) = tempWord;
  856. /*
  857. ** Poll for the programming completion.
  858. */
  859. while ( (*((WORDREG)writeAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  860. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  861. {
  862. /*
  863. ** Test to see if the programming operation
  864. ** has timed out.
  865. */
  866. if ((*((WORDREG)targetAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  867. {
  868. /*
  869. ** Just because the programming operation has timed
  870. ** out does not necessarily mean that it has failed.
  871. ** If DQ7 (data bit 7) is still the inverse of the data
  872. ** being programmed then the operation has failed.
  873. */
  874. if ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  875. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  876. {
  877. /*
  878. ** Reset the FLASH ROM back to read mode.
  879. */
  880. CFIAMDReset(this);
  881. /*
  882. ** Test to see if the word actually programmed.
  883. */
  884. if(*((WORDREG)writeAddress) == tempWord)
  885. {
  886. break;
  887. }
  888. /*
  889. ** Return FAILURE, as the programming failed.
  890. ** The most likely reason being that an attempt
  891. ** was made to program a '0' to a '1'.
  892. */
  893. EXCEndCriticalSection(irqState);
  894. return FAILURE;
  895. }
  896. }
  897. }
  898. }
  899. /************************************************************************
  900. ** Aligned writes.
  901. ************************************************************************/
  902. /*
  903. ** Enter unlock bypass mode.
  904. ** Pre-amble first, then unlock bypass command.
  905. */
  906. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  907. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  908. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_UNLOCK_BYPASS;
  909. while(i < numBytes)
  910. {
  911. /*
  912. ** Issue the program command
  913. */
  914. ((WORDREG)this->baseAddress)[0x0] = CFI_AMD_COMMAND_PROGRAM;
  915. /*
  916. ** Write the word. 
  917. */
  918. tempWord = CFISetEndian((UINT16)((sourceData[i]<<8) | sourceData[i+1]));
  919. *((WORDREG)targetAddress) = tempWord;
  920. /*
  921. ** Poll for the programming completion.
  922. */
  923. while ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  924.             (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  925. {
  926. /*
  927. ** Test to see if the programming operation
  928. ** has timed out.
  929. */
  930. if ((*((WORDREG)targetAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  931. {
  932. /*
  933. ** Just because the programming operation has timed
  934. ** out does not necessarily mean that it has failed.
  935. ** If DQ7 (data bit 7) is still the inverse of the data
  936. ** being programmed then the operation has failed.
  937. */
  938. if ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  939. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  940. {
  941. /*
  942. ** Reset the FLASH ROM back to read mode.
  943. */
  944. *((WORDREG)this->baseAddress) = CFI_AMD_UNLOCK_BYPASS_RESET_1;
  945. *((WORDREG)this->baseAddress) = CFI_AMD_UNLOCK_BYPASS_RESET_2;
  946. /*
  947. ** Return FAILURE, as the programming failed.
  948. ** The most likely reason being that an attempt
  949. ** was made to program a '0' to a '1'.
  950. */
  951. EXCEndCriticalSection(irqState);
  952. return FAILURE;
  953. }
  954. }
  955. }
  956. /*
  957. ** Increment the source and target addresses.
  958. */
  959. targetAddress++;
  960. i += 2;
  961. }
  962. /*
  963. ** Reset the FLASH ROM back to read mode.
  964. */
  965. *((WORDREG)this->baseAddress) = CFI_AMD_UNLOCK_BYPASS_RESET_1;
  966. *((WORDREG)this->baseAddress) = CFI_AMD_UNLOCK_BYPASS_RESET_2;
  967. /*
  968. ** Return SUCCESS.
  969. */
  970. EXCEndCriticalSection(irqState);
  971. return SUCCESS;
  972. }
  973. /****************************************************************************
  974. ** Function CFIAMDIDCodesEntry(): This function places an AMD compatible
  975. ** FLASH ROM in the read indentify codes mode,
  976. **
  977. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  978. **
  979. ** Outputs:     None
  980. **
  981. ** Returns:     Nothing.
  982. ****************************************************************************/
  983. void CFIAMDIDCodesEntry(T_CFIRomDevice *this)
  984. {
  985. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  986. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  987. ((WORDREG)this->baseAddress)[CFI_IDENTIFIER_CODES_ADDRESS] = CFI_IDENTIFIER_CODES_COMMAND;
  988. }
  989. /****************************************************************************
  990. ** Function CFIAMDProgram(): This function will program the
  991. ** specified area of an AMD FLASH ROM. This is a blocking function and will
  992. ** not return control until either the programming is complete or an error
  993. ** occurs.
  994. **
  995. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  996. **              targetAddress, the start address to program to in the ROM.
  997. **              sourceData, a pointer to the start of the data to be
  998. **               programmed.
  999. **              numBytes, the number of bytes to be programmed.
  1000. **
  1001. ** Outputs:     None
  1002. **
  1003. ** Returns:     SUCCESS if the programming is successful.
  1004. **              FAILURE if this function is not running in RAM, or the
  1005. **               programming failed. The programming is likely to fail
  1006. **               if an attempt is made to program an area of memory that
  1007. **               has not been erased. Specifically if an attempt is made
  1008. **               to change a 0 to a 1.
  1009. ****************************************************************************/
  1010. INT32 CFIAMDProgram(T_CFIRomDevice *this, UINT16 *targetAddress,
  1011.                     UINT8 *sourceData, UINT32 numBytes)
  1012. {
  1013. UINT32 i=0;
  1014. UINT16 tempWord;
  1015. UINT16 *writeAddress;
  1016. UINT32 irqState;
  1017. irqState = EXCStartCriticalSection();
  1018. /************************************************************************
  1019. ** Mis-aligned write detection and handling.
  1020. ************************************************************************/
  1021. /*
  1022. ** Our FLASH ROM is a 16-bit device, however we may be asked to write an
  1023. ** odd number of bytes, or the target address may not be on a 16-bit
  1024. ** boundary. If this is the case write use read/modify/write cycles to
  1025. ** write the misaligned data.
  1026. */
  1027. /*
  1028. ** If the start address is mis-aligned, write the first
  1029. ** byte to align the start address.
  1030. */
  1031. if (((UINT32)targetAddress & 1) != 0)
  1032. {
  1033. /*
  1034. ** Calculate what to write to where, i.e. do the read and modify.
  1035. ** The function parameters will also be adapted ready for the
  1036. ** main body of this function.
  1037. */
  1038. targetAddress = (UINT16 *)((UINT32)targetAddress & ~1);
  1039. tempWord = targetAddress[0] & CFISetEndian(0xFF00); // We are masking off the lowest addressed byte which is a different part of the 16-bit word on big and little endian machines.
  1040. tempWord |= CFISetEndian((UINT16)sourceData[0]);
  1041. writeAddress = targetAddress;
  1042. targetAddress++;
  1043. numBytes--;
  1044. sourceData++;
  1045. /*
  1046. ** Write the data.
  1047. */
  1048. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  1049. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  1050. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_PROGRAM;
  1051. *((WORDREG)writeAddress) = tempWord;
  1052. /*
  1053. ** Poll for the programming completion.
  1054. */
  1055. while ( (*((WORDREG)writeAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  1056. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  1057. {
  1058. /*
  1059. ** Test to see if the programming operation
  1060. ** has timed out.
  1061. */
  1062. if ((*((WORDREG)targetAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  1063. {
  1064. /*
  1065. ** Just because the programming operation has timed
  1066. ** out does not necessarily mean that it has failed.
  1067. ** If DQ7 (data bit 7) is still the inverse of the data
  1068. ** being programmed then the operation has failed.
  1069. */
  1070. if ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  1071. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  1072. {
  1073. /*
  1074. ** Reset the FLASH ROM back to read mode.
  1075. */
  1076. CFIAMDReset(this);
  1077. /*
  1078. ** Test to see if the word actually programmed.
  1079. */
  1080. if(*((WORDREG)writeAddress) == tempWord)
  1081. {
  1082. break;
  1083. }
  1084. /*
  1085. ** Return FAILURE, as the programming failed.
  1086. ** The most likely reason being that an attempt
  1087. ** was made to program a '0' to a '1'.
  1088. */
  1089. EXCEndCriticalSection(irqState);
  1090. return FAILURE;
  1091. }
  1092. }
  1093. }
  1094. }
  1095. /*
  1096. ** If there is now an odd number of bytes to write, the last
  1097. ** byte has to be written to align the data length.
  1098. */
  1099. if ((numBytes & 1) != 0)
  1100. {
  1101. tempWord = targetAddress[((numBytes-1) >> 1)] & CFISetEndian(0x00FF);
  1102. tempWord |= CFISetEndian((UINT16)(sourceData[(numBytes-1)] << 8));
  1103. writeAddress = &(targetAddress[((numBytes-1) >> 1)]);
  1104. numBytes--;
  1105. /*
  1106. ** Write the data.
  1107. */
  1108. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  1109. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  1110. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_PROGRAM;
  1111. *((WORDREG)writeAddress) = tempWord;
  1112. /*
  1113. ** Poll for the programming completion.
  1114. */
  1115. while ( (*((WORDREG)writeAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  1116. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  1117. {
  1118. /*
  1119. ** Test to see if the programming operation
  1120. ** has timed out.
  1121. */
  1122. //if ((*((WORDREG)targetAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  1123. if ((*((WORDREG)writeAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  1124. {
  1125. /*
  1126. ** Just because the programming operation has timed
  1127. ** out does not necessarily mean that it has failed.
  1128. ** If DQ7 (data bit 7) is still the inverse of the data
  1129. ** being programmed then the operation has failed.
  1130. */
  1131. //if ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  1132. if ( (*((WORDREG)writeAddress) & CFI_AMD_DQ7_BIT_MASK) !=
  1133. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  1134. {
  1135. /*
  1136. ** Reset the FLASH ROM back to read mode.
  1137. */
  1138. CFIAMDReset(this);
  1139. /*
  1140. ** Return FAILURE, as the programming failed.
  1141. ** The most likely reason being that an attempt
  1142. ** was made to program a '0' to a '1'.
  1143. */
  1144. EXCEndCriticalSection(irqState);
  1145. return FAILURE;
  1146. }
  1147. }
  1148. }
  1149. }
  1150. /************************************************************************
  1151. ** Aligned writes.
  1152. ************************************************************************/
  1153. while(i < numBytes)
  1154. {
  1155. /*
  1156. ** Write the data.
  1157. */
  1158. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_1] = CFI_COMMAND_PREAMBLE_1_DATA;
  1159. ((WORDREG)this->baseAddress)[CFI_COMMAND_PREAMBLE_2] = CFI_COMMAND_PREAMBLE_2_DATA;
  1160. ((WORDREG)this->baseAddress)[CFI_COMMAND_TYPE] = CFI_AMD_COMMAND_PROGRAM;
  1161. tempWord = CFISetEndian((UINT16)((sourceData[i]<<8) | sourceData[i+1]));
  1162. *((WORDREG)targetAddress) = tempWord;
  1163. /*
  1164. ** Poll for the programming completion.
  1165. */
  1166. while ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  1167.             (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  1168. {
  1169. /*
  1170. ** Test to see if the programming operation
  1171. ** has timed out.
  1172. */
  1173. if ((*((WORDREG)targetAddress) & CFI_AMD_TIMEOUT_BIT_MASK) != 0)
  1174. {
  1175. /*
  1176. ** Just because the programming operation has timed
  1177. ** out does not necessarily mean that it has failed.
  1178. ** If DQ7 (data bit 7) is still the inverse of the data
  1179. ** being programmed then the operation has failed.
  1180. */
  1181. if ( (*((WORDREG)targetAddress) & CFI_AMD_DQ7_BIT_MASK) != 
  1182. (tempWord & CFI_AMD_DQ7_BIT_MASK) )
  1183. {
  1184. /*
  1185. ** Reset the FLASH ROM back to read mode.
  1186. */
  1187. CFIAMDReset(this);
  1188. /*
  1189. ** Return FAILURE, as the programming failed.
  1190. ** The most likely reason being that an attempt
  1191. ** was made to program a '0' to a '1'.
  1192. */
  1193. EXCEndCriticalSection(irqState);
  1194. return FAILURE;
  1195. }
  1196. }
  1197. }
  1198. /*
  1199. ** Increment the source and target addresses.
  1200. */
  1201. targetAddress++;
  1202. i += 2;
  1203. }
  1204. /*
  1205. ** Reset the FLASH ROM back to read mode.
  1206. */
  1207. CFIAMDReset(this);
  1208. /*
  1209. ** Return SUCCESS.
  1210. */
  1211. EXCEndCriticalSection(irqState);
  1212. return SUCCESS;
  1213. }
  1214. /****************************************************************************
  1215. ** Function CFIAMDReset(): This function resets an AMD compatible FLASH ROM
  1216. ** back to read array mode.. 
  1217. **
  1218. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  1219. **
  1220. ** Outputs:     None
  1221. **
  1222. ** Returns:     Nothing.
  1223. ****************************************************************************/
  1224. void CFIAMDReset(T_CFIRomDevice *this)
  1225. {
  1226. *(WORDREG)this->baseAddress = 0xF0;
  1227. }
  1228. /****************************************************************************
  1229. ** Function CFIIntelBusy(): This function tests to see if a FLASH ROM command
  1230. ** is currently being executed. 
  1231. **
  1232. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  1233. **
  1234. ** Outputs:     None
  1235. **
  1236. ** Returns:     TRUE if the ROM is busy.
  1237. **              FALSE if the ROM is not busy.
  1238. ****************************************************************************/
  1239. INT32 CFIIntelBusy(T_CFIRomDevice *this)
  1240. {
  1241. return !(*((WORDREG)this->baseAddress) & CFI_INTEL_STATUS_BUSY);
  1242. }
  1243. /****************************************************************************
  1244. ** Function CFIIntelEraseSector(): This function will erase the specified
  1245. ** sector of an Intel FLASH ROM. This is function can be either blocking or
  1246. ** non-blocking. If the blocking mode is used then this function will not
  1247. ** return control until either the sector is erased or an error occurs. If a 
  1248. ** non-blocking mode is used then the CFIIntelBusy() should be used to poll for
  1249. ** completion.
  1250. **
  1251. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  1252. **              targetAddress, an address inside the sector to be erased.
  1253. **              blocking, CFI_BLOCKING or CFI_NON_BLOCKING
  1254. **
  1255. ** Outputs:     None
  1256. **
  1257. ** Returns:     SUCCESS if the ROM is successfully erased.
  1258. **              FAILURE if this function is not running in RAM, or the
  1259. **               erase failed.
  1260. ****************************************************************************/
  1261. INT32 CFIIntelEraseSector(T_CFIRomDevice *this, UINT16 *targetAddress,
  1262.                           UINT32 blocking)
  1263. {  
  1264. INT32 nret;
  1265. UINT32 irqState;
  1266. irqState = EXCStartCriticalSection();
  1267. /*
  1268. ** Enter sector erase mode.
  1269. ** Block erase setup first, then block erase confirm.
  1270. */
  1271. *((WORDREG)targetAddress) = CFI_INTEL_ERASE_COMMAND_SETUP;
  1272. *((WORDREG)targetAddress) = CFI_INTEL_ERASE_COMMAND_CONFIRM;
  1273. /*
  1274. ** If this function was called in the non-blocking mode then
  1275. ** return immediately, otherwise wait for the erase command
  1276. ** to be completed.
  1277. */
  1278. if (blocking == CFI_BLOCKING)
  1279. {
  1280. /*
  1281. ** Wait for the erase command to be completed.
  1282. */
  1283. while (CFIIntelBusy(this));
  1284. /*
  1285. ** Test for an error.
  1286. */
  1287. if (*((WORDREG)targetAddress) != 0x80)
  1288. {
  1289. /*
  1290. ** An error occurred. Clear the status register, put 
  1291. ** the device back into read mode and return.
  1292. */
  1293. *((WORDREG)this->baseAddress) = CFI_INTEL_CLEAR_STATUS;
  1294. *((WORDREG)this->baseAddress) = CFI_INTEL_RESET_TO_READ;
  1295. nret = FAILURE;
  1296. }
  1297. else
  1298. {
  1299. /*
  1300. ** The erase command completed successfully. Put the 
  1301. ** device back into read mode and return.
  1302. */
  1303. CFIIntelReset(this);
  1304. nret = SUCCESS;
  1305. }
  1306. }
  1307. else
  1308. {
  1309. nret = SUCCESS;
  1310. }
  1311. EXCEndCriticalSection(irqState);
  1312. return nret;
  1313. }
  1314. /****************************************************************************
  1315. ** Function CFIIntelExtendedProgram(): This function will program the specified area
  1316. ** of an Intel FLASH ROM. This is a blocking function and will not
  1317. ** return control until either the programming is complete or an error occurs.
  1318. **
  1319. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  1320. **              targetAddress, the start address to program in the ROM.
  1321. **              sourceData, a pointer to the start of the data to be
  1322. **               programmed.
  1323. **              numBytes, the number of bytes to be programmed.
  1324. **
  1325. ** Outputs:     None
  1326. **
  1327. ** Returns:     SUCCESS if the programming is successful.
  1328. **              FAILURE if this function is not running in RAM, or the
  1329. **               programming failed. The programming is likely to fail
  1330. **               if an attempt is made to program an area of memory that
  1331. **               has not been erased. Specifically if an attempt is made
  1332. **               to change a 0 to a 1.
  1333. ****************************************************************************/
  1334. INT32 CFIIntelExtendedProgram(T_CFIRomDevice *this, UINT16 *targetAddress, 
  1335.                               UINT8 *sourceData, UINT32 numBytes)
  1336. {
  1337. UINT32 i=0, count;
  1338. INT32 nret;
  1339. UINT16 tempWord;
  1340. UINT16 *sectorAddress;
  1341. UINT32 irqState;
  1342. irqState = EXCStartCriticalSection();
  1343. /************************************************************************
  1344. ** Mis-aligned write detection and handling.
  1345. ************************************************************************/
  1346. /*
  1347. ** Our FLASH ROM is a 16-bit device, however we may be asked to write an
  1348. ** odd number of bytes, or the target address may not be on a 16-bit
  1349. ** boundary. If this is the case write use read/modify/write cycles to
  1350. ** write the misaligned data.
  1351. */
  1352. if (((UINT32)targetAddress & 1) != 0)
  1353. {
  1354. /*
  1355. ** The start address is mis-aligned, write the first
  1356. ** byte to align the start address.
  1357. */
  1358. /*
  1359. ** Read and modify the first word.
  1360. */
  1361. targetAddress = (UINT16 *)((UINT32)targetAddress & ~1);
  1362. tempWord = targetAddress[0] & CFISetEndian(0xFF00);
  1363. tempWord |= CFISetEndian(sourceData[0]);
  1364. /*
  1365. ** Write the word write command.
  1366. */
  1367. *((WORDREG)targetAddress) = CFI_INTEL_WRITE_WORD;
  1368. /*
  1369. ** Write the data
  1370. */
  1371. *((WORDREG)targetAddress) = tempWord;
  1372. /*
  1373. ** Poll for completion.
  1374. */
  1375. while (CFIIntelBusy(this));
  1376. targetAddress++;
  1377. numBytes--;
  1378. sourceData++;
  1379. }
  1380. if ((numBytes & 1) != 0)
  1381. {
  1382. /*
  1383. ** The data length is now mis-aligned, write the last byte
  1384. ** to align to data length.
  1385. */
  1386. /*
  1387. ** Put the device back into read mode.
  1388. */
  1389. *((WORDREG)this->baseAddress) = CFI_INTEL_RESET_TO_READ;
  1390. tempWord = targetAddress[((numBytes-1) >> 1)] & CFISetEndian(0x00FF);
  1391. tempWord |= CFISetEndian((UINT16)(sourceData[(numBytes-1)] << 8));
  1392. /*
  1393. ** Write the word write command.
  1394. */
  1395. ((WORDREG)targetAddress)[((numBytes-1) >> 1)] = CFI_INTEL_WRITE_WORD;
  1396. /*
  1397. ** Write the data
  1398. */
  1399. ((WORDREG)targetAddress)[((numBytes-1) >> 1)] = tempWord;
  1400. /*
  1401. ** Poll for completion.
  1402. */
  1403. while (CFIIntelBusy(this));
  1404. numBytes--;
  1405. }
  1406. /************************************************************************
  1407. **  Aligned writes over sector boundaries.
  1408. ************************************************************************/
  1409. /*
  1410. ** We cannot do buffered writes over sector boundaries. This may
  1411. ** happen if the targetAddress is not on a 32 byte boundary. If
  1412. ** this is the case the first X bytes before a 32 byte boundary
  1413. ** are written a word at a time. Buffered writes will then
  1414. ** happen on sector boundaries.
  1415. */
  1416. if (((UINT32)targetAddress & 0x1F) != 0)
  1417. {
  1418. /*
  1419. ** Calculate the number of words to write to
  1420. ** get to a 32 bytes boundary. Also test to 
  1421. ** see that this isn't greater than the 
  1422. ** number of bytes to transfer.
  1423. */
  1424. count = (0x20 - ((UINT32)targetAddress & 0x1F)) >> 1;
  1425. if (count > (numBytes >> 1))
  1426. {
  1427. count = numBytes >> 1;
  1428. }
  1429. /*
  1430. ** Write the data.
  1431. */
  1432. while (count-- != 0)
  1433. {
  1434. /*
  1435. ** Write the word write command.
  1436. */
  1437. *((WORDREG)targetAddress) = CFI_INTEL_WRITE_WORD;
  1438. /*
  1439. ** Write the data
  1440. */
  1441. *((WORDREG)targetAddress) = CFISetEndian((UINT16)((sourceData[i]<<8) | sourceData[i+1]));
  1442. /*
  1443. ** Poll for completion.
  1444. */
  1445. while (CFIIntelBusy(this));
  1446. targetAddress++;
  1447. i += 2;
  1448. }
  1449. }
  1450. /************************************************************************
  1451. **  Aligned writes not over sector boundaries.
  1452. ************************************************************************/
  1453. while(i < numBytes)
  1454. {
  1455. /*
  1456. ** We write 16 bits at a time, so convert the byte count to a word
  1457. ** count.
  1458. */
  1459. count = (numBytes - i) >> 1;
  1460. /*
  1461. ** We can only write a maximum of 32 bytes (16 words) at a time.
  1462. */
  1463. if (count > 16)
  1464. {
  1465. count = 16;
  1466. }
  1467. /*
  1468. ** Store the sector address.
  1469. */
  1470. sectorAddress = targetAddress;
  1471. /*
  1472. ** Write the buffer setup command until it is accepted.
  1473. */
  1474. do 
  1475. {
  1476. *((WORDREG)targetAddress) = CFI_INTEL_WRITE_BUFFER_SETUP;
  1477. } while ((*((WORDREG)targetAddress) & CFI_INTEL_STATUS_BUSY) == 0);
  1478. /*
  1479. ** Write the word count - 1.
  1480. */
  1481. *((WORDREG)targetAddress) = (UINT16)(count - 1);
  1482. /*
  1483. ** Write the data.
  1484. */
  1485. while (count-- != 0)
  1486. {
  1487. *((WORDREG)targetAddress) = CFISetEndian((UINT16)((sourceData[i]<<8) | sourceData[i+1]));
  1488. targetAddress++;
  1489. i += 2;
  1490. }
  1491. /*
  1492. ** Issue the write confirm command.
  1493. */
  1494. *((WORDREG)sectorAddress) = CFI_INTEL_WRITE_CONFIRM;
  1495. }
  1496. /*
  1497. ** Poll for completion of the write.
  1498. */
  1499. while (CFIIntelBusy(this));
  1500. /*
  1501. ** Test for an error.
  1502. */
  1503. if (*((WORDREG)this->baseAddress) != 0x80)
  1504. {
  1505. /*
  1506. ** An error occurred. Clear the status register, put 
  1507. ** the device back into read mode and return.
  1508. */
  1509. *((WORDREG)this->baseAddress) = CFI_INTEL_CLEAR_STATUS;
  1510. *((WORDREG)this->baseAddress) = CFI_INTEL_RESET_TO_READ;
  1511. nret = FAILURE;
  1512. }
  1513. else
  1514. {
  1515. /*
  1516. ** The erase command completed successfully. Put the 
  1517. ** device back into read mode and return.
  1518. */
  1519. *((WORDREG)this->baseAddress) = CFI_INTEL_RESET_TO_READ;
  1520. nret = SUCCESS;
  1521. }
  1522. EXCEndCriticalSection(irqState);
  1523. return nret;
  1524. }
  1525. /****************************************************************************
  1526. ** Function CFIIntelIDCodesEntry(): This function places an Intel compatible
  1527. ** FLASH ROM in the read indentify codes mode,
  1528. **
  1529. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  1530. **
  1531. ** Outputs:     None
  1532. **
  1533. ** Returns:     Nothing.
  1534. ****************************************************************************/
  1535. void CFIIntelIDCodesEntry(T_CFIRomDevice *this)
  1536. {
  1537. ((WORDREG)this->baseAddress)[CFI_IDENTIFIER_CODES_ADDRESS] = CFI_IDENTIFIER_CODES_COMMAND;
  1538. }
  1539. /****************************************************************************
  1540. ** Function CFIIntelProgram(): This function will program the specified area
  1541. ** of an Intel compatible FLASH ROM. This is a blocking function and will not
  1542. ** return control until either the programming is complete or an error occurs.
  1543. **
  1544. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  1545. **              targetAddress, the start address to program to in the ROM.
  1546. **              sourceData, a pointer to the start of the data to be
  1547. **               programmed.
  1548. **              numBytes, the number of bytes to be programmed.
  1549. **
  1550. ** Outputs:     None
  1551. **
  1552. ** Returns:     SUCCESS if the programming is successful.
  1553. **              FAILURE if this function is not running in RAM, or the
  1554. **               programming failed. The programming is likely to fail
  1555. **               if an attempt is made to program an area of memory that
  1556. **               has not been erased. Specifically if an attempt is made
  1557. **               to change a 0 to a 1.
  1558. ****************************************************************************/
  1559. INT32 CFIIntelProgram(T_CFIRomDevice *this, UINT16 *targetAddress, 
  1560.                       UINT8 *sourceData, UINT32 numBytes)
  1561. {
  1562. UINT32 count;
  1563. INT32 nret;
  1564. UINT16 tempWord;
  1565. UINT32 irqState;
  1566. irqState = EXCStartCriticalSection();
  1567. /************************************************************************
  1568. ** Mis-aligned write detection and handling.
  1569. ************************************************************************/
  1570. /*
  1571. ** Our FLASH ROM is a 16-bit device, however we may be asked to write an
  1572. ** odd number of bytes, or the target address may not be on a 16-bit
  1573. ** boundary. If this is the case use read/modify/write cycles to
  1574. ** write the misaligned data.
  1575. */
  1576. if (((UINT32)targetAddress & 1) != 0)
  1577. {
  1578. /*
  1579. ** The start address is mis-aligned, write the first
  1580. ** byte to align the start address.
  1581. */
  1582. /*
  1583. ** Read and modify the first word.
  1584. */
  1585. targetAddress = (UINT16 *)((UINT32)targetAddress & ~1);
  1586. tempWord = targetAddress[0] & CFISetEndian(0xFF00);
  1587. tempWord |= CFISetEndian(sourceData[0]);
  1588. /*
  1589. ** Write the word write command.
  1590. */
  1591. *((WORDREG)targetAddress) = CFI_INTEL_WRITE_WORD;
  1592. /*
  1593. ** Write the data
  1594. */
  1595. *((WORDREG)targetAddress) = tempWord;
  1596. /*
  1597. ** Poll for completion.
  1598. */
  1599. while (CFIIntelBusy(this));
  1600. targetAddress++;
  1601. numBytes--;
  1602. sourceData++;
  1603. }
  1604. if ((numBytes & 1) != 0)
  1605. {
  1606. /*
  1607. ** The data length is now mis-aligned, write the last byte
  1608. ** to align to data length.
  1609. */
  1610. /*
  1611. ** Put the device back into read mode.
  1612. */
  1613. *((WORDREG)this->baseAddress) = CFI_INTEL_RESET_TO_READ;
  1614. tempWord = targetAddress[((numBytes-1) >> 1)] & CFISetEndian(0x00FF);
  1615. tempWord |= CFISetEndian((UINT16)(sourceData[(numBytes-1)] << 8));
  1616. /*
  1617. ** Write the word write command.
  1618. */
  1619. ((WORDREG)targetAddress)[((numBytes-1) >> 1)] = CFI_INTEL_WRITE_WORD;
  1620. /*
  1621. ** Write the data
  1622. */
  1623. ((WORDREG)targetAddress)[((numBytes-1) >> 1)] = tempWord;
  1624. /*
  1625. ** Poll for completion.
  1626. */
  1627. while (CFIIntelBusy(this));
  1628. numBytes--;
  1629. }
  1630. /************************************************************************
  1631. ** Main programming loop.
  1632. ************************************************************************/
  1633. /*
  1634. ** Convert the number of bytes to program to a number of 
  1635. ** 16-bit words to program.
  1636. */
  1637. count = numBytes >> 1;
  1638. /*
  1639. ** Write the data.
  1640. */
  1641. while (count-- != 0)
  1642. {
  1643. /*
  1644. ** Wait for the device to be ready.
  1645. */
  1646. while (CFIIntelBusy(this));
  1647. /*
  1648. ** Write the word write command.
  1649. */
  1650. *((WORDREG)targetAddress) = CFI_INTEL_WRITE_WORD;
  1651. /*
  1652. ** Write the data
  1653. */
  1654. *((WORDREG)targetAddress) = CFISetEndian((UINT16)((sourceData[0]<<8) | sourceData[1]));
  1655. targetAddress++;
  1656. sourceData += 2;
  1657. }
  1658. /*
  1659. ** Poll for completion of the write.
  1660. */
  1661. while (CFIIntelBusy(this));
  1662. /*
  1663. ** Test for an error.
  1664. */
  1665. if (*((WORDREG)this->baseAddress) != 0x80)
  1666. {
  1667. /*
  1668. ** An error occurred. Clear the status register, put 
  1669. ** the device back into read mode and return.
  1670. */
  1671. *((WORDREG)this->baseAddress) = CFI_INTEL_CLEAR_STATUS;
  1672. *((WORDREG)this->baseAddress) = CFI_INTEL_RESET_TO_READ;
  1673. nret = FAILURE;
  1674. }
  1675. else
  1676. {
  1677. /*
  1678. ** The program command completed successfully. Put the 
  1679. ** device back into read mode and return.
  1680. */
  1681. *((WORDREG)this->baseAddress) = CFI_INTEL_RESET_TO_READ;
  1682. nret = SUCCESS;
  1683. }
  1684. EXCEndCriticalSection(irqState);
  1685. return nret;
  1686. }
  1687. /****************************************************************************
  1688. ** Function CFIIntelReset(): This function resets an Intel compatible FLASH
  1689. ** ROM back to read array mode.
  1690. **
  1691. ** Inputs:      this, pointer to a T_CFIROMDevice structure.
  1692. **
  1693. ** Outputs:     None
  1694. **
  1695. ** Returns:     Nothing.
  1696. ****************************************************************************/
  1697. void CFIIntelReset(T_CFIRomDevice *this)
  1698. {
  1699. *(WORDREG)this->baseAddress = CFI_INTEL_RESET_TO_READ;
  1700. }
  1701. /****************************************************************************
  1702. ** Function CFISetEndian(): This function swaps the byte order of a 16-bit
  1703. ** word only if this image has been compiled for little endian operation.
  1704. ** The reason this function is required is that our ROMs are 16-bit devices,
  1705. ** but yet we program them with byte data. This means that we have endian
  1706. ** issues to deal with. All of the functions in this module assume big endian
  1707. ** rules for converting byte data to half-word data. This function is called
  1708. ** in those cases to make sure that they work for little endian operation.
  1709. **
  1710. ** Big endian vs. Little endian example
  1711. ** Say memory contains for following data in byte order 0xAA, 0xBB, 0xCC, 0xDD.
  1712. ** If you read the lowest address as a half word then for a big endian machine
  1713. ** the result will be 0xAABB and 0xBBAA for a little endian machine. If you
  1714. ** want to perform a read, modify, write cycle to replace 0xBB with 0xEE then
  1715. ** the sequence of operations is different for big and little endian. For big
  1716. ** endian you would perform 'new_data = ((old_data & 0xFF00) | 0xEE);'. For
  1717. ** little endian you would perform 'new_data = ((old_data & 0x00FF) | 0xEE00);'
  1718. **
  1719. ** Inputs:      value, the 16-bit word to swap or not.
  1720. **
  1721. ** Outputs:     None
  1722. **
  1723. ** Returns:     value byte swapped if compiled for little endian, or
  1724. **                unaltered if compiled for big endian.
  1725. ****************************************************************************/
  1726. UINT16 CFISetEndian(UINT16 value)
  1727. {
  1728. /*
  1729. ** ST5105 platform is little endian, and maybe other ST platforms are
  1730. ** little endian also. Please make sure that
  1731. */
  1732. #if 1 /* __MIPSEL */
  1733. return((UINT16)((value & 0xFF) << 8) | (UINT16)(value >> 8));
  1734. #else
  1735. return(value);
  1736. #endif
  1737. }