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*);