commit 2c77246844ef513be4f03fd34c2dc656aed31b1c
parent adda469e79e83323a1244345fd8729e93fcef693
Author: yiyus <yiyu.jgl@gmail.com>
Date: Tue, 20 Jul 2010 14:59:40 +0200
more work on a/
Diffstat:
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