merge
This commit is contained in:
commit
35d19fc6fb
4 changed files with 142 additions and 156 deletions
|
@ -1133,3 +1133,62 @@ timerset(Tval x)
|
||||||
if(doi8253set)
|
if(doi8253set)
|
||||||
(*arch->timerset)(x);
|
(*arch->timerset)(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* put the processor in the halt state if we've no processes to run.
|
||||||
|
* an interrupt will get us going again.
|
||||||
|
*
|
||||||
|
* halting in an smp system can result in a startup latency for
|
||||||
|
* processes that become ready.
|
||||||
|
* if idle_spin is zero, we care more about saving energy
|
||||||
|
* than reducing this latency.
|
||||||
|
*
|
||||||
|
* the performance loss with idle_spin == 0 seems to be slight
|
||||||
|
* and it reduces lock contention (thus system time and real time)
|
||||||
|
* on many-core systems with large values of NPROC.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
idlehands(void)
|
||||||
|
{
|
||||||
|
extern int nrdy, idle_spin;
|
||||||
|
|
||||||
|
if(conf.nmach == 1)
|
||||||
|
halt();
|
||||||
|
else if(m->cpuidcx & Monitor)
|
||||||
|
mwait(&nrdy);
|
||||||
|
else if(idle_spin == 0)
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
isaconfig(char *class, int ctlrno, ISAConf *isa)
|
||||||
|
{
|
||||||
|
char cc[32], *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
|
||||||
|
p = getconf(cc);
|
||||||
|
if(p == nil)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
isa->type = "";
|
||||||
|
isa->nopt = tokenize(p, isa->opt, NISAOPT);
|
||||||
|
for(i = 0; i < isa->nopt; i++){
|
||||||
|
p = isa->opt[i];
|
||||||
|
if(cistrncmp(p, "type=", 5) == 0)
|
||||||
|
isa->type = p + 5;
|
||||||
|
else if(cistrncmp(p, "port=", 5) == 0)
|
||||||
|
isa->port = strtoul(p+5, &p, 0);
|
||||||
|
else if(cistrncmp(p, "irq=", 4) == 0)
|
||||||
|
isa->irq = strtoul(p+4, &p, 0);
|
||||||
|
else if(cistrncmp(p, "dma=", 4) == 0)
|
||||||
|
isa->dma = strtoul(p+4, &p, 0);
|
||||||
|
else if(cistrncmp(p, "mem=", 4) == 0)
|
||||||
|
isa->mem = strtoul(p+4, &p, 0);
|
||||||
|
else if(cistrncmp(p, "size=", 5) == 0)
|
||||||
|
isa->size = strtoul(p+5, &p, 0);
|
||||||
|
else if(cistrncmp(p, "freq=", 5) == 0)
|
||||||
|
isa->freq = strtoul(p+5, &p, 0);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -1000,109 +1000,3 @@ exit(int ispanic)
|
||||||
shutdown(ispanic);
|
shutdown(ispanic);
|
||||||
arch->reset();
|
arch->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
isaconfig(char *class, int ctlrno, ISAConf *isa)
|
|
||||||
{
|
|
||||||
char cc[32], *p;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
|
|
||||||
p = getconf(cc);
|
|
||||||
if(p == nil)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
isa->type = "";
|
|
||||||
isa->nopt = tokenize(p, isa->opt, NISAOPT);
|
|
||||||
for(i = 0; i < isa->nopt; i++){
|
|
||||||
p = isa->opt[i];
|
|
||||||
if(cistrncmp(p, "type=", 5) == 0)
|
|
||||||
isa->type = p + 5;
|
|
||||||
else if(cistrncmp(p, "port=", 5) == 0)
|
|
||||||
isa->port = strtoul(p+5, &p, 0);
|
|
||||||
else if(cistrncmp(p, "irq=", 4) == 0)
|
|
||||||
isa->irq = strtoul(p+4, &p, 0);
|
|
||||||
else if(cistrncmp(p, "dma=", 4) == 0)
|
|
||||||
isa->dma = strtoul(p+4, &p, 0);
|
|
||||||
else if(cistrncmp(p, "mem=", 4) == 0)
|
|
||||||
isa->mem = strtoul(p+4, &p, 0);
|
|
||||||
else if(cistrncmp(p, "size=", 5) == 0)
|
|
||||||
isa->size = strtoul(p+5, &p, 0);
|
|
||||||
else if(cistrncmp(p, "freq=", 5) == 0)
|
|
||||||
isa->freq = strtoul(p+5, &p, 0);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
cistrcmp(char *a, char *b)
|
|
||||||
{
|
|
||||||
int ac, bc;
|
|
||||||
|
|
||||||
for(;;){
|
|
||||||
ac = *a++;
|
|
||||||
bc = *b++;
|
|
||||||
|
|
||||||
if(ac >= 'A' && ac <= 'Z')
|
|
||||||
ac = 'a' + (ac - 'A');
|
|
||||||
if(bc >= 'A' && bc <= 'Z')
|
|
||||||
bc = 'a' + (bc - 'A');
|
|
||||||
ac -= bc;
|
|
||||||
if(ac)
|
|
||||||
return ac;
|
|
||||||
if(bc == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
cistrncmp(char *a, char *b, int n)
|
|
||||||
{
|
|
||||||
unsigned ac, bc;
|
|
||||||
|
|
||||||
while(n > 0){
|
|
||||||
ac = *a++;
|
|
||||||
bc = *b++;
|
|
||||||
n--;
|
|
||||||
|
|
||||||
if(ac >= 'A' && ac <= 'Z')
|
|
||||||
ac = 'a' + (ac - 'A');
|
|
||||||
if(bc >= 'A' && bc <= 'Z')
|
|
||||||
bc = 'a' + (bc - 'A');
|
|
||||||
|
|
||||||
ac -= bc;
|
|
||||||
if(ac)
|
|
||||||
return ac;
|
|
||||||
if(bc == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* put the processor in the halt state if we've no processes to run.
|
|
||||||
* an interrupt will get us going again.
|
|
||||||
*
|
|
||||||
* halting in an smp system can result in a startup latency for
|
|
||||||
* processes that become ready.
|
|
||||||
* if idle_spin is zero, we care more about saving energy
|
|
||||||
* than reducing this latency.
|
|
||||||
*
|
|
||||||
* the performance loss with idle_spin == 0 seems to be slight
|
|
||||||
* and it reduces lock contention (thus system time and real time)
|
|
||||||
* on many-core systems with large values of NPROC.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
idlehands(void)
|
|
||||||
{
|
|
||||||
extern int nrdy;
|
|
||||||
|
|
||||||
if(conf.nmach == 1)
|
|
||||||
halt();
|
|
||||||
else if(m->cpuidcx & Monitor)
|
|
||||||
mwait(&nrdy);
|
|
||||||
else if(idle_spin == 0)
|
|
||||||
halt();
|
|
||||||
}
|
|
||||||
|
|
|
@ -331,10 +331,20 @@ TEXT mb586(SB), 1, $-4
|
||||||
CPUID
|
CPUID
|
||||||
RET
|
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.
|
* BIOS32.
|
||||||
*/
|
*/
|
||||||
TEXT bios32call(SB), 1, $-1
|
TEXT bios32call(SB), 1, $-4
|
||||||
XORL AX, AX
|
XORL AX, AX
|
||||||
INCL AX
|
INCL AX
|
||||||
RET
|
RET
|
||||||
|
@ -526,14 +536,30 @@ TEXT setlabel(SB), 1, $-4
|
||||||
MOVL $0, AX /* return 0 */
|
MOVL $0, AX /* return 0 */
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT idle(SB), $0
|
TEXT halt(SB), 1, $-4
|
||||||
_idle:
|
CLI
|
||||||
|
CMPL nrdy(SB), $0
|
||||||
|
JEQ _nothingready
|
||||||
|
STI
|
||||||
|
RET
|
||||||
|
_nothingready:
|
||||||
STI
|
STI
|
||||||
HLT
|
HLT
|
||||||
JMP _idle
|
RET
|
||||||
|
|
||||||
TEXT halt(SB), 1, $-4
|
TEXT mwait(SB), 1, $-4
|
||||||
HLT
|
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
|
RET
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -26,6 +26,8 @@ char *confname[MAXCONF];
|
||||||
char *confval[MAXCONF];
|
char *confval[MAXCONF];
|
||||||
int nconf;
|
int nconf;
|
||||||
int delaylink;
|
int delaylink;
|
||||||
|
int idle_spin;
|
||||||
|
|
||||||
uchar *sp; /* user stack of init proc */
|
uchar *sp; /* user stack of init proc */
|
||||||
|
|
||||||
extern void (*i8237alloc)(void);
|
extern void (*i8237alloc)(void);
|
||||||
|
@ -419,12 +421,56 @@ main()
|
||||||
schedinit();
|
schedinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
exit(int)
|
shutdown(int ispanic)
|
||||||
{
|
{
|
||||||
print("exit\n");
|
int ms, once;
|
||||||
splhi();
|
|
||||||
for(;;);
|
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
|
void
|
||||||
|
@ -433,12 +479,6 @@ reboot(void*, void*, ulong)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
idlehands(void)
|
|
||||||
{
|
|
||||||
halt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SIMD Floating Point.
|
* SIMD Floating Point.
|
||||||
* Assembler support to get at the individual instructions
|
* Assembler support to get at the individual instructions
|
||||||
|
@ -707,36 +747,3 @@ procsave(Proc *p)
|
||||||
*/
|
*/
|
||||||
mmuflushtlb();
|
mmuflushtlb();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
isaconfig(char *class, int ctlrno, ISAConf *isa)
|
|
||||||
{
|
|
||||||
char cc[32], *p;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
|
|
||||||
p = getconf(cc);
|
|
||||||
if(p == nil)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
isa->type = "";
|
|
||||||
isa->nopt = tokenize(p, isa->opt, NISAOPT);
|
|
||||||
for(i = 0; i < isa->nopt; i++){
|
|
||||||
p = isa->opt[i];
|
|
||||||
if(cistrncmp(p, "type=", 5) == 0)
|
|
||||||
isa->type = p + 5;
|
|
||||||
else if(cistrncmp(p, "port=", 5) == 0)
|
|
||||||
isa->port = strtoul(p+5, &p, 0);
|
|
||||||
else if(cistrncmp(p, "irq=", 4) == 0)
|
|
||||||
isa->irq = strtoul(p+4, &p, 0);
|
|
||||||
else if(cistrncmp(p, "dma=", 4) == 0)
|
|
||||||
isa->dma = strtoul(p+4, &p, 0);
|
|
||||||
else if(cistrncmp(p, "mem=", 4) == 0)
|
|
||||||
isa->mem = strtoul(p+4, &p, 0);
|
|
||||||
else if(cistrncmp(p, "size=", 5) == 0)
|
|
||||||
isa->size = strtoul(p+5, &p, 0);
|
|
||||||
else if(cistrncmp(p, "freq=", 5) == 0)
|
|
||||||
isa->freq = strtoul(p+5, &p, 0);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue