diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index c78a39f1c738..994b3206f4d6 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -831,7 +831,10 @@ acpi_attach(device_t dev) acpi_powerres_debug(sc); } - EVENTHANDLER_REGISTER(shutdown_final, acpi_soft_off, sc, SHUTDOWN_PRI_LAST); + EVENTHANDLER_REGISTER(shutdown_pre_sync, acpi_disable_events, + sc, SHUTDOWN_PRI_LAST); + EVENTHANDLER_REGISTER(shutdown_final, acpi_soft_off, + sc, SHUTDOWN_PRI_LAST); sc->dev_t = make_dev(&acpi_cdevsw, 0, 0, 5, 0660, "acpi"); sc->dev_t->si_drv1 = sc; @@ -962,3 +965,39 @@ acpi_attach_resource(acpi_softc_t *sc, int type, int *wantidx, u_long start, u_l return(ENXIO); } } + +/* + * System service interface + */ + +#include + +int +acpi_sleep(u_int32_t micro) +{ + static u_int8_t count = 0; + int x, error; + u_int32_t timo; + + x = error = 0; + + if (micro == 0) { + return (1); + } + + if (curproc == NULL) { + return (2); + } + + timo = ((hz * micro) / 1000000L) ? ((hz * micro) / 1000000L) : 1; + error = tsleep((caddr_t)acpi_sleep + count, PWAIT, "acpislp", timo); + if (error != 0 && error != EWOULDBLOCK) { + return (2); + } + x = splhigh(); + count++; + splx(x); + + return (0); +} + diff --git a/sys/dev/acpi/acpi_event.c b/sys/dev/acpi/acpi_event.c index a66ec237af4b..5f965df58a5b 100644 --- a/sys/dev/acpi/acpi_event.c +++ b/sys/dev/acpi/acpi_event.c @@ -297,6 +297,19 @@ acpi_enable_events(acpi_softc_t *sc) acpi_io_pm_timer(sc, ACPI_REGISTER_INPUT, &status); } +void +acpi_disable_events(acpi_softc_t *sc) +{ + u_int32_t zero; + + if (sc->enabled) { + zero = 0; + acpi_io_pm1_enable(sc, ACPI_REGISTER_OUTPUT, &zero); + acpi_io_gpe0_enable(sc, ACPI_REGISTER_OUTPUT, &zero); + acpi_io_gpe1_enable(sc, ACPI_REGISTER_OUTPUT, &zero); + } +} + void acpi_clear_ignore_events(void *arg) { diff --git a/sys/dev/acpi/acpireg.h b/sys/dev/acpi/acpireg.h index 635c2b7e503c..1d64e92314ab 100644 --- a/sys/dev/acpi/acpireg.h +++ b/sys/dev/acpi/acpireg.h @@ -328,6 +328,9 @@ ACPI_STATUS OsdReadPciCfgDword(UINT32, UINT32 , UINT32 , UINT32 *); ACPI_STATUS OsdWritePciCfgByte(UINT32, UINT32 , UINT32 , UINT8); ACPI_STATUS OsdWritePciCfgWord(UINT32, UINT32 , UINT32 , UINT16); ACPI_STATUS OsdWritePciCfgDword(UINT32, UINT32 , UINT32 , UINT32); + +ACPI_STATUS OsdSleep(UINT32, UINT32); +ACPI_STATUS OsdSleepUsec(UINT32); #endif /* ACPI_NO_OSDFUNC_INLINE */ #else /* !_KERNEL */ diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index d06794d47de1..011a6b100097 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -202,6 +202,7 @@ extern void acpi_intr(void *data); extern void acpi_queue_event(acpi_softc_t *sc, int type, int arg); extern int acpi_send_pm_event(acpi_softc_t *sc, u_int8_t state); extern void acpi_enable_events(acpi_softc_t *sc); +extern void acpi_disable_events(acpi_softc_t *sc); extern void acpi_clear_ignore_events(void *arg); extern void acpi_event_thread(void *arg); @@ -244,3 +245,9 @@ extern void acpi_mapmem(void); extern int acpi_debug; #define ACPI_DEVPRINTF(args...) printf("acpi0: " args) #define ACPI_DEBUGPRINT(args...) do { if (acpi_debug) ACPI_DEVPRINTF(args);} while(0) + +/* + * System service interface + */ +extern int acpi_sleep(u_int32_t micro); + diff --git a/sys/dev/acpi/aml/aml_common.h b/sys/dev/acpi/aml/aml_common.h index 4988385d5134..827c324d1e04 100644 --- a/sys/dev/acpi/aml/aml_common.h +++ b/sys/dev/acpi/aml/aml_common.h @@ -47,11 +47,15 @@ printf(fmt, args); \ } while(0) #define AML_DEBUGGER(x, y) /* no debugger in kernel */ +#define AML_STALL(micro) DELAY(micro) +#define AML_SLEEP(sec, milli) OsdSleep(sec, milli) #else /* !_KERNEL */ #define AML_SYSASSERT(x) assert(x) #define AML_SYSABORT() abort() #define AML_SYSERRX(eval, fmt, args...) errx(eval, fmt, args) #define AML_DEBUGGER(x, y) aml_dbgr(x, y) +#define AML_STALL(micro) /* not required in userland */ +#define AML_SLEEP(sec, milli) /* not required in userland */ #endif /* _KERNEL */ union aml_object; diff --git a/sys/dev/acpi/aml/aml_parse.c b/sys/dev/acpi/aml/aml_parse.c index f98977d3bd62..ce40e647fd51 100644 --- a/sys/dev/acpi/aml/aml_parse.c +++ b/sys/dev/acpi/aml/aml_parse.c @@ -55,6 +55,14 @@ #include "debug.h" #else /* _KERNEL */ #include +#include +#include +#include +#include +#include +#ifndef ACPI_NO_OSDFUNC_INLINE +#include +#endif #endif /* !_KERNEL */ static int findsetleftbit(int num); @@ -1484,14 +1492,18 @@ aml_parse_termobj(struct aml_environ *env, int indent) aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; - case 0x21: /* StallOp *//* XXX Not yet */ + case 0x21: /* StallOp */ AML_DEBUGPRINT("Stall("); - aml_parse_termobj(env, indent); + num1 = aml_objtonum(env, aml_eval_name(env, + aml_parse_termobj(env, indent))); AML_DEBUGPRINT(")"); + AML_STALL(num1); break; - case 0x22: /* SleepOp *//* XXX Not yet */ + case 0x22: /* SleepOp */ AML_DEBUGPRINT("Sleep("); - aml_parse_termobj(env, indent); + num1 = aml_objtonum(env, aml_eval_name(env, + aml_parse_termobj(env, indent))); + AML_SLEEP(0, num1); AML_DEBUGPRINT(")"); break; case 0x23: /* AcquireOp *//* XXX Not yet */ diff --git a/sys/i386/include/acpica_osd.h b/sys/i386/include/acpica_osd.h index 9255e74cac6a..63a6466b05aa 100644 --- a/sys/i386/include/acpica_osd.h +++ b/sys/i386/include/acpica_osd.h @@ -38,8 +38,16 @@ #include #include +#include + #include "pcib_if.h" +#ifdef ACPI_NO_OSDFUNC_INLINE +#define _ACPICA_INLINE_ +#else +#define _ACPICA_INLINE_ static __inline +#endif + /* * ACPICA compatibility */ @@ -98,28 +106,19 @@ OsdInX(ACPI_IO_ADDRESS InPort, int bytes) return (retval); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -UINT8 +_ACPICA_INLINE_ UINT8 OsdIn8(ACPI_IO_ADDRESS InPort) { return (OsdInX(InPort, 1) & 0xff); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -UINT16 +_ACPICA_INLINE_ UINT16 OsdIn16(ACPI_IO_ADDRESS InPort) { return (OsdInX(InPort, 2) & 0xffff); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -UINT32 +_ACPICA_INLINE_ UINT32 OsdIn32(ACPI_IO_ADDRESS InPort) { return (OsdInX(InPort, 4)); @@ -148,37 +147,25 @@ OsdOutX(ACPI_IO_ADDRESS OutPort, UINT32 Value, int bytes) } } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -void +_ACPICA_INLINE_ void OsdOut8(ACPI_IO_ADDRESS OutPort, UINT8 Value) { OsdOutX(OutPort, Value, 1); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -void +_ACPICA_INLINE_ void OsdOut16(ACPI_IO_ADDRESS OutPort, UINT16 Value) { OsdOutX(OutPort, Value, 2); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -void +_ACPICA_INLINE_ void OsdOut32(ACPI_IO_ADDRESS OutPort, UINT32 Value) { OsdOutX(OutPort, Value, 4); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -ACPI_STATUS +_ACPICA_INLINE_ ACPI_STATUS OsdMapMemory(void *PhysicalAddress, UINT32 Length, void **LogicalAddress) { vm_offset_t PhysicalEnd; @@ -203,10 +190,7 @@ OsdMapMemory(void *PhysicalAddress, UINT32 Length, void **LogicalAddress) return (AE_OK); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -void +_ACPICA_INLINE_ void OsdUnMapMemory(void *LogicalAddress, UINT32 Length) { @@ -234,10 +218,7 @@ OsdReadPciCfg(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 *Value, return (AE_OK); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -ACPI_STATUS +_ACPICA_INLINE_ ACPI_STATUS OsdReadPciCfgByte(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT8 *Value) { ACPI_STATUS status; @@ -248,10 +229,7 @@ OsdReadPciCfgByte(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT8 *Val return (status); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -ACPI_STATUS +_ACPICA_INLINE_ ACPI_STATUS OsdReadPciCfgWord(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT16 *Value) { ACPI_STATUS status; @@ -262,10 +240,7 @@ OsdReadPciCfgWord(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT16 *Va return (status); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -ACPI_STATUS +_ACPICA_INLINE_ ACPI_STATUS OsdReadPciCfgDword(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 *Value) { ACPI_STATUS status; @@ -291,29 +266,53 @@ OsdWritePciCfg(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 Value, return (AE_OK); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -ACPI_STATUS +_ACPICA_INLINE_ ACPI_STATUS OsdWritePciCfgByte(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT8 Value) { return (OsdWritePciCfg(Bus, DeviceFunction, Register, (UINT32) Value, 1)); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -ACPI_STATUS +_ACPICA_INLINE_ ACPI_STATUS OsdWritePciCfgWord(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT16 Value) { return (OsdWritePciCfg(Bus, DeviceFunction, Register, (UINT32) Value, 2)); } -#ifndef ACPI_NO_OSDFUNC_INLINE -static __inline -#endif -ACPI_STATUS +_ACPICA_INLINE_ ACPI_STATUS OsdWritePciCfgDword(UINT32 Bus, UINT32 DeviceFunction, UINT32 Register, UINT32 Value) { return (OsdWritePciCfg(Bus, DeviceFunction, Register, Value, 4)); } + +_ACPICA_INLINE_ ACPI_STATUS +OsdSleepUsec(UINT32 Microseconds) +{ + int error; + ACPI_STATUS status; + + error = acpi_sleep(Microseconds); + switch (error) { + case 0: + /* The running thread slept for the time specified */ + status = AE_OK; + break; + case 1: + /* TBD!!!! */ + status = AE_BAD_PARAMETER; + break; + case 2: + default: + /* The running thread did not slept because of a host OS error */ + status = AE_ERROR; + break; + } + + return (status); +} + +_ACPICA_INLINE_ ACPI_STATUS +OsdSleep(UINT32 Seconds, UINT32 Milliseconds) +{ + return OsdSleepUsec(Seconds * 1000000L + Milliseconds * 1000); +} + diff --git a/usr.sbin/acpi/amldb/aml/aml_common.h b/usr.sbin/acpi/amldb/aml/aml_common.h index 4988385d5134..827c324d1e04 100644 --- a/usr.sbin/acpi/amldb/aml/aml_common.h +++ b/usr.sbin/acpi/amldb/aml/aml_common.h @@ -47,11 +47,15 @@ printf(fmt, args); \ } while(0) #define AML_DEBUGGER(x, y) /* no debugger in kernel */ +#define AML_STALL(micro) DELAY(micro) +#define AML_SLEEP(sec, milli) OsdSleep(sec, milli) #else /* !_KERNEL */ #define AML_SYSASSERT(x) assert(x) #define AML_SYSABORT() abort() #define AML_SYSERRX(eval, fmt, args...) errx(eval, fmt, args) #define AML_DEBUGGER(x, y) aml_dbgr(x, y) +#define AML_STALL(micro) /* not required in userland */ +#define AML_SLEEP(sec, milli) /* not required in userland */ #endif /* _KERNEL */ union aml_object; diff --git a/usr.sbin/acpi/amldb/aml/aml_parse.c b/usr.sbin/acpi/amldb/aml/aml_parse.c index f98977d3bd62..ce40e647fd51 100644 --- a/usr.sbin/acpi/amldb/aml/aml_parse.c +++ b/usr.sbin/acpi/amldb/aml/aml_parse.c @@ -55,6 +55,14 @@ #include "debug.h" #else /* _KERNEL */ #include +#include +#include +#include +#include +#include +#ifndef ACPI_NO_OSDFUNC_INLINE +#include +#endif #endif /* !_KERNEL */ static int findsetleftbit(int num); @@ -1484,14 +1492,18 @@ aml_parse_termobj(struct aml_environ *env, int indent) aml_parse_termobj(env, indent); AML_DEBUGPRINT(")"); break; - case 0x21: /* StallOp *//* XXX Not yet */ + case 0x21: /* StallOp */ AML_DEBUGPRINT("Stall("); - aml_parse_termobj(env, indent); + num1 = aml_objtonum(env, aml_eval_name(env, + aml_parse_termobj(env, indent))); AML_DEBUGPRINT(")"); + AML_STALL(num1); break; - case 0x22: /* SleepOp *//* XXX Not yet */ + case 0x22: /* SleepOp */ AML_DEBUGPRINT("Sleep("); - aml_parse_termobj(env, indent); + num1 = aml_objtonum(env, aml_eval_name(env, + aml_parse_termobj(env, indent))); + AML_SLEEP(0, num1); AML_DEBUGPRINT(")"); break; case 0x23: /* AcquireOp *//* XXX Not yet */