This commit is contained in:
cinap_lenrek 2011-09-02 14:13:15 +02:00
commit 933d48e43e
18 changed files with 2081 additions and 1 deletions

View file

@ -42,4 +42,5 @@ The 'IE users have lower IQs' story was a hoax.
Do you know anything about vim?
today there were problems with the Fossil FS on my Plan9 test installation.
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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View file

298
sys/src/9/omap4/l.s Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}
}