// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <threads.h>

#include <hw/inout.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zxcpp/new.h>
#include <fbl/auto_lock.h>
#include <fbl/intrusive_hash_table.h>
#include <fbl/unique_ptr.h>

#if !defined(__x86_64__) && !defined(__x86__)
#error "Unsupported architecture"
#endif

#include "acpi.h"

__WEAK zx_handle_t root_resource_handle;

#define _COMPONENT          ACPI_OS_SERVICES
ACPI_MODULE_NAME    ("oszircon")

#define LOCAL_TRACE 0

#define TRACEF(str, x...) do { printf("%s:%d: " str, __FUNCTION__, __LINE__, ## x); } while (0)
#define LTRACEF(x...) do { if (LOCAL_TRACE) { TRACEF(x); } } while (0)

/* Data used for implementing AcpiOsExecute and
 * AcpiOsWaitEventsComplete */
static mtx_t os_execute_lock = MTX_INIT;
static cnd_t os_execute_cond;
static int os_execute_tasks = 0;

class AcpiOsMappingNode :
      public fbl::SinglyLinkedListable<fbl::unique_ptr<AcpiOsMappingNode>> {
public:
    using HashTable =
        fbl::HashTable<uintptr_t, fbl::unique_ptr<AcpiOsMappingNode>>;

    // @param vaddr Virtual address returned to ACPI, used as key to the hashtable.
    // @param vaddr_actual Actual virtual address of the mapping. May be different than
    //                     vaddr if it is unaligned.
    // @param length Length of the mapping
    // @param vmo_handle Handle to the mapped VMO
    AcpiOsMappingNode(uintptr_t vaddr, uintptr_t vaddr_actual,
                      size_t length, zx_handle_t vmo_handle);
    ~AcpiOsMappingNode();

    // Trait implementation for fbl::HashTable
    uintptr_t GetKey() const { return vaddr_; }
    static size_t GetHash(uintptr_t key) { return key; }

private:
    uintptr_t vaddr_;
    uintptr_t vaddr_actual_;
    size_t length_;
    zx_handle_t vmo_handle_;
};

fbl::Mutex os_mapping_lock;

AcpiOsMappingNode::HashTable os_mapping_tbl;

const size_t PCIE_MAX_DEVICES_PER_BUS = 32;
const size_t PCIE_MAX_FUNCTIONS_PER_DEVICE = 8;

AcpiOsMappingNode::AcpiOsMappingNode(uintptr_t vaddr, uintptr_t vaddr_actual,
                                     size_t length, zx_handle_t vmo_handle)
    : vaddr_(vaddr), vaddr_actual_(vaddr_actual),
      length_(length), vmo_handle_(vmo_handle) {
}

AcpiOsMappingNode::~AcpiOsMappingNode() {
    zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)vaddr_actual_, length_);
    zx_handle_close(vmo_handle_);
}

static zx_status_t mmap_physical(zx_paddr_t phys, size_t size, uint32_t cache_policy,
                                 zx_handle_t* out_vmo, zx_vaddr_t* out_vaddr) {
    zx_handle_t vmo;
    zx_vaddr_t vaddr;
    zx_status_t st = zx_vmo_create_physical(root_resource_handle, phys, size, &vmo);
    if (st != ZX_OK) {
        return st;
    }
    st = zx_vmo_set_cache_policy(vmo, cache_policy);
    if (st != ZX_OK) {
        zx_handle_close(vmo);
        return st;
    }
    st = zx_vmar_map(zx_vmar_root_self(), 0, vmo, 0, size,
                     ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | ZX_VM_FLAG_MAP_RANGE,
                     &vaddr);
    if (st != ZX_OK) {
        zx_handle_close(vmo);
        return st;
    } else {
        *out_vmo = vmo;
        *out_vaddr = vaddr;
        return ZX_OK;
    }
}

static ACPI_STATUS thrd_status_to_acpi_status(int status) {
    switch (status) {
        case thrd_success: return AE_OK;
        case thrd_nomem: return AE_NO_MEMORY;
        case thrd_timedout: return AE_TIME;
        default: return AE_ERROR;
    }
}

/**
 * @brief Initialize the OSL subsystem.
 *
 * This function allows the OSL to initialize itself.  It is called during
 * intiialization of the ACPICA subsystem.
 *
 * @return Initialization status
 */
ACPI_STATUS AcpiOsInitialize() {
    ACPI_STATUS status = thrd_status_to_acpi_status(
            cnd_init(&os_execute_cond));
    if (status != AE_OK) {
        return status;
    }
    /* TODO(teisenbe): be less permissive */
    zx_mmap_device_io(root_resource_handle, 0, 65536);
    return AE_OK;
}

/**
 * @brief Terminate the OSL subsystem.
 *
 * This function allows the OSL to cleanup and terminate.  It is called during
 * termination of the ACPICA subsystem.
 *
 * @return Termination status
 */
ACPI_STATUS AcpiOsTerminate() {
    cnd_destroy(&os_execute_cond);

    return AE_OK;
}

/**
 * @brief Obtain the Root ACPI table pointer (RSDP).
 *
 * @return The physical address of the RSDP
 */
ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer() {
    ACPI_PHYSICAL_ADDRESS TableAddress = 0;
    ACPI_STATUS status = AcpiFindRootPointer(&TableAddress);

    uint32_t uefi_rsdp = (uint32_t)zx_acpi_uefi_rsdp(root_resource_handle);
    if (uefi_rsdp != 0) {
        return uefi_rsdp;
    }

    if (status != AE_OK) {
        return 0;
    }
    return TableAddress;
}

/**
 * @brief Allow the host OS to override a predefined ACPI object.
 *
 * @param PredefinedObject A pointer to a predefind object (name and initial
 *        value)
 * @param NewValue Where a new value for the predefined object is returned.
 *        NULL if there is no override for this object.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsPredefinedOverride(
        const ACPI_PREDEFINED_NAMES *PredefinedObject,
        ACPI_STRING *NewValue) {
    *NewValue = NULL;
    return AE_OK;
}

/**
 * @brief Allow the host OS to override a firmware ACPI table via a logical
 *        address.
 *
 * @param ExistingTable A pointer to the header of the existing ACPI table
 * @param NewTable Where the pointer to the replacment table is returned.  The
 *        OSL returns NULL if no replacement is provided.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsTableOverride(
        ACPI_TABLE_HEADER *ExistingTable,
        ACPI_TABLE_HEADER **NewTable) {
    *NewTable = NULL;
    return AE_OK;
}

/**
 * @brief Allow the host OS to override a firmware ACPI table via a physical
 *        address.
 *
 * @param ExistingTable A pointer to the header of the existing ACPI table
 * @param NewAddress Where the physical address of the replacment table is
 *        returned.  The OSL returns NULL if no replacement is provided.
 * @param NewLength Where the length of the replacement table is returned.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsPhysicalTableOverride(
        ACPI_TABLE_HEADER *ExistingTable,
        ACPI_PHYSICAL_ADDRESS *NewAddress,
        UINT32 *NewTableLength) {
    *NewAddress = 0;
    return AE_OK;
}

// If we decide to make use of a more Zircon specific cache mechanism,
// remove the ACPI_USE_LOCAL_CACHE define from the header and implement these
// functions.
#if 0
/**
 * @brief Create a memory cache object.
 *
 * @param CacheName An ASCII identfier for the cache.
 * @param ObjectSize The size of each object in the cache.
 * @param MaxDepth Maximum number of objects in the cache.
 * @param ReturnCache Where a pointer to the cache object is returned.
 *
 * @return AE_OK The cache was successfully created.
 * @return AE_BAD_PARAMETER The ReturnCache pointer is NULL or ObjectSize < 16.
 * @return AE_NO_MEMORY Insufficient dynamic memory to complete the operation.
 */
ACPI_STATUS AcpiOsCreateCache(
        char *CacheName,
        UINT16 ObjectSize,
        UINT16 MaxDepth,
        ACPI_CACHE_T **ReturnCache) {
    PANIC_UNIMPLEMENTED;
    return AE_NO_MEMORY;
}

/**
 * @brief Delete a memory cache object.
 *
 * @param Cache The cache object to be deleted.
 *
 * @return AE_OK The cache was successfully deleted.
 * @return AE_BAD_PARAMETER The Cache pointer is NULL.
 */
ACPI_STATUS AcpiOsDeleteCache(ACPI_CACHE_T *Cache) {
    PANIC_UNIMPLEMENTED;
    return AE_OK;
}

/**
 * @brief Free all objects currently within a cache object.
 *
 * @param Cache The cache object to purge.
 *
 * @return AE_OK The cache was successfully purged.
 * @return AE_BAD_PARAMETER The Cache pointer is NULL.
 */
ACPI_STATUS AcpiOsPurgeCache(ACPI_CACHE_T *Cache) {
    PANIC_UNIMPLEMENTED;
    return AE_OK;
}


/**
 * @brief Acquire an object from a cache.
 *
 * @param Cache The cache object from which to acquire an object.
 *
 * @return A pointer to a cache object. NULL if the object could not be
 *         acquired.
 */
void *AcpiOsAcquireObject(ACPI_CACHE_T *Cache) {
    PANIC_UNIMPLEMENTED;
    return NULL;
}

/**
 * @brief Release an object to a cache.
 *
 * @param Cache The cache object to which the object will be released.
 * @param Object The object to be released.
 *
 * @return AE_OK The object was successfully released.
 * @return AE_BAD_PARAMETER The Cache or Object pointer is NULL.
 */
ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object) {
    PANIC_UNIMPLEMENTED;
    return AE_OK;
}
#endif

/**
 * @brief Map physical memory into the caller's address space.
 *
 * @param PhysicalAddress A full physical address of the memory to be mapped
 *        into the caller's address space
 * @param Length The amount of memory to mapped starting at the given physical
 *        address
 *
 * @return Logical pointer to the mapped memory. A NULL pointer indicated failures.
 */
void *AcpiOsMapMemory(
        ACPI_PHYSICAL_ADDRESS PhysicalAddress,
        ACPI_SIZE Length) {

    fbl::AutoLock lock(&os_mapping_lock);

    // Caution: PhysicalAddress might not be page-aligned, Length might not
    // be a page multiple.

    ACPI_PHYSICAL_ADDRESS aligned_address = PhysicalAddress & ~(PAGE_SIZE - 1);
    ACPI_PHYSICAL_ADDRESS end = (PhysicalAddress + Length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);

    uintptr_t vaddr;
    size_t length = end - aligned_address;
    zx_handle_t vmo;
    zx_status_t status = mmap_physical(aligned_address, end - aligned_address,
                                       ZX_CACHE_POLICY_CACHED, &vmo, &vaddr);
    if (status != ZX_OK) {
        return NULL;
    }

    void* out_addr = (void*)(vaddr + (PhysicalAddress - aligned_address));
    fbl::unique_ptr<AcpiOsMappingNode> mn(
            new AcpiOsMappingNode(reinterpret_cast<uintptr_t>(out_addr),
                                  vaddr, length, vmo));
    os_mapping_tbl.insert(fbl::move(mn));

    return out_addr;
}

/**
 * @brief Remove a physical to logical memory mapping.
 *
 * @param LogicalAddress The logical address that was returned from a previous
 *        call to AcpiOsMapMemory.
 * @param Length The amount of memory that was mapped. This value must be
 *        identical to the value used in the call to AcpiOsMapMemory.
 */
void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length) {
    fbl::AutoLock lock(&os_mapping_lock);
    fbl::unique_ptr<AcpiOsMappingNode> mn = os_mapping_tbl.erase((uintptr_t)LogicalAddress);
    if (mn == NULL) {
        printf("AcpiOsUnmapMemory nonexisting mapping %p\n", LogicalAddress);
    }
}

/**
 * @brief Allocate memory from the dynamic memory pool.
 *
 * @param Size Amount of memory to allocate.
 *
 * @return A pointer to the allocated memory. A NULL pointer is returned on
 *         error.
 */
void *AcpiOsAllocate(ACPI_SIZE Size) {
    return malloc(Size);
}

/**
 * @brief Free previously allocated memory.
 *
 * @param Memory A pointer to the memory to be freed.
 */
void AcpiOsFree(void *Memory) {
    free(Memory);
}

/**
 * @brief Obtain the ID of the currently executing thread.
 *
 * @return A unique non-zero value that represents the ID of the currently
 *         executing thread. The value -1 is reserved and must not be returned
 *         by this interface.
 */
static_assert(sizeof(ACPI_THREAD_ID) >= sizeof(zx_handle_t), "tid size");
ACPI_THREAD_ID AcpiOsGetThreadId() {
    return (uintptr_t)thrd_current();
}

/* Structures used for implementing AcpiOsExecute and
 * AcpiOsWaitEventsComplete */
struct acpi_os_task_ctx {
    ACPI_OSD_EXEC_CALLBACK func;
    void *ctx;
};

static int acpi_os_task(void *raw_ctx) {
    struct acpi_os_task_ctx *ctx = (struct acpi_os_task_ctx*)raw_ctx;

    ctx->func(ctx->ctx);

    mtx_lock(&os_execute_lock);
    os_execute_tasks--;
    if (os_execute_tasks == 0) {
        cnd_broadcast(&os_execute_cond);
    }
    mtx_unlock(&os_execute_lock);

    free(ctx);
    return 0;
}

/**
 * @brief Schedule a procedure for deferred execution.
 *
 * @param Type Type of the callback function.
 * @param Function Address of the procedure to execute.
 * @param Context A context value to be passed to the called procedure.
 *
 * @return AE_OK The procedure was successfully queued for execution.
 * @return AE_BAD_PARAMETER The Type is invalid or the Function pointer
 *         is NULL.
 */
ACPI_STATUS AcpiOsExecute(
        ACPI_EXECUTE_TYPE Type,
        ACPI_OSD_EXEC_CALLBACK Function,
        void *Context) {

    if (Function == NULL) {
        return AE_BAD_PARAMETER;
    }

    switch (Type) {
        case OSL_GLOBAL_LOCK_HANDLER:
        case OSL_NOTIFY_HANDLER:
        case OSL_GPE_HANDLER:
        case OSL_DEBUGGER_MAIN_THREAD:
        case OSL_DEBUGGER_EXEC_THREAD:
        case OSL_EC_POLL_HANDLER:
        case OSL_EC_BURST_HANDLER: break;
        default: return AE_BAD_PARAMETER;
    }

    struct acpi_os_task_ctx *ctx = (struct acpi_os_task_ctx*)malloc(sizeof(*ctx));
    if (!ctx) {
        return AE_NO_MEMORY;
    }
    ctx->func = Function;
    ctx->ctx = Context;

    mtx_lock(&os_execute_lock);
    os_execute_tasks++;
    mtx_unlock(&os_execute_lock);

    // TODO(teisenbe): Instead of spawning a thread each time for this,
    // we should back this with a thread pool.
    thrd_t thread;
    ACPI_STATUS status = thrd_status_to_acpi_status(
            thrd_create(&thread, acpi_os_task, ctx));
    if (status != AE_OK) {
        free(ctx);
        mtx_lock(&os_execute_lock);
        os_execute_tasks--;
        if (os_execute_tasks == 0) {
            cnd_broadcast(&os_execute_cond);
        }
        mtx_unlock(&os_execute_lock);
        return status;
    }

    thrd_detach(thread);
    return AE_OK;
}

/**
 * @brief Wait for completion of asynchronous events.
 *
 * This function blocks until all asynchronous events initiated by
 * AcpiOsExecute have completed.
 */
void AcpiOsWaitEventsComplete(void) {
    mtx_lock(&os_execute_lock);
    while (os_execute_tasks > 0) {
        cnd_wait(&os_execute_cond, &os_execute_lock);
    }
    mtx_unlock(&os_execute_lock);
}

/**
 * @brief Suspend the running task (course granularity).
 *
 * @param Milliseconds The amount of time to sleep, in milliseconds.
 */
void AcpiOsSleep(UINT64 Milliseconds) {
    if (Milliseconds > UINT32_MAX) {
        // If we're asked to sleep for a long time (>1.5 months), shorten it
        Milliseconds = UINT32_MAX;
    }
    zx_nanosleep(zx_deadline_after(ZX_MSEC(Milliseconds)));
}

/**
 * @brief Wait for a short amount of time (fine granularity).
 *
 * Execution of the running thread is not suspended for this time.
 *
 * @param Microseconds The amount of time to delay, in microseconds.
 */
void AcpiOsStall(UINT32 Microseconds) {
    zx_nanosleep(zx_deadline_after(ZX_USEC(Microseconds)));
}

/**
 * @brief Create a semaphore.
 *
 * @param MaxUnits The maximum number of units this semaphore will be required
 *        to accept
 * @param InitialUnits The initial number of units to be assigned to the
 *        semaphore.
 * @param OutHandle A pointer to a locaton where a handle to the semaphore is
 *        to be returned.
 *
 * @return AE_OK The semaphore was successfully created.
 * @return AE_BAD_PARAMETER The InitialUnits is invalid or the OutHandle
 *         pointer is NULL.
 * @return AE_NO_MEMORY Insufficient memory to create the semaphore.
 */
ACPI_STATUS AcpiOsCreateSemaphore(
        UINT32 MaxUnits,
        UINT32 InitialUnits,
        ACPI_SEMAPHORE *OutHandle) {
    sem_t *sem = (sem_t*)malloc(sizeof(sem_t));
    if (!sem) {
        return AE_NO_MEMORY;
    }
    if (sem_init(sem, 0, InitialUnits) < 0) {
        free(sem);
        return AE_ERROR;
    }
    *OutHandle = sem;
    return AE_OK;
}

/**
 * @brief Delete a semaphore.
 *
 * @param Handle A handle to a semaphore objected that was returned by a
 *        previous call to AcpiOsCreateSemaphore.
 *
 * @return AE_OK The semaphore was successfully deleted.
 * @return AE_BAD_PARAMETER The Handle is invalid.
 */
ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle) {
    free(Handle);
    return AE_OK;
}

/**
 * @brief Wait for units from a semaphore.
 *
 * @param Handle A handle to a semaphore objected that was returned by a
 *        previous call to AcpiOsCreateSemaphore.
 * @param Units The number of units the caller is requesting.
 * @param Timeout How long the caller is willing to wait for the requested
 *        units, in milliseconds.  A value of -1 indicates that the caller
 *        is willing to wait forever. Timeout may be 0.
 *
 * @return AE_OK The requested units were successfully received.
 * @return AE_BAD_PARAMETER The Handle is invalid.
 * @return AE_TIME The units could not be acquired within the specified time.
 */
ACPI_STATUS AcpiOsWaitSemaphore(
        ACPI_SEMAPHORE Handle,
        UINT32 Units,
        UINT16 Timeout) {

    if (Timeout == UINT16_MAX) {
        if (sem_wait(Handle) < 0) {
            ZX_ASSERT_MSG(false, "sem_wait failed %d", errno);
        }
        return AE_OK;
    }

    zx_time_t now = zx_time_get(ZX_CLOCK_UTC);
    struct timespec then = {
        .tv_sec = static_cast<time_t>(now / ZX_SEC(1)),
        .tv_nsec = static_cast<long>(now % ZX_SEC(1)),
    };
    then.tv_nsec += ZX_MSEC(Timeout);
    if (then.tv_nsec > static_cast<long>(ZX_SEC(1))) {
        then.tv_sec += then.tv_nsec / ZX_SEC(1);
        then.tv_nsec %= ZX_SEC(1);
    }

    if (sem_timedwait(Handle, &then) < 0) {
        ZX_ASSERT_MSG(errno == ETIMEDOUT, "sem_timedwait failed unexpectedly %d", errno);
        return AE_TIME;
    }
    return AE_OK;
}

/**
 * @brief Send units to a semaphore.
 *
 * @param Handle A handle to a semaphore objected that was returned by a
 *        previous call to AcpiOsCreateSemaphore.
 * @param Units The number of units to send to the semaphore.
 *
 * @return AE_OK The semaphore was successfully signaled.
 * @return AE_BAD_PARAMETER The Handle is invalid.
 */
ACPI_STATUS AcpiOsSignalSemaphore(
        ACPI_SEMAPHORE Handle,
        UINT32 Units) {
    // TODO: Implement support for Units > 1
    assert(Units == 1);

    sem_post(Handle);
    return AE_OK;
}

/**
 * @brief Create a spin lock.
 *
 * @param OutHandle A pointer to a locaton where a handle to the lock is
 *        to be returned.
 *
 * @return AE_OK The lock was successfully created.
 * @return AE_BAD_PARAMETER The OutHandle pointer is NULL.
 * @return AE_NO_MEMORY Insufficient memory to create the lock.
 */
ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle) {
    // Since we don't have a notion of interrupt contex in usermode, just make
    // these mutexes.
    mtx_t* lock = (mtx_t*)malloc(sizeof(mtx_t));
    if (!lock) {
        return AE_NO_MEMORY;
    }

    ACPI_STATUS status = thrd_status_to_acpi_status(
            mtx_init(lock, mtx_plain));
    if (status != AE_OK) {
        return status;
    }
    *OutHandle = lock;
    return AE_OK;
}

/**
 * @brief Delete a spin lock.
 *
 * @param Handle A handle to a lock objected that was returned by a
 *        previous call to AcpiOsCreateLock.
 *
 * @return AE_OK The lock was successfully deleted.
 * @return AE_BAD_PARAMETER The Handle is invalid.
 */
void AcpiOsDeleteLock(ACPI_SPINLOCK Handle) {
    mtx_destroy(Handle);
    free(Handle);
}

/**
 * @brief Acquire a spin lock.
 *
 * @param Handle A handle to a lock objected that was returned by a
 *        previous call to AcpiOsCreateLock.
 *
 * @return Platform-dependent CPU flags.  To be used when the lock is released.
 */
ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle) {
    mtx_lock(Handle);
    return 0;
}

/**
 * @brief Release a spin lock.
 *
 * @param Handle A handle to a lock objected that was returned by a
 *        previous call to AcpiOsCreateLock.
 * @param Flags CPU Flags that were returned from AcpiOsAcquireLock.
 */
void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags) {
    mtx_unlock(Handle);
}

// Wrapper structs for interfacing between our interrupt handler convention and
// ACPICA's
struct acpi_irq_thread_arg {
    ACPI_OSD_HANDLER handler;
    zx_handle_t irq_handle;
    void *context;
};
static int acpi_irq_thread(void *arg) {
    struct acpi_irq_thread_arg *real_arg = (struct acpi_irq_thread_arg *)arg;
    while (1) {
        zx_status_t status = zx_interrupt_wait(real_arg->irq_handle);
        if (status != ZX_OK) {
            continue;
        }

        // TODO: Should we do something with the return value from the handler?
        real_arg->handler(real_arg->context);

        zx_interrupt_complete(real_arg->irq_handle);
    }
    return 0;
}

/**
 * @brief Install a handler for a hardware interrupt.
 *
 * @param InterruptLevel Interrupt level that the handler will service.
 * @param Handler Address of the handler.
 * @param Context A context value that is passed to the handler when the
 *        interrupt is dispatched.
 *
 * @return AE_OK The handler was successfully installed.
 * @return AE_BAD_PARAMETER The InterruptNumber is invalid or the Handler
 *         pointer is NULL.
 * @return AE_ALREADY_EXISTS A handler for this interrupt level is already
 *         installed.
 */
ACPI_STATUS AcpiOsInstallInterruptHandler(
        UINT32 InterruptLevel,
        ACPI_OSD_HANDLER Handler,
        void *Context) {
    // Note that InterruptLevel here is ISA IRQs (or global of the legacy PIC
    // does't exist), not system exceptions.

    // TODO: Clean this up to be less x86 centric.

    if (InterruptLevel == 0) {
        /* Some buggy firmware fails to populate the SCI_INT field of the FADT
         * properly.  0 is a known bad value, since the legacy PIT uses it and
         * cannot be remapped.  Just lie and say we installed a handler; this
         * system will just never receive an SCI.  If we return an error here,
         * ACPI init will fail completely, and the system will be unusable. */
        return AE_OK;
    }

    assert(InterruptLevel == 0x9); // SCI

    struct acpi_irq_thread_arg *arg = (struct acpi_irq_thread_arg*)malloc(sizeof(*arg));
    if (!arg) {
        return AE_NO_MEMORY;
    }

    zx_handle_t handle;
    zx_status_t status = zx_interrupt_create(root_resource_handle, InterruptLevel,
                                             ZX_FLAG_REMAP_IRQ, &handle);
    if (status != ZX_OK) {
        free(arg);
        return AE_ERROR;
    }

    arg->handler = Handler;
    arg->context = Context;
    arg->irq_handle = handle;

    thrd_t thread;
    int ret = thrd_create(&thread, acpi_irq_thread, arg);
    if (ret != 0) {
        free(arg);
        return AE_ERROR;
    }
    thrd_detach(thread);

    return AE_OK;
}

/**
 * @brief Remove an interrupt handler.
 *
 * @param InterruptNumber Interrupt number that the handler is currently
 *        servicing.
 * @param Handler Address of the handler that was previously installed.
 *
 * @return AE_OK The handler was successfully removed.
 * @return AE_BAD_PARAMETER The InterruptNumber is invalid, the Handler
 *         pointer is NULL, or the Handler address is no the same as the one
 *         currently installed.
 * @return AE_NOT_EXIST There is no handler installed for this interrupt level.
 */
ACPI_STATUS AcpiOsRemoveInterruptHandler(
        UINT32 InterruptNumber,
        ACPI_OSD_HANDLER Handler) {
    assert(false);
    return AE_NOT_EXIST;
}

/**
 * @brief Read a value from a memory location.
 *
 * @param Address Memory address to be read.
 * @param Value A pointer to a location where the data is to be returned.
 * @param Width The memory width in bits, either 8, 16, 32, or 64.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsReadMemory(
        ACPI_PHYSICAL_ADDRESS Address,
        UINT64 *Value,
        UINT32 Width) {
    assert(false);
    return AE_OK;
}

/**
 * @brief Write a value to a memory location.
 *
 * @param Address Memory address where data is to be written.
 * @param Value Data to be written to the memory location.
 * @param Width The memory width in bits, either 8, 16, 32, or 64.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsWriteMemory(
        ACPI_PHYSICAL_ADDRESS Address,
        UINT64 Value,
        UINT32 Width) {
    assert(false);
    return AE_OK;
}

/**
 * @brief Read a value from an input port.
 *
 * @param Address Hardware I/O port address to be read.
 * @param Value A pointer to a location where the data is to be returned.
 * @param Width The port width in bits, either 8, 16, or 32.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsReadPort(
        ACPI_IO_ADDRESS Address,
        UINT32 *Value,
        UINT32 Width) {
    if (Address > 0xffff) {
        return AE_BAD_PARAMETER;
    }

    switch (Width) {
        case 8:
            *Value = inp((uint16_t)Address);
            break;
        case 16:
            *Value = inpw((uint16_t)Address);
            break;
        case 32:
            *Value = inpd((uint16_t)Address);
            break;
        default:
            return AE_BAD_PARAMETER;
    }
    return AE_OK;
}

/**
 * @brief Write a value to an output port.
 *
 * @param Address Hardware I/O port address where data is to be written.
 * @param Value The value to be written.
 * @param Width The port width in bits, either 8, 16, or 32.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsWritePort(
        ACPI_IO_ADDRESS Address,
        UINT32 Value,
        UINT32 Width) {
    if (Address > 0xffff) {
        return AE_BAD_PARAMETER;
    }

    switch (Width) {
        case 8:
            outp((uint16_t)Address, (uint8_t)Value);
            break;
        case 16:
            outpw((uint16_t)Address, (uint16_t)Value);
            break;
        case 32:
            outpd((uint16_t)Address, (uint32_t)Value);
            break;
        default:
            return AE_BAD_PARAMETER;
    }
    return AE_OK;
}

/**
 * @brief Read/Write a value from a PCI configuration register.
 *
 * @param PciId The full PCI configuration space address, consisting of a
 *        segment number, bus number, device number, and function number.
 * @param Register The PCI register address to be read from.
 * @param Value A pointer to a location where the data is to be returned.
 * @param Width The register width in bits, either 8, 16, 32, or 64.
 * @param Write Write or Read.
 *
 * @return Exception code that indicates success or reason for failure.
 */
static ACPI_STATUS AcpiOsReadWritePciConfiguration(
        ACPI_PCI_ID *PciId,
        UINT32 Register,
        UINT64 *Value,
        UINT32 Width,
        bool Write) {

    if (LOCAL_TRACE) {
        printf("ACPIOS: %s PCI Config %x:%x:%x:%x register %#x width %u\n",
            Write ? "write" : "read" ,PciId->Segment, PciId->Bus, PciId->Device, PciId->Function, Register, Width);
    }

    // Only segment 0 is supported for now
    if (PciId->Segment != 0) {
        printf("ACPIOS: read/write config, segment != 0 not supported.\n");
        return AE_ERROR;
    }

    // Check bounds of device and function offsets
    if (PciId->Device >= PCIE_MAX_DEVICES_PER_BUS
            || PciId->Function >= PCIE_MAX_FUNCTIONS_PER_DEVICE) {
        printf("ACPIOS: device out of reasonable bounds.\n");
        return AE_ERROR;
    }

    // PCI config only supports up to 32 bit values
    if (Write && (*Value > UINT_MAX)) {
        printf("ACPIOS: read/write config, Value passed does not fit confg registers.\n");
    }

    // Clear higher bits before a read
    if (!Write) {
        *Value = 0;
    }

#if __x86_64__
    uint8_t bus = static_cast<uint8_t>(PciId->Bus);
    uint8_t dev = static_cast<uint8_t>(PciId->Device);
    uint8_t func = static_cast<uint8_t>(PciId->Function);
    uint8_t offset = static_cast<uint8_t>(Register);
    uint8_t width = static_cast<uint8_t>(Width);
    uint32_t val = *Value & 0xFFFFFFFF; // PIO access can only be 32 bits
    zx_status_t status = zx_pci_cfg_pio_rw(root_resource_handle, bus, dev, func, offset,
                                           &val, width, Write);

    *Value = val;

#ifdef ACPI_DEBUG_OUTPUT
    if (status != ZX_OK) {
        printf("ACPIOS: pci rw error: %d\n", status);
    }
#endif // ACPI_DEBUG_OUTPUT
    return (status == ZX_OK) ? AE_OK : AE_ERROR;
#endif // __x86_64__

    return AE_NOT_IMPLEMENTED;
}
/**
 * @brief Read a value from a PCI configuration register.
 *
 * @param PciId The full PCI configuration space address, consisting of a
 *        segment number, bus number, device number, and function number.
 * @param Register The PCI register address to be read from.
 * @param Value A pointer to a location where the data is to be returned.
 * @param Width The register width in bits, either 8, 16, 32, or 64.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsReadPciConfiguration(
        ACPI_PCI_ID *PciId,
        UINT32 Register,
        UINT64 *Value,
        UINT32 Width) {

    return AcpiOsReadWritePciConfiguration(PciId, Register, Value, Width, false);
}

/**
 * @brief Write a value to a PCI configuration register.
 *
 * @param PciId The full PCI configuration space address, consisting of a
 *        segment number, bus number, device number, and function number.
 * @param Register The PCI register address to be written to.
 * @param Value Data to be written.
 * @param Width The register width in bits, either 8, 16, or 32.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsWritePciConfiguration(
        ACPI_PCI_ID *PciId,
        UINT32 Register,
        UINT64 Value,
        UINT32 Width) {

    return AcpiOsReadWritePciConfiguration(PciId, Register, &Value, Width, true);
}

/**
 * @brief Formatted stream output.
 *
 * @param Format A standard print format string.
 * @param ...
 */
void ACPI_INTERNAL_VAR_XFACE AcpiOsPrintf(const char *Format, ...) {
    va_list argp;
    va_start(argp, Format);
    AcpiOsVprintf(Format, argp);
    va_end(argp);
}

/**
 * @brief Formatted stream output.
 *
 * @param Format A standard print format string.
 * @param Args A variable parameter list
 */
void AcpiOsVprintf(const char *Format, va_list Args) {
    // Only implement if ACPI_DEBUG_OUTPUT is defined, otherwise this causes
    // excess boot spew.
#ifdef ACPI_DEBUG_OUTPUT
    vprintf(Format, Args);
#endif
}

/**
 * @brief Get current value of the system timer
 *
 * @return The current value of the system timer in 100-ns units.
 */
UINT64 AcpiOsGetTimer() {
    assert(false);
    return 0;
}

/**
 * @brief Break to the debugger or display a breakpoint message.
 *
 * @param Function Signal to be sent to the host operating system.  Either
 *        ACPI_SIGNAL_FATAL or ACPI_SIGNAL_BREAKPOINT
 * @param Info Data associated with the signal; type depends on signal type.
 *
 * @return Exception code that indicates success or reason for failure.
 */
ACPI_STATUS AcpiOsSignal(
        UINT32 Function,
        void *Info) {
    assert(false);
    return AE_OK;
}

/* @brief Acquire the ACPI global lock
 *
 * Implementation for ACPI_ACQUIRE_GLOBAL_LOCK
 *
 * @param FacsPtr pointer to the FACS ACPI structure
 *
 * @return True if the lock was successfully acquired
 */
bool _acpica_acquire_global_lock(void *FacsPtr)
{
    ACPI_TABLE_FACS *table = (ACPI_TABLE_FACS*)FacsPtr;
    uint32_t old_val, new_val, test_val;
    do {
        old_val = test_val = table->GlobalLock;
        new_val = old_val & ~ACPI_GLOCK_PENDING;
        // If the lock is owned, we'll mark it pending
        if (new_val & ACPI_GLOCK_OWNED) {
            new_val |= ACPI_GLOCK_PENDING;
        }
        new_val |= ACPI_GLOCK_OWNED;
        __atomic_compare_exchange_n(&table->GlobalLock, &old_val, new_val, false,
                                    __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
    } while (old_val != test_val);

    /* If we're here, we either acquired the lock or marked it pending */
    return !(new_val & ACPI_GLOCK_PENDING);
}


/* @brief Release the ACPI global lock
 *
 * Implementation for ACPI_RELEASE_GLOBAL_LOCK
 *
 * @param FacsPtr pointer to the FACS ACPI structure
 *
 * @return True if there is someone waiting to acquire the lock
 */
bool _acpica_release_global_lock(void *FacsPtr)
{
    ACPI_TABLE_FACS *table = (ACPI_TABLE_FACS*)FacsPtr;
    uint32_t old_val, new_val, test_val;
    do {
        old_val = test_val = table->GlobalLock;
        new_val = old_val & ~(ACPI_GLOCK_PENDING | ACPI_GLOCK_OWNED);
        __atomic_compare_exchange_n(&table->GlobalLock, &old_val, new_val, false,
                                    __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
    } while (old_val != test_val);

    return !!(old_val & ACPI_GLOCK_PENDING);
}
