Plan 9 from Bell Labs’s /usr/web/sources/contrib/uriel/changes/2005/1106/1

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


Add untested code to recognize SIS900 and WPC-11 ethernet cards.

Move PC kernel to 0xF0000000, rewrite PC mmu.c accordingly.
Make memory banks described by array inside of hard-coding two banks.
On PC, add E820 memory map scan and VGA VESA support.
 [rsc] --rw-rw-r-- M 451989 glenda sys 23542 Nov  6 09:32 sys/src/9/pc/ether83815.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether83815.c:81,86 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether83815.c:81,87
	  
	  enum {				/* Variants */
	  	Nat83815	= (0x0020<<16)|0x100B,
	+ 	Sis900 = (0x0630<<16)|0x1039,	/* untested */
	  };
	  
	  typedef struct Ctlr Ctlr;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether83815.c:841,846 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether83815.c:842,848
	  			continue;
	  
	  		case Nat83815:
	+ 		case Sis900:
	  			break;
	  		}
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 630 Nov  6 10:08 sys/src/9/alphapc/apc
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/apc:36,42 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/apc:36,42
	  	arch164
	  
	  	sdata		pci sdscsi
	- 	sd53c8xx	pci sdscsi
	+ #	sd53c8xx	pci sdscsi
	  
	  	uarti8250
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 5196 Nov  6 10:08 sys/src/9/alphapc/dat.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/dat.h:1,4 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/dat.h:1,5
	  typedef struct Conf	Conf;
	+ typedef struct Confmem	Confmem;
	  typedef struct FPsave	FPsave;
	  typedef struct ISAConf	ISAConf;
	  typedef struct Label	Label;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/dat.h:32,37 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/dat.h:33,39
	  	ulong	sr;
	  	ulong	pc;
	  	Proc	*p;
	+ 	Mach	*m;
	  	ulong	pid;
	  	ushort	isilock;
	  };
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/dat.h:63,77 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/dat.h:65,84
	  	long	fpstatus;
	  };
	  
	+ struct Confmem
	+ {
	+ 	ulong	base;
	+ 	ulong	npage;
	+ 	ulong	kbase;
	+ 	ulong	klimit;
	+ };
	+ 
	  struct Conf
	  {
	  	ulong	nmach;		/* processors */
	  	ulong	nproc;		/* processes */
	- 	ulong	npage0;		/* total physical pages of memory */
	- 	ulong	npage1;		/* total physical pages of memory */
	+ 	Confmem	mem[2];
	  	ulong	npage;		/* total physical pages of memory */
	- 	ulong	base0;		/* base of bank 0 */
	- 	ulong	base1;		/* base of bank 1 */
	  	ulong	upages;		/* user page pool */
	  	ulong	nimage;		/* number of page cache image headers */
	  	ulong	nswap;		/* number of swap pages */
 [rsc] --rw-rw-r-- M 451989 glenda sys 7420 Nov  6 10:08 sys/src/9/alphapc/devvga.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/devvga.c:130,139 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/devvga.c:130,136
	  		len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
	  		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
	  		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
	- 		if(scr->pciaddr)
	- 			snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->pciaddr);
	- 		else
	- 			snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->aperture);
	+ 		snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->paddr);
	  		n = readstr(offset, a, n, p);
	  		poperror();
	  		free(p);
 [rsc] --rw-rw-r-- M 451989 glenda sys 3613 Nov  6 10:08 sys/src/9/alphapc/fns.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/fns.h:98,108 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/fns.h:98,110
	  void	touser(void*);
	  void	trapinit(void);
	  void	unaligned(void);
	- ulong	upamalloc(ulong, int, int);
	+ ulong	upaalloc(int, int);
	  void	upafree(ulong, int);
	  #define	userureg(ur) ((ur)->status & UMODE)
	+ void*	vmap(ulong, int);
	  void	wrent(int, void*);
	  void	wrvptptr(uvlong);
	+ void	vunmap(void*, int);
	  
	  #define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
	  #define KADDR(a)	((void*)((ulong)(a)|KZERO))
 [rsc] --rw-rw-r-- M 451989 glenda sys 13672 Nov  6 10:08 sys/src/9/alphapc/main.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/main.c:454,470 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/main.c:454,470
	  	 * 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.mem[0].npage = (8*1024*1024)/BY2PG;
	+ 	conf.mem[0].base = 0;
	  
	- 	conf.npage1 = (b->max-8*1024*1024)/BY2PG;
	- 	conf.base1 = 8*1024*1024;
	+ 	conf.mem[1].npage = (b->max-8*1024*1024)/BY2PG;
	+ 	conf.mem[1].base = 8*1024*1024;
	  
	- 	conf.npage = conf.npage0+conf.npage1;
	+ 	conf.npage = conf.mem[0].npage+conf.mem[1].npage;
	  	conf.upages = (conf.npage*70)/100;
	  
	- 	conf.npage0 -= ktop/BY2PG;
	- 	conf.base0 += ktop;
	+ 	conf.mem[0].npage -= ktop/BY2PG;
	+ 	conf.mem[0].base += ktop;
	  	conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
	  
	  	/*
 [rsc] --rw-rw-r-- M 451989 glenda sys 4945 Nov  6 10:08 sys/src/9/alphapc/mmu.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/mmu.c:224,231 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/mmu.c:224,231
	  
	  }
	  
	- ulong
	- upamalloc(ulong pa, int size, int align)
	+ void*
	+ vmap(ulong pa, int size)
	  {
	  	void *va;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/mmu.c:234,250 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/mmu.c:234,249
	  	 */
	  	if(pa == 0)
	  		return 0;
	- 	USED(align);
	  	va = kmapv(((uvlong)0x88<<32LL)|pa, size);
	  	if(va == nil)
	  		return 0;
	- 	return PADDR(va);
	+ 	return (void*)va;
	  }
	  
	  void
	- upafree(ulong, int)
	+ vunmap(void*, int)
	  {
	- 	print("upafree: virtual mapping not freed\n");
	+ 	print("vunmap: virtual mapping not freed\n");
	  }
	  
	  void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/mmu.c:263,266 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/mmu.c:262,280
	  	}
	  }
	  
	- void checkmmu(ulong, ulong) { }
	+ ulong
	+ upaalloc(int, int)
	+ {
	+ 	return 0;
	+ }
	+ 
	+ void
	+ upafree(ulong, int)
	+ {
	+ }
	+ 
	+ void
	+ checkmmu(ulong, ulong)
	+ {
	+ }
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 3818 Nov  6 10:08 sys/src/9/alphapc/screen.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/screen.h:68,74 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/screen.h:68,74
	  	void	(*enable)(VGAscr*);
	  	void	(*disable)(VGAscr*);
	  	void	(*page)(VGAscr*, int);
	- 	ulong	(*linear)(VGAscr*, int*, int*);
	+ 	void	(*linear)(VGAscr*, int, int);
	  	void	(*drawinit)(VGAscr*);
	  	int	(*fill)(VGAscr*, Rectangle, ulong);
	  	void (*flush)(VGAscr*, Rectangle);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/screen.h:91,96 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/screen.h:91,97
	  struct VGAscr {
	  	Lock	devlock;
	  	VGAdev*	dev;
	+ 	Pcidev*	pci;
	  
	  	VGAcur*	cur;
	  	ulong	storage;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/screen.h:98,114 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/screen.h:99,114
	  
	  	int	useflush;
	  
	- 	ulong	aperture;			/* physical address, kernel */
	- 	ulong	pciaddr;			/* physical address, user */
	- 	int	isupamem;
	+ 	ulong	paddr;		/* frame buffer */
	+ 	void*	vaddr;
	  	int	apsize;
	  
	  	ulong	io;				/* device specific registers */
	- 
	+ 	ulong	*mmio;
	+ 	
	  	ulong	colormap[Pcolours][3];
	  	int	palettedepth;
	  
	- 	ulong	*mmio;
	  	Memimage* gscreen;
	  	Memdata* gscreendata;
	  	Memsubfont* memdefont;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/screen.h:142,155 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/screen.h:142,168
	  extern Rectangle physgscreenr;	/* actual monitor size */
	  extern void	blankscreen(int);
	  
	+ extern VGAcur swcursor;
	+ extern void swcursorinit(void);
	+ extern void swcursorhide(void);
	+ extern void swcursoravoid(Rectangle);
	+ extern void swcursorunhide(void);
	+ 
	  /* devdraw.c */
	  extern void	deletescreenimage(void);
	  extern int	drawhasclients(void);
	  extern ulong	blanktime;
	+ extern QLock	drawlock;
	+ 
	  /* vga.c */
	  extern void	vgascreenwin(VGAscr*);
	  extern void	vgaimageinit(ulong);
	- extern ulong	vgapcilinear(VGAscr*, int*, int*, int, int);
	+ extern void	vgalinearpciid(VGAscr*, int, int);
	+ extern void	vgalinearpci(VGAscr*);
	+ extern void	vgalinearaddr(VGAscr*, ulong, int);
	  
	  extern void	drawblankscreen(int);
	  extern void	vgablank(VGAscr*, int);
	+ 
	+ extern Lock	vgascreenlock;
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 50963 Nov  6 10:08 sys/src/9/alphapc/sd53c8xx.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/alphapc/sd53c8xx.c:1817,1824 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/alphapc/sd53c8xx.c:1817,1822
	  { SYM_1010_DID,  0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
	  };
	  
	- #define offsetof(s, t) ((ulong)&((s *)0)->t)
	- 
	  static int
	  xfunc(Controller *c, enum na_external x, unsigned long *v)
	  {
 [rsc] --rw-rw-r-- M 451989 glenda bitsy 5829 Nov  6 10:09 sys/src/9/bitsy/dat.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/dat.h:1,5 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/dat.h:1,6
	  typedef struct Cisdat 		Cisdat;
	  typedef struct Conf		Conf;
	+ typedef struct Confmem	Confmem;
	  typedef struct FPU		FPU;
	  typedef struct FPenv		FPenv;
	  typedef struct FPsave		FPsave;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/dat.h:37,42 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/dat.h:38,44
	  	ulong	sr;
	  	ulong	pc;
	  	Proc	*p;
	+ 	Mach	*m;
	  	ushort	isilock;
	  };
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/dat.h:62,80 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/dat.h:64,88
	  	ulong	regs[8][3];	/* emulated fp */	
	  };
	  
	+ struct Confmem
	+ {
	+ 	ulong	base;
	+ 	ulong	npage;
	+ 	ulong	limit;
	+ 	ulong	kbase;
	+ 	ulong	klimit;
	+ };
	+ 
	  struct Conf
	  {
	  	ulong	nmach;		/* processors */
	  	ulong	nproc;		/* processes */
	- 	ulong	npage0;		/* total physical pages of memory */
	- 	ulong	npage1;		/* total physical pages of memory */
	+ 	Confmem	mem[2];
	  	ulong	npage;		/* total physical pages of memory */
	  	ulong	upages;		/* user page pool */
	  	ulong	nimage;		/* number of page cache image headers */
	  	ulong	nswap;		/* number of swap pages */
	  	int	nswppo;		/* max # of pageouts per segment pass */
	- 	ulong	base0;		/* base of bank 0 */
	- 	ulong	base1;		/* base of bank 1 */
	  	ulong	copymode;	/* 0 is copy on write, 1 is copy on reference */
	  	int	monitor;
	  	ulong	ialloc;		/* bytes available for interrupt time allocation */
 [rsc] --rw-rw-r-- M 451989 glenda bitsy 9589 Nov  6 10:09 sys/src/9/bitsy/devpenmouse.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/devpenmouse.c:53,58 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/devpenmouse.c:53,60
	  	Lock;
	  	Mousestate;
	  	ulong	lastcounter;	/* value when /dev/mouse read */
	+ 	ulong	resize;
	+ 	ulong	lastresize;
	  	Rendez	r;
	  	Ref;
	  	QLock;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/devpenmouse.c:285,290 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/devpenmouse.c:287,296
	  		mouse.lastcounter = m.counter;
	  		if(n > 1+4*12)
	  			n = 1+4*12;
	+ 		if(mouse.lastresize != mouse.resize){
	+ 			mouse.lastresize = mouse.resize;
	+ 			buf[0] = 'r';
	+ 		}
	  		memmove(va, buf, n);
	  		return n;
	  	}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/devpenmouse.c:481,487 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/devpenmouse.c:487,494
	  int
	  penmousechanged(void*)
	  {
	- 	return mouse.lastcounter != mouse.counter;
	+ 	return mouse.lastcounter != mouse.counter ||
	+ 		mouse.lastresize != mouse.resize;
	  }
	  
	  Point
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/devpenmouse.c:489,491 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/devpenmouse.c:496,509
	  {
	  	return mouse.xy;
	  }
	+ 
	+ /*
	+  * notify reader that screen has been resized (ha!)
	+  */
	+ void
	+ mouseresize(void)
	+ {
	+ 	mouse.resize++;
	+ 	wakeup(&mouse.r);
	+ }
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda bitsy 8816 Nov  6 10:09 sys/src/9/bitsy/main.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/main.c:268,273 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/main.c:268,274
	  int
	  probemem(ulong addr)
	  {
	+ 	int i;
	  	ulong *p;
	  	ulong a;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/main.c:274,287 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/main.c:275,286
	  	addr += OneMeg - sizeof(ulong);
	  	p = (ulong*)addr;
	  	*p = addr;
	- 	for(a = conf.base0+OneMeg-sizeof(ulong); a < conf.npage0; a += OneMeg){
	- 		p = (ulong*)a;
	- 		*p = 0;
	+ 	for(i=0; i<nelem(conf.mem); i++){
	+ 		for(a = conf.mem[i].base+OneMeg-sizeof(ulong); a < conf.mem[i].limit; a += OneMeg){
	+ 			p = (ulong*)a;
	+ 			*p = 0;
	+ 		}
	  	}
	- 	for(a = conf.base1+OneMeg-sizeof(ulong); a < conf.npage1; a += OneMeg){
	- 		p = (ulong*)a;
	- 		*p = 0;
	- 	}
	  	p = (ulong*)addr;
	  	if(*p != addr)
	  		return -1;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/main.c:295,350 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/main.c:294,339
	  void
	  confinit(void)
	  {
	- 	int i;
	+ 	int i, j;
	  	ulong addr;
	  	ulong ktop;
	  
	  	/* find first two contiguous sections of available memory */
	  	addr = PHYSDRAM0;
	- 	conf.base0 = conf.npage0 = addr;
	- 	conf.base1 = conf.npage1 = addr;
	- 	for(i = 0; i < 512; i++){
	- 		if(probemem(addr) == 0)
	- 			break;
	- 		addr += OneMeg;
	+ 	for(i=0; i<nelem(conf.mem); i++){
	+ 		conf.mem[i].base = addr;
	+ 		conf.mem[i].limit = addr;
	  	}
	- 	for(; i < 512; i++){
	- 		if(probemem(addr) < 0)
	- 			break;
	- 		addr += OneMeg;
	- 		conf.npage0 = addr;
	+ 	for(j=0; j<nelem(conf.mem); j++){
	+ 		conf.mem[j].base = addr;
	+ 		conf.mem[j].limit = addr;
	+ 		
	+ 		for(i = 0; i < 512; i++){
	+ 			if(probemem(addr) == 0)
	+ 				break;
	+ 			addr += OneMeg;
	+ 		}
	+ 		for(; i < 512; i++){
	+ 			if(probemem(addr) < 0)
	+ 				break;
	+ 			addr += OneMeg;
	+ 			conf.mem[j].limit = addr;
	+ 		}
	  	}
	+ 	
	+ 	conf.npage = 0;
	+ 	for(i=0; i<nelem(conf.mem); i++){
	+ 		/* take kernel out of allocatable space */
	+ 		ktop = PGROUND((ulong)end);
	+ 		if(ktop >= conf.mem[i].base && ktop <= conf.mem[i].limit)
	+ 			conf.mem[i].base = ktop;
	+ 		
	+ 		/* zero memory */
	+ 		memset((void*)conf.mem[i].base, 0, conf.mem[i].limit - conf.mem[i].base);
	  
	- 	conf.base1 = conf.npage1 = addr;
	- 	for(; i < 512; i++){
	- 		if(probemem(addr) == 0)
	- 			break;
	- 		addr += OneMeg;
	+ 		conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
	+ 		conf.npage += conf.mem[i].npage;
	  	}
	- 	for(; i < 512; i++){
	- 		if(probemem(addr) < 0)
	- 			break;
	- 		addr += OneMeg;
	- 		conf.npage1 = addr;
	- 	}
	- 
	- 	/* take kernel out of allocatable space */
	- 	ktop = PGROUND((ulong)end);
	- 	if(ktop >= conf.base0 && ktop <= conf.npage0)
	- 		conf.base0 = ktop;
	- 	else if(ktop >= conf.base1 && ktop <= conf.npage1)
	- 		conf.base1 = ktop;
	- 	else
	- 		iprint("kernel not in allocatable space\n");
	- 
	- 	/* zero memory */
	- 	memset((void*)conf.base0, 0, conf.npage0 - conf.base0);
	- 	memset((void*)conf.base1, 0, conf.npage1 - conf.base1);
	- 
	- 	/* make npage the right thing */
	- 	conf.npage0 = (conf.npage0 - conf.base0)/BY2PG;
	- 	conf.npage1 = (conf.npage1 - conf.base1)/BY2PG;
	- 	conf.npage = conf.npage0+conf.npage1;
	  
	  	if(conf.npage > 16*MB/BY2PG){
	  		conf.upages = (conf.npage*60)/100;
 [rsc] --rw-rw-r-- M 451989 glenda bitsy 2459 Nov  6 10:09 sys/src/9/bitsy/mkfile
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/mkfile:104,110 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/mkfile:104,110
	  	$AS init9.s
	  	$LD -l -R1 -o init.out init9.$O initcode.$O /arm/lib/libc.a
	  	{echo 'uchar initcode[]={'
	- 	 strip < init.out | xd -1x |
	+ 	 strip -o /fd/1 init.out | xd -1x |
	  		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
	  	 echo '};'} > init.h
	  
 [rsc] --rw-rw-r-- M 451989 glenda bitsy 44404 Nov  6 10:09 sys/src/9/bitsy/sdata.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/sdata.c:742,747 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/sdata.c:742,748
	  
	  	sdev->ifc = &sdataifc;
	  	sdev->ctlr = ctlr;
	+ 	sdev->idno = 'C';
	  	sdev->nunit = 1;
	  	ctlr->sdev = sdev;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/sdata.c:1571,1596 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/sdata.c:1572,1577
	  	return ataprobe(port, port+0x204, irq);
	  }
	  
	- static SDev*
	- ataid(SDev* sdev)
	- {
	- 	int i;
	- 
	- 	if(sdev == nil)
	- 		return nil;
	- 	i = 0;
	- 	while(sdev){
	- 		if(sdev->ifc == &sdataifc){
	- 			sdev->idno = 'C'+i;
	- 			i++;
	- 			snprint(sdev->name, KNAMELEN, "sd%c", sdev->idno);
	- 		}
	- 		sdev = sdev->next;
	- 	}
	- 
	- 	return nil;
	- }
	- 
	  static int ataitype;
	  static int atairq;
	  static int
	/n/sourcesdump/2005/1106/plan9/sys/src/9/bitsy/sdata.c:2089,2095 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/bitsy/sdata.c:2070,2075
	  
	  	nil,				/* pnp */
	  	atalegacy,			/* legacy */
	- 	ataid,				/* id */
	  	ataenable,			/* enable */
	  	nil,				/* disable */
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 1160 Nov  6 10:09 sys/src/9/boot/bootauth.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/boot/bootauth.c:22,28 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/boot/bootauth.c:22,30
	  	ac = 0;
	  	av = argv;
	  	av[ac++] = "factotum";
	- //av[ac++] = "-d";
	+ 	if(getenv("debugfactotum"))
	+ 		av[ac++] = "-p";
	+ //av[ac++] = "-d";	//debug traces
	  //av[ac++] = "-D";	//9p messages
	  	if(cpuflag)
	  		av[ac++] = "-S";
 [rsc] --rw-rw-r-- M 451989 glenda sys 3843 Nov  6 10:10 sys/src/9/mtx/dat.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/mtx/dat.h:1,4 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/mtx/dat.h:1,5
	  typedef struct Conf	Conf;
	+ typedef struct Confmem	Confmem;
	  typedef struct FPsave	FPsave;
	  typedef struct ISAConf	ISAConf;
	  typedef struct Label	Label;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/mtx/dat.h:33,39 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/mtx/dat.h:34,40
	  	ulong	sr;
	  	ulong	pc;
	  	Proc	*p;
	- 	ulong	pid;
	+ 	Mach	*m;
	  	ushort	isilock;
	  };
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/mtx/dat.h:68,82 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/mtx/dat.h:69,88
	  	};
	  };
	  
	+ struct Confmem
	+ {
	+ 	ulong	base;
	+ 	ulong	npage;
	+ 	ulong	kbase;
	+ 	ulong	klimit;
	+ };
	+ 
	  struct Conf
	  {
	  	ulong	nmach;		/* processors */
	  	ulong	nproc;		/* processes */
	- 	ulong	npage0;		/* total physical pages of memory */
	- 	ulong	npage1;		/* total physical pages of memory */
	+ 	Confmem	mem[1];
	  	ulong	npage;		/* total physical pages of memory */
	- 	ulong	base0;		/* base of bank 0 */
	- 	ulong	base1;		/* base of bank 1 */
	  	ulong	upages;		/* user page pool */
	  	ulong	nimage;		/* number of page cache image headers */
	  	ulong	nswap;		/* number of swap pages */
 [rsc] --rw-rw-r-- M 451989 glenda sys 8307 Nov  6 10:10 sys/src/9/mtx/main.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/mtx/main.c:288,300 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/mtx/main.c:288,296
	  
	  	pa = PGROUND(PADDR(end));
	  
	- 	conf.npage0 = memsize/BY2PG;
	- 	conf.base0 = pa;
	- 	
	- 	conf.npage1 = 0;
	- 	conf.base1 = pa;
	- 
	- 	conf.npage = conf.npage0 + conf.npage1;
	+ 	conf.mem[0].npage = memsize/BY2PG;
	+ 	conf.mem[0].base = pa;
	+ 	conf.npage = conf.mem[0].npage;
	  
	  	conf.nmach = 1;
	  	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
 [rsc] --rw-rw-r-- M 451989 glenda sys 8748 Nov  6 10:16 sys/src/9/pc/apic.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/apic.c:376,378 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/apic.c:376,391
	  {
	  	timerintr(u, 0);
	  }
	+ 
	+ void
	+ lapicintron(void)
	+ {
	+ 	lapicw(LapicTPR, 0);
	+ }
	+ 
	+ void
	+ lapicintroff(void)
	+ {
	+ 	lapicw(LapicTPR, 0xFF);
	+ }
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 3723 Nov  6 10:16 sys/src/9/pc/apm.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/apm.c:103,108 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/apm.c:103,110
	  	if(isaconfig("apm", 0, &isa) == 0)
	  		return;
	  
	+ /* XXX use realmode() */
	+ 
	  	/*
	  	 * APM info passed from boot loader.
	  	 * Now we need to set up the GDT entries for APM.
 [rsc] --rw-rw-r-- M 451989 glenda sys 2357 Nov  6 10:16 sys/src/9/pc/archmp.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/archmp.c:62,67 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/archmp.c:62,69
	  .reset=		mpshutdown,
	  .intrinit=	mpinit,
	  .intrenable=	mpintrenable,
	+ .intron=	lapicintron,
	+ .introff=	lapicintroff,
	  .fastclock=	i8253read,
	  .timerset=	lapictimerset,
	  };
 [rsc] --rw-rw-r-- M 451989 glenda sys 6462 Nov  6 10:16 sys/src/9/pc/dat.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/dat.h:1,4 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/dat.h:1,5
	  typedef struct Conf	Conf;
	+ typedef struct Confmem	Confmem;
	  typedef struct FPsave	FPsave;
	  typedef struct ISAConf	ISAConf;
	  typedef struct Label	Label;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/dat.h:32,37 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/dat.h:33,39
	  	ulong	sr;
	  	ulong	pc;
	  	Proc	*p;
	+ 	Mach	*m;
	  	ushort	isilock;
	  };
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/dat.h:73,85 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/dat.h:75,94
	  	uchar	regs[80];	/* floating point registers */
	  };
	  
	+ struct Confmem
	+ {
	+ 	ulong	base;
	+ 	ulong	npage;
	+ 	ulong	kbase;
	+ 	ulong	klimit;
	+ };
	+ 
	  struct Conf
	  {
	  	ulong	nmach;		/* processors */
	  	ulong	nproc;		/* processes */
	  	ulong	monitor;	/* has monitor? */
	- 	ulong	npage0;		/* total physical pages of memory */
	- 	ulong	npage1;		/* total physical pages of memory */
	+ 	Confmem	mem[4];		/* physical memory */
	  	ulong	npage;		/* total physical pages of memory */
	  	ulong	upages;		/* user page pool */
	  	ulong	nimage;		/* number of page cache image headers */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/dat.h:102,107 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/dat.h:111,117
	  	Page*	mmupdb;			/* page directory base */
	  	Page*	mmufree;		/* unused page table pages */
	  	Page*	mmuused;		/* used page table pages */
	+ 	uint	lastkmap;		/* last entry used by kmap */
	  };
	  
	  /*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/dat.h:212,223 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/dat.h:222,233
	  };
	  
	  /*
	-  * Fake kmap
	+  * KMap the structure doesn't exist, but the functions do.
	   */
	- typedef void		KMap;
	- #define	VA(k)		((ulong)(k))
	- #define	kmap(p)		(KMap*)((p)->pa|KZERO)
	- #define	kunmap(k)
	+ typedef struct KMap		KMap;
	+ #define	VA(k)		((void*)(k))
	+ KMap*	kmap(Page*);
	+ void	kunmap(KMap*);
	  
	  struct
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/dat.h:243,248 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/dat.h:253,260
	  	int	(*intrenable)(Vctl*);
	  	int	(*intrvecno)(int);
	  	int	(*intrdisable)(int);
	+ 	void	(*introff)(void);
	+ 	void	(*intron)(void);
	  
	  	void	(*clockenable)(void);
	  	uvlong	(*fastclock)(uvlong*);
 [rsc] --rw-rw-r-- M 451989 glenda sys 18594 Nov  6 10:17 sys/src/9/pc/devarch.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devarch.c:520,525 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devarch.c:520,527
	  .intrenable=	i8259enable,
	  .intrvecno=	i8259vecno,
	  .intrdisable=	i8259disable,
	+ .intron=		i8259on,
	+ .introff=		i8259off,
	  
	  .clockenable=	i8253enable,
	  .fastclock=	i8253read,
 [rsc] --rw-rw-r-- M 451989 glenda sys 10315 Nov  6 10:17 sys/src/9/pc/devether.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devether.c:416,422 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devether.c:416,422
	  	i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %d",
	  		ctlrno, cards[cardno].type, ether->mbps, ether->port, ether->irq);
	  	if(ether->mem)
	- 		i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
	+ 		i += sprint(buf+i, " addr 0x%luX", ether->mem);
	  	if(ether->size)
	  		i += sprint(buf+i, " size 0x%luX", ether->size);
	  	i += sprint(buf+i, ": %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devether.c:425,440 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devether.c:425,439
	  	sprint(buf+i, "\n");
	  	print(buf);
	  
	- 	if (ether->mbps >= 1000) {
	+ 	if(ether->mbps >= 1000){
	  		netifinit(ether, name, Ntypes, 512*1024);
	  		if(ether->oq == 0)
	  			ether->oq = qopen(512*1024, Qmsg, 0, 0);
	- 	} else if(ether->mbps >= 100){
	+ 	}else if(ether->mbps >= 100){
	  		netifinit(ether, name, Ntypes, 256*1024);
	  		if(ether->oq == 0)
	  			ether->oq = qopen(256*1024, Qmsg, 0, 0);
	- 	}
	- 	else{
	+ 	}else{
	  		netifinit(ether, name, Ntypes, 128*1024);
	  		if(ether->oq == 0)
	  			ether->oq = qopen(128*1024, Qmsg, 0, 0);
 [rsc] --rw-rw-r-- M 451989 glenda sys 40203 Nov  6 10:18 sys/src/9/pc/devpccard.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devpccard.c:515,520 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devpccard.c:515,521
	  	int i;
	  	uchar intl;
	  	char *p;
	+ 	void *baddrva;
	  
	  	if (initialized) 
	  		return;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devpccard.c:623,636 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devpccard.c:624,638
	  		intl = pci->intl;
	  
	  		if ((baddr = pcicfgr32(cb->pci, PciBAR0)) == 0) {
	- 			int align = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;
	+ 			int size = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;
	  
	- 			baddr = upamalloc(baddr, align, align);
	+ 			baddr = upaalloc(size, size);
	+ 			baddrva = vmap(baddr, size);
	  			pcicfgw32(cb->pci, PciBAR0, baddr);
	- 			cb->regs = (ulong *)KADDR(baddr);
	+ 			cb->regs = (ulong *)baddrva;
	  		}
	  		else
	- 			cb->regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0));
	+ 			cb->regs = (ulong *)vmap(baddr, 4096);
	  		cb->state = SlotEmpty;
	  
	  		/* Don't really know what to do with this... */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devpccard.c:810,816 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devpccard.c:812,818
	  				continue;
	  			}
	  
	- 			bar = upamalloc(0, pci->mem[i].size, BY2PG);
	+ 			bar = upaalloc(pci->mem[i].size, BY2PG);
	  			pci->mem[i].bar = bar | (pci->mem[i].bar & 0x80);
	  			pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), pci->mem[i].bar);
	  			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, bar);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devpccard.c:834,840 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devpccard.c:836,842
	  				print("#Y%ld: WARNING: Too many memory spaces, not mapping ROM space\n",
	  					cb - cbslots);
	  			else {
	- 				pci->rom.bar = upamalloc(0, size, BY2PG);
	+ 				pci->rom.bar = upaalloc(size, BY2PG);
	  				pci->rom.size = size;
	  
	  				pcicfgw32(pci, PciEBAR0, pci->rom.bar);
 [rsc] --rw-rw-r-- M 451989 glenda sys 45676 Nov  6 10:18 sys/src/9/pc/devtv.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:557,563 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:557,563
	  		tv = &tvs[ntvs++];
	  		tv->variant = &variant[i];
	  		tv->pci = pci;
	- 		tv->bt848 = (Bt848 *)upamalloc(pci->mem[0].bar & ~0x0F, 4 * K, K);
	+ 		tv->bt848 = (Bt848 *)vmap(pci->mem[0].bar & ~0x0F, 4 * K);
	  		if (tv->bt848 == nil)
	  			panic("#V: Cannot allocate memory for Bt848");
	  		bt848 = tv->bt848;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:591,597 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:591,597
	  				panic("#V: Unsupported Hauppage board");
	  
	  			tv->bt878 = bt878 = 
	- 				(Bt848 *)upamalloc(pci878->mem[0].bar & ~0x0F, 4 * K, K);
	+ 				(Bt848 *)vmap(pci878->mem[0].bar & ~0x0F, 4 * K);
	  			if (bt878 == nil)
	  				panic("#V: Cannot allocate memory for the Bt878");
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1206,1212 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1206,1212
	  }
	  
	  static ulong *
	- riscpacked(ulong paddr, int fnum, int w, int h, int stride, ulong **lastjmp)
	+ riscpacked(ulong pa, int fnum, int w, int h, int stride, ulong **lastjmp)
	  {
	  	ulong *p, *pbase;
	  	int i;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1224,1230 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1224,1230
	  
	  	for (i = 0; i != h / 2; i++) {
	  		*p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
	- 		*p++ = paddr + i * 2 * stride;
	+ 		*p++ = pa + i * 2 * stride;
	  	}
	  
	  	*p++ = riscsync | riscsync_resync | riscsync_vro;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1235,1241 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1235,1241
	  
	  	for (i = 0; i != h / 2; i++) {
	  		*p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
	- 		*p++ = paddr + (i * 2 + 1) * stride;
	+ 		*p++ = pa + (i * 2 + 1) * stride;
	  	}
	  
	  	// reset status.  you really need two instructions ;-(.
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1248,1254 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1248,1254
	  }
	  
	  static ulong *
	- riscplanar411(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
	+ riscplanar411(ulong pa, int fnum, int w, int h, ulong **lastjmp)
	  {
	  	ulong *p, *pbase, Cw, Yw, Ch;
	  	uchar *Ybase, *Cbbase, *Crbase;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1260,1266 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1260,1266
	  	assert(p);
	  
	  	Yw = w;
	- 	Ybase = (uchar *)paddr;
	+ 	Ybase = (uchar *)pa;
	  	Cw = w >> 1;
	  	Ch = h >> 1;
	  	Cbbase = Ybase + Yw * h;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1302,1308 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1302,1308
	  }
	  
	  static ulong *
	- riscplanar422(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
	+ riscplanar422(ulong pa, int fnum, int w, int h, ulong **lastjmp)
	  {
	  	ulong *p, *pbase, Cw, Yw;
	  	uchar *Ybase, *Cbbase, *Crbase;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1314,1320 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1314,1320
	  	assert(p);
	  
	  	Yw = w;
	- 	Ybase = (uchar *)paddr;
	+ 	Ybase = (uchar *)pa;
	  	Cw = w >> 1;
	  	Cbbase = Ybase + Yw * h;
	  	Crbase = Cbbase + Cw * h;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1357,1363 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1357,1363
	  }
	  
	  static ulong *
	- riscaudio(ulong paddr, int nblocks, int bsize)
	+ riscaudio(ulong pa, int nblocks, int bsize)
	  {
	  	ulong *p, *pbase;
	  	int i;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1372,1378 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1372,1378
	  		*p++ = riscwrite | riscwrite_sol | riscwrite_eol | bsize | riscirq |
	  				((i & 0xf) << risclabelshift_set) | 
	  				((~i & 0xf) << risclabelshift_reset);
	- 		*p++ = paddr + i * bsize;
	+ 		*p++ = pa + i * bsize;
	  	}
	  
	  	*p++ = riscsync | riscsync_vro;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1556,1562 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1556,1562
	  }
	  
	  static void
	- vgastart(Tv *tv, ulong paddr, int stride)
	+ vgastart(Tv *tv, ulong pa, int stride)
	  {
	  	Frame *frame;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devtv.c:1568,1574 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devtv.c:1568,1574
	  	}
	  
	  	frame->fbase = nil;
	- 	frame->fstart = riscpacked(paddr, 0, ntsc_hactive * getbitspp(tv) / 8, 
	+ 	frame->fstart = riscpacked(pa, 0, ntsc_hactive * getbitspp(tv) / 8, 
	  						   ntsc_vactive, stride * getbitspp(tv) / 8, 
	  						   &frame->fjmp);
	  	*frame->fjmp = PADDR(frame->fstart);
 [rsc] --rw-rw-r-- M 451989 glenda sys 9332 Nov  6 10:18 sys/src/9/pc/devvga.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:6,11 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:6,12
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:16,21 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:17,23
	  
	  enum {
	  	Qdir,
	+ 	Qvgabios,
	  	Qvgactl,
	  	Qvgaovl,
	  	Qvgaovlctl,
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:23,28 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:25,31
	  
	  static Dirtab vgadir[] = {
	  	".",	{ Qdir, 0, QTDIR },		0,	0550,
	+ 	"vgabios",	{ Qvgabios, 0 },	0x100000, 0440,
	  	"vgactl",		{ Qvgactl, 0 },		0,	0660,
	  	"vgaovl",		{ Qvgaovl, 0 },		0,	0660,
	  	"vgaovlctl",	{ Qvgaovlctl, 0 },	0, 	0660,
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:40,45 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:43,49
	  	CMpalettedepth,
	  	CMpanning,
	  	CMsize,
	+ 	CMtextmode,
	  	CMtype,
	  	CMunblank,
	  };
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:56,61 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:60,66
	  	CMpalettedepth,	"palettedepth",	2,
	  	CMpanning,	"panning",	2,
	  	CMsize,		"size",		3,
	+ 	CMtextmode,	"textmode",	1,
	  	CMtype,		"type",		2,
	  	CMunblank,	"unblank",	1,
	  };
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:153,158 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:158,171
	  	case Qdir:
	  		return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
	  
	+ 	case Qvgabios:
	+ 		if(offset >= 0x100000)
	+ 			return 0;
	+ 		if(offset+n >= 0x100000)
	+ 			n = 0x100000 - offset;
	+ 		memmove(a, (uchar*)kaddr(0)+offset, n);
	+ 		return n;
	+ 
	  	case Qvgactl:
	  		scr = &vgascreen[0];
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:186,192 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:199,207
	  		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
	  		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
	  		len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
	- 		snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->aperture);
	+ 		len += snprint(p+len, READSTR-len, "addr p 0x%lux v 0x%p size 0x%ux\n", scr->paddr, scr->vaddr, scr->apsize);
	+ 		USED(len);
	+ 
	  		n = readstr(offset, a, n, p);
	  		poperror();
	  		free(p);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:233,239 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:248,264
	  			unlock(&cursor);
	  			return;
	  		}
	- 
	+ 		if(strcmp(cb->f[1], "soft") == 0){
	+ 			lock(&cursor);
	+ 			swcursorinit();
	+ 			if(scr->cur && scr->cur->disable)
	+ 				scr->cur->disable(scr);
	+ 			scr->cur = &swcursor;
	+ 			if(scr->cur->enable)
	+ 				scr->cur->enable(scr);
	+ 			unlock(&cursor);
	+ 			return;
	+ 		}
	  		for(i = 0; vgacur[i]; i++){
	  			if(strcmp(cb->f[1], vgacur[i]->name))
	  				continue;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:261,269 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:286,296
	  		}
	  		break;
	  
	+ 	case CMtextmode:
	+ 		screeninit();
	+ 		return;
	+ 
	  	case CMsize:
	- 		if(drawhasclients())
	- 			error(Ebusy);
	  
	  		x = strtoul(cb->f[1], &p, 0);
	  		if(x == 0 || x > 2048)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:291,296 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:318,324
	  		if(screensize(x, y, z, chan))
	  			error(Egreg);
	  		vgascreenwin(scr);
	+ 		resetscreenimage();
	  		cursoron(1);
	  		return;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devvga.c:337,343 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devvga.c:365,371
	  			align = 0;
	  		else
	  			align = strtoul(cb->f[2], 0, 0);
	- 		if(screenaperture(size, align))
	+ 		if(screenaperture(size, align) < 0)
	  			error("not enough free address space");
	  		return;
	  /*	
 [rsc] --rw-rw-r-- M 451989 glenda sys 4715 Nov  6 10:18 sys/src/9/pc/dma.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/dma.c:140,149 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/dma.c:140,148
	  	 *  if this isn't kernel memory or crossing 64k boundary or above 16 meg
	  	 *  use the bounce buffer.
	  	 */
	- 	pa = PADDR(va);
	- 	if((((ulong)va)&0xF0000000) != KZERO
	- 	|| (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
	- 	|| pa >= 16*MB) {
	+ 	if((ulong)va < KZERO 
	+ 	|| ((pa=PADDR(va))&0xFFFF0000) != ((pa+len)&0xFFFF0000)
	+ 	|| pa >= 16*MB){
	  		if(xp->bva == nil)
	  			return -1;
	  		if(len > xp->blen)
 [rsc] --rw-rw-r-- M 451989 glenda sys 13953 Nov  6 10:18 sys/src/9/pc/ether79c970.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether79c970.c:522,528 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether79c970.c:522,527
	  		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;
	  	}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether79c970.c:538,545 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether79c970.c:537,542
	  		break;
	  	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;
 [rsc] --rw-rw-r-- M 451989 glenda sys 18400 Nov  6 10:19 sys/src/9/pc/ether8139.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8139.c:243,249 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8139.c:243,249
	  
	  	ctlr = edev->ctlr;
	  	p = malloc(READSTR);
	- 	l = snprint(p, READSTR, "rcr %8.8uX\n", ctlr->rcr);
	+ 	l = snprint(p, READSTR, "rcr %#8.8ux\n", ctlr->rcr);
	  	l += snprint(p+l, READSTR-l, "ierrs %d\n", ctlr->ierrs);
	  	l += snprint(p+l, READSTR-l, "etxth %d\n", ctlr->etxth);
	  	l += snprint(p+l, READSTR-l, "taligned %d\n", ctlr->taligned);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8139.c:255,274 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8139.c:255,274
	  	ctlr->rec += csr16r(ctlr, Rec);
	  	l += snprint(p+l, READSTR-l, "rec %d\n", ctlr->rec);
	  
	- 	l += snprint(p+l, READSTR-l, "Tcr %8.8luX\n", csr32r(ctlr, Tcr));
	- 	l += snprint(p+l, READSTR-l, "Config0 %2.2uX\n", csr8r(ctlr, Config0));
	- 	l += snprint(p+l, READSTR-l, "Config1 %2.2uX\n", csr8r(ctlr, Config1));
	- 	l += snprint(p+l, READSTR-l, "Msr %2.2uX\n", csr8r(ctlr, Msr));
	- 	l += snprint(p+l, READSTR-l, "Config3 %2.2uX\n", csr8r(ctlr, Config3));
	- 	l += snprint(p+l, READSTR-l, "Config4 %2.2uX\n", csr8r(ctlr, Config4));
	+ 	l += snprint(p+l, READSTR-l, "Tcr %#8.8lux\n", csr32r(ctlr, Tcr));
	+ 	l += snprint(p+l, READSTR-l, "Config0 %#2.2ux\n", csr8r(ctlr, Config0));
	+ 	l += snprint(p+l, READSTR-l, "Config1 %#2.2ux\n", csr8r(ctlr, Config1));
	+ 	l += snprint(p+l, READSTR-l, "Msr %#2.2ux\n", csr8r(ctlr, Msr));
	+ 	l += snprint(p+l, READSTR-l, "Config3 %#2.2ux\n", csr8r(ctlr, Config3));
	+ 	l += snprint(p+l, READSTR-l, "Config4 %#2.2ux\n", csr8r(ctlr, Config4));
	  
	- 	l += snprint(p+l, READSTR-l, "Bmcr %4.4uX\n", csr16r(ctlr, Bmcr));
	- 	l += snprint(p+l, READSTR-l, "Bmsr %4.4uX\n", csr16r(ctlr, Bmsr));
	- 	l += snprint(p+l, READSTR-l, "Anar %4.4uX\n", csr16r(ctlr, Anar));
	- 	l += snprint(p+l, READSTR-l, "Anlpar %4.4uX\n", csr16r(ctlr, Anlpar));
	- 	l += snprint(p+l, READSTR-l, "Aner %4.4uX\n", csr16r(ctlr, Aner));
	- 	l += snprint(p+l, READSTR-l, "Nwaytr %4.4uX\n", csr16r(ctlr, Nwaytr));
	- 	snprint(p+l, READSTR-l, "Cscr %4.4uX\n", csr16r(ctlr, Cscr));
	+ 	l += snprint(p+l, READSTR-l, "Bmcr %#4.4ux\n", csr16r(ctlr, Bmcr));
	+ 	l += snprint(p+l, READSTR-l, "Bmsr %#4.4ux\n", csr16r(ctlr, Bmsr));
	+ 	l += snprint(p+l, READSTR-l, "Anar %#4.4ux\n", csr16r(ctlr, Anar));
	+ 	l += snprint(p+l, READSTR-l, "Anlpar %#4.4ux\n", csr16r(ctlr, Anlpar));
	+ 	l += snprint(p+l, READSTR-l, "Aner %#4.4ux\n", csr16r(ctlr, Aner));
	+ 	l += snprint(p+l, READSTR-l, "Nwaytr %#4.4ux\n", csr16r(ctlr, Nwaytr));
	+ 	snprint(p+l, READSTR-l, "Cscr %#4.4ux\n", csr16r(ctlr, Cscr));
	  	n = readstr(offset, a, n, p);
	  	free(p);
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8139.c:589,595 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8139.c:589,595
	  		 * other than try to reinitialise the chip?
	  		 */
	  		if((isr & (Serr|Timerbit)) != 0){
	- 			iprint("rtl8139interrupt: imr %4.4uX isr %4.4uX\n",
	+ 			iprint("rtl8139interrupt: imr %#4.4ux isr %#4.4ux\n",
	  				csr16r(ctlr, Imr), isr);
	  			if(isr & Timerbit)
	  				csr32w(ctlr, TimerInt, 0);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8139.c:621,627 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8139.c:621,627
	  			continue;
	  
	  		if(ioalloc(port, p->mem[0].size, 0, "rtl8139") < 0){
	- 			print("rtl8139: port 0x%uX in use\n", port);
	+ 			print("rtl8139: port %#ux in use\n", port);
	  			continue;
	  		}
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 32294 Nov  6 10:19 sys/src/9/pc/ether82543gc.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82543gc.c:1243,1249 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82543gc.c:1243,1250
	  static void
	  gc82543pci(void)
	  {
	- 	int port, cls;
	+ 	int cls;
	+ 	void *mem;
	  	Pcidev *p;
	  	Ctlr *ctlr;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82543gc.c:1262,1269 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82543gc.c:1263,1270
	  			break;
	  		}
	  
	- 		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
	- 		if(port == 0){
	+ 		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
	+ 		if(mem == 0){
	  			print("gc82543: can't map %8.8luX\n", p->mem[0].bar);
	  			continue;
	  		}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82543gc.c:1280,1290 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82543gc.c:1281,1290
	  					cls*4);
	  		}
	  		ctlr = malloc(sizeof(Ctlr));
	- 		ctlr->port = port;
	+ 		ctlr->port = p->mem[0].bar & ~0x0F;
	  		ctlr->pcidev = p;
	  		ctlr->id = (p->did<<16)|p->vid;
	- 
	- 		ctlr->nic = KADDR(ctlr->port);
	+ 		ctlr->nic = mem;
	  
	  		if(gc82543reset(ctlr)){
	  			free(ctlr);
 [rsc] --rw-rw-r-- M 451989 glenda sys 30107 Nov  6 10:19 sys/src/9/pc/ether82557.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:290,296 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:290,296
	  	if(timeo >= 100){
	  		ctlr->command = -1;
	  		iunlock(&ctlr->rlock);
	- 		iprint("i82557: command 0x%uX %uX timeout\n", c, v);
	+ 		iprint("i82557: command %#ux %#ux timeout\n", c, v);
	  		return;
	  	}
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:462,468 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:462,468
	  	for(i = 0; i < (1<<ctlr->eepromsz); i++){
	  		if(i && ((i & 0x07) == 0))
	  			len += snprint(p+len, READSTR-len, "\n       ");
	- 		len += snprint(p+len, READSTR-len, " %4.4uX", ctlr->eeprom[i]);
	+ 		len += snprint(p+len, READSTR-len, " %4.4ux", ctlr->eeprom[i]);
	  	}
	  
	  	if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000)){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:471,477 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:471,477
	  		for(i = 0; i < 6; i++){
	  			static int miir(Ctlr*, int, int);
	  
	- 			len += snprint(p+len, READSTR-len, " %4.4uX",
	+ 			len += snprint(p+len, READSTR-len, " %4.4ux",
	  				miir(ctlr, phyaddr, i));
	  		}
	  	}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:523,529 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:523,529
	  			ctlr->action = 0;
	  		}
	  		else{
	- 			print("#l%d: action 0x%uX\n", ether->ctlrno, ctlr->action);
	+ 			print("#l%d: action %#ux\n", ether->ctlrno, ctlr->action);
	  			ctlr->action = 0;
	  			break;
	  		}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:630,636 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:630,636
	  			pbp = nil;
	  			count = rfd->count & 0x3FFF;
	  			if((count < ETHERMAXTU/4) && (pbp = iallocb(count))){
	- 				memmove(pbp->rp, bp->rp+sizeof(Rfd)-sizeof(rfd->data), count);
	+ 				memmove(pbp->rp, bp->rp+offsetof(Rfd, data[0]), count);
	  				pbp->wp = pbp->rp + count;
	  
	  				rfd->count = 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:637,643 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:637,643
	  				rfd->field = 0;
	  			}
	  			else if(xbp = rfdalloc(rfd->link)){
	- 				bp->rp += sizeof(Rfd)-sizeof(rfd->data);
	+ 				bp->rp += offsetof(Rfd, data[0]);
	  				bp->wp = bp->rp + count;
	  
	  				xbp->next = bp->next;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:748,754 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:748,754
	  		}
	  
	  		if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
	- 			panic("#l%d: status %uX\n", ether->ctlrno, status);
	+ 			panic("#l%d: status %#ux\n", ether->ctlrno, status);
	  	}
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:955,961 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:955,961
	  		 */
	  		port = p->mem[1].bar & ~0x01;
	  		if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
	- 			print("i82557: port 0x%uX in use\n", port);
	+ 			print("i82557: port %#ux in use\n", port);
	  			continue;
	  		}
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:997,1003 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:997,1003
	  		oui <<= 6;
	  		x = miir(ctlr, i, 3);
	  		oui |= x>>10;
	- 		//print("phy%d: oui %uX reg1 %uX\n", i, oui, miir(ctlr, i, 1));
	+ 		//print("phy%d: oui %#ux reg1 %#ux\n", i, oui, miir(ctlr, i, 1));
	  
	  		ctlr->eeprom[6] = i;
	  		if(oui == 0xAA00)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether82557.c:1093,1099 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether82557.c:1093,1099
	  		sum += x;
	  	}
	  	if(sum != 0xBABA)
	- 		print("#l%d: EEPROM checksum - 0x%4.4uX\n", ether->ctlrno, sum);
	+ 		print("#l%d: EEPROM checksum - %#4.4ux\n", ether->ctlrno, sum);
	  
	  	/*
	  	 * Eeprom[6] indicates whether there is a PHY and whether
 [rsc] --rw-rw-r-- M 451989 glenda sys 17702 Nov  6 10:19 sys/src/9/pc/ether8390.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8390.c:400,406 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8390.c:400,406
	  		 */
	  		if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop
	  		  || len < 60 || len > sizeof(Etherpkt)){
	- 			print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%lud\n",
	+ 			print("dp8390: H%2.2ux+%2.2ux+%2.2ux+%2.2ux,%lud\n",
	  				hdr.status, hdr.next, hdr.len0, hdr.len1, len);
	  			regw(ctlr, Cr, Page0|RdABORT|Stp);
	  			ringinit(ctlr);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8390.c:588,594 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8390.c:588,594
	  		if(isr & (Txe|Ptx)){
	  			r = regr(ctlr, Tsr);
	  			if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){
	- 				print("dp8390: Tsr#%2.2ux|", r);
	+ 				print("dp8390: Tsr %#2.2ux", r);
	  				ether->oerrs++;
	  			}
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8390.c:686,692 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8390.c:686,692
	  	if(reverse[1] == 0){
	  		for(i = 0; i < 64; i++)
	  			reverse[i] = ((i&1)<<5) | ((i&2)<<3) | ((i&4)<<1)
	- 					| ((i&8)>>1) | ((i&16)>>3) | ((i&32)>>5);
	+ 				   | ((i&8)>>1) | ((i&16)>>3) | ((i&32)>>5);
	  	}
	  
	  	/*
 [rsc] --rw-rw-r-- M 451989 glenda sys 48733 Nov  6 10:19 sys/src/9/pc/etherelnk3.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherelnk3.c:1485,1499 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherelnk3.c:1485,1499
	  			break;
	  		case 0x5157:
	  			ctlr->eepromcmd = EepromRead8bRegister;
	- 			ctlr->cbfnpa = upamalloc(p->mem[2].bar, p->mem[2].size, 0);
	+ 			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
	+ 			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
	  			break;
	  		case 0x6056:
	  			ctlr->eepromcmd = EepromReadOffRegister;
	- 			ctlr->cbfnpa = upamalloc(p->mem[2].bar, p->mem[2].size, 0);
	+ 			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
	+ 			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
	  			break;
	  		}
	- 		if(ctlr->cbfnpa != 0)
	- 			ctlr->cbfn = KADDR(ctlr->cbfnpa);
	  		pcisetbme(p);
	  	}
	  }
 [rsc] --rw-rw-r-- M 451989 jmk sys 44431 Nov  6 10:19 sys/src/9/pc/etherigbe.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherigbe.c:439,445 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherigbe.c:439,445
	  
	  typedef struct Ctlr Ctlr;
	  typedef struct Ctlr {
	- 	int	port;
	+ 	ulong	port;
	  	Pcidev*	pcidev;
	  	Ctlr*	next;
	  	int	active;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherigbe.c:1468,1474 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherigbe.c:1468,1475
	  		ctlr->mii = nil;
	  		return -1;
	  	}
	- 	print("oui %X phyno %d\n", phy->oui, phy->phyno);
	+ 	USED(phy);
	+ 	// print("oui %X phyno %d\n", phy->oui, phy->phyno);
	  
	  	/*
	  	 * 8254X-specific PHY registers not in 802.3:
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherigbe.c:1848,1857 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherigbe.c:1849,1859
	  static void
	  igbepci(void)
	  {
	- 	int port, cls;
	+ 	int cls;
	  	Pcidev *p;
	  	Ctlr *ctlr;
	- 
	+ 	void *mem;
	+ 	
	  	p = nil;
	  	while(p = pcimatch(p, 0, 0)){
	  		if(p->ccrb != 0x02 || p->ccru != 0)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherigbe.c:1874,1881 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherigbe.c:1876,1883
	  			break;
	  		}
	  
	- 		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
	- 		if(port == 0){
	+ 		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
	+ 		if(mem == nil){
	  			print("igbe: can't map %8.8luX\n", p->mem[0].bar);
	  			continue;
	  		}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherigbe.c:1893,1903 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherigbe.c:1895,1905
	  				break;
	  		}
	  		ctlr = malloc(sizeof(Ctlr));
	- 		ctlr->port = port;
	+ 		ctlr->port = p->mem[0].bar & ~0x0F;
	  		ctlr->pcidev = p;
	  		ctlr->id = (p->did<<16)|p->vid;
	  		ctlr->cls = cls*4;
	- 		ctlr->nic = KADDR(ctlr->port);
	+ 		ctlr->nic = mem;
	  
	  		if(igbereset(ctlr)){
	  			free(ctlr);
 [rsc] --rw-rw-r-- M 451989 glenda sys 3747 Nov  6 10:19 sys/src/9/pc/etherwavelan.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherwavelan.c:87,92 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherwavelan.c:87,93
	  	int did;
	  } wavelanpci[] = {
	  	0x1260, 0x3873,	/* Intersil Prism2.5 */
	+ 	0x1737,	0x0019,	/* Linksys WPC-11 untested */
	  };
	  
	  static Ctlr *ctlrhead, *ctlrtail;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherwavelan.c:95,101 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherwavelan.c:96,102
	  wavelanpciscan(void)
	  {
	  	int i;
	- 	ulong pa;
	+ 	void *mem;
	  	Pcidev *p;
	  	Ctlr *ctlr;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherwavelan.c:117,129 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherwavelan.c:118,130
	  
	  		ctlr = malloc(sizeof(Ctlr));
	  		ctlr->pcidev = p;
	- 		pa = upamalloc(p->mem[0].bar&~0xF, p->mem[0].size, 0);
	- 		if(pa == 0){
	- 			print("wavelanpci: %.4ux %.4ux: upamalloc 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
	+ 		mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);
	+ 		if(mem == nil){
	+ 			print("wavelanpci: %.4ux %.4ux: vmap 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
	  			free(ctlr);
	  			continue;
	  		}
	- 		ctlr->mmb = (ushort*)KADDR(pa);
	+ 		ctlr->mmb = mem;
	  		if(ctlrhead != nil)
	  			ctlrtail->next = ctlr;
	  		else
 [rsc] --rw-rw-r-- M 451989 glenda sys 4461 Nov  6 10:19 sys/src/9/pc/fns.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:3,11 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:3,9
	  void	aamloop(int);
	  Dirtab*	addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
	  void	archinit(void);
	- void	bootargs(ulong);
	- int	cistrcmp(char*, char*);
	- int	cistrncmp(char*, char*, int);
	+ void	bootargs(void*);
	  void	clockintr(Ureg*, void*);
	  void	(*coherence)(void);
	  void	cpuid(char*, int*, int*);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:46,56 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:44,56
	  void	i8253link(void);
	  uvlong	i8253read(uvlong*);
	  void	i8253timerset(uvlong);
	+ int	i8259disable(int);
	+ int	i8259enable(Vctl*);
	  void	i8259init(void);
	  int	i8259isr(int);
	- int	i8259enable(Vctl*);
	+ void	i8259on(void);
	+ void	i8259off(void);
	  int	i8259vecno(int);
	- int	i8259disable(int);
	  void	idle(void);
	  void	idlehands(void);
	  int	inb(int);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:61,66 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:61,69
	  void	insl(int, void*, int);
	  int	intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
	  void	intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
	+ void	introff(void);
	+ void	intron(void);
	+ void	invlpg(ulong);
	  void	iofree(int);
	  void	ioinit(void);
	  int	iounused(int, int);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:68,73 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:71,77
	  int	ioreserve(int, int, int, char*);
	  int	iprint(char*, ...);
	  int	isaconfig(char*, int, ISAConf*);
	+ void*	kaddr(ulong);
	  void	kbdenable(void);
	  void	kbdinit(void);
	  #define	kmapinval()
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:82,91 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:86,94
	  void	mb386(void);
	  void	mb586(void);
	  void	meminit(void);
	+ void	memorysummary(void);
	  #define mmuflushtlb(pdb) putcr3(pdb)
	  void	mmuinit(void);
	- ulong	mmukmap(ulong, ulong, int);
	- int	mmukmapsync(ulong);
	  ulong*	mmuwalk(ulong*, ulong, int, int);
	  uchar	nvramread(int);
	  void	nvramwrite(int, uchar);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:95,100 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:98,104
	  void	outss(int, void*, int);
	  void	outl(int, ulong);
	  void	outsl(int, void*, int);
	+ ulong	paddr(void*);
	  int	pciscan(int, Pcidev**);
	  ulong	pcibarsize(Pcidev*, int);
	  int	pcicfgr8(Pcidev*, int);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:122,139 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:126,149
	  void	pcmspecialclose(int);
	  void	(*_pcmspecialclose)(int);
	  void	pcmunmap(int, PCMmap*);
	+ int	pdbmap(ulong*, ulong, ulong, int);
	  void	procrestore(Proc*);
	  void	procsave(Proc*);
	  void	procsetup(Proc*);
	  void	putcr3(ulong);
	  void	putcr4(ulong);
	+ void*	rampage(void);
	  void	rdmsr(int, vlong*);
	+ void	realmode(Ureg*);
	  void	screeninit(void);
	  void	(*screenputs)(char*, int);
	  void	syncclock(void);
	+ void*	tmpmap(Page*);
	+ void	tmpunmap(void*);
	  void	touser(void*);
	  void	trapenable(int, void (*)(Ureg*, void*), void*, char*);
	  void	trapinit(void);
	+ void	trapinit0(void);
	  int	tas(void*);
	  uvlong	tscticks(uvlong*);
	  ulong	umbmalloc(ulong, int, int);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/fns.h:140,154 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/fns.h:150,168
	  void	umbfree(ulong, int);
	  ulong	umbrwmalloc(ulong, int, int);
	  void	umbrwfree(ulong, int);
	- ulong	upamalloc(ulong, int, int);
	+ ulong	upaalloc(int, int);
	  void	upafree(ulong, int);
	+ void	upareserve(ulong, int);
	  #define	userureg(ur) (((ur)->cs & 0xFFFF) == UESEL)
	  void	vectortable(void);
	+ void*	vmap(ulong, int);
	+ int	vmapsync(ulong);
	+ void	vunmap(void*, int);
	  void	wrmsr(int, vlong);
	  int	xchgw(ushort*, int);
	  
	  #define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
	- #define KADDR(a)	((void*)((ulong)(a)|KZERO))
	- #define PADDR(a)	((ulong)(a)&~KZERO)
	+ #define	KADDR(a)	kaddr(a)
	+ #define PADDR(a)	paddr((void*)(a))
	  
	  #define	dcflush(a, b)
 [rsc] --rw-rw-r-- M 451989 glenda sys 4586 Nov  6 10:19 sys/src/9/pc/i8259.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/i8259.c:197,199 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/i8259.c:197,214
	  	iunlock(&i8259lock);
	  	return 0;
	  }
	+ 
	+ void
	+ i8259on(void)
	+ {
	+ 	outb(Int0aux, i8259mask&0xFF);
	+ 	outb(Int1aux, (i8259mask>>8)&0xFF);
	+ }
	+ 
	+ void
	+ i8259off(void)
	+ {
	+ 	outb(Int0aux, 0xFF);
	+ 	outb(Int1aux, 0xFF);
	+ }
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 28347 Nov  6 10:20 sys/src/9/pc/l.s
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:1,4 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:1,6
	  #include "mem.h"
	+ #include "/sys/src/boot/pc/x16.h"
	+ #undef DELAY
	  
	  #define PADDR(a)	((a) & ~KZERO)
	  #define KADDR(a)	(KZERO|(a))
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:13,18 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:15,21
	  #define RDTSC 		BYTE $0x0F; BYTE $0x31	/* RDTSC, result in AX/DX (lo/hi) */
	  #define RDMSR		BYTE $0x0F; BYTE $0x32	/* RDMSR, result in AX/DX (lo/hi) */
	  #define HLT		BYTE $0xF4
	+ #define INVLPG	BYTE $0x0F; BYTE $0x01; BYTE $0x39	/* INVLPG (%ecx) */
	  
	  /*
	   * Macros for calculating offsets within the page directory base
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:27,34 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:30,37
	   * 9load currently sets up the mmu, however the first 16MB of memory is identity
	   * mapped, so behave as if the mmu was not setup
	   */
	- TEXT _start0x80100020(SB), $0
	- 	MOVL	$_start0x00100020(SB), AX
	+ TEXT _startKADDR(SB), $0
	+ 	MOVL	$_startPADDR(SB), AX
	  	ANDL	$~KZERO, AX
	  	JMP*	AX
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:40,49 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:43,52
	  	LONG	$0x00010003			/* flags */
	  	LONG	$-(0x1BADB002 + 0x00010003)	/* checksum */
	  	LONG	$_multibootheader-KZERO(SB)	/* header_addr */
	- 	LONG	$_start0x80100020-KZERO(SB)	/* load_addr */
	+ 	LONG	$_startKADDR-KZERO(SB)		/* load_addr */
	  	LONG	$edata-KZERO(SB)		/* load_end_addr */
	  	LONG	$end-KZERO(SB)			/* bss_end_addr */
	- 	LONG	$_start0x80100020-KZERO(SB)	/* entry_addr */
	+ 	LONG	$_startKADDR-KZERO(SB)		/* entry_addr */
	  	LONG	$0				/* mode_type */
	  	LONG	$0				/* width */
	  	LONG	$0				/* height */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:51,57 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:54,60
	  
	  /*
	   * In protected mode with paging turned off and segment registers setup to linear map all memory.
	-  * Entered via a jump to 0x00100020, the physical address of the virtual kernel entry point of 0x80100020
	+  * Entered via a jump to PADDR(entry), the physical address of the virtual kernel entry point of KADDR(entry)
	   * Make the basic page tables for processor 0. Four pages are needed for the basic set:
	   * a page directory, a page table for mapping the first 4MB of physical memory to KZERO,
	   * and virtual and physical pages for mapping the Mach structure.
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:60,66 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:63,69
	   * identity mapping is removed once the MMU is going and the JMP has been made
	   * to virtual memory.
	   */
	- TEXT _start0x00100020(SB), $0
	+ TEXT _startPADDR(SB), $0
	  	CLI					/* make sure interrupts are off */
	  
	  	/* set up the gdt so we have sane plan 9 style gdts. */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:109,118 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:112,132
	   *  that's needed as we start executing in physical addresses. 
	   */
	  TEXT tgdtptr(SB), $0
	- 
	  	WORD	$(3*8)
	  	LONG	$tgdt-KZERO(SB)
	  
	+ TEXT m0rgdtptr(SB), $0
	+ 	WORD	$(NGDT*8-1)
	+ 	LONG	$(CPU0GDT-KZERO)
	+ 
	+ TEXT m0gdtptr(SB), $0
	+ 	WORD	$(NGDT*8-1)
	+ 	LONG	$CPU0GDT
	+ 
	+ TEXT m0idtptr(SB), $0
	+ 	WORD $(256*8-1)
	+ 	LONG $IDTADDR
	+ 
	  TEXT mode32bit(SB), $0
	  	/* At this point, the GDT setup is done. */
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:126,132 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:140,146
	  
	  	MOVL	$PADDR(CPU0PDB), AX
	  	ADDL	$PDO(KZERO), AX			/* page directory offset for KZERO */
	- 	MOVL	$PADDR(CPU0PTE), (AX)		/* PTE's for 0x80000000 */
	+ 	MOVL	$PADDR(CPU0PTE), (AX)		/* PTE's for KZERO */
	  	MOVL	$(PTEWRITE|PTEVALID), BX	/* page permissions */
	  	ORL	BX, (AX)
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:212,217 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:226,459
	  	JMP	_idle
	  
	  /*
	+  * Save registers.
	+  */
	+ TEXT saveregs(SB), $0
	+ 	/* appease 8l */
	+ 	SUBL $32, SP
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	
	+ 	PUSHL	AX
	+ 	PUSHL	BX
	+ 	PUSHL	CX
	+ 	PUSHL	DX
	+ 	PUSHL	BP
	+ 	PUSHL	DI
	+ 	PUSHL	SI
	+ 	PUSHFL
	+ 
	+ 	XCHGL	32(SP), AX	/* swap return PC and saved flags */
	+ 	XCHGL	0(SP), AX
	+ 	XCHGL	32(SP), AX
	+ 	RET
	+ 
	+ TEXT restoreregs(SB), $0
	+ 	/* appease 8l */
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	ADDL	$32, SP
	+ 	
	+ 	XCHGL	32(SP), AX	/* swap return PC and saved flags */
	+ 	XCHGL	0(SP), AX
	+ 	XCHGL	32(SP), AX
	+ 
	+ 	POPFL
	+ 	POPL	SI
	+ 	POPL	DI
	+ 	POPL	BP
	+ 	POPL	DX
	+ 	POPL	CX
	+ 	POPL	BX
	+ 	POPL	AX
	+ 	RET
	+ 
	+ /*
	+  * Assumed to be in protected mode at time of call.
	+  * Switch to real mode, execute an interrupt, and
	+  * then switch back to protected mode.  
	+  *
	+  * Assumes:
	+  *
	+  *	- no device interrupts are going to come in
	+  *	- 0-16MB is identity mapped in page tables
	+  *	- realmode() has copied us down from 0x100000 to 0x8000
	+  *	- can use code segment 0x0800 in real mode
	+  *		to get at l.s code
	+  *	- l.s code is less than 1 page
	+  */
	+ #define RELOC	(RMCODE-KTZERO)
	+ 
	+ TEXT realmodeidtptr(SB), $0
	+ 	WORD	$(4*256-1)
	+ 	LONG	$0
	+ 
	+ TEXT realmode0(SB), $0
	+ 	CALL	saveregs(SB)
	+ 
	+ 	/* switch to low code address */
	+ 	LEAL	physcode-KZERO(SB), AX
	+ 	JMP *AX
	+ 
	+ TEXT physcode(SB), $0
	+ 
	+ 	/* switch to low stack */
	+ 	MOVL	SP, AX
	+ 	MOVL	$0x7C00, SP
	+ 	PUSHL	AX
	+ 
	+ 	/* change gdt to physical pointer */
	+ 	MOVL	m0rgdtptr-KZERO(SB), GDTR
	+ 
	+ 	/* load IDT with real-mode version*/
	+ 	MOVL	realmodeidtptr-KZERO(SB), IDTR
	+ 
	+ 	/* edit INT $0x00 instruction below */
	+ 	MOVL	$(RMUADDR-KZERO+48), AX	/* &rmu.trap */
	+ 	MOVL	(AX), AX
	+ 	MOVB	AX, realmodeintrinst+(-KZERO+1+RELOC)(SB)
	+ 
	+ 	/* disable paging */
	+ 	MOVL	CR0, AX
	+ 	ANDL	$0x7FFFFFFF, AX
	+ 	MOVL	AX, CR0
	+ 	/* JMP .+2 to clear prefetch queue*/
	+ 	BYTE $0xEB; BYTE $0x00
	+ 
	+ 	/* jump to 16-bit code segment */
	+ /*	JMPFAR	SELECTOR(KESEG16, SELGDT, 0):$again16bit(SB) /**/
	+ 	 BYTE	$0xEA
	+ 	 LONG	$again16bit-KZERO(SB)
	+ 	 WORD	$SELECTOR(KESEG16, SELGDT, 0)
	+ 
	+ TEXT again16bit(SB), $0
	+ 	/*
	+ 	 * Now in 16-bit compatibility mode.
	+ 	 * These are 32-bit instructions being interpreted
	+ 	 * as 16-bit instructions.  I'm being lazy and
	+ 	 * not using the macros because I know when
	+ 	 * the 16- and 32-bit instructions look the same
	+ 	 * or close enough.
	+ 	 */
	+ 
	+ 	/* disable protected mode and jump to real mode cs */
	+ 	OPSIZE; MOVL CR0, AX
	+ 	OPSIZE; XORL BX, BX
	+ 	OPSIZE; INCL BX
	+ 	OPSIZE; XORL BX, AX
	+ 	OPSIZE; MOVL AX, CR0
	+ 
	+ 	/* JMPFAR 0x0800:now16real */
	+ 	 BYTE $0xEA
	+ 	 WORD	$now16real-KZERO(SB)
	+ 	 WORD	$0x0800
	+ 
	+ TEXT now16real(SB), $0
	+ 	/* copy the registers for the bios call */
	+ 	LWI(0x0000, rAX)
	+ 	MOVW	AX,SS
	+ 	LWI(RMUADDR, rBP)
	+ 	
	+ 	/* offsets are in Ureg */
	+ 	LXW(44, xBP, rAX)
	+ 	MOVW	AX, DS
	+ 	LXW(40, xBP, rAX)
	+ 	MOVW	AX, ES
	+ 
	+ 	OPSIZE; LXW(0, xBP, rDI)
	+ 	OPSIZE; LXW(4, xBP, rSI)
	+ 	OPSIZE; LXW(16, xBP, rBX)
	+ 	OPSIZE; LXW(20, xBP, rDX)
	+ 	OPSIZE; LXW(24, xBP, rCX)
	+ 	OPSIZE; LXW(28, xBP, rAX)
	+ 
	+ 	CLC
	+ 
	+ TEXT realmodeintrinst(SB), $0
	+ 	INT $0x00
	+ 
	+ 	/* save the registers after the call */
	+ 
	+ 	LWI(0x7bfc, rSP)
	+ 	OPSIZE; PUSHFL
	+ 	OPSIZE; PUSHL AX
	+ 
	+ 	LWI(0, rAX)
	+ 	MOVW	AX,SS
	+ 	LWI(RMUADDR, rBP)
	+ 	
	+ 	OPSIZE; SXW(rDI, 0, xBP)
	+ 	OPSIZE; SXW(rSI, 4, xBP)
	+ 	OPSIZE; SXW(rBX, 16, xBP)
	+ 	OPSIZE; SXW(rDX, 20, xBP)
	+ 	OPSIZE; SXW(rCX, 24, xBP)
	+ 	OPSIZE; POPL AX
	+ 	OPSIZE; SXW(rAX, 28, xBP)
	+ 
	+ 	MOVW	DS, AX
	+ 	OPSIZE; SXW(rAX, 44, xBP)
	+ 	MOVW	ES, AX
	+ 	OPSIZE; SXW(rAX, 40, xBP)
	+ 
	+ 	OPSIZE; POPL AX
	+ 	OPSIZE; SXW(rAX, 64, xBP)	/* flags */
	+ 
	+ 	/* re-enter protected mode and jump to 32-bit code */
	+ 	OPSIZE; MOVL $1, AX
	+ 	OPSIZE; MOVL AX, CR0
	+ 	
	+ /*	JMPFAR	SELECTOR(KESEG, SELGDT, 0):$again32bit(SB) /**/
	+ 	 OPSIZE
	+ 	 BYTE $0xEA
	+ 	 LONG	$again32bit-KZERO(SB)
	+ 	 WORD	$SELECTOR(KESEG, SELGDT, 0)
	+ 
	+ TEXT again32bit(SB), $0
	+ 	MOVW	$SELECTOR(KDSEG, SELGDT, 0),AX
	+ 	MOVW	AX,DS
	+ 	MOVW	AX,SS
	+ 	MOVW	AX,ES
	+ 	MOVW	AX,FS
	+ 	MOVW	AX,GS
	+ 
	+ 	/* enable paging and jump to kzero-address code */
	+ 	MOVL	CR0, AX
	+ 	ORL	$0x80000000, AX
	+ 	MOVL	AX, CR0
	+ 	LEAL	again32kzero(SB), AX
	+ 	JMP*	AX
	+ 
	+ TEXT again32kzero(SB), $0
	+ 	/* breathe a sigh of relief - back in 32-bit protected mode */
	+ 
	+ 	/* switch to old stack */	
	+ 	PUSHL	AX	/* match popl below for 8l */
	+ 	MOVL	$0x7BFC, SP
	+ 	POPL	SP
	+ 
	+ 	/* restore idt */
	+ 	MOVL	m0idtptr(SB),IDTR
	+ 
	+ 	/* restore gdt */
	+ 	MOVL	m0gdtptr(SB), GDTR
	+ 
	+ 	CALL	restoreregs(SB)
	+ 	RET
	+ 
	+ /*
	+ /*
	   * Port I/O.
	   *	in[bsl]		input a byte|short|long
	   *	ins[bsl]	input a string of bytes|shorts|longs
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:347,352 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:589,600
	  	MOVL	AX, CR4
	  	RET
	  
	+ TEXT invlpg(SB), $0
	+ 	/* 486+ only */
	+ 	MOVL	va+0(FP), CX
	+ 	INVLPG
	+ 	RET
	+ 
	  TEXT _cycles(SB), $0				/* time stamp counter */
	  	RDTSC
	  	MOVL	vlong+0(FP), CX			/* &vlong */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/l.s:442,462 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/l.s:690,710
	   * FNxxx variations) so WAIT instructions must be explicitly placed in the
	   * code as necessary.
	   */
	- #define	FPOFF(l)							;\
	- 	MOVL	CR0, AX 					 	;\
	- 	ANDL	$0xC, AX			/* EM, TS */	 	;\
	- 	CMPL	AX, $0x8					 	;\
	- 	JEQ 	l						 	;\
	- 	WAIT							 	;\
	- l:								 	;\
	- 	MOVL	CR0, AX							;\
	- 	ANDL	$~0x4, AX			/* EM=0 */		;\
	- 	ORL	$0x28, AX			/* NE=1, TS=1 */	;\
	+ #define	FPOFF(l)						 ;\
	+ 	MOVL	CR0, AX 					 ;\
	+ 	ANDL	$0xC, AX			/* EM, TS */	 ;\
	+ 	CMPL	AX, $0x8					 ;\
	+ 	JEQ 	l						 ;\
	+ 	WAIT							 ;\
	+ l:								 ;\
	+ 	MOVL	CR0, AX						 ;\
	+ 	ANDL	$~0x4, AX			/* EM=0 */	 ;\
	+ 	ORL	$0x28, AX			/* NE=1, TS=1 */ ;\
	  	MOVL	AX, CR0
	  
	- #define	FPON								;\
	- 	MOVL	CR0, AX							;\
	- 	ANDL	$~0xC, AX			/* EM=0, TS=0 */	;\
	+ #define	FPON							 ;\
	+ 	MOVL	CR0, AX						 ;\
	+ 	ANDL	$~0xC, AX			/* EM=0, TS=0 */ ;\
	  	MOVL	AX, CR0
	  	
	  TEXT fpoff(SB), $0				/* disable */
 [rsc] --rw-rw-r-- M 451989 glenda sys 15224 Nov  6 10:20 sys/src/9/pc/main.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:29,34 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:29,35
	  char *confval[MAXCONF];
	  int nconf;
	  uchar *sp;	/* user stack of init proc */
	+ int delaylink;
	  
	  static void
	  options(void)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:69,74 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:70,76
	  	}
	  }
	  
	+ void mmuinit0(void);
	  void
	  main(void)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:81,86 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:83,91
	  
	  	print("\nPlan 9\n");
	  
	+ 	trapinit0();
	+ 	mmuinit0();
	+ 
	  	kbdinit();
	  	i8253init();
	  	cpuidentify();
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:101,107 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:106,116
	  		arch->clockenable();
	  	procinit0();
	  	initseg();
	- 	links();
	+ 	if(delaylink){
	+ 		bootlinks();
	+ 		pcimatch(0, 0, 0);
	+ 	}else
	+ 		links();
	  	conf.monitor = 1;
	  	chandevreset();
	  	pageinit();
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:194,202 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:203,211
	  void
	  userinit(void)
	  {
	+ 	void *v;
	  	Proc *p;
	  	Segment *s;
	- 	KMap *k;
	  	Page *pg;
	  
	  	p = newproc();
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:226,239 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:235,252
	  
	  	/*
	  	 * User Stack
	+ 	 *
	+ 	 * N.B. cannot call newpage() with clear=1, because pc kmap
	+ 	 * requires up != nil.  use tmpmap instead.
	  	 */
	  	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
	  	p->seg[SSEG] = s;
	- 	pg = newpage(1, 0, USTKTOP-BY2PG);
	+ 	pg = newpage(0, 0, USTKTOP-BY2PG);
	+ 	v = tmpmap(pg);
	+ 	memset(v, 0, BY2PG);
	  	segpage(s, pg);
	- 	k = kmap(pg);
	- 	bootargs(VA(k));
	- 	kunmap(k);
	+ 	bootargs(v);
	+ 	tmpunmap(v);
	  
	  	/*
	  	 * Text
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:241,252 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:254,266
	  	s = newseg(SG_TEXT, UTZERO, 1);
	  	s->flushme++;
	  	p->seg[TSEG] = s;
	- 	pg = newpage(1, 0, UTZERO);
	+ 	pg = newpage(0, 0, UTZERO);
	  	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
	  	segpage(s, pg);
	- 	k = kmap(s->map[0]->pages[0]);
	- 	memmove((ulong*)VA(k), initcode, sizeof initcode);
	- 	kunmap(k);
	+ 	v = tmpmap(pg);
	+ 	memset(v, 0, BY2PG);
	+ 	memmove(v, initcode, sizeof initcode);
	+ 	tmpunmap(v);
	  
	  	ready(p);
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:263,269 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:277,283
	  }
	  
	  void
	- bootargs(ulong base)
	+ bootargs(void *base)
	  {
	   	int i, ac;
	  	uchar *av[32];
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:295,303 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:309,317
	  	sp -= (ac+1)*sizeof(sp);
	  	lsp = (uchar**)sp;
	  	for(i = 0; i < ac; i++)
	- 		*lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
	+ 		*lsp++ = av[i] + ((USTKTOP - BY2PG) - (ulong)base);
	  	*lsp = 0;
	- 	sp += (USTKTOP - BY2PG) - base - sizeof(ulong);
	+ 	sp += (USTKTOP - BY2PG) - (ulong)base - sizeof(ulong);
	  }
	  
	  char*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:344,350 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:358,364
	  confinit(void)
	  {
	  	char *p;
	- 	int userpcnt;
	+ 	int i, userpcnt;
	  	ulong kpages;
	  
	  	if(p = getconf("*kernelpercent"))
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:352,358 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:366,374
	  	else
	  		userpcnt = 0;
	  
	- 	conf.npage = conf.npage0 + conf.npage1;
	+ 	conf.npage = 0;
	+ 	for(i=0; i<nelem(conf.mem); i++)
	+ 		conf.npage += conf.mem[i].npage;
	  
	  	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
	  	if(cpuserver)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:397,402 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:413,426
	  		if(conf.npage*BY2PG < 16*MB)
	  			imagmem->minarena = 4*1024*1024;
	  	}
	+ 
	+ 	/*
	+ 	 * can't go past the end of virtual memory
	+ 	 * (ulong)-KZERO is 2^32 - KZERO
	+ 	 */
	+ 	if(kpages > ((ulong)-KZERO)/BY2PG)
	+ 		kpages = ((ulong)-KZERO)/BY2PG;
	+ 
	  	conf.upages = conf.npage - kpages;
	  	conf.ialloc = (kpages/2)*BY2PG;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:493,499 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:517,523
	   *  math coprocessor emulation fault
	   */
	  static void
	- mathemu(Ureg*, void*)
	+ mathemu(Ureg *ureg, void*)
	  {
	  	if(up->fpstate & FPillegal){
	  		/* someone did floating point in a note handler */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/main.c:521,527 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/main.c:545,552
	  		up->fpstate = FPactive;
	  		break;
	  	case FPactive:
	- 		panic("math emu");
	+ 		panic("math emu pid %ld %s pc 0x%lux", 
	+ 			up->pid, up->text, ureg->pc);
	  		break;
	  	}
	  }
 [rsc] --rw-rw-r-- M 451989 glenda sys 5209 Nov  6 10:20 sys/src/9/pc/mem.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mem.h:11,16 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mem.h:11,17
	  #define	BY2V		8			/* bytes per double word */
	  #define	BY2PG		4096			/* bytes per page */
	  #define	WD2PG		(BY2PG/BY2WD)		/* words per page */
	+ #define	BY2XPG		(4096*1024)	/* bytes per big page */
	  #define	PGSHIFT		12			/* log(BY2PG) */
	  #define	ROUND(s, sz)	(((s)+((sz)-1))&~((sz)-1))
	  #define	PGROUND(s)	ROUND(s, BY2PG)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mem.h:27,66 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mem.h:28,75
	  #define	TK2SEC(t)	((t)/HZ)		/* ticks to seconds */
	  
	  /*
	-  * Fundamental addresses
	-  */
	- #define	IDTADDR		0x80000800		/* idt */
	- #define	REBOOTADDR	0x00001000		/* reboot code - physical address */
	- #define	APBOOTSTRAP	0x80001000		/* AP bootstrap code */
	- #define	CONFADDR	0x80001200		/* info passed from boot loader */
	- #define	CPU0PDB		0x80002000		/* bootstrap processor PDB */
	- #define	CPU0PTE		0x80003000		/* bootstrap processor PTE's for 0-4MB */
	- #define	CPU0GDT		0x80004000		/* bootstrap processor GDT */
	- #define	MACHADDR	0x80005000		/* as seen by current processor */
	- #define	CPU0MACH	0x80006000		/* Mach for bootstrap processor */
	- #define	MACHSIZE	BY2PG
	- /*
	-  * N.B.  ramscan knows that CPU0MACH+BY2PG is the end of reserved data
	-  * N.B.  _start0x00100020 knows that CPU0PDB is the first reserved page
	-  * and that there are 5 of them.
	-  */
	- 
	- /*
	   *  Address spaces
	-  *
	-  *  User is at 0-2GB
	-  *  Kernel is at 2GB-4GB
	   */
	+ #define	KZERO		0xF0000000		/* base of kernel address space */
	+ #define	KTZERO		(KZERO+0x100000)		/* first address in kernel text - 9load sits below */
	+ #define	VPT			(KZERO-VPTSIZE)
	+ #define	VPTSIZE		BY2XPG
	+ #define	NVPT		(VPTSIZE/BY2WD)
	+ #define	KMAP		(VPT-KMAPSIZE)
	+ #define	KMAPSIZE	BY2XPG
	+ #define	VMAP		(KMAP-VMAPSIZE)
	+ #define	VMAPSIZE	(0x10000000-VPTSIZE-KMAPSIZE)
	  #define	UZERO		0			/* base of user address space */
	  #define	UTZERO		(UZERO+BY2PG)		/* first address in user text */
	- #define	KZERO		0x80000000		/* base of kernel address space */
	- #define	KTZERO		0x80100000		/* first address in kernel text */
	- #define	USTKTOP		(KZERO-BY2PG)		/* byte just beyond user stack */
	+ #define	USTKTOP		(VMAP-BY2PG)		/* byte just beyond user stack */
	  #define	USTKSIZE	(16*1024*1024)		/* size of user stack */
	  #define	TSTKTOP		(USTKTOP-USTKSIZE)	/* end of new stack in sysexec */
	  #define	TSTKSIZ 	100
	  
	  /*
	+  * Fundamental addresses - bottom 64kB saved for return to real mode
	+  */
	+ #define	CONFADDR	(KZERO+0x1200)		/* info passed from boot loader */
	+ #define	TMPADDR		(KZERO+0x2000)		/* used for temporary mappings */
	+ #define	APBOOTSTRAP	(KZERO+0x3000)		/* AP bootstrap code */
	+ #define	RMUADDR		(KZERO+0x7C00)		/* real mode Ureg */
	+ #define	RMCODE		(KZERO+0x8000)		/* copy of first page of KTEXT */
	+ #define	RMBUF		(KZERO+0x9000)		/* buffer for user space - known to vga */
	+ #define	IDTADDR		(KZERO+0x10800)		/* idt */
	+ #define	REBOOTADDR	(KZERO+0x11000)		/* reboot code - physical address */
	+ #define	CPU0PDB		(KZERO+0x12000)		/* bootstrap processor PDB */
	+ #define	CPU0PTE		(KZERO+0x13000)		/* bootstrap processor PTE's for 0-4MB */
	+ #define	CPU0GDT		(KZERO+0x14000)		/* bootstrap processor GDT */
	+ #define	MACHADDR	(KZERO+0x15000)		/* as seen by current processor */
	+ #define	CPU0MACH	(KZERO+0x16000)		/* Mach for bootstrap processor */
	+ #define	MACHSIZE	BY2PG
	+ /*
	+  * N.B.  ramscan knows that CPU0MACH+BY2PG is the end of reserved data
	+  * N.B.  _startPADDR knows that CPU0PDB is the first reserved page
	+  * and that there are 5 of them.
	+  */
	+ 
	+ /*
	   *  known x86 segments (in GDT) and their selectors
	   */
	  #define	NULLSEG	0	/* null segment */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mem.h:72,77 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mem.h:81,87
	  #define	APMCSEG		6	/* APM code segment */
	  #define	APMCSEG16	7	/* APM 16-bit code segment */
	  #define	APMDSEG		8	/* APM data segment */
	+ #define	KESEG16		9	/* kernel executable 16-bit */
	  #define	NGDT		10	/* number of GDT entries required */
	  /* #define	APM40SEG	8	/* APM segment 0x40 */
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mem.h:141,143 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mem.h:151,154
	  #define	PTX(va)		((((ulong)(va))>>12) & 0x03FF)
	  
	  #define	getpgcolor(a)	0
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 18222 Nov  6 10:20 sys/src/9/pc/memory.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:8,13 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:8,14
	  #include "dat.h"
	  #include "fns.h"
	  #include "io.h"
	+ #include "ureg.h"
	  
	  #define MEMDEBUG	0
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:15,26 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:16,28
	  	MemUPA		= 0,		/* unbacked physical address */
	  	MemRAM		= 1,		/* physical memory */
	  	MemUMB		= 2,		/* upper memory block (<16MB) */
	- 	NMemType	= 3,
	+ 	MemReserved	= 3,
	+ 	NMemType	= 4,
	  
	  	KB		= 1024,
	  
	  	MemMinMB	= 4,		/* minimum physical memory (<=4MB) */
	- 	MemMaxMB	= 768,		/* maximum physical memory to check */
	+ 	MemMaxMB	= 3*1024+768,		/* maximum physical memory to check */
	  
	  	NMemBase	= 10,
	  };
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:27,33 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:29,35
	  
	  typedef struct Map Map;
	  struct Map {
	- 	int	size;
	+ 	ulong	size;
	  	ulong	addr;
	  };
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:40,45 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:42,50
	  	Lock;
	  };
	  
	+ /* 
	+  * Memory allocation tracking.
	+  */
	  static Map mapupa[16];
	  static RMap rmapupa = {
	  	"unallocated unbacked physical memory",
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:82,88 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:87,93
	  
	  	print("%s\n", rmap->name);	
	  	for(mp = rmap->map; mp->size; mp++)
	- 		print("\t%8.8luX %8.8uX %8.8luX\n", mp->addr, mp->size, mp->addr+mp->size);
	+ 		print("\t%8.8luX %8.8luX (%lud)\n", mp->addr, mp->addr+mp->size, mp->size);
	  }
	  
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:91,99 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:96,101
	  {
	  	ulong maxpa, maxpa1, maxpa2;
	  
	- 	if(MEMDEBUG == 0)
	- 		return;
	- 
	  	maxpa = (nvramread(0x18)<<8)|nvramread(0x17);
	  	maxpa1 = (nvramread(0x31)<<8)|nvramread(0x30);
	  	maxpa2 = (nvramread(0x16)<<8)|nvramread(0x15);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:209,214 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:211,231
	  	return 0;
	  }
	  
	+ /*
	+  * Allocate from the ram map directly to make page tables.
	+  * Called by mmuwalk during e820scan.
	+  */
	+ void*
	+ rampage(void)
	+ {
	+ 	ulong m;
	+ 	
	+ 	m = mapalloc(&rmapram, 0, BY2PG, BY2PG);
	+ 	if(m == 0)
	+ 		return nil;
	+ 	return KADDR(m);
	+ }
	+ 
	  static void
	  umbscan(void)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:269,287 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:286,297
	  }
	  
	  static void
	- ramscan(ulong maxmem)
	+ lowraminit(void)
	  {
	- 	ulong *k0, kzero, map, maxpa, pa, *pte, *table, *va, x, n;
	- 	int nvalid[NMemType];
	+ 	ulong n, pa, x;
	  	uchar *bda;
	  
	  	/*
	- 	 * The bootstrap code has has created a prototype page
	- 	 * table which maps the first MemMinMB of physical memory to KZERO.
	- 	 * The page directory is at m->pdb and the first page of
	- 	 * free memory is after the per-processor MMU information.
	- 	 */
	- 	/*
	  	 * Initialise the memory bank information for conventional memory
	  	 * (i.e. less than 640KB). The base is the first location after the
	  	 * bootstrap processor MMU information and the limit is obtained from
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:297,304 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:307,329
	  	pa = MemMinMB*MB;
	  	mapfree(&rmapram, x, pa-x);
	  	memset(KADDR(x), 0, pa-x);		/* keep us honest */
	+ }
	  
	+ static void
	+ ramscan(ulong maxmem)
	+ {
	+ 	ulong *k0, kzero, map, maxkpa, maxpa, pa, *pte, *table, *va, vbase, x;
	+ 	int nvalid[NMemType];
	+ 
	  	/*
	+ 	 * The bootstrap code has has created a prototype page
	+ 	 * table which maps the first MemMinMB of physical memory to KZERO.
	+ 	 * The page directory is at m->pdb and the first page of
	+ 	 * free memory is after the per-processor MMU information.
	+ 	 */
	+ 	pa = MemMinMB*MB;
	+ 
	+ 	/*
	  	 * Check if the extended memory size can be obtained from the CMOS.
	  	 * If it's 0 then it's either not known or >= 64MB. Always check
	  	 * at least 24MB in case there's a memory gap (up to 8MB) below 16MB;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:314,323 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:339,347
	  			maxpa = MB+x*KB;
	  		if(maxpa < 24*MB)
	  			maxpa = 24*MB;
	- 		maxmem = MemMaxMB*MB;
	- 	}
	- 	else
	+ 	}else
	  		maxpa = maxmem;
	+ 	maxkpa = (u32int)-KZERO;	/* 2^32 - KZERO */
	  
	  	/*
	  	 * March up memory from MemMinMB to maxpa 1MB at a time,
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:330,344 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:354,377
	  	map = 0;
	  	x = 0x12345678;
	  	memset(nvalid, 0, sizeof(nvalid));
	+ 	
	+ 	/*
	+ 	 * Can't map memory to KADDR(pa) when we're walking because
	+ 	 * can only use KADDR for relatively low addresses.  Instead,
	+ 	 * map each 4MB we scan to the virtual address range 4MB-8MB
	+ 	 * while we are scanning.
	+ 	 */
	+ 	vbase = 4*MB;
	  	while(pa < maxpa){
	  		/*
	  		 * Map the page. Use mapalloc(&rmapram, ...) to make
	  		 * the page table if necessary, it will be returned to the
	- 		 * pool later if it isn't needed.
	+ 		 * pool later if it isn't needed.  Map in a fixed range (the second 4M)
	+ 		 * because high physical addresses cannot be passed to KADDR.
	  		 */
	- 		va = KADDR(pa);
	+ 		va = (void*)(vbase + pa%(4*MB));
	  		table = &m->pdb[PDX(va)];
	- 		if(*table == 0){
	+ 		if(pa%(4*MB) == 0){
	  			if(map == 0 && (map = mapalloc(&rmapram, 0, BY2PG, BY2PG)) == 0)
	  				break;
	  			memset(KADDR(map), 0, BY2PG);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:350,359 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:383,391
	  
	  		*pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
	  		mmuflushtlb(PADDR(m->pdb));
	- 
	  		/*
	  		 * Write a pattern to the page and write a different
	- 		 * pattern to a possible mirror at KZER0. If the data
	+ 		 * pattern to a possible mirror at KZERO. If the data
	  		 * reads back correctly the chunk is some type of RAM (possibly
	  		 * a linearly-mapped VGA framebuffer, for instance...) and
	  		 * can be cleared and added to the memory pool. If not, the
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:389,395 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:421,426
	  			*pte = 0;
	  			pa += MB;
	  		}
	- 
	  		/*
	  		 * Done with this 4MB chunk, review the options:
	  		 * 1) not physical memory and >=16MB - invalidate the PDB entry;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:399,406 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:430,446
	  		 * 4) mixed or no 4MB page extension - commit the already
	  		 *    initialised space for the page table.
	  		 */
	- 		if((pa % (4*MB)) == 0){
	- 			table = &m->pdb[PDX(va)];
	+ 		if(pa%(4*MB) == 0 && pa >= 32*MB && nvalid[MemUPA] == (4*MB)/BY2PG){
	+ 			/*
	+ 			 * If we encounter a 4MB chunk of missing memory
	+ 			 * at a sufficiently high offset, call it the end of
	+ 			 * memory.  Otherwise we run the risk of thinking
	+ 			 * that video memory is real RAM.
	+ 			 */
	+ 			break;
	+ 		}
	+ 		if(pa <= maxkpa && pa%(4*MB) == 0){
	+ 			table = &m->pdb[PDX(KADDR(pa - 4*MB))];
	  			if(nvalid[MemUPA] == (4*MB)/BY2PG)
	  				*table = 0;
	  			else if(nvalid[MemRAM] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:407,444 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:447,713
	  				*table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEVALID;
	  			else if(nvalid[MemUMB] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
	  				*table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
	- 			else
	+ 			else{
	+ 				*table = map|PTEWRITE|PTEVALID;
	  				map = 0;
	+ 			}
	  		}
	- 
	  		mmuflushtlb(PADDR(m->pdb));
	  		x += 0x3141526;
	  	}
	- 
	  	/*
	  	 * If we didn't reach the end of the 4MB chunk, that part won't
	  	 * be mapped.  Commit the already initialised space for the page table.
	  	 */
	- 	if(pa % (4*MB))
	+ 	if(pa % (4*MB) && pa <= maxkpa){
	+ 		m->pdb[PDX(KADDR(pa))] = map|PTEWRITE|PTEVALID;
	  		map = 0;
	- 
	+ 	}
	  	if(map)
	  		mapfree(&rmapram, map, BY2PG);
	- 	if(pa < maxmem)
	- 		mapfree(&rmapupa, pa, maxmem-pa);
	- 	if(maxmem < 0xFFE00000)
	- 		mapfree(&rmapupa, maxmem, 0x00000000-maxmem);
	- 	if(MEMDEBUG)
	- 		print("maxmem %luX %luX\n", maxmem, 0x00000000-maxmem);
	+ 
	+ 	m->pdb[PDX(vbase)] = 0;
	+ 	mmuflushtlb(PADDR(m->pdb));
	+ 
	+ 	mapfree(&rmapupa, pa, (u32int)-pa);
	  	*k0 = kzero;
	  }
	  
	+ /*
	+  * BIOS Int 0x15 E820 memory map.
	+  */
	+ enum
	+ {
	+ 	SMAP = ('S'<<24)|('M'<<16)|('A'<<8)|'P',
	+ 	Ememory = 1,
	+ 	Ereserved = 2,
	+ 	Carry = 1,
	+ };
	+ 
	+ typedef struct Emap Emap;
	+ struct Emap
	+ {
	+ 	uvlong base;
	+ 	uvlong len;
	+ 	ulong type;
	+ };
	+ static Emap emap[16];
	+ int nemap;
	+ 
	+ static char *etypes[] =
	+ {
	+ 	"type=0",
	+ 	"memory",
	+ 	"reserved",
	+ 	"acpi reclaim",
	+ 	"acpi nvs",
	+ };
	+ 
	+ static int
	+ emapcmp(const void *va, const void *vb)
	+ {
	+ 	Emap *a, *b;
	+ 	
	+ 	a = (Emap*)va;
	+ 	b = (Emap*)vb;
	+ 	if(a->base < b->base)
	+ 		return -1;
	+ 	if(a->base > b->base)
	+ 		return 1;
	+ 	if(a->len < b->len)
	+ 		return -1;
	+ 	if(a->len > b->len)
	+ 		return 1;
	+ 	return a->type - b->type;
	+ }
	+ 
	+ static void
	+ map(ulong base, ulong len, int type)
	+ {
	+ 	ulong e, n;
	+ 	ulong *table, flags, maxkpa;
	+ 	
	+ 	/*
	+ 	 * Split any call crossing 4*MB to make below simpler.
	+ 	 */
	+ 	if(base < 4*MB && len > 4*MB-base){
	+ 		n = 4*MB - base;
	+ 		map(base, n, type);
	+ 		map(4*MB, len-n, type);
	+ 	}
	+ 	
	+ 	/*
	+ 	 * Let lowraminit and umbscan hash out the low 4MB.
	+ 	 */
	+ 	if(base < 4*MB)
	+ 		return;
	+ 
	+ 	/*
	+ 	 * Any non-memory below 16*MB is used as upper mem blocks.
	+ 	 */
	+ 	if(type == MemUPA && base < 16*MB && base+len > 16*MB){
	+ 		map(base, 16*MB-base, MemUMB);
	+ 		map(16*MB, len-(16*MB-base), MemUPA);
	+ 		return;
	+ 	}
	+ 	
	+ 	/*
	+ 	 * Memory below CPU0MACH is reserved for the kernel
	+ 	 * and already mapped.
	+ 	 */
	+ 	if(base < PADDR(CPU0MACH)+BY2PG){
	+ 		n = PADDR(CPU0MACH)+BY2PG - base;
	+ 		if(len <= n)
	+ 			return;
	+ 		map(PADDR(CPU0MACH), len-n, type);
	+ 		return;
	+ 	}
	+ 	
	+ 	/*
	+ 	 * Memory between KTZERO and end is the kernel itself
	+ 	 * and is already mapped.
	+ 	 */
	+ 	if(base < PADDR(KTZERO) && base+len > PADDR(KTZERO)){
	+ 		map(base, PADDR(KTZERO)-base, type);
	+ 		return;
	+ 	}
	+ 	if(PADDR(KTZERO) < base && base < PADDR(PGROUND((ulong)end))){
	+ 		n = PADDR(PGROUND((ulong)end));
	+ 		if(len <= n)
	+ 			return;
	+ 		map(PADDR(PGROUND((ulong)end)), len-n, type);
	+ 		return;
	+ 	}
	+ 	
	+ 	/*
	+ 	 * Now we have a simple case.
	+ 	 */
	+ 	// print("map %.8lux %.8lux %d\n", base, base+len, type);
	+ 	switch(type){
	+ 	case MemRAM:
	+ 		mapfree(&rmapram, base, len);
	+ 		flags = PTEWRITE;
	+ 		break;
	+ 	case MemUMB:
	+ 		mapfree(&rmapumb, base, len);
	+ 		flags = PTEWRITE|PTEUNCACHED;
	+ 		break;
	+ 	case MemUPA:
	+ 		mapfree(&rmapupa, base, len);
	+ 		/* don't need to map this but will anyway */
	+ 		flags = PTEWRITE|PTEUNCACHED;
	+ 		break;
	+ 	default:
	+ 	case MemReserved:
	+ 		/* don't put in any pools but still map it. */
	+ 		flags = PTEWRITE|PTEUNCACHED;
	+ 		break;
	+ 	}
	+ 	
	+ 	/*
	+ 	 * bottom 4MB is already mapped - just twiddle flags.
	+ 	 * (not currently used - see above)
	+ 	 */
	+ 	if(base < 4*MB){
	+ 		table = KADDR(PPN(m->pdb[PDX(base)]));
	+ 		e = base+len;
	+ 		base = PPN(base);
	+ 		for(; base<e; base+=BY2PG)
	+ 			table[PTX(base)] |= flags;
	+ 		return;
	+ 	}
	+ 	
	+ 	/*
	+ 	 * Only map from KZERO to 2^32.
	+ 	 */
	+ 	maxkpa = -KZERO;
	+ 	if(base >= maxkpa)
	+ 		return;
	+ 	if(len > maxkpa-base)
	+ 		len = maxkpa - base;
	+ 	pdbmap(m->pdb, base|flags, base+KZERO, len);
	+ }
	+ 
	+ static int
	+ e820scan(void)
	+ {
	+ 	int i;
	+ 	Ureg u;
	+ 	ulong cont, base, last, len;
	+ 	Emap *e;
	+ 
	+ 	if(getconf("*norealmode") || getconf("*noe820scan"))
	+ 		return -1;
	+ 
	+ 	cont = 0;
	+ 	for(i=0; i<nelem(emap); i++){
	+ 		memset(&u, 0, sizeof u);
	+ 		u.ax = 0xE820;
	+ 		u.bx = cont;
	+ 		u.cx = 20;
	+ 		u.dx = SMAP;
	+ 		u.es = (PADDR(RMBUF)>>4)&0xF000;
	+ 		u.di = PADDR(RMBUF)&0xFFFF;
	+ 		u.trap = 0x15;
	+ 		realmode(&u);
	+ 		cont = u.bx;
	+ 		if((u.flags&Carry) || u.ax != SMAP || u.cx != 20)
	+ 			break;
	+ 		e = &emap[nemap++];
	+ 		*e = *(Emap*)RMBUF;
	+ 		if(u.bx == 0)
	+ 			break;
	+ 	}
	+ 	if(nemap == 0)
	+ 		return -1;
	+ 	
	+ 	qsort(emap, nemap, sizeof emap[0], emapcmp);
	+ 	
	+ 	for(i=0; i<nemap; i++){
	+ 		e = &emap[i];
	+ 		print("E820: %.8llux %.8llux ", e->base, e->base+e->len);
	+ 		if(e->type < nelem(etypes))
	+ 			print("%s\n", etypes[e->type]);
	+ 		else
	+ 			print("type=%lud\n", e->type);
	+ 	}
	+ 
	+ 	last = 0;
	+ 	for(i=0; i<nemap; i++){	
	+ 		e = &emap[i];
	+ 		/*
	+ 		 * pull out the info but only about the low 32 bits...
	+ 		 */
	+ 		if(e->base >= (1LL<<32))
	+ 			break;
	+ 		base = e->base;
	+ 		if(base+e->len > (1LL<<32))
	+ 			len = -base;
	+ 		else
	+ 			len = e->len;
	+ 		/*
	+ 		 * If the map skips addresses, mark them available.
	+ 		 */
	+ 		if(last < e->base)
	+ 			map(last, e->base-last, MemUPA);
	+ 		last = base+len;
	+ 		if(e->type == Ememory)
	+ 			map(base, len, MemRAM);
	+ 		else
	+ 			map(base, len, MemReserved);
	+ 	}
	+ 	
	+ 	return 0;
	+ }
	+ 
	  void
	  meminit(void)
	  {
	- 	Map *mp, *xmp;
	+ 	int i;
	+ 	Map *mp;
	+ 	Confmem *cm;
	  	ulong pa, *pte;
	- 	ulong maxmem;
	+ 	ulong maxmem, lost;
	  	char *p;
	  
	  	if(p = getconf("*maxmem"))
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:463,493 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:732,764
	  	mmuflushtlb(PADDR(m->pdb));
	  
	  	umbscan();
	- 	ramscan(maxmem);
	+ 	lowraminit();
	+ 	if(e820scan() < 0)
	+ 		ramscan(maxmem);
	  
	  	/*
	- 	 * Set the conf entries describing two banks of allocatable memory.
	- 	 * Grab the first and largest entries in rmapram as left by ramscan().
	- 	 *
	- 	 * It would be nice to have more than 2 memory banks describable in conf.
	+ 	 * Set the conf entries describing banks of allocatable memory.
	  	 */
	- 	mp = rmapram.map;
	- 	conf.base0 = mp->addr;
	- 	conf.npage0 = mp->size/BY2PG;
	- 	mp++;
	- 	for(xmp = 0; mp->size; mp++){
	- 		if(xmp == 0 || mp->size > xmp->size)
	- 			xmp = mp;
	+ 	for(i=0; i<nelem(mapram) && i<nelem(conf.mem); i++){
	+ 		mp = &rmapram.map[i];
	+ 		cm = &conf.mem[i];
	+ 		cm->base = mp->addr;
	+ 		cm->npage = mp->size/BY2PG;
	  	}
	+ 	
	+ 	lost = 0;
	+ 	for(; i<nelem(mapram); i++)
	+ 		lost += rmapram.map[i].size;
	+ 	if(lost)
	+ 		print("meminit - lost %lud bytes\n", lost);
	  
	- 	if(xmp){		
	- 		conf.base1 = xmp->addr;
	- 		conf.npage1 = xmp->size/BY2PG;
	- 	}
	  	if(MEMDEBUG)
	  		memdebug();
	  }
	  
	+ /*
	+  * Allocate memory from the upper memory blocks.
	+  */
	  ulong
	  umbmalloc(ulong addr, int size, int align)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:536,576 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:807,828
	  	mapfree(&rmapumbrw, PADDR(addr), size);
	  }
	  
	+ /*
	+  * Give out otherwise-unused physical address space
	+  * for use in configuring devices.  Note that unlike upamalloc
	+  * before it, upaalloc does not map the physical address
	+  * into virtual memory.  Call vmap to do that.
	+  */
	  ulong
	- upamalloc(ulong pa, int size, int align)
	+ upaalloc(int size, int align)
	  {
	- 	ulong a, ae;
	+ 	ulong a;
	  
	- 	if(a = mapalloc(&xrmapupa, pa, size, align))
	- 		return a;
	- 
	- 	if((a = mapalloc(&rmapupa, pa, size, align)) == 0){
	- 		memdebug();
	- 		return 0;
	+ 	a = mapalloc(&rmapupa, 0, size, align);
	+ 	if(a == 0){
	+ 		print("out of physical address space allocating %d\n", size);
	+ 		mapprint(&rmapupa);
	  	}
	- 
	- 	/*
	- 	 * Upamalloc is a request to map a range of physical addresses.
	- 	 * Therefore, if pa is 0 mapalloc will choose the base address.
	- 	 * Note, however, mmukmap is always asked to give a 1-to-1 mapping
	- 	 * of va to pa.
	- 	ae = mmukmap(a, a, size);
	- 	 * ...but for the moment go back to the old scheme for VLB cards.
	- 	 */
	- 	ae = mmukmap(a, 0, size);
	- 
	- 	/*
	- 	 * Should check here that it was all delivered
	- 	 * and put it back and barf if not.
	- 	 */
	- 	USED(ae);
	- 
	- 	/*
	- 	 * Be very careful this returns a PHYSICAL address
	- 	 * mapped 1-to-1 with the virtual address.
	- 	 * If a < KZERO it's probably not a good idea to
	- 	 * try KADDR(a)...
	- 	 */
	  	return a;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/memory.c:577,582 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/memory.c:829,858
	  void
	  upafree(ulong pa, int size)
	  {
	- 	mapfree(&xrmapupa, pa, size);
	+ 	mapfree(&rmapupa, pa, size);
	+ }
	+ 
	+ void
	+ upareserve(ulong pa, int size)
	+ {
	+ 	ulong a;
	+ 	
	+ 	a = mapalloc(&rmapupa, pa, size, 0);
	+ 	if(a != pa){
	+ 		/*
	+ 		 * This can happen when we're using the E820
	+ 		 * map, which might have already reserved some
	+ 		 * of the regions claimed by the pci devices.
	+ 		 */
	+ 	//	print("upareserve: cannot reserve pa=%#.8lux size=%d\n", pa, size);
	+ 		if(a != 0)
	+ 			mapfree(&rmapupa, a, size);
	+ 	}
	+ }
	+ 
	+ void
	+ memorysummary(void)
	+ {
	+ 	memdebug();
	  }
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 19739 Nov  6 20:17 sys/src/9/pc/mmu.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:1,3 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:1,37
	+ /*
	+  * Memory mappings.  Life was easier when 2G of memory was enough.
	+  *
	+  * The kernel memory starts at KZERO, with the text loaded at KZERO+1M
	+  * (9load sits under 1M during the load).  The memory from KZERO to the
	+  * top of memory is mapped 1-1 with physical memory, starting at physical
	+  * address 0.  All kernel memory and data structures (i.e., the entries stored
	+  * into conf.mem) must sit in this physical range: if KZERO is at 0xF0000000,
	+  * then the kernel can only have 256MB of memory for itself.
	+  * 
	+  * The 256M below KZERO comprises three parts.  The lowest 4M is the
	+  * virtual page table, a virtual address representation of the current 
	+  * page table tree.  The second 4M is used for temporary per-process
	+  * mappings managed by kmap and kunmap.  The remaining 248M is used
	+  * for global (shared by all procs and all processors) device memory
	+  * mappings and managed by vmap and vunmap.  The total amount (256M)
	+  * could probably be reduced somewhat if desired.  The largest device
	+  * mapping is that of the video card, and even though modern video cards
	+  * have embarrassing amounts of memory, the video drivers only use one
	+  * frame buffer worth (at most 16M).  Each is described in more detail below.
	+  *
	+  * The VPT is a 4M frame constructed by inserting the pdb into itself.
	+  * This short-circuits one level of the page tables, with the result that 
	+  * the contents of second-level page tables can be accessed at VPT.  
	+  * We use the VPT to edit the page tables (see mmu) after inserting them
	+  * into the page directory.  It is a convenient mechanism for mapping what
	+  * might be otherwise-inaccessible pages.  The idea was borrowed from
	+  * the Exokernel.
	+  *
	+  * The VPT doesn't solve all our problems, because we still need to 
	+  * prepare page directories before we can install them.  For that, we
	+  * use tmpmap/tmpunmap, which map a single page at TMPADDR.
	+  */
	+ 
	  #include	"u.h"
	  #include	"../port/lib.h"
	  #include	"mem.h"
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:5,12 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:39,50
	  #include	"fns.h"
	  #include	"io.h"
	  
	+ /*
	+  * Simple segment descriptors with no translation.
	+  */
	  #define	DATASEGM(p) 	{ 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
	  #define	EXECSEGM(p) 	{ 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
	+ #define	EXEC16SEGM(p) 	{ 0xFFFF, SEGG|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
	  #define	TSSSEGM(b,p)	{ ((b)<<16)|sizeof(Tss),\
	  			  ((b)&0xFF000000)|(((b)>>16)&0xFF)|SEGTSS|SEGPL(p)|SEGP }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:18,80 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:56,76
	  [UDSEG]		DATASEGM(3),		/* user data/stack */
	  [UESEG]		EXECSEGM(3),		/* user code */
	  [TSSSEG]	TSSSEGM(0,0),		/* tss segment */
	+ [KESEG16]		EXEC16SEGM(0),	/* kernel code 16-bit */
	  };
	  
	- static void
	- taskswitch(ulong pdb, ulong stack)
	- {
	- 	Tss *tss;
	+ static int didmmuinit;
	+ static void taskswitch(ulong, ulong);
	+ static void memglobal(void);
	  
	- 	tss = m->tss;
	- 	tss->ss0 = KDSEL;
	- 	tss->esp0 = stack;
	- 	tss->ss1 = KDSEL;
	- 	tss->esp1 = stack;
	- 	tss->ss2 = KDSEL;
	- 	tss->esp2 = stack;
	- 	tss->cr3 = pdb;
	- 	putcr3(pdb);
	- }
	+ #define	vpt ((ulong*)VPT)
	+ #define	VPTX(va)		(((ulong)(va))>>12)
	+ #define	vpd (vpt+VPTX(VPT))
	  
	- /* 
	-  * On processors that support it, we set the PTEGLOBAL bit in
	-  * page table and page directory entries that map kernel memory.
	-  * Doing this tells the processor not to bother flushing them
	-  * from the TLB when doing the TLB flush associated with a 
	-  * context switch (write to CR3).  Since kernel memory mappings
	-  * are never removed, this is safe.  (If we ever remove kernel memory
	-  * mappings, we can do a full flush by turning off the PGE bit in CR4,
	-  * writing to CR3, and then turning the PGE bit back on.) 
	-  *
	-  * See also mmukmap below.
	-  * 
	-  * Processor support for the PTEGLOBAL bit is enabled in devarch.c.
	-  */
	- static void
	- memglobal(void)
	+ void
	+ mmuinit0(void)
	  {
	- 	int i, j;
	- 	ulong *pde, *pte;
	- 
	- 	/* only need to do this once, on bootstrap processor */
	- 	if(m->machno != 0)
	- 		return;
	- 
	- 	if(!m->havepge)
	- 		return;
	- 
	- 	pde = m->pdb;
	- 	for(i=512; i<1024; i++){	/* 512: start at entry for virtual 0x80000000 */
	- 		if(pde[i] & PTEVALID){
	- 			pde[i] |= PTEGLOBAL;
	- 			if(!(pde[i] & PTESIZE)){
	- 				pte = KADDR(pde[i]&~(BY2PG-1));
	- 				for(j=0; j<1024; j++)
	- 					if(pte[j] & PTEVALID)
	- 						pte[j] |= PTEGLOBAL;
	- 			}
	- 		}
	- 	}			
	+ 	memmove(m->gdt, gdt, sizeof gdt);
	  }
	  
	  void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:83,90 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:79,92
	  	ulong x, *p;
	  	ushort ptr[3];
	  
	- 	memglobal();
	+ 	didmmuinit = 1;
	  
	+ 	if(0) print("vpt=%#.8ux vpd=%#.8lux kmap=%#.8ux\n",
	+ 		VPT, (ulong)vpd, KMAP);
	+ 
	+ 	memglobal();
	+ 	m->pdb[PDX(VPT)] = PADDR(m->pdb)|PTEWRITE|PTEVALID;
	+ 	
	  	m->tss = malloc(sizeof(Tss));
	  	memset(m->tss, 0, sizeof(Tss));
	  	m->tss->iomap = 0xDFFF<<16;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:98,104 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:100,105
	  	 * than Intels in this regard).  Under VMware it pays off
	  	 * a factor of about 10 to 100.
	  	 */
	- 
	  	memmove(m->gdt, gdt, sizeof gdt);
	  	x = (ulong)m->tss;
	  	m->gdt[TSSSEG].d0 = (x<<16)|sizeof(Tss);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:128,133 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:129,180
	  	ltr(TSSSEL);
	  }
	  
	+ /* 
	+  * On processors that support it, we set the PTEGLOBAL bit in
	+  * page table and page directory entries that map kernel memory.
	+  * Doing this tells the processor not to bother flushing them
	+  * from the TLB when doing the TLB flush associated with a 
	+  * context switch (write to CR3).  Since kernel memory mappings
	+  * are never removed, this is safe.  (If we ever remove kernel memory
	+  * mappings, we can do a full flush by turning off the PGE bit in CR4,
	+  * writing to CR3, and then turning the PGE bit back on.) 
	+  *
	+  * See also mmukmap below.
	+  * 
	+  * Processor support for the PTEGLOBAL bit is enabled in devarch.c.
	+  */
	+ static void
	+ memglobal(void)
	+ {
	+ 	int i, j;
	+ 	ulong *pde, *pte;
	+ 
	+ 	/* only need to do this once, on bootstrap processor */
	+ 	if(m->machno != 0)
	+ 		return;
	+ 
	+ 	if(!m->havepge)
	+ 		return;
	+ 
	+ 	pde = m->pdb;
	+ 	for(i=PDX(KZERO); i<1024; i++){
	+ 		if(pde[i] & PTEVALID){
	+ 			pde[i] |= PTEGLOBAL;
	+ 			if(!(pde[i] & PTESIZE)){
	+ 				pte = KADDR(pde[i]&~(BY2PG-1));
	+ 				for(j=0; j<1024; j++)
	+ 					if(pte[j] & PTEVALID)
	+ 						pte[j] |= PTEGLOBAL;
	+ 			}
	+ 		}
	+ 	}			
	+ }
	+ 
	+ /*
	+  * Flush all the user-space and device-mapping mmu info
	+  * for this process, because something has been deleted.
	+  * It will be paged back in on demand.
	+  */
	  void
	  flushmmu(void)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:139,163 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:186,293
	  	splx(s);
	  }
	  
	+ /*
	+  * Flush a single page mapping from the tlb.
	+  */
	+ void
	+ flushpg(ulong va)
	+ {
	+ 	if(X86FAMILY(m->cpuidax) >= 4)
	+ 		invlpg(va);
	+ 	else
	+ 		putcr3(m->tss->cr3);
	+ }
	+ 	
	+ /*
	+  * Allocate a new page for a page directory. 
	+  * We keep a small cache of pre-initialized
	+  * page directories in each mach.
	+  */
	+ static Page*
	+ mmupdballoc(void)
	+ {
	+ 	int s;
	+ 	Page *page;
	+ 	ulong *pdb;
	+ 
	+ 	s = splhi();
	+ 	if(m->pdbpool == 0){
	+ 		spllo();
	+ 		page = newpage(0, 0, 0);
	+ 		page->va = (ulong)vpd;
	+ 		splhi();
	+ 		pdb = tmpmap(page);
	+ 		memmove(pdb, m->pdb, BY2PG);
	+ 		pdb[PDX(VPT)] = page->pa|PTEWRITE|PTEVALID;	/* set up VPT */
	+ 		tmpunmap(pdb);
	+ 	}else{
	+ 		page = m->pdbpool;
	+ 		m->pdbpool = page->next;
	+ 		m->pdbcnt--;
	+ 	}
	+ 	splx(s);
	+ 	return page;
	+ }
	+ 
	  static void
	+ mmupdbfree(Proc *proc, Page *p)
	+ {
	+ 	if(islo())
	+ 		panic("mmupdbfree: islo");
	+ 	if(m->pdbcnt >= 10){
	+ 		p->next = proc->mmufree;
	+ 		proc->mmufree = p;
	+ 	}else{
	+ 		p->next = m->pdbpool;
	+ 		m->pdbpool = p;
	+ 	}
	+ }
	+ 
	+ /*
	+  * A user-space memory segment has been deleted, or the
	+  * process is exiting.  Clear all the pde entries for user-space
	+  * memory mappings and device mappings.  Any entries that
	+  * are needed will be paged back in as necessary.
	+  */
	+ static void
	  mmuptefree(Proc* proc)
	  {
	+ 	int s;
	  	ulong *pdb;
	  	Page **last, *page;
	  
	- 	if(proc->mmupdb && proc->mmuused){
	- 		pdb = (ulong*)proc->mmupdb->va;
	- 		last = &proc->mmuused;
	- 		for(page = *last; page; page = page->next){
	- 			pdb[page->daddr] = 0;
	- 			last = &page->next;
	- 		}
	- 		*last = proc->mmufree;
	- 		proc->mmufree = proc->mmuused;
	- 		proc->mmuused = 0;
	+ 	if(proc->mmupdb == nil || proc->mmuused == nil)
	+ 		return;
	+ 	s = splhi();
	+ 	pdb = tmpmap(proc->mmupdb);
	+ 	last = &proc->mmuused;
	+ 	for(page = *last; page; page = page->next){
	+ 		pdb[page->daddr] = 0;
	+ 		last = &page->next;
	  	}
	+ 	tmpunmap(pdb);
	+ 	splx(s);
	+ 	*last = proc->mmufree;
	+ 	proc->mmufree = proc->mmuused;
	+ 	proc->mmuused = 0;
	  }
	  
	+ static void
	+ taskswitch(ulong pdb, ulong stack)
	+ {
	+ 	Tss *tss;
	+ 
	+ 	tss = m->tss;
	+ 	tss->ss0 = KDSEL;
	+ 	tss->esp0 = stack;
	+ 	tss->ss1 = KDSEL;
	+ 	tss->esp1 = stack;
	+ 	tss->ss2 = KDSEL;
	+ 	tss->esp2 = stack;
	+ 	tss->cr3 = pdb;
	+ 	putcr3(pdb);
	+ }
	+ 
	  void
	  mmuswitch(Proc* proc)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:169,215 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:299,335
	  	}
	  
	  	if(proc->mmupdb){
	- 		pdb = (ulong*)proc->mmupdb->va;
	+ 		pdb = tmpmap(proc->mmupdb);
	  		pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
	+ 		tmpunmap(pdb);
	  		taskswitch(proc->mmupdb->pa, (ulong)(proc->kstack+KSTACK));
	- 	}
	- 	else
	+ 	}else
	  		taskswitch(PADDR(m->pdb), (ulong)(proc->kstack+KSTACK));
	  }
	  
	+ /*
	+  * Release any pages allocated for a page directory base or page-tables
	+  * for this process:
	+  *   switch to the prototype pdb for this processor (m->pdb);
	+  *   call mmuptefree() to place all pages used for page-tables (proc->mmuused)
	+  *   onto the process' free list (proc->mmufree). This has the side-effect of
	+  *   cleaning any user entries in the pdb (proc->mmupdb);
	+  *   if there's a pdb put it in the cache of pre-initialised pdb's
	+  *   for this processor (m->pdbpool) or on the process' free list;
	+  *   finally, place any pages freed back into the free pool (palloc).
	+  * This routine is only called from sched() with palloc locked.
	+  */
	  void
	  mmurelease(Proc* proc)
	  {
	  	Page *page, *next;
	  
	- 	/*
	- 	 * Release any pages allocated for a page directory base or page-tables
	- 	 * for this process:
	- 	 *   switch to the prototype pdb for this processor (m->pdb);
	- 	 *   call mmuptefree() to place all pages used for page-tables (proc->mmuused)
	- 	 *   onto the process' free list (proc->mmufree). This has the side-effect of
	- 	 *   cleaning any user entries in the pdb (proc->mmupdb);
	- 	 *   if there's a pdb put it in the cache of pre-initialised pdb's
	- 	 *   for this processor (m->pdbpool) or on the process' free list;
	- 	 *   finally, place any pages freed back into the free pool (palloc).
	- 	 * This routine is only called from sched() with palloc locked.
	- 	 */
	  	taskswitch(PADDR(m->pdb), (ulong)m + BY2PG);
	- 	mmuptefree(proc);
	- 
	  	if(proc->mmupdb){
	- 		if(m->pdbcnt > 10){
	- 			proc->mmupdb->next = proc->mmufree;
	- 			proc->mmufree = proc->mmupdb;
	- 		}
	- 		else{
	- 			proc->mmupdb->next = m->pdbpool;
	- 			m->pdbpool = proc->mmupdb;
	- 			m->pdbcnt++;
	- 		}
	+ 		mmuptefree(proc);
	+ 		mmupdbfree(proc, proc->mmupdb);
	  		proc->mmupdb = 0;
	  	}
	- 
	  	for(page = proc->mmufree; page; page = next){
	  		next = page->next;
	  		if(--page->ref)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:221,323 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:341,430
	  	proc->mmufree = 0;
	  }
	  
	- static Page*
	- mmupdballoc(void)
	+ /*
	+  * Allocate and install pdb for the current process.
	+  */
	+ static void
	+ upallocpdb(void)
	  {
	  	int s;
	+ 	ulong *pdb;
	  	Page *page;
	- 
	+ 	
	+ 	page = mmupdballoc();
	  	s = splhi();
	- 	if(m->pdbpool == 0){
	- 		spllo();
	- 		page = newpage(0, 0, 0);
	- 		page->va = VA(kmap(page));
	- 		memmove((void*)page->va, m->pdb, BY2PG);
	- 	}
	- 	else{
	- 		page = m->pdbpool;
	- 		m->pdbpool = page->next;
	- 		m->pdbcnt--;
	- 	}
	+ 	pdb = tmpmap(page);
	+ 	pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
	+ 	tmpunmap(pdb);
	+ 	up->mmupdb = page;
	+ 	mmuflushtlb(up->mmupdb->pa);
	  	splx(s);
	- 	return page;
	  }
	- 
	- void
	- checkmmu(ulong va, ulong pa)
	- {
	- 	ulong *pdb, *pte;
	- 	int pdbx;
	  	
	- 	if(up->mmupdb == 0)
	- 		return;
	- 
	- 	pdb = (ulong*)up->mmupdb->va;
	- 	pdbx = PDX(va);
	- 	if(PPN(pdb[pdbx]) == 0){
	- 		/* okay to be empty - will fault and get filled */
	- 		return;
	- 	}
	- 	
	- 	pte = KADDR(PPN(pdb[pdbx]));
	- 	if(pte[PTX(va)] == 0)
	- 		return;
	- 	if((pte[PTX(va)]&~4095) != pa)
	- 		print("%ld %s: va=0x%08lux pa=0x%08lux pte=0x%08lux\n",
	- 			up->pid, up->text,
	- 			va, pa, pte[PTX(va)]);
	- }
	- 
	+ /*
	+  * Update the mmu in response to a user fault.  pa may have PTEWRITE set.
	+  */
	  void
	  putmmu(ulong va, ulong pa, Page*)
	  {
	- 	int pdbx;
	+ 	int old;
	  	Page *page;
	- 	ulong *pdb, *pte;
	- 	int s;
	  
	- 	if(up->mmupdb == 0)
	- 		up->mmupdb = mmupdballoc();
	- 	pdb = (ulong*)up->mmupdb->va;
	- 	pdbx = PDX(va);
	+ 	if(up->mmupdb == nil)
	+ 		upallocpdb();
	  
	- 	if(PPN(pdb[pdbx]) == 0){
	- 		if(up->mmufree == 0){
	- 			page = newpage(1, 0, 0);
	- 			page->va = VA(kmap(page));
	- 		}
	- 		else {
	+ 	if(!(vpd[PDX(va)]&PTEVALID)){
	+ 		if(up->mmufree == 0)
	+ 			page = newpage(0, 0, 0);
	+ 		else{
	  			page = up->mmufree;
	  			up->mmufree = page->next;
	- 			memset((void*)page->va, 0, BY2PG);
	  		}
	- 		pdb[pdbx] = PPN(page->pa)|PTEUSER|PTEWRITE|PTEVALID;
	- 		page->daddr = pdbx;
	+ 		vpd[PDX(va)] = PPN(page->pa)|PTEUSER|PTEWRITE|PTEVALID;
	+ 		/* page is now mapped into the VPT - clear it */
	+ 		memset((void*)(VPT+PDX(va)*BY2PG), 0, BY2PG);
	+ 		page->daddr = PDX(va);
	  		page->next = up->mmuused;
	  		up->mmuused = page;
	  	}
	+ 	old = vpt[VPTX(va)];
	+ 	vpt[VPTX(va)] = pa|PTEUSER|PTEVALID;
	+ 	if(old&PTEVALID)
	+ 		flushpg(va);
	+ }
	  
	- 	pte = KADDR(PPN(pdb[pdbx]));
	- 	pte[PTX(va)] = pa|PTEUSER;
	- 
	- 	s = splhi();
	- 	pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
	- 	mmuflushtlb(up->mmupdb->pa);
	- 	splx(s);
	+ /*
	+  * Double-check the user MMU.
	+  * Error checking only.
	+  */
	+ void
	+ checkmmu(ulong va, ulong pa)
	+ {
	+ 	if(up->mmupdb == 0)
	+ 		return;
	+ 	if(!(vpd[PDX(va)]&PTEVALID) || !(vpt[VPTX(va)]&PTEVALID))
	+ 		return;
	+ 	if(PPN(vpt[VPTX(va)]) != pa)
	+ 		print("%ld %s: va=0x%08lux pa=0x%08lux pte=0x%08lux\n",
	+ 			up->pid, up->text,
	+ 			va, pa, vpt[VPTX(va)]);
	  }
	  
	+ /*
	+  * Walk the page-table pointed to by pdb and return a pointer
	+  * to the entry for virtual address va at the requested level.
	+  * If the entry is invalid and create isn't requested then bail
	+  * out early. Otherwise, for the 2nd level walk, allocate a new
	+  * page-table page and register it in the 1st level.  This is used
	+  * only to edit kernel mappings, which use pages from kernel memory,
	+  * so it's okay to use KADDR to look at the tables.
	+  */
	  ulong*
	  mmuwalk(ulong* pdb, ulong va, int level, int create)
	  {
	- 	ulong pa, *table;
	+ 	ulong *table;
	+ 	void *map;
	  
	- 	/*
	- 	 * Walk the page-table pointed to by pdb and return a pointer
	- 	 * to the entry for virtual address va at the requested level.
	- 	 * If the entry is invalid and create isn't requested then bail
	- 	 * out early. Otherwise, for the 2nd level walk, allocate a new
	- 	 * page-table page and register it in the 1st level.
	- 	 */
	  	table = &pdb[PDX(va)];
	  	if(!(*table & PTEVALID) && create == 0)
	  		return 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mmu.c:334,496 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mmu.c:441,870
	  		if(*table & PTESIZE)
	  			panic("mmuwalk2: va %luX entry %luX\n", va, *table);
	  		if(!(*table & PTEVALID)){
	- 			pa = PADDR(xspanalloc(BY2PG, BY2PG, 0));
	- 			*table = pa|PTEWRITE|PTEVALID;
	+ 			/*
	+ 			 * Have to call low-level allocator from
	+ 			 * memory.c if we haven't set up the xalloc
	+ 			 * tables yet.
	+ 			 */
	+ 			if(didmmuinit)
	+ 				map = xspanalloc(BY2PG, BY2PG, 0);
	+ 			else
	+ 				map = rampage();
	+ 			if(map == nil)
	+ 				panic("mmuwalk xspanalloc failed");
	+ 			*table = PADDR(map)|PTEWRITE|PTEVALID;
	  		}
	  		table = KADDR(PPN(*table));
	- 
	  		return &table[PTX(va)];
	  	}
	  }
	  
	- static Lock mmukmaplock;
	+ /*
	+  * Device mappings are shared by all procs and processors and
	+  * live in the virtual range VMAP to VMAP+VMAPSIZE.  The master
	+  * copy of the mappings is stored in mach0->pdb, and they are
	+  * paged in from there as necessary by vmapsync during faults.
	+  */
	  
	- int
	- mmukmapsync(ulong va)
	- {
	- 	Mach *mach0;
	- 	ulong entry, *pte;
	+ static Lock vmaplock;
	  
	- 	mach0 = MACHP(0);
	+ static int findhole(ulong *a, int n, int count);
	+ static ulong vmapalloc(ulong size);
	+ static void pdbunmap(ulong*, ulong, int);
	  
	- 	ilock(&mmukmaplock);
	+ /*
	+  * Add a device mapping to the vmap range.
	+  */
	+ void*
	+ vmap(ulong pa, int size)
	+ {
	+ 	int osize;
	+ 	ulong o, va;
	+ 	
	+ 	/*
	+ 	 * might be asking for less than a page.
	+ 	 */
	+ 	osize = size;
	+ 	o = pa & (BY2PG-1);
	+ 	pa -= o;
	+ 	size += o;
	  
	- 	if((pte = mmuwalk(mach0->pdb, va, 1, 0)) == nil){
	- 		iunlock(&mmukmaplock);
	- 		return 0;
	+ 	size = ROUND(size, BY2PG);
	+ 	if(pa == 0){
	+ 		print("vmap pa=0 pc=%#.8lux\n", getcallerpc(&pa));
	+ 		return nil;
	  	}
	- 	if(!(*pte & PTESIZE) && mmuwalk(mach0->pdb, va, 2, 0) == nil){
	- 		iunlock(&mmukmaplock);
	+ 	ilock(&vmaplock);
	+ 	if((va = vmapalloc(size)) == 0 
	+ 	|| pdbmap(MACHP(0)->pdb, pa|PTEUNCACHED|PTEWRITE, va, size) < 0){
	+ 		iunlock(&vmaplock);
	  		return 0;
	  	}
	- 	entry = *pte;
	+ 	iunlock(&vmaplock);
	+ 	/* avoid trap on local processor
	+ 	for(i=0; i<size; i+=4*MB)
	+ 		vmapsync(va+i);
	+ 	*/
	+ 	USED(osize);
	+ //	print("  vmap %#.8lux %d => %#.8lux\n", pa+o, osize, va+o);
	+ 	return (void*)(va + o);
	+ }
	  
	- 	if(!(m->pdb[PDX(va)] & PTEVALID))
	- 		m->pdb[PDX(va)] = entry;
	+ static int
	+ findhole(ulong *a, int n, int count)
	+ {
	+ 	int have, i;
	+ 	
	+ 	have = 0;
	+ 	for(i=0; i<n; i++){
	+ 		if(a[i] == 0)
	+ 			have++;
	+ 		else
	+ 			have = 0;
	+ 		if(have >= count)
	+ 			return i+1 - have;
	+ 	}
	+ 	return -1;
	+ }
	  
	- 	if(up && up->mmupdb){
	- 		((ulong*)up->mmupdb->va)[PDX(va)] = entry;
	- 		mmuflushtlb(up->mmupdb->pa);
	+ /*
	+  * Look for free space in the vmap.
	+  */
	+ static ulong
	+ vmapalloc(ulong size)
	+ {
	+ 	int i, n, o;
	+ 	ulong *vpdb;
	+ 	int vpdbsize;
	+ 	
	+ 	vpdb = &MACHP(0)->pdb[PDX(VMAP)];
	+ 	vpdbsize = VMAPSIZE/(4*MB);
	+ 
	+ 	if(size >= 4*MB){
	+ 		n = (size+4*MB-1) / (4*MB);
	+ 		if((o = findhole(vpdb, vpdbsize, n)) != -1)
	+ 			return VMAP + o*4*MB;
	+ 		return VMAP + o;
	  	}
	- 	else
	- 		mmuflushtlb(PADDR(m->pdb));
	+ 	n = (size+BY2PG-1) / BY2PG;
	+ 	for(i=0; i<vpdbsize; i++)
	+ 		if((vpdb[i]&PTEVALID) && !(vpdb[i]&PTESIZE))
	+ 			if((o = findhole(KADDR(PPN(vpdb[i])), WD2PG, n)) != -1)
	+ 				return VMAP + i*4*MB + o*BY2PG;
	+ 	if((o = findhole(vpdb, vpdbsize, 1)) != -1)
	+ 		return VMAP + o*4*MB;
	+ 		
	+ 	/*
	+ 	 * could span page directory entries, but not worth the trouble.
	+ 	 * not going to be very much contention.
	+ 	 */
	+ 	return 0;
	+ }
	  
	- 	iunlock(&mmukmaplock);
	+ /*
	+  * Remove a device mapping from the vmap range.
	+  * Since pdbunmap does not remove page tables, just entries,
	+  * the call need not be interlocked with vmap.
	+  */
	+ void
	+ vunmap(void *v, int size)
	+ {
	+ 	int i;
	+ 	ulong va, o;
	+ 	Mach *nm;
	+ 	Proc *p;
	+ 	
	+ 	/*
	+ 	 * might not be aligned
	+ 	 */
	+ 	va = (ulong)v;
	+ 	o = va&(BY2PG-1);
	+ 	va -= o;
	+ 	size += o;
	+ 	size = ROUND(size, BY2PG);
	+ 	
	+ 	if(size < 0 || va < VMAP || va+size > VMAP+VMAPSIZE)
	+ 		panic("vunmap va=%#.8lux size=%#x pc=%#.8lux\n",
	+ 			va, size, getcallerpc(&va));
	  
	- 	return 1;
	+ 	pdbunmap(MACHP(0)->pdb, va, size);
	+ 	
	+ 	/*
	+ 	 * Flush mapping from all the tlbs and copied pdbs.
	+ 	 * This can be (and is) slow, since it is called only rarely.
	+ 	 */
	+ 	for(i=0; i<conf.nproc; i++){
	+ 		p = proctab(i);
	+ 		if(p->state == Dead)
	+ 			continue;
	+ 		if(p != up)
	+ 			p->newtlb = 1;
	+ 	}
	+ 	for(i=0; i<conf.nmach; i++){
	+ 		nm = MACHP(i);
	+ 		if(nm != m)
	+ 			nm->flushmmu = 1;
	+ 	}
	+ 	flushmmu();
	+ 	for(i=0; i<conf.nmach; i++){
	+ 		nm = MACHP(i);
	+ 		if(nm != m)
	+ 			while((active.machs&(1<<nm->machno)) && nm->flushmmu)
	+ 				;
	+ 	}
	  }
	  
	- ulong
	- mmukmap(ulong pa, ulong va, int size)
	+ /*
	+  * Add kernel mappings for pa -> va for a section of size bytes.
	+  */
	+ int
	+ pdbmap(ulong *pdb, ulong pa, ulong va, int size)
	  {
	- 	Mach *mach0;
	- 	ulong ova, pae, *table, pgsz, *pte, x;
	- 	int pse, sync;
	+ 	int pse;
	+ 	ulong pae, pgsz, *pte, *table;
	+ 	ulong flag;
	+ 	
	+ 	flag = pa&0xFFF;
	+ 	pa &= ~0xFFF;
	  
	- 	mach0 = MACHP(0);
	- 	if((mach0->cpuiddx & 0x08) && (getcr4() & 0x10))
	+ 	if((MACHP(0)->cpuiddx & 0x08) && (getcr4() & 0x10))
	  		pse = 1;
	  	else
	  		pse = 0;
	- 	sync = 0;
	  
	- 	pa = PPN(pa);
	- 	if(va == 0)
	- 		va = (ulong)KADDR(pa);
	- 	else
	- 		va = PPN(va);
	- 	ova = va;
	- 
	  	pae = pa + size;
	- 	ilock(&mmukmaplock);
	  	while(pa < pae){
	- 		table = &mach0->pdb[PDX(va)];
	- 		/*
	- 		 * Possibly already mapped.
	- 		 */
	- 		if(*table & PTEVALID){
	- 			if(*table & PTESIZE){
	- 				/*
	- 				 * Big page. Does it fit within?
	- 				 * If it does, adjust pgsz so the correct end can be
	- 				 * returned and get out.
	- 				 * If not, adjust pgsz up to the next 4MB boundary
	- 				 * and continue.
	- 				 */
	- 				x = PPN(*table);
	- 				if(x != pa)
	- 					panic("mmukmap1: pa %luX  entry %luX\n",
	- 						pa, *table);
	- 				x += 4*MB;
	- 				if(pae <= x){
	- 					pa = pae;
	- 					break;
	- 				}
	- 				pgsz = x - pa;
	- 				pa += pgsz;
	- 				va += pgsz;
	+ 		table = &pdb[PDX(va)];
	+ 		if((*table&PTEVALID) && (*table&PTESIZE))
	+ 			panic("vmap: va=%#.8lux pa=%#.8lux pde=%#.8lux",
	+ 				va, pa, *table);
	  
	- 				continue;
	- 			}
	- 			else{
	- 				/*
	- 				 * Little page. Walk to the entry.
	- 				 * If the entry is valid, set pgsz and continue.
	- 				 * If not, make it so, set pgsz, sync and continue.
	- 				 */
	- 				pte = mmuwalk(mach0->pdb, va, 2, 0);
	- 				if(pte && *pte & PTEVALID){
	- 					x = PPN(*pte);
	- 					if(x != pa)
	- 						panic("mmukmap2: pa %luX entry %luX\n",
	- 							pa, *pte);
	- 					pgsz = BY2PG;
	- 					pa += pgsz;
	- 					va += pgsz;
	- 					sync++;
	- 
	- 					continue;
	- 				}
	- 			}
	- 		}
	- 
	  		/*
	- 		 * Not mapped. Check if it can be mapped using a big page -
	- 		 * starts on a 4MB boundary, size >= 4MB and processor can do it.
	- 		 * If not a big page, walk the walk, talk the talk.
	- 		 * Sync is set.
	- 		 *
	- 		 * If we're creating a kernel mapping, we know that it will never
	- 		 * expire and thus we can set the PTEGLOBAL bit to make the entry
	- 	 	 * persist in the TLB across flushes.  If we do add support later for
	- 		 * unmapping kernel addresses, see devarch.c for instructions on
	- 		 * how to do a full TLB flush.
	+ 		 * Check if it can be mapped using a 4MB page:
	+ 		 * va, pa aligned and size >= 4MB and processor can do it.
	  		 */
	- 		if(pse && (pa % (4*MB)) == 0 && (pae >= pa+4*MB)){
	- 			*table = pa|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
	- 			if((va&KZERO) && m->havepge)
	- 				*table |= PTEGLOBAL;
	+ 		if(pse && pa%(4*MB) == 0 && va%(4*MB) == 0 && (pae >= pa+4*MB)){
	+ 			*table = pa|PTESIZE|flag|PTEVALID;
	  			pgsz = 4*MB;
	- 		}
	- 		else{
	- 			pte = mmuwalk(mach0->pdb, va, 2, 1);
	- 			*pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
	- 			if((va&KZERO) && m->havepge)
	- 				*pte |= PTEGLOBAL;
	+ 		}else{
	+ 			pte = mmuwalk(pdb, va, 2, 1);
	+ 			if(*pte&PTEVALID)
	+ 				panic("vmap: va=%#.8lux pa=%#.8lux pte=%#.8lux",
	+ 					va, pa, *pte);
	+ 			*pte = pa|flag|PTEVALID;
	  			pgsz = BY2PG;
	  		}
	  		pa += pgsz;
	  		va += pgsz;
	- 		sync++;
	  	}
	- 	iunlock(&mmukmaplock);
	+ 	return 0;
	+ }
	  
	+ /*
	+  * Remove mappings.  Must already exist, for sanity.
	+  * Only used for kernel mappings, so okay to use KADDR.
	+  */
	+ static void
	+ pdbunmap(ulong *pdb, ulong va, int size)
	+ {
	+ 	ulong vae;
	+ 	ulong *table;
	+ 	
	+ 	vae = va+size;
	+ 	while(va < vae){
	+ 		table = &pdb[PDX(va)];
	+ 		if(!(*table & PTEVALID)){
	+ 			panic("vunmap: not mapped");
	+ 			/* 
	+ 			va = (va+4*MB-1) & ~(4*MB-1);
	+ 			continue;
	+ 			*/
	+ 		}
	+ 		if(*table & PTESIZE){
	+ 			*table = 0;
	+ 			va = (va+4*MB-1) & ~(4*MB-1);
	+ 			continue;
	+ 		}
	+ 		table = KADDR(PPN(*table));
	+ 		if(!(table[PTX(va)] & PTEVALID))
	+ 			panic("vunmap: not mapped");
	+ 		table[PTX(va)] = 0;
	+ 		va += BY2PG;
	+ 	}
	+ }
	+ 
	+ /*
	+  * Handle a fault by bringing vmap up to date.
	+  * Only copy pdb entries and they never go away,
	+  * so no locking needed.
	+  */
	+ int
	+ vmapsync(ulong va)
	+ {
	+ 	ulong entry, *table;
	+ 
	+ 	if(va < VMAP || va >= VMAP+VMAPSIZE)
	+ 		return 0;
	+ 
	+ 	entry = MACHP(0)->pdb[PDX(va)];
	+ 	if(!(entry&PTEVALID))
	+ 		return 0;
	+ 	if(!(entry&PTESIZE)){
	+ 		/* make sure entry will help the fault */
	+ 		table = KADDR(PPN(entry));
	+ 		if(!(table[PTX(va)]&PTEVALID))
	+ 			return 0;
	+ 	}
	+ 	vpd[PDX(va)] = entry;
	  	/*
	- 	 * If something was added
	- 	 * then need to sync up.
	+ 	 * TLB doesn't cache negative results, so no flush needed.
	  	 */
	- 	if(sync)
	- 		mmukmapsync(ova);
	+ 	return 1;
	+ }
	  
	- 	return pa;
	+ 
	+ /*
	+  * KMap is used to map individual pages into virtual memory.
	+  * It is rare to have more than a few KMaps at a time (in the 
	+  * absence of interrupts, only two at a time are ever used,
	+  * but interrupts can stack).  The mappings are local to a process,
	+  * so we can use the same range of virtual address space for
	+  * all processes without any coordination.
	+  */
	+ #define kpt (vpt+VPTX(KMAP))
	+ #define NKPT (KMAPSIZE/BY2PG)
	+ 
	+ KMap*
	+ kmap(Page *page)
	+ {
	+ 	int i, o, s;
	+ 	Page *pdb;
	+ 
	+ 	if(up == nil)
	+ 		panic("kmap: up=0 pc=%#.8lux", getcallerpc(&page));
	+ 	if(up->mmupdb == nil)
	+ 		upallocpdb();
	+ 	if(!(vpd[PDX(KMAP)]&PTEVALID)){
	+ 		/* allocate page directory */
	+ 		if(KMAPSIZE > BY2XPG)
	+ 			panic("bad kmapsize");
	+ 		s = spllo();
	+ 		pdb = newpage(0, 0, 0);
	+ 		splx(s);
	+ 		vpd[PDX(KMAP)] = pdb->pa|PTEWRITE|PTEVALID;
	+ 		memset(kpt, 0, BY2PG);
	+ 
	+ 		/* might as well finish the job */
	+ 		kpt[0] = page->pa|PTEWRITE|PTEVALID;
	+ 		up->lastkmap = 0;
	+ 		return (KMap*)KMAP;
	+ 	}
	+ 	o = up->lastkmap+1;
	+ 	for(i=0; i<NKPT; i++){
	+ 		if(kpt[(i+o)%NKPT] == 0){
	+ 			o = (i+o)%NKPT;
	+ 			kpt[o] = page->pa|PTEWRITE|PTEVALID;
	+ 			up->lastkmap = o;
	+ 			return (KMap*)(KMAP+o*BY2PG);
	+ 		}
	+ 	}
	+ 	panic("out of kmap");
	+ 	return nil;
	+ }
	+ 
	+ void
	+ kunmap(KMap *k)
	+ {
	+ 	ulong va;
	+ 
	+ 	va = (ulong)k;
	+ 	if(up->mmupdb == nil || !(vpd[PDX(KMAP)]&PTEVALID))
	+ 		panic("kunmap: no kmaps");
	+ 	if(va < KMAP || va >= KMAP+KMAPSIZE)
	+ 		panic("kunmap: bad address %#.8lux pc=%#.8lux", va, getcallerpc(&k));
	+ 	if(!(vpt[VPTX(va)]&PTEVALID))
	+ 		panic("kunmap: not mapped %#.8lux pc=%#.8lux", va, getcallerpc(&k));
	+ 	vpt[VPTX(va)] = 0;
	+ 	flushpg(va);
	+ }
	+ 
	+ 
	+ /*
	+  * Temporary one-page mapping used to edit page directories.
	+  *
	+  * The fasttmp #define controls whether the code optimizes
	+  * the case where the page is already mapped in the physical
	+  * memory window.  
	+  */
	+ #define fasttmp 1
	+ 
	+ void*
	+ tmpmap(Page *p)
	+ {
	+ 	ulong i;
	+ 	ulong *entry;
	+ 	
	+ 	if(islo())
	+ 		panic("tmpaddr: islo");
	+ 
	+ 	if(fasttmp && p->pa < -KZERO)
	+ 		return KADDR(p->pa);
	+ 
	+ 	/*
	+ 	 * PDX(TMPADDR) == PDX(MACHADDR), so this
	+ 	 * entry is private to the processor and shared 
	+ 	 * between up->mmupdb (if any) and m->pdb.
	+ 	 */
	+ 	entry = &vpt[VPTX(TMPADDR)];
	+ 	if(!(*entry&PTEVALID)){
	+ 		for(i=KZERO; i<=CPU0MACH; i+=BY2PG)
	+ 			print("%.8lux: *%.8lux=%.8lux (vpt=%.8lux index=%.8lux)\n", i, &vpt[VPTX(i)], vpt[VPTX(i)], vpt, VPTX(i));
	+ 		panic("tmpmap: no entry");
	+ 	}
	+ 	if(PPN(*entry) != PPN(TMPADDR-KZERO))
	+ 		panic("tmpmap: already mapped entry=%#.8lux", *entry);
	+ 	*entry = p->pa|PTEWRITE|PTEVALID;
	+ 	flushpg(TMPADDR);
	+ 	return (void*)TMPADDR;
	+ }
	+ 
	+ void
	+ tmpunmap(void *v)
	+ {
	+ 	ulong *entry;
	+ 	
	+ 	if(islo())
	+ 		panic("tmpaddr: islo");
	+ 	if(fasttmp && (ulong)v >= KZERO && v != (void*)TMPADDR)
	+ 		return;
	+ 	if(v != (void*)TMPADDR)
	+ 		panic("tmpunmap: bad address");
	+ 	entry = &vpt[VPTX(TMPADDR)];
	+ 	if(!(*entry&PTEVALID) || PPN(*entry) == PPN(PADDR(TMPADDR)))
	+ 		panic("tmpmap: not mapped entry=%#.8lux", *entry);
	+ 	*entry = PPN(TMPADDR-KZERO)|PTEWRITE|PTEVALID;
	+ 	flushpg(TMPADDR);
	+ }
	+ 
	+ /*
	+  * These could go back to being macros once the kernel is debugged,
	+  * but the extra checking is nice to have.
	+  */
	+ void*
	+ kaddr(ulong pa)
	+ {
	+ 	if(pa > (ulong)-KZERO)
	+ 		panic("kaddr: pa=%#.8lux", pa);
	+ 	return (void*)(pa+KZERO);
	+ }
	+ 
	+ ulong
	+ paddr(void *v)
	+ {
	+ 	ulong va;
	+ 	
	+ 	va = (ulong)v;
	+ 	if(va < KZERO)
	+ 		panic("paddr: va=%#.8lux", va);
	+ 	return va-KZERO;
	  }
 [rsc] --rw-rw-r-- M 451989 glenda sys 17157 Nov  6 20:17 sys/src/9/pc/mp.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.c:137,142 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.c:137,143
	  mkioapic(PCMPioapic* p)
	  {
	  	Apic *apic;
	+ 	void *va;
	  
	  	if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO)
	  		return 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.c:144,156 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.c:145,157
	  	/*
	  	 * Map the I/O APIC.
	  	 */
	- 	if(mmukmap(p->addr, 0, 1024) == 0)
	+ 	if((va = vmap(p->addr, 1024)) == 0)
	  		return 0;
	  
	  	apic = &mpapic[p->apicno];
	  	apic->type = PcmpIOAPIC;
	  	apic->apicno = p->apicno;
	- 	apic->addr = KADDR(p->addr);
	+ 	apic->addr = va;
	  	apic->flags = p->flags;
	  
	  	return apic;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.c:440,445 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.c:441,449
	  	*p++ = PADDR(APBOOTSTRAP);
	  	*p++ = PADDR(APBOOTSTRAP)>>8;
	  	i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
	+ 	/* code assumes i==0 */
	+ 	if(i != 0)
	+ 		print("mp: bad APBOOTSTRAP\n");
	  	*p++ = i;
	  	*p = i>>8;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.c:465,470 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.c:469,475
	  	PCMP *pcmp;
	  	uchar *e, *p;
	  	Apic *apic, *bpapic;
	+ 	void *va;
	  
	  	i8259init();
	  	syncclock();
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.c:476,482 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.c:481,487
	  	/*
	  	 * Map the local APIC.
	  	 */
	- 	if(mmukmap(pcmp->lapicbase, 0, 1024) == 0)
	+ 	if((va = vmap(pcmp->lapicbase, 1024)) == nil)
	  		return;
	  
	  	bpapic = nil;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.c:508,514 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.c:513,519
	  			 * guarantee that the bootstrap processor appears
	  			 * first in the table before the others.
	  			 */
	- 			apic->addr = KADDR(pcmp->lapicbase);
	+ 			apic->addr = va;
	  			if(apic->flags & PcmpBP)
	  				bpapic = apic;
	  		}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.c:766,772 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.c:771,777
	  		if(vno != -1)
	  			return vno;
	  	}
	- 
	+ 	print("mpintrenable: out of choices %d %d\n", mpeisabus, mpisabus);
	  	return -1;
	  }
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 6638 Nov  6 10:21 sys/src/9/pc/mp.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mp.h:217,222 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mp.h:217,224
	  extern int lapicisr(int);
	  extern int lapiceoi(int);
	  extern void lapicicrw(int, int);
	+ extern void lapicintron(void);
	+ extern void lapicintroff(void);
	  
	  extern void mpinit(void);
	  extern void mpshutdown(void);
 [rsc] --rw-rw-r-- M 451989 glenda sys 1427 Nov  6 10:21 sys/src/9/pc/pc
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pc:38,43 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pc:38,44
	  link
	  	devpccard
	  	devi82365
	+ 	realmode
	  	ether2000	ether8390
	  	ether2114x	pci
	  	ether589	etherelnk3
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pc:93,98 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pc:94,100
	  	vgat2r4		+cur
	  	vgatvp3020	=cur
	  	vgatvp3026	=cur
	+ 	vgavesa
	  	vgavmware	+cur
	  
	  ip
 [rsc] --rw-rw-r-- M 451989 glenda sys 714 Nov  6 10:21 sys/src/9/pc/pcauth
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcauth:37,42 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcauth:37,43
	  	loopbackmedium
	  
	  misc
	+ 	realmode
	  	sdata		pci sdscsi
	  
	  	uarti8250
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcauth:43,49 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcauth:44,50
	  	uartpci
	  
	  	vgamach64xx	+cur
	- 	vgas3  +cur vgasavage
	+ 	vgas3 		+cur vgasavage
	  
	  ip
	  	il
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcauth:65,68 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcauth:66,71
	  	bootpcauth.out boot
	  	/386/bin/ip/ipconfig
	  	/386/bin/auth/factotum
	+ 	/386/bin/fossil/fossil
	+ 	/386/bin/venti/venti
	  	/386/bin/disk/kfs
 [rsc] --rw-rw-r-- M 451989 glenda sys 866 Nov  6 10:21 sys/src/9/pc/pccpu
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pccpu:28,33 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pccpu:28,34
	  	usb
	  
	  link
	+ 	realmode
	  	ether2000	ether8390
	  	ether2114x	pci
	  	ether79c970	pci
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pccpu:53,58 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pccpu:54,60
	  
	  	sdata		pci sdscsi
	  	sd53c8xx	pci sdscsi
	+ 	sdmv50xx	pci sdscsi
	  
	  
	  ip
 [rsc] --rw-rw-r-- M 451989 glenda sys 1446 Nov  6 12:59 sys/src/9/pc/pcdisk
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcdisk:60,65 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcdisk:60,66
	  	usbuhci
	  
	  misc
	+ 	realmode
	  	archmp		mp apic
	  
	  	sdata		pci sdscsi
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcdisk:89,94 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcdisk:90,96
	  	vgat2r4		+cur
	  	vgatvp3020	=cur
	  	vgatvp3026	=cur
	+ 	vgavesa
	  	vgavmware	+cur
	  
	  ip
 [rsc] --rw-rw-r-- M 451989 presotto sys 1504 Nov  6 12:59 sys/src/9/pc/pcf
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcf:62,67 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcf:62,68
	  	usbuhci
	  
	  misc
	+ 	realmode
	  	archmp		mp apic
	  
	  	sdata		pci sdscsi
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcf:91,96 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcf:92,98
	  	vgat2r4		+cur
	  	vgatvp3020	=cur
	  	vgatvp3026	=cur
	+ 	vgavesa
	  	vgavmware	+cur
	  
	  ip
 [rsc] --rw-rw-r-- M 451989 glenda sys 26817 Nov  6 10:21 sys/src/9/pc/pci.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pci.c:759,764 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pci.c:759,766
	  	}
	  }
	  
	+ static void pcireservemem(void);
	+ 
	  static void
	  pcicfginit(void)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pci.c:898,907 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pci.c:900,926
	  		pcirouting();
	  
	  out:
	+ 	pcireservemem();
	  	unlock(&pcicfginitlock);
	  
	  	if(getconf("*pcihinv"))
	  		pcihinv(nil);
	+ }
	+ 
	+ static void
	+ pcireservemem(void)
	+ {
	+ 	int i;
	+ 	Pcidev *p;
	+ 	
	+ 	/*
	+ 	 * mark all the physical address space claimed by pci devices
	+ 	 * as in use, so that upaalloc doesn't give it out.
	+ 	 */
	+ 	for(p=pciroot; p; p=p->list)
	+ 		for(i=0; i<nelem(p->mem); i++)
	+ 			if(p->mem[i].bar && (p->mem[i].bar&1) == 0)
	+ 				upareserve(p->mem[i].bar&~0x0F, p->mem[i].size);
	  }
	  
	  static int
 [rsc] --rw-rw-r-- M 451989 glenda sys 13460 Nov  6 10:21 sys/src/9/pc/screen.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:38,48 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:38,51
	  	},
	  };
	  
	+ int didswcursorinit;
	+ 
	  int
	  screensize(int x, int y, int z, ulong chan)
	  {
	  	VGAscr *scr;
	  
	+ 	lock(&vgascreenlock);
	  	memimageinit();
	  	scr = &vgascreen[0];
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:50,56 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:53,59
	  	 * BUG: need to check if any xalloc'ed memory needs to
	  	 * be given back if aperture is set.
	  	 */
	- 	if(scr->aperture == 0){
	+ 	if(scr->paddr == 0){
	  		int width = (x*z)/BI2WD;
	  
	  		gscreendata.bdata = xalloc(width*BY2WD*y);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:58,76 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:61,83
	  			error("screensize: vga soft memory");
	  /*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */
	  		scr->useflush = 1;
	- 		scr->aperture = VGAMEM();
	+ 		scr->paddr = VGAMEM();
	+ 		scr->vaddr = KADDR(scr->paddr);
	  		scr->apsize = 1<<16;
	  	}
	  	else
	- 		gscreendata.bdata = KADDR(scr->aperture);
	+ 		gscreendata.bdata = scr->vaddr;
	  
	  	if(gscreen)
	  		freememimage(gscreen);
	+ 	scr->gscreen = nil;
	  
	  	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
	  	vgaimageinit(chan);
	- 	if(gscreen == nil)
	+ 	if(gscreen == nil){
	+ 		unlock(&vgascreenlock);
	  		return -1;
	+ 	}
	  
	  	if(scr->dev && scr->dev->flush)
	  		scr->useflush = 1;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:81,87 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:88,97
	  	scr->gscreen = gscreen;
	  
	  	physgscreenr = gscreen->r;
	+ 	unlock(&vgascreenlock);
	  
	+ 	if(didswcursorinit)
	+ 		swcursorinit();
	  	drawcmap();
	  	return 0;
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:90,121 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:100,130
	  screenaperture(int size, int align)
	  {
	  	VGAscr *scr;
	- 	ulong aperture;
	  
	  	scr = &vgascreen[0];
	  
	- 	if(size == 0){
	- 		if(scr->aperture && scr->isupamem)
	- 			upafree(scr->aperture, scr->apsize);
	- 		scr->aperture = 0;
	- 		scr->isupamem = 0;
	+ 	if(scr->paddr)	/* set up during enable */
	  		return 0;
	- 	}
	- 	if(scr->dev && scr->dev->linear){
	- 		aperture = scr->dev->linear(scr, &size, &align);
	- 		if(aperture == 0)
	- 			return 1;
	- 	}else{
	- 		aperture = upamalloc(0, size, align);
	- 		if(aperture == 0)
	- 			return 1;
	  
	- 		if(scr->aperture && scr->isupamem)
	- 			upafree(scr->aperture, scr->apsize);
	- 		scr->isupamem = 1;
	+ 	if(size == 0)
	+ 		return 0;
	+ 
	+ 	if(scr->dev && scr->dev->linear){
	+ 		scr->dev->linear(scr, size, align);
	+ 		return 0;
	  	}
	  
	- 	scr->aperture = aperture;
	+ 	/*
	+ 	 * Need to allocate some physical address space.
	+ 	 * The driver will tell the card to use it.
	+ 	 */
	+ 	size = PGROUND(size);
	+ 	scr->paddr = upaalloc(size, align);
	+ 	if(scr->paddr == 0)
	+ 		return -1;
	+ 	scr->vaddr = vmap(scr->paddr, size);
	+ 	if(scr->vaddr == nil)
	+ 		return -1;
	  	scr->apsize = size;
	  
	  	return 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:179,185 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:188,194
	  	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);
	+ 	disp = scr->vaddr;
	  	sdisp = disp+off;
	  	edisp = disp+scr->apsize;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:339,355 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:348,376
	  hwdraw(Memdrawparam *par)
	  {
	  	VGAscr *scr;
	- 	Memimage *dst, *src;
	+ 	Memimage *dst, *src, *mask;
	  	int m;
	  
	  	if(hwaccel == 0)
	  		return 0;
	  
	- 	dst = par->dst;
	  	scr = &vgascreen[0];
	- 	if(dst == nil || dst->data == nil)
	+ 	if((dst=par->dst) == nil || dst->data == nil)
	  		return 0;
	+ 	if((src=par->src) == nil || src->data == nil)
	+ 		return 0;
	+ 	if((mask=par->mask) == nil || mask->data == nil)
	+ 		return 0;
	  
	+ 	if(scr->cur == &swcursor){
	+ 		if(dst->data->bdata == gscreendata.bdata)
	+ 			swcursoravoid(par->r);
	+ 		if(src->data->bdata == gscreendata.bdata)
	+ 			swcursoravoid(par->sr);
	+ 		if(mask->data->bdata == gscreendata.bdata)
	+ 			swcursoravoid(par->mr);
	+ 	}
	+ 	
	  	if(dst->data->bdata != gscreendata.bdata)
	  		return 0;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:374,380 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:395,400
	  	 * the source is not replicated, memmove suffices.
	  	 */
	  	m = Simplemask|Fullmask;
	- 	src = par->src;
	  	if(scr->scroll
	  	&& src->data->bdata==dst->data->bdata
	  	&& !(src->flags&Falpha)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.c:398,400 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.c:418,711
	  			vgablank(scr, blank);
	  	}
	  }
	+ 
	+ void
	+ vgalinearpciid(VGAscr *scr, int vid, int did)
	+ {
	+ 	Pcidev *p;
	+ 
	+ 	p = nil;
	+ 	while((p = pcimatch(p, vid, 0)) != nil){
	+ 		if(p->ccrb != 3)	/* video card */
	+ 			continue;
	+ 		if(did != 0 && p->did != did)
	+ 			continue;
	+ 		break;
	+ 	}
	+ 	if(p == nil)
	+ 		error("pci video card not found");
	+ 
	+ 	scr->pci = p;
	+ 	vgalinearpci(scr);
	+ }
	+ 
	+ void
	+ vgalinearpci(VGAscr *scr)
	+ {
	+ 	ulong paddr;
	+ 	int i, size, best;
	+ 	Pcidev *p;
	+ 	
	+ 	p = scr->pci;
	+ 	if(p == nil)
	+ 		return;
	+ 
	+ 	/*
	+ 	 * Scan for largest memory region on card.
	+ 	 * Some S3 cards (e.g. Savage) have enormous
	+ 	 * mmio regions (but even larger frame buffers).
	+ 	 */
	+ 	best = -1;
	+ 	for(i=0; i<nelem(p->mem); i++){
	+ 		if(p->mem[i].bar&1)	/* not memory */
	+ 			continue;
	+ 		if(p->mem[i].size < 640*480)	/* not big enough */
	+ 			continue;
	+ 		if(best==-1 || p->mem[i].size > p->mem[best].size)
	+ 			best = i;
	+ 	}
	+ 	if(best >= 0){
	+ 		paddr = p->mem[best].bar & ~0x0F;
	+ 		size = p->mem[best].size;
	+ 		vgalinearaddr(scr, paddr, size);
	+ 		return;
	+ 	}
	+ 	error("no video memory found on pci card");
	+ }
	+ 
	+ void
	+ vgalinearaddr(VGAscr *scr, ulong paddr, int size)
	+ {
	+ 	int x, nsize;
	+ 	ulong npaddr;
	+ 
	+ 	/*
	+ 	 * new approach.  instead of trying to resize this
	+ 	 * later, let's assume that we can just allocate the
	+ 	 * entire window to start with.
	+ 	 */
	+ 
	+ 	if(scr->paddr == paddr && size <= scr->apsize)
	+ 		return;
	+ 
	+ 	if(scr->paddr){
	+ 		/*
	+ 		 * could call vunmap and vmap,
	+ 		 * but worried about dangling pointers in devdraw
	+ 		 */
	+ 		error("cannot grow vga frame buffer");
	+ 	}
	+ 	
	+ 	/* round to page boundary, just in case */
	+ 	x = paddr&(BY2PG-1);
	+ 	npaddr = paddr-x;
	+ 	nsize = PGROUND(size+x);
	+ 
	+ 	scr->vaddr = vmap(npaddr, nsize);
	+ 	if(scr->vaddr == 0)
	+ 		error("cannot allocate vga frame buffer");
	+ 	scr->vaddr = (char*)scr->vaddr+x;
	+ 	scr->paddr = paddr;
	+ 	scr->apsize = nsize;
	+ }
	+ 
	+ 
	+ /*
	+  * Software cursor. 
	+  */
	+ int	swvisible;	/* is the cursor visible? */
	+ int	swenabled;	/* is the cursor supposed to be on the screen? */
	+ Memimage*	swback;	/* screen under cursor */
	+ Memimage*	swimg;	/* cursor image */
	+ Memimage*	swmask;	/* cursor mask */
	+ Memimage*	swimg1;
	+ Memimage*	swmask1;
	+ 
	+ Point	swoffset;
	+ Rectangle	swrect;	/* screen rectangle in swback */
	+ Point	swpt;	/* desired cursor location */
	+ Point	swvispt;	/* actual cursor location */
	+ int	swvers;	/* incremented each time cursor image changes */
	+ int	swvisvers;	/* the version on the screen */
	+ 
	+ /*
	+  * called with drawlock locked for us, most of the time.
	+  * kernel prints at inopportune times might mean we don't
	+  * hold the lock, but memimagedraw is now reentrant so
	+  * that should be okay: worst case we get cursor droppings.
	+  */
	+ void
	+ swcursorhide(void)
	+ {
	+ 	if(swvisible == 0)
	+ 		return;
	+ 	if(swback == nil)
	+ 		return;
	+ 	swvisible = 0;
	+ 	memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
	+ }
	+ 
	+ void
	+ swcursoravoid(Rectangle r)
	+ {
	+ 	if(swvisible && rectXrect(r, swrect))
	+ 		swcursorhide();
	+ }
	+ 
	+ void
	+ swcursordraw(void)
	+ {
	+ 	if(swvisible)
	+ 		return;
	+ 	if(swenabled == 0)
	+ 		return;
	+ 	if(swback == nil || swimg1 == nil || swmask1 == nil)
	+ 		return;
	+ 	assert(!canqlock(&drawlock));
	+ 	swvispt = swpt;
	+ 	swvisvers = swvers;
	+ 	swrect = rectaddpt(Rect(0,0,16,16), swvispt);
	+ 	memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
	+ 	memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
	+ 	swvisible = 1;
	+ }
	+ 
	+ /*
	+  * Need to lock drawlock for ourselves.
	+  */
	+ void
	+ swenable(VGAscr*)
	+ {
	+ 	swenabled = 1;
	+ 	if(canqlock(&drawlock)){
	+ 		swcursordraw();
	+ 		qunlock(&drawlock);
	+ 	}
	+ }
	+ 
	+ void
	+ swdisable(VGAscr*)
	+ {
	+ 	swenabled = 0;
	+ 	if(canqlock(&drawlock)){
	+ 		swcursorhide();
	+ 		qunlock(&drawlock);
	+ 	}
	+ }
	+ 
	+ void
	+ swload(VGAscr*, Cursor *curs)
	+ {
	+ 	uchar *ip, *mp;
	+ 	int i, j, set, clr;
	+ 
	+ 	if(!swimg || !swmask || !swimg1 || !swmask1)
	+ 		return;
	+ 	/*
	+ 	 * Build cursor image and mask.
	+ 	 * Image is just the usual cursor image
	+ 	 * but mask is a transparent alpha mask.
	+ 	 * 
	+ 	 * The 16x16x8 memimages do not have
	+ 	 * padding at the end of their scan lines.
	+ 	 */
	+ 	ip = byteaddr(swimg, ZP);
	+ 	mp = byteaddr(swmask, ZP);
	+ 	for(i=0; i<32; i++){
	+ 		set = curs->set[i];
	+ 		clr = curs->clr[i];
	+ 		for(j=0x80; j; j>>=1){
	+ 			*ip++ = set&j ? 0x00 : 0xFF;
	+ 			*mp++ = (clr|set)&j ? 0xFF : 0x00;
	+ 		}
	+ 	}
	+ 	swoffset = curs->offset;
	+ 	swvers++;
	+ 	memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
	+ 	memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
	+ }
	+ 
	+ int
	+ swmove(VGAscr*, Point p)
	+ {
	+ 	swpt = addpt(p, swoffset);
	+ 	return 0;
	+ }
	+ 
	+ void
	+ swcursorclock(void)
	+ {
	+ 	int x;
	+ 
	+ 	if(!swenabled)
	+ 		return;
	+ 	if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
	+ 		return;
	+ 
	+ 	x = splhi();
	+ 	if(swenabled)
	+ 	if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
	+ 	if(canqlock(&drawlock)){
	+ 		swcursorhide();
	+ 		swcursordraw();
	+ 		qunlock(&drawlock);
	+ 	}
	+ 	splx(x);
	+ }
	+ 
	+ void
	+ swcursorinit(void)
	+ {
	+ 	static int init, warned;
	+ 	VGAscr *scr;
	+ 
	+ 	didswcursorinit = 1;
	+ 	if(!init){
	+ 		init = 1;
	+ 		addclock0link(swcursorclock, 50);
	+ 	}
	+ 	scr = &vgascreen[0];
	+ 	if(scr==nil || scr->gscreen==nil)
	+ 		return;
	+ 
	+ 	if(scr->dev == nil || scr->dev->linear == nil){
	+ 		if(!warned){
	+ 			print("cannot use software cursor on non-linear vga screen\n");
	+ 			warned = 1;
	+ 		}
	+ 		return;
	+ 	}
	+ 
	+ 	if(swback){
	+ 		freememimage(swback);
	+ 		freememimage(swmask);
	+ 		freememimage(swmask1);
	+ 		freememimage(swimg);
	+ 		freememimage(swimg1);
	+ 	}
	+ 
	+ 	swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
	+ 	swmask = allocmemimage(Rect(0,0,16,16), GREY8);
	+ 	swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
	+ 	swimg = allocmemimage(Rect(0,0,16,16), GREY8);
	+ 	swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
	+ 	if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
	+ 		print("software cursor: allocmemimage: %r");
	+ 		return;
	+ 	}
	+ 
	+ 	memfillcolor(swmask, DOpaque);
	+ 	memfillcolor(swmask1, DOpaque);
	+ 	memfillcolor(swimg, DBlack);
	+ 	memfillcolor(swimg1, DBlack);
	+ }
	+ 
	+ VGAcur swcursor =
	+ {
	+ 	"soft",
	+ 	swenable,
	+ 	swdisable,
	+ 	swload,
	+ 	swmove,
	+ };
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 4156 Nov  6 10:21 sys/src/9/pc/screen.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.h:67,73 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.h:67,73
	  	void	(*enable)(VGAscr*);
	  	void	(*disable)(VGAscr*);
	  	void	(*page)(VGAscr*, int);
	- 	ulong	(*linear)(VGAscr*, int*, int*);
	+ 	void	(*linear)(VGAscr*, int, int);
	  	void	(*drawinit)(VGAscr*);
	  	int	(*fill)(VGAscr*, Rectangle, ulong);
	  	void	(*ovlctl)(VGAscr*, Chan*, void*, int);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.h:91,96 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.h:91,97
	  struct VGAscr {
	  	Lock	devlock;
	  	VGAdev*	dev;
	+ 	Pcidev*	pci;
	  
	  	VGAcur*	cur;
	  	ulong	storage;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.h:98,113 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.h:99,114
	  
	  	int	useflush;
	  
	- 	ulong	aperture;			/* physical address */
	- 	int	isupamem;
	- 	int	apsize;
	+ 	ulong	paddr;		/* frame buffer */
	+ 	void*	vaddr;
	+ 	int		apsize;
	  
	  	ulong	io;				/* device specific registers */
	- 
	+ 	ulong	*mmio;
	+ 	
	  	ulong	colormap[Pcolours][3];
	  	int	palettedepth;
	  
	- 	ulong	*mmio;
	  	Memimage* gscreen;
	  	Memdata* gscreendata;
	  	Memsubfont* memdefont;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.h:128,133 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.h:129,135
	  
	  /* mouse.c */
	  extern void mousectl(Cmdbuf*);
	+ extern void mouseresize(void);
	  
	  /* screen.c */
	  extern int		hwaccel;	/* use hw acceleration; default on */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/screen.h:144,161 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/screen.h:146,179
	  extern Rectangle physgscreenr;	/* actual monitor size */
	  extern void	blankscreen(int);
	  
	+ extern VGAcur swcursor;
	+ extern void swcursorinit(void);
	+ extern void swcursorhide(void);
	+ extern void swcursoravoid(Rectangle);
	+ extern void swcursorunhide(void);
	+ 
	  /* devdraw.c */
	  extern void	deletescreenimage(void);
	+ extern void	resetscreenimage(void);
	  extern int		drawhasclients(void);
	  extern ulong	blanktime;
	  extern void	setscreenimageclipr(Rectangle);
	  extern void	drawflush(void);
	  extern int drawidletime(void);
	+ extern QLock	drawlock;
	  
	  /* vga.c */
	  extern void	vgascreenwin(VGAscr*);
	  extern void	vgaimageinit(ulong);
	- extern ulong	vgapcilinear(VGAscr*, int*, int*, int, int);
	+ extern void	vgalinearpciid(VGAscr*, int, int);
	+ extern void	vgalinearpci(VGAscr*);
	+ extern void	vgalinearaddr(VGAscr*, ulong, int);
	  
	  extern void	drawblankscreen(int);
	  extern void	vgablank(VGAscr*, int);
	+ 
	+ extern Lock	vgascreenlock;
	+ 
	+ 
	+ 
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 55206 Nov  6 10:22 sys/src/9/pc/sd53c8xx.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:52,59 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:52,60
	  
	  #else
	  
	- #define KPRINT	if(0) print
	- #define IPRINT	if(0) print
	+ static int idebug = 1;
	+ #define KPRINT	if(0) iprint
	+ #define IPRINT	if(idebug) iprint
	  #define DEBUG(n)	(0)
	  #define IFLUSH()
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:304,310 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:305,310
	  	struct {
	  		Lock;
	  		uchar head[4];		/* head of free list (NCR byte order) */
	- 		Dsa	*tail;
	  		Dsa	*freechain;
	  	} dsalist;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:383,388 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:383,417
	  
	  #include "sd53c8xx.i"
	  
	+ /*
	+  * We used to use a linked list of Dsas with nil as the terminator,
	+  * but occasionally the 896 card seems not to notice that the 0
	+  * is really a 0, and then it tries to reference the Dsa at address 0.
	+  * To address this, we use a sentinel dsa that links back to itself
	+  * and has state A_STATE_END.  If the card takes an iteration or
	+  * two to notice that the state says A_STATE_END, that's no big 
	+  * deal.  Clearly this isn't the right approach, but I'm just
	+  * stumped.  Even with this, we occasionally get prints about
	+  * "WSR set", usually with about the same frequency that the
	+  * card used to walk past 0. 
	+  */
	+ static Dsa *dsaend;
	+ 
	+ static Dsa*
	+ dsaallocnew(Controller *c)
	+ {
	+ 	Dsa *d;
	+ 	
	+ 	/* c->dsalist must be ilocked */
	+ 	d = xalloc(sizeof *d);
	+ 	lesetl(d->next, legetl(c->dsalist.head));
	+ 	lesetl(&d->stateb, A_STATE_FREE);
	+ 	coherence();
	+ 	lesetl(c->dsalist.head, DMASEG(d));
	+ 	coherence();
	+ 	return d;
	+ }
	+ 
	  static Dsa *
	  dsaalloc(Controller *c, int target, int lun)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:389,414 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:418,433
	  	Dsa *d;
	  
	  	ilock(&c->dsalist);
	- 	if ((d = c->dsalist.freechain) == 0) {
	- 		d = xalloc(sizeof(*d));
	- 		if (DEBUG(1)) {
	- 			KPRINT(PRINTPREFIX "%d/%d: allocated new dsa %lux\n", target, lun, (ulong)d);
	- 		}
	- 		lesetl(d->next, 0);
	- 		lesetl(&d->stateb, A_STATE_ALLOCATED);
	- 		if (legetl(c->dsalist.head) == 0)
	- 			lesetl(c->dsalist.head, DMASEG(d));	/* ATOMIC?!? */
	- 		else
	- 			lesetl(c->dsalist.tail->next, DMASEG(d));	/* ATOMIC?!? */
	- 		c->dsalist.tail = d;
	+ 	if ((d = c->dsalist.freechain) != 0) {
	+ 		if (DEBUG(1))
	+ 			IPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
	+ 	} else {	
	+ 		d = dsaallocnew(c);
	+ 		if (DEBUG(1))
	+ 			IPRINT(PRINTPREFIX "%d/%d: allocated dsa %lux\n", target, lun, (ulong)d);
	  	}
	- 	else {
	- 		if (DEBUG(1)) {
	- 			KPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
	- 		}
	- 		c->dsalist.freechain = d->freechain;
	- 		lesetl(&d->stateb, A_STATE_ALLOCATED);
	- 	}
	+ 	c->dsalist.freechain = d->freechain;
	+ 	lesetl(&d->stateb, A_STATE_ALLOCATED);
	  	iunlock(&c->dsalist);
	  	d->target = target;
	  	d->lun = lun;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:425,435 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:444,493
	  	iunlock(&c->dsalist);
	  }
	  
	+ static void
	+ dsadump(Controller *c)
	+ {
	+ 	Dsa *d;
	+ 	u32int *a;
	+ 	
	+ 	iprint("dsa controller list: c=%p head=%.8lux\n", c, legetl(c->dsalist.head));
	+ 	for(d=KPTR(legetl(c->dsalist.head)); d != dsaend; d=KPTR(legetl(d->next))){
	+ 		if(d == (void*)-1){
	+ 			iprint("\t dsa %p\n", d);
	+ 			break;
	+ 		}
	+ 		a = (u32int*)d;
	+ 		iprint("\tdsa %p %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux\n", a, a[0], a[1], a[2], a[3], a[4], a[5]);
	+ 	}
	+ 
	+ /*
	+ 	a = KPTR(c->scriptpa+E_dsa_addr);
	+ 	iprint("dsa_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n",
	+ 		a[0], a[1], a[2], a[3], a[4]);
	+ 	a = KPTR(c->scriptpa+E_issue_addr);
	+ 	iprint("issue_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n",
	+ 		a[0], a[1], a[2], a[3], a[4]);
	+ 
	+ 	a = KPTR(c->scriptpa+E_issue_test_begin);
	+ 	e = KPTR(c->scriptpa+E_issue_test_end);
	+ 	iprint("issue_test code (at offset %.8ux):\n", E_issue_test_begin);
	+ 	
	+ 	i = 0;
	+ 	for(; a<e; a++){
	+ 		iprint(" %.8ux", *a);
	+ 		if(++i%8 == 0)
	+ 			iprint("\n");
	+ 	}
	+ 	if(i%8)
	+ 		iprint("\n");
	+ */
	+ }
	+ 
	  static Dsa *
	  dsafind(Controller *c, uchar target, uchar lun, uchar state)
	  {
	  	Dsa *d;
	- 	for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
	+ 	for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
	  		if (d->target != 0xff && d->target != target)
	  			continue;
	  		if (lun != 0xff && d->lun != lun)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:764,769 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:822,828
	  	c->running = 1;
	  	p = c->scriptpa + entry;
	  	lesetl(c->n->dsp, p);
	+ 	coherence();
	  	if (c->ssm)
	  		c->n->dcntl |= 0x4;		/* start DMA in SSI mode */
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:775,780 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:834,840
	  		panic(PRINTPREFIX "ncrcontinue called while running");
	  	/* set the start DMA bit to continue execution */
	  	c->running = 1;
	+ 	coherence();
	  	c->n->dcntl |= 0x4;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1126,1131 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1186,1192
	  	int wakeme = 0;
	  	int cont = -1;
	  	Dsa *dsa;
	+ 	ulong dsapa;
	  	Controller *c = a;
	  	Ncr *n = c->n;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1143,1149 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1204,1210
	  		}
	  		n->istat = Intf;
	  		/* search for structures in A_STATE_DONE */
	- 		for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
	+ 		for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
	  			if (d->stateb == A_STATE_DONE) {
	  				d->p9status = d->status;
	  				if (DEBUG(1)) {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1168,1174 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1229,1253
	  
	  	sist = (n->sist1<<8)|n->sist0;	/* BUG? can two-byte read be inconsistent? */
	  	dstat = n->dstat;
	- 	dsa = (Dsa *)DMASEG_TO_KADDR(legetl(n->dsa));
	+ 	dsapa = legetl(n->dsa);
	+ 
	+ 	/*
	+ 	 * Can't compute dsa until we know that dsapa is valid.
	+ 	 */
	+ 	if(dsapa < -KZERO)
	+ 		dsa = (Dsa*)DMASEG_TO_KADDR(dsapa);
	+ 	else{
	+ 		dsa = nil;
	+ 		/*
	+ 		 * happens at startup on some cards but we 
	+ 		 * don't actually deref dsa because none of the
	+ 		 * flags we are about are set.
	+ 		 * still, print in case that changes and we're
	+ 		 * about to dereference nil.
	+ 		 */
	+ 		iprint("sd53c8xxinterrupt: dsa=%.8lux istat=%ux sist=%ux dstat=%ux\n", dsapa, istat, sist, dstat);
	+ 	}
	+ 
	  	c->running = 0;
	  	if (istat & Sip) {
	  		if (DEBUG(1)) {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1315,1320 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1394,1400
	  			}
	  			dsa->p9status = SDtimeout;
	  			dsa->stateb = A_STATE_DONE;
	+ 			coherence();
	  			softreset(c);
	  			cont = E_issue_check;
	  			wakeme = 1;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1336,1343 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1416,1422
	  			IPRINT("dstat = %.2x\n", dstat);
	  		}
	  		/*else*/ if (dstat & Ssi) {
	- 			ulong *p = DMASEG_TO_KADDR(legetl(n->dsp));
	- 			ulong w = (uchar *)p - (uchar *)c->script;
	+ 			ulong w = legetl(n->dsp) - c->scriptpa;
	  			IPRINT("[%lux]", w);
	  			USED(w);
	  			cont = -2;	/* restart */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1375,1380 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1454,1468
	  				dumpncrregs(c, 1);
	  				wakeme = 1;
	  				break;
	+ 			case A_SIR_NOTIFY_LOAD_STATE:
	+ 				IPRINT(PRINTPREFIX ": load_state dsa=%p\n", dsa);
	+ 				if (dsa == (void*)KZERO || dsa == (void*)-1) {
	+ 					dsadump(c);
	+ 					dumpncrregs(c, 1);
	+ 					panic("bad dsa in load_state");
	+ 				}
	+ 				cont = -2;
	+ 				break;
	  			case A_SIR_NOTIFY_MSG_IN:
	  				IPRINT(PRINTPREFIX "%d/%d: msg_in %d\n",
	  				    dsa->target, dsa->lun, n->sfbr);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1431,1437 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1519,1525
	  				cont = -2;
	  				break;
	  			case A_SIR_NOTIFY_ISSUE:
	- 				IPRINT(PRINTPREFIX "%d/%d: issue:", dsa->target, dsa->lun);
	+ 				IPRINT(PRINTPREFIX "%d/%d: issue dsa=%p end=%p:", dsa->target, dsa->lun, dsa, dsaend);
	  			dsadump:
	  				IPRINT(" tgt=%d", dsa->target);
	  				IPRINT(" time=%ld", TK2MS(m->ticks));
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1447,1453 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1535,1541
	  				cont = -2;
	  				break;
	  			case A_SIR_NOTIFY_DUMP_NEXT_CODE: {
	- 				ulong *dsp = DMASEG_TO_KADDR(legetl(n->dsp));
	+ 				ulong *dsp = c->script + (legetl(n->dsp)-c->scriptpa)/4;
	  				int x;
	  				IPRINT(PRINTPREFIX "code at %lux", dsp - c->script);
	  				for (x = 0; x < 6; x++) {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1475,1483 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1563,1571
	  				cont = -2;
	  				break;
	  			case A_error_reselected:		/* dsa isn't valid here */
	- 				print(PRINTPREFIX "reselection error\n");
	+ 				iprint(PRINTPREFIX "reselection error\n");
	  				dumpncrregs(c, 1);
	- 				for (dsa = KPTR(legetl(c->dsalist.head)); dsa; dsa = KPTR(legetl(dsa->next))) {
	+ 				for (dsa = KPTR(legetl(c->dsalist.head)); dsa != dsaend; dsa = KPTR(legetl(dsa->next))) {
	  					IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
	  				}
	  				break;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1489,1503 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1577,1616
	  			}
	  		}
	  		/*else*/ if (dstat & Iid) {
	- 			ulong addr = legetl(n->dsp);
	- 			ulong dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
	+ 			int i, target, lun;
	+ 			ulong addr, dbc, *v;
	+ 			
	+ 			addr = legetl(n->dsp);
	+ 			if(dsa){
	+ 				target = dsa->target;
	+ 				lun = dsa->lun;
	+ 			}else{
	+ 				target = -1;
	+ 				lun = -1;
	+ 			}
	+ 			dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
	+ 
	+ 		//	if(dsa == nil)
	+ 				idebug++;
	  			IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
	- 			    dsa->target, dsa->lun,
	+ 			    target, lun,
	  			    addr, addr - c->scriptpa, dbc);
	- 			addr = (ulong)DMASEG_TO_KADDR(addr);
	- 			IPRINT("%.8lux %.8lux %.8lux\n",
	- 			    *(ulong *)(addr - 12), *(ulong *)(addr - 8), *(ulong *)(addr - 4));
	+ 			addr = (ulong)c->script + addr - c->scriptpa;
	+ 			addr -= 64;
	+ 			addr &= ~63;
	+ 			v = (ulong*)addr;
	+ 			for(i=0; i<8; i++){
	+ 				IPRINT("%.8lux: %.8lux %.8lux %.8lux %.8lux\n", 
	+ 					addr, v[0], v[1], v[2], v[3]);
	+ 				addr += 4*4;
	+ 				v += 4;
	+ 			}
	  			USED(addr, dbc);
	+ 			if(dsa == nil){
	+ 				dsadump(c);
	+ 				dumpncrregs(c, 1);
	+ 				panic("bad dsa");
	+ 			}
	  			dsa->p9status = SDeio;
	  			wakeme = 1;
	  		}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1634,1639 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1747,1753
	  
	  	if((target = r->unit->subno) == 0x07)
	  		return r->status = SDtimeout;	/* assign */
	+ 
	  	c = r->unit->dev->ctlr;
	  
	  	check = 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1702,1708 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1816,1822
	  
	  	setmovedata(&d->msg_out_buf, DMASEG(d->msg_out), bc);
	  	setmovedata(&d->cmd_buf, DMASEG(r->cmd), r->clen);
	- 	calcblockdma(d, DMASEG(r->data), r->dlen);
	+ 	calcblockdma(d, r->data ? DMASEG(r->data) : 0, r->dlen);
	  
	  	if (DEBUG(0)) {
	  		KPRINT(PRINTPREFIX "%d/%d: exec: ", target, r->lun);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1722,1735 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1836,1850
	  
	  	d->p9status = SDnostatus;
	  	d->parityerror = 0;
	- 
	+ 	coherence();
	  	d->stateb = A_STATE_ISSUE;		/* start operation */
	+ 	coherence();
	  
	  	ilock(c);
	  	if (c->ssm)
	- 		c->n->dcntl |= 0x10;		/* SSI */
	+ 		c->n->dcntl |= 0x10;		/* single step */
	  	if (c->running) {
	- 		c->n->istat |= Sigp;
	+ 		c->n->istat = Sigp;
	  	}
	  	else {
	  		start(c, E_issue_check);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1802,1807 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1917,1923
	  		 * so the Dsa can be re-used.
	  		 */
	  		lesetl(&d->stateb, A_STATE_ALLOCATED);
	+ 		coherence();
	  		goto docheck;
	  	}
	  	qunlock(&c->q[target]);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1825,1836 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1941,1954
	  	return r->status = status;
	  }
	  
	+ #define	vpt ((ulong*)VPT)
	+ #define	VPTX(va)		(((ulong)(va))>>12)
	  static void
	  cribbios(Controller *c)
	  {
	  	c->bios.scntl3 = c->n->scntl3;
	  	c->bios.stest2 = c->n->stest2;
	- 	KPRINT(PRINTPREFIX "bios scntl3(%.2x) stest2(%.2x)\n", c->bios.scntl3, c->bios.stest2);
	+ 	print(PRINTPREFIX "bios scntl3(%.2x) stest2(%.2x)\n", c->bios.scntl3, c->bios.stest2);
	  }
	  
	  static int
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1879,1886 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:1997,2002
	  { SYM_1011_DID,   0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
	  };
	  
	- #define offsetof(s, t) ((ulong)&((s *)0)->t)
	- 
	  static int
	  xfunc(Controller *c, enum na_external x, unsigned long *v)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1968,1973 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2084,2090
	  	Controller *ctlr;
	  	SDev *sdev, *head, *tail;
	  	ulong regpa, *script, scriptpa;
	+ 	void *regva, *scriptva;
	  
	  	if(cp = getconf("*maxsd53c8xx"))
	  		nctlr = strtoul(cp, 0, 0);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:1995,2017 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2112,2138
	  				continue;
	  			ba++;
	  		}
	- 		regpa = upamalloc(regpa & ~0x0F, p->mem[1].size, 0);
	  		if(regpa == 0)
	+ 			print("regpa 0\n");
	+ 		regpa &= ~0xF;
	+ 		regva = vmap(regpa, p->mem[1].size);
	+ 		if(regva == 0)
	  			continue;
	  
	  		script = nil;
	  		scriptpa = 0;
	+ 		scriptva = nil;
	  		scriptma = nil;
	  		if((v->feature & LocalRAM) && sizeof(na_script) <= 4096){
	  			scriptpa = p->mem[ba].bar;
	  			if((scriptpa & 0x04) && p->mem[ba+1].bar){
	- 				upafree(regpa, p->mem[1].size);
	+ 				vunmap(regva, p->mem[1].size);
	  				continue;
	  			}
	- 			scriptpa = upamalloc(scriptpa & ~0x0F,
	- 					p->mem[ba].size, 0);
	- 			if(scriptpa)
	- 				script = KADDR(scriptpa);
	+ 			scriptpa &= ~0x0F;
	+ 			scriptva = vmap(scriptpa, p->mem[ba].size);
	+ 			if(scriptva)
	+ 				script = scriptva;
	  		}
	  		if(scriptpa == 0){
	  			/*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:2020,2026 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2141,2147
	  			 */
	  			scriptma = malloc(sizeof(na_script));
	  			if(scriptma == nil){
	- 				upafree(regpa, p->mem[1].size);
	+ 				vunmap(regva, p->mem[1].size);
	  				continue;
	  			}
	  			scriptpa = DMASEG(scriptma);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:2037,2049 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2158,2180
	  				free(sdev);
	  			if(scriptma)
	  				free(scriptma);
	- 			else
	- 				upafree(scriptpa, p->mem[ba].size);
	- 			upafree(regpa, p->mem[1].size);
	+ 			else if(scriptva)
	+ 				vunmap(scriptva, p->mem[ba].size);
	+ 			if(regva)
	+ 				vunmap(regva, p->mem[1].size);
	  			continue;
	  		}
	  
	- 		ctlr->n = KADDR(regpa);
	+ 		if(dsaend == nil)
	+ 			dsaend = xalloc(sizeof *dsaend);
	+ 		lesetl(&dsaend->stateb, A_STATE_END);
	+ 	//	lesetl(dsaend->next, DMASEG(dsaend));
	+ 		coherence();
	+ 		lesetl(ctlr->dsalist.head, DMASEG(dsaend));
	+ 		coherence();
	+ 		ctlr->dsalist.freechain = 0;
	+ 
	+ 		ctlr->n = regva;
	  		ctlr->v = v;
	  		ctlr->script = script;
	  		memmove(ctlr->script, na_script, sizeof(na_script));
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:2062,2080 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2193,2209
	  		}
	  		swabl(ctlr->script, ctlr->script, sizeof(na_script));
	  
	- 		ctlr->dsalist.freechain = 0;
	- 		lesetl(ctlr->dsalist.head, 0);
	- 
	  		ctlr->pcidev = p;
	  
	  		sdev->ifc = &sd53c8xxifc;
	  		sdev->ctlr = ctlr;
	+ 		sdev->idno = '0';
	  		if(!(v->feature & Wide))
	  			sdev->nunit = 8;
	  		else
	  			sdev->nunit = MAXTARGET;
	  		ctlr->sdev = sdev;
	- 
	+ 		
	  		if(head != nil)
	  			tail->next = sdev;
	  		else
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:2087,2098 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2216,2221
	  	return head;
	  }
	  
	- static SDev*
	- sd53c8xxid(SDev* sdev)
	- {
	- 	return scsiid(sdev, &sd53c8xxifc);
	- }
	- 
	  static int
	  sd53c8xxenable(SDev* sdev)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:2104,2116 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2227,2239
	  	pcidev = ctlr->pcidev;
	  
	  	pcisetbme(pcidev);
	- 	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
	- 	intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
	  
	  	ilock(ctlr);
	  	synctabinit(ctlr);
	  	cribbios(ctlr);
	  	reset(ctlr);
	+ 	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
	+ 	intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
	  	iunlock(ctlr);
	  
	  	return 1;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.c:2121,2127 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.c:2244,2249
	  
	  	sd53c8xxpnp,			/* pnp */
	  	nil,				/* legacy */
	- 	sd53c8xxid,			/* id */
	  	sd53c8xxenable,			/* enable */
	  	nil,				/* disable */
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 12657 Nov  6 10:22 sys/src/9/pc/sd53c8xx.n
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:54,59 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:54,60
	  SIR_NOTIFY_WSR = 115
	  SIR_NOTIFY_LOAD_SYNC = 116
	  SIR_NOTIFY_RESELECTED_ON_SELECT = 117
	+ SIR_NOTIFY_LOAD_STATE = 118
	  
	  STATE_FREE = 0
	  STATE_ALLOCATED = 1
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:60,65 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:61,67
	  STATE_ISSUE = 2
	  STATE_DISCONNECTED = 3
	  STATE_DONE = 4
	+ STATE_END = 5
	  
	  RESULT_OK = 0
	  	
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:76,82 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:78,84
	  BSIZE = 512
	  //BSIZE=4096
	  
	- idle:
	+  // idle:
	  	jump	wait_for_reselection	
	  start:
	  	call	load_sync
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:84,90 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:86,92
	  //	int	SIR_NOTIFY_ISSUE
	  	clear	target
	  	select	atn from scsi_id_buf, reselected_on_select // do I need to clear ATN here?
	- 	jump	start1, when msg_in
	+ 	jump	start1, when msg_in	// why is this here?
	  start1:
	  //	move	14 to ctest0
	  	move	from msg_out_buf, when msg_out
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:320,334 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:322,327
	   	move	memory 4, dsa_head, dsa
	  find_dsa_loop:
	  //	move	7 to ctest0
	- 	move	dsa0 to sfbr
	- 	jump	find_dsa_1, if not 0
	- 	move	dsa1 to sfbr
	- 	jump	find_dsa_1, if not 0
	- 	move	dsa2 to sfbr
	- 	jump	find_dsa_1, if not 0
	- 	move	dsa3 to sfbr
	- 	int	error_reselected, if 0			// couldn't match dsa (panic)
	- find_dsa_1:
	  //	move	8 to ctest0
	  	// load state from DSA into dsa_copy
	  	call	load_state
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:335,340 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:328,334
	  	move	memory 4, state, scratcha		// get dsastate in scratcha
	  	move	scratcha0 to sfbr			// and state variable in sfbr
	  	jump	find_dsa_next, if not STATE_DISCONNECTED // wrong state
	+ 	int	error_reselected, if STATE_END
	  	move	ssid & ssid_mask to sfbr			// get target ID
	  	move	memory 1, targ, find_dsa_smc1		// forge target comparison instruction
	  find_dsa_smc1:
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:350,355 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:344,350
	  // id_out terminated early
	  // most likely the message wasn't recognised
	  // clear ATN and accept the message in
	+ // called from sd53c8xx.c directly
	  id_out_mismatch_recover:
	  	clear	atn
	          jump    msg_in_phase, when msg_in
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:374,379 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:369,375
	  	jump	status_phase, if status
	  	jump	msg_in_phase, if msg_in
	  	int	error_unexpected_phase
	+ 
	  post_data_to_decisions:
	  	jump	status_phase, when status
	  	jump	msg_in_phase, if msg_in
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:398,403 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:394,423
	  dsa_save_len = dsa_save_end - dsa_copy
	  
	  load_state:
	+ //	int	SIR_NOTIFY_LOAD_STATE
	+ 	jump load_state_okay
	+ 
	+ 	move	dsa0 to sfbr
	+ 	jump load_state_okay, if not 0
	+ 	move	dsa1 to sfbr
	+ 	jump load_state_okay, if not 0
	+ 	move	dsa2 to sfbr
	+ 	jump load_state_okay, if not 0
	+ 	move	dsa3 to sfbr
	+ 	jump load_state_okay, if not 0
	+ 	// dsa is 0
	+ 	move	memory 4, dsa, dmaaddr
	+ 	move	memory 4, dsa, targ
	+ 	move	memory 4, dsa, lun
	+ 	move	memory 4, dsa, sync
	+ 	move	memory 4, dsa, next
	+ 	move	memory 4, dsa, scratcha
	+ 	move	STATE_END to sfbr
	+ 	move	sfbr to scratcha0
	+ 	move	memory 4, scratcha, state
	+ 	return
	+ 
	+ load_state_okay:
	  	// load state from DSA into dsa_copy
	  //	move	9 to ctest0
	  	move	memory 4, dsa, load_state_smc0 + 4
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:419,443 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:439,454
	  //	move	1 to ctest0
	  	move	memory 4, dsa_head, dsa
	  issue_check_loop:
	- //	move	2 to ctest0
	- 	move	dsa0 to sfbr
	- 	jump	issue_check_1, if not 0
	- 	move	dsa1 to sfbr
	- 	jump	issue_check_1, if not 0
	- 	move	dsa2 to sfbr
	- 	jump	issue_check_1, if not 0
	- 	move	dsa3 to sfbr
	- 	jump	wait_for_reselection, if 0		// nothing to do
	- issue_check_1:
	- //	move	3 to ctest0
	   	call	load_state
	  	move	memory 4, state, scratcha		// get dsastate in scratcha
	  	move	scratcha0 to sfbr			// and state variable in sfbr
	  	jump	start, if STATE_ISSUE			// right state
	- issue_check_next:
	- //	move	4 to ctest0
	+ 	jump	wait_for_reselection, if STATE_END
	+  //	move	4 to ctest0
	  	move	memory 4, next, dsa			// find next
	  	jump	issue_check_loop
	+ 
	+ 
	  load_sync:
	  	move	memory 4, sync, scratcha		// load the sync stuff
	  	move	scratcha0 to sfbr			// assuming load_state has been called
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sd53c8xx.n:444,448 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sd53c8xx.n:455,459
	  	move	sfbr to scntl3
	  	move	scratcha1 to sfbr
	  	move	sfbr to sxfer
	- //	int	SIR_NOTIFY_LOAD_SYNC
	+  //	int	SIR_NOTIFY_LOAD_SYNC
	  	return
 [rsc] --rw-rw-r-- M 451989 glenda sys 52168 Nov  6 10:22 sys/src/9/pc/sdata.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:9,14 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:9,17
	  
	  #include "../port/sd.h"
	  
	+ #define	HOWMANY(x, y)	(((x)+((y)-1))/(y))
	+ #define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))
	+ 
	  extern SDifc sdataifc;
	  
	  enum {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:254,267 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:257,271
	  typedef struct Ctlr Ctlr;
	  typedef struct Drive Drive;
	  
	- typedef struct Prd {
	+ typedef struct Prd {			/* Physical Region Descriptor */
	  	ulong	pa;			/* Physical Base Address */
	  	int	count;
	  } Prd;
	  
	  enum {
	- 	PRDmaxio	= 32*1024,	/* must be power of 2 <= 64*1024 */
	- 	Nprd		= SDmaxio/PRDmaxio+2,
	+ 	BMspan		= 64*1024,	/* must be power of 2 <= 64*1024 */
	+ 
	+ 	Nprd		= SDmaxio/BMspan+2,
	  };
	  
	  typedef struct Ctlr {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:270,275 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:274,281
	  	int	irq;
	  	int	tbdf;
	  	int	bmiba;			/* bus master interface base address */
	+ 	int	maxio;			/* sector count transfer maximum */
	+ 	int	span;			/* don't span this boundary with dma */
	  
	  	Pcidev*	pcidev;
	  	void	(*ienable)(Ctlr*);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:734,740 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:740,747
	  	SDev *sdev;
	  	Drive *drive;
	  	int dev, error, rhi, rlo;
	- 
	+ 	static int nonlegacy = 'C';
	+ 	
	  	if(ioalloc(cmdport, 8, 0, "atacmd") < 0) {
	  		print("ataprobe: Cannot allocate %X\n", cmdport);
	  		return nil;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:877,883 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:884,903
	  	ctlr->irq = irq;
	  	ctlr->tbdf = BUSUNKNOWN;
	  	ctlr->command = Cedd;		/* debugging */
	- 
	+ 	
	+ 	switch(cmdport){
	+ 	default:
	+ 		sdev->idno = nonlegacy;
	+ 		break;
	+ 	case 0x1F0:
	+ 		sdev->idno = 'C';
	+ 		nonlegacy = 'E';
	+ 		break;
	+ 	case 0x170:
	+ 		sdev->idno = 'D';
	+ 		nonlegacy = 'E';
	+ 		break;
	+ 	}
	  	sdev->ifc = &sdataifc;
	  	sdev->ctlr = ctlr;
	  	sdev->nunit = 2;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:921,932 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:941,966
	  static SDev*
	  ataprobew(DevConf *cf)
	  {
	+ 	char *p;
	+ 	ISAConf isa;
	+ 	
	  	if (cf->nports != 2)
	  		error(Ebadarg);
	  
	+ 	memset(&isa, 0, sizeof isa);
	+ 	isa.port = cf->ports[0].port;
	+ 	isa.irq = cf->intnum;
	+ 	if((p=strchr(cf->type, '/')) == nil || pcmspecial(p+1, &isa) < 0)
	+ 		error("cannot find controller");
	+ 
	  	return ataprobe(cf->ports[0].port, cf->ports[1].port, cf->intnum);
	  }
	  
	+ /*
	+  * These are duplicated with sdsetsense, etc., in devsd.c, but
	+  * those assume that the disk is not SCSI while in fact here
	+  * ata drives are not SCSI but ATAPI ones kind of are.
	+  */
	  static int
	  atasetsense(Drive* drive, int status, int key, int asc, int ascq)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:938,943 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:972,1004
	  }
	  
	  static int
	+ atamodesense(Drive* drive, uchar* cmd)
	+ {
	+ 	int len;
	+ 
	+ 	/*
	+ 	 * Fake a vendor-specific request with page code 0,
	+ 	 * return the drive info.
	+ 	 */
	+ 	if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
	+ 		return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
	+ 	len = (cmd[7]<<8)|cmd[8];
	+ 	if(len == 0)
	+ 		return SDok;
	+ 	if(len < 8+sizeof(drive->info))
	+ 		return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
	+ 	if(drive->data == nil || drive->dlen < len)
	+ 		return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
	+ 	memset(drive->data, 0, 8);
	+ 	drive->data[0] = sizeof(drive->info)>>8;
	+ 	drive->data[1] = sizeof(drive->info);
	+ 	memmove(drive->data+8, drive->info, sizeof(drive->info));
	+ 	drive->data += 8+sizeof(drive->info);
	+ 
	+ 	return SDok;
	+ }
	+ 
	+ static int
	  atastandby(Drive* drive, int period)
	  {
	  	Ctlr* ctlr;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:959,965 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1020,1026
	  
	  	while(waserror())
	  		;
	- 	tsleep(ctlr, atadone, ctlr, 30*1000);
	+ 	tsleep(ctlr, atadone, ctlr, 60*1000);
	  	poperror();
	  
	  	done = ctlr->done;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:970,1002 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1031,1036
	  	return SDok;
	  }
	  
	- static int
	- atamodesense(Drive* drive, uchar* cmd)
	- {
	- 	int len;
	- 
	- 	/*
	- 	 * Fake a vendor-specific request with page code 0,
	- 	 * return the drive info.
	- 	 */
	- 	if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
	- 		return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
	- 	len = (cmd[7]<<8)|cmd[8];
	- 	if(len == 0)
	- 		return SDok;
	- 	if(len < 8+sizeof(drive->info))
	- 		return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
	- 	if(drive->data == nil || drive->dlen < len)
	- 		return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
	- 	memset(drive->data, 0, 8);
	- 	drive->data[0] = sizeof(drive->info)>>8;
	- 	drive->data[1] = sizeof(drive->info);
	- 	memmove(drive->data+8, drive->info, sizeof(drive->info));
	- 	drive->data += 8+sizeof(drive->info);
	- 
	- 	return SDok;
	- }
	- 
	  static void
	  atanop(Drive* drive, int subcommand)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1055,1072 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1089,1106
	  	Prd *prd;
	  	ulong pa;
	  	Ctlr *ctlr;
	- 	int bmiba, bmisx, count;
	+ 	int bmiba, bmisx, count, i, span;
	  
	+ 	ctlr = drive->ctlr;
	  	pa = PCIWADDR(drive->data);
	  	if(pa & 0x03)
	  		return -1;
	- 	ctlr = drive->ctlr;
	- 	prd = ctlr->prdt;
	  
	  	/*
	  	 * Sometimes drives identify themselves as being DMA capable
	  	 * although they are not on a busmastering controller.
	  	 */
	+ 	prd = ctlr->prdt;
	  	if(prd == nil){
	  		drive->dmactl = 0;
	  		print("disabling dma: not on a busmastering controller\n");
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1073,1083 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1107,1120
	  		return -1;
	  	}
	  
	- 	for(;;){
	+ 	for(i = 0; len && i < Nprd; i++){
	  		prd->pa = pa;
	- 		count = PRDmaxio - (pa & (PRDmaxio-1));
	+ 		span = ROUNDUP(pa, ctlr->span);
	+ 		if(span == pa)
	+ 			span += ctlr->span;
	+ 		count = span - pa;
	  		if(count >= len){
	- 			prd->count = PrdEOT|(len & (PRDmaxio-1));
	+ 			prd->count = PrdEOT|len;
	  			break;
	  		}
	  		prd->count = count;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1085,1090 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1122,1129
	  		pa += count;
	  		prd++;
	  	}
	+ 	if(i == Nprd)
	+ 		(prd-1)->count |= PrdEOT;
	  
	  	bmiba = ctlr->bmiba;
	  	outl(bmiba+Bmidtpx, PCIWADDR(ctlr->prdt));
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1271,1277 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1310,1316
	  			break;
	  		ilock(ctlr);
	  		atadmainterrupt(drive, 0);
	- 		if(!drive->error && timeo > 10){
	+ 		if(!drive->error && timeo > 20){
	  			ataabort(drive, 0);
	  			atadmastop(ctlr);
	  			drive->dmactl = 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1389,1395 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1428,1435
	  	case Cws:
	  	case Cwsm:
	  		microdelay(1);
	- 		as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 1000);
	+ 		/* 10*1000 for flash ide drives - maybe detect them? */
	+ 		as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 10*1000);
	  		if(as < 0 || (as & Err)){
	  			iunlock(ctlr);
	  			return -1;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1430,1437 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1470,1477
	  {
	  	uchar *p;
	  	Ctlr *ctlr;
	- 	int count, max;
	  	vlong lba, len;
	+ 	int count, maxio;
	  
	  	/*
	  	 * Map SCSI commands into ATA commands for discs.
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1522,1528 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1562,1568
	  		*p++ = len>>16;
	  		*p++ = len>>8;
	  		*p = len;
	- 		drive->data += 8;
	+ 		drive->data += 12;
	  		return SDok;
	  
	  	case 0x28:			/* read */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1541,1550 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1581,1595
	  	if(drive->dlen < count*drive->secsize)
	  		count = drive->dlen/drive->secsize;
	  	qlock(ctlr);
	+ 	if(ctlr->maxio)
	+ 		maxio = ctlr->maxio;
	+ 	else if(drive->flags & Lba48)
	+ 		maxio = 65536;
	+ 	else
	+ 		maxio = 256;
	  	while(count){
	- 		max = (drive->flags&Lba48) ? 65536 : 256;
	- 		if(count > max)
	- 			drive->count = max;
	+ 		if(count > maxio)
	+ 			drive->count = maxio;
	  		else
	  			drive->count = count;
	  		if(atageniostart(drive, lba)){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1557,1563 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1602,1608
	  
	  		while(waserror())
	  			;
	- 		tsleep(ctlr, atadone, ctlr, 30*1000);
	+ 		tsleep(ctlr, atadone, ctlr, 60*1000);
	  		poperror();
	  		if(!ctlr->done){
	  			/*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1797,1804 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1842,1849
	  {
	  	Ctlr *ctlr;
	  	Pcidev *p;
	- 	int channel, ispc87415, pi, r;
	  	SDev *legacy[2], *sdev, *head, *tail;
	+ 	int channel, ispc87415, maxio, pi, r, span;
	  
	  	legacy[0] = legacy[1] = head = tail = nil;
	  	if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1839,1844 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1884,1891
	  			continue;
	  		pi = p->ccrp;
	  		ispc87415 = 0;
	+ 		maxio = 0;
	+ 		span = BMspan;
	  
	  		switch((p->did<<16)|p->vid){
	  		default:
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1868,1875 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1915,1925
	  		case (0x4D69<<16)|0x105A:	/* Promise Ultra/133 TX2 */
	  		case (0x3373<<16)|0x105A:	/* Promise 20378 RAID */
	  		case (0x3149<<16)|0x1106:	/* VIA VT8237 SATA/RAID */
	- 		case (0x3112<<16)|0x1095:   	/* SiL 3112 SATA (DMA busted?) */
	- 		case (0x3114<<16)|0x1095:	/* SiL 3114 SATA/RAID */
	+ 		case (0x3112<<16)|0x1095:   	/* SiI 3112 SATA/RAID */
	+ 			maxio = 15;
	+ 			span = 8*1024;
	+ 			/*FALLTHROUGH*/
	+ 		case (0x3114<<16)|0x1095:	/* SiI 3114 SATA/RAID */
	  			pi = 0x85;
	  			break;
	  		case (0x0004<<16)|0x1103:	/* HighPoint HPT366 */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1932,1937 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:1982,1988
	  				r &= ~0x2000;
	  				pcicfgw32(sb, 0x64, r);
	  			}
	+ 			span = 32*1024;
	  			break;
	  		case (0x5513<<16)|0x1039:	/* SiS 962 */
	  		case (0x0646<<16)|0x1095:	/* CMD 646 */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:1979,1984 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:2030,2037
	  				ctlr = sdev->ctlr;
	  
	  			ctlr->pcidev = p;
	+ 			ctlr->maxio = maxio;
	+ 			ctlr->span = span;
	  			if(!(pi & 0x80))
	  				continue;
	  			ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:2030,2075 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:2083,2088
	  	return ataprobe(port, port+0x204, irq);
	  }
	  
	- static SDev*
	- ataid(SDev* sdev)
	- {
	- 	int i;
	- 	Ctlr *ctlr;
	- 	char name[32];
	- 
	- 	/*
	- 	 * Legacy controllers are always 'C' and 'D' and if
	- 	 * they exist and have drives will be first in the list.
	- 	 * If there are no active legacy controllers, native
	- 	 * controllers start at 'C'.
	- 	 */
	- 	if(sdev == nil)
	- 		return nil;
	- 	ctlr = sdev->ctlr;
	- 	if(ctlr->cmdport == 0x1F0 || ctlr->cmdport == 0x170)
	- 		i = 2;
	- 	else
	- 		i = 0;
	- 	while(sdev){
	- 		if(sdev->ifc == &sdataifc){
	- 			ctlr = sdev->ctlr;
	- 			if(ctlr->cmdport == 0x1F0)
	- 				sdev->idno = 'C';
	- 			else if(ctlr->cmdport == 0x170)
	- 				sdev->idno = 'D';
	- 			else{
	- 				sdev->idno = 'C'+i;
	- 				i++;
	- 			}
	- 			snprint(name, sizeof(name), "sd%c", sdev->idno);
	- 			kstrdup(&sdev->name, name);
	- 		}
	- 		sdev = sdev->next;
	- 	}
	- 
	- 	return nil;
	- }
	- 
	  static int
	  ataenable(SDev* sdev)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdata.c:2230,2236 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdata.c:2243,2248
	  
	  	atapnp,				/* pnp */
	  	atalegacy,			/* legacy */
	- 	ataid,				/* id */
	  	ataenable,			/* enable */
	  	atadisable,			/* disable */
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 27737 Nov  6 10:23 sys/src/9/pc/sdmylex.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdmylex.c:1012,1017 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdmylex.c:1012,1018
	  		goto buggery;
	  	sdev->ifc = &sdmylexifc;
	  	sdev->ctlr = ctlr;
	+ 	sdev->idno = '0';
	  	ctlr->sdev = sdev;
	  	if(!ctlr->wide)
	  		sdev->nunit = 8;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdmylex.c:1089,1100 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdmylex.c:1090,1095
	  	return head;
	  }
	  
	- static SDev*
	- mylexid(SDev* sdev)
	- {
	- 	return scsiid(sdev, &sdmylexifc);
	- }
	- 
	  static int
	  mylex24enable(Ctlr* ctlr)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdmylex.c:1232,1238 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdmylex.c:1227,1232
	  
	  	mylexpnp,			/* pnp */
	  	nil,				/* legacy */
	- 	mylexid,			/* id */
	  	mylexenable,			/* enable */
	  	nil,				/* disable */
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 21180 Nov  6 14:44 sys/src/9/pc/trap.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:9,14 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:9,16
	  #include	"../port/error.h"
	  #include	<trace.h>
	  
	+ static int trapinited;
	+ 
	  void	noted(Ureg*, ulong);
	  
	  static void debugbpt(Ureg*, void*);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:175,182 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:177,189
	  	outb(0x61, x);
	  }
	  
	+ /*
	+  * Minimal trap setup.  Just enough so that we can panic
	+  * on traps (bugs) during kernel initialization.  
	+  * Called very early - malloc is not yet available.
	+  */
	  void
	- trapinit(void)
	+ trapinit0(void)
	  {
	  	int d1, v;
	  	ulong vaddr;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:204,210 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:211,221
	  		idt[v].d1 = d1;
	  		vaddr += 6;
	  	}
	+ }
	  
	+ void
	+ trapinit(void)
	+ {
	  	/*
	  	 * Special traps.
	  	 * Syscall() is called directly without going through trap().
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:216,221 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:227,233
	  	nmienable();
	  
	  	addarchfile("irqalloc", 0444, irqallocread, nil);
	+ 	trapinited = 1;
	  }
	  
	  static char* excname[32] = {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:306,311 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:318,330
	  	Vctl *ctl, *v;
	  	Mach *mach;
	  
	+ 	if(!trapinited){
	+ 		/* fault386 can give a better error message */
	+ 		if(ureg->trap == VectorPF)
	+ 			fault386(ureg, nil);
	+ 		panic("trap %lud: not ready", ureg->trap);
	+ 	}
	+ 
	  	m->perf.intrts = perfticks();
	  	user = (ureg->cs & 0xFFFF) == UESEL;
	  	if(user){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:507,513 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:526,532
	  	iprint("dumpstack\n");
	  
	  	x = 0;
	- 	x += print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp);
	+ 	x += print("ktrace /kernel/path %.8lux %.8lux <<EOF\n", ureg->pc, ureg->sp);
	  	i = 0;
	  	if(up
	  	&& (ulong)&l >= (ulong)up->kstack
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:522,528 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:541,547
	  
	  	for(l=(ulong)&l; l<estack; l+=4){
	  		v = *(ulong*)l;
	- 		if((KTZERO < v && v < (ulong)&etext) || estack-l<256){
	+ 		if((KTZERO < v && v < (ulong)&etext) || estack-l<32){
	  			/*
	  			 * we could Pick off general CALL (((uchar*)v)[-5] == 0xE8)
	  			 * and CALL indirect through AX (((uchar*)v)[-2] == 0xFF && ((uchar*)v)[-2] == 0xD0),
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:538,543 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:557,563
	  	}
	  	if(i)
	  		print("\n");
	+ 	print("EOF\n");
	  }
	  
	  void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:571,578 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:591,596
	  	print("unexpected trap %lud; ignoring\n", ureg->trap);
	  }
	  
	- extern void checkpages(void);
	- 
	  static void
	  fault386(Ureg* ureg, void*)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:581,592 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:599,618
	  	char buf[ERRMAX];
	  
	  	addr = getcr2();
	- 	user = (ureg->cs & 0xFFFF) == UESEL;
	- 	if(!user && mmukmapsync(addr))
	- 		return;
	  	read = !(ureg->ecode & 2);
	+ 
	+ 	user = (ureg->cs & 0xFFFF) == UESEL;
	+ 	if(!user){
	+ 		if(vmapsync(addr))
	+ 			return;
	+ 		if(addr >= USTKTOP)
	+ 			panic("kernel fault: bad address pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
	+ 		if(up == nil)
	+ 			panic("kernel fault: no user process pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
	+ 	}
	  	if(up == nil)
	- 		panic("fault but up is zero; pc 0x%8.8lux addr 0x%8.8lux\n", ureg->pc, addr);
	+ 		panic("user fault: up=0 pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
	+ 
	  	insyscall = up->insyscall;
	  	up->insyscall = 1;
	  	n = fault(addr, read);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:597,603 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:623,629
	  		}
	  		checkpages();
	  		sprint(buf, "sys: trap: fault %s addr=0x%lux",
	- 			read? "read" : "write", addr);
	+ 			read ? "read" : "write", addr);
	  		postnote(up, 1, buf, NDebug);
	  	}
	  	up->insyscall = insyscall;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/trap.c:887,892 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/trap.c:913,921
	  {
	  	ulong *sp;
	  	Ureg *ureg;
	+ 
	+ 	up->fpstate = FPinit;
	+ 	fpoff();
	  
	  	sp = (ulong*)(USTKTOP - ssize);
	  	*--sp = nargs;
 [rsc] --rw-rw-r-- M 451989 glenda sys 4030 Nov  6 10:23 sys/src/9/pc/vgai81x.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:49,142 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:49,92
	  	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;
	+ 	int 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)
	+ 	ulong *pgtbl, *rp, cursor, *pte, fbuf, fbend;
	+ 	
	+ 	if(scr->mmio)
	  		return;
	  	p = i81xpcimatch();
	  	if(p == nil)
	  		return;
	- 	scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
	- 	if(scr->io == 0)
	+ 	scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
	+ 	if(scr->mmio == 0)
	  		return;
	+ 	addvgaseg("i81xmmio", p->mem[1].bar&~0x0F, p->mem[1].size);
	  
	  	/* allocate page table */
	- 	pgtbl = PADDR(xspanalloc(64*1024, BY2PG, 0));
	- 	rp = KADDR(scr->io+0x2020);
	- 	*rp = pgtbl | 1;
	+ 	pgtbl = xspanalloc(64*1024, BY2PG, 0);
	+ 	scr->mmio[0x2020/4] = PADDR(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);
	+ 	if(size > 0)
	+ 		size = Fbsize;
	+ 	vgalinearaddr(scr, p->mem[0].bar&~0xF, size);
	+ 	addvgaseg("i81xscreen", p->mem[0].bar&~0xF, size);
	+ 
	+ 	/*
	+ 	 * allocate backing store for frame buffer
	+ 	 * and populate device page tables.
	+ 	 */
	+ 	fbuf = PADDR(xspanalloc(size, BY2PG, 0));
	+ 	fbend = PGROUND(fbuf+size);
	+ 	rp = scr->mmio+0x10000/4;
	+ 	while(fbuf < fbend) {
	+ 		*rp++ = fbuf | 1;
	+ 		fbuf += BY2PG;
	  	}
	  
	  	/*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:147,155 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:97,105
	  	mach0 = MACHP(0);
	  	pte = mmuwalk(mach0->pdb, cursor, 2, 0);
	  	if(pte == nil)
	- 		panic("i81x cursor");
	+ 		panic("i81x cursor mmuwalk");
	  	*pte |= PTEUNCACHED;
	- 	scr->storage = PADDR(cursor);
	+ 	scr->storage = cursor;
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:157,165 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:107,115
	  {
	  	CursorI81x *hwcurs;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	hwcurs = KADDR(scr->io+hwCur);
	+ 	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
	  	hwcurs->ctl = (1<<4);
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:170,178 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:120,128
	  	uchar *p;
	  	CursorI81x *hwcurs;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	hwcurs = KADDR(scr->io+hwCur);
	+ 	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
	  
	  	/*
	  	 * Disable the cursor then load the new image in
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:181,187 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:131,137
	  	 * transparent.
	  	 */
	  	hwcurs->ctl = (1<<4);
	- 	p = KADDR(scr->storage);
	+ 	p = (uchar*)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]);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:213,221 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:163,171
	  	ulong pos;
	  	CursorI81x *hwcurs;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	- 	hwcurs = KADDR(scr->io+hwCur);
	+ 	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
	  
	  	x = p.x+scr->offset.x;
	  	y = p.y+scr->offset.y;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:242,256 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:192,206
	  	CursorI81x *hwcurs;
	  
	  	i81xenable(scr);
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	hwcurs = KADDR(scr->io+hwCur);
	+ 	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
	  
	  	/*
	  	 * Initialise the 32x32 cursor to be transparent in 2bpp mode.
	  	 */
	- 	hwcurs->base = scr->storage;
	- 	p = KADDR(scr->storage);
	+ 	hwcurs->base = PADDR(scr->storage);
	+ 	p = (uchar*)scr->storage;
	  	for(i = 0; i < 32/2; i++) {
	  		memset(p, 0xff, 8);
	  		memset(p+8, 0, 8);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgai81x.c:269,275 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgai81x.c:219,225
	  	i81xenable,
	  	nil,
	  	nil,
	- 	i81xlinear,
	+ 	nil,
	  };
	  
	  VGAcur vgai81xcur = {
 [rsc] --rw-rw-r-- M 451989 rsc sys 2369 Nov  6 10:23 sys/src/9/pc/vgavesa.c
 [rsc] --rw-rw-r-- M 451989 presotto sys 7505 Nov  6 10:17 sys/src/9/pc/devlml.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devlml.c:127,132 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devlml.c:127,133
	  {
	  	Physseg segbuf;
	  	ulong regpa;
	+ 	void *regva;
	  	ISAConf isa;
	  	char name[32];
	  	Pcidev *pcidev;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/devlml.c:157,168 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/devlml.c:158,170
	  
	  		print("zr36067 found at 0x%.8lux", pcidev->mem[0].bar & ~0x0F);
	  
	- 		regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
	- 		if (regpa == 0) {
	+ 		regpa = pcidev->mem[0].bar & ~0x0F;
	+ 		regva = vmap(regpa, pcidev->mem[0].size, 0);
	+ 		if (regva == 0) {
	  			print("lml: failed to map registers\n");
	  			return;
	  		}
	- 		lml->pciBaseAddr = (ulong)KADDR(regpa);
	+ 		lml->pciBaseAddr = (ulong)regva;
	  		print(", mapped at 0x%.8lux\n", lml->pciBaseAddr);
	  
	  		memset(&segbuf, 0, sizeof(segbuf));
 [rsc] --rw-rw-r-- M 451989 jmk sys 22723 Nov  6 10:19 sys/src/9/pc/ether8169.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8169.c:357,363 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8169.c:357,364
	  		ctlr->mii = nil;
	  		return -1;
	  	}
	- 	print("oui %X phyno %d\n", phy->oui, phy->phyno);
	+ 	USED(phy);
	+ 	// print("oui %X phyno %d\n", phy->oui, phy->phyno);
	  
	  	miiane(ctlr->mii, ~0, ~0, ~0);
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8169.c:451,458 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8169.c:452,459
	  	l += snprint(p+l, READSTR-l, "punlc: %ud\n", ctlr->punlc);
	  	l += snprint(p+l, READSTR-l, "fovw: %ud\n", ctlr->fovw);
	  
	- 	l += snprint(p+l, READSTR-l, "tcr: %8.8uX\n", ctlr->tcr);
	- 	l += snprint(p+l, READSTR-l, "rcr: %8.8uX\n", ctlr->rcr);
	+ 	l += snprint(p+l, READSTR-l, "tcr: %#8.8ux\n", ctlr->tcr);
	+ 	l += snprint(p+l, READSTR-l, "rcr: %#8.8ux\n", ctlr->rcr);
	  
	  	if(ctlr->mii != nil && ctlr->mii->curphy != nil){
	  		l += snprint(p+l, READSTR, "phy:   ");
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8169.c:460,466 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8169.c:461,467
	  			if(i && ((i & 0x07) == 0))
	  				l += snprint(p+l, READSTR-l, "\n       ");
	  			r = miimir(ctlr->mii, i);
	- 			l += snprint(p+l, READSTR-l, " %4.4uX", r);
	+ 			l += snprint(p+l, READSTR-l, " %4.4ux", r);
	  		}
	  		snprint(p+l, READSTR-l, "\n");
	  	}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8169.c:811,817 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8169.c:812,818
	  		else{
	  			/*
	  			 * Error stuff here.
	- 			print("control %8.8uX\n", control);
	+ 			print("control %#8.8ux\n", control);
	  			 */
	  		}
	  		d->control &= Eor;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8169.c:865,871 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8169.c:866,872
	  		 * Some of the reserved bits get set sometimes...
	  		 */
	  		if(isr & (Serr|Timeout|Tdu|Fovw|Punlc|Rdu|Ter|Tok|Rer|Rok))
	- 			panic("rtl8169interrupt: imr %4.4uX isr %4.4uX\n",
	+ 			panic("rtl8169interrupt: imr %#4.4ux isr %#4.4ux\n",
	  				csr16r(ctlr, Imr), isr);
	  	}
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ether8169.c:892,898 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ether8169.c:893,899
	  			continue;
	  
	  		if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
	- 			print("rtl8169: port 0x%uX in use\n", port);
	+ 			print("rtl8169: port %#ux in use\n", port);
	  			continue;
	  		}
	  
 [rsc] --rw-rw-r-- M 451989 jmk sys 29128 Nov  6 10:19 sys/src/9/pc/etherdp83820.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherdp83820.c:1114,1120 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherdp83820.c:1114,1120
	  static void
	  dp83820pci(void)
	  {
	- 	int port;
	+ 	void *mem;
	  	Pcidev *p;
	  	Ctlr *ctlr;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherdp83820.c:1130,1147 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherdp83820.c:1130,1147
	  			break;
	  		}
	  
	- 		port = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
	- 		if(port == 0){
	+ 		mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
	+ 		if(mem == 0){
	  			print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
	  			continue;
	  		}
	  
	  		ctlr = malloc(sizeof(Ctlr));
	- 		ctlr->port = port;
	+ 		ctlr->port = p->mem[1].bar & ~0x0F;
	  		ctlr->pcidev = p;
	  		ctlr->id = (p->did<<16)|p->vid;
	  
	- 		ctlr->nic = KADDR(ctlr->port);
	+ 		ctlr->nic = mem;
	  		if(dp83820reset(ctlr)){
	  			free(ctlr);
	  			continue;
 [rsc] --rw-rw-r-- M 451989 presotto sys 28748 Nov  6 10:19 sys/src/9/pc/etherga620.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherga620.c:758,764 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherga620.c:758,764
	  	 * memory it is accessed via the Local Memory Window; with a send
	  	 * ring size of 128 the window covers the whole ring and then need
	  	 * only be set once:
	- 	 *	ctlr->sr = KADDR(ctlr->port+Lmw);
	+ 	 *	ctlr->sr = (uchar*)ctlr->nic+Lmw;
	  	 *	ga620lmw(ctlr, Sr, nil, sizeof(Sbd)*Nsr);
	  	 *	ctlr->gib->srcb.addr.lo = Sr;
	  	 * There is nowhere in the Sbd to hold the Block* associated
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherga620.c:1114,1120 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherga620.c:1114,1120
	  static void
	  ga620pci(void)
	  {
	- 	int port;
	+ 	void *mem;
	  	Pcidev *p;
	  	Ctlr *ctlr;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/etherga620.c:1135,1152 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/etherga620.c:1135,1152
	  			break;
	  		}
	  
	- 		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
	- 		if(port == 0){
	+ 		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
	+ 		if(mem == 0){
	  			print("ga620: can't map %8.8luX\n", p->mem[0].bar);
	  			continue;
	  		}
	  
	  		ctlr = malloc(sizeof(Ctlr));
	- 		ctlr->port = port;
	+ 		ctlr->port = p->mem[0].bar & ~0x0F;
	  		ctlr->pcidev = p;
	  		ctlr->id = (p->did<<16)|p->vid;
	  
	- 		ctlr->nic = KADDR(ctlr->port);
	+ 		ctlr->nic = mem;
	  		if(ga620reset(ctlr)){
	  			free(ctlr);
	  			continue;
 [rsc] --rw-rw-r-- M 451989 jmk sys 22572 Nov  6 10:19 sys/src/9/pc/ethervt6102.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/ethervt6102.c:925,931 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/ethervt6102.c:925,931
	  		ctlr->mii = nil;
	  		return -1;
	  	}
	- 	print("oui %X phyno %d\n", phy->oui, phy->phyno);
	+ 	// print("oui %X phyno %d\n", phy->oui, phy->phyno);
	  
	  	//miiane(ctlr->mii, ~0, ~0, ~0);
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 1418 Nov  6 10:21 sys/src/9/pc/pccd
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pccd:61,66 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pccd:61,67
	  	usbuhci
	  
	  misc
	+ 	realmode
	  	archmp		mp apic
	  
	  	sdata		pci sdscsi
 [rsc] --rw-rw-r-- M 451989 presotto sys 1486 Nov  6 12:59 sys/src/9/pc/pccpuf
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pccpuf:58,63 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pccpuf:58,64
	  	usbuhci
	  
	  misc
	+ 	realmode
	  	archmp		mp apic
	  
	  	uarti8250
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pccpuf:86,91 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pccpuf:87,93
	  	vgat2r4		+cur
	  	vgatvp3020	=cur
	  	vgatvp3026	=cur
	+ 	vgavesa
	  	vgavmware	+cur
	  
	  
 [rsc] --rw-rw-r-- M 451989 rsc sys 1473 Nov  6 12:59 sys/src/9/pc/pcflop
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcflop:62,67 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcflop:62,68
	  #	usbuhci
	  
	  misc
	+ 	realmode
	  #	archmp		mp apic
	  
	  	sdata		pci sdscsi
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/pcflop:91,96 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/pcflop:92,98
	  	vgat2r4		+cur
	  	vgatvp3020	=cur
	  	vgatvp3026	=cur
	+ 	vgavesa
	  	vgavmware	+cur
	  
	  ip
 [rsc] --rw-rw-r-- M 451989 rsc sys 25780 Nov  6 10:23 sys/src/9/pc/sdmv50xx.c
 [rsc] --rw-rw-r-- M 451989 glenda sys 5148 Nov  6 10:23 sys/src/9/pc/vga.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga.c:18,24 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga.c:19,25
	  static Rectangle window;
	  static int *xp;
	  static int xbuf[256];
	- static Lock vgascreenlock;
	+ Lock vgascreenlock;
	  int drawdebug;
	  
	  void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga.c:136,142 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga.c:137,143
	  static void
	  vgascreenputs(char* s, int n)
	  {
	- 	int i;
	+ 	int i, gotdraw;
	  	Rune r;
	  	char buf[4];
	  	VGAscr *scr;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga.c:155,160 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga.c:156,167
	  	else
	  		lock(&vgascreenlock);
	  
	+ 	/*
	+ 	 * Be nice to hold this, but not going to deadlock
	+ 	 * waiting for it.  Just try and see.
	+ 	 */
	+ 	gotdraw = canqlock(&drawlock);
	+ 
	  	flushr = Rect(10000, 10000, -10000, -10000);
	  
	  	while(n > 0){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga.c:172,177 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga.c:179,186
	  	}
	  	flushmemscreen(flushr);
	  
	+ 	if(gotdraw)
	+ 		qunlock(&drawlock);
	  	unlock(&vgascreenlock);
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga.c:241,247 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga.c:250,256
	  	Point p;
	  
	  	scr = &vgascreen[0];
	- 	if(scr->aperture == 0 || screenputs != vgascreenputs)
	+ 	if(scr->vaddr == nil || screenputs != vgascreenputs)
	  		return;
	  	p = memsubfontwidth(scr->memdefont, s);
	  	w = p.x;
 [rsc] --rw-rw-r-- M 451989 glenda sys 3833 Nov  6 10:23 sys/src/9/pc/vga3dfx.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:28,93 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:28,40
	  	hwCur		= 0x5C,
	  };
	  
	- static ulong
	- tdfxlinear(VGAscr* scr, int* size, int* align)
	- {
	- 	Pcidev *p;
	- 	int oapsize, wasupamem;
	- 	ulong aperture, oaperture;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	aperture = 0;
	- 	if(p = pcimatch(nil, 0x121A, 0)){
	- 		switch(p->did){
	- 		case 0x0003:		/* Banshee */
	- 		case 0x0005:		/* Avenger (a.k.a. Voodoo3) */
	- 		case 0x0009:		/* Voodoo5 */
	- 			aperture = p->mem[1].bar & ~0x0F;
	- 			*size = p->mem[1].size;
	- 			break;
	- 		default:
	- 			break;
	- 		}
	- 	}
	- 
	- 	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;
	- 
	- 	return aperture;
	- }
	- 
	  static void
	  tdfxenable(VGAscr* scr)
	  {
	  	Pcidev *p;
	- 	ulong aperture;
	- 	int align, i, *mmio, size;
	+ 	int i, *mmio;
	  
	- 	/*
	- 	 * Only once, can't be disabled for now.
	- 	 * scr->io holds the physical address of
	- 	 * the MMIO registers.
	- 	 */
	- 	if(scr->io)
	+ 	if(scr->mmio)
	  		return;
	  	if(p = pcimatch(nil, 0x121A, 0)){
	  		switch(p->did){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:100,120 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:47,63
	  	}
	  	else
	  		return;
	- 	scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
	- 	if(scr->io == 0)
	+ 	
	+ 	scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
	+ 	if(scr->mmio == nil)
	  		return;
	+ 	scr->pci = p;
	+ 	
	+ 	addvgaseg("3dfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size);
	+ 	vgalinearpci(scr);
	+ 	if(scr->apsize)
	+ 		addvgaseg("3dfxscreen", scr->paddr, scr->apsize);
	  
	- 	addvgaseg("3dfxmmio", (ulong)scr->io, p->mem[0].size);
	- 
	- 	size = p->mem[1].size;
	- 	align = 0;
	- 	aperture = tdfxlinear(scr, &size, &align);
	- 	if(aperture){
	- 		scr->aperture = aperture;
	- 		scr->apsize = size;
	- 		addvgaseg("3dfxscreen", aperture, size);
	- 	}
	- 
	  	/*
	  	 * Find a place for the cursor data in display memory.
	  	 * If SDRAM then there's 16MB memory else it's SGRAM
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:123,129 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:66,72
	  	 * 8 of them.
	  	 * Use the last 1KB of the framebuffer.
	  	 */
	- 	mmio = KADDR(scr->io + dramInit0);
	+ 	mmio = (void*)((uchar*)scr->mmio+dramInit0);
	  	if(*(mmio+1) & 0x40000000)
	  		i = 16*1024*1024;
	  	else{
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:144,152 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:87,95
	  {
	  	Cursor3dfx *cursor3dfx;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursor3dfx = KADDR(scr->io+hwCur);
	+ 	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
	  	cursor3dfx->vidProcCfg &= ~0x08000000;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:157,165 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:100,108
	  	uchar *p;
	  	Cursor3dfx *cursor3dfx;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursor3dfx = KADDR(scr->io+hwCur);
	+ 	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
	  
	  	/*
	  	 * Disable the cursor then load the new image in
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:177,183 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:120,126
	  	 * transparent.
	  	 */
	  	cursor3dfx->vidProcCfg &= ~0x08000000;
	- 	p = KADDR(scr->aperture + scr->storage);
	+ 	p = (uchar*)scr->vaddr + scr->storage;
	  	for(y = 0; y < 16; y++){
	  		*p++ = curs->clr[2*y]|curs->set[2*y];
	  		*p++ = curs->clr[2*y+1]|curs->set[2*y+1];
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:201,209 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:144,152
	  {
	  	Cursor3dfx *cursor3dfx;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	- 	cursor3dfx = KADDR(scr->io+hwCur);
	+ 	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
	  
	  	cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x);
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:216,224 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:159,167
	  	Cursor3dfx *cursor3dfx;
	  
	  	tdfxenable(scr);
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursor3dfx = KADDR(scr->io+hwCur);
	+ 	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
	  
	  	/*
	  	 * Cursor colours.
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:230,236 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:173,179
	  	 * Initialise the 64x64 cursor to be transparent (X11 mode).
	  	 */
	  	cursor3dfx->hwCurPatAddr = scr->storage;
	- 	memset(KADDR(scr->aperture + scr->storage), 0, 64*16);
	+ 	memset((uchar*)scr->vaddr + scr->storage, 0, 64*16);
	  
	  	/*
	  	 * Load, locate and enable the 64x64 cursor in X11 mode.
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vga3dfx.c:246,252 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vga3dfx.c:189,195
	  	tdfxenable,
	  	nil,
	  	nil,
	- 	tdfxlinear,
	+ 	nil,
	  };
	  
	  VGAcur vga3dfxcur = {
 [rsc] --rw-rw-r-- M 451989 glenda sys 3422 Nov  6 10:23 sys/src/9/pc/vgaark2000pv.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaark2000pv.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaark2000pv.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaark2000pv.c:90,96 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaark2000pv.c:91,97
	  	 */
	  	seq10 = vgaxi(Seqx, 0x10);
	  	opage = 0;
	- 	p = KADDR(scr->aperture);
	+ 	p = scr->vaddr;
	  	if(!(seq10 & 0x10)){
	  		lock(&scr->devlock);
	  		opage = ark2000pvpageset(scr, scr->storage>>16);
 [rsc] --rw-rw-r-- M 451989 glenda sys 5057 Nov  6 10:23 sys/src/9/pc/vgabt485.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgabt485.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgabt485.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
 [rsc] --rw-rw-r-- M 451989 glenda sys 4550 Nov  6 10:23 sys/src/9/pc/vgaclgd542x.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd542x.c:41,76 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd542x.c:41,50
	  	unlock(&scr->devlock);
	  }
	  
	- static ulong
	- clgd542xlinear(VGAscr* scr, int* size, int* align)
	+ static void
	+ clgd542xlinear(VGAscr* scr, int, int)
	  {
	- 	ulong aperture, oaperture;
	- 	int oapsize, wasupamem;
	- 	Pcidev *p;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 	if(wasupamem)
	- 		upafree(oaperture, oapsize);
	- 	scr->isupamem = 0;
	- 
	- 	if(p = pcimatch(nil, 0x1013, 0)){
	- 		aperture = p->mem[0].bar & ~0x0F;
	- 		*size = p->mem[0].size;
	- 	}
	- 	else
	- 		aperture = 0;
	- 
	- 	aperture = upamalloc(aperture, *size, *align);
	- 	if(aperture == 0){
	- 		if(wasupamem && upamalloc(oaperture, oapsize, 0))
	- 			scr->isupamem = 1;
	- 	}
	- 	else
	- 		scr->isupamem = 1;
	- 
	- 	return aperture;
	+ 	vgalinearpciid(scr, 0x1013, 0);
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd542x.c:171,177 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd542x.c:145,151
	  	 */
	  	seq07 = vgaxi(Seqx, 0x07);
	  	opage = 0;
	- 	p = KADDR(scr->aperture);
	+ 	p = scr->vaddr;
	  	if(!(seq07 & 0xF0)){
	  		lock(&scr->devlock);
	  		opage = clgd542xpageset(scr, scr->storage>>16);
 [rsc] --rw-rw-r-- M 451989 glenda sys 3716 Nov  6 10:23 sys/src/9/pc/vgaclgd546x.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd546x.c:26,118 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd546x.c:26,60
	  	CursorMMIO	= 0xE0,
	  };
	  
	- static ulong
	- clgd546xlinear(VGAscr* scr, int* size, int* align)
	+ static void
	+ clgd546xlinear(VGAscr* scr, int, int)
	  {
	- 	ulong aperture, oaperture;
	- 	int oapsize, wasupamem;
	- 	Pcidev *p;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	aperture = 0;
	- 	if(p = pcimatch(nil, 0x1013, 0)){
	- 		switch(p->did){
	- 		case 0xD0:
	- 		case 0xD4:
	- 		case 0xD6:
	- 			aperture = p->mem[0].bar & ~0x0F;
	- 			*size = p->mem[0].size;
	- 			break;
	- 		default:
	- 			break;
	- 		}
	- 	}
	- 
	- 	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;
	- 
	- 	return aperture;
	+ 	vgalinearpci(scr);
	  }
	+ 
	  static void
	  clgd546xenable(VGAscr* scr)
	  {
	  	Pcidev *p;
	- 	int size, align;
	- 	ulong aperture;
	  
	- 	/*
	- 	 * Only once, can't be disabled for now.
	- 	 * scr->io holds the virtual address of
	- 	 * the MMIO registers.
	- 	 */
	- 	if(scr->io)
	+ 	if(scr->mmio)
	  		return;
	- 	if(p = pcimatch(nil, 0x1013, 0)){
	- 		switch(p->did){
	- 		case 0xD0:
	- 		case 0xD4:
	- 		case 0xD6:
	- 			break;
	- 		default:
	- 			return;
	- 		}
	- 	}
	- 	else
	+ 	if((p = pcimatch(nil, 0x1013, 0)) == nil)
	  		return;
	- 	scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
	- 	if(scr->io == 0)
	+ 	switch(p->did){
	+ 	case 0xD0:
	+ 	case 0xD4:
	+ 	case 0xD6:
	+ 		break;
	+ 	default:
	  		return;
	- 	addvgaseg("clgd546xmmio", scr->io, p->mem[1].size);
	- 
	- 	scr->io = (ulong)KADDR(scr->io);
	- 
	- 	size = p->mem[0].size;
	- 	align = 0;
	- 	aperture = clgd546xlinear(scr, &size, &align);
	- 	if(aperture) {
	- 		scr->aperture = aperture;
	- 		scr->apsize = size;
	- 		addvgaseg("clgd546xscreen", aperture, size);
	  	}
	+ 
	+ 	scr->pci = p;
	+ 	scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
	+ 	if(scr->mmio == 0)
	+ 		return;
	+ 	addvgaseg("clgd546xmmio", p->mem[1].bar&~0x0F, p->mem[1].size);
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd546x.c:120,128 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd546x.c:62,70
	  {
	  	Cursor546x *cursor546x;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
	+ 	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
	  	cursor546x->enable = 0;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd546x.c:133,141 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd546x.c:75,83
	  	uchar *p;
	  	Cursor546x *cursor546x;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
	+ 	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
	  
	  	/*
	  	 * Disable the cursor then change only the bits
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd546x.c:142,148 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd546x.c:84,90
	  	 * that need it.
	  	 */
	  	cursor546x->enable = 0;
	- 	p = (uchar*)(scr->aperture + scr->storage);
	+ 	p = (uchar*)scr->vaddr + scr->storage;
	  	for(y = 0; y < 16; y++){
	  		c = curs->set[2*y];
	  		m = 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd546x.c:189,197 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd546x.c:131,139
	  	int x, xo, y, yo;
	  	Cursor546x *cursor546x;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	- 	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
	+ 	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
	  
	  	if((x = p.x+scr->offset.x) < 0){
	  		xo = -x;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd546x.c:220,234 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd546x.c:162,176
	  	Cursor546x *cursor546x;
	  
	  	clgd546xenable(scr);
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
	+ 	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
	  
	  	/*
	  	 * Cursor colours.
	  	 * Can't call setcolor here as cursor is already locked.
	  	 */
	- 	p = (uchar*)(scr->io+PaletteState);
	+ 	p = (uchar*)scr->mmio+PaletteState;
	  	*p |= 0x08;
	  	vgao(PaddrW, 0x00);
	  	vgao(Pdata, Pwhite);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaclgd546x.c:248,254 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaclgd546x.c:190,196
	  	 */
	  	scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
	  	cursor546x->addr = (scr->storage>>10)<<2;
	- 	memset((uchar*)(scr->aperture + scr->storage), 0, 2*64*16);
	+ 	memset((uchar*)scr->vaddr + scr->storage, 0, 2*64*16);
	  
	  	/*
	  	 * Load, locate and enable the 64x64 cursor.
 [rsc] --rw-rw-r-- M 451989 glenda sys 2249 Nov  6 10:23 sys/src/9/pc/vgact65545.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgact65545.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgact65545.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgact65545.c:52,58 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgact65545.c:53,59
	  	uint and, clr, set, xor;
	  	int i, x, y;
	  
	- 	mem = KADDR(scr->aperture);
	+ 	mem = scr->vaddr;
	  	mem += scr->storage + index*1024;
	  
	  	for(y = yo; y < 16; y++){
 [rsc] --rw-rw-r-- M 451989 glenda sys 3707 Nov  6 10:23 sys/src/9/pc/vgacyber938x.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgacyber938x.c:38,87 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgacyber938x.c:38,65
	  	unlock(&scr->devlock);
	  }
	  
	- static ulong
	- cyber938xlinear(VGAscr* scr, int* size, int* align)
	+ static void
	+ cyber938xlinear(VGAscr* scr, int, int)
	  {
	- 	ulong aperture, oaperture;
	- 	int oapsize, wasupamem;
	- 	int osize;
	  	Pcidev *p;
	  
	- 	osize = *size;
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 	if(wasupamem)
	- 		upafree(oaperture, oapsize);
	- 	scr->isupamem = 0;
	- 	scr->mmio = 0;
	+ 	if(scr->vaddr)
	+ 		return;
	+ 	
	+ 	vgalinearpciid(scr, 0x1023, 0);
	+ 	p = scr->pci;
	  
	- 	if(p = pcimatch(nil, 0x1023, 0)){
	- 		aperture = p->mem[0].bar & ~0x0F;
	- 		*size = p->mem[0].size;
	- 		/*
	- 		 * Heuristic to detect the MMIO space.  We're flying blind
	- 		 * here, with only the XFree86 source to guide us.
	- 		 */
	- 		if(p->mem[1].size == 0x20000)
	- 			scr->mmio = (ulong*)(p->mem[1].bar & ~0x0F);
	- 	}
	- 	else
	- 		aperture = 0;
	+ 	/*
	+ 	 * Heuristic to detect the MMIO space.  We're flying blind
	+ 	 * here, with only the XFree86 source to guide us.
	+ 	 */
	+ 	if(p->mem[1].size == 0x20000)
	+ 		scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
	  
	- 	aperture = upamalloc(aperture, *size, *align);
	- 	if(aperture == 0){
	- 		if(wasupamem && upamalloc(oaperture, oapsize, 0))
	- 			scr->isupamem = 1;
	- 	}
	- 	else
	- 		scr->isupamem = 1;
	- 
	- 	if(aperture)
	- 		addvgaseg("cyber938xscreen", aperture, osize);
	+ 	if(scr->apsize)
	+ 		addvgaseg("cyber938xscreen", scr->paddr, scr->apsize);
	  	if(scr->mmio)
	- 		addvgaseg("cyber938xmmio", (ulong)scr->mmio, 0x20000);
	- 
	- 	return aperture;
	+ 		addvgaseg("cyber938xmmio", p->mem[1].bar&~0x0F, 0x20000);
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgacyber938x.c:99,105 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgacyber938x.c:77,83
	  	cyber938xcurdisable(scr);
	  
	  	opage = 0;
	- 	p = KADDR(scr->aperture);
	+ 	p = scr->vaddr;
	  	islinear = vgaxi(Crtx, 0x21) & 0x20;
	  	if(!islinear){
	  		lock(&scr->devlock);
 [rsc] --rw-rw-r-- M 451989 glenda sys 5111 Nov  6 10:23 sys/src/9/pc/vgaet4000.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaet4000.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaet4000.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgaet4000.c:139,145 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgaet4000.c:140,146
	  	et4000disable(scr);
	  
	  	setet4000page(scr->storage>>16);
	- 	mem = (uchar*)KADDR(scr->aperture) + (scr->storage & 0xFFFF);
	+ 	mem = (uchar*)scr->vaddr + (scr->storage & 0xFFFF);
	  
	  	/*
	  	 * Initialise the 64x64 cursor RAM array. There are 2 planes,
 [rsc] --rw-rw-r-- M 451989 glenda sys 4098 Nov  6 10:23 sys/src/9/pc/vgahiqvideo.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgahiqvideo.c:34,85 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgahiqvideo.c:34,42
	  	outb(port+1, data);
	  }
	  
	- static ulong
	- hiqvideolinear(VGAscr* scr, int* size, int* align)
	+ static void
	+ hiqvideolinear(VGAscr*, int, int)
	  {
	- 	ulong aperture, oaperture;
	- 	int oapsize, wasupamem;
	- 	Pcidev *p;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	aperture = 0;
	- 	if(p = pcimatch(nil, 0x102C, 0)){
	- 		switch(p->did){
	- 		case 0x00C0:		/* 69000 HiQVideo */
	- 		case 0x00E0:		/* 65550 HiQV32 */
	- 		case 0x00E4:		/* 65554 HiQV32 */
	- 		case 0x00E5:		/* 65555 HiQV32 */
	- 			aperture = p->mem[0].bar & ~0x0F;
	- 			*size = p->mem[0].size;
	- 			break;
	- 		default:
	- 			break;
	- 		}
	- 	}
	- 
	- 	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;
	- 
	- 	return aperture;
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgahiqvideo.c:86,98 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgahiqvideo.c:43,54
	  hiqvideoenable(VGAscr* scr)
	  {
	  	Pcidev *p;
	- 	int align, size, vmsize;
	- 	ulong aperture;
	+ 	int vmsize;
	  
	  	/*
	  	 * Only once, can't be disabled for now.
	  	 */
	- 	if(scr->io)
	+ 	if(scr->mmio)
	  		return;
	  	if(p = pcimatch(nil, 0x102C, 0)){
	  		switch(p->did){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgahiqvideo.c:119,141 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgahiqvideo.c:75,95
	  	else
	  		return;
	  
	- 	size = p->mem[0].size;
	- 	align = 0;
	- 	aperture = hiqvideolinear(scr, &size, &align);
	- 	if(aperture) {
	- 		scr->aperture = aperture;
	- 		scr->apsize = size;
	- 		addvgaseg("hiqvideoscreen", aperture, size);
	+ 	scr->pci = p;
	+ 	vgalinearpci(scr);
	+ 	
	+ 	if(scr->paddr) {
	+ 		addvgaseg("hiqvideoscreen", scr->paddr, scr->apsize);
	  	}
	  
	  	/*
	  	 * Find a place for the cursor data in display memory.
	  	 * Must be on a 4096-byte boundary.
	- 	 * scr->io holds the physical address of the cursor
	+ 	 * scr->mmio holds the virtual address of the cursor
	  	 * storage area in the framebuffer region.
	  	 */
	  	scr->storage = vmsize-4096;
	- 	scr->io = scr->aperture+scr->storage;
	+ 	scr->mmio = (ulong*)((uchar*)scr->vaddr+scr->storage);
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgahiqvideo.c:155,163 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgahiqvideo.c:109,117
	  	 */
	  	hiqvideocurdisable(scr);
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	p = KADDR(scr->io);
	+ 	p = (uchar*)scr->mmio;
	  
	  	for(y = 0; y < 16; y += 2){
	  		*p++ = ~(curs->clr[2*y]|curs->set[2*y]);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgahiqvideo.c:197,203 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgahiqvideo.c:151,157
	  {
	  	int x, y;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	  
	  	if((x = p.x+scr->offset.x) < 0)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgahiqvideo.c:219,225 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgahiqvideo.c:173,179
	  	uchar xr80;
	  
	  	hiqvideoenable(scr);
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	  
	  	/*
 [rsc] --rw-rw-r-- M 451989 glenda sys 28257 Nov  6 10:23 sys/src/9/pc/vgamach64xx.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamach64xx.c:168,180 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamach64xx.c:168,178
	  {
	  	Pcidev *p;
	  
	- 	/*
	- 	 * Only once, can't be disabled for now.
	- 	 */
	  	if(scr->io)
	  		return;
	  	if(p = mach64xxpci()){
	  		scr->id = p->did;
	+ 		scr->pci = p;
	  
	  		/*
	  		 * The CT doesn't always have the I/O base address
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamach64xx.c:189,241 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamach64xx.c:187,201
	  	}
	  }
	  
	- static ulong
	- mach64xxlinear(VGAscr* scr, int* size, int* align)
	+ static void
	+ mach64xxlinear(VGAscr* scr, int size, int)
	  {
	- 	ulong aperture, osize, oaperture;
	- 	int i, oapsize, wasupamem;
	- 	Pcidev *p;
	- 
	- 	osize = *size;
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	if(p = mach64xxpci()){
	- 		for(i=0; i<nelem(p->mem); i++){
	- 			if(p->mem[i].size >= *size
	- 			&& ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0)
	- 				break;
	- 		}
	- 		if(i >= nelem(p->mem)){
	- 			print("vgamach64xx: aperture not found\n");
	- 			return 0;
	- 		}
	- 		aperture = p->mem[i].bar & ~0x0F;
	- 		*size = p->mem[i].size;
	- 	}
	- 	else
	- 		aperture = 0;
	- 
	- 	if(wasupamem)
	- 		upafree(oaperture, oapsize);
	- 	scr->isupamem = 0;
	- 
	- 	aperture = upamalloc(aperture, *size, *align);
	- 	if(aperture == 0){
	- 		if(wasupamem && upamalloc(oaperture, oapsize, 0))
	- 			scr->isupamem = 1;
	- 	}
	- 	else
	- 		scr->isupamem = 1;
	- 
	- 	scr->mmio = KADDR(aperture+osize-0x400);
	- 	if(oaperture && oaperture != aperture)
	- 		print("warning (BUG): redefinition of aperture does not change mach64mmio segment\n");
	- 	addvgaseg("mach64mmio", aperture+osize-BY2PG, BY2PG);
	- 	addvgaseg("mach64screen", aperture, osize);
	- 
	- 	return aperture;
	+ 	vgalinearpci(scr);
	+ 	if(scr->paddr == 0)
	+ 		return;
	+ 	scr->mmio = (ulong*)((uchar*)scr->vaddr+size-1024);
	+ 	addvgaseg("mach64mmio", scr->paddr+size-BY2PG, BY2PG);
	+ 	addvgaseg("mach64screen", scr->paddr, scr->apsize);
	  }
	  
	  enum {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamach64xx.c:474,480 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamach64xx.c:434,440
	  	r = ior32(scr, GenTestCntl);
	  	iow32(scr, GenTestCntl, r & ~0x80);
	  
	- 	p = KADDR(scr->aperture);
	+ 	p = scr->vaddr;
	  	p += scr->storage;
	  
	  	/*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamach64xx.c:792,798 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamach64xx.c:752,758
	  	}
	  
	  	/* Get the base freq from the BIOS */
	- 	bios  = KADDR(0xC000);
	+ 	bios  = kaddr(0xC000);
	  	table = *(ushort *)(bios + 0x48);
	  	table = *(ushort *)(bios + table + 0x10);
	  	switch (*(ushort *)(bios + table + 0x08)) {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamach64xx.c:1120,1126 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamach64xx.c:1080,1086
	  		   mach64revb? "yes": "no",
	  		   mach64refclock);
	  	pprint("%s: storage @%.8luX, aperture @%8.ulX, ovl buf @%.8ulX\n",
	- 		   scr->dev->name, scr->storage, scr->aperture,
	+ 		   scr->dev->name, scr->storage, scr->paddr,
	  		   mach64overlay);
	  }
	  	
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamach64xx.c:1215,1221 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamach64xx.c:1175,1181
	  
	  		_offs = (ulong)(offs % ovl_fib);
	  		nb     = (_offs + len > ovl_fib)? ovl_fib - _offs: len;
	- 		memmove((uchar *)KADDR(scr->aperture + mach64overlay + _offs), 
	+ 		memmove((uchar *)scr->vaddr + mach64overlay + _offs, 
	  				  src, nb);
	  		offs += nb;
	  		src  += nb;
 [rsc] --rw-rw-r-- M 451989 glenda sys 4637 Nov  6 10:23 sys/src/9/pc/vgamga2164w.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga2164w.c:42,100 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga2164w.c:42,53
	  	return p;
	  }
	  
	- static ulong
	- mga2164wlinear(VGAscr* scr, int* size, int* align)
	- {
	- 	ulong aperture, oaperture;
	- 	int oapsize, wasupamem;
	- 	Pcidev *p;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	if(p = mgapcimatch()){
	- 		aperture = p->mem[p->did==MGA2064? 1 : 0].bar & ~0x0F;
	- 		*size = (p->did==MGA2064? 8 :16)*1024*1024;
	- 	}
	- 	else
	- 		aperture = 0;
	- 
	- 	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;
	- 
	- 	return aperture;
	- }
	- 
	  static void
	  mga2164wenable(VGAscr* scr)
	  {
	  	Pcidev *p;
	- 	int size, align, immio;
	- 	ulong aperture;
	  
	- 	/*
	- 	 * Only once, can't be disabled for now.
	- 	 * scr->io holds the virtual address of
	- 	 * the MMIO registers.
	- 	 */
	- 	if(scr->io)
	+ 	if(scr->mmio)
	  		return;
	  
	  	p = mgapcimatch();
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga2164w.c:101,123 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga2164w.c:54,72
	  	if(p == nil)
	  		return;
	  
	- 	immio = p->did==MGA2064? 0 : 1;
	- 	scr->io = upamalloc(p->mem[immio].bar & ~0x0F, p->mem[immio].size, 0);
	- 	if(scr->io == 0)
	- 		return;
	- 	addvgaseg("mga2164wmmio", scr->io, p->mem[immio].size);
	- 
	- 	scr->io = (ulong)KADDR(scr->io);
	- 
	- 	/* need to map frame buffer here too, so vga can find memory size */
	- 	size = (p->did==MGA2064? 8 :16)*1024*1024;
	- 	align = 0;
	- 	aperture = mga2164wlinear(scr, &size, &align);
	- 	if(aperture) {
	- 		scr->aperture = aperture;
	- 		scr->apsize = size;
	- 		addvgaseg("mga2164wscreen", aperture, size);
	+ 	if(p->did == MGA2064){
	+ 		scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
	+ 		if(scr->mmio == nil)
	+ 			return;
	+ 		vgalinearaddr(scr, p->mem[1].bar&~0x0F, 8*MB);
	+ 	}else{
	+ 		scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
	+ 		if(scr->mmio == nil)
	+ 			return;
	+ 		vgalinearaddr(scr, p->mem[0].bar&~0x0F, 16*MB);
	  	}
	+ 	if(scr->paddr)
	+ 		addvgaseg("mga2164wscreen", scr->paddr, scr->apsize);
	  }
	  
	  enum {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga2164w.c:142,150 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga2164w.c:91,99
	  {
	  	uchar *tvp3026;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	tvp3026 = KADDR(scr->io+0x3C00);
	+ 	tvp3026 = (uchar*)scr->mmio+0x3C00;
	  
	  	/*
	  	 * Make sure cursor is off
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga2164w.c:161,169 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga2164w.c:110,118
	  	int x, y;
	  	uchar *tvp3026;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	tvp3026 = KADDR(scr->io+0x3C00);
	+ 	tvp3026 = (uchar*)scr->mmio+0x3C00;
	  
	  	/*
	  	 * Make sure cursor is off by initialising the cursor
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga2164w.c:223,231 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga2164w.c:172,180
	  	int x, y;
	  	uchar *tvp3026;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	- 	tvp3026 = KADDR(scr->io+0x3C00);
	+ 	tvp3026 = (uchar*)scr->mmio+0x3C00;
	  
	  	x = p.x+scr->offset.x;
	  	y = p.y+scr->offset.y;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga2164w.c:244,252 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga2164w.c:193,201
	  	int i;
	  	uchar *tvp3026;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	tvp3026 = KADDR(scr->io+0x3C00);
	+ 	tvp3026 = (uchar*)scr->mmio+0x3C00;
	  
	  	tvp3026disable(scr);
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga2164w.c:276,282 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga2164w.c:225,231
	  	mga2164wenable,			/* enable */
	  	0,				/* disable */
	  	0,				/* page */
	- 	mga2164wlinear,			/* linear */
	+ 	0,				/* linear */
	  };
	  
	  VGAcur vgamga2164wcur = {
 [rsc] --rw-rw-r-- M 451989 glenda sys 10201 Nov  6 10:23 sys/src/9/pc/vgamga4xx.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:23,31 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:23,28
	  	MGA4xx			= 0x0525,
	  	MGA200			= 0x0521,
	  
	- 	Kilo				= 1024,
	- 	Meg				= 1024*1024,
	- 
	  	FCOL			= 0x1c24,
	  	FXRIGHT			= 0x1cac,	
	  	FXLEFT			= 0x1ca8,
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:91,149 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:88,104
	  	return p;
	  }
	  
	- static ulong
	- mga4xxlinear(VGAscr* scr, int* size, int* align)
	- {
	- 	ulong 	aperture, oaperture;
	- 	int 		oapsize, wasupamem;
	- 	Pcidev *	p;
	  
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	if(p = mgapcimatch()){
	- 		aperture = p->mem[0].bar & ~0x0F;
	- 		if(p->did == MGA4xx)
	- 			*size = 32*Meg;
	- 		else
	- 			*size = 8*Meg;
	- 	}
	- 	else
	- 		aperture = 0;
	- 
	- 	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;
	- 
	- 	return aperture;
	- }
	- 
	  static void
	  mgawrite8(VGAscr* scr, int index, uchar val)
	  {
	- 	((uchar*)scr->io)[index] = val;
	+ 	((uchar*)scr->mmio)[index] = val;
	  }
	  
	  static uchar
	  mgaread8(VGAscr* scr, int index)
	  {
	- 	return ((uchar*)scr->io)[index];
	+ 	return ((uchar*)scr->mmio)[index];
	  }
	  
	  static uchar
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:163,181 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:118,130
	  mga4xxenable(VGAscr* scr)
	  {
	  	Pcidev *	pci;
	- 	int 		size, align;
	- 	ulong 	aperture;
	+ 	int 		size;
	  	int 		i, n, k;
	  	uchar *	p;
	  	uchar	x[16];
	  	uchar	crtcext3;
	  
	- 	/*
	- 	 * Only once, can't be disabled for now.
	- 	 * scr->io holds the virtual address of
	- 	 * the MMIO registers.
	- 	 */
	- 	if(scr->io)
	+ 	if(scr->mmio)
	  		return;
	  
	  	pci = mgapcimatch();
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:182,222 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:131,170
	  	if(pci == nil)
	  		return;
	  
	- 	scr->io = upamalloc(pci->mem[1].bar & ~0x0F, 16*1024, 0);
	- 	if(scr->io == 0)
	+ 	scr->mmio = vmap(pci->mem[1].bar&~0x0F, 16*1024);
	+ 	if(scr->mmio == nil)
	  		return;
	+ 	
	+ 	addvgaseg("mga4xxmmio", pci->mem[1].bar&~0x0F, pci->mem[1].size);
	  
	- 	addvgaseg("mga4xxmmio", scr->io, pci->mem[1].size);
	- 
	- 	scr->io = (ulong)KADDR(scr->io);
	- 
	  	/* need to map frame buffer here too, so vga can find memory size */
	- 	size = 8*Meg;
	- 	align = 0;
	- 	aperture = mga4xxlinear(scr, &size, &align);
	- 	if(aperture) {
	- 		scr->aperture = aperture;
	- 		addvgaseg("mga4xxscreen", aperture, size);
	+ 	if(pci->did == MGA4xx)
	+ 		size = 32*MB;
	+ 	else
	+ 		size = 8*MB;
	+ 	vgalinearaddr(scr, pci->mem[0].bar&~0x0F, size);
	  
	- 		/* Find out how much memory is here, some multiple of 2 Meg */
	+ 	if(scr->paddr){
	  
	+ 		/* Find out how much memory is here, some multiple of 2 MB */
	+ 
	  		/* First Set MGA Mode ... */
	  		crtcext3 = crtcextset(scr, 3, 0x80, 0x00);
	  
	- 		p = (uchar*)aperture;
	- 		n = (size / Meg) / 2;
	+ 		p = scr->vaddr;
	+ 		n = (size / MB) / 2;
	  		for (i = 0; i < n; i++) {
	- 			k = (2*i+1)*Meg;
	+ 			k = (2*i+1)*MB;
	  			p[k] = 0;
	  			p[k] = i+1;
	- 			*((uchar*)(scr->io + CACHEFLUSH)) = 0;
	+ 			*((uchar*)scr->mmio + CACHEFLUSH) = 0;
	  			x[i] = p[k];
	   		}
	  		for(i = 1; i < n; i++)
	  			if(x[i] != i+1)
	  				break;
	-   		scr->apsize = 2*i*Meg;
	- 
	+ 		scr->apsize = 2*i*MB;	/* sketchy */
	+ 		addvgaseg("mga4xxscreen", scr->paddr, scr->apsize);
	  		crtcextset(scr, 3, crtcext3, 0xff);
	  	}
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:240,249 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:188,197
	  {
	  	uchar * 	dac4xx;
	  	
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	  
	- 	dac4xx = KADDR(scr->io+0x3C00);
	+ 	dac4xx = (uchar*)scr->mmio+0x3C00;
	  	
	  	*(dac4xx+Index) = Icctl;
	  	*(dac4xx+Data) = 0x00;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:256,269 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:204,217
	  	uchar *	p;
	  	uchar * 	dac4xx;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	  
	- 	dac4xx = KADDR(scr->io+0x3C00);
	+ 	dac4xx = (uchar*)scr->mmio+0x3C00;
	  	
	  	dac4xxdisable(scr);
	  
	- 	p = KADDR(scr->storage);
	+ 	p = scr->vaddr;
	  	for(y = 0; y < 64; y++){
	  		*p++ = 0; *p++ = 0; *p++ = 0;
	  		*p++ = 0; *p++ = 0; *p++ = 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:296,305 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:244,253
	  	int 		x, y;
	  	uchar *	dac4xx;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	  
	- 	dac4xx = KADDR(scr->io + 0x3C00);
	+ 	dac4xx = (uchar*)scr->mmio + 0x3C00;
	  
	  	x = p.x + scr->offset.x;
	  	y = p.y + scr->offset.y;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:319,327 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:267,275
	  	uchar *	dac4xx;
	  	ulong	storage;
	  	
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	dac4xx = KADDR(scr->io+0x3C00);
	+ 	dac4xx = (uchar*)scr->mmio+0x3C00;
	  
	  	dac4xxdisable(scr);
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:332,338 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:280,286
	  	*(dac4xx+Index) = Icuradrh;
	  	*(dac4xx+Data) = 0xff & (storage >> 18);		
	  
	- 	scr->storage = (ulong) KADDR((ulong)scr->aperture + (ulong)storage);
	+ 	scr->storage = (ulong)scr->vaddr + storage;
	  
	  	/* Show X11-Like Cursor */
	  	*(dac4xx+Index) = Icctl;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:380,388 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:328,336
	  	/* blank = 0 -> turn screen on */
	  	/* blank = 1 -> turn screen off */
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	mga = KADDR(scr->io);	
	+ 	mga = (uchar*)scr->mmio;	
	  
	  	if (blank == 0) {
	  		seq1 = 0x00;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:432,440 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:380,388
	  	uchar * 		mga;
	   
	  	/* Constant Shaded Trapezoids / Rectangle Fills */
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 0;
	- 	mga = KADDR(scr->io);
	+ 	mga = (uchar*)scr->mmio;
	  
	  	mgawrite32(mga, DWGCTL, 0);
	  	mgawrite32(mga, FCOL, color);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:460,469 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:408,417
	  	int 		ydir;
	   
	  	/* Two-operand Bitblts */
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 0;
	  
	- 	mga = KADDR(scr->io);
	+ 	mga = (uchar*)scr->mmio;
	  
	  	pitch = Dx(scr->gscreen->r);
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:556,564 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:504,512
	  	if (p == nil)
	  		return ;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	mga = KADDR(scr->io);
	+ 	mga = (uchar*)scr->mmio;
	  
	  	mgawrite32(mga, SRCORG, 0);
	  	mgawrite32(mga, DSTORG, 0);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgamga4xx.c:590,596 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgamga4xx.c:538,544
	  	mga4xxenable,		/* enable */
	  	0,					/* disable */
	  	0,					/* page */
	- 	mga4xxlinear,			/* linear */
	+ 	0,					/* linear */
	  	mga4xxdrawinit,
	  };
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 10143 Nov  6 10:23 sys/src/9/pc/vganeomagic.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:22,93 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:22,41
	  	int	addr;
	  };
	  
	- static ulong
	- neomagiclinear(VGAscr* scr, int* size, int* align)
	- {
	- 	ulong aperture, oaperture;
	- 	int oapsize, wasupamem;
	- 	Pcidev *p;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	aperture = 0;
	- 	if(p = pcimatch(nil, 0x10C8, 0)){
	- 		switch(p->did){
	- 		case 0x0003:		/* MagicGraph 128ZV */
	- 		case 0x0083:		/* MagicGraph 128ZV+ */
	- 		case 0x0004:		/* MagicGraph 128XD */
	- 		case 0x0005:		/* MagicMedia 256AV */
	- 		case 0x0006:		/* MagicMedia 256ZX */
	- 			aperture = p->mem[0].bar & ~0x0F;
	- 			*size = p->mem[0].size;
	- 			break;
	- 		default:
	- 			break;
	- 		}
	- 	}
	- 
	- 	if(wasupamem){
	- 		if(oaperture == aperture)
	- 			return oaperture;
	- 		upafree(oaperture, oapsize);
	- 	}
	- 	scr->isupamem = 0;
	- 
	- 	aperture = upamalloc(aperture, *size, *align);
	- //print("neomagiclinear1 %lux %d\n", aperture, *size);
	- 	if(aperture == 0){
	- 		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
	- 			aperture = oaperture;
	- 			scr->isupamem = 1;
	- 		}
	- 		else
	- 			scr->isupamem = 0;
	- 	}
	- 	else
	- 		scr->isupamem = 1;
	- 
	- 	return aperture;
	- }
	- 
	  static void
	  neomagicenable(VGAscr* scr)
	  {
	  	Pcidev *p;
	- 	int align, curoff, size, vmsize;
	- 	ulong aperture;
	+ 	int curoff, vmsize;
	  	ulong ioaddr;
	  	ulong iosize;
	  
	  	/*
	- 	 * Only once, can't be disabled for now.
	- 	 * scr->io holds the physical address of the cursor registers
	+ 	 * scr->mmio holds the virtual address of the cursor registers
	  	 * in the MMIO space. This may need to change for older chips
	  	 * which have the MMIO space offset in the framebuffer region.
	  	 */
	- 	if(scr->io)
	+ 	if(scr->mmio)
	  		return;
	  	if(p = pcimatch(nil, 0x10C8, 0)){
	  		switch(p->did){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:127,137 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:75,86
	  	}
	  	else
	  		return;
	- 	scr->io = upamalloc(ioaddr, iosize, 0);
	- 	if(scr->io == 0)
	+ 	scr->pci = p;
	+ 
	+ 	scr->mmio = vmap(ioaddr, iosize);
	+ 	if(scr->mmio == nil)
	  		return;
	- 	addvgaseg("neomagicmmio", scr->io, iosize);
	- 	scr->mmio = KADDR(scr->io);
	+ 	addvgaseg("neomagicmmio", ioaddr, iosize);
	  
	  	/*
	  	 * Find a place for the cursor data in display memory.
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:139,154 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:88,97
	  	 * last 2KB of the framebuffer.
	  	 */
	  	scr->storage = vmsize-2*1024;
	- 	scr->io += curoff;
	- 
	- 	size = p->mem[0].size;
	- 	align = 0;
	- 	aperture = neomagiclinear(scr, &size, &align);
	- 	if(aperture) {
	- 		scr->aperture = aperture;
	- 		scr->apsize = size;
	- 		addvgaseg("neomagicscreen", aperture, size);
	- 	}
	+ 	scr->mmio = (ulong*)((uchar*)scr->mmio + curoff);
	+ 	vgalinearpci(scr);
	+ 	if(scr->paddr)
	+ 		addvgaseg("neomagicscreen", scr->paddr, scr->apsize);
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:156,164 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:99,107
	  {
	  	CursorNM *cursornm;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursornm = KADDR(scr->io);
	+ 	cursornm = (void*)scr->mmio;
	  	cursornm->enable = 0;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:169,175 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:112,118
	  	uint p0, p1;
	  	int x, y;
	  
	- 	p = KADDR(scr->aperture);
	+ 	p = (uchar*)scr->mmio;
	  	p += scr->storage + index*1024;
	  
	  	for(y = yo; y < 16; y++){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:211,219 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:154,162
	  {
	  	CursorNM *cursornm;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursornm = KADDR(scr->io);
	+ 	cursornm = (void*)scr->mmio;
	  
	  	cursornm->enable = 0;
	  	memmove(&scr->Cursor, curs, sizeof(Cursor));
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:227,235 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:170,178
	  	CursorNM *cursornm;
	  	int addr, index, x, xo, y, yo;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	- 	cursornm = KADDR(scr->io);
	+ 	cursornm = (void*)scr->mmio;
	  
	  	index = 0;
	  	if((x = p.x+scr->offset.x) < 0){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:266,274 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:209,217
	  	CursorNM *cursornm;
	  
	  	neomagicenable(scr);
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	- 	cursornm = KADDR(scr->io);
	+ 	cursornm = (void*)scr->mmio;
	  	cursornm->enable = 0;
	  
	  	/*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:426,432 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:369,375
	  		| NEO_BC0_SRC_IS_FG
	  		| NEO_BC3_SKIP_MAPPING
	  		| GXcopy;
	- 	mmio[DstStartOff] = scr->aperture
	+ 	mmio[DstStartOff] = scr->paddr
	  		+ r.min.y*scr->gscreen->width*BY2WD
	  		+ r.min.x*scr->gscreen->depth/BI2BY;
	  	mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:452,460 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:395,403
	  			| NEO_BC3_FIFO_EN
	  			| NEO_BC3_SKIP_MAPPING
	  			| GXcopy;
	- 		mmio[SrcStartOff] = scr->aperture
	+ 		mmio[SrcStartOff] = scr->paddr
	  			+ sr.min.y*pitch + sr.min.x*pixel;
	- 		mmio[DstStartOff] = scr->aperture
	+ 		mmio[DstStartOff] = scr->paddr
	  			+ r.min.y*pitch + r.min.x*pixel;
	  	} else {
	  		/* start from lower-right */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:465,473 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:408,416
	  			| NEO_BC3_FIFO_EN
	  			| NEO_BC3_SKIP_MAPPING
	  			| GXcopy;
	- 		mmio[SrcStartOff] = scr->aperture
	+ 		mmio[SrcStartOff] = scr->paddr
	  			+ (sr.max.y-1)*pitch + (sr.max.x-1)*pixel;
	- 		mmio[DstStartOff] = scr->aperture
	+ 		mmio[DstStartOff] = scr->paddr
	  			+ (r.max.y-1)*pitch + (r.max.x-1)*pixel;
	  	}
	  	mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganeomagic.c:549,555 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganeomagic.c:492,498
	  	neomagicenable,
	  	nil,
	  	nil,
	- 	neomagiclinear,
	+ 	nil,
	  	neomagicdrawinit,
	  };
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 11783 Nov  6 10:23 sys/src/9/pc/vganvidia.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:77,84 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:77,82
	  	int		dmamax;
	  } nv;
	  
	- 
	- /* Nvidia is good about backwards compatibility -- any did >= 0x20 is fine */
	  static Pcidev*
	  nvidiapci(void)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:92,134 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:90,98
	  	return nil;
	  }
	  
	- static ulong
	- nvidialinear(VGAscr* scr, int* size, int* align)
	+ static void
	+ nvidialinear(VGAscr*, int, int)
	  {
	- 	Pcidev *p;
	- 	int oapsize, wasupamem;
	- 	ulong aperture, oaperture;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	aperture = 0;
	- 	if(p = nvidiapci()){
	- 		aperture = p->mem[1].bar & ~0x0F;
	- 		*size = p->mem[1].size;
	- 	}
	- 
	- 	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;
	- 
	- 	return aperture;
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:135,174 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:99,129
	  nvidiaenable(VGAscr* scr)
	  {
	  	Pcidev *p;
	- 	ulong aperture, *q;
	- 	int align, size, tmp;
	+ 	ulong *q;
	+ 	int tmp;
	  
	- 	/*
	- 	 * Only once, can't be disabled for now.
	- 	 * scr->io holds the physical address of
	- 	 * the MMIO registers.
	- 	 */
	- 	if(scr->io)
	+ 	if(scr->mmio)
	  		return;
	  	p = nvidiapci();
	  	if(p == nil)
	  		return;
	  	scr->id = p->did;
	+ 	scr->pci = p;
	  
	- 	scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
	- 	if(scr->io == 0)
	+ 	scr->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
	+ 	if(scr->mmio == nil)
	  		return;
	- 	addvgaseg("nvidiammio", scr->io, p->mem[0].size);
	+ 	addvgaseg("nvidiammio", p->mem[0].bar&~0x0F, p->mem[0].size);
	  
	- 	size = p->mem[1].size;
	- 	align = 0;
	- 	aperture = nvidialinear(scr, &size, &align);
	- 	if(aperture){
	- 		scr->aperture = aperture;
	- 		scr->apsize = size;
	- 		addvgaseg("nvidiascreen", aperture, size);
	- 	}
	+ 	vgalinearpci(scr);
	+ 	if(scr->apsize)
	+ 		addvgaseg("nvidiascreen", scr->paddr, scr->apsize);
	  
	  	/* find video memory size */
	  	switch (scr->id & 0x0ff0) {
	  	case 0x0020:
	  	case 0x00A0:
	- 		q = KADDR(scr->io + Pfb);
	+ 		q = (void*)((uchar*)scr->mmio + Pfb);
	  		tmp = *q;
	  		if (tmp & 0x0100) {
	  			scr->storage = ((tmp >> 12) & 0x0F) * 1024 + 1024 * 2;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:191,197 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:146,152
	  		scr->storage = (((tmp >> 4) & 127) + 1) * 1024 * 1024;
	  		break;
	  	default:
	- 		q = KADDR(scr->io + Pfb +  0x020C);
	+ 		q = (void*)((uchar*)scr->mmio + Pfb +  0x020C);
	  		tmp = (*q >> 20) & 0xFF;
	  		if (tmp == 0)
	  			tmp = 16;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:203,209 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:158,164
	  static void
	  nvidiacurdisable(VGAscr* scr)
	  {
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	  
	  	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:218,224 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:173,179
	  	ushort	c,s;
	  	ulong	tmp;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	  
	  	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:226,235 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:181,190
	  	switch (scr->id & 0x0ff0) {
	  	case 0x0020:
	  	case 0x00A0:
	- 		p = KADDR(scr->io + Pramin + 0x1E00 * 4);
	+ 		p = (void*)((uchar*)scr->mmio + Pramin + 0x1E00 * 4);
	  		break;
	  	default:
	- 		p = KADDR(scr->aperture + scr->storage - 96*1024);
	+ 		p = (void*)((uchar*)scr->vaddr + scr->storage - 96*1024);
	  		break;
	  	}
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:268,277 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:223,232
	  {
	  	ulong*	cursorpos;
	  
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return 1;
	  
	- 	cursorpos = KADDR(scr->io + hwCurPos);
	+ 	cursorpos = (void*)((uchar*)scr->mmio + hwCurPos);
	  	*cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);
	  
	  	return 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:281,287 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:236,242
	  nvidiacurenable(VGAscr* scr)
	  {
	  	nvidiaenable(scr);
	- 	if(scr->io == 0)
	+ 	if(scr->mmio == 0)
	  		return;
	  
	  	vgaxo(Crtx, 0x1F, 0x57);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:299,307 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:254,262
	  	ulong	*fifo;
	  
	  	outb(0x3D0,0);
	- 	p=KADDR(scr->aperture);
	+ 	p = scr->vaddr;
	  	scratch = *p;
	- 	fifo = KADDR(scr->io + Fifo);
	+ 	fifo = (void*)((uchar*)scr->mmio + Fifo);
	  	fifo[0x10] = (data << 2);
	  	USED(scratch);
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:311,317 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:266,272
	  {
	  	ulong	*fifo;
	  
	- 	fifo = KADDR(scr->io + Fifo);
	+ 	fifo = (void*)((uchar*)scr->mmio + Fifo);
	  	return (fifo[0x0011] >> 2);
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:375,381 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:330,336
	  	ulong*	pgraph;
	  	int x;
	  
	- 	pgraph = KADDR(scr->io + Pgraph);
	+ 	pgraph = (void*)((uchar*)scr->mmio + Pgraph);
	  
	  	x = 0;
	  	while((readget(scr) != nv.dmaput) && x++ < 1000000)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:388,394 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:343,349
	  		;
	  
	  	if(x >= 1000000)
	- 		iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->io, scr, getcallerpc(&scr));
	+ 		iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->mmio, scr, getcallerpc(&scr));
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vganvidia.c:399,405 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vganvidia.c:354,360
	  
	  	pitch = scr->gscreen->width*BY2WD;
	  
	- 	nv.dmabase = KADDR(scr->aperture + scr->storage - 128*1024);
	+ 	nv.dmabase = (void*)((uchar*)scr->vaddr + scr->storage - 128*1024);
	  
	  	for(i=0; i<SKIPS; i++)
	  		nv.dmabase[i] = 0x00000000;
 [rsc] --rw-rw-r-- M 451989 glenda sys 4251 Nov  6 10:23 sys/src/9/pc/vgargb524.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgargb524.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgargb524.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
 [rsc] --rw-rw-r-- M 451989 glenda sys 10994 Nov  6 10:23 sys/src/9/pc/vgas3.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgas3.c:88,188 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgas3.c:88,136
	  	}
	  }
	  
	- static ulong
	- s3linear(VGAscr* scr, int* size, int* align)
	+ static void
	+ s3linear(VGAscr* scr, int, int)
	  {
	- 	char *mmioname;
	- 	ulong aperture, oaperture, mmiobase, mmiosize;
	- 	int i, id, j, osize, oapsize, wasupamem;
	+ 	int id, j;
	+ 	ulong mmiobase, mmiosize;
	  	Pcidev *p;
	- 
	- 	osize = *size;
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	mmiosize = 0;
	- 	mmiobase = 0;
	- 	mmioname = nil;
	- 
	- 	/*
	- 	 * S3 makes cards other than display controllers, so
	- 	 * look for the first S3 display controller (device class 3)
	- 	 * and not one of their sound cards.
	- 	 */
	- 	p = nil;
	- 	while(p = pcimatch(p, PCIS3, 0)){
	- 		if(p->ccrb == 0x03)
	- 			break;
	- 	}
	- 	if(p != nil){
	- 		for(i=0; i<nelem(p->mem); i++){
	- 			if(p->mem[i].size >= *size
	- 			&& ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0)
	+ 	
	+ 	vgalinearpciid(scr, PCIS3, 0);
	+ 	p = scr->pci;
	+ 	if(scr->paddr == 0 || p == nil)
	+ 		return;
	+ 		
	+ 	addvgaseg("s3screen", scr->paddr, scr->apsize);
	+ 	
	+ 	id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
	+ 	switch(id){			/* find mmio */
	+ 	case SAVAGE4:
	+ 	case PROSAVAGEP:
	+ 	case PROSAVAGEK:
	+ 	case PROSAVAGE8:
	+ 	case SUPERSAVAGEIXC16:
	+ 		/*
	+ 		 * We could assume that the MMIO registers
	+ 		 * will be in the screen segment and just use
	+ 		 * that, but PCI software is allowed to move them
	+ 		 * if it feels like it, so we look for an aperture of
	+ 		 * the right size; only the first 512k actually means
	+ 		 * anything.  The S3 engineers overestimated how
	+ 		 * much space they would need in the first design.
	+ 		 */
	+ 		for(j=0; j<nelem(p->mem); j++){
	+ 			if((p->mem[j].bar&~0x0F) != scr->paddr)
	+ 			if(p->mem[j].size==512*1024 || p->mem[j].size==16*1024*1024){
	+ 				mmiobase = p->mem[j].bar & ~0x0F;
	+ 				mmiosize = 512*1024;
	+ 				scr->mmio = vmap(mmiobase, mmiosize);
	+ 				if(scr->mmio == nil)
	+ 					return;
	+ 				addvgaseg("savagemmio", mmiobase, mmiosize);
	  				break;
	- 		}
	- 		if(i >= nelem(p->mem)){
	- 			print("vgas3: aperture not found\n");
	- 			return 0;
	- 		}
	- 		aperture = p->mem[i].bar & ~0x0F;
	- 		*size = p->mem[i].size;
	- 
	- 		id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
	- 		switch(id){			/* find mmio */
	- 		case SAVAGE4:
	- 		case PROSAVAGEP:
	- 		case PROSAVAGEK:
	- 		case PROSAVAGE8:
	- 		case SUPERSAVAGEIXC16:
	- 			/*
	- 			 * We could assume that the MMIO registers
	- 			 * will be in the screen segment and just use
	- 			 * that, but PCI software is allowed to move them
	- 			 * if it feels like it, so we look for an aperture of
	- 			 * the right size; only the first 512k actually means
	- 			 * anything.  The S3 engineers overestimated how
	- 			 * much space they would need in the first design.
	- 			 */
	- 			for(j=0; j<nelem(p->mem); j++){
	- 				if(i == j)
	- 					continue;
	- 				if(p->mem[j].size==512*1024 || p->mem[j].size==16*1024*1024){
	- 					mmiobase = p->mem[j].bar & ~0x0F;
	- 					mmiosize = 512*1024;
	- 					scr->mmio = (ulong*)upamalloc(mmiobase, mmiosize, 0);
	- 					mmioname = "savagemmio";
	- 					break;
	- 				}
	  			}
	- 			if(mmiosize == 0){
	- 				print("savage4: mmio not found\n");
	- 				return 0;
	- 			}
	  		}
	- 	}else
	- 		aperture = 0;
	- 
	- 	if(wasupamem)
	- 		upafree(oaperture, oapsize);
	- 	scr->isupamem = 0;
	- 
	- 	aperture = upamalloc(aperture, *size, *align);
	- 	if(aperture == 0){
	- 		if(wasupamem && upamalloc(oaperture, oapsize, 0))
	- 			scr->isupamem = 1;
	  	}
	- 	else
	- 		scr->isupamem = 1;
	- 
	- 	if(oaperture && oaperture != aperture)
	- 		print("warning (BUG): redefinition of aperture does not change s3screen segment\n");
	- 	addvgaseg("s3screen", aperture, osize);
	- 
	- 	if(mmiosize)
	- 		addvgaseg(mmioname, mmiobase, mmiosize);
	- 
	- 	return aperture;
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgas3.c:223,229 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgas3.c:171,177
	  	s3disable(scr);
	  
	  	opage = 0;
	- 	p = KADDR(scr->aperture);
	+ 	p = scr->vaddr;
	  	id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
	  	switch(id){
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgas3.c:498,505 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgas3.c:446,453
	  	mmio = scr->mmio;
	  	waitforlinearfifo(scr);
	  	waitforfifo(scr, 7);
	- 	mmio[SrcBase] = scr->aperture;
	- 	mmio[DstBase] = scr->aperture;
	+ 	mmio[SrcBase] = scr->paddr;
	+ 	mmio[DstBase] = scr->paddr;
	  	mmio[Stride] = (stride<<16)|stride;
	  	mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
	  	mmio[SrcXY] = (sp.x<<16)|sp.y;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgas3.c:524,532 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgas3.c:472,480
	  	mmio = scr->mmio;
	  	waitforlinearfifo(scr);
	  	waitforfifo(scr, 8);
	- 	mmio[SrcBase] = scr->aperture;
	- 	mmio[DstBase] = scr->aperture;
	- 	mmio[DstBase] = scr->aperture;
	+ 	mmio[SrcBase] = scr->paddr;
	+ 	mmio[DstBase] = scr->paddr;
	+ 	mmio[DstBase] = scr->paddr;
	  	mmio[Stride] = (stride<<16)|stride;
	  	mmio[FgrdData] = sval;
	  	mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgas3.c:579,591 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgas3.c:527,539
	  	case VIRGE:
	  	case VIRGEVX:
	  	case VIRGEGX2:
	- 		scr->mmio = (ulong*)(scr->aperture+0x1000000);
	+ 		scr->mmio = (ulong*)((char*)scr->vaddr+0x1000000);
	  		scr->fill = hwfill;
	  		scr->scroll = hwscroll;
	  		break;
	  	case SAVAGEMXMV:
	  	case SAVAGEIXMV:
	- 		scr->mmio = (ulong*)(scr->aperture+0x1000000);
	+ 		scr->mmio = (ulong*)((char*)scr->vaddr+0x1000000);
	  		savageinit(scr);	
	  		break;
	  	case SUPERSAVAGEIXC16:
 [rsc] --rw-rw-r-- M 451989 glenda sys 9351 Nov  6 10:23 sys/src/9/pc/vgat2r4.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgat2r4.c:56,118 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgat2r4.c:56,67
	  	CursorMode	= CursorMode32x32,
	  };
	  
	- static ulong
	- t2r4linear(VGAscr* scr, int* size, int* align)
	- {
	- 	ulong aperture, oaperture;
	- 	int oapsize, wasupamem;
	- 	Pcidev *p;
	- 
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	- 	aperture = 0;
	- 	if(p = pcimatch(nil, 0x105D, 0)){
	- 		switch(p->did){
	- 		case 0x5348:
	- 			aperture = p->mem[0].bar & ~0x0F;
	- 			*size = p->mem[0].size;
	- 			break;
	- 		default:
	- 			break;
	- 		}
	- 	}
	- 
	- 	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;
	- 
	- 	return aperture;
	- }
	- 
	  static void
	  t2r4enable(VGAscr* scr)
	  {
	  	Pcidev *p;
	- 	int size, align;
	- 	ulong aperture, mmio;
	+ 	void *mmio;
	  
	- 	/*
	- 	 * Only once, can't be disabled for now.
	- 	 * scr->mmio holds the virtual address of
	- 	 * the MMIO registers.
	- 	 */
	  	if(scr->mmio)
	  		return;
	  	if(p = pcimatch(nil, 0x105D, 0)){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgat2r4.c:125,145 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgat2r4.c:74,90
	  	}
	  	else
	  		return;
	- 	mmio = upamalloc(p->mem[4].bar & ~0x0F, p->mem[4].size, 0);
	- 	if(mmio == 0)
	+ 	scr->pci = p;
	+ 	
	+ 	mmio = vmap(p->mem[4].bar & ~0x0F, p->mem[4].size);
	+ 	if(mmio == nil)
	  		return;
	- 	addvgaseg("t2r4mmio", mmio, p->mem[4].size);
	+ 	addvgaseg("t2r4mmio", p->mem[4].bar & ~0x0F, p->mem[4].size);
	  
	- 	scr->mmio = KADDR(mmio);
	- 
	- 	size = p->mem[0].size;
	- 	align = 0;
	- 	aperture = t2r4linear(scr, &size, &align);
	- 	if(aperture){
	- 		scr->aperture = aperture;
	- 		scr->apsize = size;
	- 		addvgaseg("t2r4screen", aperture, size);
	- 	}
	+ 	scr->mmio = mmio;
	+ 	vgalinearpci(scr);
	+ 	if(scr->paddr)
	+ 		addvgaseg("t2r4screen", scr->paddr, scr->apsize);
	  }
	  
	  static uchar
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgat2r4.c:571,577 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgat2r4.c:516,522
	  	t2r4enable,
	  	nil,
	  	nil,
	- 	t2r4linear,
	+ 	nil,
	  	t2r4drawinit,
	  };
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 4507 Nov  6 10:23 sys/src/9/pc/vgatvp3020.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgatvp3020.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgatvp3020.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
 [rsc] --rw-rw-r-- M 451989 glenda sys 3956 Nov  6 10:23 sys/src/9/pc/vgatvp3026.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgatvp3026.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgatvp3026.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
 [rsc] --rw-rw-r-- M 451989 glenda sys 5840 Nov  6 10:23 sys/src/9/pc/vgavmware.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgavmware.c:144,162 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgavmware.c:144,155
	  		;
	  }
	  
	- static ulong
	- vmwarelinear(VGAscr* scr, int* size, int* align)
	+ static void
	+ vmwarelinear(VGAscr* scr, int, int)
	  {
	  	char err[64];
	- 	ulong aperture, oaperture;
	- 	int osize, oapsize, wasupamem;
	  	Pcidev *p;
	  
	- 	osize = *size;
	- 	oaperture = scr->aperture;
	- 	oapsize = scr->apsize;
	- 	wasupamem = scr->isupamem;
	- 
	  	p = pcimatch(nil, PCIVMWARE, 0);
	  	if(p == nil)
	  		error("no vmware card found");
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgavmware.c:176,200 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgavmware.c:169,177
	  		vm->rd = vm->ra + 1;
	  	}
	  
	- 	aperture = (ulong)(vmrd(vm, Rfbstart));
	- 	*size = vmrd(vm, Rfbsize);
	- 
	- 	if(wasupamem)
	- 		upafree(oaperture, oapsize);
	- 	scr->isupamem = 0;
	- 
	- 	aperture = upamalloc(aperture, *size, *align);
	- 	if(aperture == 0){
	- 		if(wasupamem && upamalloc(oaperture, oapsize, 0))
	- 			scr->isupamem = 1;
	- 	}else
	- 		scr->isupamem = 1;
	- 
	- 	if(oaperture && aperture != oaperture)
	- 		print("warning (BUG): redefinition of aperture does not change vmwarescreen segment\n");
	- 	addvgaseg("vmwarescreen", aperture, osize);
	- 
	- 	return aperture;
	+ 	vgalinearaddr(scr, vmrd(vm, Rfbstart), vmrd(vm, Rfbsize));
	+ 	if(scr->apsize)
	+ 		addvgaseg("vmwarescreen", scr->paddr, scr->apsize);
	  }
	  
	  static void
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgavmware.c:341,351 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgavmware.c:318,328
	  		if(mmiobase == 0)
	  			return;
	  		mmiosize = vmrd(vm, Rmemsize);
	- 		scr->mmio = KADDR(upamalloc(mmiobase, mmiosize, 0));
	- 		vm->mmio = scr->mmio;
	- 		vm->mmiosize = mmiosize;
	+ 		scr->mmio = vmap(mmiobase, mmiosize);
	  		if(scr->mmio == nil)
	  			return;
	+ 		vm->mmio = scr->mmio;
	+ 		vm->mmiosize = mmiosize;
	  		addvgaseg("vmwaremmio", mmiobase, mmiosize);
	  	}
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 1671 Nov  6 10:23 sys/src/9/pc/vgax.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/vgax.c:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/vgax.c:3,9
	  #include "mem.h"
	  #include "dat.h"
	  #include "fns.h"
	+ #include "io.h"
	  #include "../port/error.h"
	  
	  #define	Image	IMAGE
 [rsc] --rw-rw-r-- M 451989 glenda sys 8219 Nov  6 10:11 sys/src/9/port/dev.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/dev.c:157,163 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/dev.c:157,162
	  	nc->qid = c->qid;
	  	nc->offset = c->offset;
	  	nc->umh = nil;
	- 	nc->mountid = c->mountid;
	  	nc->aux = c->aux;
	  	nc->mqid = c->mqid;
	  	nc->mcp = c->mcp;
 [rsc] --rw-rw-r-- M 451989 glenda sys 43537 Nov  6 10:11 sys/src/9/port/devdraw.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:16,21 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:16,22
	  {
	  	Qtopdir		= 0,
	  	Qnew,
	+ 	Qwinname,
	  	Q3rd,
	  	Q2nd,
	  	Qcolormap,
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:53,59 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:54,59
	  
	  struct Draw
	  {
	- 	QLock;
	  	int		clientid;
	  	int		nclient;
	  	Client**	client;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:154,161 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:154,166
	  };
	  
	  static	Draw		sdraw;
	+ 	QLock	drawlock;
	+ 
	  static	Memimage	*screenimage;
	- static	Memdata		screendata;
	+ static	DImage*	screendimage;
	+ static	char	screenname[40];
	+ static	int	screennameid;
	+ 
	  static	Rectangle	flushrect;
	  static	int		waste;
	  static	DScreen*	dscreen;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:164,169 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:169,175
	  	void		drawuninstall(Client*, int);
	  	void		drawfreedimage(DImage*);
	  	Client*		drawclientofpath(ulong);
	+ 	DImage*	allocdimage(Memimage*);
	  
	  static	char Enodrawimage[] =	"unknown id for draw image";
	  static	char Enodrawscreen[] =	"unknown id for draw screen";
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:184,190 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:190,214
	  static	char Enamed[] = 	"image already has name";
	  static	char Ewrongname[] = 	"wrong name for image";
	  
	+ static void
	+ dlock(void)
	+ {
	+ 	qlock(&drawlock);
	+ }
	+ 
	  static int
	+ candlock(void)
	+ {
	+ 	return canqlock(&drawlock);
	+ }
	+ 
	+ static void
	+ dunlock(void)
	+ {
	+ 	qunlock(&drawlock);
	+ }
	+ 
	+ static int
	  drawgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
	  {
	  	int t;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:226,231 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:250,259
	  			mkqid(&q, Q2nd, 0, QTDIR);
	  			devdir(c, q, "draw", 0, eve, 0555, dp);
	  			break;
	+ 		case 1:
	+ 			mkqid(&q, Qwinname, 0, 0);
	+ 			devdir(c, q, "winname", 0, eve, 0444, dp);
	+ 			break;
	  		default:
	  			return -1;
	  		}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:498,505 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:526,533
	  	return 0;
	  }
	  
	- Memimage*
	- drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
	+ DImage*
	+ allocdimage(Memimage *i)
	  {
	  	DImage *d;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:506,512 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:534,539
	  	d = malloc(sizeof(DImage));
	  	if(d == 0)
	  		return 0;
	- 	d->id = id;
	  	d->ref = 1;
	  	d->name = 0;
	  	d->vers = 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:514,519 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:541,558
	  	d->nfchar = 0;
	  	d->fchar = 0;
	  	d->fromname = 0;
	+ 	return d;
	+ }
	+ 
	+ Memimage*
	+ drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
	+ {
	+ 	DImage *d;
	+ 
	+ 	d = allocdimage(i);
	+ 	if(d == 0)
	+ 		return 0;
	+ 	d->id = id;
	  	d->dscreen = dscreen;
	  	d->next = client->dimage[id&HASHMASK];
	  	client->dimage[id&HASHMASK] = d;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:637,644 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:676,683
	  		drawfreedimage(dimage->fromname);
	  		goto Return;
	  	}
	- 	if(dimage->image == screenimage)	/* don't free the display */
	- 		goto Return;
	+ //	if(dimage->image == screenimage)	/* don't free the display */
	+ //		goto Return;
	  	ds = dimage->dscreen;
	  	if(ds){
	  		l = dimage->image;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:856,885 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:895,954
	  	return p;
	  }
	  
	- static int
	- initscreenimage(void)
	+ static DImage*
	+ makescreenimage(void)
	  {
	  	int width, depth;
	  	ulong chan;
	+ 	DImage *di;
	+ 	Memdata *md;
	+ 	Memimage *i;
	  	Rectangle r;
	  
	+ 	md = malloc(sizeof *md);
	+ 	if(md == nil)
	+ 		return nil;
	+ 	md->allocd = 1;
	+ 	md->base = nil;
	+ 	md->bdata = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen);
	+ 	if(md->bdata == nil){
	+ 		free(md);
	+ 		return nil;
	+ 	}
	+ 	md->ref = 1;
	+ 	i = allocmemimaged(r, chan, md);
	+ 	if(i == nil){
	+ 		free(md);
	+ 		return nil;
	+ 	}
	+ 	i->width = width;
	+ 	i->clipr = r;
	+ 
	+ 	di = allocdimage(i);
	+ 	if(di == nil){
	+ 		freememimage(i);	/* frees md */
	+ 		return nil;
	+ 	}
	+ 	if(!waserror()){
	+ 		snprint(screenname, sizeof screenname, "noborder.screen.%d", ++screennameid);
	+ 		drawaddname(nil, di, strlen(screenname), screenname);
	+ 		poperror();
	+ 	}
	+ 	return di;
	+ }
	+ 
	+ static int
	+ initscreenimage(void)
	+ {
	  	if(screenimage != nil)
	  		return 1;
	  
	- 	screendata.base = nil;
	- 	screendata.bdata = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen);
	- 	if(screendata.bdata == nil)
	+ 	screendimage = makescreenimage();
	+ 	if(screendimage == nil)
	  		return 0;
	- 	screendata.ref = 1;
	- 
	- 	screenimage = allocmemimaged(r, chan, &screendata);
	- 	if(screenimage == nil){
	- 		/* RSC: BUG: detach screen */
	- 		return 0;
	- 	}
	- 
	- 	screenimage->width = width;
	- 	screenimage->clipr = r;
	+ 	screenimage = screendimage->image;
	+ // iprint("initscreenimage %p %p\n", screendimage, screenimage);
	+ 	mouseresize();
	  	return 1;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:886,908 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:955,990
	  void
	  deletescreenimage(void)
	  {
	- 	qlock(&sdraw);
	- 	/* RSC: BUG: detach screen */
	- 	if(screenimage)
	- 		freememimage(screenimage);
	- 	screenimage = nil;
	- 	qunlock(&sdraw);
	+ 	dlock();
	+ 	if(screenimage){
	+ 		/* will be freed via screendimage; disable */
	+ 		screenimage->clipr = ZR;
	+ 		screenimage = nil;
	+ 	}
	+ 	if(screendimage){
	+ 		drawfreedimage(screendimage);
	+ 		screendimage = nil;
	+ 	}
	+ 	dunlock();
	  }
	  
	+ void
	+ resetscreenimage(void)
	+ {
	+ 	dlock();
	+ 	initscreenimage();
	+ 	dunlock();
	+ }
	+ 
	  static Chan*
	  drawattach(char *spec)
	  {
	- 	qlock(&sdraw);
	+ 	dlock();
	  	if(!initscreenimage()){
	- 		qunlock(&sdraw);
	+ 		dunlock();
	  		error("no frame buffer");
	  	}
	- 	qunlock(&sdraw);
	+ 	dunlock();
	  	return devattach('i', spec);
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:909,915 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:991,997
	  static Walkqid*
	  drawwalk(Chan *c, Chan *nc, char **name, int nname)
	  {
	- 	if(screendata.bdata == nil)
	+ 	if(screenimage == nil)
	  		error("no frame buffer");
	  	return devwalk(c, nc, name, nname, 0, 0, drawgen);
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:924,929 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1006,1013
	  drawopen(Chan *c, int omode)
	  {
	  	Client *cl;
	+ 	DName *dn;
	+ 	DImage *di;
	  
	  	if(c->qid.type & QTDIR){
	  		c = devopen(c, omode, 0, 0, drawgen);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:930,938 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1014,1022
	  		c->iounit = IOUNIT;
	  	}
	  
	- 	qlock(&sdraw);
	+ 	dlock();
	  	if(waserror()){
	- 		qunlock(&sdraw);
	+ 		dunlock();
	  		nexterror();
	  	}
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:944,949 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1028,1036
	  	}
	  
	  	switch(QID(c->qid)){
	+ 	case Qwinname:
	+ 		break;
	+ 
	  	case Qnew:
	  		break;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:953,961 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1040,1061
	  			error(Einuse);
	  		cl->busy = 1;
	  		flushrect = Rect(10000, 10000, -10000, -10000);
	- 		drawinstall(cl, 0, screenimage, 0);
	+ 		dn = drawlookupname(strlen(screenname), screenname);
	+ 		if(dn == 0)
	+ 			error("draw: cannot happen 2");
	+ 		if(drawinstall(cl, 0, dn->dimage->image, 0) == 0)
	+ 			error(Edrawmem);
	+ 		di = drawlookup(cl, 0, 0);
	+ 		if(di == 0)
	+ 			error("draw: cannot happen 1");
	+ 		di->vers = dn->vers;
	+ 		di->name = smalloc(strlen(screenname)+1);
	+ 		strcpy(di->name, screenname);
	+ 		di->fromname = dn->dimage;
	+ 		di->fromname->ref++;
	  		incref(&cl->r);
	  		break;
	+ 
	  	case Qcolormap:
	  	case Qdata:
	  	case Qrefresh:
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:963,969 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1063,1069
	  		incref(&cl->r);
	  		break;
	  	}
	- 	qunlock(&sdraw);
	+ 	dunlock();
	  	poperror();
	  	c->mode = openmode(omode);
	  	c->flag |= COPEN;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:982,990 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1082,1090
	  
	  	if(QID(c->qid) < Qcolormap)	/* Qtopdir, Qnew, Q3rd, Q2nd have no client */
	  		return;
	- 	qlock(&sdraw);
	+ 	dlock();
	  	if(waserror()){
	- 		qunlock(&sdraw);
	+ 		dunlock();
	  		nexterror();
	  	}
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:1017,1023 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1117,1123
	  		drawflush();	/* to erase visible, now dead windows */
	  		free(cl);
	  	}
	- 	qunlock(&sdraw);
	+ 	dunlock();
	  	poperror();
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:1036,1045 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1136,1148
	  
	  	if(c->qid.type & QTDIR)
	  		return devdirread(c, a, n, 0, 0, drawgen);
	+ 	if(QID(c->qid) == Qwinname)
	+ 		return readstr(off, a, n, screenname);
	+ 
	  	cl = drawclient(c);
	- 	qlock(&sdraw);
	+ 	dlock();
	  	if(waserror()){
	- 		qunlock(&sdraw);
	+ 		dunlock();
	  		nexterror();
	  	}
	  	switch(QID(c->qid)){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:1096,1109 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1199,1212
	  		for(;;){
	  			if(cl->refreshme || cl->refresh)
	  				break;
	- 			qunlock(&sdraw);
	+ 			dunlock();
	  			if(waserror()){
	- 				qlock(&sdraw);	/* restore lock for waserror() above */
	+ 				dlock();	/* restore lock for waserror() above */
	  				nexterror();
	  			}
	  			sleep(&cl->refrend, drawrefactive, cl);
	  			poperror();
	- 			qlock(&sdraw);
	+ 			dlock();
	  		}
	  		p = a;
	  		while(cl->refresh && n>=5*4){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:1120,1127 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1223,1231
	  		}
	  		cl->refreshme = 0;
	  		n = p-(uchar*)a;
	+ 		break;
	  	}
	- 	qunlock(&sdraw);
	+ 	dunlock();
	  	poperror();
	  	return n;
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:1149,1158 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1253,1262
	  	if(c->qid.type & QTDIR)
	  		error(Eisdir);
	  	cl = drawclient(c);
	- 	qlock(&sdraw);
	+ 	dlock();
	  	if(waserror()){
	  		drawwakeall();
	- 		qunlock(&sdraw);
	+ 		dunlock();
	  		nexterror();
	  	}
	  	switch(QID(c->qid)){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:1206,1212 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:1310,1316
	  	default:
	  		error(Ebadusefd);
	  	}
	- 	qunlock(&sdraw);
	+ 	dunlock();
	  	poperror();
	  	return n;
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:2022,2031 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:2126,2135
	  
	  	if(blank == sdraw.blanked)
	  		return;
	- 	if(!canqlock(&sdraw))
	+ 	if(!candlock())
	  		return;
	  	if(!initscreenimage()){
	- 		qunlock(&sdraw);
	+ 		dunlock();
	  		return;
	  	}
	  	p = sdraw.savemap;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devdraw.c:2048,2054 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devdraw.c:2152,2158
	  		}
	  	}
	  	sdraw.blanked = blank;
	- 	qunlock(&sdraw);
	+ 	dunlock();
	  }
	  
	  /*
 [rsc] --rw-rw-r-- M 451989 glenda sys 28233 Nov  6 10:11 sys/src/9/port/devproc.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devproc.c:669,686 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devproc.c:669,688
	  static long
	  procread(Chan *c, void *va, long n, vlong off)
	  {
	- 	int m, navail, ne;
	+ 	char *a, flag[10], *sps, *srv, statbuf[NSEG*32];
	+ 	int i, j, m, navail, ne, pid, rsize;
	  	long l;
	- 	Proc *p;
	- 	Waitq *wq;
	- 	Ureg kur;
	  	uchar *rptr;
	+ 	ulong offset;
	+ 	Confmem *cm;
	  	Mntwalk *mw;
	+ 	Proc *p;
	  	Segment *sg, *s;
	- 	char *a = va, *sps;
	- 	int i, j, rsize, pid;
	- 	char statbuf[NSEG*32], *srv, flag[10];
	- 	ulong offset = off;
	+ 	Ureg kur;
	+ 	Waitq *wq;
	+ 	
	+ 	a = va;
	+ 	offset = off;
	  
	  	if(c->qid.type & QTDIR)
	  		return devdirread(c, a, n, 0, 0, procgen);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devproc.c:723,730 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devproc.c:725,731
	  		return n;
	  
	  	case Qmem:
	- 		if(offset < KZERO
	- 		|| (offset >= USTKTOP-USTKSIZE && offset < USTKTOP))
	+ 		if(offset < KZERO)
	  			return procctlmemio(p, offset, n, va, 1);
	  
	  		if(!iseve())
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devproc.c:737,754 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devproc.c:738,751
	  			memmove(a, (char*)offset, n);
	  			return n;
	  		}
	- 		/* conf.base* and conf.npage* are set by xinit to refer to kernel allocation, not user pages */
	- 		if(offset >= conf.base0 && offset < conf.npage0){
	- 			if(offset+n > conf.npage0)
	- 				n = conf.npage0 - offset;
	- 			memmove(a, (char*)offset, n);
	- 			return n;
	- 		}
	- 		if(offset >= conf.base1 && offset < conf.npage1){
	- 			if(offset+n > conf.npage1)
	- 				n = conf.npage1 - offset;
	- 			memmove(a, (char*)offset, n);
	- 			return n;
	+ 		for(i=0; i<nelem(conf.mem); i++){
	+ 			cm = &conf.mem[i];
	+ 			if(cm->kbase <= offset && offset < cm->klimit){
	+ 				if(offset+n > cm->klimit)
	+ 					n = cm->klimit - offset;
	+ 				memmove(a, (char*)offset, n);
	+ 				return n;
	+ 			}
	  		}
	  		error(Ebadarg);
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 30798 Nov  6 10:11 sys/src/9/port/devsd.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:15,29 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:15,29
	  extern Dev sddevtab;
	  extern SDifc* sdifc[];
	  
	- typedef struct SDevgrp {
	- 	SDev*	dev;
	- 	int	nunits;		/* num units in dev */
	- } SDevgrp;
	+ static char Echange[] = "media or partition has changed";
	  
	- static SDevgrp* devs;			/* all devices */
	- static QLock devslock;			/* insertion and removal of devices */
	- static int ndevs;			/* total number of devices in the system */
	+ static char devletters[] = "0123456789"
	+ 	"abcdefghijklmnopqrstuvwxyz"
	+ 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	  
	+ static SDev *devs[sizeof devletters-1];
	+ static QLock devslock;
	+ 
	  enum {
	  	Rawcmd,
	  	Rawdata,
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:33,40 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:33,39
	  enum {
	  	Qtopdir		= 1,		/* top level directory */
	  	Qtopbase,
	- 	Qtopctl = Qtopbase,
	- 	Qtopstat,
	+ 	Qtopctl		 = Qtopbase,
	  
	  	Qunitdir,			/* directory per unit */
	  	Qunitbase,
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:59,66 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:58,65
	  
	  	DevLOG		= 8,
	  	NDev		= (1 << DevLOG),
	- 	DevMASK	= (NDev-1),
	- 	DevSHIFT = (UnitLOG+PartLOG+TypeLOG),
	+ 	DevMASK		= (NDev-1),
	+ 	DevSHIFT	 = (UnitLOG+PartLOG+TypeLOG),
	  
	  	Ncmd = 20,
	  };
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:221,226 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:220,236
	  	return 1;
	  }
	  
	+ static int
	+ sdindex(int idno)
	+ {
	+ 	char *p;
	+ 	
	+ 	p = strchr(devletters, idno);
	+ 	if(p == nil)
	+ 		return -1;
	+ 	return p-devletters;
	+ }
	+ 
	  static SDev*
	  sdgetdev(int idno)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:227,243 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:237,248
	  	SDev *sdev;
	  	int i;
	  
	+ 	if((i = sdindex(idno)) < 0)
	+ 		return nil;
	+ 
	  	qlock(&devslock);
	- 	for(i = 0; i != ndevs; i++)
	- 		if(devs[i].dev->idno == idno)
	- 			break;
	- 	
	- 	if(i == ndevs)
	- 		sdev = nil;
	- 	else{
	- 		sdev = devs[i].dev;
	+ 	if(sdev = devs[i])
	  		incref(&sdev->r);
	- 	}
	  	qunlock(&devslock);
	  	return sdev;
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:307,374 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:312,370
	  sdreset(void)
	  {
	  	int i;
	- 	SDev *sdev, *tail, *sdlist;
	+ 	SDev *sdev;
	  
	  	/*
	- 	 * Probe all configured controllers and make a list
	- 	 * of devices found, accumulating a possible maximum number
	- 	 * of units attached and marking each device with an index
	- 	 * into the linear top-level directory array of units.
	+ 	 * Probe all known controller types and register any devices found.
	  	 */
	- 	tail = sdlist = nil;
	  	for(i = 0; sdifc[i] != nil; i++){
	  		if(sdifc[i]->pnp == nil || (sdev = sdifc[i]->pnp()) == nil)
	  			continue;
	- 		if(sdlist != nil)
	- 			tail->next = sdev;
	- 		else
	- 			sdlist = sdev;
	- 		for(tail = sdev; tail->next != nil; tail = tail->next){
	- 			tail->unit = (SDunit**)malloc(tail->nunit * sizeof(SDunit*));
	- 			tail->unitflg = (int*)malloc(tail->nunit * sizeof(int));
	- 			assert(tail->unit && tail->unitflg);
	- 			ndevs++;
	- 		}
	- 		tail->unit = (SDunit**)malloc(tail->nunit * sizeof(SDunit*));
	- 		tail->unitflg = (int*)malloc(tail->nunit * sizeof(int));
	- 		ndevs++;
	+ 		sdadddevs(sdev);
	  	}
	- 	
	- 	/*
	- 	 * Legacy and option code goes here. This will be hard...
	- 	 */
	+ }
	  
	- 	/*
	- 	 * The maximum number of possible units is known, allocate
	- 	 * placeholders for their datastructures; the units will be
	- 	 * probed and structures allocated when attached.
	- 	 * Allocate controller names for the different types.
	- 	 */
	- 	if(ndevs == 0)
	- 		return;
	- 	for(i = 0; sdifc[i] != nil; i++){
	- 		/*
	- 		 * BUG: no check is made here or later when a
	- 		 * unit is attached that the id and name are set.
	- 		 */
	- 		if(sdifc[i]->id)
	- 			sdifc[i]->id(sdlist);
	+ void
	+ sdadddevs(SDev *sdev)
	+ {
	+ 	int i, j, id;
	+ 	SDev *next;
	+ 	
	+ 	for(; sdev; sdev=next){
	+ 		next = sdev->next;
	+ 		
	+ 		sdev->unit = (SDunit**)malloc(sdev->nunit * sizeof(SDunit*));
	+ 		sdev->unitflg = (int*)malloc(sdev->nunit * sizeof(int));
	+ 		if(sdev->unit == nil || sdev->unitflg == nil){
	+ 			print("sdadddevs: out of memory\n");
	+ 		giveup:
	+ 			free(sdev->unit);
	+ 			free(sdev->unitflg);
	+ 			if(sdev->ifc->clear)
	+ 				sdev->ifc->clear(sdev);
	+ 			free(sdev);
	+ 			continue;
	+ 		}
	+ 		id = sdindex(sdev->idno);
	+ 		if(id == -1){
	+ 			print("sdadddevs: bad id number %d (%C)\n", id, id);
	+ 			goto giveup;
	+ 		}
	+ 		qlock(&devslock);
	+ 		for(i=0; i<nelem(devs); i++){
	+ 			if(devs[j = (id+i)%nelem(devs)] == nil){
	+ 				sdev->idno = devletters[j];
	+ 				devs[j] = sdev;
	+ 				snprint(sdev->name, sizeof sdev->name, "sd%c", devletters[j]);
	+ 				break;
	+ 			}
	+ 		}
	+ 		qunlock(&devslock);
	+ 		if(i == nelem(devs)){
	+ 			print("sdadddevs: out of device letters\n");
	+ 			goto giveup;
	+ 		}
	  	}
	- 
	- 	/* 
	- 	  * The IDs have been set, unlink the sdlist and copy the spec to
	- 	  * the devtab.
	- 	  */
	- 	devs = (SDevgrp*)malloc(ndevs * sizeof(SDevgrp));
	- 	memset(devs, 0, ndevs * sizeof(SDevgrp));
	- 	i = 0;
	- 	while(sdlist != nil){
	- 		devs[i].dev = sdlist;
	- 		devs[i].nunits = sdlist->nunit;
	- 		sdlist = sdlist->next;
	- 		devs[i].dev->next = nil;
	- 		i++;
	- 	}
	  }
	  
	  static int
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:438,447 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:434,439
	  		mkqid(&q, QID(0, 0, 0, Qtopctl), 0, QTFILE);
	  		devdir(c, q, "sdctl", 0, eve, 0640, dp);
	  		return 1;
	- 	case Qtopstat:
	- 		mkqid(&q, QID(0, 0, 0, Qtopstat), 0, QTFILE);
	- 		devdir(c, q, "sdstat", 0, eve, 0640, dp);
	- 		return 1;
	  	}
	  	return -1;
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:465,488 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:457,482
	  			return 1;
	  		}
	  
	- 		if(s == 0 || s == 1)
	- 			return sd1gen(c, s + Qtopbase, dp);
	- 		s -= 2;
	+ 		if(s+Qtopbase < Qunitdir)
	+ 			return sd1gen(c, s+Qtopbase, dp);
	+ 		s -= (Qunitdir-Qtopbase);
	  
	  		qlock(&devslock);
	- 		for(i = 0; i != ndevs; i++){
	- 			if(s < devs[i].nunits)
	- 				break;
	- 			s -= devs[i].nunits;
	+ 		for(i=0; i<nelem(devs); i++){
	+ 			if(devs[i]){
	+ 				if(s < devs[i]->nunit)
	+ 					break;
	+ 				s -= devs[i]->nunit;
	+ 			}
	  		}
	  		
	- 		if(i == ndevs){
	- 			/* Run of the end of the list */
	+ 		if(i == nelem(devs)){
	+ 			/* Run off the end of the list */
	  			qunlock(&devslock);
	  			return -1;
	  		}
	  
	- 		if((sdev = devs[i].dev) == nil){
	+ 		if((sdev = devs[i]) == nil){
	  			qunlock(&devslock);
	  			return 0;
	  		}
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:572,578 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:566,571
	  		decref(&sdev->r);
	  		return r;
	  	case Qtopctl:
	- 	case Qtopstat:
	  		return sd1gen(c, TYPE(c->qid), dp);
	  	default:
	  		break;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:587,595 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:580,588
	  	Chan *c;
	  	char *p;
	  	SDev *sdev;
	- 	int idno, subno, i;
	+ 	int idno, subno;
	  
	- 	if(ndevs == 0 || *spec == '\0'){
	+ 	if(*spec == '\0'){
	  		c = devattach(sddevtab.dc, spec);
	  		mkqid(&c->qid, QID(0, 0, 0, Qtopdir), 0, QTDIR);
	  		return c;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:602,618 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:595,606
	  	if(p == &spec[3])
	  		error(Ebadspec);
	  
	- 	qlock(&devslock);
	- 	for (sdev = nil, i = 0; i != ndevs; i++)
	- 		if((sdev = devs[i].dev) != nil && sdev->idno == idno)
	- 			break;
	- 
	- 	if(i == ndevs || subno >= sdev->nunit || sdgetunit(sdev, subno) == nil){
	- 		qunlock(&devslock);
	+ 	if((sdev=sdgetdev(idno)) == nil)
	  		error(Enonexist);
	+ 	if(sdgetunit(sdev, subno) == nil){
	+ 		decref(&sdev->r);
	+ 		error(Enonexist);
	  	}
	- 	incref(&sdev->r);
	- 	qunlock(&devslock);
	  
	  	c = devattach(sddevtab.dc, spec);
	  	mkqid(&c->qid, QID(sdev->idno, subno, 0, Qunitdir), 0, QTDIR);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:738,744 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:726,732
	  	}
	  	pp = &unit->part[PART(c->qid)];
	  	if(unit->vers+pp->vers != c->qid.vers)
	- 		error(Eio);
	+ 		error(Echange);
	  
	  	/*
	  	 * Check the request is within bounds.
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:867,872 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:855,1049
	  	return r->rlen;
	  }
	  
	+ /*
	+  * SCSI simulation for non-SCSI devices
	+  */
	+ int
	+ sdsetsense(SDreq *r, int status, int key, int asc, int ascq)
	+ {
	+ 	int len;
	+ 	SDunit *unit;
	+ 	
	+ 	unit = r->unit;
	+ 	unit->sense[2] = key;
	+ 	unit->sense[12] = asc;
	+ 	unit->sense[13] = ascq;
	+ 
	+ 	if(status == SDcheck && !(r->flags & SDnosense)){
	+ 		/* request sense case from sdfakescsi */
	+ 		len = sizeof unit->sense;
	+ 		if(len > sizeof r->sense-1)
	+ 			len = sizeof r->sense-1;
	+ 		memmove(r->sense, unit->sense, len);
	+ 		unit->sense[2] = 0;
	+ 		unit->sense[12] = 0;
	+ 		unit->sense[13] = 0;
	+ 		r->flags |= SDvalidsense;
	+ 		return SDok;
	+ 	}
	+ 	return status;
	+ }
	+ 
	+ int
	+ sdmodesense(SDreq *r, uchar *cmd, void *info, int ilen)
	+ {
	+ 	int len;
	+ 	uchar *data;
	+ 	
	+ 	/*
	+ 	 * Fake a vendor-specific request with page code 0,
	+ 	 * return the drive info.
	+ 	 */
	+ 	if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
	+ 		return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
	+ 	len = (cmd[7]<<8)|cmd[8];
	+ 	if(len == 0)
	+ 		return SDok;
	+ 	if(len < 8+ilen)
	+ 		return sdsetsense(r, SDcheck, 0x05, 0x1A, 0);
	+ 	if(r->data == nil || r->dlen < len)
	+ 		return sdsetsense(r, SDcheck, 0x05, 0x20, 1);
	+ 	data = r->data;
	+ 	memset(data, 0, 8);
	+ 	data[0] = ilen>>8;
	+ 	data[1] = ilen;
	+ 	if(ilen)
	+ 		memmove(data+8, info, ilen);
	+ 	r->rlen = 8+ilen;
	+ 	return sdsetsense(r, SDok, 0, 0, 0);
	+ }
	+ 
	+ int
	+ sdfakescsi(SDreq *r, void *info, int ilen)
	+ {
	+ 	uchar *cmd, *p;
	+ 	uvlong len;
	+ 	SDunit *unit;
	+ 	
	+ 	cmd = r->cmd;
	+ 	r->rlen = 0;
	+ 	unit = r->unit;
	+ 	
	+ 	/*
	+ 	 * Rewrite read(6)/write(6) into read(10)/write(10).
	+ 	 */
	+ 	switch(cmd[0]){
	+ 	case 0x08:	/* read */
	+ 	case 0x0A:	/* write */
	+ 		cmd[9] = 0;
	+ 		cmd[8] = cmd[4];
	+ 		cmd[7] = 0;
	+ 		cmd[6] = 0;
	+ 		cmd[5] = cmd[3];
	+ 		cmd[4] = cmd[2];
	+ 		cmd[3] = cmd[1] & 0x0F;
	+ 		cmd[2] = 0;
	+ 		cmd[1] &= 0xE0;
	+ 		cmd[0] |= 0x20;
	+ 		break;
	+ 	}
	+ 
	+ 	/*
	+ 	 * Map SCSI commands into ATA commands for discs.
	+ 	 * Fail any command with a LUN except INQUIRY which
	+ 	 * will return 'logical unit not supported'.
	+ 	 */
	+ 	if((cmd[1]>>5) && cmd[0] != 0x12)
	+ 		return sdsetsense(r, SDcheck, 0x05, 0x25, 0);
	+ 	
	+ 	switch(cmd[0]){
	+ 	default:
	+ 		return sdsetsense(r, SDcheck, 0x05, 0x20, 0);
	+ 	
	+ 	case 0x00:	/* test unit ready */
	+ 		return sdsetsense(r, SDok, 0, 0, 0);
	+ 	
	+ 	case 0x03:	/* request sense */
	+ 		if(cmd[4] < sizeof unit->sense)
	+ 			len = cmd[4];
	+ 		else
	+ 			len = sizeof unit->sense;
	+ 		if(r->data && r->dlen >= len){
	+ 			memmove(r->data, unit->sense, len);
	+ 			r->rlen = len;
	+ 		}
	+ 		return sdsetsense(r, SDok, 0, 0, 0);
	+ 	
	+ 	case 0x12:	/* inquiry */
	+ 		if(cmd[4] < sizeof unit->inquiry)
	+ 			len = cmd[4];
	+ 		else
	+ 			len = sizeof unit->inquiry;
	+ 		if(r->data && r->dlen >= len){
	+ 			memmove(r->data, r->sense, len);
	+ 			r->rlen = len;
	+ 		}
	+ 		return sdsetsense(r, SDok, 0, 0, 0);
	+ 
	+ 	case 0x1B:	/* start/stop unit */
	+ 		/*
	+ 		 * nop for now, can use power management later.
	+ 		 */
	+ 		return sdsetsense(r, SDok, 0, 0, 0);
	+ 	
	+ 	case 0x25:	/* read capacity */
	+ 		if((cmd[1] & 0x01) || cmd[2] || cmd[3])
	+ 			return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
	+ 		if(r->data == nil || r->dlen < 8)
	+ 			return sdsetsense(r, SDcheck, 0x05, 0x20, 1);
	+ 		
	+ 		/*
	+ 		 * Read capacity returns the LBA of the last sector.
	+ 		 */
	+ 		len = unit->sectors - 1;
	+ 		p = r->data;
	+ 		*p++ = len>>24;
	+ 		*p++ = len>>16;
	+ 		*p++ = len>>8;
	+ 		*p++ = len;
	+ 		len = 512;
	+ 		*p++ = len>>24;
	+ 		*p++ = len>>16;
	+ 		*p++ = len>>8;
	+ 		*p++ = len;
	+ 		r->rlen = p - (uchar*)r->data;
	+ 		return sdsetsense(r, SDok, 0, 0, 0);
	+ 
	+ 	case 0x9E:	/* long read capacity */
	+ 		if((cmd[1] & 0x01) || cmd[2] || cmd[3])
	+ 			return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
	+ 		if(r->data == nil || r->dlen < 8)
	+ 			return sdsetsense(r, SDcheck, 0x05, 0x20, 1);	
	+ 		/*
	+ 		 * Read capcity returns the LBA of the last sector.
	+ 		 */
	+ 		len = unit->sectors - 1;
	+ 		p = r->data;
	+ 		*p++ = len>>56;
	+ 		*p++ = len>>48;
	+ 		*p++ = len>>40;
	+ 		*p++ = len>>32;
	+ 		*p++ = len>>24;
	+ 		*p++ = len>>16;
	+ 		*p++ = len>>8;
	+ 		*p++ = len;
	+ 		len = 512;
	+ 		*p++ = len>>24;
	+ 		*p++ = len>>16;
	+ 		*p++ = len>>8;
	+ 		*p++ = len;
	+ 		r->rlen = p - (uchar*)r->data;
	+ 		return sdsetsense(r, SDok, 0, 0, 0);
	+ 	
	+ 	case 0x5A:	/* mode sense */
	+ 		return sdmodesense(r, cmd, info, ilen);
	+ 	
	+ 	case 0x28:	/* read */
	+ 	case 0x2A:	/* write */
	+ 		return SDnostatus;
	+ 	}
	+ }
	+ 
	  static long
	  sdread(Chan *c, void *a, long n, vlong off)
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:875,898 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1052,1073
	  	SDunit *unit;
	  	SDev *sdev;
	  	ulong offset;
	- 	int i, l, status;
	+ 	int i, l, m, status;
	  
	  	offset = off;
	  	switch(TYPE(c->qid)){
	  	default:
	  		error(Eperm);
	- 	case Qtopstat:
	- 		p = buf = malloc(READSTR);
	+ 	case Qtopctl:
	+ 		m = 64*1024;	/* room for register dumps */
	+ 		p = buf = malloc(m);
	  		assert(p);
	- 		e = p + READSTR;
	+ 		e = p + m;
	  		qlock(&devslock);
	- 		for(i = 0; i != ndevs; i++){
	- 			SDev *sdev = devs[i].dev;
	- 
	- 			if(sdev->ifc->stat)
	- 				p = sdev->ifc->stat(sdev, p, e);
	- 			else
	- 				p = seprint(e, "%s; no statistics available\n", sdev->name);
	+ 		for(i = 0; i < nelem(devs); i++){
	+ 			sdev = devs[i];
	+ 			if(sdev && sdev->ifc->rtopctl)
	+ 				p = sdev->ifc->rtopctl(sdev, p, e);
	  		}
	  		qunlock(&devslock);
	  		n = readstr(off, a, n, buf);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:909,916 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1084,1092
	  			error(Enonexist);
	  
	  		unit = sdev->unit[UNIT(c->qid)];
	- 		p = malloc(READSTR);
	- 		l = snprint(p, READSTR, "inquiry %.48s\n",
	+ 		m = 16*1024;	/* room for register dumps */
	+ 		p = malloc(m);
	+ 		l = snprint(p, m, "inquiry %.48s\n",
	  			(char*)unit->inquiry+8);
	  		qlock(&unit->ctl);
	  		/*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:919,936 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1095,1112
	  		 * and the garscadden trains.
	  		 */
	  		if(unit->dev->ifc->rctl)
	- 			l += unit->dev->ifc->rctl(unit, p+l, READSTR-l);
	+ 			l += unit->dev->ifc->rctl(unit, p+l, m-l);
	  		if(unit->sectors == 0)
	  			sdinitpart(unit);
	  		if(unit->sectors){
	  			if(unit->dev->ifc->rctl == nil)
	- 				l += snprint(p+l, READSTR-l,
	+ 				l += snprint(p+l, m-l,
	  					"geometry %ld %ld\n",
	  					unit->sectors, unit->secsize);
	  			pp = unit->part;
	  			for(i = 0; i < unit->npart; i++){
	  				if(pp->valid)
	- 					l += snprint(p+l, READSTR-l,
	+ 					l += snprint(p+l, m-l,
	  						"part %s %lud %lud\n",
	  						pp->name, pp->start, pp->end);
	  				pp++;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:978,1142 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1154,1227
	  	return 0;
	  }
	  
	- typedef struct Confdata Confdata;
	- struct Confdata {
	- 	int	on;
	- 	char*	spec;
	- 	DevConf	cf;
	- };
	+ static void legacytopctl(Cmdbuf*);
	  
	- static void
	- parseswitch(Confdata* cd, char* option)
	- {
	- 	if(!strcmp("on", option))
	- 		cd->on = 1;
	- 	else if(!strcmp("off", option))
	- 		cd->on = 0;
	- 	else
	- 		error(Ebadarg);
	- }
	- 
	- static void
	- parsespec(Confdata* cd, char* option)
	- {
	- 	if(strlen(option) > 1) 
	- 		error(Ebadarg);
	- 	cd->spec = option;
	- }
	- 
	- static Devport*
	- getnewport(DevConf* dc)
	- {
	- 	Devport *p;
	- 
	- 	p = (Devport *)malloc((dc->nports + 1) * sizeof(Devport));
	- 	if(dc->nports > 0){
	- 		memmove(p, dc->ports, dc->nports * sizeof(Devport));
	- 		free(dc->ports);
	- 	}
	- 	dc->ports = p;
	- 	p = &dc->ports[dc->nports++];
	- 	p->size = -1;
	- 	p->port = (ulong)-1;
	- 	return p;
	- }
	- 
	- static void
	- parseport(Confdata* cd, char* option)
	- {
	- 	char *e;
	- 	Devport *p;
	- 
	- 	if(cd->cf.nports == 0 || cd->cf.ports[cd->cf.nports-1].port != (ulong)-1)
	- 		p = getnewport(&cd->cf);
	- 	else
	- 		p = &cd->cf.ports[cd->cf.nports-1];
	- 	p->port = strtol(option, &e, 0);
	- 	if(e == nil || *e != '\0')
	- 		error(Ebadarg);
	- }
	- 
	- static void
	- parsesize(Confdata* cd, char* option)
	- {
	- 	char *e;
	- 	Devport *p;
	- 
	- 	if(cd->cf.nports == 0 || cd->cf.ports[cd->cf.nports-1].size != -1)
	- 		p = getnewport(&cd->cf);
	- 	else
	- 		p = &cd->cf.ports[cd->cf.nports-1];
	- 	p->size = (int)strtol(option, &e, 0);
	- 	if(e == nil || *e != '\0')
	- 		error(Ebadarg);
	- }
	- 
	- static void
	- parseirq(Confdata* cd, char* option)
	- {
	- 	char *e;
	- 
	- 	cd->cf.intnum = strtoul(option, &e, 0);
	- 	if(e == nil || *e != '\0')
	- 		error(Ebadarg);
	- }
	- 
	- static void
	- parsetype(Confdata* cd, char* option)
	- {
	- 	cd->cf.type = option;
	- }
	- 
	- static struct {
	- 	char	*option;
	- 	void	(*parse)(Confdata*, char*);
	- } options[] = {
	- 	{ 	"switch",	parseswitch,	},
	- 	{	"spec",		parsespec,	},
	- 	{	"port",		parseport,	},
	- 	{	"size",		parsesize,	},
	- 	{	"irq",		parseirq,	},
	- 	{	"type",		parsetype,	},
	- };
	- 
	  static long
	  sdwrite(Chan* c, void* a, long n, vlong off)
	  {
	+ 	char *f0;
	+ 	int i;
	+ 	ulong end, start;
	  	Cmdbuf *cb;
	+ 	SDifc *ifc;
	  	SDreq *req;
	  	SDunit *unit;
	  	SDev *sdev;
	- 	ulong end, start;
	  
	  	switch(TYPE(c->qid)){
	  	default:
	  		error(Eperm);
	- 	case Qtopctl: {
	- 		Confdata cd;
	- 		char buf[256], *field[Ncmd];
	- 		int nf, i, j;
	- 
	- 		memset(&cd, 0, sizeof(Confdata));
	- 		if(n > sizeof(buf)-1) n = sizeof(buf)-1;
	- 		memmove(buf, a, n);
	- 		buf[n] = '\0';
	- 
	- 		cd.on = -1;
	- 		cd.spec = '\0';
	- 		memset(&cd.cf, 0, sizeof(DevConf));
	- 
	- 		nf = tokenize(buf, field, Ncmd);
	- 		for(i = 0; i < nf; i++){
	- 			char *opt = field[i++];
	- 			if(i >= nf)
	- 				error(Ebadarg);
	- 			for(j = 0; j != nelem(options); j++)
	- 				if(!strcmp(opt, options[j].option))
	- 					break;
	- 					
	- 			if(j == nelem(options))
	- 				error(Ebadarg);
	- 			options[j].parse(&cd, field[i]);
	+ 	case Qtopctl:
	+ 		cb = parsecmd(a, n);
	+ 		if(waserror()){
	+ 			free(cb);
	+ 			nexterror();
	  		}
	- 
	- 		if(cd.on < 0) 
	- 			error(Ebadarg);
	- 
	- 		if(cd.on){
	- 			if(cd.spec == '\0' || cd.cf.nports == 0 || 
	- 			     cd.cf.intnum == 0 || cd.cf.type == nil)
	- 				error(Ebadarg);
	+ 		if(cb->nf == 0)
	+ 			error("empty control message");
	+ 		f0 = cb->f[0];
	+ 		cb->f++;
	+ 		cb->nf--;
	+ 		if(strcmp(f0, "config") == 0){
	+ 			/* wormhole into ugly legacy interface */
	+ 			legacytopctl(cb);
	+ 			poperror();
	+ 			free(cb);
	+ 			break;
	  		}
	- 		else{
	- 			if(cd.spec == '\0')
	- 				error(Ebadarg);
	+ 		ifc = nil;
	+ 		sdev = nil;
	+ 		for(i=0; sdifc[i]; i++){
	+ 			if(strcmp(sdifc[i]->name, f0) == 0){
	+ 				ifc = sdifc[i];
	+ 				sdev = nil;
	+ 				goto subtopctl;
	+ 			}
	  		}
	- 
	- 		if(sddevtab.config == nil)
	- 			error("No configuration function");
	- 		sddevtab.config(cd.on, cd.spec, &cd.cf);
	+ 		if(f0[0]=='s' && f0[1]=='d' && f0[2] && f0[3] == 0){
	+ 			if((sdev = sdgetdev(f0[2])) != nil){
	+ 				ifc = sdev->ifc;
	+ 				goto subtopctl;
	+ 			}
	+ 		}
	+ 		error("unknown interface");
	+ 	
	+ 	subtopctl:
	+ 		if(waserror()){
	+ 			if(sdev)
	+ 				decref(&sdev->r);
	+ 			nexterror();
	+ 		}
	+ 		if(ifc->wtopctl)
	+ 			ifc->wtopctl(sdev, cb);
	+ 		else
	+ 			error(Ebadctl);
	+ 		poperror();
	+ 		poperror();
	+ 		decref(&sdev->r);
	+ 		free(cb);
	  		break;
	- 	}
	+ 
	  	case Qctl:
	  		cb = parsecmd(a, n);
	  		sdev = sdgetdev(DEV(c->qid));
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:1152,1158 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1237,1243
	  			nexterror();
	  		}
	  		if(unit->vers != c->qid.vers)
	- 			error(Eio);
	+ 			error(Echange);
	  
	  		if(cb->nf < 1)
	  			error(Ebadctl);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:1293,1395 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1378,1411
	  	return n;
	  }
	  
	- static char
	- getspec(char base)
	- {
	- 	while(1){
	- 		int i;
	- 		SDev *sdev;
	- 
	- 		for(i = 0; i != ndevs; i++)
	- 			if((sdev = devs[i].dev) != nil && (char)sdev->idno == base)
	- 				break;
	- 
	- 		if(i == ndevs)
	- 			return base;
	- 		base++;
	- 	}
	- 	return '\0';
	- }
	- 
	  static int
	  configure(char* spec, DevConf* cf)
	  {
	- 	ISAConf isa;
	- 	SDevgrp *tmpdevs;
	- 	SDev *tail, *sdev, *(*probe)(DevConf*);
	- 	char *p, name[32];
	- 	int i, nnew;
	+ 	SDev *s, *sdev;
	+ 	char *p;
	+ 	int i;
	  
	+ 	if(sdindex(*spec) < 0)
	+ 		error("bad sd spec");
	+ 
	  	if((p = strchr(cf->type, '/')) != nil)
	  		*p++ = '\0';
	  
	  	for(i = 0; sdifc[i] != nil; i++)
	- 		if(!strcmp(sdifc[i]->name, cf->type))
	+ 		if(strcmp(sdifc[i]->name, cf->type) == 0)
	  			break;
	- 
	  	if(sdifc[i] == nil)
	- 		error("type not found");
	- 	
	- 	if((probe = sdifc[i]->probe) == nil)
	- 		error("No probe function");
	+ 		error("sd type not found");
	+ 	if(p)
	+ 		*(p-1) = '/';
	  
	- 	if(p){
	- 		/* Try to find the card on the ISA bus.  This code really belongs
	- 		     in sdata and I'll move it later.  Really! */
	- 		memset(&isa, 0, sizeof(isa));
	- 		isa.port = cf->ports[0].port;
	- 		isa.irq = cf->intnum;
	+ 	if(sdifc[i]->probe == nil)
	+ 		error("sd type cannot probe");
	  
	- 		if(pcmspecial(p, &isa) < 0)
	- 			error("Cannot find controller");
	- 	}
	- 
	- 	qlock(&devslock);
	- 	if(waserror()){
	- 		qunlock(&devslock);
	- 		nexterror();
	- 	}
	- 	
	- 	for(i = 0; i != ndevs; i++)
	- 		if((sdev = devs[i].dev) != nil && sdev->idno == *spec)
	- 			break;
	- 	if(i != ndevs)
	- 		error(Eexist);
	- 
	- 	if((sdev = (*probe)(cf)) == nil)
	- 		error("Cannot probe controller");
	- 	poperror();
	- 
	- 	nnew = 0;
	- 	tail = sdev;
	- 	while(tail){
	- 		nnew++;
	- 		tail = tail->next;
	- 	}
	- 	
	- 	tmpdevs = (SDevgrp*)malloc((ndevs + nnew) * sizeof(SDevgrp));
	- 	memmove(tmpdevs, devs, ndevs * sizeof(SDevgrp));
	- 	free(devs);
	- 	devs = tmpdevs;
	- 
	- 	while(sdev){
	- 		/* Assign `spec' to the device */
	- 		*spec = getspec(*spec);
	- 		snprint(name, sizeof(name), "sd%c", *spec);
	- 		kstrdup(&sdev->name, name);
	- 		sdev->idno = *spec;
	- 		sdev->unit = (SDunit **)malloc(sdev->nunit * sizeof(SDunit*));
	- 		sdev->unitflg = (int *)malloc(sdev->nunit * sizeof(int));
	- 		assert(sdev->unit && sdev->unitflg);
	- 
	- 		devs[ndevs].dev = sdev;
	- 		devs[ndevs].nunits = sdev->nunit;
	- 		sdev = sdev->next;
	- 		devs[ndevs].dev->next = nil;
	- 		ndevs++;
	- 	}
	- 
	- 	qunlock(&devslock);
	+ 	sdev = sdifc[i]->probe(cf);
	+ 	for(s=sdev; s; s=s->next)
	+ 		s->idno = *spec;
	+ 	sdadddevs(sdev);
	  	return 0;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:1398,1444 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1414,1451
	  {
	  	int i;	
	  	SDev *sdev;
	+ 	SDunit *unit;
	  
	+ 	if((i = sdindex(*spec)) < 0)
	+ 		error(Enonexist);
	+ 
	  	qlock(&devslock);
	- 	if(waserror()){
	+ 	if((sdev = devs[i]) == nil){
	  		qunlock(&devslock);
	- 		nexterror();
	- 	}
	- 
	- 	sdev = nil;
	- 	for(i = 0; i != ndevs; i++)
	- 		if((sdev = devs[i].dev) != nil && sdev->idno == *spec)
	- 			break;
	- 
	- 	if(i == ndevs)
	  		error(Enonexist);
	- 
	- 	if(sdev->r.ref)
	+ 	}
	+ 	if(sdev->r.ref){
	+ 		qunlock(&devslock);
	  		error(Einuse);
	- 
	+ 	}
	+ 	devs[i] = nil;
	+ 	qunlock(&devslock);
	+ 	
	  	/* make sure no interrupts arrive anymore before removing resources */
	  	if(sdev->enabled && sdev->ifc->disable)
	  		sdev->ifc->disable(sdev);
	  
	- 	/* we're alone and the device tab is locked; make the device unavailable */
	- 	memmove(&devs[i], &devs[ndevs - 1], sizeof(SDevgrp));
	- 	memset(&devs[ndevs - 1], 0, sizeof(SDevgrp));
	- 	ndevs--;
	- 
	- 	qunlock(&devslock);
	- 	poperror();
	- 
	- 	for(i = 0; i != sdev->nunit; i++)
	- 		if(sdev->unit[i]){
	- 			SDunit *unit = sdev->unit[i];
	- 
	+ 	for(i = 0; i != sdev->nunit; i++){
	+ 		if(unit = sdev->unit[i]){
	  			free(unit->name);
	  			free(unit->user);
	  			free(unit);
	  		}
	+ 	}
	  
	  	if(sdev->ifc->clear)
	  		sdev->ifc->clear(sdev);
	+ 	free(sdev);
	  	return 0;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsd.c:1472,1474 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsd.c:1479,1617
	  	devpower,
	  	sdconfig,
	  };
	+ 
	+ /*
	+  * This is wrong for so many reasons.  This code must go.
	+  */
	+ typedef struct Confdata Confdata;
	+ struct Confdata {
	+ 	int	on;
	+ 	char*	spec;
	+ 	DevConf	cf;
	+ };
	+ 
	+ static void
	+ parseswitch(Confdata* cd, char* option)
	+ {
	+ 	if(!strcmp("on", option))
	+ 		cd->on = 1;
	+ 	else if(!strcmp("off", option))
	+ 		cd->on = 0;
	+ 	else
	+ 		error(Ebadarg);
	+ }
	+ 
	+ static void
	+ parsespec(Confdata* cd, char* option)
	+ {
	+ 	if(strlen(option) > 1) 
	+ 		error(Ebadarg);
	+ 	cd->spec = option;
	+ }
	+ 
	+ static Devport*
	+ getnewport(DevConf* dc)
	+ {
	+ 	Devport *p;
	+ 
	+ 	p = (Devport *)malloc((dc->nports + 1) * sizeof(Devport));
	+ 	if(dc->nports > 0){
	+ 		memmove(p, dc->ports, dc->nports * sizeof(Devport));
	+ 		free(dc->ports);
	+ 	}
	+ 	dc->ports = p;
	+ 	p = &dc->ports[dc->nports++];
	+ 	p->size = -1;
	+ 	p->port = (ulong)-1;
	+ 	return p;
	+ }
	+ 
	+ static void
	+ parseport(Confdata* cd, char* option)
	+ {
	+ 	char *e;
	+ 	Devport *p;
	+ 
	+ 	if(cd->cf.nports == 0 || cd->cf.ports[cd->cf.nports-1].port != (ulong)-1)
	+ 		p = getnewport(&cd->cf);
	+ 	else
	+ 		p = &cd->cf.ports[cd->cf.nports-1];
	+ 	p->port = strtol(option, &e, 0);
	+ 	if(e == nil || *e != '\0')
	+ 		error(Ebadarg);
	+ }
	+ 
	+ static void
	+ parsesize(Confdata* cd, char* option)
	+ {
	+ 	char *e;
	+ 	Devport *p;
	+ 
	+ 	if(cd->cf.nports == 0 || cd->cf.ports[cd->cf.nports-1].size != -1)
	+ 		p = getnewport(&cd->cf);
	+ 	else
	+ 		p = &cd->cf.ports[cd->cf.nports-1];
	+ 	p->size = (int)strtol(option, &e, 0);
	+ 	if(e == nil || *e != '\0')
	+ 		error(Ebadarg);
	+ }
	+ 
	+ static void
	+ parseirq(Confdata* cd, char* option)
	+ {
	+ 	char *e;
	+ 
	+ 	cd->cf.intnum = strtoul(option, &e, 0);
	+ 	if(e == nil || *e != '\0')
	+ 		error(Ebadarg);
	+ }
	+ 
	+ static void
	+ parsetype(Confdata* cd, char* option)
	+ {
	+ 	cd->cf.type = option;
	+ }
	+ 
	+ static struct {
	+ 	char	*name;
	+ 	void	(*parse)(Confdata*, char*);
	+ } options[] = {
	+ 	"switch",	parseswitch,
	+ 	"spec",		parsespec,
	+ 	"port",		parseport,
	+ 	"size",		parsesize,
	+ 	"irq",		parseirq,
	+ 	"type",		parsetype,
	+ };
	+ 
	+ static void
	+ legacytopctl(Cmdbuf *cb)
	+ {
	+ 	char *opt;
	+ 	int i, j;
	+ 	Confdata cd;
	+ 
	+ 	memset(&cd, 0, sizeof cd);
	+ 	cd.on = -1;
	+ 	for(i=0; i<cb->nf; i+=2){
	+ 		if(i+2 > cb->nf)
	+ 			error(Ebadarg);
	+ 		opt = cb->f[i];
	+ 		for(j=0; j<nelem(options); j++)
	+ 			if(strcmp(opt, options[j].name) == 0){
	+ 				options[j].parse(&cd, cb->f[i+1]);
	+ 				break;
	+ 			}
	+ 		if(j == nelem(options))
	+ 			error(Ebadarg);
	+ 	}
	+ 	if(cd.on < 0)
	+ 		error(Ebadarg);
	+ 	if(cd.on
	+ 	&& (cd.spec == 0 || cd.cf.nports == 0 || cd.cf.intnum == 0 || cd.cf.type == nil))
	+ 		error(Ebadarg);
	+ 	if(!cd.on && cd.spec == 0)
	+ 		error(Ebadarg);
	+ 	sdconfig(cd.on, cd.spec, &cd.cf);
	+ }
	+ 	
 [rsc] --rw-rw-r-- M 451989 glenda sys 9610 Nov  6 10:11 sys/src/9/port/devsegment.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/devsegment.c:486,492 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/devsegment.c:486,492
	  	s = g->s;
	  	if(s == nil)
	  		error("global segment not assigned a virtual address");
	- 	if(isoverlap(p, s->base, s->top) != nil)
	+ 	if(isoverlap(p, s->base, s->top - s->base) != nil)
	  		error("overlaps existing segment");
	  	incref(s);
	  	unlock(&globalseglock);
 [rsc] --rw-rw-r-- M 451989 glenda sys 7271 Nov  6 10:11 sys/src/9/port/fault.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/fault.c:352,358 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/fault.c:352,358
	  			return t;
	  		a += m;
	  		n -= m;
	- 		if((a & KZERO) != KZERO)
	+ 		if(a < KZERO)
	  			validaddr(a, 1, 0);
	  	}
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 6040 Nov  6 10:11 sys/src/9/port/lib.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/lib.h:1,6 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/lib.h:1,9
	  /*
	   * functions (possibly) linked in, complete, from libc.
	   */
	+ #define nelem(x)	(sizeof(x)/sizeof((x)[0]))
	+ #define offsetof(s, m)	(ulong)(&(((s*)0)->m))
	+ #define assert(x)	if(x){}else _assert("x")
	  
	  /*
	   * mem routines
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/lib.h:27,32 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/lib.h:30,37
	  extern	char*	strstr(char*, char*);
	  extern	int	atoi(char*);
	  extern	int	fullrune(char*, int);
	+ extern	int	cistrcmp(char*, char*);
	+ extern	int	cistrncmp(char*, char*, int);
	  
	  enum
	  {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/lib.h:103,108 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/lib.h:108,114
	  extern	int	getfields(char*, char**, int, int, char*);
	  extern	int	tokenize(char*, char**, int);
	  extern	int	dec64(uchar*, int, char*, int);
	+ extern	void	qsort(void*, long, long, int (*)(void*, void*));
	  
	  /*
	   * Syscall data structures
 [rsc] --rw-rw-r-- M 451989 glenda sys 510 Nov  6 10:12 sys/src/9/port/master
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/master:40,45 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/master:40,46
	  s	srv
	  t	uart
	  v	vga
	+ w	wd
	  y	i82365
	  y	pcmcia
	  z	mntstats
 [rsc] --rw-rw-r-- M 451989 glenda sys 8449 Nov  6 10:12 sys/src/9/port/page.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/page.c:12,22 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/page.c:12,27
	  void
	  pageinit(void)
	  {
	- 	int color;
	+ 	int color, i, j;
	  	Page *p;
	- 	ulong np, vm, pm;
	+ 	Pallocmem *pm;
	+ 	ulong m, np, k, vkb, pkb;
	  
	- 	np = palloc.np0+palloc.np1;
	+ 	np = 0;
	+ 	for(i=0; i<nelem(palloc.mem); i++){
	+ 		pm = &palloc.mem[i];
	+ 		np += pm->npage;
	+ 	}
	  	palloc.head = xalloc(np*sizeof(Page));
	  	if(palloc.head == 0)
	  		panic("pageinit");
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/page.c:23,65 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/page.c:28,66
	  
	  	color = 0;
	  	p = palloc.head;
	- 	while(palloc.np0 > 0) {
	- 		p->prev = p-1;
	- 		p->next = p+1;
	- 		p->pa = palloc.p0;
	- 		p->color = color;
	- 		palloc.freecount++;
	- 		color = (color+1)%NCOLOR;
	- 		palloc.p0 += BY2PG;
	- 		palloc.np0--;
	- 		p++;
	+ 	for(i=0; i<nelem(palloc.mem); i++){
	+ 		pm = &palloc.mem[i];
	+ 		for(j=0; j<pm->npage; j++){
	+ 			p->prev = p-1;
	+ 			p->next = p+1;
	+ 			p->pa = pm->base+j*BY2PG;
	+ 			p->color = color;
	+ 			palloc.freecount++;
	+ 			color = (color+1)%NCOLOR;
	+ 			p++;
	+ 		}
	  	}
	- 	while(palloc.np1 > 0) {
	- 		p->prev = p-1;
	- 		p->next = p+1;
	- 		p->pa = palloc.p1;
	- 		p->color = color;
	- 		palloc.freecount++;
	- 		color = (color+1)%NCOLOR;
	- 		palloc.p1 += BY2PG;
	- 		palloc.np1--;
	- 		p++;
	- 	}
	  	palloc.tail = p - 1;
	  	palloc.head->prev = 0;
	  	palloc.tail->next = 0;
	  
	  	palloc.user = p - palloc.head;
	- 	pm = palloc.user*BY2PG/1024;
	- 	vm = pm + (conf.nswap*BY2PG)/1024;
	+ 	pkb = palloc.user*BY2PG/1024;
	+ 	vkb = pkb + (conf.nswap*BY2PG)/1024;
	  
	- 	/* Pageing numbers */
	+ 	/* Paging numbers */
	  	swapalloc.highwater = (palloc.user*5)/100;
	  	swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4);
	  
	- 	print("%lud free pages, ", palloc.user);
	- 	print("%ludK bytes, ", pm);
	- 	print("%ludK swap\n", vm);
	+ 	m = 0;
	+ 	for(i=0; i<nelem(conf.mem); i++)
	+ 		if(conf.mem[i].npage)
	+ 			m += conf.mem[i].npage*BY2PG;
	+ 	k = PGROUND(end - (char*)KTZERO);
	+ 	print("%ldM memory: ", (m+k+1024*1024-1)/(1024*1024));
	+ 	print("%ldM kernel data, ", (m+k-pkb*1024+1024*1024-1)/(1024*1024));
	+ 	print("%ldM user, ", pkb/1024);
	+ 	print("%ldM swap\n", vkb/1024);
	  }
	  
	  static void
 [rsc] --rw-rw-r-- M 451989 glenda sys 22628 Nov  6 10:12 sys/src/9/port/portdat.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:3,8 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:3,9
	  typedef struct Chan	Chan;
	  typedef struct Cmdbuf	Cmdbuf;
	  typedef struct Cmdtab	Cmdtab;
	+ typedef struct Confmem	Confmem;
	  typedef struct Dev	Dev;
	  typedef struct Dirtab	Dirtab;
	  typedef struct Edf	Edf;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:23,28 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:24,30
	  typedef struct Page	Page;
	  typedef struct Path	Path;
	  typedef struct Palloc	Palloc;
	+ typedef struct Pallocmem	Pallocmem;
	  typedef struct Perf	Perf;
	  typedef struct PhysUart	PhysUart;
	  typedef struct Pgrp	Pgrp;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:176,182 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:178,183
	  	int	mrock;
	  	QLock	rockqlock;
	  	int	ismtpt;
	- 	ulong	mountid;
	  	Mntcache*mcp;			/* Mount cache pointer */
	  	Mnt*	mux;			/* Mnt for clients using me for messages */
	  	union {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:480,490 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:481,496
	  	DELTAFD	= 20		/* incremental increase in Fgrp.fd's */
	  };
	  
	+ struct Pallocmem
	+ {
	+ 	ulong base;
	+ 	ulong npage;
	+ };
	+ 
	  struct Palloc
	  {
	  	Lock;
	- 	ulong	p0, p1;			/* base of pages in bank 0/1 */
	- 	ulong	np0, np1;		/* number of pages in bank 0/1 */
	+ 	Pallocmem	mem[4];
	  	Page	*head;			/* most recently used */
	  	Page	*tail;			/* least recently used */
	  	ulong	freecount;		/* how many pages on free list now */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:660,668 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:666,674
	  	ulong	pc;		/* DEBUG only */
	  
	  	Lock	rlock;		/* sync sleep/wakeup with postnote */
	- 	Rendez	*r;			/* rendezvous point slept on */
	+ 	Rendez	*r;		/* rendezvous point slept on */
	  	Rendez	sleep;		/* place for syssleep/debug */
	- 	int	notepending;/* note issued but not acted on */
	+ 	int	notepending;	/* note issued but not acted on */
	  	int	kp;		/* true if a kernel process */
	  	Proc	*palarm;	/* Next alarm time */
	  	ulong	alarm;		/* Time of call */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:669,676 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:675,682
	  	int	newtlb;		/* Pager has changed my pte's, I must flush */
	  	int	noswap;		/* process is not swappable */
	  
	- 	ulong	rendtag;	/* Tag for rendezvous */
	- 	ulong	rendval;	/* Value for rendezvous */
	+ 	uintptr	rendtag;	/* Tag for rendezvous */
	+ 	uintptr	rendval;	/* Value for rendezvous */
	  	Proc	*rendhash;	/* Hash list for tag values */
	  
	  	Timer;			/* For tsleep and real-time */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:747,763 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:753,770
	  extern	char*	conffile;
	  extern	int	cpuserver;
	  extern	Dev*	devtab[];
	- extern  char*	eve;
	+ extern	char*	eve;
	  extern	char	hostdomain[];
	  extern	uchar	initcode[];
	- extern  Queue*	kbdq;
	- extern  Queue*	kprintoq;
	- extern  Ref	noteidalloc;
	+ extern	int	kbdbuttons;
	+ extern	Queue*	kbdq;
	+ extern	Queue*	kprintoq;
	+ extern 	Ref	noteidalloc;
	+ extern	int	nsyscall;
	  extern	Palloc	palloc;
	- extern  Queue*	serialoq;
	+ extern	Queue*	serialoq;
	  extern	char*	statename[];
	- extern  Image	swapimage;
	- extern	int	nsyscall;
	+ extern	Image	swapimage;
	  extern	char*	sysname;
	  extern	Talarm	talarm;
	  extern	uint	qiomaxatomic;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:943,949 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:950,956
	  #pragma	varargck	argpos	snprint	3
	  #pragma	varargck	argpos	sprint	2
	  #pragma	varargck	argpos	fprint	2
	- #pragma varargck	argpos	panic	1
	+ #pragma	varargck	argpos	panic	1
	  
	  #pragma	varargck	type	"lld"	vlong
	  #pragma	varargck	type	"llx"	vlong
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portdat.h:972,975 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portdat.h:979,982
	  #pragma	varargck	type	"M"	uchar*
	  #pragma	varargck	type	"p"	void*
	  #pragma	varargck	type	"q"	char*
	- #pragma varargck	flag	','
	+ #pragma	varargck	flag	','
 [rsc] --rw-rw-r-- M 451989 glenda sys 10925 Nov  6 10:12 sys/src/9/port/portfns.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portfns.h:1,3 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portfns.h:1,4
	+ void		_assert(char*);
	  void		accounttime(void);
	  Timer*		addclock0link(void (*)(void), int);
	  int		addphysseg(Physseg*);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portfns.h:8,15 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portfns.h:9,14
	  Block*		allocb(int);
	  int		anyhigher(void);
	  int		anyready(void);
	- #define		assert(x)	if(x){}else _assert("assert(x) failed")
	- void		_assert(char*);
	  Image*		attachimage(int, Chan*, ulong, ulong);
	  Page*		auxpage(void);
	  Block*		bl2mem(uchar*, Block*, int);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portfns.h:176,181 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portfns.h:175,181
	  void		mmuswitch(Proc*);
	  Chan*		mntauth(Chan*, char*);
	  long		mntversion(Chan*, char*, int, int);
	+ void		mouseresize(void);
	  void		mountfree(Mount*);
	  ulong		ms2tk(ulong);
	  ulong		msize(void*);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portfns.h:185,191 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portfns.h:185,190
	  void		muxclose(Mnt*);
	  Chan*		namec(char*, int, int, ulong);
	  void		nameerror(char*, char*);
	- #define		nelem(x)	(sizeof(x)/sizeof(x[0]))
	  Chan*		newchan(void);
	  int		newfd(Chan*);
	  Mhead*		newmhead(Chan*);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portfns.h:211,219 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portfns.h:210,215
	  void		pathclose(Path*);
	  ulong		perfticks(void);
	  void		pexit(char*, int);
	- int		preempted(void);
	- void		printinit(void);
	- int		procindex(ulong);
	  void		pgrpcpy(Pgrp*, Pgrp*);
	  void		pgrpnote(ulong, char*, long, int);
	  void		pio(Segment *, ulong, ulong, Page **);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/portfns.h:220,230 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/portfns.h:216,229
	  #define		poperror()		up->nerrlab--
	  int		postnote(Proc*, int, char*, int);
	  int		pprint(char*, ...);
	+ int		preempted(void);
	  void		prflush(void);
	+ void		printinit(void);
	  ulong		procalarm(ulong);
	  void		procctl(Proc*);
	  void		procdump(void);
	  int		procfdprint(Chan*, int, int, char*, int);
	+ int		procindex(ulong);
	  void		procinit0(void);
	  void		procflushseg(Segment*);
	  void		procpriority(Proc*, int, int);
 [rsc] --rw-rw-r-- M 451989 glenda sys 28264 Nov  6 10:13 sys/src/9/port/proc.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/proc.c:113,125 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/proc.c:113,125
	  void
	  sched(void)
	  {
	- 	int x[1];
	  	Proc *p;
	  
	  	if(m->ilockdepth)
	  		panic("ilockdepth %d, last lock 0x%p at 0x%lux, sched called from 0x%lux",
	  			m->ilockdepth, up?up->lastilock:nil,
	- 			(up && up->lastilock)?up->lastilock->pc:0, getcallerpc(x+3));
	+ 			(up && up->lastilock)?up->lastilock->pc:0,
	+ 			getcallerpc(&p+2));
	  
	  	if(up){
	  		if(up->nlocks.ref && up->state != Moribund && up->delaysched < 20){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/proc.c:688,695 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/proc.c:688,697
	  	int i;
	  
	  	procalloc.free = xalloc(conf.nproc*sizeof(Proc));
	- 	if(procalloc.free == nil)
	- 		panic("cannot allocate %lud procs\n", conf.nproc);
	+ 	if(procalloc.free == nil){
	+ 		xsummary();
	+ 		panic("cannot allocate %lud procs (%ludMB)\n", conf.nproc, conf.nproc*sizeof(Proc)/(1024*1024));
	+ 	}
	  	procalloc.arena = procalloc.free;
	  
	  	p = procalloc.free;
 [rsc] --rw-rw-r-- M 451989 glenda sys 2494 Nov  6 10:13 sys/src/9/port/sd.h
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sd.h:26,31 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sd.h:26,32
	  	SDev*	dev;
	  	int	subno;
	  	uchar	inquiry[256];		/* format follows SCSI spec */
	+ 	uchar	sense[18];		/* format follows SCSI spec */
	  	SDperm;
	  
	  	QLock	ctl;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sd.h:45,52 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sd.h:46,51
	  
	  /* 
	   * Each controller is represented by a SDev.
	-  * Each controller is responsible for allocating its unit structures.
	-  * Each controller has at least one unit.
	   */ 
	  struct SDev {
	  	Ref	r;			/* Number of callers using device */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sd.h:53,59 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sd.h:52,58
	  	SDifc*	ifc;			/* pnp/legacy */
	  	void*	ctlr;
	  	int	idno;
	- 	char*	name;
	+ 	char	name[8];
	  	SDev*	next;
	  
	  	QLock;				/* enable/disable */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sd.h:69,75 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sd.h:68,73
	  
	  	SDev*	(*pnp)(void);
	  	SDev*	(*legacy)(int, int);
	- 	SDev*	(*id)(SDev*);
	  	int	(*enable)(SDev*);
	  	int	(*disable)(SDev*);
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sd.h:82,88 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sd.h:80,87
	  	long	(*bio)(SDunit*, int, int, void*, long, long);
	  	SDev*	(*probe)(DevConf*);
	  	void	(*clear)(SDev*);
	- 	char*	(*stat)(SDev*, char*, char*);
	+ 	char*	(*rtopctl)(SDev*, char*, char*);
	+ 	int	(*wtopctl)(SDev*, Cmdbuf*);
	  };
	  
	  struct SDreq {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sd.h:124,129 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sd.h:123,134
	  
	  #define sdmalloc(n)	malloc(n)
	  #define sdfree(p)	free(p)
	+ 
	+ /* devsd.c */
	+ extern void sdadddevs(SDev*);
	+ extern int sdsetsense(SDreq*, int, int, int, int);
	+ extern int sdmodesense(SDreq*, uchar*, void*, int);
	+ extern int sdfakescsi(SDreq*, void*, int);
	  
	  /* sdscsi.c */
	  extern int scsiverify(SDunit*);
 [rsc] --rw-rw-r-- M 451989 glenda sys 13722 Nov  6 12:35 sys/src/9/port/segment.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/segment.c:521,527 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/segment.c:521,527
	  			pg = s->map[i]->pages[j];
	  			/*
	  			 * We want to zero s->map[i]->page[j] and putpage(pg),
	- 			 * but we have to make sure other processors flush the entry
	+ 			 * but we have to make sure other processors flush the
	  			 * entry from their TLBs before the page is freed.
	  			 * We construct a list of the pages to be freed, zero
	  			 * the entries, then (below) call procflushseg, and call
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/segment.c:627,633 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/segment.c:627,633
	  	Segment *s, *os;
	  	Physseg *ps;
	  
	- 	if(va != 0 && (va&KZERO) == KZERO)	/* BUG: Only ok for now */
	+ 	if(va != 0 && va >= USTKTOP)
	  		error(Ebadarg);
	  
	  	validaddr((ulong)name, 1, 0);
 [rsc] --rw-rw-r-- M 451989 glenda sys 3928 Nov  6 10:13 sys/src/9/port/taslock.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/taslock.c:123,162 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/taslock.c:123,162
	  	lockstats.locks++;
	  
	  	x = splhi();
	- 	if(tas(&l->key) == 0){
	- 		m->ilockdepth++;
	- 		if(up)
	- 			up->lastilock = l;
	- 		l->sr = x;
	- 		l->pc = pc;
	- 		l->p = up;
	- 		l->isilock = 1;
	- 		return;
	- 	}
	- 
	- 	lockstats.glare++;
	- 	if(conf.nmach < 2){
	- 		dumplockmem("ilock:", l);
	- 		panic("ilock: no way out: pc %luX\n", pc);
	- 	}
	- 
	- 	for(;;){
	- 		lockstats.inglare++;
	- 		splx(x);
	- 		while(l->key)
	- 			;
	- 		x = splhi();
	- 		if(tas(&l->key) == 0){
	- 			m->ilockdepth++;
	- 			if(up)
	- 				up->lastilock = l;
	- 			l->sr = x;
	- 			l->pc = pc;
	- 			l->p = up;
	- 			l->isilock = 1;
	- 			return;
	+ 	if(tas(&l->key) != 0){
	+ 		lockstats.glare++;
	+ 		/*
	+ 		 * Cannot also check l->pc and l->m here because
	+ 		 * they might just not be set yet, or the lock might 
	+ 		 * even have been let go.
	+ 		 */
	+ 		if(!l->isilock){
	+ 			dumplockmem("ilock:", l);
	+ 			panic("corrupt ilock %p pc=%luX m=%p isilock=%d", 
	+ 				l, l->pc, l->m, l->isilock);
	  		}
	+ 		if(l->m == MACHP(m->machno))
	+ 			panic("ilock: deadlock on cpu%d pc=%luX lockpc=%luX\n", 
	+ 				m->machno, pc, l->pc);
	+ 		for(;;){
	+ 			lockstats.inglare++;
	+ 			splx(x);
	+ 			while(l->key)
	+ 				;
	+ 			x = splhi();
	+ 			if(tas(&l->key) == 0)
	+ 				goto acquire;
	+ 		}
	  	}
	+ acquire:
	+ 	m->ilockdepth++;
	+ 	if(up)
	+ 		up->lastilock = l;
	+ 	l->sr = x;
	+ 	l->pc = pc;
	+ 	l->p = up;
	+ 	l->isilock = 1;
	+ 	l->m = MACHP(m->machno);
	  }
	  
	  int
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/taslock.c:174,179 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/taslock.c:174,180
	  		up->lastlock = l;
	  	l->pc = getcallerpc(&l);
	  	l->p = up;
	+ 	l->m = MACHP(m->machno);
	  	l->isilock = 0;
	  	return 1;
	  }
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/taslock.c:187,192 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/taslock.c:188,194
	  		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->m = nil;
	  	l->key = 0;
	  	coherence();
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/taslock.c:212,217 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/taslock.c:214,220
	  		print("iunlock while lo: pc %lux, held by %lux\n", getcallerpc(&l), l->pc);
	  
	  	sr = l->sr;
	+ 	l->m = nil;
	  	l->key = 0;
	  	coherence();
	  
 [rsc] --rw-rw-r-- M 451989 glenda sys 4063 Nov  6 10:14 sys/src/9/port/xalloc.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/xalloc.c:45,52 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/xalloc.c:45,55
	  void
	  xinit(void)
	  {
	+ 	int i, n, upages, kpages;
	+ 	ulong maxkpa;
	+ 	Confmem *m;
	+ 	Pallocmem *pm;
	  	Hole *h, *eh;
	- 	int upages, np0, np1;
	  
	  	eh = &xlists.hole[Nhole-1];
	  	for(h = xlists.hole; h < eh; h++)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/xalloc.c:55,86 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/xalloc.c:58,94
	  	xlists.flist = xlists.hole;
	  
	  	upages = conf.upages;
	- 	np1 = upages;
	- 	if(np1 > conf.npage1)
	- 		np1 = conf.npage1;
	- 
	- 	palloc.p1 = conf.base1 + (conf.npage1 - np1)*BY2PG;
	- 	conf.npage1 -= np1;
	- 	xhole(conf.base1, conf.npage1*BY2PG);
	- 	conf.npage1 = conf.base1+(conf.npage1*BY2PG);
	- 	upages -= np1;
	- 
	- 	np0 = upages;
	- 	if(np0 > conf.npage0)
	- 		np0 = conf.npage0;
	- 
	- 	palloc.p0 = conf.base0 + (conf.npage0 - np0)*BY2PG;
	- 	conf.npage0 -= np0;
	- 	xhole(conf.base0, conf.npage0*BY2PG);
	- 	conf.npage0 = conf.base0+(conf.npage0*BY2PG);
	- 
	- 	palloc.np0 = np0;
	- 	palloc.np1 = np1;
	- 	/* Save the bounds of kernel alloc memory for kernel mmu mapping */
	- 	conf.base0 = (ulong)KADDR(conf.base0);
	- 	conf.base1 = (ulong)KADDR(conf.base1);
	- 	conf.npage0 = (ulong)KADDR(conf.npage0);
	- 	conf.npage1 = (ulong)KADDR(conf.npage1);
	+ 	kpages = conf.npage - upages;
	+ 	pm = palloc.mem;
	+ 	maxkpa = -KZERO;
	+ 	for(i=0; i<nelem(conf.mem); i++){
	+ 		m = &conf.mem[i];
	+ 		n = m->npage;
	+ 		if(n > kpages)
	+ 			n = kpages;
	+ 		if(m->base >= maxkpa)
	+ 			n = 0;
	+ 		else if(n > 0 && m->base+n*BY2PG >= maxkpa)
	+ 			n = (maxkpa - m->base)/BY2PG;
	+ 		/* first give to kernel */
	+ 		if(n > 0){
	+ 			m->kbase = (ulong)KADDR(m->base);
	+ 			m->klimit = (ulong)KADDR(m->base+n*BY2PG);
	+ 			xhole(m->base, n*BY2PG);
	+ 			kpages -= n;
	+ 		}
	+ 		/* if anything left over, give to user */
	+ 		if(n < m->npage){
	+ 			if(pm >= palloc.mem+nelem(palloc.mem)){
	+ 				print("xinit: losing %lud pages\n", m->npage-n);
	+ 				continue;
	+ 			}
	+ 			pm->base = m->base+n*BY2PG;
	+ 			pm->npage = m->npage - n;
	+ 			pm++;
	+ 		}
	+ 	}
	+ 	xsummary();
	  }
	  
	  void*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/xalloc.c:122,128 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/xalloc.c:130,136
	  	l = &xlists.table;
	  	for(h = *l; h; h = h->link) {
	  		if(h->size >= size) {
	- 			p = (Xhdr*)h->addr;
	+ 			p = (Xhdr*)KADDR(h->addr);
	  			h->addr += size;
	  			h->size -= size;
	  			if(h->size == 0) {
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/xalloc.c:131,137 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/xalloc.c:139,144
	  				xlists.flist = h;
	  			}
	  			iunlock(&xlists);
	- 			p = KADDR(p);
	  			if(zero)
	  				memset(p->data, 0, size);
	  			p->magix = Magichole;
 [rsc] --rw-rw-r-- M 451989 presotto sys 1076 Nov  6 10:14 sys/src/9/ppc/clock.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/clock.c:57,63 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/clock.c:57,67
	  {
	  	ulong i, j;
	  
	- 	j = m->loopconst;
	+ 	j = 0;
	+ 	if(m)
	+ 		j = m->loopconst;
	+ 	if(j == 0)
	+ 		j = 1096;
	  	while(l-- > 0)
	  		for(i=0; i < j; i++)
	  			;
 [rsc] --rw-rw-r-- M 451989 presotto sys 9327 Nov  6 10:16 sys/src/9/ppc/devether.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/devether.c:11,16 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/devether.c:11,17
	  #include "etherif.h"
	  
	  static Ether *etherxx[MaxEther];
	+ extern uchar etheraddr[];
	  
	  Chan*
	  etherattach(char* spec)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/devether.c:365,370 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/devether.c:366,372
	  		for(n = 0; cards[n].type; n++){
	  			if(cistrcmp(cards[n].type, ether->type))
	  				continue;
	+ 			memmove(ether->ea, etheraddr, 6);
	  			for(i = 0; i < ether->nopt; i++){
	  				if(strncmp(ether->opt[i], "ea=", 3))
	  					continue;
 [rsc] --rw-rw-r-- M 451989 presotto sys 19599 Nov  6 10:15 sys/src/9/ppc/etherfcc.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/etherfcc.c:8,19 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/etherfcc.c:8,19
	  #include "dat.h"
	  #include "fns.h"
	  #include "io.h"
	- #include "m8260.h"
	+ #include "imm.h"
	  #include "../port/error.h"
	  #include "../port/netif.h"
	  
	  #include "etherif.h"
	- #include "ethermii.h"
	+ #include "../ppc/ethermii.h"
	  
	  #define DBG 1
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/etherfcc.c:523,545 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/etherfcc.c:523,545
	  		/* Step 1 (Section 28.9), write the parallel ports */
	  		ctlr->pmdio = 0x01000000;
	  		ctlr->pmdck = 0x08000000;
	- 		iomem->port[0].pdir &= ~A1dir0;
	- 		iomem->port[0].pdir |= A1dir1;
	- 		iomem->port[0].psor &= ~A1psor0;
	- 		iomem->port[0].psor |= A1psor1;
	- 		iomem->port[0].ppar |= (A1dir0 | A1dir1);
	+ 		imm->port[0].pdir &= ~A1dir0;
	+ 		imm->port[0].pdir |= A1dir1;
	+ 		imm->port[0].psor &= ~A1psor0;
	+ 		imm->port[0].psor |= A1psor1;
	+ 		imm->port[0].ppar |= (A1dir0 | A1dir1);
	  		/* Step 2, Port C clocks */
	- 		iomem->port[2].psor &= ~0x00000c00;
	- 		iomem->port[2].pdir &= ~0x00000c00;
	- 		iomem->port[2].ppar |= 0x00000c00;
	- 		iomem->port[3].pdat |= (ctlr->pmdio | ctlr->pmdck);
	- 		iomem->port[3].podr |= ctlr->pmdio;
	- 		iomem->port[3].pdir |= (ctlr->pmdio | ctlr->pmdck);
	- 		iomem->port[3].ppar &= ~(ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[2].psor &= ~0x00000c00;
	+ 		imm->port[2].pdir &= ~0x00000c00;
	+ 		imm->port[2].ppar |= 0x00000c00;
	+ 		imm->port[3].pdat |= (ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[3].podr |= ctlr->pmdio;
	+ 		imm->port[3].pdir |= (ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[3].ppar &= ~(ctlr->pmdio | ctlr->pmdck);
	  		eieio();
	  		/* Step 3, Serial Interface clock routing */
	- 		iomem->cmxfcr &= ~0xff000000;	/* Clock mask */
	- 		iomem->cmxfcr |= 0x37000000;	/* Clock route */
	+ 		imm->cmxfcr &= ~0xff000000;	/* Clock mask */
	+ 		imm->cmxfcr |= 0x37000000;	/* Clock route */
	  		break;
	  
	  	case 1:
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/etherfcc.c:546,595 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/etherfcc.c:546,595
	  		/* Step 1 (Section 28.9), write the parallel ports */
	  		ctlr->pmdio = 0x00400000;
	  		ctlr->pmdck = 0x00200000;
	- 		iomem->port[1].pdir &= ~B2dir0;
	- 		iomem->port[1].pdir |= B2dir1;
	- 		iomem->port[1].psor &= ~B2psor0;
	- 		iomem->port[1].psor |= B2psor1;
	- 		iomem->port[1].ppar |= (B2dir0 | B2dir1);
	+ 		imm->port[1].pdir &= ~B2dir0;
	+ 		imm->port[1].pdir |= B2dir1;
	+ 		imm->port[1].psor &= ~B2psor0;
	+ 		imm->port[1].psor |= B2psor1;
	+ 		imm->port[1].ppar |= (B2dir0 | B2dir1);
	  		/* Step 2, Port C clocks */
	- 		iomem->port[2].psor &= ~0x00003000;
	- 		iomem->port[2].pdir &= ~0x00003000;
	- 		iomem->port[2].ppar |= 0x00003000;
	+ 		imm->port[2].psor &= ~0x00003000;
	+ 		imm->port[2].pdir &= ~0x00003000;
	+ 		imm->port[2].ppar |= 0x00003000;
	  
	- 		iomem->port[2].pdat |= (ctlr->pmdio | ctlr->pmdck);
	- 		iomem->port[2].podr |= ctlr->pmdio;
	- 		iomem->port[2].pdir |= (ctlr->pmdio | ctlr->pmdck);
	- 		iomem->port[2].ppar &= ~(ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[2].pdat |= (ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[2].podr |= ctlr->pmdio;
	+ 		imm->port[2].pdir |= (ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[2].ppar &= ~(ctlr->pmdio | ctlr->pmdck);
	  		eieio();
	  		/* Step 3, Serial Interface clock routing */
	- 		iomem->cmxfcr &= ~0x00ff0000;
	- 		iomem->cmxfcr |= 0x00250000;
	+ 		imm->cmxfcr &= ~0x00ff0000;
	+ 		imm->cmxfcr |= 0x00250000;
	  		break;
	  
	  	case 2:
	  		/* Step 1 (Section 28.9), write the parallel ports */
	- 		iomem->port[1].pdir &= ~B3dir0;
	- 		iomem->port[1].pdir |= B3dir1;
	- 		iomem->port[1].psor &= ~B3psor0;
	- 		iomem->port[1].psor |= B3psor1;
	- 		iomem->port[1].ppar |= (B3dir0 | B3dir1);
	+ 		imm->port[1].pdir &= ~B3dir0;
	+ 		imm->port[1].pdir |= B3dir1;
	+ 		imm->port[1].psor &= ~B3psor0;
	+ 		imm->port[1].psor |= B3psor1;
	+ 		imm->port[1].ppar |= (B3dir0 | B3dir1);
	  		/* Step 2, Port C clocks */
	- 		iomem->port[2].psor &= ~0x0000c000;
	- 		iomem->port[2].pdir &= ~0x0000c000;
	- 		iomem->port[2].ppar |= 0x0000c000;
	- 		iomem->port[3].pdat |= (ctlr->pmdio | ctlr->pmdck);
	- 		iomem->port[3].podr |= ctlr->pmdio;
	- 		iomem->port[3].pdir |= (ctlr->pmdio | ctlr->pmdck);
	- 		iomem->port[3].ppar &= ~(ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[2].psor &= ~0x0000c000;
	+ 		imm->port[2].pdir &= ~0x0000c000;
	+ 		imm->port[2].ppar |= 0x0000c000;
	+ 		imm->port[3].pdat |= (ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[3].podr |= ctlr->pmdio;
	+ 		imm->port[3].pdir |= (ctlr->pmdio | ctlr->pmdck);
	+ 		imm->port[3].ppar &= ~(ctlr->pmdio | ctlr->pmdck);
	  		eieio();
	  		/* Step 3, Serial Interface clock routing */
	- 		iomem->cmxfcr &= ~0x0000ff00;
	- 		iomem->cmxfcr |= 0x00003700;
	+ 		imm->cmxfcr &= ~0x0000ff00;
	+ 		imm->cmxfcr |= 0x00003700;
	  		break;
	  	}
	  	iopunlock();
	  
	- 	p = (Etherparam*)(m->imap->prmfcc + ctlr->port);
	+ 	p = (Etherparam*)(m->immr->prmfcc + ctlr->port);
	  	memset(p, 0, sizeof(Etherparam));
	  
	  	/* Step 4 */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/etherfcc.c:623,632 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/etherfcc.c:623,632
	  		p->paddr[2-i/2] = (ea[i+1]<<8)|ea[i];
	  
	  	/* Step 7, initialize parameter ram, configuration-dependent values */
	- 	p->riptr = m->imap->fccextra[ctlr->port].ri - (uchar*)INTMEM;
	- 	p->tiptr = m->imap->fccextra[ctlr->port].ti - (uchar*)INTMEM;
	- 	p->padptr = m->imap->fccextra[ctlr->port].pad - (uchar*)INTMEM;
	- 	memset(m->imap->fccextra[ctlr->port].pad, 0x88, 0x20);
	+ 	p->riptr = m->immr->fccextra[ctlr->port].ri - (uchar*)IMMR;
	+ 	p->tiptr = m->immr->fccextra[ctlr->port].ti - (uchar*)IMMR;
	+ 	p->padptr = m->immr->fccextra[ctlr->port].pad - (uchar*)IMMR;
	+ 	memset(m->immr->fccextra[ctlr->port].pad, 0x88, 0x20);
	  
	  	/* Step 8, clear out events */
	  	fcc->fcce = ~0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/etherfcc.c:690,696 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/etherfcc.c:690,696
	  	}
	  	ether->irq = fccirq[ether->port];
	  	ether->tbdf = BusPPC;
	- 	fcc = iomem->fcc + ether->port;
	+ 	fcc = imm->fcc + ether->port;
	  
	  	ctlr = malloc(sizeof(*ctlr));
	  	ether->ctlr = ctlr;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/etherfcc.c:786,792 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/etherfcc.c:786,792
	  	 */
	  
	  	ctlr = mii->ctlr;
	- 	port = iomem->port + 3;
	+ 	port = imm->port + 3;
	  	cmd = MDIwrite | (pa<<(5+2+16))| (ra<<(2+16)) | (data & 0xffff);
	  
	  	x = splhi();
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/etherfcc.c:815,821 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/etherfcc.c:815,821
	  	Ctlr *ctlr;
	  
	  	ctlr = mii->ctlr;
	- 	port = iomem->port + 3;
	+ 	port = imm->port + 3;
	  
	  	cmd = MDIread | pa<<(5+2+16) | ra<<(2+16);
	  
 [rsc] --rw-rw-r-- M 451989 presotto sys 9075 Nov  6 10:15 sys/src/9/ppc/main.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/main.c:330,342 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/main.c:330,342
	  	pa = PGROUND(PADDR(end));
	  
	  	/* Blast Board specific */
	- 	conf.npage0 = (MEM1SIZE - pa)/BY2PG;
	- 	conf.base0 = pa;
	+ 	conf.mem[0].npage = (MEM1SIZE - pa)/BY2PG;
	+ 	conf.mem[0].base = pa;
	  	
	- 	conf.npage1 = MEM2SIZE/BY2PG;
	- 	conf.base1 = MEM2BASE;
	+ 	conf.mem[1].npage = MEM2SIZE/BY2PG;
	+ 	conf.mem[1].base = MEM2BASE;
	  
	- 	conf.npage = conf.npage0 + conf.npage1;
	+ 	conf.npage = conf.mem[0].npage + conf.mem[1].npage;
	  
	  	conf.nmach = 1;
	  	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
 [rsc] --rw-rw-r-- M 451989 presotto sys 17067 Nov  6 10:15 sys/src/9/ppc/trap.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/trap.c:9,15 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/trap.c:9,15
	  #include	<trace.h>
	  
	  static Lock vctllock;
	- static Vctl *vctl[256];
	+ Vctl *vctl[256];
	  
	  void
	  intrenable(int irq, void (*f)(Ureg*, void*), void* a, char *name)
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/trap.c:56,63 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/trap.c:56,68
	  		  ((*pv)->irq != irq || (*pv)->f != f || (*pv)->a != a ||
	  		   strcmp((*pv)->name, name)))
	  		pv = &((*pv)->next);
	- 	assert(*pv);
	  
	+ 	if(*pv == nil){
	+ 		print("intrdisable: irq %d not found\n", irq);
	+ 		iunlock(&vctllock);
	+ 		return;
	+ 	}
	+ 
	  	v = *pv;
	  	*pv = (*pv)->next;	/* Link out the entry */
	  	
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/trap.c:154,159 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/trap.c:159,165
	  {
	  	int ecode, user;
	  	char buf[ERRMAX], *s;
	+ 	extern FPsave initfp;
	  
	  	ecode = (ureg->cause >> 8) & 0xff;
	  	user = (ureg->srr1 & MSR_PR) != 0;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/trap.c:379,471 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/trap.c:385,390
	  		vp[n] = 0x4e800021;		/* BL (LR) */
	  	}else
	  		vp[n] = (18<<26)|(pa&0x3FFFFFC)|3;	/* bla */
	- }
	- 
	- int intrstack[5];
	- uvlong intrtime[5];
	- vlong lastoffset;
	- int inintr;
	- int nintr[10];
	- int nintro;
	- int dblintr[64];
	- ulong thisto[32];
	- ulong thistoo;
	- vlong vnot[64];
	- ulong vnon[64];
	- 
	- void
	- dumpvno(void)
	- {
	- 	int i;
	- 
	- 	for(i = 0; i < nelem(vnon); i++){
	- 		if(vnon[i])
	- 			print("%d	%lld	%lud\n", i, vnot[i], vnon[i]);
	- 		vnot[i] = 0;
	- 		vnon[i] = 0;
	- 	}
	- 	for(i = 0; i < nelem(thisto); i++){
	- 		if(thisto[i]) print("%d	%lud\n", i, thisto[i]);
	- 		thisto[i] = 0;
	- 	}
	- 	if(thistoo) print("ovl	%lud\n", thistoo);
	- 	thistoo = 0;
	- }
	- 
	- void
	- intr(Ureg *ureg)
	- {
	- 	int vno, pvno, i;
	- 	Vctl *ctl, *v;
	- 	void (*pt)(Proc*, int, vlong);
	- 	uvlong tt, x;
	- 
	- 	cycles(&tt);
	- 	pt = proctrace;
	- 	pvno = -1;
	- 	for(i = 0; i < 64; i++){
	- 		vno = intvec();
	- 		if(vno == 0)
	- 			break;
	- 		cycles(&x);
	- 		vnot[vno] -= x;
	- 		if(vno == pvno)
	- 			dblintr[vno]++;
	- 		pvno = vno;
	- 		if(pt && up && up->trace)
	- 			pt(up, (vno << 16) | SInts, 0);
	- 	
	- 		if(vno > nelem(vctl) || (ctl = vctl[vno]) == 0) {
	- 			iprint("spurious intr %d\n", vno);
	- 			return;
	- 		}
	- 
	- 		for(v = ctl; v != nil; v = v->next)
	- 			if(v->f)
	- 				v->f(ureg, v->a);
	- 
	- 		intend(vno);	/* reenable the interrupt */
	- 
	- 		if(pt && up && up->trace)
	- 			pt(up, (vno << 16) | SInte, 0);
	- 		cycles(&x);
	- 		vnot[vno] += x;
	- 		vnon[vno]++;
	- 	}
	- 	if(i < nelem(nintr))
	- 		nintr[i]++;
	- 	else
	- 		nintro++;
	- 	cycles(&x);
	- 	tt = x - tt;
	- 	i = tt / 3600;	 /* 100 microseconds units */
	- 	if(i < nelem(thisto))
	- 		thisto[i]++;
	- 	else
	- 		thistoo++;
	- 
	- 	if(up)
	- 		preempted();
	  }
	  
	  char*
 [rsc] --rw-rw-r-- M 451989 presotto sys 9764 Nov  6 10:16 sys/src/9/ppc/uartsmc.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:4,11 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:4,12
	  #include "dat.h"
	  #include "fns.h"
	  #include "io.h"
	- #include "m8260.h"
	+ #include "imm.h"
	  #include "../port/error.h"
	+ #include "../ppc/uartsmc.h"
	  
	  /*
	   * PowerPC 8260 SMC UART
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:12,19 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:13,18
	   */
	  
	  enum {
	- 	Nuart	= 1,		/* Number of SMC Uarts */
	- 
	  	/* SMC Mode Registers */
	  	Clen		= 0x7800,	/* Character length */
	  	Sl		= 0x0400,	/* Stop length, 0: one stop bit, 1: two */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:36,44 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:35,43
	  	BDContin=	1<<9,
	  	BDIdle=		1<<8,
	  	BDPreamble=	1<<8,
	- 	BDBreak=		1<<5,
	+ 	BDBreak=	1<<5,
	  	BDFrame=	1<<4,
	- 	BDParity=		1<<3,
	+ 	BDParity=	1<<3,
	  	BDOverrun=	1<<1,
	  
	  	/* Tx and Rx buffer sizes (32 bytes) */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:71,96 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:70,81
	  */
	  };
	  
	- typedef struct UartData UartData;
	- struct UartData
	- {
	- 	int		smcno;	/* smc number: 0 or 1 */
	- 	SMC		*smc;
	- 	Uartsmc	*usmc;
	- 	char		*rxbuf;
	- 	char		*txbuf;
	- 	BD*		rxb;
	- 	BD*		txb;
	- 	int		initialized;
	- 	int		enabled;
	- } uartdata[Nuart];
	- 
	  int uartinited = 0;
	  
	  static void smcinterrupt(Ureg*, void*);
	  static void smcputc(Uart *uart, int c);
	  
	- static int
	+ int
	  baudgen(int baud)
	  {
	  	int d;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:111,117 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:96,102
	  	return smcuart;
	  }
	  
	- static void
	+ void
	  smcinit(Uart *uart)
	  {
	  	Uartsmc *p;
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:125,136 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:110,120
	  	if (ud->initialized)
	  		return;
	  
	- 	/* magic addresses */
	- 	p = m->imap->uartsmc + ud->smcno;
	- 	smc = iomem->smc + ud->smcno;	/* SMC1 */
	- 	ud->smc = smc;
	- 	ud->usmc = p;
	+ 	smcsetup(uart);	/* Steps 1 through 4, PPC-dependent */
	+ 	p = ud->usmc;
	+ 	smc = ud->smc;
	  
	+ 	/* step 5: set up buffer descriptors */
	  	/* setup my uart structure */
	  	if (ud->rxb == nil)
	  		ud->rxb = bdalloc(1);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:137,180 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:121,129
	  	if (ud->txb == nil)
	  		ud->txb = bdalloc(1);
	  
	- 	/* step 0: disable rx/tx */
	- 	smc->smcmr &= ~3;
	+ 	p->rbase = ((ulong)ud->rxb) - (ulong)IMMR;
	+ 	p->tbase = ((ulong)ud->txb) - (ulong)IMMR;
	  
	- 	ioplock();
	- 
	- 	/* step 1, Using Port D */
	- 	if (ud->smcno != 0)
	- 		panic("Don't know how to set Port D bits");
	- 	iomem->port[SMC1PORT].ppar |= SMRXD1|SMTXD1;
	- 	iomem->port[SMC1PORT].pdir |= SMTXD1;
	- 	iomem->port[SMC1PORT].pdir &= ~SMRXD1;
	- 	iomem->port[SMC1PORT].psor &= ~(SMRXD1|SMTXD1);
	- 
	- 	/* step 2: set up brgc1 */
	- 	iomem->brgc[ud->smcno]  = baudgen(uart->baud) | 0x10000;
	- 
	- 	/* step 3: route clock to SMC1 */
	- 	iomem->cmxsmr &= (ud->smcno == 0) ? ~0xb0 : ~0xb;	/* clear smcx and smcxcs */
	- 
	- 	iopunlock();
	- 
	- 	/* step 4: assign a pointer to the SMCparameter RAM */
	- 	m->imap->param[ud->smcno].smcbase = (ulong)p - INTMEM;
	- 
	- 	/* step 5: set up buffer descriptors */
	- 	p->rbase = ((ulong)ud->rxb) - (ulong)INTMEM;
	- 	p->tbase = ((ulong)ud->txb) - (ulong)INTMEM;
	- 
	- 	/* step 6: issue command to CP */
	- 	if (ud->smcno == 0)
	- 		cpmop(InitRxTx, SMC1ID, 0);
	- 	else
	- 		cpmop(InitRxTx, SMC2ID, 0);
	- 
	- 	/* step 7: protocol parameters */
	- 	p->rfcr = 0x30;
	- 	p->tfcr = 0x30;
	- 
	  	/* step 8: receive buffer size */
	  	p->mrblr = Rxsize;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:206,213 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:155,160
	  	/* 
	  	 * step 15: enable interrupts (done later)
	  	 * smc->smcm = ce_Brke | ce_Br | ce_Bsy | ce_Txb | ce_Rxb;
	- 
	- 	 * intrenable(4 + ud->smcno, smcinterrupt, up, 0, uart->name);
	  	 */
	  
	  	/* step 17: set parity, no of bits, UART mode, ... */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:261,267 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:208,214
	  	smc->smce = ce_Brke | ce_Br | ce_Bsy | ce_Txb | ce_Rxb;
	  	/* enable interrupts */
	  	smc->smcm = ce_Brke | ce_Br | ce_Bsy | ce_Txb | ce_Rxb;
	- 	intrenable(4 + ud->smcno, smcinterrupt, uart, uart->name);
	+ 	intrenable(VecSMC1 + ud->smcno, smcinterrupt, uart, uart->name);
	  	ud->enabled = 1;
	  }
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:426,433 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:373,380
	  		if(uart->freq == 0 || baud <= 0)
	  			return -1;
	  	
	- 		i = sp - iomem->smc;
	- 		iomem->brgc[i] = (((m->brghz >> 4) / baud) << 1) | 0x00010000;
	+ 		i = sp - imm->smc;
	+ 		imm->brgc[i] = (((m->brghz >> 4) / baud) << 1) | 0x00010000;
	  	}
	  	uart->baud = baud;
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/ppc/uartsmc.c:636,669 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/ppc/uartsmc.c:583,585
	  	consuart = uart;
	  	uart->console = 1;
	  } 
	- 
	- void
	- dbgputc(int c)
	- {
	- 	Uartsmc *su;
	- 	BD *tbdf;
	- 	Imap *imap;
	- 	char *addr;
	- 
	- 	/* Should work as long as Imap is mapped at 0xf0000000 (INTMEM) */
	- 
	- 	imap = (Imap*)INTMEM;
	- 	su = (Uartsmc *)(INTMEM | imap->param[0].smcbase);
	- 	tbdf = (BD *)(INTMEM | su->tbase);
	- 
	- 	/* Wait for last character to go.
	- 	*/
	- 	while (tbdf->status & BDReady)
	- 		;
	- 
	- 	addr = KADDR(tbdf->addr);
	- 	*addr = c;
	- 	tbdf->length = 1;
	- 	sync();
	- 	tbdf->status |= BDReady;
	- 
	- 	while (tbdf->status & BDReady)
	- 		;
	- 
	- 	delay(300);
	- }
 [rsc] --rw-rw-r-- M 451989 glenda sys 3037 Nov  6 11:14 sys/src/9/pc/apbootstrap.s
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/apbootstrap.s:1,3 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/apbootstrap.s:1,13
	+ /*
	+  * Start an Application Processor. This must be placed on a 4KB boundary
	+  * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
	+  * due to some shortcuts below it's restricted further to within the 1st
	+  * 64KB. The AP starts in real-mode, with
	+  *   CS selector set to the startup memory address/16;
	+  *   CS base set to startup memory address;
	+  *   CS limit set to 64KB;
	+  *   CPL and IP set to 0.
	+  */
	  #include "mem.h"
	  
	  #define NOP		BYTE $0x90		/* NOP */
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/apbootstrap.s:23,38 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/apbootstrap.s:33,38
	  #define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
	  #define PTO(a)		(((((a))>>12) & 0x03FF)<<2)
	  
	- /*
	-  * Start an Application Processor. This must be placed on a 4KB boundary
	-  * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
	-  * due to some shortcuts below it's restricted further to within the 1st
	-  * 64KB. The AP starts in real-mode, with
	-  *   CS selector set to the startup memory address/16;
	-  *   CS base set to startup memory address;
	-  *   CS limit set to 64KB;
	-  *   CPL and IP set to 0.
	-  */
	  TEXT apbootstrap(SB), $0
	  	FARJUMP16(0, _apbootstrap(SB))
	  TEXT _apvector(SB), $0				/* address APBOOTSTRAP+0x08 */
 [rsc] --rw-rw-r-- M 451989 glenda sys 7133 Nov  6 11:09 sys/src/9/pc/sdscsi.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/sdscsi.c:372,394 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/sdscsi.c:372,374
	  	return rlen;
	  }
	  
	- SDev*
	- scsiid(SDev* sdev, SDifc* ifc)
	- {
	- 	char name[32];
	- 	static char idno[16] = "0123456789abcdef";
	- 	static char *p = idno;
	- 
	- 	while(sdev){
	- 		if(sdev->ifc == ifc){
	- 			sdev->idno = *p++;
	- 			snprint(name, sizeof(name), "sd%c", sdev->idno);
	- 			kstrdup(&sdev->name, name);
	- 			if(p >= &idno[sizeof(idno)])
	- 				break;
	- 		}
	- 		sdev = sdev->next;
	- 	}
	- 
	- 	return nil;
	- }
 [rsc] --rw-rw-r-- M 451989 rsc sys 2658 Nov  6 11:30 sys/src/9/pc/realmode.c
 [rsc] --rw-rw-r-- M 451989 glenda sys 15159 Nov  6 12:35 sys/src/9/port/sysproc.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sysproc.c:259,265 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sysproc.c:259,265
	  		text = l2be(exec.text);
	  		entry = l2be(exec.entry);
	  		if(n==sizeof(Exec) && (magic == AOUT_MAGIC)){
	- 			if((text&KZERO) == KZERO
	+ 			if(text >= USTKTOP-UTZERO
	  			|| entry < UTZERO+sizeof(Exec)
	  			|| entry >= UTZERO+sizeof(Exec)+text)
	  				error(Ebadexec);
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sysproc.c:298,304 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sysproc.c:298,304
	  	d = (t + data + (BY2PG-1)) & ~(BY2PG-1);
	  	bssend = t + data + bss;
	  	b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
	- 	if(((t|d|b) & KZERO) == KZERO)
	+ 	if(t >= KZERO || d >= KZERO || b >= KZERO)
	  		error(Ebadexec);
	  
	  	/*
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/sysproc.c:807,819 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/sysproc.c:807,818
	  long
	  sysrendezvous(ulong *arg)
	  {
	- 	ulong tag;
	- 	ulong val;
	+ 	uintptr tag, val;
	  	Proc *p, **l;
	  
	  	tag = arg[0];
	  	l = &REND(up->rgrp, tag);
	- 	up->rendval = ~0UL;
	+ 	up->rendval = ~(uintptr)0;
	  
	  	lock(up->rgrp);
	  	for(p = *l; p; p = p->rendhash) {
 [rsc] --rw-rw-r-- M 451989 glenda sys 3580 Nov  6 11:34 sys/src/9/pc/mkfile
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:1,11 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:1,18
	  CONF=pc
	  CONFLIST=pc pccpu pcf pccpuf pcdisk pcauth
	- CRAPLIST=pccd pccpud pccpusape pcext pcf pcflop pcglenda pcgr pclml pcmartha pcsape pcblast
	+ CRAPLIST=pccd pcflop pcmartha
	+ EXTRACOPIES=
	+ #EXTRACOPIES=lookout boundary	# copy to these servers on install
	  
	  objtype=386
	  </$objtype/mkfile
	  p=9
	  
	+ # must match mem.h
	+ 
	+ APBOOTSTRAP=0xF0003000
	+ KTZERO=0xF0100020
	+ 
	  DEVS=`{rc ../port/mkdevlist $CONF}
	  
	  PORT=\
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:16,24 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:23,31
	  	cache.$O\
	  	chan.$O\
	  	dev.$O\
	+ 	edf.$O\
	  	fault.$O\
	  	latin1.$O\
	- 	edf.$O\
	  	page.$O\
	  	parse.$O\
	  	pgrp.$O\
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:27,32 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:34,40
	  	proc.$O\
	  	qio.$O\
	  	qlock.$O\
	+ 	rdb.$O\
	  	rebootcmd.$O\
	  	segment.$O\
	  	swap.$O\
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:47,53 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:55,60
	  	memory.$O\
	  	mmu.$O\
	  	random.$O\
	- 	rdb.$O\
	  	trap.$O\
	  	$CONF.root.$O\
	  	$CONF.rootc.$O\
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:67,81 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:74,89
	  
	  $p$CONF:	$CONF.c $OBJ $LIB
	  	$CC $CFLAGS '-DKERNDATE='`{date -n} $CONF.c
	- 	$LD -o $target -T0x80100020 -l $OBJ $CONF.$O $LIB
	+ 	$LD -o $target -T$KTZERO -l $OBJ $CONF.$O $LIB
	  	size $target
	  
	- $p$CONF.gz: $p$CONF
	- 	strip < $p$CONF | gzip -9 > $p$CONF.gz
	+ $p$CONF.gz:	$p$CONF
	+ 	strip -o /fd/1 $p$CONF | gzip -9 > $p$CONF.gz
	  
	- install:V: $p$CONF $p$CONF.gz
	+ install:V:	$p$CONF $p$CONF.gz
	  	cp $p$CONF $p$CONF.gz /$objtype/
	- 	# import lookout / /n/lookout && cp $p$CONF $p$CONF.gz /n/lookout/$objtype/
	+ 	for(i in $EXTRACOPIES)
	+ 		import $i / /n/$i && cp $p$CONF $p$CONF.gz /n/$i/$objtype/
	  
	  <../boot/bootmkfile
	  <../port/portmkfile
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:90,109 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:98,118
	  $SDEV:				../port/sd.h
	  sd53c8xx.$O:			sd53c8xx.i
	  main.$O:			init.h reboot.h
	- wavelan.$O:	wavelan.c ../pc/wavelan.c ../pc/wavelan.h
	- etherwavelan.$O:	etherwavelan.c  ../pc/wavelan.h
	- devusb.$O usbuhci.$O usbohci.$O:	usb.h
	- trap.$O:	/sys/include/tos.h
	+ wavelan.$O:			wavelan.c ../pc/wavelan.c ../pc/wavelan.h
	+ etherwavelan.$O:		etherwavelan.c ../pc/wavelan.h
	+ devusb.$O usbuhci.$O usbohci.$O: usb.h
	+ trap.$O:			/sys/include/tos.h
	  
	  sd53c8xx.i:	sd53c8xx.n
	  	aux/na $prereq > $target
	  
	- init.h:	../port/initcode.c init9.c
	+ init.h:		../port/initcode.c init9.c
	  	$CC ../port/initcode.c
	  	$CC init9.c
	  	$LD -l -R1 -o init.out init9.$O initcode.$O /386/lib/libc.a
	+ 	strip init.out
	  	{echo 'uchar initcode[]={'
	- 	 strip < init.out | xd -1x |
	+ 	 cat init.out | xd -1x |
	  		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
	  	 echo '};'} > init.h
	  
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:117,123 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:126,132
	  
	  apbootstrap.h:	apbootstrap.s mem.h
	  	$AS $prereq
	- 	$LD -o apbootstrap.out -T0x80001000 -R4 -l -s apbootstrap.$O
	+ 	$LD -o apbootstrap.out -T$APBOOTSTRAP -R4 -l -s apbootstrap.$O
	  	{echo 'uchar apbootstrap[]={'
	  	 xd -1x apbootstrap.out |
	  		sed -e '1,2d' -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:124,130 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:133,139
	  	 echo '};'} > $target
	  
	  acid:V:
	- 	8c -a -w -I. ../port/qio.c>acid
	+ 	8c -a -w -I. i8253.c>acid
	  
	  %.checkether:VQ:
	  	for (i in ether*.c){
	/n/sourcesdump/2005/1106/plan9/sys/src/9/pc/mkfile:148,151 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/pc/mkfile:157,172
	  		mk $i.$j
	  
	  %.clean:V:
	- 	rm -f $stem.c [9bz]$stem [9bz]$stem.gz boot$stem.*
	+ 	rm -f $stem.c [9bz]$stem [9bz]$stem.gz boot$stem.* reboot.h apbootstrap.h init.h
	+ 
	+ # testing
	+ 9load:D: /usr/rsc/boot/$O.load 9pcload
	+ 	cat $prereq >$target
	+ 
	+ 9load.flp: 9load
	+ 	disk/format -b /386/pbs -df $target $prereq
	+ 
	+ $p$CONF.flp: /386/9load plan9.ini $p$CONF.gz
	+ 	disk/format -b /386/pbs -df $target $prereq
	+ 
	+ 
 [rsc] --rw-rw-r-- M 451989 glenda sys 33663 Nov  6 12:38 sys/src/9/port/chan.c
	/n/sourcesdump/2005/1106/plan9/sys/src/9/port/chan.c:1600,1606 - 
	/n/sourcesdump/2005/1107/plan9/sys/src/9/port/chan.c:1600,1607
	  	Rune r;
	  
	  	name = aname;
	- 	if(((ulong)name & KZERO) != KZERO){
	+ 	if((ulong)name < KZERO){
	+ 		validaddr((ulong)name, 1, 0);
	  		if(!dup)
	  			print("warning: validname called from %lux with user pointer", pc);
	  		p = name;
 [rsc] --rw-rw-r-- M 451989 glenda sys 13722 Nov  6 12:35 sys/src/9/port/segment.c
 [rsc] --rw-rw-r-- M 451989 glenda sys 15159 Nov  6 12:35 sys/src/9/port/sysproc.c
 [rsc] --rw-rw-r-- M 451989 glenda sys 1446 Nov  6 12:59 sys/src/9/pc/pcdisk
 [rsc] --rw-rw-r-- M 451989 presotto sys 1504 Nov  6 12:59 sys/src/9/pc/pcf
 [rsc] --rw-rw-r-- M 451989 presotto sys 1486 Nov  6 12:59 sys/src/9/pc/pccpuf
 [rsc] --rw-rw-r-- M 451989 rsc sys 1473 Nov  6 12:59 sys/src/9/pc/pcflop
 [rsc] --rw-rw-r-- M 451989 glenda sys 21180 Nov  6 14:44 sys/src/9/pc/trap.c
 [rsc] --rw-rw-r-- M 451989 glenda sys 19739 Nov  6 20:17 sys/src/9/pc/mmu.c
 [rsc] --rw-rw-r-- M 451989 glenda sys 17157 Nov  6 20:17 sys/src/9/pc/mp.c


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].