kernel: use monitor/mwait instruction on pc multiprocessor for idlehands
This commit is contained in:
parent
3ce608921a
commit
aa015b1c4f
|
@ -218,6 +218,7 @@ struct Mach
|
||||||
uvlong cyclefreq; /* Frequency of user readable cycle counter */
|
uvlong cyclefreq; /* Frequency of user readable cycle counter */
|
||||||
uvlong cpuhz;
|
uvlong cpuhz;
|
||||||
int cpuidax;
|
int cpuidax;
|
||||||
|
int cpuidcx;
|
||||||
int cpuiddx;
|
int cpuiddx;
|
||||||
char cpuidid[16];
|
char cpuidid[16];
|
||||||
char* cpuidtype;
|
char* cpuidtype;
|
||||||
|
@ -277,6 +278,9 @@ struct PCArch
|
||||||
|
|
||||||
/* cpuid instruction result register bits */
|
/* cpuid instruction result register bits */
|
||||||
enum {
|
enum {
|
||||||
|
/* cx */
|
||||||
|
Monitor = 1<<3,
|
||||||
|
|
||||||
/* dx */
|
/* dx */
|
||||||
Fpuonchip = 1<<0,
|
Fpuonchip = 1<<0,
|
||||||
// Pse = 1<<3, /* page size extensions */
|
// Pse = 1<<3, /* page size extensions */
|
||||||
|
|
|
@ -732,8 +732,8 @@ cpuidprint(void)
|
||||||
if(m->cpuidid[0])
|
if(m->cpuidid[0])
|
||||||
i += sprint(buf+i, "%12.12s ", m->cpuidid);
|
i += sprint(buf+i, "%12.12s ", m->cpuidid);
|
||||||
seprint(buf+i, buf + sizeof buf - 1,
|
seprint(buf+i, buf + sizeof buf - 1,
|
||||||
"%s (cpuid: AX 0x%4.4uX DX 0x%4.4uX)\n",
|
"%s (cpuid: AX 0x%4.4uX CX 0x%4.4uX DX 0x%4.4uX)\n",
|
||||||
m->cpuidtype, m->cpuidax, m->cpuiddx);
|
m->cpuidtype, m->cpuidax, m->cpuidcx, m->cpuiddx);
|
||||||
print(buf);
|
print(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,6 +766,7 @@ cpuidentify(void)
|
||||||
|
|
||||||
cpuid(Procsig, regs);
|
cpuid(Procsig, regs);
|
||||||
m->cpuidax = regs[0];
|
m->cpuidax = regs[0];
|
||||||
|
m->cpuidcx = regs[2];
|
||||||
m->cpuiddx = regs[3];
|
m->cpuiddx = regs[3];
|
||||||
|
|
||||||
if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0 ||
|
if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0 ||
|
||||||
|
|
|
@ -42,6 +42,7 @@ ulong getcr4(void);
|
||||||
char* getconf(char*);
|
char* getconf(char*);
|
||||||
void guesscpuhz(int);
|
void guesscpuhz(int);
|
||||||
void halt(void);
|
void halt(void);
|
||||||
|
void mwait(void*);
|
||||||
int i8042auxcmd(int);
|
int i8042auxcmd(int);
|
||||||
int i8042auxcmds(uchar*, int);
|
int i8042auxcmds(uchar*, int);
|
||||||
void i8042auxenable(void (*)(int, int));
|
void i8042auxenable(void (*)(int, int));
|
||||||
|
|
|
@ -855,6 +855,21 @@ _nothingready:
|
||||||
HLT
|
HLT
|
||||||
RET
|
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.
|
* Interrupt/exception handling.
|
||||||
* Each entry in the vector table calls either _strayintr or _strayintrx depending
|
* Each entry in the vector table calls either _strayintr or _strayintrx depending
|
||||||
|
|
|
@ -868,6 +868,10 @@ cistrncmp(char *a, char *b, int n)
|
||||||
void
|
void
|
||||||
idlehands(void)
|
idlehands(void)
|
||||||
{
|
{
|
||||||
|
extern int nrdy;
|
||||||
|
|
||||||
if(conf.nmach == 1)
|
if(conf.nmach == 1)
|
||||||
halt();
|
halt();
|
||||||
|
else if(m->cpuidcx & Monitor)
|
||||||
|
mwait(&nrdy);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue