From 294530301d08ede88bafdbc8f17d34700f11172c Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 22 Jun 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-06-22 --- bitsy/clock.c | 1 + bitsy/power.c | 85 +++++++----- bitsy/screen.c | 334 +++++++++++++++++++++++++++++++++++++++++++++++- pc/devarch.c | 55 ++++++++ pc/devether.c | 1 + pc/etherelnk3.c | 63 +++++++-- pc/fns.h | 4 + pc/io.h | 4 + pc/pci.c | 42 ++++-- 9 files changed, 530 insertions(+), 59 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index aa9114c93789d0a1e3309fe8a5b01feebd004039..5ebe94abeaa98ce8d4440cd0bc99c8845ad0aae5 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -30,6 +30,7 @@ clockpower(int on) timerregs->oier = 1<<0; timerregs->osmr[0] = timerregs->oscr + ClockFreq/HZ; } + clockinited = on; } void diff --git a/bitsy/power.c b/bitsy/power.c index 830ac66a4a11717df522e806f552acd17db16887..856652dfa7f5cf8fb62c7b7b3a8299b30fae3cfd 100644 --- a/bitsy/power.c +++ b/bitsy/power.c @@ -19,6 +19,7 @@ ulong powerflag = 0; /* set to start power-off sequence */ extern void sa1100_power_resume(void); extern int setpowerlabel(void); +extern void _start(void); extern Uart sa1110uart[]; GPIOregs savedgpioregs; @@ -71,29 +72,40 @@ gpiocpy(GPIOregs *to, GPIOregs *from) to->direction = from->direction; } +void (*restart)(void) = nil; + static void sa1100_power_off(void) { + cacheflush(); + mmuinvalidate(); + mmudisable(); + /* enable wakeup by µcontroller, on/off switch or real-time clock alarm */ powerregs->pwer = 1 << IRQrtc | 1 << IRQgpio0 | 1 << IRQgpio1; /* clear previous reset status */ resetregs->rcsr = RCSR_all; +sa1100_power_resume(); + /* disable internal oscillator, float CS lines */ powerregs->pcfr = PCFR_opde | PCFR_fp | PCFR_fs; powerregs->pgsr = 0; /* set resume address. The loader jumps to it */ - powerregs->pspr = (ulong)sa1100_power_resume; +// powerregs->pspr = (ulong)sa1100_power_resume; +// powerregs->pspr = (ulong)_start; /* set lowest clock; delay to avoid resume hangs on fast sa1110 */ + delay(90); - powerregs->ppcr = 0; +// powerregs->ppcr = 0; delay(90); /* set all GPIOs to input mode */ gpioregs->direction = 0; delay(100); /* enter sleep mode */ + powerregs->pmcr = PCFR_suspend; for(;;); } @@ -109,28 +121,6 @@ bitno(ulong x) return i; } -void -onoffintr(Ureg* , void*) -{ - int i; - - /* Power down interrupt comes on power button release. - * Act only after button has been released a full 100 ms - */ - - if (powerflag) - return; - - for (i = 0; i < 100; i++) { - delay(1); - if ((gpioregs->level & GPIO_PWR_ON_i) == 0) - return; /* bounced */ - } - - powerflag = 1; - wakeup(&powerr); -} - int powerdown(void *) { @@ -140,8 +130,13 @@ powerdown(void *) void deepsleep(void) { static int power_pl; + void *xsp, *xlink; power_pl = splhi(); + xsp = getsp(); + xlink = getlink(); + iprint("starting power down, sp = %lux, link = %lux\n", xsp, xlink); + delay(1000); cachewb(); delay(500); if (setpowerlabel()) { @@ -167,6 +162,11 @@ deepsleep(void) { iprint("\nresuming execution\n"); // dumpitall(); delay(800); + delay(1000); + xsp = getsp(); + xlink = getlink(); + iprint("power restored, sp = %lux, link = %lux\n", xsp, xlink); + splx(power_pl); return; } @@ -189,33 +189,48 @@ deepsleep(void) { void powerkproc(void*) { - void *xsp, *xlink; for(;;){ while(powerflag == 0) sleep(&powerr, powerdown, 0); + + deepsleep(); + + delay(2000); + powerflag = 0; - xsp = getsp(); - xlink = getlink(); - iprint("starting power down, sp = %lux, link = %lux\n", xsp, xlink); - delay(1000); + } +} - deepsleep(); +void +onoffintr(Ureg* , void*) +{ + int i; - delay(1000); - xsp = getsp(); - xlink = getlink(); - iprint("power restored, sp = %lux, link = %lux\n", xsp, xlink); + /* Power down interrupt comes on power button release. + * Act only after button has been released a full 100 ms + */ + if (powerflag) + return; + + for (i = 0; i < 100; i++) { + delay(1); + if ((gpioregs->level & GPIO_PWR_ON_i) == 0) + return; /* bounced */ } + + deepsleep(); +// powerflag = 1; +// wakeup(&powerr); } void powerinit(void) { - intrenable(GPIOrising, bitno(GPIO_PWR_ON_i), onoffintr, (void*)0x12344321, "on/off"); + intrenable(GPIOrising, bitno(GPIO_PWR_ON_i), onoffintr, nil, "on/off"); } void diff --git a/bitsy/screen.c b/bitsy/screen.c index c0959dd3061edfafc2eba6bac015d3d38d5278f6..cf59d514f55f672bbb871741b43b0fdef13b1b82 100644 --- a/bitsy/screen.c +++ b/bitsy/screen.c @@ -151,4 +151,336 @@ Point curpos; int h, w; int drawdebug; -static ulong rep(u +static ulong rep(ulong, int); +static void screenwin(void); +static void screenputc(char *buf); +static void bitsyscreenputs(char *s, int n); +static void scroll(void); + +static void +lcdstop(void) { + lcd->lccr0 &= ~(0<lcsr & LDD) == 0) + delay(10); + lcdpower(0); +} + +static void +lcdinit(void) +{ + /* the following line works because main memory is direct mapped */ + lcd->dbar1 = framebuf->palette; + lcd->lccr3 = pcd<lccr2 = (Wid-1)<lccr1 = (Ht-16)<lccr0 = 1<r = Rect(0, 0, Ht, Wid); + gscreen->clipr = gscreen->r; + xgdata.bdata = (uchar *)framebuf->pixel; + } else { + gscreen->r = Rect(0, 0, Wid, Ht); + gscreen->clipr = gscreen->r; + xgdata.bdata = (uchar *)vscreen; + } + landscape = ls; +} + +void +lcdtweak(Cmdbuf *cmd) +{ + if(cmd->nf < 4) + return; + if(*cmd->f[0] == 'h') + lcd->lccr1 = ((Ht-16)<f[1])<f[2])<f[3])<f[0] == 'v') + lcd->lccr2 = ((Wid-1)<f[1])<f[2])<f[3])<palette, sizeof framebuf->palette); + blankscreen(1); + } else { + memmove(framebuf->palette, savedpalette, sizeof framebuf->palette); + blankscreen(0); + } +} + +void +screeninit(void) +{ + int i; + + /* map the lcd regs into the kernel's virtual space */ + lcd = (struct sa1110regs*)mapspecial(LCDREGS, sizeof(struct sa1110regs));; + + framebuf = xspanalloc(sizeof *framebuf, 0x100, 0); + + vscreen = xalloc(sizeof(ushort)*Wid*Ht); + + framebuf->palette[0] = Pal0; + + lcdpower(1); + lcdinit(); + + gscreen = &xgscreen; + xgdata.ref = 1; + i = 0; + if (landscape) { + xgdata.bdata = (uchar *)framebuf->pixel; + while (i < Wid*Ht*1/3) framebuf->pixel[i++] = 0xf800; /* red */ + while (i < Wid*Ht*2/3) framebuf->pixel[i++] = 0xffff; /* white */ + while (i < Wid*Ht*3/3) framebuf->pixel[i++] = 0x001f; /* blue */ + } else { + xgdata.bdata = (uchar *)vscreen; + while (i < Wid*Ht*1/3) vscreen[i++] = 0xf800; /* red */ + while (i < Wid*Ht*2/3) vscreen[i++] = 0xffff; /* white */ + while (i < Wid*Ht*3/3) vscreen[i++] = 0x001f; /* blue */ + flushmemscreen(gscreen->r); + } + memimageinit(); + memdefont = getmemdefont(); + + out.pos.x = MINX; + out.pos.y = 0; + out.bwid = memdefont->info[' '].width; + + blanktime = 3; /* minutes */ + + screenwin(); + screenputs = bitsyscreenputs; +} + +void +flushmemscreen(Rectangle r) +{ + int x, y; + ulong start, end; + + if (landscape == 0) { + if (r.min.x < 0) r.min.x = 0; + if (r.max.x > Wid) r.max.x = Wid; + if (r.min.y < 0) r.min.y = 0; + if (r.max.y > Ht) r.max.y = Ht; + for (x = r.min.x; x < r.max.x; x++) + for (y = r.min.y; y < r.max.y; y++) + framebuf->pixel[(x+1)*Ht-1-y] = gamma[vscreen[y*Wid+x]]; + start = (ulong)&framebuf->pixel[(r.min.x+1)*Ht-1-(r.max.y-1)]; + end = (ulong)&framebuf->pixel[(r.max.x-1+1)*Ht-1-(r.min.y)]; + } else { + start = (ulong)&framebuf->pixel[r.min.y*Ht + r.min.x]; + end = (ulong)&framebuf->pixel[(r.max.y-1)*Ht + r.max.x - 1]; + } + cachewbregion(start, end-start); +} + +/* + * export screen to devdraw + */ +uchar* +attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen) +{ + *r = gscreen->r; + *d = gscreen->depth; + *chan = gscreen->chan; + *width = gscreen->width; + *softscreen = (landscape == 0); + + return (uchar*)gscreen->data->bdata; +} + +void +getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb) +{ + USED(p, pr, pg, pb); +} + +int +setcolor(ulong p, ulong r, ulong g, ulong b) +{ + USED(p,r,g,b); + return 0; +} + +void +blankscreen(int blank) +{ + if (blank) { + lcdpower(0); + } else { + lcdpower(1); + lcdinit(); + } +} + +static void +bitsyscreenputs(char *s, int n) +{ + int i; + Rune r; + char buf[4]; + + if(!islo()) { + /* don't deadlock trying to print in interrupt */ + if(!canlock(&screenlock)) + return; + } + else + lock(&screenlock); + + while(n > 0){ + i = chartorune(&r, s); + if(i == 0){ + s++; + --n; + continue; + } + memmove(buf, s, i); + buf[i] = 0; + n -= i; + s += i; + screenputc(buf); + } + unlock(&screenlock); +} + +static void +screenwin(void) +{ + Point p, q; + char *greet; + Memimage *orange; + Rectangle r; + + memsetchan(gscreen, RGB16); + + back = memwhite; + conscol = memblack; + + orange = allocmemimage(Rect(0,0,1,1), RGB16); + orange->flags |= Frepl; + orange->clipr = gscreen->r; + orange->data->bdata[0] = 0x40; + orange->data->bdata[1] = 0xfd; + + w = memdefont->info[' '].width; + h = memdefont->height; + + r = insetrect(gscreen->r, 4); + + memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP); + window = insetrect(r, 4); + memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP); + + memimagedraw(gscreen, Rect(window.min.x, window.min.y, + window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP); + freememimage(orange); + window = insetrect(window, 5); + + greet = " Plan 9 Console "; + p = addpt(window.min, Pt(10, 0)); + q = memsubfontwidth(memdefont, greet); + memimagestring(gscreen, p, conscol, ZP, memdefont, greet); + flushmemscreen(r); + window.min.y += h+6; + curpos = window.min; + window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; +} + +static void +screenputc(char *buf) +{ + Point p; + int w, pos; + Rectangle r; + static int *xp; + static int xbuf[256]; + + if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) + xp = xbuf; + + switch(buf[0]) { + case '\n': + if(curpos.y+h >= window.max.y) + scroll(); + curpos.y += h; + screenputc("\r"); + break; + case '\r': + xp = xbuf; + curpos.x = window.min.x; + break; + case '\t': + p = memsubfontwidth(memdefont, " "); + w = p.x; + if(curpos.x >= window.max.x-4*w) + screenputc("\n"); + + pos = (curpos.x-window.min.x)/w; + pos = 4-(pos%4); + *xp++ = curpos.x; + r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h); + memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); + flushmemscreen(r); + curpos.x += pos*w; + break; + case '\b': + if(xp <= xbuf) + break; + xp--; + r = Rect(*xp, curpos.y, curpos.x, curpos.y + h); + memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); + flushmemscreen(r); + curpos.x = *xp; + break; + case '\0': + break; + default: + p = memsubfontwidth(memdefont, buf); + w = p.x; + + if(curpos.x >= window.max.x-w) + screenputc("\n"); + + *xp++ = curpos.x; + r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h); + memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min); + memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); + flushmemscreen(r); + curpos.x += w; + } +} + +static void +scroll(void) +{ + int o; + Point p; + Rectangle r; + + o = 8*h; + r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); + p = Pt(window.min.x, window.min.y+o); + memimagedraw(gscreen, r, gscreen, p, nil, p); + flushmemscreen(r); + r = Rpt(Pt(window.min.x, window.max.y-o), window.max); + memimagedraw(gscreen, r, back, ZP, nil, ZP); + flushmemscreen(r); + + curpos.y -= o; +} diff --git a/pc/devarch.c b/pc/devarch.c index 2f1e99f1d8bd231808db463c4ec50b0993ab0e33..7129be4a26e0294f60ec02c619014854cc67f25f 100644 --- a/pc/devarch.c +++ b/pc/devarch.c @@ -11,6 +11,7 @@ typedef struct IOMap IOMap; struct IOMap { IOMap *next; + int reserved; char tag[13]; ulong start; ulong end; @@ -103,6 +104,54 @@ ioinit(void) // a dummy entry at 2^16 ioalloc(0x10000, 1, 0, "dummy"); + ioalloc(0x1000, 1, 0, "dummy"); +} + +// Reserve a range to be ioalloced later. This is in particular useful for exchangable cards, such +// as pcmcia and cardbus cards. +int +ioreserve(int port, int size, int align, char *tag) +{ + IOMap *m, **l; + int i; + + lock(&iomap); + // find a free port above 0x400 and below 0x1000 + port = 0x400; + for(l = &iomap.m; *l; l = &(*l)->next){ + m = *l; + if (m->start < 0x400) continue; + i = m->start - port; + if(i > size) + break; + if(align > 0) + port = ((port+align-1)/align)*align; + else + port = m->end; + } + if(*l == nil){ + unlock(&iomap); + return -1; + } + m = iomap.free; + if(m == nil){ + print("ioalloc: out of maps"); + unlock(&iomap); + return port; + } + iomap.free = m->next; + m->next = *l; + m->start = port; + m->end = port + size; + m->reserved = 1; + strncpy(m->tag, tag, sizeof(m->tag)); + m->tag[sizeof(m->tag)-1] = 0; + *l = m; + + archdir[0].qid.vers++; + + unlock(&iomap); + return m->start; } // @@ -121,6 +170,7 @@ ioalloc(int port, int size, int align, char *tag) port = 0x400; for(l = &iomap.m; *l; l = &(*l)->next){ m = *l; + if (m->start < 0x400) continue; i = m->start - port; if(i > size) break; @@ -144,6 +194,11 @@ ioalloc(int port, int size, int align, char *tag) m = *l; if(m->end <= port) continue; + if(m->reserved && m->start == port && m->end == port + size) { + m->reserved = 0; + unlock(&iomap); + return m->start; + } if(m->start >= port+size) break; unlock(&iomap); diff --git a/pc/devether.c b/pc/devether.c index a522dc8d14ac2503a2f7a38c28bc5c937c2c2f86..abcf385034e955f3d3851e7d0ca919a3df5517b4 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -354,6 +354,7 @@ etherreset(void) int i, n, ctlrno; char name[32], buf[128]; + print("Searching for ethernet devices\n"); for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){ if(ether == 0) ether = malloc(sizeof(Ether)); diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index e20615388b76c35141a516b1360108013cab45a2..89ab002dd4ecff6c1be90d9343947a35259d79ff 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -167,6 +167,7 @@ enum { /* Window 0 - setup */ auiAvailable9 = 0x2000, /* EepromCommand bits */ EepromReadRegister = 0x0080, + EepromRead8bRegister = 0x0230, EepromBusy = 0x8000, }; @@ -571,6 +572,13 @@ multicast(void* arg, uchar *addr, int on) COMMAND(port, SetRxFilter, filter); } +/* On the 575B and C, interrupts need to be acknowledged in CardBus memory space */ +static void +intrack3c575(ulong *cbfns) +{ + cbfns[1] = 0x8000; +} + static void attach(Ether* ether) { @@ -604,10 +612,13 @@ attach(Ether* ether) } COMMAND(port, SetIndicationEnable, x); COMMAND(port, SetInterruptEnable, x); - COMMAND(port, RxEnable, 0); COMMAND(port, TxEnable, 0); + if (ether->mem) + /* This must be a cardbus card. Acknowledge the interrupt */ + intrack3c575(KADDR(ether->mem)); + /* * Prime the busmaster channel for receiving directly into a * receive packet buffer if necessary. @@ -1127,6 +1138,8 @@ interrupt(Ureg*, void* arg) panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status); COMMAND(port, AcknowledgeInterrupt, interruptLatch); + if (ether->mem) intrack3c575((ulong *)KADDR(ether->mem)); + }while((status = STATUS(port)) & (interruptMask|interruptLatch)); if(ctlr->busmaster == 2) @@ -1220,11 +1233,13 @@ typedef struct Adapter { int port; int irq; int tbdf; + int did; + ulong cbfns; } Adapter; static Block* adapter; static void -tcmadapter(int port, int irq, int tbdf) +tcmadapter(int port, int irq, int tbdf, int did, ulong cbfns) { Block *bp; Adapter *ap; @@ -1236,6 +1251,8 @@ tcmadapter(int port, int irq, int tbdf) ap->port = port; ap->irq = irq; ap->tbdf = tbdf; + ap->did = did; + ap->cbfns = cbfns; bp->next = adapter; adapter = bp; @@ -1385,7 +1402,7 @@ tcm509isa(void) COMMAND(port, AcknowledgeInterrupt, 0xFF); irq = (ins(port+ResourceConfig)>>12) & 0x0F; - tcmadapter(port, irq, BUSUNKNOWN); + tcmadapter(port, irq, BUSUNKNOWN, 0, 0); } } @@ -1431,7 +1448,7 @@ tcm5XXeisa(void) COMMAND(port, AcknowledgeInterrupt, 0xFF); irq = (ins(port+ResourceConfig)>>12) & 0x0F; - tcmadapter(port, irq, BUSUNKNOWN); + tcmadapter(port, irq, BUSUNKNOWN, 0, 0); } } @@ -1443,6 +1460,8 @@ tcm59Xpci(void) p = nil; while(p = pcimatch(p, 0x10B7, 0)){ + ulong bar; + /* * Not prepared to deal with memory-mapped * devices yet. @@ -1459,7 +1478,14 @@ tcm59Xpci(void) while(STATUS(port) & commandInProgress) ; - tcmadapter(port, irq, p->tbdf); + bar = 0; + if (p->did == 0x5157) { + /* Map the CardBus functions */ + bar = pcicfgr32(p, PciBAR2); + print("tcmp59Xpci: CardBus functions at %.8uX\n", bar & ~KZERO); + } + + tcmadapter(port, irq, p->tbdf, p->did, bar); pcisetbme(p); } } @@ -1711,12 +1737,12 @@ autoselect(int port, int xcvr, int is9) } static int -eepromdata(int port, int offset) +eepromdata(int did, int port, int offset) { COMMAND(port, SelectRegisterWindow, Wsetup); while(EEPROMBUSY(port)) ; - EEPROMCMD(port, EepromReadRegister, offset); + EEPROMCMD(port, (did == 0x5157)? EepromRead8bRegister: EepromReadRegister, offset); while(EEPROMBUSY(port)) ; return EEPROMDATA(port); @@ -1750,13 +1776,16 @@ etherelnk3reset(Ether* ether) * otherwise the ports must match. */ port = 0; + did = 0; bpp = &adapter; for(bp = *bpp; bp; bp = bp->next){ ap = (Adapter*)bp->rp; if(ether->port == 0 || ether->port == ap->port){ port = ap->port; + did = ap->did; ether->irq = ap->irq; ether->tbdf = ap->tbdf; + ether->mem = ap->cbfns; *bpp = bp->next; freeb(bp); break; @@ -1770,7 +1799,7 @@ etherelnk3reset(Ether* ether) * Read the DeviceID from the EEPROM, it's at offset 0x03, * and do something depending on capabilities. */ - switch(did = eepromdata(port, 0x03)){ + switch(did = eepromdata(did, port, 0x03)){ case 0x9000: case 0x9001: @@ -1779,6 +1808,7 @@ etherelnk3reset(Ether* ether) case 0x9051: case 0x9055: case 0x9200: + case 0x5157: /* 3C575 Cyclone */ if(BUSTYPE(ether->tbdf) != BusPCI) goto buggery; busmaster = 2; @@ -1822,7 +1852,7 @@ etherelnk3reset(Ether* ether) memset(ea, 0, Eaddrlen); if(memcmp(ea, ether->ea, Eaddrlen) == 0){ for(i = 0; i < Eaddrlen/2; i++){ - x = eepromdata(port, i); + x = eepromdata(did, port, i); ether->ea[2*i] = x>>8; ether->ea[2*i+1] = x; } @@ -1854,10 +1884,18 @@ etherelnk3reset(Ether* ether) /* * forgive me, but i am weak */ - if(did == 0x9055 || did == 0x9200){ + if(did == 0x9055 || did == 0x9200 || did == 0x5157){ xcvr = xcvrMii; txrxreset(port); XCVRDEBUG("905[BC] reset ops 0x%uX\n", ins(port+ResetOp905B)); + if (did == 0x5157) { + ushort reset_opts; + + COMMAND(port, SelectRegisterWindow, Wstation); + reset_opts = ins(port + ResetOp905B); + reset_opts |= 0x0010; /* Invert LED */ + outs(port + ResetOp905B, reset_opts); + } } else if(xcvr & autoSelect) xcvr = autoselect(port, xcvr, rxstatus9); @@ -1870,7 +1908,7 @@ etherelnk3reset(Ether* ether) * Quick hack. scanphy(port); */ - phyaddr = 24; + phyaddr = (did == 0x5157)? 0: 24; for(i = 0; i < 7; i++) XCVRDEBUG(" %2.2uX", miir(port, phyaddr, i)); XCVRDEBUG("\n"); @@ -2016,7 +2054,7 @@ etherelnk3reset(Ether* ether) * until the whole packet has been received. */ ctlr->upenabled = 1; - x = eepromdata(port, 0x0F); + x = eepromdata(did, port, 0x0F); if(!(x & 0x01)) outl(port+PktStatus, upRxEarlyEnable); @@ -2072,4 +2110,5 @@ etherelnk3link(void) { addethercard("elnk3", etherelnk3reset); addethercard("3C509", etherelnk3reset); + addethercard("3C575", etherelnk3reset); } diff --git a/pc/fns.h b/pc/fns.h index d07040b6270391bf280221ca376cf6d6b9609c8b..405826e96e891dd61a0a3b3d5cd4b1722f9add28 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -6,6 +6,7 @@ Dirtab* addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,v //void addscsilink(char*, Scsiio (*)(int, ISAConf*)); void archinit(void); void bootargs(ulong); +void cbinit(void); vlong checkcycintr(Ureg*, void*); int cistrcmp(char*, char*); int cistrncmp(char*, char*, int); @@ -59,6 +60,7 @@ void iofree(int); void ioinit(void); int iounused(int, int); int ioalloc(int, int, int, char*); +int ioreserve(int, int, int, char*); int iprint(char*, ...); int isaconfig(char*, int, ISAConf*); void kbdinit(void); @@ -83,6 +85,8 @@ void outs(int, ushort); void outss(int, void*, int); void outl(int, ulong); void outsl(int, void*, int); +int pciscan(int, Pcidev **); +ulong pcibarsize(Pcidev *, int); int pcicfgr8(Pcidev*, int); int pcicfgr16(Pcidev*, int); int pcicfgr32(Pcidev*, int); diff --git a/pc/io.h b/pc/io.h index 9d4378edab7bd6aa089c90a8c130e32cd3d3f692..3673ed23d6da467e57c727a40b5926c620eb10a2 100644 --- a/pc/io.h +++ b/pc/io.h @@ -191,6 +191,10 @@ struct Pcidev int size; } mem[6]; + struct { + ulong bar; + int size; + } rom; uchar intl; /* interrupt line */ Pcidev* list; diff --git a/pc/pci.c b/pc/pci.c index 2ef3dc6b06fa1619e7e1b50521f47bba2c832fd7..1a3058347b24476838d67c46e4cc3c58cc28aa06 100644 --- a/pc/pci.c +++ b/pc/pci.c @@ -57,7 +57,7 @@ enum }; static Lock pcicfglock; -static Lock pcicfginitlock; +static QLock pcicfginitlock; static int pcicfgmode = -1; static int pcimaxbno = 7; static int pcimaxdno; @@ -359,7 +359,7 @@ pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg) } static int -pciscan(int bno, Pcidev** list) +pcilscan(int bno, Pcidev** list) { Pcidev *p, *head, *tail; int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn; @@ -482,20 +482,31 @@ pciscan(int bno, Pcidev** list) l = (MaxUBN<<16)|(sbn<<8)|bno; pcicfgw32(p, PciPBN, l); pcicfgw16(p, PciSPSR, 0xFFFF); - maxubn = pciscan(sbn, &p->bridge); + maxubn = pcilscan(sbn, &p->bridge); l = (maxubn<<16)|(sbn<<8)|bno; pcicfgw32(p, PciPBN, l); } else { maxubn = ubn; - pciscan(sbn, &p->bridge); + pcilscan(sbn, &p->bridge); } } return maxubn; } +int +pciscan(int bno, Pcidev **list) +{ + int ubn; + + qlock(&pcicfginitlock); + ubn = pcilscan(bno, list); + qunlock(&pcicfginitlock); + return ubn; +} + static void pcicfginit(void) { @@ -504,7 +515,7 @@ pcicfginit(void) Pcidev **list; ulong mema, ioa; - lock(&pcicfginitlock); + qlock(&pcicfginitlock); if(pcicfgmode != -1) goto out; @@ -543,7 +554,7 @@ pcicfginit(void) list = &pciroot; for(bno = 0; bno <= pcimaxbno; bno++) { - bno = pciscan(bno, list); + bno = pcilscan(bno, list); while(*list) list = &(*list)->link; } @@ -573,11 +584,12 @@ pcicfginit(void) pcibusmap(pciroot, &mema, &ioa, 1); DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa); - unlock(&pcicfginitlock); + qunlock(&pcicfginitlock); return; } out: - unlock(&pcicfginitlock); + qunlock(&pcicfginitlock); + cbinit(); } static int @@ -785,8 +797,8 @@ pcimatchtbdf(int tbdf) return pcidev; } -void -pcihinv(Pcidev* p) +static void +pcilhinv(Pcidev* p) { int i; Pcidev *t; @@ -819,7 +831,15 @@ pcihinv(Pcidev* p) if(p->bridge != nil) pcihinv(p->bridge); p = p->link; - } + } +} + +void +pcihinv(Pcidev* p) +{ + qlock(&pcicfginitlock); + pcilhinv(p); + qunlock(&pcicfginitlock); } void