diff options
-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; |