A alphapc/cycintr.c => alphapc/cycintr.c +27 -0
@@ 0,0 1,27 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+int
+havecycintr(void)
+{
+ return 0;
+}
+
+void
+cycintradd(Cycintr *)
+{
+}
+
+void
+cycintrdel(Cycintr *)
+{
+}
+
+void
+clockintrsched(void)
+{
+}
M alphapc/dat.h => alphapc/dat.h +12 -0
@@ 1,4 1,5 @@
typedef struct Conf Conf;
+typedef struct Cycintr Cycintr;
typedef struct FPsave FPsave;
typedef struct ISAConf ISAConf;
typedef struct Label Label;
@@ 247,3 248,14 @@ struct DevConf
int nports; /* Number of ports */
port_t *ports; /* The ports themselves */
};
+
+/*
+ * fasttick timer interrupts (Dummy for now)
+ */
+struct Cycintr
+{
+ vlong when; /* fastticks when f should be called */
+ void (*f)(Ureg*, Cycintr*);
+ void *a;
+ Cycintr *next;
+};
M alphapc/fns.h => alphapc/fns.h +4 -0
@@ 7,11 7,14 @@ void arith(void);
void clearmmucache(void);
void clock(Ureg*);
void clockinit(void);
+void clockintrsched(void);
#define coherence mb
int cistrcmp(char*, char*);
int cistrncmp(char*, char*, int);
void cpuidprint(void);
void cserve(ulong, ulong);
+void cycintradd(Cycintr *);
+void cycintrdel(Cycintr *);
int dmacount(int);
int dmadone(int);
void dmaend(int);
@@ 32,6 35,7 @@ char *getconf(char*);
ulong getfcr(void);
ulong getstatus(void);
void gotopc(ulong);
+int havecycintr(void);
int i8042auxcmd(int);
void i8042auxenable(void (*)(int, int));
void i8042reset(void);
M bitsy/devether.c => bitsy/devether.c +1 -1
@@ 87,7 87,7 @@ etherconfig(int on, char *spec, DevConf *cf)
if(ether->mem)
p = seprint(p, e, " addr 0x%luX", PADDR(ether->mem));
if(ether->size)
- p = seprint(p, e, " size 0x%luX", ether->size);
+ p = seprint(p, e, " size 0x%X", ether->size);
p = seprint(p, e, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX",
ether->ea[0], ether->ea[1], ether->ea[2],
ether->ea[3], ether->ea[4], ether->ea[5]);
M bitsy/devflash.c => bitsy/devflash.c +1 -1
@@ 338,7 338,7 @@ flashctlread(FPart *fp, void* a, long n, vlong off)
buf = smalloc(1024);
e = buf + 1024;
- p = seprint(buf, e, "0x%-9lux 0x%-9lux 0x%-9lux 0x%-9lux\n", fp->end-fp->start,
+ p = seprint(buf, e, "0x%-9lux 0x%-9x 0x%-9ux 0x%-9ux\n", fp->end-fp->start,
flash.wbsize, flash.manid, flash.devid);
addr = fp->start;
for(i = 0; i < flash.nr && addr < fp->end; i++)
M bitsy/fns.h => bitsy/fns.h +4 -0
@@ 13,7 13,10 @@ int cistrcmp(char*, char*);
int cistrncmp(char*, char*, int);
void clockinit(void);
void clockpower(int);
+void clockintrsched(void);
#define coherence()
+void cycintradd(Cycintr *);
+void cycintrdel(Cycintr *);
#define dcflush(a, b)
void delay(int);
void µdelay(ulong);
@@ 40,6 43,7 @@ void* getlink(void);
ulong getsp(void);
void gpiointrenable(ulong, int, void (*)(Ureg*, void*), void*, char*);
void h3650uartsetup(void);
+int havecycintr(void);
void icacheinvalidate(void);
void idle(void);
void idlehands(void);
A mtx/cycintr.c => mtx/cycintr.c +27 -0
@@ 0,0 1,27 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+int
+havecycintr(void)
+{
+ return 0;
+}
+
+void
+cycintradd(Cycintr *)
+{
+}
+
+void
+cycintrdel(Cycintr *)
+{
+}
+
+void
+clockintrsched(void)
+{
+}
M mtx/dat.h => mtx/dat.h +11 -0
@@ 1,4 1,5 @@
typedef struct Conf Conf;
+typedef struct Cycintr Cycintr;
typedef struct FPsave FPsave;
typedef struct ISAConf ISAConf;
typedef struct Label Label;
@@ 191,6 192,16 @@ struct ISAConf {
int nopt;
char *opt[NISAOPT];
};
+/*
+ * fasttick timer interrupts (Dummy for now)
+ */
+struct Cycintr
+{
+ vlong when; /* fastticks when f should be called */
+ void (*f)(Ureg*, Cycintr*);
+ void *a;
+ Cycintr *next;
+};
#define MACHP(n) ((Mach *)((int)&mach0+n*BY2PG))
extern Mach mach0;
M mtx/fns.h => mtx/fns.h +4 -0
@@ 6,7 6,10 @@ int cistrncmp(char*, char*, int);
void clockcheck(void);
void clockinit(void);
void clockintr(Ureg*);
+void clockintrsched(void);
#define coherence() eieio()
+void cycintradd(Cycintr *);
+void cycintrdel(Cycintr *);
void cpuidentify(void);
void cpuidprint(void);
void dcflush(void*, ulong);
@@ 33,6 36,7 @@ ulong getpvr(void);
ulong gettbl(void);
ulong gettbu(void);
void gotopc(ulong);
+int havecycintr(void);
void hwintrinit(void);
void i8250console(void);
void i8259init(void);
M pc/dat.h => pc/dat.h +1 -2
@@ 1,4 1,5 @@
typedef struct Conf Conf;
+typedef struct Cycintr Cycintr;
typedef struct FPsave FPsave;
typedef struct ISAConf ISAConf;
typedef struct Label Label;
@@ 199,8 200,6 @@ struct Mach
int stack[1];
};
-typedef struct Cycintr Cycintr;
-
/*
* fasttick timer interrupts
*/
M pc/devarch.c => pc/devarch.c +6 -10
@@ 363,21 363,19 @@ archread(Chan *c, void *a, long n, vlong offset)
if(n & 1)
error(Ebadarg);
checkport(offset, offset+n);
- n /= 2;
sp = a;
for(port = offset; port < offset+n; port += 2)
*sp++ = ins(port);
- return n*2;
+ return n;
case Qiol:
if(n & 3)
error(Ebadarg);
checkport(offset, offset+n);
- n /= 4;
lp = a;
for(port = offset; port < offset+n; port += 4)
*lp++ = inl(port);
- return n*4;
+ return n;
case Qioalloc:
break;
@@ 427,24 425,22 @@ archwrite(Chan *c, void *a, long n, vlong offset)
return n;
case Qiow:
- if((n & 01) || (offset & 01))
+ if(n & 1)
error(Ebadarg);
checkport(offset, offset+n);
- n /= 2;
sp = a;
for(port = offset; port < offset+n; port += 2)
outs(port, *sp++);
- return n*2;
+ return n;
case Qiol:
- if((n & 0x03) || (offset & 0x03))
+ if(n & 3)
error(Ebadarg);
checkport(offset, offset+n);
- n /= 4;
lp = a;
for(port = offset; port < offset+n; port += 4)
outl(port, *lp++);
- return n*4;
+ return n;
default:
if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
M pc/ether79c970.c => pc/ether79c970.c +3 -3
@@ 501,9 501,6 @@ reset(Ether* ether)
/*
* Allocate a controller structure and start to initialise it.
*/
- if(ioalloc(ctlr->port, 0x20, 0, "ether79c970") < 0)
- return -1;
-
ether->ctlr = ctlr;
ether->port = ctlr->port;
ether->irq = ctlr->pcidev->intl;
@@ 523,6 520,7 @@ reset(Ether* ether)
ctlr->iow = io32w;
}else{
print("#l%d: card doesn't talk right\n", ether->ctlrno);
+iprint("#l%d: card doesn't talk right\n", ether->ctlrno);
iunlock(ctlr);
return -1;
}
@@ 539,6 537,8 @@ reset(Ether* ether)
default:
print("#l%d: unknown PCnet card version %.7ux\n",
ether->ctlrno, x&0xFFFFFFF);
+iprint("#l%d: unknown PCnet card version %.7ux\n",
+ ether->ctlrno, x&0xFFFFFFF);
iunlock(ctlr);
return -1;
}
M pc/fns.h => pc/fns.h +1 -0
@@ 3,6 3,7 @@
void aamloop(int);
Dirtab* addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
//void addscsilink(char*, Scsiio (*)(int, ISAConf*));
+void apicclkenable(void);
void archinit(void);
void bootargs(ulong);
vlong checkcycintr(Ureg*, void*);
M pc/i8253.c => pc/i8253.c +2 -5
@@ 118,33 118,30 @@ i8253init(int aalcycles, int havecycleclock)
* prefetch buffer.
*
*/
- outb(Tmode, Latch0);
if(havecycleclock)
rdtsc(&a);
+ outb(Tmode, Latch0);
x = inb(T0cntr);
x |= inb(T0cntr)<<8;
aamloop(loops);
- outb(Tmode, Latch0);
if(havecycleclock)
rdtsc(&b);
y = inb(T0cntr);
y |= inb(T0cntr)<<8;
x -= y;
-
+
if(x < 0)
x += Freq/HZ;
if(x > Freq/(3*HZ))
break;
}
-
/*
* figure out clock frequency and a loop multiplier for delay().
* n.b. counter goes up by 2*Freq
*/
cpufreq = loops*((aalcycles*2*Freq)/x);
m->loopconst = (cpufreq/1000)/aalcycles; /* AAM+LOOP's for 1 ms */
-
if(havecycleclock){
/* counter goes up by 2*Freq */
M pc/mp.c => pc/mp.c +37 -0
@@ 43,6 43,43 @@ static char* buses[] = {
0,
};
+void
+apicclkenable(void)
+{
+ Apic *apic;
+
+ i8259init();
+
+ /* Uniprocessor local apic init for apic clock */
+ apic = &mpapic[0];
+ apic->type = PcmpPROCESSOR;
+ apic->apicno = 0;
+ apic->flags = 0;
+ apic->lintr[0] = ApicIMASK;
+ apic->lintr[1] = ApicIMASK;
+ apic->machno = 0;
+ apic->addr = (ulong*)0xfee00000;
+ machno2apicno[0] = 0;
+
+ /*
+ * Map the local APIC.
+ */
+ if(mmukmap((ulong)apic->addr, 0, 1024) == 0)
+ return;
+
+ /*
+ * These interrupts are local to the processor
+ * and do not appear in the I/O APIC so it is OK
+ * to set them now.
+ */
+ intrenable(IrqTIMER, clockintr, 0, BUSUNKNOWN, "clock");
+ intrenable(IrqERROR, lapicerror, 0, BUSUNKNOWN, "lapicerror");
+ intrenable(IrqSPURIOUS, lapicspurious, 0, BUSUNKNOWN, "lapicspurious");
+
+ lapicinit(apic);
+ lapiconline();
+}
+
static Apic*
mkprocessor(PCMPprocessor* p)
{
M pc/screen.c => pc/screen.c +7 -0
@@ 72,6 72,9 @@ screensize(int x, int y, int z, ulong chan)
if(gscreen == nil)
return -1;
+ if(scr->dev && scr->dev->flush)
+ scr->useflush = 1;
+
scr->palettedepth = 6; /* default */
scr->gscreendata = &gscreendata;
scr->memdefont = getmemdefont();
@@ 147,6 150,10 @@ flushmemscreen(Rectangle r)
int y, len, incs, off, page;
scr = &vgascreen[0];
+ if(scr->dev && scr->dev->flush){
+ scr->dev->flush(scr, r);
+ return;
+ }
if(scr->gscreen == nil || scr->useflush == 0)
return;
if(scr->dev == nil || scr->dev->page == nil)
M pc/screen.h => pc/screen.h +2 -0
@@ 70,6 70,7 @@ struct VGAdev {
int (*fill)(VGAscr*, Rectangle, ulong);
void (*ovlctl)(VGAscr*, Chan*, void*, int);
int (*ovlwrite)(VGAscr*, void*, int, vlong);
+ void (*flush)(VGAscr*, Rectangle);
};
struct VGAcur {
@@ 144,6 145,7 @@ extern void deletescreenimage(void);
extern int drawhasclients(void);
extern ulong blanktime;
extern void setscreenimageclipr(Rectangle);
+extern void drawflush(void);
/* vga.c */
extern void vgascreenwin(VGAscr*);
M pc/trap.c => pc/trap.c +7 -5
@@ 434,15 434,17 @@ callwithureg(void (*fn)(Ureg*))
static void
_dumpstack(Ureg *ureg)
{
- ulong l, v, i;
+ ulong l, v, i, estack;
extern ulong etext;
- if(up == 0)
- return;
-
print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp);
i = 0;
- for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){
+ if(up)
+ estack = (ulong)up->kstack+KSTACK;
+ else
+ estack = (ulong)m+MACHSIZE;
+
+ for(l=(ulong)&l; l<estack; l+=4){
v = *(ulong*)l;
if(KTZERO < v && v < (ulong)&etext){
/*
M pc/vgavmware.c => pc/vgavmware.c +209 -5
@@ 25,43 25,95 @@ enum {
Rwidth,
Rheight,
Rmaxwidth,
+
Rmaxheight,
Rdepth,
Rbpp,
Rpseudocolor,
Rrmask,
+
Rgmask,
Rbmask,
Rbpl,
Rfbstart,
Rfboffset,
+
Rfbmaxsize,
Rfbsize,
Rcap,
Rmemstart,
Rmemsize,
+
Rconfigdone,
Rsync,
Rbusy,
Rguestid,
Rcursorid,
+
Rcursorx,
Rcursory,
Rcursoron,
Nreg,
+ Crectfill = 1<<0,
+ Crectcopy = 1<<1,
+ Crectpatfill = 1<<2,
+ Coffscreen = 1<<3,
+ Crasterop = 1<<4,
+ Ccursor = 1<<5,
+ Ccursorbypass = 1<<6,
+ Ccursorbypass2 = 1<<7,
+ C8bitemulation = 1<<8,
+ Calphacursor = 1<<9,
+
+ FifoMin = 0,
+ FifoMax = 1,
+ FifoNextCmd = 2,
+ FifoStop = 3,
+ FifoUser = 4,
+
+ Xupdate = 1,
+ Xrectfill = 2,
+ Xrectcopy = 3,
+ Xdefinebitmap = 4,
+ Xdefinebitmapscanline = 5,
+ Xdefinepixmap = 6,
+ Xdefinepixmapscanline = 7,
+ Xrectbitmapfill = 8,
+ Xrectpixmapfill = 9,
+ Xrectbitmapcopy = 10,
+ Xrectpixmapcopy = 11,
+ Xfreeobject = 12,
+ Xrectropfill = 13,
+ Xrectropcopy = 14,
+ Xrectropbitmapfill = 15,
+ Xrectroppixmapfill = 16,
+ Xrectropbitmapcopy = 17,
+ Xrectroppixmapcopy = 18,
+ Xdefinecursor = 19,
+ Xdisplaycursor = 20,
+ Xmovecursor = 21,
+ Xdefinealphacursor = 22,
+ Xcmdmax = 23,
+
+ CursorOnHide = 0,
+ CursorOnShow = 1,
+ CursorOnRemoveFromFb = 2,
+ CursorOnRestoreToFb = 3,
+
Rpalette = 1024,
};
typedef struct Vmware Vmware;
struct Vmware {
- ulong mmio;
ulong fb;
ulong ra;
ulong rd;
ulong r[Nreg];
+ ulong *mmio;
+ ulong mmiosize;
char chan[32];
int depth;
@@ 84,6 136,14 @@ vmwr(Vmware *vm, int i, ulong v)
outl(vm->rd, v);
}
+static void
+vmwait(Vmware *vm)
+{
+ vmwr(vm, Rsync, 1);
+ while(vmrd(vm, Rbusy))
+ ;
+}
+
static ulong
vmwarelinear(VGAscr* scr, int* size, int* align)
{
@@ 97,6 157,7 @@ vmwarelinear(VGAscr* scr, int* size, int* align)
oapsize = scr->apsize;
wasupamem = scr->isupamem;
+iprint("osize %d oaperture %.8lux oapsize %d wasupamem %d\n", osize, oaperture, oapsize, wasupamem);
p = pcimatch(nil, PCIVMWARE, 0);
if(p == nil)
error("no vmware card found");
@@ 128,33 189,111 @@ vmwarelinear(VGAscr* scr, int* size, int* align)
if(wasupamem && upamalloc(oaperture, oapsize, 0))
scr->isupamem = 1;
}else
+{
+memset((void*)KADDR(aperture), 0x7F, 1048576);
scr->isupamem = 1;
+}
+iprint("aperture %lux size %lux\n", aperture, *size);
if(oaperture && aperture != oaperture)
print("warning (BUG): redefinition of aperture does not change vmwarescreen segment\n");
addvgaseg("vmwarescreen", aperture, osize);
+
return aperture;
}
static void
-vmwaredisable(VGAscr*)
+vmfifowr(Vmware *vm, ulong v)
{
+ ulong *mm;
+
+ mm = vm->mmio;
+ if(mm == nil){
+ iprint("!");
+ return;
+ }
+
+ if(mm[FifoNextCmd]+sizeof(ulong) == mm[FifoStop]
+ || (mm[FifoNextCmd]+sizeof(ulong) == mm[FifoMax]
+ && mm[FifoStop] == mm[FifoMin]))
+ vmwait(vm);
+
+ mm[mm[FifoNextCmd]/sizeof(ulong)] = v;
+ mm[FifoNextCmd] += sizeof(ulong);
+ if(mm[FifoNextCmd]==mm[FifoMax])
+ mm[FifoNextCmd] = mm[FifoMin];
+}
+
+static void
+vmwareflush(VGAscr*, Rectangle r)
+{
+ if(vm->mmio == nil)
+ return;
+
+ vmfifowr(vm, Xupdate);
+ vmfifowr(vm, r.min.x);
+ vmfifowr(vm, r.min.y);
+ vmfifowr(vm, r.max.x-r.min.x);
+ vmfifowr(vm, r.max.y-r.min.y);
+ vmwait(vm);
}
static void
-vmwareload(VGAscr*, Cursor*)
+vmwareload(VGAscr*, Cursor *c)
{
+ int i;
+ ulong clr, set;
+ ulong and[16];
+ ulong xor[16];
+
+ if(vm->mmio == nil)
+ return;
+ vmfifowr(vm, Xdefinecursor);
+ vmfifowr(vm, 1); /* cursor id */
+ vmfifowr(vm, -c->offset.x);
+ vmfifowr(vm, -c->offset.y);
+
+ vmfifowr(vm, 16); /* width */
+ vmfifowr(vm, 16); /* height */
+ vmfifowr(vm, 1); /* depth for and mask */
+ vmfifowr(vm, 1); /* depth for xor mask */
+
+ for(i=0; i<16; i++){
+ clr = (c->clr[i*2+1]<<8) | c->clr[i*2];
+ set = (c->set[i*2+1]<<8) | c->set[i*2];
+ and[i] = ~(clr|set); /* clr and set pixels => black */
+ xor[i] = clr&~set; /* clr pixels => white */
+ }
+ for(i=0; i<16; i++)
+ vmfifowr(vm, and[i]);
+ for(i=0; i<16; i++)
+ vmfifowr(vm, xor[i]);
+
+ vmwait(vm);
}
static int
-vmwaremove(VGAscr*, Point)
+vmwaremove(VGAscr*, Point p)
{
+ vmwr(vm, Rcursorid, 1);
+ vmwr(vm, Rcursorx, p.x);
+ vmwr(vm, Rcursory, p.y);
+ vmwr(vm, Rcursoron, CursorOnShow);
return 0;
}
static void
+vmwaredisable(VGAscr*)
+{
+ vmwr(vm, Rcursorid, 1);
+ vmwr(vm, Rcursoron, CursorOnHide);
+}
+
+static void
vmwareenable(VGAscr*)
{
+ vmwr(vm, Rcursorid, 1);
+ vmwr(vm, Rcursoron, CursorOnShow);
}
static void
@@ 162,9 301,70 @@ vmwareblank(int)
{
}
+static int
+vmwarescroll(VGAscr*, Rectangle r, Rectangle sr)
+{
+ if(vm->mmio == nil)
+ return 0;
+ vmfifowr(vm, Xrectropcopy);
+ vmfifowr(vm, r.max.x);
+ vmfifowr(vm, r.max.y);
+ vmfifowr(vm, r.min.x);
+ vmfifowr(vm, r.min.y);
+ vmfifowr(vm, sr.min.x - r.min.x);
+ vmfifowr(vm, sr.min.y - r.min.y);
+ vmfifowr(vm, 3); /* code for copy */
+ vmwait(vm);
+ return 1;
+}
+
+static int
+vmwarefill(VGAscr*, Rectangle r, ulong sval)
+{
+ if(vm->mmio == nil)
+ return 0;
+ vmfifowr(vm, Xrectfill);
+ vmfifowr(vm, sval);
+ vmfifowr(vm, r.min.x);
+ vmfifowr(vm, r.min.y);
+ vmfifowr(vm, r.max.x-r.min.x);
+ vmfifowr(vm, r.max.y-r.min.y);
+ vmwait(vm);
+ return 1;
+}
+
static void
-vmwaredrawinit(VGAscr*)
+vmwaredrawinit(VGAscr *scr)
{
+ ulong mmiobase, mmiosize;
+
+extern int iprintscreenputs;
+ iprintscreenputs = 0;
+
+ if(scr->mmio==nil){
+ mmiobase = vmrd(vm, Rmemstart);
+ if(mmiobase == 0){
+ iprint("mmiobase 0\n");
+ return;
+ }
+ mmiosize = vmrd(vm, Rmemsize);
+ scr->mmio = KADDR(upamalloc(mmiobase, mmiosize, 0));
+iprint("mmio %p\n", scr->mmio);
+ vm->mmio = scr->mmio;
+ vm->mmiosize = mmiosize;
+ if(scr->mmio == nil)
+ return;
+ addvgaseg("vmwaremmio", mmiobase, mmiosize);
+ }
+
+ scr->mmio[FifoMin] = 4*sizeof(ulong);
+ scr->mmio[FifoMax] = vm->mmiosize;
+ scr->mmio[FifoNextCmd] = 4*sizeof(ulong);
+ scr->mmio[FifoStop] = 4*sizeof(ulong);
+ vmwr(vm, Rconfigdone, 1);
+
+ scr->scroll = vmwarescroll;
+ scr->fill = vmwarefill;
}
VGAdev vgavmwaredev = {
@@ 175,6 375,10 @@ VGAdev vgavmwaredev = {
0,
vmwarelinear,
vmwaredrawinit,
+ 0,
+ 0,
+ 0,
+ vmwareflush,
};
VGAcur vgavmwarecur = {
M port/devcons.c => port/devcons.c +23 -8
@@ 16,6 16,7 @@ Queue* lineq; /* processed console input */
Queue* serialoq; /* serial console output */
Queue* kprintoq; /* console output, for /dev/kprint */
ulong kprintinuse; /* test and set whether /dev/kprint is open */
+int iprintscreenputs = 1;
static struct
{
@@ 56,7 57,7 @@ enum
CMpanic,
};
-Cmdtab reboottbl[] =
+Cmdtab rebootmsg[] =
{
CMreboot, "reboot", 0,
CMpanic, "panic", 0,
@@ 185,7 186,7 @@ iprint(char *fmt, ...)
va_start(arg, fmt);
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
va_end(arg);
- if(screenputs != nil)
+ if(screenputs != nil && iprintscreenputs)
screenputs(buf, n);
if(serialputs != nil)
serialputs(buf, n);
@@ 348,15 349,21 @@ echo(char *buf, int n)
/* ^T escapes */
ctrlt = 0;
switch(*p){
+ case 'S':
+ x = splhi();
+ dumpstack();
+ procdump();
+ splx(x);
+ return;
case 's':
dumpstack();
- break;
+ return;
case 'x':
xsummary();
ixsummary();
mallocsummary();
pagersummary();
- break;
+ return;
case 'd':
if(consdebug == nil)
consdebug = rdb;
@@ 376,14 383,22 @@ echo(char *buf, int n)
return;
case 'q':
scheddump();
- break;
+ return;
+#ifdef RSC
+case 'Q':
+{
+extern void dumpschedlog(void);
+dumpschedlog();
+return;
+}
+#endif
case 'k':
if(!cpuserver)
killbig();
- break;
+ return;
case 'r':
exit(0);
- break;
+ return;
}
}
@@ 924,7 939,7 @@ conswrite(Chan *c, void *va, long n, vlong off)
free(cb);
nexterror();
}
- ct = lookupcmd(cb, reboottbl, nelem(reboottbl));
+ ct = lookupcmd(cb, rebootmsg, nelem(rebootmsg));
switch(ct->index) {
case CMreboot:
rebootcmd(cb->nf-1, cb->f+1);
M port/devdraw.c => port/devdraw.c +4 -3
@@ 368,7 368,8 @@ addflush(Rectangle r)
return;
}
/* emit current state */
- flushmemscreen(flushrect);
+ if(flushrect.min.x < flushrect.max.x)
+ flushmemscreen(flushrect);
flushrect = r;
waste = 0;
}
@@ 395,11 396,11 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
addflush(r);
}
-static
void
drawflush(void)
{
- flushmemscreen(flushrect);
+ if(flushrect.min.x < flushrect.max.x)
+ flushmemscreen(flushrect);
flushrect = Rect(10000, 10000, -10000, -10000);
}
M port/devrealtime.c => port/devrealtime.c +6 -0
@@ 224,12 224,16 @@ devrtinit(void)
static Chan *
devrtattach(char *param)
{
+ if(havecycintr() == 0)
+ error("no edf on multiprocessors");
return devattach('R', param);
}
static Walkqid *
devrtwalk(Chan *c, Chan *nc, char **name, int nname)
{
+ if (havecycintr() == 0)
+ error("no edf on multiprocessors");
return devwalk(c, nc, name, nname, nil, 0, schedgen);
}
@@ 263,6 267,8 @@ devrtopen(Chan *c, int mode)
{
Task *t;
+ if (havecycintr() == 0)
+ error("no edf on multiprocessors");
switch ((ulong)c->qid.path){
case Qlog:
case Qnblog:
M port/devwpsd.c => port/devwpsd.c +43 -29
@@ 1,3 1,6 @@
+/*
+ * Storage Device.
+ */
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
@@ 9,11 12,7 @@
#include "../port/sd.h"
-/*
- * Storage Device.
- */
-
-extern Dev sddevtab;
+extern Dev wpsddevtab;
extern SDifc* sdifc[];
typedef struct {
@@ 31,6 30,20 @@ enum {
Rawstatus,
};
+enum
+{
+ CMpart,
+ CMdelpart,
+ CMwildcard,
+};
+
+Cmdtab ctlmsg[] =
+{
+ CMpart, "part", 3,
+ CMdelpart, "delpart", 1,
+ CMwildcard, "*", 0,
+};
+
enum {
Qtopdir = 1, /* top level directory */
Qtopbase,
@@ 461,7 474,7 @@ sdgen(Chan* c, char*, Dirtab*, int, int s, Dir* dp)
case Qtopdir:
if(s == DEVDOTDOT){
mkqid(&q, QID(0, s, 0, Qtopdir), 0, QTDIR);
- sprint(up->genbuf, "#%C", sddevtab.dc);
+ sprint(up->genbuf, "#%C", wpsddevtab.dc);
devdir(c, q, up->genbuf, 0, eve, 0555, dp);
return 1;
}
@@ 507,7 520,7 @@ sdgen(Chan* c, char*, Dirtab*, int, int s, Dir* dp)
case Qunitdir:
if(s == DEVDOTDOT){
mkqid(&q, QID(0, s, 0, Qtopdir), 0, QTDIR);
- sprint(up->genbuf, "#%C", sddevtab.dc);
+ sprint(up->genbuf, "#%C", wpsddevtab.dc);
devdir(c, q, up->genbuf, 0, eve, 0555, dp);
return 1;
}
@@ 591,7 604,7 @@ sdattach(char* spec)
int idno, subno, i;
if(ndevs == 0 || *spec == '\0'){
- c = devattach(sddevtab.dc, spec);
+ c = devattach(wpsddevtab.dc, spec);
mkqid(&c->qid, QID(0, 0, 0, Qtopdir), 0, QTDIR);
return c;
}
@@ 615,7 628,7 @@ sdattach(char* spec)
incref(&sdev->r);
qunlock(&devslock);
- c = devattach(sddevtab.dc, spec);
+ c = devattach(wpsddevtab.dc, spec);
mkqid(&c->qid, QID(sdev->idno, subno, 0, Qunitdir), 0, QTDIR);
c->dev = (sdev->idno << UnitLOG) + subno;
decref(&sdev->r);
@@ 657,7 670,7 @@ sdopen(Chan* c, int omode)
break;
case Qraw:
c->qid.vers = unit->vers;
- if(!canlock(&unit->rawinuse)){
+ if(tas(&unit->rawinuse) != 0){
c->flag &= ~COPEN;
error(Einuse);
}
@@ 698,7 711,7 @@ sdclose(Chan* c)
sdev = sdgetdev(DEV(c->qid));
if (sdev) {
unit = sdev->unit[UNIT(c->qid)];
- unlock(&unit->rawinuse);
+ unit->rawinuse = 0;
decref(&sdev->r);
}
break;
@@ 783,6 796,8 @@ sdbio(Chan* c, int write, char* a, long len, vlong off)
}
offset = off%unit->secsize;
+ if(offset+len > nb*unit->secsize)
+ len = nb*unit->secsize - offset;
if(write){
if(offset || (len%unit->secsize)){
l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);
@@ 1081,6 1096,7 @@ static long
sdwrite(Chan* c, void* a, long n, vlong off)
{
Cmdbuf *cb;
+ Cmdtab *ct;
SDreq *req;
SDunit *unit;
SDev *sdev;
@@ 1130,18 1146,18 @@ sdwrite(Chan* c, void* a, long n, vlong off)
error(Ebadarg);
}
- if(sddevtab.config == nil)
+ if(wpsddevtab.config == nil)
error("No configuration function");
- sddevtab.config(cd.o_on, cd.o_spec, &cd.o_cf);
+ wpsddevtab.config(cd.o_on, cd.o_spec, &cd.o_cf);
break;
}
case Qctl:
- cb = parsecmd(a, n);
sdev = sdgetdev(DEV(c->qid));
if (sdev == nil)
error(Enonexist);
unit = sdev->unit[UNIT(c->qid)];
+ cb = parsecmd(a, n);
qlock(&unit->ctl);
if(waserror()){
qunlock(&unit->ctl);
@@ 1152,29 1168,27 @@ sdwrite(Chan* c, void* a, long n, vlong off)
if(unit->vers != c->qid.vers)
error(Eio);
- if(cb->nf < 1)
- error(Ebadctl);
- if(strcmp(cb->f[0], "part") == 0){
- if(cb->nf != 4)
- error(Ebadctl);
+ ct = lookupcmd(cb, ctlmsg, nelem(ctlmsg));
+ switch(ct->index) {
+ case CMpart:
if(unit->sectors == 0 && !sdinitpart(unit))
error(Eio);
start = strtoul(cb->f[2], 0, 0);
end = strtoul(cb->f[3], 0, 0);
sdaddpart(unit, cb->f[1], start, end);
- }
- else if(strcmp(cb->f[0], "delpart") == 0){
- if(cb->nf != 2 || unit->part == nil)
- error(Ebadctl);
+ break;
+ case CMdelpart:
sddelpart(unit, cb->f[1]);
- }
- else if(unit->dev->ifc->wctl)
+ break;
+ case CMwildcard:
+ if(unit->dev->ifc->wctl == nil)
+ error(Ebadctl);
unit->dev->ifc->wctl(unit, cb);
- else
- error(Ebadctl);
+ break;
+ }
+ poperror();
qunlock(&unit->ctl);
decref(&sdev->r);
- poperror();
free(cb);
break;
@@ 1448,7 1462,7 @@ sdconfig(int on, char* spec, DevConf* cf)
return unconfigure(spec);
}
-Dev sddevtab = {
+Dev wpwpsddevtab = {
'S',
"sd",
M port/edf.c => port/edf.c +0 -3
@@ 477,8 477,6 @@ edfdeadlineintr(Ureg*, Cycintr*)
}
}
}
- if (up->nlocks)
- iprint("have %lud locks at deadline\n", up->nlocks);
}
iunlock(&edflock);
sched();
@@ 869,7 867,6 @@ edf_testschedulability(Task *thetask)
}
H=0;
G=0;
- ticks = 0;
for(steps = 0; steps < Maxsteps; steps++){
t = qschedulability;
qschedulability = t->testnext;
M port/portclock.c => port/portclock.c +7 -0
@@ 5,6 5,7 @@
#include "fns.h"
#include "io.h"
#include "ureg.h"
+#include "../port/edf.h"
void (*kproftimer)(ulong);
@@ 75,6 76,12 @@ portclock(Ureg *ur)
if(up == 0 || up->state != Running)
return;
+ // i.e. don't schedule an EDF process here!
+ if(!isedf(up) && anyready()){
+ sched();
+ splhi();
+ }
+
/* user profiling clock */
if(userureg(ur)) {
(*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1);
M port/portdat.h => port/portdat.h +1 -1
@@ 640,7 640,7 @@ struct Proc
Mach *wired;
Mach *mp; /* machine this process last ran on */
- ulong nlocks; /* number of locks held by proc */
+ ulong nlocks; /* number of locks held by proc */
ulong delaysched;
ulong priority; /* priority level */
ulong basepri; /* base priority level */
M port/proc.c => port/proc.c +68 -4
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
+#include "../port/edf.h"
int nrdy;
Ref noteidalloc;
@@ 42,6 43,37 @@ char *statename[] =
static void pidhash(Proc*);
static void pidunhash(Proc*);
+/*DEBUGGING: scheduling event log */
+#ifdef RSC
+static ulong *lg;
+enum {Nlg = 1024*1024};
+static ulong wp, rp;
+static void
+le(int c, Proc *p)
+{
+ if(lg==nil)
+ lg = malloc(Nlg*sizeof(lg[0]));
+ lg[wp++&(Nlg-1)] = MACHP(0)->ticks;
+ lg[wp++&(Nlg-1)] = c;
+ lg[wp++&(Nlg-1)] = (ulong)p;
+}
+void
+dumpschedlog(void)
+{
+ int i;
+
+ i=0;
+ iprint("%lux=>%lux\n", rp, wp);
+ while((rp&(Nlg-1))!=(wp&(Nlg-1))){
+ iprint("%lux ", lg[rp++&(Nlg-1)]);
+ if(++i%8==0)
+ iprint("\n");
+ }
+ if(i%8)
+ iprint("\n");
+}
+#endif
+
/*
* Always splhi()'ed.
*/
@@ 57,6 89,8 @@ schedinit(void) /* never returns */
break;
case Moribund:
up->state = Dead;
+ if (isedf(up))
+ edf_bury(up);
/*
* Holding locks from pexit:
@@ 73,6 107,9 @@ schedinit(void) /* never returns */
break;
}
up->mach = 0;
+#ifdef RSC
+le('e', up);
+#endif
up = nil;
}
sched();
@@ 106,6 143,9 @@ sched(void)
gotolabel(&m->sched);
}
up = runproc();
+#ifdef RSC
+le('u',up);
+#endif
up->state = Running;
up->mach = MACHP(m->machno);
m->proc = up;
@@ 116,7 156,7 @@ sched(void)
int
anyready(void)
{
- return nrdy;
+ return nrdy || edf_anyready();
}
int
@@ 146,7 186,15 @@ ready(Proc *p)
Schedq *rq;
s = splhi();
+#ifdef RSC
+le('r',p);
+#endif
+ if(isedf(p)){
+ edf_ready(p);
+ splx(s);
+ return;
+ }
if(p->fixedpri){
pri = p->basepri;
} else {
@@ 197,6 245,9 @@ runproc(void)
Proc *p, *l;
ulong rt;
+ if ((p = edf_runproc()) != nil)
+ return p;
+
loop:
/*
@@ 348,6 399,8 @@ newproc(void)
p->syserrstr = p->errbuf1;
p->errbuf0[0] = '\0';
p->errbuf1[0] = '\0';
+ p->nlocks = 0;
+ p->delaysched = 0;
kstrdup(&p->user, "*nouser");
kstrdup(&p->text, "*notext");
kstrdup(&p->args, "");
@@ 433,6 486,9 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
s = splhi();
+ if (up->nlocks)
+ print("process %lud sleeps with %lud locks held, last lock 0x%p locked at pc 0x%lux\n",
+ up->pid, up->nlocks, up->lastlock, up->lastlock->pc);
lock(r);
lock(&up->rlock);
if(r->p){
@@ 480,9 536,11 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
*/
unlock(&up->rlock);
unlock(r);
-
// Behind unlock, we may call wakeup on ourselves.
+ if (isedf(up))
+ edf_block(up);
+
gotolabel(&m->sched);
}
}
@@ 690,6 748,8 @@ addbroken(Proc *p)
broken.p[broken.n++] = p;
qunlock(&broken);
+ if (isedf(up))
+ edf_bury(up);
p->state = Broken;
p->psstate = 0;
sched();
@@ 857,6 917,8 @@ pexit(char *exitstr, int freemem)
lock(&procalloc);
lock(&palloc);
+ if (isedf(up))
+ edf_bury(up);
up->state = Moribund;
sched();
panic("pexit");
@@ 932,9 994,9 @@ dumpaproc(Proc *p)
s = p->psstate;
if(s == 0)
s = statename[p->state];
- print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux\n",
+ print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %lux\n",
p->pid, p->text, p->pc, dbgpc(p), s, statename[p->state],
- p->time[0], p->time[1], bss, p->qpc);
+ p->time[0], p->time[1], bss, p->qpc, p->nlocks, p->delaysched, p->lastlock ? p->lastlock->pc : 0);
}
void
@@ 1109,6 1171,8 @@ procctl(Proc *p)
qunlock(&p->debug);
splhi();
p->state = Stopped;
+ if (isedf(up))
+ edf_block(up);
sched();
p->psstate = state;
splx(s);
M port/qlock.c => port/qlock.c +7 -0
@@ 3,6 3,7 @@
#include "mem.h"
#include "dat.h"
#include "fns.h"
+#include "../port/edf.h"
struct {
ulong rlock;
@@ 39,6 40,8 @@ qlock(QLock *q)
mp->state = Queueing;
up->qpc = getcallerpc(&q);
unlock(&q->use);
+ if (isedf(mp))
+ edf_block(mp);
sched();
}
@@ 102,6 105,8 @@ rlock(RWlock *q)
mp->qnext = 0;
mp->state = QueueingR;
unlock(&q->use);
+ if (isedf(mp))
+ edf_block(mp);
sched();
}
@@ 158,6 163,8 @@ wlock(RWlock *q)
mp->qnext = 0;
mp->state = QueueingW;
unlock(&q->use);
+ if (isedf(mp))
+ edf_block(mp);
sched();
}
M port/sd.h => port/sd.h +0 -2
@@ 42,8 42,6 @@ typedef struct SDunit {
int state;
SDreq* req;
SDperm rawperm;
-
- Log log;
} SDunit;
/*
M port/sysproc.c => port/sysproc.c +3 -0
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
+#include "../port/edf.h"
#include <a.out.h>
@@ 825,6 826,8 @@ sysrendezvous(ulong *arg)
*l = up;
up->state = Rendezvous;
unlock(up->rgrp);
+ if (isedf(up))
+ edf_block(up);
sched();
M port/taslock.c => port/taslock.c +5 -4
@@ 53,7 53,8 @@ lock(Lock *l)
if(up)
up->nlocks++; /* prevent being scheded */
if(tas(&l->key) == 0){
- if (up) up->lastlock = l;
+ if(up)
+ up->lastlock = l;
l->pc = pc;
l->p = up;
l->isilock = 0;
@@ 85,6 86,7 @@ lock(Lock *l)
if(up)
up->nlocks--;
}
+ return 0; /* For the compiler */
}
void
@@ 120,7 122,8 @@ ilock(Lock *l)
;
x = splhi();
if(tas(&l->key) == 0){
- if (up) up->lastlock = l;
+ if(up)
+ up->lastlock = l;
l->sr = x;
l->pc = pc;
l->p = up;
@@ 158,7 161,6 @@ unlock(Lock *l)
print("unlock of ilock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc);
if(l->p != up)
print("unlock: up changed: pc %lux, acquired at pc %lux, lock p 0x%p, unlock up 0x%p\n", getcallerpc(&l), l->pc, l->p, up);
- l->pc = ~0;
l->key = 0;
if (up && --up->nlocks == 0 && up->delaysched){
up->delaysched = 0;
@@ 178,7 180,6 @@ iunlock(Lock *l)
print("iunlock of lock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc);
sr = l->sr;
- l->pc = ~1;
l->key = 0;
coherence();