]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/devarch.c
kernel: cleanup the software mouse cursor mess
[plan9front.git] / sys / src / 9 / pc / devarch.c
index 9ea14d06d50d7a6ce9561f3018b1758a2187c210..2da6f5d556590560a186c954ea46e777f605ab63 100644 (file)
@@ -309,8 +309,11 @@ iounused(int start, int end)
 }
 
 static void
-checkport(int start, int end)
+checkport(uint start, uint end)
 {
+       if(end < start || end > 0x10000)
+               error(Ebadarg);
+
        /* standard vga regs are OK */
        if(start >= 0x2b0 && end <= 0x2df+1)
                return;
@@ -355,47 +358,49 @@ static long
 archread(Chan *c, void *a, long n, vlong offset)
 {
        char buf[32], *p;
-       int port, i;
+       uint port, end;
        ushort *sp;
        ulong *lp;
        vlong *vp;
        IOMap *m;
        Rdwrfn *fn;
+       int i;
 
+       port = offset;
+       end = port+n;
        switch((ulong)c->qid.path){
        case Qdir:
                return devdirread(c, a, n, archdir, narchdir, devgen);
 
        case Qiob:
-               port = offset;
-               checkport(offset, offset+n);
-               for(p = a; port < offset+n; port++)
+               checkport(port, end);
+               for(p = a; port < end; port++)
                        *p++ = inb(port);
                return n;
 
        case Qiow:
                if(n & 1)
                        error(Ebadarg);
-               checkport(offset, offset+n);
-               sp = a;
-               for(port = offset; port < offset+n; port += 2)
+               checkport(port, end);
+               for(sp = a; port < end; port += 2)
                        *sp++ = ins(port);
                return n;
 
        case Qiol:
                if(n & 3)
                        error(Ebadarg);
-               checkport(offset, offset+n);
-               lp = a;
-               for(port = offset; port < offset+n; port += 4)
+               checkport(port, end);
+               for(lp = a; port < end; port += 4)
                        *lp++ = inl(port);
                return n;
 
        case Qmsr:
                if(n & 7)
                        error(Ebadarg);
-               vp = a;
-               for(port = offset; port < offset+n; port += 8)
+               if((uint)n/8 > -port)
+                       error(Ebadarg);
+               end = port+(n/8);
+               for(vp = a; port != end; port++)
                        if(rdmsr(port, vp++) < 0)
                                error(Ebadarg);
                return n;
@@ -404,7 +409,8 @@ archread(Chan *c, void *a, long n, vlong offset)
                lock(&iomap);
                i = 0;
                for(m = iomap.m; m != nil; m = m->next){
-                       i = snprint(buf, sizeof(buf), "%8lux %8lux %-12.12s\n", m->start, m->end-1, m->tag);
+                       i = snprint(buf, sizeof(buf), "%8lux %8lux %-12.12s\n",
+                               m->start, m->end-1, m->tag);
                        offset -= i;
                        if(offset < 0)
                                break;
@@ -429,44 +435,45 @@ archread(Chan *c, void *a, long n, vlong offset)
 static long
 archwrite(Chan *c, void *a, long n, vlong offset)
 {
+       uint port, end;
        char *p;
-       int port;
        ushort *sp;
        ulong *lp;
        vlong *vp;
        Rdwrfn *fn;
 
+       port = offset;
+       end = port+n;
        switch((ulong)c->qid.path){
        case Qiob:
-               p = a;
-               checkport(offset, offset+n);
-               for(port = offset; port < offset+n; port++)
+               checkport(port, end);
+               for(p = a; port < end; port++)
                        outb(port, *p++);
                return n;
 
        case Qiow:
                if(n & 1)
                        error(Ebadarg);
-               checkport(offset, offset+n);
-               sp = a;
-               for(port = offset; port < offset+n; port += 2)
+               checkport(port, end);
+               for(sp = a; port < end; port += 2)
                        outs(port, *sp++);
                return n;
 
        case Qiol:
                if(n & 3)
                        error(Ebadarg);
-               checkport(offset, offset+n);
-               lp = a;
-               for(port = offset; port < offset+n; port += 4)
+               checkport(port, end);
+               for(lp = a; port < end; port += 4)
                        outl(port, *lp++);
                return n;
 
        case Qmsr:
                if(n & 7)
                        error(Ebadarg);
-               vp = a;
-               for(port = offset; port < offset+n; port += 8)
+               if((uint)n/8 > -port)
+                       error(Ebadarg);
+               end = port+(n/8);
+               for(vp = a; port != end; port++)
                        if(wrmsr(port, *vp++) < 0)
                                error(Ebadarg);
                return n;
@@ -677,6 +684,7 @@ static X86type x86amd[] =
        { 6,    -1,     11,     "AMD-Athlon", },/* guesswork */
        { 0xF,  -1,     11,     "AMD-K8", },    /* guesswork */
        { 0x1F, -1,     11,     "AMD-K10", },   /* guesswork */
+       { 23,   1,      13,     "AMD Ryzen" },
 
        { -1,   -1,     11,     "unknown", },   /* total default */
 };
@@ -753,6 +761,19 @@ cpuidentify(void)
        m->cpuidax = regs[0];
        m->cpuidcx = regs[2];
        m->cpuiddx = regs[3];
+       
+       m->cpuidfamily = m->cpuidax >> 8 & 0xf;
+       m->cpuidmodel = m->cpuidax >> 4 & 0xf;
+       m->cpuidstepping = m->cpuidax & 0xf;
+       switch(m->cpuidfamily){
+       case 15:
+               m->cpuidfamily += m->cpuidax >> 20 & 0xff;
+               m->cpuidmodel += m->cpuidax >> 16 & 0xf;
+               break;
+       case 6:
+               m->cpuidmodel += m->cpuidax >> 16 & 0xf;
+               break;
+       }
 
        if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0 ||
           strncmp(m->cpuidid, "Geode by NSC", 12) == 0)
@@ -764,8 +785,8 @@ cpuidentify(void)
        else
                tab = x86intel;
 
-       family = X86FAMILY(m->cpuidax);
-       model = X86MODEL(m->cpuidax);
+       family = m->cpuidfamily;
+       model = m->cpuidmodel;
        for(t=tab; t->name; t++)
                if((t->family == family && t->model == model)
                || (t->family == family && t->model == -1)
@@ -878,10 +899,26 @@ cpuidentify(void)
        else
                hwrandbuf = nil;
        
-       /* 8-byte watchpoints are supported in Long Mode */
-       if(sizeof(uintptr) == 8)
+       if(sizeof(uintptr) == 8) {
+               /* 8-byte watchpoints are supported in Long Mode */
                m->havewatchpt8 = 1;
-       else if(strcmp(m->cpuidid, "GenuineIntel") == 0){
+
+               /* check and enable NX bit */
+               cpuid(Highextfunc, regs);
+               if(regs[0] >= Procextfeat){
+                       cpuid(Procextfeat, regs);
+                       if((regs[3] & (1<<20)) != 0){
+                               vlong efer;
+
+                               /* enable no-execute feature */
+                               if(rdmsr(Efer, &efer) != -1){
+                                       efer |= 1ull<<11;
+                                       if(wrmsr(Efer, efer) != -1)
+                                               m->havenx = 1;
+                               }
+                       }
+               }
+       } else if(strcmp(m->cpuidid, "GenuineIntel") == 0){
                /* some random CPUs that support 8-byte watchpoints */
                if(family == 15 && (model == 3 || model == 4 || model == 6)
                || family == 6 && (model == 15 || model == 23 || model == 28))
@@ -994,7 +1031,7 @@ archctlwrite(Chan*, void *a, long n, vlong)
                if(strcmp(cb->f[1], "mb386") == 0)
                        coherence = mb386;
                else if(strcmp(cb->f[1], "mb586") == 0){
-                       if(X86FAMILY(m->cpuidax) < 5)
+                       if(m->cpuidfamily < 5)
                                error("invalid coherence ctl on this cpu family");
                        coherence = mb586;
                }else if(strcmp(cb->f[1], "mfence") == 0){
@@ -1093,13 +1130,13 @@ archinit(void)
         *  We get another chance to set it in mpinit() for a
         *  multiprocessor.
         */
-       if(X86FAMILY(m->cpuidax) == 3)
+       if(m->cpuidfamily == 3)
                conf.copymode = 1;
 
-       if(X86FAMILY(m->cpuidax) >= 4)
+       if(m->cpuidfamily >= 4)
                cmpswap = cmpswap486;
 
-       if(X86FAMILY(m->cpuidax) >= 5)
+       if(m->cpuidfamily >= 5)
                coherence = mb586;
 
        if(m->cpuiddx & Sse2)