X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2F9%2Fpc%2Fdevarch.c;h=e877eab5feccae66490112e99a7bad628174d905;hb=97d136fb21aa6068825c4fda5a7936ba98743ac2;hp=bd216c2ade583dc8709a746fdc09160a04db81f6;hpb=e5888a1ffdae813d7575f5fb02275c6bb07e5199;p=plan9front.git diff --git a/sys/src/9/pc/devarch.c b/sys/src/9/pc/devarch.c old mode 100755 new mode 100644 index bd216c2ad..e877eab5f --- a/sys/src/9/pc/devarch.c +++ b/sys/src/9/pc/devarch.c @@ -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); } /*