diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1997-10-24 06:49:21 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1997-10-24 06:49:21 +0000 |
commit | 7a53134fd57267b99882e2338eb013ab23290684 (patch) | |
tree | d5230144b111b7176c0e73ee56b5a2f4288c5d6d /sys/arch | |
parent | fd4f545692dd63307863efb512ec48cd67add913 (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
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/i386/apm.c | 164 | ||||
-rw-r--r-- | sys/arch/i386/i386/bios.c | 13 | ||||
-rw-r--r-- | sys/arch/i386/include/biosvar.h | 11 |
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(®s, 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(®s, sizeof(regs)); if ((apm_flags & APM_IDLE_SLOWS) && - apmcall(APM_CPU_BUSY, 0, ®s) != 0) + apmcall(APM_CPU_BUSY, 0, ®s) != 0) { + +#ifdef DIAGNOSTIC apm_perror("set CPU busy", ®s); +#endif + apmidleon = 0; + } } void apm_cpu_idle() { struct apmregs regs; - if (!apminited || !apmidleon) + if (!apm_cd.cd_ndevs || !apmidleon) return; + bzero(®s, sizeof(regs)); - if (apmcall(APM_CPU_IDLE, 0, ®s) != 0) + if (apmcall(APM_CPU_IDLE, 0, ®s) != 0) { + +#ifdef DIAGNOSTIC apm_perror("set CPU idle", ®s); +#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; |