M alphapc/arch164.c => alphapc/arch164.c +15 -90
@@ 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<<i)))
- continue;
- mach = MACHP(i);
- if(m->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,
M alphapc/audio.h => alphapc/audio.h +2 -2
@@ 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")
M alphapc/dat.h => alphapc/dat.h +5 -7
@@ 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);
A alphapc/devarch.c => alphapc/devarch.c +437 -0
@@ 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 = "<unknown>";
+ 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 = "<unknown>";
+ 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);
+}
M alphapc/devether.c => alphapc/devether.c +30 -16
@@ 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)
M alphapc/devvga.c => alphapc/devvga.c +126 -77
@@ 14,24 14,27 @@
#include <cursor.h>
#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<<scr->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;
M alphapc/dma.c => alphapc/dma.c +4 -0
@@ 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);
M alphapc/ether2114x.c => alphapc/ether2114x.c +6 -1
@@ 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;
M alphapc/floppy.h => alphapc/floppy.h +8 -1
@@ 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");
}
/*
M alphapc/fns.h => alphapc/fns.h +10 -2
@@ 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);
M alphapc/i8259.c => alphapc/i8259.c +8 -7
@@ 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<<v))
- irqctl->eoi = i8259isr;
+ vctl->eoi = i8259isr;
else
- irqctl->isr = i8259isr;
- irqctl->isintr = 1;
+ vctl->isr = i8259isr;
+ vctl->isintr = 1;
return v;
}
M alphapc/io.h => alphapc/io.h +12 -25
@@ 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 */
M alphapc/kbd.c => alphapc/kbd.c +26 -2
@@ 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);
}
M alphapc/main.c => alphapc/main.c +181 -49
@@ 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;
+}
M alphapc/mmu.c => alphapc/mmu.c +2 -2
@@ 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");
}
M alphapc/ns16552.h => alphapc/ns16552.h +6 -2
@@ 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);
}
M alphapc/pci.c => alphapc/pci.c +10 -1
@@ 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 */
M alphapc/screen.c => alphapc/screen.c +264 -63
@@ 13,26 13,14 @@
#include <cursor.h>
#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<<z))/BI2WD;
- gscreendata.data = xalloc(width*BY2WD*y);
- if(gscreendata.data == 0)
+ gscreendata.bdata = xalloc(width*BY2WD*y);
+ if(gscreendata.bdata == 0)
error("screensize: vga soft memory");
- memset(gscreendata.data, Backgnd, width*BY2WD*y);
+ memset(gscreendata.bdata, Backgnd, width*BY2WD*y);
scr->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<<gscreen.ldepth)+31)/32;
- gscreen.r.min = ZP;
- gscreen.r.max = Pt(x, y);
- gscreen.clipr = gscreen.r;
- gscreen.repl = 0;
+ if(gscreen)
+ freememimage(gscreen);
- scr->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];
@@ 244,37 235,57 @@ getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
}
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<<bpp)-1;
+ break;
+ case 8:
+ val = p[0];
+ break;
+ case 16:
+ val = p[0]|(p[1]<<8);
+ break;
+ case 24:
+ val = p[0]|(p[1]<<8)|(p[2]<<16);
+ break;
+ case 32:
+ val = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
+ break;
+ }
+ while(bpp<32){
+ val |= val<<bpp;
+ bpp *= 2;
+ }
+ return val;
+}
+
+
+static ulong
+imgtorgba(Memimage *img, ulong val)
+{
+ uchar r, g, b, a;
+ int nb, ov, v;
+ ulong chan;
+ uchar *p;
+
+ a = 0xFF;
+ r = g = b = 0xAA; /* garbage */
+ for(chan=img->chan; chan; chan>>=8){
+ nb = NBITS(chan);
+ ov = v = val&((1<<nb)-1);
+ val >>= nb;
+
+ while(nb < 8){
+ v |= v<<nb;
+ nb *= 2;
+ }
+ 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))<<d;
+ break;
+ case CGreen:
+ v |= (g>>(8-nb))<<d;
+ break;
+ case CBlue:
+ v |= (b>>(8-nb))<<d;
+ break;
+ case CAlpha:
+ v |= (a>>(8-nb))<<d;
+ break;
+ case CMap:
+ p = img->cmap->rgb2cmap;
+ m = p[(r>>4)*256+(g>>4)*16+(b>>4)];
+ v |= m<<d;
+ break;
+ case CGrey:
+ m = RGB2K(r,g,b);
+ v |= m<<d;
+ break;
+ }
+ d += nb;
+ }
+// print("rgba2img %.8lux = %.*lux\n", rgba, 2*d/8, v);
+ return v;
+}
+
+Memimage *lastbadi;
+Memdata *lastbad;
+Memimage *lastbadsrc, *lastbaddst;
+int hwaccel = 1;
+
+int
+hwdraw(Memdrawparam *par)
+{
+ VGAscr *scr;
+ Memimage *dst, *src;
+
+ if(hwaccel == 0)
+ return 0;
+
+ dst = par->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;
+}
M alphapc/screen.h => alphapc/screen.h +21 -2
@@ 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);
M alphapc/trap.c => alphapc/trap.c +153 -19
@@ 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; 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);
+ 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;
@@ 100,6 177,79 @@ mcheck(void *x)
}
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<<i)))
+ continue;
+ mach = MACHP(i);
+ if(m->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)
{
char buf[ERRLEN];
@@ 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");
M alphapc/vga.c => alphapc/vga.c +36 -39
@@ 11,42 11,37 @@
#include <cursor.h>
#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
M alphapc/vgas3.c => alphapc/vgas3.c +13 -21
@@ 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:
M boot/key.c => boot/key.c +1 -4
@@ 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");