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

VxWorks

开发平台:

C/C++

  1. /* m85xxTimer.c - PowerPC Book E timer library */
  2. /*
  3. ****************************************************************************
  4.    This source and object code has been made available to you by IBM on an
  5.    AS-IS basis.
  6.    IT IS PROVIDED WITHOUT WARRANTY OF ANY KIND, INCLUDING THE WARRANTIES OF
  7.    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE OR OF NONINFRINGEMENT
  8.    OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL IBM OR ITS LICENSORS BE LIABLE
  9.    FOR INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES.  IBMS OR ITS LICENSORS
  10.    DAMAGES FOR ANY CAUSE OF ACTION, WHETHER IN CONTRACT OR IN TORT, AT LAW OR
  11.    AT EQUITY, SHALL BE LIMITED TO A MAXIMUM OF $1,000 PER LICENSE.  No license
  12.    under IBM patents or patent applications is to be implied by the copyright
  13.    license.
  14.    Any user of this software should understand that neither IBM nor its
  15.    licensors will be responsible for any consequences resulting from the use
  16.    of this software.
  17.    Any person who transfers this source code or any derivative work must
  18.    include the IBM copyright notice, this paragraph, and the preceding two
  19.    paragraphs in the transferred software.
  20.    Any person who transfers this object code or any derivative work must
  21.    include the IBM copyright notice in the transferred software.
  22.    COPYRIGHT   I B M   CORPORATION 2000
  23.    LICENSED MATERIAL  -  PROGRAM PROPERTY OF  I B M"
  24. ****************************************************************************
  25. NOMANUAL
  26. */
  27. /* Copyright 1984-2004 Wind River Systems, Inc. */
  28. /*
  29. modification history
  30. --------------------
  31. 01f,22oct04,dtr  Remove gnu compiler warning.
  32. 01e,01sep04,pch  fix masks in wdtTable
  33. 01d,31aug04,mdo  Documentation fixes for apigen
  34. 01c,05dec01,mcg  remove #include of ppc403Timer.c, used ppc440.h instead
  35. 01b,08nov01,jtp  TSR fields now cleared correctly
  36. 01a,24oct01,jtp  checked in. mcg ported this from ppc405Timer.c version 01h
  37. */
  38. /*
  39. DESCRIPTION
  40. This library provides PowerPC Book E Timer routines. This library handles
  41. the system clock, the auxiliary clock and timestamp functions. To
  42. include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must
  43. be defined.
  44. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  45. AUX_CLK_RATE_MAX must be defined to provide parameter checking for
  46. sysClkRateSet().
  47. The BSP is responsible for connecting the interrupt handlers,
  48. sysClkInt(), and sysAuxClkInt(), to the appropriate vectors.
  49. The BSP must also initialize a global variable sysTimerClkFreq prior to using
  50. this driver to indicate what frequency the timebase is running.  This value
  51. is often calculated at run time, especially when an internal timer clock source
  52. is being used.
  53. INCLUDE FILES:
  54. SEE ALSO:
  55. .pG "Configuration"
  56. */
  57. /* includes */
  58. #include "vxWorks.h"
  59. #include "vxLib.h"
  60. #include "intLib.h"
  61. #include "drv/timer/timestampDev.h"
  62. /* local defines */
  63. /* extern declarations */
  64. IMPORT UINT32 sysTimerClkFreq;
  65. /* typedefs */
  66. typedef struct
  67.     {
  68.     unsigned long long fitPeriod;         /* Fixed Interval Timer periods */
  69.     UINT32   fpMask;                      /* corresponding TCR mask       */
  70.     } FIT_PERIOD;
  71. typedef struct
  72.     {
  73.     unsigned long long wdtPeriod;         /* Watchdog Timer periods       */
  74.     UINT32   fpMask;                      /* corresponding TCR mask       */
  75.     } WDT_PERIOD;
  76. /* Locals */
  77. LOCAL FIT_PERIOD fitTable[] =                   /* available FIT periods */
  78.     {
  79. { ((unsigned long long) 1 << 0), 0x0301e000 }, /* TBL[63] */
  80. { ((unsigned long long) 1 << 1), 0x0201e000 }, /* TBL[62] */
  81. { ((unsigned long long) 1 << 2), 0x0101e000 }, /* TBL[61] */
  82. { ((unsigned long long) 1 << 3), 0x0001e000 }, /* TBL[60] */
  83. { ((unsigned long long) 1 << 4), 0x0301c000 }, /* TBL[59] */
  84. { ((unsigned long long) 1 << 5), 0x0201c000 }, /* TBL[58] */
  85. { ((unsigned long long) 1 << 6), 0x0101c000 }, /* TBL[57] */
  86. { ((unsigned long long) 1 << 7), 0x0001c000 }, /* TBL[56] */
  87. { ((unsigned long long) 1 << 8), 0x0301a000 }, /* TBL[55] */
  88. { ((unsigned long long) 1 << 9), 0x0201a000 }, /* TBL[54] */
  89. { ((unsigned long long) 1 << 10), 0x0101a000 }, /* TBL[53] */
  90. { ((unsigned long long) 1 << 11), 0x0001a000 }, /* TBL[52] */
  91. { ((unsigned long long) 1 << 12), 0x03018000 }, /* TBL[51] */
  92. { ((unsigned long long) 1 << 13), 0x02018000 }, /* TBL[50] */
  93. { ((unsigned long long) 1 << 14), 0x01018000 }, /* TBL[49] */
  94. { ((unsigned long long) 1 << 15), 0x00018000 }, /* TBL[48] */
  95. { ((unsigned long long) 1 << 16), 0x03016000 }, /* TBL[47] */
  96. { ((unsigned long long) 1 << 17), 0x02016000 }, /* TBL[46] */
  97. { ((unsigned long long) 1 << 18), 0x01016000 }, /* TBL[45] */
  98. { ((unsigned long long) 1 << 19), 0x00016000 }, /* TBL[44] */
  99. { ((unsigned long long) 1 << 20), 0x03014000 }, /* TBL[43] */
  100. { ((unsigned long long) 1 << 21), 0x02014000 }, /* TBL[42] */
  101. { ((unsigned long long) 1 << 22), 0x01014000 }, /* TBL[41] */
  102. { ((unsigned long long) 1 << 23), 0x00014000 }, /* TBL[40] */
  103. { ((unsigned long long) 1 << 24), 0x03012000 }, /* TBL[39] */
  104. { ((unsigned long long) 1 << 25), 0x02012000 }, /* TBL[38] */
  105. { ((unsigned long long) 1 << 26), 0x01012000 }, /* TBL[37] */
  106. { ((unsigned long long) 1 << 27), 0x00012000 }, /* TBL[36] */
  107. { ((unsigned long long) 1 << 28), 0x03010000 }, /* TBL[35] */
  108. { ((unsigned long long) 1 << 29), 0x02010000 }, /* TBL[34] */
  109. { ((unsigned long long) 1 << 30), 0x01010000 }, /* TBL[33] */
  110. { ((unsigned long long) 1 << 31), 0x00010000 }, /* TBL[32] */
  111. { ((unsigned long long) 1 << 32), 0x0300e000 }, /* TBU[31] */
  112. { ((unsigned long long) 1 << 33), 0x0200e000 }, /* TBU[30] */
  113. { ((unsigned long long) 1 << 34), 0x0100e000 }, /* TBU[29] */
  114. { ((unsigned long long) 1 << 35), 0x0000e000 }, /* TBU[28] */
  115. { ((unsigned long long) 1 << 36), 0x0300c000 }, /* TBU[27] */
  116. { ((unsigned long long) 1 << 37), 0x0200c000 }, /* TBU[26] */
  117. { ((unsigned long long) 1 << 38), 0x0100c000 }, /* TBU[25] */
  118. { ((unsigned long long) 1 << 39), 0x0000c000 }, /* TBU[24] */
  119. { ((unsigned long long) 1 << 40), 0x0300a000 }, /* TBU[23] */
  120. { ((unsigned long long) 1 << 41), 0x0200a000 }, /* TBU[22] */
  121. { ((unsigned long long) 1 << 42), 0x0100a000 }, /* TBU[21] */
  122. { ((unsigned long long) 1 << 43), 0x0000a000 }, /* TBU[20] */
  123. { ((unsigned long long) 1 << 44), 0x03008000 }, /* TBU[19] */
  124. { ((unsigned long long) 1 << 45), 0x02008000 }, /* TBU[18] */
  125. { ((unsigned long long) 1 << 46), 0x01008000 }, /* TBU[17] */
  126. { ((unsigned long long) 1 << 47), 0x00008000 }, /* TBU[16] */
  127. { ((unsigned long long) 1 << 48), 0x03006000 }, /* TBU[15] */
  128. { ((unsigned long long) 1 << 49), 0x02006000 }, /* TBU[14] */
  129. { ((unsigned long long) 1 << 50), 0x01006000 }, /* TBU[13] */
  130. { ((unsigned long long) 1 << 51), 0x00006000 }, /* TBU[12] */
  131. { ((unsigned long long) 1 << 52), 0x03004000 }, /* TBU[11] */
  132. { ((unsigned long long) 1 << 53), 0x02004000 }, /* TBU[10] */
  133. { ((unsigned long long) 1 << 54), 0x01004000 }, /* TBU[9] */
  134. { ((unsigned long long) 1 << 55), 0x00004000 }, /* TBU[8] */
  135. { ((unsigned long long) 1 << 56), 0x03002000 }, /* TBU[7] */
  136. { ((unsigned long long) 1 << 57), 0x02002000 }, /* TBU[6] */
  137. { ((unsigned long long) 1 << 58), 0x01002000 }, /* TBU[5] */
  138. { ((unsigned long long) 1 << 59), 0x00002000 }, /* TBU[4] */
  139. { ((unsigned long long) 1 << 60), 0x03000000 }, /* TBU[3] */
  140. { ((unsigned long long) 1 << 61), 0x02000000 }, /* TBU[2] */
  141. { ((unsigned long long) 1 << 62), 0x01000000 }, /* TBU[1] */
  142. { ((unsigned long long) 1 << 63), 0x00000000 } /* TBU[0] */
  143.     };
  144. LOCAL WDT_PERIOD wdtTable[] =                   /* available WDT periods */
  145.     {
  146. { ((unsigned long long) 1 << 0),  0xc01e0000 }, /* TBL[63] */
  147. { ((unsigned long long) 1 << 1),  0x801e0000 }, /* TBL[62] */
  148. { ((unsigned long long) 1 << 2),  0x401e0000 }, /* TBL[61] */
  149. { ((unsigned long long) 1 << 3),  0x001e0000 }, /* TBL[60] */
  150. { ((unsigned long long) 1 << 4),  0xc01c0000 }, /* TBL[59] */
  151. { ((unsigned long long) 1 << 5),  0x801c0000 }, /* TBL[58] */
  152. { ((unsigned long long) 1 << 6),  0x401c0000 }, /* TBL[57] */
  153. { ((unsigned long long) 1 << 7),  0x001c0000 }, /* TBL[56] */
  154. { ((unsigned long long) 1 << 8),  0xc01a0000 }, /* TBL[55] */
  155. { ((unsigned long long) 1 << 9),  0x801a0000 }, /* TBL[54] */
  156. { ((unsigned long long) 1 << 10), 0x401a0000 }, /* TBL[53] */
  157. { ((unsigned long long) 1 << 11), 0x001a0000 }, /* TBL[52] */
  158. { ((unsigned long long) 1 << 12), 0xc0180000 }, /* TBL[51] */
  159. { ((unsigned long long) 1 << 13), 0x80180000 }, /* TBL[50] */
  160. { ((unsigned long long) 1 << 14), 0x40180000 }, /* TBL[49] */
  161. { ((unsigned long long) 1 << 15), 0x00180000 }, /* TBL[48] */
  162. { ((unsigned long long) 1 << 16), 0xc0160000 }, /* TBL[47] */
  163. { ((unsigned long long) 1 << 17), 0x80160000 }, /* TBL[46] */
  164. { ((unsigned long long) 1 << 18), 0x40160000 }, /* TBL[45] */
  165. { ((unsigned long long) 1 << 19), 0x00160000 }, /* TBL[44] */
  166. { ((unsigned long long) 1 << 20), 0xc0140000 }, /* TBL[43] */
  167. { ((unsigned long long) 1 << 21), 0x80140000 }, /* TBL[42] */
  168. { ((unsigned long long) 1 << 22), 0x40140000 }, /* TBL[41] */
  169. { ((unsigned long long) 1 << 23), 0x00140000 }, /* TBL[40] */
  170. { ((unsigned long long) 1 << 24), 0xc0120000 }, /* TBL[39] */
  171. { ((unsigned long long) 1 << 25), 0x80120000 }, /* TBL[38] */
  172. { ((unsigned long long) 1 << 26), 0x40120000 }, /* TBL[37] */
  173. { ((unsigned long long) 1 << 27), 0x00120000 }, /* TBL[36] */
  174. { ((unsigned long long) 1 << 28), 0xc0100000 }, /* TBL[35] */
  175. { ((unsigned long long) 1 << 29), 0x80100000 }, /* TBL[34] */
  176. { ((unsigned long long) 1 << 30), 0x40100000 }, /* TBL[33] */
  177. { ((unsigned long long) 1 << 31), 0x00100000 }, /* TBL[32] */
  178. { ((unsigned long long) 1 << 32), 0xc00e0000 }, /* TBU[31] */
  179. { ((unsigned long long) 1 << 33), 0x800e0000 }, /* TBU[30] */
  180. { ((unsigned long long) 1 << 34), 0x400e0000 }, /* TBU[29] */
  181. { ((unsigned long long) 1 << 35), 0x000e0000 }, /* TBU[28] */
  182. { ((unsigned long long) 1 << 36), 0xc00c0000 }, /* TBU[27] */
  183. { ((unsigned long long) 1 << 37), 0x800c0000 }, /* TBU[26] */
  184. { ((unsigned long long) 1 << 38), 0x400c0000 }, /* TBU[25] */
  185. { ((unsigned long long) 1 << 39), 0x000c0000 }, /* TBU[24] */
  186. { ((unsigned long long) 1 << 40), 0xc00a0000 }, /* TBU[23] */
  187. { ((unsigned long long) 1 << 41), 0x800a0000 }, /* TBU[22] */
  188. { ((unsigned long long) 1 << 42), 0x400a0000 }, /* TBU[21] */
  189. { ((unsigned long long) 1 << 43), 0x000a0000 }, /* TBU[20] */
  190. { ((unsigned long long) 1 << 44), 0xc0080000 }, /* TBU[19] */
  191. { ((unsigned long long) 1 << 45), 0x80080000 }, /* TBU[18] */
  192. { ((unsigned long long) 1 << 46), 0x40080000 }, /* TBU[17] */
  193. { ((unsigned long long) 1 << 47), 0x00080000 }, /* TBU[16] */
  194. { ((unsigned long long) 1 << 48), 0xc0060000 }, /* TBU[15] */
  195. { ((unsigned long long) 1 << 49), 0x80060000 }, /* TBU[14] */
  196. { ((unsigned long long) 1 << 50), 0x40060000 }, /* TBU[13] */
  197. { ((unsigned long long) 1 << 51), 0x00060000 }, /* TBU[12] */
  198. { ((unsigned long long) 1 << 52), 0xc0040000 }, /* TBU[11] */
  199. { ((unsigned long long) 1 << 53), 0x80040000 }, /* TBU[10] */
  200. { ((unsigned long long) 1 << 54), 0x40040000 }, /* TBU[9]  */
  201. { ((unsigned long long) 1 << 55), 0x00040000 }, /* TBU[8]  */
  202. { ((unsigned long long) 1 << 56), 0xc0020000 }, /* TBU[7]  */
  203. { ((unsigned long long) 1 << 57), 0x80020000 }, /* TBU[6]  */
  204. { ((unsigned long long) 1 << 58), 0x40020000 }, /* TBU[5]  */
  205. { ((unsigned long long) 1 << 59), 0x00020000 }, /* TBU[4]  */
  206. { ((unsigned long long) 1 << 60), 0xc0000000 }, /* TBU[3]  */
  207. { ((unsigned long long) 1 << 61), 0x80000000 }, /* TBU[2]  */
  208. { ((unsigned long long) 1 << 62), 0x40000000 }, /* TBU[1]  */
  209. { ((unsigned long long) 1 << 63), 0x00000000 } /* TBU[0] */
  210.     };
  211. LOCAL int       sysClkTicksPerSecond    = 60;   /* default ticks/second */
  212. LOCAL FUNCPTR   sysClkRoutine           = NULL;
  213. LOCAL int       sysClkArg               = (int)NULL;
  214. LOCAL BOOL      sysClkConnectFirstTime  = TRUE;
  215. LOCAL BOOL      sysClkRunning           = FALSE;
  216. LOCAL int       sysAuxClkTicksPerSecond = 0;
  217. LOCAL FUNCPTR   sysAuxClkRoutine        = NULL;
  218. LOCAL int       sysAuxClkArg            = (int)NULL;
  219. LOCAL BOOL      sysAuxClkRunning        = FALSE;
  220. LOCAL int       sysWdtTicksPerSecond    = 0;
  221. LOCAL FUNCPTR   sysWdtRoutine           = NULL;
  222. LOCAL int       sysWdtArg               = (int)NULL;
  223. LOCAL BOOL      sysWdtRunning           = FALSE;
  224. LOCAL UINT32    decCountVal;                    /* DEC counter value */
  225. LOCAL UINT32    fitPeriodMask = 0x00000000;     /* used to set TCR[FP]      */
  226. LOCAL UINT32    wdtPeriodMask = 0x00000000;     /* used to set TCR[WP]      */
  227. #ifdef  INCLUDE_TIMESTAMP
  228. LOCAL BOOL      sysTimestampRunning = FALSE;    /* timestamp running flag */
  229. #endif  /* INCLUDE_TIMESTAMP */
  230. #define TCR_WP          (_PPC_TCR_WP_U    << 16)
  231. #define TCR_WP_EXT      (0x001e  << 16)
  232. #define TCR_WRC         (_PPC_TCR_WRC_U   << 16)
  233. #define TCR_WIE         (_PPC_TCR_WIE_U   << 16)
  234. #define TCR_DIE         (_PPC_TCR_DIE)
  235. #define TCR_FP          (_PPC_TCR_FP_U    << 16)
  236. #define TCR_FP_EXT      (0x0001e000)
  237. #define TCR_FIE         (_PPC_TCR_FIE_U   << 16)
  238. #define TCR_ARE         (_PPC_TCR_ARE_U   << 16)
  239. #define TSR_ENW         (_PPC_TSR_ENW_U   << 16)
  240. #define TSR_WIS         (_PPC_TSR_WIS_U   << 16)
  241. #define TSR_WRS         (_PPC_TSR_WRS_U   << 16)
  242. #define TSR_DIS         (_PPC_TSR_DIS)
  243. #define TSR_FIS         (_PPC_TSR_FIS_U   << 16)
  244. /***************************************************************************
  245. *
  246. * sysClkInt - clock interrupt handler
  247. *
  248. * This routine handles the clock interrupt on the PowerPC Book E
  249. * architecture. It is attached to the Programmable Interval Timer vector
  250. * by the routine sysClkConnect().
  251. *
  252. * RETURNS : N/A
  253. */
  254. LOCAL void sysClkInt (void)
  255.     {
  256.     /* Acknowledge DEC interrupt */
  257.     vxDecIntAck ();
  258.     /* The DEC reloads itself automatically from DECAR */
  259.     /* Execute the system clock routine */
  260.     if (sysClkRoutine != NULL)
  261.         (*(FUNCPTR) sysClkRoutine) (sysClkArg);
  262.     }
  263. /***************************************************************************
  264. *
  265. * sysClkConnect - connect a routine to the system clock interrupt
  266. *
  267. * This routine specifies the interrupt service routine to be called at
  268. * each clock interrupt. Normally, it is called from usrRoot() in
  269. * usrConfig.c to connect usrClock() to the system clock interrupt. It
  270. * also connects the clock error interrupt service routine.
  271. *
  272. * RETURNS: OK, or ERROR if the routine cannot be connected to the
  273. * interrupt.
  274. *
  275. * SEE ALSO: usrClock(), sysClkEnable()
  276. */
  277. STATUS sysClkConnect
  278.     (
  279.     FUNCPTR     routine,        /* routine to connect */
  280.     int         arg             /* argument with which to call the routine */
  281.     )
  282.     {
  283.     if (sysClkConnectFirstTime)
  284.         {
  285.         sysHwInit2();
  286.         sysClkConnectFirstTime = FALSE;
  287.         }
  288.     sysClkRoutine       = routine;
  289.     sysClkArg           = arg;
  290.     return (OK);
  291.     }
  292. /***************************************************************************
  293. *
  294. * sysClkEnable - turn on system clock interrupts
  295. *
  296. * This routine enables system clock interrupts.
  297. *
  298. * RETURNS: N/A
  299. *
  300. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  301. */
  302. void sysClkEnable (void)
  303.     {
  304.     if (!sysClkRunning)
  305.         {
  306.         /* clear the pending DEC interrupt */
  307.         vxTsrSet (TSR_DIS);
  308.         /* load the DEC counter and DECAR with interval value */
  309.         vxDecarSet (decCountVal);
  310.         vxDecSet (decCountVal);
  311.         /* Enable the DEC interrupt & enable autoreload */
  312.         vxTcrSet (vxTcrGet() | TCR_DIE | TCR_ARE);
  313. /* Enable the TBEN in HID0 */
  314. vxHid0Set (vxHid0Get() | _PPC_HID0_TBEN);
  315.         /* set the running flag */
  316.         sysClkRunning = TRUE;
  317.         }
  318.     }
  319. /***************************************************************************
  320. *
  321. * sysClkDisable - turn off system clock interrupts
  322. *
  323. * This routine disables system clock interrupts.
  324. *
  325. * RETURNS: N/A
  326. *
  327. * SEE ALSO: sysClkEnable()
  328. */
  329. void sysClkDisable (void)
  330.     {
  331.     if (sysClkRunning)
  332.         {
  333.         /* disable the DEC interrupt and auto-reload capability */
  334.         vxTcrSet (vxTcrGet() & ~ (TCR_DIE | TCR_ARE));
  335.         /* clear the DEC counter and DECAR */
  336.         vxDecSet (0);
  337.         /* clear the pending DEC interrupt */
  338.         vxTsrSet (TSR_DIS);
  339.         /* reset the running flag */
  340.         sysClkRunning = FALSE;
  341.         }
  342.     }
  343. /***************************************************************************
  344. *
  345. * sysClkRateGet - get the system clock rate
  346. *
  347. * This routine returns the system clock rate.
  348. *
  349. * RETURNS: The number of ticks per second of the system clock.
  350. *
  351. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  352. */
  353. int sysClkRateGet (void)
  354.     {
  355.     return (sysClkTicksPerSecond);
  356.     }
  357. /***************************************************************************
  358. *
  359. * sysClkRateSet - set the system clock rate
  360. *
  361. * This routine sets the interrupt rate of the system clock. It does not
  362. * enable system clock interrupts. It is called by usrRoot() in
  363. * usrConfig.c.
  364. *
  365. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot
  366. * be set.
  367. *
  368. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  369. */
  370. STATUS sysClkRateSet
  371.     (
  372.     int         ticksPerSecond  /* number of clock interrupts per second */
  373.     )
  374.     {
  375.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  376.         return (ERROR);
  377.     /* save the clock speed */
  378.     sysClkTicksPerSecond = ticksPerSecond;
  379.     /*
  380.      * compute the value to load in the decrementer. The new value will
  381.      * be loaded into the decrementer after the end of the current period
  382.      */
  383.     decCountVal = sysTimerClkFreq / ticksPerSecond;
  384.     /* Update the DEC interval  FIX 11/27/00 */
  385.     vxDecarSet (decCountVal);
  386.     vxDecSet (decCountVal);
  387.     return (OK);
  388.     }
  389. /***************************************************************************
  390. *
  391. * sysAuxClkInt - auxiliary clock interrupt handler
  392. *
  393. * This routine handles the auxiliary clock interrupt on the PowerPC Book E
  394. * architecture. It is attached to the Fix Interval Timer vector by the
  395. * routine sysAuxClkConnect().
  396. *
  397. * RETURNS : N/A
  398. */
  399. void sysAuxClkInt (void)
  400.     {
  401.     vxFitIntAck ();             /* acknowledge FIT interrupt */
  402.     /* program TCR with the FIT period */
  403.     vxTcrSet ((vxTcrGet() & ~(TCR_FP|TCR_FP_EXT)) | fitPeriodMask);
  404.     /* execute the system clock routine */
  405.     if (sysAuxClkRoutine != NULL)
  406.         (*(FUNCPTR) sysAuxClkRoutine) (sysAuxClkArg);
  407.     }
  408. /***************************************************************************
  409. *
  410. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  411. *
  412. * This routine specifies the interrupt service routine to be called at
  413. * each auxiliary clock interrupt. It does not enable auxiliary clock
  414. * interrupts.
  415. *
  416. * RETURNS: OK, or ERROR if the routine cannot be connected to the
  417. * interrupt.
  418. *
  419. * SEE ALSO: excIntConnectTimer(), sysAuxClkEnable()
  420. */
  421. STATUS sysAuxClkConnect
  422.     (
  423.     FUNCPTR     routine, /* routine called at each aux. clock interrupt */
  424.     int         arg      /* argument to auxiliary clock interrupt */
  425.     )
  426.     {
  427.     sysAuxClkRoutine    = routine;
  428.     sysAuxClkArg        = arg;
  429.     return (OK);
  430.     }
  431. /***************************************************************************
  432. *
  433. * sysAuxClkEnable - turn on auxiliary clock interrupts
  434. *
  435. * This routine enables auxiliary clock interrupts.
  436. *
  437. * RETURNS: N/A
  438. *
  439. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  440. */
  441. void sysAuxClkEnable (void)
  442.     {
  443.     if (!sysAuxClkRunning)
  444.         {
  445.         /* clear the pending FIT interrupt */
  446.         vxTsrSet (TSR_FIS);
  447.         /* program TCR with the FIT period */
  448.         vxTcrSet ((vxTcrGet() & ~(TCR_FP|TCR_FP_EXT)) | fitPeriodMask);
  449.         /* Enable the FIT interrupt */
  450.         vxTcrSet (vxTcrGet() | TCR_FIE);
  451.         /* set the running flag */
  452.         sysAuxClkRunning = TRUE;
  453.         }
  454.     }
  455. /***************************************************************************
  456. *
  457. * sysAuxClkDisable - turn off auxiliary clock interrupts
  458. *
  459. * This routine disables auxiliary clock interrupts.
  460. *
  461. *
  462. * RETURNS: N/A
  463. *
  464. * SEE ALSO: sysAuxClkEnable()
  465. */
  466. void sysAuxClkDisable (void)
  467.     {
  468.     if (sysAuxClkRunning)
  469.         {
  470.         /* disable the FIT interrupt */
  471.         vxTcrSet (vxTcrGet() & (~TCR_FIE));
  472.         /* clear the pending FIT interrupt */
  473.         vxTsrSet (TSR_FIS);
  474.         /* reset the running flag */
  475.         sysAuxClkRunning = FALSE;
  476.         }
  477.     }
  478. /***************************************************************************
  479. *
  480. * sysAuxClkRateGet - get the auxiliary clock rate
  481. *
  482. * This routine returns the interrupt rate of the auxiliary clock.
  483. *
  484. * RETURNS: The number of ticks per second of the auxiliary clock.
  485. *
  486. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  487. */
  488. int sysAuxClkRateGet (void)
  489.     {
  490.     return (sysAuxClkTicksPerSecond);
  491.     }
  492. /***************************************************************************
  493. *
  494. * sysAuxClkRateSet - set the auxiliary clock rate
  495. *
  496. * This routine sets the interrupt rate of the auxiliary clock. It does
  497. * not enable auxiliary clock interrupts.
  498. *
  499. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot
  500. * be set.
  501. *
  502. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  503. */
  504. STATUS sysAuxClkRateSet
  505.     (
  506.     int         ticksPerSecond  /* number of clock interrupts per second */
  507.     )
  508.     {
  509.     int ix;
  510.     int jx = 0;
  511.     unsigned long long fitPeriod;
  512.     /*
  513.      * compute the FIT period.  The closest value to <ticksPerSecond>
  514.      * is being used.
  515.      */
  516.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  517.         return (ERROR);
  518.     fitPeriod = (sysTimerClkFreq >> 1) / ticksPerSecond;
  519.     /* get the closest value to ticksPerSecond supported by the FIT */
  520.     for (ix = 0; ix < (int) NELEMENTS (fitTable); ix++)
  521.         {
  522.         if (fitPeriod <= fitTable [ix].fitPeriod)
  523.             {
  524.             if (ix != 0)
  525.                 if ( fitPeriod <
  526.                      ((fitTable [ix].fitPeriod + fitTable [ix-1].fitPeriod)/2))
  527.                     jx = ix-1;
  528.                 else
  529.                     jx = ix;
  530.             else
  531.                 jx = ix;
  532.             break;
  533.             }
  534.         if (ix == NELEMENTS (fitTable) - 1)
  535.             jx = ix;
  536.         }
  537.     fitPeriod = fitTable [jx].fitPeriod;        /* actual period of the FIT */
  538.     fitPeriodMask = fitTable [jx].fpMask;       /* Mask to program TCR with */
  539.     /* save the clock speed */
  540.     sysAuxClkTicksPerSecond = (sysTimerClkFreq >> 1) / fitPeriod;
  541.     return (OK);
  542.     }
  543. /***************************************************************************
  544. *
  545. * sysWdtInt - watchdog interrupt handler.
  546. *
  547. * This routine handles the watchdog interrupt on the PowerPC Book E
  548. * architecture. It is attached to the watchdog timer vector by the
  549. * routine sysWdtConnect().
  550. *
  551. * RETURNS : N/A
  552. */
  553. LOCAL void sysWdtInt (void)
  554.     {
  555.     /* acknowledge WDT interrupt */
  556.     vxTsrSet (TSR_WIS);
  557.     /* execute the watchdog  clock routine */
  558.     if (sysWdtRoutine != NULL)
  559.         (*(FUNCPTR) sysWdtRoutine) (sysWdtArg);
  560.     }
  561. /***************************************************************************
  562. *
  563. * sysWdtConnect - connect a routine to the watchdog interrupt
  564. *
  565. * This routine specifies the interrupt service routine to be called at
  566. * each watchdog interrupt. It does not enable watchdog interrupts.
  567. *
  568. * RETURNS: OK, or ERROR if the routine cannot be connected to the
  569. * watchdog
  570. * interrupt.
  571. *
  572. * SEE ALSO: excIntCrtConnect(), sysWdtEnable()
  573. */
  574. STATUS sysWdtConnect
  575.     (
  576.     FUNCPTR     routine, /* routine called at each watchdog interrupt */
  577.     int         arg      /* argument with which to call routine        */
  578.     )
  579.     {
  580.     /* connect the routine to the WDT vector */
  581.     excIntCrtConnect ((VOIDFUNCPTR *) _EXC_OFF_WD, (VOIDFUNCPTR) sysWdtInt);
  582.     sysWdtRoutine    = routine;
  583.     sysWdtArg        = arg;
  584.     return (OK);
  585.     }
  586. /***************************************************************************
  587. *
  588. * sysWdtEnable - turn on watchdog interrupts
  589. *
  590. * This routine enables watchdog interrupts.
  591. *
  592. * RETURNS: N/A
  593. *
  594. * SEE ALSO: sysWdtConnect(), sysWdtDisable(), sysWdtRateSet()
  595. */
  596. void sysWdtEnable (void)
  597.     {
  598.     if (!sysWdtRunning)
  599.         {
  600.         /* clear the pending WDT interrupt */
  601.         vxTsrSet (TSR_WIS);
  602.         /* program TCR with the WDT period */
  603.         vxTcrSet ((vxTcrGet() & ~(TCR_WP|TCR_WP_EXT)) | wdtPeriodMask);
  604.         /* Enable the WDT interrupt */
  605.         vxTcrSet (vxTcrGet() | TCR_WIE);
  606.         /* Enable critical interrupt */
  607.         vxMsrSet (vxMsrGet() | _PPC_MSR_CE);
  608.         /* set the running flag */
  609.         sysWdtRunning = TRUE;
  610.         }
  611.     }
  612. /***************************************************************************
  613. *
  614. * sysWdtDisable - turn off watchdog interrupts
  615. *
  616. * This routine disables watchdog interrupts. This routine does not
  617. * disable critical interrupts.
  618. *
  619. * RETURNS: N/A
  620. *
  621. * SEE ALSO: sysWdtEnable()
  622. */
  623. void sysWdtDisable (void)
  624.     {
  625.     if (sysWdtRunning)
  626.         {
  627.         /* disable the WDT interrupt */
  628.         vxTcrSet (vxTcrGet() & ~ (TCR_WIE));
  629.         /* clear the pending WDT interrupt */
  630.         vxTsrSet (TSR_WIS);
  631.         /* reset the running flag */
  632.         sysWdtRunning = FALSE;
  633.         }
  634.     }
  635. /***************************************************************************
  636. *
  637. * sysWdtRateGet - get the watchdog timer rate
  638. *
  639. * This routine returns the interrupt rate of the watchdog timer.
  640. *
  641. * RETURNS: The number of watchdog interrupts per second.
  642. *
  643. * SEE ALSO: sysWdtEnable(), sysWdtRateSet()
  644. */
  645. int sysWdtRateGet (void)
  646.     {
  647.     return (sysWdtTicksPerSecond);
  648.     }
  649. /***************************************************************************
  650. *
  651. * sysWdtRateSet - set the watchdog timer rate
  652. *
  653. * This routine sets the interrupt rate of the watchdog timer. It does
  654. * not enable watchdog interrupts.
  655. *
  656. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot
  657. * be set.
  658. *
  659. * SEE ALSO: sysWdtEnable(), sysWdtRateGet()
  660. */
  661. STATUS sysWdtRateSet
  662.     (
  663.     int         ticksPerSecond  /* number of clock interrupts per second */
  664.     )
  665.     {
  666.     int ix;
  667.     int jx = 0;
  668.     unsigned long long wdtPeriod;
  669.     /*
  670.      * compute the WDT period.
  671.      * only 4 values are possible (cf wdtTable[]). The closest value to
  672.      * <ticksPerSecond> is being used.
  673.      */
  674.     if ((ticksPerSecond < (int) WDT_RATE_MIN) ||
  675.         (ticksPerSecond > (int) WDT_RATE_MAX))
  676.         return (ERROR);
  677.     wdtPeriod = (sysTimerClkFreq >> 1) / ticksPerSecond;
  678.     /* get the closest value to ticksPerSecond supported by the WDT */
  679.     for (ix = 0; ix < (int) NELEMENTS (wdtTable); ix++)
  680.         {
  681.         if (wdtPeriod <= wdtTable [ix].wdtPeriod)
  682.             {
  683.             if (ix != 0)
  684.                 if ( wdtPeriod <
  685.                      ((wdtTable [ix].wdtPeriod + wdtTable [ix-1].wdtPeriod)/2))
  686.                     jx = ix-1;
  687.                 else
  688.                     jx = ix;
  689.             else
  690.                 jx = ix;
  691.             break;
  692.             }
  693.         if (ix == NELEMENTS (wdtTable) - 1)
  694.             jx = ix;
  695.         }
  696.     wdtPeriod = wdtTable [jx].wdtPeriod;        /* actual period of the WDT */
  697.     wdtPeriodMask = wdtTable [jx].fpMask;       /* Mask to program TCR with */
  698.     /* save the clock speed */
  699.     sysWdtTicksPerSecond = (sysTimerClkFreq >> 1) / wdtPeriod;
  700.     return (OK);
  701.     }
  702. #ifdef  INCLUDE_TIMESTAMP
  703. /***************************************************************************
  704. *
  705. * sysTimestampConnect - connect a user routine to a timestamp timer interrupt
  706. *
  707. * This routine specifies the user interrupt routine to be called at each
  708. * timestamp timer interrupt. In this case, however, the timestamp timer
  709. * interrupt is not used since the on-chip timer is also used by the
  710. * system clock.
  711. *
  712. * RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not
  713. * used.
  714. */
  715. STATUS sysTimestampConnect
  716.     (
  717.     FUNCPTR     routine, /* routine called at each timestamp timer interrupt */
  718.     int         arg      /* argument with which to call routine */
  719.     )
  720.     {
  721.     return (ERROR);
  722.     }
  723. /***************************************************************************
  724. *
  725. * sysTimestampEnable - initialize and enable a timestamp timer
  726. *
  727. * This routine disables the timestamp timer interrupt and initializes
  728. * the counter registers. If the timestamp timer is already running, this
  729. * routine merely resets the timer counter.
  730. *
  731. * This routine does not initialize the timer rate. The rate of the
  732. * timestamp timer should be set explicitly in the BSP by sysHwInit().
  733. *
  734. * RETURNS: OK, or ERROR if the timestamp timer cannot be enabled.
  735. */
  736. STATUS sysTimestampEnable (void)
  737.    {
  738.    if (sysTimestampRunning)
  739.       {
  740.       return (OK);
  741.       }
  742.    if (!sysClkRunning)
  743.       return (ERROR);
  744.    sysTimestampRunning = TRUE;
  745.    return (OK);
  746.    }
  747. /*******************************************************************************
  748. *
  749. * sysTimestampDisable - disable a timestamp timer
  750. *
  751. * This routine disables the timestamp timer. Interrupts are not
  752. * disabled; however, because the tick counter does not increment after
  753. * the timestamp timer is disabled, interrupts no longer are generated.
  754. *
  755. * RETURNS: OK, or ERROR if the timestamp timer cannot be disabled.
  756. */
  757. STATUS sysTimestampDisable (void)
  758.     {
  759.     if (sysTimestampRunning)
  760.         sysTimestampRunning = FALSE;
  761.     return (OK);
  762.     }
  763. /*******************************************************************************
  764. *
  765. * sysTimestampPeriod - get a timestamp timer period
  766. *
  767. * This routine specifies the period of the timestamp timer, in ticks.
  768. * The period, or terminal count, is the number of ticks to which the
  769. * timestamp timer counts before rolling over and restarting the counting
  770. * process.
  771. *
  772. * RETURNS: The period of the timestamp timer in counter ticks.
  773. */
  774. UINT32 sysTimestampPeriod (void)
  775.     {
  776.     /*
  777.      * The period of the timestamp depends on the clock rate of the
  778.      * on-chip timer (ie the Decrementer reload value).
  779.      */
  780.     return (decCountVal);
  781.     }
  782. /*******************************************************************************
  783. *
  784. * sysTimestampFreq - get a timestamp timer clock frequency
  785. *
  786. * This routine specifies the frequency of the timer clock, in ticks per
  787. * second. The rate of the timestamp timer should be set explicitly in
  788. * the BSP by sysHwInit().
  789. *
  790. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  791. */
  792. UINT32 sysTimestampFreq (void)
  793.     {
  794.     return (sysTimerClkFreq);
  795.     }
  796. /*******************************************************************************
  797. *
  798. * sysTimestamp - get a timestamp timer tick count
  799. *
  800. * This routine returns the current value of the timestamp timer tick
  801. * counter. The tick count can be converted to seconds by dividing by the
  802. * return of sysTimestampFreq().
  803. *
  804. * This routine should be called with interrupts locked. If interrupts
  805. * are not locked, sysTimestampLock() should be used instead.
  806. *
  807. * RETURNS: The current timestamp timer tick count.
  808. *
  809. * SEE ALSO: sysTimestampFreq(), sysTimestampLock()
  810. */
  811. UINT32 sysTimestamp (void)
  812.     {
  813.     return (decCountVal - (UINT32) vxDecGet());
  814.     }
  815. /***************************************************************************
  816. *
  817. * sysTimestampLock - lock an interrupt and get a timestamp timer tick count
  818. *
  819. * This routine locks interrupts when stop the tick counter must be
  820. * stopped in order to read it or when two independent counters must be
  821. * read. It then returns the current value of the timestamp timer tick
  822. * counter.
  823. *
  824. * The tick count can be converted to seconds by dividing by the return
  825. * of sysTimestampFreq().
  826. *
  827. * If interrupts are already locked, sysTimestamp() should be used
  828. * instead.
  829. *
  830. * RETURNS: The current timestamp timer tick count.
  831. *
  832. * SEE ALSO: sysTimestamp()
  833. */
  834. UINT32 sysTimestampLock (void)
  835.     {
  836.     UINT32 currentDecValue;
  837.     int oldLevel;
  838.     oldLevel = intLock ();                              /* LOCK INTERRUPT */
  839.     currentDecValue = vxDecGet();
  840.     intUnlock (oldLevel);                               /* UNLOCK INTERRUPT */
  841.     return (decCountVal - currentDecValue);
  842.     }
  843. #endif  /* INCLUDE_TIMESTAMP */