~kris/9p

9hist

cc01e61703af9f49ee42563fce64ca40f103e67e — David du Colombier 24 years ago 34c099d
Plan 9 from Bell Labs 2002-04-20
12 files changed, 327 insertions(+), 33 deletions(-)

M alphapc/dat.h
M bitsy/dat.h
M mtx/dat.h
M pc/dat.h
M pc/pci.c
M pc/trap.c
A pc/vgai81x.c
M port/edf.c
M port/proc.c
M port/qlock.c
M port/segment.c
M port/taslock.c
M alphapc/dat.h => alphapc/dat.h +1 -0
@@ 156,6 156,7 @@ struct Mach
	int	load;
	int	intr;
	int	flushmmu;		/* make current proc flush it's mmu state */
	int		ilockdepth;

	ulong	spuriousintr;
	int	lastintr;

M bitsy/dat.h => bitsy/dat.h +1 -0
@@ 136,6 136,7 @@ struct Mach
	vlong	intrts;			/* time stamp of last interrupt */
	ulong	spuriousintr;
	int	lastintr;
	int		ilockdepth;

	int	flushmmu;		/* make current proc flush it's mmu state */
	Proc	*pid2proc[31];		/* what proc holds what pid */

M mtx/dat.h => mtx/dat.h +1 -0
@@ 151,6 151,7 @@ struct Mach
	int	load;
	int	intr;
	int	flushmmu;		/* make current proc flush it's mmu state */
	int	ilockdepth;

	ulong	ptabbase;		/* start of page table in kernel virtual space */
	int		slotgen;		/* next pte (byte offset) when pteg is full */

M pc/dat.h => pc/dat.h +1 -0
@@ 177,6 177,7 @@ struct Mach
	int	intr;
	vlong	intrts;			/* time stamp of last interrupt */
	int	flushmmu;		/* make current proc flush it's mmu state */
	int		ilockdepth;

	ulong	spuriousintr;
	int	lastintr;

M pc/pci.c => pc/pci.c +8 -8
@@ 57,7 57,7 @@ enum
};

static Lock pcicfglock;
static QLock pcicfginitlock;
static Lock pcicfginitlock;
static int pcicfgmode = -1;
static int pcimaxbno = 7;
static int pcimaxdno;


@@ 498,9 498,9 @@ pciscan(int bno, Pcidev **list)
{
	int ubn;

	qlock(&pcicfginitlock);
	lock(&pcicfginitlock);
	ubn = pcilscan(bno, list);
	qunlock(&pcicfginitlock);
	unlock(&pcicfginitlock);
	return ubn;
}



@@ 747,7 747,7 @@ pcicfginit(void)
	Pcidev **list;
	ulong mema, ioa;

	qlock(&pcicfginitlock);
	lock(&pcicfginitlock);
	if(pcicfgmode != -1)
		goto out;



@@ 839,14 839,14 @@ pcicfginit(void)
		pcibusmap(pciroot, &mema, &ioa, 1);
		DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa);
	
		qunlock(&pcicfginitlock);
		unlock(&pcicfginitlock);
		return;
	}

	pcirouting();

out:
	qunlock(&pcicfginitlock);
	unlock(&pcicfginitlock);

}



@@ 1117,9 1117,9 @@ pcihinv(Pcidev* p)
{
	if(pcicfgmode == -1)
		pcicfginit();
	qlock(&pcicfginitlock);
	lock(&pcicfginitlock);
	pcilhinv(p);
	qunlock(&pcicfginitlock);
	unlock(&pcicfginitlock);
}

void

M pc/trap.c => pc/trap.c +1 -0
@@ 287,6 287,7 @@ trap(Ureg* ureg)
		 */
		if(ctl->isintr && ctl->irq != IrqTIMER && ctl->irq != IrqCLOCK)
		if(up && up->state == Running)
		if(up->nlocks == 0)
		if(anyhigher())
		if(up->preempted == 0)
		if(!active.exiting){

A pc/vgai81x.c => pc/vgai81x.c +281 -0
@@ 0,0 1,281 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"

#define	Image	IMAGE
#include <draw.h>
#include <memdraw.h>
#include <cursor.h>
#include "screen.h"

typedef struct
{
	ushort	ctl;
	ushort	pad;
	ulong	base;
	ulong	pos;
} CursorI81x;

enum {
	Fbsize		= 8*MB,

	hwCur		= 0x70080,
};

static Pcidev *
i81xpcimatch(void)
{
	Pcidev *p;

	p = nil;
	while((p = pcimatch(p, 0x8086, 0)) != nil){
		switch(p->did){
		default:
			continue;
		case 0x7121:
		case 0x7123:
		case 0x7125:
		case 0x1102:
		case 0x1112:
		case 0x1132:
			return p;
		}
	}
	return nil;
}

static ulong
i81xlinear(VGAscr* scr, int* size, int* align)
{
	Pcidev *p;
	int oapsize, wasupamem;
	ulong aperture, oaperture, fbuf, fbend, *rp;

	oaperture = scr->aperture;
	oapsize = scr->apsize;
	wasupamem = scr->isupamem;

	aperture = 0;
	p = i81xpcimatch();
	if(p != nil) {
		aperture = p->mem[0].bar & ~0x0F;
		*size = p->mem[0].size;
		if(*size > Fbsize)
			*size = Fbsize;
	}

	if(wasupamem){
		if(oaperture == aperture)
			return oaperture;
		upafree(oaperture, oapsize);
	}
	scr->isupamem = 0;

	aperture = upamalloc(aperture, *size, *align);
	if(aperture == 0){
		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
			aperture = oaperture;
			scr->isupamem = 1;
		}
		else
			scr->isupamem = 0;
	}
	else
		scr->isupamem = 1;

	/* allocate space for frame buffer, populate page table */
	if(oapsize == 0) {
		fbuf = PADDR(xspanalloc(*size, BY2PG, 0));
		fbend = PGROUND(fbuf+*size);
		rp = KADDR(scr->io+0x10000);
		while(fbuf < fbend) {
			*rp++ = fbuf | (1<<0);
			fbuf += BY2PG;
		}
	}
	return aperture;
}

static void
i81xenable(VGAscr* scr)
{
	Pcidev *p;
	int align, size;
	Mach *mach0;
	ulong aperture, pgtbl, *rp, cursor, *pte;

	/*
	 * Only once, can't be disabled for now.
	 * scr->io holds the physical address of
	 * the MMIO registers.
	 */
	if(scr->io)
		return;
	p = i81xpcimatch();
	if(p == nil)
		return;
	scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
	if(scr->io == 0)
		return;

	/* allocate page table */
	pgtbl = PADDR(xspanalloc(64*1024, BY2PG, 0));
	rp = KADDR(scr->io+0x2020);
	*rp = pgtbl | 1;

	addvgaseg("i81xmmio", (ulong)scr->io, p->mem[0].size);

	size = p->mem[0].size;
	align = 0;
	aperture = i81xlinear(scr, &size, &align);
	if(aperture){
		scr->aperture = aperture;
		scr->apsize = size;
		addvgaseg("i81xscreen", aperture, size);
	}

	/*
	 * allocate space for the cursor data in system memory.
	 * must be uncached.
	 */
	cursor = (ulong)xspanalloc(BY2PG, BY2PG, 0);
	mach0 = MACHP(0);
	pte = mmuwalk(mach0->pdb, cursor, 2, 0);
	if(pte == nil)
		panic("i81x cursor");
	*pte |= PTEUNCACHED;
	scr->storage = PADDR(cursor);
}

static void
i81xcurdisable(VGAscr* scr)
{
	CursorI81x *hwcurs;

	if(scr->io == 0)
		return;
	hwcurs = KADDR(scr->io+hwCur);
	hwcurs->ctl = (1<<4);
}

static void
i81xcurload(VGAscr* scr, Cursor* curs)
{
	int y;
	uchar *p;
	CursorI81x *hwcurs;

	if(scr->io == 0)
		return;
	hwcurs = KADDR(scr->io+hwCur);

	/*
	 * Disable the cursor then load the new image in
	 * the top-left of the 32x32 array.
	 * Unused portions of the image have been initialised to be
	 * transparent.
	 */
	hwcurs->ctl = (1<<4);
	p = KADDR(scr->storage);
	for(y = 0; y < 16; y += 2) {
		*p++ = ~(curs->clr[2*y]|curs->set[2*y]);
		*p++ = ~(curs->clr[2*y+1]|curs->set[2*y+1]);
		p += 2;
		*p++ = ~(curs->clr[2*y+2]|curs->set[2*y+2]);
		*p++ = ~(curs->clr[2*y+3]|curs->set[2*y+3]);
		p += 2;
		*p++ = curs->set[2*y];
		*p++ = curs->set[2*y+1];
		p += 2;
		*p++ = curs->set[2*y+2];
		*p++ = curs->set[2*y+3];
		p += 2;
	}

	/*
	 * Save the cursor hotpoint and enable the cursor.
	 * The 0,0 cursor point is top-left.
	 */
	scr->offset.x = curs->offset.x;
	scr->offset.y = curs->offset.y;
	hwcurs->ctl = (1<<4)|1;
}

static int
i81xcurmove(VGAscr* scr, Point p)
{
	int x, y;
	ulong pos;
	CursorI81x *hwcurs;

	if(scr->io == 0)
		return 1;
	hwcurs = KADDR(scr->io+hwCur);

	x = p.x+scr->offset.x;
	y = p.y+scr->offset.y;
	pos = 0;
	if(x < 0) {
		pos |= (1<<15);
		x = -x;
	}
	if(y < 0) {
		pos |= (1<<31);
		y = -y;
	}
	pos |= ((y&0x7ff)<<16)|(x&0x7ff);
	hwcurs->pos = pos;

	return 0;
}

static void
i81xcurenable(VGAscr* scr)
{
	int i;
	uchar *p;
	CursorI81x *hwcurs;

	i81xenable(scr);
	if(scr->io == 0)
		return;
	hwcurs = KADDR(scr->io+hwCur);

	/*
	 * Initialise the 32x32 cursor to be transparent in 2bpp mode.
	 */
	hwcurs->base = scr->storage;
	p = KADDR(scr->storage);
	for(i = 0; i < 32/2; i++) {
		memset(p, 0xff, 8);
		memset(p+8, 0, 8);
		p += 16;
	}
	/*
	 * Load, locate and enable the 32x32 cursor in 2bpp mode.
	 */
	i81xcurload(scr, &arrow);
	i81xcurmove(scr, ZP);
}

VGAdev vgai81xdev = {
	"i81x",

	i81xenable,
	nil,
	nil,
	i81xlinear,
};

VGAcur vgai81xcur = {
	"i81xhwgc",

	i81xcurenable,
	i81xcurdisable,
	i81xcurload,
	i81xcurmove,
};

M port/edf.c => port/edf.c +3 -0
@@ 40,6 40,7 @@ int			ntasks;
Resource		resources[Maxresources];
int			nresources;
int			edfstateupdate;
int			misseddeadlines;

enum{
	Deadline,	/* Invariant for schedulability test: Deadline < Release */


@@ 465,6 466,8 @@ edfdeadlineintr(Ureg*, Timer*)
	
			if (t->d <= now || t->S == 0LL){
				/* Task has reached its deadline/slice, remove from queue */
				if (t->S > 0LL)
					misseddeadlines++;
				deadline(up, SSlice);
				while (t = edfstack[m->machno].head){
					if (now < t->d)

M port/proc.c => port/proc.c +5 -3
@@ 87,10 87,12 @@ schedinit(void)		/* never returns */
void
sched(void)
{
	if(m->ilockdepth)
		panic("ilockdepth %d", m->ilockdepth);

	if(up){
		if(up->state == Running && up->nlocks){
			up->delaysched = 1;
			delayedscheds++;
		if(up->nlocks && up->state != Moribund){
 			delayedscheds++;
			return;
		}


M port/qlock.c => port/qlock.c +20 -11
@@ 13,10 13,22 @@ struct {
	ulong qlockq;
} rwstats;

int shutup=1;	/* RSC: you can take this out, it's just to silence a print in a loop on the dist floppy */
void
qlock(QLock *q)
{
	Proc *p, *mp;
	Proc *p;

	if(up == 0)
		panic("qlock");
	if(m->ilockdepth != 0 && !shutup){
		print("qlock: %lux: ilockdepth %d", getcallerpc(&q), m->ilockdepth);
		shutup = 1;
	}
	if(up->nlocks && !shutup){
		print("qlock: %lux: nlocks %d", getcallerpc(&q), up->nlocks);
		shutup = 1;
	}

	lock(&q->use);
	rwstats.qlock++;


@@ 27,20 39,17 @@ qlock(QLock *q)
	}
	rwstats.qlockq++;
	p = q->tail;
	mp = up;
	if(mp == nil)
		panic("qlock");
	if(p == 0)
		q->head = mp;
		q->head = up;
	else
		p->qnext = mp;
	q->tail = mp;
	mp->qnext = 0;
	mp->state = Queueing;
		p->qnext = up;
	q->tail = up;
	up->qnext = 0;
	up->state = Queueing;
	up->qpc = getcallerpc(&q);
	unlock(&q->use);
	if (isedf(mp))
		edfblock(mp);
	if (isedf(up))
		edfblock(up);
	sched();
}


M port/segment.c => port/segment.c +1 -1
@@ 112,6 112,7 @@ putseg(Segment *s)
		unlock(s);
		return;
	}
	unlock(s);

	qlock(&s->lk);
	if(i)


@@ 127,7 128,6 @@ putseg(Segment *s)
		free(s->map);
	if(s->profile != 0)
		free(s->profile);
	unlock(s);	/* keep lock/unlocks balanced */
	free(s);
}


M port/taslock.c => port/taslock.c +4 -10
@@ 36,9 36,6 @@ lockloop(Lock *l, ulong pc)
	dumpaproc(up);
	if(p != nil)
		dumpaproc(p);

	if(up && up->state == Running && islo())
		sched();
}

int


@@ 99,6 96,7 @@ ilock(Lock *l)
	lockstats.locks++;

	x = splhi();
	m->ilockdepth++;
	if(tas(&l->key) == 0){
		if(up)
			up->lastlock = l;


@@ 164,13 162,8 @@ unlock(Lock *l)
	l->key = 0;
	coherence();

	/* give up the processor if ... */
	if(up && --up->nlocks == 0	/* we've closed the last nexted lock */
	&& up->delaysched		/* we delayed scheduling because of the lock */
	&& up->state == Running){	/* we're in running state */
		up->delaysched = 0;
		sched();
	}
	if(up)
		--up->nlocks;
}

void


@@ 190,5 183,6 @@ iunlock(Lock *l)
	coherence();

	m->splpc = getcallerpc(&l);
	m->ilockdepth--;
	splxpc(sr);
}