From 1068873b2424310954cfa73f6c98c3994db2acbd Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 16 Sep 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-09-16 --- boot/key.c | 60 ++++---- carrera/devrtc.c | 383 +++++++++++++++++++++++++++++++++++++++++++++++ carrera/io.h | 5 +- carrera/screen.c | 31 ++-- 4 files changed, 431 insertions(+), 48 deletions(-) create mode 100644 carrera/devrtc.c diff --git a/boot/key.c b/boot/key.c index b567571ea702e1497b2a4f6fbee549f118d05c21..2d670c933e3667f2b407b90e9ee10153b40e283f 100644 --- a/boot/key.c +++ b/boot/key.c @@ -3,62 +3,62 @@ #include #include <../boot/boot.h> -char *homsg = "can't set user name or key; please reboot"; - -getsafe(char *field, int len, uchar *sum, char *file, int pass) +static void +check(void *x, int len, uchar sum, char *msg) { - char buf[64]; - - if(nvcsum(field, len) != *sum){ - if(readfile(file, buf, sizeof(buf)) < 0){ - kflag |= 1; - return -1; - } - memset(field, 0, len); - if(pass) - passtokey(field, buf); - else - strncpy(field, buf, len-1); - } - return 0; + if(nvcsum(x, len) == sum) + return; + memset(x, 0, len); + kflag = 1; + warning(msg); } +/* + * get info out of nvram. since there isn't room in the PC's nvram use + * a disk partition there. + */ void key(int islocal, Method *mp) { - int fd; + int fd, safeoff; Nvrsafe safe; char password[20]; USED(islocal); USED(mp); - fd = open("#r/nvram", ORDWR); + if(strcmp(cputype, "sparc") == 0){ + fd = open("#r/nvram", ORDWR); + safeoff = 1024+850; + } else if(strcmp(cputype, "386") == 0){ + fd = open("#H/hd0nvram", ORDWR); + if(fd < 0) + fd = open("#w/sd0nvram", ORDWR); + safeoff = 0x0; + } else { + fd = open("#r/nvram", ORDWR); + safeoff = 1024+900; + } + if(fd < 0 - || seek(fd, 1024+900, 0) < 0 + || seek(fd, safeoff, 0) < 0 || read(fd, &safe, sizeof safe) != sizeof safe){ memset(&safe, 0, sizeof(safe)); warning("can't read nvram"); } - if(getsafe(safe.machkey, DESKEYLEN, &safe.machsum, "#e/password", 1) < 0) - warning("bad nvram key"); - if(getsafe(safe.authid, NAMELEN, &safe.authidsum, "#e/authid", 0) < 0) - warning("bad authentication id"); - if(getsafe(safe.authdom, DOMLEN, &safe.authdomsum, "#e/authdom", 0) < 0) - warning("bad authentication domain"); - + check(safe.machkey, DESKEYLEN, safe.machsum, "bad nvram key"); + check(safe.authid, NAMELEN, safe.authidsum, "bad authentication id"); + check(safe.authdom, DOMLEN, safe.authdomsum, "bad authentication domain"); if(kflag){ - do getpasswd(password, sizeof password); while(!passtokey(safe.machkey, password)); - outin("authid", safe.authid, sizeof(safe.authid)); outin("authdom", safe.authdom, sizeof(safe.authdom)); safe.machsum = nvcsum(safe.machkey, DESKEYLEN); safe.authidsum = nvcsum(safe.authid, sizeof(safe.authid)); safe.authdomsum = nvcsum(safe.authdom, sizeof(safe.authdom)); - if(seek(fd, 1024+900, 0) < 0 + if(seek(fd, safeoff, 0) < 0 || write(fd, &safe, sizeof safe) != sizeof safe) warning("can't write key to nvram"); } diff --git a/carrera/devrtc.c b/carrera/devrtc.c new file mode 100644 index 0000000000000000000000000000000000000000..1b21ebdb7cc949eb61ffef2089799fed5b53923d --- /dev/null +++ b/carrera/devrtc.c @@ -0,0 +1,383 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" +#include "devtab.h" +#include "io.h" + +/* + * real time clock and non-volatile ram + */ + +typedef struct Rtc Rtc; +struct Rtc +{ + int sec; + int min; + int hour; + int mday; + int mon; + int year; +}; +QLock rtclock; /* mutex on clock operations */ + + +enum{ + Qrtc = 1, + Qnvram, + + Seconds= 0x00, + Minutes= 0x02, + Hours= 0x04, + Mday= 0x07, + Month= 0x08, + Year= 0x09, + Status= 0x0A, + + Nvsize = 4096, +}; + +#define NRTC 2 +Dirtab rtcdir[]={ + "nvram", {Qnvram, 0}, Nvsize, 0664, + "rtc", {Qrtc, 0}, 0, 0664, +}; + +ulong rtc2sec(Rtc*); +void sec2rtc(ulong, Rtc*); +int *yrsize(int); + +void +rtcreset(void) +{ +} + +void +rtcinit(void) +{ +} + +Chan* +rtcattach(char *spec) +{ + return devattach('r', spec); +} + +Chan* +rtcclone(Chan *c, Chan *nc) +{ + return devclone(c, nc); +} + +int +rtcwalk(Chan *c, char *name) +{ + return devwalk(c, name, rtcdir, NRTC, devgen); +} + +void +rtcstat(Chan *c, char *dp) +{ + devstat(c, dp, rtcdir, NRTC, devgen); +} + +Chan* +rtcopen(Chan *c, int omode) +{ + omode = openmode(omode); + switch(c->qid.path){ + case Qrtc: + if(strcmp(up->user, eve)!=0 && omode!=OREAD) + error(Eperm); + break; + case Qnvram: + if(strcmp(up->user, eve)!=0) + error(Eperm); + } + return devopen(c, omode, rtcdir, NRTC, devgen); +} + +void +rtccreate(Chan *c, char *name, int omode, ulong perm) +{ + USED(c, name, omode, perm); + error(Eperm); +} + +void +rtcclose(Chan *c) +{ + USED(c); +} + +static uchar +bcd2binary(int reg) +{ + uchar x; +/* + x = (*(uchar*)Rtcindex)&~0x7f; + *(uchar*)Rtcindex = x|reg; + x = *(uchar*)Rtcdata; + return (x&0xf) + 10*(x>>4); +/**/ + return 0; +} + +long +rtctime(void) +{ + Rtc rtc; + int x; + + /* + * read and convert from bcd + */ + x = splhi(); + rtc.sec = bcd2binary(Seconds); + rtc.min = bcd2binary(Minutes); + rtc.hour = bcd2binary(Hours); + rtc.mday = bcd2binary(Mday); + rtc.mon = bcd2binary(Month); + rtc.year = bcd2binary(Year); + splx(x); + + /* + * the world starts jan 1 1970 + */ + if(rtc.year < 70) + rtc.year += 2000; + else + rtc.year += 1900; + return rtc2sec(&rtc); +} + +long +rtcread(Chan *c, void *buf, long n, ulong offset) +{ + ulong t, ot; + uchar *f, *to, *e; + + if(c->qid.path & CHDIR) + return devdirread(c, buf, n, rtcdir, NRTC, devgen); + + switch(c->qid.path){ + case Qrtc: + t = rtctime(); + do{ + ot = t; + t = rtctime(); /* make sure there's no skew */ + }while(t != ot); + n = readnum(offset, buf, n, t, 12); + return n; + case Qnvram: + if(offset > Nvsize) + return -1; + if(offset + n > Nvsize) + n = Nvsize - offset; + f = (uchar*)Nvram+offset; + to = buf; + e = f + n; + while(f < e) + *to++ = *f++; + return n; + } + error(Ebadarg); + return 0; +} + +static void +binary2bcd(int reg, uchar val) +{ + uchar x; +/* + x = (*(uchar*)Rtcindex)&~0x7f; + *(uchar*)Rtcindex = x|reg; + *(uchar*)Rtcdata = (val % 10) | (((val / 10) % 10)<<4); +/**/ +} + + +long +rtcwrite(Chan *c, void *buf, long n, ulong offset) +{ + Rtc rtc; + ulong secs; + char *cp, *ep; + uchar *f, *t, *e; + int s; + + USED(c); + switch(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); + sec2rtc(secs, &rtc); + + /* + * convert to bcd + */ + s = splhi(); + binary2bcd(Seconds, rtc.sec); + binary2bcd(Minutes, rtc.min); + binary2bcd(Hours, rtc.hour); + binary2bcd(Mday, rtc.mday); + binary2bcd(Month, rtc.mon); + binary2bcd(Year, rtc.year); + splx(s); + + return n; + case Qnvram: + if(offset > Nvsize) + return -1; + if(offset + n > Nvsize) + n = Nvsize - offset; + t = (uchar*)Nvram+offset; + f = buf; + e = f + n; + while(f < e) + *t++ = *f++; + return n; + } + error(Ebadarg); + return 0; +} + +void +rtcremove(Chan *c) +{ + USED(c); + error(Eperm); +} + +void +rtcwstat(Chan *c, char *dp) +{ + USED(c, dp); + error(Eperm); +} + +#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 + */ +int * +yrsize(int yr) +{ + if((yr % 4) == 0) + return ldmsize; + else + return dmsize; +} + +/* + * compute seconds since Jan 1 1970 + */ +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 + */ +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; +} diff --git a/carrera/io.h b/carrera/io.h index 5c87af7f69c0db4d77a7d87969a756d246a32d59..d5673e864de6e6bb0e5294cb8ab48425ad351f67 100644 --- a/carrera/io.h +++ b/carrera/io.h @@ -37,6 +37,9 @@ enum VideoMEM = 0x40000000, I386ack = 0xE000023f, EisaControl = 0xE0010000, /* Second 64K Page from Devicevirt */ + Eisanmi = EisaControl+0x77, + Rtcindex = Eisanmi, + Rtcdata = 0xE0004007, Eisamphys = 0x91000000, Eisavgaphys = Eisamphys+0xA0000, Eisamvirt = 0xE0300000, /* Second 1M page entry from Intctl */ @@ -75,6 +78,6 @@ struct Tte #define EISA(v) (Eisamvirt+(v)) #define EISAINB(port) (*(uchar*)((EisaControl+(port))^7)) -#define EISAINW(port) (*(ushort*)((EisaControl+(port))^7)) +#define EISAINW(port) (*(ushort*)((EisaControl+(port))^6)) #define EISAOUTB(port, v) EISAINB(port) = v #define EISAOUTW(port, v) EISAINW(port) = v diff --git a/carrera/screen.c b/carrera/screen.c index 5d6bc6ac6f12f4a5c6f7eae416fbd789246fbf53..340788492dad0523a0d65264b42f60f845c9704d 100644 --- a/carrera/screen.c +++ b/carrera/screen.c @@ -146,6 +146,20 @@ static Point cursor; static int h, w; extern Cursor arrow; +#define IOPORT ((uchar*)0xE0010000) + +static uchar +inb(int port) +{ + return IOPORT[port^7]; +} + +static void +outb(int port, int val) +{ + IOPORT[port^7] = val; +} + void gborder(GBitmap *l, Rectangle r, int i, Fcode c) { @@ -190,23 +204,6 @@ screeninit(void) int i, j; uchar *scr; -EISAOUTB(0x3C3, 1); -EISAOUTB(0x46e8, 8); -EISAOUTB(0x3bf, 1); -i = EISAINB(0x3b8); -print("=%2.2ux\n", i); -EISAOUTB(0x3bf, 3); -i = EISAINB(0x3b8); -print("=%2.2ux\n", i); -EISAOUTB(0x3bf, 1); -i = EISAINB(0x3d8); -print("=%2.2ux\n", i); -EISAOUTB(0x3bf, 3); -i = EISAINB(0x3d8); -print("=%2.2ux\n", i); -EISAOUTB(0x3d8, 0xa0); - - setmode(&dfltmode); setmode(&dfltmode); getvmode(&x); writeregisters(&x);