From 8783251074b7b09db581532c376675e4990e4cd8 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 1 Apr 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-04-01 --- alphapc/arch164.c | 105 ++--------- alphapc/audio.h | 4 +- alphapc/dat.h | 12 +- alphapc/devarch.c | 437 +++++++++++++++++++++++++++++++++++++++++++ alphapc/devether.c | 46 +++-- alphapc/devvga.c | 203 ++++++++++++-------- alphapc/dma.c | 4 + alphapc/ether2114x.c | 7 +- alphapc/floppy.h | 9 +- alphapc/fns.h | 12 +- alphapc/i8259.c | 15 +- alphapc/io.h | 37 ++-- alphapc/kbd.c | 28 ++- alphapc/main.c | 230 ++++++++++++++++++----- alphapc/mmu.c | 4 +- alphapc/ns16552.h | 8 +- alphapc/pci.c | 11 +- alphapc/screen.c | 327 +++++++++++++++++++++++++------- alphapc/screen.h | 23 ++- alphapc/trap.c | 172 +++++++++++++++-- alphapc/vga.c | 75 ++++---- alphapc/vgas3.c | 34 ++-- boot/key.c | 5 +- 23 files changed, 1376 insertions(+), 432 deletions(-) create mode 100644 alphapc/devarch.c diff --git a/alphapc/arch164.c b/alphapc/arch164.c index 61883a6845db736af04a6a9be93b3bd9eb40a337..66c845243a0f461f7af05ccff9d619d828fcf140 100644 --- a/alphapc/arch164.c +++ b/alphapc/arch164.c @@ -164,100 +164,26 @@ pcimem2117x(int addr, int len) return kmapio(0x88, addr, len); } -/* - * interrupts -- adapted from PC, needs work. - */ - -static Lock irqctllock; -static Irqctl *irqctl[256]; -static char irqmask[3]; - -static void -intr164(Ureg *ur) +static int +intrenable164(Vctl *v) { - int i, v; - Irqctl *ctl; - Irq *irq; - Mach *mach; - - v = (ulong)ur->a1>>4; - if (v < 0x80) { - iprint("unknown device intr v %d\n", v); - return; - } - v -= 0x80; - if(v < 256 && (ctl = irqctl[v])){ - if(ctl->isintr){ - m->intr++; - if(ctl->isr) - ctl->isr(v); -/* if(v >= VectorPIC && v <= MaxVectorPIC) - m->lastintr = v-VectorPIC; */ - } - - for(irq = ctl->irq; irq; irq = irq->next) - irq->f(ur, irq->a); - - if(ctl->eoi) - ctl->eoi(v); - } - else if(v >= VectorPIC && v <= MaxVectorPIC){ - /* - * An unknown interrupt. - * Check for a default IRQ7. This can happen when - * the IRQ input goes away before the acknowledge. - * In this case, a 'default IRQ7' is generated, but - * the corresponding bit in the ISR isn't set. - * In fact, just ignore all such interrupts. - */ - iprint("cpu%d: spurious interrupt %d, last %d", - m->machno, v-VectorPIC, 0 /*m->lastintr*/); - for(i = 0; i < 32; i++){ - if(!(active.machs & (1<machno == mach->machno) - continue; - iprint(": cpu%d: last %d", mach->machno, 0 /*mach->lastintr*/); - } - iprint("\n"); -/* m->spuriousintr++; */ - return; + int vec, irq; + + irq = v->irq; + if(irq > MaxIrqPIC) { + print("intrenable: irq %d out of range\n", v->irq); + return -1; } - else{ - dumpregs(ur); - panic("unknown intr: %d\n", v); /* */ + if(BUSTYPE(v->tbdf) == BusPCI) { + vec = irq+VectorPCI; + cserve(52, irq); } -} - -static int -intrenable164(int v, void (*f)(Ureg*, void*), void*a, int tbdf) -{ - Irq * irq; - Irqctl *ctl; - - lock(&irqctllock); - if(irqctl[v] == 0){ - ctl = xalloc(sizeof(Irqctl)); -/* this is all wrong; FIXME! */ - if(BUSTYPE(tbdf) == BusPCI) - cserve(52, v-VectorPCI); - else if(v >= VectorPIC && i8259enable(v, tbdf, ctl) == -1){ - unlock(&irqctllock); - iprint("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf); - xfree(ctl); + else { + vec = irq+VectorPIC; + if(i8259enable(irq, v->tbdf, v) == -1) return -1; - } - irqctl[v] = ctl; } - ctl = irqctl[v]; - irq = xalloc(sizeof(Irq)); - irq->f = f; - irq->a = a; - irq->next = ctl->irq; - ctl->irq = irq; - unlock(&irqctllock); - return 0; + return vec; } /* @@ -405,7 +331,6 @@ PCArch arch164 = { coredetach, pcicfg2117x, pcimem2117x, - intr164, intrenable164, inb2117x, diff --git a/alphapc/audio.h b/alphapc/audio.h index 3085a2cea414925712fbbbd699ce5d7777d1fd93..53d5a8afbe2aa41b9ae524e943034fbe9660364a 100644 --- a/alphapc/audio.h +++ b/alphapc/audio.h @@ -12,5 +12,5 @@ enum #define UNCACHED(type, v) (type*)((ulong)(v)) #define dcflush(a, b) -#define Int0vec VectorPIC -#define setvec(v, f, a) intrenable(v, f, a, BUSUNKNOWN) +#define Int0vec +#define setvec(v, f, a) intrenable(v, f, a, BUSUNKNOWN, "audio") diff --git a/alphapc/dat.h b/alphapc/dat.h index 166d03eeab19d3c115f37a8fb0581c66f2ff4adf..3299d5a348ce7f96b4013516314351af57df6338 100644 --- a/alphapc/dat.h +++ b/alphapc/dat.h @@ -1,7 +1,5 @@ typedef struct Conf Conf; typedef struct FPsave FPsave; -typedef struct Irq Irq; -typedef struct Irqctl Irqctl; typedef struct ISAConf ISAConf; typedef struct Label Label; typedef struct Lock Lock; @@ -12,9 +10,10 @@ typedef struct PCArch PCArch; typedef struct PCB PCB; typedef struct Pcidev Pcidev; typedef struct PMMU PMMU; +typedef struct Proc Proc; typedef struct Sys Sys; typedef struct Ureg Ureg; -typedef struct Proc Proc; +typedef struct Vctl Vctl; /* * parameters for sysproc.c @@ -72,8 +71,6 @@ struct Conf ulong nswap; /* number of swap pages */ int nswppo; /* max # of pageouts per segment pass */ ulong copymode; /* 0 is copy on write, 1 is copy on reference */ - ulong ptebase; - ulong mbytes; int monitor; /* has display? */ ulong ialloc; /* bytes available for interrupt time allocation */ ulong pipeqsize; /* size in bytes of pipe queues */ @@ -144,6 +141,7 @@ struct Mach Page *ufreeme; /* address of upage of exited process */ int nrdy; ulong fairness; /* for runproc */ + int lastintr; ulong cpuhz; /* hwrpb->cfreq */ ulong pcclast; @@ -155,6 +153,7 @@ struct Mach int syscall; int load; int intr; + int spuriousintr; int flushmmu; /* make current proc flush it's mmu state */ PCB; @@ -185,8 +184,7 @@ struct PCArch void (*coredetach)(void); /* restore core logic before return to console */ void *(*pcicfg)(int, int); /* map and point to PCI cfg space */ void *(*pcimem)(int, int); /* map and point to PCI memory space */ - void (*intr)(Ureg*); - int (*intrenable)(int, void (*)(Ureg*, void*), void*, int); + int (*intrenable)(Vctl*); int (*_inb)(int); ushort (*_ins)(int); diff --git a/alphapc/devarch.c b/alphapc/devarch.c new file mode 100644 index 0000000000000000000000000000000000000000..6e2db73eccee115b726eb582f62029d05eb9dbd2 --- /dev/null +++ b/alphapc/devarch.c @@ -0,0 +1,437 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" +#include "axp.h" + +typedef struct IOMap IOMap; +struct IOMap +{ + IOMap *next; + char tag[13]; + ulong start; + ulong end; +}; + +static struct +{ + Lock; + IOMap *m; + IOMap *free; + IOMap maps[32]; // some initial free maps + + QLock ql; // lock for reading map +} iomap; + +enum { + Qdir, + Qcputype, + Qioalloc, + Qiob, + Qiow, + Qiol, + Qirqalloc, +}; + +static Dirtab ioallocdir[] = { + "cputype", { Qcputype, 0 }, 0, 0444, + "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, +}; + +void +ioinit(void) +{ + int i; + + for(i = 0; i < nelem(iomap.maps)-1; i++) + iomap.maps[i].next = &iomap.maps[i+1]; + iomap.maps[i].next = nil; + iomap.free = iomap.maps; + + // a dummy entry at 2^16 + ioalloc(0x10000, 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. +// +int +ioalloc(int port, int size, int align, char *tag) +{ + IOMap *m, **l; + int i; + + lock(&iomap); + if(port < 0){ + // find a free port above 0x400 and below 0x1000 + port = 0x400; + for(l = &iomap.m; *l; l = &(*l)->next){ + m = *l; + i = m->start - port; + if(i > size) + break; + if(align > 0) + port = ((port+align-1)/align)*align; + else + port = m->end; + } + if(*l == nil){ + unlock(&iomap); + return -1; + } + } else { + // see if the space clashes with previously allocated ports + for(l = &iomap.m; *l; l = &(*l)->next){ + m = *l; + if(m->end <= port) + continue; + if(m->start >= port+size) + break; + unlock(&iomap); + return -1; + } + } + m = iomap.free; + if(m == nil){ + print("ioalloc: out of maps"); + unlock(&iomap); + return port; + } + iomap.free = m->next; + m->next = *l; + m->start = port; + m->end = port + size; + strncpy(m->tag, tag, sizeof(m->tag)); + m->tag[sizeof(m->tag)-1] = 0; + *l = m; + + ioallocdir[0].qid.vers++; + + unlock(&iomap); + return m->start; +} + +void +iofree(int port) +{ + IOMap *m, **l; + + lock(&iomap); + for(l = &iomap.m; *l; l = &(*l)->next){ + if((*l)->start == port){ + m = *l; + *l = m->next; + m->next = iomap.free; + iomap.free = m; + break; + } + if((*l)->start > port) + break; + } + ioallocdir[0].qid.vers++; + unlock(&iomap); +} + +int +iounused(int start, int end) +{ + IOMap *m; + + for(m = iomap.m; m; m = m->next){ + if(start >= m->start && start < m->end + || start <= m->start && end > m->start) + return 0; + } + return 1; +} + +static void +checkport(int start, int end) +{ + /* standard vga regs are OK */ + if(start >= 0x2b0 && end <= 0x2df+1) + return; + if(start >= 0x3c0 && end <= 0x3da+1) + return; + + if(iounused(start, end)) + return; + error(Eperm); +} + +static Chan* +archattach(char* spec) +{ + return devattach('P', spec); +} + +int +archwalk(Chan* c, char* name) +{ + return devwalk(c, name, ioallocdir, nelem(ioallocdir), devgen); +} + +static void +archstat(Chan* c, char* dp) +{ + devstat(c, dp, ioallocdir, nelem(ioallocdir), devgen); +} + +static Chan* +archopen(Chan* c, int omode) +{ + return devopen(c, omode, ioallocdir, nelem(ioallocdir), devgen); +} + +static void +archclose(Chan*) +{ +} + +enum +{ + Linelen= 31, +}; + +static long +archread(Chan *c, void *a, long n, vlong offset) +{ + char *p; + IOMap *m; + char buf[Linelen+1]; + int port; + ushort *sp; + ulong *lp; + + switch(c->qid.path & ~CHDIR){ + + case Qdir: + return devdirread(c, a, n, ioallocdir, nelem(ioallocdir), devgen); + + case Qiob: + port = offset; + checkport(offset, offset+n); + for(p = a; port < offset+n; port++) + *p++ = inb(port); + return n; + + case Qiow: + if((n & 0x01) || (offset & 0x01)) + error(Ebadarg); + checkport(offset, offset+n+1); + n /= 2; + sp = a; + for(port = offset; port < offset+n; port += 2) + *sp++ = ins(port); + return n*2; + + case Qiol: + if((n & 0x03) || (offset & 0x03)) + error(Ebadarg); + checkport(offset, offset+n+3); + n /= 4; + lp = a; + for(port = offset; port < offset+n; port += 4) + *lp++ = inl(port); + return n*4; + + case Qioalloc: + break; + + case Qirqalloc: + return irqallocread(a, n, offset); + + case Qcputype: + return cputyperead(a, n, offset); + + default: + error(Eperm); + break; + } + + offset = offset/Linelen; + n = n/Linelen; + p = a; + lock(&iomap); + for(m = iomap.m; n > 0 && m != nil; m = m->next){ + if(offset-- > 0) + continue; + if(strcmp(m->tag, "dummy") == 0) + break; + sprint(buf, "%8lux %8lux %-12.12s\n", m->start, m->end-1, m->tag); + memmove(p, buf, Linelen); + p += Linelen; + n--; + } + unlock(&iomap); + + return p - (char*)a; +} + +static long +archwrite(Chan *c, void *a, long n, vlong offset) +{ + int port; + ushort *sp; + ulong *lp; + char *p; + + switch(c->qid.path & ~CHDIR){ + + case Qiob: + p = a; + checkport(offset, offset+n); + for(port = offset; port < offset+n; port++) + outb(port, *p++); + return n; + + case Qiow: + if((n & 01) || (offset & 01)) + error(Ebadarg); + checkport(offset, offset+n+1); + n /= 2; + sp = a; + for(port = offset; port < offset+n; port += 2) + outs(port, *sp++); + return n*2; + + case Qiol: + if((n & 0x03) || (offset & 0x03)) + error(Ebadarg); + checkport(offset, offset+n+3); + n /= 4; + lp = a; + for(port = offset; port < offset+n; port += 4) + outl(port, *lp++); + return n*4; + + default: + error(Eperm); + break; + } + return 0; +} + +Dev archdevtab = { + 'P', + "arch", + + devreset, + devinit, + archattach, + devclone, + archwalk, + archstat, + archopen, + devcreate, + archclose, + archread, + devbread, + archwrite, + devbwrite, + devremove, + devwstat, +}; + +PCArch* arch; +extern PCArch* knownarch[]; + +PCArch archgeneric = { + "generic", /* id */ + 0, /* ident */ + + 0, /* coreinit */ + 0, /* coredetach */ +}; + +static char *sysnames[] = +{ +// [26] "EB164", +[26] "AlphaPC 164", +}; + +static char *cpunames[] = +{ +[7] "21164A", +}; + +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; + Hwcpu *cpu; + Hwdsr *dsr; + char *s; + + print("\n"); + + if (hwrpb->rev >= 6) { + dsr = (Hwdsr*)((ulong)hwrpb + hwrpb->dsroff); + + s = (char*)dsr + dsr->sysnameoff + 8; + print("%s\n", s); + } + else { + s = ""; + if (hwrpb->systype < nelem(sysnames)) + s = sysnames[hwrpb->systype]; + print("DEC %s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev); + } + + for (i = 0; i < hwrpb->ncpu; i++) { + cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + i*hwrpb->cpulen); + s = ""; + maj = (ulong)cpu->cputype; + min = (ulong)(cpu->cputype>>32); + if (maj < nelem(cpunames)) + s = cpunames[maj]; + print("cpu%d: %s-%d (%d.%d, %llux, %llux)\n", + i, s, min, maj, min, cpu->cpuvar, cpu->cpurev); + } + + print("\n"); +} + +static long +cputyperead(char *a, int n, ulong offset) +{ + char str[32], *cputype; + ulong mhz, maj; + Hwcpu *cpu; + + mhz = (m->cpuhz+999999)/1000000; + cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff); + cputype = "unknown"; + maj = (ulong)cpu->cputype; + if (maj < nelem(cpunames)) + cputype = cpunames[maj]; + + snprint(str, sizeof(str), "%s %lud\n", cputype, mhz); + return readstr(offset, a, n, str); +} diff --git a/alphapc/devether.c b/alphapc/devether.c index 37710031e72607d3db4b80c9d133b0821ae9cf27..fc9e06889f787b35b41f405311652b5a78b6c2b4 100644 --- a/alphapc/devether.c +++ b/alphapc/devether.c @@ -130,11 +130,11 @@ etherrtrace(Netfile* f, Etherpkt* pkt, int len) } Block* -etheriq(Ether* ether, Block* bp, int freebp) +etheriq(Ether* ether, Block* bp, int fromwire) { Etherpkt *pkt; ushort type; - int len; + int len, multi, tome, fromme; Netfile **ep, *f, **fp, *fx; Block *xbp; @@ -146,10 +146,11 @@ etheriq(Ether* ether, Block* bp, int freebp) fx = 0; ep = ðer->f[Ntypes]; + multi = pkt->d[0] & 1; /* check for valid multcast addresses */ - if((pkt->d[0] & 1) && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){ + if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){ if(!activemulti(ether, pkt->d, sizeof(pkt->d))){ - if(freebp){ + if(fromwire){ freeb(bp); bp = 0; } @@ -157,16 +158,25 @@ etheriq(Ether* ether, Block* bp, int freebp) } } + /* is it for me? */ + tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; + fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0; + /* * Multiplex the packet to all the connections which want it. - * If the packet is not to be used subsequently (freebp != 0), + * If the packet is not to be used subsequently (fromwire != 0), * attempt to simply pass it into one of the connections, thereby * saving a copy of the data (usual case hopefully). */ for(fp = ether->f; fp < ep; fp++){ - if((f = *fp) && (f->type == type || f->type < 0)){ - if(f->type > -2){ - if(freebp && fx == 0) + if(f = *fp) + if(f->type == type || f->type < 0) + if(tome || multi || f->prom){ + /* Don't want to hear bridged packets */ + if(f->bridge && !fromwire && !fromme) + continue; + if(!f->headersonly){ + if(fromwire && fx == 0) fx = f; else if(xbp = iallocb(len)){ memmove(xbp->wp, pkt, len); @@ -182,10 +192,11 @@ etheriq(Ether* ether, Block* bp, int freebp) } if(fx){ - qpass(fx->in, bp); + if(qpass(fx->in, bp) < 0) + ether->soverflows++; return 0; } - if(freebp){ + if(fromwire){ freeb(bp); return 0; } @@ -207,20 +218,23 @@ etheroq(Ether* ether, Block* bp) * in promiscuous mode. * If it's a loopback packet indicate to etheriq that the data isn't * needed and return, etheriq will pass-on or free the block. + * To enable bridging to work, only packets that were originated + * by this interface are fed back. */ pkt = (Etherpkt*)bp->rp; len = BLEN(bp); - loopback = (memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0); + loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){ s = splhi(); - etheriq(ether, bp, loopback); + etheriq(ether, bp, 0); splx(s); } if(!loopback){ qbwrite(ether->oq, bp); ether->transmit(ether); - } + } else + freeb(bp); return len; } @@ -354,9 +368,10 @@ etherreset(void) */ if(ether->irq == 2) ether->irq = 9; - intrenable(VectorPCI+ether->irq, ether->interrupt, ether, ether->tbdf); + snprint(name, sizeof(name), "ether%d", ctlrno); + intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name); - i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %ld", + i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud", ctlrno, ether->type, ether->mbps, ether->port, ether->irq); if(ether->mem) i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem)); @@ -368,7 +383,6 @@ etherreset(void) sprint(buf+i, "\n"); print(buf); - snprint(name, sizeof(name), "ether%d", ctlrno); if(ether->mbps == 100){ netifinit(ether, name, Ntypes, 256*1024); if(ether->oq == 0) diff --git a/alphapc/devvga.c b/alphapc/devvga.c index fad3287ca5c5610ed20fc62d114bc2c57fb0c4d9..7652ce7bac913bddf66284a581e099dcdad0b47d 100644 --- a/alphapc/devvga.c +++ b/alphapc/devvga.c @@ -14,24 +14,27 @@ #include #include "screen.h" +extern uchar *vgabios; + enum { Qdir, - Qvgaiob, - Qvgaiow, - Qvgaiol, Qvgactl, + Qvgabios, }; static Dirtab vgadir[] = { - "vgaiob", { Qvgaiob, 0 }, 0, 0660, - "vgaiow", { Qvgaiow, 0 }, 0, 0660, - "vgaiol", { Qvgaiol, 0 }, 0, 0660, "vgactl", { Qvgactl, 0 }, 0, 0660, + "vgabios", { Qvgabios, 0 }, 0x10000, 0440, }; static void vgareset(void) { + /* reserve the 'standard' vga registers */ + if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0) + panic("vga ports already allocated"); + if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0) + panic("vga ports already allocated"); conf.monitor = 1; } @@ -69,10 +72,8 @@ vgaclose(Chan*) static long vgaread(Chan* c, void* a, long n, vlong off) { - int len, port; + int len; char *p, *s; - ushort *sp; - ulong *lp; VGAscr *scr; ulong offset = off; @@ -93,21 +94,21 @@ vgaread(Chan* c, void* a, long n, vlong off) s = scr->dev->name; else s = "cga"; - len = snprint(p, READSTR, "type %s\n", s); + len = snprint(p, READSTR, "type: %s\n", s); if(scr->gscreen) - len += snprint(p+len, READSTR-len, "size %dx%dx%d\n", + len += snprint(p+len, READSTR-len, "size: %dx%dx%d\n", scr->gscreen->r.max.x, scr->gscreen->r.max.y, - 1<gscreen->ldepth); + scr->gscreen->depth); if(scr->cur) s = scr->cur->name; else s = "off"; - len += snprint(p+len, READSTR-len, "hwgc %s\n", s); + len += snprint(p+len, READSTR-len, "hwgc: %s\n", s); if(scr->pciaddr) - snprint(p+len, READSTR-len, "addr 0x%lux\n", + snprint(p+len, READSTR-len, "addr: 0x%lux\n", scr->pciaddr); else - snprint(p+len, READSTR-len, "addr 0x%lux\n", + snprint(p+len, READSTR-len, "addr: 0x%lux\n", scr->aperture); n = readstr(offset, a, n, p); @@ -116,30 +117,18 @@ vgaread(Chan* c, void* a, long n, vlong off) return n; - case Qvgaiob: - port = offset; - for(p = a; port < offset+n; port++) - *p++ = inb(port); + case Qvgabios: + if(vgabios == nil) + error(Egreg); + if(offset&0x80000000) + offset &= ~0x800E0000; + if(offset+n > 0x10000) + n = 0x10000-offset; + if(n < 0) + return 0; + memmove(a, vgabios+offset, n); return n; - case Qvgaiow: - if((n & 0x01) || (offset & 0x01)) - error(Ebadarg); - n /= 2; - sp = a; - for(port = offset; port < offset+n; port += 2) - *sp++ = ins(port); - return n*2; - - case Qvgaiol: - if((n & 0x03) || (offset & 0x03)) - error(Ebadarg); - n /= 4; - lp = a; - for(port = offset; port < offset+n; port += 4) - *lp++ = inl(port); - return n*4; - default: error(Egreg); break; @@ -148,23 +137,32 @@ vgaread(Chan* c, void* a, long n, vlong off) return 0; } +static char Ebusy[] = "vga already configured"; + static void vgactl(char* a) { int align, i, n, size, x, y, z; - char *field[4], *p; + char *chanstr, *field[6], *p; + ulong chan; VGAscr *scr; extern VGAdev *vgadev[]; extern VGAcur *vgacur[]; + Rectangle r; - n = getfields(a, field, 4, 1, " "); - if(n < 2) + n = getfields(a, field, nelem(field), 1, " "); + if(n < 1) error(Ebadarg); scr = &vgascreen[0]; if(strcmp(field[0], "hwgc") == 0){ if(n < 2) error(Ebadarg); + + /* BUG: drawinit should become a different message rather than piggybacking */ + if(scr && scr->dev && scr->dev->drawinit) + scr->dev->drawinit(scr); + if(strcmp(field[1], "off") == 0){ lock(&cursor); if(scr->cur){ @@ -205,8 +203,11 @@ vgactl(char* a) } } else if(strcmp(field[0], "size") == 0){ - if(n < 2) + if(n < 3) error(Ebadarg); + if(drawhasclients()) + error(Ebusy); + x = strtoul(field[1], &p, 0); if(x == 0 || x > 2048) error(Ebadarg); @@ -219,23 +220,76 @@ vgactl(char* a) if(*p) p++; - switch(strtoul(p, &p, 0)){ - case 8: - z = 3; - break; + z = strtoul(p, &p, 0); - default: - z = 0; - error(Ebadarg); - } + chanstr = field[2]; + if((chan = strtochan(chanstr)) == 0) + error("bad channel"); + + if(chantodepth(chan) != z) + error("depth, channel do not match"); cursoroff(1); - if(screensize(x, y, z)) + deletescreenimage(); + if(screensize(x, y, z, chan)) error(Egreg); vgascreenwin(scr); cursoron(1); return; } + else if(strcmp(field[0], "actualsize") == 0){ + if(scr->gscreen == nil) + error("set the screen size first"); + + if(n < 2) + error(Ebadarg); + x = strtoul(field[1], &p, 0); + if(x == 0 || x > 2048) + error(Ebadarg); + if(*p) + p++; + + y = strtoul(p, nil, 0); + if(y == 0 || y > 2048) + error(Ebadarg); + + if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y) + error("physical screen bigger than virtual"); + + r = Rect(0,0,x,y); + if(!eqrect(r, scr->gscreen->r)){ + if(scr->cur == nil || scr->cur->doespanning == 0) + error("virtual screen not supported"); + } + + physgscreenr = r; + return; + } + else if(strcmp(field[0], "palettedepth") == 0){ + if(n < 2) + error(Ebadarg); + + x = strtoul(field[1], &p, 0); + if(x != 8 && x != 6) + error(Ebadarg); + + scr->palettedepth = x; + return; + } + else if(strcmp(field[0], "drawinit") == 0){ + /* + * This is a separate message, but first we need to make + * aux/vga send it; once everyone has the new vga, we + * can take the drawinit stuff out of hwgc. + */ + + /* + if(scr && scr->dev && scr->dev->drawinit) + scr->dev->drawinit(scr); + */ + + return; + } else if(strcmp(field[0], "linear") == 0){ if(n < 2) error(Ebadarg); @@ -249,6 +303,28 @@ vgactl(char* a) error("not enough free address space"); return; } +/* else if(strcmp(field[0], "memset") == 0){ + if(n < 4) + error(Ebadarg); + memset((void*)strtoul(field[1], 0, 0), atoi(field[2]), atoi(field[3])); + return; + } +*/ + else if(strcmp(field[0], "blank") == 0){ + if(n < 2) + error(Ebadarg); + drawblankscreen(atoi(field[1])); + return; + } + else if(strcmp(field[0], "hwaccel") == 0){ + if(n < 2) + error(Ebadarg); + if(strcmp(field[1], "on") == 0) + hwaccel = 1; + else if(strcmp(field[1], "off") == 0) + hwaccel = 0; + return; + } error(Ebadarg); } @@ -256,10 +332,7 @@ vgactl(char* a) static long vgawrite(Chan* c, void* a, long n, vlong off) { - int port; char *p; - ushort *sp; - ulong *lp; ulong offset = off; switch(c->qid.path & ~CHDIR){ @@ -282,30 +355,6 @@ vgawrite(Chan* c, void* a, long n, vlong off) free(p); return n; - case Qvgaiob: - p = a; - for(port = offset; port < offset+n; port++) - outb(port, *p++); - return n; - - case Qvgaiow: - if((n & 01) || (offset & 01)) - error(Ebadarg); - n /= 2; - sp = a; - for(port = offset; port < offset+n; port += 2) - outs(port, *sp++); - return n*2; - - case Qvgaiol: - if((n & 0x03) || (offset & 0x03)) - error(Ebadarg); - n /= 4; - lp = a; - for(port = offset; port < offset+n; port += 4) - outl(port, *lp++); - return n*4; - default: error(Egreg); break; diff --git a/alphapc/dma.c b/alphapc/dma.c index 59ec5dcce923a14653ee5c1fcdc48454c9e24d95..0576172eda766c0baf18a711587a7d1a17caceab 100644 --- a/alphapc/dma.c +++ b/alphapc/dma.c @@ -96,6 +96,10 @@ dmainit(int chan, int maxtransfer) static int once; if(once == 0){ + if(ioalloc(0x00, 0x10, 0, "dma") < 0 + || ioalloc(0x80, 0x10, 0, "dma") < 0 + || ioalloc(0xd0, 0x10, 0, "dma") < 0) + panic("dmainit"); outb(dma[0].mc, 0); outb(dma[1].mc, 0); outb(dma[0].cmask, 0); diff --git a/alphapc/ether2114x.c b/alphapc/ether2114x.c index 290db548bf50c69f0dd3e8af317b1571e2e0bbb2..40f931193657d37b1d4d15beac9cf50381cbd240 100644 --- a/alphapc/ether2114x.c +++ b/alphapc/ether2114x.c @@ -1297,6 +1297,12 @@ dec2114xpci(void) ctlr->port = p->mem[0].bar & ~0x01; ctlr->pcidev = p; + if(ioalloc(ctlr->port, p->mem[0].size, 0, "dec2114x") < 0){ + print("dec2114x: port %d in use\n", ctlr->port); + free(ctlr); + continue; + } + /* * Some cards (e.g. ANA-6910FX) seem to need the Ps bit * set or they don't always work right after a hardware @@ -1326,7 +1332,6 @@ reset(Ether* ether) uchar ea[Eaddrlen]; static int scandone; -pcihinv(nil); if(scandone == 0){ dec2114xpci(); scandone = 1; diff --git a/alphapc/floppy.h b/alphapc/floppy.h index 8376e59729c34f5de9502d35abc65f029a0cbfb3..cb9671de3041d510dbbe7cb8705517e66c39bb50 100644 --- a/alphapc/floppy.h +++ b/alphapc/floppy.h @@ -136,6 +136,13 @@ pcfloppyintr(Ureg *ur, void *a) void floppysetup0(FController *fl) { + fl->ndrive = 0; + if(ioalloc(Psra, 6, 0, "floppy") < 0) + return; + if(ioalloc(Pdir, 1, 0, "floppy") < 0){ + iofree(Psra); + return; + } fl->ndrive = 1; } @@ -151,7 +158,7 @@ floppysetup1(FController *fl) floppysetdef(&fl->d[1]); } - intrenable(VectorPIC+IrqFLOPPY, pcfloppyintr, fl, BUSUNKNOWN); + intrenable(IrqFLOPPY, pcfloppyintr, fl, BUSUNKNOWN, "floppy"); } /* diff --git a/alphapc/fns.h b/alphapc/fns.h index 7e95c7ea930c8fdc8b617fe0c1ecdd71e43100a9..adf4e7e3f74ffb719898482af88abafb1f08abc9 100644 --- a/alphapc/fns.h +++ b/alphapc/fns.h @@ -26,6 +26,7 @@ void firmware(void); #define flushpage(s) icflush() void fpenab(int); void fptrap(Ureg*); +int getcfields(char*, char**, int, char*); char *getconf(char*); ulong getfcr(void); ulong getstatus(void); @@ -34,13 +35,17 @@ int i8042auxcmd(int); void i8042auxenable(void (*)(int, int)); void i8042reset(void); void i8259init(void); -int i8259enable(int, int, Irqctl*); +int i8259enable(int, int, Vctl*); #define idlehands() /* nothing to do in the runproc */ void icflush(void); void illegal0(void); void intr0(void); -void intrenable(int, void (*)(Ureg*, void*), void*, int); +void intrenable(int, void (*)(Ureg*, void*), void*, int, char*); +int ioalloc(int, int, int, char*); +void iofree(int); +void ioinit(void); int iprint(char*, ...); +int irqallocread(char*, long, vlong); int isaconfig(char*, int, ISAConf*); void kbdinit(void); void *kmapv(uvlong, int); @@ -49,6 +54,7 @@ void launchinit(void); void launch(int); void links(void); void mb(void); +void memholes(void); ulong meminit(void); void mmuinit(void); #define mmunewpage(x) @@ -83,6 +89,8 @@ void tlbflush(int, ulong); void touser(void*); void trapinit(void); void unaligned(void); +ulong upamalloc(ulong, int, int); +void upafree(ulong, int); void wrent(int, void*); void wrvptptr(uvlong); diff --git a/alphapc/i8259.c b/alphapc/i8259.c index 0959a279ef9e983c78209061a486e4b9d2e81274..fe1f55708365f2be7cad7d6d03dd064814c513ed 100644 --- a/alphapc/i8259.c +++ b/alphapc/i8259.c @@ -35,6 +35,8 @@ i8259init(void) { int /*elcr1, */ x; + ioalloc(Int0ctl, 2, 0, "i8259.0"); + ioalloc(Int1ctl, 2, 0, "i8259.1"); int0mask = 0xFF; int1mask = 0xFF; @@ -121,13 +123,12 @@ i8259isr(int v) } int -i8259enable(int v, int, Irqctl* irqctl) +i8259enable(int v, int, Vctl* vctl) { - if(v < VectorPIC || v > MaxVectorPIC){ - iprint("i8259enable: vector %d out of range\n", v); + if(v > MaxIrqPIC){ + print("i8259enable: vector %d out of range\n", v); return -1; } - v -= VectorPIC; /* * enable corresponding interrupt in 8259 @@ -142,10 +143,10 @@ i8259enable(int v, int, Irqctl* irqctl) } if(elcr & (1<eoi = i8259isr; + vctl->eoi = i8259isr; else - irqctl->isr = i8259isr; - irqctl->isintr = 1; + vctl->isr = i8259isr; + vctl->isintr = 1; return v; } diff --git a/alphapc/io.h b/alphapc/io.h index 8fb896039c2bdbc5e4f2fbefc556df90f1f91ab3..49a97ccd3e235a746296afdaf68adcc1fc131b05 100644 --- a/alphapc/io.h +++ b/alphapc/io.h @@ -5,7 +5,6 @@ enum { }; enum { -/* VectorPIC = 32, /* external i8259 interrupts */ IrqCLOCK = 0, IrqKBD = 1, IrqUART1 = 3, @@ -19,37 +18,24 @@ enum { IrqATA0 = 14, MaxIrqPIC = 15, -/* deprecated: */ - VectorPIC = 128, /* external [A]PIC interrupts */ - VectorCLOCK = VectorPIC+0, - VectorKBD = VectorPIC+1, - VectorUART1 = VectorPIC+3, - VectorUART0 = VectorPIC+4, - VectorPCMCIA = VectorPIC+5, - VectorFLOPPY = VectorPIC+6, - VectorLPT = VectorPIC+7, - VectorIRQ7 = VectorPIC+7, - VectorAUX = VectorPIC+12, /* PS/2 port */ - VectorIRQ13 = VectorPIC+13, /* coprocessor on x386 */ - VectorATA0 = VectorPIC+14, - MaxVectorPIC = VectorPIC+15, + VectorPIC = 64, + MaxVectorPIC = VectorPIC+MaxIrqPIC, VectorPCI = 16, /* PCI bus (PLD) */ }; -typedef struct Irq { - void (*f)(Ureg*, void*); /* handler to call */ - void* a; /* argument to call it with */ - - Irq* next; /* link to next handler */ -} Irq; +typedef struct Vctl { + Vctl* next; /* handlers on this vector */ -typedef struct Irqctl { + char name[NAMELEN]; /* of driver */ + int isintr; /* interrupt or fault/trap */ + int irq; + int tbdf; int (*isr)(int); /* get isr bit for this irq */ int (*eoi)(int); /* eoi */ - int isintr; - Irq* irq; /* handlers on this IRQ */ -} Irqctl; + void (*f)(Ureg*, void*); /* handler to call */ + void* a; /* argument to call it with */ +} Vctl; enum { BusCBUS = 0, /* Corollary CBUS */ @@ -105,6 +91,7 @@ enum { /* type 0 and type 1 pre-defined header */ PciBAR0 = 0x10, /* base address */ PciBAR1 = 0x14, + PciROM = 0x30, PciINTL = 0x3C, /* interrupt line */ PciINTP = 0x3D, /* interrupt pin */ diff --git a/alphapc/kbd.c b/alphapc/kbd.c index acdd7faca17d84e5e2a561fbed41bfad28135919..73ad3e1dd54670cc571a736c36f517dfc6a06c3e 100644 --- a/alphapc/kbd.c +++ b/alphapc/kbd.c @@ -389,10 +389,30 @@ i8042auxenable(void (*putc)(int, int)) return; } auxputc = putc; - intrenable(VectorAUX, i8042intr, 0, BUSUNKNOWN); + intrenable(IrqAUX, i8042intr, 0, BUSUNKNOWN, "kbdaux"); iunlock(&i8042lock); } +static void +setscan(int code) +{ + char *err = "setscan: set scan code failed\n"; + + outb(Data, 0xF0); + if(inready() < 0 || inb(Data) != 0xFA || outready() < 0) { + print(err); + return; + } + outb(Data, code); + if(inready() < 0) { + print(err); + return; + } + inb(Data); + if(outready() < 0) + print(err); +} + void kbdinit(void) { @@ -403,7 +423,10 @@ kbdinit(void) panic("kbdinit"); qnoblock(kbdq, 1); - intrenable(VectorKBD, i8042intr, 0, BUSUNKNOWN); + ioalloc(Data, 1, 0, "kbd"); + ioalloc(Cmd, 1, 0, "kbd"); + + intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN, "kbd"); /* wait for a quiescent controller */ while((c = inb(Status)) & (Outbusy | Inready)) @@ -429,4 +452,5 @@ kbdinit(void) print("kbd init failed\n"); outb(Data, ccc); outready(); + setscan(0x02); } diff --git a/alphapc/main.c b/alphapc/main.c index 1a710b968f3bfb9dc5cf2f6d27235e60a9599263..e3fb87599965cef453c0bb82d92cd49d065ec37f 100644 --- a/alphapc/main.c +++ b/alphapc/main.c @@ -17,6 +17,37 @@ Conf conf; FPsave initfp; uvlong initfpcr = 0x2800800000000000LL; +char bootargs[BOOTARGSLEN]; +char *confname[MAXCONF]; +char *confval[MAXCONF]; +int nconf; + +static void +options(void) +{ + char *cp, *line[MAXCONF]; + int i, n; + + cp = bootconf->bootargs; + cp[BOOTARGSLEN-1] = 0; + strcpy(bootargs, cp); + + n = getcfields(bootargs, line, MAXCONF, "\n"); + for(i = 0; i < n; i++){ + if(*line[i] == '#') + continue; + cp = strchr(line[i], '='); + if(cp == 0) + continue; + *cp++ = 0; + if(cp - line[i] >= NAMELEN+1) + *(line[i]+NAMELEN-1) = 0; + confname[nconf] = line[i]; + confval[nconf] = cp; + nconf++; + } +} + void main(void) { @@ -24,12 +55,15 @@ main(void) hwrpb = (Hwrpb*)(KZERO|hwrpb->phys); arginit(); machinit(); + ioinit(); + options(); clockinit(); confinit(); archinit(); - mmuinit(); xinit(); - if (arch->coreinit) + memholes(); + mmuinit(); + if(arch->coreinit) arch->coreinit(); trapinit(); screeninit(); @@ -41,7 +75,7 @@ main(void) kbdinit(); cpuidprint(); - if (arch->corehello) + if(arch->corehello) arch->corehello(); #ifdef NEVER @@ -87,6 +121,7 @@ machinit(void) void init0(void) { + int i; char buf[2*NAMELEN]; spllo(); @@ -102,9 +137,16 @@ init0(void) if(!waserror()){ ksetenv("cputype", "alpha"); - sprint(buf, "alpha %s axp", conffile); + sprint(buf, "alpha %s alphapc", conffile); ksetenv("terminal", buf); ksetenv("sysname", sysname); + if(cpuserver) + ksetenv("service", "cpu"); + else + ksetenv("service", "terminal"); + for(i = 0; i < nconf; i++) + if(confname[i] && confname[i][0] != '*') + ksetenv(confname[i], confval[i]); poperror(); } @@ -223,7 +265,7 @@ exit(int) splhi(); delay(1000); /* give serial fifo time to finish flushing */ - if (arch->coredetach) + if(arch->coredetach) arch->coredetach(); firmware(); } @@ -231,55 +273,145 @@ exit(int) void confinit(void) { - long mbytes; - int mul; - ulong ktop; + ulong ktop, kpages; + Bank *b, *eb; + extern void _main(void); + int userpcnt; + char *p; + + if(p = getconf("*kernelpercent")) + userpcnt = 100 - strtol(p, 0, 0); + else + userpcnt = 0; - mbytes = 50; /* BUG FIXME */ + /* + * The console firmware divides memory into 1 or more banks. + * FInd the bank with the kernel in it. + */ + b = bootconf->bank; + eb = b+bootconf->nbank; + ktop = PGROUND((ulong)end); + ktop = PADDR(ktop); + while(b < eb) { + if(b->min < ktop && ktop < b->max) + break; + b++; + } + if(b == eb) + panic("confinit"); /* - * This split of memory into 2 banks fools the allocator into - * allocating low memory pages from bank 0 for the ethernet since - * it has only a 24bit address counter. - * Note that the rom monitor has the bottom 2 megs + * Split the bank of memory into 2 banks to fool the allocator into + * allocating low memory pages from bank 0 for any peripherals + * which only have a 24bit address counter. */ conf.npage0 = (8*1024*1024)/BY2PG; conf.base0 = 0; - conf.npage1 = (mbytes-8)*1024/8; + conf.npage1 = (b->max-8*1024*1024)/BY2PG; conf.base1 = 8*1024*1024; conf.npage = conf.npage0+conf.npage1; conf.upages = (conf.npage*70)/100; - ktop = PGROUND((ulong)end); - conf.ptebase = ktop; - ktop = PADDR(ktop); - ktop += ((mbytes+7)/8 + 2)*BY2PG; /* space for kernel ptes */ conf.npage0 -= ktop/BY2PG; conf.base0 += ktop; - conf.mbytes = mbytes; conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; - mul = (mbytes+11)/12; - if(mul > 2) - mul = 2; + /* + * Fix up the bank we found to be the remnant, below the kernel. + * This, and the other banks, will be passed to xhole() later. + * BUG: conf.upages needs to be adjusted, but how? In practice, + * we only have 1 bank, and the remnant is small. + */ + b->max = (uvlong)_main & ~(BY2PG-1); + conf.nmach = 1; - conf.nproc = 20 + 50*mul; + conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5; + if(cpuserver) + conf.nproc *= 3; + if(conf.nproc > 2000) + conf.nproc = 2000; + conf.nimage = 200; conf.nswap = conf.nproc*80; - conf.nimage = 50; + conf.nswppo = 4096; conf.copymode = 0; /* copy on write */ - if(cpuserver) - conf.nproc = 500; + if(cpuserver) { + if(userpcnt < 10) + userpcnt = 70; + kpages = conf.npage - (conf.npage*userpcnt)/100; + + /* + * Hack for the big boys. Only good while physmem < 4GB. + * Give the kernel a max. of 16MB + enough to allocate the + * page pool. + * This is an overestimate as conf.upages < conf.npages. + * The patch of nimage is a band-aid, scanning the whole + * page list in imagereclaim just takes too long. + */ + if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){ + kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG; + conf.nimage = 2000; + kpages += (conf.nproc*KSTACK)/BY2PG; + } + } else { + if(userpcnt < 10) { + if(conf.npage*BY2PG < 16*MB) + userpcnt = 40; + else + userpcnt = 60; + } + kpages = conf.npage - (conf.npage*userpcnt)/100; + + /* + * Make sure terminals with low memory get at least + * 4MB on the first Image chunk allocation. + */ + if(conf.npage*BY2PG < 16*MB) + imagmem->minarena = 4*1024*1024; + } + conf.upages = conf.npage - kpages; + conf.ialloc = (kpages/2)*BY2PG; + + /* + * Guess how much is taken by the large permanent + * datastructures. Mntcache and Mntrpc are not accounted for + * (probably ~300KB). + */ + kpages *= BY2PG; + kpages -= conf.upages*sizeof(Page) + + conf.nproc*sizeof(Proc) + + conf.nimage*sizeof(Image) + + conf.nswap + + conf.nswppo*sizeof(Page); + mainmem->maxsize = kpages; + if(!cpuserver){ + /* + * give terminals lots of image memory, too; the dynamic + * allocation will balance the load properly, hopefully. + * be careful with 32-bit overflow. + */ + imagmem->maxsize = kpages; + } + conf.monitor = 1; /* BUG */ } void -lights(int l) +memholes(void) { - USED(l); + Bank *b, *eb; + + b = bootconf->bank; + eb = b+bootconf->nbank; + while(b < eb) { + if(b->min < (1LL<<32) && b->max < (1LL<<32)) + xhole(b->min, b->max-b->min); + b++; + } } + char *sp; char * @@ -304,27 +436,6 @@ arginit(void) *av = 0; } -/* - * Q&D fake-out of plan9.ini until we resolve the booting issues - */ -char *confname[] = -{ - "ether0", - "scsi0", - "audio0", - "ether1", -}; - -char *confval[] = -{ - "type=2114x", - "type=ata", - "type=sb16", - "type=2114x", -}; - -int nconf = nelem(confname); - char * getconf(char *name) { @@ -439,3 +550,24 @@ cistrncmp(char *a, char *b, int n) return 0; } + +int +getcfields(char* lp, char** fields, int n, char* sep) +{ + int i; + + for(i = 0; lp && *lp && i < n; i++){ + while(*lp && strchr(sep, *lp) != 0) + *lp++ = 0; + if(*lp == 0) + break; + fields[i] = lp; + while(*lp && strchr(sep, *lp) == 0){ + if(*lp == '\\' && *(lp+1) == '\n') + *lp++ = ' '; + lp++; + } + } + + return i; +} diff --git a/alphapc/mmu.c b/alphapc/mmu.c index 40652ddf6f078768c2c63db71ba63e5276f07ff4..92834642e1e32bd1d5b28869bd920e9b65060823 100644 --- a/alphapc/mmu.c +++ b/alphapc/mmu.c @@ -250,7 +250,7 @@ upamalloc(ulong pa, int size, int align) } void -upafree(...) +upafree(ulong, int) { - panic("upafree"); + print("upafree: virtual mapping not freed\n"); } diff --git a/alphapc/ns16552.h b/alphapc/ns16552.h index 68e293689b7445447402b28bdb415210f4a365af..b95b61fcb73d411307e61bb3742f589278e01433 100644 --- a/alphapc/ns16552.h +++ b/alphapc/ns16552.h @@ -25,10 +25,14 @@ ns16552install(void) return; already = 1; + if(ioalloc(Uart0, 8, 0, "eia0") < 0) + print("eia0: port %d in use\n", Uart0); ns16552setup(Uart0, UartFREQ, "eia0", Ns550); - intrenable(VectorUART0, ns16552intrx, (void*)0, BUSUNKNOWN); + intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN, "eia0"); + if(ioalloc(Uart1, 8, 0, "eia1") < 0) + print("eia1: port %d in use\n", Uart1); ns16552setup(Uart1, UartFREQ, "eia1", Ns550); - intrenable(VectorUART1, ns16552intrx, (void*)0, BUSUNKNOWN); + intrenable(IrqUART1, ns16552intrx, (void*)0, BUSUNKNOWN, "eia1"); addclock0link(uartclock); } diff --git a/alphapc/pci.c b/alphapc/pci.c index 45c8df1ac23e59d7365ed8d4183dcdd2fdaa3a0f..9b757ab31da84d287e6c9299316ee8f5d5db8547 100644 --- a/alphapc/pci.c +++ b/alphapc/pci.c @@ -26,6 +26,8 @@ static Pcidev* pcitail; static int pcicfgrw32(int, int, int, int); +uchar *vgabios; + static int pciscan(int bno, Pcidev** list) { @@ -89,9 +91,16 @@ pciscan(int bno, Pcidev** list) */ switch(p->ccrb){ + case 0x03: /* display controller */ + if(vgabios == nil) { + v = pcicfgr32(p, PciROM); + pcicfgw32(p, PciROM, v|1); /* enable decode */ + vgabios = kmapv(((uvlong)0x88<<32LL)|(v&~0xffff), 0x10000); + // print("VGA BIOS %lux -> %lux\n", v, vgabios); + } + /* fall through */ case 0x01: /* mass storage controller */ case 0x02: /* network controller */ - case 0x03: /* display controller */ case 0x04: /* multimedia device */ case 0x07: /* simple communication controllers */ case 0x08: /* base system peripherals */ diff --git a/alphapc/screen.c b/alphapc/screen.c index 70e439e94729f0d10666bbae5909f615738018a4..1906ef16bbf3b8e2dee870617e61534b171922ea 100644 --- a/alphapc/screen.c +++ b/alphapc/screen.c @@ -13,26 +13,14 @@ #include #include "screen.h" -static ulong onesbits = ~0; -static Memdata onesdata = { - nil, - &onesbits, -}; -static Memimage xones = { - { 0, 0, 1, 1 }, - { -100000, -100000, 100000, 100000 }, - 3, - 1, - &onesdata, - 0, - 1 -}; -Memimage *memones = &xones; +#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19) Point ZP = {0, 0}; +Rectangle physgscreenr; + Memdata gscreendata; -Memimage gscreen; +Memimage *gscreen; VGAscr vgascreen[1]; @@ -51,10 +39,11 @@ Cursor arrow = { }; int -screensize(int x, int y, int z) +screensize(int x, int y, int z, ulong chan) { VGAscr *scr; + memimageinit(); scr = &vgascreen[0]; /* @@ -64,34 +53,32 @@ screensize(int x, int y, int z) if(scr->aperture == 0){ int width = (x*(1<useflush = 1; scr->aperture = PADDR(arch->pcimem(0xA0000, 1<<16)); scr->apsize = 1<<16; } else - gscreendata.data = KADDR(scr->aperture); + gscreendata.bdata = KADDR(scr->aperture); - gscreen.data = &gscreendata; - gscreen.ldepth = z; - gscreen.width = (x*(1<gscreendata = gscreen.data; - scr->memdefont = getmemdefont(); - scr->gscreen = &gscreen; - -// memset(gscreen.data->data, Backgnd, scr->apsize); + gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata); + vgaimageinit(chan); + if(gscreen == nil) + return -1; - drawcmap(0); + scr->palettedepth = 6; /* default */ + scr->gscreendata = &gscreendata; + scr->memdefont = getmemdefont(); + scr->gscreen = gscreen; + drawcmap(); return 0; } @@ -131,8 +118,8 @@ screenaperture(int size, int align) return 0; } -ulong* -attachscreen(Rectangle* r, int* ld, int* width, int *softscreen) +uchar* +attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen) { VGAscr *scr; @@ -141,13 +128,17 @@ attachscreen(Rectangle* r, int* ld, int* width, int *softscreen) return nil; *r = scr->gscreen->r; - *ld = scr->gscreen->ldepth; + *chan = scr->gscreen->chan; + *d = scr->gscreen->depth; *width = scr->gscreen->width; *softscreen = scr->useflush; - return scr->gscreendata->data; + return scr->gscreendata->bdata; } +/* + * It would be fair to say that this doesn't work for >8-bit screens. + */ void flushmemscreen(Rectangle r) { @@ -166,27 +157,28 @@ flushmemscreen(Rectangle r) incs = scr->gscreen->width * BY2WD; - switch(scr->gscreen->ldepth){ + switch(scr->gscreen->depth){ default: len = 0; - panic("flushmemscreen: ldepth\n"); + panic("flushmemscreen: depth\n"); break; - case 3: + case 8: len = Dx(r); break; } if(len < 1) return; - off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x>>(3-scr->gscreen->ldepth)); + off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8; page = off/scr->apsize; off %= scr->apsize; disp = KADDR(scr->aperture); sdisp = disp+off; edisp = disp+scr->apsize; - off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x>>(3-scr->gscreen->ldepth)); - sp = ((uchar*)scr->gscreendata->data) + off; + off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8; + + sp = scr->gscreendata->bdata + off; scr->dev->page(scr, page); for(y = r.min.y; y < r.max.y; y++) { @@ -225,16 +217,15 @@ getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb) if(scr->gscreen == nil) return; - switch(scr->gscreen->ldepth){ + switch(scr->gscreen->depth){ default: x = 0x0F; break; - case 3: + case 8: x = 0xFF; break; } p &= x; - p ^= x; lock(&cursor); *pr = scr->colormap[p][0]; @@ -243,38 +234,58 @@ getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb) unlock(&cursor); } +int +setpalette(ulong p, ulong r, ulong g, ulong b) +{ + VGAscr *scr; + int d; + + scr = &vgascreen[0]; + d = scr->palettedepth; + + lock(&cursor); + scr->colormap[p][0] = r; + scr->colormap[p][1] = g; + scr->colormap[p][2] = b; + vgao(PaddrW, p); + vgao(Pdata, r>>(32-d)); + vgao(Pdata, g>>(32-d)); + vgao(Pdata, b>>(32-d)); + unlock(&cursor); + + return ~0; +} + +/* + * On some video cards (e.g. Mach64), the palette is used as the + * DAC registers for >8-bit modes. We don't want to set them when the user + * is trying to set a colormap and the card is in one of these modes. + */ int setcolor(ulong p, ulong r, ulong g, ulong b) { VGAscr *scr; - ulong x; + int x; scr = &vgascreen[0]; if(scr->gscreen == nil) return 0; - switch(scr->gscreen->ldepth){ - default: + switch(scr->gscreen->depth){ + case 1: + case 2: + case 4: x = 0x0F; break; - case 3: + case 8: x = 0xFF; break; + default: + return 0; } p &= x; - p ^= x; - - lock(&cursor); - scr->colormap[p][0] = r; - scr->colormap[p][1] = g; - scr->colormap[p][2] = b; - vgao(PaddrW, p); - vgao(Pdata, r>>(32-6)); - vgao(Pdata, g>>(32-6)); - vgao(Pdata, b>>(32-6)); - unlock(&cursor); - return ~0; + return setpalette(p, r, g, b); } int @@ -312,3 +323,193 @@ setcursor(Cursor* curs) scr->cur->load(scr, curs); } + +static ulong +pixelbits(Memimage *i, Point pt) +{ + uchar *p; + ulong val; + int off, bpp, npack; + + val = 0; + p = byteaddr(i, pt); + switch(bpp=i->depth){ + case 1: + case 2: + case 4: + npack = 8/bpp; + off = pt.x%npack; + val = p[0] >> bpp*(npack-1-off); + val &= (1<chan; chan; chan>>=8){ + nb = NBITS(chan); + ov = v = val&((1<>= nb; + + while(nb < 8){ + v |= v<>= (nb-8); + + switch(TYPE(chan)){ + case CRed: + r = v; + break; + case CGreen: + g = v; + break; + case CBlue: + b = v; + break; + case CAlpha: + a = v; + break; + case CGrey: + r = g = b = v; + break; + case CMap: + p = img->cmap->cmap2rgb+3*ov; + r = *p++; + g = *p++; + b = *p; + break; + } + } + return (r<<24)|(g<<16)|(b<<8)|a; +} + +static ulong +rgbatoimg(Memimage *img, ulong rgba) +{ + ulong chan; + int d, nb; + ulong v; + uchar *p, r, g, b, a, m; + + v = 0; + r = rgba>>24; + g = rgba>>16; + b = rgba>>8; + a = rgba; + d = 0; + for(chan=img->chan; chan; chan>>=8){ + nb = NBITS(chan); + switch(TYPE(chan)){ + case CRed: + v |= (r>>(8-nb))<>(8-nb))<>(8-nb))<>(8-nb))<cmap->rgb2cmap; + m = p[(r>>4)*256+(g>>4)*16+(b>>4)]; + v |= m<dst; + scr = &vgascreen[0]; + if(dst == nil || dst->data == nil) + return 0; + + if(dst->data->bdata != gscreendata.bdata) + return 0; + +// if(dst->data != &gscreendata){ +// lastbad = dst->data; +// lastbadi = dst; +// return 0; +// } + + if(scr->fill==nil && scr->scroll==nil) + return 0; + + /* + * If we have an opaque mask and source is one opaque + * pixel we can convert to the destination format and just + * replicate with memset. + */ + if(scr->fill && (par->state&(Simplemask|Simplesrc|Fullmask))==(Simplemask|Simplesrc|Fullmask)) + return scr->fill(scr, par->r, par->sdval); + + /* + * If no source alpha, an opaque mask, we can just copy the + * source onto the destination. If the channels are the same and + * the source is not replicated, memmove suffices. + */ + src = par->src; + if(scr->scroll && src->data->bdata==dst->data->bdata && !(src->flags&Falpha) + && (par->state&(Simplemask|Fullmask))==(Simplemask|Fullmask)){ +// if(src->zero != dst->zero){ +// lastbadsrc = src; +// lastbaddst = dst; +// iprint("#"); +// } + return scr->scroll(scr, par->r, par->sr); + } + + return 0; +} diff --git a/alphapc/screen.h b/alphapc/screen.h index 9c1ca1e95746340832344bd9981949c29f864a77..565159b1332ff5163fd2d3f6093e7a9b9d5efa95 100644 --- a/alphapc/screen.h +++ b/alphapc/screen.h @@ -66,6 +66,9 @@ struct VGAdev { void (*disable)(VGAscr*); void (*page)(VGAscr*, int); ulong (*linear)(VGAscr*, int*, int*); + void (*drawinit)(VGAscr*); + int (*fill)(VGAscr*, Rectangle, ulong); + }; struct VGAcur { @@ -75,6 +78,8 @@ struct VGAcur { void (*disable)(VGAscr*); void (*load)(VGAscr*, Cursor*); int (*move)(VGAscr*, Point); + + int doespanning; }; /* @@ -97,27 +102,41 @@ struct VGAscr { ulong io; /* device specific registers */ ulong colormap[Pcolours][3]; + int palettedepth; Memimage* gscreen; Memdata* gscreendata; Memsubfont* memdefont; + + int (*fill)(VGAscr*, Rectangle, ulong); + int (*scroll)(VGAscr*, Rectangle, Rectangle); + ulong id; /* internal identifier for driver use */ }; extern VGAscr vgascreen[]; enum { - Backgnd = Pwhite, + Backgnd = 0, /* black */ }; /* mouse.c */ extern void mousectl(char*[], int); /* screen.c */ +extern int hwaccel; /* use hw acceleration; default on */ extern void flushmemscreen(Rectangle); extern int cursoron(int); extern void cursoroff(int); extern void setcursor(Cursor*); -extern int screensize(int, int, int); +extern int screensize(int, int, int, ulong); extern int screenaperture(int, int); +extern Rectangle physgscreenr; /* actual monitor size */ + +/* devdraw.c */ +extern void deletescreenimage(void); +extern int drawhasclients(void); /* vga.c */ extern void vgascreenwin(VGAscr*); +extern void vgaimageinit(ulong); + +extern void drawblankscreen(int); diff --git a/alphapc/trap.c b/alphapc/trap.c index 63b4e560c001df28a1d1cdd4538f08fc8a526890..878ba992013daa26bc03260b4e976bf3d4b06398 100644 --- a/alphapc/trap.c +++ b/alphapc/trap.c @@ -29,10 +29,87 @@ char *regname[]={ "R18", }; +static Lock vctllock; +static Vctl *vctl[256]; + void -intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf) +intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name) +{ + int vno; + Vctl *v, *p; + + v = xalloc(sizeof(Vctl)); + v->isintr = 1; + v->irq = irq; + v->tbdf = tbdf; + v->f = f; + v->a = a; + strncpy(v->name, name, NAMELEN-1); + v->name[NAMELEN-1] = 0; + + ilock(&vctllock); + vno = arch->intrenable(v); + if(vno == -1){ + iunlock(&vctllock); + print("intrenable: couldn't enable irq %d, tbdf 0x%uX for %s\n", + irq, tbdf, v->name); + if(p=vctl[vno]){ + print("intrenable: irq %d is already used by", irq); + for(; p; p=p->next) + print(" %s", p->name); + print("\n"); + } + xfree(v); + return; + } + if(vctl[vno]){ + if(vctl[vno]->isr != v->isr || vctl[vno]->eoi != v->eoi) + panic("intrenable: handler: %s %s %luX %luX %luX %luX\n", + vctl[vno]->name, v->name, + vctl[vno]->isr, v->isr, vctl[vno]->eoi, v->eoi); + v->next = vctl[vno]; + } + vctl[vno] = v; + iunlock(&vctllock); +} + +int +irqallocread(char *buf, long n, vlong offset) { - arch->intrenable(irq, f, a, tbdf); + int vno; + Vctl *v; + long oldn; + char str[11+1+NAMELEN+1], *p; + int m; + + if(n < 0 || offset < 0) + error(Ebadarg); + + oldn = n; + for(vno=0; vnonext){ + m = snprint(str, sizeof str, "%11d %11d %.*s\n", vno, v->irq, NAMELEN, v->name); + if(m <= offset) /* if do not want this, skip entry */ + offset -= m; + else{ + /* skip offset bytes */ + m -= offset; + p = str+offset; + offset = 0; + + /* write at most max(n,m) bytes */ + if(m > n) + m = n; + memmove(buf, p, m); + n -= m; + buf += m; + + if(n == 0) + return oldn; + } + } + } + return oldn - n; } typedef struct Mcheck Mcheck; @@ -99,6 +176,79 @@ mcheck(void *x) firmware(); } +void +intr(Ureg *ur) +{ + int i, vno; + Vctl *ctl, *v; + Mach *mach; + + vno = (ulong)ur->a1>>4; + vno -= 0x80; + if(vno < nelem(vctl) && (ctl = vctl[vno])){ + if(ctl->isintr){ + m->intr++; + if(vno >= VectorPIC && vno <= MaxVectorPIC) + m->lastintr = vno-VectorPIC; + } + + if(ctl->isr) + ctl->isr(vno); + for(v = ctl; v != nil; v = v->next) { + if(v->f) + v->f(ur, v->a); + } + + if(ctl->eoi) + ctl->eoi(vno); + + /* + * preemptive scheduling. to limit stack depth, + * make sure process has a chance to return from + * the current interrupt before being preempted a + * second time. + */ + if(ctl->isintr) + if(up && up->state == Running) + if(anyhigher()) + if(up->preempted == 0) + if(!active.exiting){ + up->preempted = 1; + sched(); + splhi(); + up->preempted = 0; + return; + } + } + else if(vno >= VectorPIC && vno <= MaxVectorPIC){ + /* + * An unknown interrupt. + * Check for a default IRQ7. This can happen when + * the IRQ input goes away before the acknowledge. + * In this case, a 'default IRQ7' is generated, but + * the corresponding bit in the ISR isn't set. + * In fact, just ignore all such interrupts. + */ + iprint("cpu%d: spurious interrupt %d, last %d", + m->machno, vno-VectorPIC, m->lastintr); + for(i = 0; i < 32; i++){ + if(!(active.machs & (1<machno == mach->machno) + continue; + iprint(": cpu%d: last %d", mach->machno, mach->lastintr); + } + iprint("\n"); + m->spuriousintr++; + return; + } + else{ + dumpregs(ur); + panic("unknown intr: %d\n", vno); /* */ + } +} + void trap(Ureg *ur) { @@ -133,23 +283,7 @@ trap(Ureg *ur) mcheck((void*)(KZERO|(ulong)ur->a2)); break; case 3: /* device */ - arch->intr(ur); - /* - * preemptive scheduling. to limit stack depth, - * make sure process has a chance to return from - * the current interrupt before being preempted a - * second time. - */ - if(up && up->state == Running) - if(anyhigher()) - if(up->preempted == 0) - if(!active.exiting){ - up->preempted = 1; - sched(); - splhi(); - up->preempted = 0; - return; - } + intr(ur); break; case 4: /* perf counter */ panic("perf count"); diff --git a/alphapc/vga.c b/alphapc/vga.c index 7ca41d658d1d7f0020fe4a16a9837216f4a5e342..043143b55c7e804d9f130502be0e1abd4d0421a9 100644 --- a/alphapc/vga.c +++ b/alphapc/vga.c @@ -11,42 +11,37 @@ #include #include "screen.h" -static ulong backbits = (Backgnd<<24)|(Backgnd<<16)|(Backgnd<<8)|Backgnd; -static Memdata backdata = { - nil, - &backbits -}; -static Memimage xback = { - { 0, 0, 1, 1 }, - { -100000, -100000, 100000, 100000 }, - 3, - 1, - &backdata, - 0, - 1 -}; -static Memimage* back = &xback; - -static ulong consbits = 0; -static Memdata consdata = { - nil, - &consbits -}; -static Memimage conscol = { - { 0, 0, 1, 1 }, - { -100000, -100000, 100000, 100000 }, - 3, - 1, - &consdata, - 0, - 1 -}; +static Memimage* back; +static Memimage *conscol; static Point curpos; static Rectangle window; static int *xp; static int xbuf[256]; static Lock vgascreenlock; +int drawdebug; + +void +vgaimageinit(ulong chan) +{ + if(back == nil){ + back = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */ + if(back == nil) + panic("back alloc"); /* RSC BUG */ + back->flags |= Frepl; + back->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); + memfillcolor(back, DBlack); + } + + if(conscol == nil){ + conscol = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */ + if(conscol == nil) + panic("conscol alloc"); /* RSC BUG */ + conscol->flags |= Frepl; + conscol->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF); + memfillcolor(conscol, DWhite); + } +} static void vgascroll(VGAscr* scr) @@ -59,9 +54,9 @@ vgascroll(VGAscr* scr) o = 8*h; r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); p = Pt(window.min.x, window.min.y+o); - memimagedraw(scr->gscreen, r, scr->gscreen, p, memones, p); + memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p); r = Rpt(Pt(window.min.x, window.max.y-o), window.max); - memimagedraw(scr->gscreen, r, back, ZP, memones, ZP); + memimagedraw(scr->gscreen, r, back, ZP, nil, ZP); curpos.y -= o; } @@ -73,6 +68,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr) int h, w, pos; Rectangle r; +// drawdebug = 1; if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) xp = xbuf; @@ -100,8 +96,8 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr) pos = (curpos.x-window.min.x)/w; pos = 4-(pos%4); r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y+h); - memimagedraw(scr->gscreen, r, back, back->r.min, memones, back->r.min); - bbox(flushr, r); + memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP); + combinerect(flushr, r); curpos.x += pos*w; break; @@ -110,8 +106,8 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr) break; xp--; r = Rect(*xp, curpos.y, curpos.x, curpos.y+h); - memimagedraw(scr->gscreen, r, back, back->r.min, memones, back->r.min); - bbox(flushr, r); + memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP); + combinerect(flushr, r); curpos.x = *xp; break; @@ -124,11 +120,12 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr) *xp++ = curpos.x; r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h); - memimagedraw(scr->gscreen, r, back, back->r.min, memones, back->r.min); - memimagestring(scr->gscreen, curpos, &conscol, scr->memdefont, buf); - bbox(flushr, r); + memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min); + memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf); + combinerect(flushr, r); curpos.x += w; } +// drawdebug = 0; } static void diff --git a/alphapc/vgas3.c b/alphapc/vgas3.c index 01e0daf8bc7ec7542c00a9e6ab2523b5b1b826c6..37e84849c1346717a4f55b1903e138a8927c211c 100644 --- a/alphapc/vgas3.c +++ b/alphapc/vgas3.c @@ -19,7 +19,7 @@ s3pageset(VGAscr* scr, int page) int opage; crt35 = vgaxi(Crtx, 0x35); - if(scr->gscreen->ldepth == 3){ + if(scr->gscreen->depth >= 8){ /* * The S3 registers need to be unlocked for this. * Let's hope they are already: @@ -127,7 +127,7 @@ s3disable(VGAscr*) static void s3enable(VGAscr* scr) { - int i, id; + int i; ulong storage; s3disable(scr); @@ -135,30 +135,16 @@ s3enable(VGAscr* scr) /* * Cursor colours. Set both the CR0[EF] and the colour * stack in case we are using a 16-bit RAMDAC. - * This stuff is just a mystery for the ViRGE/GX2. */ vgaxo(Crtx, 0x0E, Pwhite); vgaxo(Crtx, 0x0F, Pblack); vgaxi(Crtx, 0x45); - id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E); - switch(id){ - - case 0xE110: /* ViRGE/GX2 */ - for(i = 0; i < 3; i++) - vgaxo(Crtx, 0x4A, Pblack); - vgaxi(Crtx, 0x45); - for(i = 0; i < 3; i++) - vgaxo(Crtx, 0x4B, Pwhite); - break; - default: - for(i = 0; i < 3; i++) - vgaxo(Crtx, 0x4A, Pwhite); - vgaxi(Crtx, 0x45); - for(i = 0; i < 3; i++) - vgaxo(Crtx, 0x4B, Pblack); - break; - } + for(i = 0; i < 3; i++) + vgaxo(Crtx, 0x4A, Pblack); + vgaxi(Crtx, 0x45); + for(i = 0; i < 3; i++) + vgaxo(Crtx, 0x4B, Pwhite); /* * Find a place for the cursor data in display memory. @@ -195,7 +181,10 @@ s3load(VGAscr* scr, Cursor* curs) id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E); switch(id){ + case 0xE131: /* ViRGE */ + case 0xE18A: /* ViRGE/[DG]X */ case 0xE110: /* ViRGE/GX2 */ + case 0xE13D: /* ViRGE/VX */ p += scr->storage; break; @@ -238,7 +227,10 @@ s3load(VGAscr* scr, Cursor* curs) switch(id){ + case 0xE131: /* ViRGE */ + case 0xE18A: /* ViRGE/[DG]X */ case 0xE110: /* ViRGE/GX2 */ + case 0xE13D: /* ViRGE/VX */ break; default: diff --git a/boot/key.c b/boot/key.c index b05bd463a5956f4151a931ea1348db43c3da7893..74cbed2cb8fea7a4002cd4ad5e8e6c29740ac923 100644 --- a/boot/key.c +++ b/boot/key.c @@ -37,7 +37,7 @@ key(int islocal, Method *mp) if(strcmp(cputype, "sparc") == 0){ fd = open("#r/nvram", ORDWR); safeoff = 1024+850; - } else if(strcmp(cputype, "386") == 0){ + } else if(strcmp(cputype, "386") == 0 || strcmp(cputype, "alpha") == 0){ fd = open("#H/hd0nvram", ORDWR); if(fd < 0) fd = open("#w/sd0nvram", ORDWR); @@ -83,9 +83,6 @@ key(int islocal, Method *mp) } close(fd); -//fprint(2, "hostowner = %s\n", safe->authid); -//fprint(2, "hostdomain = %s\n", safe->authdom); - /* set host's key */ if(writefile("#c/key", safe->machkey, DESKEYLEN) < 0) fatal("#c/key");