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= 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<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; iminarena = 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= 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>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; ibase, 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; ibase >= (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; ibase = mp->addr; + cm->npage = mp->size/BY2PG; } + + lost = 0; + for(; iaddr; - 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 %#.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= 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 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; istate == Dead) + continue; + if(p != up) + p->newtlb = 1; + } + for(i=0; iflushmmu = 1; + } + flushmmu(); + for(i=0; imachno)) && 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; ipa|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; imem); 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; imem); 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(; adsalist.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 + 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 <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; ltrap); } - 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; imem); 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; iaperture; - 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; imem); 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; jmem); 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; jmem); 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; ikbase <= 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; iidno = 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; inunit) + 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; inf; i+=2){ + if(i+2 > cb->nf) + error(Ebadarg); + opt = cb->f[i]; + for(j=0; jf[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; inpage; + } 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; inpage; 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; inerrlab-- 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; inpage; + 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 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 $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