[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/5] acpica: Add acpi_init
From: |
Damien Zammit |
Subject: |
[PATCH 3/5] acpica: Add acpi_init |
Date: |
Thu, 1 Apr 2021 00:23:28 +1100 |
---
libacpica/acpi_init.c | 478 ++++++++++++++++++++++++++++++++++++++++++
libacpica/acpi_init.h | 8 +
2 files changed, 486 insertions(+)
create mode 100644 libacpica/acpi_init.c
create mode 100644 libacpica/acpi_init.h
diff --git a/libacpica/acpi_init.c b/libacpica/acpi_init.c
new file mode 100644
index 00000000..754da4be
--- /dev/null
+++ b/libacpica/acpi_init.c
@@ -0,0 +1,478 @@
+#include "acpi_init.h"
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/io.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <mach/vm_param.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+void
+acpi_ds_dump_method_stack(acpi_status status, ...)
+// struct acpi_walk_state *walk_state,
+// union acpi_parse_object *op)
+{
+ return;
+}
+
+void
+acpi_os_printf(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ acpi_os_vprintf(fmt, args);
+ va_end(args);
+}
+
+void
+acpi_os_vprintf(const char *fmt, va_list args)
+{
+ static char buffer[512];
+
+ vsnprintf(buffer, 512, fmt, args);
+ printf(buffer);
+}
+
+acpi_cpu_flags
+acpi_os_acquire_lock(acpi_spinlock lockp)
+{
+ pthread_mutex_lock(&lockp);
+ return 0;
+}
+
+void
+acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
+{
+ pthread_mutex_unlock(&lockp);
+}
+
+void
+acpi_os_delete_lock(acpi_spinlock handle)
+{
+}
+
+/* FIXME: Need proper semaphores */
+acpi_status
+acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_semaphore *
handle)
+{
+ acpi_spinlock *lockp = (acpi_spinlock *)handle;
+
+ assert (max_units <= 1);
+ assert (initial_units <= 1);
+
+ acpi_os_create_lock (lockp);
+
+ if (initial_units == 1)
+ acpi_os_acquire_lock (*lockp);
+
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_delete_semaphore(acpi_semaphore handle)
+{
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
+{
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_signal_semaphore(acpi_handle handle, u32 units)
+{
+ acpi_spinlock *lockp = (acpi_spinlock *)&handle;
+ assert (units <= 1);
+ if (units == 1)
+ acpi_os_release_lock (*lockp, 0);
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_execute(acpi_execute_type type,
+ acpi_osd_exec_callback function, void *context)
+{
+ acpi_os_printf("XXX acpi_os_execute: not implemented\n");
+ return (AE_OK);
+}
+
+acpi_physical_address
+acpi_os_get_root_pointer(void)
+{
+ acpi_physical_address pa;
+
+ acpi_find_root_pointer(&pa);
+ return pa;
+}
+
+/* Supposed to be 64 bit free-running
+ * monotonic timer with 100ns granularity
+ */
+u64
+acpi_os_get_timer(void)
+{
+ struct timespec now;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return (u64)(now.tv_nsec / 100);
+}
+
+void *
+acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+ int fd_mem;
+ void * virt_addr;
+ uintptr_t into_page = phys % PAGE_SIZE;
+ uintptr_t nearest_page = (uintptr_t)trunc_page(phys);
+
+ if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
+ acpi_os_printf("Can't open /dev/mem\n");
+ return (void *)-1;
+ }
+
+ virt_addr = mmap(NULL, size + into_page, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_FIXED, fd_mem, nearest_page);
+ if (virt_addr == MAP_FAILED) {
+ acpi_os_printf("Can't map memory 0x%llx\n", phys);
+ return (void *)-1;
+ }
+
+ return virt_addr + into_page;
+}
+
+acpi_status
+acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
+{
+ u32 dummy;
+
+ if (!value)
+ value = &dummy;
+
+ *value = 0;
+ if (width <= 8) {
+ *(u8 *) value = inb(port);
+ } else if (width <= 16) {
+ *(u16 *) value = inw(port);
+ } else if (width <= 32) {
+ *(u32 *) value = inl(port);
+ } else {
+ acpi_os_printf("ACPI: read port invalid width\n");
+ }
+
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
+ acpi_string *new_val)
+{
+ if (!init_val || !new_val)
+ return AE_BAD_PARAMETER;
+
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_signal(u32 function, void *info)
+{
+ switch (function) {
+ case ACPI_SIGNAL_FATAL:
+ acpi_os_printf("ACPI: Fatal opcode executed\n");
+ break;
+ case ACPI_SIGNAL_BREAKPOINT:
+ break;
+ default:
+ break;
+ }
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_physical_table_override(struct acpi_table_header *existing_table,
+ acpi_physical_address *address,
+ u32 *table_length)
+{
+ *table_length = 0;
+ *address = 0;
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_table_override(struct acpi_table_header *existing_table,
+ struct acpi_table_header **new_table)
+{
+ if (!existing_table || !new_table)
+ return AE_BAD_PARAMETER;
+
+ *new_table = NULL;
+ return AE_OK;
+}
+
+void
+acpi_os_unmap_memory(void *virt, acpi_size size)
+{
+ void *freeme = (void *)trunc_page(virt);
+ if (!freeme) {
+ acpi_os_printf("Nothing to unmap\n");
+ return;
+ }
+ munmap(freeme, size + (ptrdiff_t)(virt - trunc_page(virt)));
+}
+
+static acpi_status
+acpi_os_read_iomem(void *virt_addr, u64 *value, u32 width)
+{
+
+ switch (width) {
+ case 8:
+ *(u8 *) value = *((volatile u8 *)virt_addr);
+ break;
+ case 16:
+ *(u16 *) value = *((volatile u16 *)virt_addr);
+ break;
+ case 32:
+ *(u32 *) value = *((volatile u32 *)virt_addr);
+ break;
+ case 64:
+ *(u64 *) value = *((volatile u64 *)virt_addr);
+ break;
+ default:
+ return AE_ERROR;
+ }
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
+{
+ void *virt_addr;
+ unsigned int size = width / 8;
+ u64 dummy;
+ acpi_status err = AE_BAD_ADDRESS;
+
+ virt_addr = acpi_os_map_memory (phys_addr, size);
+ if (!virt_addr)
+ return err;
+
+ if (!value)
+ value = &dummy;
+
+ if (!acpi_os_read_iomem (virt_addr, value, width))
+ err = AE_OK;
+
+ acpi_os_unmap_memory (virt_addr, size);
+
+ return err;
+}
+
+void
+acpi_os_sleep(u64 ms)
+{
+ usleep(1000 * ms);
+}
+
+void
+acpi_os_stall(u32 us)
+{
+ usleep(us);
+}
+
+void acpi_os_wait_events_complete(void)
+{
+ return;
+}
+
+acpi_status
+acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
+{
+ void *virt_addr;
+ unsigned int size = width / 8;
+ acpi_status err = AE_OK;
+
+ virt_addr = acpi_os_map_memory (phys_addr, size);
+ if (!virt_addr)
+ return AE_BAD_ADDRESS;
+
+ switch (width) {
+ case 8:
+ *((volatile u8 *)virt_addr) = (u8)value;
+ break;
+ case 16:
+ *((volatile u16 *)virt_addr) = (u16)value;
+ break;
+ case 32:
+ *((volatile u32 *)virt_addr) = (u32)value;
+ break;
+ case 64:
+ *((volatile u64 *)virt_addr) = value;
+ break;
+ default:
+ acpi_os_printf("ACPI: Bad write memory width\n");
+ err = AE_BAD_ADDRESS;
+ break;
+ }
+
+ acpi_os_unmap_memory (virt_addr, size);
+
+ return err;
+}
+
+acpi_status
+acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
+{
+ if (width <= 8) {
+ outb(port, value);
+ } else if (width <= 16) {
+ outw(port, value);
+ } else if (width <= 32) {
+ outl(port, value);
+ } else {
+ acpi_os_printf("ACPI: Bad write port width\n");
+ }
+
+ return AE_OK;
+}
+
+
+acpi_status
+acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
+ void *context)
+{
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler)
+{
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+ u64 *value, u32 width)
+{
+ acpi_os_printf("ACPI: Tried to read pci config\n");
+ return AE_ERROR;
+}
+
+acpi_status
+acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+ u64 value, u32 width)
+{
+ acpi_os_printf("ACPI: Tried to write pci config\n");
+ return AE_ERROR;
+}
+
+acpi_status
+acpi_os_initialize(void)
+{
+ return AE_OK;
+}
+
+acpi_status
+acpi_os_terminate(void)
+{
+ acpi_os_printf("Bye!\n");
+ return AE_OK;
+}
+
+/*
+ * Missing symbols to implement:
+ *
+ * x isdigit
+ * x isprint
+ * x isspace
+ * x isxdigit
+ * x tolower
+ * x toupper
+ * x acpi_ds_dump_method_stack
+ * x acpi_os_acquire_lock
+ * x acpi_os_create_cache
+ * x acpi_os_create_semaphore
+ * x acpi_os_delete_cache
+ * x acpi_os_delete_lock
+ * x acpi_os_delete_semaphore
+ * x acpi_os_get_root_pointer
+ * x acpi_os_get_timer
+ * x acpi_os_map_memory
+ * x acpi_os_physical_table_override
+ * x acpi_os_predefined_override
+ * x acpi_os_printf
+ * x acpi_os_read_memory
+ * x acpi_os_read_port
+ * x acpi_os_release_lock
+ * x acpi_os_release_object
+ * x acpi_os_signal
+ * x acpi_os_signal_semaphore
+ * x acpi_os_sleep
+ * x acpi_os_stall
+ * x acpi_os_table_override
+ * x acpi_os_unmap_memory
+ * x acpi_os_vprintf
+ * x acpi_os_wait_events_complete
+ * x acpi_os_wait_semaphore
+ * x acpi_os_write_memory
+ * x acpi_os_write_port
+ * xx acpi_os_execute
+ * xx acpi_os_install_interrupt_handler
+ * xx acpi_os_read_pci_configuration
+ * xx acpi_os_remove_interrupt_handler
+ * xx acpi_os_write_pci_configuration
+ * x acpi_os_initialize
+ * x acpi_os_purge_cache
+ * x acpi_os_terminate
+ */
+
+void acpi_init(void)
+{
+ int where = 0;
+ acpi_status err;
+
+ // Hack to increase verbosity except parsing AML
+ acpi_dbg_level = (ACPI_LV_ALL); //& ~(ACPI_LV_FUNCTIONS);
+
+ err = acpi_initialize_tables (NULL, 64, 1);
+ if (ACPI_FAILURE (err)) {
+ where = 1;
+ goto die;
+ }
+
+ err = acpi_initialize_subsystem ();
+ if (ACPI_FAILURE (err)) {
+ where = 2;
+ goto die;
+ }
+
+ err = acpi_load_tables ();
+ if (ACPI_FAILURE (err)) {
+ where = 3;
+ goto die;
+ }
+
+ err = acpi_enable_subsystem (ACPI_FULL_INITIALIZATION);
+ if (ACPI_FAILURE (err)) {
+ where = 4;
+ goto die;
+ }
+
+ err = acpi_initialize_objects (ACPI_FULL_INITIALIZATION);
+ if (ACPI_FAILURE (err)) {
+ where = 5;
+ goto die;
+ }
+
+ acpi_os_printf("PASS! (wait here)\n");
+ for (;;);
+die:
+ acpi_os_printf("OUCH! where = %d\n", where);
+ for (;;);
+}
diff --git a/libacpica/acpi_init.h b/libacpica/acpi_init.h
new file mode 100644
index 00000000..f20c216c
--- /dev/null
+++ b/libacpica/acpi_init.h
@@ -0,0 +1,8 @@
+#ifndef ACPI_INIT_H
+#define ACPI_INIT_H
+
+#include <acpi/acpi.h>
+
+void acpi_init(void);
+
+#endif
--
2.30.1