ref: 4474fc6f24a5cdc319a3937884f51380a15717b2
parent: 751d73c598ddac68c4204c9dd38f9a1ee6168e73
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Fri May 4 07:02:11 EDT 2012
kernel: use monitor/mwait instruction on pc multiprocessor for idlehands
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -218,6 +218,7 @@
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 @@
/* cpuid instruction result register bits */
enum {+ /* cx */
+ Monitor = 1<<3,
+
/* dx */
Fpuonchip = 1<<0,
// Pse = 1<<3, /* page size extensions */
--- a/sys/src/9/pc/devarch.c
+++ b/sys/src/9/pc/devarch.c
@@ -732,8 +732,8 @@
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 @@
cpuid(Procsig, regs);
m->cpuidax = regs[0];
+ m->cpuidcx = regs[2];
m->cpuiddx = regs[3];
if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0 ||
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -42,6 +42,7 @@
char* getconf(char*);
void guesscpuhz(int);
void halt(void);
+void mwait(void*);
int i8042auxcmd(int);
int i8042auxcmds(uchar*, int);
void i8042auxenable(void (*)(int, int));
--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -855,6 +855,21 @@
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
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -868,6 +868,10 @@
void
idlehands(void)
{+ extern int nrdy;
+
if(conf.nmach == 1)
halt();
+ else if(m->cpuidcx & Monitor)
+ mwait(&nrdy);
}
--
⑨