vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

commit 2c77246844ef513be4f03fd34c2dc656aed31b1c
parent adda469e79e83323a1244345fd8729e93fcef693
Author: yiyus <yiyu.jgl@gmail.com>
Date:   Tue, 20 Jul 2010 14:59:40 +0200

more work on a/

Diffstat:
src/9vx/a/dat.ed | 1-
src/9vx/a/devtls.ed | 1-
src/9vx/a/fault.c | 13+++++++++----
src/9vx/a/fault.ed | 88++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
src/9vx/a/fns.ed | 4++++
src/9vx/a/fns.h | 16++++++++++------
src/9vx/a/io.h | 4+++-
src/9vx/a/lib.ed | 1+
src/9vx/a/mem.h | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
src/9vx/a/memdraw.ed | 1+
src/9vx/makea | 11+++++++----
11 files changed, 215 insertions(+), 27 deletions(-)

diff --git a/src/9vx/a/dat.ed b/src/9vx/a/dat.ed @@ -10,7 +10,6 @@ v/typedef/ s!Lock;!Lock lk;!g Uspace *us; uchar *uzero; . -g/^#pragma/d g/mmufree/d g/mmuused/d g/lastkmap/d diff --git a/src/9vx/a/devtls.ed b/src/9vx/a/devtls.ed @@ -13,4 +13,3 @@ #endif . ,s/u32int/uint32/ -/^#pragma/d diff --git a/src/9vx/a/fault.c b/src/9vx/a/fault.c @@ -13,7 +13,10 @@ fault(ulong addr, int read) Segment *s; char *sps; -if(up->nlocks.ref) print("fault nlocks %ld\n", up->nlocks.ref); + if(up == nil) + panic("fault: nil up"); + if(up->nlocks.ref) + print("fault: nlocks %ld\n", up->nlocks.ref); sps = up->psstate; up->psstate = "Fault"; @@ -327,6 +330,7 @@ okaddr(ulong addr, ulong len, int write) ulong addr0; addr0 = addr; + if((long)len >= 0) { for(;;) { s = seg(up, addr, 1); @@ -336,6 +340,7 @@ okaddr(ulong addr, ulong len, int write) qunlock(&s->lk); break; } + if(addr+len > s->top) { len -= s->top - addr; addr = s->top; @@ -346,7 +351,7 @@ okaddr(ulong addr, ulong len, int write) return up->pmmu.uzero+addr0; } } - pprint("suicide: invalid address 0x%lux/%lud in sys call pc=0x%lux\n", addr, len, userpc()); + pprint("suicide: invalid address %#lux/%lud in sys call pc=%#lux\n", addr, len, userpc()); return 0; } @@ -381,7 +386,7 @@ uvalidaddr(ulong addr, ulong len, int write) } /* - * &s[0] is known to be a valid, translated address. + * &s[0] is known to be a valid address. */ void* vmemchr(void *s, int c, int n) @@ -404,7 +409,7 @@ vmemchr(void *s, int c, int n) } /* fits in one page */ - return memchr(a, c, n); + return memchr((void*)a, c, n); } Segment* diff --git a/src/9vx/a/fault.ed b/src/9vx/a/fault.ed @@ -1,18 +1,96 @@ +1i +#define WANT_M + +. ,s/lock(lkp)/lock(\&lkp->lk)/g -,s/lkp->ref\.ref/lkp->ref/g ,s/s->ref/s->ref.ref/g -/^validaddr/+3a +/^fault/ s/^// +/if(s == 0)/a +iprint("%ld %s fault %#x no segment\n", up->pid, up->text, addr); +{ Segment **s, **et, *n; + + et = &up->seg[NSEG]; + for(s = up->seg; s < et; s++) { + n = *s; + if(n == 0) + continue; + print("segment %#lux %#lux\n", n->base, n->top); + } +} +. +/qunlock(&s->lk)/a +iprint("%ld %s fault %#x write in read-only\n", up->pid, up->text, addr); +. +/done:/ s/$/;/ ++1;/^}/-1d +/^okaddr/-1c +void* +. +/^{/+1a + ulong addr0; + + addr0 = addr; +. +/s = seg/ s/0/1/ +/if(s == 0/;+1 c + if(s == 0) + break; + if(write && (s->type&SG_RONLY)){ + qunlock(&s->lk); + break; + } +. +/continue/i + qunlock(&s->lk); +. +/return/c + qunlock(&s->lk); + return up->pmmu.uzero+addr0; +. +/^validaddr/-1;+1 c +void* +uvalidaddr(ulong addr, ulong len, int write) +. +/okaddr/c + void *v; + + v = okaddr(addr, len, write); + if(v == nil) +. +/Suicide/a // This is a valid address, but the host kernel // might not know that. In case we're going // to pass the address to the host kernel in a // system call, fault in the pages. - volatile char *a = (char*)addr; + volatile char *a = v; ulong i; for(i=0; i<len; i+=BY2PG){ if(write) - *a = *a; + a[i] = a[i]; else - (void)*a; + (void)a[i]; } + if(len > 0){ + if(write) + a[len-1] = a[len-1]; + else + (void)a[len-1]; + } + return v; +. +/^vmemchr/ s/^// +/int m/ s/m/m_/ +/ulong a/ s/ulong /uchar */ +/a = (ulong)s/;/while/c + a = s; + while(PGROUND((ulong)a) != PGROUND((ulong)a+n-1)){ . +/m =/ s/m/m_/ +s/a/(ulong)a/ +/memchr/ s/m)/m_)/ +s/(void\*)a/a/ +/m;/ s/m/m_/ +/m;/ s/m/m_/ +/KZERO/ s/(.*)/(isuaddr(a))/ ++1 s/validaddr(.*)/uvalidaddr(a-up->pmmu.uzero, 1, 0)/ diff --git a/src/9vx/a/fns.ed b/src/9vx/a/fns.ed @@ -5,17 +5,21 @@ $a // Plan 9 VX additions void gotolabel(Label*); +int isuaddr(void*); void labelinit(Label *l, ulong pc, ulong sp); void latin1putc(int, void(*)(int)); void makekprocdev(Dev*); void newmach(void); void oserror(void); void oserrstr(void); +void restoretty(void); int setlabel(Label*); +void setsigsegv(int invx32); int tailkmesg(char*, int); void trap(Ureg*); void uartecho(char*, int); void uartinit(int); +void *uvalidaddr(ulong addr, ulong len, int write); #define GSHORT(p) (((p)[1]<<8)|(p)[0]) #define GLONG(p) ((GSHORT(p+2)<<16)|GSHORT(p)) diff --git a/src/9vx/a/fns.h b/src/9vx/a/fns.h @@ -9,7 +9,7 @@ void clockintr(Ureg*, void*); int (*cmpswap)(long*, long, long); int cmpswap486(long*, long, long); void (*coherence)(void); -void cpuid(char*, int*, int*); +void cpuid(int, ulong regs[]); int cpuidentify(void); void cpuidprint(void); void (*cycles)(uvlong*); @@ -80,6 +80,7 @@ void kbdinit(void); #define kmapinval() void lgdt(ushort[3]); void lidt(ushort[3]); +void links(void); void ltr(ulong); void mach0init(void); void mathinit(void); @@ -90,6 +91,9 @@ void memorysummary(void); #define mmuflushtlb(pdb) putcr3(pdb) void mmuinit(void); ulong* mmuwalk(ulong*, ulong, int, int); +int mtrr(uvlong, uvlong, char *); +void mtrrclock(void); +int mtrrprint(char *, long); uchar nvramread(int); void nvramwrite(int, uchar); void outb(int, int); @@ -112,6 +116,7 @@ int pdbmap(ulong*, ulong, ulong, int); void procrestore(Proc*); void procsave(Proc*); void procsetup(Proc*); +void putcr0(ulong); void putcr3(ulong); void putcr4(ulong); void* rampage(void); @@ -140,6 +145,7 @@ void vectortable(void); void* vmap(ulong, int); int vmapsync(ulong); void vunmap(void*, int); +void wbinvd(void); void wrmsr(int, vlong); int xchgw(ushort*, int); @@ -151,20 +157,21 @@ int xchgw(ushort*, int); // Plan 9 VX additions void gotolabel(Label*); +int isuaddr(void*); void labelinit(Label *l, ulong pc, ulong sp); void latin1putc(int, void(*)(int)); void makekprocdev(Dev*); void newmach(void); void oserror(void); void oserrstr(void); +void restoretty(void); int setlabel(Label*); +void setsigsegv(int invx32); int tailkmesg(char*, int); void trap(Ureg*); void uartecho(char*, int); void uartinit(int); void *uvalidaddr(ulong addr, ulong len, int write); -int isuaddr(void*); -void setsigsegv(int invx32); #define GSHORT(p) (((p)[1]<<8)|(p)[0]) #define GLONG(p) ((GSHORT(p+2)<<16)|GSHORT(p)) @@ -174,8 +181,6 @@ void __punlock(Psleep*); void __pwakeup(Psleep*); void __psleep(Psleep*); -void restoretty(void); - extern int tracelock; #define lockfngen(type) __ ## type @@ -217,4 +222,3 @@ extern int tracelock; #define RUNLOCK(x) runlock(&((x)->rwlock)) #define WLOCK(x) wlock(&((x)->rwlock)) #define WUNLOCK(x) wunlock(&((x)->rwlock)) - diff --git a/src/9vx/a/io.h b/src/9vx/a/io.h @@ -1,5 +1,6 @@ #define X86STEPPING(x) ((x) & 0x0F) -#define X86MODEL(x) (((x)>>4) & 0x0F) +/* incorporate extended-model bits */ +#define X86MODEL(x) ((((x)>>4) & 0x0F) | (((x)>>16) & 0x0F)<<4) #define X86FAMILY(x) (((x)>>8) & 0x0F) enum { @@ -366,3 +367,4 @@ struct PCMslot int time; PCMmap mmap[4]; /* maps, last is always for the kernel */ }; + diff --git a/src/9vx/a/lib.ed b/src/9vx/a/lib.ed @@ -1,4 +1,5 @@ g/assert/d +g/encodefmt/d g/memccpy/d g/memset/d g/memcmp/d diff --git a/src/9vx/a/mem.h b/src/9vx/a/mem.h @@ -18,24 +18,109 @@ #define BLOCKALIGN 8 #define MAXMACH 128 /* max # cpus system can run */ -#define KSTACK (1024*1024) /* Size of kernel stack */ +#define KSTACK 65536 /* Size of kernel stack */ /* * Time */ -#define HZ (1000) /* clock frequency */ +#define HZ (100) /* clock frequency */ #define MS2HZ (1000/HZ) /* millisec per clock tick */ #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ /* - * Address spaces - only user code! + * Address spaces */ +#define KZERO 0x80000000 /* base of kernel address space */ +#define KTZERO (KZERO+0x100000) /* first address in kernel text - 9load sits below */ +#define VPT (KZERO-VPTSIZE) +#define VPTSIZE BY2XPG +#define NVPT (VPTSIZE/BY2WD) +#define KMAP (VPT-KMAPSIZE) +#define KMAPSIZE BY2XPG +#define VMAP (KMAP-VMAPSIZE) +#define VMAPSIZE (0x10000000-VPTSIZE-KMAPSIZE) #define UZERO 0 /* base of user address space */ #define UTZERO (UZERO+BY2PG) /* first address in user text */ -#define USTKTOP (0x10000000) /* byte just beyond user stack */ +#define USTKTOP (0x4000000) /* byte just beyond user stack */ #define USTKSIZE (16*1024*1024) /* size of user stack */ #define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */ -#define TSTKSIZ 100 +#define TSTKSIZ 100 /* pages in new stack; limits exec args */ + +/* + * Fundamental addresses - bottom 64kB saved for return to real mode + */ +#define CONFADDR (KZERO+0x1200) /* info passed from boot loader */ +#define TMPADDR (KZERO+0x2000) /* used for temporary mappings */ +#define APBOOTSTRAP (KZERO+0x3000) /* AP bootstrap code */ +#define RMUADDR (KZERO+0x7C00) /* real mode Ureg */ +#define RMCODE (KZERO+0x8000) /* copy of first page of KTEXT */ +#define RMBUF (KZERO+0x9000) /* buffer for user space - known to vga */ +#define IDTADDR (KZERO+0x10800) /* idt */ +#define REBOOTADDR (0x11000) /* reboot code - physical address */ +#define CPU0PDB (KZERO+0x12000) /* bootstrap processor PDB */ +#define CPU0PTE (KZERO+0x13000) /* bootstrap processor PTE's for 0-4MB */ +#define CPU0GDT (KZERO+0x14000) /* bootstrap processor GDT */ +#define MACHADDR (KZERO+0x15000) /* as seen by current processor */ +#define CPU0MACH (KZERO+0x16000) /* Mach for bootstrap processor */ +#define MACHSIZE BY2PG +#define CPU0PTE1 (KZERO+0x17000) /* bootstrap processor PTE's for 4MB-8MB */ +#define CPU0END (CPU0PTE1+BY2PG) +/* + * N.B. ramscan knows that CPU0END is the end of reserved data + * N.B. _startPADDR knows that CPU0PDB is the first reserved page + * and that there are 6 of them. + */ + +/* + * known x86 segments (in GDT) and their selectors + */ +#define NULLSEG 0 /* null segment */ +#define KDSEG 1 /* kernel data/stack */ +#define KESEG 2 /* kernel executable */ +#define UDSEG 3 /* user data/stack */ +#define UESEG 4 /* user executable */ +#define TSSSEG 5 /* task segment */ +#define APMCSEG 6 /* APM code segment */ +#define APMCSEG16 7 /* APM 16-bit code segment */ +#define APMDSEG 8 /* APM data segment */ +#define KESEG16 9 /* kernel executable 16-bit */ +#define NGDT 10 /* number of GDT entries required */ + +#define SELGDT (0<<2) /* selector is in gdt */ +#define SELLDT (1<<2) /* selector is in ldt */ + +#define SELECTOR(i, t, p) (((i)<<3) | (t) | (p)) + +#define NULLSEL SELECTOR(NULLSEG, SELGDT, 0) +#define KDSEL SELECTOR(KDSEG, SELGDT, 0) +#define KESEL SELECTOR(KESEG, SELGDT, 0) +#define UESEL SELECTOR(UESEG, SELGDT, 3) +#define UDSEL SELECTOR(UDSEG, SELGDT, 3) +#define TSSSEL SELECTOR(TSSSEG, SELGDT, 0) +#define APMCSEL SELECTOR(APMCSEG, SELGDT, 0) +#define APMCSEL16 SELECTOR(APMCSEG16, SELGDT, 0) +#define APMDSEL SELECTOR(APMDSEG, SELGDT, 0) +/* #define APM40SEL SELECTOR(APM40SEG, SELGDT, 0) */ + +/* + * fields in segment descriptors + */ +#define SEGDATA (0x10<<8) /* data/stack segment */ +#define SEGEXEC (0x18<<8) /* executable segment */ +#define SEGTSS (0x9<<8) /* TSS segment */ +#define SEGCG (0x0C<<8) /* call gate */ +#define SEGIG (0x0E<<8) /* interrupt gate */ +#define SEGTG (0x0F<<8) /* trap gate */ +#define SEGTYPE (0x1F<<8) + +#define SEGP (1<<15) /* segment present */ +#define SEGPL(x) ((x)<<13) /* priority level */ +#define SEGB (1<<22) /* granularity 1==4k (for expand-down) */ +#define SEGG (1<<23) /* granularity 1==4k (for other) */ +#define SEGE (1<<10) /* expand down */ +#define SEGW (1<<9) /* writable (for data/stack) */ +#define SEGR (1<<9) /* readable (for code) */ +#define SEGD (1<<22) /* default 1==32bit (for code) */ /* * virtual MMU @@ -59,5 +144,12 @@ #define PTESIZE (1<<7) #define PTEGLOBAL (1<<8) +/* + * Macros for calculating offsets within the page directory base + * and page tables. + */ +#define PDX(va) ((((ulong)(va))>>22) & 0x03FF) +#define PTX(va) ((((ulong)(va))>>12) & 0x03FF) + #define getpgcolor(a) 0 diff --git a/src/9vx/a/memdraw.ed b/src/9vx/a/memdraw.ed @@ -25,3 +25,4 @@ extern ulong imgtorgba(Memimage*, ulong); Fullsrc=1<<4, Fullmask=1<<5, . +,s/ulong/uint32/g diff --git a/src/9vx/makea b/src/9vx/makea @@ -11,9 +11,11 @@ if [ $# -gt 0 ]; then shift fi fi -orig=$orig/sys/src/9 +port=$orig/sys/src/9/port +pc=$orig/sys/src/9/pc +inc=$orig/sys/include -if [ ! -d $orig ]; then +if [ ! -d $port -a -d $pc -a -d $inc ]; then echo "Error: $orig is not a valid Plan9 root" 1>&2 exit 1 fi @@ -22,13 +24,14 @@ files=a/*.ed if [ $# -gt 0 ]; then files=$* fi -hfiles=a/*.h +hfiles="a/*.h *.h" for f in $files; do name=`echo $f | sed 's,.*/,,;s,\.ed,,'` - ofile=`(ls $orig/port/$name.[ch] || ls $orig/pc/$name.[ch]) 2>/dev/null` + ofile=`ls $port/$name.[ch] $pc/$name.[ch] $inc/$name.h 2>/dev/null | sed 1q` dfile=`echo $ofile | sed 's,.*/,a/,'` echo -e ",p\nq" | cat $f - | ed -s $ofile | sed -r ' /^#include/s,../port/,, /^#include[ ]+<('`echo $hfiles | sed 's,a/,,g; s/\./\\./g; s/ /|/g'`')>/s,[<>],",g +/^#pragma/d ' > $dfile done