From 2922666380077e8eb43ca0f565494031d9cb24cd Mon Sep 17 00:00:00 2001 From: Nate Williams Date: Tue, 23 Apr 1996 19:59:14 +0000 Subject: [PATCH] - This code adds some backwards compatability hacks for buggy APM BIOS implementations, and synchronizes us with the Nomad's latest code. This code is based on the Nomad code, but heavily hacked by me. Reviewed by: phk Submitted by: the 'Nomads' --- sys/i386/apm/apm.c | 26 +++++++++++++++++++++++++- sys/i386/bios/apm.c | 26 +++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/sys/i386/apm/apm.c b/sys/i386/apm/apm.c index e175cd52eac6..870006075fc5 100644 --- a/sys/i386/apm/apm.c +++ b/sys/i386/apm/apm.c @@ -14,7 +14,7 @@ * * Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD) * - * $Id: apm.c,v 1.39 1996/04/22 19:40:18 nate Exp $ + * $Id: apm.c,v 1.40 1996/04/23 16:02:45 nate Exp $ */ #include "apm.h" @@ -688,6 +688,13 @@ apmattach(struct isa_device *dvp) { #define APM_KERNBASE KERNBASE struct apm_softc *sc = &apm_softc; +#ifdef APM_DSVALUE_BUG + caddr_t apm_bios_work; + + apm_bioswork = (caddr_t)malloc(apm_ds_limit, M_DEVBUG, M_NOWAIT); + bcopy((caddr_t)((apm_ds_base << 4) + APM_KERNBASE), apm_bios_work, + apm_ds_limit); +#endif /* APM_DSVALUE_BUG */ sc->initialized = 0; @@ -702,6 +709,10 @@ apmattach(struct isa_device *dvp) sc->ds_limit = apm_ds_limit; sc->cs_entry = apm_cs_entry; +#ifdef APM_DSVALUE_BUG + sc->ds_base = (u_int)apm_bios_work; +#endif /* APM_DSVALUE_BUG */ + /* Always call HLT in idle loop */ sc->always_halt_cpu = 1; @@ -720,9 +731,11 @@ apmattach(struct isa_device *dvp) printf("apm: CS_limit=%x, DS_limit=%x\n", sc->cs_limit, sc->ds_limit); #endif /* APM_DEBUG */ +#ifdef APM_DEBUG /* Workaround for some buggy APM BIOS implementations */ sc->cs_limit = 0xffff; sc->ds_limit = 0xffff; +#endif /* setup GDT */ setup_apm_gdt(sc->cs32_base, sc->cs16_base, sc->ds_base, @@ -732,6 +745,15 @@ apmattach(struct isa_device *dvp) apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL); apm_addr.offset = sc->cs_entry; +#ifdef FORCE_APM10 + apm_version = 0x100; + sc->majorversion = 1; + sc->minorversion = 0; + sc->intversion = INTVERSION(sc->majorversion, sc->minorversion); + printf("apm: running in APM 1.0 compatible mode\n"); + kcd_apm.kdc_description = + "Advanced Power Management BIOS (1.0 compatability mode)", +#else /* Try to kick bios into 1.1 or greater mode */ apm_driver_version(); sc->minorversion = ((apm_version & 0x00f0) >> 4) * 10 + @@ -749,6 +771,8 @@ apmattach(struct isa_device *dvp) printf("apm: found APM BIOS version %d.%d\n", sc->majorversion, sc->minorversion); +#endif /* FORCE_APM10 */ + #ifdef APM_DEBUG printf("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu)); #endif diff --git a/sys/i386/bios/apm.c b/sys/i386/bios/apm.c index e175cd52eac6..870006075fc5 100644 --- a/sys/i386/bios/apm.c +++ b/sys/i386/bios/apm.c @@ -14,7 +14,7 @@ * * Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD) * - * $Id: apm.c,v 1.39 1996/04/22 19:40:18 nate Exp $ + * $Id: apm.c,v 1.40 1996/04/23 16:02:45 nate Exp $ */ #include "apm.h" @@ -688,6 +688,13 @@ apmattach(struct isa_device *dvp) { #define APM_KERNBASE KERNBASE struct apm_softc *sc = &apm_softc; +#ifdef APM_DSVALUE_BUG + caddr_t apm_bios_work; + + apm_bioswork = (caddr_t)malloc(apm_ds_limit, M_DEVBUG, M_NOWAIT); + bcopy((caddr_t)((apm_ds_base << 4) + APM_KERNBASE), apm_bios_work, + apm_ds_limit); +#endif /* APM_DSVALUE_BUG */ sc->initialized = 0; @@ -702,6 +709,10 @@ apmattach(struct isa_device *dvp) sc->ds_limit = apm_ds_limit; sc->cs_entry = apm_cs_entry; +#ifdef APM_DSVALUE_BUG + sc->ds_base = (u_int)apm_bios_work; +#endif /* APM_DSVALUE_BUG */ + /* Always call HLT in idle loop */ sc->always_halt_cpu = 1; @@ -720,9 +731,11 @@ apmattach(struct isa_device *dvp) printf("apm: CS_limit=%x, DS_limit=%x\n", sc->cs_limit, sc->ds_limit); #endif /* APM_DEBUG */ +#ifdef APM_DEBUG /* Workaround for some buggy APM BIOS implementations */ sc->cs_limit = 0xffff; sc->ds_limit = 0xffff; +#endif /* setup GDT */ setup_apm_gdt(sc->cs32_base, sc->cs16_base, sc->ds_base, @@ -732,6 +745,15 @@ apmattach(struct isa_device *dvp) apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL); apm_addr.offset = sc->cs_entry; +#ifdef FORCE_APM10 + apm_version = 0x100; + sc->majorversion = 1; + sc->minorversion = 0; + sc->intversion = INTVERSION(sc->majorversion, sc->minorversion); + printf("apm: running in APM 1.0 compatible mode\n"); + kcd_apm.kdc_description = + "Advanced Power Management BIOS (1.0 compatability mode)", +#else /* Try to kick bios into 1.1 or greater mode */ apm_driver_version(); sc->minorversion = ((apm_version & 0x00f0) >> 4) * 10 + @@ -749,6 +771,8 @@ apmattach(struct isa_device *dvp) printf("apm: found APM BIOS version %d.%d\n", sc->majorversion, sc->minorversion); +#endif /* FORCE_APM10 */ + #ifdef APM_DEBUG printf("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu)); #endif