more work on a/ - vx32 - Local 9vx git repository for patches.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit 2c77246844ef513be4f03fd34c2dc656aed31b1c
 (DIR) parent adda469e79e83323a1244345fd8729e93fcef693
 (HTM) 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(-)
       ---
 (DIR) 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
 (DIR) diff --git a/src/9vx/a/devtls.ed b/src/9vx/a/devtls.ed
       @@ -13,4 +13,3 @@
        #endif
        .
        ,s/u32int/uint32/
       -/^#pragma/d
 (DIR) 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*
 (DIR) 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)/
 (DIR) 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))
 (DIR) 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))
       -
 (DIR) 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 */
        };
       +
 (DIR) 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
 (DIR) 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
        
 (DIR) 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
 (DIR) 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