From 7523131e78a0974154cc90272b41991435b1ec19 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 19 Dec 2014 23:34:43 +0100 Subject: [PATCH] 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. --- sys/src/9/pc/archacpi.c | 58 ++++++++++++++++++++++------------------- sys/src/9/pc/archmp.c | 12 ++++++++- sys/src/9/pc/devarch.c | 3 ++- sys/src/9/pc/fns.h | 2 +- sys/src/9/pc/mp.c | 23 +--------------- sys/src/9/pc64/fns.h | 2 +- 6 files changed, 47 insertions(+), 53 deletions(-) diff --git a/sys/src/9/pc/archacpi.c b/sys/src/9/pc/archacpi.c index 6805f5c87..644df59b9 100644 --- a/sys/src/9/pc/archacpi.c +++ b/sys/src/9/pc/archacpi.c @@ -625,12 +625,42 @@ Foundapic: 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, @@ -887,29 +917,3 @@ 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; - } -} diff --git a/sys/src/9/pc/archmp.c b/sys/src/9/pc/archmp.c index 8fb269569..723433db8 100644 --- a/sys/src/9/pc/archmp.c +++ b/sys/src/9/pc/archmp.c @@ -354,12 +354,22 @@ pcmpinit(void) 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, diff --git a/sys/src/9/pc/devarch.c b/sys/src/9/pc/devarch.c index 412ca767e..24c5f0e7b 100644 --- a/sys/src/9/pc/devarch.c +++ b/sys/src/9/pc/devarch.c @@ -528,7 +528,7 @@ nop(void) { } -static void +void archreset(void) { i8042reset(); @@ -548,6 +548,7 @@ archreset(void) outb(0xcf9, 0x02); outb(0xcf9, 0x06); + print("can't reset\n"); for(;;) idle(); } diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h index ccf5ea092..77eebd2fc 100644 --- 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*); diff --git a/sys/src/9/pc/mp.c b/sys/src/9/pc/mp.c index 63fe687fa..8bfc52204 100644 --- a/sys/src/9/pc/mp.c +++ b/sys/src/9/pc/mp.c @@ -562,7 +562,6 @@ mpintrenable(Vctl* v) return -1; } - void mpshutdown(void) { @@ -572,7 +571,7 @@ mpshutdown(void) if(m->machno != 0){ splhi(); arch->introff(); - idle(); + for(;;) idle(); } print("mpshutdown: active = %#8.8ux\n", active.machs); @@ -585,24 +584,4 @@ mpshutdown(void) 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(); } diff --git a/sys/src/9/pc64/fns.h b/sys/src/9/pc64/fns.h index 652d07737..0af15138f 100644 --- 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*);