kernel: cleanup exit()/shutdown()/reboot() code
introduce cpushutdown() function that does the common operation of initiating shutdown, returning once all cpu's got the message and are about to shutdown. this avoids duplicated code which isnt really machine specific. automatic reboot on panic only when *debug= is not set and the machine is a cpu server or has no display, otherwise just hang.
This commit is contained in:
parent
254031cf70
commit
7f3659e78f
32 changed files with 79 additions and 579 deletions
|
@ -186,7 +186,6 @@ struct
|
|||
Lock;
|
||||
short machs;
|
||||
short exiting;
|
||||
short ispanic;
|
||||
}active;
|
||||
|
||||
/*
|
||||
|
|
|
@ -308,123 +308,21 @@ setupboot(int halt)
|
|||
cpu->state |= (halt? Cpuhaltstayhalted: Cpuhaltwarmboot);
|
||||
}
|
||||
|
||||
/* from ../pc */
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
print("cpu%d: exiting\n", m->machno);
|
||||
spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(active.ispanic && m->machno == 0) {
|
||||
if(cpuserver)
|
||||
delay(10000);
|
||||
else
|
||||
for (;;)
|
||||
continue;
|
||||
} else
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
/* from ../pc: */
|
||||
void
|
||||
reboot(void *entry, void *code, ulong size)
|
||||
reboot(void *, void *, ulong)
|
||||
{
|
||||
// writeconf(); // pass kernel environment to next kernel
|
||||
shutdown(0);
|
||||
|
||||
/*
|
||||
* should be the only processor running now
|
||||
*/
|
||||
print("shutting down...\n");
|
||||
delay(200);
|
||||
|
||||
splhi();
|
||||
|
||||
/* turn off buffered serial console */
|
||||
serialoq = nil;
|
||||
|
||||
/* shutdown devices */
|
||||
chandevshutdown();
|
||||
|
||||
#ifdef FUTURE
|
||||
{
|
||||
ulong *pdb;
|
||||
/*
|
||||
* Modify the machine page table to directly map the low 4MB of memory
|
||||
* This allows the reboot code to turn off the page mapping
|
||||
*/
|
||||
pdb = m->pdb;
|
||||
pdb[PDX(0)] = pdb[PDX(KZERO)];
|
||||
mmuflushtlb(PADDR(pdb));
|
||||
}
|
||||
/* setup reboot trampoline function */
|
||||
{
|
||||
void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR;
|
||||
|
||||
memmove(f, rebootcode, sizeof(rebootcode));
|
||||
#else
|
||||
USED(entry, code, size);
|
||||
#endif
|
||||
|
||||
print("rebooting...\n");
|
||||
#ifdef FUTURE
|
||||
/* off we go - never to return */
|
||||
(*f)(PADDR(entry), PADDR(code), size);
|
||||
}
|
||||
#endif
|
||||
setupboot(0); // reboot, don't halt
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
canlock(&active);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
spllo();
|
||||
print("cpu %d exiting\n", m->machno);
|
||||
do
|
||||
delay(100);
|
||||
while(consactive());
|
||||
|
||||
cpushutdown();
|
||||
splhi();
|
||||
delay(1000); /* give serial fifo time to finish flushing */
|
||||
if (getconf("*debug") != nil) {
|
||||
USED(ispanic);
|
||||
delay(60*1000); /* give us time to read the screen */
|
||||
}
|
||||
if(arch->coredetach)
|
||||
arch->coredetach();
|
||||
setupboot(1); // set up to halt
|
||||
for (; ; )
|
||||
for (;;)
|
||||
firmware();
|
||||
|
||||
// on PC is just:
|
||||
//if (0) {
|
||||
// shutdown(ispanic);
|
||||
// arch->reset();
|
||||
//}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -225,7 +225,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
}active;
|
||||
|
||||
extern register Mach* m; /* R10 */
|
||||
|
|
|
@ -522,39 +522,13 @@ confinit(void)
|
|||
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
iprint("cpu%d: exiting\n", m->machno);
|
||||
spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* exit kernel either on a panic or user request
|
||||
*/
|
||||
void
|
||||
exit(int code)
|
||||
exit(int)
|
||||
{
|
||||
shutdown(code);
|
||||
cpushutdown();
|
||||
splfhi();
|
||||
archreboot();
|
||||
}
|
||||
|
@ -579,17 +553,8 @@ reboot(void *entry, void *code, ulong size)
|
|||
{
|
||||
void (*f)(ulong, ulong, ulong);
|
||||
|
||||
print("starting reboot...");
|
||||
writeconf();
|
||||
shutdown(0);
|
||||
|
||||
/*
|
||||
* should be the only processor running now
|
||||
*/
|
||||
|
||||
print("reboot entry %#lux code %#lux size %ld\n",
|
||||
PADDR(entry), PADDR(code), size);
|
||||
delay(100);
|
||||
cpushutdown();
|
||||
|
||||
/* turn off buffered serial console */
|
||||
serialoq = nil;
|
||||
|
@ -612,10 +577,6 @@ reboot(void *entry, void *code, ulong size)
|
|||
|
||||
/* off we go - never to return */
|
||||
(*f)(PADDR(entry), PADDR(code), size);
|
||||
|
||||
iprint("loaded kernel returned!\n");
|
||||
delay(1000);
|
||||
archreboot();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -180,7 +180,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
}active;
|
||||
|
||||
#define MACHP(n) ((Mach *)(MACHADDR+(n)*BY2PG))
|
||||
|
|
|
@ -56,7 +56,6 @@ main(void)
|
|||
void
|
||||
reboot(void*, void*, ulong)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,13 +63,12 @@ reboot(void*, void*, ulong)
|
|||
* exit kernel either on a panic or user request
|
||||
*/
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
void (*f)(void);
|
||||
|
||||
USED(ispanic);
|
||||
delay(1000);
|
||||
|
||||
cpushutdown();
|
||||
splhi();
|
||||
iprint("it's a wonderful day to die\n");
|
||||
cacheflush();
|
||||
mmuinvalidate();
|
||||
|
|
|
@ -196,7 +196,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
}active;
|
||||
|
||||
enum {
|
||||
|
|
|
@ -355,39 +355,13 @@ machinit(void)
|
|||
up = nil;
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
iprint("cpu%d: exiting\n", m->machno);
|
||||
spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* exit kernel either on a panic or user request
|
||||
*/
|
||||
void
|
||||
exit(int code)
|
||||
exit(int)
|
||||
{
|
||||
shutdown(code);
|
||||
cpushutdown();
|
||||
splhi();
|
||||
archreboot();
|
||||
}
|
||||
|
@ -401,17 +375,8 @@ reboot(void *entry, void *code, ulong size)
|
|||
{
|
||||
void (*f)(ulong, ulong, ulong);
|
||||
|
||||
iprint("starting reboot...");
|
||||
writeconf();
|
||||
|
||||
shutdown(0);
|
||||
|
||||
/*
|
||||
* should be the only processor running now
|
||||
*/
|
||||
|
||||
print("shutting down...\n");
|
||||
delay(200);
|
||||
cpushutdown();
|
||||
|
||||
/* turn off buffered serial console */
|
||||
serialoq = nil;
|
||||
|
@ -430,19 +395,10 @@ reboot(void *entry, void *code, ulong size)
|
|||
cacheuwbinv();
|
||||
l2cacheuwb();
|
||||
|
||||
print("rebooting...");
|
||||
iprint("entry %#lux code %#lux size %ld\n",
|
||||
PADDR(entry), PADDR(code), size);
|
||||
delay(100); /* wait for uart to quiesce */
|
||||
|
||||
/* off we go - never to return */
|
||||
cacheuwbinv();
|
||||
l2cacheuwb();
|
||||
(*f)(PADDR(entry), PADDR(code), size);
|
||||
|
||||
iprint("loaded kernel returned!\n");
|
||||
delay(1000);
|
||||
archreboot();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -183,7 +183,6 @@ struct
|
|||
Lock;
|
||||
short machs;
|
||||
short exiting;
|
||||
short ispanic;
|
||||
}active;
|
||||
|
||||
/*
|
||||
|
|
|
@ -211,42 +211,12 @@ userinit(void)
|
|||
void
|
||||
reboot(void*, void*, ulong)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
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);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
print("cpu%d: exiting\n", m->machno);
|
||||
spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(active.ispanic && m->machno == 0){
|
||||
if(cpuserver)
|
||||
delay(10000);
|
||||
else if(conf.monitor)
|
||||
for(;;);
|
||||
}
|
||||
else
|
||||
delay(1000);
|
||||
|
||||
cpushutdown();
|
||||
watchreset();
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
}active;
|
||||
|
||||
extern register Mach* m; /* R10 */
|
||||
|
|
|
@ -301,39 +301,13 @@ machinit(void)
|
|||
up = nil;
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
iprint("cpu%d: exiting\n", m->machno);
|
||||
spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* exit kernel either on a panic or user request
|
||||
*/
|
||||
void
|
||||
exit(int code)
|
||||
exit(int)
|
||||
{
|
||||
shutdown(code);
|
||||
cpushutdown();
|
||||
splhi();
|
||||
archreboot();
|
||||
}
|
||||
|
@ -380,17 +354,8 @@ reboot(void *entry, void *code, ulong size)
|
|||
{
|
||||
void (*f)(ulong, ulong, ulong);
|
||||
|
||||
print("starting reboot...");
|
||||
writeconf();
|
||||
shutdown(0);
|
||||
|
||||
/*
|
||||
* should be the only processor running now
|
||||
*/
|
||||
|
||||
print("reboot entry %#lux code %#lux size %ld\n",
|
||||
PADDR(entry), PADDR(code), size);
|
||||
delay(100);
|
||||
cpushutdown();
|
||||
|
||||
/* turn off buffered serial console */
|
||||
serialoq = nil;
|
||||
|
@ -414,10 +379,6 @@ reboot(void *entry, void *code, ulong size)
|
|||
|
||||
/* off we go - never to return */
|
||||
(*f)(PADDR(entry), PADDR(code), size);
|
||||
|
||||
iprint("loaded kernel returned!\n");
|
||||
delay(1000);
|
||||
archreboot();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -132,7 +132,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
}active;
|
||||
|
||||
extern Mach *m;
|
||||
|
|
|
@ -272,7 +272,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
int thunderbirdsarego; /* lets the added processors continue to schedinit */
|
||||
}active;
|
||||
|
||||
|
|
|
@ -163,7 +163,6 @@ main(void)
|
|||
pcimatch(0, 0, 0);
|
||||
}else
|
||||
links();
|
||||
conf.monitor = 1;
|
||||
chandevreset();
|
||||
pageinit();
|
||||
swapinit();
|
||||
|
@ -890,50 +889,6 @@ procsave(Proc *p)
|
|||
mmuflushtlb(PADDR(m->pdb));
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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 calls
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
reboot(void *entry, void *code, ulong size)
|
||||
{
|
||||
|
@ -952,10 +907,7 @@ reboot(void *entry, void *code, ulong size)
|
|||
procwired(up, 0);
|
||||
sched();
|
||||
}
|
||||
shutdown(0);
|
||||
|
||||
iprint("shutting down...\n");
|
||||
delay(200);
|
||||
cpushutdown();
|
||||
|
||||
splhi();
|
||||
|
||||
|
@ -985,8 +937,8 @@ reboot(void *entry, void *code, ulong size)
|
|||
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
shutdown(ispanic);
|
||||
cpushutdown();
|
||||
arch->reset();
|
||||
}
|
||||
|
|
|
@ -664,6 +664,8 @@ bootscreeninit(void)
|
|||
scr->cur = &swcursor;
|
||||
scr->cur->enable(scr);
|
||||
cursoron();
|
||||
|
||||
conf.monitor = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -235,7 +235,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
int thunderbirdsarego; /* lets the added processors continue to schedinit */
|
||||
}active;
|
||||
|
||||
|
|
|
@ -512,7 +512,6 @@ main()
|
|||
pcimatch(0, 0, 0);
|
||||
}else
|
||||
links();
|
||||
conf.monitor = 1;
|
||||
chandevreset();
|
||||
preallocpages();
|
||||
pageinit();
|
||||
|
@ -522,54 +521,10 @@ main()
|
|||
schedinit();
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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 calls
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
shutdown(ispanic);
|
||||
cpushutdown();
|
||||
arch->reset();
|
||||
}
|
||||
|
||||
|
@ -590,10 +545,7 @@ reboot(void *entry, void *code, ulong size)
|
|||
procwired(up, 0);
|
||||
sched();
|
||||
}
|
||||
shutdown(0);
|
||||
|
||||
iprint("shutting down...\n");
|
||||
delay(200);
|
||||
cpushutdown();
|
||||
|
||||
splhi();
|
||||
|
||||
|
|
|
@ -86,10 +86,8 @@ iallocb(int size)
|
|||
|
||||
if(ialloc.bytes > conf.ialloc){
|
||||
if((m1++%10000)==0){
|
||||
if(mp++ > 1000){
|
||||
active.exiting = 1;
|
||||
exit(0);
|
||||
}
|
||||
if(mp++ > 1000)
|
||||
panic("iallocb: out of memory");
|
||||
iprint("iallocb: limited %lud/%lud\n",
|
||||
ialloc.bytes, conf.ialloc);
|
||||
}
|
||||
|
@ -98,10 +96,8 @@ iallocb(int size)
|
|||
|
||||
if((b = _allocb(size)) == nil){
|
||||
if((m2++%10000)==0){
|
||||
if(mp++ > 1000){
|
||||
active.exiting = 1;
|
||||
exit(0);
|
||||
}
|
||||
if(mp++ > 1000)
|
||||
panic("iallocb: out of memory");
|
||||
iprint("iallocb: no memory %lud/%lud\n",
|
||||
ialloc.bytes, conf.ialloc);
|
||||
}
|
||||
|
|
|
@ -260,9 +260,15 @@ panic(char *fmt, ...)
|
|||
splx(s);
|
||||
prflush();
|
||||
dumpstack();
|
||||
if(!cpuserver)
|
||||
for(;;);
|
||||
exit(1);
|
||||
|
||||
/* reboot cpu servers and headless machines when not debugging */
|
||||
if(getconf("*debug") == nil)
|
||||
if(cpuserver || !conf.monitor)
|
||||
exit(1);
|
||||
|
||||
/* otherwise, just hang */
|
||||
while(islo()) idlehands();
|
||||
for(;;);
|
||||
}
|
||||
|
||||
/* libmp at least contains a few calls to sysfatal; simulate with panic */
|
||||
|
@ -1038,3 +1044,26 @@ writebintime(char *buf, int n)
|
|||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
cpushutdown(void)
|
||||
{
|
||||
int ms, once;
|
||||
|
||||
lock(&active);
|
||||
once = active.machs & (1<<m->machno);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ int cmount(Chan**, Chan*, int, char*);
|
|||
void confinit(void);
|
||||
int consactive(void);
|
||||
void (*consdebug)(void);
|
||||
void cpushutdown(void);
|
||||
void copen(Chan*);
|
||||
void cclunk(Chan*);
|
||||
Block* concatblock(Block*);
|
||||
|
|
|
@ -103,6 +103,5 @@ rebootcmd(int argc, char *argv[])
|
|||
setbootcmd(argc-1, argv+1);
|
||||
|
||||
reboot((void*)entry, p, size);
|
||||
|
||||
panic("return from reboot!");
|
||||
error(Egreg);
|
||||
}
|
||||
|
|
|
@ -78,24 +78,10 @@ uciallocb(int size)
|
|||
Block *b;
|
||||
static int m1, m2, mp;
|
||||
|
||||
if(0 && ucialloc.bytes > conf.ialloc){
|
||||
if((m1++%10000)==0){
|
||||
if(mp++ > 1000){
|
||||
active.exiting = 1;
|
||||
exit(0);
|
||||
}
|
||||
iprint("uciallocb: limited %lud/%lud\n",
|
||||
ucialloc.bytes, conf.ialloc);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
if((b = _ucallocb(size)) == nil){
|
||||
if(0 && (m2++%10000)==0){
|
||||
if(mp++ > 1000){
|
||||
active.exiting = 1;
|
||||
exit(0);
|
||||
}
|
||||
if(mp++ > 1000)
|
||||
panic("uciallocb: out of memory");
|
||||
iprint("uciallocb: no memory %lud/%lud\n",
|
||||
ucialloc.bytes, conf.ialloc);
|
||||
}
|
||||
|
|
|
@ -191,7 +191,6 @@ struct
|
|||
Lock;
|
||||
short machs;
|
||||
short exiting;
|
||||
short ispanic;
|
||||
}active;
|
||||
|
||||
/*
|
||||
|
|
|
@ -243,38 +243,10 @@ userinit(void)
|
|||
}
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
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);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
print("cpu%d: exiting\n", m->machno);
|
||||
spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(active.ispanic && m->machno == 0){
|
||||
if(cpuserver)
|
||||
delay(10000);
|
||||
else if(conf.monitor)
|
||||
for(;;);
|
||||
}
|
||||
else
|
||||
delay(1000);
|
||||
|
||||
cpushutdown();
|
||||
for(;;) idlehands();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -424,8 +396,6 @@ confinit(void)
|
|||
*/
|
||||
imagmem->maxsize = kpages;
|
||||
}
|
||||
|
||||
// conf.monitor = 1; /* BUG */
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -206,7 +206,6 @@ struct
|
|||
Lock;
|
||||
long machs; /* bitmap of processors */
|
||||
short exiting;
|
||||
int ispanic;
|
||||
}active;
|
||||
|
||||
extern register Mach *m;
|
||||
|
|
|
@ -372,10 +372,10 @@ userinit(void)
|
|||
}
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
cpushutdown();
|
||||
splhi();
|
||||
while(ispanic);
|
||||
arcs(0x18); /* reboot */
|
||||
}
|
||||
|
||||
|
|
|
@ -250,7 +250,6 @@ struct
|
|||
int wfi; /* bitmap of CPUs in WFI state */
|
||||
int stopped; /* bitmap of CPUs stopped */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
int thunderbirdsarego; /* lets the added processors continue to schedinit */
|
||||
}active;
|
||||
|
||||
|
|
|
@ -480,51 +480,13 @@ main(void)
|
|||
panic("cpu%d: schedinit returned", m->machno);
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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 idles non-bootstrap cpus and returns
|
||||
* on bootstrap processors (to permit 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) {
|
||||
delay(m->machno*1000); /* stagger them */
|
||||
iprint("cpu%d: exiting\n", m->machno);
|
||||
}
|
||||
spllo();
|
||||
if (m->machno == 0)
|
||||
ms = 5*1000;
|
||||
else
|
||||
ms = 2*1000;
|
||||
for(; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
|
||||
/*
|
||||
* exit kernel either on a panic or user request
|
||||
*/
|
||||
void
|
||||
exit(int code)
|
||||
exit(int)
|
||||
{
|
||||
shutdown(code);
|
||||
cpushutdown();
|
||||
splhi();
|
||||
if (m->machno == 0)
|
||||
archreboot();
|
||||
|
@ -576,10 +538,8 @@ isaconfig(char *class, int ctlrno, ISAConf *isa)
|
|||
void
|
||||
reboot(void *entry, void *code, ulong size)
|
||||
{
|
||||
int cpu, nmach, want, ms;
|
||||
void (*f)(ulong, ulong, ulong);
|
||||
|
||||
nmach = conf.nmach;
|
||||
writeconf();
|
||||
|
||||
/*
|
||||
|
@ -590,33 +550,12 @@ reboot(void *entry, void *code, ulong size)
|
|||
procwired(up, 0);
|
||||
sched();
|
||||
}
|
||||
if (m->machno != 0)
|
||||
print("on cpu%d (not 0)!\n", m->machno);
|
||||
|
||||
/*
|
||||
* the other cpus could be holding locks that will never get
|
||||
* released (e.g., in the print path) if we put them into
|
||||
* reset now, so force them to shutdown gracefully first.
|
||||
*/
|
||||
for (want = 0, cpu = 1; cpu < navailcpus; cpu++)
|
||||
want |= 1 << cpu;
|
||||
active.stopped = 0;
|
||||
shutdown(0);
|
||||
for (ms = 15*1000; ms > 0 && active.stopped != want; ms -= 10)
|
||||
delay(10);
|
||||
delay(20);
|
||||
if (active.stopped != want) {
|
||||
for (cpu = 1; cpu < nmach; cpu++)
|
||||
stopcpu(cpu); /* make really sure */
|
||||
delay(20);
|
||||
}
|
||||
cpushutdown();
|
||||
|
||||
/*
|
||||
* should be the only processor running now
|
||||
*/
|
||||
pcireset();
|
||||
// print("reboot entry %#lux code %#lux size %ld\n",
|
||||
// PADDR(entry), PADDR(code), size);
|
||||
|
||||
/* turn off buffered serial console */
|
||||
serialoq = nil;
|
||||
|
@ -642,9 +581,6 @@ reboot(void *entry, void *code, ulong size)
|
|||
|
||||
/* off we go - never to return */
|
||||
(*f)(PADDR(entry), PADDR(code), size);
|
||||
|
||||
iprint("loaded kernel returned!\n");
|
||||
archreboot();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -644,58 +644,13 @@ procsave(Proc *p)
|
|||
mmuflushtlb(0);
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown(int ispanic)
|
||||
{
|
||||
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);
|
||||
active.machs &= ~(1<<m->machno);
|
||||
active.exiting = 1;
|
||||
unlock(&active);
|
||||
|
||||
if(once)
|
||||
print("cpu%d: exiting\n", m->machno);
|
||||
//spllo();
|
||||
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
|
||||
delay(TK2MS(2));
|
||||
if(active.machs == 0 && consactive() == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(getconf("*debug"))
|
||||
delay(5*60*1000);
|
||||
|
||||
if(active.ispanic){
|
||||
if(!cpuserver)
|
||||
for(;;)
|
||||
halt();
|
||||
delay(10000);
|
||||
}else
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void
|
||||
reboot(void *entry, void *code, ulong size)
|
||||
{
|
||||
void (*f)(ulong, ulong, ulong);
|
||||
//ulong *pdb;
|
||||
|
||||
writeconf();
|
||||
|
||||
shutdown(0);
|
||||
|
||||
/*
|
||||
* should be the only processor running now
|
||||
*/
|
||||
|
||||
print("shutting down...\n");
|
||||
delay(200);
|
||||
cpushutdown();
|
||||
|
||||
splhi();
|
||||
|
||||
|
@ -709,28 +664,19 @@ reboot(void *entry, void *code, ulong size)
|
|||
if(entry == 0)
|
||||
HYPERVISOR_shutdown(0);
|
||||
|
||||
/*
|
||||
* Modify the machine page table to directly map the low 4MB of memory
|
||||
* This allows the reboot code to turn off the page mapping
|
||||
*/
|
||||
//pdb = m->pdb;
|
||||
//pdb[PDX(0)] = pdb[PDX(KZERO)];
|
||||
mmuflushtlb(0);
|
||||
|
||||
/* setup reboot trampoline function */
|
||||
f = (void*)REBOOTADDR;
|
||||
memmove(f, rebootcode, sizeof(rebootcode));
|
||||
|
||||
print("rebooting...\n");
|
||||
|
||||
/* off we go - never to return */
|
||||
(*f)(PADDR(entry), PADDR(code), size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
exit(int ispanic)
|
||||
exit(int)
|
||||
{
|
||||
shutdown(ispanic);
|
||||
cpushutdown();
|
||||
arch->reset();
|
||||
}
|
||||
|
|
|
@ -177,7 +177,6 @@ struct
|
|||
Lock;
|
||||
int machs; /* bitmap of active CPUs */
|
||||
int exiting; /* shutdown */
|
||||
int ispanic; /* shutdown in response to a panic */
|
||||
}active;
|
||||
|
||||
extern register Mach* m; /* R10 */
|
||||
|
|
|
@ -21,13 +21,13 @@ int nconf;
|
|||
void
|
||||
exit(int)
|
||||
{
|
||||
NOPE
|
||||
cpushutdown();
|
||||
for(;;) idlehands();
|
||||
}
|
||||
|
||||
void
|
||||
reboot(void *, void *, ulong)
|
||||
{
|
||||
NOPE
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue