Qiob,
Qiow,
Qiol,
+ Qmsr,
Qbase,
Qmax = 16,
"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;
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;
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;
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;
int port;
ushort *sp;
ulong *lp;
+ vlong *vp;
IOMap *m;
Rdwrfn *fn;
*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;
int port;
ushort *sp;
ulong *lp;
+ vlong *vp;
Rdwrfn *fn;
switch((ulong)c->qid.path){
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);
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);
}
cpuid(Procsig, regs);
m->cpuidax = regs[0];
+ m->cpuidcx = regs[2];
m->cpuiddx = regs[3];
if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0 ||
* 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);
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,
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)
{
addarchfile("cputype", 0444, cputyperead, nil);
addarchfile("archctl", 0664, archctlread, archctlwrite);
+ addarchfile("realmodemem", 0660, rmemread, rmemwrite);
}
/*