Integrate uACPI

This commit is contained in:
2025-08-17 18:37:57 +02:00
parent 069870cd0d
commit 92ccd189e7
166 changed files with 42104 additions and 33 deletions

View File

@ -0,0 +1,3 @@
#pragma once
#include <uacpi/platform/compiler.h>

View File

@ -0,0 +1,155 @@
#pragma once
#include <uacpi/acpi.h>
#include <uacpi/types.h>
#include <uacpi/uacpi.h>
#include <uacpi/internal/dynamic_array.h>
#include <uacpi/internal/shareable.h>
#include <uacpi/context.h>
struct uacpi_runtime_context {
/*
* A local copy of FADT that has been verified & converted to most optimal
* format for faster access to the registers.
*/
struct acpi_fadt fadt;
uacpi_u64 flags;
#ifndef UACPI_BAREBONES_MODE
/*
* A cached pointer to FACS so that we don't have to look it up in interrupt
* contexts as we can't take mutexes.
*/
struct acpi_facs *facs;
/*
* pm1{a,b}_evt_blk split into two registers for convenience
*/
struct acpi_gas pm1a_status_blk;
struct acpi_gas pm1b_status_blk;
struct acpi_gas pm1a_enable_blk;
struct acpi_gas pm1b_enable_blk;
#define UACPI_SLEEP_TYP_INVALID 0xFF
uacpi_u8 last_sleep_typ_a;
uacpi_u8 last_sleep_typ_b;
uacpi_u8 s0_sleep_typ_a;
uacpi_u8 s0_sleep_typ_b;
uacpi_bool global_lock_acquired;
#ifndef UACPI_REDUCED_HARDWARE
uacpi_bool was_in_legacy_mode;
uacpi_bool has_global_lock;
uacpi_bool sci_handle_valid;
uacpi_handle sci_handle;
#endif
uacpi_u64 opcodes_executed;
uacpi_u32 loop_timeout_seconds;
uacpi_u32 max_call_stack_depth;
uacpi_u32 global_lock_seq_num;
/*
* These are stored here to protect against stuff like:
* - CopyObject(JUNK, \)
* - CopyObject(JUNK, \_GL)
*/
uacpi_mutex *global_lock_mutex;
uacpi_object *root_object;
#ifndef UACPI_REDUCED_HARDWARE
uacpi_handle *global_lock_event;
uacpi_handle *global_lock_spinlock;
uacpi_bool global_lock_pending;
#endif
uacpi_bool bad_timesource;
uacpi_u8 init_level;
#endif // !UACPI_BAREBONES_MODE
#ifndef UACPI_REDUCED_HARDWARE
uacpi_bool is_hardware_reduced;
#endif
/*
* This is a per-table value but we mimic the NT implementation:
* treat all other definition blocks as if they were the same revision
* as DSDT.
*/
uacpi_bool is_rev1;
uacpi_u8 log_level;
};
extern struct uacpi_runtime_context g_uacpi_rt_ctx;
static inline uacpi_bool uacpi_check_flag(uacpi_u64 flag)
{
return (g_uacpi_rt_ctx.flags & flag) == flag;
}
static inline uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
{
return lvl <= g_uacpi_rt_ctx.log_level;
}
static inline uacpi_bool uacpi_is_hardware_reduced(void)
{
#ifndef UACPI_REDUCED_HARDWARE
return g_uacpi_rt_ctx.is_hardware_reduced;
#else
return UACPI_TRUE;
#endif
}
#ifndef UACPI_BAREBONES_MODE
static inline const uacpi_char *uacpi_init_level_to_string(uacpi_u8 lvl)
{
switch (lvl) {
case UACPI_INIT_LEVEL_EARLY:
return "early";
case UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED:
return "subsystem initialized";
case UACPI_INIT_LEVEL_NAMESPACE_LOADED:
return "namespace loaded";
case UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED:
return "namespace initialized";
default:
return "<invalid>";
}
}
#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl) \
do { \
if (uacpi_unlikely(g_uacpi_rt_ctx.init_level < lvl)) { \
uacpi_error( \
"while evaluating %s: init level %d (%s) is too low, " \
"expected at least %d (%s)\n", __FUNCTION__, \
g_uacpi_rt_ctx.init_level, \
uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
uacpi_init_level_to_string(lvl) \
); \
return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
} \
} while (0)
#define UACPI_ENSURE_INIT_LEVEL_IS(lvl) \
do { \
if (uacpi_unlikely(g_uacpi_rt_ctx.init_level != lvl)) { \
uacpi_error( \
"while evaluating %s: invalid init level %d (%s), " \
"expected %d (%s)\n", __FUNCTION__, \
g_uacpi_rt_ctx.init_level, \
uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
uacpi_init_level_to_string(lvl) \
); \
return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
} \
} while (0)
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,185 @@
#pragma once
#include <uacpi/types.h>
#include <uacpi/internal/stdlib.h>
#include <uacpi/kernel_api.h>
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE(name, type, inline_capacity) \
struct name { \
type inline_storage[inline_capacity]; \
type *dynamic_storage; \
uacpi_size dynamic_capacity; \
uacpi_size size_including_inline; \
}; \
#define DYNAMIC_ARRAY_SIZE(arr) ((arr)->size_including_inline)
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_EXPORTS(name, type, prefix) \
prefix uacpi_size name##_inline_capacity(struct name *arr); \
prefix type *name##_at(struct name *arr, uacpi_size idx); \
prefix type *name##_alloc(struct name *arr); \
prefix type *name##_calloc(struct name *arr); \
prefix void name##_pop(struct name *arr); \
prefix uacpi_size name##_size(struct name *arr); \
prefix type *name##_last(struct name *arr) \
prefix void name##_clear(struct name *arr);
#ifndef UACPI_BAREBONES_MODE
#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
UACPI_MAYBE_UNUSED \
prefix type *name##_alloc(struct name *arr) \
{ \
uacpi_size inline_cap; \
type *out_ptr; \
\
inline_cap = name##_inline_capacity(arr); \
\
if (arr->size_including_inline >= inline_cap) { \
uacpi_size dynamic_size; \
\
dynamic_size = arr->size_including_inline - inline_cap; \
if (dynamic_size == arr->dynamic_capacity) { \
uacpi_size bytes, type_size; \
void *new_buf; \
\
type_size = sizeof(*arr->dynamic_storage); \
\
if (arr->dynamic_capacity == 0) { \
bytes = type_size * inline_cap; \
} else { \
bytes = (arr->dynamic_capacity / 2) * type_size; \
if (bytes == 0) \
bytes += type_size; \
\
bytes += arr->dynamic_capacity * type_size; \
} \
\
new_buf = uacpi_kernel_alloc(bytes); \
if (uacpi_unlikely(new_buf == UACPI_NULL)) \
return UACPI_NULL; \
\
arr->dynamic_capacity = bytes / type_size; \
\
if (arr->dynamic_storage) { \
uacpi_memcpy(new_buf, arr->dynamic_storage, \
dynamic_size * type_size); \
} \
uacpi_free(arr->dynamic_storage, dynamic_size * type_size); \
arr->dynamic_storage = new_buf; \
} \
\
out_ptr = &arr->dynamic_storage[dynamic_size]; \
goto ret; \
} \
out_ptr = &arr->inline_storage[arr->size_including_inline]; \
ret: \
arr->size_including_inline++; \
return out_ptr; \
}
#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
prefix void name##_clear(struct name *arr) \
{ \
uacpi_free( \
arr->dynamic_storage, \
arr->dynamic_capacity * sizeof(*arr->dynamic_storage) \
); \
arr->size_including_inline = 0; \
arr->dynamic_capacity = 0; \
arr->dynamic_storage = UACPI_NULL; \
}
#else
#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
UACPI_MAYBE_UNUSED \
prefix type *name##_alloc(struct name *arr) \
{ \
uacpi_size inline_cap; \
type *out_ptr; \
\
inline_cap = name##_inline_capacity(arr); \
\
if (arr->size_including_inline >= inline_cap) { \
uacpi_size dynamic_size; \
\
dynamic_size = arr->size_including_inline - inline_cap; \
if (uacpi_unlikely(dynamic_size == arr->dynamic_capacity)) \
return UACPI_NULL; \
\
out_ptr = &arr->dynamic_storage[dynamic_size]; \
goto ret; \
} \
out_ptr = &arr->inline_storage[arr->size_including_inline]; \
ret: \
arr->size_including_inline++; \
return out_ptr; \
}
#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
prefix void name##_clear(struct name *arr) \
{ \
arr->size_including_inline = 0; \
arr->dynamic_capacity = 0; \
arr->dynamic_storage = UACPI_NULL; \
}
#endif
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL(name, type, prefix) \
UACPI_MAYBE_UNUSED \
prefix uacpi_size name##_inline_capacity(struct name *arr) \
{ \
return sizeof(arr->inline_storage) / sizeof(arr->inline_storage[0]); \
} \
\
UACPI_MAYBE_UNUSED \
prefix uacpi_size name##_capacity(struct name *arr) \
{ \
return name##_inline_capacity(arr) + arr->dynamic_capacity; \
} \
\
prefix type *name##_at(struct name *arr, uacpi_size idx) \
{ \
if (idx >= arr->size_including_inline) \
return UACPI_NULL; \
\
if (idx < name##_inline_capacity(arr)) \
return &arr->inline_storage[idx]; \
\
return &arr->dynamic_storage[idx - name##_inline_capacity(arr)]; \
} \
\
DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
\
UACPI_MAYBE_UNUSED \
prefix type *name##_calloc(struct name *arr) \
{ \
type *ret; \
\
ret = name##_alloc(arr); \
if (ret) \
uacpi_memzero(ret, sizeof(*ret)); \
\
return ret; \
} \
\
UACPI_MAYBE_UNUSED \
prefix void name##_pop(struct name *arr) \
{ \
if (arr->size_including_inline == 0) \
return; \
\
arr->size_including_inline--; \
} \
\
UACPI_MAYBE_UNUSED \
prefix uacpi_size name##_size(struct name *arr) \
{ \
return arr->size_including_inline; \
} \
\
UACPI_MAYBE_UNUSED \
prefix type *name##_last(struct name *arr) \
{ \
return name##_at(arr, arr->size_including_inline - 1); \
} \
\
DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix)

View File

@ -0,0 +1,25 @@
#pragma once
#include <uacpi/event.h>
// This fixed event is internal-only, and we don't expose it in the enum
#define UACPI_FIXED_EVENT_GLOBAL_LOCK 0
UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(
uacpi_status uacpi_initialize_events_early(void)
)
UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(
uacpi_status uacpi_initialize_events(void)
)
UACPI_STUB_IF_REDUCED_HARDWARE(
void uacpi_deinitialize_events(void)
)
UACPI_STUB_IF_REDUCED_HARDWARE(
void uacpi_events_match_post_dynamic_table_load(void)
)
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
uacpi_status uacpi_clear_all_events(void)
)

View File

@ -0,0 +1,7 @@
#pragma once
#include <uacpi/helpers.h>
#define UACPI_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define UACPI_UNUSED(x) (void)(x)

View File

@ -0,0 +1,24 @@
#pragma once
#include <uacpi/types.h>
#include <uacpi/status.h>
#include <uacpi/internal/namespace.h>
#ifndef UACPI_BAREBONES_MODE
enum uacpi_table_load_cause {
UACPI_TABLE_LOAD_CAUSE_LOAD_OP,
UACPI_TABLE_LOAD_CAUSE_LOAD_TABLE_OP,
UACPI_TABLE_LOAD_CAUSE_INIT,
UACPI_TABLE_LOAD_CAUSE_HOST,
};
uacpi_status uacpi_execute_table(void*, enum uacpi_table_load_cause cause);
uacpi_status uacpi_osi(uacpi_handle handle, uacpi_object *retval);
uacpi_status uacpi_execute_control_method(
uacpi_namespace_node *scope, uacpi_control_method *method,
const uacpi_object_array *args, uacpi_object **ret
);
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,77 @@
#pragma once
#include <uacpi/internal/types.h>
#include <uacpi/acpi.h>
#include <uacpi/io.h>
#ifndef UACPI_BAREBONES_MODE
typedef struct uacpi_mapped_gas {
uacpi_handle mapping;
uacpi_u8 access_bit_width;
uacpi_u8 total_bit_width;
uacpi_u8 bit_offset;
uacpi_status (*read)(
uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
);
uacpi_status (*write)(
uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
);
void (*unmap)(uacpi_handle, uacpi_size);
} uacpi_mapped_gas;
uacpi_status uacpi_map_gas_noalloc(
const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped
);
void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas);
uacpi_size uacpi_round_up_bits_to_bytes(uacpi_size bit_length);
void uacpi_read_buffer_field(
const uacpi_buffer_field *field, void *dst
);
void uacpi_write_buffer_field(
uacpi_buffer_field *field, const void *src, uacpi_size size
);
uacpi_status uacpi_field_unit_get_read_type(
struct uacpi_field_unit *field, uacpi_object_type *out_type
);
uacpi_status uacpi_field_unit_get_bit_length(
struct uacpi_field_unit *field, uacpi_size *out_length
);
uacpi_status uacpi_read_field_unit(
uacpi_field_unit *field, void *dst, uacpi_size size,
uacpi_data_view *wtr_response
);
uacpi_status uacpi_write_field_unit(
uacpi_field_unit *field, const void *src, uacpi_size size,
uacpi_data_view *wtr_response
);
uacpi_status uacpi_system_memory_read(
void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
);
uacpi_status uacpi_system_memory_write(
void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
);
uacpi_status uacpi_system_io_read(
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
);
uacpi_status uacpi_system_io_write(
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
);
uacpi_status uacpi_pci_read(
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
);
uacpi_status uacpi_pci_write(
uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
);
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,23 @@
#pragma once
#include <uacpi/kernel_api.h>
#include <uacpi/internal/context.h>
#include <uacpi/log.h>
#ifdef UACPI_FORMATTED_LOGGING
#define uacpi_log uacpi_kernel_log
#else
UACPI_PRINTF_DECL(2, 3)
void uacpi_log(uacpi_log_level, const uacpi_char*, ...);
#endif
#define uacpi_log_lvl(lvl, ...) \
do { if (uacpi_should_log(lvl)) uacpi_log(lvl, __VA_ARGS__); } while (0)
#define uacpi_debug(...) uacpi_log_lvl(UACPI_LOG_DEBUG, __VA_ARGS__)
#define uacpi_trace(...) uacpi_log_lvl(UACPI_LOG_TRACE, __VA_ARGS__)
#define uacpi_info(...) uacpi_log_lvl(UACPI_LOG_INFO, __VA_ARGS__)
#define uacpi_warn(...) uacpi_log_lvl(UACPI_LOG_WARN, __VA_ARGS__)
#define uacpi_error(...) uacpi_log_lvl(UACPI_LOG_ERROR, __VA_ARGS__)
void uacpi_logger_initialize(void);

View File

@ -0,0 +1,82 @@
#pragma once
#include <uacpi/internal/types.h>
#include <uacpi/kernel_api.h>
#ifndef UACPI_BAREBONES_MODE
uacpi_bool uacpi_this_thread_owns_aml_mutex(uacpi_mutex*);
uacpi_status uacpi_acquire_aml_mutex(uacpi_mutex*, uacpi_u16 timeout);
uacpi_status uacpi_release_aml_mutex(uacpi_mutex*);
static inline uacpi_status uacpi_acquire_native_mutex(uacpi_handle mtx)
{
if (uacpi_unlikely(mtx == UACPI_NULL))
return UACPI_STATUS_INVALID_ARGUMENT;
return uacpi_kernel_acquire_mutex(mtx, 0xFFFF);
}
uacpi_status uacpi_acquire_native_mutex_with_timeout(
uacpi_handle mtx, uacpi_u16 timeout
);
static inline uacpi_status uacpi_release_native_mutex(uacpi_handle mtx)
{
if (uacpi_unlikely(mtx == UACPI_NULL))
return UACPI_STATUS_INVALID_ARGUMENT;
uacpi_kernel_release_mutex(mtx);
return UACPI_STATUS_OK;
}
static inline uacpi_status uacpi_acquire_native_mutex_may_be_null(
uacpi_handle mtx
)
{
if (mtx == UACPI_NULL)
return UACPI_STATUS_OK;
return uacpi_kernel_acquire_mutex(mtx, 0xFFFF);
}
static inline uacpi_status uacpi_release_native_mutex_may_be_null(
uacpi_handle mtx
)
{
if (mtx == UACPI_NULL)
return UACPI_STATUS_OK;
uacpi_kernel_release_mutex(mtx);
return UACPI_STATUS_OK;
}
struct uacpi_recursive_lock {
uacpi_handle mutex;
uacpi_size depth;
uacpi_thread_id owner;
};
uacpi_status uacpi_recursive_lock_init(struct uacpi_recursive_lock *lock);
uacpi_status uacpi_recursive_lock_deinit(struct uacpi_recursive_lock *lock);
uacpi_status uacpi_recursive_lock_acquire(struct uacpi_recursive_lock *lock);
uacpi_status uacpi_recursive_lock_release(struct uacpi_recursive_lock *lock);
struct uacpi_rw_lock {
uacpi_handle read_mutex;
uacpi_handle write_mutex;
uacpi_size num_readers;
};
uacpi_status uacpi_rw_lock_init(struct uacpi_rw_lock *lock);
uacpi_status uacpi_rw_lock_deinit(struct uacpi_rw_lock *lock);
uacpi_status uacpi_rw_lock_read(struct uacpi_rw_lock *lock);
uacpi_status uacpi_rw_unlock_read(struct uacpi_rw_lock *lock);
uacpi_status uacpi_rw_lock_write(struct uacpi_rw_lock *lock);
uacpi_status uacpi_rw_unlock_write(struct uacpi_rw_lock *lock);
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,123 @@
#pragma once
#include <uacpi/types.h>
#include <uacpi/internal/shareable.h>
#include <uacpi/status.h>
#include <uacpi/namespace.h>
#ifndef UACPI_BAREBONES_MODE
#define UACPI_NAMESPACE_NODE_FLAG_ALIAS (1 << 0)
/*
* This node has been uninstalled and has no object associated with it.
*
* This is used to handle edge cases where an object needs to reference
* a namespace node, where the node might end up going out of scope before
* the object lifetime ends.
*/
#define UACPI_NAMESPACE_NODE_FLAG_DANGLING (1u << 1)
/*
* This node is method-local and must not be exposed via public API as its
* lifetime is limited.
*/
#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY (1u << 2)
#define UACPI_NAMESPACE_NODE_PREDEFINED (1u << 31)
typedef struct uacpi_namespace_node {
struct uacpi_shareable shareable;
uacpi_object_name name;
uacpi_u32 flags;
uacpi_object *object;
struct uacpi_namespace_node *parent;
struct uacpi_namespace_node *child;
struct uacpi_namespace_node *next;
} uacpi_namespace_node;
uacpi_status uacpi_initialize_namespace(void);
void uacpi_deinitialize_namespace(void);
uacpi_namespace_node *uacpi_namespace_node_alloc(uacpi_object_name name);
void uacpi_namespace_node_unref(uacpi_namespace_node *node);
uacpi_status uacpi_namespace_node_type_unlocked(
const uacpi_namespace_node *node, uacpi_object_type *out_type
);
uacpi_status uacpi_namespace_node_is_one_of_unlocked(
const uacpi_namespace_node *node, uacpi_object_type_bits type_mask,
uacpi_bool *out
);
uacpi_object *uacpi_namespace_node_get_object(const uacpi_namespace_node *node);
uacpi_object *uacpi_namespace_node_get_object_typed(
const uacpi_namespace_node *node, uacpi_object_type_bits type_mask
);
uacpi_status uacpi_namespace_node_acquire_object(
const uacpi_namespace_node *node, uacpi_object **out_obj
);
uacpi_status uacpi_namespace_node_acquire_object_typed(
const uacpi_namespace_node *node, uacpi_object_type_bits,
uacpi_object **out_obj
);
uacpi_status uacpi_namespace_node_reacquire_object(
uacpi_object *obj
);
uacpi_status uacpi_namespace_node_release_object(
uacpi_object *obj
);
uacpi_status uacpi_namespace_node_install(
uacpi_namespace_node *parent, uacpi_namespace_node *node
);
uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node);
uacpi_namespace_node *uacpi_namespace_node_find_sub_node(
uacpi_namespace_node *parent,
uacpi_object_name name
);
enum uacpi_may_search_above_parent {
UACPI_MAY_SEARCH_ABOVE_PARENT_NO,
UACPI_MAY_SEARCH_ABOVE_PARENT_YES,
};
enum uacpi_permanent_only {
UACPI_PERMANENT_ONLY_NO,
UACPI_PERMANENT_ONLY_YES,
};
enum uacpi_should_lock {
UACPI_SHOULD_LOCK_NO,
UACPI_SHOULD_LOCK_YES,
};
uacpi_status uacpi_namespace_node_resolve(
uacpi_namespace_node *scope, const uacpi_char *path, enum uacpi_should_lock,
enum uacpi_may_search_above_parent, enum uacpi_permanent_only,
uacpi_namespace_node **out_node
);
uacpi_status uacpi_namespace_do_for_each_child(
uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback,
uacpi_iteration_callback ascending_callback,
uacpi_object_type_bits, uacpi_u32 max_depth, enum uacpi_should_lock,
enum uacpi_permanent_only, void *user
);
uacpi_bool uacpi_namespace_node_is_dangling(uacpi_namespace_node *node);
uacpi_bool uacpi_namespace_node_is_temporary(uacpi_namespace_node *node);
uacpi_bool uacpi_namespace_node_is_predefined(uacpi_namespace_node *node);
uacpi_status uacpi_namespace_read_lock(void);
uacpi_status uacpi_namespace_read_unlock(void);
uacpi_status uacpi_namespace_write_lock(void);
uacpi_status uacpi_namespace_write_unlock(void);
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,13 @@
#pragma once
#include <uacpi/internal/types.h>
#include <uacpi/notify.h>
#ifndef UACPI_BAREBONES_MODE
uacpi_status uacpi_initialize_notify(void);
void uacpi_deinitialize_notify(void);
uacpi_status uacpi_notify_all(uacpi_namespace_node *node, uacpi_u64 value);
#endif // !UACPI_BAREBONES_MODE

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
#pragma once
#include <uacpi/internal/types.h>
#include <uacpi/opregion.h>
#ifndef UACPI_BAREBONES_MODE
uacpi_status uacpi_initialize_opregion(void);
void uacpi_deinitialize_opregion(void);
void uacpi_trace_region_error(
uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret
);
uacpi_status uacpi_install_address_space_handler_with_flags(
uacpi_namespace_node *device_node, enum uacpi_address_space space,
uacpi_region_handler handler, uacpi_handle handler_context,
uacpi_u16 flags
);
void uacpi_opregion_uninstall_handler(uacpi_namespace_node *node);
uacpi_bool uacpi_address_space_handler_is_default(
uacpi_address_space_handler *handler
);
uacpi_address_space_handlers *uacpi_node_get_address_space_handlers(
uacpi_namespace_node *node
);
uacpi_status uacpi_initialize_opregion_node(uacpi_namespace_node *node);
uacpi_status uacpi_opregion_attach(uacpi_namespace_node *node);
void uacpi_install_default_address_space_handlers(void);
uacpi_bool uacpi_is_buffer_access_address_space(uacpi_address_space space);
union uacpi_opregion_io_data {
uacpi_u64 *integer;
uacpi_data_view buffer;
};
uacpi_status uacpi_dispatch_opregion_io(
uacpi_field_unit *field, uacpi_u32 offset,
uacpi_region_op op, union uacpi_opregion_io_data data
);
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,8 @@
#pragma once
#include <uacpi/osi.h>
uacpi_status uacpi_initialize_interfaces(void);
void uacpi_deinitialize_interfaces(void);
uacpi_status uacpi_handle_osi(const uacpi_char *string, uacpi_bool *out_value);

View File

@ -0,0 +1,7 @@
#pragma once
#include <uacpi/types.h>
#include <uacpi/registers.h>
uacpi_status uacpi_initialize_registers(void);
void uacpi_deinitialize_registers(void);

View File

@ -0,0 +1,327 @@
#pragma once
#include <uacpi/internal/types.h>
#include <uacpi/resources.h>
#ifndef UACPI_BAREBONES_MODE
enum uacpi_aml_resource {
UACPI_AML_RESOURCE_TYPE_INVALID = 0,
// Small resources
UACPI_AML_RESOURCE_IRQ,
UACPI_AML_RESOURCE_DMA,
UACPI_AML_RESOURCE_START_DEPENDENT,
UACPI_AML_RESOURCE_END_DEPENDENT,
UACPI_AML_RESOURCE_IO,
UACPI_AML_RESOURCE_FIXED_IO,
UACPI_AML_RESOURCE_FIXED_DMA,
UACPI_AML_RESOURCE_VENDOR_TYPE0,
UACPI_AML_RESOURCE_END_TAG,
// Large resources
UACPI_AML_RESOURCE_MEMORY24,
UACPI_AML_RESOURCE_GENERIC_REGISTER,
UACPI_AML_RESOURCE_VENDOR_TYPE1,
UACPI_AML_RESOURCE_MEMORY32,
UACPI_AML_RESOURCE_FIXED_MEMORY32,
UACPI_AML_RESOURCE_ADDRESS32,
UACPI_AML_RESOURCE_ADDRESS16,
UACPI_AML_RESOURCE_EXTENDED_IRQ,
UACPI_AML_RESOURCE_ADDRESS64,
UACPI_AML_RESOURCE_ADDRESS64_EXTENDED,
UACPI_AML_RESOURCE_GPIO_CONNECTION,
UACPI_AML_RESOURCE_PIN_FUNCTION,
UACPI_AML_RESOURCE_SERIAL_CONNECTION,
UACPI_AML_RESOURCE_PIN_CONFIGURATION,
UACPI_AML_RESOURCE_PIN_GROUP,
UACPI_AML_RESOURCE_PIN_GROUP_FUNCTION,
UACPI_AML_RESOURCE_PIN_GROUP_CONFIGURATION,
UACPI_AML_RESOURCE_CLOCK_INPUT,
UACPI_AML_RESOURCE_MAX = UACPI_AML_RESOURCE_CLOCK_INPUT,
};
enum uacpi_aml_resource_size_kind {
UACPI_AML_RESOURCE_SIZE_KIND_FIXED,
UACPI_AML_RESOURCE_SIZE_KIND_FIXED_OR_ONE_LESS,
UACPI_AML_RESOURCE_SIZE_KIND_VARIABLE,
};
enum uacpi_aml_resource_kind {
UACPI_AML_RESOURCE_KIND_SMALL = 0,
UACPI_AML_RESOURCE_KIND_LARGE,
};
enum uacpi_resource_convert_opcode {
UACPI_RESOURCE_CONVERT_OPCODE_END = 0,
/*
* AML -> native:
* Take the mask at 'aml_offset' and convert to an array of uacpi_u8
* at 'native_offset' with the value corresponding to the bit index.
* The array size is written to the byte at offset 'arg2'.
*
* native -> AML:
* Walk each element of the array at 'native_offset' and set the
* corresponding bit in the mask at 'aml_offset' to 1. The array size is
* read from the byte at offset 'arg2'.
*/
UACPI_RESOURCE_CONVERT_OPCODE_PACKED_ARRAY_8,
UACPI_RESOURCE_CONVERT_OPCODE_PACKED_ARRAY_16,
/*
* AML -> native:
* Grab the bits at the byte at 'aml_offset' + 'bit_index', and copy its
* value into the byte at 'native_offset'.
*
* native -> AML:
* Grab first N bits at 'native_offset' and copy to 'aml_offset' starting
* at the 'bit_index'.
*
* NOTE:
* These must be contiguous in this order.
*/
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_1,
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_2,
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_3,
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_6 =
UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_3 + 3,
/*
* AML -> native:
* Copy N bytes at 'aml_offset' to 'native_offset'.
*
* native -> AML:
* Copy N bytes at 'native_offset' to 'aml_offset'.
*
* 'imm' is added to the accumulator.
*
* NOTE: These are affected by the current value in the accumulator. If it's
* set to 0 at the time of evalution, this is executed once, N times
* otherwise. 0xFF is considered a special value, which resets the
* accumulator to 0 unconditionally.
*/
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_8,
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_16,
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_32,
UACPI_RESOURCE_CONVERT_OPCODE_FIELD_64,
/*
* If the length of the current resource is less than 'arg0', then skip
* 'imm' instructions.
*/
UACPI_RESOURCE_CONVERT_OPCODE_SKIP_IF_AML_SIZE_LESS_THAN,
/*
* Skip 'imm' instructions if 'arg0' is not equal to the value in the
* accumulator.
*/
UACPI_RESOURCE_CONVERT_OPCODE_SKIP_IF_NOT_EQUALS,
/*
* AML -> native:
* Set the byte at 'native_offset' to 'imm'.
*
* native -> AML:
* Set the byte at 'aml_offset' to 'imm'.
*/
UACPI_RESOURCE_CONVERT_OPCODE_SET_TO_IMM,
/*
* AML -> native:
* Load the AML resoruce length into the accumulator as well as the field at
* 'native_offset' of width N.
*
* native -> AML:
* Load the resource length into the accumulator.
*/
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_AML_SIZE_32,
/*
* AML -> native:
* Load the 8 bit field at 'aml_offset' into the accumulator and store at
* 'native_offset'.
*
* native -> AML:
* Load the 8 bit field at 'native_offset' into the accumulator and store
* at 'aml_offset'.
*
* The accumulator is multiplied by 'imm' unless it's set to zero.
*/
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_8_STORE,
/*
* Load the N bit field at 'native_offset' into the accumulator
*/
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_8_NATIVE,
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_16_NATIVE,
/*
* Load 'imm' into the accumulator.
*/
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_IMM,
/*
* AML -> native:
* Load the resource source at offset = aml size + accumulator into the
* uacpi_resource_source struct at 'native_offset'. The string bytes are
* written to the offset at resource size + accumulator. The presence is
* detected by comparing the length of the resource to the offset,
* 'arg2' optionally specifies the offset to the upper bound of the string.
*
* native -> AML:
* Load the resource source from the uacpi_resource_source struct at
* 'native_offset' to aml_size + accumulator. aml_size + accumulator is
* optionally written to 'aml_offset' if it's specified.
*/
UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_SOURCE,
UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_SOURCE_NO_INDEX,
UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_LABEL,
/*
* AML -> native:
* Load the pin table with upper bound specified at 'aml_offset'.
* The table length is calculated by subtracting the upper bound from
* aml_size and is written into the accumulator.
*
* native -> AML:
* Load the pin table length from 'native_offset' and multiply by 2, store
* the result in the accumulator.
*/
UACPI_RESOURCE_CONVERT_OPCODE_LOAD_PIN_TABLE_LENGTH,
/*
* AML -> native:
* Store the accumulator divided by 2 at 'native_offset'.
* The table is copied to the offset at resource size from offset at
* aml_size with the pointer written to the offset at 'arg2'.
*
* native -> AML:
* Read the pin table from resource size offset, write aml_size to
* 'aml_offset'. Copy accumulator bytes to the offset at aml_size.
*/
UACPI_RESOURCE_CONVERT_OPCODE_PIN_TABLE,
/*
* AML -> native:
* Load vendor data with offset stored at 'aml_offset'. The length is
* calculated as aml_size - aml_offset and is written to 'native_offset'.
* The data is written to offset - aml_size with the pointer written back
* to the offset at 'arg2'.
*
* native -> AML:
* Read vendor data from the pointer at offset 'arg2' and size at
* 'native_offset', the offset to write to is calculated as the difference
* between the data pointer and the native resource end pointer.
* offset + aml_size is written to 'aml_offset' and the data is copied
* there as well.
*/
UACPI_RESOURCE_CONVERT_OPCODE_VENDOR_DATA,
/*
* AML -> native:
* Read the serial type from the byte at 'aml_offset' and write it to the
* type field of the uacpi_resource_serial_bus_common structure. Convert
* the serial type to native and set the resource type to it. Copy the
* vendor data to the offset at native size, the length is calculated
* as type_data_length - extra-type-specific-size, and is written to
* vendor_data_length, as well as the accumulator. The data pointer is
* written to vendor_data.
*
* native -> AML:
* Set the serial type at 'aml_offset' to the value stored at
* 'native_offset'. Load the vendor data to the offset at aml_size,
* the length is read from 'vendor_data_length', and the data is copied from
* 'vendor_data'.
*/
UACPI_RESOURCE_CONVERT_OPCODE_SERIAL_TYPE_SPECIFIC,
/*
* Produces an error if encountered in the instruction stream.
* Used to trap invalid/unexpected code flow.
*/
UACPI_RESOURCE_CONVERT_OPCODE_UNREACHABLE,
};
struct uacpi_resource_convert_instruction {
uacpi_u8 code;
union {
uacpi_u8 aml_offset;
uacpi_u8 arg0;
} f1;
union {
uacpi_u8 native_offset;
uacpi_u8 arg1;
} f2;
union {
uacpi_u8 imm;
uacpi_u8 bit_index;
uacpi_u8 arg2;
} f3;
};
struct uacpi_resource_spec {
uacpi_u8 type : 5;
uacpi_u8 native_type : 5;
uacpi_u8 resource_kind : 1;
uacpi_u8 size_kind : 2;
/*
* Size of the resource as appears in the AML byte stream, for variable
* length resources this is the minimum.
*/
uacpi_u16 aml_size;
/*
* Size of the native human-readable uacpi resource, for variable length
* resources this is the minimum. The final length is this field plus the
* result of extra_size_for_native().
*/
uacpi_u16 native_size;
/*
* Calculate the amount of extra bytes that must be allocated for a specific
* native resource given the AML counterpart. This being NULL means no extra
* bytes are needed, aka native resources is always the same size.
*/
uacpi_size (*extra_size_for_native)(
const struct uacpi_resource_spec*, void*, uacpi_size
);
/*
* Calculate the number of bytes needed to represent a native resource as
* AML. The 'aml_size' field is used if this is NULL.
*/
uacpi_size (*size_for_aml)(
const struct uacpi_resource_spec*, uacpi_resource*
);
const struct uacpi_resource_convert_instruction *to_native;
const struct uacpi_resource_convert_instruction *to_aml;
};
typedef uacpi_iteration_decision (*uacpi_aml_resource_iteration_callback)(
void*, uacpi_u8 *data, uacpi_u16 resource_size,
const struct uacpi_resource_spec*
);
uacpi_status uacpi_for_each_aml_resource(
uacpi_data_view, uacpi_aml_resource_iteration_callback cb, void *user
);
uacpi_status uacpi_find_aml_resource_end_tag(
uacpi_data_view, uacpi_size *out_offset
);
uacpi_status uacpi_native_resources_from_aml(
uacpi_data_view, uacpi_resources **out_resources
);
uacpi_status uacpi_native_resources_to_aml(
uacpi_resources *resources, uacpi_object **out_template
);
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,21 @@
#pragma once
#include <uacpi/types.h>
struct uacpi_shareable {
uacpi_u32 reference_count;
};
void uacpi_shareable_init(uacpi_handle);
uacpi_bool uacpi_bugged_shareable(uacpi_handle);
void uacpi_make_shareable_bugged(uacpi_handle);
uacpi_u32 uacpi_shareable_ref(uacpi_handle);
uacpi_u32 uacpi_shareable_unref(uacpi_handle);
void uacpi_shareable_unref_and_delete_if_last(
uacpi_handle, void (*do_free)(uacpi_handle)
);
uacpi_u32 uacpi_shareable_refcount(uacpi_handle);

View File

@ -0,0 +1,128 @@
#pragma once
#include <uacpi/internal/types.h>
#include <uacpi/internal/helpers.h>
#include <uacpi/platform/libc.h>
#include <uacpi/platform/config.h>
#include <uacpi/kernel_api.h>
#ifdef UACPI_USE_BUILTIN_STRING
#ifndef uacpi_memcpy
void *uacpi_memcpy(void *dest, const void *src, uacpi_size count);
#endif
#ifndef uacpi_memmove
void *uacpi_memmove(void *dest, const void *src, uacpi_size count);
#endif
#ifndef uacpi_memset
void *uacpi_memset(void *dest, uacpi_i32 ch, uacpi_size count);
#endif
#ifndef uacpi_memcmp
uacpi_i32 uacpi_memcmp(const void *lhs, const void *rhs, uacpi_size count);
#endif
#else
#ifndef uacpi_memcpy
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMCPY
#define uacpi_memcpy __builtin_memcpy
#else
extern void *memcpy(void *dest, const void *src, uacpi_size count);
#define uacpi_memcpy memcpy
#endif
#endif
#ifndef uacpi_memmove
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMMOVE
#define uacpi_memmove __builtin_memmove
#else
extern void *memmove(void *dest, const void *src, uacpi_size count);
#define uacpi_memmove memmove
#endif
#endif
#ifndef uacpi_memset
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMSET
#define uacpi_memset __builtin_memset
#else
extern void *memset(void *dest, int ch, uacpi_size count);
#define uacpi_memset memset
#endif
#endif
#ifndef uacpi_memcmp
#ifdef UACPI_COMPILER_HAS_BUILTIN_MEMCMP
#define uacpi_memcmp __builtin_memcmp
#else
extern int memcmp(const void *lhs, const void *rhs, uacpi_size count);
#define uacpi_memcmp memcmp
#endif
#endif
#endif
#ifndef uacpi_strlen
uacpi_size uacpi_strlen(const uacpi_char *str);
#endif
#ifndef uacpi_strnlen
uacpi_size uacpi_strnlen(const uacpi_char *str, uacpi_size max);
#endif
#ifndef uacpi_strcmp
uacpi_i32 uacpi_strcmp(const uacpi_char *lhs, const uacpi_char *rhs);
#endif
#ifndef uacpi_snprintf
UACPI_PRINTF_DECL(3, 4)
uacpi_i32 uacpi_snprintf(
uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt, ...
);
#endif
#ifndef uacpi_vsnprintf
uacpi_i32 uacpi_vsnprintf(
uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt,
uacpi_va_list vlist
);
#endif
#ifdef UACPI_SIZED_FREES
#define uacpi_free(mem, size) uacpi_kernel_free(mem, size)
#else
#define uacpi_free(mem, _) uacpi_kernel_free(mem)
#endif
#define uacpi_memzero(ptr, size) uacpi_memset(ptr, 0, size)
#define UACPI_COMPARE(x, y, op) ((x) op (y) ? (x) : (y))
#define UACPI_MIN(x, y) UACPI_COMPARE(x, y, <)
#define UACPI_MAX(x, y) UACPI_COMPARE(x, y, >)
#define UACPI_ALIGN_UP_MASK(x, mask) (((x) + (mask)) & ~(mask))
#define UACPI_ALIGN_UP(x, val, type) UACPI_ALIGN_UP_MASK(x, (type)(val) - 1)
#define UACPI_ALIGN_DOWN_MASK(x, mask) ((x) & ~(mask))
#define UACPI_ALIGN_DOWN(x, val, type) UACPI_ALIGN_DOWN_MASK(x, (type)(val) - 1)
#define UACPI_IS_ALIGNED_MASK(x, mask) (((x) & (mask)) == 0)
#define UACPI_IS_ALIGNED(x, val, type) UACPI_IS_ALIGNED_MASK(x, (type)(val) - 1)
#define UACPI_IS_POWER_OF_TWO(x, type) UACPI_IS_ALIGNED(x, x, type)
void uacpi_memcpy_zerout(void *dst, const void *src,
uacpi_size dst_size, uacpi_size src_size);
// Returns the one-based bit location of LSb or 0
uacpi_u8 uacpi_bit_scan_forward(uacpi_u64);
// Returns the one-based bit location of MSb or 0
uacpi_u8 uacpi_bit_scan_backward(uacpi_u64);
#ifndef UACPI_NATIVE_ALLOC_ZEROED
void *uacpi_builtin_alloc_zeroed(uacpi_size size);
#define uacpi_kernel_alloc_zeroed uacpi_builtin_alloc_zeroed
#endif

View File

@ -0,0 +1,70 @@
#pragma once
#include <uacpi/internal/context.h>
#include <uacpi/internal/interpreter.h>
#include <uacpi/types.h>
#include <uacpi/status.h>
#include <uacpi/tables.h>
enum uacpi_table_origin {
#ifndef UACPI_BAREBONES_MODE
UACPI_TABLE_ORIGIN_FIRMWARE_VIRTUAL = 0,
#endif
UACPI_TABLE_ORIGIN_FIRMWARE_PHYSICAL = 1,
UACPI_TABLE_ORIGIN_HOST_VIRTUAL,
UACPI_TABLE_ORIGIN_HOST_PHYSICAL,
};
struct uacpi_installed_table {
uacpi_phys_addr phys_addr;
struct acpi_sdt_hdr hdr;
void *ptr;
uacpi_u16 reference_count;
#define UACPI_TABLE_LOADED (1 << 0)
#define UACPI_TABLE_CSUM_VERIFIED (1 << 1)
#define UACPI_TABLE_INVALID (1 << 2)
uacpi_u8 flags;
uacpi_u8 origin;
};
uacpi_status uacpi_initialize_tables(void);
void uacpi_deinitialize_tables(void);
uacpi_bool uacpi_signatures_match(const void *const lhs, const void *const rhs);
uacpi_status uacpi_check_table_signature(void *table, const uacpi_char *expect);
uacpi_status uacpi_verify_table_checksum(void *table, uacpi_size size);
uacpi_status uacpi_table_install_physical_with_origin(
uacpi_phys_addr phys, enum uacpi_table_origin origin, uacpi_table *out_table
);
uacpi_status uacpi_table_install_with_origin(
void *virt, enum uacpi_table_origin origin, uacpi_table *out_table
);
#ifndef UACPI_BAREBONES_MODE
void uacpi_table_mark_as_loaded(uacpi_size idx);
uacpi_status uacpi_table_load_with_cause(
uacpi_size idx, enum uacpi_table_load_cause cause
);
#endif // !UACPI_BAREBONES_MODE
typedef uacpi_iteration_decision (*uacpi_table_iteration_callback)
(void *user, struct uacpi_installed_table *tbl, uacpi_size idx);
uacpi_status uacpi_for_each_table(
uacpi_size base_idx, uacpi_table_iteration_callback, void *user
);
typedef uacpi_bool (*uacpi_table_match_callback)
(struct uacpi_installed_table *tbl);
uacpi_status uacpi_table_match(
uacpi_size base_idx, uacpi_table_match_callback, uacpi_table *out_table
);
#define UACPI_PRI_TBL_HDR "'%.4s' (OEM ID '%.6s' OEM Table ID '%.8s')"
#define UACPI_FMT_TBL_HDR(hdr) (hdr)->signature, (hdr)->oemid, (hdr)->oem_table_id

View File

@ -0,0 +1,310 @@
#pragma once
#include <uacpi/status.h>
#include <uacpi/types.h>
#include <uacpi/internal/shareable.h>
#ifndef UACPI_BAREBONES_MODE
// object->flags field if object->type == UACPI_OBJECT_REFERENCE
enum uacpi_reference_kind {
UACPI_REFERENCE_KIND_REFOF = 0,
UACPI_REFERENCE_KIND_LOCAL = 1,
UACPI_REFERENCE_KIND_ARG = 2,
UACPI_REFERENCE_KIND_NAMED = 3,
UACPI_REFERENCE_KIND_PKG_INDEX = 4,
};
// object->flags field if object->type == UACPI_OBJECT_STRING
enum uacpi_string_kind {
UACPI_STRING_KIND_NORMAL = 0,
UACPI_STRING_KIND_PATH,
};
typedef struct uacpi_buffer {
struct uacpi_shareable shareable;
union {
void *data;
uacpi_u8 *byte_data;
uacpi_char *text;
};
uacpi_size size;
} uacpi_buffer;
typedef struct uacpi_package {
struct uacpi_shareable shareable;
uacpi_object **objects;
uacpi_size count;
} uacpi_package;
typedef struct uacpi_buffer_field {
uacpi_buffer *backing;
uacpi_size bit_index;
uacpi_u32 bit_length;
uacpi_bool force_buffer;
} uacpi_buffer_field;
typedef struct uacpi_buffer_index {
uacpi_size idx;
uacpi_buffer *buffer;
} uacpi_buffer_index;
typedef struct uacpi_mutex {
struct uacpi_shareable shareable;
uacpi_handle handle;
uacpi_thread_id owner;
uacpi_u16 depth;
uacpi_u8 sync_level;
} uacpi_mutex;
typedef struct uacpi_event {
struct uacpi_shareable shareable;
uacpi_handle handle;
} uacpi_event;
typedef struct uacpi_address_space_handler {
struct uacpi_shareable shareable;
uacpi_region_handler callback;
uacpi_handle user_context;
struct uacpi_address_space_handler *next;
struct uacpi_operation_region *regions;
uacpi_u16 space;
#define UACPI_ADDRESS_SPACE_HANDLER_DEFAULT (1 << 0)
uacpi_u16 flags;
} uacpi_address_space_handler;
/*
* NOTE: These are common object headers.
* Any changes to these structs must be propagated to all objects.
* ==============================================================
* Common for the following objects:
* - UACPI_OBJECT_OPERATION_REGION
* - UACPI_OBJECT_PROCESSOR
* - UACPI_OBJECT_DEVICE
* - UACPI_OBJECT_THERMAL_ZONE
*/
typedef struct uacpi_address_space_handlers {
struct uacpi_shareable shareable;
uacpi_address_space_handler *head;
} uacpi_address_space_handlers;
typedef struct uacpi_device_notify_handler {
uacpi_notify_handler callback;
uacpi_handle user_context;
struct uacpi_device_notify_handler *next;
} uacpi_device_notify_handler;
/*
* Common for the following objects:
* - UACPI_OBJECT_PROCESSOR
* - UACPI_OBJECT_DEVICE
* - UACPI_OBJECT_THERMAL_ZONE
*/
typedef struct uacpi_handlers {
struct uacpi_shareable shareable;
uacpi_address_space_handler *address_space_head;
uacpi_device_notify_handler *notify_head;
} uacpi_handlers;
// This region has a corresponding _REG method that was succesfully executed
#define UACPI_OP_REGION_STATE_REG_EXECUTED (1 << 0)
// This region was successfully attached to a handler
#define UACPI_OP_REGION_STATE_ATTACHED (1 << 1)
typedef struct uacpi_operation_region {
struct uacpi_shareable shareable;
uacpi_address_space_handler *handler;
uacpi_handle user_context;
uacpi_u16 space;
uacpi_u8 state_flags;
uacpi_u64 offset;
uacpi_u64 length;
union {
// If space == TABLE_DATA
uacpi_u64 table_idx;
// If space == PCC
uacpi_u8 *internal_buffer;
};
// Used to link regions sharing the same handler
struct uacpi_operation_region *next;
} uacpi_operation_region;
typedef struct uacpi_device {
struct uacpi_shareable shareable;
uacpi_address_space_handler *address_space_handlers;
uacpi_device_notify_handler *notify_handlers;
} uacpi_device;
typedef struct uacpi_processor {
struct uacpi_shareable shareable;
uacpi_address_space_handler *address_space_handlers;
uacpi_device_notify_handler *notify_handlers;
uacpi_u8 id;
uacpi_u32 block_address;
uacpi_u8 block_length;
} uacpi_processor;
typedef struct uacpi_thermal_zone {
struct uacpi_shareable shareable;
uacpi_address_space_handler *address_space_handlers;
uacpi_device_notify_handler *notify_handlers;
} uacpi_thermal_zone;
typedef struct uacpi_power_resource {
uacpi_u8 system_level;
uacpi_u16 resource_order;
} uacpi_power_resource;
typedef uacpi_status (*uacpi_native_call_handler)(
uacpi_handle ctx, uacpi_object *retval
);
typedef struct uacpi_control_method {
struct uacpi_shareable shareable;
union {
uacpi_u8 *code;
uacpi_native_call_handler handler;
};
uacpi_mutex *mutex;
uacpi_u32 size;
uacpi_u8 sync_level : 4;
uacpi_u8 args : 3;
uacpi_u8 is_serialized : 1;
uacpi_u8 named_objects_persist: 1;
uacpi_u8 native_call : 1;
uacpi_u8 owns_code : 1;
} uacpi_control_method;
typedef enum uacpi_access_type {
UACPI_ACCESS_TYPE_ANY = 0,
UACPI_ACCESS_TYPE_BYTE = 1,
UACPI_ACCESS_TYPE_WORD = 2,
UACPI_ACCESS_TYPE_DWORD = 3,
UACPI_ACCESS_TYPE_QWORD = 4,
UACPI_ACCESS_TYPE_BUFFER = 5,
} uacpi_access_type;
typedef enum uacpi_lock_rule {
UACPI_LOCK_RULE_NO_LOCK = 0,
UACPI_LOCK_RULE_LOCK = 1,
} uacpi_lock_rule;
typedef enum uacpi_update_rule {
UACPI_UPDATE_RULE_PRESERVE = 0,
UACPI_UPDATE_RULE_WRITE_AS_ONES = 1,
UACPI_UPDATE_RULE_WRITE_AS_ZEROES = 2,
} uacpi_update_rule;
typedef enum uacpi_field_unit_kind {
UACPI_FIELD_UNIT_KIND_NORMAL = 0,
UACPI_FIELD_UNIT_KIND_INDEX = 1,
UACPI_FIELD_UNIT_KIND_BANK = 2,
} uacpi_field_unit_kind;
typedef struct uacpi_field_unit {
struct uacpi_shareable shareable;
union {
// UACPI_FIELD_UNIT_KIND_NORMAL
struct {
uacpi_namespace_node *region;
};
// UACPI_FIELD_UNIT_KIND_INDEX
struct {
struct uacpi_field_unit *index;
struct uacpi_field_unit *data;
};
// UACPI_FIELD_UNIT_KIND_BANK
struct {
uacpi_namespace_node *bank_region;
struct uacpi_field_unit *bank_selection;
uacpi_u64 bank_value;
};
};
uacpi_object *connection;
uacpi_u32 byte_offset;
uacpi_u32 bit_length;
uacpi_u32 pin_offset;
uacpi_u8 bit_offset_within_first_byte;
uacpi_u8 access_width_bytes;
uacpi_u8 access_length;
uacpi_u8 attributes : 4;
uacpi_u8 update_rule : 2;
uacpi_u8 kind : 2;
uacpi_u8 lock_rule : 1;
} uacpi_field_unit;
typedef struct uacpi_object {
struct uacpi_shareable shareable;
uacpi_u8 type;
uacpi_u8 flags;
union {
uacpi_u64 integer;
uacpi_package *package;
uacpi_buffer_field buffer_field;
uacpi_object *inner_object;
uacpi_control_method *method;
uacpi_buffer *buffer;
uacpi_mutex *mutex;
uacpi_event *event;
uacpi_buffer_index buffer_index;
uacpi_operation_region *op_region;
uacpi_device *device;
uacpi_processor *processor;
uacpi_thermal_zone *thermal_zone;
uacpi_address_space_handlers *address_space_handlers;
uacpi_handlers *handlers;
uacpi_power_resource power_resource;
uacpi_field_unit *field_unit;
};
} uacpi_object;
uacpi_object *uacpi_create_object(uacpi_object_type type);
enum uacpi_assign_behavior {
UACPI_ASSIGN_BEHAVIOR_DEEP_COPY,
UACPI_ASSIGN_BEHAVIOR_SHALLOW_COPY,
};
uacpi_status uacpi_object_assign(uacpi_object *dst, uacpi_object *src,
enum uacpi_assign_behavior);
void uacpi_object_attach_child(uacpi_object *parent, uacpi_object *child);
void uacpi_object_detach_child(uacpi_object *parent);
struct uacpi_object *uacpi_create_internal_reference(
enum uacpi_reference_kind kind, uacpi_object *child
);
uacpi_object *uacpi_unwrap_internal_reference(uacpi_object *object);
enum uacpi_prealloc_objects {
UACPI_PREALLOC_OBJECTS_NO,
UACPI_PREALLOC_OBJECTS_YES,
};
uacpi_bool uacpi_package_fill(
uacpi_package *pkg, uacpi_size num_elements,
enum uacpi_prealloc_objects prealloc_objects
);
uacpi_mutex *uacpi_create_mutex(void);
void uacpi_mutex_unref(uacpi_mutex*);
void uacpi_method_unref(uacpi_control_method*);
void uacpi_address_space_handler_unref(uacpi_address_space_handler *handler);
void uacpi_buffer_to_view(uacpi_buffer*, uacpi_data_view*);
#endif // !UACPI_BAREBONES_MODE

View File

@ -0,0 +1,45 @@
#pragma once
#include <uacpi/types.h>
#include <uacpi/utilities.h>
#include <uacpi/internal/log.h>
#include <uacpi/internal/stdlib.h>
static inline uacpi_phys_addr uacpi_truncate_phys_addr_with_warn(uacpi_u64 large_addr)
{
if (sizeof(uacpi_phys_addr) < 8 && large_addr > 0xFFFFFFFF) {
uacpi_warn(
"truncating a physical address 0x%"UACPI_PRIX64
" outside of address space\n", UACPI_FMT64(large_addr)
);
}
return (uacpi_phys_addr)large_addr;
}
#define UACPI_PTR_TO_VIRT_ADDR(ptr) ((uacpi_virt_addr)(ptr))
#define UACPI_VIRT_ADDR_TO_PTR(vaddr) ((void*)(vaddr))
#define UACPI_PTR_ADD(ptr, value) ((void*)(((uacpi_u8*)(ptr)) + value))
/*
* Target buffer must have a length of at least 8 bytes.
*/
void uacpi_eisa_id_to_string(uacpi_u32, uacpi_char *out_string);
enum uacpi_base {
UACPI_BASE_AUTO,
UACPI_BASE_OCT = 8,
UACPI_BASE_DEC = 10,
UACPI_BASE_HEX = 16,
};
uacpi_status uacpi_string_to_integer(
const uacpi_char *str, uacpi_size max_chars, enum uacpi_base base,
uacpi_u64 *out_value
);
uacpi_bool uacpi_is_valid_nameseg(uacpi_u8 *nameseg);
void uacpi_free_dynamic_string(const uacpi_char *str);
#define UACPI_NANOSECONDS_PER_SEC (1000ull * 1000ull * 1000ull)