diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c index c56e8c1bda..7b77368daa 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -258,9 +258,21 @@ status_t evaluate_method (const char *object, const char *method, acpi_object_ty return (status == AE_OK) ? B_OK : B_ERROR; } +void waking_vector(void) { + //--- This should do something --- +} + status_t enter_sleep_state (uint8 state) { ACPI_STATUS status; cpu_status cpu; + physical_entry wake_vector; + + lock_memory(&waking_vector,sizeof(waking_vector),0); + get_memory_map(&waking_vector,sizeof(waking_vector),&wake_vector,1); + + status = AcpiSetFirmwareWakingVector(wake_vector.address); + if (status != AE_OK) + return B_ERROR; status = AcpiEnterSleepStatePrep(state); if (status != AE_OK) @@ -275,9 +287,9 @@ status_t enter_sleep_state (uint8 state) { if (status != AE_OK) return B_ERROR; - status = AcpiLeaveSleepState(state); + /*status = AcpiLeaveSleepState(state); if (status != AE_OK) - return B_ERROR; + return B_ERROR;*/ return B_OK; } diff --git a/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h b/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h index b7cf44abce..658747eb5d 100644 --- a/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h +++ b/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h @@ -151,8 +151,7 @@ #define ACPI_INTERNAL_VAR_XFACE -#define ACPI_FLUSH_CPU_CACHE() -/* Implement ACPI_FLUSH_CPU_CACHE to do something! */ +#define ACPI_FLUSH_CPU_CACHE() __asm __volatile("wbinvd"); #ifdef ACPI_DEBUG #define ACPI_DEBUG_OUTPUT @@ -188,8 +187,12 @@ #define ACPI_USE_SYSTEM_CLIBRARY #define ACPI_USE_NATIVE_DIVIDE -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) +extern int acpi_acquire_global_lock(uint32 *lock); +extern int acpi_release_global_lock(uint32 *lock); + +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) ((Acq) = acpi_acquire_global_lock(GLptr)) +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) ((Acq) = acpi_release_global_lock(GLptr)) + /* Kernel doesn't have strupr, should be fixed. */ static __inline char * diff --git a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c index 47fecac14a..91d3c68979 100644 --- a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c +++ b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c @@ -684,6 +684,16 @@ AcpiOsSignalSemaphore ( return AE_OK; } +/* For R5 compatibility */ + +inline int32 +_atomic_test_and_set(volatile int32 *value, int32 newValue, int32 testAgainst) +{ + int32 oldValue; + asm volatile("lock; cmpxchg %%ecx, (%%edx)" + : "=a" (oldValue) : "a" (testAgainst), "c" (newValue), "d" (value)); + return oldValue; +} ACPI_STATUS AcpiOsCreateLock ( @@ -726,7 +736,7 @@ AcpiOsAcquireLock ( call is hanging the system? I'm not sure how to detect that though. Anyway, this works, even if it's stupid. */ - while (atomic_add(((spinlock *)(Handle)),0) <= 0); + while (_atomic_test_and_set(((spinlock *)(Handle)),0,1) <= 0); } @@ -1270,4 +1280,48 @@ AcpiOsSignal ( return (AE_OK); } +/* The following stolen from FreeBSD */ +/* Section 5.2.9.1: global lock acquire/release functions */ +#define GL_ACQUIRED (-1) +#define GL_BUSY 0 +#define GL_BIT_PENDING 0x1 +#define GL_BIT_OWNED 0x2 +#define GL_BIT_MASK (GL_BIT_PENDING | GL_BIT_OWNED) + +/* + * Acquire the global lock. If busy, set the pending bit. The caller + * will wait for notification from the BIOS that the lock is available + * and then attempt to acquire it again. + */ +int +acpi_acquire_global_lock(uint32 *lock) +{ + uint32 new, old; + + do { + old = *lock; + new = ((old & ~GL_BIT_MASK) | GL_BIT_OWNED) | + ((old >> 1) & GL_BIT_PENDING); + } while (_atomic_test_and_set(lock, new, old) != old); + + return ((new < GL_BIT_MASK) ? GL_ACQUIRED : GL_BUSY); +} + +/* + * Release the global lock, returning whether there is a waiter pending. + * If the BIOS set the pending bit, OSPM must notify the BIOS when it + * releases the lock. + */ +int +acpi_release_global_lock(uint32 *lock) +{ + uint32 new, old; + + do { + old = *lock; + new = old & ~GL_BIT_MASK; + } while (_atomic_test_and_set(lock, new, old) != old); + + return (old & GL_BIT_PENDING); +}