summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/i386/i386/apm.c164
-rw-r--r--sys/arch/i386/i386/bios.c13
-rw-r--r--sys/arch/i386/include/biosvar.h11
3 files changed, 125 insertions, 63 deletions
diff --git a/sys/arch/i386/i386/apm.c b/sys/arch/i386/i386/apm.c
index 18ff03a27e0..31f802ae4f1 100644
--- a/sys/arch/i386/i386/apm.c
+++ b/sys/arch/i386/i386/apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apm.c,v 1.13 1997/10/22 23:37:10 mickey Exp $ */
+/* $OpenBSD: apm.c,v 1.14 1997/10/24 06:49:19 mickey Exp $ */
/*-
* Copyright (c) 1995 John T. Kohl. All rights reserved.
@@ -107,7 +107,6 @@ struct cfdriver apm_cd = {
STATIC u_int apm_flags;
STATIC u_char apm_majver;
STATIC u_char apm_minver;
-STATIC u_short apminited;
int apm_dobusy;
STATIC struct {
u_int32_t entry;
@@ -176,6 +175,8 @@ apm_err_translate(code)
}
}
+int apmerrors = 0;
+
STATIC void
apm_perror(str, regs)
const char *str;
@@ -184,6 +185,8 @@ apm_perror(str, regs)
printf("APM %s: %s (%d)\n", str,
apm_err_translate(APM_ERR_CODE(regs)),
APM_ERR_CODE(regs));
+
+ apmerrors++;
}
STATIC void
@@ -196,23 +199,23 @@ apm_power_print (sc, regs)
sc->sc_dev.dv_xname,
BATT_LIFE(regs));
}
- printf("%s: AC state: ", sc->sc_dev.dv_xname);
+ printf("%s: AC ", sc->sc_dev.dv_xname);
switch (AC_STATE(regs)) {
case APM_AC_OFF:
- printf("off\n");
+ printf("off,");
break;
case APM_AC_ON:
- printf("on\n");
+ printf("on,");
break;
case APM_AC_BACKUP:
- printf("backup power\n");
+ printf("backup power,");
break;
default:
case APM_AC_UNKNOWN:
- printf("unknown\n");
+ printf("unknown,");
break;
}
- printf("%s: battery charge state:", sc->sc_dev.dv_xname);
+ printf(" battery charge ");
if (apm_minver == 0)
switch (BATT_STATE(regs)) {
case APM_BATT_HIGH:
@@ -231,29 +234,30 @@ apm_power_print (sc, regs)
printf("unknown\n");
break;
default:
- printf("undecoded state %x\n", BATT_STATE(regs));
+ printf("undecoded (%x)\n", BATT_STATE(regs));
break;
}
else if (apm_minver >= 1) {
if (BATT_FLAGS(regs) & APM_BATT_FLAG_NOBATTERY)
- printf(" no battery\n");
+ printf("[no battery]");
else {
if (BATT_FLAGS(regs) & APM_BATT_FLAG_HIGH)
- printf(" high");
+ printf("high");
if (BATT_FLAGS(regs) & APM_BATT_FLAG_LOW)
- printf(" low");
+ printf("low");
if (BATT_FLAGS(regs) & APM_BATT_FLAG_CRITICAL)
- printf(" critical");
+ printf("critical");
if (BATT_FLAGS(regs) & APM_BATT_FLAG_CHARGING)
- printf(" charging");
- printf("\n");
+ printf("charging");
if (BATT_REM_VALID(regs))
- printf("%s: estimated %d:%02d minutes\n",
- sc->sc_dev.dv_xname,
+ printf(", estimated %d:%02d minutes\n",
BATT_REMAINING(regs) / 60,
BATT_REMAINING(regs)%60);
}
}
+
+ printf("\n");
+
return;
}
@@ -431,8 +435,14 @@ apm_periodic_check(arg)
} else if (apm_standbys || apm_userstandbys) {
apm_standby();
}
- apm_suspends = apm_standbys = apm_battlow = apm_userstandbys =0;
- timeout(apm_periodic_check, sc, hz);
+ apm_suspends = apm_standbys = apm_battlow = apm_userstandbys = 0;
+
+ if(apmerrors < 10)
+ timeout(apm_periodic_check, sc, hz);
+#ifdef DIAGNOSTIC
+ else
+ printf("APM: too many errors, turning off timeout\n");
+#endif
}
#ifdef notused
@@ -491,7 +501,7 @@ apm_set_powstate(dev, state)
u_int dev, state;
{
struct apmregs regs;
- if (!apminited || (apm_minver == 0 && state > APM_SYS_OFF))
+ if (!apm_cd.cd_ndevs || (apm_minver == 0 && state > APM_SYS_OFF))
return EINVAL;
bzero(&regs, sizeof(regs));
regs.cx = state;
@@ -502,33 +512,40 @@ apm_set_powstate(dev, state)
return 0;
}
-#ifdef APM_NOIDLE
-int apmidleon = 0;
-#else
int apmidleon = 1;
-#endif
void
apm_cpu_busy()
{
struct apmregs regs;
- if (!apminited || !apmidleon)
+ if (!apm_cd.cd_ndevs || !apmidleon)
return;
bzero(&regs, sizeof(regs));
if ((apm_flags & APM_IDLE_SLOWS) &&
- apmcall(APM_CPU_BUSY, 0, &regs) != 0)
+ apmcall(APM_CPU_BUSY, 0, &regs) != 0) {
+
+#ifdef DIAGNOSTIC
apm_perror("set CPU busy", &regs);
+#endif
+ apmidleon = 0;
+ }
}
void
apm_cpu_idle()
{
struct apmregs regs;
- if (!apminited || !apmidleon)
+ if (!apm_cd.cd_ndevs || !apmidleon)
return;
+
bzero(&regs, sizeof(regs));
- if (apmcall(APM_CPU_IDLE, 0, &regs) != 0)
+ if (apmcall(APM_CPU_IDLE, 0, &regs) != 0) {
+
+#ifdef DIAGNOSTIC
apm_perror("set CPU idle", &regs);
+#endif
+ apmidleon = 0;
+ }
}
#ifdef APM_V10_ONLY
@@ -556,7 +573,6 @@ apm_set_ver(self)
apm_minver = 0;
}
printf(": Power Management spec V%d.%d", apm_majver, apm_minver);
- apminited = 1;
if (apm_flags & APM_IDLE_SLOWS) {
#ifdef DEBUG
/* not relevant much */
@@ -598,16 +614,44 @@ apmprobe(parent, match, aux)
void *match, *aux;
{
struct bios_attach_args *ba = aux;
+ bios_apminfo_t *ap = ba->bios_apmp;
+ bus_space_handle_t ch, dh;
+
+ if (apm_cd.cd_ndevs ||
+ strcmp(ba->bios_dev, "apm") ||
+ ba->bios_apmp->apm_detail & APM_BIOS_PM_DISABLED ||
+ ba->bios_apmp->apm_detail & APM_BIOS_PM_DISENGAGED ||
+ !(ba->bios_apmp->apm_detail & APM_32BIT_SUPPORTED)) {
+#ifdef DEBUG
+ printf("%s: %x\n", ba->bios_dev, ba->bios_apmp->apm_detail);
+#endif
+ return 0;
+ }
- if (apminited)
+ if (ap->apm_code32_base + ap->apm_code_len > IOM_END)
+ ap->apm_code_len -= ap->apm_code32_base + ap->apm_code_len -
+ IOM_END;
+ if (bus_space_map(ba->bios_memt, ap->apm_code32_base,
+ ap->apm_code_len, 1, &ch) != 0) {
+#ifdef DEBUG
+ printf("apm0: can't map code\n");
+#endif
return 0;
- if (!(ba->bios_apmp->apm_detail & APM_BIOS_PM_DISABLED) &&
- !(ba->bios_apmp->apm_detail & APM_BIOS_PM_DISENGAGED) &&
- (ba->bios_apmp->apm_detail & APM_32BIT_SUPPORTED) &&
- strcmp(ba->bios_dev, "apm") == 0) {
- return 1;
}
- return 0;
+ bus_space_unmap(ba->bios_memt, ch, ap->apm_code_len);
+ if (ap->apm_data_base + ap->apm_data_len > IOM_END)
+ ap->apm_data_len -= ap->apm_data_base + ap->apm_data_len -
+ IOM_END;
+ if (bus_space_map(ba->bios_memt, ap->apm_data_base,
+ ap->apm_data_len, 1, &dh) != 0) {
+#ifdef DEBUG
+ printf("apm0: can't map data\n");
+#endif
+ return 0;
+ }
+ bus_space_unmap(ba->bios_memt, dh, ap->apm_data_len);
+
+ return 1;
}
void
@@ -616,9 +660,11 @@ apmattach(parent, self, aux)
void *aux;
{
extern union descriptor *dynamic_gdt;
- bios_apminfo_t *ap = ((struct bios_attach_args *)aux)->bios_apmp;
+ struct bios_attach_args *ba = aux;
+ bios_apminfo_t *ap = ba->bios_apmp;
struct apm_softc *sc = (void *)self;
struct apmregs regs;
+ bus_space_handle_t ch, dh;
/*
* set up GDT descriptors for APM
@@ -627,25 +673,43 @@ apmattach(parent, self, aux)
apm_flags = ap->apm_detail;
apm_ep.seg = GSEL(GAPM32CODE_SEL,SEL_KPL);
apm_ep.entry = ap->apm_entry;
- setsegment(&dynamic_gdt[GAPM32CODE_SEL].sd,
- (void *)ISA_HOLE_VADDR(ap->apm_code32_base),
+ if ((ap->apm_code32_base <= ap->apm_data_base &&
+ ap->apm_code32_base+ap->apm_code_len >= ap->apm_data_base)
+ ||(ap->apm_code32_base >= ap->apm_data_base &&
+ ap->apm_data_base+ap->apm_data_len>=ap->apm_code32_base)){
+ int l;
+ l = max(ap->apm_data_base + ap->apm_data_len,
+ ap->apm_code32_base + ap->apm_data_len) -
+ min(ap->apm_data_base, ap->apm_code32_base);
+ bus_space_map(ba->bios_memt,
+ min(ap->apm_data_base, ap->apm_code32_base),
+ l, 1, &ch);
+ dh = ch;
+ if (ap->apm_data_base < ap->apm_code32_base)
+ ch += ap->apm_code32_base - ap->apm_data_base;
+ else
+ dh += ap->apm_data_base - ap->apm_code32_base;
+ } else {
+
+ bus_space_map(ba->bios_memt,
+ ba->bios_apmp->apm_code32_base,
+ ba->bios_apmp->apm_code_len, 1, &ch);
+ bus_space_map(ba->bios_memt,
+ ba->bios_apmp->apm_data_base,
+ ba->bios_apmp->apm_data_len, 1, &dh);
+ }
+ setsegment(&dynamic_gdt[GAPM32CODE_SEL].sd, (void *)ch,
ap->apm_code_len-1, SDT_MEMERA, SEL_KPL, 1, 0);
- setsegment(&dynamic_gdt[GAPM16CODE_SEL].sd,
- (void *)ISA_HOLE_VADDR(ap->apm_code16_base),
+ setsegment(&dynamic_gdt[GAPM16CODE_SEL].sd, (void *)ch,
ap->apm_code_len-1, SDT_MEMERA, SEL_KPL, 0, 0);
- setsegment(&dynamic_gdt[GAPMDATA_SEL].sd,
- (void *)ISA_HOLE_VADDR(ap->apm_data_base),
+ setsegment(&dynamic_gdt[GAPMDATA_SEL].sd, (void *)dh,
ap->apm_data_len-1, SDT_MEMRWA, SEL_KPL, 1, 0);
#if defined(DEBUG) || defined(APMDEBUG)
printf(": flags %x code 32:%x/%x 16:%x/%x %x "
"data %x/%x/%x ep %x (%x:%x)\n%s", apm_flags,
- ap->apm_code32_base, ISA_HOLE_VADDR(ap->apm_code32_base),
- ap->apm_code16_base, ISA_HOLE_VADDR(ap->apm_code16_base),
- ap->apm_code_len,
- ap->apm_data_base, ISA_HOLE_VADDR(ap->apm_data_base),
- ap->apm_data_len,
- ap->apm_entry, apm_ep.seg,
- ap->apm_entry+ISA_HOLE_VADDR(ap->apm_code32_base),
+ ap->apm_code32_base, ch, ap->apm_code16_base, ch,
+ ap->apm_code_len, ap->apm_data_base, dh, ap->apm_data_len,
+ ap->apm_entry, apm_ep.seg, ap->apm_entry+ch,
sc->sc_dev.dv_xname);
#endif
apm_set_ver(sc);
diff --git a/sys/arch/i386/i386/bios.c b/sys/arch/i386/i386/bios.c
index 3d3bc4ac556..a40efa9d05c 100644
--- a/sys/arch/i386/i386/bios.c
+++ b/sys/arch/i386/i386/bios.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bios.c,v 1.11 1997/10/22 23:37:11 mickey Exp $ */
+/* $OpenBSD: bios.c,v 1.12 1997/10/24 06:49:20 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -178,19 +178,20 @@ biosattach(parent, self, aux)
}
printf("\n");
+#if NAPM > 0
+ {
+ struct bios_attach_args ba;
#ifdef DEBUG
printf("apminfo: %x, code %x/%x[%x], data %x[%x], entry %x\n",
apm->apm_detail, apm->apm_code32_base,
apm->apm_code16_base, apm->apm_code_len,
apm->apm_data_base, apm->apm_data_len, apm->apm_entry);
#endif
-#if NAPM > 0
- {
- struct bios_attach_args ba;
-
- ba.bios_apmp = apm;
ba.bios_dev = "apm";
ba.bios_func = 0x15;
+ ba.bios_memt = bia->bios_memt;
+ ba.bios_iot = bia->bios_iot;
+ ba.bios_apmp = apm;
config_found(self, &ba, bios_print);
}
#endif
diff --git a/sys/arch/i386/include/biosvar.h b/sys/arch/i386/include/biosvar.h
index b125b18c165..00b75e40cdf 100644
--- a/sys/arch/i386/include/biosvar.h
+++ b/sys/arch/i386/include/biosvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosvar.h,v 1.21 1997/10/22 23:37:13 mickey Exp $ */
+/* $OpenBSD: biosvar.h,v 1.22 1997/10/24 06:49:19 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -145,17 +145,14 @@ extern struct BIOS_regs {
struct bios_attach_args {
char *bios_dev;
u_int bios_func;
+ bus_space_tag_t bios_iot;
+ bus_space_tag_t bios_memt;
union {
- struct {
- bus_space_tag_t _bios_iot;
- bus_space_tag_t _bios_memt;
- } bios;
+ void *_p;
bios_apminfo_t *_bios_apmp;
} _;
};
-#define bios_iot _.bios._bios_iot
-#define bios_memt _.bios._bios_memt
#define bios_apmp _._bios_apmp
struct consdev;