This commit is contained in:
cinap_lenrek 2011-11-06 15:21:14 +01:00
commit ff0dc1668f
16 changed files with 417 additions and 79 deletions

View file

@ -760,10 +760,10 @@ and
.BR off . .BR off .
The first two specify differing levels of power saving; The first two specify differing levels of power saving;
the third turns the monitor off completely. the third turns the monitor off completely.
.SS \fL*vesashadow=\fP .SS \fL*novesashadow=\fP
This enables the shadow framebuffer or softscreen of the VESA This disables the shadow framebuffer or softscreen of the VESA
video driver. This is usefull on devices where access to video driver. This can improve performance on some graphics
the physical framebuffer is slow. cards.
.SS NVRAM .SS NVRAM
.SS \fLnvram=\fIfile\fP .SS \fLnvram=\fIfile\fP
.SS \fLnvrlen=\fIlength\fP .SS \fLnvrlen=\fIlength\fP

View file

@ -21,6 +21,8 @@
#define PsrDfiq 0x00000040 /* disable FIQ interrupts */ #define PsrDfiq 0x00000040 /* disable FIQ interrupts */
#define PsrDirq 0x00000080 /* disable IRQ interrupts */ #define PsrDirq 0x00000080 /* disable IRQ interrupts */
#define PsrOK 0xF80F0000 /* user processes may touch these */
#define PsrV 0x10000000 /* overflow */ #define PsrV 0x10000000 /* overflow */
#define PsrC 0x20000000 /* carry/borrow/extend */ #define PsrC 0x20000000 /* carry/borrow/extend */
#define PsrZ 0x40000000 /* zero */ #define PsrZ 0x40000000 /* zero */

View file

@ -65,7 +65,7 @@ perfticks(void)
} }
void void
clocktick(Ureg* ureg) clocktick(Ureg* ureg, void *)
{ {
timerintr(ureg, 0); timerintr(ureg, 0);
} }
@ -74,7 +74,7 @@ void
localclockinit(void) localclockinit(void)
{ {
local[2] = 0xFF06; local[2] = 0xFF06;
intenable(29, clocktick); intenable(29, clocktick, nil);
timerset(0); timerset(0);
} }

View file

@ -8,6 +8,7 @@ typedef struct PMMU PMMU;
typedef struct Confmem Confmem; typedef struct Confmem Confmem;
typedef struct Conf Conf; typedef struct Conf Conf;
typedef struct Proc Proc; typedef struct Proc Proc;
typedef struct ISAConf ISAConf;
typedef uvlong Tval; typedef uvlong Tval;
typedef void KMap; typedef void KMap;
#define VA(k) ((uintptr)(k)) #define VA(k) ((uintptr)(k))
@ -142,3 +143,9 @@ extern uintptr kseg0;
#define AOUT_MAGIC (E_MAGIC) #define AOUT_MAGIC (E_MAGIC)
#define NCOLOR 1 #define NCOLOR 1
struct ISAConf
{
char *type;
ulong port, irq;
};

View file

@ -33,7 +33,9 @@ void touser(Ureg*);
void links(void); void links(void);
void globalclockinit(void); void globalclockinit(void);
void localclockinit(void); void localclockinit(void);
void intenable(int, void(*)(Ureg*)); void intenable(int, void(*)(Ureg*, void *), void *);
void setled(int, int);
void uartinit(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);

View file

@ -51,7 +51,7 @@ uartloop:
EWAVE('n') EWAVE('n')
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 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 MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
EWAVE(' ') EWAVE(' ')

View file

@ -147,12 +147,15 @@ userinit(void)
void void
main() main()
{ {
extern int ehcidebug;
wave('f'); wave('f');
memset(edata, 0, end - edata); memset(edata, 0, end - edata);
wave('r'); wave('r');
machinit(); machinit();
wave('o'); wave('o');
mmuinit(); mmuinit();
gpioinit();
wave('m'); wave('m');
trapinit(); trapinit();
uartinit(); uartinit();
@ -166,8 +169,9 @@ main()
swapinit(); swapinit();
initseg(); initseg();
quotefmtinstall(); quotefmtinstall();
chandevreset(); ehcidebug = 1;
links(); links();
chandevreset();
userinit(); userinit();
schedinit(); schedinit();
} }

View file

@ -37,6 +37,7 @@
#define MAXSYSARG 7 #define MAXSYSARG 7
#define MAXMACH 2 #define MAXMACH 2
#define BI2BY 8
#define BY2WD 4 #define BY2WD 4
#define BY2V 8 #define BY2V 8
#define BY2PG 4096 #define BY2PG 4096

View file

@ -19,6 +19,7 @@ PORT=\
dev.$O\ dev.$O\
edf.$O\ edf.$O\
fault.$O\ fault.$O\
gpio.$O\
mul64fract.$O\ mul64fract.$O\
rebootcmd.$O\ rebootcmd.$O\
page.$O\ page.$O\

View file

@ -9,7 +9,6 @@
char iopages[NIOPAGES / 8]; char iopages[NIOPAGES / 8];
Lock iopagelock; Lock iopagelock;
uchar *periph; uchar *periph;
ulong *ledgpio;
static int static int
isfree(int i) isfree(int i)
@ -95,19 +94,10 @@ vunmap(void *virt, ulong length)
flushtlb(); flushtlb();
} }
void
setled(int n, int s)
{
ulong *r;
r = &ledgpio[0x190/4];
r[s != 0] = (1 << (7 + n));
}
void void
markidle(int n) markidle(int n)
{ {
setled(m->machno, !n); setgpio(7 + m->machno, !n);
} }
void void
@ -126,7 +116,6 @@ mmuinit(void)
l2 += L2SIZ; l2 += L2SIZ;
} }
uart = vmap((ulong) uart, BY2PG); uart = vmap((ulong) uart, BY2PG);
ledgpio = vmap(0x4A310000, BY2PG);
periph = vmap(0x48240000, 2 * BY2PG); periph = vmap(0x48240000, 2 * BY2PG);
memset(l1, 0, sizeof(ulong) * (IZERO / MiB)); memset(l1, 0, sizeof(ulong) * (IZERO / MiB));
l1[4095] = PRIVL2 | Coarse; l1[4095] = PRIVL2 | Coarse;
@ -137,9 +126,6 @@ mmuinit(void)
pl2[241] = FIRSTMACH | L2AP(Krw) | Small | Cached | Buffered; pl2[241] = FIRSTMACH | L2AP(Krw) | Small | Cached | Buffered;
flushtlb(); flushtlb();
m = (Mach *) MACHADDR; m = (Mach *) MACHADDR;
ledgpio[0x134/4] &= ~((1<<8)|(1<<7));
setled(0, 1);
setled(1, 1);
} }
void void

View file

@ -22,35 +22,34 @@ dev
# flash # flash
# ether netif # 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 # draw screen
# dss # dss
# mouse # mouse
uart uart
# usb usb
link link
# archoma # archoma
# ethermedium ethermedium
# flashigep # flashigep
# loopbackmedium # loopbackmedium
# netdevmedium netdevmedium
## avoid tickling errata 3.1.1.183 # usbohci
## usbohci usbehci usbehciomap
# usbehci usbehciomap
ip ip
# tcp tcp
# udp udp
# ipifc ipifc
# icmp icmp
# icmp6 icmp6
# ipmux ipmux
# gre gre
# esp esp
misc misc
# rdb # rdb

View file

@ -12,7 +12,8 @@
extern uchar *periph; extern uchar *periph;
ulong *intc, *intd; ulong *intc, *intd;
void (*irqhandler[MAXMACH][256])(Ureg*); void (*irqhandler[MAXMACH][256])(Ureg *, void *);
void *irqaux[MAXMACH][256];
static char *trapname[] = { static char *trapname[] = {
"reset", /* wtf */ "reset", /* wtf */
@ -20,7 +21,6 @@ static char *trapname[] = {
"supervisor call", "supervisor call",
"prefetch abort", "prefetch abort",
"data abort", "data abort",
"unknown trap",
"IRQ", "IRQ",
"FIQ", "FIQ",
}; };
@ -52,24 +52,28 @@ trapinit(void)
} }
void void
intenable(int i, void (*fn)(Ureg *)) intenable(int i, void (*fn)(Ureg *, void *), void *aux)
{ {
intd[0x40 + (i / 32)] = 1 << (i % 32); intd[0x40 + (i / 32)] = 1 << (i % 32);
irqhandler[m->machno][i] = fn; irqhandler[m->machno][i] = fn;
irqaux[m->machno][i] = aux;
} }
void void
irqroute(int i, void (*fn)(Ureg *)) irqroute(int i, void (*fn)(Ureg *, void *), void *aux)
{ {
ulong x, y, z; 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]; x = intd[0x208 + i/4];
y = 0xFF << ((i%4) * 8); y = 0xFF << ((i%4) * 8);
z = 1 << (m->machno + (i%4) * 8); z = 1 << (m->machno + (i%4) * 8);
x = (x & ~y) | z; x = (x & ~y) | z;
intd[0x208 + i/4] = x; intd[0x208 + i/4] = x;
// intd[0x200/4 + (i+32)/32] = 1 << (i % 32);
} }
void void
@ -128,6 +132,133 @@ updatetos(void)
tos->pid = up->pid; 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 void
trap(Ureg *ureg) trap(Ureg *ureg)
{ {
@ -149,10 +280,13 @@ trap(Ureg *ureg)
x = intc[3]; x = intc[3];
intn = x & 0x3FF; intn = x & 0x3FF;
if(irqhandler[m->machno][intn] != nil) 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; intc[4] = x;
if(intn != 29) if(intn != 29)
preempted(); preempted();
splhi();
if(up && up->delaysched && (intn == 29)){ if(up && up->delaysched && (intn == 29)){
sched(); sched();
splhi(); splhi();
@ -170,6 +304,8 @@ trap(Ureg *ureg)
} }
} }
if(user){ if(user){
if(up->procctl || up->nnote)
notify(ureg);
updatetos(); updatetos();
up->dbgreg = nil; up->dbgreg = nil;
} }
@ -193,7 +329,6 @@ syscall(Ureg *ureg)
} }
scall = ureg->r0; scall = ureg->r0;
up->scallnr = scall; up->scallnr = scall;
// print("%s\n", sysctab[scall]);
spllo(); spllo();
sp = ureg->sp; sp = ureg->sp;
@ -224,8 +359,16 @@ syscall(Ureg *ureg)
procctl(up); procctl(up);
splx(s); splx(s);
} }
up->insyscall = 0; up->insyscall = 0;
up->psstate = nil; up->psstate = nil;
if(scall == NOTED)
noted(ureg, *(ulong *)(sp + BY2WD));
if(scall != RFORK && (up->procctl || up->nnote)){
splhi();
notify(ureg);
}
splhi(); splhi();
if(up->delaysched){ if(up->delaysched){
sched(); sched();

View file

@ -24,20 +24,23 @@ omappnp(void)
static void static void
omapkick(Uart *u) omapkick(Uart *u)
{ {
int x;
x = splhi();
while((uart[17] & 1) == 0){ while((uart[17] & 1) == 0){
if(u->op >= u->oe) if(u->op >= u->oe)
if(uartstageoutput(u) == 0) if(uartstageoutput(u) == 0){
break;
uart[0] = *u->op++;
}
if(u->op < u->oe || qlen(u->oq))
uart[1] |= (1<<1);
else
uart[1] &= ~(1<<1); uart[1] &= ~(1<<1);
break;
}
uart[0] = *u->op++;
uart[1] |= (1<<1);
}
splx(x);
} }
void void
omapinterrupt(Ureg *) omapinterrupt(Ureg *, void *)
{ {
ulong st; ulong st;
@ -45,6 +48,12 @@ omapinterrupt(Ureg *)
if((st & 1) != 0) if((st & 1) != 0)
return; return;
switch((st >> 1) & 0x1F){ 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: case 1:
uartkick(&puart); uartkick(&puart);
break; break;
@ -54,23 +63,164 @@ omapinterrupt(Ureg *)
uartrecv(&puart, uart[0]); uartrecv(&puart, uart[0]);
break; break;
default: default:
print("unknown UART interrupt %d\n", (st>>1) & 0x1F); print("unknown UART interrupt %uld\n", (st>>1) & 0x1F);
uartkick(&puart); uartkick(&puart);
} }
} }
static void static void
omapenable(Uart *, int ie) omapenable(Uart *u, int ie)
{ {
while(uart[5] & (1<<6)) while(uart[5] & (1<<6))
; ;
if(ie){ if(ie){
irqroute(74, omapinterrupt); irqroute(74, omapinterrupt, u);
uart[1] = (1<<0); 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 static int
omapgetc(Uart *) omapgetc(Uart *)
{ {
@ -87,19 +237,22 @@ omapputc(Uart *, int c)
uart[0] = c; uart[0] = c;
} }
static void
omaprts(Uart *, int)
{
}
PhysUart omapphysuart = { PhysUart omapphysuart = {
.name = "omap4430 uart", .name = "omap4430 uart",
.pnp = omappnp, .pnp = omappnp,
.getc = omapgetc, .getc = omapgetc,
.putc = omapputc, .putc = omapputc,
.enable = omapenable, .enable = omapenable,
.disable = omapdisable,
.kick = omapkick, .kick = omapkick,
.rts = omaprts, .rts = omaprts,
.parity = omapparity,
.baud = omapbaud,
.bits = omapbits,
.stop = omapstop,
.modemctl = omapmodemctl,
.dtr = omapdtr,
.status = omapstatus,
}; };
void void

View file

@ -425,7 +425,7 @@ bcminterrupt(Ureg*, void *arg)
iunlock(&ctlr->imlock); iunlock(&ctlr->imlock);
} }
static void static int
bcminit(Ether *edev) bcminit(Ether *edev)
{ {
ulong i, j; ulong i, j;
@ -436,7 +436,12 @@ bcminit(Ether *edev)
/* initialization procedure according to the datasheet */ /* initialization procedure according to the datasheet */
csr32(ctlr, MiscHostCtl) |= MaskPCIInt | ClearIntA; csr32(ctlr, MiscHostCtl) |= MaskPCIInt | ClearIntA;
csr32(ctlr, SwArbitration) |= SwArbitSet1; 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, MemArbiterMode) |= Enable;
csr32(ctlr, MiscHostCtl) |= IndirectAccessEnable | EnablePCIStateRegister | EnableClockControlRegister; csr32(ctlr, MiscHostCtl) |= IndirectAccessEnable | EnablePCIStateRegister | EnableClockControlRegister;
csr32(ctlr, MemoryWindow) = 0; csr32(ctlr, MemoryWindow) = 0;
@ -452,7 +457,12 @@ bcminit(Ether *edev)
csr32(ctlr, ModeControl) |= ByteWordSwap; csr32(ctlr, ModeControl) |= ByteWordSwap;
csr32(ctlr, MACMode) = (csr32(ctlr, MACMode) & MACPortMask) | MACPortGMII; csr32(ctlr, MACMode) = (csr32(ctlr, MACMode) & MACPortMask) | MACPortGMII;
microdelay(40000); 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); csr32(ctlr, TLPControl) |= (1<<25) | (1<<29);
memset(ctlr->status, 0, 20); memset(ctlr->status, 0, 20);
csr32(ctlr, DMARWControl) = (csr32(ctlr, DMARWControl) & DMAWatermarkMask) | DMAWatermarkValue; csr32(ctlr, DMARWControl) = (csr32(ctlr, DMARWControl) & DMAWatermarkMask) | DMAWatermarkValue;
@ -462,10 +472,20 @@ bcminit(Ether *edev)
csr32(ctlr, MBUFHighWatermark) = 0x60; csr32(ctlr, MBUFHighWatermark) = 0x60;
csr32(ctlr, LowWatermarkMaximum) = (csr32(ctlr, LowWatermarkMaximum) & LowWatermarkMaxMask) | LowWatermarkMaxValue; csr32(ctlr, LowWatermarkMaximum) = (csr32(ctlr, LowWatermarkMaximum) & LowWatermarkMaxMask) | LowWatermarkMaxValue;
csr32(ctlr, BufferManMode) |= Enable | Attn; 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) = -1;
csr32(ctlr, FTQReset) = 0; 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) = 0;
csr32(ctlr, ReceiveBDHostAddr + 4) = PADDR(ctlr->recvprod); csr32(ctlr, ReceiveBDHostAddr + 4) = PADDR(ctlr->recvprod);
csr32(ctlr, ReceiveBDFlags) = RecvProdRingLen << 16; csr32(ctlr, ReceiveBDFlags) = RecvProdRingLen << 16;
@ -503,7 +523,12 @@ bcminit(Ether *edev)
csr32(ctlr, SendInitiatorMask) = 0xFFFFFF; csr32(ctlr, SendInitiatorMask) = 0xFFFFFF;
csr32(ctlr, SendInitiatorConfiguration) |= SendStats; csr32(ctlr, SendInitiatorConfiguration) |= SendStats;
csr32(ctlr, HostCoalescingMode) = 0; 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, HostCoalescingRecvTicks) = 150;
csr32(ctlr, HostCoalescingSendTicks) = 150; csr32(ctlr, HostCoalescingSendTicks) = 150;
csr32(ctlr, RecvMaxCoalescedFrames) = 10; csr32(ctlr, RecvMaxCoalescedFrames) = 10;
@ -539,7 +564,12 @@ bcminit(Ether *edev)
csr32(ctlr, MIMode) = 0xC0000; csr32(ctlr, MIMode) = 0xC0000;
microdelay(40); microdelay(40);
miiw(ctlr, PhyControl, 1<<15); 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); miiw(ctlr, PhyAuxControl, 2);
miir(ctlr, PhyIntStatus); miir(ctlr, PhyIntStatus);
miir(ctlr, PhyIntStatus); miir(ctlr, PhyIntStatus);
@ -554,6 +584,7 @@ bcminit(Ether *edev)
csr32(ctlr, ReceiveRulesConfiguration) = 1 << 3; csr32(ctlr, ReceiveRulesConfiguration) = 1 << 3;
csr32(ctlr, MSIMode) |= Enable; csr32(ctlr, MSIMode) |= Enable;
csr32(ctlr, MiscHostCtl) &= ~(MaskPCIInt | ClearIntA); csr32(ctlr, MiscHostCtl) &= ~(MaskPCIInt | ClearIntA);
return 0;
} }
static void static void
@ -637,6 +668,7 @@ bcmpnp(Ether* edev)
{ {
Ctlr *ctlr; Ctlr *ctlr;
again:
if(bcmhead == nil) if(bcmhead == nil)
bcmpci(); bcmpci();
@ -664,7 +696,10 @@ bcmpnp(Ether* edev)
edev->arg = edev; edev->arg = edev;
edev->mbps = 1000; edev->mbps = 1000;
bcminit(edev); if(bcminit(edev) < 0){
edev->ctlr = nil;
goto again;
}
return 0; return 0;
} }

View file

@ -162,10 +162,10 @@ vesalinear(VGAscr *scr, int, int)
vgalinearaddr(scr, paddr, size); vgalinearaddr(scr, paddr, size);
if(scr->apsize) if(scr->apsize)
addvgaseg("vesascreen", scr->paddr, scr->apsize); addvgaseg("vesascreen", scr->paddr, scr->apsize);
if(getconf("*vesashadow")){ if(getconf("*novesashadow"))
return;
hardscreen = scr->vaddr; hardscreen = scr->vaddr;
scr->paddr = scr->apsize = 0; scr->paddr = scr->apsize = 0;
}
} }
static void static void

View file

@ -77,6 +77,11 @@ asmb(void)
curtext = P; curtext = P;
switch(HEADTYPE) { switch(HEADTYPE) {
case 0: case 0:
if(debug['P']){
OFFSET = rnd(textsize, INITRND);
seek(cout, OFFSET, 0);
break;
}
case 1: case 1:
case 2: case 2:
case 5: case 5: