Index: apm.c =================================================================== RCS file: /home/ncvs/src/sys/i386/apm/apm.c,v retrieving revision 1.114.2.2 diff -u -r1.114.2.2 apm.c --- apm.c 2000/08/19 17:13:47 1.114.2.2 +++ apm.c 2001/05/03 08:06:35 @@ -235,12 +235,112 @@ return (sc->bios.r.ebx & 0xffff); } +#define APM_FIVA_HACK +#ifdef APM_FIVA_HACK +/* + * CASSIOPEIA FIVA suspend/resume hack by iwasaki@FreeBSD.org + * The following hack was done by the translation from the FIVA + * ACPI data blocks (_PTS and _WAK) into C code. + */ + +#include + +/* FIVA _PTS (Prepare To Sleep) */ +static void +apm_fiva_pts(void) +{ + u_int8_t *bdatap, bdata; + pcicfgregs cfg; + + /* + * Store(0x85, \_SB_.PCI0.ISA_.BCMD) + * [aml_region_write(0, 0, 0x85, 0x6ffff2c, 0x0, 0x8)] + */ + pmap_kenter((vm_offset_t)ptvmmap, (0x6ffff2c) & ~PAGE_MASK); + bdatap = (u_int8_t *) &ptvmmap[0x6ffff2c & PAGE_MASK]; + *bdatap = 0x85; + + /* + * Store(0x0, \_SB_.PCI0.ISA_.SMIC) + * [aml_region_write(1, 0, 0x0, 0x8038, 0x0, 0x8)] + */ + outb(0x8038, 0x0); + + /* + * Store(0x81, \_SB_.PCI0.ISA_.BCMD) + * [aml_region_write(0, 0, 0x81, 0x6ffff2c, 0x0, 0x8)] + */ + *bdatap = 0x81; + + /* + * Store(0x0, \_SB_.PCI0.ISA_.SMIC) + * [aml_region_write(1, 0, 0x0, 0x8038, 0x0, 0x8)] + */ + outb(0x8038, 0x0); + + /* + * Store(0x0, \_SB_.PCI0.PM__.PPCM) + * [aml_region_write(2, 1, 0x0, 0x0, 0x454, 0x1)] + * Note: pciconf -v -l gives us the following; + * chip1@pci0:17:0: + * class=0x068000 card=0x00000000 chip=0x710110b9 rev=0x00 hdr=0x00 + * vendor = 'Acer Labs Inc.' + * device = 'M7101 Power Management Controller' + * class = bridge + * subclass = PCI-unknown + */ + cfg.bus = 0; cfg.slot = 17; cfg.func = 0; + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata &= ~(1 << 4); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); + + /* + * Store(0x0, \_SB_.PCI0.PM__.PVGA) + * [aml_region_write(2, 1, 0x0, 0x0, 0x455, 0x1)] + */ + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata &= ~(1 << 5); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); + + pmap_kremove((vm_offset_t)ptvmmap); +} + +/* FIVA _WAK (Wakeup) */ +static void +apm_fiva_wak(void) +{ + u_int8_t bdata; + pcicfgregs cfg; + + /* + * Store(0x1, \_SB_.PCI0.PM__.PPCM) + * [aml_region_write(2, 1, 0x1, 0x0, 0x454, 0x1)] + */ + cfg.bus = 0; cfg.slot = 17; cfg.func = 0; + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata |= (1 << 4); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); + + /* + * Store(0x1, \_SB_.PCI0.PM__.PVGA) + * [aml_region_write(2, 1, 0x1, 0x0, 0x455, 0x1)] + */ + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata |= (1 << 5); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); + +} +#endif + /* suspend entire system */ static int apm_suspend_system(int state) { struct apm_softc *sc = &apm_softc; +#ifdef APM_FIVA_HACK + apm_fiva_pts(); +#endif sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; sc->bios.r.ebx = PMDV_ALLDEV; sc->bios.r.ecx = state; @@ -402,6 +502,9 @@ u_int second, minute, hour; struct timeval resume_time, tmp_time; +#ifdef APM_FIVA_HACK + apm_fiva_wak(); +#endif /* modified for adjkerntz */ pl = splsoftclock(); i8254_restore(); /* restore timer_freq and hz */