Skip to content

Commit

Permalink
cmosgetdate() for system-call homework
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Cody Cutler committed Sep 12, 2014
1 parent 75dee12 commit aae4e74
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 3 deletions.
2 changes: 2 additions & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ struct file;
struct inode;
struct pipe;
struct proc;
struct rtcdate;
struct spinlock;
struct stat;
struct superblock;
Expand Down Expand Up @@ -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);
Expand Down
71 changes: 68 additions & 3 deletions lapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "types.h"
#include "defs.h"
#include "date.h"
#include "memlayout.h"
#include "traps.h"
#include "mmu.h"
Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand All @@ -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 change: 1 addition & 0 deletions sysproc.c
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
1 change: 1 addition & 0 deletions user.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
struct stat;
struct rtcdate;

// system calls
int fork(void);
Expand Down

0 comments on commit aae4e74

Please sign in to comment.