remove unmaintained omap4 (pandaboard) kernel

This commit is contained in:
cinap_lenrek 2016-05-05 16:35:25 +02:00
parent 76e4f7caf9
commit 7d45ee4f6a
17 changed files with 0 additions and 2407 deletions

View file

@ -3,7 +3,6 @@ ARCH=\
kw\
mtx\
omap\
omap4\
pc\
pc64\
ppc\

View file

@ -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);
}

View file

@ -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)

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
};

View file

@ -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);

View file

@ -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

View file

View file

@ -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

View file

@ -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");
}

View file

@ -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)

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}