Plan 9 from Bell Labs 2000-08-31
6 files changed, 731 insertions(+), 0 deletions(-) A bitsy/dat.h A bitsy/fns.h A bitsy/io.h A bitsy/l.s A bitsy/main.c A bitsy/mem.h
A bitsy/dat.h => bitsy/dat.h +171 -0
@@ 0,0 1,171 @@ typedef struct Conf Conf; typedef struct FPsave FPsave; typedef struct Label Label; typedef struct Lock Lock; typedef struct MMU MMU; typedef struct Mach Mach; typedef struct Notsave Notsave; typedef struct Page Page; typedef struct PMMU PMMU; typedef struct Proc Proc; typedef struct Ureg Ureg; typedef struct Vctl Vctl; /* * parameters for sysproc.c */ #define AOUT_MAGIC (I_MAGIC) struct Lock { ulong key; ulong sr; ulong pc; Proc *p; ushort isilock; }; struct Label { ulong sp; ulong pc; }; /* * no floating point, hence nothing to save */ struct FPsave { int dummy; }; struct Conf { ulong nmach; /* processors */ ulong nproc; /* processes */ ulong monitor; /* has monitor? */ ulong npage0; /* total physical pages of memory */ ulong npage1; /* total physical pages of memory */ ulong npage; /* total physical pages of memory */ ulong upages; /* user page pool */ ulong nimage; /* number of page cache image headers */ ulong nswap; /* number of swap pages */ int nswppo; /* max # of pageouts per segment pass */ ulong base0; /* base of bank 0 */ ulong base1; /* base of bank 1 */ 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 */ }; /* * MMU stuff in proc */ #define NCOLOR 1 struct PMMU { int dummy; }; /* * things saved in the Proc structure during a notify */ struct Notsave { int dummy; }; #include "../port/portdat.h" struct Mach { int machno; /* physical id of processor */ ulong splpc; /* pc of last caller to splhi */ ulong* pdb; /* page directory base for this processor (va) */ Proc* proc; /* current process on this processor */ Proc* externup; /* extern register Proc *up */ Page* pdbpool; int pdbcnt; 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 */ ulong fairness; /* for runproc */ int tlbfault; int tlbpurge; int pfault; int cs; int syscall; int load; int intr; vlong fastclock; /* last sampled value */ vlong intrts; /* time stamp of last interrupt */ int flushmmu; /* make current proc flush it's mmu state */ ulong spuriousintr; int lastintr; int loopconst; int cpumhz; int cpuhz; int cpuidax; int cpuiddx; char cpuidid[16]; char* cpuidtype; vlong mtrrcap; vlong mtrrdef; vlong mtrrfix[11]; vlong mtrrvar[32]; /* 256 max. */ int stack[1]; }; typedef struct Cycintr Cycintr; /* * fasttick timer interrupts */ struct Cycintr { vlong when; /* fastticks when f should be called */ void (*f)(Ureg*, Cycintr*); void *a; Cycintr *next; }; /* * Fake kmap */ typedef void KMap; #define VA(k) ((ulong)(k)) #define kmap(p) (KMap*)((p)->pa|KZERO) #define kunmap(k) struct { Lock; int machs; /* bitmap of active CPUs */ int exiting; /* shutdown */ int ispanic; /* shutdown in response to a panic */ }active; /* * Each processor sees its own Mach structure at address MACHADDR. * However, the Mach structures must also be available via the per-processor * MMU information array machp, mainly for disambiguation and access to * the clock which is only maintained by the bootstrap processor (0). */ Mach* machp[MAXMACH]; #define MACHP(n) (machp[n]) extern Mach *m; #define up (((Mach*)MACHADDR)->externup)
A bitsy/fns.h => bitsy/fns.h +28 -0
@@ 0,0 1,28 @@ #include "../port/portfns.h" int cistrcmp(char*, char*); int cistrncmp(char*, char*, int); #define clearmmucache() /* x86 doesn't have one */ void clockintr(Ureg*, void*); void clockintrsched(void); void (*coherence)(void); void delay(int); void idle(void); #define idlehands() /* nothing to do in the runproc */ #define procrestore(p) void procsave(Proc*); void procsetup(Proc*); void screeninit(void); int screenprint(char*, ...); /* debugging */ void (*screenputs)(char*, int); void touser(void*); void trapenable(int, void (*)(Ureg*, void*), void*, char*); void trapinit(void); int tas(void*); void wbflush(void); #define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) #define KADDR(a) ((void*)((ulong)(a)|KZERO)) #define PADDR(a) ((ulong)(a)&~KZERO) #define dcflush(a, b)
A bitsy/io.h => bitsy/io.h +112 -0
@@ 0,0 1,112 @@ /* replicated in part from the boot code, for now */ #define XTAL 3686400 #define CORECLOCK 199066000 #define MONITOR 0x00020000 #define SYS_REGBASE 0x90000000 #define SYSR_FIRQ 0x1000 #define SYSR_IRQ 0x1400 #define SIRQ_PCI (1<<2) #define SIRQ_UART (1<<8) #define SYSR_UART_SR 0x3400 /* UART Status Register */ #define SYSR_UART_CR 0x3800 /* UART Control Register */ #define SYSR_UART_DR 0x3C00 /* UART Data Register */ #define SYS_FIRQ (0x90000000+SYSR_FIRQ) #define SYS_IRQ (0x90000000+SYSR_IRQ) #define PCI_REGBASE 0x42000000 #define PCI_IPXRESET 0x07C #define PCI_IRQSTATUS 0x180 #define PCI_IRQRSTATUS 0x184 #define PCI_IRQENABLE 0x188 #define PCI_IRQENA_SET 0x188 #define PCI_IRQENA_CLR 0x18C #define PCI_IRQSOFT 0x190 #define PCI_FIRQSTATUS 0x280 #define PCI_FIRQRSTATUS 0x284 #define PCI_FIRQENABLE 0x288 #define PCI_FIRQENA_SET 0x288 #define PCI_FIRQENA_CLR 0x28C #define PCI_FIRQSOFT 0x290 #define PCI_TIMERLOAD 0x300 #define PCI_TIMERVALUE 0x304 #define PCI_TIMERCTL 0x308 #define PCI_TIMERCLEAR 0x30C #define TIMER_OFF 0x020 #define TIMER1_LOAD (PCI_REGBASE+PCI_TIMERLOAD) #define TIMER1_VALUE (PCI_REGBASE+PCI_TIMERVALUE) #define TIMER1_CTL (PCI_REGBASE+PCI_TIMERCTL) #define TIMER1_CLEAR (PCI_REGBASE+PCI_TIMERCLEAR) #define TIMER_PERIODIC (1<<6) #define TIMER_ENABLE (1<<7) #define IRQ_STATUS (PCI_REGBASE+PCI_IRQSTATUS) #define IRQ_ENABLE_SET (PCI_REGBASE+PCI_IRQENA_SET) #define IRQ_ENABLE_CLR (PCI_REGBASE+PCI_IRQENA_CLR) #define FIRQ_OFF 0x100 #define IRQ_SOFT 1 #define IRQ_TIMER1 4 #define IRQ_TIMER2 5 #define IRQ_TIMER3 6 #define IRQ_TIMER4 7 #define IRQ_DOOR 15 #define IRQ_DMA1 16 #define IRQ_DMA2 17 #define IRQ_PCI 18 #define IRQ_DMA1NB 20 #define IRQ_DMA2NB 21 #define IRQ_BIST 22 #define IRQ_SERR 23 #define IRQ_I2OIN 25 #define IRQ_POWER 26 #define IRQ_DTIMER 27 #define IRQ_PARITY 28 #define IRQ_MABORT 29 #define IRQ_TABORT 30 #define IRQ_DPARITY 31 #define PCI_CONF1_BASE 0x52000000 #define PCI_CONF0_BASE 0x53000000 #define PCI_IO_BASE 0x54000000 #define PCI_IO_SIZE 0x00010000 #define PCI_MEM_BASE 0x60000000 #define PCI_MEM_SIZE 0x20000000 /* MMU. */ #define MMUCR_M_ENABLE (1<<0) /* MMU enable */ #define MMUCR_A_ENABLE (1<<1) /* Address alignment fault enable */ #define MMUCR_C_ENABLE (1<<2) /* (data) cache enable */ #define MMUCR_W_ENABLE (1<<3) /* write buffer enable */ #define MMUCR_PROG32 (1<<4) /* PROG32 */ #define MMUCR_DATA32 (1<<5) /* DATA32 */ #define MMUCR_L_ENABLE (1<<6) /* Late abort on earlier CPUs */ #define MMUCR_BIGEND (1<<7) /* Big-endian (=1), little-endian (=0) */ #define MMUCR_SYSTEM (1<<8) /* System bit, modifies MMU protections */ #define MMUCR_ROM (1<<9) /* ROM bit, modifies MMU protections */ #define MMUCR_F (1<<10) /* Should Be Zero */ #define MMUCR_Z_ENABLE (1<<11) /* Branch prediction enable on 810 */ #define MMUCR_I_ENABLE (1<<12) /* Instruction cache enable on SA110 */ #define SDRAM_BASE 0xC0000000 #define SDRAM_RESV (16*1024*1024) #define SDRAM_SIZE (32*1024*1024) #define PMEM_BASE (SDRAM_BASE+SDRAM_RESV) #define PMEM_TOP (SDRAM_BASE+SDRAM_SIZE) #define KTOP (KZERO + (SDRAM_SIZE - SDRAM_RESV)) #define SLOW_BASE 0x38400000 #define SLEDOFFSET 0x00108000 #define LEDADDR (SLOW_BASE+SLEDOFFSET) #define SACADDR 0x08100000
A bitsy/l.s => bitsy/l.s +354 -0
@@ 0,0 1,354 @@ #include "mem.h" #include "arm7500.h" #include "io.h" /* * Entered here from the boot loader with * MMU, IDC and WB enabled. */ TEXT _startup(SB), $-4 MOVW $setR12(SB), R12 _main: MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 /* SVC mode, interrupts disabled */ MOVW R1, CPSR MOVW $(MACHADDR+BY2PG), R13 /* stack */ SUB $4, R13 /* link */ BL main(SB) _mainloop: BEQ _mainloop BNE _mainloop BL _div(SB) /* loader botch */ BL _mainloop TEXT mmuregr(SB), $-4 CMP $CpCPUID, R0 BNE _fsrr MRC CpMMU, 0, R0, C(CpCPUID), C(0) RET _fsrr: CMP $CpFSR, R0 BNE _farr MRC CpMMU, 0, R0, C(CpFSR), C(0) RET _farr: CMP $CpFAR, R0 BNE _ctlr MRC CpMMU, 0, R0, C(CpFAR), C(0) RET _ctlr: CMP $CpControl, R0 BNE _mmuregbad MCR CpMMU, 0, R0, C(CpControl), C(0) RET _mmuregbad: MOVW $-1, R0 RET TEXT mmuregw(SB), $-4 CMP $CpControl, R0 BNE _ttbw MOVW 4(FP), R0 MCR CpMMU, 0, R0, C(CpControl), C(0) RET _ttbw: CMP $CpTTB, R0 BNE _dacw MOVW 4(FP), R0 MCR CpMMU, 0, R0, C(CpTTB), C(0) RET _dacw: CMP $CpDAC, R0 BNE _TLBflushw MOVW 4(FP), R0 MCR CpMMU, 0, R0, C(CpDAC), C(0) RET _TLBflushw: CMP $CpTLBflush, R0 BNE _TLBpurgew MCR CpMMU, 0, R0, C(CpTLBflush), C(0) RET _TLBpurgew: CMP $CpTLBpurge, R0 BNE _IDCflushw MOVW 4(FP), R0 MCR CpMMU, 0, R0, C(CpTLBpurge), C(0) RET _IDCflushw: CMP $CpIDCflush, R0 BNE _WBdrain MCR CpMMU, 0, R0, C(CpIDCflush), C(CpIDCflush) RET _WBdrain: CMP $CpWBdrain, R0 BNE _mmuregbad MCR CpMMU, 4, R0, C(CpIDCflush), C(CpWBdrain), 4 RET TEXT mmuttb(SB), $-4 MCR CpMMU, 0, R0, C(CpIDCflush), C(CpIDCflush) MCR CpMMU, 0, R0, C(CpTLBflush), C(0) MCR CpMMU, 0, R0, C(CpTTB), C(0) RET TEXT mmureset(SB), $-4 MOVW CPSR, R0 ORR $(PsrDfiq|PsrDirq), R0, R0 MOVW R0, CPSR MOVW $0, R0 MOVW $(CpCsystem), R1 MCR CpMMU, 0, R1, C(CpControl), C(0) B (R0) TEXT setr13(SB), $-4 MOVW 4(FP), R1 MOVW CPSR, R2 BIC $PsrMask, R2, R3 ORR R0, R3 MOVW R3, CPSR MOVW R13, R0 MOVW R1, R13 MOVW R2, CPSR RET TEXT vectors(SB), $-4 MOVW 0x18(R15), R15 /* reset */ MOVW 0x18(R15), R15 /* undefined */ MOVW 0x18(R15), R15 /* SWI */ MOVW 0x18(R15), R15 /* prefetch abort */ MOVW 0x18(R15), R15 /* data abort */ MOVW 0x18(R15), R15 /* reserved */ MOVW 0x18(R15), R15 /* IRQ */ MOVW 0x18(R15), R15 /* FIQ */ TEXT vtable(SB), $-4 WORD $_vsvc(SB) /* reset, in svc mode already */ WORD $_vund(SB) /* undefined, switch to svc mode */ WORD $_vsvc(SB) /* swi, in svc mode already */ WORD $_vpab(SB) /* prefetch abort, switch to svc mode */ WORD $_vdab(SB) /* data abort, switch to svc mode */ WORD $_vsvc(SB) /* reserved */ WORD $_virq(SB) /* IRQ, switch to svc mode */ WORD $_vfiq(SB) /* FIQ, switch to svc mode */ TEXT _vund(SB), $-4 /* undefined */ MOVM.IA [R0-R3], (R13) MOVW $PsrMund, R0 B _vswitch TEXT _vsvc(SB), $-4 /* reset or SWI or reserved */ SUB $12, R13 MOVW R14, 8(R13) MOVW CPSR, R14 MOVW R14, 4(R13) MOVW $PsrMsvc, R14 MOVW R14, (R13) MOVW 8(R13), R14 B _vsaveu TEXT _vpab(SB), $-4 /* prefetch abort */ MOVM.IA [R0-R3], (R13) MOVW $PsrMabt, R0 B _vswitch TEXT _vdab(SB), $-4 /* data abort */ MOVM.IA [R0-R3], (R13) MOVW $(PsrMabt+1), R0 B _vswitch TEXT _virq(SB), $-4 /* IRQ */ MOVM.IA [R0-R3], (R13) MOVW $PsrMirq, R0 B _vswitch TEXT _vfiq(SB), $-4 /* FIQ */ MOVM.IA [R0-R3], (R13) MOVW $PsrMfiq, R0 B _vswitch _vswitch: /* switch to svc, type in R0 */ MOVW SPSR, R1 /* psr for ureg */ MOVW R14, R2 /* saved pc for ureg */ MOVW R13, R3 /* [R0-R3] save area */ MOVW CPSR, R14 /* switch */ BIC $PsrMask, R14 ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14 MOVW R14, CPSR MOVM.DB.W [R0-R2], (R13) /* top of ureg */ MOVM.IA (R3), [R0-R3] /* restore [R0-R3] */ B _vsaveu _vsaveu: SUB $4, R13 /* save link */ MOVW R14, (R13) MOVM.DB.W [R0-R14], (R13) /* save svc registers */ MOVW $setR12(SB), R12 /* safety */ MOVW R13, R0 /* argument is &ureg */ SUB $8, R13 /* space for argument+link */ BL exception(SB) _vrfe: ADD $(8+4*15), R13 /* [r0-R14]+argument+link */ MOVW (R13), R14 /* restore link */ MOVW 8(R13), R0 /* restore SPSR */ MOVW R0, SPSR MOVM.DB (R13), [R0-R14] /* restore registers */ ADD $12, R13 /* skip saved link+type+SPSR */ RFE /* MOVM.IA.S.W (R13), [R15] */ TEXT splhi(SB), $-4 MOVW CPSR, R0 ORR $(PsrDfiq|PsrDirq), R0, R1 MOVW R1, CPSR RET TEXT spllo(SB), $-4 MOVW CPSR, R0 BIC $(PsrDfiq|PsrDirq), R0, R1 MOVW R1, CPSR RET TEXT splx(SB), $-4 MOVW R0, R1 MOVW CPSR, R0 MOVW R1, CPSR RET TEXT islo(SB), $-4 MOVW CPSR, R0 AND $(PsrDfiq|PsrDirq), R0 EOR $(PsrDfiq|PsrDirq), R0 RET TEXT _exit(SB), $-4 MRC CpMMU, 0, R1, C(CpControl), C(0), 0 /* Read MMUCR */ BIC $MMUCR_M_ENABLE, R1 /* Clear MMU Enable bit */ MCR CpMMU, 0, R1, C(CpControl), C(0), 0 /* Write to MMU CR */ MCR CpMMU, 0, R1, C(CpIDCflush), C(7) /* Flush (inval) I,D-cache */ B (R0) TEXT cpsrr(SB), $-4 MOVW CPSR, R0 RET TEXT spsrr(SB), $-4 MOVW SPSR, R0 RET TEXT aamloop(SB), $-4 /* 3 */ _aamloop: MOVW R0, R0 /* 1 */ MOVW R0, R0 /* 1 */ MOVW R0, R0 /* 1 */ SUB $1, R0 /* 1 */ CMP $0, R0 /* 1 */ BNE _aamloop /* 3 */ RET /* 3 */ TEXT getcallerpc(SB), $-4 MOVW 0(R13), R0 RET TEXT tas(SB), $-4 MOVW R0, R1 MOVW $0xDEADDEAD, R2 SWPW R2, (R1), R0 RET TEXT setlabel(SB), $-4 MOVW R13, 0(R0) /* sp */ MOVW R14, 4(R0) /* pc */ MOVW $0, R0 RET TEXT gotolabel(SB), $-4 MOVW 0(R0), R13 /* sp */ MOVW 4(R0), R14 /* pc */ MOVW $1, R0 RET TEXT mmuctlregr(SB), $-4 MRC CpMMU, 0, R0, C(CpControl), C(0) RET TEXT mmuctlregw(SB), $-4 MCR CpMMU, 0, R0, C(CpControl), C(0) MOVW R0, R0 MOVW R0, R0 RET TEXT flushIcache(SB), $-4 MCR CpMMU, 0, R0, C(CpCacheCtl), C(5), 0 MOVW R0,R0 MOVW R0,R0 MOVW R0,R0 MOVW R0,R0 RET TEXT cleanDentry(SB), $-4 MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 1 RET TEXT flushDentry(SB), $-4 MCR CpMMU, 0, R0, C(CpCacheCtl), C(6), 1 RET TEXT drainWBuffer(SB), $-4 MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4 RET TEXT writeBackDC(SB), $-4 MOVW $0xE0000000, R0 MOVW $8192, R1 ADD R0, R1 wbflush: MOVW.P.W 32(R0), R2 CMP R1,R0 BNE wbflush RET TEXT flushDcache(SB), $-4 MCR CpMMU, 0, R0, C(CpCacheCtl), C(6), 0 RET TEXT writeBackBDC(SB), $-4 MOVW $0xE4000000, R0 MOVW $0x200, R1 ADD R0, R1 wbbflush: MOVW.P.W 32(R0), R2 CMP R1,R0 BNE wbbflush MCR CpMMU, 0, R0, C(CpCacheCtl), C(10), 4 MOVW R0,R0 MOVW R0,R0 MOVW R0,R0 MOVW R0,R0 RET TEXT flushIDC(SB), $-4 /*BUG*/ BL drainWBuffer(SB) BL writeBackDC(SB) BL flushDcache(SB) BL flushIcache(SB) RET
A bitsy/main.c => bitsy/main.c +16 -0
@@ 0,0 1,16 @@ #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "ureg.h" #include "init.h" #include "pool.h" Mach *m; void main(void) { }
A bitsy/mem.h => bitsy/mem.h +50 -0
@@ 0,0 1,50 @@ /* * Memory and machine-specific definitions. Used in C and assembler. */ /* * Sizes */ #define BI2BY 8 /* bits per byte */ #define BI2WD 32 /* bits per word */ #define BY2WD 4 /* bytes per word */ #define BY2V 8 /* bytes per double word */ #define BY2PG 4096 /* bytes per page */ #define WD2PG (BY2PG/BY2WD) /* words per page */ #define PGSHIFT 12 /* log(BY2PG) */ #define ROUND(s, sz) (((s)+(sz-1))&~(sz-1)) #define PGROUND(s) ROUND(s, BY2PG) #define MAXMACH 1 /* max # cpus system can run */ /* * Time */ #define HZ (100) /* clock frequency */ #define MS2HZ (1000/HZ) /* millisec per clock tick */ #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ #define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ #define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ /* * Address spaces */ #define KZERO 0x80000000 #define MACHADDR (KZERO+0x00001000) #define KTTB (KZERO+0x00004000) #define KTZERO (KZERO+0x00010000) #define KSTACK (16*1024) /* Size of kernel stack */ /* * virtual MMU */ #define PTEMAPMEM (1024*1024) #define PTEPERTAB (PTEMAPMEM/BY2PG) #define SEGMAPSIZE 1984 #define SSEGMAPSIZE 16 #define PPN(x) ((x)&~(BY2PG-1)) /* * physical MMU */