remove unmaintained omap4 (pandaboard) kernel
This commit is contained in:
parent
76e4f7caf9
commit
7d45ee4f6a
17 changed files with 0 additions and 2407 deletions
|
@ -3,7 +3,6 @@ ARCH=\
|
||||||
kw\
|
kw\
|
||||||
mtx\
|
mtx\
|
||||||
omap\
|
omap\
|
||||||
omap4\
|
|
||||||
pc\
|
pc\
|
||||||
pc64\
|
pc64\
|
||||||
ppc\
|
ppc\
|
||||||
|
|
|
@ -1,175 +0,0 @@
|
||||||
#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);
|
|
||||||
|
|
||||||
uintptr
|
|
||||||
userpc(void)
|
|
||||||
{
|
|
||||||
return dbgpc(up);
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr
|
|
||||||
dbgpc(Proc *p)
|
|
||||||
{
|
|
||||||
Ureg *ureg;
|
|
||||||
|
|
||||||
ureg = p->dbgreg;
|
|
||||||
if(ureg == 0)
|
|
||||||
return 0;
|
|
||||||
return ureg->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
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
|
|
||||||
procsave(Proc *p)
|
|
||||||
{
|
|
||||||
uvlong t;
|
|
||||||
|
|
||||||
cycles(&t);
|
|
||||||
p->pcycles += t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
procrestore(Proc *p)
|
|
||||||
{
|
|
||||||
uvlong t;
|
|
||||||
|
|
||||||
cycles(&t);
|
|
||||||
p->pcycles -= t;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr
|
|
||||||
execregs(uintptr entry, ulong ssize, ulong nargs)
|
|
||||||
{
|
|
||||||
ulong *sp;
|
|
||||||
Ureg *ureg;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 PsrOK 0xF80F0000 /* user processes may touch these */
|
|
||||||
|
|
||||||
#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)
|
|
|
@ -1,31 +0,0 @@
|
||||||
#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;
|
|
|
@ -1,123 +0,0 @@
|
||||||
#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,
|
|
||||||
MaxPeriod = PERIPHCLK / (256 * 100),
|
|
||||||
MinPeriod = MaxPeriod / 100,
|
|
||||||
} ;
|
|
||||||
|
|
||||||
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, void *)
|
|
||||||
{
|
|
||||||
timerintr(ureg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
localclockinit(void)
|
|
||||||
{
|
|
||||||
local[2] = 0xFF06;
|
|
||||||
intenable(29, clocktick, nil);
|
|
||||||
timerset(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
timerset(uvlong val)
|
|
||||||
{
|
|
||||||
uvlong now, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,150 +0,0 @@
|
||||||
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 struct ISAConf ISAConf;
|
|
||||||
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 */
|
|
||||||
}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
|
|
||||||
|
|
||||||
struct ISAConf
|
|
||||||
{
|
|
||||||
char *type;
|
|
||||||
ulong port, irq;
|
|
||||||
};
|
|
|
@ -1,41 +0,0 @@
|
||||||
#include "../port/portfns.h"
|
|
||||||
|
|
||||||
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
|
|
||||||
#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 *);
|
|
||||||
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 *);
|
|
||||||
extern void markidle(int);
|
|
||||||
#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*, void *), void *);
|
|
||||||
void uartinit(void);
|
|
||||||
void irqroute(int, void(*)(Ureg*, void *), void *);
|
|
||||||
void gpioinit(void);
|
|
||||||
void setgpio(int, int);
|
|
||||||
void gpiomode(int, int);
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
|
@ -1,281 +0,0 @@
|
||||||
#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|CpCicache), 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
|
|
||||||
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 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)
|
|
||||||
MOVW 72(R13), R0
|
|
||||||
AND $PsrMask, R0
|
|
||||||
CMP $PsrMusr, R0
|
|
||||||
B.EQ _forkret
|
|
||||||
ADD $8, R13
|
|
||||||
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
|
|
||||||
_forkret:
|
|
||||||
ADD $8, R13
|
|
||||||
MOVW R13, R0
|
|
||||||
ADD $72, R13
|
|
||||||
|
|
||||||
TEXT touser(SB), 1, $-4
|
|
||||||
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
|
|
||||||
|
|
||||||
TEXT getr13(SB), 0, $-4
|
|
||||||
MOVW R13, R0
|
|
||||||
RET
|
|
|
@ -1,199 +0,0 @@
|
||||||
#include "u.h"
|
|
||||||
#include "ureg.h"
|
|
||||||
#include "pool.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;
|
|
||||||
conf.ialloc = 65536;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
ksetenv("console", "0", 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);
|
|
||||||
pg->txtflush = ~0;
|
|
||||||
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 ehcidebug;
|
|
||||||
|
|
||||||
wave('f');
|
|
||||||
memset(edata, 0, end - edata);
|
|
||||||
wave('r');
|
|
||||||
machinit();
|
|
||||||
wave('o');
|
|
||||||
mmuinit();
|
|
||||||
gpioinit();
|
|
||||||
wave('m');
|
|
||||||
trapinit();
|
|
||||||
uartinit();
|
|
||||||
print(" Bell Labs\n");
|
|
||||||
xinit();
|
|
||||||
globalclockinit();
|
|
||||||
localclockinit();
|
|
||||||
timersinit();
|
|
||||||
procinit0();
|
|
||||||
pageinit();
|
|
||||||
swapinit();
|
|
||||||
initseg();
|
|
||||||
quotefmtinstall();
|
|
||||||
ehcidebug = 1;
|
|
||||||
links();
|
|
||||||
chandevreset();
|
|
||||||
userinit();
|
|
||||||
schedinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
exit(int)
|
|
||||||
{
|
|
||||||
uartputs("resting\n", 9);
|
|
||||||
splhi();
|
|
||||||
while(1)
|
|
||||||
idlehands();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
reboot()
|
|
||||||
{
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rdb()
|
|
||||||
{
|
|
||||||
panic("rdb");
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
#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 USTKSIZE (8*MiB)
|
|
||||||
|
|
||||||
#define HZ (100) /* clock frequency */
|
|
||||||
#define MS2HZ (1000/HZ) /* millisec per clock tick */
|
|
||||||
|
|
||||||
#define MAXSYSARG 7
|
|
||||||
#define MAXMACH 2
|
|
||||||
|
|
||||||
#define BI2BY 8
|
|
||||||
#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)
|
|
|
@ -1,103 +0,0 @@
|
||||||
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\
|
|
||||||
gpio.$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\
|
|
||||||
syscallfmt.$O\
|
|
||||||
sysfile.$O\
|
|
||||||
sysproc.$O\
|
|
||||||
taslock.$O\
|
|
||||||
tod.$O\
|
|
||||||
xalloc.$O\
|
|
||||||
random.$O\
|
|
||||||
|
|
||||||
OBJ=\
|
|
||||||
l.$O\
|
|
||||||
main.$O\
|
|
||||||
mmu.$O\
|
|
||||||
clock.$O\
|
|
||||||
arch.$O\
|
|
||||||
trap.$O\
|
|
||||||
syscall.$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
|
|
|
@ -1,243 +0,0 @@
|
||||||
#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
|
|
||||||
markidle(int n)
|
|
||||||
{
|
|
||||||
setgpio(7 + m->machno, !n);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
periph = vmap(0x48240000, 2 * 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mmuswitch(Proc *p)
|
|
||||||
{
|
|
||||||
ulong *l1;
|
|
||||||
|
|
||||||
l1 = KADDR(L1PT);
|
|
||||||
memmove(l1, p->l1, sizeof p->l1);
|
|
||||||
flushtlb();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
putmmu(uintptr va, uintptr 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;
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
# 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
|
|
||||||
|
|
||||||
# usbohci
|
|
||||||
# usbehci usbehciomap
|
|
||||||
|
|
||||||
ip
|
|
||||||
tcp
|
|
||||||
udp
|
|
||||||
ipifc
|
|
||||||
icmp
|
|
||||||
icmp6
|
|
||||||
ipmux
|
|
||||||
gre
|
|
||||||
esp
|
|
||||||
|
|
||||||
misc
|
|
||||||
# rdb
|
|
||||||
# coproc
|
|
||||||
# dma
|
|
||||||
# mouse
|
|
||||||
# sdaoe sdscsi
|
|
||||||
# softfpu
|
|
||||||
# uarti8250
|
|
||||||
# ucalloc
|
|
||||||
# ucallocb
|
|
||||||
uartomap
|
|
||||||
|
|
||||||
port
|
|
||||||
int cpuserver = 1;
|
|
||||||
|
|
||||||
bootdir
|
|
||||||
/$objtype/bin/paqfs
|
|
||||||
/$objtype/bin/auth/factotum
|
|
||||||
bootfs.paq
|
|
||||||
boot
|
|
|
@ -1,385 +0,0 @@
|
||||||
#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"
|
|
||||||
#include "tos.h"
|
|
||||||
|
|
||||||
extern uchar *periph;
|
|
||||||
ulong *intc, *intd;
|
|
||||||
void (*irqhandler[MAXMACH][256])(Ureg *, void *);
|
|
||||||
void *irqaux[MAXMACH][256];
|
|
||||||
|
|
||||||
static char *trapname[] = {
|
|
||||||
"reset", /* wtf */
|
|
||||||
"undefined instruction",
|
|
||||||
"supervisor call",
|
|
||||||
"prefetch abort",
|
|
||||||
"data abort",
|
|
||||||
"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 *, void *), void *aux)
|
|
||||||
{
|
|
||||||
intd[0x40 + (i / 32)] = 1 << (i % 32);
|
|
||||||
irqhandler[m->machno][i] = fn;
|
|
||||||
irqaux[m->machno][i] = aux;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
irqroute(int i, void (*fn)(Ureg *, void *), void *aux)
|
|
||||||
{
|
|
||||||
ulong x, y, z;
|
|
||||||
|
|
||||||
if(irqhandler[m->machno][i] != nil){
|
|
||||||
print("irqroute: irq already used: i=%d pc=%#p newfn=%#p oldfn=%#p\n", i, getcallerpc(&i), fn, irqhandler[m->machno][i]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
intenable(32 + i, fn, aux);
|
|
||||||
x = intd[0x208 + i/4];
|
|
||||||
y = 0xFF << ((i%4) * 8);
|
|
||||||
z = 1 << (m->machno + (i%4) * 8);
|
|
||||||
x = (x & ~y) | z;
|
|
||||||
intd[0x208 + i/4] = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
|
||||||
serialoq = nil;
|
|
||||||
printureg(ureg);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
nsys = up->insyscall;
|
|
||||||
up->insyscall = 1;
|
|
||||||
n = fault(addr, read);
|
|
||||||
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 = t + up->pcycles;
|
|
||||||
tos->pid = up->pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
notify(Ureg *ureg)
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
ulong s, sp;
|
|
||||||
Note *n;
|
|
||||||
|
|
||||||
if(up->procctl)
|
|
||||||
procctl();
|
|
||||||
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)){
|
|
||||||
qunlock(&up->debug);
|
|
||||||
if(n->flag == NDebug)
|
|
||||||
pprint("suicide: %s\n", n->msg);
|
|
||||||
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((uintptr)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(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:
|
|
||||||
up->lastnote.flag = NDebug;
|
|
||||||
/* fallthrough */
|
|
||||||
|
|
||||||
case NDFLT:
|
|
||||||
qunlock(&up->debug);
|
|
||||||
if(up->lastnote.flag == NDebug)
|
|
||||||
pprint("suicide: %s\n", up->lastnote.msg);
|
|
||||||
pexit(up->lastnote.msg, up->lastnote.flag != NDebug);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
trap(Ureg *ureg)
|
|
||||||
{
|
|
||||||
int user, intn, x;
|
|
||||||
char buf[ERRMAX];
|
|
||||||
|
|
||||||
user = (ureg->psr & PsrMask) == PsrMusr;
|
|
||||||
if(user){
|
|
||||||
fillureguser(ureg);
|
|
||||||
up->dbgreg = ureg;
|
|
||||||
cycles(&up->kentry);
|
|
||||||
}
|
|
||||||
switch(ureg->type){
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
faultarm(ureg);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
x = intc[3];
|
|
||||||
intn = x & 0x3FF;
|
|
||||||
if(irqhandler[m->machno][intn] != nil)
|
|
||||||
irqhandler[m->machno][intn](ureg, irqaux[m->machno][intn]);
|
|
||||||
else
|
|
||||||
print("unexpected interrupt %d\n", intn);
|
|
||||||
intc[4] = x;
|
|
||||||
if(intn != 29)
|
|
||||||
preempted();
|
|
||||||
splhi();
|
|
||||||
if(up && up->delaysched && (intn == 29)){
|
|
||||||
sched();
|
|
||||||
splhi();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
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(up->procctl || up->nnote)
|
|
||||||
notify(ureg);
|
|
||||||
updatetos();
|
|
||||||
up->dbgreg = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
syscall(Ureg *ureg)
|
|
||||||
{
|
|
||||||
int scall, ret;
|
|
||||||
ulong s, sp;
|
|
||||||
char *e;
|
|
||||||
vlong startns, stopns;
|
|
||||||
|
|
||||||
m->syscall++;
|
|
||||||
up->insyscall = 1;
|
|
||||||
up->pc = ureg->pc;
|
|
||||||
up->dbgreg = ureg;
|
|
||||||
cycles(&up->kentry);
|
|
||||||
scall = ureg->r0;
|
|
||||||
up->scallnr = scall;
|
|
||||||
spllo();
|
|
||||||
|
|
||||||
sp = ureg->sp;
|
|
||||||
up->nerrlab = 0;
|
|
||||||
ret = -1;
|
|
||||||
if(!waserror()){
|
|
||||||
validaddr(sp, sizeof(Sargs) + BY2WD, 0);
|
|
||||||
up->s = *((Sargs*)(sp + BY2WD));
|
|
||||||
if(up->procctl == Proc_tracesyscall){
|
|
||||||
syscallfmt(scall, ureg->pc, (va_list)up->s.args);
|
|
||||||
s = splhi();
|
|
||||||
up->procctl = Proc_stopme;
|
|
||||||
procctl();
|
|
||||||
splx(s);
|
|
||||||
startns = todget(nil);
|
|
||||||
}
|
|
||||||
if(scall >= nsyscall){
|
|
||||||
postnote(up, 1, "sys: bad syscall", NDebug);
|
|
||||||
error(Ebadarg);
|
|
||||||
}
|
|
||||||
up->psstate = sysctab[scall];
|
|
||||||
ret = systab[scall]((va_list)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){
|
|
||||||
stopns = todget(nil);
|
|
||||||
sysretfmt(scall, (va_list)up->s.args, ret, startns, stopns);
|
|
||||||
s = splhi();
|
|
||||||
up->procctl = Proc_stopme;
|
|
||||||
procctl();
|
|
||||||
splx(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
up->insyscall = 0;
|
|
||||||
up->psstate = nil;
|
|
||||||
|
|
||||||
if(scall == NOTED)
|
|
||||||
noted(ureg, *((ulong*)up->s.args));
|
|
||||||
if(scall != RFORK && (up->procctl || up->nnote)){
|
|
||||||
splhi();
|
|
||||||
notify(ureg);
|
|
||||||
}
|
|
||||||
splhi();
|
|
||||||
if(up->delaysched){
|
|
||||||
sched();
|
|
||||||
splhi();
|
|
||||||
}
|
|
||||||
updatetos();
|
|
||||||
up->dbgreg = nil;
|
|
||||||
}
|
|
|
@ -1,263 +0,0 @@
|
||||||
#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)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
|
|
||||||
x = splhi();
|
|
||||||
while((uart[17] & 1) == 0){
|
|
||||||
if(u->op >= u->oe)
|
|
||||||
if(uartstageoutput(u) == 0){
|
|
||||||
uart[1] &= ~(1<<1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
uart[0] = *u->op++;
|
|
||||||
uart[1] |= (1<<1);
|
|
||||||
}
|
|
||||||
splx(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
omapinterrupt(Ureg *, void *)
|
|
||||||
{
|
|
||||||
ulong st;
|
|
||||||
|
|
||||||
st = uart[2];
|
|
||||||
if((st & 1) != 0)
|
|
||||||
return;
|
|
||||||
switch((st >> 1) & 0x1F){
|
|
||||||
case 0:
|
|
||||||
case 16:
|
|
||||||
puart.cts = (uart[6] & (1<<4)) != 0;
|
|
||||||
puart.dsr = (uart[6] & (1<<5)) != 0;
|
|
||||||
puart.dcd = (uart[6] & (1<<7)) != 0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
uartkick(&puart);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
case 6:
|
|
||||||
while(uart[5] & 1)
|
|
||||||
uartrecv(&puart, uart[0]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
print("unknown UART interrupt %uld\n", (st>>1) & 0x1F);
|
|
||||||
uartkick(&puart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
omapenable(Uart *u, int ie)
|
|
||||||
{
|
|
||||||
while(uart[5] & (1<<6))
|
|
||||||
;
|
|
||||||
if(ie){
|
|
||||||
irqroute(74, omapinterrupt, u);
|
|
||||||
uart[1] = (1<<0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
omapdisable(Uart *)
|
|
||||||
{
|
|
||||||
uart[1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
omapdobreak(Uart *, int ms)
|
|
||||||
{
|
|
||||||
if(ms <= 0)
|
|
||||||
ms = 200;
|
|
||||||
|
|
||||||
uart[3] |= (1<<6);
|
|
||||||
tsleep(&up->sleep, return0, 0, ms);
|
|
||||||
uart[3] &= ~(1<<6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
omapbaud(Uart *u, int baud)
|
|
||||||
{
|
|
||||||
int val;
|
|
||||||
|
|
||||||
if(baud <= 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
val = (48000000 / 16) / baud;
|
|
||||||
uart[3] |= (1<<7);
|
|
||||||
uart[0] = val & 0xFF;
|
|
||||||
uart[1] = (val >> 8) & 0xFF;
|
|
||||||
uart[3] &= ~(1<<7);
|
|
||||||
u->baud = baud;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
omapbits(Uart *u, int bits)
|
|
||||||
{
|
|
||||||
if(bits < 5 || bits > 8)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uart[3] = (uart[3] & ~3) | (bits - 5);
|
|
||||||
u->bits = bits;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
omapstop(Uart *u, int stop)
|
|
||||||
{
|
|
||||||
if(stop < 1 || stop > 2)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uart[3] &= ~4;
|
|
||||||
if(stop == 2)
|
|
||||||
uart[3] |= 4;
|
|
||||||
u->stop = stop;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
omapparity(Uart *u, int parity)
|
|
||||||
{
|
|
||||||
uart[3] &= ~0x38;
|
|
||||||
switch(parity){
|
|
||||||
case 'n':
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
uart[3] |= (1<<3);
|
|
||||||
case 'e':
|
|
||||||
uart[3] |= (1<<3) | (1<<4);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
u->parity = parity;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
omapmodemctl(Uart *u, int on)
|
|
||||||
{
|
|
||||||
if(on){
|
|
||||||
u->modem = 1;
|
|
||||||
u->cts = (uart[6] & (1<<4)) != 0;
|
|
||||||
uart[1] |= (1<<6);
|
|
||||||
}else{
|
|
||||||
u->modem = 0;
|
|
||||||
u->cts = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
omaprts(Uart *, int i)
|
|
||||||
{
|
|
||||||
uart[4] = (uart[4] & ~2) | (i << 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
omapdtr(Uart *, int i)
|
|
||||||
{
|
|
||||||
uart[4] = (uart[4] & ~1) | i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static long
|
|
||||||
omapstatus(Uart* u, void* buf, long n, long offset)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
ulong msr;
|
|
||||||
|
|
||||||
msr = uart[6];
|
|
||||||
p = malloc(READSTR);
|
|
||||||
snprint(p, READSTR,
|
|
||||||
"b%d c%d d%d e%d l%d m%d p%c r%d s%d\n"
|
|
||||||
"dev(%d) type(%d) framing(%d) overruns(%d) "
|
|
||||||
"berr(%d) serr(%d)%s%s%s%s\n",
|
|
||||||
|
|
||||||
u->baud,
|
|
||||||
u->hup_dcd,
|
|
||||||
u->dsr,
|
|
||||||
u->hup_dsr,
|
|
||||||
u->bits,
|
|
||||||
u->modem,
|
|
||||||
u->parity,
|
|
||||||
(uart[3] & 2) != 0,
|
|
||||||
u->stop,
|
|
||||||
|
|
||||||
u->dev,
|
|
||||||
u->type,
|
|
||||||
u->ferr,
|
|
||||||
u->oerr,
|
|
||||||
u->berr,
|
|
||||||
u->serr,
|
|
||||||
(msr & (1<<4)) ? " cts": "",
|
|
||||||
(msr & (1<<5)) ? " dsr": "",
|
|
||||||
(msr & (1<<7)) ? " dcd": "",
|
|
||||||
(msr & (1<<6)) ? " ri": ""
|
|
||||||
);
|
|
||||||
n = readstr(offset, buf, n, p);
|
|
||||||
free(p);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
omapgetc(Uart *)
|
|
||||||
{
|
|
||||||
while((uart[5] & 1) == 0)
|
|
||||||
;
|
|
||||||
return uart[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
omapputc(Uart *, int c)
|
|
||||||
{
|
|
||||||
while(uart[17] & 1)
|
|
||||||
;
|
|
||||||
uart[0] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhysUart omapphysuart = {
|
|
||||||
.name = "omap4430 uart",
|
|
||||||
.pnp = omappnp,
|
|
||||||
.getc = omapgetc,
|
|
||||||
.putc = omapputc,
|
|
||||||
.enable = omapenable,
|
|
||||||
.disable = omapdisable,
|
|
||||||
.kick = omapkick,
|
|
||||||
.rts = omaprts,
|
|
||||||
.parity = omapparity,
|
|
||||||
.baud = omapbaud,
|
|
||||||
.bits = omapbits,
|
|
||||||
.stop = omapstop,
|
|
||||||
.modemctl = omapmodemctl,
|
|
||||||
.dtr = omapdtr,
|
|
||||||
.status = omapstatus,
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
uartinit(void)
|
|
||||||
{
|
|
||||||
consuart = &puart;
|
|
||||||
puart.console = 1;
|
|
||||||
}
|
|
Loading…
Reference in a new issue