~kris/9p

9hist

1068873b2424310954cfa73f6c98c3994db2acbd — David du Colombier 33 years ago c35f9ac
Plan 9 from Bell Labs 1993-09-16
4 files changed, 431 insertions(+), 48 deletions(-)

M boot/key.c
A carrera/devrtc.c
M carrera/io.h
M carrera/screen.c
M boot/key.c => boot/key.c +30 -30
@@ 3,62 3,62 @@
#include <auth.h>
#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");
	}

A carrera/devrtc.c => carrera/devrtc.c +383 -0
@@ 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;
}

M carrera/io.h => carrera/io.h +4 -1
@@ 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

M carrera/screen.c => carrera/screen.c +14 -17
@@ 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);