1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-19 15:33:56 +00:00

Merge PC98 support.

This commit is contained in:
Matthew N. Dodd 2003-03-25 05:19:18 +00:00
parent adbc4f03a6
commit 94c35e0af2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112590
6 changed files with 123 additions and 1599 deletions

View File

@ -157,6 +157,7 @@ gnu/i386/fpemul/reg_u_mul.s optional gpl_math_emulate
gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate
gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate
gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate
i386/bios/apm.c optional apm
i386/i386/atomic.c standard \
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}"
i386/i386/autoconf.c standard
@ -355,7 +356,6 @@ libkern/qdivrem.c standard
libkern/ucmpdi2.c standard
libkern/udivdi3.c standard
libkern/umoddi3.c standard
pc98/apm/apm.c optional apm
pc98/apm/apm_bioscall.s optional apm
pc98/i386/busio.s standard
pc98/i386/busiosubr.c standard

View File

@ -43,6 +43,10 @@
#include <machine/stdarg.h>
#include <machine/vm86.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_param.h>
@ -71,6 +75,19 @@ int apm_evindex;
#define APMDEV_NORMAL 0
#define APMDEV_CTL 8
#ifdef PC98
extern int bios32_apm98(struct bios_regs *, u_int, u_short);
/* PC98's SMM definition */
#define APM_NECSMM_PORT 0x6b8e
#define APM_NECSMM_PORTSZ 1
#define APM_NECSMM_EN 0x10
static __inline void apm_enable_smm(struct apm_softc *);
static __inline void apm_disable_smm(struct apm_softc *);
int apm_necsmm_addr;
u_int32_t apm_necsmm_mask;
#endif
static struct apmhook *hook[NAPM_HOOK]; /* XXX */
#define is_enabled(foo) ((foo) ? "enabled" : "disabled")
@ -113,6 +130,30 @@ SYSCTL_INT(_machdep, OID_AUTO, apm_suspend_delay, CTLFLAG_RW, &apm_suspend_delay
SYSCTL_INT(_machdep, OID_AUTO, apm_standby_delay, CTLFLAG_RW, &apm_standby_delay, 1, "");
SYSCTL_INT(_debug, OID_AUTO, apm_debug, CTLFLAG_RW, &apm_debug, 0, "");
#ifdef PC98
static __inline void
apm_enable_smm(sc)
struct apm_softc *sc;
{
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
if (apm_necsmm_addr != 0)
bus_space_write_1(iot, ioh, 0,
(bus_space_read_1(iot, ioh, 0) | ~apm_necsmm_mask));
}
static __inline void
apm_disable_smm(sc)
struct apm_softc *sc;
{
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
if (apm_necsmm_addr != 0)
bus_space_write_1(iot, ioh, 0,
(bus_space_read_1(iot, ioh, 0) & apm_necsmm_mask));
}
#endif
/*
* return 0 if the function successfull,
* return 1 if the function unsuccessfull,
@ -132,6 +173,12 @@ apm_bioscall(void)
}
sc->bios_busy = 1;
#ifdef PC98
set_bios_selectors(&sc->bios.seg, BIOSCODE_FLAG | BIOSDATA_FLAG);
if (bios32_apm98(&sc->bios.r, sc->bios.entry,
GSEL(GBIOSCODE32_SEL, SEL_KPL)) != 0)
return 1;
#else
if (sc->connectmode == APM_PROT32CONNECT) {
set_bios_selectors(&sc->bios.seg,
BIOSCODE_FLAG | BIOSDATA_FLAG);
@ -140,6 +187,7 @@ apm_bioscall(void)
} else {
errno = bios16(&sc->bios, NULL);
}
#endif
sc->bios_busy = 0;
return (errno);
}
@ -152,6 +200,11 @@ apm_check_function_supported(u_int version, u_int func)
if (func == APM_DRVVERSION) {
return (1);
}
#ifdef PC98
if (func == APM_GETPWSTATUS) {
return (1);
}
#endif
switch (version) {
case INTVERSION(1, 0):
@ -250,11 +303,17 @@ apm_suspend_system(int state)
sc->bios.r.ecx = state;
sc->bios.r.edx = 0;
#ifdef PC98
apm_disable_smm(sc);
#endif
if (apm_bioscall()) {
printf("Entire system suspend failure: errcode = %d\n",
0xff & (sc->bios.r.eax >> 8));
return 1;
}
#ifdef PC98
apm_enable_smm(sc);
#endif
return 0;
}
@ -793,6 +852,9 @@ apm_probe(device_t dev)
struct vm86frame vmf;
struct apm_softc *sc = &apm_softc;
int disabled, flags;
#ifdef PC98
int rid;
#endif
device_set_desc(dev, "APM BIOS");
@ -841,6 +903,38 @@ apm_probe(device_t dev)
vmf.vmf_bx = 0;
vm86_intcall(APM_INT, &vmf); /* disconnect, just in case */
#ifdef PC98
/* PC98 have bogos APM 32bit BIOS */
if ((vmf.vmf_cx & APM_32BIT_SUPPORT) == 0)
return ENXIO;
rid = 0;
bus_set_resource(dev, SYS_RES_IOPORT, rid,
APM_NECSMM_PORT, APM_NECSMM_PORTSZ);
sc->sc_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
APM_NECSMM_PORT, ~0, APM_NECSMM_PORTSZ, RF_ACTIVE);
if (sc->sc_res == NULL) {
printf("apm: cannot open NEC smm device\n");
return ENXIO;
}
bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_res);
vmf.vmf_ah = APM_BIOS;
vmf.vmf_al = APM_PROT32CONNECT;
vmf.vmf_bx = 0;
if (vm86_intcall(APM_INT, &vmf)) {
printf("apm: 32-bit connection error.\n");
return (ENXIO);
}
sc->bios.seg.code32.base = (vmf.vmf_ax << 4) + APM_KERNBASE;
sc->bios.seg.code32.limit = 0xffff;
sc->bios.seg.code16.base = (vmf.vmf_cx << 4) + APM_KERNBASE;
sc->bios.seg.code16.limit = 0xffff;
sc->bios.seg.data.base = (vmf.vmf_dx << 4) + APM_KERNBASE;
sc->bios.seg.data.limit = 0xffff;
sc->bios.entry = vmf.vmf_ebx;
sc->connectmode = APM_PROT32CONNECT;
#else
if ((vmf.vmf_cx & APM_32BIT_SUPPORT) != 0) {
vmf.vmf_ah = APM_BIOS;
vmf.vmf_al = APM_PROT32CONNECT;
@ -873,6 +967,7 @@ apm_probe(device_t dev)
sc->bios.entry = vmf.vmf_bx;
sc->connectmode = APM_PROT16CONNECT;
}
#endif
return(0);
}
@ -1006,6 +1101,9 @@ apm_processevent(void)
break;
}
} while (apm_event != PMEV_NOEVENT);
#ifdef PC98
apm_disable_smm(sc);
#endif
}
/*
@ -1020,6 +1118,9 @@ apm_attach(device_t dev)
struct apm_softc *sc = &apm_softc;
int flags;
int drv_version;
#ifdef PC98
int rid;
#endif
if (resource_int_value("apm", 0, "flags", &flags) != 0)
flags = 0;
@ -1047,6 +1148,22 @@ apm_attach(device_t dev)
APM_DPRINT("apm: CS_limit=0x%x, DS_limit=0x%x\n",
sc->bios.seg.code16.limit, sc->bios.seg.data.limit);
#ifdef PC98
rid = 0;
sc->sc_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
APM_NECSMM_PORT, ~0, APM_NECSMM_PORTSZ, RF_ACTIVE);
if (sc->sc_res == NULL)
panic("%s: counldn't map I/O ports", device_get_name(dev));
sc->sc_iot = rman_get_bustag(sc->sc_res);
sc->sc_ioh = rman_get_bushandle(sc->sc_res);
if (apm_version==0x112 || apm_version==0x111 || apm_version==0x110)
apm_necsmm_addr = APM_NECSMM_PORT;
else
apm_necsmm_addr = 0;
apm_necsmm_mask = ~APM_NECSMM_EN;
#endif /* PC98 */
/*
* In one test, apm bios version was 1.02; an attempt to register
* a 1.04 driver resulted in a 1.00 connection! Registering a

View File

@ -23,6 +23,11 @@
/* static data */
struct apm_softc {
#ifdef PC98
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
struct resource *sc_res;
#endif
int initialized, active, bios_busy;
int always_halt_cpu, slow_idle_cpu;
int disabled, disengaged;

View File

@ -1,10 +1,6 @@
# $FreeBSD$
.if ${MACHINE} == "pc98"
.PATH: ${.CURDIR}/../../pc98/apm
.else
.PATH: ${.CURDIR}/../../i386/bios
.endif
KMOD= apm
SRCS= apm.c apm.h \

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +0,0 @@
/*
* APM (Advanced Power Management) BIOS Device Driver
*
* Copyright (c) 1994 UKAI, Fumitoshi.
* Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>
* Copyright (c) 1996 Nate Williams <nate@FreeBSD.org>
* Copyright (c) 1997 Poul-Henning Kamp <phk@FreeBSD.org>
*
* This software may be used, modified, copied, and distributed, in
* both source and binary form provided that the above copyright and
* these terms are retained. Under no circumstances is the author
* responsible for the proper functioning of this software, nor does
* the author assume any responsibility for damages incurred with its
* use.
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $FreeBSD$
*/
#define APM_NEVENTS 16
#define APM_NPMEV 13
/* static data */
struct apm_softc {
#ifdef PC98
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
struct resource *sc_res;
#endif
int initialized, active, bios_busy;
int always_halt_cpu, slow_idle_cpu;
int disabled, disengaged;
int suspending;
int standby_countdown, suspend_countdown;
u_int minorversion, majorversion;
u_int intversion, connectmode;
u_int standbys, suspends;
struct bios_args bios;
struct apmhook sc_suspend;
struct apmhook sc_resume;
struct selinfo sc_rsel;
int sc_flags;
int event_count;
int event_ptr;
struct apm_event_info event_list[APM_NEVENTS];
u_char event_filter[APM_NPMEV];
};