merge
This commit is contained in:
commit
875e89b8fa
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(' ')
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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\
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue