summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@rei2.9hal>2011-11-06 15:21:14 +0100
committercinap_lenrek <cinap_lenrek@rei2.9hal>2011-11-06 15:21:14 +0100
commitff0dc1668f11abdab7b8b5738a7320731ac909e5 (patch)
tree328588e546309f357908aaa378b1a5ef4912103e
parent183a08bc9529b372e20600ad9898565ff3e55201 (diff)
parent875e89b8fa62f8e98f2e9d769355e930f7ddc521 (diff)
merge
-rw-r--r--sys/man/8/plan9.ini8
-rw-r--r--sys/src/9/omap4/arm.h2
-rw-r--r--sys/src/9/omap4/clock.c4
-rw-r--r--sys/src/9/omap4/dat.h7
-rw-r--r--sys/src/9/omap4/fns.h8
-rw-r--r--sys/src/9/omap4/l.s4
-rw-r--r--sys/src/9/omap4/main.c6
-rw-r--r--sys/src/9/omap4/mem.h1
-rw-r--r--sys/src/9/omap4/mkfile1
-rw-r--r--sys/src/9/omap4/mmu.c16
-rw-r--r--sys/src/9/omap4/panda29
-rw-r--r--sys/src/9/omap4/trap.c163
-rw-r--r--sys/src/9/omap4/uartomap.c183
-rw-r--r--sys/src/9/pc/etherbcm.c51
-rw-r--r--sys/src/9/pc/vgavesa.c8
-rw-r--r--sys/src/cmd/5l/asm.c5
16 files changed, 417 insertions, 79 deletions
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)
@@ -96,18 +95,9 @@ vunmap(void *virt, ulong length)
}
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: