shithub: riscv

Download patch

ref: 7523131e78a0974154cc90272b41991435b1ec19
parent: d94dc3314dc2431cafb49b394ac84123dd7b25d8
author: cinap_lenrek <[email protected]>
date: Fri Dec 19 18:34:43 EST 2014

pc, pc64: untangle acpireset() from mpshutdown()

mpshutdown() used to call acpireset() making it impossible to build
a kernel without archacpi. now, mpshutdown() is a helper function
that only shuts down the application processors that gets used from
mpreset() and acpireset().

the generic machine reset code in exported by devarch's archreset()
function that is called by mpreset() and from acpireset() as a fallback.
so the code duplication that was in mpshutdown() is avoided.

--- a/sys/src/9/pc/archacpi.c
+++ b/sys/src/9/pc/archacpi.c
@@ -625,12 +625,42 @@
 	mpinit();
 }
 
+static void
+acpireset(void)
+{
+	uchar *p;
+	Tbl *t;
+	int i;
+
+	/* stop application processors */
+	mpshutdown();
+
+	/* locate and write platform reset register */
+	for(i=0; i < ntblmap; i++){
+		t = tblmap[i];
+		if(memcmp(t->sig, "FACP", 4) != 0)
+			continue;
+		if(get32(t->len) <= 128)
+			break;
+		p = (uchar*)t;
+		if((get32(p + 112) & (1<<10)) == 0)
+			break;
+		if(p[116+0] != IoSpace)
+			break;
+		outb(get32(p+116+4), p[128]);
+		break;
+	}
+
+	/* acpi shutdown failed, try generic reset */
+	archreset();
+}
+
 static int identify(void);
 
 PCArch archacpi = {
 .id=		"ACPI",	
 .ident=		identify,
-.reset=		mpshutdown,
+.reset=		acpireset,
 .intrinit=	acpiinit,
 .intrenable=	mpintrenable,
 .intron=	lapicintron,
@@ -886,30 +916,4 @@
 amldelay(int us)
 {
 	microdelay(us);
-}
-
-/*
- * reset machine by writing acpi reset register.
- */
-void
-acpireset(void)
-{
-	uchar *p;
-	Tbl *t;
-	int i;
-
-	for(i=0; i < ntblmap; i++){
-		t = tblmap[i];
-		if(memcmp(t->sig, "FACP", 4) != 0)
-			continue;
-		if(get32(t->len) <= 128)
-			break;
-		p = (uchar*)t;
-		if((get32(p + 112) & (1<<10)) == 0)
-			break;
-		if(p[116+0] != IoSpace)
-			break;
-		outb(get32(p+116+4), p[128]);
-		break;
-	}
 }
--- a/sys/src/9/pc/archmp.c
+++ b/sys/src/9/pc/archmp.c
@@ -354,12 +354,22 @@
 	mpinit();
 }
 
+static void
+mpreset(void)
+{
+	/* stop application processors */
+	mpshutdown();
+
+	/* do generic reset */
+	archreset();
+}
+
 static int identify(void);
 
 PCArch archmp = {
 .id=		"_MP_",	
 .ident=		identify,
-.reset=		mpshutdown,
+.reset=		mpreset,
 .intrinit=	pcmpinit,
 .intrenable=	mpintrenable,
 .intron=	lapicintron,
--- a/sys/src/9/pc/devarch.c
+++ b/sys/src/9/pc/devarch.c
@@ -528,7 +528,7 @@
 {
 }
 
-static void
+void
 archreset(void)
 {
 	i8042reset();
@@ -548,6 +548,7 @@
 	outb(0xcf9, 0x02);
 	outb(0xcf9, 0x06);
 
+	print("can't reset\n");
 	for(;;)
 		idle();
 }
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -1,9 +1,9 @@
 #include "../port/portfns.h"
 
 void	aamloop(int);
-void	acpireset(void);
 Dirtab*	addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
 void	archinit(void);
+void	archreset(void);
 int	bios32call(BIOS32ci*, u16int[3]);
 int	bios32ci(BIOS32si*, BIOS32ci*);
 void	bios32close(BIOS32si*);
--- a/sys/src/9/pc/mp.c
+++ b/sys/src/9/pc/mp.c
@@ -562,7 +562,6 @@
 	return -1;
 }
 
-
 void
 mpshutdown(void)
 {
@@ -572,7 +571,7 @@
 	if(m->machno != 0){
 		splhi();
 		arch->introff();
-		idle();
+		for(;;) idle();
 	}
 
 	print("mpshutdown: active = %#8.8ux\n", active.machs);
@@ -585,24 +584,4 @@
 	lapicicrw(0, 0x000C0000|ApicINIT);
 
 	pcireset();
-	acpireset();
-	i8042reset();
-
-	/*
-	 * Often the BIOS hangs during restart if a conventional 8042
-	 * warm-boot sequence is tried. The following is Intel specific and
-	 * seems to perform a cold-boot, but at least it comes back.
-	 * And sometimes there is no keyboard...
-	 *
-	 * The reset register (0xcf9) is usually in one of the bridge
-	 * chips. The actual location and sequence could be extracted from
-	 * ACPI but why bother, this is the end of the line anyway.
-	 */
-	print("no kbd; trying bios warm boot...");
-	*(ushort*)KADDR(0x472) = 0x1234;	/* BIOS warm-boot flag */
-	outb(0xCF9, 0x02);
-	outb(0xCF9, 0x06);
-
-	print("can't reset\n");
-	idle();
 }
--- a/sys/src/9/pc64/fns.h
+++ b/sys/src/9/pc64/fns.h
@@ -1,9 +1,9 @@
 #include "../port/portfns.h"
 
 void	aamloop(int);
-void	acpireset(void);
 Dirtab*	addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
 void	archinit(void);
+void	archreset(void);
 int	bios32call(BIOS32ci*, u16int[3]);
 int	bios32ci(BIOS32si*, BIOS32ci*);
 void	bios32close(BIOS32si*);