merge
This commit is contained in:
commit
933d48e43e
18 changed files with 2081 additions and 1 deletions
|
@ -42,4 +42,5 @@ The 'IE users have lower IQs' story was a hoax.
|
||||||
Do you know anything about vim?
|
Do you know anything about vim?
|
||||||
today there were problems with the Fossil FS on my Plan9 test installation.
|
today there were problems with the Fossil FS on my Plan9 test installation.
|
||||||
Epistemology is the most important science.
|
Epistemology is the most important science.
|
||||||
The problem with all the economists is that they base their theories on empiric observations.
|
The problem with all the economists is that they base their theories on empiric observations.
|
||||||
|
Why would you program in C if you know Lisp anyway?
|
||||||
|
|
161
sys/src/9/omap4/arch.c
Normal file
161
sys/src/9/omap4/arch.c
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
#include "u.h"
|
||||||
|
#include "ureg.h"
|
||||||
|
#include "../port/lib.h"
|
||||||
|
#include "../port/error.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "arm.h"
|
||||||
|
#include "tos.h"
|
||||||
|
|
||||||
|
void (*proctrace)(Proc *, int, vlong);
|
||||||
|
|
||||||
|
ulong
|
||||||
|
userpc(void)
|
||||||
|
{
|
||||||
|
return dbgpc(up);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong
|
||||||
|
dbgpc(Proc *p)
|
||||||
|
{
|
||||||
|
Ureg *ureg;
|
||||||
|
|
||||||
|
ureg = p->dbgreg;
|
||||||
|
if(ureg == 0)
|
||||||
|
return 0;
|
||||||
|
return ureg->pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
procsave(Proc *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
procrestore(Proc *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
procfork(Proc *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
procsetup(Proc *p)
|
||||||
|
{
|
||||||
|
p->fpstate = FPinit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
linkproc(void)
|
||||||
|
{
|
||||||
|
spllo();
|
||||||
|
up->kpfun(up->kparg);
|
||||||
|
pexit("kproc exiting", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kprocchild(Proc *p, void (*func)(void *), void *arg)
|
||||||
|
{
|
||||||
|
p->sched.pc = (ulong) linkproc;
|
||||||
|
p->sched.sp = (ulong) p->kstack + KSTACK;
|
||||||
|
p->kpfun = func;
|
||||||
|
p->kparg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
forkchild(Proc *p, Ureg *ureg)
|
||||||
|
{
|
||||||
|
Ureg *cureg;
|
||||||
|
|
||||||
|
p->sched.sp = (ulong) p->kstack + KSTACK - (sizeof(Ureg) + 8);
|
||||||
|
p->sched.pc = (ulong) forkret;
|
||||||
|
cureg = (Ureg*) (p->sched.sp + 8);
|
||||||
|
memmove(cureg, ureg, sizeof(Ureg));
|
||||||
|
cureg->r0 = 0;
|
||||||
|
p->psstate = 0;
|
||||||
|
p->insyscall = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
execregs(ulong entry, ulong ssize, ulong nargs)
|
||||||
|
{
|
||||||
|
ulong *sp;
|
||||||
|
Ureg *ureg;
|
||||||
|
|
||||||
|
up->fpstate = FPinit;
|
||||||
|
sp = (ulong *) (USTKTOP - ssize);
|
||||||
|
*--sp = nargs;
|
||||||
|
|
||||||
|
ureg = up->dbgreg;
|
||||||
|
memset(ureg, 0, sizeof *ureg);
|
||||||
|
ureg->psr = PsrMusr;
|
||||||
|
ureg->sp = (ulong) sp;
|
||||||
|
ureg->pc = entry;
|
||||||
|
return USTKTOP - sizeof(Tos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evenaddr(uintptr addr)
|
||||||
|
{
|
||||||
|
if(addr & 3){
|
||||||
|
postnote(up, 1, "sys: odd address", NDebug);
|
||||||
|
error(Ebadarg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Segment *
|
||||||
|
data2txt(Segment *)
|
||||||
|
{
|
||||||
|
panic("data2txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_dumpstack(ulong sp, ulong pc)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
uintptr l, v, i, estack;
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
x += iprint("ktrace /arm/s9panda %#.8lux %#.8lux <<EOF\n",
|
||||||
|
pc, sp);
|
||||||
|
i = 0;
|
||||||
|
if(up
|
||||||
|
&& (uintptr)&l >= (uintptr)up->kstack
|
||||||
|
&& (uintptr)&l <= (uintptr)up->kstack+KSTACK)
|
||||||
|
estack = (uintptr)up->kstack+KSTACK;
|
||||||
|
else if((uintptr)&l >= (uintptr)(KTZERO - BY2PG)
|
||||||
|
&& (uintptr)&l <= (uintptr)KTZERO)
|
||||||
|
estack = (uintptr)KTZERO;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
x += iprint("estackx %p\n", estack);
|
||||||
|
|
||||||
|
for(l = (uintptr)&l; l < estack; l += sizeof(uintptr)){
|
||||||
|
v = *(uintptr*)l;
|
||||||
|
if((KTZERO < v && v < (uintptr)etext) || estack-l < 32){
|
||||||
|
x += iprint("%.8p=%.8p ", l, v);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(i == 4){
|
||||||
|
i = 0;
|
||||||
|
x += iprint("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i)
|
||||||
|
iprint("\n");
|
||||||
|
iprint("EOF\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
printureg(Ureg *ureg)
|
||||||
|
{
|
||||||
|
print("R0 %.8ulx R1 %.8ulx R2 %.8ulx R3 %.8ulx\n", ureg->r0, ureg->r1, ureg->r2, ureg->r3);
|
||||||
|
print("R4 %.8ulx R5 %.8ulx R6 %.8ulx R7 %.8ulx\n", ureg->r4, ureg->r5, ureg->r6, ureg->r7);
|
||||||
|
print("R8 %.8ulx R9 %.8ulx R10 %.8ulx R11 %.8ulx\n", ureg->r8, ureg->r9, ureg->r10, ureg->r11);
|
||||||
|
print("R12 %.8ulx R13 %.8ulx R14 %.8ulx R15 %.8ulx\n", ureg->r12, ureg->r13, ureg->r14, ureg->pc);
|
||||||
|
print("PSR %.8ulx exception %ld\n", ureg->psr, ureg->type);
|
||||||
|
}
|
246
sys/src/9/omap4/arm.h
Normal file
246
sys/src/9/omap4/arm.h
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
/*
|
||||||
|
* arm-specific definitions for cortex-a8
|
||||||
|
* these are used in C and assembler
|
||||||
|
*
|
||||||
|
* `cortex' refers specifically to the cortex-a8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Program Status Registers
|
||||||
|
*/
|
||||||
|
#define PsrMusr 0x00000010 /* mode */
|
||||||
|
#define PsrMfiq 0x00000011
|
||||||
|
#define PsrMirq 0x00000012
|
||||||
|
#define PsrMsvc 0x00000013 /* `protected mode for OS' */
|
||||||
|
#define PsrMmon 0x00000016 /* `secure monitor' (trustzone hyper) */
|
||||||
|
#define PsrMabt 0x00000017
|
||||||
|
#define PsrMund 0x0000001B
|
||||||
|
#define PsrMsys 0x0000001F /* `privileged user mode for OS' (trustzone) */
|
||||||
|
#define PsrMask 0x0000001F
|
||||||
|
|
||||||
|
#define PsrDfiq 0x00000040 /* disable FIQ interrupts */
|
||||||
|
#define PsrDirq 0x00000080 /* disable IRQ interrupts */
|
||||||
|
|
||||||
|
#define PsrV 0x10000000 /* overflow */
|
||||||
|
#define PsrC 0x20000000 /* carry/borrow/extend */
|
||||||
|
#define PsrZ 0x40000000 /* zero */
|
||||||
|
#define PsrN 0x80000000 /* negative/less than */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Coprocessors
|
||||||
|
*/
|
||||||
|
#define CpFP 10 /* float FP, VFP cfg. */
|
||||||
|
#define CpDFP 11 /* double FP */
|
||||||
|
#define CpSC 15 /* System Control */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Primary (CRn) CpSC registers.
|
||||||
|
*/
|
||||||
|
#define CpID 0 /* ID and cache type */
|
||||||
|
#define CpCONTROL 1 /* miscellaneous control */
|
||||||
|
#define CpTTB 2 /* Translation Table Base(s) */
|
||||||
|
#define CpDAC 3 /* Domain Access Control */
|
||||||
|
#define CpFSR 5 /* Fault Status */
|
||||||
|
#define CpFAR 6 /* Fault Address */
|
||||||
|
#define CpCACHE 7 /* cache/write buffer control */
|
||||||
|
#define CpTLB 8 /* TLB control */
|
||||||
|
#define CpCLD 9 /* L2 Cache Lockdown, op1==1 */
|
||||||
|
#define CpTLD 10 /* TLB Lockdown, with op2 */
|
||||||
|
#define CpVECS 12 /* vector bases, op1==0, Crm==0, op2s (cortex) */
|
||||||
|
#define CpPID 13 /* Process ID */
|
||||||
|
#define CpDTLB 15 /* TLB, L1 cache stuff (cortex) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpTTB op1==0, Crm==0 opcode2 values.
|
||||||
|
*/
|
||||||
|
#define CpTTB0 0
|
||||||
|
#define CpTTB1 1 /* cortex */
|
||||||
|
#define CpTTBctl 2 /* cortex */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpID Secondary (CRm) registers.
|
||||||
|
*/
|
||||||
|
#define CpIDidct 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpID op1==0 opcode2 fields.
|
||||||
|
* the cortex has more op1 codes for cache size, etc.
|
||||||
|
*/
|
||||||
|
#define CpIDid 0 /* main ID */
|
||||||
|
#define CpIDct 1 /* cache type */
|
||||||
|
#define CpIDtlb 3 /* tlb type (cortex) */
|
||||||
|
#define CpIDmpid 5 /* multiprocessor id (cortex) */
|
||||||
|
|
||||||
|
/* CpIDid op1 values */
|
||||||
|
#define CpIDcsize 1 /* cache size (cortex) */
|
||||||
|
#define CpIDcssel 2 /* cache size select (cortex) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpCONTROL op2 codes, op1==0, Crm==0.
|
||||||
|
*/
|
||||||
|
#define CpMainctl 0
|
||||||
|
#define CpAuxctl 1
|
||||||
|
#define CpCPaccess 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpCONTROL: op1==0, CRm==0, op2==CpMainctl.
|
||||||
|
* main control register.
|
||||||
|
* cortex/armv7 has more ops and CRm values.
|
||||||
|
*/
|
||||||
|
#define CpCmmu 0x00000001 /* M: MMU enable */
|
||||||
|
#define CpCalign 0x00000002 /* A: alignment fault enable */
|
||||||
|
#define CpCdcache 0x00000004 /* C: data cache on */
|
||||||
|
#define CpCsbo (3<<22|1<<18|1<<16|017<<3) /* must be 1 (armv7) */
|
||||||
|
#define CpCsbz (CpCtre|1<<26|CpCve|1<<15|7<<7) /* must be 0 (armv7) */
|
||||||
|
#define CpCsw (1<<10) /* SW: SWP(B) enable (deprecated in v7) */
|
||||||
|
#define CpCpredict 0x00000800 /* Z: branch prediction (armv7) */
|
||||||
|
#define CpCicache 0x00001000 /* I: instruction cache on */
|
||||||
|
#define CpChv 0x00002000 /* V: high vectors */
|
||||||
|
#define CpCrr (1<<14) /* RR: round robin vs random cache replacement */
|
||||||
|
#define CpCha (1<<17) /* HA: hw access flag enable */
|
||||||
|
#define CpCdz (1<<19) /* DZ: divide by zero fault enable */
|
||||||
|
#define CpCfi (1<<21) /* FI: fast intrs */
|
||||||
|
#define CpCve (1<<24) /* VE: intr vectors enable */
|
||||||
|
#define CpCee (1<<25) /* EE: exception endianness */
|
||||||
|
#define CpCnmfi (1<<27) /* NMFI: non-maskable fast intrs. */
|
||||||
|
#define CpCtre (1<<28) /* TRE: TEX remap enable */
|
||||||
|
#define CpCafe (1<<29) /* AFE: access flag (ttb) enable */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpCONTROL: op1==0, CRm==0, op2==CpAuxctl.
|
||||||
|
* Auxiliary control register on cortex at least.
|
||||||
|
*/
|
||||||
|
#define CpACcachenopipe (1<<20) /* don't pipeline cache maint. */
|
||||||
|
#define CpACcp15serial (1<<18) /* serialise CP1[45] ops. */
|
||||||
|
#define CpACcp15waitidle (1<<17) /* CP1[45] wait-on-idle */
|
||||||
|
#define CpACcp15pipeflush (1<<16) /* CP1[45] flush pipeline */
|
||||||
|
#define CpACneonissue1 (1<<12) /* neon single issue */
|
||||||
|
#define CpACldstissue1 (1<<11) /* force single issue ld, st */
|
||||||
|
#define CpACissue1 (1<<10) /* force single issue */
|
||||||
|
#define CpACnobsm (1<<7) /* no branch size mispredicts */
|
||||||
|
#define CpACibe (1<<6) /* cp15 invalidate & btb enable */
|
||||||
|
#define CpACl1neon (1<<5) /* cache neon (FP) data in L1 cache */
|
||||||
|
#define CpACasa (1<<4) /* enable speculative accesses */
|
||||||
|
#define CpACl1pe (1<<3) /* l1 cache parity enable */
|
||||||
|
#define CpACl2en (1<<1) /* l2 cache enable; default 1 */
|
||||||
|
/*
|
||||||
|
* CpCONTROL Secondary (CRm) registers and opcode2 fields.
|
||||||
|
*/
|
||||||
|
#define CpCONTROLscr 1
|
||||||
|
|
||||||
|
#define CpSCRscr 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpCACHE Secondary (CRm) registers and opcode2 fields. op1==0.
|
||||||
|
* In ARM-speak, 'flush' means invalidate and 'clean' means writeback.
|
||||||
|
*/
|
||||||
|
#define CpCACHEintr 0 /* interrupt (op2==4) */
|
||||||
|
#define CpCACHEisi 1 /* inner-sharable I cache (v7) */
|
||||||
|
#define CpCACHEpaddr 4 /* 0: phys. addr (cortex) */
|
||||||
|
#define CpCACHEinvi 5 /* instruction, branch table */
|
||||||
|
#define CpCACHEinvd 6 /* data or unified */
|
||||||
|
// #define CpCACHEinvu 7 /* unified (not on cortex) */
|
||||||
|
#define CpCACHEva2pa 8 /* va -> pa translation (cortex) */
|
||||||
|
#define CpCACHEwb 10 /* writeback */
|
||||||
|
#define CpCACHEinvdse 11 /* data or unified by mva */
|
||||||
|
#define CpCACHEwbi 14 /* writeback+invalidate */
|
||||||
|
|
||||||
|
#define CpCACHEall 0 /* entire (not for invd nor wb(i) on cortex) */
|
||||||
|
#define CpCACHEse 1 /* single entry */
|
||||||
|
#define CpCACHEsi 2 /* set/index (set/way) */
|
||||||
|
#define CpCACHEtest 3 /* test loop */
|
||||||
|
#define CpCACHEwait 4 /* wait (prefetch flush on cortex) */
|
||||||
|
#define CpCACHEdmbarr 5 /* wb only (cortex) */
|
||||||
|
#define CpCACHEflushbtc 6 /* flush branch-target cache (cortex) */
|
||||||
|
#define CpCACHEflushbtse 7 /* ⋯ or just one entry in it (cortex) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpTLB Secondary (CRm) registers and opcode2 fields.
|
||||||
|
*/
|
||||||
|
#define CpTLBinvi 5 /* instruction */
|
||||||
|
#define CpTLBinvd 6 /* data */
|
||||||
|
#define CpTLBinvu 7 /* unified */
|
||||||
|
|
||||||
|
#define CpTLBinv 0 /* invalidate all */
|
||||||
|
#define CpTLBinvse 1 /* invalidate single entry */
|
||||||
|
#define CpTBLasid 2 /* by ASID (cortex) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpCLD Secondary (CRm) registers and opcode2 fields for op1==0. (cortex)
|
||||||
|
*/
|
||||||
|
#define CpCLDena 12 /* enables */
|
||||||
|
#define CpCLDcyc 13 /* cycle counter */
|
||||||
|
#define CpCLDuser 14 /* user enable */
|
||||||
|
|
||||||
|
#define CpCLDenapmnc 0
|
||||||
|
#define CpCLDenacyc 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpCLD Secondary (CRm) registers and opcode2 fields for op1==1.
|
||||||
|
*/
|
||||||
|
#define CpCLDl2 0 /* l2 cache */
|
||||||
|
|
||||||
|
#define CpCLDl2aux 2 /* auxiliary control */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* l2 cache aux. control
|
||||||
|
*/
|
||||||
|
#define CpCl2ecc (1<<28) /* use ecc, not parity */
|
||||||
|
#define CpCl2noldforw (1<<27) /* no ld forwarding */
|
||||||
|
#define CpCl2nowrcomb (1<<25) /* no write combining */
|
||||||
|
#define CpCl2nowralldel (1<<24) /* no write allocate delay */
|
||||||
|
#define CpCl2nowrallcomb (1<<23) /* no write allocate combine */
|
||||||
|
#define CpCl2nowralloc (1<<22) /* no write allocate */
|
||||||
|
#define CpCl2eccparity (1<<21) /* enable ecc or parity */
|
||||||
|
#define CpCl2inner (1<<16) /* inner cacheability */
|
||||||
|
/* other bits are tag ram & data ram latencies */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpTLD Secondary (CRm) registers and opcode2 fields.
|
||||||
|
*/
|
||||||
|
#define CpTLDlock 0 /* TLB lockdown registers */
|
||||||
|
#define CpTLDpreload 1 /* TLB preload */
|
||||||
|
|
||||||
|
#define CpTLDi 0 /* TLB instr. lockdown reg. */
|
||||||
|
#define CpTLDd 1 /* " data " " */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CpVECS Secondary (CRm) registers and opcode2 fields.
|
||||||
|
*/
|
||||||
|
#define CpVECSbase 0
|
||||||
|
|
||||||
|
#define CpVECSnorm 0 /* (non-)secure base addr */
|
||||||
|
#define CpVECSmon 1 /* secure monitor base addr */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MMU page table entries.
|
||||||
|
*/
|
||||||
|
#define Fault 0x00000000 /* L[12] pte: unmapped */
|
||||||
|
|
||||||
|
#define Coarse (1) /* L1 */
|
||||||
|
#define Section (2) /* L1 1MB */
|
||||||
|
#define Fine (3) /* L1 */
|
||||||
|
|
||||||
|
#define Large 0x00000001 /* L2 64KB */
|
||||||
|
#define Small 0x00000002 /* L2 4KB */
|
||||||
|
#define Tiny 0x00000003 /* L2 1KB: not in v7 */
|
||||||
|
#define Buffered 0x00000004 /* L[12]: write-back not -thru */
|
||||||
|
#define Cached 0x00000008 /* L[12] */
|
||||||
|
#define ExecuteNever (1<<4)
|
||||||
|
|
||||||
|
#define Noaccess 0 /* AP, DAC */
|
||||||
|
#define Krw 1 /* AP */
|
||||||
|
/* armv7 deprecates AP[2] == 1 & AP[1:0] == 2 (Uro), prefers 3 (new in v7) */
|
||||||
|
#define Uro 2 /* AP */
|
||||||
|
#define Urw 3 /* AP */
|
||||||
|
#define Client 1 /* DAC */
|
||||||
|
#define Manager 3 /* DAC */
|
||||||
|
|
||||||
|
#define AP(n, v) F((v), ((n)*2)+4, 2)
|
||||||
|
#define L1AP(ap) (AP(3, (ap)))
|
||||||
|
#define L2AP(ap) (AP(0, (ap))) /* armv7 */
|
||||||
|
#define DAC(n, v) F((v), (n)*2, 2)
|
||||||
|
|
||||||
|
#define HVECTORS 0xffff0000
|
||||||
|
#define PTEDRAM (L1AP(Krw)|Section|Cached|Buffered)
|
||||||
|
#define PTEIO (ExecuteNever)
|
31
sys/src/9/omap4/arm.s
Normal file
31
sys/src/9/omap4/arm.s
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "arm.h"
|
||||||
|
|
||||||
|
/* arm v7 arch defines these */
|
||||||
|
#define WFI WORD $0xe320f003 /* wait for interrupt */
|
||||||
|
#define DMB WORD $0xf57ff05f /* data mem. barrier; last f = SY */
|
||||||
|
#define DSB WORD $0xf57ff04f /* data synch. barrier; last f = SY */
|
||||||
|
#define ISB WORD $0xf57ff06f /* instr. sync. barrier; last f = SY */
|
||||||
|
#define NOOP WORD $0xe320f000
|
||||||
|
#define CLZ(s, d) WORD $(0xe16f0f10 | (d) << 12 | (s)) /* count leading 0s */
|
||||||
|
#define CPSIE WORD $0xf1080080 /* intr enable: zeroes I bit */
|
||||||
|
#define CPSID WORD $0xf10c0080 /* intr disable: sets I bit */
|
||||||
|
|
||||||
|
#define EWAVE(n)\
|
||||||
|
MOVW $0x48020000, R0; \
|
||||||
|
MOVW $n, R1; \
|
||||||
|
MOVW R1, (R0);
|
||||||
|
|
||||||
|
#define WAVE(n)\
|
||||||
|
MOVW $0xE0000000, R0; \
|
||||||
|
MOVW $n, R1; \
|
||||||
|
MOVW R1, (R0);
|
||||||
|
|
||||||
|
#define LDREX(a,r) WORD $(0xe<<28|0x01900f9f | (a)<<16 | (r)<<12)
|
||||||
|
#define STREX(a,v,r) WORD $(0xe<<28|0x01800f90 | (a)<<16 | (r)<<12 | (v)<<0)
|
||||||
|
#define CLREX WORD $0xf57ff01f
|
||||||
|
|
||||||
|
#define BARRIERS\
|
||||||
|
MOVW $0, R11; \
|
||||||
|
MCR CpSC, 0, R11, C(CpCACHE), C(CpCACHEinvi), CpCACHEflushbtc; \
|
||||||
|
DSB; \
|
||||||
|
ISB;
|
117
sys/src/9/omap4/clock.c
Normal file
117
sys/src/9/omap4/clock.c
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
#include "u.h"
|
||||||
|
#include "ureg.h"
|
||||||
|
#include "../port/lib.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
extern uchar *periph;
|
||||||
|
ulong *global, *local;
|
||||||
|
enum { PERIPHCLK = 506965000 } ;
|
||||||
|
|
||||||
|
void
|
||||||
|
globalclockinit(void)
|
||||||
|
{
|
||||||
|
global = (ulong*) (periph + 0x200);
|
||||||
|
local = (ulong*) (periph + 0x600);
|
||||||
|
global[2] &= 0xFFFF00F0;
|
||||||
|
global[0] = 0;
|
||||||
|
global[1] = 0;
|
||||||
|
global[2] |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cycles(uvlong *x)
|
||||||
|
{
|
||||||
|
ulong hi, newhi, lo, *y;
|
||||||
|
|
||||||
|
newhi = global[1];
|
||||||
|
do{
|
||||||
|
hi = newhi;
|
||||||
|
lo = global[0];
|
||||||
|
}while((newhi = global[1]) != hi);
|
||||||
|
y = (ulong *) x;
|
||||||
|
y[0] = lo;
|
||||||
|
y[1] = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
uvlong
|
||||||
|
fastticks(uvlong *hz)
|
||||||
|
{
|
||||||
|
uvlong ret;
|
||||||
|
|
||||||
|
if(hz != nil)
|
||||||
|
*hz = PERIPHCLK;
|
||||||
|
cycles(&ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong
|
||||||
|
µs(void)
|
||||||
|
{
|
||||||
|
return fastticks2us(fastticks(nil));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ulong
|
||||||
|
perfticks(void)
|
||||||
|
{
|
||||||
|
return global[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
intenable(29, clocktick);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
timerset(uvlong val)
|
||||||
|
{
|
||||||
|
uvlong now, ticks;
|
||||||
|
|
||||||
|
cycles(&now);
|
||||||
|
ticks = (val - now) * (PERIPHCLK / 256) / 1000000000;
|
||||||
|
if(ticks == 0)
|
||||||
|
ticks++;
|
||||||
|
local[2] &= ~1;
|
||||||
|
local[0] = local[1] = ticks;
|
||||||
|
local[2] |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
waituntil(uvlong n)
|
||||||
|
{
|
||||||
|
uvlong now, then;
|
||||||
|
|
||||||
|
cycles(&now);
|
||||||
|
then = now + n;
|
||||||
|
while(now < then)
|
||||||
|
cycles(&now);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
microdelay(int n)
|
||||||
|
{
|
||||||
|
waituntil(((uvlong)n) * PERIPHCLK / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
delay(int n)
|
||||||
|
{
|
||||||
|
waituntil(((uvlong)n) * PERIPHCLK / 1000);
|
||||||
|
}
|
||||||
|
|
144
sys/src/9/omap4/dat.h
Normal file
144
sys/src/9/omap4/dat.h
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
typedef struct Lock Lock;
|
||||||
|
typedef struct Label Label;
|
||||||
|
typedef struct Ureg Ureg;
|
||||||
|
typedef struct Mach Mach;
|
||||||
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct Notsave Notsave;
|
||||||
|
typedef struct PMMU PMMU;
|
||||||
|
typedef struct Confmem Confmem;
|
||||||
|
typedef struct Conf Conf;
|
||||||
|
typedef struct Proc Proc;
|
||||||
|
typedef uvlong Tval;
|
||||||
|
typedef void KMap;
|
||||||
|
#define VA(k) ((uintptr)(k))
|
||||||
|
#define kmap(p) (KMap*)((p)->pa|kseg0)
|
||||||
|
#define kunmap(k)
|
||||||
|
|
||||||
|
#pragma incomplete Ureg
|
||||||
|
|
||||||
|
struct Lock
|
||||||
|
{
|
||||||
|
ulong key;
|
||||||
|
u32int sr;
|
||||||
|
uintptr pc;
|
||||||
|
Proc* p;
|
||||||
|
Mach* m;
|
||||||
|
int isilock;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Label
|
||||||
|
{
|
||||||
|
ulong sp;
|
||||||
|
ulong pc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FPsave
|
||||||
|
{
|
||||||
|
ulong status;
|
||||||
|
ulong control;
|
||||||
|
ulong regs[8][3];
|
||||||
|
int fpstate;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FPinit,
|
||||||
|
FPactive,
|
||||||
|
FPinactive,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Notsave
|
||||||
|
{
|
||||||
|
int emptiness;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PMMU
|
||||||
|
{
|
||||||
|
ulong l1[USTKTOP / MiB];
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "../port/portdat.h"
|
||||||
|
|
||||||
|
struct Mach
|
||||||
|
{
|
||||||
|
int machno; /* physical id of processor */
|
||||||
|
uintptr splpc; /* pc of last caller to splhi */
|
||||||
|
|
||||||
|
Proc* proc; /* current process */
|
||||||
|
Proc* externup;
|
||||||
|
|
||||||
|
int flushmmu; /* flush current proc mmu state */
|
||||||
|
|
||||||
|
ulong ticks; /* of the clock since boot time */
|
||||||
|
Label sched; /* scheduler wakeup */
|
||||||
|
Lock alarmlock; /* access to alarm list */
|
||||||
|
void* alarm; /* alarms bound to this clock */
|
||||||
|
int inclockintr;
|
||||||
|
|
||||||
|
Proc* readied; /* for runproc */
|
||||||
|
ulong schedticks; /* next forced context switch */
|
||||||
|
|
||||||
|
int cputype;
|
||||||
|
ulong delayloop;
|
||||||
|
|
||||||
|
/* stats */
|
||||||
|
int tlbfault;
|
||||||
|
int tlbpurge;
|
||||||
|
int pfault;
|
||||||
|
int cs;
|
||||||
|
int syscall;
|
||||||
|
int load;
|
||||||
|
int intr;
|
||||||
|
uvlong fastclock; /* last sampled value */
|
||||||
|
uvlong inidle; /* time spent in idlehands() */
|
||||||
|
ulong spuriousintr;
|
||||||
|
int lastintr;
|
||||||
|
int ilockdepth;
|
||||||
|
Perf perf;
|
||||||
|
uvlong cyclefreq; /* Frequency of user readable cycle counter */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Confmem
|
||||||
|
{
|
||||||
|
uintptr base;
|
||||||
|
usize npage;
|
||||||
|
uintptr limit;
|
||||||
|
uintptr kbase;
|
||||||
|
uintptr klimit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Conf
|
||||||
|
{
|
||||||
|
ulong nmach; /* processors */
|
||||||
|
ulong nproc; /* processes */
|
||||||
|
Confmem mem[1]; /* physical memory */
|
||||||
|
ulong npage; /* total physical pages of memory */
|
||||||
|
usize upages; /* user page pool */
|
||||||
|
ulong copymode; /* 0 is copy on write, 1 is copy on reference */
|
||||||
|
ulong ialloc; /* max interrupt time allocation in bytes */
|
||||||
|
ulong pipeqsize; /* size in bytes of pipe queues */
|
||||||
|
ulong nimage; /* number of page cache image headers */
|
||||||
|
ulong nswap; /* number of swap pages */
|
||||||
|
int nswppo; /* max # of pageouts per segment pass */
|
||||||
|
ulong hz; /* processor cycle freq */
|
||||||
|
ulong mhz;
|
||||||
|
int monitor; /* flag */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Lock;
|
||||||
|
int machs; /* bitmap of active CPUs */
|
||||||
|
int exiting; /* shutdown */
|
||||||
|
int ispanic; /* shutdown in response to a panic */
|
||||||
|
}active;
|
||||||
|
|
||||||
|
extern Mach *m;
|
||||||
|
#define up (((Mach*)MACHADDR)->externup)
|
||||||
|
extern Mach* machaddr[MAXMACH];
|
||||||
|
#define MACHP(n) (machaddr[n])
|
||||||
|
extern uintptr kseg0;
|
||||||
|
|
||||||
|
#define AOUT_MAGIC (E_MAGIC)
|
||||||
|
#define NCOLOR 1
|
34
sys/src/9/omap4/fns.h
Normal file
34
sys/src/9/omap4/fns.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include "../port/portfns.h"
|
||||||
|
|
||||||
|
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
|
||||||
|
#define getpgcolor(x) 0
|
||||||
|
#define kmapinval()
|
||||||
|
#define checkmmu(a,b)
|
||||||
|
|
||||||
|
extern void procsave(Proc *);
|
||||||
|
extern void procrestore(Proc *);
|
||||||
|
extern void idlehands(void);
|
||||||
|
extern void coherence(void);
|
||||||
|
extern int tas(void*);
|
||||||
|
extern int cmpswap(long*, long, long);
|
||||||
|
extern void evenaddr(uintptr);
|
||||||
|
extern void procsetup(Proc*);
|
||||||
|
extern void procfork(Proc*);
|
||||||
|
extern uintptr cankaddr(uintptr);
|
||||||
|
extern void* KADDR(ulong);
|
||||||
|
extern ulong paddr(void *);
|
||||||
|
extern void cycles(uvlong *);
|
||||||
|
#define PADDR(x) paddr((void*)(x))
|
||||||
|
|
||||||
|
void mmuinit(void);
|
||||||
|
void flushtlb(void);
|
||||||
|
void trapinit(void);
|
||||||
|
void* vmap(ulong, ulong);
|
||||||
|
void vunmap(void*, ulong);
|
||||||
|
void printureg(Ureg*);
|
||||||
|
void fillureguser(Ureg*);
|
||||||
|
void touser(Ureg*);
|
||||||
|
void links(void);
|
||||||
|
void globalclockinit(void);
|
||||||
|
void localclockinit(void);
|
||||||
|
void intenable(int, void(*)(Ureg*));
|
25
sys/src/9/omap4/init9.s
Normal file
25
sys/src/9/omap4/init9.s
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* This is the same as the C programme:
|
||||||
|
*
|
||||||
|
* void
|
||||||
|
* main(char* argv0)
|
||||||
|
* {
|
||||||
|
* startboot(argv0, &argv0);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* It is in assembler because SB needs to be
|
||||||
|
* set and doing this in C drags in too many
|
||||||
|
* other routines.
|
||||||
|
*/
|
||||||
|
TEXT main(SB), 1, $8
|
||||||
|
MOVW $setR12(SB), R12 /* load the SB */
|
||||||
|
MOVW $boot(SB), R0
|
||||||
|
|
||||||
|
ADD $12, R13, R1 /* pointer to 0(FP) */
|
||||||
|
|
||||||
|
MOVW R0, 4(R13) /* pass argc, argv */
|
||||||
|
MOVW R1, 8(R13)
|
||||||
|
|
||||||
|
BL startboot(SB)
|
||||||
|
_loop:
|
||||||
|
B _loop
|
0
sys/src/9/omap4/io.h
Normal file
0
sys/src/9/omap4/io.h
Normal file
298
sys/src/9/omap4/l.s
Normal file
298
sys/src/9/omap4/l.s
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
#include "arm.s"
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
TEXT _start(SB), 1, $-4
|
||||||
|
MOVW $setR12(SB), R12
|
||||||
|
ADD $(PHYSDRAM - KZERO), R12
|
||||||
|
|
||||||
|
MOVW $(PsrDirq | PsrDfiq | PsrMsvc), CPSR
|
||||||
|
|
||||||
|
MOVW $0x48020014, R1
|
||||||
|
uartloop:
|
||||||
|
MOVW (R1), R0
|
||||||
|
AND.S $(1<<6), R0
|
||||||
|
B.EQ uartloop
|
||||||
|
|
||||||
|
EWAVE('\r')
|
||||||
|
EWAVE('\n')
|
||||||
|
|
||||||
|
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||||
|
BIC $(CpCmmu), R1
|
||||||
|
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||||
|
|
||||||
|
EWAVE('P')
|
||||||
|
|
||||||
|
MOVW $KZERO, R1
|
||||||
|
MOVW $(PHYSDRAM|PTEDRAM), R2
|
||||||
|
MOVW $256, R3
|
||||||
|
BL _mapmbs(SB)
|
||||||
|
MOVW $PHYSDRAM, R1
|
||||||
|
MOVW $(PHYSDRAM|PTEDRAM), R2
|
||||||
|
MOVW $256, R3
|
||||||
|
BL _mapmbs(SB)
|
||||||
|
MOVW $0x48000000, R1
|
||||||
|
MOVW $(0x48000000| L1AP(Krw) | Section | PTEIO), R2
|
||||||
|
MOVW $1, R3
|
||||||
|
BL _mapmbs(SB)
|
||||||
|
|
||||||
|
EWAVE('l')
|
||||||
|
|
||||||
|
MOVW $L1PT, R1
|
||||||
|
MCR CpSC, 0, R1, C(CpTTB), C(0), CpTTB0
|
||||||
|
MCR CpSC, 0, R1, C(CpTTB), C(0), CpTTB1
|
||||||
|
|
||||||
|
EWAVE('a')
|
||||||
|
|
||||||
|
MOVW $Client, R1
|
||||||
|
MCR CpSC, 0, R1, C(CpDAC), C(0)
|
||||||
|
MOVW $0, R1
|
||||||
|
MCR CpSC, 0, R1, C(CpPID), C(0x0)
|
||||||
|
|
||||||
|
EWAVE('n')
|
||||||
|
|
||||||
|
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||||
|
ORR $(CpCmmu|CpChv|CpCsw), R1
|
||||||
|
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||||
|
|
||||||
|
EWAVE(' ')
|
||||||
|
|
||||||
|
BL _jumphi(SB)
|
||||||
|
|
||||||
|
EWAVE('9')
|
||||||
|
|
||||||
|
MOVW $setR12(SB), R12
|
||||||
|
MOVW $KTZERO, R13
|
||||||
|
|
||||||
|
EWAVE(' ')
|
||||||
|
|
||||||
|
BL main(SB)
|
||||||
|
a:
|
||||||
|
WFI
|
||||||
|
B a
|
||||||
|
BL _div(SB) /* hack */
|
||||||
|
|
||||||
|
/* R1: virtual start, R2: physical start, R3: number of MB */
|
||||||
|
TEXT _mapmbs(SB), 1, $-4
|
||||||
|
MOVW $L1PT, R11
|
||||||
|
ADD R1>>18, R11, R1
|
||||||
|
mapmbsl:
|
||||||
|
MOVW.P R2, 4(R1)
|
||||||
|
ADD $MiB, R2
|
||||||
|
SUB.S $1, R3
|
||||||
|
B.NE mapmbsl
|
||||||
|
MOVW R14, PC
|
||||||
|
|
||||||
|
TEXT _jumphi(SB), 1, $-4
|
||||||
|
ADD $(KZERO - PHYSDRAM), R14
|
||||||
|
MOVW R14, PC
|
||||||
|
|
||||||
|
TEXT coherence(SB), 1, $-4
|
||||||
|
BARRIERS
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT splhi(SB), 1, $-4
|
||||||
|
MOVW CPSR, R0
|
||||||
|
CPSID
|
||||||
|
MOVW $(MACHADDR + 4), R11
|
||||||
|
MOVW R14, (R11)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT spllo(SB), 1, $-4
|
||||||
|
MOVW CPSR, R0
|
||||||
|
CPSIE
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT splx(SB), 1, $-4
|
||||||
|
MOVW CPSR, R1
|
||||||
|
MOVW R0, CPSR
|
||||||
|
MOVW R1, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT islo(SB), 1, $-4
|
||||||
|
MOVW CPSR, R0
|
||||||
|
AND $PsrDirq, R0
|
||||||
|
EOR $PsrDirq, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT tas(SB), $-4
|
||||||
|
spintas:
|
||||||
|
LDREX(0,1)
|
||||||
|
CMP.S $0, R1
|
||||||
|
B.NE tasnope
|
||||||
|
MOVW $1, R3
|
||||||
|
STREX(0,3,2)
|
||||||
|
CMP.S $0, R2
|
||||||
|
B.NE spintas
|
||||||
|
tasnope:
|
||||||
|
CLREX
|
||||||
|
MOVW R1, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT cmpswap(SB), $-4
|
||||||
|
MOVW 4(FP), R3
|
||||||
|
MOVW 8(FP), R4
|
||||||
|
casspin:
|
||||||
|
LDREX(0,1)
|
||||||
|
CMP.S R3, R1
|
||||||
|
B.NE casfail
|
||||||
|
STREX(0,1,2)
|
||||||
|
CMP.S $0, R2
|
||||||
|
B.NE casspin
|
||||||
|
MOVW $1, R0
|
||||||
|
RET
|
||||||
|
casfail:
|
||||||
|
CLREX
|
||||||
|
MOVW $0, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ainc(SB), $-4
|
||||||
|
TEXT _xinc(SB), $-4
|
||||||
|
spinainc:
|
||||||
|
LDREX(0,1)
|
||||||
|
ADD $1, R1
|
||||||
|
STREX(0,1,2)
|
||||||
|
CMP.S $0, R2
|
||||||
|
B.NE spinainc
|
||||||
|
MOVW R1, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT adec(SB), $-4
|
||||||
|
TEXT _xdec(SB), $-4
|
||||||
|
spinadec:
|
||||||
|
LDREX(0,1)
|
||||||
|
SUB $1, R1
|
||||||
|
STREX(0,1,2)
|
||||||
|
CMP.S $0, R2
|
||||||
|
B.NE spinadec
|
||||||
|
MOVW R1, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT setlabel(SB), 1, $-4
|
||||||
|
MOVW R13, 0(R0)
|
||||||
|
MOVW R14, 4(R0)
|
||||||
|
MOVW $0, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT gotolabel(SB), 1, $-4
|
||||||
|
MOVW 0(R0), R13
|
||||||
|
MOVW 4(R0), R14
|
||||||
|
MOVW $1, R0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT idlehands(SB), 1, $-4
|
||||||
|
BARRIERS
|
||||||
|
WFI
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT flushtlb(SB), $-4
|
||||||
|
BARRIERS
|
||||||
|
MCR CpSC, 0, R1, C(8), C(7), 0
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define TRAP(n,a)\
|
||||||
|
SUB $n, R14;\
|
||||||
|
WORD $0xf96d0513;\
|
||||||
|
WORD $0xf10e0093;\
|
||||||
|
MOVW R14, -8(R13);\
|
||||||
|
MOVW $a, R14;\
|
||||||
|
MOVW R14, -4(R13);\
|
||||||
|
B _trap(SB)
|
||||||
|
|
||||||
|
TEXT _reset(SB), 1, $-4
|
||||||
|
TRAP(4, 0)
|
||||||
|
TEXT _undefined(SB), 1, $-4
|
||||||
|
TRAP(4, 1)
|
||||||
|
TEXT _prefabort(SB), 1, $-4
|
||||||
|
TRAP(4, 3)
|
||||||
|
TEXT _dataabort(SB), 1, $-4
|
||||||
|
TRAP(8, 4)
|
||||||
|
TEXT _wtftrap(SB), 1, $-4
|
||||||
|
TRAP(4, 5)
|
||||||
|
TEXT _irq(SB), 1, $-4
|
||||||
|
TRAP(4, 6)
|
||||||
|
TEXT _fiq(SB), 1, $-4
|
||||||
|
TRAP(4, 7)
|
||||||
|
|
||||||
|
TEXT _trap(SB), 1, $-4
|
||||||
|
SUB $64, R13
|
||||||
|
MOVM.IA [R0-R12], (R13)
|
||||||
|
MOVW $setR12(SB), R12
|
||||||
|
MOVW 64(R13), R0
|
||||||
|
MOVW 68(R13), R1
|
||||||
|
MOVW R0, 68(R13)
|
||||||
|
MOVW R1, 64(R13)
|
||||||
|
ADD $72, R13, R0
|
||||||
|
MOVW R0, 52(R13)
|
||||||
|
MOVW R13, R0
|
||||||
|
SUB $8, R13
|
||||||
|
BL trap(SB)
|
||||||
|
ADD $8, R13
|
||||||
|
MOVW 64(R13), R0
|
||||||
|
AND $PsrMask, R0
|
||||||
|
CMP $PsrMusr, R0
|
||||||
|
MOVW.EQ R13, R0
|
||||||
|
B.EQ gotouser
|
||||||
|
MOVW 68(R13), R0
|
||||||
|
MOVW R0, 60(R13)
|
||||||
|
MOVW 64(R13), R0
|
||||||
|
MOVW R0, SPSR
|
||||||
|
MOVW R13, R0
|
||||||
|
ADD $72, R13
|
||||||
|
WORD $0xE8D0FFFF
|
||||||
|
|
||||||
|
TEXT _syscall(SB), 1, $-4
|
||||||
|
WORD $0xf96d0513
|
||||||
|
WORD $0xf10e0093
|
||||||
|
SUB $64, R13
|
||||||
|
MOVM.IA.S [R0-R14], (R13)
|
||||||
|
MOVW $setR12(SB), R12
|
||||||
|
MOVW 64(R13), R0
|
||||||
|
MOVW 68(R13), R1
|
||||||
|
MOVW R0, 68(R13)
|
||||||
|
MOVW R1, 64(R13)
|
||||||
|
MOVW R13, R0
|
||||||
|
SUB $8, R13
|
||||||
|
BL syscall(SB)
|
||||||
|
|
||||||
|
TEXT forkret(SB), 1, $-4
|
||||||
|
ADD $8, R13
|
||||||
|
MOVW R13, R0
|
||||||
|
|
||||||
|
TEXT touser(SB), 1, $-4
|
||||||
|
gotouser:
|
||||||
|
ADD $52, R0
|
||||||
|
MOVM.IA.S (R0), [R13-R14]
|
||||||
|
SUB $52, R0
|
||||||
|
MOVW 68(R0), R1
|
||||||
|
MOVW R1, 52(R0)
|
||||||
|
MOVW 64(R0), R1
|
||||||
|
MOVW R1, SPSR
|
||||||
|
WORD $0xE8D09FFF
|
||||||
|
|
||||||
|
TEXT fillureguser(SB), $-4
|
||||||
|
ADD $52, R0
|
||||||
|
MOVM.IA.S [R13-R14], (R0)
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
TEXT dumpstack(SB), 0, $8
|
||||||
|
MOVW R14, 8(R13)
|
||||||
|
ADD $12, R13, R0
|
||||||
|
BL _dumpstack(SB)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT getdfsr(SB), 0, $-4
|
||||||
|
MRC CpSC, 0, R0, C(5), C(0), 0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT getifsr(SB), 0, $-4
|
||||||
|
MRC CpSC, 0, R0, C(5), C(0), 1
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT getdfar(SB), 0, $-4
|
||||||
|
MRC CpSC, 0, R0, C(6), C(0), 0
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT getifar(SB), 0, $-4
|
||||||
|
MRC CpSC, 0, R0, C(6), C(0), 2
|
||||||
|
RET
|
194
sys/src/9/omap4/main.c
Normal file
194
sys/src/9/omap4/main.c
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
#include "u.h"
|
||||||
|
#include "ureg.h"
|
||||||
|
#include "../port/lib.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "tos.h"
|
||||||
|
#include "arm.h"
|
||||||
|
|
||||||
|
ulong *uart = (ulong *) 0x48020000;
|
||||||
|
#define wave(x) (*uart = (char) (x))
|
||||||
|
uintptr kseg0 = KZERO;
|
||||||
|
uchar *sp;
|
||||||
|
|
||||||
|
Mach *m;
|
||||||
|
Mach *machaddr[MAXMACH];
|
||||||
|
Conf conf;
|
||||||
|
|
||||||
|
void
|
||||||
|
machinit(void)
|
||||||
|
{
|
||||||
|
machaddr[0] = m = KADDR(FIRSTMACH);
|
||||||
|
memset(m, 0, sizeof(Mach));
|
||||||
|
active.machs = conf.nmach = 1;
|
||||||
|
active.exiting = 0;
|
||||||
|
up = nil;
|
||||||
|
|
||||||
|
conf.mem[0].base = ROUNDUP(PADDR(end), BY2PG);
|
||||||
|
conf.mem[0].limit = ROUNDDN(PHYSDRAM + DRAMSIZ, BY2PG);
|
||||||
|
conf.mem[0].npage = (conf.mem[0].limit - conf.mem[0].base) / BY2PG;
|
||||||
|
conf.npage = conf.mem[0].npage;
|
||||||
|
conf.upages = conf.npage - 64 * MiB / BY2PG;
|
||||||
|
conf.nproc = 100;
|
||||||
|
conf.pipeqsize = 32768;
|
||||||
|
conf.nimage = 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init0(void)
|
||||||
|
{
|
||||||
|
Ureg ureg;
|
||||||
|
|
||||||
|
spllo();
|
||||||
|
up->nerrlab = 0;
|
||||||
|
up->slash = namec("#/", Atodir, 0, 0);
|
||||||
|
pathclose(up->slash->path);
|
||||||
|
up->slash->path = newpath("/");
|
||||||
|
up->dot = cclone(up->slash);
|
||||||
|
chandevinit();
|
||||||
|
if(!waserror()){
|
||||||
|
ksetenv("terminal", "generic /sys/src/9/omap4/panda", 0);
|
||||||
|
ksetenv("cputype", "arm", 0);
|
||||||
|
ksetenv("service", "cpu", 0);
|
||||||
|
poperror();
|
||||||
|
}
|
||||||
|
kproc("alarm", alarmkproc, 0);
|
||||||
|
memset(&ureg, 0, sizeof ureg);
|
||||||
|
ureg.pc = UTZERO + 32;
|
||||||
|
ureg.r13 = (ulong) sp;
|
||||||
|
ureg.psr = PsrMusr;
|
||||||
|
touser(&ureg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uchar *
|
||||||
|
pusharg(char *p)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = strlen(p) + 1;
|
||||||
|
sp -= n;
|
||||||
|
memmove(sp, p, n);
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bootargs(void *base)
|
||||||
|
{
|
||||||
|
int ac, i;
|
||||||
|
uchar *av[32], **lsp;
|
||||||
|
sp = (uchar*)base + BY2PG - sizeof(Tos);
|
||||||
|
|
||||||
|
ac = 0;
|
||||||
|
av[ac++] = pusharg("boot");
|
||||||
|
sp = (uchar *) ROUNDDN((ulong)sp, 4);
|
||||||
|
sp -= (ac + 1) * 4;
|
||||||
|
lsp = (uchar **) sp;
|
||||||
|
for(i = 0; i < ac; i++)
|
||||||
|
lsp[i] = av[i] + ((USTKTOP - BY2PG) - (ulong) base);
|
||||||
|
lsp[i] = 0;
|
||||||
|
sp += (USTKTOP - BY2PG) - (ulong)base;
|
||||||
|
sp -= BY2WD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
userinit(void)
|
||||||
|
{
|
||||||
|
Proc *p;
|
||||||
|
Segment *s;
|
||||||
|
Page *pg;
|
||||||
|
void *v;
|
||||||
|
|
||||||
|
p = newproc();
|
||||||
|
p->pgrp = newpgrp();
|
||||||
|
p->egrp = smalloc(sizeof(Egrp));
|
||||||
|
p->egrp->ref = 1;
|
||||||
|
p->fgrp = dupfgrp(nil);
|
||||||
|
p->rgrp = newrgrp();
|
||||||
|
p->procmode = 0640;
|
||||||
|
|
||||||
|
kstrdup(&eve, "");
|
||||||
|
kstrdup(&p->text, "*init*");
|
||||||
|
kstrdup(&p->user, eve);
|
||||||
|
|
||||||
|
procsetup(p);
|
||||||
|
|
||||||
|
p->sched.pc = (ulong)init0;
|
||||||
|
p->sched.sp = (ulong)p->kstack + KSTACK - sizeof(Sargs) - BY2WD;
|
||||||
|
|
||||||
|
s = newseg(SG_STACK, USTKTOP - USTKSIZE, USTKSIZE / BY2PG);
|
||||||
|
p->seg[SSEG] = s;
|
||||||
|
pg = newpage(0, 0, USTKTOP - BY2PG);
|
||||||
|
v = vmap(pg->pa, BY2PG);
|
||||||
|
memset(v, 0, BY2PG);
|
||||||
|
segpage(s, pg);
|
||||||
|
bootargs(v);
|
||||||
|
vunmap(v, BY2PG);
|
||||||
|
|
||||||
|
s = newseg(SG_TEXT, UTZERO, 1);
|
||||||
|
s->flushme++;
|
||||||
|
p->seg[TSEG] = s;
|
||||||
|
pg = newpage(0, 0, UTZERO);
|
||||||
|
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
|
||||||
|
segpage(s, pg);
|
||||||
|
v = vmap(pg->pa, BY2PG);
|
||||||
|
memset(v, 0, BY2PG);
|
||||||
|
memmove(v, initcode, sizeof initcode);
|
||||||
|
vunmap(v, BY2PG);
|
||||||
|
|
||||||
|
ready(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
extern int chandebug;
|
||||||
|
|
||||||
|
wave('f');
|
||||||
|
memset(edata, 0, end - edata);
|
||||||
|
wave('r');
|
||||||
|
machinit();
|
||||||
|
wave('o');
|
||||||
|
mmuinit();
|
||||||
|
wave('m');
|
||||||
|
trapinit();
|
||||||
|
print(" Bell Labs\n");
|
||||||
|
xinit();
|
||||||
|
globalclockinit();
|
||||||
|
localclockinit();
|
||||||
|
timersinit();
|
||||||
|
procinit0();
|
||||||
|
pageinit();
|
||||||
|
swapinit();
|
||||||
|
initseg();
|
||||||
|
quotefmtinstall();
|
||||||
|
chandevreset();
|
||||||
|
links();
|
||||||
|
chandebug++;
|
||||||
|
userinit();
|
||||||
|
schedinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
exit(int)
|
||||||
|
{
|
||||||
|
uartputs("resting\n", 9);
|
||||||
|
splhi();
|
||||||
|
while(1)
|
||||||
|
idlehands();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reboot()
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rdb()
|
||||||
|
{
|
||||||
|
panic("rdb");
|
||||||
|
}
|
||||||
|
|
65
sys/src/9/omap4/mem.h
Normal file
65
sys/src/9/omap4/mem.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#define KiB 1024u /* Kibi 0x0000000000000400 */
|
||||||
|
#define MiB 1048576u /* Mebi 0x0000000000100000 */
|
||||||
|
#define GiB 1073741824u /* Gibi 000000000040000000 */
|
||||||
|
|
||||||
|
#define HOWMANY(x, y) (((x)+((y)-1))/(y))
|
||||||
|
#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y)) /* ceiling */
|
||||||
|
#define ROUNDDN(x, y) (((x)/(y))*(y)) /* floor */
|
||||||
|
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||||
|
#define MAX(a, b) ((a) > (b)? (a): (b))
|
||||||
|
#define PGROUND(s) ROUNDUP(s, BY2PG)
|
||||||
|
#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1))
|
||||||
|
#define PPN(x) ((x)&~(BY2PG-1))
|
||||||
|
#define F(v, o, w) (((v) & ((1<<(w))-1))<<(o))
|
||||||
|
|
||||||
|
#define FMASK(o, w) (((1<<(w))-1)<<(o))
|
||||||
|
|
||||||
|
#define KZERO 0xF0000000
|
||||||
|
#define KTZERO 0xF2000000
|
||||||
|
#define VECTORS 0xFFFF0000
|
||||||
|
#define MACHADDR 0xFFFF1000
|
||||||
|
|
||||||
|
#define UZERO 0
|
||||||
|
#define UTZERO BY2PG
|
||||||
|
#define USTKTOP 0xE0000000
|
||||||
|
|
||||||
|
/* we map MMIO somewhere here */
|
||||||
|
#define IZERO 0xE0000000
|
||||||
|
#define NIOPAGES ROUNDDN((KZERO - IZERO) / BY2PG, 256)
|
||||||
|
|
||||||
|
#define KSTKSIZ (16*KiB)
|
||||||
|
#define KSTACK KSTKSIZ
|
||||||
|
#define TSTKSIZ 256
|
||||||
|
#define USTKSIZE (8*MiB)
|
||||||
|
#define TSTKTOP (USTKTOP - USTKSIZE)
|
||||||
|
#define HZ 100
|
||||||
|
|
||||||
|
#define MAXSYSARG 7
|
||||||
|
#define MAXMACH 2
|
||||||
|
|
||||||
|
#define BY2WD 4
|
||||||
|
#define BY2V 8
|
||||||
|
#define BY2PG 4096
|
||||||
|
#define PGSHIFT 12
|
||||||
|
#define PTEMAPMEM 1048576
|
||||||
|
#define PTEPERTAB (PTEMAPMEM/BY2PG)
|
||||||
|
#define SEGMAPSIZE 1984
|
||||||
|
#define SSEGMAPSIZE 16
|
||||||
|
#define BLOCKALIGN 32
|
||||||
|
|
||||||
|
#define PTEVALID (1<<0)
|
||||||
|
#define PTERONLY 0
|
||||||
|
#define PTEWRITE (1<<1)
|
||||||
|
#define PTEUNCACHED (1<<2)
|
||||||
|
#define PTEKERNEL (1<<3)
|
||||||
|
|
||||||
|
#define PHYSDRAM 0x80000000
|
||||||
|
#define DRAMSIZ (1024 * MiB)
|
||||||
|
|
||||||
|
#define L1PT PHYSDRAM
|
||||||
|
#define L1SIZ (16 * KiB)
|
||||||
|
#define IOPT (L1PT + L1SIZ)
|
||||||
|
#define L2SIZ (1 * KiB)
|
||||||
|
#define PRIVL2 (IOPT + L2SIZ * (NIOPAGES / 256))
|
||||||
|
#define PHYSVECTORS ROUNDUP(PRIVL2 + L2SIZ, BY2PG)
|
||||||
|
#define FIRSTMACH (PHYSVECTORS + BY2PG)
|
101
sys/src/9/omap4/mkfile
Normal file
101
sys/src/9/omap4/mkfile
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
CONF=panda
|
||||||
|
CONFLIST=panda
|
||||||
|
|
||||||
|
loadaddr=0xF2000000
|
||||||
|
|
||||||
|
objtype=arm
|
||||||
|
</$objtype/mkfile
|
||||||
|
p=9
|
||||||
|
|
||||||
|
DEVS=`{rc ../port/mkdevlist $CONF}
|
||||||
|
|
||||||
|
PORT=\
|
||||||
|
alarm.$O\
|
||||||
|
alloc.$O\
|
||||||
|
allocb.$O\
|
||||||
|
auth.$O\
|
||||||
|
cache.$O\
|
||||||
|
chan.$O\
|
||||||
|
dev.$O\
|
||||||
|
edf.$O\
|
||||||
|
fault.$O\
|
||||||
|
mul64fract.$O\
|
||||||
|
rebootcmd.$O\
|
||||||
|
page.$O\
|
||||||
|
parse.$O\
|
||||||
|
pgrp.$O\
|
||||||
|
portclock.$O\
|
||||||
|
print.$O\
|
||||||
|
proc.$O\
|
||||||
|
qio.$O\
|
||||||
|
qlock.$O\
|
||||||
|
segment.$O\
|
||||||
|
swap.$O\
|
||||||
|
sysfile.$O\
|
||||||
|
sysproc.$O\
|
||||||
|
taslock.$O\
|
||||||
|
tod.$O\
|
||||||
|
xalloc.$O\
|
||||||
|
|
||||||
|
OBJ=\
|
||||||
|
l.$O\
|
||||||
|
main.$O\
|
||||||
|
mmu.$O\
|
||||||
|
random.$O\
|
||||||
|
clock.$O\
|
||||||
|
arch.$O\
|
||||||
|
uart.$O\
|
||||||
|
trap.$O\
|
||||||
|
$CONF.root.$O\
|
||||||
|
$CONF.rootc.$O\
|
||||||
|
$DEVS\
|
||||||
|
$PORT\
|
||||||
|
|
||||||
|
LIB=\
|
||||||
|
/$objtype/lib/libmemlayer.a\
|
||||||
|
/$objtype/lib/libmemdraw.a\
|
||||||
|
/$objtype/lib/libdraw.a\
|
||||||
|
/$objtype/lib/libip.a\
|
||||||
|
/$objtype/lib/libsec.a\
|
||||||
|
/$objtype/lib/libmp.a\
|
||||||
|
/$objtype/lib/libc.a\
|
||||||
|
|
||||||
|
9:V: $p$CONF s$p$CONF
|
||||||
|
|
||||||
|
$p$CONF:DQ: $CONF.c $OBJ $LIB mkfile
|
||||||
|
$CC $CFLAGS '-DKERNDATE='`{date -n} $CONF.c
|
||||||
|
echo '# linking raw kernel'
|
||||||
|
$LD -o $target -H0 -P -R4096 -T$loadaddr -l $OBJ $CONF.$O $LIB
|
||||||
|
|
||||||
|
s$p$CONF:DQ: $CONF.$O $OBJ $LIB
|
||||||
|
echo '# linking kernel with symbols'
|
||||||
|
# $LD -o $target -R4096 -T$loadaddr -l -a $OBJ $CONF.$O $LIB >$target.list
|
||||||
|
$LD -o $target -R4096 -T$loadaddr -l $OBJ $CONF.$O $LIB
|
||||||
|
size $target
|
||||||
|
|
||||||
|
$p$CONF.gz:D: $p$CONF
|
||||||
|
gzip -9 <$p$CONF >$target
|
||||||
|
|
||||||
|
$OBJ: $HFILES
|
||||||
|
|
||||||
|
l.$O: arm.s
|
||||||
|
|
||||||
|
install:V: /$objtype/$p$CONF
|
||||||
|
|
||||||
|
/$objtype/$p$CONF:D: $p$CONF s$p$CONF
|
||||||
|
cp $p$CONF s$p$CONF /$objtype
|
||||||
|
|
||||||
|
<../boot/bootmkfile
|
||||||
|
<../port/portmkfile
|
||||||
|
<|../port/mkbootrules $CONF
|
||||||
|
|
||||||
|
CFLAGS= -I. -I../port $CFLAGS # hack to compile private sysproc.c (e.g.)
|
||||||
|
|
||||||
|
init.h:D: ../port/initcode.c init9.s
|
||||||
|
$CC ../port/initcode.c
|
||||||
|
$AS init9.s
|
||||||
|
$LD -l -R1 -s -o init.out init9.$O initcode.$O /$objtype/lib/libc.a
|
||||||
|
{echo 'uchar initcode[]={'
|
||||||
|
xd -1x <init.out |
|
||||||
|
sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
|
||||||
|
echo '};'} > init.h
|
237
sys/src/9/omap4/mmu.c
Normal file
237
sys/src/9/omap4/mmu.c
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
#include "u.h"
|
||||||
|
#include "../port/lib.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "arm.h"
|
||||||
|
|
||||||
|
char iopages[NIOPAGES / 8];
|
||||||
|
Lock iopagelock;
|
||||||
|
uchar *periph;
|
||||||
|
|
||||||
|
static int
|
||||||
|
isfree(int i)
|
||||||
|
{
|
||||||
|
return (iopages[i / 8] & (1 << (i % 8))) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
freeio(int i)
|
||||||
|
{
|
||||||
|
iopages[i / 8] &= ~(1 << (i % 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getiopages(int n)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
lock(&iopagelock);
|
||||||
|
for(i = 0; i <= NIOPAGES - n; i++){
|
||||||
|
for(j = 0; j < n; j++)
|
||||||
|
if(!isfree(i + j))
|
||||||
|
goto next;
|
||||||
|
for(j = 0; j < n; j++)
|
||||||
|
iopages[(i + j) / 8] |= (1 << ((i + j) % 8));
|
||||||
|
unlock(&iopagelock);
|
||||||
|
return i;
|
||||||
|
next: ;
|
||||||
|
}
|
||||||
|
panic("out of i/o pages");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
putiopages(int i, int n)
|
||||||
|
{
|
||||||
|
lock(&iopagelock);
|
||||||
|
while(n--)
|
||||||
|
freeio(i++);
|
||||||
|
unlock(&iopagelock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
vmap(ulong phys, ulong length)
|
||||||
|
{
|
||||||
|
ulong virt, off, *l2;
|
||||||
|
|
||||||
|
off = phys % BY2PG;
|
||||||
|
length = (ROUNDUP(phys + length, BY2PG) - ROUNDDN(phys, BY2PG)) / BY2PG;
|
||||||
|
if(length == 0)
|
||||||
|
return nil;
|
||||||
|
phys = ROUNDDN(phys, BY2PG);
|
||||||
|
virt = getiopages(length);
|
||||||
|
l2 = KADDR(IOPT);
|
||||||
|
l2 += virt;
|
||||||
|
while(length--){
|
||||||
|
*l2++ = phys | L2AP(Krw) | Small | PTEIO;
|
||||||
|
phys += BY2PG;
|
||||||
|
}
|
||||||
|
flushtlb();
|
||||||
|
return (void *) (IZERO + BY2PG * virt + off);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vunmap(void *virt, ulong length)
|
||||||
|
{
|
||||||
|
ulong v, *l2;
|
||||||
|
|
||||||
|
if((ulong)virt < IZERO || (ulong)virt >= IZERO + NIOPAGES * BY2PG)
|
||||||
|
panic("vunmap: virt=%p", virt);
|
||||||
|
v = (ROUNDDN((ulong) virt, BY2PG) - IZERO) / BY2PG;
|
||||||
|
length = (ROUNDUP(((ulong) virt) + length, BY2PG) - ROUNDDN((ulong) virt, BY2PG)) / BY2PG;
|
||||||
|
if(length == 0)
|
||||||
|
return;
|
||||||
|
l2 = KADDR(IOPT);
|
||||||
|
l2 += v;
|
||||||
|
lock(&iopagelock);
|
||||||
|
while(length--){
|
||||||
|
*l2++ = 0;
|
||||||
|
freeio(v++);
|
||||||
|
}
|
||||||
|
unlock(&iopagelock);
|
||||||
|
flushtlb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mmuinit(void)
|
||||||
|
{
|
||||||
|
ulong *l1, l2, *pl2;
|
||||||
|
int i, n;
|
||||||
|
extern ulong *uart;
|
||||||
|
|
||||||
|
l1 = KADDR(L1PT);
|
||||||
|
l2 = IOPT;
|
||||||
|
n = NIOPAGES / 256;
|
||||||
|
memset(KADDR(l2), 0, n * L2SIZ);
|
||||||
|
for(i = 0; i < n; i++){
|
||||||
|
l1[(IZERO / MiB) + i] = l2 | Coarse;
|
||||||
|
l2 += L2SIZ;
|
||||||
|
}
|
||||||
|
uart = vmap((ulong) uart, BY2PG);
|
||||||
|
memset(l1, 0, sizeof(ulong) * (IZERO / MiB));
|
||||||
|
l1[4095] = PRIVL2 | Coarse;
|
||||||
|
pl2 = KADDR(PRIVL2);
|
||||||
|
for(i = 0; i < 240; i++)
|
||||||
|
pl2[i] = (0x8FF00000 + i * BY2PG) | L2AP(Krw) | Small | Cached | Buffered;
|
||||||
|
pl2[240] = PHYSVECTORS | L2AP(Krw) | Small | Cached | Buffered;
|
||||||
|
pl2[241] = FIRSTMACH | L2AP(Krw) | Small | Cached | Buffered;
|
||||||
|
flushtlb();
|
||||||
|
m = (Mach *) MACHADDR;
|
||||||
|
periph = vmap(0x48240000, 2 * BY2PG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mmuswitch(Proc *p)
|
||||||
|
{
|
||||||
|
ulong *l1;
|
||||||
|
|
||||||
|
l1 = KADDR(L1PT);
|
||||||
|
memmove(l1, p->l1, sizeof p->l1);
|
||||||
|
flushtlb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putmmu(ulong va, ulong pa, Page *)
|
||||||
|
{
|
||||||
|
ulong *l1a, *l1b, *l2;
|
||||||
|
int l1o, l2o;
|
||||||
|
|
||||||
|
l1o = va / MiB;
|
||||||
|
l2o = (va % MiB) / BY2PG;
|
||||||
|
l1a = KADDR(L1PT);
|
||||||
|
l1b = up->l1;
|
||||||
|
if(l1a[l1o] == 0){
|
||||||
|
if((pa & PTEVALID) == 0)
|
||||||
|
return;
|
||||||
|
l2 = xspanalloc(L2SIZ, L2SIZ, 0);
|
||||||
|
l1a[l1o] = l1b[l1o] = PADDR(l2) | Coarse;
|
||||||
|
} else
|
||||||
|
l2 = KADDR(ROUNDDN(l1a[l1o], L2SIZ));
|
||||||
|
l2 += l2o;
|
||||||
|
if((pa & PTEVALID) == 0){
|
||||||
|
*l2 = 0;
|
||||||
|
flushtlb();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*l2 = ROUNDDN(pa, BY2PG) | Small;
|
||||||
|
if((pa & PTEWRITE) == 0)
|
||||||
|
*l2 |= L2AP(Uro);
|
||||||
|
else
|
||||||
|
*l2 |= L2AP(Urw);
|
||||||
|
if((pa & PTEUNCACHED) == 0)
|
||||||
|
*l2 |= Buffered | Cached;
|
||||||
|
flushtlb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
flushmmu(void)
|
||||||
|
{
|
||||||
|
int s, i;
|
||||||
|
ulong p;
|
||||||
|
ulong *l1;
|
||||||
|
|
||||||
|
l1 = KADDR(L1PT);
|
||||||
|
s = splhi();
|
||||||
|
for(i = 0; i < nelem(up->l1); i++){
|
||||||
|
p = l1[i];
|
||||||
|
if(p & Small)
|
||||||
|
free(KADDR(ROUNDDN(p, BY2PG)));
|
||||||
|
}
|
||||||
|
memset(up->l1, 0, sizeof up->l1);
|
||||||
|
memset(l1, 0, sizeof up->l1);
|
||||||
|
flushtlb();
|
||||||
|
splx(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mmurelease(Proc *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ulong pg;
|
||||||
|
|
||||||
|
if(p == up){
|
||||||
|
flushmmu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(i = 0; i < nelem(p->l1); i++){
|
||||||
|
pg = p->l1[i];
|
||||||
|
if(pg & Small)
|
||||||
|
free(KADDR(ROUNDDN(pg, BY2PG)));
|
||||||
|
}
|
||||||
|
memset(p->l1, 0, sizeof p->l1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
countpagerefs()
|
||||||
|
{
|
||||||
|
panic("countpagerefs");
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
KADDR(ulong pa)
|
||||||
|
{
|
||||||
|
if(pa < (ulong)PHYSDRAM || pa > (ulong)(PHYSDRAM + VECTORS - KZERO))
|
||||||
|
panic("kaddr: pa=%#.8lux, pc=%p", pa, getcallerpc(&pa));
|
||||||
|
return (void*)(pa + KZERO - PHYSDRAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong
|
||||||
|
paddr(void* v)
|
||||||
|
{
|
||||||
|
ulong va;
|
||||||
|
|
||||||
|
va = (ulong) v;
|
||||||
|
if(va < KZERO)
|
||||||
|
panic("paddr: v=%p", v);
|
||||||
|
return va - KZERO + PHYSDRAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong
|
||||||
|
cankaddr(ulong arg)
|
||||||
|
{
|
||||||
|
if(arg < PHYSDRAM || arg > (ulong)(PHYSDRAM + VECTORS - KZERO))
|
||||||
|
return 0;
|
||||||
|
return PHYSDRAM - KZERO - arg;
|
||||||
|
}
|
78
sys/src/9/omap4/panda
Normal file
78
sys/src/9/omap4/panda
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
# panda board
|
||||||
|
dev
|
||||||
|
root
|
||||||
|
cons
|
||||||
|
env
|
||||||
|
pipe
|
||||||
|
# proc
|
||||||
|
mnt
|
||||||
|
srv
|
||||||
|
shr
|
||||||
|
# dup
|
||||||
|
# arch
|
||||||
|
# ssl
|
||||||
|
# tls
|
||||||
|
# bridge log
|
||||||
|
# sdp thwack unthwack
|
||||||
|
# cap
|
||||||
|
# kprof
|
||||||
|
# aoe
|
||||||
|
# sd
|
||||||
|
# fs
|
||||||
|
# flash
|
||||||
|
|
||||||
|
# ether netif
|
||||||
|
# ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno
|
||||||
|
|
||||||
|
# draw screen
|
||||||
|
# dss
|
||||||
|
# mouse
|
||||||
|
|
||||||
|
# uart
|
||||||
|
# usb
|
||||||
|
|
||||||
|
link
|
||||||
|
# archoma
|
||||||
|
# ethermedium
|
||||||
|
# flashigep
|
||||||
|
# loopbackmedium
|
||||||
|
# netdevmedium
|
||||||
|
|
||||||
|
## avoid tickling errata 3.1.1.183
|
||||||
|
## usbohci
|
||||||
|
# usbehci usbehciomap
|
||||||
|
|
||||||
|
ip
|
||||||
|
# tcp
|
||||||
|
# udp
|
||||||
|
# ipifc
|
||||||
|
# icmp
|
||||||
|
# icmp6
|
||||||
|
# ipmux
|
||||||
|
# gre
|
||||||
|
# esp
|
||||||
|
|
||||||
|
misc
|
||||||
|
# rdb
|
||||||
|
# coproc
|
||||||
|
# dma
|
||||||
|
# mouse
|
||||||
|
# sdaoe sdscsi
|
||||||
|
# softfpu
|
||||||
|
# syscall
|
||||||
|
# uarti8250
|
||||||
|
# ucalloc
|
||||||
|
# ucallocb
|
||||||
|
|
||||||
|
port
|
||||||
|
int cpuserver = 1;
|
||||||
|
|
||||||
|
boot cpu
|
||||||
|
tcp
|
||||||
|
local
|
||||||
|
|
||||||
|
bootdir
|
||||||
|
boot$CONF.out boot
|
||||||
|
/$objtype/bin/paqfs
|
||||||
|
/$objtype/bin/auth/factotum
|
||||||
|
bootfs.paq
|
138
sys/src/9/omap4/random.c
Normal file
138
sys/src/9/omap4/random.c
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
#include "u.h"
|
||||||
|
#include "../port/lib.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "../port/error.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct Rb
|
||||||
|
{
|
||||||
|
QLock;
|
||||||
|
Rendez producer;
|
||||||
|
Rendez consumer;
|
||||||
|
ulong randomcount;
|
||||||
|
uchar buf[128];
|
||||||
|
uchar *ep;
|
||||||
|
uchar *rp;
|
||||||
|
uchar *wp;
|
||||||
|
uchar next;
|
||||||
|
uchar wakeme;
|
||||||
|
ushort bits;
|
||||||
|
ulong randn;
|
||||||
|
} rb;
|
||||||
|
|
||||||
|
static int
|
||||||
|
rbnotfull(void*)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = rb.rp - rb.wp;
|
||||||
|
return i != 1 && i != (1 - sizeof(rb.buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rbnotempty(void*)
|
||||||
|
{
|
||||||
|
return rb.wp != rb.rp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
genrandom(void*)
|
||||||
|
{
|
||||||
|
up->basepri = PriNormal;
|
||||||
|
up->priority = up->basepri;
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
for(;;)
|
||||||
|
if(++rb.randomcount > 100000)
|
||||||
|
break;
|
||||||
|
if(anyhigher())
|
||||||
|
sched();
|
||||||
|
if(!rbnotfull(0))
|
||||||
|
sleep(&rb.producer, rbnotfull, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* produce random bits in a circular buffer
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
randomclock(void)
|
||||||
|
{
|
||||||
|
if(rb.randomcount == 0 || !rbnotfull(0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
rb.bits = (rb.bits<<2) ^ rb.randomcount;
|
||||||
|
rb.randomcount = 0;
|
||||||
|
|
||||||
|
rb.next++;
|
||||||
|
if(rb.next != 8/2)
|
||||||
|
return;
|
||||||
|
rb.next = 0;
|
||||||
|
|
||||||
|
*rb.wp ^= rb.bits;
|
||||||
|
if(rb.wp+1 == rb.ep)
|
||||||
|
rb.wp = rb.buf;
|
||||||
|
else
|
||||||
|
rb.wp = rb.wp+1;
|
||||||
|
|
||||||
|
if(rb.wakeme)
|
||||||
|
wakeup(&rb.consumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
randominit(void)
|
||||||
|
{
|
||||||
|
addclock0link(randomclock, 1000/HZ);
|
||||||
|
rb.ep = rb.buf + sizeof(rb.buf);
|
||||||
|
rb.rp = rb.wp = rb.buf;
|
||||||
|
kproc("genrandom", genrandom, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* consume random bytes from a circular buffer
|
||||||
|
*/
|
||||||
|
ulong
|
||||||
|
randomread(void *xp, ulong n)
|
||||||
|
{
|
||||||
|
uchar *e, *p;
|
||||||
|
ulong x;
|
||||||
|
|
||||||
|
p = xp;
|
||||||
|
|
||||||
|
if(waserror()){
|
||||||
|
qunlock(&rb);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
|
||||||
|
qlock(&rb);
|
||||||
|
for(e = p + n; p < e; ){
|
||||||
|
if(rb.wp == rb.rp){
|
||||||
|
rb.wakeme = 1;
|
||||||
|
wakeup(&rb.producer);
|
||||||
|
sleep(&rb.consumer, rbnotempty, 0);
|
||||||
|
rb.wakeme = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* beating clocks will be predictable if
|
||||||
|
* they are synchronized. Use a cheap pseudo
|
||||||
|
* random number generator to obscure any cycles.
|
||||||
|
*/
|
||||||
|
x = rb.randn*1103515245 ^ *rb.rp;
|
||||||
|
*p++ = rb.randn = x;
|
||||||
|
|
||||||
|
if(rb.rp+1 == rb.ep)
|
||||||
|
rb.rp = rb.buf;
|
||||||
|
else
|
||||||
|
rb.rp = rb.rp+1;
|
||||||
|
}
|
||||||
|
qunlock(&rb);
|
||||||
|
poperror();
|
||||||
|
|
||||||
|
wakeup(&rb.producer);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
192
sys/src/9/omap4/trap.c
Normal file
192
sys/src/9/omap4/trap.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
#include "u.h"
|
||||||
|
#include "ureg.h"
|
||||||
|
#include "../port/lib.h"
|
||||||
|
#include "../port/error.h"
|
||||||
|
#include "../port/systab.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "arm.h"
|
||||||
|
|
||||||
|
extern uchar *periph;
|
||||||
|
ulong *intc, *intd;
|
||||||
|
void (*irqhandler[256])(Ureg*);
|
||||||
|
|
||||||
|
static char *trapname[] = {
|
||||||
|
"reset", /* wtf */
|
||||||
|
"undefined instruction",
|
||||||
|
"supervisor call",
|
||||||
|
"prefetch abort",
|
||||||
|
"data abort",
|
||||||
|
"unknown trap",
|
||||||
|
"IRQ",
|
||||||
|
"FIQ",
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
trapinit(void)
|
||||||
|
{
|
||||||
|
extern void _dataabort(), _undefined(), _prefabort(), _irq(), _fiq(), _reset(), _wtftrap(), _syscall();
|
||||||
|
int i;
|
||||||
|
ulong *trapv;
|
||||||
|
|
||||||
|
trapv = (ulong *) 0xFFFF0000;
|
||||||
|
for(i = 0; i < 8; i++)
|
||||||
|
trapv[i] = 0xE59FF018;
|
||||||
|
trapv[8] = (ulong) _reset;
|
||||||
|
trapv[9] = (ulong) _undefined;
|
||||||
|
trapv[10] = (ulong) _syscall;
|
||||||
|
trapv[11] = (ulong) _prefabort;
|
||||||
|
trapv[12] = (ulong) _dataabort;
|
||||||
|
trapv[13] = (ulong) _wtftrap;
|
||||||
|
trapv[14] = (ulong) _irq;
|
||||||
|
trapv[15] = (ulong) _fiq;
|
||||||
|
|
||||||
|
intc = (ulong *) (periph + 0x100);
|
||||||
|
intc[1] = 0;
|
||||||
|
intc[0] |= 1;
|
||||||
|
intd = (ulong *) (periph + 0x1000);
|
||||||
|
intd[0] |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
intenable(int i, void (*fn)(Ureg *))
|
||||||
|
{
|
||||||
|
intd[0x40 + (i / 32)] |= 1 << (i % 32);
|
||||||
|
irqhandler[i] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
faultarm(Ureg *ureg)
|
||||||
|
{
|
||||||
|
ulong addr, sr;
|
||||||
|
int user, n, read, nsys;
|
||||||
|
extern ulong getdfsr(void), getifsr(void), getdfar(void), getifar(void);
|
||||||
|
char buf[ERRMAX];
|
||||||
|
|
||||||
|
user = (ureg->psr & PsrMask) == PsrMusr;
|
||||||
|
read = 1;
|
||||||
|
if(ureg->type == 3){
|
||||||
|
sr = getifsr();
|
||||||
|
addr = getifar();
|
||||||
|
}else{
|
||||||
|
sr = getdfsr();
|
||||||
|
addr = getdfar();
|
||||||
|
if(sr & (1<<11))
|
||||||
|
read = 0;
|
||||||
|
}
|
||||||
|
if(!user && addr >= KZERO){
|
||||||
|
kernel:
|
||||||
|
printureg(ureg);
|
||||||
|
panic("kernel fault: addr=%#.8lux pc=%#.8lux sr=%#.8lux", addr, ureg->pc, sr);
|
||||||
|
}
|
||||||
|
if(up == nil){
|
||||||
|
printureg(ureg);
|
||||||
|
panic("%s fault: up=nil addr=%#.8lux pc=%#.8lux sr=%#.8lux", user ? "user" : "kernel", addr, ureg->pc, sr);
|
||||||
|
}
|
||||||
|
nsys = up->insyscall;
|
||||||
|
up->insyscall = 1;
|
||||||
|
n = fault(addr, read);
|
||||||
|
if(n < 0){
|
||||||
|
if(!user)
|
||||||
|
goto kernel;
|
||||||
|
sprint(buf, "sys: trap: fault %s addr=0x%lux", read ? "read" : "write", addr);
|
||||||
|
postnote(up, 1, buf, NDebug);
|
||||||
|
}
|
||||||
|
up->insyscall = nsys;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
trap(Ureg *ureg)
|
||||||
|
{
|
||||||
|
int user, intn, x;
|
||||||
|
|
||||||
|
user = (ureg->psr & PsrMask) == PsrMusr;
|
||||||
|
if(user){
|
||||||
|
fillureguser(ureg);
|
||||||
|
up->dbgreg = ureg;
|
||||||
|
}
|
||||||
|
switch(ureg->type){
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
faultarm(ureg);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
x = intc[3];
|
||||||
|
intn = x & 0x3F;
|
||||||
|
if(irqhandler[intn] != nil)
|
||||||
|
irqhandler[intn](ureg);
|
||||||
|
intc[4] = x;
|
||||||
|
if(intn != 29)
|
||||||
|
preempted();
|
||||||
|
if(up && up->delaysched && (intn == 29)){
|
||||||
|
sched();
|
||||||
|
splhi();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printureg(ureg);
|
||||||
|
panic("%s", trapname[ureg->type]);
|
||||||
|
}
|
||||||
|
if(user)
|
||||||
|
up->dbgreg = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
syscall(Ureg *ureg)
|
||||||
|
{
|
||||||
|
int scall, ret;
|
||||||
|
ulong s, sp;
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
m->syscall++;
|
||||||
|
up->insyscall = 1;
|
||||||
|
up->pc = ureg->pc;
|
||||||
|
up->dbgreg = ureg;
|
||||||
|
if(up->procctl == Proc_tracesyscall){
|
||||||
|
up->procctl = Proc_stopme;
|
||||||
|
procctl(up);
|
||||||
|
}
|
||||||
|
scall = ureg->r0;
|
||||||
|
up->scallnr = scall;
|
||||||
|
// print("%s\n", sysctab[scall]);
|
||||||
|
spllo();
|
||||||
|
|
||||||
|
sp = ureg->sp;
|
||||||
|
up->nerrlab = 0;
|
||||||
|
ret = -1;
|
||||||
|
if(!waserror()){
|
||||||
|
if(scall >= nsyscall){
|
||||||
|
postnote(up, 1, "sys: bad syscall", NDebug);
|
||||||
|
error(Ebadarg);
|
||||||
|
}
|
||||||
|
validaddr(sp, sizeof(Sargs) + BY2WD, 0);
|
||||||
|
up->s = *((Sargs*)(sp + BY2WD));
|
||||||
|
up->psstate = sysctab[scall];
|
||||||
|
ret = systab[scall](up->s.args);
|
||||||
|
poperror();
|
||||||
|
}else{
|
||||||
|
e = up->syserrstr;
|
||||||
|
up->syserrstr = up->errstr;
|
||||||
|
up->errstr = e;
|
||||||
|
}
|
||||||
|
if(up->nerrlab != 0)
|
||||||
|
panic("error stack");
|
||||||
|
ureg->r0 = ret;
|
||||||
|
|
||||||
|
if(up->procctl == Proc_tracesyscall){
|
||||||
|
up->procctl = Proc_stopme;
|
||||||
|
s = splhi();
|
||||||
|
procctl(up);
|
||||||
|
splx(s);
|
||||||
|
}
|
||||||
|
up->insyscall = 0;
|
||||||
|
up->psstate = nil;
|
||||||
|
splhi();
|
||||||
|
if(up->delaysched){
|
||||||
|
sched();
|
||||||
|
splhi();
|
||||||
|
}
|
||||||
|
up->dbgreg = nil;
|
||||||
|
}
|
18
sys/src/9/omap4/uart.c
Normal file
18
sys/src/9/omap4/uart.c
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue