clock.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * sheevaplug clock
  3. */
  4. #include "u.h"
  5. #include "../port/lib.h"
  6. #include "mem.h"
  7. #include "dat.h"
  8. #include "fns.h"
  9. #include "io.h"
  10. #include "ureg.h"
  11. enum {
  12. Tcycles = CLOCKFREQ / HZ, /* cycles per clock tick */
  13. };
  14. static void
  15. clockintr(Ureg *ureg, void*)
  16. {
  17. m->fastclock++;
  18. timerintr(ureg, 0);
  19. intrclear(Irqbridge, IRQcputimer0);
  20. }
  21. void
  22. clockinit(void)
  23. {
  24. int s;
  25. long cyc;
  26. TimerReg *tmr = TIMERREG;
  27. tmr->ctl = 0;
  28. intrenable(Irqbridge, IRQcputimer0, clockintr, nil, "clock");
  29. s = spllo(); /* risky */
  30. /* take any deferred clock (& other) interrupts here */
  31. splx(s);
  32. /* adjust m->bootdelay, used by delay()? */
  33. m->ticks = 0;
  34. m->fastclock = 0;
  35. tmr->timer0 = Tcycles;
  36. tmr->ctl = Tmr0enable; /* just once */
  37. s = spllo(); /* risky */
  38. /* one iteration seems to take about 40 ns. */
  39. for (cyc = Tcycles; cyc > 0 && m->fastclock == 0; cyc--)
  40. ;
  41. splx(s);
  42. if (m->fastclock == 0) {
  43. serialputc('?');
  44. if (tmr->timer0 == 0)
  45. panic("clock not interrupting");
  46. else if (tmr->timer0 == tmr->reload0)
  47. panic("clock not ticking");
  48. else
  49. panic("clock running very slowly");
  50. }
  51. tmr->ctl = 0;
  52. tmr->timer0 = Tcycles;
  53. tmr->reload0 = Tcycles;
  54. tmr->ctl = Tmr0enable | Tmr0periodic;
  55. }
  56. void
  57. timerset(uvlong next)
  58. {
  59. #ifdef FANCYTIMERS
  60. Tn *tn;
  61. Tval offset;
  62. ilock(&timers.tn1lock);
  63. tn = (Tn*)Tn1;
  64. tn->cr = Tm;
  65. offset = next + tn->cv;
  66. if(offset < timers.tn1minperiod)
  67. offset = timers.tn1minperiod;
  68. else if(offset > timers.tn1maxperiod)
  69. offset = timers.tn1maxperiod;
  70. tn->lc = offset;
  71. tn->cr = Tm|Te;
  72. iunlock(&timers.tn1lock);
  73. #else
  74. USED(next);
  75. #endif
  76. }
  77. uvlong
  78. fastticks(uvlong *hz)
  79. {
  80. if(hz)
  81. *hz = HZ;
  82. return m->fastclock;
  83. }
  84. ulong
  85. µs(void)
  86. {
  87. return fastticks2us(fastticks(nil));
  88. }
  89. void
  90. microdelay(int l)
  91. {
  92. int i;
  93. l *= m->delayloop;
  94. l /= 1000;
  95. if(l <= 0)
  96. l = 1;
  97. for(i = 0; i < l; i++)
  98. ;
  99. }
  100. void
  101. delay(int l)
  102. {
  103. ulong i, j;
  104. j = m->delayloop;
  105. while(l-- > 0)
  106. for(i=0; i < j; i++)
  107. ;
  108. }
  109. ulong
  110. perfticks(void)
  111. {
  112. // return ((Tn*)Tn0)->cv; // TODO: FANCYTIMERS
  113. return (ulong)fastticks(nil);
  114. }