]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/devarch.c
etheriwl: implement 4965 firmware bootstrap (untested)
[plan9front.git] / sys / src / 9 / pc / devarch.c
index bd216c2ade583dc8709a746fdc09160a04db81f6..e877eab5feccae66490112e99a7bad628174d905 100644 (file)
@@ -33,6 +33,7 @@ enum {
        Qiob,
        Qiow,
        Qiol,
+       Qmsr,
        Qbase,
 
        Qmax = 16,
@@ -55,6 +56,7 @@ static Dirtab archdir[Qmax] = {
        "iob",          { Qiob, 0 },            0,      0660,
        "iow",          { Qiow, 0 },            0,      0660,
        "iol",          { Qiol, 0 },            0,      0660,
+       "msr",  { Qmsr, 0},     0,      0660,
 };
 Lock archwlock;        /* the lock is only for changing archdir */
 int narchdir = Qbase;
@@ -186,7 +188,7 @@ ioreserve(int, int size, int align, char *tag)
        m->start = port;
        m->end = port + size;
        m->reserved = 1;
-       strncpy(m->tag, tag, sizeof(m->tag));
+       strncpy(m->tag, tag, sizeof(m->tag)-1);
        m->tag[sizeof(m->tag)-1] = 0;
        *l = m;
 
@@ -236,7 +238,7 @@ ioalloc(int port, int size, int align, char *tag)
                        m = *l;
                        if(m->end <= port)
                                continue;
-                       if(m->reserved && m->start == port && m->end == port + size) {
+                       if(m->reserved && m->start == port && m->end >= port + size) {
                                m->reserved = 0;
                                unlock(&iomap);
                                return m->start;
@@ -257,7 +259,7 @@ ioalloc(int port, int size, int align, char *tag)
        m->next = *l;
        m->start = port;
        m->end = port + size;
-       strncpy(m->tag, tag, sizeof(m->tag));
+       strncpy(m->tag, tag, sizeof(m->tag)-1);
        m->tag[sizeof(m->tag)-1] = 0;
        *l = m;
 
@@ -356,6 +358,7 @@ archread(Chan *c, void *a, long n, vlong offset)
        int port;
        ushort *sp;
        ulong *lp;
+       vlong *vp;
        IOMap *m;
        Rdwrfn *fn;
 
@@ -389,6 +392,15 @@ archread(Chan *c, void *a, long n, vlong offset)
                        *lp++ = inl(port);
                return n;
 
+       case Qmsr:
+               if(n & 7)
+                       error(Ebadarg);
+               vp = a;
+               for(port = offset; port < offset+n; port += 8)
+                       if(rdmsr(port, vp++) < 0)
+                               error(Ebadarg);
+               return n;
+
        case Qioalloc:
                break;
 
@@ -429,6 +441,7 @@ archwrite(Chan *c, void *a, long n, vlong offset)
        int port;
        ushort *sp;
        ulong *lp;
+       vlong *vp;
        Rdwrfn *fn;
 
        switch((ulong)c->qid.path){
@@ -458,6 +471,15 @@ archwrite(Chan *c, void *a, long n, vlong offset)
                        outl(port, *lp++);
                return n;
 
+       case Qmsr:
+               if(n & 7)
+                       error(Ebadarg);
+               vp = a;
+               for(port = offset; port < offset+n; port += 8)
+                       if(wrmsr(port, *vp++) < 0)
+                               error(Ebadarg);
+               return n;
+
        default:
                if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
                        return fn(c, a, n, offset);
@@ -710,8 +732,8 @@ cpuidprint(void)
        if(m->cpuidid[0])
                i += sprint(buf+i, "%12.12s ", m->cpuidid);
        seprint(buf+i, buf + sizeof buf - 1,
-               "%s (cpuid: AX 0x%4.4uX DX 0x%4.4uX)\n",
-               m->cpuidtype, m->cpuidax, m->cpuiddx);
+               "%s (cpuid: AX 0x%4.4uX CX 0x%4.4uX DX 0x%4.4uX)\n",
+               m->cpuidtype, m->cpuidax, m->cpuidcx, m->cpuiddx);
        print(buf);
 }
 
@@ -744,6 +766,7 @@ cpuidentify(void)
 
        cpuid(Procsig, regs);
        m->cpuidax = regs[0];
+       m->cpuidcx = regs[2];
        m->cpuiddx = regs[3];
 
        if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0 ||
@@ -786,9 +809,9 @@ cpuidentify(void)
         * are supported enable them in CR4 and clear any other set extensions.
         * If machine check was enabled clear out any lingering status.
         */
-       if(m->cpuiddx & (Pge|Mce|0x8)){
+       if(m->cpuiddx & (Pge|Mce|Pse)){
                cr4 = 0;
-               if(m->cpuiddx & 0x08)
+               if(m->cpuiddx & Pse)
                        cr4 |= 0x10;            /* page size extensions */
                if(p = getconf("*nomce"))
                        nomce = strtoul(p, 0, 0);
@@ -849,7 +872,7 @@ archctlread(Chan*, void *a, long nn, vlong offset)
        int n;
        char *buf, *p, *ep;
 
-       p = buf = malloc(READSTR);
+       p = buf = smalloc(READSTR);
        ep = p + READSTR;
        p = seprint(p, ep, "cpu %s %lud%s\n",
                cputype->name, (ulong)(m->cpuhz+999999)/1000000,
@@ -967,6 +990,39 @@ archctlwrite(Chan*, void *a, long n, vlong)
        return n;
 }
 
+static long
+rmemrw(int isr, void *a, long n, vlong off)
+{
+       if(off < 0 || n < 0)
+               error("bad offset/count");
+       if(isr){
+               if(off >= MB)
+                       return 0;
+               if(off+n >= MB)
+                       n = MB - off;
+               memmove(a, KADDR((ulong)off), n);
+       }else{
+               /* allow vga framebuf's access */
+               if(off >= MB || off+n > MB ||
+                   (off < 0xA0000 || off+n > 0xB0000+0x10000))
+                       error("bad offset/count in write");
+               memmove(KADDR((ulong)off), a, n);
+       }
+       return n;
+}
+
+static long
+rmemread(Chan*, void *a, long n, vlong off)
+{
+       return rmemrw(1, a, n, off);
+}
+
+static long
+rmemwrite(Chan*, void *a, long n, vlong off)
+{
+       return rmemrw(0, a, n, off);
+}
+
 void
 archinit(void)
 {
@@ -1015,6 +1071,7 @@ archinit(void)
 
        addarchfile("cputype", 0444, cputyperead, nil);
        addarchfile("archctl", 0664, archctlread, archctlwrite);
+       addarchfile("realmodemem", 0660, rmemread, rmemwrite);
 }
 
 /*