M alphapc/clock.c => alphapc/clock.c +5 -68
@@ 5,36 5,8 @@
#include "fns.h"
#include "io.h"
#include "axp.h"
-
#include "ureg.h"
-void (*kproftimer)(ulong);
-
-typedef struct Clock0link Clock0link;
-typedef struct Clock0link {
- void (*clock)(void);
- Clock0link* link;
-} Clock0link;
-
-static Clock0link *clock0link;
-static Lock clock0lock;
-
-void
-addclock0link(void (*clock)(void))
-{
- Clock0link *lp;
-
- if((lp = malloc(sizeof(Clock0link))) == 0){
- print("addclock0link: too many links\n");
- return;
- }
- ilock(&clock0lock);
- lp->clock = clock;
- lp->link = clock0link;
- clock0link = lp;
- iunlock(&clock0lock);
-}
-
void
clockinit(void)
{
@@ 97,58 69,23 @@ microdelay(int us)
}
void
-/*milli*/delay(int ms)
+delay(int millisecs)
{
- microdelay(ms*1000);
+ microdelay(millisecs*1000);
}
void
-clock(Ureg *ur)
+clock(Ureg *ureg)
{
- Clock0link *lp;
static int count;
cycletimer();
+
/* HZ == 100, timer == 1024Hz. error < 1ms */
count += 100;
if (count < 1024)
return;
count -= 1024;
- m->ticks++;
- if(m->proc)
- m->proc->pc = ur->pc;
-
- accounttime();
-
- if(kproftimer != nil)
- kproftimer(ur->pc);
-
- if((active.machs&(1<<m->machno)) == 0)
- return;
-
- if(active.exiting && (active.machs & (1<<m->machno))) {
- print("someone's exiting\n");
- exit(0);
- }
-
- checkalarms();
- if(m->machno == 0){
- lock(&clock0lock);
- for(lp = clock0link; lp; lp = lp->link)
- lp->clock();
- unlock(&clock0lock);
- }
-
- if(up == 0 || up->state != Running)
- return;
-
- if(anyready())
- sched();
-
- /* user profiling clock */
- if(ur->status & UMODE) {
- (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1);
- segclock(ur->pc);
- }
+ portclock(ureg);
}
M alphapc/dat.h => alphapc/dat.h +10 -9
@@ 132,30 132,32 @@ struct Mach
Proc *proc; /* current process on this processor */
/* ordering from here on irrelevant */
- int tlbfault; /* only used by devproc; no access to tlb */
- int tlbpurge; /* ... */
+
ulong ticks; /* of the clock since boot time */
Label sched; /* scheduler wakeup */
Lock alarmlock; /* access to alarm list */
void *alarm; /* alarms bound to this clock */
- Page *ufreeme; /* address of upage of exited process */
- int nrdy;
+ int inclockintr;
+
ulong fairness; /* for runproc */
- int lastintr;
ulong cpuhz; /* hwrpb->cfreq */
ulong pcclast;
uvlong fastclock;
vlong intrts; /* time stamp of last interrupt */
+ int tlbfault; /* only used by devproc; no access to tlb */
+ int tlbpurge; /* ... */
int pfault;
int cs;
int syscall;
int load;
int intr;
- int spuriousintr;
int flushmmu; /* make current proc flush it's mmu state */
+ ulong spuriousintr;
+ int lastintr;
+
PCB;
/* MUST BE LAST */
@@ 203,11 205,10 @@ struct PCArch
/*
* a parsed plan9.ini line
*/
-#define ISAOPTLEN 16
#define NISAOPT 8
struct ISAConf {
- char type[NAMELEN];
+ char *type;
ulong port;
ulong irq;
ulong dma;
@@ 216,7 217,7 @@ struct ISAConf {
ulong freq;
int nopt;
- char opt[NISAOPT][ISAOPTLEN];
+ char *opt[NISAOPT];
};
extern PCArch *arch;
M alphapc/devarch.c => alphapc/devarch.c +93 -49
@@ 27,23 27,69 @@ static struct
} iomap;
enum {
- Qdir,
- Qcputype,
- Qioalloc,
+ Qdir = 0,
+ Qioalloc = 1,
Qiob,
Qiow,
Qiol,
- Qirqalloc,
+ Qbase,
+
+ Qmax = 16,
};
-static Dirtab ioallocdir[] = {
- "cputype", { Qcputype, 0 }, 0, 0444,
+typedef long Rdwrfn(Chan*, void*, long, vlong);
+
+static Rdwrfn *readfn[Qmax];
+static Rdwrfn *writefn[Qmax];
+
+static Dirtab archdir[] = {
+ ".", { Qdir, 0, QTDIR }, 0, 0555,
"ioalloc", { Qioalloc, 0 }, 0, 0444,
"iob", { Qiob, 0 }, 0, 0660,
"iow", { Qiow, 0 }, 0, 0660,
"iol", { Qiol, 0 }, 0, 0660,
- "irqalloc", { Qirqalloc, 0}, 0, 0444,
};
+Lock archwlock; /* the lock is only for changing archdir */
+int narchdir = Qbase;
+
+/*
+ * Add a file to the #P listing. Once added, you can't delete it.
+ * You can't add a file with the same name as one already there,
+ * and you get a pointer to the Dirtab entry so you can do things
+ * like change the Qid version. Changing the Qid path is disallowed.
+ */
+Dirtab*
+addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
+{
+ int i;
+ Dirtab d;
+ Dirtab *dp;
+
+ memset(&d, 0, sizeof d);
+ strcpy(d.name, name);
+ d.perm = perm;
+
+ lock(&archwlock);
+ if(narchdir >= Qmax){
+ unlock(&archwlock);
+ return nil;
+ }
+
+ for(i=0; i<narchdir; i++)
+ if(strcmp(archdir[i].name, name) == 0){
+ unlock(&archwlock);
+ return nil;
+ }
+
+ d.qid.path = narchdir;
+ archdir[narchdir] = d;
+ readfn[narchdir] = rdfn;
+ writefn[narchdir] = wrfn;
+ dp = &archdir[narchdir++];
+ unlock(&archwlock);
+
+ return dp;
+}
void
ioinit(void)
@@ 59,8 105,6 @@ ioinit(void)
ioalloc(0x20000, 1, 0, "dummy");
}
-static long cputyperead(char*, int, ulong);
-
//
// alloc some io port space and remember who it was
// alloced to. if port < 0, find a free region.
@@ 115,7 159,7 @@ ioalloc(int port, int size, int align, char *tag)
m->tag[sizeof(m->tag)-1] = 0;
*l = m;
- ioallocdir[0].qid.vers++;
+ archdir[0].qid.vers++;
unlock(&iomap);
return m->start;
@@ 138,7 182,7 @@ iofree(int port)
if((*l)->start > port)
break;
}
- ioallocdir[0].qid.vers++;
+ archdir[0].qid.vers++;
unlock(&iomap);
}
@@ 175,22 219,22 @@ archattach(char* spec)
return devattach('P', spec);
}
-int
-archwalk(Chan* c, char* name)
+Walkqid*
+archwalk(Chan* c, Chan *nc, char** name, int nname)
{
- return devwalk(c, name, ioallocdir, nelem(ioallocdir), devgen);
+ return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
}
-static void
-archstat(Chan* c, char* dp)
+static int
+archstat(Chan* c, uchar* dp, int n)
{
- devstat(c, dp, ioallocdir, nelem(ioallocdir), devgen);
+ return devstat(c, dp, n, archdir, narchdir, devgen);
}
static Chan*
archopen(Chan* c, int omode)
{
- return devopen(c, omode, ioallocdir, nelem(ioallocdir), devgen);
+ return devopen(c, omode, archdir, nelem(archdir), devgen);
}
static void
@@ 206,17 250,17 @@ enum
static long
archread(Chan *c, void *a, long n, vlong offset)
{
- char *p;
- IOMap *m;
- char buf[Linelen+1];
+ char buf[Linelen+1], *p;
int port;
ushort *sp;
ulong *lp;
+ IOMap *m;
+ Rdwrfn *fn;
- switch(c->qid.path & ~CHDIR){
+ switch((ulong)c->qid.path){
case Qdir:
- return devdirread(c, a, n, ioallocdir, nelem(ioallocdir), devgen);
+ return devdirread(c, a, n, archdir, nelem(archdir), devgen);
case Qiob:
port = offset;
@@ 248,13 292,9 @@ archread(Chan *c, void *a, long n, vlong offset)
case Qioalloc:
break;
- case Qirqalloc:
- return irqallocread(a, n, offset);
-
- case Qcputype:
- return cputyperead(a, n, offset);
-
default:
+ if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
+ return fn(c, a, n, offset);
error(Eperm);
break;
}
@@ 281,12 321,13 @@ archread(Chan *c, void *a, long n, vlong offset)
static long
archwrite(Chan *c, void *a, long n, vlong offset)
{
+ char *p;
int port;
ushort *sp;
ulong *lp;
- char *p;
+ Rdwrfn *fn;
- switch(c->qid.path & ~CHDIR){
+ switch((ulong)c->qid.path){
case Qiob:
p = a;
@@ 316,6 357,8 @@ archwrite(Chan *c, void *a, long n, vlong offset)
return n*4;
default:
+ if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
+ return fn(c, a, n, offset);
error(Eperm);
break;
}
@@ 329,7 372,6 @@ Dev archdevtab = {
devreset,
devinit,
archattach,
- devclone,
archwalk,
archstat,
archopen,
@@ 366,22 408,6 @@ static char *cpunames[] =
};
void
-archinit(void)
-{
- PCArch **p;
-
- arch = 0;
- for(p = knownarch; *p; p++){
- if((*p)->ident && (*p)->ident() == 0){
- arch = *p;
- break;
- }
- }
- if(arch == 0)
- arch = &archgeneric;
-}
-
-void
cpuidprint(void)
{
int i, maj, min;
@@ 419,7 445,7 @@ cpuidprint(void)
}
static long
-cputyperead(char *a, int n, ulong offset)
+cputyperead(Chan*, void *a, long n, vlong offset)
{
char str[32], *cputype;
ulong mhz, maj;
@@ 435,3 461,21 @@ cputyperead(char *a, int n, ulong offset)
snprint(str, sizeof(str), "%s %lud\n", cputype, mhz);
return readstr(offset, a, n, str);
}
+
+void
+archinit(void)
+{
+ PCArch **p;
+
+ arch = 0;
+ for(p = knownarch; *p; p++){
+ if((*p)->ident && (*p)->ident() == 0){
+ arch = *p;
+ break;
+ }
+ }
+ if(arch == 0)
+ arch = &archgeneric;
+
+ addarchfile("cputype", 0444, cputyperead, nil);
+}
M alphapc/devether.c => alphapc/devether.c +13 -12
@@ 35,16 35,16 @@ etherattach(char* spec)
return chan;
}
-static int
-etherwalk(Chan* chan, char* name)
+static Walkqid*
+etherwalk(Chan* chan, Chan* nchan, char** name, int nname)
{
- return netifwalk(etherxx[chan->dev], chan, name);
+ return netifwalk(etherxx[chan->dev], chan, nchan, name, nname);
}
-static void
-etherstat(Chan* chan, char* dp)
+static int
+etherstat(Chan* chan, uchar* dp, int n)
{
- netifstat(etherxx[chan->dev], chan, dp);
+ return netifstat(etherxx[chan->dev], chan, dp, n);
}
static Chan*
@@ 71,7 71,7 @@ etherread(Chan* chan, void* buf, long n, vlong off)
ulong offset = off;
ether = etherxx[chan->dev];
- if((chan->qid.path & CHDIR) == 0 && ether->ifstat){
+ if((chan->qid.type & QTDIR) == 0 && ether->ifstat){
/*
* With some controllers it is necessary to reach
* into the chip to extract statistics.
@@ 96,10 96,10 @@ etherremove(Chan*)
{
}
-static void
-etherwstat(Chan* chan, char* dp)
+static int
+etherwstat(Chan* chan, uchar* dp, int n)
{
- netifwstat(etherxx[chan->dev], chan, dp);
+ return netifwstat(etherxx[chan->dev], chan, dp, n);
}
static void
@@ 338,7 338,7 @@ etherreset(void)
{
Ether *ether;
int i, n, ctlrno;
- char name[NAMELEN], buf[128];
+ char name[32], buf[128];
for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){
if(ether == 0)
@@ 347,6 347,8 @@ etherreset(void)
ether->ctlrno = ctlrno;
ether->tbdf = BUSUNKNOWN;
ether->mbps = 10;
+ ether->minmtu = ETHERMINTU;
+ ether->maxmtu = ETHERMAXTU;
if(isaconfig("ether", ctlrno, ether) == 0)
continue;
for(n = 0; cards[n].type; n++){
@@ 435,7 437,6 @@ Dev etherdevtab = {
etherreset,
devinit,
etherattach,
- devclone,
etherwalk,
etherstat,
etheropen,
M alphapc/devfloppy.c => alphapc/devfloppy.c +13 -14
@@ 104,7 104,7 @@ static void floppywait(void);
static long floppyxfer(FDrive*, int, void*, long, long);
Dirtab floppydir[]={
-// "fd0disk", {Qdata + 0}, 0, 0660,
+ ".", {Qdir, 0, QTDIR}, 0, 0550,
"fd0disk", {Qdata + 0}, 0, 0666,
"fd0ctl", {Qctl + 0}, 0, 0660,
"fd1disk", {Qdata + 1}, 0, 0660,
@@ 134,7 134,7 @@ floppysetdef(FDrive *dp)
for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++)
if(dp->dt == t->dt){
dp->t = t;
- floppydir[NFDIR*dp->dev].length = dp->t->cap;
+ floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
break;
}
}
@@ 212,22 212,22 @@ floppyattach(char *spec)
return devattach('f', spec);
}
-static int
-floppywalk(Chan *c, char *name)
+static Walkqid*
+floppywalk(Chan *c, Chan *nc, char **name, int nname)
{
- return devwalk(c, name, floppydir, fl.ndrive*NFDIR, devgen);
+ return devwalk(c, nc, name, nname, floppydir, 1+fl.ndrive*NFDIR, devgen);
}
-static void
-floppystat(Chan *c, char *dp)
+static int
+floppystat(Chan *c, uchar *dp, int n)
{
- devstat(c, dp, floppydir, fl.ndrive*NFDIR, devgen);
+ return devstat(c, dp, n, floppydir, 1+fl.ndrive*NFDIR, devgen);
}
static Chan*
floppyopen(Chan *c, int omode)
{
- return devopen(c, omode, floppydir, fl.ndrive*NFDIR, devgen);
+ return devopen(c, omode, floppydir, 1+fl.ndrive*NFDIR, devgen);
}
static void
@@ 280,7 280,7 @@ changed(Chan *c, FDrive *dp)
if(dp->dt == dp->t->dt)
break;
}
- floppydir[NFDIR*dp->dev].length = dp->t->cap;
+ floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
floppyon(dp);
DPRINT("changed: trying %s\n", dp->t->name);
fldump();
@@ 328,8 328,8 @@ floppyread(Chan *c, void *a, long n, vlong off)
uchar *aa;
ulong offset = off;
- if(c->qid.path == CHDIR)
- return devdirread(c, a, n, floppydir, fl.ndrive*NFDIR, devgen);
+ if(c->qid.type & QTDIR)
+ return devdirread(c, a, n, floppydir, 1+fl.ndrive*NFDIR, devgen);
rv = 0;
dp = &fl.d[c->qid.path & ~Qmask];
@@ 915,7 915,7 @@ floppyformat(FDrive *dp, char *params)
for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){
dp->t = t;
- floppydir[NFDIR*dp->dev].length = dp->t->cap;
+ floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
break;
}
}
@@ 1043,7 1043,6 @@ Dev floppydevtab = {
floppyreset,
devinit,
floppyattach,
- devclone,
floppywalk,
floppystat,
floppyopen,
M alphapc/devvga.c => alphapc/devvga.c +9 -9
@@ 24,6 24,7 @@ enum {
};
static Dirtab vgadir[] = {
+ ".", { Qdir, 0, QTDIR }, 0, 0550,
"vgactl", { Qvgactl, 0 }, 0, 0660,
"vgabios", { Qvgabios, 0 }, 0x10000, 0440,
};
@@ 47,16 48,16 @@ vgaattach(char* spec)
return devattach('v', spec);
}
-int
-vgawalk(Chan* c, char* name)
+Walkqid*
+vgawalk(Chan* c, Chan *nc, char** name, int nname)
{
- return devwalk(c, name, vgadir, nelem(vgadir), devgen);
+ return devwalk(c, nc, name, nname, vgadir, nelem(vgadir), devgen);
}
-static void
-vgastat(Chan* c, char* dp)
+static int
+vgastat(Chan* c, uchar* dp, int n)
{
- devstat(c, dp, vgadir, nelem(vgadir), devgen);
+ return devstat(c, dp, n, vgadir, nelem(vgadir), devgen);
}
static Chan*
@@ 93,7 94,7 @@ vgaread(Chan* c, void* a, long n, vlong off)
ulong offset = off;
char chbuf[30];
- switch(c->qid.path & ~CHDIR){
+ switch((ulong)c->qid.path){
case Qdir:
return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
@@ 359,7 360,7 @@ vgawrite(Chan* c, void* a, long n, vlong off)
char *p;
ulong offset = off;
- switch(c->qid.path & ~CHDIR){
+ switch((ulong)c->qid.path){
case Qdir:
error(Eperm);
@@ 394,7 395,6 @@ Dev vgadevtab = {
vgareset,
devinit,
vgaattach,
- devclone,
vgawalk,
vgastat,
vgaopen,
M alphapc/ether2114x.c => alphapc/ether2114x.c +1 -1
@@ 19,7 19,7 @@
#include "etherif.h"
-#define DEBUG (1)
+#define DEBUG (0)
#define debug if(DEBUG)print
enum {
M alphapc/etherif.h => alphapc/etherif.h +4 -0
@@ 10,12 10,16 @@ struct Ether {
int ctlrno;
int tbdf; /* type+busno+devno+funcno */
int mbps; /* Mbps */
+ int minmtu;
+ int maxmtu;
uchar ea[Eaddrlen];
+ int encry;
void (*attach)(Ether*); /* filled in by reset routine */
void (*transmit)(Ether*);
void (*interrupt)(Ureg*, void*);
long (*ifstat)(Ether*, void*, long, ulong);
+ long (*ctl)(Ether*, void*, long); /* custom ctl messages */
void *ctlr;
Queue* oq;
M alphapc/faultalpha.c => alphapc/faultalpha.c +3 -5
@@ 15,7 15,7 @@ faultalpha(Ureg *ur)
{
ulong addr, cause;
int read, user;
- char buf[ERRLEN];
+ char buf[ERRMAX];
uvlong x;
x = ur->a0&0xffffffff80000000LL;
@@ 42,10 42,8 @@ faultalpha(Ureg *ur)
}
iprint("kernel %s vaddr=0x%lux\n", read? (cause != 0) ? "ifetch" : "read" : "write", (ulong)ur->a0);
-iprint("ptbr %lux up %lux\n", (ulong)m->ptbr, up);
-if(up) iprint("top %lux lvl2 %lux\n", up->mmutop->va, up->mmulvl2->va);
-if(up) iprint("top[N-1] %lux\n", ((uvlong *)up->mmutop->va)[PTE2PG-1]);
- iprint("st=0x%lux pc=0x%lux sp=0x%lux\n", (ulong)ur->status, (ulong)ur->pc, (ulong)ur->sp);
+ if(0)
+ mmudump();
dumpregs(ur);
panic("fault");
}
M alphapc/fns.h => alphapc/fns.h +5 -1
@@ 1,6 1,6 @@
#include "../port/portfns.h"
-void addclock0link(void (*)(void));
+Dirtab* addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
void archinit(void);
void arginit(void);
void arith(void);
@@ 34,6 34,7 @@ void gotopc(ulong);
int i8042auxcmd(int);
void i8042auxenable(void (*)(int, int));
void i8042reset(void);
+void i8250console(void);
void i8259init(void);
int i8259enable(int, int, Vctl*);
#define idlehands() /* nothing to do in the runproc */
@@ 49,6 50,7 @@ int iprint(char*, ...);
int irqallocread(char*, long, vlong);
int isaconfig(char*, int, ISAConf*);
void kbdinit(void);
+#define kmapinval()
void *kmapv(uvlong, int);
int kprint(char*, ...);
void launchinit(void);
@@ 57,6 59,7 @@ void links(void);
void mb(void);
void memholes(void);
ulong meminit(void);
+void mmudump(void);
void mmuinit(void);
#define mmunewpage(x)
void mntdump(void);
@@ 95,6 98,7 @@ void upafree(ulong, int);
#define userureg(ur) ((ur)->status & UMODE)
void wrent(int, void*);
void wrvptptr(uvlong);
+ulong TK2MS(ulong); /* ticks to milliseconds */
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
#define kmapperm(x) kmap(x)
M alphapc/fptrap.c => alphapc/fptrap.c +1 -1
@@ 21,7 21,7 @@ char *fpexcname(Ureg*, ulong, char*);
void
fptrap(Ureg *ur)
{
- char buf[ERRLEN];
+ char buf[ERRMAX];
int i;
ulong reason;
M alphapc/io.h => alphapc/io.h +1 -7
@@ 1,10 1,4 @@
enum {
- Uart0 = 0x3F8,
- Uart1 = 0x2F8,
- UartFREQ = 1843200,
-};
-
-enum {
IrqCLOCK = 0,
IrqKBD = 1,
IrqUART1 = 3,
@@ 27,7 21,7 @@ enum {
typedef struct Vctl {
Vctl* next; /* handlers on this vector */
- char name[NAMELEN]; /* of driver */
+ char name[KNAMELEN]; /* of driver */
int isintr; /* interrupt or fault/trap */
int irq;
int tbdf;
M alphapc/main.c => alphapc/main.c +40 -52
@@ 26,23 26,34 @@ int nconf;
static void
options(void)
{
- char *cp, *line[MAXCONF];
- int i, n;
+ long i, n;
+ char *cp, *line[MAXCONF], *p, *q;
cp = bootconf->bootargs;
cp[BOOTARGSLEN-1] = 0;
strcpy(bootargs, cp);
- n = getcfields(bootargs, line, MAXCONF, "\n");
+ /*
+ * Strip out '\r', change '\t' -> ' '.
+ */
+ p = cp;
+ for(q = cp; *q; q++){
+ if(*q == '\r')
+ continue;
+ if(*q == '\t')
+ *q = ' ';
+ *p++ = *q;
+ }
+ *p = 0;
+
+ n = getfields(cp, line, MAXCONF, 1, "\n");
for(i = 0; i < n; i++){
if(*line[i] == '#')
continue;
cp = strchr(line[i], '=');
- if(cp == 0)
+ if(cp == nil)
continue;
- *cp++ = 0;
- if(cp - line[i] >= NAMELEN+1)
- *(line[i]+NAMELEN-1) = 0;
+ *cp++ = '\0';
confname[nconf] = line[i];
confval[nconf] = cp;
nconf++;
@@ 56,8 67,8 @@ main(void)
hwrpb = (Hwrpb*)(KZERO|hwrpb->phys);
arginit();
machinit();
- ioinit();
options();
+ ioinit();
clockinit();
confinit();
archinit();
@@ 69,11 80,9 @@ main(void)
trapinit();
screeninit();
printinit();
-
- /* console */
- ns16552install();
- ns16552special(0, 9600, 0, &printq, kbdcr2nl);
kbdinit();
+ i8250console();
+ print("\nPlan 9\n");
cpuidprint();
if(arch->corehello)
@@ 123,7 132,9 @@ void
init0(void)
{
int i;
- char buf[2*NAMELEN];
+ char tstr[32];
+
+ up->nerrlab = 0;
spllo();
@@ 134,15 145,14 @@ init0(void)
up->slash = namec("#/", Atodir, 0, 0);
cnameclose(up->slash->name);
up->slash->name = newcname("/");
- up->dot = cclone(up->slash, 0);
+ up->dot = cclone(up->slash);
chandevinit();
if(!waserror()){
ksetenv("cputype", "alpha");
- sprint(buf, "alpha %s alphapc", conffile);
- ksetenv("terminal", buf);
- ksetenv("sysname", sysname);
+ sprint(tstr, "alpha %s alphapc", conffile);
+ ksetenv("terminal", tstr);
if(cpuserver)
ksetenv("service", "cpu");
else
@@ 174,8 184,9 @@ userinit(void)
p->rgrp = newrgrp();
p->procmode = 0640;
- strcpy(p->text, "*init*");
- strcpy(p->user, eve);
+ kstrdup(&eve, "");
+ kstrdup(&p->text, "*init*");
+ kstrdup(&p->user, eve);
procsetup(p);
@@ 398,7 409,7 @@ confinit(void)
imagmem->maxsize = kpages;
}
- conf.monitor = 1; /* BUG */
+// conf.monitor = 1; /* BUG */
}
void
@@ 454,29 465,18 @@ getconf(char *name)
int
isaconfig(char *class, int ctlrno, ISAConf *isa)
{
- char cc[NAMELEN], *p, *q, *r;
- int n;
+ char cc[32], *p;
+ int i, n;
- sprint(cc, "%s%d", class, ctlrno);
+ snprint(cc, sizeof cc, "%s%d", class, ctlrno);
for(n = 0; n < nconf; n++){
- if(cistrncmp(confname[n], cc, NAMELEN))
+ if(cistrcmp(confname[n], cc) != 0)
continue;
- isa->nopt = 0;
- p = confval[n];
- while(*p){
- while(*p == ' ' || *p == '\t')
- p++;
- if(*p == '\0')
- break;
- if(cistrncmp(p, "type=", 5) == 0){
- p += 5;
- for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
- if(*p == '\0' || *p == ' ' || *p == '\t')
- break;
- *q = *p++;
- }
- *q = '\0';
- }
+ isa->nopt = tokenize(confval[n], isa->opt, NISAOPT);
+ for(i = 0; i < isa->nopt; i++){
+ p = isa->opt[i];
+ if(cistrncmp(p, "type=", 5) == 0)
+ isa->type = p + 5;
else if(cistrncmp(p, "port=", 5) == 0)
isa->port = strtoul(p+5, &p, 0);
else if(cistrncmp(p, "irq=", 4) == 0)
@@ 489,18 489,6 @@ isaconfig(char *class, int ctlrno, ISAConf *isa)
isa->size = strtoul(p+5, &p, 0);
else if(cistrncmp(p, "freq=", 5) == 0)
isa->freq = strtoul(p+5, &p, 0);
- else if(isa->nopt < NISAOPT){
- r = isa->opt[isa->nopt];
- while(*p && *p != ' ' && *p != '\t'){
- *r++ = *p++;
- if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
- break;
- }
- *r = '\0';
- isa->nopt++;
- }
- while(*p && *p != ' ' && *p != '\t')
- p++;
}
return 1;
}
M alphapc/mem.h => alphapc/mem.h +0 -1
@@ 29,7 29,6 @@
#define HZ 100 /* clock frequency */
#define MS2HZ (1000/HZ)
#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
-#define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */
#define MS2TK(t) (((t)*HZ+500)/1000) /* milliseconds to closest tick */
/*
M alphapc/mmu.c => alphapc/mmu.c +16 -0
@@ 254,3 254,19 @@ upafree(ulong, int)
{
print("upafree: virtual mapping not freed\n");
}
+
+void
+mmudump(void)
+{
+ Page *top, *lvl2;
+
+ iprint("ptbr %lux up %lux\n", (ulong)m->ptbr, up);
+ if(up) {
+ top = up->mmutop;
+ if(top != nil)
+ iprint("top %lux top[N-1] %lux\n", top->va, ((uvlong *)top->va)[PTE2PG-1]);
+ lvl2 = up->mmulvl2;
+ if(lvl2 != nil)
+ iprint("lvl2 %lux\n", lvl2->va);
+ }
+}
M alphapc/mouse.c => alphapc/mouse.c +9 -3
@@ 29,6 29,7 @@ static int mousetype;
static void
serialmouse(int port, char *type, int setspeed)
{
+#ifdef notdef
if(mousetype == Mouseserial)
error(Emouseset);
@@ 39,10 40,15 @@ serialmouse(int port, char *type, int setspeed)
if(setspeed)
setspeed = 1200;
if(type && *type == 'M')
- ns16552special(port, setspeed, 0, 0, m3mouseputc);
+ uartspecial(port, setspeed, 0, 0, m3mouseputc);
else
- ns16552special(port, setspeed, 0, 0, mouseputc);
+ uartspecial(port, setspeed, 0, 0, mouseputc);
mousetype = Mouseserial;
+ packetsize = 3;
+#else
+ error("serial mouse not supported yet");
+ USED(port, type, setspeed);
+#endif /* notdef */
}
/*
@@ 79,7 85,7 @@ ps2mouseputc(int c, int shift)
buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
dx = msg[1];
dy = -msg[2];
- mousetrack(buttons, dx, dy);
+ mousetrack(buttons, dx, dy, TK2MS(MACHP(0)->ticks));
}
return;
}
M alphapc/screen.h => alphapc/screen.h +2 -1
@@ 6,7 6,7 @@ struct Cursorinfo {
};
/* devmouse.c */
-extern void mousetrack(int, int, int);
+extern void mousetrack(int, int, int, int);
extern Point mousexy(void);
extern void mouseaccelerate(int);
@@ 127,6 127,7 @@ extern void mousectl(char*[], int);
/* screen.c */
extern int hwaccel; /* use hw acceleration; default on */
extern int hwblank; /* use hw blanking; default on */
+extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*);
extern void flushmemscreen(Rectangle);
extern int cursoron(int);
extern void cursoroff(int);
M alphapc/sd53c8xx.c => alphapc/sd53c8xx.c +2 -2
@@ 2030,13 2030,13 @@ symenable(SDev* sdev)
{
Pcidev *pcidev;
Controller *ctlr;
- char name[NAMELEN];
+ char name[32];
ctlr = sdev->ctlr;
pcidev = ctlr->pcidev;
pcisetbme(pcidev);
- snprint(name, NAMELEN, "%s (%s)", sdev->name, sdev->ifc->name);
+ snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
intrenable(pcidev->intl, interrupt, ctlr, pcidev->tbdf, name);
ilock(ctlr);
M alphapc/trap.c => alphapc/trap.c +12 -12
@@ 44,8 44,8 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
v->tbdf = tbdf;
v->f = f;
v->a = a;
- strncpy(v->name, name, NAMELEN-1);
- v->name[NAMELEN-1] = 0;
+ strncpy(v->name, name, KNAMELEN-1);
+ v->name[KNAMELEN-1] = 0;
ilock(&vctllock);
vno = arch->intrenable(v);
@@ 79,7 79,7 @@ irqallocread(char *buf, long n, vlong offset)
int vno;
Vctl *v;
long oldn;
- char str[11+1+NAMELEN+1], *p;
+ char str[11+1+KNAMELEN+1], *p;
int m;
if(n < 0 || offset < 0)
@@ 88,7 88,7 @@ irqallocread(char *buf, long n, vlong offset)
oldn = n;
for(vno=0; vno<nelem(vctl); vno++){
for(v=vctl[vno]; v; v=v->next){
- m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, NAMELEN, v->name);
+ m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, KNAMELEN, v->name);
if(m <= offset) /* if do not want this, skip entry */
offset -= m;
else{
@@ 252,7 252,7 @@ intr(Ureg *ur)
void
trap(Ureg *ur)
{
- char buf[ERRLEN];
+ char buf[ERRMAX];
int user, x;
m->intrts = fastticks(nil);
@@ 335,7 335,7 @@ trapinit(void)
void
fataltrap(Ureg *ur, char *reason)
{
- char buf[ERRLEN];
+ char buf[ERRMAX];
if(ur->status&UMODE) {
spllo();
@@ 474,8 474,8 @@ notify(Ureg *ur)
n = &up->note[0];
if(strncmp(n->msg, "sys:", 4) == 0) {
l = strlen(n->msg);
- if(l > ERRLEN-15) /* " pc=0x12345678\0" */
- l = ERRLEN-15;
+ if(l > ERRMAX-15) /* " pc=0x12345678\0" */
+ l = ERRMAX-15;
sprint(n->msg+l, " pc=0x%lux", (ulong)ur->pc);
}
@@ 501,7 501,7 @@ notify(Ureg *ur)
sp -= sizeof(Ureg);
if(!okaddr((ulong)up->notify, BY2WD, 0)
- || !okaddr(sp-ERRLEN-6*BY2WD, sizeof(Ureg)+ERRLEN-6*BY2WD, 1)) {
+ || !okaddr(sp-ERRMAX-6*BY2WD, sizeof(Ureg)+ERRMAX-6*BY2WD, 1)) {
pprint("suicide: bad address or sp in notify\n");
print("suicide: bad address or sp in notify\n");
qunlock(&up->debug);
@@ 511,8 511,8 @@ print("suicide: bad address or sp in notify\n");
memmove((Ureg*)sp, ur, sizeof(Ureg));
*(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
up->ureg = (void*)sp;
- sp -= 2*BY2WD+ERRLEN;
- memmove((char*)sp, up->note[0].msg, ERRLEN);
+ sp -= 2*BY2WD+ERRMAX;
+ memmove((char*)sp, up->note[0].msg, ERRMAX);
sp -= 4*BY2WD;
*(ulong*)(sp+3*BY2WD) = sp+4*BY2WD; /* arg 2 is string */
ur->r0 = (ulong)up->ureg; /* arg 1 (R0) is ureg* */
@@ 603,7 603,7 @@ print("suicide: trap in noted\n");
pexit("Suicide", 0);
}
qunlock(&up->debug);
- sp = oureg-4*BY2WD-ERRLEN;
+ sp = oureg-4*BY2WD-ERRMAX;
splhi();
(*urp)->sp = sp;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
A alphapc/uarti8250.c => alphapc/uarti8250.c +648 -0
@@ 0,0 1,648 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+/*
+ * 8250 UART and compatibles.
+ */
+enum {
+ Uart0 = 0x3F8, /* COM1 */
+ Uart0IRQ = 4,
+ Uart1 = 0x2F8, /* COM2 */
+ Uart1IRQ = 3,
+
+ UartFREQ = 1843200,
+};
+
+enum { /* I/O ports */
+ Rbr = 0, /* Receiver Buffer (RO) */
+ Thr = 0, /* Transmitter Holding (WO) */
+ Ier = 1, /* Interrupt Enable */
+ Iir = 2, /* Interrupt Identification (RO) */
+ Fcr = 2, /* FIFO Control (WO) */
+ Lcr = 3, /* Line Control */
+ Mcr = 4, /* Modem Control */
+ Lsr = 5, /* Line Status */
+ Msr = 6, /* Modem Status */
+ Scr = 7, /* Scratch Pad */
+ Dll = 0, /* Divisor Latch LSB */
+ Dlm = 1, /* Divisor Latch MSB */
+};
+
+enum { /* Ier */
+ Erda = 0x01, /* Enable Received Data Available */
+ Ethre = 0x02, /* Enable Thr Empty */
+ Erls = 0x04, /* Enable Receiver Line Status */
+ Ems = 0x08, /* Enable Modem Status */
+};
+
+enum { /* Iir */
+ Ims = 0x00, /* Ms interrupt */
+ Ip = 0x01, /* Interrupt Pending (not) */
+ Ithre = 0x02, /* Thr Empty */
+ Irda = 0x04, /* Received Data Available */
+ Irls = 0x06, /* Receiver Line Status */
+ Ictoi = 0x0C, /* Character Time-out Indication */
+ IirMASK = 0x3F,
+ Ife = 0xC0, /* FIFOs enabled */
+};
+
+enum { /* Fcr */
+ FIFOena = 0x01, /* FIFO enable */
+ FIFOrclr = 0x02, /* clear Rx FIFO */
+ FIFOtclr = 0x04, /* clear Tx FIFO */
+ FIFO1 = 0x00, /* Rx FIFO trigger level 1 byte */
+ FIFO4 = 0x40, /* 4 bytes */
+ FIFO8 = 0x80, /* 8 bytes */
+ FIFO14 = 0xC0, /* 14 bytes */
+};
+
+enum { /* Lcr */
+ Wls5 = 0x00, /* Word Length Select 5 bits/byte */
+ Wls6 = 0x01, /* 6 bits/byte */
+ Wls7 = 0x02, /* 7 bits/byte */
+ Wls8 = 0x03, /* 8 bits/byte */
+ WlsMASK = 0x03,
+ Stb = 0x04, /* 2 stop bits */
+ Pen = 0x08, /* Parity Enable */
+ Eps = 0x10, /* Even Parity Select */
+ Stp = 0x20, /* Stick Parity */
+ Brk = 0x40, /* Break */
+ Dlab = 0x80, /* Divisor Latch Access Bit */
+};
+
+enum { /* Mcr */
+ Dtr = 0x01, /* Data Terminal Ready */
+ Rts = 0x02, /* Ready To Send */
+ Out1 = 0x04, /* no longer in use */
+ Ie = 0x08, /* IRQ Enable */
+ Dm = 0x10, /* Diagnostic Mode loopback */
+};
+
+enum { /* Lsr */
+ Dr = 0x01, /* Data Ready */
+ Oe = 0x02, /* Overrun Error */
+ Pe = 0x04, /* Parity Error */
+ Fe = 0x08, /* Framing Error */
+ Bi = 0x10, /* Break Interrupt */
+ Thre = 0x20, /* Thr Empty */
+ Temt = 0x40, /* Tramsmitter Empty */
+ FIFOerr = 0x80, /* error in receiver FIFO */
+};
+
+enum { /* Msr */
+ Dcts = 0x01, /* Delta Cts */
+ Ddsr = 0x02, /* Delta Dsr */
+ Teri = 0x04, /* Trailing Edge of Ri */
+ Ddcd = 0x08, /* Delta Dcd */
+ Cts = 0x10, /* Clear To Send */
+ Dsr = 0x20, /* Data Set Ready */
+ Ri = 0x40, /* Ring Indicator */
+ Dcd = 0x80, /* Data Set Ready */
+};
+
+typedef struct Ctlr {
+ int io;
+ int irq;
+ int tbdf;
+ int iena;
+
+ uchar sticky[8];
+
+ Lock;
+ int fifo;
+ int fena;
+} Ctlr;
+
+extern PhysUart i8250physuart;
+
+static Ctlr i8250ctlr[2] = {
+{ .io = Uart0,
+ .irq = Uart0IRQ,
+ .tbdf = BUSUNKNOWN, },
+
+{ .io = Uart1,
+ .irq = Uart1IRQ,
+ .tbdf = BUSUNKNOWN, },
+};
+
+static Uart i8250uart[2] = {
+{ .regs = &i8250ctlr[0],
+ .name = "COM1",
+ .freq = UartFREQ,
+ .phys = &i8250physuart,
+ .special=0,
+ .next = &i8250uart[1], },
+
+{ .regs = &i8250ctlr[1],
+ .name = "COM2",
+ .freq = UartFREQ,
+ .phys = &i8250physuart,
+ .special=0,
+ .next = nil, },
+};
+
+static Uart* consuart;
+
+#define csr8r(c, r) inb((c)->io+(r))
+#define csr8w(c, r, v) outb((c)->io+(r), (c)->sticky[(r)]|(v))
+
+static long
+i8250status(Uart* uart, void* buf, long n, long offset)
+{
+ char *p;
+ Ctlr *ctlr;
+ uchar ier, lcr, mcr, msr;
+
+ ctlr = uart->regs;
+ p = malloc(READSTR);
+ mcr = ctlr->sticky[Mcr];
+ msr = csr8r(ctlr, Msr);
+ ier = ctlr->sticky[Ier];
+ lcr = ctlr->sticky[Lcr];
+ snprint(p, READSTR,
+ "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
+ "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n",
+
+ uart->baud,
+ uart->hup_dcd,
+ (msr & Dsr) != 0,
+ uart->hup_dsr,
+ (lcr & WlsMASK) + 5,
+ (ier & Ems) != 0,
+ (lcr & Pen) ? ((lcr & Eps) ? 'e': 'o'): 'n',
+ (mcr & Rts) != 0,
+ (lcr & Stb) ? 2: 1,
+ ctlr->fena,
+
+ uart->dev,
+ uart->type,
+ uart->ferr,
+ uart->oerr,
+ (msr & Cts) ? " cts": "",
+ (msr & Dsr) ? " dsr": "",
+ (msr & Dcd) ? " dcd": "",
+ (msr & Ri) ? " ring": ""
+ );
+ n = readstr(offset, buf, n, p);
+ free(p);
+
+ return n;
+}
+
+static void
+i8250fifo(Uart* uart, int on)
+{
+ int i;
+ Ctlr *ctlr;
+
+ /*
+ * Toggle FIFOs:
+ * if none, do nothing;
+ * reset the Rx and Tx FIFOs;
+ * empty the Rx buffer and clear any interrupt conditions;
+ * if enabling, try to turn them on.
+ */
+ ctlr = uart->regs;
+
+ ilock(ctlr);
+ if(!ctlr->fifo){
+ csr8w(ctlr, Fcr, FIFOtclr|FIFOrclr);
+ for(i = 0; i < 16; i++){
+ csr8r(ctlr, Iir);
+ csr8r(ctlr, Rbr);
+ }
+
+ ctlr->fena = 0;
+ if(on){
+ csr8w(ctlr, Fcr, FIFO4|FIFOena);
+ if(!(csr8r(ctlr, Iir) & Ife))
+ ctlr->fifo = 1;
+ ctlr->fena = 1;
+ }
+ }
+ iunlock(ctlr);
+}
+
+static void
+i8250dtr(Uart* uart, int on)
+{
+ Ctlr *ctlr;
+
+ /*
+ * Toggle DTR.
+ */
+ ctlr = uart->regs;
+ if(on)
+ ctlr->sticky[Mcr] |= Dtr;
+ else
+ ctlr->sticky[Mcr] &= ~Dtr;
+ csr8w(ctlr, Mcr, 0);
+}
+
+static void
+i8250rts(Uart* uart, int on)
+{
+ Ctlr *ctlr;
+
+ /*
+ * Toggle RTS.
+ */
+ ctlr = uart->regs;
+ if(on)
+ ctlr->sticky[Mcr] |= Rts;
+ else
+ ctlr->sticky[Mcr] &= ~Rts;
+ csr8w(ctlr, Mcr, 0);
+}
+
+static void
+i8250modemctl(Uart* uart, int on)
+{
+ Ctlr *ctlr;
+
+ ctlr = uart->regs;
+ ilock(&uart->tlock);
+ if(on){
+ ctlr->sticky[Ier] |= Ems;
+ csr8w(ctlr, Ier, 0);
+ uart->modem = 1;
+ uart->cts = csr8r(ctlr, Msr) & Cts;
+ }
+ else{
+ ctlr->sticky[Ier] &= ~Ems;
+ csr8w(ctlr, Ier, 0);
+ uart->modem = 0;
+ uart->cts = 1;
+ }
+ iunlock(&uart->tlock);
+
+ /* modem needs fifo */
+ (*uart->phys->fifo)(uart, on);
+}
+
+static int
+i8250parity(Uart* uart, int parity)
+{
+ int lcr;
+ Ctlr *ctlr;
+
+ ctlr = uart->regs;
+ lcr = ctlr->sticky[Lcr] & ~(Eps|Pen);
+
+ switch(parity){
+ case 'e':
+ lcr |= Eps|Pen;
+ break;
+ case 'o':
+ lcr |= Pen;
+ break;
+ case 'n':
+ default:
+ break;
+ }
+ ctlr->sticky[Lcr] = lcr;
+ csr8w(ctlr, Lcr, 0);
+
+ uart->parity = parity;
+
+ return 0;
+}
+
+static int
+i8250stop(Uart* uart, int stop)
+{
+ int lcr;
+ Ctlr *ctlr;
+
+ ctlr = uart->regs;
+ lcr = ctlr->sticky[Lcr] & ~Stb;
+
+ switch(stop){
+ case 1:
+ break;
+ case 2:
+ lcr |= Stb;
+ break;
+ default:
+ return -1;
+ }
+ ctlr->sticky[Lcr] = lcr;
+ csr8w(ctlr, Lcr, 0);
+
+ uart->stop = stop;
+
+ return 0;
+}
+
+static int
+i8250bits(Uart* uart, int bits)
+{
+ int lcr;
+ Ctlr *ctlr;
+
+ ctlr = uart->regs;
+ lcr = ctlr->sticky[Lcr] & ~WlsMASK;
+
+ switch(bits){
+ case 5:
+ lcr |= Wls5;
+ break;
+ case 6:
+ lcr |= Wls6;
+ break;
+ case 7:
+ lcr |= Wls7;
+ break;
+ case 8:
+ lcr |= Wls8;
+ break;
+ default:
+ return -1;
+ }
+ ctlr->sticky[Lcr] = lcr;
+ csr8w(ctlr, Lcr, 0);
+
+ uart->bits = bits;
+
+ return 0;
+}
+
+static int
+i8250baud(Uart* uart, int baud)
+{
+ ulong bgc;
+ Ctlr *ctlr;
+
+ /*
+ * Set the Baud rate by calculating and setting the Baud rate
+ * Generator Constant. This will work with fairly non-standard
+ * Baud rates.
+ */
+ if(uart->freq == 0 || baud <= 0)
+ return -1;
+ bgc = (uart->freq+8*baud-1)/(16*baud);
+
+ ctlr = uart->regs;
+ csr8w(ctlr, Lcr, Dlab);
+ outb(ctlr->io+Dlm, bgc>>8);
+ outb(ctlr->io+Dll, bgc);
+ csr8w(ctlr, Lcr, 0);
+
+ uart->baud = baud;
+
+ return 0;
+}
+
+static void
+i8250break(Uart* uart, int ms)
+{
+ Ctlr *ctlr;
+
+ /*
+ * Send a break.
+ */
+ if(ms == 0)
+ ms = 200;
+
+ ctlr = uart->regs;
+ csr8w(ctlr, Lcr, Brk);
+ tsleep(&up->sleep, return0, 0, ms);
+ csr8w(ctlr, Lcr, 0);
+}
+
+static void
+i8250kick(Uart* uart)
+{
+ int i;
+ Ctlr *ctlr;
+
+ if(uart->cts == 0 || uart->blocked)
+ return;
+
+ /*
+ * 128 here is an arbitrary limit to make sure
+ * we don't stay in this loop too long. If the
+ * chip's output queue is longer than 128, too
+ * bad -- presotto
+ */
+ ctlr = uart->regs;
+ for(i = 0; i < 128; i++){
+ if(!(csr8r(ctlr, Lsr) & Thre))
+ break;
+ if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
+ break;
+ outb(ctlr->io+Thr, *(uart->op++));
+ }
+}
+
+static void
+i8250interrupt(Ureg*, void* arg)
+{
+ Ctlr *ctlr;
+ Uart *uart;
+ int iir, lsr, old, r;
+
+ uart = arg;
+
+ ctlr = uart->regs;
+ for(iir = csr8r(ctlr, Iir); !(iir & Ip); iir = csr8r(ctlr, Iir)){
+ switch(iir & IirMASK){
+ case Ims: /* Ms interrupt */
+ r = csr8r(ctlr, Msr);
+ if(r & Dcts){
+ ilock(&uart->tlock);
+ old = uart->cts;
+ uart->cts = r & Cts;
+ if(old == 0 && uart->cts)
+ uart->ctsbackoff = 2;
+ iunlock(&uart->tlock);
+ }
+ if(r & Ddsr){
+ old = r & Dsr;
+ if(uart->hup_dsr && uart->dsr && !old)
+ uart->dohup = 1;
+ uart->dsr = old;
+ }
+ if(r & Ddcd){
+ old = r & Dcd;
+ if(uart->hup_dcd && uart->dcd && !old)
+ uart->dohup = 1;
+ uart->dcd = old;
+ }
+ break;
+ case Ithre: /* Thr Empty */
+ uartkick(uart);
+ break;
+ case Irda: /* Received Data Available */
+ case Ictoi: /* Character Time-out Indication */
+ /*
+ * Consume any received data.
+ * If the received byte came in with a break,
+ * parity or framing error, throw it away;
+ * overrun is an indication that something has
+ * already been tossed.
+ */
+ while((lsr = csr8r(ctlr, Lsr)) & Dr){
+ if(lsr & Oe)
+ uart->oerr++;
+ if(lsr & Pe)
+ uart->perr++;
+ if(lsr & Fe)
+ uart->ferr++;
+ r = csr8r(ctlr, Rbr);
+ if(!(lsr & (Bi|Fe|Pe)))
+ uartrecv(uart, r);
+ }
+ break;
+ default:
+ iprint("weird uart interrupt 0x%2.2uX\n", iir);
+ break;
+ }
+ }
+}
+
+static void
+i8250disable(Uart* uart)
+{
+ Ctlr *ctlr;
+
+ /*
+ * Turn off DTR and RTS, disable interrupts and fifos.
+ */
+ (*uart->phys->dtr)(uart, 0);
+ (*uart->phys->rts)(uart, 0);
+ (*uart->phys->fifo)(uart, 0);
+
+ ctlr = uart->regs;
+ ctlr->sticky[Ier] = 0;
+ csr8w(ctlr, Ier, 0);
+}
+
+static void
+i8250enable(Uart* uart, int ie)
+{
+ Ctlr *ctlr;
+
+ /*
+ * Enable interrupts and turn on DTR and RTS.
+ * Be careful if this is called to set up a polled serial line
+ * early on not to try to enable interrupts as interrupt-
+ * -enabling mechanisms might not be set up yet.
+ */
+ ctlr = uart->regs;
+ if(ie){
+ if(ctlr->iena == 0){
+ intrenable(ctlr->irq, i8250interrupt, uart, ctlr->tbdf, uart->name);
+ ctlr->iena = 1;
+ }
+ ctlr->sticky[Ier] = Ethre|Erda;
+ ctlr->sticky[Mcr] |= Ie;
+ }
+ else{
+ ctlr->sticky[Ier] = 0;
+ ctlr->sticky[Mcr] = 0;
+ }
+ csr8w(ctlr, Ier, ctlr->sticky[Ier]);
+ csr8w(ctlr, Mcr, ctlr->sticky[Mcr]);
+
+ (*uart->phys->dtr)(uart, 1);
+ (*uart->phys->rts)(uart, 1);
+}
+
+static Uart*
+i8250pnp(void)
+{
+ return i8250uart;
+}
+
+PhysUart i8250physuart = {
+ .name = "i8250",
+ .pnp = i8250pnp,
+ .enable = i8250enable,
+ .disable = i8250disable,
+ .kick = i8250kick,
+ .dobreak = i8250break,
+ .baud = i8250baud,
+ .bits = i8250bits,
+ .stop = i8250stop,
+ .parity = i8250parity,
+ .modemctl = i8250modemctl,
+ .rts = i8250rts,
+ .dtr = i8250dtr,
+ .status = i8250status,
+ .fifo = i8250fifo,
+};
+
+int
+serialgetc(void)
+{
+ return -1;
+}
+
+static void
+i8250putc(Ctlr* ctlr, int c)
+{
+ int i;
+
+ for(i = 0; i < 128; i++){
+ if(csr8r(ctlr, Lsr) & Thre)
+ break;
+ delay(1);
+ }
+ outb(ctlr->io+Thr, c);
+}
+
+static void
+i8250puts(char* s, int n)
+{
+ Ctlr *ctlr;
+ Uart *uart;
+
+ if((uart = consuart) == nil)
+ return;
+
+ ctlr = uart->regs;
+ while(n--){
+ if(*s == '\n')
+ i8250putc(ctlr, '\r');
+ i8250putc(ctlr, *s++);
+ }
+}
+
+void
+i8250console(void)
+{
+ Uart *uart;
+ int n;
+ char *cmd, *p;
+
+ if((p = getconf("console")) == nil)
+ return;
+ n = strtoul(p, &cmd, 0);
+ if(p == cmd)
+ return;
+ switch(n){
+ default:
+ return;
+ case 0:
+ uart = &i8250uart[0];
+ break;
+ case 1:
+ uart = &i8250uart[1];
+ break;
+ }
+
+ if(*cmd == 0)
+ cmd = "b9600 l8 pn s1";
+ uartctl(uart, cmd);
+ (*uart->phys->enable)(uart, 0);
+
+ consuart = uart;
+ serialputs = i8250puts;
+ uart->console = 1;
+}
M pc/sdata.c => pc/sdata.c +14 -4
@@ 531,10 531,10 @@ ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info)
static Drive*
atadrive(int cmdport, int ctlport, int dev)
{
- ushort *sp;
Drive *drive;
int as, i, pkt;
uchar buf[512], *p;
+ ushort iconfig, *sp;
atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
pkt = 1;
@@ 567,8 567,18 @@ retry:
}
drive->secsize = 512;
- if((drive->info[Iconfig] & 0xC000) == 0x8000){
- if(drive->info[Iconfig] & 0x01)
+
+ /*
+ * Beware the CompactFlash Association feature set.
+ * Now, why this value in Iconfig just walks all over the bit
+ * definitions used in the other parts of the ATA/ATAPI standards
+ * is a mystery and a sign of true stupidity on someone's part.
+ * Anyway, the standard says if this value is 0x848A then it's
+ * CompactFlash and it's NOT a packet device.
+ */
+ iconfig = drive->info[Iconfig];
+ if(iconfig != 0x848A && (iconfig & 0xC000) == 0x8000){
+ if(iconfig & 0x01)
drive->pkt = 16;
else
drive->pkt = 12;
@@ 598,7 608,7 @@ retry:
if(DEBUG & DbgCONFIG){
print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
dev, cmdport,
- drive->info[Iconfig], drive->info[Icapabilities]);
+ iconfig, drive->info[Icapabilities]);
print(" mwdma %4.4uX", drive->info[Imwdma]);
if(drive->info[Ivalid] & 0x04)
print(" udma %4.4uX", drive->info[Iudma]);
M port/sysfile.c => port/sysfile.c +16 -18
@@ 414,18 414,17 @@ sys_read(ulong *arg)
long
syspread(ulong *arg)
{
- union {
- uvlong v;
- ulong u[2];
- } o;
+ uvlong v;
+ va_list list;
- if(arg[3]==~0UL && arg[4]==~0UL)
- return read(arg, nil);
+ va_start(list, arg[2]);
+ v = va_arg(list, uvlong);
+ va_end(list);
- o.u[0] = arg[3];
- o.u[1] = arg[4];
+ if(v ==~0ULL)
+ return read(arg, nil);
- return read(arg, &o.v);
+ return read(arg, &v);
}
static long
@@ 487,18 486,17 @@ sys_write(ulong *arg)
long
syspwrite(ulong *arg)
{
- union {
- uvlong v;
- ulong u[2];
- } o;
+ uvlong v;
+ va_list list;
- if(arg[3]==~0UL && arg[4]==~0UL)
- return write(arg, nil);
+ va_start(list, arg[2]);
+ v = va_arg(list, uvlong);
+ va_end(list);
- o.u[0] = arg[3];
- o.u[1] = arg[4];
+ if(v ==~0ULL)
+ return write(arg, nil);
- return write(arg, &o.v);
+ return write(arg, &v);
}
static void