ReactOS 0.4.17-dev-683-g0dafdc5
interpreter.c File Reference
Include dependency graph for interpreter.c:

Go to the source code of this file.

Classes

struct  package_length
 
struct  item
 
struct  op_context
 
struct  code_block
 
struct  call_frame
 
struct  execution_context
 
struct  field_specific_data
 

Macros

#define AML_READ(ptr, offset)   (*(((uacpi_u8*)(ptr)) + offset))
 
#define EXEC_OP_DO_LVL(lvl, reason, ...)
 
#define EXEC_OP_DO_ERR(reason, ...)   EXEC_OP_DO_LVL(error, reason, __VA_ARGS__)
 
#define EXEC_OP_DO_WARN(reason, ...)   EXEC_OP_DO_LVL(warn, reason, __VA_ARGS__)
 
#define EXEC_OP_ERR_3(reason, arg0, arg1, arg2)    EXEC_OP_DO_ERR(reason, ,arg0, arg1, arg2)
 
#define EXEC_OP_ERR_2(reason, arg0, arg1)   EXEC_OP_DO_ERR(reason, ,arg0, arg1)
 
#define EXEC_OP_ERR_1(reason, arg0)   EXEC_OP_DO_ERR(reason, ,arg0)
 
#define EXEC_OP_ERR(reason)   EXEC_OP_DO_ERR(reason)
 
#define EXEC_OP_WARN(reason)   EXEC_OP_DO_WARN(reason)
 
#define SPEC_SIMPLE_NAME   "SimpleName := NameString | ArgObj | LocalObj"
 
#define SPEC_SUPER_NAME    "SuperName := SimpleName | DebugObj | ReferenceTypeOpcode"
 
#define SPEC_TERM_ARG    "TermArg := ExpressionOpcode | DataObject | ArgObj | LocalObj"
 
#define SPEC_OPERAND   "Operand := TermArg => Integer"
 
#define SPEC_STRING   "String := TermArg => String"
 
#define SPEC_TARGET   "Target := SuperName | NullName"
 
#define SPEC_COMPUTATIONAL_DATA
 
#define EXT_OP_IDX(op)   (op & 0xFF)
 

Enumerations

enum  item_type {
  ITEM_NONE = 0 , ITEM_NAMESPACE_NODE , ITEM_OBJECT , ITEM_EMPTY_OBJECT ,
  ITEM_PACKAGE_LENGTH , ITEM_IMMEDIATE
}
 
enum  code_block_type { CODE_BLOCK_IF = 1 , CODE_BLOCK_ELSE = 2 , CODE_BLOCK_WHILE = 3 , CODE_BLOCK_SCOPE = 4 }
 
enum  force_release { FORCE_RELEASE_NO , FORCE_RELEASE_YES }
 
enum  resolve_behavior { RESOLVE_CREATE_LAST_NAMESEG_FAIL_IF_EXISTS , RESOLVE_FAIL_IF_DOESNT_EXIST }
 
enum  argx_or_localx { ARGX , LOCALX }
 
enum  match_op {
  MTR = 0 , MEQ = 1 , MLE = 2 , MLT = 3 ,
  MGE = 4 , MGT = 5
}
 
enum  op_trace_action_type { OP_TRACE_ACTION_BEGIN , OP_TRACE_ACTION_RESUME , OP_TRACE_ACTION_END }
 
enum  op_handler {
  OP_HANDLER_UNINSTALLED = 0 , OP_HANDLER_LOCAL , OP_HANDLER_ARG , OP_HANDLER_STRING ,
  OP_HANDLER_BINARY_MATH , OP_HANDLER_CONTROL_FLOW , OP_HANDLER_CODE_BLOCK , OP_HANDLER_RETURN ,
  OP_HANDLER_CREATE_METHOD , OP_HANDLER_COPY_OBJECT_OR_STORE , OP_HANDLER_INC_DEC , OP_HANDLER_REF_OF ,
  OP_HANDLER_DEREF_OF , OP_HANDLER_LOGICAL_NOT , OP_HANDLER_BINARY_LOGIC , OP_HANDLER_NAMED_OBJECT ,
  OP_HANDLER_BUFFER , OP_HANDLER_PACKAGE , OP_HANDLER_CREATE_NAMED , OP_HANDLER_CREATE_BUFFER_FIELD ,
  OP_HANDLER_READ_FIELD , OP_HANDLER_ALIAS , OP_HANDLER_CONCATENATE , OP_HANDLER_CONCATENATE_RES ,
  OP_HANDLER_SIZEOF , OP_HANDLER_UNARY_MATH , OP_HANDLER_INDEX , OP_HANDLER_OBJECT_TYPE ,
  OP_HANDLER_CREATE_OP_REGION , OP_HANDLER_CREATE_DATA_REGION , OP_HANDLER_CREATE_FIELD , OP_HANDLER_TO ,
  OP_HANDLER_TO_STRING , OP_HANDLER_TIMER , OP_HANDLER_MID , OP_HANDLER_MATCH ,
  OP_HANDLER_CREATE_MUTEX_OR_EVENT , OP_HANDLER_BCD , OP_HANDLER_UNLOAD , OP_HANDLER_LOAD_TABLE ,
  OP_HANDLER_LOAD , OP_HANDLER_STALL_OR_SLEEP , OP_HANDLER_EVENT_CTL , OP_HANDLER_MUTEX_CTL ,
  OP_HANDLER_NOTIFY , OP_HANDLER_FIRMWARE_REQUEST
}
 
enum  method_call_type { METHOD_CALL_NATIVE , METHOD_CALL_AML , METHOD_CALL_TABLE_LOAD }
 

Functions

 DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL (op_context_array, struct op_context, static)
 
 DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL (code_block_array, struct code_block, static)
 
static void held_mutexes_array_remove_idx (struct held_mutexes_array *arr, uacpi_size i)
 
static uacpi_status held_mutexes_array_remove_and_release (struct held_mutexes_array *arr, uacpi_mutex *mutex, enum force_release force)
 
 DYNAMIC_ARRAY_WITH_INLINE_STORAGE (DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL(temp_namespace_node_array, uacpi_namespace_node *, 8)
 
static voidcall_frame_cursor (struct call_frame *frame)
 
static uacpi_size call_frame_code_bytes_left (struct call_frame *frame)
 
static uacpi_bool call_frame_has_code (struct call_frame *frame)
 
 DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL (call_frame_array, struct call_frame, static)
 
static uacpi_status parse_nameseg (uacpi_u8 *cursor, uacpi_object_name *out_name)
 
static uacpi_status name_string_to_path (struct call_frame *frame, uacpi_size offset, uacpi_char **out_string, uacpi_size *out_size)
 
static uacpi_status resolve_name_string (struct call_frame *frame, enum resolve_behavior behavior, struct uacpi_namespace_node **out_node)
 
static uacpi_status do_install_node_item (struct call_frame *frame, struct item *item)
 
static uacpi_u8 peek_next_op (struct call_frame *frame, uacpi_aml_op *out_op)
 
static bool op_is_internal (const struct uacpi_op_spec *op)
 
static bool op_is_invalid (const struct uacpi_op_spec *op)
 
static uacpi_status get_op (struct execution_context *ctx)
 
static uacpi_status handle_buffer (struct execution_context *ctx)
 
static uacpi_status handle_string (struct execution_context *ctx)
 
static uacpi_status handle_package (struct execution_context *ctx)
 
static uacpi_size sizeof_int (void)
 
static uacpi_status get_object_storage (uacpi_object *obj, uacpi_data_view *out_buf, uacpi_bool include_null)
 
static uacpi_u8buffer_index_cursor (uacpi_buffer_index *buf_idx)
 
static void write_buffer_index (uacpi_buffer_index *buf_idx, uacpi_data_view *src_buf)
 
static uacpi_status object_assign_with_implicit_cast (uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
 
static uacpi_status handle_arg_or_local (struct execution_context *ctx, uacpi_size idx, enum argx_or_localx type)
 
static uacpi_status handle_local (struct execution_context *ctx)
 
static uacpi_status handle_arg (struct execution_context *ctx)
 
static uacpi_status handle_named_object (struct execution_context *ctx)
 
static uacpi_status handle_create_alias (struct execution_context *ctx)
 
static uacpi_status handle_create_op_region (struct execution_context *ctx)
 
static uacpi_status table_id_error (const uacpi_char *opcode, const uacpi_char *arg, uacpi_buffer *str)
 
static void report_table_id_find_error (const uacpi_char *opcode, struct uacpi_table_identifiers *id, uacpi_status ret)
 
static uacpi_status build_table_id (const uacpi_char *opcode, struct uacpi_table_identifiers *out_id, uacpi_buffer *signature, uacpi_buffer *oem_id, uacpi_buffer *oem_table_id)
 
static uacpi_status handle_create_data_region (struct execution_context *ctx)
 
static uacpi_bool is_dynamic_table_load (enum uacpi_table_load_cause cause)
 
static uacpi_status prepare_table_load (void *ptr, enum uacpi_table_load_cause cause, uacpi_control_method *in_method)
 
static uacpi_status do_load_table (uacpi_namespace_node *parent, struct acpi_sdt_hdr *tbl, enum uacpi_table_load_cause cause)
 
static uacpi_status handle_load_table (struct execution_context *ctx)
 
static uacpi_status handle_load (struct execution_context *ctx)
 
uacpi_status uacpi_execute_table (void *tbl, enum uacpi_table_load_cause cause)
 
static uacpi_u32 get_field_length (struct item *item)
 
static uacpi_status ensure_is_a_field_unit (uacpi_namespace_node *node, uacpi_field_unit **out_field)
 
static uacpi_status ensure_is_an_op_region (uacpi_namespace_node *node, uacpi_namespace_node **out_node)
 
static uacpi_status handle_create_field (struct execution_context *ctx)
 
static void truncate_number_if_needed (uacpi_object *obj)
 
static uacpi_u64 ones (void)
 
static uacpi_status method_get_ret_target (struct execution_context *ctx, uacpi_object **out_operand)
 
static uacpi_status method_get_ret_object (struct execution_context *ctx, uacpi_object **out_obj)
 
static struct code_blockfind_last_block (struct code_block_array *blocks, enum code_block_type type, uacpi_size *out_idx_plus_one)
 
static uacpi_status begin_block_execution (struct execution_context *ctx)
 
static void frame_reset_post_end_block (struct execution_context *ctx, enum code_block_type type)
 
static void debug_store_no_recurse (const uacpi_char *prefix, uacpi_object *src)
 
static uacpi_status debug_store (uacpi_object *src)
 
static uacpi_objectreference_unwind (uacpi_object *obj)
 
static uacpi_iteration_decision opregion_try_detach_from_parent (void *user, uacpi_namespace_node *node, uacpi_u32 node_depth)
 
static void object_replace_child (uacpi_object *parent, uacpi_object *new_child)
 
static uacpi_status copy_object_to_reference (uacpi_object *dst, uacpi_object *src)
 
static uacpi_status store_to_reference (uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
 
static uacpi_status handle_ref_of (struct execution_context *ctx)
 
static uacpi_status do_binary_math (uacpi_object *arg0, uacpi_object *arg1, uacpi_object *tgt0, uacpi_object *tgt1, uacpi_aml_op op)
 
static uacpi_status handle_binary_math (struct execution_context *ctx)
 
static uacpi_status handle_unary_math (struct execution_context *ctx)
 
static uacpi_status ensure_valid_idx (uacpi_object *obj, uacpi_size idx, uacpi_size src_size)
 
static uacpi_status handle_index (struct execution_context *ctx)
 
static uacpi_u64 object_to_integer (const uacpi_object *obj, uacpi_size max_buffer_bytes)
 
static uacpi_status integer_to_string (uacpi_u64 integer, uacpi_buffer *str, uacpi_bool is_hex)
 
static uacpi_status buffer_to_string (uacpi_buffer *buf, uacpi_buffer *str, uacpi_bool is_hex)
 
static uacpi_status do_make_empty_object (uacpi_buffer *buf, uacpi_bool is_string)
 
static uacpi_status make_null_string (uacpi_buffer *buf)
 
static uacpi_status make_null_buffer (uacpi_buffer *buf)
 
static uacpi_status handle_to (struct execution_context *ctx)
 
static uacpi_status handle_to_string (struct execution_context *ctx)
 
static uacpi_status handle_mid (struct execution_context *ctx)
 
static uacpi_status handle_concatenate (struct execution_context *ctx)
 
static uacpi_status handle_concatenate_res (struct execution_context *ctx)
 
static uacpi_status handle_sizeof (struct execution_context *ctx)
 
static uacpi_status handle_object_type (struct execution_context *ctx)
 
static uacpi_status handle_timer (struct execution_context *ctx)
 
static uacpi_status handle_stall_or_sleep (struct execution_context *ctx)
 
static uacpi_status handle_bcd (struct execution_context *ctx)
 
static uacpi_status handle_unload (struct execution_context *ctx)
 
static uacpi_status handle_logical_not (struct execution_context *ctx)
 
static uacpi_bool handle_logical_equality (uacpi_object *lhs, uacpi_object *rhs)
 
static uacpi_bool handle_logical_less_or_greater (uacpi_aml_op op, uacpi_object *lhs, uacpi_object *rhs)
 
static uacpi_status handle_binary_logic (struct execution_context *ctx)
 
static uacpi_bool match_one (enum match_op op, uacpi_u64 lhs, uacpi_u64 rhs)
 
static uacpi_status handle_match (struct execution_context *ctx)
 
static uacpi_status parse_package_length (struct call_frame *frame, struct package_length *out_pkg)
 
static void init_method_flags (uacpi_control_method *method, uacpi_u8 flags_byte)
 
static uacpi_status handle_create_method (struct execution_context *ctx)
 
static uacpi_status handle_create_mutex_or_event (struct execution_context *ctx)
 
static uacpi_status handle_event_ctl (struct execution_context *ctx)
 
static uacpi_status handle_mutex_ctl (struct execution_context *ctx)
 
static uacpi_status handle_notify (struct execution_context *ctx)
 
static uacpi_status handle_firmware_request (struct execution_context *ctx)
 
static uacpi_status handle_create_named (struct execution_context *ctx)
 
static uacpi_object_type buffer_field_get_read_type (struct uacpi_buffer_field *field)
 
static uacpi_status field_get_read_type (uacpi_object *obj, uacpi_object_type *out_type)
 
static uacpi_status field_byte_size (uacpi_object *obj, uacpi_size *out_size)
 
static uacpi_status handle_deref_of (struct execution_context *ctx)
 
static uacpi_status handle_field_read (struct execution_context *ctx)
 
static uacpi_status handle_create_buffer_field (struct execution_context *ctx)
 
static uacpi_status handle_control_flow (struct execution_context *ctx)
 
static uacpi_status create_named_scope (struct op_context *op_ctx)
 
static uacpi_status handle_code_block (struct execution_context *ctx)
 
static uacpi_status handle_return (struct execution_context *ctx)
 
static void refresh_ctx_pointers (struct execution_context *ctx)
 
static uacpi_bool ctx_has_non_preempted_op (struct execution_context *ctx)
 
static void trace_op (const struct uacpi_op_spec *op, enum op_trace_action_type action)
 
static void trace_pop (uacpi_u8 pop)
 
static uacpi_status frame_push_args (struct call_frame *frame, struct op_context *op_ctx)
 
static uacpi_status frame_setup_base_scope (struct call_frame *frame, uacpi_namespace_node *scope, uacpi_control_method *method)
 
static uacpi_status push_new_frame (struct execution_context *ctx, struct call_frame **out_frame)
 
static uacpi_bool maybe_end_block (struct execution_context *ctx)
 
static uacpi_status store_to_target (uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
 
static uacpi_status handle_copy_object_or_store (struct execution_context *ctx)
 
static uacpi_status handle_inc_dec (struct execution_context *ctx)
 
static uacpi_status enter_method (struct execution_context *ctx, struct call_frame *new_frame, uacpi_control_method *method)
 
static uacpi_status push_op (struct execution_context *ctx)
 
static uacpi_bool pop_item (struct op_context *op_ctx)
 
static void pop_op (struct execution_context *ctx)
 
static void call_frame_clear (struct call_frame *frame)
 
static const uacpi_u8op_decode_cursor (const struct op_context *ctx)
 
static uacpi_u8 op_decode_byte (struct op_context *ctx)
 
static uacpi_aml_op op_decode_aml_op (struct op_context *op_ctx)
 
static uacpi_bool op_wants_supername (enum uacpi_parse_op op)
 
static uacpi_bool op_wants_term_arg_or_operand (enum uacpi_parse_op op)
 
static uacpi_bool op_allows_unresolved (enum uacpi_parse_op op)
 
static uacpi_bool op_allows_unresolved_if_load (enum uacpi_parse_op op)
 
static uacpi_status op_typecheck (const struct op_context *op_ctx, const struct op_context *cur_op_ctx)
 
static uacpi_status typecheck_obj (const struct op_context *op_ctx, const uacpi_object *obj, enum uacpi_object_type expected_type, const uacpi_char *spec_desc)
 
static uacpi_status typecheck_operand (const struct op_context *op_ctx, const uacpi_object *obj)
 
static uacpi_status typecheck_string (const struct op_context *op_ctx, const uacpi_object *obj)
 
static uacpi_status typecheck_computational_data (const struct op_context *op_ctx, const uacpi_object *obj)
 
static void emit_op_skip_warn (const struct op_context *op_ctx)
 
static void trace_named_object_lookup_or_creation_failure (struct call_frame *frame, uacpi_size offset, enum uacpi_parse_op op, uacpi_status ret, enum uacpi_log_level level)
 
static uacpi_status uninstalled_op_handler (struct execution_context *ctx)
 
static uacpi_status prepare_method_call (struct execution_context *ctx, uacpi_namespace_node *node, uacpi_control_method *method, enum method_call_type type, const uacpi_object_array *args)
 
static void apply_tracked_pkg (struct call_frame *frame, struct op_context *op_ctx)
 
static uacpi_status exec_op (struct execution_context *ctx)
 
static void ctx_reload_post_ret (struct execution_context *ctx)
 
static void trace_method_abort (struct code_block *block, uacpi_size depth, uacpi_u32 aml_offset, uacpi_u32 method_size, const uacpi_char *op)
 
static void stack_unwind (struct execution_context *ctx)
 
static void execution_context_release (struct execution_context *ctx)
 
uacpi_status uacpi_execute_control_method (uacpi_namespace_node *scope, uacpi_control_method *method, const uacpi_object_array *args, uacpi_object **out_obj)
 
uacpi_status uacpi_osi (uacpi_handle handle, uacpi_object *retval)
 

Variables

static const uacpi_char *const op_trace_action_types [3]
 
static uacpi_u8 parse_op_generates_item [0x100]
 
static uacpi_status(* op_handlers [])(struct execution_context *ctx)
 
static uacpi_u8 handler_idx_of_op [0x100]
 
static uacpi_u8 handler_idx_of_ext_op [0x100]
 

Macro Definition Documentation

◆ AML_READ

#define AML_READ (   ptr,
  offset 
)    (*(((uacpi_u8*)(ptr)) + offset))

Definition at line 340 of file interpreter.c.

◆ EXEC_OP_DO_ERR

#define EXEC_OP_DO_ERR (   reason,
  ... 
)    EXEC_OP_DO_LVL(error, reason, __VA_ARGS__)

Definition at line 4723 of file interpreter.c.

◆ EXEC_OP_DO_LVL

#define EXEC_OP_DO_LVL (   lvl,
  reason,
  ... 
)
Value:
uacpi_##lvl("Op 0x%04X ('%s'): "reason, \
op_ctx->op->code, op_ctx->op->name __VA_ARGS__)
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1971

Definition at line 4719 of file interpreter.c.

◆ EXEC_OP_DO_WARN

#define EXEC_OP_DO_WARN (   reason,
  ... 
)    EXEC_OP_DO_LVL(warn, reason, __VA_ARGS__)

Definition at line 4724 of file interpreter.c.

◆ EXEC_OP_ERR

#define EXEC_OP_ERR (   reason)    EXEC_OP_DO_ERR(reason)

Definition at line 4730 of file interpreter.c.

◆ EXEC_OP_ERR_1

#define EXEC_OP_ERR_1 (   reason,
  arg0 
)    EXEC_OP_DO_ERR(reason, ,arg0)

Definition at line 4729 of file interpreter.c.

◆ EXEC_OP_ERR_2

#define EXEC_OP_ERR_2 (   reason,
  arg0,
  arg1 
)    EXEC_OP_DO_ERR(reason, ,arg0, arg1)

Definition at line 4728 of file interpreter.c.

◆ EXEC_OP_ERR_3

#define EXEC_OP_ERR_3 (   reason,
  arg0,
  arg1,
  arg2 
)     EXEC_OP_DO_ERR(reason, ,arg0, arg1, arg2)

Definition at line 4726 of file interpreter.c.

◆ EXEC_OP_WARN

#define EXEC_OP_WARN (   reason)    EXEC_OP_DO_WARN(reason)

Definition at line 4732 of file interpreter.c.

◆ EXT_OP_IDX

#define EXT_OP_IDX (   op)    (op & 0xFF)

Definition at line 5200 of file interpreter.c.

◆ SPEC_COMPUTATIONAL_DATA

#define SPEC_COMPUTATIONAL_DATA
Value:
"ComputationalData := ByteConst | WordConst | DWordConst | QWordConst " \
"| String | ConstObj | RevisionOp | DefBuffer"

Definition at line 4743 of file interpreter.c.

◆ SPEC_OPERAND

#define SPEC_OPERAND   "Operand := TermArg => Integer"

Definition at line 4739 of file interpreter.c.

◆ SPEC_SIMPLE_NAME

#define SPEC_SIMPLE_NAME   "SimpleName := NameString | ArgObj | LocalObj"

Definition at line 4734 of file interpreter.c.

◆ SPEC_STRING

#define SPEC_STRING   "String := TermArg => String"

Definition at line 4740 of file interpreter.c.

◆ SPEC_SUPER_NAME

#define SPEC_SUPER_NAME    "SuperName := SimpleName | DebugObj | ReferenceTypeOpcode"

Definition at line 4735 of file interpreter.c.

◆ SPEC_TARGET

#define SPEC_TARGET   "Target := SuperName | NullName"

Definition at line 4741 of file interpreter.c.

◆ SPEC_TERM_ARG

#define SPEC_TERM_ARG    "TermArg := ExpressionOpcode | DataObject | ArgObj | LocalObj"

Definition at line 4737 of file interpreter.c.

Enumeration Type Documentation

◆ argx_or_localx

Enumerator
ARGX 
LOCALX 

Definition at line 1034 of file interpreter.c.

1034 {
1035 ARGX,
1036 LOCALX,
1037};
@ LOCALX
Definition: interpreter.c:1036
@ ARGX
Definition: interpreter.c:1035

◆ code_block_type

Enumerator
CODE_BLOCK_IF 
CODE_BLOCK_ELSE 
CODE_BLOCK_WHILE 
CODE_BLOCK_SCOPE 

Definition at line 87 of file interpreter.c.

87 {
88 CODE_BLOCK_IF = 1,
92};
@ CODE_BLOCK_ELSE
Definition: interpreter.c:89
@ CODE_BLOCK_IF
Definition: interpreter.c:88
@ CODE_BLOCK_WHILE
Definition: interpreter.c:90
@ CODE_BLOCK_SCOPE
Definition: interpreter.c:91

◆ force_release

Enumerator
FORCE_RELEASE_NO 
FORCE_RELEASE_YES 

Definition at line 180 of file interpreter.c.

180 {
183};
@ FORCE_RELEASE_NO
Definition: interpreter.c:181
@ FORCE_RELEASE_YES
Definition: interpreter.c:182

◆ item_type

Enumerator
ITEM_NONE 
ITEM_NAMESPACE_NODE 
ITEM_OBJECT 
ITEM_EMPTY_OBJECT 
ITEM_PACKAGE_LENGTH 
ITEM_IMMEDIATE 

Definition at line 23 of file interpreter.c.

23 {
24 ITEM_NONE = 0,
30};
@ ITEM_OBJECT
Definition: interpreter.c:26
@ ITEM_EMPTY_OBJECT
Definition: interpreter.c:27
@ ITEM_IMMEDIATE
Definition: interpreter.c:29
@ ITEM_NONE
Definition: interpreter.c:24
@ ITEM_PACKAGE_LENGTH
Definition: interpreter.c:28
@ ITEM_NAMESPACE_NODE
Definition: interpreter.c:25

◆ match_op

Enumerator
MTR 
MEQ 
MLE 
MLT 
MGE 
MGT 

Definition at line 3390 of file interpreter.c.

3390 {
3391 MTR = 0,
3392 MEQ = 1,
3393 MLE = 2,
3394 MLT = 3,
3395 MGE = 4,
3396 MGT = 5,
3397};
@ MGE
Definition: interpreter.c:3395
@ MLT
Definition: interpreter.c:3394
@ MGT
Definition: interpreter.c:3396
@ MLE
Definition: interpreter.c:3393
@ MEQ
Definition: interpreter.c:3392
@ MTR
Definition: interpreter.c:3391

◆ method_call_type

Enumerator
METHOD_CALL_NATIVE 
METHOD_CALL_AML 
METHOD_CALL_TABLE_LOAD 

Definition at line 5240 of file interpreter.c.

5240 {
5244};
@ METHOD_CALL_AML
Definition: interpreter.c:5242
@ METHOD_CALL_TABLE_LOAD
Definition: interpreter.c:5243
@ METHOD_CALL_NATIVE
Definition: interpreter.c:5241

◆ op_handler

Enumerator
OP_HANDLER_UNINSTALLED 
OP_HANDLER_LOCAL 
OP_HANDLER_ARG 
OP_HANDLER_STRING 
OP_HANDLER_BINARY_MATH 
OP_HANDLER_CONTROL_FLOW 
OP_HANDLER_CODE_BLOCK 
OP_HANDLER_RETURN 
OP_HANDLER_CREATE_METHOD 
OP_HANDLER_COPY_OBJECT_OR_STORE 
OP_HANDLER_INC_DEC 
OP_HANDLER_REF_OF 
OP_HANDLER_DEREF_OF 
OP_HANDLER_LOGICAL_NOT 
OP_HANDLER_BINARY_LOGIC 
OP_HANDLER_NAMED_OBJECT 
OP_HANDLER_BUFFER 
OP_HANDLER_PACKAGE 
OP_HANDLER_CREATE_NAMED 
OP_HANDLER_CREATE_BUFFER_FIELD 
OP_HANDLER_READ_FIELD 
OP_HANDLER_ALIAS 
OP_HANDLER_CONCATENATE 
OP_HANDLER_CONCATENATE_RES 
OP_HANDLER_SIZEOF 
OP_HANDLER_UNARY_MATH 
OP_HANDLER_INDEX 
OP_HANDLER_OBJECT_TYPE 
OP_HANDLER_CREATE_OP_REGION 
OP_HANDLER_CREATE_DATA_REGION 
OP_HANDLER_CREATE_FIELD 
OP_HANDLER_TO 
OP_HANDLER_TO_STRING 
OP_HANDLER_TIMER 
OP_HANDLER_MID 
OP_HANDLER_MATCH 
OP_HANDLER_CREATE_MUTEX_OR_EVENT 
OP_HANDLER_BCD 
OP_HANDLER_UNLOAD 
OP_HANDLER_LOAD_TABLE 
OP_HANDLER_LOAD 
OP_HANDLER_STALL_OR_SLEEP 
OP_HANDLER_EVENT_CTL 
OP_HANDLER_MUTEX_CTL 
OP_HANDLER_NOTIFY 
OP_HANDLER_FIRMWARE_REQUEST 

Definition at line 4988 of file interpreter.c.

4988 {
5035};
@ OP_HANDLER_LOGICAL_NOT
Definition: interpreter.c:5002
@ OP_HANDLER_INDEX
Definition: interpreter.c:5015
@ OP_HANDLER_CREATE_METHOD
Definition: interpreter.c:4997
@ OP_HANDLER_MUTEX_CTL
Definition: interpreter.c:5032
@ OP_HANDLER_STALL_OR_SLEEP
Definition: interpreter.c:5030
@ OP_HANDLER_BINARY_MATH
Definition: interpreter.c:4993
@ OP_HANDLER_INC_DEC
Definition: interpreter.c:4999
@ OP_HANDLER_CREATE_DATA_REGION
Definition: interpreter.c:5018
@ OP_HANDLER_BINARY_LOGIC
Definition: interpreter.c:5003
@ OP_HANDLER_NOTIFY
Definition: interpreter.c:5033
@ OP_HANDLER_LOCAL
Definition: interpreter.c:4990
@ OP_HANDLER_LOAD_TABLE
Definition: interpreter.c:5028
@ OP_HANDLER_ALIAS
Definition: interpreter.c:5010
@ OP_HANDLER_REF_OF
Definition: interpreter.c:5000
@ OP_HANDLER_OBJECT_TYPE
Definition: interpreter.c:5016
@ OP_HANDLER_UNLOAD
Definition: interpreter.c:5027
@ OP_HANDLER_STRING
Definition: interpreter.c:4992
@ OP_HANDLER_BUFFER
Definition: interpreter.c:5005
@ OP_HANDLER_UNARY_MATH
Definition: interpreter.c:5014
@ OP_HANDLER_CREATE_MUTEX_OR_EVENT
Definition: interpreter.c:5025
@ OP_HANDLER_PACKAGE
Definition: interpreter.c:5006
@ OP_HANDLER_MID
Definition: interpreter.c:5023
@ OP_HANDLER_CREATE_FIELD
Definition: interpreter.c:5019
@ OP_HANDLER_COPY_OBJECT_OR_STORE
Definition: interpreter.c:4998
@ OP_HANDLER_BCD
Definition: interpreter.c:5026
@ OP_HANDLER_CODE_BLOCK
Definition: interpreter.c:4995
@ OP_HANDLER_TO_STRING
Definition: interpreter.c:5021
@ OP_HANDLER_SIZEOF
Definition: interpreter.c:5013
@ OP_HANDLER_NAMED_OBJECT
Definition: interpreter.c:5004
@ OP_HANDLER_LOAD
Definition: interpreter.c:5029
@ OP_HANDLER_CONCATENATE_RES
Definition: interpreter.c:5012
@ OP_HANDLER_READ_FIELD
Definition: interpreter.c:5009
@ OP_HANDLER_CONCATENATE
Definition: interpreter.c:5011
@ OP_HANDLER_EVENT_CTL
Definition: interpreter.c:5031
@ OP_HANDLER_CONTROL_FLOW
Definition: interpreter.c:4994
@ OP_HANDLER_MATCH
Definition: interpreter.c:5024
@ OP_HANDLER_RETURN
Definition: interpreter.c:4996
@ OP_HANDLER_FIRMWARE_REQUEST
Definition: interpreter.c:5034
@ OP_HANDLER_CREATE_BUFFER_FIELD
Definition: interpreter.c:5008
@ OP_HANDLER_TIMER
Definition: interpreter.c:5022
@ OP_HANDLER_ARG
Definition: interpreter.c:4991
@ OP_HANDLER_CREATE_NAMED
Definition: interpreter.c:5007
@ OP_HANDLER_UNINSTALLED
Definition: interpreter.c:4989
@ OP_HANDLER_CREATE_OP_REGION
Definition: interpreter.c:5017
@ OP_HANDLER_DEREF_OF
Definition: interpreter.c:5001
@ OP_HANDLER_TO
Definition: interpreter.c:5020

◆ op_trace_action_type

Enumerator
OP_TRACE_ACTION_BEGIN 
OP_TRACE_ACTION_RESUME 
OP_TRACE_ACTION_END 

Definition at line 4271 of file interpreter.c.

4271 {
4275};
@ OP_TRACE_ACTION_RESUME
Definition: interpreter.c:4273
@ OP_TRACE_ACTION_BEGIN
Definition: interpreter.c:4272
@ OP_TRACE_ACTION_END
Definition: interpreter.c:4274

◆ resolve_behavior

Enumerator
RESOLVE_CREATE_LAST_NAMESEG_FAIL_IF_EXISTS 
RESOLVE_FAIL_IF_DOESNT_EXIST 

Definition at line 475 of file interpreter.c.

475 {
478};
@ RESOLVE_FAIL_IF_DOESNT_EXIST
Definition: interpreter.c:477
@ RESOLVE_CREATE_LAST_NAMESEG_FAIL_IF_EXISTS
Definition: interpreter.c:476

Function Documentation

◆ apply_tracked_pkg()

static void apply_tracked_pkg ( struct call_frame frame,
struct op_context op_ctx 
)
static

Definition at line 5322 of file interpreter.c.

5325{
5326 struct item *item;
5327
5328 if (op_ctx->tracked_pkg_idx == 0)
5329 return;
5330
5331 item = item_array_at(&op_ctx->items, op_ctx->tracked_pkg_idx - 1);
5332 frame->code_offset = item->pkg.end;
5333}
uacpi_u32 code_offset
Definition: interpreter.c:283
struct package_length pkg
Definition: interpreter.c:43
uacpi_u8 tracked_pkg_idx
Definition: interpreter.c:60
struct item_array items
Definition: interpreter.c:65

Referenced by exec_op().

◆ begin_block_execution()

static uacpi_status begin_block_execution ( struct execution_context ctx)
static

Definition at line 2029 of file interpreter.c.

2030{
2031 struct call_frame *cur_frame = ctx->cur_frame;
2032 struct op_context *op_ctx = ctx->cur_op_ctx;
2033 struct package_length *pkg;
2034 struct code_block *block;
2035
2036 block = code_block_array_alloc(&cur_frame->code_blocks);
2039
2040 pkg = &item_array_at(&op_ctx->items, 0)->pkg;
2041
2042 // Disarm the tracked package so that we don't skip the Scope
2043 op_ctx->tracked_pkg_idx = 0;
2044
2045 switch (op_ctx->op->code) {
2046 case UACPI_AML_OP_IfOp:
2047 block->type = CODE_BLOCK_IF;
2048 break;
2049 case UACPI_AML_OP_ElseOp:
2050 block->type = CODE_BLOCK_ELSE;
2051 break;
2052 case UACPI_AML_OP_WhileOp:
2053 block->type = CODE_BLOCK_WHILE;
2054
2055 if (pkg->begin == cur_frame->prev_while_code_offset) {
2056 uacpi_u64 cur_ticks;
2057
2059
2060 if (uacpi_unlikely(cur_ticks > block->expiration_point)) {
2061 uacpi_error("loop time out after running for %u seconds",
2062 g_uacpi_rt_ctx.loop_timeout_seconds);
2063 code_block_array_pop(&cur_frame->code_blocks);
2065 }
2066
2067 block->expiration_point = cur_frame->prev_while_expiration;
2068 } else {
2069 /*
2070 * Calculate the expiration point for this loop.
2071 * If a loop is executed past this point, it will get aborted.
2072 */
2073 block->expiration_point = uacpi_kernel_get_nanoseconds_since_boot();
2074 block->expiration_point +=
2075 g_uacpi_rt_ctx.loop_timeout_seconds * UACPI_NANOSECONDS_PER_SEC;
2076 }
2077
2078 cur_frame->last_while_idx_plus_one = code_block_array_size(
2079 &cur_frame->code_blocks
2080 );
2081 break;
2082 case UACPI_AML_OP_ScopeOp:
2083 case UACPI_AML_OP_DeviceOp:
2084 case UACPI_AML_OP_ProcessorOp:
2085 case UACPI_AML_OP_PowerResOp:
2086 case UACPI_AML_OP_ThermalZoneOp:
2087 block->type = CODE_BLOCK_SCOPE;
2088 block->node = item_array_at(&op_ctx->items, 1)->node;
2089 cur_frame->cur_scope = block->node;
2090 break;
2091 default:
2092 code_block_array_pop(&cur_frame->code_blocks);
2094 }
2095
2096 // -1 because we want to re-evaluate at the start of the op next time
2097 block->begin = pkg->begin - 1;
2098 block->end = pkg->end;
2099 ctx->cur_block = block;
2100
2101 return UACPI_STATUS_OK;
2102}
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:17
#define uacpi_error(...)
Definition: log.h:36
#define uacpi_unlikely(expr)
Definition: compiler.h:88
uint64_t uacpi_u64
Definition: types.h:22
#define UACPI_NULL
Definition: types.h:33
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
@ UACPI_STATUS_AML_LOOP_TIMEOUT
Definition: status.h:43
@ UACPI_STATUS_OK
Definition: status.h:11
#define UACPI_NANOSECONDS_PER_SEC
Definition: utilities.h:45
uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void)
Definition: uacpiosl.c:35
uacpi_u32 prev_while_code_offset
Definition: interpreter.c:281
struct uacpi_namespace_node * cur_scope
Definition: interpreter.c:285
uacpi_size last_while_idx_plus_one
Definition: interpreter.c:278
struct code_block_array code_blocks
Definition: interpreter.c:274
uacpi_u64 prev_while_expiration
Definition: interpreter.c:280
const struct uacpi_op_spec * op
Definition: interpreter.c:64
uacpi_u32 begin
Definition: interpreter.c:33
uacpi_u32 end
Definition: interpreter.c:34
static unsigned int block
Definition: xmlmemory.c:101

Referenced by handle_code_block().

◆ buffer_field_get_read_type()

static uacpi_object_type buffer_field_get_read_type ( struct uacpi_buffer_field field)
static

Definition at line 3837 of file interpreter.c.

3840{
3841 if (field->bit_length > (g_uacpi_rt_ctx.is_rev1 ? 32u : 64u) ||
3842 field->force_buffer)
3843 return UACPI_OBJECT_BUFFER;
3844
3845 return UACPI_OBJECT_INTEGER;
3846}
@ UACPI_OBJECT_BUFFER
Definition: types.h:114
@ UACPI_OBJECT_INTEGER
Definition: types.h:112
Definition: parser.c:44

Referenced by field_get_read_type().

◆ buffer_index_cursor()

static uacpi_u8 * buffer_index_cursor ( uacpi_buffer_index buf_idx)
static

Definition at line 953 of file interpreter.c.

954{
955 uacpi_u8 *out_cursor;
956
957 out_cursor = buf_idx->buffer->data;
958 out_cursor += buf_idx->idx;
959
960 return out_cursor;
961}
uint8_t uacpi_u8
Definition: types.h:19
uacpi_buffer * buffer
Definition: types.h:49
uacpi_size idx
Definition: types.h:48
void * data
Definition: types.h:27

Referenced by debug_store_no_recurse(), handle_deref_of(), handle_inc_dec(), and write_buffer_index().

◆ buffer_to_string()

static uacpi_status buffer_to_string ( uacpi_buffer buf,
uacpi_buffer str,
uacpi_bool  is_hex 
)
static

Definition at line 2733 of file interpreter.c.

2736{
2737 int repr_len;
2738 uacpi_char int_buf[5];
2739 uacpi_size i, final_size;
2741
2742 if (is_hex) {
2743 final_size = 4 * buf->size;
2744 } else {
2745 final_size = 0;
2746
2747 for (i = 0; i < buf->size; ++i) {
2748 uacpi_u8 value = ((uacpi_u8*)buf->data)[i];
2749
2750 if (value < 10)
2751 final_size += 1;
2752 else if (value < 100)
2753 final_size += 2;
2754 else
2755 final_size += 3;
2756 }
2757 }
2758
2759 // Comma for every value but one
2760 final_size += buf->size - 1;
2761
2762 // Null terminator
2763 final_size += 1;
2764
2765 str->data = uacpi_kernel_alloc(final_size);
2766 if (uacpi_unlikely(str->data == UACPI_NULL))
2768
2769 cursor = str->data;
2770
2771 for (i = 0; i < buf->size; ++i) {
2772 repr_len = uacpi_snprintf(
2773 int_buf, sizeof(int_buf),
2774 is_hex ? "0x%02X" : "%d",
2775 ((uacpi_u8*)buf->data)[i]
2776 );
2777 if (uacpi_unlikely(repr_len < 0)) {
2778 uacpi_free(str->data, final_size);
2779 str->data = UACPI_NULL;
2781 }
2782
2783 uacpi_memcpy(cursor, int_buf, repr_len + 1);
2784 cursor += repr_len;
2785
2786 if (i != buf->size - 1)
2787 *cursor++ = ',';
2788 }
2789
2790 str->size = final_size;
2791 return UACPI_STATUS_OK;
2792}
uacpi_i32 uacpi_snprintf(uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt,...)
Definition: stdlib.c:684
#define uacpi_memcpy
Definition: stdlib.h:34
#define uacpi_free(mem, _)
Definition: stdlib.h:96
size_t uacpi_size
Definition: types.h:37
char uacpi_char
Definition: types.h:44
#define is_hex(c)
Definition: registry.c:430
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char cursor[]
Definition: icontest.c:13
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
const WCHAR * str
Definition: pdh_main.c:96

Referenced by handle_concatenate(), and handle_to().

◆ build_table_id()

static uacpi_status build_table_id ( const uacpi_char opcode,
struct uacpi_table_identifiers out_id,
uacpi_buffer signature,
uacpi_buffer oem_id,
uacpi_buffer oem_table_id 
)
static

Definition at line 1192 of file interpreter.c.

1198{
1199 if (uacpi_unlikely(signature->size != (sizeof(uacpi_object_name) + 1)))
1200 return table_id_error(opcode, "SignatureString", signature);
1201
1202 uacpi_memcpy(out_id->signature.text, signature->text,
1203 sizeof(uacpi_object_name));
1204
1205 if (uacpi_unlikely(oem_id->size > (sizeof(out_id->oemid) + 1)))
1206 return table_id_error(opcode, "OemIDString", oem_id);
1207
1209 out_id->oemid, oem_id->text,
1210 sizeof(out_id->oemid), oem_id->size ? oem_id->size - 1 : 0
1211 );
1212
1213 if (uacpi_unlikely(oem_table_id->size > (sizeof(out_id->oem_table_id) + 1)))
1214 return table_id_error(opcode, "OemTableIDString", oem_table_id);
1215
1217 out_id->oem_table_id, oem_table_id->text,
1218 sizeof(out_id->oem_table_id),
1219 oem_table_id->size ? oem_table_id->size - 1 : 0
1220 );
1221
1222 return UACPI_STATUS_OK;
1223}
void uacpi_memcpy_zerout(void *dst, const void *src, uacpi_size dst_size, uacpi_size src_size)
Definition: stdlib.c:112
static uacpi_status table_id_error(const uacpi_char *opcode, const uacpi_char *arg, uacpi_buffer *str)
Definition: interpreter.c:1170
uacpi_size size
Definition: types.h:31
uacpi_char * text
Definition: types.h:29
uacpi_object_name signature
Definition: tables.h:16
char oem_table_id[8]
Definition: tables.h:22
uacpi_char text[4]
Definition: types.h:24

Referenced by handle_create_data_region(), and handle_load_table().

◆ call_frame_clear()

static void call_frame_clear ( struct call_frame frame)
static

Definition at line 4631 of file interpreter.c.

4632{
4633 uacpi_size i;
4634 op_context_array_clear(&frame->pending_ops);
4635 code_block_array_clear(&frame->code_blocks);
4636
4637 while (temp_namespace_node_array_size(&frame->temp_nodes) != 0) {
4639
4640 node = *temp_namespace_node_array_last(&frame->temp_nodes);
4642 temp_namespace_node_array_pop(&frame->temp_nodes);
4643 }
4644 temp_namespace_node_array_clear(&frame->temp_nodes);
4645
4646 for (i = 0; i < 7; ++i)
4647 uacpi_object_unref(frame->args[i]);
4648 for (i = 0; i < 8; ++i)
4649 uacpi_object_unref(frame->locals[i]);
4650
4651 uacpi_method_unref(frame->method);
4652}
uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node)
Definition: namespace.c:349
void uacpi_method_unref(uacpi_control_method *)
Definition: types.c:655
void uacpi_object_unref(uacpi_object *obj)
Definition: types.c:762
uacpi_object * locals[8]
Definition: interpreter.c:271
struct temp_namespace_node_array temp_nodes
Definition: interpreter.c:275
struct op_context_array pending_ops
Definition: interpreter.c:273
uacpi_object * args[7]
Definition: interpreter.c:270
struct uacpi_control_method * method
Definition: interpreter.c:268
Definition: dlist.c:348

Referenced by ctx_reload_post_ret(), and prepare_method_call().

◆ call_frame_code_bytes_left()

static uacpi_size call_frame_code_bytes_left ( struct call_frame frame)
static

Definition at line 296 of file interpreter.c.

297{
298 return frame->method->size - frame->code_offset;
299}

Referenced by call_frame_has_code(), exec_op(), handle_string(), parse_package_length(), and resolve_name_string().

◆ call_frame_cursor()

static void * call_frame_cursor ( struct call_frame frame)
static

Definition at line 291 of file interpreter.c.

292{
293 return frame->method->code + frame->code_offset;
294}

Referenced by exec_op(), handle_string(), parse_package_length(), peek_next_op(), and resolve_name_string().

◆ call_frame_has_code()

static uacpi_bool call_frame_has_code ( struct call_frame frame)
static

Definition at line 301 of file interpreter.c.

302{
303 return call_frame_code_bytes_left(frame) > 0;
304}
static uacpi_size call_frame_code_bytes_left(struct call_frame *frame)
Definition: interpreter.c:296

Referenced by uacpi_execute_control_method().

◆ copy_object_to_reference()

static uacpi_status copy_object_to_reference ( uacpi_object dst,
uacpi_object src 
)
static

Definition at line 2319 of file interpreter.c.

2321{
2323 uacpi_object *src_obj, *new_obj;
2324
2325 switch (dst->flags) {
2327 uacpi_object *referenced_obj;
2328
2329 referenced_obj = uacpi_unwrap_internal_reference(dst);
2330 if (referenced_obj->type == UACPI_OBJECT_REFERENCE) {
2331 dst = reference_unwind(referenced_obj);
2332 break;
2333 }
2334
2336 }
2340 break;
2341 default:
2343 }
2344
2346
2348 if (uacpi_unlikely(new_obj == UACPI_NULL))
2350
2351 ret = uacpi_object_assign(new_obj, src_obj,
2354 return ret;
2355
2356 object_replace_child(dst, new_obj);
2357 uacpi_object_unref(new_obj);
2358
2359 return UACPI_STATUS_OK;
2360}
uacpi_object * uacpi_create_object(uacpi_object_type type)
Definition: types.c:327
@ UACPI_REFERENCE_KIND_LOCAL
Definition: types.h:12
@ UACPI_REFERENCE_KIND_ARG
Definition: types.h:13
@ UACPI_REFERENCE_KIND_PKG_INDEX
Definition: types.h:15
@ UACPI_REFERENCE_KIND_NAMED
Definition: types.h:14
uacpi_status uacpi_object_assign(uacpi_object *dst, uacpi_object *src, enum uacpi_assign_behavior)
Definition: types.c:1372
@ UACPI_ASSIGN_BEHAVIOR_DEEP_COPY
Definition: types.h:276
uacpi_object * uacpi_unwrap_internal_reference(uacpi_object *object)
Definition: types.c:1486
#define UACPI_FALLTHROUGH
Definition: compiler.h:100
#define uacpi_unlikely_error(expr)
Definition: status.h:49
uacpi_status
Definition: status.h:10
@ UACPI_OBJECT_UNINITIALIZED
Definition: types.h:111
@ UACPI_OBJECT_REFERENCE
Definition: types.h:128
static uacpi_object * reference_unwind(uacpi_object *obj)
Definition: interpreter.c:2255
static void object_replace_child(uacpi_object *parent, uacpi_object *new_child)
Definition: interpreter.c:2286
return ret
Definition: mutex.c:147
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
uacpi_u8 type
Definition: types.h:249

Referenced by handle_copy_object_or_store().

◆ create_named_scope()

static uacpi_status create_named_scope ( struct op_context op_ctx)
static

Definition at line 4159 of file interpreter.c.

4160{
4163
4164 node = item_array_at(&op_ctx->items, 1)->node;
4165 obj = item_array_last(&op_ctx->items)->obj;
4166
4167 switch (op_ctx->op->code) {
4168 case UACPI_AML_OP_ProcessorOp: {
4169 uacpi_processor *proc = obj->processor;
4170 proc->id = item_array_at(&op_ctx->items, 2)->immediate;
4171 proc->block_address = item_array_at(&op_ctx->items, 3)->immediate;
4172 proc->block_length = item_array_at(&op_ctx->items, 4)->immediate;
4173 break;
4174 }
4175
4176 case UACPI_AML_OP_PowerResOp: {
4177 uacpi_power_resource *power_res = &obj->power_resource;
4178 power_res->system_level = item_array_at(&op_ctx->items, 2)->immediate;
4179 power_res->resource_order = item_array_at(&op_ctx->items, 3)->immediate;
4180 break;
4181 }
4182
4183 default:
4184 break;
4185 }
4186
4188 obj);
4189 if (uacpi_unlikely(node->object == UACPI_NULL))
4191
4192 return UACPI_STATUS_OK;
4193}
struct uacpi_object * uacpi_create_internal_reference(enum uacpi_reference_kind kind, uacpi_object *child)
Definition: types.c:1471
static HANDLE proc()
Definition: pdb.c:32
uacpi_u8 system_level
Definition: types.h:159
uacpi_u16 resource_order
Definition: types.h:160

Referenced by handle_code_block().

◆ ctx_has_non_preempted_op()

static uacpi_bool ctx_has_non_preempted_op ( struct execution_context ctx)
static

Definition at line 4266 of file interpreter.c.

4267{
4268 return ctx->cur_op_ctx && !ctx->cur_op_ctx->preempted;
4269}

Referenced by exec_op(), and uacpi_execute_control_method().

◆ ctx_reload_post_ret()

static void ctx_reload_post_ret ( struct execution_context ctx)
static

Definition at line 6011 of file interpreter.c.

6012{
6013 uacpi_control_method *method = ctx->cur_frame->method;
6014
6015 if (method->is_serialized) {
6017 &ctx->held_mutexes, method->mutex, FORCE_RELEASE_YES
6018 );
6019 ctx->sync_level = ctx->cur_frame->prev_sync_level;
6020 }
6021
6022 call_frame_clear(ctx->cur_frame);
6023 call_frame_array_pop(&ctx->call_stack);
6024
6025 ctx->cur_frame = call_frame_array_last(&ctx->call_stack);
6027}
method
Definition: dragdrop.c:54
static uacpi_status held_mutexes_array_remove_and_release(struct held_mutexes_array *arr, uacpi_mutex *mutex, enum force_release force)
Definition: interpreter.c:185
static void call_frame_clear(struct call_frame *frame)
Definition: interpreter.c:4631
static void refresh_ctx_pointers(struct execution_context *ctx)
Definition: interpreter.c:4250

Referenced by stack_unwind(), and uacpi_execute_control_method().

◆ debug_store()

static uacpi_status debug_store ( uacpi_object src)
static

Definition at line 2222 of file interpreter.c.

2223{
2224 /*
2225 * Don't bother running the body if current log level is not set to trace.
2226 * All DebugOp logging is done as TRACE exclusively.
2227 */
2229 return UACPI_STATUS_OK;
2230
2232
2233 debug_store_no_recurse("[AML DEBUG]", src);
2234
2235 if (src->type == UACPI_OBJECT_PACKAGE) {
2236 uacpi_package *pkg = src->package;
2237 uacpi_size i;
2238
2239 for (i = 0; i < pkg->count; ++i) {
2240 uacpi_object *obj = pkg->objects[i];
2241 if (obj->type == UACPI_OBJECT_REFERENCE &&
2243 obj = obj->inner_object;
2244
2245 debug_store_no_recurse("Element:", obj);
2246 }
2247 }
2248
2249 return UACPI_STATUS_OK;
2250}
static uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
Definition: context.h:95
@ UACPI_LOG_TRACE
Definition: log.h:18
@ UACPI_OBJECT_PACKAGE
Definition: types.h:115
static void debug_store_no_recurse(const uacpi_char *prefix, uacpi_object *src)
Definition: interpreter.c:2139
uacpi_object ** objects
Definition: types.h:36
uacpi_size count
Definition: types.h:37

Referenced by store_to_target().

◆ debug_store_no_recurse()

static void debug_store_no_recurse ( const uacpi_char prefix,
uacpi_object src 
)
static

Definition at line 2139 of file interpreter.c.

2140{
2141 switch (src->type) {
2143 uacpi_trace("%s Uninitialized", prefix);
2144 break;
2146 uacpi_trace("%s String => \"%s\"", prefix, src->buffer->text);
2147 break;
2149 if (g_uacpi_rt_ctx.is_rev1) {
2151 "%s Integer => 0x%08X", prefix, (uacpi_u32)src->integer
2152 );
2153 } else {
2155 "%s Integer => 0x%016"UACPI_PRIX64, prefix,
2156 UACPI_FMT64(src->integer)
2157 );
2158 }
2159 break;
2161 uacpi_trace("%s Reference @%p => %p", prefix, src, src->inner_object);
2162 break;
2165 "%s Package @%p (%p) (%zu elements)",
2166 prefix, src, src->package, src->package->count
2167 );
2168 break;
2171 "%s Buffer @%p (%p) (%zu bytes)",
2172 prefix, src, src->buffer, src->buffer->size
2173 );
2174 break;
2177 "%s OperationRegion (ASID %d) 0x%016"UACPI_PRIX64
2178 " -> 0x%016"UACPI_PRIX64, prefix,
2179 src->op_region->space, UACPI_FMT64(src->op_region->offset),
2180 UACPI_FMT64(src->op_region->offset + src->op_region->length)
2181 );
2182 break;
2185 "%s Power Resource %d %d",
2186 prefix, src->power_resource.system_level,
2187 src->power_resource.resource_order
2188 );
2189 break;
2192 "%s Processor[%d] 0x%08X (%d)",
2193 prefix, src->processor->id, src->processor->block_address,
2194 src->processor->block_length
2195 );
2196 break;
2199 "%s Buffer Index %p[%zu] => 0x%02X",
2200 prefix, src->buffer_index.buffer->data, src->buffer_index.idx,
2201 *buffer_index_cursor(&src->buffer_index)
2202 );
2203 break;
2204 case UACPI_OBJECT_MUTEX:
2206 "%s Mutex @%p (%p => %p) sync level %d",
2207 prefix, src, src->mutex, src->mutex->handle,
2208 src->mutex->sync_level
2209 );
2210 break;
2212 uacpi_trace("%s Method @%p (%p)", prefix, src, src->method);
2213 break;
2214 default:
2216 "%s %s @%p",
2218 );
2219 }
2220}
#define uacpi_trace(...)
Definition: log.h:33
#define UACPI_PRIX64
Definition: types.h:61
uint32_t uacpi_u32
Definition: types.h:21
#define UACPI_FMT64(val)
Definition: types.h:62
const uacpi_char * uacpi_object_type_to_string(uacpi_object_type)
Definition: types.c:51
@ UACPI_OBJECT_METHOD
Definition: types.h:119
@ UACPI_OBJECT_STRING
Definition: types.h:113
@ UACPI_OBJECT_PROCESSOR
Definition: types.h:123
@ UACPI_OBJECT_POWER_RESOURCE
Definition: types.h:122
@ UACPI_OBJECT_MUTEX
Definition: types.h:120
@ UACPI_OBJECT_OPERATION_REGION
Definition: types.h:121
@ UACPI_OBJECT_BUFFER_INDEX
Definition: types.h:129
static uacpi_u8 * buffer_index_cursor(uacpi_buffer_index *buf_idx)
Definition: interpreter.c:953
Character const *const prefix
Definition: tempnam.cpp:195

Referenced by debug_store().

◆ do_binary_math()

static uacpi_status do_binary_math ( uacpi_object arg0,
uacpi_object arg1,
uacpi_object tgt0,
uacpi_object tgt1,
uacpi_aml_op  op 
)
static

Definition at line 2452 of file interpreter.c.

2457{
2458 uacpi_u64 lhs, rhs, res;
2459 uacpi_bool should_negate = UACPI_FALSE;
2460
2461 lhs = arg0->integer;
2462 rhs = arg1->integer;
2463
2464 switch (op)
2465 {
2466 case UACPI_AML_OP_AddOp:
2467 res = lhs + rhs;
2468 break;
2469 case UACPI_AML_OP_SubtractOp:
2470 res = lhs - rhs;
2471 break;
2472 case UACPI_AML_OP_MultiplyOp:
2473 res = lhs * rhs;
2474 break;
2475 case UACPI_AML_OP_ShiftLeftOp:
2476 case UACPI_AML_OP_ShiftRightOp:
2477 if (rhs <= (g_uacpi_rt_ctx.is_rev1 ? 31 : 63)) {
2478 if (op == UACPI_AML_OP_ShiftLeftOp)
2479 res = lhs << rhs;
2480 else
2481 res = lhs >> rhs;
2482 } else {
2483 res = 0;
2484 }
2485 break;
2486 case UACPI_AML_OP_NandOp:
2487 should_negate = UACPI_TRUE;
2489 case UACPI_AML_OP_AndOp:
2490 res = rhs & lhs;
2491 break;
2492 case UACPI_AML_OP_NorOp:
2493 should_negate = UACPI_TRUE;
2495 case UACPI_AML_OP_OrOp:
2496 res = rhs | lhs;
2497 break;
2498 case UACPI_AML_OP_XorOp:
2499 res = rhs ^ lhs;
2500 break;
2501 case UACPI_AML_OP_DivideOp:
2502 if (uacpi_unlikely(rhs == 0)) {
2503 uacpi_error("attempted to divide by zero");
2505 }
2506 tgt1->integer = lhs / rhs;
2507 res = lhs % rhs;
2508 break;
2509 case UACPI_AML_OP_ModOp:
2510 if (uacpi_unlikely(rhs == 0)) {
2511 uacpi_error("attempted to calculate modulo of zero");
2513 }
2514 res = lhs % rhs;
2515 break;
2516 default:
2518 }
2519
2520 if (should_negate)
2521 res = ~res;
2522
2523 tgt0->integer = res;
2524 return UACPI_STATUS_OK;
2525}
UINT op
Definition: effect.c:236
bool uacpi_bool
Definition: types.h:31
#define UACPI_FALSE
Definition: types.h:30
#define UACPI_TRUE
Definition: types.h:29
@ UACPI_STATUS_AML_BAD_ENCODING
Definition: status.h:39
GLuint res
Definition: glext.h:9613
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
uacpi_u64 integer
Definition: types.h:253

Referenced by handle_binary_math().

◆ do_install_node_item()

static uacpi_status do_install_node_item ( struct call_frame frame,
struct item item 
)
static

Definition at line 640 of file interpreter.c.

642{
644
647 return ret;
648
649 if (!frame->method->named_objects_persist)
650 ret = temp_namespace_node_array_push(&frame->temp_nodes, item->node);
651
654
655 return ret;
656}
uacpi_status uacpi_namespace_node_install(uacpi_namespace_node *parent, uacpi_namespace_node *node)
Definition: namespace.c:299
#define uacpi_likely_success(expr)
Definition: status.h:53
struct uacpi_namespace_node * node
Definition: interpreter.c:42

Referenced by exec_op(), and handle_create_field().

◆ do_load_table()

static uacpi_status do_load_table ( uacpi_namespace_node parent,
struct acpi_sdt_hdr *  tbl,
enum uacpi_table_load_cause  cause 
)
static

Definition at line 1304 of file interpreter.c.

1308{
1309 struct uacpi_control_method method = { 0 };
1311
1312 ret = prepare_table_load(tbl, cause, &method);
1314 return ret;
1315
1318 return ret;
1319
1320 if (is_dynamic_table_load(cause))
1322
1323 return ret;
1324}
void uacpi_events_match_post_dynamic_table_load(void)
Definition: event.c:970
static uacpi_status prepare_table_load(void *ptr, enum uacpi_table_load_cause cause, uacpi_control_method *in_method)
Definition: interpreter.c:1274
uacpi_status uacpi_execute_control_method(uacpi_namespace_node *scope, uacpi_control_method *method, const uacpi_object_array *args, uacpi_object **out_obj)
Definition: interpreter.c:6150
static uacpi_bool is_dynamic_table_load(enum uacpi_table_load_cause cause)
Definition: interpreter.c:1269
r parent
Definition: btrfs.c:3010

Referenced by uacpi_execute_table().

◆ do_make_empty_object()

static uacpi_status do_make_empty_object ( uacpi_buffer buf,
uacpi_bool  is_string 
)
static

Definition at line 2794 of file interpreter.c.

2796{
2797 buf->text = uacpi_kernel_alloc_zeroed(sizeof(uacpi_char));
2798 if (uacpi_unlikely(buf->text == UACPI_NULL))
2800
2801 if (is_string)
2802 buf->size = sizeof(uacpi_char);
2803
2804 return UACPI_STATUS_OK;
2805}
#define uacpi_kernel_alloc_zeroed
Definition: stdlib.h:127
static BOOL is_string(parse_buffer *buf)
Definition: parsing.c:600

Referenced by make_null_buffer(), and make_null_string().

◆ DYNAMIC_ARRAY_WITH_INLINE_STORAGE()

DYNAMIC_ARRAY_WITH_INLINE_STORAGE ( DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL temp_namespace_node_array,
uacpi_namespace_node ,
 
)

Definition at line 247 of file interpreter.c.

256{
258
259 slot = temp_namespace_node_array_alloc(arr);
262
263 *slot = node;
264 return UACPI_STATUS_OK;
265}
Definition: vfat.h:185
struct _slot slot
Definition: vfat.h:196

◆ DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL() [1/3]

DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL ( call_frame_array  ,
struct call_frame  ,
static   
)

Definition at line 307 of file interpreter.c.

314{
316
317 size = call_frame_array_size(arr);
318
319 if (size < 2)
320 return UACPI_NULL;
321
322 return call_frame_array_at(arr, size - 2);
323}
GLsizeiptr size
Definition: glext.h:5919

◆ DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL() [2/3]

DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL ( code_block_array  ,
struct code_block  ,
static   
)

Definition at line 104 of file interpreter.c.

116{
118
119 slot = held_mutexes_array_alloc(arr);
122
123 *slot = mutex;
125 return UACPI_STATUS_OK;
126}
uacpi_u32 uacpi_shareable_ref(uacpi_handle)
Definition: shareable.c:31
Definition: module.h:456

◆ DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL() [3/3]

DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL ( op_context_array  ,
struct op_context  ,
static   
)

Definition at line 69 of file interpreter.c.

76{
78
79 size = op_context_array_size(arr);
80
81 if (size < 2)
82 return UACPI_NULL;
83
84 return op_context_array_at(arr, size - 2);
85}

◆ emit_op_skip_warn()

static void emit_op_skip_warn ( const struct op_context op_ctx)
static

Definition at line 4899 of file interpreter.c.

4900{
4901 EXEC_OP_WARN("skipping due to previous errors");
4902}
#define EXEC_OP_WARN(reason)
Definition: interpreter.c:4732

Referenced by exec_op().

◆ ensure_is_a_field_unit()

static uacpi_status ensure_is_a_field_unit ( uacpi_namespace_node node,
uacpi_field_unit **  out_field 
)
static

Definition at line 1639 of file interpreter.c.

1641{
1643
1645 if (obj->type != UACPI_OBJECT_FIELD_UNIT) {
1647 "invalid argument: '%.4s' is not a field unit (%s)",
1648 node->name.text, uacpi_object_type_to_string(obj->type)
1649 );
1651 }
1652
1653 *out_field = obj->field_unit;
1654 return UACPI_STATUS_OK;
1655}
uacpi_object * uacpi_namespace_node_get_object(const uacpi_namespace_node *node)
Definition: namespace.c:646
@ UACPI_STATUS_AML_INCOMPATIBLE_OBJECT_TYPE
Definition: status.h:38
@ UACPI_OBJECT_FIELD_UNIT
Definition: types.h:116

Referenced by handle_create_field().

◆ ensure_is_an_op_region()

static uacpi_status ensure_is_an_op_region ( uacpi_namespace_node node,
uacpi_namespace_node **  out_node 
)
static

Definition at line 1657 of file interpreter.c.

1659{
1661
1663 if (obj->type != UACPI_OBJECT_OPERATION_REGION) {
1665 "invalid argument: '%.4s' is not an operation region (%s)",
1666 node->name.text, uacpi_object_type_to_string(obj->type)
1667 );
1669 }
1670
1671 *out_node = node;
1672 return UACPI_STATUS_OK;
1673}

Referenced by handle_create_field().

◆ ensure_valid_idx()

static uacpi_status ensure_valid_idx ( uacpi_object obj,
uacpi_size  idx,
uacpi_size  src_size 
)
static

Definition at line 2574 of file interpreter.c.

2576{
2577 if (uacpi_likely(idx < src_size))
2578 return UACPI_STATUS_OK;
2579
2581 "invalid index %zu, %s@%p has %zu elements",
2582 idx, uacpi_object_type_to_string(obj->type), obj, src_size
2583 );
2585}
unsigned int idx
Definition: utils.c:41
#define uacpi_likely(expr)
Definition: compiler.h:89
@ UACPI_STATUS_AML_OUT_OF_BOUNDS_INDEX
Definition: status.h:40

Referenced by handle_index().

◆ enter_method()

static uacpi_status enter_method ( struct execution_context ctx,
struct call_frame new_frame,
uacpi_control_method method 
)
static

Definition at line 4541 of file interpreter.c.

4545{
4547
4549
4550 if (!method->is_serialized)
4551 return ret;
4552
4553 if (uacpi_unlikely(ctx->sync_level > method->sync_level)) {
4555 "cannot invoke method @%p, sync level %d is too low "
4556 "(current is %d)",
4557 method, method->sync_level, ctx->sync_level
4558 );
4560 }
4561
4562 if (method->mutex == UACPI_NULL) {
4563 method->mutex = uacpi_create_mutex();
4564 if (uacpi_unlikely(method->mutex == UACPI_NULL))
4566 method->mutex->sync_level = method->sync_level;
4567 }
4568
4570 ret = uacpi_acquire_aml_mutex(method->mutex, 0xFFFF);
4572 return ret;
4573
4574 ret = held_mutexes_array_push(&ctx->held_mutexes, method->mutex);
4577 return ret;
4578 }
4579 }
4580
4581 new_frame->prev_sync_level = ctx->sync_level;
4582 ctx->sync_level = method->sync_level;
4583 return UACPI_STATUS_OK;
4584}
uacpi_status uacpi_acquire_aml_mutex(uacpi_mutex *, uacpi_u16 timeout)
Definition: mutex.c:202
uacpi_status uacpi_release_aml_mutex(uacpi_mutex *)
Definition: mutex.c:242
uacpi_bool uacpi_this_thread_owns_aml_mutex(uacpi_mutex *)
Definition: mutex.c:194
uacpi_mutex * uacpi_create_mutex(void)
Definition: types.c:181
@ UACPI_STATUS_AML_SYNC_LEVEL_TOO_HIGH
Definition: status.h:41
uacpi_u8 prev_sync_level
Definition: interpreter.c:288

Referenced by prepare_method_call().

◆ exec_op()

static uacpi_status exec_op ( struct execution_context ctx)
static

Definition at line 5335 of file interpreter.c.

5336{
5338 struct call_frame *frame = ctx->cur_frame;
5339 struct op_context *op_ctx;
5340 struct item *item = UACPI_NULL;
5341 enum uacpi_parse_op prev_op = 0, op;
5342
5343 /*
5344 * Allocate a new op context if previous is preempted (looking for a
5345 * dynamic argument), or doesn't exist at all.
5346 */
5348 ret = push_op(ctx);
5350 return ret;
5351 } else {
5352 trace_op(ctx->cur_op_ctx->op, OP_TRACE_ACTION_RESUME);
5353 }
5354
5355 if (ctx->prev_op_ctx)
5356 prev_op = *op_decode_cursor(ctx->prev_op_ctx);
5357
5358 for (;;) {
5360 return ret;
5361
5362 op_ctx = ctx->cur_op_ctx;
5363 frame = ctx->cur_frame;
5364
5365 if (op_ctx->pc == 0 && ctx->prev_op_ctx) {
5366 /*
5367 * Type check the current arg type against what is expected by the
5368 * preempted op. This check is able to catch most type violations
5369 * with the only exception being Operand as we only know whether
5370 * that evaluates to an integer after the fact.
5371 */
5372 ret = op_typecheck(ctx->prev_op_ctx, ctx->cur_op_ctx);
5374 return ret;
5375 }
5376
5377 op = op_decode_byte(op_ctx);
5378 trace_pop(op);
5379
5381 item = item_array_alloc(&op_ctx->items);
5384
5386 if (item->type == ITEM_OBJECT) {
5388
5390 type = op_decode_byte(op_ctx);
5391
5395 } else {
5397 }
5398 } else if (item == UACPI_NULL) {
5399 item = item_array_last(&op_ctx->items);
5400 }
5401
5402 switch (op) {
5403 case UACPI_PARSE_OP_END:
5405 trace_op(ctx->cur_op_ctx->op, OP_TRACE_ACTION_END);
5406
5408 uacpi_u8 idx;
5409
5410 idx = op_decode_byte(op_ctx);
5411 if (item_array_at(&op_ctx->items, idx)->handle != UACPI_NULL)
5412 break;
5413
5414 emit_op_skip_warn(op_ctx);
5415 }
5416
5417 apply_tracked_pkg(frame, op_ctx);
5418
5419 pop_op(ctx);
5420 if (ctx->cur_op_ctx) {
5421 ctx->cur_op_ctx->preempted = UACPI_FALSE;
5422 ctx->cur_op_ctx->pc++;
5423 }
5424
5425 return UACPI_STATUS_OK;
5426 }
5427
5429 emit_op_skip_warn(op_ctx);
5430 break;
5431
5443 /*
5444 * Preempt this op parsing for now as we wait for the dynamic arg
5445 * to be parsed.
5446 */
5447 op_ctx->preempted = UACPI_TRUE;
5448 op_ctx->pc--;
5449 return UACPI_STATUS_OK;
5450
5452 op_ctx->tracked_pkg_idx = item_array_size(&op_ctx->items);
5455 ret = parse_package_length(frame, &item->pkg);
5456 break;
5457
5460 void *dst;
5461 uacpi_u8 src_width;
5462
5465 dst = &item->obj->integer;
5466 src_width = 8;
5467 } else {
5468 dst = &item->immediate;
5469 src_width = op_decode_byte(op_ctx);
5470 }
5471
5473 dst, op_decode_cursor(op_ctx),
5474 sizeof(uacpi_u64), src_width
5475 );
5476 op_ctx->pc += src_width;
5477 break;
5478 }
5479
5481 break;
5482
5486 void *dst;
5487
5488 width = op_decode_byte(op_ctx);
5491
5494 item->obj->integer = 0;
5495 dst = &item->obj->integer;
5496 } else {
5498 }
5499
5501 frame->code_offset += width;
5502 break;
5503 }
5504
5508 obj->type = UACPI_OBJECT_INTEGER;
5509 obj->integer = op == UACPI_PARSE_OP_LOAD_FALSE_OBJECT ? 0 : ones();
5510 break;
5511 }
5512
5514 item->immediate = frame->code_offset;
5515 break;
5516
5519 break;
5520
5522 uacpi_object_type expected_type;
5523
5524 expected_type = op_decode_byte(op_ctx);
5525
5526 if (uacpi_unlikely(item->obj->type != expected_type)) {
5527 EXEC_OP_ERR_2("bad object type: expected %s, got %s!",
5528 uacpi_object_type_to_string(expected_type),
5531 }
5532
5533 break;
5534 }
5535
5537 uacpi_object_type_bits expected_mask = 0;
5538 uacpi_bool one_of;
5540 uacpi_u8 num_types, i;
5541
5542 num_types = op_decode_byte(op_ctx);
5543 for (i = 0; i < num_types; i++) {
5544 type = op_decode_byte(op_ctx);
5545 if (i < UACPI_ARRAY_SIZE(types))
5546 types[i] = type;
5547
5548 expected_mask |= 1u << type;
5549 }
5550
5551 one_of = uacpi_object_is_one_of(item->obj, expected_mask);
5552 if (uacpi_likely(one_of))
5553 break;
5554
5556
5557 if (i == 2) {
5559 "bad object type: expected one of %s/%s, got %s!",
5563 );
5564 break;
5565 }
5566
5568 "bad object type: expected one of 0x%08X, got %s!",
5569 expected_mask, uacpi_object_type_to_string(item->obj->type)
5570 );
5571 break;
5572 }
5573
5575 frame->code_offset--;
5576 break;
5577
5579 item_array_at(&op_ctx->items, op_decode_byte(op_ctx))->immediate--;
5580 break;
5581
5583 pop_item(op_ctx);
5584 item = item_array_last(&op_ctx->items);
5585 break;
5586
5588 uacpi_size pkg_idx = op_ctx->tracked_pkg_idx - 1;
5589 struct package_length *pkg;
5590 uacpi_u8 bytes_skip;
5591
5592 bytes_skip = op_decode_byte(op_ctx);
5593 pkg = &item_array_at(&op_ctx->items, pkg_idx)->pkg;
5594
5595 if (frame->code_offset >= pkg->end)
5596 op_ctx->pc += bytes_skip;
5597
5598 break;
5599 }
5600
5605 uacpi_u8 idx, bytes_skip;
5606 uacpi_bool is_null, skip_if_null;
5607
5611 } else {
5612 idx = op_decode_byte(op_ctx);
5613 is_null = item_array_at(&op_ctx->items, idx)->handle == UACPI_NULL;
5614 }
5615
5616 bytes_skip = op_decode_byte(op_ctx);
5617 skip_if_null = op == UACPI_PARSE_OP_IF_NOT_NULL ||
5619
5620 if (is_null == skip_if_null)
5621 op_ctx->pc += bytes_skip;
5622
5623 break;
5624 }
5625
5627 uacpi_u8 value, bytes_skip;
5628
5629 value = op_decode_byte(op_ctx);
5630 bytes_skip = op_decode_byte(op_ctx);
5631
5632 if (item->immediate != value)
5633 op_ctx->pc += bytes_skip;
5634
5635 break;
5636 }
5637
5640 uacpi_u8 bytes_skip;
5641 uacpi_bool is_false, skip_if_false;
5642
5643 bytes_skip = op_decode_byte(op_ctx);
5644 is_false = item->obj->integer == 0;
5645 skip_if_false = op == UACPI_PARSE_OP_IF_LAST_TRUE;
5646
5647 if (is_false == skip_if_false)
5648 op_ctx->pc += bytes_skip;
5649
5650 break;
5651 }
5652
5653 case UACPI_PARSE_OP_JMP: {
5654 op_ctx->pc = op_decode_byte(op_ctx);
5655 break;
5656 }
5657
5663 uacpi_size offset = frame->code_offset;
5664 enum resolve_behavior behavior;
5665
5669 else
5671
5672 ret = resolve_name_string(frame, behavior, &item->node);
5673
5674 if (ret == UACPI_STATUS_NOT_FOUND) {
5675 uacpi_bool is_ok;
5676
5677 if (prev_op) {
5678 is_ok = op_allows_unresolved(prev_op);
5679 is_ok &= op_allows_unresolved(op);
5680 } else {
5681 // This is the only standalone op where we allow unresolved
5682 is_ok = op_ctx->op->code == UACPI_AML_OP_ExternalOp;
5683 }
5684
5685 if (is_ok)
5687 }
5688
5691 uacpi_status trace_ret = ret;
5692 uacpi_bool abort_whileif = UACPI_FALSE;
5693
5694 if (frame->method->named_objects_persist &&
5697 struct op_context *first_ctx;
5698
5699 first_ctx = op_context_array_at(&frame->pending_ops, 0);
5700 abort_whileif = first_ctx->op->code == UACPI_AML_OP_WhileOp ||
5701 first_ctx->op->code == UACPI_AML_OP_IfOp;
5702
5703 if (op_allows_unresolved_if_load(op) || abort_whileif) {
5704 lvl = UACPI_LOG_WARN;
5706 }
5707 }
5708
5710 frame, offset, op, trace_ret, lvl
5711 );
5712
5713 if (abort_whileif) {
5714 while (op_context_array_size(&frame->pending_ops) != 1)
5715 pop_op(ctx);
5716
5717 op_ctx = op_context_array_at(&frame->pending_ops, 0);
5718 op_ctx->pc++;
5719 op_ctx->preempted = UACPI_FALSE;
5720 break;
5721 }
5722
5725 }
5726
5728 !frame->method->named_objects_persist)
5730
5731 break;
5732 }
5733
5735 uacpi_aml_op code = op_ctx->op->code;
5736 uacpi_u8 idx;
5737
5738 if (code <= 0xFF)
5740 else
5742
5743 ret = op_handlers[idx](ctx);
5744 break;
5745 }
5746
5748 item = item_array_at(&op_ctx->items, op_decode_byte(op_ctx));
5749 ret = do_install_node_item(frame, item);
5751 uacpi_object_unref(item->node->object);
5752 item->node->object = UACPI_NULL;
5753 }
5754 break;
5755
5759 struct item *dst;
5760
5761 if (!ctx->prev_op_ctx)
5762 break;
5763
5764 switch (prev_op) {
5770
5771 if (prev_op == UACPI_PARSE_OP_OPERAND)
5772 ret = typecheck_operand(ctx->prev_op_ctx, src);
5773 else if (prev_op == UACPI_PARSE_OP_STRING)
5774 ret = typecheck_string(ctx->prev_op_ctx, src);
5775 else if (prev_op == UACPI_PARSE_OP_COMPUTATIONAL_DATA)
5776 ret = typecheck_computational_data(ctx->prev_op_ctx, src);
5777
5778 break;
5781 src = item->obj;
5782 break;
5783
5789 src = item->obj;
5790 break;
5791
5792 default:
5793 EXEC_OP_ERR_1("don't know how to copy/transfer object to %d",
5794 prev_op);
5796 break;
5797 }
5798
5800 dst = item_array_last(&ctx->prev_op_ctx->items);
5801 dst->type = ITEM_OBJECT;
5802
5804 dst->obj = src;
5805 uacpi_object_ref(dst->obj);
5806 } else {
5808 if (uacpi_unlikely(dst->obj == UACPI_NULL)) {
5810 break;
5811 }
5812
5815 }
5816 }
5817 break;
5818 }
5819
5822 uacpi_object *dst, *src;
5823
5824 dst = item_array_at(&op_ctx->items, op_decode_byte(op_ctx))->obj;
5825
5827 src = item_array_at(&op_ctx->items,
5828 op_decode_byte(op_ctx))->obj;
5829 } else {
5830 src = item->obj;
5831 }
5832
5834 break;
5835 }
5836
5837 // Nothing to do here, object is allocated automatically
5841 break;
5842
5846 enum uacpi_assign_behavior behavior;
5847
5848 item_array_pop(&op_ctx->items);
5849 item = item_array_last(&op_ctx->items);
5850
5853 else
5855
5856 ret = uacpi_object_assign(temp, item->obj, behavior);
5858 break;
5859
5861 item->obj = temp;
5862 break;
5863 }
5864
5866 struct uacpi_namespace_node *node;
5868
5869 node = item_array_at(&op_ctx->items, 0)->node;
5871
5874 );
5875 return ret;
5876 }
5877
5879 struct uacpi_namespace_node *node;
5881
5882 node = item_array_at(&op_ctx->items, 0)->node;
5883 method = item_array_at(&op_ctx->items, 1)->obj->method;
5884
5887 );
5888 return ret;
5889 }
5890
5892 uacpi_aml_op new_op = UACPI_AML_OP_InternalOpNamedObject;
5894
5895 if (item->node == UACPI_NULL) {
5896 if (!op_allows_unresolved(prev_op))
5898 break;
5899 }
5900
5902
5903 switch (obj->type) {
5904 case UACPI_OBJECT_METHOD: {
5905 uacpi_bool should_invoke;
5906
5907 switch (prev_op) {
5910 should_invoke = UACPI_FALSE;
5911 break;
5912 default:
5913 should_invoke = !op_wants_supername(prev_op);
5914 }
5915
5916 if (!should_invoke)
5917 break;
5918
5919 new_op = UACPI_AML_OP_InternalOpMethodCall0Args;
5920 new_op += obj->method->args;
5921 break;
5922 }
5923
5927
5928 if (!op_wants_term_arg_or_operand(prev_op))
5929 break;
5930
5933 const uacpi_char *field_path;
5934
5936 item->node
5937 );
5938
5940 "unable to perform a read from field %s: "
5941 "parent opregion gone", field_path
5942 );
5943 uacpi_free_absolute_path(field_path);
5944 }
5945
5946 switch (type) {
5948 new_op = UACPI_AML_OP_InternalOpReadFieldAsBuffer;
5949 break;
5951 new_op = UACPI_AML_OP_InternalOpReadFieldAsInteger;
5952 break;
5953 default:
5955 continue;
5956 }
5957 break;
5958 }
5959 default:
5960 break;
5961 }
5962
5963 op_ctx->pc = 0;
5964 op_ctx->op = uacpi_get_op_spec(new_op);
5965 break;
5966 }
5967
5969 uacpi_aml_op next_op, target_op;
5970 uacpi_u32 cur_offset;
5971 uacpi_u8 op_length;
5972
5973 cur_offset = frame->code_offset;
5974 apply_tracked_pkg(frame, op_ctx);
5975 op_length = peek_next_op(frame, &next_op);
5976
5977 target_op = op_decode_aml_op(op_ctx);
5978 if (op_length == 0 || next_op != target_op) {
5979 // Revert tracked package
5980 frame->code_offset = cur_offset;
5981 break;
5982 }
5983
5984 frame->code_offset += op_length;
5985 op_ctx->switched_from = op_ctx->op->code;
5986 op_ctx->op = uacpi_get_op_spec(target_op);
5987 op_ctx->pc = 0;
5988 break;
5989 }
5990
5992 uacpi_aml_op target_op;
5993 uacpi_u8 skip_bytes;
5994
5995 target_op = op_decode_aml_op(op_ctx);
5996 skip_bytes = op_decode_byte(op_ctx);
5997
5998 if (op_ctx->switched_from != target_op)
5999 op_ctx->pc += skip_bytes;
6000 break;
6001 }
6002
6003 default:
6004 EXEC_OP_ERR_1("unhandled parser op '%d'", op);
6006 break;
6007 }
6008 }
6009}
#define UACPI_ARRAY_SIZE(arr)
Definition: helpers.h:5
#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY
Definition: namespace.h:25
uacpi_parse_op
Definition: opcodes.h:18
@ UACPI_PARSE_OP_OPERAND
Definition: opcodes.h:55
@ UACPI_PARSE_OP_COMPUTATIONAL_DATA
Definition: opcodes.h:64
@ UACPI_PARSE_OP_OBJECT_CONVERT_TO_DEEP_COPY
Definition: opcodes.h:119
@ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL_IF_LOAD
Definition: opcodes.h:107
@ UACPI_PARSE_OP_END
Definition: opcodes.h:19
@ UACPI_PARSE_OP_TYPECHECK_ONE_OF
Definition: opcodes.h:159
@ UACPI_PARSE_OP_STORE_TO_TARGET_INDIRECT
Definition: opcodes.h:182
@ UACPI_PARSE_OP_TERM_ARG
Definition: opcodes.h:39
@ UACPI_PARSE_OP_CREATE_NAMESTRING
Definition: opcodes.h:83
@ UACPI_PARSE_OP_TRACKED_PKGLEN
Definition: opcodes.h:77
@ UACPI_PARSE_OP_CONVERT_NAMESTRING
Definition: opcodes.h:207
@ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE
Definition: opcodes.h:162
@ UACPI_PARSE_OP_IF_LAST_NULL
Definition: opcodes.h:226
@ UACPI_PARSE_OP_AML_PC_DECREMENT
Definition: opcodes.h:185
@ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV
Definition: opcodes.h:173
@ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL
Definition: opcodes.h:101
@ UACPI_PARSE_OP_LOAD_TRUE_OBJECT
Definition: opcodes.h:147
@ UACPI_PARSE_OP_PKGLEN
Definition: opcodes.h:70
@ UACPI_PARSE_OP_EXISTING_NAMESTRING
Definition: opcodes.h:95
@ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT
Definition: opcodes.h:46
@ UACPI_PARSE_OP_IF_LAST_NOT_NULL
Definition: opcodes.h:232
@ UACPI_PARSE_OP_INVOKE_HANDLER
Definition: opcodes.h:110
@ UACPI_PARSE_OP_IF_HAS_DATA
Definition: opcodes.h:213
@ UACPI_PARSE_OP_DISPATCH_TABLE_LOAD
Definition: opcodes.h:201
@ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL
Definition: opcodes.h:40
@ UACPI_PARSE_OP_TYPECHECK
Definition: opcodes.h:153
@ UACPI_PARSE_OP_SIMPLE_NAME
Definition: opcodes.h:31
@ UACPI_PARSE_OP_IF_LAST_FALSE
Definition: opcodes.h:244
@ UACPI_PARSE_OP_JMP
Definition: opcodes.h:267
@ UACPI_PARSE_OP_ITEM_POP
Definition: opcodes.h:191
@ UACPI_PARSE_OP_SWITCH_TO_NEXT_IF_EQUALS
Definition: opcodes.h:255
@ UACPI_PARSE_OP_SUPERNAME_OR_UNRESOLVED
Definition: opcodes.h:36
@ UACPI_PARSE_OP_RECORD_AML_PC
Definition: opcodes.h:128
@ UACPI_PARSE_OP_DISPATCH_METHOD_CALL
Definition: opcodes.h:194
@ UACPI_PARSE_OP_SUPERNAME
Definition: opcodes.h:34
@ UACPI_PARSE_OP_OBJECT_ALLOC
Definition: opcodes.h:113
@ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV
Definition: opcodes.h:165
@ UACPI_PARSE_OP_IF_LAST_TRUE
Definition: opcodes.h:247
@ UACPI_PARSE_OP_IF_NULL
Definition: opcodes.h:220
@ UACPI_PARSE_OP_LOAD_INLINE_IMM_AS_OBJECT
Definition: opcodes.h:131
@ UACPI_PARSE_OP_STRING
Definition: opcodes.h:58
@ UACPI_PARSE_OP_LOAD_IMM
Definition: opcodes.h:140
@ UACPI_PARSE_OP_STORE_TO_TARGET
Definition: opcodes.h:176
@ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL
Definition: opcodes.h:25
@ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD
Definition: opcodes.h:89
@ UACPI_PARSE_OP_EMPTY_OBJECT_ALLOC
Definition: opcodes.h:115
@ UACPI_PARSE_OP_LOAD_IMM_AS_OBJECT
Definition: opcodes.h:143
@ UACPI_PARSE_OP_OBJECT_CONVERT_TO_SHALLOW_COPY
Definition: opcodes.h:118
@ UACPI_PARSE_OP_TARGET
Definition: opcodes.h:67
@ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT_OR_UNRESOLVED
Definition: opcodes.h:52
@ UACPI_PARSE_OP_IF_LAST_EQUALS
Definition: opcodes.h:238
@ UACPI_PARSE_OP_IF_NOT_NULL
Definition: opcodes.h:229
@ UACPI_PARSE_OP_LOAD_FALSE_OBJECT
Definition: opcodes.h:146
@ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED
Definition: opcodes.h:125
@ UACPI_PARSE_OP_EMIT_SKIP_WARN
Definition: opcodes.h:28
@ UACPI_PARSE_OP_LOAD_ZERO_IMM
Definition: opcodes.h:137
@ UACPI_PARSE_OP_IF_SWITCHED_FROM
Definition: opcodes.h:262
@ UACPI_PARSE_OP_TRUNCATE_NUMBER
Definition: opcodes.h:150
@ UACPI_PARSE_OP_IMM_DECREMENT
Definition: opcodes.h:188
@ UACPI_PARSE_OP_LOAD_INLINE_IMM
Definition: opcodes.h:134
const struct uacpi_op_spec * uacpi_get_op_spec(uacpi_aml_op)
Definition: opcodes.c:44
uacpi_aml_op
Definition: opcodes.h:1379
#define uacpi_memzero(ptr, size)
Definition: stdlib.h:99
uacpi_assign_behavior
Definition: types.h:275
@ UACPI_ASSIGN_BEHAVIOR_SHALLOW_COPY
Definition: types.h:277
uacpi_log_level
Definition: log.h:7
@ UACPI_LOG_ERROR
Definition: log.h:35
@ UACPI_LOG_WARN
Definition: log.h:29
void uacpi_free_absolute_path(const uacpi_char *path)
Definition: namespace.c:1074
const uacpi_char * uacpi_namespace_node_generate_absolute_path(const uacpi_namespace_node *node)
Definition: namespace.c:1034
@ UACPI_STATUS_AML_OBJECT_ALREADY_EXISTS
Definition: status.h:36
@ UACPI_STATUS_NOT_FOUND
Definition: status.h:17
@ UACPI_STATUS_UNIMPLEMENTED
Definition: status.h:19
@ UACPI_STATUS_AML_UNDEFINED_REFERENCE
Definition: status.h:34
void uacpi_object_ref(uacpi_object *obj)
Definition: types.c:734
uacpi_bool uacpi_object_is_one_of(uacpi_object *, uacpi_object_type_bits type_mask)
Definition: types.c:997
uacpi_object_type_bits
Definition: types.h:134
uacpi_object_type
Definition: types.h:110
@ UACPI_OBJECT_BUFFER_FIELD
Definition: types.h:125
static uacpi_status typecheck_operand(const struct op_context *op_ctx, const uacpi_object *obj)
Definition: interpreter.c:4863
#define EXEC_OP_ERR_3(reason, arg0, arg1, arg2)
Definition: interpreter.c:4726
static uacpi_status store_to_target(uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
Definition: interpreter.c:4385
static void apply_tracked_pkg(struct call_frame *frame, struct op_context *op_ctx)
Definition: interpreter.c:5322
static uacpi_status prepare_method_call(struct execution_context *ctx, uacpi_namespace_node *node, uacpi_control_method *method, enum method_call_type type, const uacpi_object_array *args)
Definition: interpreter.c:5246
static uacpi_bool op_allows_unresolved_if_load(enum uacpi_parse_op op)
Definition: interpreter.c:4786
resolve_behavior
Definition: interpreter.c:475
static void truncate_number_if_needed(uacpi_object *obj)
Definition: interpreter.c:1935
static uacpi_status field_get_read_type(uacpi_object *obj, uacpi_object_type *out_type)
Definition: interpreter.c:3848
static uacpi_u8 parse_op_generates_item[0x100]
Definition: interpreter.c:4654
static uacpi_u64 ones(void)
Definition: interpreter.c:1943
static void trace_pop(uacpi_u8 pop)
Definition: interpreter.c:4293
static void pop_op(struct execution_context *ctx)
Definition: interpreter.c:4619
static void trace_named_object_lookup_or_creation_failure(struct call_frame *frame, uacpi_size offset, enum uacpi_parse_op op, uacpi_status ret, enum uacpi_log_level level)
Definition: interpreter.c:4904
static uacpi_bool pop_item(struct op_context *op_ctx)
Definition: interpreter.c:4600
static uacpi_u8 handler_idx_of_ext_op[0x100]
Definition: interpreter.c:5202
static void emit_op_skip_warn(const struct op_context *op_ctx)
Definition: interpreter.c:4899
static uacpi_bool op_wants_supername(enum uacpi_parse_op op)
Definition: interpreter.c:4747
static uacpi_status push_op(struct execution_context *ctx)
Definition: interpreter.c:4586
static uacpi_status parse_package_length(struct call_frame *frame, struct package_length *out_pkg)
Definition: interpreter.c:3464
static void * call_frame_cursor(struct call_frame *frame)
Definition: interpreter.c:291
static uacpi_u8 peek_next_op(struct call_frame *frame, uacpi_aml_op *out_op)
Definition: interpreter.c:658
static uacpi_u8 op_decode_byte(struct op_context *ctx)
Definition: interpreter.c:4698
static uacpi_bool op_wants_term_arg_or_operand(enum uacpi_parse_op op)
Definition: interpreter.c:4760
static uacpi_u8 handler_idx_of_op[0x100]
Definition: interpreter.c:5090
static uacpi_bool op_allows_unresolved(enum uacpi_parse_op op)
Definition: interpreter.c:4774
static void trace_op(const struct uacpi_op_spec *op, enum op_trace_action_type action)
Definition: interpreter.c:4283
static uacpi_status typecheck_string(const struct op_context *op_ctx, const uacpi_object *obj)
Definition: interpreter.c:4871
static uacpi_status(* op_handlers[])(struct execution_context *ctx)
Definition: interpreter.c:5037
static uacpi_aml_op op_decode_aml_op(struct op_context *op_ctx)
Definition: interpreter.c:4708
static uacpi_status do_install_node_item(struct call_frame *frame, struct item *item)
Definition: interpreter.c:640
static uacpi_status resolve_name_string(struct call_frame *frame, enum resolve_behavior behavior, struct uacpi_namespace_node **out_node)
Definition: interpreter.c:480
#define EXEC_OP_ERR_1(reason, arg0)
Definition: interpreter.c:4729
#define EXEC_OP_ERR_2(reason, arg0, arg1)
Definition: interpreter.c:4728
#define EXT_OP_IDX(op)
Definition: interpreter.c:5200
static uacpi_bool ctx_has_non_preempted_op(struct execution_context *ctx)
Definition: interpreter.c:4266
static uacpi_status typecheck_computational_data(const struct op_context *op_ctx, const uacpi_object *obj)
Definition: interpreter.c:4879
static uacpi_status op_typecheck(const struct op_context *op_ctx, const struct op_context *cur_op_ctx)
Definition: interpreter.c:4797
static const uacpi_u8 * op_decode_cursor(const struct op_context *ctx)
Definition: interpreter.c:4688
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLsizei width
Definition: gl.h:1546
GLintptr offset
Definition: glext.h:5920
static BOOL is_null(jsval_t v)
Definition: jsval.h:185
static calc_node_t temp
Definition: rpn_ieee.c:38
Definition: inflate.c:139
uacpi_u64 immediate
Definition: interpreter.c:44
uacpi_u8 type
Definition: interpreter.c:38
uacpi_object * obj
Definition: interpreter.c:41
uacpi_handle handle
Definition: interpreter.c:40
uacpi_u8 immediate_bytes[8]
Definition: interpreter.c:45
uacpi_bool preempted
Definition: interpreter.c:54
uacpi_u8 pc
Definition: interpreter.c:53
uacpi_aml_op switched_from
Definition: interpreter.c:62
Definition: cmds.c:130
uacpi_control_method * method
Definition: types.h:257

Referenced by uacpi_execute_control_method().

◆ execution_context_release()

static void execution_context_release ( struct execution_context ctx)
static

Definition at line 6132 of file interpreter.c.

6133{
6134 if (ctx->ret)
6135 uacpi_object_unref(ctx->ret);
6136
6137 while (held_mutexes_array_size(&ctx->held_mutexes) != 0) {
6139 &ctx->held_mutexes,
6140 *held_mutexes_array_last(&ctx->held_mutexes),
6142 );
6143 }
6144
6145 call_frame_array_clear(&ctx->call_stack);
6146 held_mutexes_array_clear(&ctx->held_mutexes);
6147 uacpi_free(ctx, sizeof(*ctx));
6148}

Referenced by uacpi_execute_control_method().

◆ field_byte_size()

static uacpi_status field_byte_size ( uacpi_object obj,
uacpi_size out_size 
)
static

Definition at line 3860 of file interpreter.c.

3863{
3864 uacpi_size bit_length;
3865
3866 if (obj->type == UACPI_OBJECT_BUFFER_FIELD) {
3867 bit_length = obj->buffer_field.bit_length;
3868 } else {
3870
3871 ret = uacpi_field_unit_get_bit_length(obj->field_unit, &bit_length);
3873 return ret;
3874 }
3875
3877 return UACPI_STATUS_OK;
3878}
uacpi_size uacpi_round_up_bits_to_bytes(uacpi_size bit_length)
Definition: io.c:11
uacpi_status uacpi_field_unit_get_bit_length(struct uacpi_field_unit *field, uacpi_size *out_length)
Definition: io.c:721
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:72

Referenced by handle_field_read().

◆ field_get_read_type()

static uacpi_status field_get_read_type ( uacpi_object obj,
uacpi_object_type out_type 
)
static

Definition at line 3848 of file interpreter.c.

3851{
3852 if (obj->type == UACPI_OBJECT_BUFFER_FIELD) {
3853 *out_type = buffer_field_get_read_type(&obj->buffer_field);
3854 return UACPI_STATUS_OK;
3855 }
3856
3857 return uacpi_field_unit_get_read_type(obj->field_unit, out_type);
3858}
uacpi_status uacpi_field_unit_get_read_type(struct uacpi_field_unit *field, uacpi_object_type *out_type)
Definition: io.c:692
static uacpi_object_type buffer_field_get_read_type(struct uacpi_buffer_field *field)
Definition: interpreter.c:3837

Referenced by exec_op(), handle_deref_of(), and handle_inc_dec().

◆ find_last_block()

static struct code_block * find_last_block ( struct code_block_array *  blocks,
enum code_block_type  type,
uacpi_size out_idx_plus_one 
)
static

Definition at line 2005 of file interpreter.c.

2009{
2010 uacpi_size i;
2011
2012 i = code_block_array_size(blocks);
2013 while (i-- > 0) {
2014 struct code_block *block;
2015
2016 block = code_block_array_at(blocks, i);
2017 if (block->type == type) {
2018 if (out_idx_plus_one != UACPI_NULL)
2019 *out_idx_plus_one = i + 1;
2020 return block;
2021 }
2022 }
2023
2024 if (out_idx_plus_one != UACPI_NULL)
2025 *out_idx_plus_one = 0;
2026 return UACPI_NULL;
2027}
static int blocks
Definition: mkdosfs.c:527

Referenced by frame_reset_post_end_block().

◆ frame_push_args()

static uacpi_status frame_push_args ( struct call_frame frame,
struct op_context op_ctx 
)
static

Definition at line 4298 of file interpreter.c.

4300{
4301 uacpi_size i;
4302
4303 /*
4304 * MethodCall items:
4305 * items[0] -> method namespace node
4306 * items[1] -> immediate that was used for parsing the arguments
4307 * items[2...nargs-1] -> method arguments
4308 * items[-1] -> return value object
4309 *
4310 * Here we only care about the arguments though.
4311 */
4312 for (i = 2; i < item_array_size(&op_ctx->items) - 1; i++) {
4313 uacpi_object *src, *dst;
4314
4315 src = item_array_at(&op_ctx->items, i)->obj;
4316
4320
4321 frame->args[i - 2] = dst;
4322 }
4323
4324 return UACPI_STATUS_OK;
4325}

Referenced by prepare_method_call().

◆ frame_reset_post_end_block()

static void frame_reset_post_end_block ( struct execution_context ctx,
enum code_block_type  type 
)
static

Definition at line 2104 of file interpreter.c.

2106{
2107 struct call_frame *frame = ctx->cur_frame;
2108
2109 if (type == CODE_BLOCK_WHILE) {
2110 struct code_block *block = ctx->cur_block;
2111
2112 // + 1 here to skip the WhileOp and get to the PkgLength
2113 frame->prev_while_code_offset = block->begin + 1;
2114 frame->prev_while_expiration = block->expiration_point;
2115 }
2116
2117 code_block_array_pop(&frame->code_blocks);
2118 ctx->cur_block = code_block_array_last(&frame->code_blocks);
2119
2120 if (type == CODE_BLOCK_WHILE) {
2122 &frame->code_blocks, type, &frame->last_while_idx_plus_one
2123 );
2124 } else if (type == CODE_BLOCK_SCOPE) {
2125 struct code_block *block;
2126
2129 );
2130 if (block == UACPI_NULL) {
2132 return;
2133 }
2134
2135 frame->cur_scope = block->node;
2136 }
2137}
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:264
static struct code_block * find_last_block(struct code_block_array *blocks, enum code_block_type type, uacpi_size *out_idx_plus_one)
Definition: interpreter.c:2005

Referenced by handle_control_flow(), and maybe_end_block().

◆ frame_setup_base_scope()

static uacpi_status frame_setup_base_scope ( struct call_frame frame,
uacpi_namespace_node scope,
uacpi_control_method method 
)
static

Definition at line 4327 of file interpreter.c.

4330{
4331 struct code_block *block;
4332
4333 block = code_block_array_alloc(&frame->code_blocks);
4336
4337 block->type = CODE_BLOCK_SCOPE;
4338 block->node = scope;
4339 block->begin = 0;
4340 block->end = method->size;
4341 frame->method = method;
4342 frame->cur_scope = scope;
4343 return UACPI_STATUS_OK;
4344}

Referenced by prepare_method_call().

◆ get_field_length()

static uacpi_u32 get_field_length ( struct item item)
static

Definition at line 1626 of file interpreter.c.

1627{
1628 struct package_length *pkg = &item->pkg;
1629 return pkg->end - pkg->begin;
1630}

Referenced by handle_create_field().

◆ get_object_storage()

static uacpi_status get_object_storage ( uacpi_object obj,
uacpi_data_view out_buf,
uacpi_bool  include_null 
)
static

Definition at line 918 of file interpreter.c.

921{
922 switch (obj->type) {
924 out_buf->length = sizeof_int();
925 out_buf->data = &obj->integer;
926 break;
928 out_buf->length = obj->buffer->size;
929 if (out_buf->length && !include_null)
930 out_buf->length--;
931
932 out_buf->text = obj->buffer->text;
933 break;
935 if (obj->buffer->size == 0) {
936 out_buf->bytes = UACPI_NULL;
937 out_buf->length = 0;
938 break;
939 }
940
941 out_buf->length = obj->buffer->size;
942 out_buf->bytes = obj->buffer->data;
943 break;
946 default:
948 }
949
950 return UACPI_STATUS_OK;
951}
static uacpi_size sizeof_int(void)
Definition: interpreter.c:913
uacpi_char * text
Definition: types.h:99
uacpi_size length
Definition: types.h:105
void * data
Definition: types.h:102
uacpi_u8 * bytes
Definition: types.h:96

Referenced by handle_concatenate(), handle_index(), handle_mid(), handle_sizeof(), handle_to(), and object_assign_with_implicit_cast().

◆ get_op()

static uacpi_status get_op ( struct execution_context ctx)
static

Definition at line 696 of file interpreter.c.

697{
700
701 length = peek_next_op(ctx->cur_frame, &op);
702 if (uacpi_unlikely(length == 0))
704
705 ctx->cur_op = uacpi_get_op_spec(op);
706 if (uacpi_unlikely(op_is_internal(ctx->cur_op) ||
707 op_is_invalid(ctx->cur_op))) {
709 "invalid opcode '%s' (0x%04X) at AML offset %u",
710 ctx->cur_op->name, op, ctx->cur_frame->code_offset
711 );
713 }
714
715 ctx->cur_frame->code_offset += length;
716 g_uacpi_rt_ctx.opcodes_executed++;
717
718 return UACPI_STATUS_OK;
719}
@ UACPI_STATUS_AML_INVALID_OPCODE
Definition: status.h:37
static bool op_is_invalid(const struct uacpi_op_spec *op)
Definition: interpreter.c:691
static bool op_is_internal(const struct uacpi_op_spec *op)
Definition: interpreter.c:686
GLuint GLsizei GLsizei * length
Definition: glext.h:6040

Referenced by uacpi_execute_control_method().

◆ handle_arg()

static uacpi_status handle_arg ( struct execution_context ctx)
static

Definition at line 1087 of file interpreter.c.

1088{
1090 struct op_context *op_ctx = ctx->cur_op_ctx;
1091
1092 idx = op_ctx->op->code - UACPI_AML_OP_Arg0Op;
1093 return handle_arg_or_local(ctx, idx, ARGX);
1094}
static uacpi_status handle_arg_or_local(struct execution_context *ctx, uacpi_size idx, enum argx_or_localx type)
Definition: interpreter.c:1039

◆ handle_arg_or_local()

static uacpi_status handle_arg_or_local ( struct execution_context ctx,
uacpi_size  idx,
enum argx_or_localx  type 
)
static

Definition at line 1039 of file interpreter.c.

1043{
1044 uacpi_object **src;
1045 struct item *dst;
1046 enum uacpi_reference_kind kind;
1047
1048 if (type == ARGX) {
1049 src = &ctx->cur_frame->args[idx];
1051 } else {
1052 src = &ctx->cur_frame->locals[idx];
1054 }
1055
1056 if (*src == UACPI_NULL) {
1057 uacpi_object *default_value;
1058
1060 if (uacpi_unlikely(default_value == UACPI_NULL))
1062
1063 *src = uacpi_create_internal_reference(kind, default_value);
1064 if (uacpi_unlikely(*src == UACPI_NULL))
1066
1067 uacpi_object_unref(default_value);
1068 }
1069
1070 dst = item_array_last(&ctx->cur_op_ctx->items);
1071 dst->obj = *src;
1072 dst->type = ITEM_OBJECT;
1073 uacpi_object_ref(dst->obj);
1074
1075 return UACPI_STATUS_OK;
1076}
uacpi_reference_kind
Definition: types.h:10

Referenced by handle_arg(), and handle_local().

◆ handle_bcd()

static uacpi_status handle_bcd ( struct execution_context ctx)
static

Definition at line 3214 of file interpreter.c.

3215{
3216 struct op_context *op_ctx = ctx->cur_op_ctx;
3217 uacpi_u64 src, dst = 0;
3218 uacpi_size i;
3219 uacpi_object *dst_obj;
3220
3221 src = item_array_at(&op_ctx->items, 0)->obj->integer;
3222 dst_obj = item_array_at(&op_ctx->items, 2)->obj;
3223 i = 64;
3224
3225 /*
3226 * NOTE: ACPICA just errors out for invalid BCD, but NT allows it just fine.
3227 * FromBCD matches NT behavior 1:1 even for invalid BCD, but ToBCD
3228 * produces different results when the input is too large.
3229 */
3230 if (op_ctx->op->code == UACPI_AML_OP_FromBCDOp) {
3231 do {
3232 i -= 4;
3233 dst *= 10;
3234 dst += (src >> i) & 0xF;
3235 } while (i);
3236 } else {
3237 while (src != 0) {
3238 dst >>= 4;
3239 i -= 4;
3240 dst |= (src % 10) << 60;
3241 src /= 10;
3242 }
3243
3244 dst >>= (i % 64);
3245 }
3246
3247 dst_obj->integer = dst;
3248 return UACPI_STATUS_OK;
3249}

◆ handle_binary_logic()

static uacpi_status handle_binary_logic ( struct execution_context ctx)
static

Definition at line 3341 of file interpreter.c.

3342{
3343 struct op_context *op_ctx = ctx->cur_op_ctx;
3344 uacpi_aml_op op = op_ctx->op->code;
3345 uacpi_object *lhs, *rhs, *dst;
3347
3348 lhs = item_array_at(&op_ctx->items, 0)->obj;
3349 rhs = item_array_at(&op_ctx->items, 1)->obj;
3350 dst = item_array_at(&op_ctx->items, 2)->obj;
3351
3352 switch (op) {
3353 case UACPI_AML_OP_LEqualOp:
3354 case UACPI_AML_OP_LLessOp:
3355 case UACPI_AML_OP_LGreaterOp:
3356 // TODO: typecheck at parse time
3357 if (lhs->type != rhs->type) {
3359 "don't know how to do a logical comparison of '%s' and '%s'",
3362 );
3364 }
3365
3366 if (op == UACPI_AML_OP_LEqualOp)
3367 res = handle_logical_equality(lhs, rhs);
3368 else
3370 break;
3371 default: {
3372 uacpi_u64 lhs_int, rhs_int;
3373
3374 // NT only looks at the first 4 bytes of a buffer
3375 lhs_int = object_to_integer(lhs, 4);
3376 rhs_int = object_to_integer(rhs, 4);
3377
3378 if (op == UACPI_AML_OP_LandOp)
3379 res = lhs_int && rhs_int;
3380 else
3381 res = lhs_int || rhs_int;
3382 break;
3383 }
3384 }
3385
3386 dst->integer = res ? ones() : 0;
3387 return UACPI_STATUS_OK;
3388}
static uacpi_u64 object_to_integer(const uacpi_object *obj, uacpi_size max_buffer_bytes)
Definition: interpreter.c:2672
static uacpi_bool handle_logical_equality(uacpi_object *lhs, uacpi_object *rhs)
Definition: interpreter.c:3288
static uacpi_bool handle_logical_less_or_greater(uacpi_aml_op op, uacpi_object *lhs, uacpi_object *rhs)
Definition: interpreter.c:3309

◆ handle_binary_math()

static uacpi_status handle_binary_math ( struct execution_context ctx)
static

Definition at line 2527 of file interpreter.c.

2528{
2529 uacpi_object *arg0, *arg1, *tgt0, *tgt1;
2530 struct item_array *items = &ctx->cur_op_ctx->items;
2531 uacpi_aml_op op = ctx->cur_op_ctx->op->code;
2532
2533 arg0 = item_array_at(items, 0)->obj;
2534 arg1 = item_array_at(items, 1)->obj;
2535
2536 if (op == UACPI_AML_OP_DivideOp) {
2537 tgt0 = item_array_at(items, 4)->obj;
2538 tgt1 = item_array_at(items, 5)->obj;
2539 } else {
2540 tgt0 = item_array_at(items, 3)->obj;
2541 tgt1 = UACPI_NULL;
2542 }
2543
2544 return do_binary_math(arg0, arg1, tgt0, tgt1, op);
2545}
static uacpi_status do_binary_math(uacpi_object *arg0, uacpi_object *arg1, uacpi_object *tgt0, uacpi_object *tgt1, uacpi_aml_op op)
Definition: interpreter.c:2452
static TCHAR * items[]
Definition: page1.c:45

◆ handle_buffer()

static uacpi_status handle_buffer ( struct execution_context ctx)
static

Definition at line 721 of file interpreter.c.

722{
723 struct package_length *pkg;
724 uacpi_u8 *src;
725 uacpi_object *dst, *declared_size;
726 uacpi_u32 buffer_size, init_size, aml_offset;
727 struct op_context *op_ctx = ctx->cur_op_ctx;
728
729 aml_offset = item_array_at(&op_ctx->items, 2)->immediate;
730 src = ctx->cur_frame->method->code;
731 src += aml_offset;
732
733 pkg = &item_array_at(&op_ctx->items, 0)->pkg;
734 init_size = pkg->end - aml_offset;
735
736 // TODO: do package bounds checking at parse time
737 if (uacpi_unlikely(pkg->end > ctx->cur_frame->method->size))
739
740 declared_size = item_array_at(&op_ctx->items, 1)->obj;
741
742 if (uacpi_unlikely(declared_size->integer > 0xE0000000)) {
744 "buffer is too large (%"UACPI_PRIu64"), assuming corrupted "
745 "bytestream", UACPI_FMT64(declared_size->integer)
746 );
748 }
749
750 if (uacpi_unlikely(declared_size->integer == 0)) {
751 uacpi_error("attempted to create an empty buffer");
753 }
754
755 buffer_size = declared_size->integer;
756 if (uacpi_unlikely(init_size > buffer_size)) {
758 "too many buffer initializers: %u (size is %u)",
759 init_size, buffer_size
760 );
762 }
763
764 dst = item_array_at(&op_ctx->items, 3)->obj;
765 dst->buffer->data = uacpi_kernel_alloc(buffer_size);
766 if (uacpi_unlikely(dst->buffer->data == UACPI_NULL))
768 dst->buffer->size = buffer_size;
769
770 uacpi_memcpy_zerout(dst->buffer->data, src, buffer_size, init_size);
771 return UACPI_STATUS_OK;
772}
#define UACPI_PRIu64
Definition: types.h:59
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95

◆ handle_code_block()

static uacpi_status handle_code_block ( struct execution_context ctx)
static

Definition at line 4195 of file interpreter.c.

4196{
4197 struct op_context *op_ctx = ctx->cur_op_ctx;
4198
4199 switch (op_ctx->op->code) {
4200 case UACPI_AML_OP_ProcessorOp:
4201 case UACPI_AML_OP_PowerResOp:
4202 case UACPI_AML_OP_ThermalZoneOp:
4203 case UACPI_AML_OP_DeviceOp: {
4205
4206 ret = create_named_scope(op_ctx);
4208 return ret;
4209
4211 }
4212 case UACPI_AML_OP_ScopeOp:
4213 case UACPI_AML_OP_IfOp:
4214 case UACPI_AML_OP_ElseOp:
4215 case UACPI_AML_OP_WhileOp: {
4216 break;
4217 }
4218 default:
4220 }
4221
4222 return begin_block_execution(ctx);
4223}
static uacpi_status create_named_scope(struct op_context *op_ctx)
Definition: interpreter.c:4159
static uacpi_status begin_block_execution(struct execution_context *ctx)
Definition: interpreter.c:2029

◆ handle_concatenate()

static uacpi_status handle_concatenate ( struct execution_context ctx)
static

Definition at line 2962 of file interpreter.c.

2963{
2965 struct op_context *op_ctx = ctx->cur_op_ctx;
2966 uacpi_object *arg0, *arg1, *dst;
2967 uacpi_u8 *dst_buf;
2968 uacpi_size buf_size = 0;
2969
2970 arg0 = item_array_at(&op_ctx->items, 0)->obj;
2971 arg1 = item_array_at(&op_ctx->items, 1)->obj;
2972 dst = item_array_at(&op_ctx->items, 3)->obj;
2973
2974 switch (arg0->type) {
2975 case UACPI_OBJECT_INTEGER: {
2976 uacpi_u64 arg1_as_int;
2977 uacpi_size int_size;
2978
2979 int_size = sizeof_int();
2980 buf_size = int_size * 2;
2981
2982 dst_buf = uacpi_kernel_alloc(buf_size);
2983 if (uacpi_unlikely(dst_buf == UACPI_NULL))
2985
2986 arg1_as_int = object_to_integer(arg1, int_size);
2987
2988 uacpi_memcpy(dst_buf, &arg0->integer, int_size);
2989 uacpi_memcpy(dst_buf+ int_size, &arg1_as_int, int_size);
2990 break;
2991 }
2992 case UACPI_OBJECT_BUFFER: {
2993 uacpi_buffer *arg0_buf = arg0->buffer;
2994 uacpi_data_view arg1_buf = { 0 };
2995
2996 get_object_storage(arg1, &arg1_buf, UACPI_TRUE);
2997 buf_size = arg0_buf->size + arg1_buf.length;
2998
2999 dst_buf = uacpi_kernel_alloc(buf_size);
3000 if (uacpi_unlikely(dst_buf == UACPI_NULL))
3002
3003 uacpi_memcpy(dst_buf, arg0_buf->data, arg0_buf->size);
3004 uacpi_memcpy(dst_buf + arg0_buf->size, arg1_buf.bytes, arg1_buf.length);
3005 break;
3006 }
3007 case UACPI_OBJECT_STRING: {
3008 uacpi_char int_buf[17];
3009 void *arg1_ptr;
3010 uacpi_size arg0_size, arg1_size;
3011 uacpi_buffer *arg0_buf = arg0->buffer;
3012
3013 switch (arg1->type) {
3014 case UACPI_OBJECT_INTEGER: {
3015 int size;
3016 size = uacpi_snprintf(int_buf, sizeof(int_buf), "%"UACPI_PRIx64,
3017 UACPI_FMT64(arg1->integer));
3018 if (size < 0)
3020
3021 arg1_ptr = int_buf;
3022 arg1_size = size + 1;
3023 break;
3024 }
3026 arg1_ptr = arg1->buffer->data;
3027 arg1_size = arg1->buffer->size;
3028 break;
3029 case UACPI_OBJECT_BUFFER: {
3030 uacpi_buffer tmp_buf;
3031
3032 ret = buffer_to_string(arg1->buffer, &tmp_buf, UACPI_TRUE);
3034 return ret;
3035
3036 arg1_ptr = tmp_buf.data;
3037 arg1_size = tmp_buf.size;
3038 break;
3039 }
3040 default:
3042 }
3043
3044 arg0_size = arg0_buf->size ? arg0_buf->size - 1 : arg0_buf->size;
3045 buf_size = arg0_size + arg1_size;
3046
3047 dst_buf = uacpi_kernel_alloc(buf_size);
3048 if (uacpi_unlikely(dst_buf == UACPI_NULL)) {
3050 goto cleanup;
3051 }
3052
3053 uacpi_memcpy(dst_buf, arg0_buf->data, arg0_size);
3054 uacpi_memcpy(dst_buf + arg0_size, arg1_ptr, arg1_size);
3055 dst->type = UACPI_OBJECT_STRING;
3056
3057 cleanup:
3058 if (arg1->type == UACPI_OBJECT_BUFFER)
3059 uacpi_free(arg1_ptr, arg1_size);
3060 break;
3061 }
3062 default:
3064 }
3065
3067 dst->buffer->data = dst_buf;
3068 dst->buffer->size = buf_size;
3069 }
3070 return ret;
3071}
static void cleanup(void)
Definition: main.c:1335
#define UACPI_PRIx64
Definition: types.h:60
static uacpi_status get_object_storage(uacpi_object *obj, uacpi_data_view *out_buf, uacpi_bool include_null)
Definition: interpreter.c:918
static uacpi_status buffer_to_string(uacpi_buffer *buf, uacpi_buffer *str, uacpi_bool is_hex)
Definition: interpreter.c:2733
uacpi_buffer * buffer
Definition: types.h:258

◆ handle_concatenate_res()

static uacpi_status handle_concatenate_res ( struct execution_context ctx)
static

Definition at line 3073 of file interpreter.c.

3074{
3076 struct op_context *op_ctx = ctx->cur_op_ctx;
3078 uacpi_object *arg0, *arg1, *dst;
3079 uacpi_u8 *dst_buf;
3080 uacpi_size dst_size, arg0_size, arg1_size;
3081
3082 arg0 = item_array_at(&op_ctx->items, 0)->obj;
3083 arg1 = item_array_at(&op_ctx->items, 1)->obj;
3084 dst = item_array_at(&op_ctx->items, 3)->obj;
3085
3089 return ret;
3090
3091 uacpi_buffer_to_view(arg1->buffer, &buffer);
3094 return ret;
3095
3096 dst_size = arg0_size + arg1_size + sizeof(struct acpi_resource_end_tag);
3097
3098 dst_buf = uacpi_kernel_alloc(dst_size);
3099 if (uacpi_unlikely(dst_buf == UACPI_NULL))
3101
3102 dst->buffer->data = dst_buf;
3103 dst->buffer->size = dst_size;
3104
3105 uacpi_memcpy(dst_buf, arg0->buffer->data, arg0_size);
3106 uacpi_memcpy(dst_buf + arg0_size, arg1->buffer->data, arg1_size);
3107
3108 /*
3109 * Small item (0), End Tag (0x0F), length 1
3110 * Leave the checksum as 0
3111 */
3112 dst_buf[dst_size - 2] =
3114 (sizeof(struct acpi_resource_end_tag) - 1);
3115 dst_buf[dst_size - 1] = 0;
3116
3117 return UACPI_STATUS_OK;
3118}
#define ACPI_SMALL_ITEM_NAME_IDX
Definition: acpi.h:1224
uacpi_status uacpi_find_aml_resource_end_tag(uacpi_data_view, uacpi_size *out_offset)
Definition: resources.c:1528
void uacpi_buffer_to_view(uacpi_buffer *, uacpi_data_view *)
Definition: types.c:1043
GLuint buffer
Definition: glext.h:5915

◆ handle_control_flow()

static uacpi_status handle_control_flow ( struct execution_context ctx)
static

Definition at line 4128 of file interpreter.c.

4129{
4130 struct call_frame *frame = ctx->cur_frame;
4131 struct op_context *op_ctx = ctx->cur_op_ctx;
4132
4133 if (uacpi_unlikely(frame->last_while_idx_plus_one == 0)) {
4135 "attempting to %s outside of a While block",
4136 op_ctx->op->code == UACPI_AML_OP_BreakOp ? "Break" : "Continue"
4137 );
4139 }
4140
4141 for (;;) {
4142 if (code_block_array_size(&frame->code_blocks) >
4143 frame->last_while_idx_plus_one) {
4144 frame_reset_post_end_block(ctx, ctx->cur_block->type);
4145 continue;
4146 }
4147
4148 if (op_ctx->op->code == UACPI_AML_OP_BreakOp)
4149 frame->code_offset = ctx->cur_block->end;
4150 else
4151 frame->code_offset = ctx->cur_block->begin;
4152 frame_reset_post_end_block(ctx, ctx->cur_block->type);
4153 break;
4154 }
4155
4156 return UACPI_STATUS_OK;
4157}
static void frame_reset_post_end_block(struct execution_context *ctx, enum code_block_type type)
Definition: interpreter.c:2104

◆ handle_copy_object_or_store()

static uacpi_status handle_copy_object_or_store ( struct execution_context ctx)
static

Definition at line 4420 of file interpreter.c.

4421{
4422 uacpi_object *src, *dst;
4423 struct op_context *op_ctx = ctx->cur_op_ctx;
4424
4425 src = item_array_at(&op_ctx->items, 0)->obj;
4426 dst = item_array_at(&op_ctx->items, 1)->obj;
4427
4428 if (op_ctx->op->code == UACPI_AML_OP_StoreOp) {
4430 uacpi_data_view wtr_response = { 0 };
4431
4432 ret = store_to_target(dst, src, &wtr_response);
4434 return ret;
4435
4436 /*
4437 * This was a write-then-read field access since we got a response
4438 * buffer back from this store. Now we have to return this buffer
4439 * as a prvalue from the StoreOp so that it can be used by AML to
4440 * retrieve the response.
4441 */
4442 if (wtr_response.data != UACPI_NULL) {
4443 uacpi_object *wtr_response_obj;
4444
4445 wtr_response_obj = uacpi_create_object(UACPI_OBJECT_BUFFER);
4446 if (uacpi_unlikely(wtr_response_obj == UACPI_NULL)) {
4447 uacpi_free(wtr_response.data, wtr_response.length);
4449 }
4450
4451 wtr_response_obj->buffer->data = wtr_response.data;
4452 wtr_response_obj->buffer->size = wtr_response.length;
4453
4455 item_array_at(&op_ctx->items, 0)->obj = wtr_response_obj;
4456 }
4457
4458 return ret;
4459 }
4460
4461 if (dst->type != UACPI_OBJECT_REFERENCE)
4463
4465}
static uacpi_status copy_object_to_reference(uacpi_object *dst, uacpi_object *src)
Definition: interpreter.c:2319

◆ handle_create_alias()

static uacpi_status handle_create_alias ( struct execution_context ctx)
static

Definition at line 1111 of file interpreter.c.

1112{
1114
1115 src = item_array_at(&ctx->cur_op_ctx->items, 0)->node;
1116 dst = item_array_at(&ctx->cur_op_ctx->items, 1)->node;
1117
1118 dst->object = src->object;
1120 uacpi_object_ref(dst->object);
1121
1122 return UACPI_STATUS_OK;
1123}
#define UACPI_NAMESPACE_NODE_FLAG_ALIAS
Definition: namespace.h:10

◆ handle_create_buffer_field()

static uacpi_status handle_create_buffer_field ( struct execution_context ctx)
static

Definition at line 4038 of file interpreter.c.

4039{
4040 struct op_context *op_ctx = ctx->cur_op_ctx;
4041 struct uacpi_namespace_node *node;
4042 uacpi_buffer *src_buf;
4043 uacpi_object *field_obj;
4045
4046 /*
4047 * Layout of items here:
4048 * [0] -> Type checked source buffer object
4049 * [1] -> Byte/bit index integer object
4050 * [2] ( if CreateField) -> bit length integer object
4051 * [3] (2 if not CreateField) -> the new namespace node
4052 * [4] (3 if not CreateField) -> the buffer field object we're creating here
4053 */
4054 src_buf = item_array_at(&op_ctx->items, 0)->obj->buffer;
4055
4056 if (op_ctx->op->code == UACPI_AML_OP_CreateFieldOp) {
4057 uacpi_object *idx_obj, *len_obj;
4058
4059 idx_obj = item_array_at(&op_ctx->items, 1)->obj;
4060 len_obj = item_array_at(&op_ctx->items, 2)->obj;
4061 node = item_array_at(&op_ctx->items, 3)->node;
4062 field_obj = item_array_at(&op_ctx->items, 4)->obj;
4063 field = &field_obj->buffer_field;
4064
4065 field->bit_index = idx_obj->integer;
4066
4067 if (uacpi_unlikely(!len_obj->integer ||
4068 len_obj->integer > 0xFFFFFFFF)) {
4069 uacpi_error("invalid bit field length (%u)", field->bit_length);
4071 }
4072
4073 field->bit_length = len_obj->integer;
4074 field->force_buffer = UACPI_TRUE;
4075 } else {
4076 uacpi_object *idx_obj;
4077
4078 idx_obj = item_array_at(&op_ctx->items, 1)->obj;
4079 node = item_array_at(&op_ctx->items, 2)->node;
4080 field_obj = item_array_at(&op_ctx->items, 3)->obj;
4081 field = &field_obj->buffer_field;
4082
4083 field->bit_index = idx_obj->integer;
4084 switch (op_ctx->op->code) {
4085 case UACPI_AML_OP_CreateBitFieldOp:
4086 field->bit_length = 1;
4087 break;
4088 case UACPI_AML_OP_CreateByteFieldOp:
4089 field->bit_length = 8;
4090 break;
4091 case UACPI_AML_OP_CreateWordFieldOp:
4092 field->bit_length = 16;
4093 break;
4094 case UACPI_AML_OP_CreateDWordFieldOp:
4095 field->bit_length = 32;
4096 break;
4097 case UACPI_AML_OP_CreateQWordFieldOp:
4098 field->bit_length = 64;
4099 break;
4100 default:
4102 }
4103
4104 if (op_ctx->op->code != UACPI_AML_OP_CreateBitFieldOp)
4105 field->bit_index *= 8;
4106 }
4107
4108 if (uacpi_unlikely((field->bit_index + field->bit_length) >
4109 src_buf->size * 8)) {
4111 "invalid buffer field: bits [%zu..%zu], buffer size is %zu bytes",
4112 field->bit_index, field->bit_index + field->bit_length,
4113 src_buf->size
4114 );
4116 }
4117
4118 field->backing = src_buf;
4119 uacpi_shareable_ref(field->backing);
4121 field_obj);
4122 if (uacpi_unlikely(node->object == UACPI_NULL))
4124
4125 return UACPI_STATUS_OK;
4126}
uacpi_buffer_field buffer_field
Definition: types.h:255

◆ handle_create_data_region()

static uacpi_status handle_create_data_region ( struct execution_context ctx)
static

Definition at line 1225 of file interpreter.c.

1226{
1228 struct item_array *items = &ctx->cur_op_ctx->items;
1229 struct uacpi_table_identifiers table_id;
1233 uacpi_operation_region *op_region;
1234
1235 node = item_array_at(items, 0)->node;
1236
1238 "DataTableRegion", &table_id,
1239 item_array_at(items, 1)->obj->buffer,
1240 item_array_at(items, 2)->obj->buffer,
1241 item_array_at(items, 3)->obj->buffer
1242 );
1244 return ret;
1245
1246 ret = uacpi_table_find(&table_id, &table);
1248 report_table_id_find_error("DataTableRegion", &table_id, ret);
1249 return ret;
1250 }
1251
1252 obj = item_array_at(items, 4)->obj;
1253 op_region = obj->op_region;
1255 op_region->offset = table.virt_addr;
1256 op_region->length = table.hdr->length;
1257 op_region->table_idx = table.index;
1258
1261 );
1262 if (uacpi_unlikely(node->object == UACPI_NULL))
1264
1266 return UACPI_STATUS_OK;
1267}
@ UACPI_ADDRESS_SPACE_TABLE_DATA
Definition: types.h:58
static void report_table_id_find_error(const uacpi_char *opcode, struct uacpi_table_identifiers *id, uacpi_status ret)
Definition: interpreter.c:1179
static uacpi_status build_table_id(const uacpi_char *opcode, struct uacpi_table_identifiers *out_id, uacpi_buffer *signature, uacpi_buffer *oem_id, uacpi_buffer *oem_table_id)
Definition: interpreter.c:1192
uacpi_status uacpi_initialize_opregion_node(uacpi_namespace_node *node)
Definition: opregion.c:788
uacpi_u64 offset
Definition: types.h:122
uacpi_u64 table_idx
Definition: types.h:127
uacpi_u16 space
Definition: types.h:120
uacpi_u64 length
Definition: types.h:123
uacpi_status uacpi_table_find(const uacpi_table_identifiers *id, uacpi_table *out_table)
Definition: tables.c:1178

◆ handle_create_field()

static uacpi_status handle_create_field ( struct execution_context ctx)
static

Definition at line 1675 of file interpreter.c.

1676{
1678 struct op_context *op_ctx = ctx->cur_op_ctx;
1680 uacpi_object *obj, *connection_obj = UACPI_NULL;
1681 struct field_specific_data field_data = { 0 };
1682 uacpi_size i = 1, bit_offset = 0;
1683 uacpi_u32 length, pin_offset = 0;
1684
1685 uacpi_u8 raw_value, access_type, lock_rule, update_rule;
1686 uacpi_u8 access_attrib = 0, access_length = 0;
1687
1688 switch (op_ctx->op->code) {
1689 case UACPI_AML_OP_FieldOp:
1690 node = item_array_at(&op_ctx->items, i++)->node;
1691 ret = ensure_is_an_op_region(node, &field_data.region);
1693 return ret;
1694 break;
1695
1696 case UACPI_AML_OP_BankFieldOp:
1697 node = item_array_at(&op_ctx->items, i++)->node;
1698 ret = ensure_is_an_op_region(node, &field_data.region);
1700 return ret;
1701
1702 node = item_array_at(&op_ctx->items, i++)->node;
1703 ret = ensure_is_a_field_unit(node, &field_data.field0);
1705 return ret;
1706
1707 field_data.value = item_array_at(&op_ctx->items, i++)->obj->integer;
1708 break;
1709
1710 case UACPI_AML_OP_IndexFieldOp:
1711 node = item_array_at(&op_ctx->items, i++)->node;
1712 ret = ensure_is_a_field_unit(node, &field_data.field0);
1714 return ret;
1715
1716 node = item_array_at(&op_ctx->items, i++)->node;
1717 ret = ensure_is_a_field_unit(node, &field_data.field1);
1719 return ret;
1720 break;
1721
1722 default:
1724 }
1725
1726 /*
1727 * ByteData
1728 * bit 0-3: AccessType
1729 * 0 AnyAcc
1730 * 1 ByteAcc
1731 * 2 WordAcc
1732 * 3 DWordAcc
1733 * 4 QWordAcc
1734 * 5 BufferAcc
1735 * 6 Reserved
1736 * 7-15 Reserved
1737 * bit 4: LockRule
1738 * 0 NoLock
1739 * 1 Lock
1740 * bit 5-6: UpdateRule
1741 * 0 Preserve
1742 * 1 WriteAsOnes
1743 * 2 WriteAsZeros
1744 * bit 7: Reserved (must be 0)
1745 */
1746 raw_value = item_array_at(&op_ctx->items, i++)->immediate;
1747 access_type = (raw_value >> 0) & 0xF;
1748 lock_rule = (raw_value >> 4) & 0x1;
1749 update_rule = (raw_value >> 5) & 0x3;
1750
1751 while (i < item_array_size(&op_ctx->items)) {
1752 struct item *item;
1753 item = item_array_at(&op_ctx->items, i++);
1754
1755 // An actual field object
1756 if (item->type == ITEM_NAMESPACE_NODE) {
1758
1759 length = get_field_length(item_array_at(&op_ctx->items, i++));
1760 node = item->node;
1761
1762 obj = item_array_at(&op_ctx->items, i++)->obj;
1763 field = obj->field_unit;
1764
1765 field->update_rule = update_rule;
1766 field->lock_rule = lock_rule;
1767 field->attributes = access_attrib;
1768 field->access_length = access_length;
1769
1770 /*
1771 * 0 AnyAcc
1772 * 1 ByteAcc
1773 * 2 WordAcc
1774 * 3 DWordAcc
1775 * 4 QWordAcc
1776 * 5 BufferAcc
1777 * 6 Reserved
1778 * 7-15 Reserved
1779 */
1780 switch (access_type) {
1781 case 0:
1782 // TODO: optimize to calculate best access strategy
1784 case 1:
1785 case 5:
1786 field->access_width_bytes = 1;
1787 break;
1788 case 2:
1789 field->access_width_bytes = 2;
1790 break;
1791 case 3:
1792 field->access_width_bytes = 4;
1793 break;
1794 case 4:
1795 field->access_width_bytes = 8;
1796 break;
1797 default:
1798 uacpi_error("invalid field '%.4s' access type %d",
1799 node->name.text, access_type);
1801 }
1802
1803 field->bit_length = length;
1804 field->pin_offset = pin_offset;
1805
1806 // FIXME: overflow, OOB, etc checks
1807 field->byte_offset = UACPI_ALIGN_DOWN(
1808 bit_offset / 8,
1809 field->access_width_bytes,
1811 );
1812
1813 field->bit_offset_within_first_byte =
1814 bit_offset & ((field->access_width_bytes * 8) - 1);
1815
1816 switch (op_ctx->op->code) {
1817 case UACPI_AML_OP_FieldOp:
1818 field->region = field_data.region;
1819 uacpi_shareable_ref(field->region);
1820
1822 break;
1823
1824 case UACPI_AML_OP_BankFieldOp:
1825 field->bank_region = field_data.region;
1826 uacpi_shareable_ref(field->bank_region);
1827
1828 field->bank_selection = field_data.field0;
1829 uacpi_shareable_ref(field->bank_selection);
1830
1831 field->bank_value = field_data.value;
1833 break;
1834
1835 case UACPI_AML_OP_IndexFieldOp:
1836 field->index = field_data.field0;
1837 uacpi_shareable_ref(field->index);
1838
1839 field->data = field_data.field1;
1841
1843 break;
1844
1845 default:
1847 }
1848
1849 field->connection = connection_obj;
1850 if (field->connection)
1851 uacpi_object_ref(field->connection);
1852
1855 );
1856 if (uacpi_unlikely(node->object == UACPI_NULL))
1858
1859 ret = do_install_node_item(ctx->cur_frame, item);
1861 uacpi_object_unref(node->object);
1862 node->object = UACPI_NULL;
1863 return ret;
1864 }
1865
1866 bit_offset += length;
1867 pin_offset += length;
1868 continue;
1869 }
1870
1871 // All other stuff
1872 switch ((int)item->immediate) {
1873 // ReservedField := 0x00 PkgLength
1874 case 0x00:
1875 length = get_field_length(item_array_at(&op_ctx->items, i++));
1876 bit_offset += length;
1877 pin_offset += length;
1878 break;
1879
1880 // AccessField := 0x01 AccessType AccessAttrib
1881 // ExtendedAccessField := 0x03 AccessType ExtendedAccessAttrib AccessLength
1882 case 0x01:
1883 case 0x03:
1884 raw_value = item_array_at(&op_ctx->items, i++)->immediate;
1885
1886 access_type = raw_value & 0xF;
1887 access_attrib = (raw_value >> 6) & 0x3;
1888
1889 raw_value = item_array_at(&op_ctx->items, i++)->immediate;
1890
1891 /*
1892 * Bits 7:6
1893 * 0 = AccessAttrib = Normal Access Attributes
1894 * 1 = AccessAttrib = AttribBytes (x)
1895 * 2 = AccessAttrib = AttribRawBytes (x)
1896 * 3 = AccessAttrib = AttribRawProcessBytes (x)
1897 * x is encoded as bits 0:7 of the AccessAttrib byte.
1898 */
1899 if (access_attrib) {
1900 switch (access_attrib) {
1901 case 1:
1902 access_attrib = UACPI_ACCESS_ATTRIBUTE_BYTES;
1903 break;
1904 case 2:
1905 access_attrib = UACPI_ACCESS_ATTRIBUTE_RAW_BYTES;
1906 break;
1907 case 3:
1909 break;
1910 }
1911
1912 access_length = raw_value;
1913 } else { // Normal access attributes
1914 access_attrib = raw_value;
1915 }
1916
1917 if (item->immediate == 3)
1918 access_length = item_array_at(&op_ctx->items, i++)->immediate;
1919 break;
1920
1921 // ConnectField := <0x02 NameString> | <0x02 BufferData>
1922 case 0x02:
1923 connection_obj = item_array_at(&op_ctx->items, i++)->obj;
1924 pin_offset = 0;
1925 break;
1926
1927 default:
1929 }
1930 }
1931
1932 return UACPI_STATUS_OK;
1933}
#define UACPI_ALIGN_DOWN(x, val, type)
Definition: stdlib.h:109
@ UACPI_FIELD_UNIT_KIND_NORMAL
Definition: types.h:204
@ UACPI_FIELD_UNIT_KIND_BANK
Definition: types.h:206
@ UACPI_FIELD_UNIT_KIND_INDEX
Definition: types.h:205
@ UACPI_ACCESS_ATTRIBUTE_RAW_BYTES
Definition: types.h:483
@ UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES
Definition: types.h:484
@ UACPI_ACCESS_ATTRIBUTE_BYTES
Definition: types.h:480
static uacpi_status ensure_is_a_field_unit(uacpi_namespace_node *node, uacpi_field_unit **out_field)
Definition: interpreter.c:1639
static uacpi_u32 get_field_length(struct item *item)
Definition: interpreter.c:1626
static uacpi_status ensure_is_an_op_region(uacpi_namespace_node *node, uacpi_namespace_node **out_node)
Definition: interpreter.c:1657
struct uacpi_field_unit * field1
Definition: interpreter.c:1635
struct uacpi_field_unit * field0
Definition: interpreter.c:1634
uacpi_namespace_node * region
Definition: interpreter.c:1633

◆ handle_create_method()

static uacpi_status handle_create_method ( struct execution_context ctx)
static

Definition at line 3529 of file interpreter.c.

3530{
3531 struct op_context *op_ctx = ctx->cur_op_ctx;
3532 struct uacpi_control_method *this_method, *method;
3533 struct package_length *pkg;
3534 struct uacpi_namespace_node *node;
3535 struct uacpi_object *dst;
3536 uacpi_u32 method_begin_offset, method_size;
3537
3538 this_method = ctx->cur_frame->method;
3539 pkg = &item_array_at(&op_ctx->items, 0)->pkg;
3540 node = item_array_at(&op_ctx->items, 1)->node;
3541 method_begin_offset = item_array_at(&op_ctx->items, 3)->immediate;
3542
3543 if (uacpi_unlikely(pkg->end < pkg->begin ||
3544 pkg->end < method_begin_offset ||
3545 pkg->end > this_method->size)) {
3547 "invalid method %.4s bounds [%u..%u] (parent size is %u)",
3548 node->name.text, method_begin_offset, pkg->end, this_method->size
3549 );
3551 }
3552
3553 dst = item_array_at(&op_ctx->items, 4)->obj;
3554
3555 method = dst->method;
3556 method_size = pkg->end - method_begin_offset;
3557
3558 if (method_size) {
3559 method->code = uacpi_kernel_alloc(method_size);
3560 if (uacpi_unlikely(method->code == UACPI_NULL))
3562
3564 method->code,
3565 ctx->cur_frame->method->code + method_begin_offset,
3566 method_size
3567 );
3568 method->size = method_size;
3569 method->owns_code = 1;
3570 }
3571
3572 init_method_flags(method, item_array_at(&op_ctx->items, 2)->immediate);
3573
3575 dst);
3576 if (uacpi_unlikely(node->object == UACPI_NULL))
3578
3579 return UACPI_STATUS_OK;
3580}
static void init_method_flags(uacpi_control_method *method, uacpi_u8 flags_byte)
Definition: interpreter.c:3522
uacpi_u32 size
Definition: types.h:174

◆ handle_create_mutex_or_event()

static uacpi_status handle_create_mutex_or_event ( struct execution_context ctx)
static

Definition at line 3582 of file interpreter.c.

3583{
3584 struct op_context *op_ctx = ctx->cur_op_ctx;
3587
3588 node = item_array_at(&op_ctx->items, 0)->node;
3589
3590 if (op_ctx->op->code == UACPI_AML_OP_MutexOp) {
3591 dst = item_array_at(&op_ctx->items, 2)->obj;
3592
3593 // bits 0-3: SyncLevel (0x00-0x0f), bits 4-7: Reserved (must be 0)
3594 dst->mutex->sync_level = item_array_at(&op_ctx->items, 1)->immediate;
3595 dst->mutex->sync_level &= 0xF;
3596 } else {
3597 dst = item_array_at(&op_ctx->items, 1)->obj;
3598 }
3599
3602 dst
3603 );
3604 if (uacpi_unlikely(node->object == UACPI_NULL))
3606
3607 return UACPI_STATUS_OK;
3608}

◆ handle_create_named()

static uacpi_status handle_create_named ( struct execution_context ctx)
static

Definition at line 3820 of file interpreter.c.

3821{
3822 struct op_context *op_ctx = ctx->cur_op_ctx;
3823 struct uacpi_namespace_node *node;
3825
3826 node = item_array_at(&op_ctx->items, 0)->node;
3827 src = item_array_at(&op_ctx->items, 1)->obj;
3828
3830 src);
3831 if (uacpi_unlikely(node->object == UACPI_NULL))
3833
3834 return UACPI_STATUS_OK;
3835}

◆ handle_create_op_region()

static uacpi_status handle_create_op_region ( struct execution_context ctx)
static

Definition at line 1125 of file interpreter.c.

1126{
1129 uacpi_operation_region *op_region;
1130 uacpi_u64 region_end;
1131
1132 node = item_array_at(&ctx->cur_op_ctx->items, 0)->node;
1133 obj = item_array_at(&ctx->cur_op_ctx->items, 4)->obj;
1134 op_region = obj->op_region;
1135
1136 op_region->space = item_array_at(&ctx->cur_op_ctx->items, 1)->immediate;
1137 op_region->offset = item_array_at(&ctx->cur_op_ctx->items, 2)->obj->integer;
1138 op_region->length = item_array_at(&ctx->cur_op_ctx->items, 3)->obj->integer;
1139 region_end = op_region->offset + op_region->length;
1140
1141 if (uacpi_unlikely(op_region->length == 0)) {
1142 // Don't abort here, as long as it's never accessed we don't care
1143 uacpi_warn("unusable/empty operation region %.4s", node->name.text);
1144 } else if (uacpi_unlikely(op_region->offset > region_end)) {
1146 "invalid operation region %.4s bounds: offset=0x%"UACPI_PRIX64
1147 " length=0x%"UACPI_PRIX64"", node->name.text,
1148 UACPI_FMT64(op_region->offset), UACPI_FMT64(op_region->length)
1149 );
1151 }
1152
1153 if (op_region->space == UACPI_ADDRESS_SPACE_PCC && op_region->offset > 255) {
1154 uacpi_warn(
1155 "invalid PCC operation region %.4s subspace %"UACPI_PRIX64,
1156 node->name.text, UACPI_FMT64(op_region->offset)
1157 );
1158 }
1159
1162 );
1163 if (uacpi_unlikely(node->object == UACPI_NULL))
1165
1167 return UACPI_STATUS_OK;
1168}
#define uacpi_warn(...)
Definition: log.h:35
@ UACPI_ADDRESS_SPACE_PCC
Definition: types.h:53

◆ handle_deref_of()

static uacpi_status handle_deref_of ( struct execution_context ctx)
static

Definition at line 3880 of file interpreter.c.

3881{
3882 uacpi_object *src, *unwound_src, *dst;
3883 uacpi_object_type read_type;
3884 bool is_field;
3886
3887 struct op_context *op_ctx = ctx->cur_op_ctx;
3888
3889 src = item_array_at(&op_ctx->items, 0)->obj;
3890 dst = item_array_at(&op_ctx->items, 1)->obj;
3891
3892 if (src->type == UACPI_OBJECT_BUFFER_INDEX) {
3893 uacpi_buffer_index *buf_idx = &src->buffer_index;
3894
3895 dst->type = UACPI_OBJECT_INTEGER;
3897 &dst->integer, buffer_index_cursor(buf_idx),
3898 sizeof(dst->integer), 1
3899 );
3900 return UACPI_STATUS_OK;
3901 }
3902
3903 /*
3904 * Explicit dereferencing [DerefOf] behavior:
3905 * Simply grabs the bottom-most object that is not a reference.
3906 * This mimics the behavior of NT Acpi.sys: any DerfOf fetches
3907 * the bottom-most reference. Note that this is different from
3908 * ACPICA where DerefOf dereferences one level.
3909 */
3910 unwound_src = reference_unwind(src)->inner_object;
3911 is_field = uacpi_object_is_one_of(
3912 unwound_src,
3914 );
3915
3916 /*
3917 * If the object is a field, find out how to read it and transform this
3918 * DerefOf into a field read op. Otherwise, simply assign this object to the
3919 * destination.
3920 */
3921 if (is_field) {
3922 uacpi_aml_op new_op;
3923
3924 ret = field_get_read_type(unwound_src, &read_type);
3927 "unable to perform a read from field %p: "
3928 "parent opregion gone", unwound_src
3929 );
3930 return ret;
3931 }
3932
3933 switch (read_type) {
3935 new_op = UACPI_AML_OP_InternalOpReadFieldAsBuffer;
3936 break;
3938 new_op = UACPI_AML_OP_InternalOpReadFieldAsInteger;
3939 break;
3940 default:
3942 }
3943
3944 op_ctx->op = uacpi_get_op_spec(new_op);
3945 op_ctx->pc = 0;
3946
3947 uacpi_object_ref(unwound_src);
3948 item_array_at(&op_ctx->items, 0)->obj = unwound_src;
3950
3951 /*
3952 * A proper destination object will be allocated by the op we have just
3953 * switched to. This one is not needed anymore.
3954 */
3956 item_array_pop(&op_ctx->items);
3957
3958 return UACPI_STATUS_OK;
3959 }
3960
3961 return uacpi_object_assign(
3962 dst, unwound_src,
3964 );
3965}
@ UACPI_OBJECT_FIELD_UNIT_BIT
Definition: types.h:139
@ UACPI_OBJECT_BUFFER_FIELD_BIT
Definition: types.h:148
uacpi_object * inner_object
Definition: types.h:256

◆ handle_event_ctl()

static uacpi_status handle_event_ctl ( struct execution_context ctx)
static

Definition at line 3610 of file interpreter.c.

3611{
3612 struct op_context *op_ctx = ctx->cur_op_ctx;
3614
3616 item_array_at(&op_ctx->items, 0)->obj
3617 );
3618 if (uacpi_unlikely(obj->type != UACPI_OBJECT_EVENT)) {
3620 "%s: invalid argument '%s', expected an Event object",
3621 op_ctx->op->name, uacpi_object_type_to_string(obj->type)
3622 );
3624 }
3625
3626 switch (op_ctx->op->code)
3627 {
3628 case UACPI_AML_OP_SignalOp:
3629 uacpi_kernel_signal_event(obj->event->handle);
3630 break;
3631 case UACPI_AML_OP_ResetOp:
3632 uacpi_kernel_reset_event(obj->event->handle);
3633 break;
3634 case UACPI_AML_OP_WaitOp: {
3637
3638 timeout = item_array_at(&op_ctx->items, 1)->obj->integer;
3639 if (timeout > 0xFFFF)
3640 timeout = 0xFFFF;
3641
3643 ret = uacpi_kernel_wait_for_event(obj->event->handle, timeout);
3645
3646 /*
3647 * The return value here is inverted, we return 0 for success and Ones
3648 * for timeout and everything else.
3649 */
3650 if (ret)
3651 item_array_at(&op_ctx->items, 2)->obj->integer = 0;
3652 break;
3653 }
3654 default:
3656 }
3657
3658 return UACPI_STATUS_OK;
3659}
uacpi_status uacpi_namespace_write_unlock(void)
Definition: namespace.c:51
uacpi_status uacpi_namespace_write_lock(void)
Definition: namespace.c:46
@ UACPI_OBJECT_EVENT
Definition: types.h:118
uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle, uacpi_u16)
Definition: uacpiosl.c:66
void uacpi_kernel_reset_event(uacpi_handle)
Definition: uacpiosl.c:79
void uacpi_kernel_signal_event(uacpi_handle)
Definition: uacpiosl.c:73
Definition: dhcpd.h:248

◆ handle_field_read()

static uacpi_status handle_field_read ( struct execution_context ctx)
static

Definition at line 3967 of file interpreter.c.

3968{
3970 struct op_context *op_ctx = ctx->cur_op_ctx;
3971 struct item *src_item;
3972 uacpi_object *src_obj, *dst_obj;
3973 uacpi_size dst_size;
3974 void *dst = UACPI_NULL;
3975 uacpi_data_view wtr_response = { 0 };
3976
3977 src_item = item_array_at(&op_ctx->items, 0);
3978
3979 /*
3980 * Source may be a namespace node or an object depending on how we ended up
3981 * here, check explicitly.
3982 */
3983 if (src_item->type == ITEM_NAMESPACE_NODE) {
3985
3986 node = item_array_at(&op_ctx->items, 0)->node;
3988 } else {
3989 src_obj = src_item->obj;
3990 }
3991
3992 dst_obj = item_array_at(&op_ctx->items, 1)->obj;
3993
3994 if (op_ctx->op->code == UACPI_AML_OP_InternalOpReadFieldAsBuffer) {
3996
3997 ret = field_byte_size(src_obj, &dst_size);
3999 return ret;
4000
4001 if (dst_size != 0) {
4002 buf = dst_obj->buffer;
4003
4004 dst = uacpi_kernel_alloc_zeroed(dst_size);
4005 if (dst == UACPI_NULL)
4007
4008 buf->data = dst;
4009 buf->size = dst_size;
4010 }
4011 } else {
4012 dst = &dst_obj->integer;
4013 dst_size = sizeof(uacpi_u64);
4014 }
4015
4016 if (src_obj->type == UACPI_OBJECT_BUFFER_FIELD) {
4018 return UACPI_STATUS_OK;
4019 }
4020
4022 src_obj->field_unit, dst, dst_size, &wtr_response
4023 );
4025 return ret;
4026
4027 if (wtr_response.data != UACPI_NULL) {
4029
4030 buf = dst_obj->buffer;
4031 buf->data = wtr_response.data;
4032 buf->size = wtr_response.length;
4033 }
4034
4035 return ret;
4036}
void uacpi_read_buffer_field(const uacpi_buffer_field *field, void *dst)
Definition: io.c:113
uacpi_status uacpi_read_field_unit(uacpi_field_unit *field, void *dst, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:530
static uacpi_status field_byte_size(uacpi_object *obj, uacpi_size *out_size)
Definition: interpreter.c:3860
uacpi_field_unit * field_unit
Definition: types.h:269

◆ handle_firmware_request()

static uacpi_status handle_firmware_request ( struct execution_context ctx)
static

Definition at line 3793 of file interpreter.c.

3794{
3795 struct op_context *op_ctx = ctx->cur_op_ctx;
3796 uacpi_firmware_request req = { 0 };
3797
3798 switch (op_ctx->op->code) {
3799 case UACPI_AML_OP_BreakPointOp:
3801 req.breakpoint.ctx = ctx;
3802 break;
3803 case UACPI_AML_OP_FatalOp:
3805 req.fatal.type = item_array_at(&op_ctx->items, 0)->immediate;
3806 req.fatal.code = item_array_at(&op_ctx->items, 1)->immediate;
3807 req.fatal.arg = item_array_at(&op_ctx->items, 2)->obj->integer;
3808 break;
3809 default:
3811 }
3812
3816
3817 return UACPI_STATUS_OK;
3818}
@ UACPI_FIRMWARE_REQUEST_TYPE_FATAL
Definition: types.h:518
@ UACPI_FIRMWARE_REQUEST_TYPE_BREAKPOINT
Definition: types.h:517
uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request *)
Definition: uacpiosl.c:177
struct uacpi_firmware_request::@711::@713 breakpoint
struct uacpi_firmware_request::@711::@714 fatal

◆ handle_inc_dec()

static uacpi_status handle_inc_dec ( struct execution_context ctx)
static

Definition at line 4467 of file interpreter.c.

4468{
4469 uacpi_object *src, *dst;
4470 struct op_context *op_ctx = ctx->cur_op_ctx;
4471 uacpi_bool field_allowed = UACPI_FALSE;
4472 uacpi_object_type true_src_type;
4474
4475 src = item_array_at(&op_ctx->items, 0)->obj;
4476 dst = item_array_at(&op_ctx->items, 1)->obj;
4477
4478 if (src->type == UACPI_OBJECT_REFERENCE) {
4479 /*
4480 * Increment/Decrement are the only two operators that modify the value
4481 * in-place, thus we need very specific dereference rules here.
4482 *
4483 * Reading buffer fields & field units is only allowed if we were passed
4484 * a namestring directly as opposed to some nested reference chain
4485 * containing a field at the bottom.
4486 */
4487 if (src->flags == UACPI_REFERENCE_KIND_NAMED)
4488 field_allowed = src->inner_object->type != UACPI_OBJECT_REFERENCE;
4489
4491 } // else buffer index
4492
4493 true_src_type = src->type;
4494
4495 switch (true_src_type) {
4497 dst->integer = src->integer;
4498 break;
4501 if (uacpi_unlikely(!field_allowed))
4502 goto out_bad_type;
4503
4504 ret = field_get_read_type(src, &true_src_type);
4506 goto out_bad_type;
4507 if (true_src_type != UACPI_OBJECT_INTEGER)
4508 goto out_bad_type;
4509
4510 if (src->type == UACPI_OBJECT_FIELD_UNIT) {
4512 src->field_unit, &dst->integer, sizeof_int(),
4514 );
4516 return ret;
4517 } else {
4518 uacpi_read_buffer_field(&src->buffer_field, &dst->integer);
4519 }
4520 break;
4522 dst->integer = *buffer_index_cursor(&src->buffer_index);
4523 break;
4524 default:
4525 goto out_bad_type;
4526 }
4527
4528 if (op_ctx->op->code == UACPI_AML_OP_IncrementOp)
4529 dst->integer++;
4530 else
4531 dst->integer--;
4532
4533 return UACPI_STATUS_OK;
4534
4535out_bad_type:
4536 uacpi_error("Increment/Decrement: invalid object type '%s'",
4537 uacpi_object_type_to_string(true_src_type));
4539}

◆ handle_index()

static uacpi_status handle_index ( struct execution_context ctx)
static

Definition at line 2587 of file interpreter.c.

2588{
2590 struct op_context *op_ctx = ctx->cur_op_ctx;
2592 struct item *dst;
2594
2595 src = item_array_at(&op_ctx->items, 0)->obj;
2596 idx = item_array_at(&op_ctx->items, 1)->obj->integer;
2597 dst = item_array_at(&op_ctx->items, 3);
2598
2599 switch (src->type) {
2601 case UACPI_OBJECT_STRING: {
2602 uacpi_buffer_index *buf_idx;
2605
2606 ret = ensure_valid_idx(src, idx, buf.length);
2608 return ret;
2609
2610 dst->type = ITEM_OBJECT;
2612 if (uacpi_unlikely(dst->obj == UACPI_NULL))
2614
2615 buf_idx = &dst->obj->buffer_index;
2616 buf_idx->idx = idx;
2617 buf_idx->buffer = src->buffer;
2618 uacpi_shareable_ref(buf_idx->buffer);
2619
2620 break;
2621 }
2622 case UACPI_OBJECT_PACKAGE: {
2623 uacpi_package *pkg = src->package;
2625
2626 ret = ensure_valid_idx(src, idx, pkg->count);
2628 return ret;
2629
2630 /*
2631 * Lazily transform the package element into an internal reference
2632 * to itself of type PKG_INDEX. This is needed to support stuff like
2633 * CopyObject(..., Index(pkg, X)) where the new object must be
2634 * propagated to anyone else with a currently alive index object.
2635 *
2636 * Sidenote: Yes, IndexOp is not a SimpleName, so technically it is
2637 * illegal to CopyObject to it. However, yet again we fall
2638 * victim to the NT ACPI driver implementation, which allows
2639 * it just fine.
2640 */
2641 obj = pkg->objects[idx];
2642 if (obj->type != UACPI_OBJECT_REFERENCE ||
2644
2647 );
2650
2651 pkg->objects[idx] = obj;
2652 uacpi_object_unref(obj->inner_object);
2653 }
2654
2655 dst->obj = obj;
2656 dst->type = ITEM_OBJECT;
2657 uacpi_object_ref(dst->obj);
2658 break;
2659 }
2660 default:
2662 "invalid argument for Index: %s, "
2663 "expected String/Buffer/Package",
2665 );
2667 }
2668
2669 return UACPI_STATUS_OK;
2670}
static uacpi_status ensure_valid_idx(uacpi_object *obj, uacpi_size idx, uacpi_size src_size)
Definition: interpreter.c:2574

◆ handle_load()

static uacpi_status handle_load ( struct execution_context ctx)
static

Definition at line 1446 of file interpreter.c.

1447{
1449 struct item_array *items = &ctx->cur_op_ctx->items;
1453 struct acpi_sdt_hdr *src_table = UACPI_NULL;
1454 void *table_buffer;
1455 uacpi_size declared_size;
1456 uacpi_bool unmap_src = UACPI_FALSE;
1457
1458 /*
1459 * If we already have the last true/false object loaded, this is a second
1460 * invocation of this handler. For the second invocation we simply want to
1461 * detect new AML GPE handlers that might've been loaded.
1462 * We do this only if table load was successful though.
1463 */
1464 if (item_array_size(items) == 6) {
1466 uacpi_table tmp_table = { 0 };
1467
1468 idx = item_array_at(items, 2)->immediate;
1469 tmp_table.index = idx;
1470 uacpi_table_unref(&tmp_table);
1471
1472 if (item_array_at(items, 5)->obj->integer != 0)
1474 return UACPI_STATUS_OK;
1475 }
1476
1477 src = item_array_at(items, 3)->obj;
1478
1479 switch (src->type) {
1481 uacpi_operation_region *op_region;
1482
1483 op_region = src->op_region;
1484 if (uacpi_unlikely(
1486 )) {
1487 uacpi_error("Load: operation region is not SystemMemory");
1489 goto error_out;
1490 }
1491
1492 if (uacpi_unlikely(op_region->length < sizeof(struct acpi_sdt_hdr))) {
1494 "Load: operation region is too small: %"UACPI_PRIu64,
1495 UACPI_FMT64(op_region->length)
1496 );
1498 goto error_out;
1499 }
1500
1501 src_table = uacpi_kernel_map(op_region->offset, op_region->length);
1502 if (uacpi_unlikely(src_table == UACPI_MAP_FAILED)) {
1504 "Load: failed to map operation region "
1505 "0x%016"UACPI_PRIX64" -> 0x%016"UACPI_PRIX64,
1506 UACPI_FMT64(op_region->offset),
1507 UACPI_FMT64(op_region->offset + op_region->length)
1508 );
1510 goto error_out;
1511 }
1512
1513 unmap_src = UACPI_TRUE;
1514 declared_size = op_region->length;
1515 break;
1516 }
1517
1518 case UACPI_OBJECT_BUFFER: {
1520
1521 buffer = src->buffer;
1522 if (buffer->size < sizeof(struct acpi_sdt_hdr)) {
1524 "Load: buffer is too small: %zu",
1525 buffer->size
1526 );
1527
1529 goto error_out;
1530 }
1531
1532 src_table = buffer->data;
1533 declared_size = buffer->size;
1534 break;
1535 }
1536
1537 default:
1539 "Load: invalid argument '%s', expected "
1540 "Buffer/Field/OperationRegion",
1542 );
1544 goto error_out;
1545 }
1546
1547 if (uacpi_unlikely(src_table->length > declared_size)) {
1549 "Load: table size %u is larger than the declared size %zu",
1550 src_table->length, declared_size
1551 );
1553 goto error_out;
1554 }
1555
1556 if (uacpi_unlikely(src_table->length < sizeof(struct acpi_sdt_hdr))) {
1557 uacpi_error("Load: table size %u is too small", src_table->length);
1559 goto error_out;
1560 }
1561
1562 table_buffer = uacpi_kernel_alloc(src_table->length);
1563 if (uacpi_unlikely(table_buffer == UACPI_NULL)) {
1565 goto error_out;
1566 }
1567
1568 uacpi_memcpy(table_buffer, src_table, src_table->length);
1569
1570 if (unmap_src) {
1571 uacpi_kernel_unmap(src_table, declared_size);
1572 unmap_src = UACPI_FALSE;
1573 }
1574
1577 );
1579 uacpi_free(table_buffer, src_table->length);
1580
1581 /*
1582 * Treat DENIED as a soft error, that is, fail the Load but don't abort
1583 * the currently running method. We simply return False to the caller
1584 * to signify an error in this case.
1585 */
1588
1590 goto error_out;
1591 }
1592
1593 method = item_array_at(items, 1)->obj->method;
1597 goto error_out;
1598 }
1599
1601 item_array_at(items, 2)->immediate = table.index;
1602
1603 item_array_at(items, 0)->node = uacpi_namespace_root();
1604 return UACPI_STATUS_OK;
1605
1606error_out:
1607 if (unmap_src && src_table)
1608 uacpi_kernel_unmap(src_table, declared_size);
1609 return ret;
1610}
@ UACPI_STATUS_OVERRIDDEN
Definition: status.h:30
@ UACPI_STATUS_INVALID_TABLE_LENGTH
Definition: status.h:16
@ UACPI_STATUS_MAPPING_FAILED
Definition: status.h:12
@ UACPI_STATUS_DENIED
Definition: status.h:31
@ UACPI_ADDRESS_SPACE_SYSTEM_MEMORY
Definition: types.h:43
uacpi_status uacpi_table_install_with_origin(void *virt, enum uacpi_table_origin origin, uacpi_table *out_table)
Definition: tables.c:935
void uacpi_table_mark_as_loaded(uacpi_size idx)
Definition: tables.c:1308
@ UACPI_TABLE_LOAD_CAUSE_LOAD_OP
Definition: interpreter.h:10
#define UACPI_MAP_FAILED
Definition: kernel_api.h:13
void uacpi_kernel_unmap(void *addr, uacpi_size len)
Definition: uacpiosl.c:198
void * uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len)
Definition: uacpiosl.c:191
uacpi_size index
Definition: tables.h:33
uacpi_status uacpi_table_unref(uacpi_table *)
Definition: tables.c:1357
@ UACPI_TABLE_ORIGIN_FIRMWARE_VIRTUAL
Definition: tables.h:188

◆ handle_load_table()

static uacpi_status handle_load_table ( struct execution_context ctx)
static

Definition at line 1326 of file interpreter.c.

1327{
1329 struct item_array *items = &ctx->cur_op_ctx->items;
1330 struct item *root_node_item;
1331 struct uacpi_table_identifiers table_id;
1333 uacpi_buffer *root_path, *param_path;
1335 uacpi_namespace_node *root_node, *param_node = UACPI_NULL;
1336
1337 /*
1338 * If we already have the last true/false object loaded, this is a second
1339 * invocation of this handler. For the second invocation we want to detect
1340 * new AML GPE handlers that might've been loaded, as well as potentially
1341 * remove the target.
1342 */
1343 if (item_array_size(items) == 12) {
1345 struct uacpi_table tmp_table = { 0 };
1346
1347 idx = item_array_at(items, 2)->immediate;
1348 tmp_table.index = idx;
1349 uacpi_table_unref(&tmp_table);
1350
1351 /*
1352 * If this load failed, remove the target that was provided via
1353 * ParameterPathString so that it doesn't get stored to.
1354 */
1355 if (uacpi_unlikely(item_array_at(items, 11)->obj->integer == 0)) {
1357
1358 target = item_array_at(items, 3)->obj;
1359 if (target != UACPI_NULL) {
1361 item_array_at(items, 3)->obj = UACPI_NULL;
1362 }
1363
1364 return UACPI_STATUS_OK;
1365 }
1366
1368 return UACPI_STATUS_OK;
1369 }
1370
1372 "LoadTable", &table_id,
1373 item_array_at(items, 5)->obj->buffer,
1374 item_array_at(items, 6)->obj->buffer,
1375 item_array_at(items, 7)->obj->buffer
1376 );
1378 return ret;
1379
1380 root_path = item_array_at(items, 8)->obj->buffer;
1381 param_path = item_array_at(items, 9)->obj->buffer;
1382 root_node_item = item_array_at(items, 0);
1383
1384 if (root_path->size > 1) {
1386 ctx->cur_frame->cur_scope, root_path->text, UACPI_SHOULD_LOCK_NO,
1388 &root_node
1389 );
1391 table_id_error("LoadTable", "RootPathString", root_path);
1394 return ret;
1395 }
1396 } else {
1397 root_node = uacpi_namespace_root();
1398 }
1399
1400 if (param_path->size > 1) {
1401 struct item *param_item;
1402
1404 root_node, param_path->text, UACPI_SHOULD_LOCK_NO,
1406 &param_node
1407 );
1409 table_id_error("LoadTable", "ParameterPathString", root_path);
1412 return ret;
1413 }
1414
1415 param_item = item_array_at(items, 3);
1416 param_item->obj = param_node->object;
1417 uacpi_object_ref(param_item->obj);
1418 param_item->type = ITEM_OBJECT;
1419 }
1420
1421 ret = uacpi_table_find(&table_id, &table);
1423 report_table_id_find_error("LoadTable", &table_id, ret);
1424 return ret;
1425 }
1426
1427 method = item_array_at(items, 1)->obj->method;
1430 );
1433 return ret;
1434 }
1435
1437 item_array_at(items, 2)->immediate = table.index;
1438
1439 root_node_item->node = root_node;
1440 root_node_item->type = ITEM_NAMESPACE_NODE;
1441 uacpi_shareable_ref(root_node);
1442
1443 return UACPI_STATUS_OK;
1444}
@ UACPI_PERMANENT_ONLY_NO
Definition: namespace.h:89
@ UACPI_SHOULD_LOCK_NO
Definition: namespace.h:94
@ UACPI_MAY_SEARCH_ABOVE_PARENT_YES
Definition: namespace.h:85
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)
Definition: namespace.c:491
@ UACPI_TABLE_LOAD_CAUSE_LOAD_TABLE_OP
Definition: interpreter.h:11
Definition: tools.h:99
uacpi_object * object
Definition: namespace.h:31

◆ handle_local()

static uacpi_status handle_local ( struct execution_context ctx)
static

Definition at line 1078 of file interpreter.c.

1079{
1081 struct op_context *op_ctx = ctx->cur_op_ctx;
1082
1083 idx = op_ctx->op->code - UACPI_AML_OP_Local0Op;
1085}

◆ handle_logical_equality()

static uacpi_bool handle_logical_equality ( uacpi_object lhs,
uacpi_object rhs 
)
static

Definition at line 3288 of file interpreter.c.

3289{
3291
3292 if (lhs->type == UACPI_OBJECT_STRING || lhs->type == UACPI_OBJECT_BUFFER) {
3293 res = lhs->buffer->size == rhs->buffer->size;
3294
3295 if (res && lhs->buffer->size) {
3296 res = uacpi_memcmp(
3297 lhs->buffer->data,
3298 rhs->buffer->data,
3299 lhs->buffer->size
3300 ) == 0;
3301 }
3302 } else if (lhs->type == UACPI_OBJECT_INTEGER) {
3303 res = lhs->integer == rhs->integer;
3304 }
3305
3306 return res;
3307}
#define uacpi_memcmp
Definition: stdlib.h:61

Referenced by handle_binary_logic().

◆ handle_logical_less_or_greater()

static uacpi_bool handle_logical_less_or_greater ( uacpi_aml_op  op,
uacpi_object lhs,
uacpi_object rhs 
)
static

Definition at line 3309 of file interpreter.c.

3312{
3313 if (lhs->type == UACPI_OBJECT_STRING || lhs->type == UACPI_OBJECT_BUFFER) {
3314 int res;
3315 uacpi_buffer *lhs_buf, *rhs_buf;
3316
3317 lhs_buf = lhs->buffer;
3318 rhs_buf = rhs->buffer;
3319
3320 res = uacpi_memcmp(lhs_buf->data, rhs_buf->data,
3321 UACPI_MIN(lhs_buf->size, rhs_buf->size));
3322 if (res == 0) {
3323 if (lhs_buf->size < rhs_buf->size)
3324 res = -1;
3325 else if (lhs_buf->size > rhs_buf->size)
3326 res = 1;
3327 }
3328
3329 if (op == UACPI_AML_OP_LLessOp)
3330 return res < 0;
3331
3332 return res > 0;
3333 }
3334
3335 if (op == UACPI_AML_OP_LLessOp)
3336 return lhs->integer < rhs->integer;
3337
3338 return lhs->integer > rhs->integer;
3339}
#define UACPI_MIN(x, y)
Definition: stdlib.h:102

Referenced by handle_binary_logic().

◆ handle_logical_not()

static uacpi_status handle_logical_not ( struct execution_context ctx)
static

Definition at line 3274 of file interpreter.c.

3275{
3276 struct op_context *op_ctx = ctx->cur_op_ctx;
3277 uacpi_object *src, *dst;
3278
3279 src = item_array_at(&op_ctx->items, 0)->obj;
3280 dst = item_array_at(&op_ctx->items, 1)->obj;
3281
3282 dst->type = UACPI_OBJECT_INTEGER;
3283 dst->integer = src->integer ? 0 : ones();
3284
3285 return UACPI_STATUS_OK;
3286}

◆ handle_match()

static uacpi_status handle_match ( struct execution_context ctx)
static

Definition at line 3419 of file interpreter.c.

3420{
3421 struct op_context *op_ctx = ctx->cur_op_ctx;
3422 uacpi_package *pkg;
3423 uacpi_u64 operand0, operand1, start_idx, i;
3424 enum match_op mop0, mop1;
3426
3427 pkg = item_array_at(&op_ctx->items, 0)->obj->package;
3428 mop0 = item_array_at(&op_ctx->items, 1)->immediate;
3429 operand0 = item_array_at(&op_ctx->items, 2)->obj->integer;
3430 mop1 = item_array_at(&op_ctx->items, 3)->immediate;
3431 operand1 = item_array_at(&op_ctx->items, 4)->obj->integer;
3432 start_idx = item_array_at(&op_ctx->items, 5)->obj->integer;
3433 dst = item_array_at(&op_ctx->items, 6)->obj;
3434
3435 for (i = start_idx; i < pkg->count; ++i) {
3436 uacpi_object *obj = pkg->objects[i];
3437
3438 if (obj->type != UACPI_OBJECT_INTEGER)
3439 continue;
3440
3441 if (match_one(mop0, obj->integer, operand0) &&
3442 match_one(mop1, obj->integer, operand1))
3443 break;
3444 }
3445
3446 if (i < pkg->count)
3447 dst->integer = i;
3448 else
3449 dst->integer = ones();
3450
3451 return UACPI_STATUS_OK;
3452}
match_op
Definition: interpreter.c:3390
static uacpi_bool match_one(enum match_op op, uacpi_u64 lhs, uacpi_u64 rhs)
Definition: interpreter.c:3399
GLuint GLuint GLsizei count
Definition: gl.h:1545

◆ handle_mid()

static uacpi_status handle_mid ( struct execution_context ctx)
static

Definition at line 2907 of file interpreter.c.

2908{
2909 struct op_context *op_ctx = ctx->cur_op_ctx;
2910 uacpi_object *src, *dst;
2911 uacpi_data_view src_buf;
2912 uacpi_buffer *dst_buf;
2915
2916 src = item_array_at(&op_ctx->items, 0)->obj;
2917 if (uacpi_unlikely(src->type != UACPI_OBJECT_STRING &&
2918 src->type != UACPI_OBJECT_BUFFER)) {
2920 "invalid argument for Mid: %s, expected String/Buffer",
2922 );
2924 }
2925
2926 idx = item_array_at(&op_ctx->items, 1)->obj->integer;
2927 len = item_array_at(&op_ctx->items, 2)->obj->integer;
2928 dst = item_array_at(&op_ctx->items, 4)->obj;
2929 dst_buf = dst->buffer;
2930
2933
2934 if (uacpi_unlikely(src_buf.length == 0 || idx >= src_buf.length ||
2935 len == 0)) {
2936 if (src->type == UACPI_OBJECT_STRING) {
2937 dst->type = UACPI_OBJECT_STRING;
2938 return make_null_string(dst_buf);
2939 }
2940
2941 return make_null_buffer(dst_buf);
2942 }
2943
2944 // Guaranteed to be at least 1 here
2945 len = UACPI_MIN(len, src_buf.length - idx);
2946
2947 dst_buf->data = uacpi_kernel_alloc(len + is_string);
2948 if (uacpi_unlikely(dst_buf->data == UACPI_NULL))
2950
2951 uacpi_memcpy(dst_buf->data, (uacpi_u8*)src_buf.bytes + idx, len);
2952 dst_buf->size = len;
2953
2954 if (is_string) {
2955 dst_buf->text[dst_buf->size++] = '\0';
2956 dst->type = UACPI_OBJECT_STRING;
2957 }
2958
2959 return UACPI_STATUS_OK;
2960}
static uacpi_status make_null_string(uacpi_buffer *buf)
Definition: interpreter.c:2807
static uacpi_status make_null_buffer(uacpi_buffer *buf)
Definition: interpreter.c:2812
GLenum GLsizei len
Definition: glext.h:6722

◆ handle_mutex_ctl()

static uacpi_status handle_mutex_ctl ( struct execution_context ctx)
static

Definition at line 3661 of file interpreter.c.

3662{
3663 struct op_context *op_ctx = ctx->cur_op_ctx;
3665
3667 item_array_at(&op_ctx->items, 0)->obj
3668 );
3669 if (uacpi_unlikely(obj->type != UACPI_OBJECT_MUTEX)) {
3671 "%s: invalid argument '%s', expected a Mutex object",
3672 op_ctx->op->name, uacpi_object_type_to_string(obj->type)
3673 );
3675 }
3676
3677 switch (op_ctx->op->code)
3678 {
3679 case UACPI_AML_OP_AcquireOp: {
3681 uacpi_u64 *return_value;
3683
3684 return_value = &item_array_at(&op_ctx->items, 2)->obj->integer;
3685
3686 if (uacpi_unlikely(ctx->sync_level > obj->mutex->sync_level)) {
3687 uacpi_warn(
3688 "ignoring attempt to acquire mutex @%p with a lower sync level "
3689 "(%d < %d)", obj->mutex, obj->mutex->sync_level,
3690 ctx->sync_level
3691 );
3692 break;
3693 }
3694
3695 timeout = item_array_at(&op_ctx->items, 1)->immediate;
3696 if (timeout > 0xFFFF)
3697 timeout = 0xFFFF;
3698
3702 *return_value = 0;
3703 break;
3704 }
3705
3708 break;
3709
3710 ret = held_mutexes_array_push(&ctx->held_mutexes, obj->mutex);
3713 return ret;
3714 }
3715
3716 ctx->sync_level = obj->mutex->sync_level;
3717 *return_value = 0;
3718 break;
3719 }
3720
3721 case UACPI_AML_OP_ReleaseOp: {
3723
3725 uacpi_warn(
3726 "attempted to release not-previously-acquired mutex object "
3727 "@%p (%p)", obj->mutex, obj->mutex->handle
3728 );
3729 break;
3730 }
3731
3733 &ctx->held_mutexes, obj->mutex,
3735 );
3737 uacpi_mutex **last_mutex;
3738
3739 last_mutex = held_mutexes_array_last(&ctx->held_mutexes);
3740 if (last_mutex == UACPI_NULL) {
3741 ctx->sync_level = 0;
3742 break;
3743 }
3744
3745 ctx->sync_level = (*last_mutex)->sync_level;
3746 }
3747 break;
3748 }
3749
3750 default:
3752 }
3753
3754 return UACPI_STATUS_OK;
3755}

◆ handle_named_object()

static uacpi_status handle_named_object ( struct execution_context ctx)
static

Definition at line 1096 of file interpreter.c.

1097{
1098 struct uacpi_namespace_node *src;
1099 struct item *dst;
1100
1101 src = item_array_at(&ctx->cur_op_ctx->items, 0)->node;
1102 dst = item_array_at(&ctx->cur_op_ctx->items, 1);
1103
1104 dst->obj = src->object;
1105 dst->type = ITEM_OBJECT;
1106 uacpi_object_ref(dst->obj);
1107
1108 return UACPI_STATUS_OK;
1109}

◆ handle_notify()

static uacpi_status handle_notify ( struct execution_context ctx)
static

Definition at line 3757 of file interpreter.c.

3758{
3760 struct op_context *op_ctx = ctx->cur_op_ctx;
3761 struct uacpi_namespace_node *node;
3763
3764 node = item_array_at(&op_ctx->items, 0)->node;
3765 value = item_array_at(&op_ctx->items, 1)->obj->integer;
3766
3769 return ret;
3770
3772 const uacpi_char *path;
3773
3775 uacpi_warn(
3776 "ignoring firmware Notify(%s, 0x%"UACPI_PRIX64") request, "
3777 "no listeners", path, UACPI_FMT64(value)
3778 );
3780
3781 return UACPI_STATUS_OK;
3782 }
3783
3785 uacpi_error("Notify() called on an invalid object %.4s",
3786 node->name.text);
3788 }
3789
3790 return ret;
3791}
@ UACPI_STATUS_NO_HANDLER
Definition: status.h:25
uacpi_status uacpi_notify_all(uacpi_namespace_node *node, uacpi_u64 value)
Definition: notify.c:69
void uacpi_free_dynamic_string(const uacpi_char *str)
Definition: utilities.c:1148

◆ handle_object_type()

static uacpi_status handle_object_type ( struct execution_context ctx)
static

Definition at line 3157 of file interpreter.c.

3158{
3159 struct op_context *op_ctx = ctx->cur_op_ctx;
3160 uacpi_object *src, *dst;
3161
3162 src = item_array_at(&op_ctx->items, 0)->obj;
3163 dst = item_array_at(&op_ctx->items, 1)->obj;
3164
3167
3168 dst->integer = src->type;
3169 if (dst->integer == UACPI_OBJECT_BUFFER_INDEX)
3170 dst->integer = UACPI_OBJECT_BUFFER_FIELD;
3171
3172 return UACPI_STATUS_OK;
3173}

◆ handle_package()

static uacpi_status handle_package ( struct execution_context ctx)
static

Definition at line 802 of file interpreter.c.

803{
804 struct op_context *op_ctx = ctx->cur_op_ctx;
805 uacpi_package *package;
806 uacpi_u32 num_elements, num_defined_elements, i;
807
808 /*
809 * Layout of items here:
810 * [0] -> Package length, not interesting
811 * [1] -> Immediate or integer object, depending on PackageOp/VarPackageOp
812 * [2..N-2] -> AML pc+Package element pairs
813 * [N-1] -> The resulting package object that we're constructing
814 */
815 package = item_array_last(&op_ctx->items)->obj->package;
816
817 // 1. Detect how many elements we have, do sanity checking
818 if (op_ctx->op->code == UACPI_AML_OP_VarPackageOp) {
819 uacpi_object *var_num_elements;
820
821 var_num_elements = item_array_at(&op_ctx->items, 1)->obj;
822 if (uacpi_unlikely(var_num_elements->integer > 0xE0000000)) {
824 "package is too large (%"UACPI_PRIu64"), assuming "
825 "corrupted bytestream", UACPI_FMT64(var_num_elements->integer)
826 );
828 }
829 num_elements = var_num_elements->integer;
830 } else {
831 num_elements = item_array_at(&op_ctx->items, 1)->immediate;
832 }
833
834 num_defined_elements = (item_array_size(&op_ctx->items) - 3) / 2;
835 if (uacpi_unlikely(num_defined_elements > num_elements)) {
837 "too many package initializers: %u, truncating to %u",
838 num_defined_elements, num_elements
839 );
840
841 num_defined_elements = num_elements;
842 }
843
844 // 2. Create every object in the package, start as uninitialized
845 if (uacpi_unlikely(!uacpi_package_fill(package, num_elements,
848
849 // 3. Go through every defined object and copy it into the package
850 for (i = 0; i < num_defined_elements; ++i) {
851 uacpi_size base_pkg_index;
853 struct item *item;
855
856 base_pkg_index = (i * 2) + 2;
857 item = item_array_at(&op_ctx->items, base_pkg_index + 1);
858 obj = item->obj;
859
860 if (obj != UACPI_NULL && obj->type == UACPI_OBJECT_REFERENCE) {
861 /*
862 * For named objects we don't actually need the object itself, but
863 * simply the path to it. Often times objects referenced by the
864 * package are not defined until later so it's not possible to
865 * resolve them. For uniformity and to follow the behavior of NT,
866 * simply convert the name string to a path string object to be
867 * resolved later when actually needed.
868 */
869 if (obj->flags == UACPI_REFERENCE_KIND_NAMED) {
872 obj = UACPI_NULL;
873 } else {
875 }
876 }
877
878 if (obj == UACPI_NULL) {
881
885
887 ctx->cur_frame,
888 item_array_at(&op_ctx->items, base_pkg_index)->immediate,
889 &path, &length
890 );
893 return ret;
894 }
895
897 obj->buffer->text = path;
898 obj->buffer->size = length;
899
900 item->obj = obj;
902 }
903
904 ret = uacpi_object_assign(package->objects[i], obj,
907 return ret;
908 }
909
910 return UACPI_STATUS_OK;
911}
@ UACPI_PREALLOC_OBJECTS_YES
Definition: types.h:293
uacpi_bool uacpi_package_fill(uacpi_package *pkg, uacpi_size num_elements, enum uacpi_prealloc_objects prealloc_objects)
Definition: types.c:124
@ UACPI_STRING_KIND_PATH
Definition: types.h:21
static uacpi_status name_string_to_path(struct call_frame *frame, uacpi_size offset, uacpi_char **out_string, uacpi_size *out_size)
Definition: interpreter.c:367

◆ handle_ref_of()

static uacpi_status handle_ref_of ( struct execution_context ctx)
static

Definition at line 2434 of file interpreter.c.

2435{
2436 struct op_context *op_ctx = ctx->cur_op_ctx;
2437 uacpi_object *dst, *src;
2438
2439 src = item_array_at(&op_ctx->items, 0)->obj;
2440
2441 if (op_ctx->op->code == UACPI_AML_OP_CondRefOfOp)
2442 dst = item_array_at(&op_ctx->items, 2)->obj;
2443 else
2444 dst = item_array_at(&op_ctx->items, 1)->obj;
2445
2447 dst->inner_object = src;
2449 return UACPI_STATUS_OK;
2450}

◆ handle_return()

static uacpi_status handle_return ( struct execution_context ctx)
static

Definition at line 4225 of file interpreter.c.

4226{
4229
4230 ctx->cur_frame->code_offset = ctx->cur_frame->method->size;
4232
4234 return ret;
4235 if (dst == UACPI_NULL)
4236 return UACPI_STATUS_OK;
4237
4238 /*
4239 * Should be possible to move here if method returns a literal
4240 * like Return(Buffer { ... }), otherwise we have to copy just to
4241 * be safe.
4242 */
4243 return uacpi_object_assign(
4244 dst,
4245 item_array_at(&ctx->cur_op_ctx->items, 0)->obj,
4247 );
4248}
static uacpi_status method_get_ret_object(struct execution_context *ctx, uacpi_object **out_obj)
Definition: interpreter.c:1988

◆ handle_sizeof()

static uacpi_status handle_sizeof ( struct execution_context ctx)
static

Definition at line 3120 of file interpreter.c.

3121{
3122 struct op_context *op_ctx = ctx->cur_op_ctx;
3123 uacpi_object *src, *dst;
3124
3125 src = item_array_at(&op_ctx->items, 0)->obj;
3126 dst = item_array_at(&op_ctx->items, 1)->obj;
3127
3130
3131 switch (src->type) {
3133 case UACPI_OBJECT_BUFFER: {
3136
3137 dst->integer = buf.length;
3138 break;
3139 }
3140
3142 dst->integer = src->package->count;
3143 break;
3144
3145 default:
3147 "invalid argument for Sizeof: %s, "
3148 "expected String/Buffer/Package",
3150 );
3152 }
3153
3154 return UACPI_STATUS_OK;
3155}

◆ handle_stall_or_sleep()

static uacpi_status handle_stall_or_sleep ( struct execution_context ctx)
static

Definition at line 3186 of file interpreter.c.

3187{
3188 struct op_context *op_ctx = ctx->cur_op_ctx;
3190
3191 time = item_array_at(&op_ctx->items, 0)->obj->integer;
3192
3193 if (op_ctx->op->code == UACPI_AML_OP_SleepOp) {
3194 /*
3195 * ACPICA doesn't allow sleeps longer than 2 seconds,
3196 * so we shouldn't either.
3197 */
3198 if (time > 2000)
3199 time = 2000;
3200
3204 } else {
3205 // Spec says this must evaluate to a ByteData
3206 if (time > 0xFF)
3207 time = 0xFF;
3209 }
3210
3211 return UACPI_STATUS_OK;
3212}
void uacpi_kernel_stall(uacpi_u8 usec)
Definition: uacpiosl.c:42
void uacpi_kernel_sleep(uacpi_u64 msec)
Definition: uacpiosl.c:47
__u16 time
Definition: mkdosfs.c:8

◆ handle_string()

static uacpi_status handle_string ( struct execution_context ctx)
static

Definition at line 774 of file interpreter.c.

775{
776 struct call_frame *frame = ctx->cur_frame;
778
780 uacpi_size length, max_bytes;
781
782 obj = item_array_last(&ctx->cur_op_ctx->items)->obj;
783 string = call_frame_cursor(frame);
784
785 // TODO: sanitize string for valid UTF-8
786 max_bytes = call_frame_code_bytes_left(frame);
787 length = uacpi_strnlen(string, max_bytes);
788
789 if (uacpi_unlikely((length == max_bytes) || (string[length++] != 0x00)))
791
792 obj->buffer->text = uacpi_kernel_alloc(length);
793 if (uacpi_unlikely(obj->buffer->text == UACPI_NULL))
795
796 uacpi_memcpy(obj->buffer->text, string, length);
797 obj->buffer->size = length;
798 frame->code_offset += length;
799 return UACPI_STATUS_OK;
800}
uacpi_size uacpi_strnlen(const uacpi_char *str, uacpi_size max)
Definition: stdlib.c:85
char string[160]
Definition: util.h:11

◆ handle_timer()

static uacpi_status handle_timer ( struct execution_context ctx)
static

Definition at line 3175 of file interpreter.c.

3176{
3177 struct op_context *op_ctx = ctx->cur_op_ctx;
3179
3180 dst = item_array_at(&op_ctx->items, 0)->obj;
3182
3183 return UACPI_STATUS_OK;
3184}

◆ handle_to()

static uacpi_status handle_to ( struct execution_context ctx)
static

Definition at line 2822 of file interpreter.c.

2823{
2825 struct op_context *op_ctx = ctx->cur_op_ctx;
2826 uacpi_object *src, *dst;
2827
2828 src = item_array_at(&op_ctx->items, 0)->obj;
2829 dst = item_array_at(&op_ctx->items, 2)->obj;
2830
2831 switch (op_ctx->op->code) {
2832 case UACPI_AML_OP_ToIntegerOp:
2833 dst->integer = object_to_integer(src, sizeof_int());
2834 break;
2835
2836 case UACPI_AML_OP_ToHexStringOp:
2837 case UACPI_AML_OP_ToDecimalStringOp: {
2838 uacpi_bool is_hex = op_ctx->op->code == UACPI_AML_OP_ToHexStringOp;
2839
2840 if (src->type == UACPI_OBJECT_INTEGER) {
2841 ret = integer_to_string(src->integer, dst->buffer, is_hex);
2842 break;
2843 } else if (src->type == UACPI_OBJECT_BUFFER) {
2844 if (uacpi_unlikely(src->buffer->size == 0))
2845 return make_null_string(dst->buffer);
2846
2847 ret = buffer_to_string(src->buffer, dst->buffer, is_hex);
2848 break;
2849 }
2851 }
2852 case UACPI_AML_OP_ToBufferOp: {
2854 uacpi_u8 *dst_buf;
2855
2858 return ret;
2859
2860 if (uacpi_unlikely(buf.length == 0))
2861 return make_null_buffer(dst->buffer);
2862
2863 dst_buf = uacpi_kernel_alloc(buf.length);
2864 if (uacpi_unlikely(dst_buf == UACPI_NULL))
2866
2867 uacpi_memcpy(dst_buf, buf.bytes, buf.length);
2868 dst->buffer->data = dst_buf;
2869 dst->buffer->size = buf.length;
2870 break;
2871 }
2872
2873 default:
2875 }
2876
2877 return ret;
2878}
static uacpi_status integer_to_string(uacpi_u64 integer, uacpi_buffer *str, uacpi_bool is_hex)
Definition: interpreter.c:2700

◆ handle_to_string()

static uacpi_status handle_to_string ( struct execution_context ctx)
static

Definition at line 2880 of file interpreter.c.

2881{
2882 struct op_context *op_ctx = ctx->cur_op_ctx;
2883 uacpi_buffer *src_buf, *dst_buf;
2884 uacpi_size req_len, len;
2885
2886 src_buf = item_array_at(&op_ctx->items, 0)->obj->buffer;
2887 req_len = item_array_at(&op_ctx->items, 1)->obj->integer;
2888 dst_buf = item_array_at(&op_ctx->items, 3)->obj->buffer;
2889
2890 len = UACPI_MIN(req_len, src_buf->size);
2891 if (uacpi_unlikely(len == 0))
2892 return make_null_string(dst_buf);
2893
2894 len = uacpi_strnlen(src_buf->text, len);
2895
2896 dst_buf->text = uacpi_kernel_alloc(len + 1);
2897 if (uacpi_unlikely(dst_buf->text == UACPI_NULL))
2899
2900 uacpi_memcpy(dst_buf->text, src_buf->data, len);
2901 dst_buf->text[len] = '\0';
2902 dst_buf->size = len + 1;
2903
2904 return UACPI_STATUS_OK;
2905}

◆ handle_unary_math()

static uacpi_status handle_unary_math ( struct execution_context ctx)
static

Definition at line 2547 of file interpreter.c.

2548{
2549 uacpi_object *arg, *tgt;
2550 struct item_array *items = &ctx->cur_op_ctx->items;
2551 uacpi_aml_op op = ctx->cur_op_ctx->op->code;
2552
2553 arg = item_array_at(items, 0)->obj;
2554 tgt = item_array_at(items, 2)->obj;
2555
2556 switch (op) {
2557 case UACPI_AML_OP_NotOp:
2558 tgt->integer = ~arg->integer;
2560 break;
2561 case UACPI_AML_OP_FindSetRightBitOp:
2562 tgt->integer = uacpi_bit_scan_forward(arg->integer);
2563 break;
2564 case UACPI_AML_OP_FindSetLeftBitOp:
2565 tgt->integer = uacpi_bit_scan_backward(arg->integer);
2566 break;
2567 default:
2569 }
2570
2571 return UACPI_STATUS_OK;
2572}
uacpi_u8 uacpi_bit_scan_forward(uacpi_u64)
Definition: stdlib.c:124
uacpi_u8 uacpi_bit_scan_backward(uacpi_u64)
Definition: stdlib.c:166
void * arg
Definition: msvc.h:10

◆ handle_unload()

static uacpi_status handle_unload ( struct execution_context ctx)
static

Definition at line 3251 of file interpreter.c.

3252{
3254
3255 /*
3256 * Technically this doesn't exist in the wild, from the dumps that I have
3257 * the only user of the Unload opcode is the Surface Pro 3, which triggers
3258 * an unload of some I2C-related table as a response to some event.
3259 *
3260 * This op has been long deprecated by the specification exactly because
3261 * it hasn't really been used by anyone and the fact that it introduces
3262 * an enormous layer of complexity, which no driver is really prepared to
3263 * deal with (aka namespace nodes disappearing under its feet).
3264 *
3265 * Just pretend we have actually unloaded whatever the AML asked for, if it
3266 * ever tries to re-load this table that will just skip opcodes that create
3267 * already existing objects, which should be good enough and mostly
3268 * transparent to the AML.
3269 */
3270 uacpi_warn("refusing to unload a table from AML");
3271 return UACPI_STATUS_OK;
3272}
#define UACPI_UNUSED(x)
Definition: helpers.h:7

◆ held_mutexes_array_remove_and_release()

static uacpi_status held_mutexes_array_remove_and_release ( struct held_mutexes_array *  arr,
uacpi_mutex mutex,
enum force_release  force 
)
static

Definition at line 185 of file interpreter.c.

189{
192
193 if (uacpi_unlikely(held_mutexes_array_size(arr) == 0))
195
196 item = *held_mutexes_array_last(arr);
197
198 if (uacpi_unlikely(item->sync_level != mutex->sync_level &&
201 "ignoring mutex @%p release due to sync level mismatch: %d vs %d",
202 mutex, mutex->sync_level, item->sync_level
203 );
204
205 // We still return OK because we don't want to abort because of this
206 return UACPI_STATUS_OK;
207 }
208
209 if (mutex->depth > 1 && force == FORCE_RELEASE_NO) {
211 return UACPI_STATUS_OK;
212 }
213
214 // Fast path for well-behaved AML that releases mutexes in descending order
215 if (uacpi_likely(item == mutex)) {
216 held_mutexes_array_pop(arr);
217 goto do_release;
218 }
219
220 /*
221 * The mutex being released is not the last one acquired, although we did
222 * verify that at least it has the same sync level. Anyway, now we have
223 * to search for it and then remove it from the array while shifting
224 * everything backwards.
225 */
226 i = held_mutexes_array_size(arr);
227 for (;;) {
228 item = *held_mutexes_array_at(arr, --i);
229 if (item == mutex)
230 break;
231
232 if (uacpi_unlikely(i == 0))
234 }
235
237
238do_release:
239 // This is either a force release, or depth was already 1 to begin with
240 mutex->depth = 1;
242
244 return UACPI_STATUS_OK;
245}
BOOL force
Definition: metahost.c:100
void uacpi_mutex_unref(uacpi_mutex *)
Definition: types.c:495
static void held_mutexes_array_remove_idx(struct held_mutexes_array *arr, uacpi_size i)
Definition: interpreter.c:128

Referenced by ctx_reload_post_ret(), execution_context_release(), and handle_mutex_ctl().

◆ held_mutexes_array_remove_idx()

static void held_mutexes_array_remove_idx ( struct held_mutexes_array *  arr,
uacpi_size  i 
)
static

Definition at line 128 of file interpreter.c.

131{
133
134 size = held_mutexes_array_inline_capacity(arr);
135
136 // Only the dynamic array part is affected
137 if (i >= size) {
138 i -= size;
139 size = arr->size_including_inline - size;
140 size -= i + 1;
141
143 &arr->dynamic_storage[i], &arr->dynamic_storage[i + 1],
144 size * sizeof(arr->inline_storage[0])
145 );
146
147 held_mutexes_array_pop(arr);
148 return;
149 }
150
151 size = UACPI_MIN(held_mutexes_array_inline_capacity(arr),
152 arr->size_including_inline);
153 size -= i + 1;
155 &arr->inline_storage[i], &arr->inline_storage[i + 1],
156 size * sizeof(arr->inline_storage[0])
157 );
158
159 size = held_mutexes_array_size(arr);
160 i = held_mutexes_array_inline_capacity(arr);
161
162 /*
163 * This array has dynamic storage as well, now we have to take the first
164 * dynamic item, move it to the top of inline storage, and then shift all
165 * dynamic items backward by 1 as well.
166 */
167 if (size > i) {
168 arr->inline_storage[i - 1] = arr->dynamic_storage[0];
169 size -= i + 1;
170
172 &arr->dynamic_storage[0], &arr->dynamic_storage[1],
173 size * sizeof(arr->inline_storage[0])
174 );
175 }
176
177 held_mutexes_array_pop(arr);
178}
#define uacpi_memmove
Definition: stdlib.h:43

Referenced by held_mutexes_array_remove_and_release().

◆ init_method_flags()

static void init_method_flags ( uacpi_control_method method,
uacpi_u8  flags_byte 
)
static

Definition at line 3522 of file interpreter.c.

3523{
3524 method->args = flags_byte & 0x7;
3525 method->is_serialized = (flags_byte >> 3) & 1;
3526 method->sync_level = flags_byte >> 4;
3527}

Referenced by handle_create_method().

◆ integer_to_string()

static uacpi_status integer_to_string ( uacpi_u64  integer,
uacpi_buffer str,
uacpi_bool  is_hex 
)
static

Definition at line 2700 of file interpreter.c.

2703{
2704 int repr_len;
2705 uacpi_char int_buf[21];
2706 uacpi_size final_size;
2707
2708 repr_len = uacpi_snprintf(
2709 int_buf, sizeof(int_buf),
2712 );
2713 if (uacpi_unlikely(repr_len < 0))
2715
2716 // 0x prefix + repr + \0
2717 final_size = (is_hex ? 2 : 0) + repr_len + 1;
2718
2719 str->data = uacpi_kernel_alloc(final_size);
2720 if (uacpi_unlikely(str->data == UACPI_NULL))
2722
2723 if (is_hex) {
2724 str->text[0] = '0';
2725 str->text[1] = 'x';
2726 }
2727 uacpi_memcpy(str->text + (is_hex ? 2 : 0), int_buf, repr_len + 1);
2728 str->size = final_size;
2729
2730 return UACPI_STATUS_OK;
2731}

Referenced by handle_to().

◆ is_dynamic_table_load()

static uacpi_bool is_dynamic_table_load ( enum uacpi_table_load_cause  cause)
static

Definition at line 1269 of file interpreter.c.

1270{
1271 return cause != UACPI_TABLE_LOAD_CAUSE_INIT;
1272}
@ UACPI_TABLE_LOAD_CAUSE_INIT
Definition: interpreter.h:12

Referenced by do_load_table(), and prepare_table_load().

◆ make_null_buffer()

static uacpi_status make_null_buffer ( uacpi_buffer buf)
static

Definition at line 2812 of file interpreter.c.

2813{
2814 /*
2815 * Allocate at least 1 byte just to be safe,
2816 * even for empty buffers. We still set the
2817 * size to 0 though.
2818 */
2820}
static uacpi_status do_make_empty_object(uacpi_buffer *buf, uacpi_bool is_string)
Definition: interpreter.c:2794

Referenced by handle_mid(), and handle_to().

◆ make_null_string()

static uacpi_status make_null_string ( uacpi_buffer buf)
static

Definition at line 2807 of file interpreter.c.

2808{
2810}

Referenced by handle_mid(), handle_to(), and handle_to_string().

◆ match_one()

static uacpi_bool match_one ( enum match_op  op,
uacpi_u64  lhs,
uacpi_u64  rhs 
)
static

Definition at line 3399 of file interpreter.c.

3400{
3401 switch (op) {
3402 case MTR:
3403 return UACPI_TRUE;
3404 case MEQ:
3405 return lhs == rhs;
3406 case MLE:
3407 return lhs <= rhs;
3408 case MLT:
3409 return lhs < rhs;
3410 case MGE:
3411 return lhs >= rhs;
3412 case MGT:
3413 return lhs > rhs;
3414 default:
3415 return UACPI_FALSE;
3416 }
3417}

Referenced by handle_match().

◆ maybe_end_block()

static uacpi_bool maybe_end_block ( struct execution_context ctx)
static

Definition at line 4368 of file interpreter.c.

4369{
4370 struct code_block *block = ctx->cur_block;
4371 struct call_frame *cur_frame = ctx->cur_frame;
4372
4373 if (!block)
4374 return UACPI_FALSE;
4375 if (cur_frame->code_offset != block->end)
4376 return UACPI_FALSE;
4377
4378 if (block->type == CODE_BLOCK_WHILE)
4379 cur_frame->code_offset = block->begin;
4380
4382 return UACPI_TRUE;
4383}

Referenced by uacpi_execute_control_method().

◆ method_get_ret_object()

static uacpi_status method_get_ret_object ( struct execution_context ctx,
uacpi_object **  out_obj 
)
static

Definition at line 1988 of file interpreter.c.

1990{
1992
1993 ret = method_get_ret_target(ctx, out_obj);
1994 if (ret == UACPI_STATUS_NOT_FOUND) {
1995 *out_obj = ctx->ret;
1996 return UACPI_STATUS_OK;
1997 }
1998 if (ret != UACPI_STATUS_OK || *out_obj == UACPI_NULL)
1999 return ret;
2000
2001 *out_obj = uacpi_unwrap_internal_reference(*out_obj);
2002 return UACPI_STATUS_OK;
2003}
static uacpi_status method_get_ret_target(struct execution_context *ctx, uacpi_object **out_operand)
Definition: interpreter.c:1948

Referenced by handle_return(), and prepare_method_call().

◆ method_get_ret_target()

static uacpi_status method_get_ret_target ( struct execution_context ctx,
uacpi_object **  out_operand 
)
static

Definition at line 1948 of file interpreter.c.

1950{
1952
1953 // Check if we're targeting the previous call frame
1954 depth = call_frame_array_size(&ctx->call_stack);
1955 if (depth > 1) {
1956 struct op_context *op_ctx;
1957 struct call_frame *frame;
1958
1959 frame = call_frame_array_at(&ctx->call_stack, depth - 2);
1960 depth = op_context_array_size(&frame->pending_ops);
1961
1962 // Ok, no one wants the return value at call site. Discard it.
1963 if (!depth) {
1964 *out_operand = UACPI_NULL;
1965 return UACPI_STATUS_OK;
1966 }
1967
1968 op_ctx = op_context_array_at(&frame->pending_ops, depth - 1);
1969
1970 /*
1971 * Prevent the table being dynamically loaded from attempting to return
1972 * a value to the caller. This is unlikely to be ever encountered in the
1973 * wild, but we should still guard against the possibility.
1974 */
1975 if (uacpi_unlikely(op_ctx->op->code == UACPI_AML_OP_LoadOp ||
1976 op_ctx->op->code == UACPI_AML_OP_LoadTableOp)) {
1977 *out_operand = UACPI_NULL;
1978 return UACPI_STATUS_OK;
1979 }
1980
1981 *out_operand = item_array_last(&op_ctx->items)->obj;
1982 return UACPI_STATUS_OK;
1983 }
1984
1986}
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546

Referenced by method_get_ret_object().

◆ name_string_to_path()

static uacpi_status name_string_to_path ( struct call_frame frame,
uacpi_size  offset,
uacpi_char **  out_string,
uacpi_size out_size 
)
static

Definition at line 367 of file interpreter.c.

371{
372 uacpi_size bytes_left, prefix_bytes, nameseg_bytes = 0, namesegs;
373 uacpi_char *base_cursor, *cursor;
374 uacpi_char prev_char;
375
376 bytes_left = frame->method->size - offset;
377 cursor = (uacpi_char*)frame->method->code + offset;
378 base_cursor = cursor;
379 namesegs = 0;
380
381 prefix_bytes = 0;
382 for (;;) {
383 if (uacpi_unlikely(bytes_left == 0))
385
386 prev_char = *cursor;
387
388 switch (prev_char) {
389 case '^':
390 case '\\':
391 prefix_bytes++;
392 cursor++;
393 bytes_left--;
394 break;
395 default:
396 break;
397 }
398
399 if (prev_char != '^')
400 break;
401 }
402
403 // At least a NullName byte is expected here
404 if (uacpi_unlikely(bytes_left == 0))
406
407 namesegs = 0;
408 bytes_left--;
409 switch (*cursor++)
410 {
412 namesegs = 2;
413 break;
415 if (uacpi_unlikely(bytes_left == 0))
417
418 namesegs = *(uacpi_u8*)cursor;
419 if (uacpi_unlikely(namesegs == 0)) {
420 uacpi_error("MultiNamePrefix but SegCount is 0");
422 }
423
424 cursor++;
425 bytes_left--;
426 break;
427 case UACPI_NULL_NAME:
428 break;
429 default:
430 /*
431 * Might be an invalid byte, but assume single nameseg for now,
432 * the code below will validate it for us.
433 */
434 cursor--;
435 bytes_left++;
436 namesegs = 1;
437 break;
438 }
439
440 if (uacpi_unlikely((namesegs * 4) > bytes_left))
442
443 if (namesegs) {
444 // 4 chars per nameseg
445 nameseg_bytes = namesegs * 4;
446
447 // dot separator for every nameseg
448 nameseg_bytes += namesegs - 1;
449 }
450
451 *out_size = nameseg_bytes + prefix_bytes + 1;
452
453 *out_string = uacpi_kernel_alloc(*out_size);
454 if (*out_string == UACPI_NULL)
456
457 uacpi_memcpy(*out_string, base_cursor, prefix_bytes);
458
459 base_cursor = *out_string;
460 base_cursor += prefix_bytes;
461
462 while (namesegs-- > 0) {
463 uacpi_memcpy(base_cursor, cursor, 4);
464 cursor += 4;
465 base_cursor += 4;
466
467 if (namesegs)
468 *base_cursor++ = '.';
469 }
470
471 *base_cursor = '\0';
472 return UACPI_STATUS_OK;
473}
#define UACPI_DUAL_NAME_PREFIX
Definition: opcodes.h:10
#define UACPI_MULTI_NAME_PREFIX
Definition: opcodes.h:11
#define UACPI_NULL_NAME
Definition: opcodes.h:12
@ UACPI_STATUS_AML_INVALID_NAMESTRING
Definition: status.h:35
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)

Referenced by handle_package(), and trace_named_object_lookup_or_creation_failure().

◆ object_assign_with_implicit_cast()

static uacpi_status object_assign_with_implicit_cast ( uacpi_object dst,
uacpi_object src,
uacpi_data_view wtr_response 
)
static

Definition at line 975 of file interpreter.c.

978{
980 uacpi_data_view src_buf;
981
984 goto out_bad_cast;
985
986 switch (dst->type) {
989 case UACPI_OBJECT_BUFFER: {
990 uacpi_data_view dst_buf;
991
994 goto out_bad_cast;
995
997 dst_buf.bytes, src_buf.bytes, dst_buf.length, src_buf.length
998 );
999 break;
1000 }
1001
1004 &dst->buffer_field, src_buf.bytes, src_buf.length
1005 );
1006 break;
1007
1010 dst->field_unit, src_buf.bytes, src_buf.length,
1011 wtr_response
1012 );
1013
1015 write_buffer_index(&dst->buffer_index, &src_buf);
1016 break;
1017
1018 default:
1020 goto out_bad_cast;
1021 }
1022
1023 return ret;
1024
1025out_bad_cast:
1027 "attempted to perform an invalid implicit cast (%s -> %s)",
1030 );
1031 return ret;
1032}
void uacpi_write_buffer_field(uacpi_buffer_field *field, const void *src, uacpi_size size)
Definition: io.c:148
uacpi_status uacpi_write_field_unit(uacpi_field_unit *field, const void *src, uacpi_size size, uacpi_data_view *wtr_response)
Definition: io.c:662
static void write_buffer_index(uacpi_buffer_index *buf_idx, uacpi_data_view *src_buf)
Definition: interpreter.c:963

Referenced by store_to_reference(), and store_to_target().

◆ object_replace_child()

static void object_replace_child ( uacpi_object parent,
uacpi_object new_child 
)
static

Definition at line 2286 of file interpreter.c.

2287{
2288 if (parent->flags == UACPI_REFERENCE_KIND_NAMED &&
2290
2291 /*
2292 * We're doing a CopyObject or similar to a namespace node that is an
2293 * operation region. Try to find the parent node and manually detach
2294 * the handler.
2295 */
2301 );
2302 }
2303
2306}
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)
Definition: namespace.c:834
void uacpi_object_detach_child(uacpi_object *parent)
Definition: types.c:966
void uacpi_object_attach_child(uacpi_object *parent, uacpi_object *child)
Definition: types.c:950
#define UACPI_MAX_DEPTH_ANY
Definition: namespace.h:102
@ UACPI_OBJECT_OPERATION_REGION_BIT
Definition: types.h:144
uacpi_bool uacpi_object_is(uacpi_object *, uacpi_object_type)
Definition: types.c:992
static uacpi_iteration_decision opregion_try_detach_from_parent(void *user, uacpi_namespace_node *node, uacpi_u32 node_depth)
Definition: interpreter.c:2271

Referenced by copy_object_to_reference(), and store_to_reference().

◆ object_to_integer()

static uacpi_u64 object_to_integer ( const uacpi_object obj,
uacpi_size  max_buffer_bytes 
)
static

Definition at line 2672 of file interpreter.c.

2674{
2675 uacpi_u64 dst;
2676
2677 switch (obj->type) {
2679 dst = obj->integer;
2680 break;
2681 case UACPI_OBJECT_BUFFER: {
2683 bytes = UACPI_MIN(max_buffer_bytes, obj->buffer->size);
2684 uacpi_memcpy_zerout(&dst, obj->buffer->data, sizeof(dst), bytes);
2685 break;
2686 }
2689 obj->buffer->text, obj->buffer->size, UACPI_BASE_AUTO, &dst
2690 );
2691 break;
2692 default:
2693 dst = 0;
2694 break;
2695 }
2696
2697 return dst;
2698}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
uacpi_status uacpi_string_to_integer(const uacpi_char *str, uacpi_size max_chars, enum uacpi_base base, uacpi_u64 *out_value)
Definition: utilities.c:233
@ UACPI_BASE_AUTO
Definition: utilities.h:31

Referenced by handle_binary_logic(), handle_concatenate(), and handle_to().

◆ ones()

static uacpi_u64 ones ( void  )
static

Definition at line 1943 of file interpreter.c.

1944{
1945 return g_uacpi_rt_ctx.is_rev1 ? 0xFFFFFFFF : 0xFFFFFFFFFFFFFFFF;
1946}

Referenced by exec_op(), handle_binary_logic(), handle_logical_not(), handle_match(), TestSSEExceptions(), and uacpi_osi().

◆ op_allows_unresolved()

static uacpi_bool op_allows_unresolved ( enum uacpi_parse_op  op)
static

Definition at line 4774 of file interpreter.c.

4775{
4776 switch (op) {
4780 return UACPI_TRUE;
4781 default:
4782 return UACPI_FALSE;
4783 }
4784}

Referenced by exec_op().

◆ op_allows_unresolved_if_load()

static uacpi_bool op_allows_unresolved_if_load ( enum uacpi_parse_op  op)
static

Definition at line 4786 of file interpreter.c.

4787{
4788 switch (op) {
4791 return UACPI_TRUE;
4792 default:
4793 return UACPI_FALSE;
4794 }
4795}

Referenced by exec_op().

◆ op_decode_aml_op()

static uacpi_aml_op op_decode_aml_op ( struct op_context op_ctx)
static

Definition at line 4708 of file interpreter.c.

4709{
4710 uacpi_aml_op op = 0;
4711
4712 op |= op_decode_byte(op_ctx);
4713 op |= op_decode_byte(op_ctx) << 8;
4714
4715 return op;
4716}

Referenced by exec_op().

◆ op_decode_byte()

static uacpi_u8 op_decode_byte ( struct op_context ctx)
static

Definition at line 4698 of file interpreter.c.

4699{
4700 uacpi_u8 byte;
4701
4702 byte = *op_decode_cursor(ctx);
4703 ctx->pc++;
4704
4705 return byte;
4706}
#define byte(x, n)
Definition: tomcrypt.h:118

Referenced by exec_op(), and op_decode_aml_op().

◆ op_decode_cursor()

static const uacpi_u8 * op_decode_cursor ( const struct op_context ctx)
static

Definition at line 4688 of file interpreter.c.

4689{
4690 const struct uacpi_op_spec *spec = ctx->op;
4691
4693 return &spec->indirect_decode_ops[ctx->pc];
4694
4695 return &spec->decode_ops[ctx->pc];
4696}
@ UACPI_OP_PROPERTY_OUT_OF_LINE
Definition: opcodes.h:279
uacpi_u8 * indirect_decode_ops
Definition: opcodes.h:296
uacpi_u8 properties
Definition: opcodes.h:298
uacpi_u8 decode_ops[16]
Definition: opcodes.h:295

Referenced by exec_op(), op_decode_byte(), and op_typecheck().

◆ op_is_internal()

static bool op_is_internal ( const struct uacpi_op_spec op)
inlinestatic

Definition at line 686 of file interpreter.c.

687{
688 return (op->properties & UACPI_OP_PROPERTY_INTERNAL) != 0;
689}
@ UACPI_OP_PROPERTY_INTERNAL
Definition: opcodes.h:289

Referenced by get_op(), and stack_unwind().

◆ op_is_invalid()

static bool op_is_invalid ( const struct uacpi_op_spec op)
inlinestatic

Definition at line 691 of file interpreter.c.

692{
693 return (op->properties & UACPI_OP_PROPERTY_INVALID) != 0;
694}
@ UACPI_OP_PROPERTY_INVALID
Definition: opcodes.h:282

Referenced by get_op().

◆ op_typecheck()

static uacpi_status op_typecheck ( const struct op_context op_ctx,
const struct op_context cur_op_ctx 
)
static

Definition at line 4797 of file interpreter.c.

4799{
4800 const uacpi_char *expected_type_str;
4801 uacpi_u8 ok_mask = 0;
4802 uacpi_u8 props = cur_op_ctx->op->properties;
4803
4804 switch (*op_decode_cursor(op_ctx)) {
4805 // SimpleName := NameString | ArgObj | LocalObj
4807 expected_type_str = SPEC_SIMPLE_NAME;
4809 break;
4810
4811 // Target := SuperName | NullName
4813 expected_type_str = SPEC_TARGET;
4815 break;
4816
4817 // SuperName := SimpleName | DebugObj | ReferenceTypeOpcode
4820 expected_type_str = SPEC_SUPER_NAME;
4821 ok_mask |= UACPI_OP_PROPERTY_SUPERNAME;
4822 break;
4823
4824 // TermArg := ExpressionOpcode | DataObject | ArgObj | LocalObj
4832 expected_type_str = SPEC_TERM_ARG;
4833 ok_mask |= UACPI_OP_PROPERTY_TERM_ARG;
4834 break;
4835 default:
4837 }
4838
4839 if (!(props & ok_mask)) {
4840 EXEC_OP_ERR_2("invalid argument: '%s', expected a %s",
4841 cur_op_ctx->op->name, expected_type_str);
4843 }
4844
4845 return UACPI_STATUS_OK;
4846}
@ UACPI_OP_PROPERTY_SIMPLE_NAME
Definition: opcodes.h:275
@ UACPI_OP_PROPERTY_TERM_ARG
Definition: opcodes.h:273
@ UACPI_OP_PROPERTY_SUPERNAME
Definition: opcodes.h:274
@ UACPI_OP_PROPERTY_TARGET
Definition: opcodes.h:276
#define SPEC_TERM_ARG
Definition: interpreter.c:4737
#define SPEC_SUPER_NAME
Definition: interpreter.c:4735
#define SPEC_TARGET
Definition: interpreter.c:4741
#define SPEC_SIMPLE_NAME
Definition: interpreter.c:4734
static const WCHAR props[]
Definition: wbemdisp.c:288

Referenced by exec_op().

◆ op_wants_supername()

static uacpi_bool op_wants_supername ( enum uacpi_parse_op  op)
static

Definition at line 4747 of file interpreter.c.

4748{
4749 switch (op) {
4754 return UACPI_TRUE;
4755 default:
4756 return UACPI_FALSE;
4757 }
4758}

Referenced by exec_op().

◆ op_wants_term_arg_or_operand()

static uacpi_bool op_wants_term_arg_or_operand ( enum uacpi_parse_op  op)
static

Definition at line 4760 of file interpreter.c.

4761{
4762 switch (op) {
4768 return UACPI_TRUE;
4769 default:
4770 return UACPI_FALSE;
4771 }
4772}

Referenced by exec_op().

◆ opregion_try_detach_from_parent()

static uacpi_iteration_decision opregion_try_detach_from_parent ( void user,
uacpi_namespace_node node,
uacpi_u32  node_depth 
)
static

Definition at line 2271 of file interpreter.c.

2274{
2275 uacpi_object *target_object = user;
2276 UACPI_UNUSED(node_depth);
2277
2278 if (node->object == target_object) {
2281 }
2282
2284}
void user(int argc, const char *argv[])
Definition: cmds.c:1350
@ UACPI_ITERATION_DECISION_BREAK
Definition: types.h:30
@ UACPI_ITERATION_DECISION_CONTINUE
Definition: types.h:29
void uacpi_opregion_uninstall_handler(uacpi_namespace_node *node)
Definition: opregion.c:403

Referenced by object_replace_child().

◆ parse_nameseg()

static uacpi_status parse_nameseg ( uacpi_u8 cursor,
uacpi_object_name out_name 
)
static

Definition at line 342 of file interpreter.c.

344{
347
348 uacpi_memcpy(&out_name->id, cursor, 4);
349 return UACPI_STATUS_OK;
350}
uacpi_bool uacpi_is_valid_nameseg(uacpi_u8 *nameseg)
Definition: utilities.c:315
uacpi_u32 id
Definition: types.h:25

Referenced by resolve_name_string().

◆ parse_package_length()

static uacpi_status parse_package_length ( struct call_frame frame,
struct package_length out_pkg 
)
static

Definition at line 3464 of file interpreter.c.

3466{
3468 uacpi_u8 *data, marker_length;
3469
3470 out_pkg->begin = frame->code_offset;
3471 marker_length = 1;
3472
3474 if (uacpi_unlikely(left < 1))
3476
3477 data = call_frame_cursor(frame);
3478 marker_length += *data >> 6;
3479
3480 if (uacpi_unlikely(left < marker_length))
3482
3483 switch (marker_length) {
3484 case 1:
3485 size = *data & 0x3F;
3486 break;
3487 case 2:
3488 case 3:
3489 case 4: {
3490 uacpi_u32 temp_byte = 0;
3491
3492 size = *data & 0xF;
3493 uacpi_memcpy(&temp_byte, data + 1, marker_length - 1);
3494
3495 // marker_length - 1 is at most 3, so this shift is safe
3496 size |= temp_byte << 4;
3497 break;
3498 }
3499 }
3500
3501 frame->code_offset += marker_length;
3502
3503 out_pkg->end = out_pkg->begin + size;
3504 if (uacpi_unlikely(out_pkg->end < out_pkg->begin)) {
3506 "PkgLength overflow: start=%u, size=%u", out_pkg->begin, size
3507 );
3509 }
3510
3511 return UACPI_STATUS_OK;
3512}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint left
Definition: glext.h:7726

Referenced by exec_op().

◆ peek_next_op()

static uacpi_u8 peek_next_op ( struct call_frame frame,
uacpi_aml_op out_op 
)
static

Definition at line 658 of file interpreter.c.

659{
661 uacpi_size bytes_left;
662 uacpi_u8 length = 0;
664 struct code_block *block;
665
666 block = code_block_array_last(&frame->code_blocks);
667 bytes_left = block->end - frame->code_offset;
668 if (bytes_left == 0)
669 return 0;
670
671 cursor = call_frame_cursor(frame);
672
673 op = AML_READ(cursor, length++);
674 if (op == UACPI_EXT_PREFIX) {
675 if (uacpi_unlikely(bytes_left < 2))
676 return 0;
677
678 op <<= 8;
679 op |= AML_READ(cursor, length++);
680 }
681
682 *out_op = op;
683 return length;
684}
#define UACPI_EXT_PREFIX
Definition: opcodes.h:7
#define AML_READ(ptr, offset)
Definition: interpreter.c:340

Referenced by exec_op(), and get_op().

◆ pop_item()

static uacpi_bool pop_item ( struct op_context op_ctx)
static

Definition at line 4600 of file interpreter.c.

4601{
4602 struct item *item;
4603
4604 if (item_array_size(&op_ctx->items) == 0)
4605 return UACPI_FALSE;
4606
4607 item = item_array_last(&op_ctx->items);
4608
4609 if (item->type == ITEM_OBJECT)
4611
4614
4615 item_array_pop(&op_ctx->items);
4616 return UACPI_TRUE;
4617}
void uacpi_namespace_node_unref(uacpi_namespace_node *node)
Definition: namespace.c:294

Referenced by exec_op(), and pop_op().

◆ pop_op()

static void pop_op ( struct execution_context ctx)
static

Definition at line 4619 of file interpreter.c.

4620{
4621 struct call_frame *frame = ctx->cur_frame;
4622 struct op_context *cur_op_ctx = ctx->cur_op_ctx;
4623
4624 while (pop_item(cur_op_ctx));
4625
4626 item_array_clear(&cur_op_ctx->items);
4627 op_context_array_pop(&frame->pending_ops);
4629}

Referenced by exec_op(), and stack_unwind().

◆ prepare_method_call()

static uacpi_status prepare_method_call ( struct execution_context ctx,
uacpi_namespace_node node,
uacpi_control_method method,
enum method_call_type  type,
const uacpi_object_array args 
)
static

Definition at line 5246 of file interpreter.c.

5251{
5253 struct call_frame *frame;
5254
5255 if (uacpi_unlikely(call_frame_array_size(&ctx->call_stack) >=
5256 g_uacpi_rt_ctx.max_call_stack_depth))
5258
5259 ret = push_new_frame(ctx, &frame);
5261 return ret;
5262
5263 ret = enter_method(ctx, frame, method);
5265 goto method_dispatch_error;
5266
5267 if (type == METHOD_CALL_NATIVE) {
5268 uacpi_u8 arg_count;
5269
5270 arg_count = args ? args->count : 0;
5271 if (uacpi_unlikely(arg_count != method->args)) {
5273 "invalid number of arguments %zu to call %.4s, expected %d",
5274 args ? args->count : 0, node->name.text, method->args
5275 );
5276
5278 goto method_dispatch_error;
5279 }
5280
5281 if (args != UACPI_NULL) {
5282 uacpi_u8 i;
5283
5284 for (i = 0; i < method->args; ++i) {
5285 frame->args[i] = args->objects[i];
5286 uacpi_object_ref(args->objects[i]);
5287 }
5288 }
5289 } else if (type == METHOD_CALL_AML) {
5290 ret = frame_push_args(frame, ctx->cur_op_ctx);
5292 goto method_dispatch_error;
5293 }
5294
5297 goto method_dispatch_error;
5298
5299 ctx->cur_frame = frame;
5300 ctx->cur_op_ctx = UACPI_NULL;
5301 ctx->prev_op_ctx = UACPI_NULL;
5302 ctx->cur_block = code_block_array_last(&ctx->cur_frame->code_blocks);
5303
5304 if (method->native_call) {
5306
5309 goto method_dispatch_error;
5310
5311 return method->handler(ctx, retval);
5312 }
5313
5314 return UACPI_STATUS_OK;
5315
5316method_dispatch_error:
5317 call_frame_clear(frame);
5318 call_frame_array_pop(&ctx->call_stack);
5319 return ret;
5320}
@ UACPI_STATUS_AML_CALL_STACK_DEPTH_LIMIT
Definition: status.h:44
static uacpi_status frame_setup_base_scope(struct call_frame *frame, uacpi_namespace_node *scope, uacpi_control_method *method)
Definition: interpreter.c:4327
static uacpi_status enter_method(struct execution_context *ctx, struct call_frame *new_frame, uacpi_control_method *method)
Definition: interpreter.c:4541
static uacpi_status push_new_frame(struct execution_context *ctx, struct call_frame **out_frame)
Definition: interpreter.c:4346
static uacpi_status frame_push_args(struct call_frame *frame, struct op_context *op_ctx)
Definition: interpreter.c:4298
Definition: match.c:390
int retval
Definition: wcstombs.cpp:91

Referenced by exec_op(), and uacpi_execute_control_method().

◆ prepare_table_load()

static uacpi_status prepare_table_load ( void ptr,
enum uacpi_table_load_cause  cause,
uacpi_control_method in_method 
)
static

Definition at line 1274 of file interpreter.c.

1278{
1279 struct acpi_dsdt *dsdt = ptr;
1280 uacpi_log_level log_level = UACPI_LOG_TRACE;
1281 const uacpi_char *log_prefix = "load of";
1282
1283 if (uacpi_unlikely(dsdt->hdr.length < sizeof(dsdt->hdr)))
1285
1286 if (is_dynamic_table_load(cause)) {
1287 log_prefix = cause == UACPI_TABLE_LOAD_CAUSE_HOST ?
1288 "host-invoked load of" : "dynamic load of";
1289 log_level = UACPI_LOG_INFO;
1290 }
1291
1293 log_level, "%s "UACPI_PRI_TBL_HDR,
1294 log_prefix, UACPI_FMT_TBL_HDR(&dsdt->hdr)
1295 );
1296
1297 in_method->code = dsdt->definition_block;
1298 in_method->size = dsdt->hdr.length - sizeof(dsdt->hdr);
1299 in_method->named_objects_persist = UACPI_TRUE;
1300
1301 return UACPI_STATUS_OK;
1302}
#define uacpi_log_lvl(lvl, fmt,...)
Definition: log.h:22
@ UACPI_LOG_INFO
Definition: log.h:24
#define UACPI_PRI_TBL_HDR
Definition: tables.h:58
#define UACPI_FMT_TBL_HDR(hdr)
Definition: tables.h:59
@ UACPI_TABLE_LOAD_CAUSE_HOST
Definition: interpreter.h:13
static PVOID ptr
Definition: dispmode.c:27
uacpi_u8 named_objects_persist
Definition: types.h:178
uacpi_u8 * code
Definition: types.h:170

Referenced by do_load_table(), handle_load(), and handle_load_table().

◆ push_new_frame()

static uacpi_status push_new_frame ( struct execution_context ctx,
struct call_frame **  out_frame 
)
static

Definition at line 4346 of file interpreter.c.

4348{
4349 struct call_frame_array *call_stack = &ctx->call_stack;
4350 struct call_frame *prev_frame;
4351
4352 *out_frame = call_frame_array_calloc(call_stack);
4353 if (uacpi_unlikely(*out_frame == UACPI_NULL))
4355
4356 /*
4357 * Allocating a new frame might have reallocated the dynamic buffer so our
4358 * execution_context members might now be pointing to freed memory.
4359 * Refresh them here.
4360 */
4361 prev_frame = call_frame_array_one_before_last(call_stack);
4362 ctx->cur_frame = prev_frame;
4364
4365 return UACPI_STATUS_OK;
4366}

Referenced by prepare_method_call().

◆ push_op()

static uacpi_status push_op ( struct execution_context ctx)
static

Definition at line 4586 of file interpreter.c.

4587{
4588 struct call_frame *frame = ctx->cur_frame;
4589 struct op_context *op_ctx;
4590
4591 op_ctx = op_context_array_calloc(&frame->pending_ops);
4592 if (op_ctx == UACPI_NULL)
4594
4595 op_ctx->op = ctx->cur_op;
4597 return UACPI_STATUS_OK;
4598}

Referenced by exec_op().

◆ reference_unwind()

static uacpi_object * reference_unwind ( uacpi_object obj)
static

Definition at line 2255 of file interpreter.c.

2256{
2258
2259 while (obj) {
2260 if (obj->type != UACPI_OBJECT_REFERENCE)
2261 return parent;
2262
2263 parent = obj;
2264 obj = parent->inner_object;
2265 }
2266
2267 // This should be unreachable
2268 return UACPI_NULL;
2269}

Referenced by copy_object_to_reference(), handle_deref_of(), handle_inc_dec(), handle_object_type(), handle_sizeof(), and store_to_reference().

◆ refresh_ctx_pointers()

static void refresh_ctx_pointers ( struct execution_context ctx)
static

Definition at line 4250 of file interpreter.c.

4251{
4252 struct call_frame *frame = ctx->cur_frame;
4253
4254 if (frame == UACPI_NULL) {
4255 ctx->cur_op_ctx = UACPI_NULL;
4256 ctx->prev_op_ctx = UACPI_NULL;
4257 ctx->cur_block = UACPI_NULL;
4258 return;
4259 }
4260
4261 ctx->cur_op_ctx = op_context_array_last(&frame->pending_ops);
4262 ctx->prev_op_ctx = op_context_array_one_before_last(&frame->pending_ops);
4263 ctx->cur_block = code_block_array_last(&frame->code_blocks);
4264}

Referenced by ctx_reload_post_ret(), pop_op(), push_new_frame(), and push_op().

◆ report_table_id_find_error()

static void report_table_id_find_error ( const uacpi_char opcode,
struct uacpi_table_identifiers id,
uacpi_status  ret 
)
static

Definition at line 1179 of file interpreter.c.

1183{
1185 "%s: unable to find table '%.4s' (OEM ID '%.6s', "
1186 "OEM Table ID '%.8s'): %s",
1187 opcode, id->signature.text, id->oemid, id->oem_table_id,
1189 );
1190}
const uacpi_char * uacpi_status_to_string(uacpi_status)
Definition: uacpi.c:60
GLuint id
Definition: glext.h:5910

Referenced by handle_create_data_region(), and handle_load_table().

◆ resolve_name_string()

static uacpi_status resolve_name_string ( struct call_frame frame,
enum resolve_behavior  behavior,
struct uacpi_namespace_node **  out_node 
)
static

Definition at line 480 of file interpreter.c.

485{
488 uacpi_size bytes_left, namesegs = 0;
489 struct uacpi_namespace_node *parent, *cur_node = frame->cur_scope;
490 uacpi_char prev_char = 0;
491 uacpi_bool just_one_nameseg = UACPI_TRUE;
492
493 bytes_left = call_frame_code_bytes_left(frame);
494 cursor = call_frame_cursor(frame);
495
496 for (;;) {
497 if (uacpi_unlikely(bytes_left == 0))
499
500 switch (*cursor) {
501 case '\\':
502 if (prev_char == '^')
504
505 cur_node = uacpi_namespace_root();
506 break;
507 case '^':
508 // Tried to go behind root
509 if (uacpi_unlikely(cur_node == uacpi_namespace_root()))
511
512 cur_node = cur_node->parent;
513 break;
514 default:
515 break;
516 }
517
518 prev_char = *cursor;
519
520 switch (prev_char) {
521 case '^':
522 case '\\':
523 just_one_nameseg = UACPI_FALSE;
524 cursor++;
525 bytes_left--;
526 break;
527 default:
528 break;
529 }
530
531 if (prev_char != '^')
532 break;
533 }
534
535 // At least a NullName byte is expected here
536 if (uacpi_unlikely(bytes_left == 0))
538
539 bytes_left--;
540 switch (*cursor++)
541 {
543 namesegs = 2;
544 just_one_nameseg = UACPI_FALSE;
545 break;
547 if (uacpi_unlikely(bytes_left == 0))
549
550 namesegs = *cursor;
551 if (uacpi_unlikely(namesegs == 0)) {
552 uacpi_error("MultiNamePrefix but SegCount is 0");
554 }
555
556 cursor++;
557 bytes_left--;
558 just_one_nameseg = UACPI_FALSE;
559 break;
560 case UACPI_NULL_NAME:
562 just_one_nameseg)
564
565 goto out;
566 default:
567 /*
568 * Might be an invalid byte, but assume single nameseg for now,
569 * the code below will validate it for us.
570 */
571 cursor--;
572 bytes_left++;
573 namesegs = 1;
574 break;
575 }
576
577 if (uacpi_unlikely((namesegs * 4) > bytes_left))
579
580 for (; namesegs; cursor += 4, namesegs--) {
582
585 return ret;
586
587 parent = cur_node;
589
590 switch (behavior) {
592 if (namesegs == 1) {
593 if (cur_node) {
594 cur_node = UACPI_NULL;
596 goto out;
597 }
598
599 // Create the node and link to parent but don't install YET
601 if (uacpi_unlikely(cur_node == UACPI_NULL)) {
603 goto out;
604 }
605
606 cur_node->parent = parent;
607 }
608 break;
610 if (just_one_nameseg) {
611 while (!cur_node && parent != uacpi_namespace_root()) {
612 cur_node = parent;
613 parent = cur_node->parent;
614
616 }
617 }
618 break;
619 default:
621 }
622
623 if (cur_node == UACPI_NULL) {
625 break;
626 }
627 }
628
629out:
630 cursor += namesegs * 4;
631 frame->code_offset = cursor - frame->method->code;
632
634 uacpi_shareable_ref(cur_node);
635
636 *out_node = cur_node;
637 return ret;
638}
uacpi_namespace_node * uacpi_namespace_node_find_sub_node(uacpi_namespace_node *parent, uacpi_object_name name)
Definition: namespace.c:446
uacpi_namespace_node * uacpi_namespace_node_alloc(uacpi_object_name name)
Definition: namespace.c:281
static uacpi_status parse_nameseg(uacpi_u8 *cursor, uacpi_object_name *out_name)
Definition: interpreter.c:342
Definition: name.c:39
uacpi_object_name name
Definition: namespace.h:29
struct uacpi_namespace_node * parent
Definition: namespace.h:32
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by exec_op().

◆ sizeof_int()

static uacpi_size sizeof_int ( void  )
static

Definition at line 913 of file interpreter.c.

914{
915 return g_uacpi_rt_ctx.is_rev1 ? 4 : 8;
916}

Referenced by get_object_storage(), handle_concatenate(), handle_inc_dec(), and handle_to().

◆ stack_unwind()

static void stack_unwind ( struct execution_context ctx)
static

Definition at line 6056 of file interpreter.c.

6057{
6059 uacpi_bool should_stop;
6060
6061 /*
6062 * Non-empty call stack here means the execution was aborted at some point,
6063 * probably due to a bytecode error.
6064 */
6065 depth = call_frame_array_size(&ctx->call_stack);
6066
6067 if (depth != 0) {
6068 uacpi_size idx = 0;
6069 uacpi_bool table_level_code;
6070 const struct uacpi_op_spec *op;
6071 const uacpi_char *op_name;
6072
6073 do {
6074 op = UACPI_NULL;
6075 table_level_code = ctx->cur_frame->method->named_objects_persist;
6076
6077 if (table_level_code && idx != 0)
6078 /*
6079 * This isn't the first frame that we are aborting.
6080 * If this is table-level code, we have just unwound a call
6081 * chain that had triggered an abort. Stop here, no need to
6082 * abort table load because of it.
6083 */
6084 break;
6085
6086 while (op_context_array_size(&ctx->cur_frame->pending_ops) != 0) {
6087 if (op == UACPI_NULL)
6088 op = op_context_array_last(
6089 &ctx->cur_frame->pending_ops
6090 )->op;
6091
6092 pop_op(ctx);
6093 }
6094
6095 /*
6096 * For the very first frame, fetch the opcode from the execution
6097 * context directly if we got nothing from the pending_ops array.
6098 * The reason we do this is because in case this was an invalid
6099 * opcode it won't actually end up in the pending_ops array at all.
6100 * This is only possible for the first frame, since all the frames
6101 * below are guaranteed to be either in MethodCallOp or
6102 * Load{Table}Op.
6103 */
6104 if (op == UACPI_NULL && idx == 0)
6105 op = ctx->cur_op;
6106
6107 if (uacpi_likely(op != UACPI_NULL)) {
6108 op_name = op->name;
6109
6110 if (op_is_internal(op))
6111 /*
6112 * All internal OPs are prefixed with this, strip to
6113 * make them look nicer in the backtrace.
6114 */
6115 op_name += sizeof("InternalOp") - 1;
6116 } else {
6117 op_name = "<unknown>";
6118 }
6119
6121 code_block_array_at(&ctx->cur_frame->code_blocks, 0), idx,
6122 ctx->cur_frame->code_offset, ctx->cur_frame->method->size,
6123 op_name
6124 );
6125
6126 should_stop = idx++ == 0 && table_level_code;
6128 } while (--depth && !should_stop);
6129 }
6130}
static void trace_method_abort(struct code_block *block, uacpi_size depth, uacpi_u32 aml_offset, uacpi_u32 method_size, const uacpi_char *op)
Definition: interpreter.c:6029
static void ctx_reload_post_ret(struct execution_context *ctx)
Definition: interpreter.c:6011

Referenced by uacpi_execute_control_method().

◆ store_to_reference()

static uacpi_status store_to_reference ( uacpi_object dst,
uacpi_object src,
uacpi_data_view wtr_response 
)
static

Definition at line 2372 of file interpreter.c.

2375{
2376 uacpi_object *src_obj;
2377 uacpi_bool overwrite = UACPI_FALSE;
2378
2379 switch (dst->flags) {
2383 uacpi_object *referenced_obj;
2384
2385 if (dst->flags == UACPI_REFERENCE_KIND_PKG_INDEX)
2386 referenced_obj = dst->inner_object;
2387 else
2388 referenced_obj = uacpi_unwrap_internal_reference(dst);
2389
2390 if (referenced_obj->type == UACPI_OBJECT_REFERENCE) {
2391 overwrite = dst->flags == UACPI_REFERENCE_KIND_ARG;
2392 dst = reference_unwind(referenced_obj);
2393 break;
2394 }
2395
2396 overwrite = UACPI_TRUE;
2397 break;
2398 }
2401 break;
2402 default:
2404 }
2405
2407 overwrite |= dst->inner_object->type == UACPI_OBJECT_UNINITIALIZED;
2408
2409 if (overwrite) {
2411 uacpi_object *new_obj;
2412
2414 if (uacpi_unlikely(new_obj == UACPI_NULL))
2416
2417 ret = uacpi_object_assign(new_obj, src_obj,
2420 uacpi_object_unref(new_obj);
2421 return ret;
2422 }
2423
2424 object_replace_child(dst, new_obj);
2425 uacpi_object_unref(new_obj);
2426 return UACPI_STATUS_OK;
2427 }
2428
2430 dst->inner_object, src_obj, wtr_response
2431 );
2432}
static uacpi_status object_assign_with_implicit_cast(uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
Definition: interpreter.c:975

Referenced by store_to_target().

◆ store_to_target()

static uacpi_status store_to_target ( uacpi_object dst,
uacpi_object src,
uacpi_data_view wtr_response 
)
static

Definition at line 4385 of file interpreter.c.

4388{
4390
4391 switch (dst->type) {
4392 case UACPI_OBJECT_DEBUG:
4393 ret = debug_store(src);
4394 break;
4396 ret = store_to_reference(dst, src, wtr_response);
4397 break;
4398
4401 ret = object_assign_with_implicit_cast(dst, src, wtr_response);
4402 break;
4403
4405 // NULL target
4406 if (dst->integer == 0) {
4408 break;
4409 }
4411 default:
4412 uacpi_error("attempted to store to an invalid target: %s",
4415 }
4416
4417 return ret;
4418}
@ UACPI_OBJECT_DEBUG
Definition: types.h:126
static uacpi_status debug_store(uacpi_object *src)
Definition: interpreter.c:2222
static uacpi_status store_to_reference(uacpi_object *dst, uacpi_object *src, uacpi_data_view *wtr_response)
Definition: interpreter.c:2372

Referenced by exec_op(), and handle_copy_object_or_store().

◆ table_id_error()

static uacpi_status table_id_error ( const uacpi_char opcode,
const uacpi_char arg,
uacpi_buffer str 
)
static

Definition at line 1170 of file interpreter.c.

1174{
1175 uacpi_error("%s: invalid %s '%s'", opcode, arg, str->text);
1177}

Referenced by build_table_id(), and handle_load_table().

◆ trace_method_abort()

static void trace_method_abort ( struct code_block block,
uacpi_size  depth,
uacpi_u32  aml_offset,
uacpi_u32  method_size,
const uacpi_char op 
)
static

Definition at line 6029 of file interpreter.c.

6033{
6034 static const uacpi_char *unknown_path = "<unknown>";
6035 uacpi_char oom_absolute_path[9] = "<?>.";
6036
6037 const uacpi_char *absolute_path;
6038
6039 if (block != UACPI_NULL && block->type == CODE_BLOCK_SCOPE) {
6041 if (uacpi_unlikely(absolute_path == UACPI_NULL))
6042 uacpi_memcpy(oom_absolute_path + 4, block->node->name.text, 4);
6043 } else {
6044 absolute_path = unknown_path;
6045 }
6046
6048 " #%zu in %s()+%u/%u at %s",
6049 depth, absolute_path, aml_offset, method_size, op
6050 );
6051
6052 if (absolute_path != oom_absolute_path && absolute_path != unknown_path)
6053 uacpi_free_dynamic_string(absolute_path);
6054}

Referenced by stack_unwind().

◆ trace_named_object_lookup_or_creation_failure()

static void trace_named_object_lookup_or_creation_failure ( struct call_frame frame,
uacpi_size  offset,
enum uacpi_parse_op  op,
uacpi_status  ret,
enum uacpi_log_level  level 
)
static

Definition at line 4904 of file interpreter.c.

4908{
4909 static const uacpi_char *oom_prefix = "<...>";
4910 static const uacpi_char *empty_string = "";
4911 static const uacpi_char *unknown_path = "<unknown-path>";
4912 static const uacpi_char *invalid_path = "<invalid-path>";
4913
4914 uacpi_status conv_ret;
4915 const uacpi_char *action;
4916 const uacpi_char *requested_path_to_print;
4917 const uacpi_char *middle_part = UACPI_NULL;
4918 const uacpi_char *prefix_path = UACPI_NULL;
4919 uacpi_char *requested_path = UACPI_NULL;
4921 uacpi_bool is_create;
4922
4923 is_create = op == UACPI_PARSE_OP_CREATE_NAMESTRING ||
4925
4926 if (is_create)
4927 action = "create";
4928 else
4929 action = "lookup";
4930
4931 conv_ret = name_string_to_path(
4932 frame, offset, &requested_path, &length
4933 );
4934 if (uacpi_unlikely_error(conv_ret)) {
4935 if (conv_ret == UACPI_STATUS_OUT_OF_MEMORY)
4936 requested_path_to_print = unknown_path;
4937 else
4938 requested_path_to_print = invalid_path;
4939 } else {
4940 requested_path_to_print = requested_path;
4941 }
4942
4943 if (requested_path && requested_path[0] != '\\') {
4945 frame->cur_scope
4946 );
4947 if (uacpi_unlikely(prefix_path == UACPI_NULL))
4948 prefix_path = oom_prefix;
4949
4950 if (prefix_path[1] != '\0')
4951 middle_part = ".";
4952 } else {
4953 prefix_path = empty_string;
4954 }
4955
4956 if (middle_part == UACPI_NULL)
4957 middle_part = empty_string;
4958
4959 if (length == 5 && !is_create) {
4961 level,
4962 "unable to %s named object '%s' within (or above) "
4963 "scope '%s': %s", action, requested_path_to_print,
4964 prefix_path, uacpi_status_to_string(ret)
4965 );
4966 } else {
4968 level,
4969 "unable to %s named object '%s%s%s': %s",
4970 action, prefix_path, middle_part,
4971 requested_path_to_print, uacpi_status_to_string(ret)
4972 );
4973 }
4974
4975 uacpi_free(requested_path, length);
4976 if (prefix_path != oom_prefix && prefix_path != empty_string)
4977 uacpi_free_dynamic_string(prefix_path);
4978}
action
Definition: namespace.c:707
GLint level
Definition: gl.h:1546

Referenced by exec_op().

◆ trace_op()

static void trace_op ( const struct uacpi_op_spec op,
enum op_trace_action_type  action 
)
inlinestatic

Definition at line 4283 of file interpreter.c.

4286{
4288 "%s OP '%s' (0x%04X)",
4289 op_trace_action_types[action], op->name, op->code
4290 );
4291}
#define uacpi_debug(...)
Definition: log.h:32
static const uacpi_char *const op_trace_action_types[3]
Definition: interpreter.c:4277

Referenced by exec_op(), and uacpi_execute_control_method().

◆ trace_pop()

static void trace_pop ( uacpi_u8  pop)
inlinestatic

Definition at line 4293 of file interpreter.c.

4294{
4295 uacpi_debug(" pOP: %s (0x%02X)", uacpi_parse_op_to_string(pop), pop);
4296}
const uacpi_char * uacpi_parse_op_to_string(enum uacpi_parse_op op)
Definition: opcodes.c:252
static calc_node_t * pop(void)
Definition: rpn_ieee.c:90

Referenced by exec_op().

◆ truncate_number_if_needed()

static void truncate_number_if_needed ( uacpi_object obj)
static

Definition at line 1935 of file interpreter.c.

1936{
1937 if (!g_uacpi_rt_ctx.is_rev1)
1938 return;
1939
1940 obj->integer &= 0xFFFFFFFF;
1941}

Referenced by exec_op(), and handle_unary_math().

◆ typecheck_computational_data()

static uacpi_status typecheck_computational_data ( const struct op_context op_ctx,
const uacpi_object obj 
)
static

Definition at line 4879 of file interpreter.c.

4883{
4884 switch (obj->type) {
4888 return UACPI_STATUS_OK;
4889 default:
4891 "invalid argument type: %s, expected a %s",
4894 );
4896 }
4897}
#define SPEC_COMPUTATIONAL_DATA
Definition: interpreter.c:4743

Referenced by exec_op().

◆ typecheck_obj()

static uacpi_status typecheck_obj ( const struct op_context op_ctx,
const uacpi_object obj,
enum uacpi_object_type  expected_type,
const uacpi_char spec_desc 
)
static

Definition at line 4848 of file interpreter.c.

4854{
4855 if (uacpi_likely(obj->type == expected_type))
4856 return UACPI_STATUS_OK;
4857
4858 EXEC_OP_ERR_2("invalid argument type: %s, expected a %s",
4859 uacpi_object_type_to_string(obj->type), spec_desc);
4861}

Referenced by typecheck_operand(), and typecheck_string().

◆ typecheck_operand()

static uacpi_status typecheck_operand ( const struct op_context op_ctx,
const uacpi_object obj 
)
static

Definition at line 4863 of file interpreter.c.

4867{
4869}
#define SPEC_OPERAND
Definition: interpreter.c:4739
static uacpi_status typecheck_obj(const struct op_context *op_ctx, const uacpi_object *obj, enum uacpi_object_type expected_type, const uacpi_char *spec_desc)
Definition: interpreter.c:4848

Referenced by exec_op().

◆ typecheck_string()

static uacpi_status typecheck_string ( const struct op_context op_ctx,
const uacpi_object obj 
)
static

Definition at line 4871 of file interpreter.c.

4875{
4877}
#define SPEC_STRING
Definition: interpreter.c:4740

Referenced by exec_op().

◆ uacpi_execute_control_method()

uacpi_status uacpi_execute_control_method ( uacpi_namespace_node scope,
uacpi_control_method method,
const uacpi_object_array args,
uacpi_object **  out_obj 
)

Definition at line 6150 of file interpreter.c.

6154{
6156 struct execution_context *ctx;
6157
6158 ctx = uacpi_kernel_alloc_zeroed(sizeof(*ctx));
6161
6162 if (out_obj != UACPI_NULL) {
6164 if (uacpi_unlikely(ctx->ret == UACPI_NULL)) {
6166 goto out;
6167 }
6168 }
6169
6172 goto out;
6173
6174 for (;;) {
6176 if (ctx->cur_frame == UACPI_NULL)
6177 break;
6178
6179 if (maybe_end_block(ctx))
6180 continue;
6181
6182 if (!call_frame_has_code(ctx->cur_frame)) {
6184 continue;
6185 }
6186
6187 ret = get_op(ctx);
6189 goto handle_method_abort;
6190
6192 }
6193
6194 ret = exec_op(ctx);
6196 goto handle_method_abort;
6197
6198 continue;
6199
6200 handle_method_abort:
6201 uacpi_error("aborting %s due to previous error: %s",
6202 ctx->cur_frame->method->named_objects_persist ?
6203 "table load" : "method invocation",
6206
6207 /*
6208 * Having a frame here implies that we just aborted a dynamic table
6209 * load. Signal to the caller that it failed by setting the return
6210 * value to false.
6211 */
6212 if (ctx->cur_frame) {
6213 struct item *it;
6214
6215 it = item_array_last(&ctx->cur_op_ctx->items);
6216 if (it != UACPI_NULL && it->obj != UACPI_NULL)
6217 it->obj->integer = 0;
6218 }
6219 }
6220
6221out:
6222 if (ctx->ret != UACPI_NULL) {
6223 uacpi_object *ret_obj = UACPI_NULL;
6224
6225 if (ctx->ret->type != UACPI_OBJECT_UNINITIALIZED) {
6226 ret_obj = ctx->ret;
6227 uacpi_object_ref(ret_obj);
6228 }
6229
6230 *out_obj = ret_obj;
6231 }
6232
6234 return ret;
6235}
static uacpi_bool maybe_end_block(struct execution_context *ctx)
Definition: interpreter.c:4368
static void stack_unwind(struct execution_context *ctx)
Definition: interpreter.c:6056
static uacpi_status exec_op(struct execution_context *ctx)
Definition: interpreter.c:5335
static uacpi_status get_op(struct execution_context *ctx)
Definition: interpreter.c:696
static void execution_context_release(struct execution_context *ctx)
Definition: interpreter.c:6132
static uacpi_bool call_frame_has_code(struct call_frame *frame)
Definition: interpreter.c:301

Referenced by async_run_gpe_handler(), do_load_table(), region_run_reg(), and uacpi_eval().

◆ uacpi_execute_table()

uacpi_status uacpi_execute_table ( void tbl,
enum uacpi_table_load_cause  cause 
)

Definition at line 1612 of file interpreter.c.

1613{
1615
1618 return ret;
1619
1620 ret = do_load_table(uacpi_namespace_root(), tbl, cause);
1621
1623 return ret;
1624}
static uacpi_status do_load_table(uacpi_namespace_node *parent, struct acpi_sdt_hdr *tbl, enum uacpi_table_load_cause cause)
Definition: interpreter.c:1304

Referenced by uacpi_table_load_with_cause().

◆ uacpi_osi()

uacpi_status uacpi_osi ( uacpi_handle  handle,
uacpi_object retval 
)

Definition at line 6237 of file interpreter.c.

6238{
6239 struct execution_context *ctx = handle;
6240 uacpi_bool is_supported;
6243
6244 arg = uacpi_unwrap_internal_reference(ctx->cur_frame->args[0]);
6245 if (arg->type != UACPI_OBJECT_STRING) {
6246 uacpi_error("_OSI: invalid argument type %s, expected a String",
6249 }
6250
6251 if (retval == UACPI_NULL)
6252 return UACPI_STATUS_OK;
6253
6255
6256 ret = uacpi_handle_osi(arg->buffer->text, &is_supported);
6258 return ret;
6259
6260 retval->integer = is_supported ? ones() : 0;
6261
6262 uacpi_trace("_OSI(%s) => reporting as %ssupported",
6263 arg->buffer->text, is_supported ? "" : "un");
6264 return UACPI_STATUS_OK;
6265}
uacpi_status uacpi_handle_osi(const uacpi_char *string, uacpi_bool *out_value)
Definition: osi.c:362

Referenced by make_object_for_predefined().

◆ uninstalled_op_handler()

static uacpi_status uninstalled_op_handler ( struct execution_context ctx)
static

Definition at line 4980 of file interpreter.c.

4981{
4982 struct op_context *op_ctx = ctx->cur_op_ctx;
4983
4984 EXEC_OP_ERR("no dedicated handler installed");
4986}
#define EXEC_OP_ERR(reason)
Definition: interpreter.c:4730

◆ write_buffer_index()

static void write_buffer_index ( uacpi_buffer_index buf_idx,
uacpi_data_view src_buf 
)
static

Definition at line 963 of file interpreter.c.

965{
967 1, src_buf->length);
968}

Referenced by object_assign_with_implicit_cast().

Variable Documentation

◆ handler_idx_of_ext_op

uacpi_u8 handler_idx_of_ext_op[0x100]
static

Definition at line 5202 of file interpreter.c.

Referenced by exec_op().

◆ handler_idx_of_op

uacpi_u8 handler_idx_of_op[0x100]
static

Definition at line 5090 of file interpreter.c.

Referenced by exec_op().

◆ op_handlers

uacpi_status(* op_handlers[])(struct execution_context *ctx) ( struct execution_context ctx)
static

Definition at line 5037 of file interpreter.c.

Referenced by exec_op().

◆ op_trace_action_types

const uacpi_char* const op_trace_action_types[3]
static
Initial value:
= {
[OP_TRACE_ACTION_BEGIN] = "BEGIN",
[OP_TRACE_ACTION_RESUME] = "RESUME",
}

Definition at line 4277 of file interpreter.c.

Referenced by trace_op().

◆ parse_op_generates_item

uacpi_u8 parse_op_generates_item[0x100]
static

Definition at line 4654 of file interpreter.c.

Referenced by exec_op().