sysTffs.c
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:18k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* sysTffs.c - BSP stub for TrueFFS Socket Component Driver */
  2. /*
  3.  * Copyright (c) 2000-2002, 2007 Wind River Systems, Inc.
  4.  *
  5.  * The right to copy, distribute, modify, or otherwise make use
  6.  * of this software may be licensed only pursuant to the terms
  7.  * of an applicable Wind River license agreement.
  8.  */
  9. /*
  10. modification history
  11. --------------------
  12. 01f,30mar07,b_m  add wrSbc8548 TFFS support.
  13. 01e,22may02,nrv  Adding INCLUDE_MTD_CFIAMD
  14. 01d,13nov01,nrv  made use of PRJ_BUILD
  15. 01c,09nov01,nrv  merging in T3 version with some cleanup
  16. 01b,14dec00,yp   Documentation cleanup
  17. 01a,29nov00,yp   derived from ads860 sysTffs.c 01j.
  18. */
  19. /*
  20. This stub file provides the user with the means to create a TrueFFS compliant
  21. socket component driver for use with any BSP. This is sample code and it is
  22. expected, even required, to be modified after it is added to a BSP by the
  23. project facility when the component INCLUDE_TFFS is added to a kernel project.
  24. Look for #error and TODO statements in the sample code.
  25. This stub does not provides code, just some procedural macros that the
  26. generic driver code will use.
  27. DESCRIPTION
  28. This library must provide board-specific hardware access routines for TrueFFS.
  29. In effect, these routines comprise the socket component driver (or drivers)
  30. for your flash device.  At socket registration time, TrueFFS stores
  31. the functions provided by this socket component driver in an 'FLSocket'
  32. structure.  When TrueFFS needs to access the flash device, it uses these
  33. functions.
  34. Because this file is, for the most part, a device driver that exports its
  35. functionality by registering function pointers with TrueFFS, very few of the
  36. functions defined here are externally callable.  For the record, the only
  37. external functions are flFitInSocketWindow() and flDelayLoop(), and you should
  38. never have to call them.
  39. However, one of the most important functions defined in this file is neither
  40. referenced in an 'FLSocket' structure, nor is it externally callable.  This
  41. function is sysTffsInit() and it should only be called by TrueFFS.  TrueFFS
  42. calls this function at initialization time to register socket component
  43. drivers for all the flash devices attached to your target.  It is this call
  44. to sysTffs() that results in assigning drive numbers to the flash devices on
  45. your target hardware.  Drive numbers are assigned by the order in which the
  46. socket component drivers are registered. The first to be registered is drive
  47. 0, the second is drive 1, and so on up to 4.  As shipped, TrueFFS supports up
  48. to five flash drives.
  49. After registering socket component drivers for a flash device, you may
  50. format the flash medium even though there is not yet a block device driver
  51. associated with the flash (see the reference entry for the tffsDevCreate()
  52. routine).  To format the flash medium for use with TrueFFS,
  53. call tffsDevFormat() or, for some BSPs, sysTffsFormat().
  54. The sysTffsFormat() routine is an optional,BSP-specific helper routine that
  55. can be called externally. Internally, sysTffsFormat() calls tffsDevFormat()
  56. with a pointer to a 'FormatParams' structure that is initialized to values
  57. that leave a space on the flash device for a boot image. This space is outside
  58. the region managed by TrueFFS.  This special region is necessary for boot
  59. images because the normal translation and wear-leveling services of TrueFFS
  60. are incompatible with the needs of the boot program and the boot image it
  61. relies upon.  To write a boot image (or any other data) into this area,
  62. use tffsBootImagePut().
  63. The function sysTffsFormat() is only provided when a Flash SIMM has to have
  64. the TrueFFS file system in some desired fraction of it. It is provided only
  65. for the purpose of simplifying the process of formatting a Flash part that
  66. that should be subdivided.
  67. The Flash SIMM might also be referred to as RFA (Resident Flash Array) in the
  68. following text.
  69. Example implentations of sysTffs.c can be found in the directory
  70.     $(WIND_BASE)/target/src/drv/tffs/sockets
  71. The files sds860-sysTffs.c and pc386-sysTffs.c have support for single and dual
  72. socketed PCMCIA devices as well if that might be useful to you. They both
  73. support multiple sockets.
  74. Finally, this file also contains define statements for symbolic constants
  75. that determine which MTDs, translation layer modules, and other utilities
  76. are ultimately included in TrueFFS.  These defines are as follows:
  77. .IP "INCLUDE_TL_FTL"
  78. To include the NOR-based translation layer module.
  79. .IP "INCLUDE_TL_SSFDC"
  80. To include the SSFDC-appropriate translation layer module.
  81. .IP "INCLUDE_MTD_I28F016"
  82. For Intel 28f016 flash devices.
  83. .IP "INCLUDE_MTD_I28F008"
  84. For Intel 28f008 flash devices.
  85. .IP "INCLUDE_MTD_I28F008_BAJA"
  86. For Intel 28f008 flash devices on the Heurikon Baja 4700.
  87. .IP "INCLUDE_MTD_AMD"
  88. For AMD, Fujitsu: 29F0{40,80,16} 8-bit flash devices.
  89. .IP "INCLUDE_MTD_CFIAMD"
  90. For CFI compliant AMD, Fujitsu flash devices.
  91. .IP "INCLUDE_MTD_CFISCS"
  92. For CFI/SCS flash devices.
  93. .IP "INCLUDE_MTD_WAMD"
  94. For AMD, Fujitsu 29F0{40,80,16} 16-bit flash devices.
  95. .IP "INCLUDE_TFFS_BOOT_IMAGE"
  96. To include tffsBootImagePut() in TrueFFS for Tornado.
  97. .LP
  98. To exclude any of the modules mentioned above, edit sysTffs.c and undefine
  99. its associated symbolic constant.
  100. INCLUDE FILES: flsocket.h, tffsDrv.h
  101. */
  102. /* includes */
  103. #include "vxWorks.h"
  104. #include "taskLib.h"
  105. #include "config.h"
  106. #include "tffs/flsocket.h"
  107. #include "tffs/tffsDrv.h"
  108. /* defines */
  109. #ifndef PRJ_BUILD
  110. #undef  INCLUDE_MTD_I28F016             /* Intel: 28f016 */
  111. #undef  INCLUDE_MTD_I28F008             /* Intel: 28f008 */
  112. #undef  INCLUDE_MTD_AMD                 /* AMD, Fujitsu: 29f0{40,80,16} 8bit */
  113. #undef  INCLUDE_MTD_CFIAMD              /* CFI driver for AMD Flash Part */
  114. #undef  INCLUDE_MTD_CFISCS              /* CFI/SCS */
  115. #undef  INCLUDE_MTD_WAMD                /* AMD, Fujitsu: 29f0{40,80,16} 16bit */
  116. #define INCLUDE_TL_FTL                  /* FTL translation layer */
  117. #undef  INCLUDE_TL_SSFDC                /* SSFDC translation layer */
  118. #define INCLUDE_SOCKET_SIMM             /* SIMM socket interface */
  119. #define INCLUDE_SOCKET_PCMCIA           /* PCMCIA socket interface */
  120. #endif  /* PRJ_BUILD */
  121. /* define this MACRO to include MTD driver for wrSbc8548 */
  122. #define INCLUDE_MTD_SBC8548
  123. #ifdef INCLUDE_MTD_SBC8548
  124. #   include "sysMtd.c"
  125. #endif
  126. #define TFFS_FORMAT_PRINT           /* print the tffs format process */
  127. /* TODO :
  128.  * If you don't use TrueFFS to write your boot image you might want
  129.  * to undefine this.
  130.  */
  131. #define INCLUDE_TFFS_BOOT_IMAGE      /* include tffsBootImagePut() */
  132. /* TODO :
  133.  * set these to board specific values.
  134.  * The values used here are fictional.
  135.  */
  136. #define VCC_DELAY_MSEC 100 /* Millisecs to wait for Vcc ramp up */
  137. #define VPP_DELAY_MSEC 100 /* Millisecs to wait for Vpp ramp up */
  138. #define KILL_TIME_FUNC  ((iz * iz) / (iz + iz)) / ((iy + iz) / (iy * iz))
  139. /* locals */
  140. LOCAL UINT32 sysTffsMsecLoopCount = 0;
  141. /* forward declarations */
  142. LOCAL FLBoolean rfaCardDetected (FLSocket vol);
  143. LOCAL void rfaVccOn (FLSocket vol);
  144. LOCAL void rfaVccOff (FLSocket vol);
  145. #ifdef SOCKET_12_VOLTS
  146. LOCAL FLStatus rfaVppOn (FLSocket vol);
  147. LOCAL void rfaVppOff (FLSocket vol);
  148. #endif /* SOCKET_12_VOLTS */
  149. LOCAL FLStatus rfaInitSocket (FLSocket vol);
  150. LOCAL void rfaSetWindow (FLSocket vol);
  151. LOCAL void rfaSetMappingContext (FLSocket vol, unsigned page);
  152. LOCAL FLBoolean rfaGetAndClearCardChangeIndicator (FLSocket vol);
  153. LOCAL FLBoolean rfaWriteProtected (FLSocket vol);
  154. LOCAL void rfaRegister (void);
  155. #ifndef DOC
  156. #include "tffsConfig.c"
  157. #endif /* DOC */
  158. /*******************************************************************************
  159. *
  160. * sysTffsInit - board level initialization for TFFS
  161. *
  162. * This routine calls the socket registration routines for the socket component
  163. * drivers that will be used with this BSP. The order of registration signifies
  164. * the logical drive number assigned to the drive associated with the socket.
  165. *
  166. * RETURNS: N/A
  167. */
  168. LOCAL void sysTffsInit (void)
  169.     {
  170.     UINT32 ix = 0;
  171.     UINT32 iy = 1;
  172.     UINT32 iz = 2;
  173.     int oldTick;
  174.     /* we assume followings:
  175.      *   - no interrupts except timer is happening.
  176.      *   - the loop count that consumes 1 msec is in 32 bit.
  177.      * it is done in the early stage of usrRoot() in tffsDrv().  */
  178.     oldTick = tickGet();
  179.     while (oldTick == tickGet()) /* wait for next clock interrupt */
  180. ;
  181.     oldTick = tickGet();
  182.     while (oldTick == tickGet()) /* loop one clock tick */
  183. {
  184. iy = KILL_TIME_FUNC; /* consume time */
  185. ix++; /* increment the counter */
  186. }
  187.     sysTffsMsecLoopCount = ix * sysClkRateGet() / 1000;
  188.     /* TODO:
  189.      * Call each sockets register routine here
  190.      */
  191.     rfaRegister (); /* RFA socket interface register */
  192.     }
  193. /*******************************************************************************
  194. *
  195. * rfaRegister - install routines for the Flash RFA
  196. *
  197. * This routine installs necessary functions for the Resident Flash Array(RFA).
  198. *
  199. * RETURNS: N/A
  200. */
  201. LOCAL void rfaRegister (void)
  202.     {
  203.     FLSocket vol = flSocketOf (noOfDrives);
  204.     tffsSocket[noOfDrives] = "RFA";
  205.     vol.window.baseAddress = FLASH1_BASE_ADRS >> 12;
  206.     vol.cardDetected = rfaCardDetected;
  207.     vol.VccOn = rfaVccOn;
  208.     vol.VccOff = rfaVccOff;
  209. #ifdef SOCKET_12_VOLTS
  210.     vol.VppOn = rfaVppOn;
  211.     vol.VppOff = rfaVppOff;
  212. #endif
  213.     vol.initSocket = rfaInitSocket;
  214.     vol.setWindow = rfaSetWindow;
  215.     vol.setMappingContext = rfaSetMappingContext;
  216.     vol.getAndClearCardChangeIndicator = rfaGetAndClearCardChangeIndicator;
  217.     vol.writeProtected =    rfaWriteProtected;
  218.     noOfDrives++;
  219.     }
  220. /*******************************************************************************
  221. *
  222. * rfaCardDetected - detect if a card is present (inserted)
  223. *
  224. * This routine detects if a card is present (inserted).
  225. * Always return TRUE in RFA environments since device is not removable.
  226. *
  227. * RETURNS: TRUE, or FALSE if the card is not present.
  228. */
  229. LOCAL FLBoolean rfaCardDetected
  230.     (
  231.     FLSocket vol /* pointer identifying drive */
  232.     )
  233.     {
  234.     return (TRUE);
  235.     }
  236. /*******************************************************************************
  237. *
  238. * rfaVccOn - turn on Vcc (3.3/5 Volts)
  239. *
  240. * This routine turns on Vcc (3.3/5 Volts).  Vcc must be known to be good
  241. * on exit. Assumed to be ON constantly in RFA environment.
  242. *
  243. * RETURNS: N/A
  244. */
  245. LOCAL void rfaVccOn
  246.     (
  247.     FLSocket vol /* pointer identifying drive */
  248.     )
  249.     {
  250.     }
  251. /*******************************************************************************
  252. *
  253. * rfaVccOff - turn off Vcc (3.3/5 Volts)
  254. *
  255. * This routine turns off Vcc (3.3/5 Volts) (PCMCIA). Assumed to be ON
  256. * constantly in RFA environment.
  257. *
  258. * RETURNS: N/A
  259. */
  260. LOCAL void rfaVccOff
  261.     (
  262.     FLSocket vol /* pointer identifying drive */
  263.     )
  264.     {
  265.     }
  266. #ifdef SOCKET_12_VOLTS
  267. /*******************************************************************************
  268. *
  269. * rfaVppOn - turns on Vpp (12 Volts)
  270. *
  271. * This routine turns on Vpp (12 Volts). Vpp must be known to be good on exit.
  272. * Assumed to be ON constantly in RFA environment. This is not optional and
  273. * must always be implemented.
  274. *
  275. * RETURNS: flOK always.
  276. */
  277. LOCAL FLStatus rfaVppOn
  278.     (
  279.     FLSocket vol /* pointer identifying drive */
  280.     )
  281.     {
  282.     return (flOK);
  283.     }
  284. /*******************************************************************************
  285. *
  286. * rfaVppOff - turns off Vpp (12 Volts)
  287. *
  288. * This routine turns off Vpp (12 Volts). Assumed to be ON constantly
  289. * in RFA environment.This is not optional and must always be implemented.
  290. *
  291. * RETURNS: N/A
  292. */
  293. LOCAL void rfaVppOff
  294.     (
  295.     FLSocket vol /* pointer identifying drive */
  296.     )
  297.     {
  298.     }
  299. #endif /* SOCKET_12_VOLTS */
  300. /*******************************************************************************
  301. *
  302. * rfaInitSocket - perform all necessary initializations of the socket
  303. *
  304. * This routine performs all necessary initializations of the socket.
  305. *
  306. * RETURNS: flOK always.
  307. */
  308. LOCAL FLStatus rfaInitSocket
  309.     (
  310.     FLSocket vol /* pointer identifying drive */
  311.     )
  312.     {
  313.     return (flOK);
  314.     }
  315. /*******************************************************************************
  316. *
  317. * rfaSetWindow - set current window attributes, base address, size, etc
  318. *
  319. * This routine sets current window hardware attributes: Base address, size,
  320. * speed and bus width.  The requested settings are given in the 'vol.window'
  321. * structure.  If it is not possible to set the window size requested in
  322. * 'vol.window.size', the window size should be set to a larger value,
  323. * if possible. In any case, 'vol.window.size' should contain the
  324. * actual window size (in 4 KB units) on exit.
  325. *
  326. * RETURNS: N/A
  327. */
  328. LOCAL void rfaSetWindow
  329.     (
  330.     FLSocket vol /* pointer identifying drive */
  331.     )
  332.     {
  333.     /* Physical base as a 4K page */
  334.     flSetWindowSize (&vol, FLASH1_SIZE >> 12);
  335.     }
  336. /*******************************************************************************
  337. *
  338. * rfaSetMappingContext - sets the window mapping register to a card address
  339. *
  340. * This routine sets the window mapping register to a card address.
  341. * The window should be set to the value of 'vol.window.currentPage',
  342. * which is the card address divided by 4 KB. An address over 128MB,
  343. * (page over 32K) specifies an attribute-space address. On entry to this
  344. * routine vol.window.currentPage is the page already mapped into the window.
  345. * (In otherwords the page that was mapped by the last call to this routine.)
  346. * The page to map is guaranteed to be on a full window-size boundary.
  347. * This is meaningful only in environments that use sliding window mechanism
  348. * to view flash memory, like in PCMCIA. Not common in RFA environments.
  349. *
  350. * RETURNS: N/A
  351. */
  352. LOCAL void rfaSetMappingContext
  353.     (
  354.     FLSocket vol, /* pointer identifying drive */
  355.     unsigned page /* page to be mapped */
  356.     )
  357.     {
  358.     }
  359. /*******************************************************************************
  360. *
  361. * rfaGetAndClearCardChangeIndicator - return the hardware card-change indicator
  362. *
  363. * This routine returns TRUE if the card has been changed and FALSE if not. It
  364. * also clears the "card-changed" indicator if it has been set.
  365. * Always return FALSE in RFA environments since device is not removable.
  366. *
  367. * RETURNS: FALSE, or TRUE if the card has been changed
  368. */
  369. LOCAL FLBoolean rfaGetAndClearCardChangeIndicator
  370.     (
  371.     FLSocket vol /* pointer identifying drive */
  372.     )
  373.     {
  374.     return (FALSE);
  375.     }
  376. /*******************************************************************************
  377. *
  378. * rfaWriteProtected - return the write-protect state of the media
  379. *
  380. * This routine returns the write-protect state of the media
  381. *
  382. * RETURNS: FALSE, or TRUE if the card is write-protected
  383. */
  384. LOCAL FLBoolean rfaWriteProtected
  385.     (
  386.     FLSocket vol /* pointer identifying drive */
  387.     )
  388.     {
  389.     return (FALSE);
  390.     }
  391. /*******************************************************************************
  392. *
  393. * flFitInSocketWindow - check whether the flash array fits in the socket window
  394. *
  395. * This routine checks whether the flash array fits in the socket window.
  396. *
  397. * RETURNS: A chip size guaranteed to fit in the socket window.
  398. */
  399. long int flFitInSocketWindow
  400.     (
  401.     long int chipSize, /* size of single physical chip in bytes */
  402.     int      interleaving, /* flash chip interleaving (1,2,4 etc) */
  403.     long int windowSize /* socket window size in bytes */
  404.     )
  405.     {
  406.     if (chipSize*interleaving > windowSize) /* doesn't fit in socket window */
  407.         {
  408.         int  roundedSizeBits;
  409.         /* fit chip in the socket window */
  410.         chipSize = windowSize / interleaving;
  411.         /* round chip size at powers of 2 */
  412.         for (roundedSizeBits = 0; (0x1L << roundedSizeBits) <= chipSize;
  413.              roundedSizeBits++)
  414.     ;
  415.         chipSize = (0x1L << (roundedSizeBits - 1));
  416.         }
  417.     return (chipSize);
  418.     }
  419. /*******************************************************************************
  420. *
  421. * flDelayMsecs - wait for specified number of milliseconds
  422. *
  423. * This routine waits for the specified number of milliseconds.
  424. *
  425. * RETURNS: N/A
  426. *
  427. * NOMANUAL
  428. */
  429. void flDelayMsecs
  430.     (
  431.     unsigned milliseconds       /* milliseconds to wait */
  432.     )
  433.     {
  434.     UINT32 ix;
  435.     UINT32 iy = 1;
  436.     UINT32 iz = 2;
  437.     /* it doesn't count time consumed in interrupt level */
  438.     for (ix = 0; ix < milliseconds; ix++)
  439.         for (ix = 0; ix < sysTffsMsecLoopCount; ix++)
  440.     {
  441.     tickGet (); /* dummy */
  442.     iy = KILL_TIME_FUNC; /* consume time */
  443.     }
  444.     }
  445. /*******************************************************************************
  446. *
  447. * flDelayLoop - consume the specified time
  448. *
  449. * This routine delays for the specified time.
  450. *
  451. * RETURNS: N/A
  452. */
  453. void flDelayLoop
  454.     (
  455.     int  cycles
  456.     )
  457.     {
  458.     while (--cycles)
  459. ;
  460.     }
  461. #ifdef TFFS_FORMAT_PRINT
  462. int sysTffsProgressCb (int totalUnitsToFormat, int totalUnitsFormattedSoFar)
  463. {
  464.     printf("Formatted %d of %d units = %d.%01d %%r",
  465.           totalUnitsFormattedSoFar, totalUnitsToFormat,
  466.           100 * totalUnitsFormattedSoFar / totalUnitsToFormat,
  467.           1000 * totalUnitsFormattedSoFar / totalUnitsToFormat % 10
  468.           );
  469. if (totalUnitsFormattedSoFar == totalUnitsToFormat)
  470.         printf ("n");
  471.    return flOK;
  472. }
  473. #define PROGRESS_CB sysTffsProgressCb
  474. #else
  475. #define PROGRESS_CB NULL
  476. #endif
  477. /*******************************************************************************
  478. *
  479. * sysTffsFormat - format the flash memory above an offset
  480. *
  481. * This routine formats the flash memory.  Because this function defines
  482. * the symbolic constant, HALF_FORMAT, the lower half of the specified flash
  483. * memory is left unformatted.  If the lower half of the flash memory was
  484. * previously formated by TrueFFS, and you are trying to format the upper half,
  485. * you need to erase the lower half of the flash memory before you format the
  486. * upper half.  To do this, you could use:
  487. * .CS
  488. * tffsRawio(0, 3, 0, 8)
  489. * .CE
  490. * The first argument in the tffsRawio() command shown above is the TrueFFS
  491. * drive number, 0.  The second argument, 3, is the function number (also
  492. * known as TFFS_PHYSICAL_ERASE).  The third argument, 0, specifies the unit
  493. * number of the first erase unit you want to erase.  The fourth argument, 8,
  494. * specifies how many erase units you want to erase.
  495. *
  496. * RETURNS: OK, or ERROR if it fails.
  497. */
  498. STATUS sysTffsFormat (void)
  499.     {
  500.     STATUS status;
  501.     /* Note: cfiamd keeps track of room to save at end of flash as required */
  502.     tffsDevFormatParams params =
  503.     {
  504.         {0, 99, 1, 0x10000l, PROGRESS_CB, {0,0,0,0}, NULL, 2, 0, NULL},
  505.         FTL_FORMAT/*FTL_FORMAT_IF_NEEDED*/
  506.     };
  507.     /* we assume that the drive number 0 is RFA */
  508.     status = tffsDevFormat (0, (int)&params);
  509.     return (status);
  510.     }