diff --git a/sys/src/9/omap4/arch.c b/sys/src/9/omap4/arch.c index 9f4548ac2..fc852143c 100644 --- a/sys/src/9/omap4/arch.c +++ b/sys/src/9/omap4/arch.c @@ -29,13 +29,34 @@ dbgpc(Proc *p) } void -procsave(Proc *) +setkernur(Ureg *ureg, Proc *p) +{ + ureg->pc = p->sched.pc; + ureg->sp = p->sched.sp+4; + ureg->r14 = (ulong) sched; +} + +void +setregisters(Ureg *, char *, char *, int) { } void -procrestore(Proc *) +procsave(Proc *p) { + uvlong t; + + cycles(&t); + p->pcycles += t; +} + +void +procrestore(Proc *p) +{ + uvlong t; + + cycles(&t); + p->pcycles -= t; } void @@ -107,12 +128,6 @@ evenaddr(uintptr addr) } } -Segment * -data2txt(Segment *) -{ - panic("data2txt"); -} - void _dumpstack(ulong sp, ulong pc) { diff --git a/sys/src/9/omap4/clock.c b/sys/src/9/omap4/clock.c index 2129fbee6..980d973ff 100644 --- a/sys/src/9/omap4/clock.c +++ b/sys/src/9/omap4/clock.c @@ -8,7 +8,11 @@ extern uchar *periph; ulong *global, *local; -enum { PERIPHCLK = 506965000 } ; +enum { + PERIPHCLK = 506965000, + MaxPeriod = PERIPHCLK / (256 * 100), + MinPeriod = MaxPeriod / 100, +} ; void globalclockinit(void) @@ -63,30 +67,32 @@ perfticks(void) void clocktick(Ureg* ureg) { - extern void _dumpstack(ulong, ulong); - static int n; - -// if(++n % 128 == 0 && up && up->pid == 1) -// _dumpstack(ureg->sp, ureg->pc); timerintr(ureg, 0); } void localclockinit(void) { - local[2] = 0xFF07; + local[2] = 0xFF06; intenable(29, clocktick); + timerset(0); } void timerset(uvlong val) { uvlong now, ticks; - - cycles(&now); - ticks = (val - now) * (PERIPHCLK / 256) / 1000000000; - if(ticks == 0) - ticks++; + + if(val == 0) + ticks = MaxPeriod; + else{ + cycles(&now); + ticks = (val - now) / 256; + if(ticks < MinPeriod) + ticks = MinPeriod; + if(ticks > MaxPeriod) + ticks = MaxPeriod; + } local[2] &= ~1; local[0] = local[1] = ticks; local[2] |= 1; diff --git a/sys/src/9/omap4/fns.h b/sys/src/9/omap4/fns.h index ce16bdc71..116712cb0 100644 --- a/sys/src/9/omap4/fns.h +++ b/sys/src/9/omap4/fns.h @@ -4,6 +4,7 @@ #define getpgcolor(x) 0 #define kmapinval() #define checkmmu(a,b) +#define userureg(ur) (((ur)->psr & 0x1F) == 0x10) extern void procsave(Proc *); extern void procrestore(Proc *); @@ -18,6 +19,7 @@ extern uintptr cankaddr(uintptr); extern void* KADDR(ulong); extern ulong paddr(void *); extern void cycles(uvlong *); +extern void markidle(int); #define PADDR(x) paddr((void*)(x)) void mmuinit(void); @@ -32,3 +34,6 @@ void links(void); void globalclockinit(void); void localclockinit(void); void intenable(int, void(*)(Ureg*)); +void setled(int, int); +void uartinit(void); +void irqroute(int, void(*)(Ureg*)); diff --git a/sys/src/9/omap4/l.s b/sys/src/9/omap4/l.s index 1a392a870..427792503 100644 --- a/sys/src/9/omap4/l.s +++ b/sys/src/9/omap4/l.s @@ -226,12 +226,11 @@ TEXT _trap(SB), 1, $-4 MOVW R13, R0 SUB $8, R13 BL trap(SB) - ADD $8, R13 - MOVW 64(R13), R0 + MOVW 72(R13), R0 AND $PsrMask, R0 CMP $PsrMusr, R0 - MOVW.EQ R13, R0 - B.EQ gotouser + B.EQ _forkret + ADD $8, R13 MOVW 68(R13), R0 MOVW R0, 60(R13) MOVW 64(R13), R0 @@ -255,11 +254,12 @@ TEXT _syscall(SB), 1, $-4 BL syscall(SB) TEXT forkret(SB), 1, $-4 +_forkret: ADD $8, R13 MOVW R13, R0 + ADD $72, R13 TEXT touser(SB), 1, $-4 -gotouser: ADD $52, R0 MOVM.IA.S (R0), [R13-R14] SUB $52, R0 @@ -296,3 +296,7 @@ TEXT getdfar(SB), 0, $-4 TEXT getifar(SB), 0, $-4 MRC CpSC, 0, R0, C(6), C(0), 2 RET + +TEXT getr13(SB), 0, $-4 + MOVW R13, R0 + RET diff --git a/sys/src/9/omap4/main.c b/sys/src/9/omap4/main.c index efe8faaa1..309bf6eb0 100644 --- a/sys/src/9/omap4/main.c +++ b/sys/src/9/omap4/main.c @@ -1,5 +1,6 @@ #include "u.h" #include "ureg.h" +#include "pool.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" @@ -35,6 +36,7 @@ machinit(void) conf.nproc = 100; conf.pipeqsize = 32768; conf.nimage = 200; + conf.ialloc = 65536; } void @@ -53,6 +55,7 @@ init0(void) ksetenv("terminal", "generic /sys/src/9/omap4/panda", 0); ksetenv("cputype", "arm", 0); ksetenv("service", "cpu", 0); + ksetenv("console", "0", 0); poperror(); } kproc("alarm", alarmkproc, 0); @@ -144,8 +147,6 @@ userinit(void) void main() { - extern int chandebug; - wave('f'); memset(edata, 0, end - edata); wave('r'); @@ -154,6 +155,7 @@ main() mmuinit(); wave('m'); trapinit(); + uartinit(); print(" Bell Labs\n"); xinit(); globalclockinit(); @@ -166,7 +168,6 @@ main() quotefmtinstall(); chandevreset(); links(); - chandebug++; userinit(); schedinit(); } diff --git a/sys/src/9/omap4/mkfile b/sys/src/9/omap4/mkfile index 69160335f..79a91f84a 100644 --- a/sys/src/9/omap4/mkfile +++ b/sys/src/9/omap4/mkfile @@ -44,7 +44,6 @@ OBJ=\ random.$O\ clock.$O\ arch.$O\ - uart.$O\ trap.$O\ $CONF.root.$O\ $CONF.rootc.$O\ diff --git a/sys/src/9/omap4/mmu.c b/sys/src/9/omap4/mmu.c index cb659eddf..afbc7794e 100644 --- a/sys/src/9/omap4/mmu.c +++ b/sys/src/9/omap4/mmu.c @@ -9,6 +9,7 @@ char iopages[NIOPAGES / 8]; Lock iopagelock; uchar *periph; +ulong *ledgpio; static int isfree(int i) @@ -94,6 +95,21 @@ 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); +} + void mmuinit(void) { @@ -110,6 +126,8 @@ 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; pl2 = KADDR(PRIVL2); @@ -119,7 +137,9 @@ mmuinit(void) pl2[241] = FIRSTMACH | L2AP(Krw) | Small | Cached | Buffered; flushtlb(); m = (Mach *) MACHADDR; - periph = vmap(0x48240000, 2 * BY2PG); + 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 61f1db0ef..003fde1d2 100644 --- a/sys/src/9/omap4/panda +++ b/sys/src/9/omap4/panda @@ -4,11 +4,11 @@ dev cons env pipe -# proc + proc mnt srv shr -# dup + dup # arch # ssl # tls @@ -28,7 +28,7 @@ dev # dss # mouse -# uart + uart # usb link @@ -63,6 +63,7 @@ misc # uarti8250 # ucalloc # ucallocb + uartomap port int cpuserver = 1; diff --git a/sys/src/9/omap4/trap.c b/sys/src/9/omap4/trap.c index a965024aa..13d54e44a 100644 --- a/sys/src/9/omap4/trap.c +++ b/sys/src/9/omap4/trap.c @@ -8,10 +8,11 @@ #include "fns.h" #include "io.h" #include "arm.h" +#include "tos.h" extern uchar *periph; ulong *intc, *intd; -void (*irqhandler[256])(Ureg*); +void (*irqhandler[MAXMACH][256])(Ureg*); static char *trapname[] = { "reset", /* wtf */ @@ -53,8 +54,22 @@ trapinit(void) void intenable(int i, void (*fn)(Ureg *)) { - intd[0x40 + (i / 32)] |= 1 << (i % 32); - irqhandler[i] = fn; + intd[0x40 + (i / 32)] = 1 << (i % 32); + irqhandler[m->machno][i] = fn; +} + +void +irqroute(int i, void (*fn)(Ureg *)) +{ + ulong x, y, z; + + intenable(32 + i, fn); + 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 @@ -78,10 +93,12 @@ faultarm(Ureg *ureg) } if(!user && addr >= KZERO){ kernel: + serialoq = nil; printureg(ureg); - panic("kernel fault: addr=%#.8lux pc=%#.8lux sr=%#.8lux", addr, ureg->pc, sr); + panic("kernel fault: addr=%#.8lux pc=%#.8lux lr=%#.8lux sr=%#.8lux", addr, ureg->pc, ureg->r14, sr); } if(up == nil){ + serialoq = nil; printureg(ureg); panic("%s fault: up=nil addr=%#.8lux pc=%#.8lux sr=%#.8lux", user ? "user" : "kernel", addr, ureg->pc, sr); } @@ -91,21 +108,37 @@ faultarm(Ureg *ureg) if(n < 0){ if(!user) goto kernel; + spllo(); sprint(buf, "sys: trap: fault %s addr=0x%lux", read ? "read" : "write", addr); postnote(up, 1, buf, NDebug); } up->insyscall = nsys; } +void +updatetos(void) +{ + Tos *tos; + uvlong t; + + tos = (Tos*) (USTKTOP - sizeof(Tos)); + cycles(&t); + tos->kcycles += t - up->kentry; + tos->pcycles = up->pcycles; + tos->pid = up->pid; +} + void trap(Ureg *ureg) { int user, intn, x; + char buf[ERRMAX]; user = (ureg->psr & PsrMask) == PsrMusr; if(user){ fillureguser(ureg); up->dbgreg = ureg; + cycles(&up->kentry); } switch(ureg->type){ case 3: @@ -114,9 +147,9 @@ trap(Ureg *ureg) break; case 6: x = intc[3]; - intn = x & 0x3F; - if(irqhandler[intn] != nil) - irqhandler[intn](ureg); + intn = x & 0x3FF; + if(irqhandler[m->machno][intn] != nil) + irqhandler[m->machno][intn](ureg); intc[4] = x; if(intn != 29) preempted(); @@ -126,11 +159,20 @@ trap(Ureg *ureg) } break; default: - printureg(ureg); - panic("%s", trapname[ureg->type]); + if(user){ + spllo(); + sprint("sys: trap: %s", trapname[ureg->type]); + postnote(up, 1, buf, NDebug); + }else{ + serialoq = nil; + printureg(ureg); + panic("%s", trapname[ureg->type]); + } } - if(user) + if(user){ + updatetos(); up->dbgreg = nil; + } } void @@ -144,6 +186,7 @@ syscall(Ureg *ureg) up->insyscall = 1; up->pc = ureg->pc; up->dbgreg = ureg; + cycles(&up->kentry); if(up->procctl == Proc_tracesyscall){ up->procctl = Proc_stopme; procctl(up); @@ -188,5 +231,6 @@ syscall(Ureg *ureg) sched(); splhi(); } + updatetos(); up->dbgreg = nil; } diff --git a/sys/src/9/omap4/uart.c b/sys/src/9/omap4/uart.c deleted file mode 100644 index 7a4a40083..000000000 --- a/sys/src/9/omap4/uart.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -extern ulong *uart; - -void -uartputs(char *s, int n) -{ - for(; n--; s++){ - while(uart[17] & 1) - ; - uart[0] = *s; - } -} diff --git a/sys/src/9/omap4/uartomap.c b/sys/src/9/omap4/uartomap.c new file mode 100644 index 000000000..e0e6c508a --- /dev/null +++ b/sys/src/9/omap4/uartomap.c @@ -0,0 +1,110 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +extern ulong *uart; +extern PhysUart omapphysuart; +static Uart puart = { + .phys = &omapphysuart, + .bits = 8, + .stop = 1, + .baud = 115200, + .parity = 'n', +}; + +static Uart * +omappnp(void) +{ + return &puart; +} + +static void +omapkick(Uart *u) +{ + while((uart[17] & 1) == 0){ + if(u->op >= u->oe) + 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); +} + +void +omapinterrupt(Ureg *) +{ + ulong st; + + st = uart[2]; + if((st & 1) != 0) + return; + switch((st >> 1) & 0x1F){ + case 1: + uartkick(&puart); + break; + case 2: + case 6: + while(uart[5] & 1) + uartrecv(&puart, uart[0]); + break; + default: + print("unknown UART interrupt %d\n", (st>>1) & 0x1F); + uartkick(&puart); + } +} + +static void +omapenable(Uart *, int ie) +{ + while(uart[5] & (1<<6)) + ; + if(ie){ + irqroute(74, omapinterrupt); + uart[1] = (1<<0); + // uart[0x10] |= (1<<3); + } +} + +static int +omapgetc(Uart *) +{ + while((uart[5] & 1) == 0) + ; + return uart[0]; +} + +static void +omapputc(Uart *, int c) +{ + while(uart[17] & 1) + ; + uart[0] = c; +} + +static void +omaprts(Uart *, int) +{ +} + +PhysUart omapphysuart = { + .name = "omap4430 uart", + .pnp = omappnp, + .getc = omapgetc, + .putc = omapputc, + .enable = omapenable, + .kick = omapkick, + .rts = omaprts, +}; + +void +uartinit(void) +{ + consuart = &puart; + puart.console = 1; +}