diff --git a/sys/src/9/pc/dat.h b/sys/src/9/pc/dat.h index 13c8a2a80..41393043e 100644 --- a/sys/src/9/pc/dat.h +++ b/sys/src/9/pc/dat.h @@ -218,6 +218,7 @@ struct Mach uvlong cyclefreq; /* Frequency of user readable cycle counter */ uvlong cpuhz; int cpuidax; + int cpuidcx; int cpuiddx; char cpuidid[16]; char* cpuidtype; @@ -277,6 +278,9 @@ struct PCArch /* cpuid instruction result register bits */ enum { + /* cx */ + Monitor = 1<<3, + /* dx */ Fpuonchip = 1<<0, // Pse = 1<<3, /* page size extensions */ diff --git a/sys/src/9/pc/devarch.c b/sys/src/9/pc/devarch.c index 5c714984b..20dc87923 100644 --- a/sys/src/9/pc/devarch.c +++ b/sys/src/9/pc/devarch.c @@ -732,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); } @@ -766,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 || diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h index 0c1774a32..06ce8f8ef 100644 --- a/sys/src/9/pc/fns.h +++ b/sys/src/9/pc/fns.h @@ -42,6 +42,7 @@ ulong getcr4(void); char* getconf(char*); void guesscpuhz(int); void halt(void); +void mwait(void*); int i8042auxcmd(int); int i8042auxcmds(uchar*, int); void i8042auxenable(void (*)(int, int)); diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s index 8926cc4c3..d3e5f5201 100644 --- a/sys/src/9/pc/l.s +++ b/sys/src/9/pc/l.s @@ -855,6 +855,21 @@ _nothingready: HLT RET +TEXT mwait(SB), $0 + MOVL addr+0(FP), AX + MOVL (AX), CX + ORL CX, CX + JNZ _mwaitdone + XORL DX, DX + BYTE $0x0f; BYTE $0x01; BYTE $0xc8 /* MONITOR */ + MOVL (AX), CX + ORL CX, CX + JNZ _mwaitdone + XORL AX, AX + BYTE $0x0f; BYTE $0x01; BYTE $0xc9 /* MWAIT */ +_mwaitdone: + RET + /* * Interrupt/exception handling. * Each entry in the vector table calls either _strayintr or _strayintrx depending diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c index 2fecf5df0..1ea96d6c7 100644 --- a/sys/src/9/pc/main.c +++ b/sys/src/9/pc/main.c @@ -868,6 +868,10 @@ cistrncmp(char *a, char *b, int n) void idlehands(void) { + extern int nrdy; + if(conf.nmach == 1) halt(); + else if(m->cpuidcx & Monitor) + mwait(&nrdy); }