pc64: implement shutdown and idlehands

just copies from pc kernel. should refactor into common
pc code.
This commit is contained in:
cinap_lenrek 2014-02-03 05:29:53 +01:00
parent ddd51650d8
commit c3028fb924
2 changed files with 91 additions and 12 deletions

View file

@ -331,10 +331,20 @@ TEXT mb586(SB), 1, $-4
CPUID
RET
/*
* Park a processor. Should never fall through a return from main to here,
* should only be called by application processors when shutting down.
*/
TEXT idle(SB), 1, $-4
_idle:
STI
HLT
JMP _idle
/*
* BIOS32.
*/
TEXT bios32call(SB), 1, $-1
TEXT bios32call(SB), 1, $-4
XORL AX, AX
INCL AX
RET
@ -526,14 +536,30 @@ TEXT setlabel(SB), 1, $-4
MOVL $0, AX /* return 0 */
RET
TEXT idle(SB), $0
_idle:
TEXT halt(SB), 1, $-4
CLI
CMPL nrdy(SB), $0
JEQ _nothingready
STI
RET
_nothingready:
STI
HLT
JMP _idle
RET
TEXT halt(SB), 1, $-4
HLT
TEXT mwait(SB), 1, $-4
MOVQ RARG, 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
/*

View file

@ -26,6 +26,8 @@ char *confname[MAXCONF];
char *confval[MAXCONF];
int nconf;
int delaylink;
int idle_spin;
uchar *sp; /* user stack of init proc */
extern void (*i8237alloc)(void);
@ -419,12 +421,56 @@ main()
schedinit();
}
void
exit(int)
static void
shutdown(int ispanic)
{
print("exit\n");
splhi();
for(;;);
int ms, once;
lock(&active);
if(ispanic)
active.ispanic = ispanic;
else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
active.ispanic = 0;
once = active.machs & (1<<m->machno);
/*
* setting exiting will make hzclock() on each processor call exit(0),
* which calls shutdown(0) and arch->reset(), which on mp systems is
* mpshutdown, from which there is no return: the processor is idled
* or initiates a reboot. clearing our bit in machs avoids calling
* exit(0) from hzclock() on this processor.
*/
active.machs &= ~(1<<m->machno);
active.exiting = 1;
unlock(&active);
if(once)
iprint("cpu%d: exiting\n", m->machno);
/* wait for any other processors to shutdown */
spllo();
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
delay(TK2MS(2));
if(active.machs == 0 && consactive() == 0)
break;
}
if(active.ispanic){
if(!cpuserver)
for(;;)
halt();
if(getconf("*debug"))
delay(5*60*1000);
else
delay(10000);
}else
delay(1000);
}
void
exit(int ispanic)
{
shutdown(ispanic);
arch->reset();
}
void
@ -436,7 +482,14 @@ reboot(void*, void*, ulong)
void
idlehands(void)
{
halt();
extern int nrdy;
if(conf.nmach == 1)
halt();
else if(m->cpuidcx & Monitor)
mwait(&nrdy);
else if(idle_spin == 0)
halt();
}
/*