diff options
| author | Cody Cutler <ccutler@mat.lcs.mit.edu> | 2014-09-12 17:18:57 -0400 | 
|---|---|---|
| committer | Cody Cutler <ccutler@mat.lcs.mit.edu> | 2014-09-12 18:09:51 -0400 | 
| commit | aae4e7490fbb61de13f61d90092b177eeb258216 (patch) | |
| tree | 22cebdefb8bc72ed95d2c11759896023adf1da99 | |
| parent | 75dee1219ffee14f9cb3ec6bb739f06bae27de9c (diff) | |
| download | xv6-labs-aae4e7490fbb61de13f61d90092b177eeb258216.tar.gz xv6-labs-aae4e7490fbb61de13f61d90092b177eeb258216.tar.bz2 xv6-labs-aae4e7490fbb61de13f61d90092b177eeb258216.zip | |
cmosgetdate() for system-call homework
the day of reckoning has come for the debug port "Shutdown" hack.
instead of mucking with ACPI or using a new hack, the student will now write
sys_date() using the cmosgetdate() helper.
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | lapic.c | 71 | ||||
| -rw-r--r-- | sysproc.c | 1 | ||||
| -rw-r--r-- | user.h | 1 | 
4 files changed, 72 insertions, 3 deletions
| @@ -4,6 +4,7 @@ struct file;  struct inode;  struct pipe;  struct proc; +struct rtcdate;  struct spinlock;  struct stat;  struct superblock; @@ -71,6 +72,7 @@ void            kinit2(void*, void*);  void            kbdintr(void);  // lapic.c +void            cmostime(struct rtcdate *r);  int             cpunum(void);  extern volatile uint*    lapic;  void            lapiceoi(void); @@ -3,6 +3,7 @@  #include "types.h"  #include "defs.h" +#include "date.h"  #include "memlayout.h"  #include "traps.h"  #include "mmu.h" @@ -130,7 +131,8 @@ microdelay(int us)  {  } -#define IO_RTC  0x70 +#define CMOS_PORT    0x70 +#define CMOS_RETURN  0x71  // Start additional processor running entry code at addr.  // See Appendix B of MultiProcessor Specification. @@ -143,8 +145,8 @@ lapicstartap(uchar apicid, uint addr)    // "The BSP must initialize CMOS shutdown code to 0AH    // and the warm reset vector (DWORD based at 40:67) to point at    // the AP startup code prior to the [universal startup algorithm]." -  outb(IO_RTC, 0xF);  // offset 0xF is shutdown code -  outb(IO_RTC+1, 0x0A); +  outb(CMOS_PORT, 0xF);  // offset 0xF is shutdown code +  outb(CMOS_PORT+1, 0x0A);    wrv = (ushort*)P2V((0x40<<4 | 0x67));  // Warm reset vector    wrv[0] = 0;    wrv[1] = addr >> 4; @@ -169,4 +171,67 @@ lapicstartap(uchar apicid, uint addr)    }  } +#define CMOS_STATA   0x0a +#define CMOS_STATB   0x0b +#define CMOS_UIP    (1 << 7)        // RTC update in progress +#define SECS    0x00 +#define MINS    0x02 +#define HOURS   0x04 +#define DAY     0x07 +#define MONTH   0x08 +#define YEAR    0x09 + +static uint cmos_read(uint reg) +{ +  outb(CMOS_PORT,  reg); +  microdelay(200); + +  return inb(CMOS_RETURN); +} + +static void fill_rtcdate(struct rtcdate *r) +{ +  r->second = cmos_read(SECS); +  r->minute = cmos_read(MINS); +  r->hour   = cmos_read(HOURS); +  r->day    = cmos_read(DAY); +  r->month  = cmos_read(MONTH); +  r->year   = cmos_read(YEAR); +} + +// qemu seems to use 24-hour GWT and the values are BCD encoded +void cmostime(struct rtcdate *r) +{ +  struct rtcdate t1, t2; +  int sb, bcd; + +  sb = cmos_read(CMOS_STATB); + +  bcd = (sb & (1 << 2)) == 0; + +  // make sure CMOS doesn't modify time while we read it +  for (;;) { +    fill_rtcdate(&t1); +    if (cmos_read(CMOS_STATA) & CMOS_UIP) +        continue; +    fill_rtcdate(&t2); +    if (memcmp(&t1, &t2, sizeof(t1)) == 0) +      break; +  } + +  // convert +  if (bcd) { +#define    CONV(x)     (t1.x = ((t1.x >> 4) * 10) + (t1.x & 0xf)) +    CONV(second); +    CONV(minute); +    CONV(hour  ); +    CONV(day   ); +    CONV(month ); +    CONV(year  ); +#undef     CONV +  } + +  *r = t1; +  r->year += 2000; +} @@ -1,6 +1,7 @@  #include "types.h"  #include "x86.h"  #include "defs.h" +#include "date.h"  #include "param.h"  #include "memlayout.h"  #include "mmu.h" @@ -1,4 +1,5 @@  struct stat; +struct rtcdate;  // system calls  int fork(void); | 
