toy.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "all.h"
  2. #include "io.h"
  3. #include "mem.h"
  4. enum {
  5. Paddr= 0x70, /* address port */
  6. Pdata= 0x71, /* data port */
  7. Seconds= 0x00,
  8. Minutes= 0x02,
  9. Hours= 0x04,
  10. Mday= 0x07,
  11. Month= 0x08,
  12. Year= 0x09,
  13. Status= 0x0A,
  14. Nbcd= 6,
  15. };
  16. #define GETBCD(o) ((bcdclock[o]&0xf) + 10*(bcdclock[o]>>4))
  17. #define PUTBCD(n,o) bcdclock[o] = (n % 10) | (((n / 10) % 10)<<4)
  18. static Lock rtclock;
  19. void
  20. setrtc(ulong secs)
  21. {
  22. Rtc rtc;
  23. uchar bcdclock[Nbcd];
  24. sec2rtc(secs, &rtc);
  25. PUTBCD(rtc.sec, 0);
  26. PUTBCD(rtc.min, 1);
  27. PUTBCD(rtc.hour, 2);
  28. PUTBCD(rtc.mday, 3);
  29. PUTBCD(rtc.mon, 4);
  30. PUTBCD(rtc.year, 5);
  31. ilock(&rtclock);
  32. outb(Paddr, Seconds); outb(Pdata, bcdclock[0]);
  33. outb(Paddr, Minutes); outb(Pdata, bcdclock[1]);
  34. outb(Paddr, Hours); outb(Pdata, bcdclock[2]);
  35. outb(Paddr, Mday); outb(Pdata, bcdclock[3]);
  36. outb(Paddr, Month); outb(Pdata, bcdclock[4]);
  37. outb(Paddr, Year); outb(Pdata, bcdclock[5]);
  38. iunlock(&rtclock);
  39. }
  40. static ulong
  41. _rtctime(void)
  42. {
  43. uchar bcdclock[Nbcd];
  44. Rtc rtc;
  45. int i;
  46. /* don't do the read until the clock is no longer busy */
  47. for(i = 0; i < 10000; i++){
  48. outb(Paddr, Status);
  49. if(inb(Pdata) & 0x80)
  50. continue;
  51. /* read clock values */
  52. outb(Paddr, Seconds); bcdclock[0] = inb(Pdata);
  53. outb(Paddr, Minutes); bcdclock[1] = inb(Pdata);
  54. outb(Paddr, Hours); bcdclock[2] = inb(Pdata);
  55. outb(Paddr, Mday); bcdclock[3] = inb(Pdata);
  56. outb(Paddr, Month); bcdclock[4] = inb(Pdata);
  57. outb(Paddr, Year); bcdclock[5] = inb(Pdata);
  58. outb(Paddr, Status);
  59. if((inb(Pdata) & 0x80) == 0)
  60. break;
  61. }
  62. /*
  63. * convert from BCD
  64. */
  65. rtc.sec = GETBCD(0);
  66. rtc.min = GETBCD(1);
  67. rtc.hour = GETBCD(2);
  68. rtc.mday = GETBCD(3);
  69. rtc.mon = GETBCD(4);
  70. rtc.year = GETBCD(5);
  71. /*
  72. * the world starts jan 1 1970
  73. */
  74. if(rtc.year < 70)
  75. rtc.year += 2000;
  76. else
  77. rtc.year += 1900;
  78. return rtc2sec(&rtc);
  79. }
  80. ulong
  81. rtctime(void)
  82. {
  83. int i;
  84. ulong t, ot;
  85. ilock(&rtclock);
  86. /* loop till we get two reads in a row the same */
  87. t = _rtctime();
  88. for(i = 0; i < 100; i++){
  89. ot = t;
  90. t = _rtctime();
  91. if(ot == t)
  92. break;
  93. }
  94. iunlock(&rtclock);
  95. return t;
  96. }
  97. uchar
  98. nvramread(int offset)
  99. {
  100. outb(Paddr, offset);
  101. return inb(Pdata);
  102. }