diff options
| author | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
|---|---|---|
| committer | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
| commit | 78ee7d5717807e6ac779293d0d3c78341de6130a (patch) | |
| tree | a43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/pc/devrtc.c | |
| parent | bdaf46cf45bbb59261da245d548a179d95a42768 (diff) | |
Move existing boards into subdits split per arch
Diffstat (limited to 'os/pc/devrtc.c')
| -rw-r--r-- | os/pc/devrtc.c | 461 |
1 files changed, 0 insertions, 461 deletions
diff --git a/os/pc/devrtc.c b/os/pc/devrtc.c deleted file mode 100644 index f6e1d911..00000000 --- a/os/pc/devrtc.c +++ /dev/null @@ -1,461 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -/* - * real time clock and non-volatile ram - */ - -enum { - Paddr= 0x70, /* address port */ - Pdata= 0x71, /* data port */ - - Seconds= 0x00, - Minutes= 0x02, - Hours= 0x04, - Mday= 0x07, - Month= 0x08, - Year= 0x09, - Status= 0x0A, - - Nvoff= 128, /* where usable nvram lives */ - Nvsize= 256, - - Nbcd= 6, -}; - -typedef struct Rtc Rtc; -struct Rtc -{ - int sec; - int min; - int hour; - int mday; - int mon; - int year; -}; - - -enum{ - Qdir = 0, - Qrtc, - Qnvram, -}; - -Dirtab rtcdir[]={ - ".", {Qdir, 0, QTDIR}, 0, 0555, - "nvram", {Qnvram, 0}, Nvsize, 0664, - "rtc", {Qrtc, 0}, 0, 0664, -}; - -static ulong rtc2sec(Rtc*); -static void sec2rtc(ulong, Rtc*); - -void -rtcinit(void) -{ - if(ioalloc(Paddr, 2, 0, "rtc/nvr") < 0) - panic("rtcinit: ioalloc failed"); -} - -static Chan* -rtcattach(char* spec) -{ - return devattach('r', spec); -} - -static Walkqid* -rtcwalk(Chan* c, Chan *nc, char** name, int nname) -{ - return devwalk(c, nc, name, nname, rtcdir, nelem(rtcdir), devgen); -} - -static int -rtcstat(Chan* c, uchar* dp, int n) -{ - return devstat(c, dp, n, rtcdir, nelem(rtcdir), devgen); -} - -static Chan* -rtcopen(Chan* c, int omode) -{ - omode = openmode(omode); - switch((ulong)c->qid.path){ - case Qrtc: - if(strcmp(up->env->user, eve)!=0 && omode!=OREAD) - error(Eperm); - break; - case Qnvram: - if(strcmp(up->env->user, eve)!=0) - error(Eperm); - } - return devopen(c, omode, rtcdir, nelem(rtcdir), devgen); -} - -static void -rtcclose(Chan*) -{ -} - -#define GETBCD(o) ((bcdclock[o]&0xf) + 10*(bcdclock[o]>>4)) - -static long -_rtctime(void) -{ - uchar bcdclock[Nbcd]; - Rtc rtc; - int i; - - /* don't do the read until the clock is no longer busy */ - for(i = 0; i < 10000; i++){ - outb(Paddr, Status); - if(inb(Pdata) & 0x80) - continue; - - /* read clock values */ - outb(Paddr, Seconds); bcdclock[0] = inb(Pdata); - outb(Paddr, Minutes); bcdclock[1] = inb(Pdata); - outb(Paddr, Hours); bcdclock[2] = inb(Pdata); - outb(Paddr, Mday); bcdclock[3] = inb(Pdata); - outb(Paddr, Month); bcdclock[4] = inb(Pdata); - outb(Paddr, Year); bcdclock[5] = inb(Pdata); - - outb(Paddr, Status); - if((inb(Pdata) & 0x80) == 0) - break; - } - - /* - * convert from BCD - */ - rtc.sec = GETBCD(0); - rtc.min = GETBCD(1); - rtc.hour = GETBCD(2); - rtc.mday = GETBCD(3); - rtc.mon = GETBCD(4); - rtc.year = GETBCD(5); - - /* - * the world starts jan 1 1970 - */ - if(rtc.year < 70) - rtc.year += 2000; - else - rtc.year += 1900; - return rtc2sec(&rtc); -} - -static Lock nvrtlock; - -long -rtctime(void) -{ - int i; - long t, ot; - - ilock(&nvrtlock); - - /* loop till we get two reads in a row the same */ - t = _rtctime(); - for(i = 0; i < 100; i++){ - ot = t; - t = _rtctime(); - if(ot == t) - break; - } - if(i == 100) print("we are boofheads\n"); - - iunlock(&nvrtlock); - - return t; -} - -static long -rtcread(Chan* c, void* buf, long n, vlong off) -{ - ulong t; - char *a, *start; - ulong offset = off; - - if(c->qid.type & QTDIR) - return devdirread(c, buf, n, rtcdir, nelem(rtcdir), devgen); - - switch((ulong)c->qid.path){ - case Qrtc: - t = rtctime(); - n = readnum(offset, buf, n, t, 12); - return n; - case Qnvram: - if(n == 0) - return 0; - if(n > Nvsize) - n = Nvsize; - a = start = smalloc(n); - - ilock(&nvrtlock); - for(t = offset; t < offset + n; t++){ - if(t >= Nvsize) - break; - outb(Paddr, Nvoff+t); - *a++ = inb(Pdata); - } - iunlock(&nvrtlock); - - if(waserror()){ - free(start); - nexterror(); - } - memmove(buf, start, t - offset); - poperror(); - - free(start); - return t - offset; - } - error(Ebadarg); - return 0; -} - -#define PUTBCD(n,o) bcdclock[o] = (n % 10) | (((n / 10) % 10)<<4) - -static long -rtcwrite(Chan* c, void* buf, long n, vlong off) -{ - int t; - char *a, *start; - Rtc rtc; - ulong secs; - uchar bcdclock[Nbcd]; - char *cp, *ep; - ulong offset = off; - - if(offset!=0) - error(Ebadarg); - - - switch((ulong)c->qid.path){ - case Qrtc: - /* - * read the time - */ - cp = ep = buf; - ep += n; - while(cp < ep){ - if(*cp>='0' && *cp<='9') - break; - cp++; - } - secs = strtoul(cp, 0, 0); - - /* - * convert to bcd - */ - sec2rtc(secs, &rtc); - PUTBCD(rtc.sec, 0); - PUTBCD(rtc.min, 1); - PUTBCD(rtc.hour, 2); - PUTBCD(rtc.mday, 3); - PUTBCD(rtc.mon, 4); - PUTBCD(rtc.year, 5); - - /* - * write the clock - */ - ilock(&nvrtlock); - outb(Paddr, Seconds); outb(Pdata, bcdclock[0]); - outb(Paddr, Minutes); outb(Pdata, bcdclock[1]); - outb(Paddr, Hours); outb(Pdata, bcdclock[2]); - outb(Paddr, Mday); outb(Pdata, bcdclock[3]); - outb(Paddr, Month); outb(Pdata, bcdclock[4]); - outb(Paddr, Year); outb(Pdata, bcdclock[5]); - iunlock(&nvrtlock); - return n; - case Qnvram: - if(n == 0) - return 0; - if(n > Nvsize) - n = Nvsize; - - start = a = smalloc(n); - if(waserror()){ - free(start); - nexterror(); - } - memmove(a, buf, n); - poperror(); - - ilock(&nvrtlock); - for(t = offset; t < offset + n; t++){ - if(t >= Nvsize) - break; - outb(Paddr, Nvoff+t); - outb(Pdata, *a++); - } - iunlock(&nvrtlock); - - free(start); - return t - offset; - } - error(Ebadarg); - return 0; -} - -Dev rtcdevtab = { - 'r', - "rtc", - - devreset, - rtcinit, - devshutdown, - rtcattach, - rtcwalk, - rtcstat, - rtcopen, - devcreate, - rtcclose, - rtcread, - devbread, - rtcwrite, - devbwrite, - devremove, - devwstat, -}; - -#define SEC2MIN 60L -#define SEC2HOUR (60L*SEC2MIN) -#define SEC2DAY (24L*SEC2HOUR) - -/* - * days per month plus days/year - */ -static int dmsize[] = -{ - 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; -static int ldmsize[] = -{ - 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -/* - * return the days/month for the given year - */ -static int* -yrsize(int y) -{ - if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0)) - return ldmsize; - else - return dmsize; -} - -/* - * compute seconds since Jan 1 1970 - */ -static ulong -rtc2sec(Rtc *rtc) -{ - ulong secs; - int i; - int *d2m; - - secs = 0; - - /* - * seconds per year - */ - for(i = 1970; i < rtc->year; i++){ - d2m = yrsize(i); - secs += d2m[0] * SEC2DAY; - } - - /* - * seconds per month - */ - d2m = yrsize(rtc->year); - for(i = 1; i < rtc->mon; i++) - secs += d2m[i] * SEC2DAY; - - secs += (rtc->mday-1) * SEC2DAY; - secs += rtc->hour * SEC2HOUR; - secs += rtc->min * SEC2MIN; - secs += rtc->sec; - - return secs; -} - -/* - * compute rtc from seconds since Jan 1 1970 - */ -static void -sec2rtc(ulong secs, Rtc *rtc) -{ - int d; - long hms, day; - int *d2m; - - /* - * break initial number into days - */ - hms = secs % SEC2DAY; - day = secs / SEC2DAY; - if(hms < 0) { - hms += SEC2DAY; - day -= 1; - } - - /* - * generate hours:minutes:seconds - */ - rtc->sec = hms % 60; - d = hms / 60; - rtc->min = d % 60; - d /= 60; - rtc->hour = d; - - /* - * year number - */ - if(day >= 0) - for(d = 1970; day >= *yrsize(d); d++) - day -= *yrsize(d); - else - for (d = 1970; day < 0; d--) - day += *yrsize(d-1); - rtc->year = d; - - /* - * generate month - */ - d2m = yrsize(rtc->year); - for(d = 1; day >= d2m[d]; d++) - day -= d2m[d]; - rtc->mday = day + 1; - rtc->mon = d; - - return; -} - -uchar -nvramread(int addr) -{ - uchar data; - - ilock(&nvrtlock); - outb(Paddr, addr); - data = inb(Pdata); - iunlock(&nvrtlock); - - return data; -} - -void -nvramwrite(int addr, uchar data) -{ - ilock(&nvrtlock); - outb(Paddr, addr); - outb(Pdata, data); - iunlock(&nvrtlock); -} |
