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.
This commit is contained in:
cinap_lenrek 2014-12-19 23:34:43 +01:00
parent d94dc3314d
commit 7523131e78
6 changed files with 47 additions and 53 deletions

View file

@ -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;
}
}

View file

@ -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,

View file

@ -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();
}

View file

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

View file

@ -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();
}

View file

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