shithub: riscv

Download patch

ref: 7f3659e78f83a59badebeae6414b9b3cd89d7a58
parent: 254031cf7020f1b185c6d0af89c653a271e0ed01
author: cinap_lenrek <[email protected]>
date: Mon Nov 30 09:56:00 EST 2015

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.

--- a/sys/src/9/alphapc/dat.h
+++ b/sys/src/9/alphapc/dat.h
@@ -186,7 +186,6 @@
 	Lock;
 	short	machs;
 	short	exiting;
-	short	ispanic;
 }active;
 
 /*
--- a/sys/src/9/alphapc/main.c
+++ b/sys/src/9/alphapc/main.c
@@ -308,123 +308,21 @@
 	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
--- a/sys/src/9/bcm/dat.h
+++ b/sys/src/9/bcm/dat.h
@@ -225,7 +225,6 @@
 	Lock;
 	int	machs;			/* bitmap of active CPUs */
 	int	exiting;		/* shutdown */
-	int	ispanic;		/* shutdown in response to a panic */
 }active;
 
 extern register Mach* m;			/* R10 */
--- a/sys/src/9/bcm/main.c
+++ b/sys/src/9/bcm/main.c
@@ -522,39 +522,13 @@
 
 }
 
-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,18 +553,9 @@
 {
 	void (*f)(ulong, ulong, ulong);
 
-	print("starting reboot...");
 	writeconf();
-	shutdown(0);
+	cpushutdown();
 
-	/*
-	 * should be the only processor running now
-	 */
-
-	print("reboot entry %#lux code %#lux size %ld\n",
-		PADDR(entry), PADDR(code), size);
-	delay(100);
-
 	/* turn off buffered serial console */
 	serialoq = nil;
 	kprintoq = nil;
@@ -612,10 +577,6 @@
 
 	/* off we go - never to return */
 	(*f)(PADDR(entry), PADDR(code), size);
-
-	iprint("loaded kernel returned!\n");
-	delay(1000);
-	archreboot();
 }
 
 int
--- a/sys/src/9/bitsy/dat.h
+++ b/sys/src/9/bitsy/dat.h
@@ -180,7 +180,6 @@
 	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))
--- a/sys/src/9/bitsy/main.c
+++ b/sys/src/9/bitsy/main.c
@@ -56,7 +56,6 @@
 void
 reboot(void*, void*, ulong)
 {
-	exit(0);
 }
 
 
@@ -64,13 +63,12 @@
  *  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();
--- a/sys/src/9/kw/dat.h
+++ b/sys/src/9/kw/dat.h
@@ -196,7 +196,6 @@
 	Lock;
 	int	machs;			/* bitmap of active CPUs */
 	int	exiting;		/* shutdown */
-	int	ispanic;		/* shutdown in response to a panic */
 }active;
 
 enum {
--- a/sys/src/9/kw/main.c
+++ b/sys/src/9/kw/main.c
@@ -355,39 +355,13 @@
 	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,18 +375,9 @@
 {
 	void (*f)(ulong, ulong, ulong);
 
-	iprint("starting reboot...");
 	writeconf();
-	
-	shutdown(0);
+	cpushutdown();
 
-	/*
-	 * should be the only processor running now
-	 */
-
-	print("shutting down...\n");
-	delay(200);
-
 	/* turn off buffered serial console */
 	serialoq = nil;
 
@@ -430,19 +395,10 @@
 	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();
 }
 
 /*
--- a/sys/src/9/mtx/dat.h
+++ b/sys/src/9/mtx/dat.h
@@ -183,7 +183,6 @@
 	Lock;
 	short	machs;
 	short	exiting;
-	short	ispanic;
 }active;
 
 /*
--- a/sys/src/9/mtx/main.c
+++ b/sys/src/9/mtx/main.c
@@ -211,42 +211,12 @@
 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();
 }
 
--- a/sys/src/9/omap/dat.h
+++ b/sys/src/9/omap/dat.h
@@ -218,7 +218,6 @@
 	Lock;
 	int	machs;			/* bitmap of active CPUs */
 	int	exiting;		/* shutdown */
-	int	ispanic;		/* shutdown in response to a panic */
 }active;
 
 extern register Mach* m;			/* R10 */
--- a/sys/src/9/omap/main.c
+++ b/sys/src/9/omap/main.c
@@ -301,39 +301,13 @@
 	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,18 +354,9 @@
 {
 	void (*f)(ulong, ulong, ulong);
 
-	print("starting reboot...");
 	writeconf();
-	shutdown(0);
+	cpushutdown();
 
-	/*
-	 * should be the only processor running now
-	 */
-
-	print("reboot entry %#lux code %#lux size %ld\n",
-		PADDR(entry), PADDR(code), size);
-	delay(100);
-
 	/* turn off buffered serial console */
 	serialoq = nil;
 	kprintoq = nil;
@@ -414,10 +379,6 @@
 
 	/* off we go - never to return */
 	(*f)(PADDR(entry), PADDR(code), size);
-
-	iprint("loaded kernel returned!\n");
-	delay(1000);
-	archreboot();
 }
 
 /*
--- a/sys/src/9/omap4/dat.h
+++ b/sys/src/9/omap4/dat.h
@@ -132,7 +132,6 @@
 	Lock;
 	int	machs;			/* bitmap of active CPUs */
 	int	exiting;		/* shutdown */
-	int	ispanic;		/* shutdown in response to a panic */
 }active;
 
 extern Mach *m;
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -272,7 +272,6 @@
 	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;
 
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -163,7 +163,6 @@
 		pcimatch(0, 0, 0);
 	}else
 		links();
-	conf.monitor = 1;
 	chandevreset();
 	pageinit();
 	swapinit();
@@ -890,50 +889,6 @@
 	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,11 +907,8 @@
 		procwired(up, 0);
 		sched();
 	}
-	shutdown(0);
+	cpushutdown();
 
-	iprint("shutting down...\n");
-	delay(200);
-
 	splhi();
 
 	/* turn off buffered serial console */
@@ -985,8 +937,8 @@
 
 
 void
-exit(int ispanic)
+exit(int)
 {
-	shutdown(ispanic);
+	cpushutdown();
 	arch->reset();
 }
--- a/sys/src/9/pc/screen.c
+++ b/sys/src/9/pc/screen.c
@@ -664,6 +664,8 @@
 	scr->cur = &swcursor;
 	scr->cur->enable(scr);
 	cursoron();
+
+	conf.monitor = 1;
 }
 
 /*
--- a/sys/src/9/pc64/dat.h
+++ b/sys/src/9/pc64/dat.h
@@ -235,7 +235,6 @@
 	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;
 
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -512,7 +512,6 @@
 		pcimatch(0, 0, 0);
 	}else
 		links();
-	conf.monitor = 1;
 	chandevreset();
 	preallocpages();
 	pageinit();
@@ -522,54 +521,10 @@
 	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 @@
 		procwired(up, 0);
 		sched();
 	}
-	shutdown(0);
-
-	iprint("shutting down...\n");
-	delay(200);
+	cpushutdown();
 
 	splhi();
 
--- a/sys/src/9/port/allocb.c
+++ b/sys/src/9/port/allocb.c
@@ -86,10 +86,8 @@
 
 	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 @@
 
 	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);
 		}
--- a/sys/src/9/port/devcons.c
+++ b/sys/src/9/port/devcons.c
@@ -260,9 +260,15 @@
 	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 */
@@ -1037,4 +1043,27 @@
 		break;
 	}
 	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;
+	}
 }
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -41,6 +41,7 @@
 void		confinit(void);
 int		consactive(void);
 void		(*consdebug)(void);
+void		cpushutdown(void);
 void		copen(Chan*);
 void		cclunk(Chan*);
 Block*		concatblock(Block*);
--- a/sys/src/9/port/rebootcmd.c
+++ b/sys/src/9/port/rebootcmd.c
@@ -103,6 +103,5 @@
 	setbootcmd(argc-1, argv+1);
 
 	reboot((void*)entry, p, size);
-
-	panic("return from reboot!");
+	error(Egreg);
 }
--- a/sys/src/9/port/ucallocb.c
+++ b/sys/src/9/port/ucallocb.c
@@ -78,24 +78,10 @@
 	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);
 		}
--- a/sys/src/9/ppc/dat.h
+++ b/sys/src/9/ppc/dat.h
@@ -191,7 +191,6 @@
 	Lock;
 	short	machs;
 	short	exiting;
-	short	ispanic;
 }active;
 
 /*
--- a/sys/src/9/ppc/main.c
+++ b/sys/src/9/ppc/main.c
@@ -243,38 +243,10 @@
 }
 
 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 @@
 		 */
 		imagmem->maxsize = kpages;
 	}
-
-//	conf.monitor = 1;	/* BUG */
 }
 
 static int
--- a/sys/src/9/sgi/dat.h
+++ b/sys/src/9/sgi/dat.h
@@ -206,7 +206,6 @@
 	Lock;
 	long	machs;		/* bitmap of processors */
 	short	exiting;
-	int	ispanic;
 }active;
 
 extern register Mach	*m;
--- a/sys/src/9/sgi/main.c
+++ b/sys/src/9/sgi/main.c
@@ -372,10 +372,10 @@
 }
 
 void
-exit(int ispanic)
+exit(int)
 {
+	cpushutdown();
 	splhi();
-	while(ispanic);
 	arcs(0x18);	/* reboot */
 }
 
--- a/sys/src/9/teg2/dat.h
+++ b/sys/src/9/teg2/dat.h
@@ -250,7 +250,6 @@
 	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;
 
--- a/sys/src/9/teg2/main.c
+++ b/sys/src/9/teg2/main.c
@@ -480,51 +480,13 @@
 	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 @@
 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 @@
 		procwired(up, 0);
 		sched();
 	}
-	if (m->machno != 0)
-		print("on cpu%d (not 0)!\n", m->machno);
+	cpushutdown();
 
 	/*
-	 * 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);
-	}
-
-	/*
 	 * 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 @@
 
 	/* off we go - never to return */
 	(*f)(PADDR(entry), PADDR(code), size);
-
-	iprint("loaded kernel returned!\n");
-	archreboot();
 }
 
 /*
--- a/sys/src/9/xen/main.c
+++ b/sys/src/9/xen/main.c
@@ -644,59 +644,14 @@
 	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();
+	cpushutdown();
 
-	shutdown(0);
-
-	/*
-	 * should be the only processor running now
-	 */
-
-	print("shutting down...\n");
-	delay(200);
-
 	splhi();
 
 	/* turn off buffered serial console */
@@ -709,12 +664,6 @@
 	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 */
@@ -721,16 +670,13 @@
 	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();
 }
--- a/sys/src/9/zynq/dat.h
+++ b/sys/src/9/zynq/dat.h
@@ -177,7 +177,6 @@
 	Lock;
 	int	machs;			/* bitmap of active CPUs */
 	int	exiting;		/* shutdown */
-	int	ispanic;		/* shutdown in response to a panic */
 }active;
 
 extern register Mach* m;			/* R10 */
--- a/sys/src/9/zynq/main.c
+++ b/sys/src/9/zynq/main.c
@@ -21,13 +21,13 @@
 void
 exit(int)
 {
-	NOPE
+	cpushutdown();
+	for(;;) idlehands();
 }
 
 void
 reboot(void *, void *, ulong)
 {
-	NOPE
 }
 
 void