~kris/9p

9hist

7f34cfa6648f562d20c03744934cb61004ea3884 — David du Colombier 24 years ago 0289f30
Plan 9 from Bell Labs 2002-04-04
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();