loApicTimer.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:21k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* loApicTimer.c - Intel Pentium[234] local APIC timer library */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01f,30nov01,hdn  doc update for 5.5
  8. 01e,24oct01,hdn  merged with VxAE 1.1
  9. 01d,12sep01,hdn  renamed TIMER_INT_VEC to INT_NUM_LOAPIC_TIMER
  10.  renamed TIMER_CLOCK_HZ to APIC_TIMER_CLOCK_HZ
  11. 01c,05sep01,hdn  shutoff the warning by changing NULL to 0
  12. 01b,21may98,hdn  re-written
  13. 01a,13jun97,sub  written
  14. */
  15. /*
  16. DESCRIPTION
  17. This library contains routines for the timer in the Intel local APIC/xAPIC 
  18. (Advanced Programmable Interrupt Controller) in P6 (PentiumPro, II, III)
  19. and P7 (Pentium4) family processor.
  20. The local APIC contains a 32-bit programmable timer for use by the local
  21. processor.  This timer is configured through the timer register in the local
  22. vector table.  The time base is derived from the processor's bus clock, 
  23. divided by a value specified in the divide configuration register. 
  24. After reset, the timer is initialized to zero.  The timer supports one-shot
  25. and periodic modes.  The timer can be configured to interrupt the local
  26. processor with an arbitrary vector.
  27. This library gets the system clock from the local APIC timer and auxClock
  28. from either RTC or PIT channel 0 (define PIT0_FOR_AUX in the BSP).
  29. The macro APIC_TIMER_CLOCK_HZ must also be defined to indicate the clock 
  30. frequency of the local APIC Timer.
  31. The parameters SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  32. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  33. sys[Aux]ClkRateSet() routines.
  34. This driver uses processor's on-chip TSC (Time Stamp Counter) for the
  35. time stamp driver.  The TSC is a 64-bit time-stamp counter that is
  36. incremented every processor clock cycle.  The counter is incremented even
  37. when the processor is halted by the HLT instruction or the external STPCLK#
  38. pin.  The time-stamp counter is set to 0 following a hardware reset of the
  39. processor.  The RDTSC instruction reads the time stamp counter and is
  40. guaranteed to return a monotonically increasing unique value whenever
  41. executed, except for 64-bit counter wraparound.  Intel guarantees,
  42. architecturally, that the time-stamp counter frequency and configuration will
  43. be such that it will not wraparound within 10 years after being reset to 0.
  44. The period for counter wrap is several thousands of years in the P6 (PentiumPro,
  45. II, III) and P7 (Pentium4) family processors.
  46. */
  47. /* includes */
  48. #include "vxWorks.h"
  49. #include "sysLib.h"
  50. #include "intLib.h"
  51. #include "taskLib.h"
  52. #include "arch/i86/pentiumLib.h"
  53. #include "drv/intrCtl/loApic.h"
  54. #include "drv/timer/mc146818.h"
  55. /* locals */
  56. LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock interrupt */
  57. LOCAL int sysClkArg = 0; /* its argument */
  58. LOCAL int sysClkRunning = FALSE;
  59. LOCAL int sysClkConnected = FALSE;
  60. LOCAL int sysClkTicksPerSecond = 60;
  61. LOCAL FUNCPTR sysAuxClkRoutine = NULL;
  62. LOCAL int sysAuxClkArg = 0;
  63. LOCAL int sysAuxClkRunning = FALSE;
  64. #ifdef PIT0_FOR_AUX
  65. LOCAL int sysAuxClkTicksPerSecond = 60;
  66. #else
  67. LOCAL int sysAuxClkTicksPerSecond = 64;
  68. LOCAL CLK_RATE auxTable[] =
  69.     {
  70.     {   2, 0x0f}, 
  71.     {   4, 0x0e}, 
  72.     {   8, 0x0d}, 
  73.     {  16, 0x0c}, 
  74.     {  32, 0x0b}, 
  75.     {  64, 0x0a}, 
  76.     { 128, 0x09}, 
  77.     { 256, 0x08}, 
  78.     { 512, 0x07}, 
  79.     {1024, 0x06}, 
  80.     {2048, 0x05}, 
  81.     {4096, 0x04}, 
  82.     {8192, 0x03} 
  83.     };
  84. #endif /* PIT0_FOR_AUX */
  85. #ifdef INCLUDE_TIMESTAMP_TSC 
  86. LOCAL BOOL sysTimestampRunning = FALSE; /* running flag */
  87. LOCAL int sysTimestampPeriodValue = 0;  /* Max counter value */
  88. LOCAL FUNCPTR sysTimestampRoutine = NULL;  /* user rollover routine */
  89. LOCAL int    sysTimestampTickCount = 0;  /* system ticks counter */
  90. LOCAL UINT32 sysTimestampFreqValue = PENTIUMPRO_TSC_FREQ; /* TSC clock */
  91. LOCAL void sysTimestampFreqGet (void);
  92. #endif /* INCLUDE_TIMESTAMP_TSC */
  93. /*******************************************************************************
  94. *
  95. * sysClkInt - interrupt level processing for system clock
  96. *
  97. * This routine handles the system clock interrupt.  It is attached to the
  98. * clock interrupt vector by the routine sysClkConnect().
  99. */
  100. void sysClkInt (void)
  101.     {
  102.     /* reset TSC */
  103. #ifdef INCLUDE_TIMESTAMP_TSC 
  104.     if (sysTimestampRoutine != NULL)
  105. (* sysTimestampRoutine) ();
  106. #endif /* INCLUDE_TIMESTAMP_TSC */
  107.     /* acknowledge interrupt */
  108.     if (sysClkRoutine != NULL)
  109. (* sysClkRoutine) (sysClkArg);
  110.     }
  111. /*******************************************************************************
  112. *
  113. * sysClkConnect - connect a routine to the system clock interrupt
  114. *
  115. * This routine specifies the interrupt service routine to be called at each
  116. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to 
  117. * connect usrClock() to the system clock interrupt.
  118. *
  119. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  120. *
  121. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  122. */
  123. STATUS sysClkConnect
  124.     (
  125.     FUNCPTR routine, /* routine to be called at each clock interrupt */
  126.     int arg /* argument with which to call routine */
  127.     )
  128.     {
  129. #ifdef _WRS_VXWORKS_5_X
  130.     if (sysClkConnected == FALSE)
  131. sysHwInit2 (); /* VxAE does this in the prjConfig */
  132. #endif /* _WRS_VXWORKS_5_X */
  133.     sysClkRoutine   = routine;
  134.     sysClkArg     = arg;
  135.     sysClkConnected = TRUE;
  136.     return (OK);
  137.     }
  138. /*******************************************************************************
  139. *
  140. * sysClkDisable - turn off system clock interrupts
  141. *
  142. * This routine disables system clock interrupts.
  143. *
  144. * RETURNS: N/A
  145. *
  146. * SEE ALSO: sysClkEnable()
  147. */
  148. void sysClkDisable (void)
  149.     {
  150.     int oldLevel;
  151.     if (sysClkRunning)
  152. {
  153.         oldLevel = intLock (); /* LOCK INTERRUPT */
  154. /* mask interrupt and reset the Initial Counter */
  155. *(int *)(loApicBase + LOAPIC_TIMER) |= LOAPIC_MASK;
  156. *(int *)(loApicBase + LOAPIC_TIMER_ICR) = 0;
  157.         intUnlock (oldLevel); /* UNLOCK INTERRUPT */
  158. sysClkRunning = FALSE;
  159. }
  160.     }
  161. /*******************************************************************************
  162. *
  163. * sysClkEnable - turn on system clock interrupts
  164. *
  165. * This routine enables system clock interrupts.
  166. *
  167. * RETURNS: N/A
  168. *
  169. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  170. */
  171. void sysClkEnable (void)
  172.     {
  173.     int oldLevel;
  174.     int count;
  175.     if (!sysClkRunning)
  176. {
  177. count = ((APIC_TIMER_CLOCK_HZ) / sysClkTicksPerSecond) - 1;
  178.         oldLevel = intLock (); /* LOCK INTERRUPT */
  179. /* set a divide value in the Configuration Register */
  180. *(int *)(loApicBase + LOAPIC_TIMER_CONFIG) = 
  181. (*(int *)(loApicBase + LOAPIC_TIMER_CONFIG) & ~0xf) | 
  182.           LOAPIC_TIMER_DIVBY_1;
  183. /* set a initial count in the Initial Count Register */
  184. *(int *)(loApicBase + LOAPIC_TIMER_ICR) = count ;
  185. /* set the vector in the local vector table (Timer) */
  186. *(int *)(loApicBase + LOAPIC_TIMER) = 
  187. (*(int *)(loApicBase + LOAPIC_TIMER) & 0xfffcff00) |
  188.  INT_NUM_LOAPIC_TIMER | LOAPIC_TIMER_PERIODIC;
  189. #ifdef INCLUDE_TIMESTAMP_TSC 
  190. sysTimestampRoutine = (FUNCPTR)pentiumTscReset;
  191. #endif /* INCLUDE_TIMESTAMP_TSC */
  192.         intUnlock (oldLevel); /* UNLOCK INTERRUPT */
  193. sysClkRunning = TRUE;
  194. #ifdef INCLUDE_TIMESTAMP_TSC 
  195. if (sysTimestampFreqValue == 0) /* get TSC freq */
  196.     {
  197.     FUNCPTR oldFunc = sysTimestampRoutine;
  198.     sysTimestampRoutine = (FUNCPTR)sysTimestampFreqGet;
  199.     taskDelay (sysClkTicksPerSecond + 5); /* wait 1 sec */
  200.     sysTimestampRoutine = oldFunc;
  201.     }
  202. #endif /* INCLUDE_TIMESTAMP_TSC */
  203. }
  204.     }
  205. /*******************************************************************************
  206. *
  207. * sysClkRateGet - get the system clock rate
  208. *
  209. * This routine returns the system clock rate.
  210. *
  211. * RETURNS: The number of ticks per second of the system clock.
  212. *
  213. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  214. */
  215. int sysClkRateGet (void)
  216.     {
  217.     return (sysClkTicksPerSecond);
  218.     }
  219. /*******************************************************************************
  220. *
  221. * sysClkRateSet - set the system clock rate
  222. *
  223. * This routine sets the interrupt rate of the system clock.
  224. * It is called by usrRoot() in usrConfig.c.
  225. *
  226. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  227. *
  228. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  229. */
  230. STATUS sysClkRateSet
  231.     (
  232.     int ticksPerSecond     /* number of clock interrupts per second */
  233.     )
  234.     {
  235.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  236. return (ERROR);
  237.     sysClkTicksPerSecond = ticksPerSecond;
  238.     if (sysClkRunning)
  239. {
  240. sysClkDisable ();
  241. sysClkEnable ();
  242. }
  243.     return (OK);
  244.     }
  245. #ifdef PIT0_FOR_AUX
  246. /*******************************************************************************
  247. *
  248. * sysAuxClkInt - handle an auxiliary clock interrupt
  249. *
  250. * This routine handles an auxiliary clock interrupt.  It acknowledges the
  251. * interrupt and calls the routine installed by sysAuxClkConnect().
  252. *
  253. * RETURNS: N/A
  254. */
  255. void sysAuxClkInt (void)
  256.     {
  257.     /* call auxiliary clock service routine */
  258.     if (sysAuxClkRoutine != NULL)
  259. (*sysAuxClkRoutine) (sysAuxClkArg);
  260.     }
  261. /*******************************************************************************
  262. *
  263. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  264. *
  265. * This routine specifies the interrupt service routine to be called at each
  266. * auxiliary clock interrupt.  It does not enable auxiliary clock interrupts.
  267. *
  268. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  269. *
  270. * SEE ALSO: intConnect(), sysAuxClkEnable()
  271. */
  272. STATUS sysAuxClkConnect
  273.     (
  274.     FUNCPTR routine,    /* routine called at each aux clock interrupt    */
  275.     int arg             /* argument to auxiliary clock interrupt routine */
  276.     )
  277.     {
  278.     sysAuxClkRoutine = routine;
  279.     sysAuxClkArg = arg;
  280.     return (OK);
  281.     }
  282. /*******************************************************************************
  283. *
  284. * sysAuxClkDisable - turn off auxiliary clock interrupts
  285. *
  286. * This routine disables auxiliary clock interrupts.
  287. *
  288. * RETURNS: N/A
  289. *
  290. * SEE ALSO: sysAuxClkEnable()
  291. */
  292. void sysAuxClkDisable (void)
  293.     {
  294.     if (sysAuxClkRunning)
  295.         {
  296. sysOutByte (PIT_CMD (PIT_BASE_ADR), 0x38);
  297. sysOutByte (PIT_CNT0 (PIT_BASE_ADR), LSB(0));
  298. sysOutByte (PIT_CNT0 (PIT_BASE_ADR), MSB(0));
  299. sysIntDisablePIC (PIT0_INT_LVL);
  300. sysAuxClkRunning = FALSE;
  301.         }
  302.     }
  303. /*******************************************************************************
  304. *
  305. * sysAuxClkEnable - turn on auxiliary clock interrupts
  306. *
  307. * This routine enables auxiliary clock interrupts.
  308. *
  309. * RETURNS: N/A
  310. *
  311. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  312. */
  313. void sysAuxClkEnable (void)
  314.     {
  315.     UINT tc;
  316.     if (!sysAuxClkRunning)
  317. {
  318. tc = PIT_CLOCK / sysAuxClkTicksPerSecond;
  319. sysOutByte (PIT_CMD (PIT_BASE_ADR), 0x36);
  320. sysOutByte (PIT_CNT0 (PIT_BASE_ADR), LSB(tc));
  321. sysOutByte (PIT_CNT0 (PIT_BASE_ADR), MSB(tc));
  322. /* enable clock interrupt */
  323. sysIntEnablePIC (PIT0_INT_LVL);
  324. sysAuxClkRunning = TRUE;
  325. }
  326.     }
  327. /*******************************************************************************
  328. *
  329. * sysAuxClkRateGet - get the auxiliary clock rate
  330. *
  331. * This routine returns the interrupt rate of the auxiliary clock.
  332. *
  333. * RETURNS: The number of ticks per second of the auxiliary clock.
  334. *
  335. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  336. */
  337. int sysAuxClkRateGet (void)
  338.     {
  339.     return (sysAuxClkTicksPerSecond);
  340.     }
  341. /*******************************************************************************
  342. *
  343. * sysAuxClkRateSet - set the auxiliary clock rate
  344. *
  345. * This routine sets the interrupt rate of the auxiliary clock.  It does not
  346. * enable auxiliary clock interrupts.
  347. *
  348. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  349. *
  350. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  351. */
  352. STATUS sysAuxClkRateSet
  353.     (
  354.     int ticksPerSecond  /* number of clock interrupts per second */
  355.     )
  356.     {
  357.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  358.         return (ERROR);
  359.     sysAuxClkTicksPerSecond = ticksPerSecond;
  360.     if (sysAuxClkRunning)
  361. {
  362. sysAuxClkDisable ();
  363. sysAuxClkEnable ();
  364. }
  365.     return (OK);
  366.     }
  367. #else /* PIT0_FOR_AUX */
  368. /*******************************************************************************
  369. *
  370. * sysAuxClkInt - handle an auxiliary clock interrupt
  371. *
  372. * This routine handles an auxiliary clock interrupt.  It acknowledges the
  373. * interrupt and calls the routine installed by sysAuxClkConnect().
  374. *
  375. * RETURNS: N/A
  376. */
  377. void sysAuxClkInt (void)
  378.     {
  379.     int oldLevel;
  380.     /* acknowledge the interrupt */
  381.     oldLevel = intLock (); /* LOCK INTERRUPT */
  382.     sysOutByte (RTC_INDEX, MC146818_STATUS_C);
  383.     sysInByte (RTC_DATA);
  384.     intUnlock (oldLevel); /* UNLOCK INTERRUPT */
  385.     /* call auxiliary clock service routine */
  386.     if (sysAuxClkRoutine != NULL)
  387. (*sysAuxClkRoutine) (sysAuxClkArg);
  388.     }
  389. /*******************************************************************************
  390. *
  391. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  392. *
  393. * This routine specifies the interrupt service routine to be called at each
  394. * auxiliary clock interrupt.  It does not enable auxiliary clock interrupts.
  395. *
  396. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  397. *
  398. * SEE ALSO: intConnect(), sysAuxClkEnable()
  399. */
  400. STATUS sysAuxClkConnect
  401.     (
  402.     FUNCPTR routine,    /* routine called at each aux clock interrupt */
  403.     int arg             /* argument to auxiliary clock interrupt routine */
  404.     )
  405.     {
  406.     sysAuxClkRoutine = routine;
  407.     sysAuxClkArg = arg;
  408.     return (OK);
  409.     }
  410. /*******************************************************************************
  411. *
  412. * sysAuxClkDisable - turn off auxiliary clock interrupts
  413. *
  414. * This routine disables auxiliary clock interrupts.
  415. *
  416. * RETURNS: N/A
  417. *
  418. * SEE ALSO: sysAuxClkEnable()
  419. */
  420. void sysAuxClkDisable (void)
  421.     {
  422.     if (sysAuxClkRunning)
  423.         {
  424. /* disable interrupts */
  425. sysOutByte (RTC_INDEX, MC146818_STATUS_B);
  426. sysOutByte (RTC_DATA, MC146818_24);
  427. sysIntDisablePIC (RTC_INT_LVL);
  428. sysAuxClkRunning = FALSE;
  429.         }
  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.     int ix;
  444.     char statusA;
  445.     int oldLevel;
  446.     if (!sysAuxClkRunning)
  447.         {
  448. /* set an interrupt rate */
  449. for (ix = 0; ix < NELEMENTS (auxTable); ix++)
  450.     {
  451.     if (auxTable [ix].rate == sysAuxClkTicksPerSecond)
  452. {
  453.         sysOutByte (RTC_INDEX, MC146818_STATUS_A);
  454.         statusA = sysInByte (RTC_DATA) & ~MC146818_RS_BITS;
  455.         sysOutByte (RTC_INDEX, MC146818_STATUS_A);
  456.         sysOutByte (RTC_DATA, statusA | auxTable [ix].bits);
  457. break;
  458. }
  459.     }
  460. /* start the timer */
  461.         oldLevel = intLock (); /* LOCK INTERRUPT */
  462.         sysOutByte (RTC_INDEX, MC146818_STATUS_C); /* clear Int Flags */
  463.         sysInByte (RTC_DATA);
  464. sysOutByte (RTC_INDEX, MC146818_STATUS_B); /* set PIE */
  465. sysOutByte (RTC_DATA, MC146818_PIE | MC146818_24);
  466. sysIntEnablePIC (RTC_INT_LVL);
  467. sysAuxClkRunning = TRUE;
  468.         intUnlock (oldLevel); /* UNLOCK INTERRUPT */
  469. }
  470.     }
  471. /*******************************************************************************
  472. *
  473. * sysAuxClkRateGet - get the auxiliary clock rate
  474. *
  475. * This routine returns the interrupt rate of the auxiliary clock.
  476. *
  477. * RETURNS: The number of ticks per second of the auxiliary clock.
  478. *
  479. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  480. */
  481. int sysAuxClkRateGet (void)
  482.     {
  483.     return (sysAuxClkTicksPerSecond);
  484.     }
  485. /*******************************************************************************
  486. *
  487. * sysAuxClkRateSet - set the auxiliary clock rate
  488. *
  489. * This routine sets the interrupt rate of the auxiliary clock.  It does not
  490. * enable auxiliary clock interrupts.
  491. *
  492. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  493. *
  494. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  495. */
  496. STATUS sysAuxClkRateSet
  497.     (
  498.     int ticksPerSecond  /* number of clock interrupts per second */
  499.     )
  500.     {
  501.     int ix; /* hold temporary variable */
  502.     BOOL match; /* hold the match status */
  503.     match = FALSE;  /* initialize to false */
  504.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  505.         return (ERROR);
  506.     for (ix = 0; ix < NELEMENTS (auxTable); ix++)
  507. {
  508. if (auxTable [ix].rate == ticksPerSecond)
  509.     {
  510.     sysAuxClkTicksPerSecond = ticksPerSecond;
  511.     match = TRUE;
  512.     break;
  513.     }
  514. }
  515.     if (!match) /* ticksPerSecond not matching the values in table */
  516.        return (ERROR);
  517.     if (sysAuxClkRunning)
  518. {
  519. sysAuxClkDisable ();
  520. sysAuxClkEnable ();
  521. }
  522.     return (OK);
  523.     }
  524. #endif /* PIT0_FOR_AUX */
  525. #ifdef INCLUDE_TIMESTAMP_TSC
  526. /*******************************************************************************
  527. *
  528. * sysTimestampConnect - connect a user routine to the timestamp timer interrupt
  529. *
  530. * This routine specifies the user interrupt routine to be called at each
  531. * timestamp timer interrupt.  It does not enable the timestamp timer itself.
  532. *
  533. * RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
  534. */
  535.  
  536. STATUS sysTimestampConnect
  537.     (
  538.     FUNCPTR routine, /* routine called at each timestamp timer interrupt */
  539.     int arg /* argument with which to call routine */
  540.     )
  541.     {
  542.     return (ERROR);
  543.     }
  544. /*******************************************************************************
  545. *
  546. * sysTimestampEnable - initialize and enable the timestamp timer
  547. *
  548. * This routine connects the timestamp timer interrupt and initializes the
  549. * counter registers.  If the timestamp timer is already running, this routine
  550. * merely resets the timer counter.
  551. *
  552. * The rate of the timestamp timer should be set explicitly within the BSP,
  553. * in the sysHwInit() routine.  This routine does not intialize the timer
  554. * rate.  
  555. *
  556. * RETURNS: OK, or ERROR if the timestamp timer cannot be enabled.
  557. */
  558.  
  559. STATUS sysTimestampEnable (void)
  560.     {
  561.     if (sysTimestampRunning)
  562. return (OK);
  563.     
  564.     sysTimestampRunning = TRUE;
  565.     return (OK);
  566.     }
  567. /********************************************************************************
  568. * sysTimestampDisable - disable the timestamp timer
  569. *
  570. * This routine disables the timestamp timer.  Interrupts are not disabled,
  571. * although the tick counter will not increment after the timestamp timer
  572. * is disabled, thus interrupts will no longer be generated.
  573. *
  574. * RETURNS: OK, or ERROR if the timestamp timer cannot be disabled.
  575. */
  576.  
  577. STATUS sysTimestampDisable (void)
  578.     {
  579.     if (sysTimestampRunning)
  580. {
  581.         sysTimestampRunning = FALSE;
  582. }
  583.     return (ERROR);
  584.     }
  585. /*******************************************************************************
  586. *
  587. * sysTimestampPeriod - get the timestamp timer period
  588. *
  589. * This routine returns the period of the timestamp timer in ticks.
  590. * The period, or terminal count, is the number of ticks to which the timestamp
  591. * timer will count before rolling over and restarting the counting process.
  592. *
  593. * RETURNS: The period of the timestamp timer in counter ticks.
  594. */
  595.  
  596. UINT32 sysTimestampPeriod (void)
  597.     {
  598.     sysTimestampPeriodValue = sysTimestampFreq () / sysClkTicksPerSecond;
  599.     return (sysTimestampPeriodValue);
  600.     }
  601. /*******************************************************************************
  602. *
  603. * sysTimestampFreq - get the timestamp timer clock frequency
  604. *
  605. * This routine returns the frequency of the timer clock, in ticks per second.
  606. * The rate of the timestamp timer should be set explicitly within the BSP,
  607. * in the sysHwInit() routine.
  608. *
  609. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  610. */
  611.  
  612. UINT32 sysTimestampFreq (void)
  613.     {
  614.     return (sysTimestampFreqValue);
  615.     }
  616.  
  617. LOCAL void sysTimestampFreqGet (void)
  618.     {
  619.     if (sysTimestampTickCount == sysClkTicksPerSecond)
  620. {
  621. sysTimestampFreqValue = pentiumTscGet32 ();
  622. sysTimestampTickCount = 0;
  623. }
  624.     if (sysTimestampTickCount == 0)
  625. pentiumTscReset ();
  626.     sysTimestampTickCount++;
  627.     }
  628. /*******************************************************************************
  629. *
  630. * sysTimestamp - get the timestamp timer tick count
  631. *
  632. * This routine returns the current value of the timestamp timer tick counter.
  633. * The tick count can be converted to seconds by dividing by the return of
  634. * sysTimestampFreq().
  635. *
  636. * This routine should be called with interrupts locked.  If interrupts are
  637. * not already locked, sysTimestampLock() should be used instead.
  638. *
  639. * RETURNS: The current timestamp timer tick count.
  640. *
  641. * SEE ALSO: sysTimestampLock()
  642. */
  643.  
  644. UINT32 sysTimestamp (void)
  645.     {
  646.     return (pentiumTscGet32 ());
  647.     }
  648. /*******************************************************************************
  649. *
  650. * sysTimestampLock - get the timestamp timer tick count
  651. *
  652. * This routine returns the current value of the timestamp timer tick counter.
  653. * The tick count can be converted to seconds by dividing by the return of
  654. * sysTimestampFreq().
  655. *
  656. * This routine locks interrupts for cases where it is necessary to stop the
  657. * tick counter in order to read it, or when two independent counters must
  658. * be read.  If interrupts are already locked, sysTimestamp() should be
  659. * used instead.
  660. *
  661. * RETURNS: The current timestamp timer tick count.
  662. *
  663. * SEE ALSO: sysTimestamp()
  664. */
  665.  
  666. UINT32 sysTimestampLock (void)
  667.     {
  668.     /* 
  669.      * pentiumTscGet32() has just one instruction "rdtsc", so locking
  670.      * the interrupt is not necessary. 
  671.      */
  672.     return (pentiumTscGet32 ());
  673.     }
  674. #endif /* INCLUDE_TIMESTAMP_TSC */