diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini index ce23d746d..09f639608 100644 --- a/sys/man/8/plan9.ini +++ b/sys/man/8/plan9.ini @@ -760,10 +760,10 @@ and .BR off . The first two specify differing levels of power saving; the third turns the monitor off completely. -.SS \fL*vesashadow=\fP -This enables the shadow framebuffer or softscreen of the VESA -video driver. This is usefull on devices where access to -the physical framebuffer is slow. +.SS \fL*novesashadow=\fP +This disables the shadow framebuffer or softscreen of the VESA +video driver. This can improve performance on some graphics +cards. .SS NVRAM .SS \fLnvram=\fIfile\fP .SS \fLnvrlen=\fIlength\fP diff --git a/sys/src/9/omap4/arm.h b/sys/src/9/omap4/arm.h index 4914d7bf2..54385dd3d 100644 --- a/sys/src/9/omap4/arm.h +++ b/sys/src/9/omap4/arm.h @@ -21,6 +21,8 @@ #define PsrDfiq 0x00000040 /* disable FIQ interrupts */ #define PsrDirq 0x00000080 /* disable IRQ interrupts */ +#define PsrOK 0xF80F0000 /* user processes may touch these */ + #define PsrV 0x10000000 /* overflow */ #define PsrC 0x20000000 /* carry/borrow/extend */ #define PsrZ 0x40000000 /* zero */ diff --git a/sys/src/9/omap4/clock.c b/sys/src/9/omap4/clock.c index 980d973ff..3aa56467f 100644 --- a/sys/src/9/omap4/clock.c +++ b/sys/src/9/omap4/clock.c @@ -65,7 +65,7 @@ perfticks(void) } void -clocktick(Ureg* ureg) +clocktick(Ureg* ureg, void *) { timerintr(ureg, 0); } @@ -74,7 +74,7 @@ void localclockinit(void) { local[2] = 0xFF06; - intenable(29, clocktick); + intenable(29, clocktick, nil); timerset(0); } diff --git a/sys/src/9/omap4/dat.h b/sys/src/9/omap4/dat.h index 940d95b59..31bf462f0 100644 --- a/sys/src/9/omap4/dat.h +++ b/sys/src/9/omap4/dat.h @@ -8,6 +8,7 @@ typedef struct PMMU PMMU; typedef struct Confmem Confmem; typedef struct Conf Conf; typedef struct Proc Proc; +typedef struct ISAConf ISAConf; typedef uvlong Tval; typedef void KMap; #define VA(k) ((uintptr)(k)) @@ -142,3 +143,9 @@ extern uintptr kseg0; #define AOUT_MAGIC (E_MAGIC) #define NCOLOR 1 + +struct ISAConf +{ + char *type; + ulong port, irq; +}; diff --git a/sys/src/9/omap4/fns.h b/sys/src/9/omap4/fns.h index 116712cb0..dafc20ee9 100644 --- a/sys/src/9/omap4/fns.h +++ b/sys/src/9/omap4/fns.h @@ -33,7 +33,9 @@ void touser(Ureg*); void links(void); void globalclockinit(void); void localclockinit(void); -void intenable(int, void(*)(Ureg*)); -void setled(int, int); +void intenable(int, void(*)(Ureg*, void *), void *); void uartinit(void); -void irqroute(int, void(*)(Ureg*)); +void irqroute(int, void(*)(Ureg*, void *), void *); +void gpioinit(void); +void setgpio(int, int); +void gpiomode(int, int); diff --git a/sys/src/9/omap4/l.s b/sys/src/9/omap4/l.s index 427792503..f6282431e 100644 --- a/sys/src/9/omap4/l.s +++ b/sys/src/9/omap4/l.s @@ -51,7 +51,7 @@ uartloop: EWAVE('n') MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl - ORR $(CpCmmu|CpChv|CpCsw), R1 + ORR $(CpCmmu|CpChv|CpCsw|CpCicache), R1 MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl EWAVE(' ') @@ -59,7 +59,7 @@ uartloop: BL _jumphi(SB) EWAVE('9') - + MOVW $setR12(SB), R12 MOVW $KTZERO, R13 diff --git a/sys/src/9/omap4/main.c b/sys/src/9/omap4/main.c index 309bf6eb0..f8e75ce94 100644 --- a/sys/src/9/omap4/main.c +++ b/sys/src/9/omap4/main.c @@ -147,12 +147,15 @@ userinit(void) void main() { + extern int ehcidebug; + wave('f'); memset(edata, 0, end - edata); wave('r'); machinit(); wave('o'); mmuinit(); + gpioinit(); wave('m'); trapinit(); uartinit(); @@ -166,8 +169,9 @@ main() swapinit(); initseg(); quotefmtinstall(); - chandevreset(); + ehcidebug = 1; links(); + chandevreset(); userinit(); schedinit(); } diff --git a/sys/src/9/omap4/mem.h b/sys/src/9/omap4/mem.h index cb43085aa..b41414e43 100644 --- a/sys/src/9/omap4/mem.h +++ b/sys/src/9/omap4/mem.h @@ -37,6 +37,7 @@ #define MAXSYSARG 7 #define MAXMACH 2 +#define BI2BY 8 #define BY2WD 4 #define BY2V 8 #define BY2PG 4096 diff --git a/sys/src/9/omap4/mkfile b/sys/src/9/omap4/mkfile index 79a91f84a..169367ab1 100644 --- a/sys/src/9/omap4/mkfile +++ b/sys/src/9/omap4/mkfile @@ -19,6 +19,7 @@ PORT=\ dev.$O\ edf.$O\ fault.$O\ + gpio.$O\ mul64fract.$O\ rebootcmd.$O\ page.$O\ diff --git a/sys/src/9/omap4/mmu.c b/sys/src/9/omap4/mmu.c index afbc7794e..f91c0342a 100644 --- a/sys/src/9/omap4/mmu.c +++ b/sys/src/9/omap4/mmu.c @@ -9,7 +9,6 @@ char iopages[NIOPAGES / 8]; Lock iopagelock; uchar *periph; -ulong *ledgpio; static int isfree(int i) @@ -95,19 +94,10 @@ vunmap(void *virt, ulong length) flushtlb(); } -void -setled(int n, int s) -{ - ulong *r; - - r = &ledgpio[0x190/4]; - r[s != 0] = (1 << (7 + n)); -} - void markidle(int n) { - setled(m->machno, !n); + setgpio(7 + m->machno, !n); } void @@ -126,7 +116,6 @@ mmuinit(void) l2 += L2SIZ; } uart = vmap((ulong) uart, BY2PG); - ledgpio = vmap(0x4A310000, BY2PG); periph = vmap(0x48240000, 2 * BY2PG); memset(l1, 0, sizeof(ulong) * (IZERO / MiB)); l1[4095] = PRIVL2 | Coarse; @@ -137,9 +126,6 @@ mmuinit(void) pl2[241] = FIRSTMACH | L2AP(Krw) | Small | Cached | Buffered; flushtlb(); m = (Mach *) MACHADDR; - ledgpio[0x134/4] &= ~((1<<8)|(1<<7)); - setled(0, 1); - setled(1, 1); } void diff --git a/sys/src/9/omap4/panda b/sys/src/9/omap4/panda index 003fde1d2..4555d2961 100644 --- a/sys/src/9/omap4/panda +++ b/sys/src/9/omap4/panda @@ -22,35 +22,34 @@ dev # flash # ether netif -# ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno + ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno # draw screen # dss # mouse uart -# usb + usb link # archoma -# ethermedium + ethermedium # flashigep # loopbackmedium -# netdevmedium + netdevmedium -## avoid tickling errata 3.1.1.183 -## usbohci -# usbehci usbehciomap +# usbohci + usbehci usbehciomap ip -# tcp -# udp -# ipifc -# icmp -# icmp6 -# ipmux -# gre -# esp + tcp + udp + ipifc + icmp + icmp6 + ipmux + gre + esp misc # rdb diff --git a/sys/src/9/omap4/trap.c b/sys/src/9/omap4/trap.c index 308860b2e..2d8b9eb04 100644 --- a/sys/src/9/omap4/trap.c +++ b/sys/src/9/omap4/trap.c @@ -12,7 +12,8 @@ extern uchar *periph; ulong *intc, *intd; -void (*irqhandler[MAXMACH][256])(Ureg*); +void (*irqhandler[MAXMACH][256])(Ureg *, void *); +void *irqaux[MAXMACH][256]; static char *trapname[] = { "reset", /* wtf */ @@ -20,7 +21,6 @@ static char *trapname[] = { "supervisor call", "prefetch abort", "data abort", - "unknown trap", "IRQ", "FIQ", }; @@ -52,24 +52,28 @@ trapinit(void) } void -intenable(int i, void (*fn)(Ureg *)) +intenable(int i, void (*fn)(Ureg *, void *), void *aux) { intd[0x40 + (i / 32)] = 1 << (i % 32); irqhandler[m->machno][i] = fn; + irqaux[m->machno][i] = aux; } void -irqroute(int i, void (*fn)(Ureg *)) +irqroute(int i, void (*fn)(Ureg *, void *), void *aux) { ulong x, y, z; - - intenable(32 + i, fn); + + if(irqhandler[m->machno][i] != nil){ + print("irqroute: irq already used: i=%d pc=%#p newfn=%#p oldfn=%#p\n", i, getcallerpc(&i), fn, irqhandler[m->machno][i]); + return; + } + intenable(32 + i, fn, aux); x = intd[0x208 + i/4]; y = 0xFF << ((i%4) * 8); z = 1 << (m->machno + (i%4) * 8); x = (x & ~y) | z; intd[0x208 + i/4] = x; -// intd[0x200/4 + (i+32)/32] = 1 << (i % 32); } void @@ -128,12 +132,139 @@ updatetos(void) tos->pid = up->pid; } +int +notify(Ureg *ureg) +{ + int l; + ulong s, sp; + Note *n; + + if(up->procctl) + procctl(up); + if(up->nnote == 0) + return 0; + s = spllo(); + qlock(&up->debug); + up->notepending = 0; + n = &up->note[0]; + if(strncmp(n->msg, "sys:", 4) == 0){ + l = strlen(n->msg); + if(l > ERRMAX-15) + l = ERRMAX-15; + sprint(n->msg + l, " pc=0x%.8lux", ureg->pc); + } + if(n->flag != NUser && (up->notified || up->notify == 0)){ + if(n->flag == NDebug) + pprint("suicide: %s\n", n->msg); + qunlock(&up->debug); + pexit(n->msg, n->flag != NDebug); + } + if(up->notified){ + qunlock(&up->debug); + splhi(); + return 0; + } + if(!up->notify){ + qunlock(&up->debug); + pexit(n->msg, n->flag != NDebug); + } + sp = ureg->sp; + sp -= 256 + sizeof(Ureg); + if(!okaddr((ulong)up->notify, 1, 0) + || !okaddr(sp - ERRMAX - 4 * BY2WD, sizeof(Ureg) + ERRMAX + 4 * BY2WD, 1)){ + qunlock(&up->debug); + pprint("suicide: bad address in notify\n"); + pexit("Suicide", 0); + } + + memmove((void *) sp, ureg, sizeof(Ureg)); + ((void**)sp)[-1] = up->ureg; + up->ureg = (void *) sp; + sp -= BY2WD + ERRMAX; + memmove((void *) sp, up->note[0].msg, ERRMAX); + sp -= 3 * BY2WD; + ((ulong*)sp)[2] = sp + 3 * BY2WD; + ((Ureg**)sp)[1] = up->ureg; + ((ulong*)sp)[0] = 0; + memset(ureg, 0, sizeof *ureg); + ureg->psr = PsrMusr; + ureg->sp = sp; + ureg->pc = (ulong) up->notify; + up->notified = 1; + up->nnote--; + memmove(&up->lastnote, &up->note[0], sizeof(Note)); + memmove(&up->note[0], &up->note[1], up->nnote * sizeof(Note)); + + qunlock(&up->debug); + splx(s); + return 1; +} + +void +noted(Ureg *ureg, ulong arg0) +{ + Ureg *nureg; + ulong oureg, sp; + + qlock(&up->debug); + if(arg0 != NRSTR && !up->notified){ + qunlock(&up->debug); + pprint("call to noted() when not notified\n"); + pexit("Suicide", 0); + } + up->notified = 0; + + nureg = up->ureg; + oureg = (ulong) nureg; + if(!okaddr((ulong) oureg - BY2WD, BY2WD + sizeof(Ureg), 0)){ + qunlock(&up->debug); + pprint("bad ureg in noted or call to noted when not notified\n"); + pexit("Suicide", 0); + } + nureg->psr = nureg->psr & PsrOK | ureg->psr & ~PsrOK; + memmove(ureg, nureg, sizeof(Ureg)); + + if(!okaddr(nureg->pc, 1, 0) && !okaddr(nureg->sp, BY2WD, 0) + && (arg0 == NCONT || arg0 == NRSTR || arg0 == NSAVE)){ + qunlock(&up->debug); + pprint("suicide: trap in noted\n"); + pexit("Suicide", 0); + } + switch(arg0){ + case NCONT: + case NRSTR: + up->ureg = (Ureg *) (*(ulong *)(oureg - BY2WD)); + qunlock(&up->debug); + break; + + case NSAVE: + qunlock(&up->debug); + sp = oureg - 4 * BY2WD - ERRMAX; + splhi(); + ureg->sp = sp; + ((ulong *) sp)[1] = oureg; + ((ulong *) sp)[0] = 0; + break; + + default: + pprint("unknown noted arg 0x%lux\n", arg0); + up->lastnote.flag = NDebug; + /* fallthrough */ + + case NDFLT: + qunlock(&up->debug); + if(up->lastnote.flag == NDebug) + pprint("suicide: %s\n", up->lastnote.msg); + pexit(up->lastnote.msg, up->lastnote.flag != NDebug); + } +} + void trap(Ureg *ureg) { int user, intn, x; char buf[ERRMAX]; - + user = (ureg->psr & PsrMask) == PsrMusr; if(user){ fillureguser(ureg); @@ -149,10 +280,13 @@ trap(Ureg *ureg) x = intc[3]; intn = x & 0x3FF; if(irqhandler[m->machno][intn] != nil) - irqhandler[m->machno][intn](ureg); + irqhandler[m->machno][intn](ureg, irqaux[m->machno][intn]); + else + print("unexpected interrupt %d\n", intn); intc[4] = x; if(intn != 29) preempted(); + splhi(); if(up && up->delaysched && (intn == 29)){ sched(); splhi(); @@ -170,6 +304,8 @@ trap(Ureg *ureg) } } if(user){ + if(up->procctl || up->nnote) + notify(ureg); updatetos(); up->dbgreg = nil; } @@ -193,7 +329,6 @@ syscall(Ureg *ureg) } scall = ureg->r0; up->scallnr = scall; -// print("%s\n", sysctab[scall]); spllo(); sp = ureg->sp; @@ -224,8 +359,16 @@ syscall(Ureg *ureg) procctl(up); splx(s); } + up->insyscall = 0; up->psstate = nil; + + if(scall == NOTED) + noted(ureg, *(ulong *)(sp + BY2WD)); + if(scall != RFORK && (up->procctl || up->nnote)){ + splhi(); + notify(ureg); + } splhi(); if(up->delaysched){ sched(); diff --git a/sys/src/9/omap4/uartomap.c b/sys/src/9/omap4/uartomap.c index e0e6c508a..1c49cdf52 100644 --- a/sys/src/9/omap4/uartomap.c +++ b/sys/src/9/omap4/uartomap.c @@ -24,20 +24,23 @@ omappnp(void) static void omapkick(Uart *u) { + int x; + + x = splhi(); while((uart[17] & 1) == 0){ if(u->op >= u->oe) - if(uartstageoutput(u) == 0) + if(uartstageoutput(u) == 0){ + uart[1] &= ~(1<<1); break; + } uart[0] = *u->op++; - } - if(u->op < u->oe || qlen(u->oq)) uart[1] |= (1<<1); - else - uart[1] &= ~(1<<1); + } + splx(x); } void -omapinterrupt(Ureg *) +omapinterrupt(Ureg *, void *) { ulong st; @@ -45,6 +48,12 @@ omapinterrupt(Ureg *) if((st & 1) != 0) return; switch((st >> 1) & 0x1F){ + case 0: + case 16: + puart.cts = (uart[6] & (1<<4)) != 0; + puart.dsr = (uart[6] & (1<<5)) != 0; + puart.dcd = (uart[6] & (1<<7)) != 0; + break; case 1: uartkick(&puart); break; @@ -54,23 +63,164 @@ omapinterrupt(Ureg *) uartrecv(&puart, uart[0]); break; default: - print("unknown UART interrupt %d\n", (st>>1) & 0x1F); + print("unknown UART interrupt %uld\n", (st>>1) & 0x1F); uartkick(&puart); } } static void -omapenable(Uart *, int ie) +omapenable(Uart *u, int ie) { while(uart[5] & (1<<6)) ; if(ie){ - irqroute(74, omapinterrupt); + irqroute(74, omapinterrupt, u); uart[1] = (1<<0); - // uart[0x10] |= (1<<3); } } +static void +omapdisable(Uart *) +{ + uart[1] = 0; +} + +static void +omapdobreak(Uart *, int ms) +{ + if(ms <= 0) + ms = 200; + + uart[3] |= (1<<6); + tsleep(&up->sleep, return0, 0, ms); + uart[3] &= ~(1<<6); +} + +static int +omapbaud(Uart *u, int baud) +{ + int val; + + if(baud <= 0) + return -1; + + val = (48000000 / 16) / baud; + uart[3] |= (1<<7); + uart[0] = val & 0xFF; + uart[1] = (val >> 8) & 0xFF; + uart[3] &= ~(1<<7); + u->baud = baud; + return 0; +} + +static int +omapbits(Uart *u, int bits) +{ + if(bits < 5 || bits > 8) + return -1; + + uart[3] = (uart[3] & ~3) | (bits - 5); + u->bits = bits; + return 0; +} + +static int +omapstop(Uart *u, int stop) +{ + if(stop < 1 || stop > 2) + return -1; + + uart[3] &= ~4; + if(stop == 2) + uart[3] |= 4; + u->stop = stop; + return 0; +} + +static int +omapparity(Uart *u, int parity) +{ + uart[3] &= ~0x38; + switch(parity){ + case 'n': + break; + case 'o': + uart[3] |= (1<<3); + case 'e': + uart[3] |= (1<<3) | (1<<4); + break; + default: + return -1; + } + u->parity = parity; + return 0; +} + +static void +omapmodemctl(Uart *u, int on) +{ + if(on){ + u->modem = 1; + u->cts = (uart[6] & (1<<4)) != 0; + uart[1] |= (1<<6); + }else{ + u->modem = 0; + u->cts = 1; + } +} + +static void +omaprts(Uart *, int i) +{ + uart[4] = (uart[4] & ~2) | (i << 1); +} + +static void +omapdtr(Uart *, int i) +{ + uart[4] = (uart[4] & ~1) | i; +} + +static long +omapstatus(Uart* u, void* buf, long n, long offset) +{ + char *p; + ulong msr; + + msr = uart[6]; + p = malloc(READSTR); + snprint(p, READSTR, + "b%d c%d d%d e%d l%d m%d p%c r%d s%d\n" + "dev(%d) type(%d) framing(%d) overruns(%d) " + "berr(%d) serr(%d)%s%s%s%s\n", + + u->baud, + u->hup_dcd, + u->dsr, + u->hup_dsr, + u->bits, + u->modem, + u->parity, + (uart[3] & 2) != 0, + u->stop, + + u->dev, + u->type, + u->ferr, + u->oerr, + u->berr, + u->serr, + (msr & (1<<4)) ? " cts": "", + (msr & (1<<5)) ? " dsr": "", + (msr & (1<<7)) ? " dcd": "", + (msr & (1<<6)) ? " ri": "" + ); + n = readstr(offset, buf, n, p); + free(p); + + return n; +} + static int omapgetc(Uart *) { @@ -87,19 +237,22 @@ omapputc(Uart *, int c) uart[0] = c; } -static void -omaprts(Uart *, int) -{ -} - PhysUart omapphysuart = { .name = "omap4430 uart", .pnp = omappnp, .getc = omapgetc, .putc = omapputc, .enable = omapenable, + .disable = omapdisable, .kick = omapkick, .rts = omaprts, + .parity = omapparity, + .baud = omapbaud, + .bits = omapbits, + .stop = omapstop, + .modemctl = omapmodemctl, + .dtr = omapdtr, + .status = omapstatus, }; void diff --git a/sys/src/9/pc/etherbcm.c b/sys/src/9/pc/etherbcm.c index a82e748d8..d45cdbfaf 100644 --- a/sys/src/9/pc/etherbcm.c +++ b/sys/src/9/pc/etherbcm.c @@ -425,7 +425,7 @@ bcminterrupt(Ureg*, void *arg) iunlock(&ctlr->imlock); } -static void +static int bcminit(Ether *edev) { ulong i, j; @@ -436,7 +436,12 @@ bcminit(Ether *edev) /* initialization procedure according to the datasheet */ csr32(ctlr, MiscHostCtl) |= MaskPCIInt | ClearIntA; csr32(ctlr, SwArbitration) |= SwArbitSet1; - while((csr32(ctlr, SwArbitration) & SwArbitWon1) == 0); + for(i = 0; i < 10000 && (csr32(ctlr, SwArbitration) & SwArbitWon1) == 0; i++) + microdelay(100); + if(i == 10000){ + iprint("bcm: arbiter failed to respond\n"); + return -1; + } csr32(ctlr, MemArbiterMode) |= Enable; csr32(ctlr, MiscHostCtl) |= IndirectAccessEnable | EnablePCIStateRegister | EnableClockControlRegister; csr32(ctlr, MemoryWindow) = 0; @@ -452,7 +457,12 @@ bcminit(Ether *edev) csr32(ctlr, ModeControl) |= ByteWordSwap; csr32(ctlr, MACMode) = (csr32(ctlr, MACMode) & MACPortMask) | MACPortGMII; microdelay(40000); - while(mem32(ctlr, 0xB50) != 0xB49A89AB); + for(i = 0; i < 100000 && mem32(ctlr, 0xB50) != 0xB49A89AB; i++) + microdelay(100); + if(i == 100000){ + iprint("bcm: chip failed to reset\n"); + return -1; + } csr32(ctlr, TLPControl) |= (1<<25) | (1<<29); memset(ctlr->status, 0, 20); csr32(ctlr, DMARWControl) = (csr32(ctlr, DMARWControl) & DMAWatermarkMask) | DMAWatermarkValue; @@ -462,10 +472,20 @@ bcminit(Ether *edev) csr32(ctlr, MBUFHighWatermark) = 0x60; csr32(ctlr, LowWatermarkMaximum) = (csr32(ctlr, LowWatermarkMaximum) & LowWatermarkMaxMask) | LowWatermarkMaxValue; csr32(ctlr, BufferManMode) |= Enable | Attn; - while((csr32(ctlr, BufferManMode) & Enable) == 0); + for(i = 0; i < 100 && (csr32(ctlr, BufferManMode) & Enable) == 0; i++) + microdelay(100); + if(i == 100){ + iprint("bcm: buffer manager failed to start\n"); + return -1; + } csr32(ctlr, FTQReset) = -1; csr32(ctlr, FTQReset) = 0; - while(csr32(ctlr, FTQReset)); + for(i = 0; i < 1000 && csr32(ctlr, FTQReset) != 0; i++) + microdelay(100); + if(i == 1000){ + iprint("bcm: ftq failed to reset\n"); + return -1; + } csr32(ctlr, ReceiveBDHostAddr) = 0; csr32(ctlr, ReceiveBDHostAddr + 4) = PADDR(ctlr->recvprod); csr32(ctlr, ReceiveBDFlags) = RecvProdRingLen << 16; @@ -503,7 +523,12 @@ bcminit(Ether *edev) csr32(ctlr, SendInitiatorMask) = 0xFFFFFF; csr32(ctlr, SendInitiatorConfiguration) |= SendStats; csr32(ctlr, HostCoalescingMode) = 0; - while(csr32(ctlr, HostCoalescingMode) != 0); + for(i = 0; i < 200 && csr32(ctlr, HostCoalescingMode) != 0; i++) + microdelay(100); + if(i == 200){ + iprint("bcm: host coalescing engine failed to stop\n"); + return -1; + } csr32(ctlr, HostCoalescingRecvTicks) = 150; csr32(ctlr, HostCoalescingSendTicks) = 150; csr32(ctlr, RecvMaxCoalescedFrames) = 10; @@ -539,7 +564,12 @@ bcminit(Ether *edev) csr32(ctlr, MIMode) = 0xC0000; microdelay(40); miiw(ctlr, PhyControl, 1<<15); - while(miir(ctlr, PhyControl) & (1<<15)); + for(i = 0; i < 1000 && miir(ctlr, PhyControl) & (1<<15); i++) + microdelay(100); + if(i == 1000){ + iprint("bcm: PHY failed to reset\n"); + return -1; + } miiw(ctlr, PhyAuxControl, 2); miir(ctlr, PhyIntStatus); miir(ctlr, PhyIntStatus); @@ -554,6 +584,7 @@ bcminit(Ether *edev) csr32(ctlr, ReceiveRulesConfiguration) = 1 << 3; csr32(ctlr, MSIMode) |= Enable; csr32(ctlr, MiscHostCtl) &= ~(MaskPCIInt | ClearIntA); + return 0; } static void @@ -637,6 +668,7 @@ bcmpnp(Ether* edev) { Ctlr *ctlr; +again: if(bcmhead == nil) bcmpci(); @@ -664,7 +696,10 @@ bcmpnp(Ether* edev) edev->arg = edev; edev->mbps = 1000; - bcminit(edev); + if(bcminit(edev) < 0){ + edev->ctlr = nil; + goto again; + } return 0; } diff --git a/sys/src/9/pc/vgavesa.c b/sys/src/9/pc/vgavesa.c index 3616e10f0..7214aae5f 100644 --- a/sys/src/9/pc/vgavesa.c +++ b/sys/src/9/pc/vgavesa.c @@ -162,10 +162,10 @@ vesalinear(VGAscr *scr, int, int) vgalinearaddr(scr, paddr, size); if(scr->apsize) addvgaseg("vesascreen", scr->paddr, scr->apsize); - if(getconf("*vesashadow")){ - hardscreen = scr->vaddr; - scr->paddr = scr->apsize = 0; - } + if(getconf("*novesashadow")) + return; + hardscreen = scr->vaddr; + scr->paddr = scr->apsize = 0; } static void diff --git a/sys/src/cmd/5l/asm.c b/sys/src/cmd/5l/asm.c index 32f2991cf..5aa051a80 100644 --- a/sys/src/cmd/5l/asm.c +++ b/sys/src/cmd/5l/asm.c @@ -77,6 +77,11 @@ asmb(void) curtext = P; switch(HEADTYPE) { case 0: + if(debug['P']){ + OFFSET = rnd(textsize, INITRND); + seek(cout, OFFSET, 0); + break; + } case 1: case 2: case 5: