summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1997-10-24 06:49:21 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1997-10-24 06:49:21 +0000
commit7a53134fd57267b99882e2338eb013ab23290684 (patch)
treed5230144b111b7176c0e73ee56b5a2f4288c5d6d
parentfd4f545692dd63307863efb512ec48cd67add913 (diff)
fix the case when data/code segment is not in the ISA memory
hole, so map 'em separatelly (or together if they intersect) and use that mapped region for segment creations... must help on some machines to avoid weird apm errors
-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;