Integrate uACPI
This commit is contained in:
570
kernel/hal/x86_64/uACPI/tests/runner/test_runner.c
Normal file
570
kernel/hal/x86_64/uACPI/tests/runner/test_runner.c
Normal file
@ -0,0 +1,570 @@
|
||||
#include "argparser.h"
|
||||
#include "helpers.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <uacpi/acpi.h>
|
||||
#include <uacpi/context.h>
|
||||
#include <uacpi/event.h>
|
||||
#include <uacpi/log.h>
|
||||
#include <uacpi/namespace.h>
|
||||
#include <uacpi/notify.h>
|
||||
#include <uacpi/opregion.h>
|
||||
#include <uacpi/osi.h>
|
||||
#include <uacpi/platform/types.h>
|
||||
#include <uacpi/resources.h>
|
||||
#include <uacpi/status.h>
|
||||
#include <uacpi/tables.h>
|
||||
#include <uacpi/types.h>
|
||||
#include <uacpi/uacpi.h>
|
||||
#include <uacpi/utilities.h>
|
||||
|
||||
void run_resource_tests(void);
|
||||
void test_object_api(void);
|
||||
void test_address_spaces(void);
|
||||
void interface_cleanup(void);
|
||||
|
||||
static uacpi_object_type string_to_object_type(const char *str)
|
||||
{
|
||||
if (strcmp(str, "int") == 0)
|
||||
return UACPI_OBJECT_INTEGER;
|
||||
if (strcmp(str, "str") == 0)
|
||||
return UACPI_OBJECT_STRING;
|
||||
|
||||
error("Unsupported type for validation: %s", str);
|
||||
return UACPI_OBJECT_UNINITIALIZED;
|
||||
}
|
||||
|
||||
static void validate_ret_against_expected(
|
||||
uacpi_object *obj, uacpi_object_type expected_type, const char *expected_val
|
||||
)
|
||||
{
|
||||
uacpi_object_type type = uacpi_object_get_type(obj);
|
||||
|
||||
if (type != expected_type)
|
||||
error(
|
||||
"returned type '%s' doesn't match expected '%s",
|
||||
uacpi_object_type_to_string(expected_type),
|
||||
uacpi_object_type_to_string(type)
|
||||
);
|
||||
|
||||
switch (type) {
|
||||
case UACPI_OBJECT_INTEGER: {
|
||||
uacpi_u64 expected_int = strtoull(expected_val, NULL, 0);
|
||||
uacpi_u64 actual_int;
|
||||
|
||||
uacpi_object_get_integer(obj, &actual_int);
|
||||
|
||||
if (expected_int != actual_int)
|
||||
error(
|
||||
"returned value '%" PRIu64 "' doesn't match expected '%" PRIu64
|
||||
"'", actual_int, expected_int
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case UACPI_OBJECT_STRING: {
|
||||
uacpi_data_view view;
|
||||
const char *actual_str;
|
||||
|
||||
uacpi_object_get_string_or_buffer(obj, &view);
|
||||
actual_str = view.text;
|
||||
|
||||
if (strcmp(expected_val, actual_str) != 0)
|
||||
error(
|
||||
"returned value '%s' doesn't match expected '%s'",
|
||||
actual_str, expected_val
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void nested_printf(uacpi_u32 depth, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
size_t padding = depth * 4;
|
||||
|
||||
while (padding-- > 0)
|
||||
printf(" ");
|
||||
|
||||
va_start(va, fmt);
|
||||
vprintf(fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
static void dump_resources(
|
||||
uacpi_u32 depth, uacpi_namespace_node *node,
|
||||
uacpi_status (*cb)(uacpi_namespace_node *, uacpi_resources **),
|
||||
const char *name
|
||||
)
|
||||
{
|
||||
uacpi_resources *res;
|
||||
uacpi_status ret = cb(node, &res);
|
||||
|
||||
if (ret == UACPI_STATUS_OK) {
|
||||
// TODO: dump resources here
|
||||
nested_printf(depth, " %s: <%u bytes>\n", name, res->length);
|
||||
uacpi_free_resources(res);
|
||||
} else if (ret != UACPI_STATUS_NOT_FOUND)
|
||||
nested_printf(
|
||||
depth, " %s: unable to evaluate (%s)\n", name,
|
||||
uacpi_status_to_string(ret)
|
||||
);
|
||||
}
|
||||
|
||||
static uacpi_iteration_decision dump_one_node(
|
||||
void *ptr, uacpi_namespace_node *node, uacpi_u32 depth
|
||||
)
|
||||
{
|
||||
struct uacpi_namespace_node_info *info;
|
||||
uacpi_status ret = uacpi_get_namespace_node_info(node, &info);
|
||||
const char *path;
|
||||
|
||||
UACPI_UNUSED(ptr);
|
||||
|
||||
if (uacpi_unlikely_error(ret)) {
|
||||
uacpi_object_name name = uacpi_namespace_node_name(node);
|
||||
|
||||
fprintf(
|
||||
stderr, "unable to get node %.4s info: %s\n", name.text,
|
||||
uacpi_status_to_string(ret)
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
path = uacpi_namespace_node_generate_absolute_path(node);
|
||||
nested_printf(
|
||||
depth, "%s [%s]", path, uacpi_object_type_to_string(info->type)
|
||||
);
|
||||
uacpi_free_absolute_path(path);
|
||||
|
||||
if (info->type == UACPI_OBJECT_METHOD)
|
||||
printf(" (%d args)", info->num_params);
|
||||
|
||||
if (info->flags)
|
||||
printf(" {\n");
|
||||
|
||||
if (info->flags)
|
||||
nested_printf(depth, " _ADR: %016" PRIX64 "\n", info->adr);
|
||||
|
||||
if (info->flags & UACPI_NS_NODE_INFO_HAS_HID)
|
||||
nested_printf(depth, " _HID: %s\n", info->hid.value);
|
||||
|
||||
if (info->flags & UACPI_NS_NODE_INFO_HAS_CID) {
|
||||
size_t i;
|
||||
|
||||
nested_printf(depth, " _CID: ");
|
||||
for (i = 0; i < info->cid.num_ids; ++i)
|
||||
printf("%s ", info->cid.ids[i].value);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (info->flags & UACPI_NS_NODE_INFO_HAS_UID)
|
||||
nested_printf(depth, " _UID: %s\n", info->uid.value);
|
||||
|
||||
if (info->flags & UACPI_NS_NODE_INFO_HAS_CLS)
|
||||
nested_printf(depth, " _CLS: %s\n", info->cls.value);
|
||||
|
||||
if (info->flags & UACPI_NS_NODE_INFO_HAS_SXD)
|
||||
nested_printf(
|
||||
depth, " _SxD: S1->D%d S2->D%d S3->D%d S4->D%d\n", info->sxd[0],
|
||||
info->sxd[1], info->sxd[2], info->sxd[3]
|
||||
);
|
||||
|
||||
if (info->flags & UACPI_NS_NODE_INFO_HAS_SXW)
|
||||
nested_printf(
|
||||
depth, " _SxW: S0->D%d S1->D%d S2->D%d S3->D%d S4->D%d\n",
|
||||
info->sxw[0], info->sxw[1], info->sxw[2], info->sxw[3], info->sxw[4]
|
||||
);
|
||||
|
||||
if (info->flags) {
|
||||
if (info->type == UACPI_OBJECT_DEVICE) {
|
||||
dump_resources(depth, node, uacpi_get_current_resources, "_CRS");
|
||||
dump_resources(depth, node, uacpi_get_possible_resources, "_PRS");
|
||||
}
|
||||
|
||||
nested_printf(depth, "}\n");
|
||||
} else
|
||||
printf("\n");
|
||||
|
||||
uacpi_free_namespace_node_info(info);
|
||||
return UACPI_ITERATION_DECISION_CONTINUE;
|
||||
}
|
||||
|
||||
static void enumerate_namespace(void)
|
||||
{
|
||||
uacpi_namespace_node *root = uacpi_namespace_root();
|
||||
|
||||
dump_one_node(NULL, root, 0);
|
||||
uacpi_namespace_for_each_child_simple(root, dump_one_node, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* DefinitionBlock ("x.aml", "SSDT", 1, "uTEST", "OVERRIDE", 0xF0F0F0F0)
|
||||
* {
|
||||
* Name (VAL, "TestRunner")
|
||||
* }
|
||||
*/
|
||||
static uint8_t table_override[] = {
|
||||
0x53, 0x53, 0x44, 0x54, 0x35, 0x00, 0x00, 0x00,
|
||||
0x01, 0xa1, 0x75, 0x54, 0x45, 0x53, 0x54, 0x00,
|
||||
0x4f, 0x56, 0x45, 0x52, 0x52, 0x49, 0x44, 0x45,
|
||||
0xf0, 0xf0, 0xf0, 0xf0, 0x49, 0x4e, 0x54, 0x4c,
|
||||
0x25, 0x09, 0x20, 0x20, 0x08, 0x56, 0x41, 0x4c,
|
||||
0x5f, 0x0d, 0x54, 0x65, 0x73, 0x74, 0x52, 0x75,
|
||||
0x6e, 0x6e, 0x65, 0x72, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* DefinitionBlock ("x.aml", "SSDT", 1, "uTEST", "RUNRIDTB", 0xF0F0F0F0)
|
||||
* {
|
||||
* Name (\_SI.TID, "uACPI")
|
||||
* Printf("TestRunner ID SSDT loaded!")
|
||||
* }
|
||||
*/
|
||||
static uint8_t runner_id_table[] = {
|
||||
0x53, 0x53, 0x44, 0x54, 0x55, 0x00, 0x00, 0x00,
|
||||
0x01, 0x45, 0x75, 0x54, 0x45, 0x53, 0x54, 0x00,
|
||||
0x52, 0x55, 0x4e, 0x52, 0x49, 0x44, 0x54, 0x42,
|
||||
0xf0, 0xf0, 0xf0, 0xf0, 0x49, 0x4e, 0x54, 0x4c,
|
||||
0x25, 0x09, 0x20, 0x20, 0x08, 0x5c, 0x2e, 0x5f,
|
||||
0x53, 0x49, 0x5f, 0x54, 0x49, 0x44, 0x5f, 0x0d,
|
||||
0x75, 0x41, 0x43, 0x50, 0x49, 0x00, 0x70, 0x0d,
|
||||
0x54, 0x65, 0x73, 0x74, 0x52, 0x75, 0x6e, 0x6e,
|
||||
0x65, 0x72, 0x20, 0x49, 0x44, 0x20, 0x53, 0x53,
|
||||
0x44, 0x54, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x65,
|
||||
0x64, 0x21, 0x00, 0x5b, 0x31
|
||||
};
|
||||
|
||||
static uacpi_table_installation_disposition handle_table_install(
|
||||
struct acpi_sdt_hdr *hdr, uacpi_u64 *out_override
|
||||
)
|
||||
{
|
||||
if (!strncmp(hdr->oem_table_id, "DENYTABL", sizeof(hdr->oem_table_id)))
|
||||
return UACPI_TABLE_INSTALLATION_DISPOSITON_DENY;
|
||||
|
||||
if (strncmp(hdr->oem_table_id, "OVERTABL", sizeof(hdr->oem_table_id)))
|
||||
return UACPI_TABLE_INSTALLATION_DISPOSITON_ALLOW;
|
||||
|
||||
*out_override = (uacpi_virt_addr)table_override;
|
||||
return UACPI_TABLE_INSTALLATION_DISPOSITON_VIRTUAL_OVERRIDE;
|
||||
}
|
||||
|
||||
static uacpi_status handle_notify(
|
||||
uacpi_handle handle, uacpi_namespace_node *node, uacpi_u64 value
|
||||
)
|
||||
{
|
||||
const char *path = uacpi_namespace_node_generate_absolute_path(node);
|
||||
|
||||
UACPI_UNUSED(handle);
|
||||
|
||||
printf("Received a notification from %s %" PRIx64 "\n", path, value);
|
||||
|
||||
free((void*)path);
|
||||
return UACPI_STATUS_OK;
|
||||
}
|
||||
|
||||
static uacpi_status handle_ec(uacpi_region_op op, uacpi_handle op_data)
|
||||
{
|
||||
switch (op) {
|
||||
case UACPI_REGION_OP_READ: {
|
||||
uacpi_region_rw_data *rw_data = (uacpi_region_rw_data*)op_data;
|
||||
|
||||
rw_data->value = 0;
|
||||
UACPI_FALLTHROUGH;
|
||||
}
|
||||
case UACPI_REGION_OP_ATTACH:
|
||||
case UACPI_REGION_OP_DETACH:
|
||||
case UACPI_REGION_OP_WRITE:
|
||||
return UACPI_STATUS_OK;
|
||||
default:
|
||||
return UACPI_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
static uacpi_interrupt_ret handle_gpe(
|
||||
uacpi_handle handle, uacpi_namespace_node *node, uint16_t idx
|
||||
)
|
||||
{
|
||||
UACPI_UNUSED(handle);
|
||||
UACPI_UNUSED(node);
|
||||
UACPI_UNUSED(idx);
|
||||
|
||||
return UACPI_INTERRUPT_HANDLED | UACPI_GPE_REENABLE;
|
||||
}
|
||||
|
||||
static void run_test(
|
||||
const char *dsdt_path, const vector_t *ssdt_paths,
|
||||
uacpi_object_type expected_type, const char *expected_value,
|
||||
bool dump_namespace
|
||||
)
|
||||
{
|
||||
static uint8_t early_table_buf[4096];
|
||||
struct acpi_rsdp rsdp = { 0 };
|
||||
struct full_xsdt *xsdt = make_xsdt(&rsdp, dsdt_path, ssdt_paths);
|
||||
uacpi_status st;
|
||||
uacpi_table tbl;
|
||||
bool is_test_mode;
|
||||
uacpi_object *ret = NULL;
|
||||
|
||||
g_rsdp = (uacpi_phys_addr)((uintptr_t)&rsdp);
|
||||
|
||||
st = uacpi_setup_early_table_access(
|
||||
early_table_buf, sizeof(early_table_buf)
|
||||
);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_table_find_by_signature(ACPI_DSDT_SIGNATURE, &tbl);
|
||||
ensure_ok_status(st);
|
||||
|
||||
if (strncmp(tbl.hdr->signature, ACPI_DSDT_SIGNATURE, 4) != 0)
|
||||
error("broken early table access!");
|
||||
|
||||
st = uacpi_table_unref(&tbl);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_initialize(UACPI_FLAG_NO_ACPI_MODE);
|
||||
ensure_ok_status(st);
|
||||
|
||||
/*
|
||||
* Go through all AML tables and manually bump their reference counts here
|
||||
* so that they're mapped before the call to uacpi_namespace_load(). The
|
||||
* reason we need this is to disambiguate calls to uacpi_kernel_map() with
|
||||
* a synthetic physical address (that is actually a virtual address for
|
||||
* tables that we constructed earlier) or a real physical address that comes
|
||||
* from some operation region or any other AML code or action.
|
||||
*/
|
||||
uacpi_table_find_by_signature(ACPI_DSDT_SIGNATURE, &tbl);
|
||||
|
||||
st = uacpi_table_find_by_signature(ACPI_SSDT_SIGNATURE, &tbl);
|
||||
while (st == UACPI_STATUS_OK) {
|
||||
uacpi_table_ref(&tbl);
|
||||
st = uacpi_table_find_next_with_same_signature(&tbl);
|
||||
}
|
||||
|
||||
g_expect_virtual_addresses = false;
|
||||
|
||||
st = uacpi_install_notify_handler(
|
||||
uacpi_namespace_root(), handle_notify, NULL
|
||||
);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_set_table_installation_handler(handle_table_install);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_install_interface("TestRunner", UACPI_INTERFACE_KIND_FEATURE);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_uninstall_interface("Windows 2006");
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_uninstall_interface("Windows 2006");
|
||||
if (st != UACPI_STATUS_NOT_FOUND)
|
||||
error("couldn't uninstall interface");
|
||||
|
||||
st = uacpi_enable_host_interface(UACPI_HOST_INTERFACE_3_0_THERMAL_MODEL);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_enable_host_interface(UACPI_HOST_INTERFACE_MODULE_DEVICE);
|
||||
ensure_ok_status(st);
|
||||
|
||||
is_test_mode = expected_type != UACPI_OBJECT_UNINITIALIZED;
|
||||
if (is_test_mode) {
|
||||
st = uacpi_table_install(runner_id_table, NULL);
|
||||
ensure_ok_status(st);
|
||||
}
|
||||
|
||||
st = uacpi_namespace_load();
|
||||
ensure_ok_status(st);
|
||||
|
||||
if (is_test_mode) {
|
||||
uacpi_object *runner_id = UACPI_NULL;
|
||||
uacpi_data_view view;
|
||||
|
||||
st = uacpi_eval_typed(
|
||||
UACPI_NULL, "\\_SI.TID", UACPI_NULL, UACPI_OBJECT_STRING_BIT,
|
||||
&runner_id
|
||||
);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_object_get_string_or_buffer(runner_id, &view);
|
||||
ensure_ok_status(st);
|
||||
|
||||
if (strcmp(view.text, "uACPI") != 0)
|
||||
error("invalid test runner id");
|
||||
uacpi_object_unref(runner_id);
|
||||
}
|
||||
|
||||
st = uacpi_install_address_space_handler(
|
||||
uacpi_namespace_root(), UACPI_ADDRESS_SPACE_EMBEDDED_CONTROLLER,
|
||||
handle_ec, NULL
|
||||
);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_install_gpe_handler(
|
||||
UACPI_NULL, 123, UACPI_GPE_TRIGGERING_EDGE, handle_gpe, NULL
|
||||
);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_enable_gpe(UACPI_NULL, 123);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_disable_gpe(UACPI_NULL, 123);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_uninstall_gpe_handler(UACPI_NULL, 123, handle_gpe);
|
||||
ensure_ok_status(st);
|
||||
|
||||
st = uacpi_namespace_initialize();
|
||||
ensure_ok_status(st);
|
||||
|
||||
if (dump_namespace)
|
||||
enumerate_namespace();
|
||||
|
||||
if (!is_test_mode)
|
||||
goto done;
|
||||
|
||||
if (strcmp(expected_value, "check-object-api-works") == 0) {
|
||||
test_object_api();
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (strcmp(expected_value, "check-address-spaces-work") == 0) {
|
||||
test_address_spaces();
|
||||
goto done;
|
||||
}
|
||||
|
||||
st = uacpi_eval(UACPI_NULL, "\\MAIN", UACPI_NULL, &ret);
|
||||
|
||||
ensure_ok_status(st);
|
||||
if (ret == NULL)
|
||||
error("\\MAIN didn't return a value");
|
||||
validate_ret_against_expected(ret, expected_type, expected_value);
|
||||
|
||||
uacpi_object_unref(ret);
|
||||
done:
|
||||
uacpi_state_reset();
|
||||
delete_xsdt(xsdt, ssdt_paths->count);
|
||||
interface_cleanup();
|
||||
}
|
||||
|
||||
static uacpi_log_level log_level_from_string(const char *arg)
|
||||
{
|
||||
static struct {
|
||||
const char *str;
|
||||
uacpi_log_level level;
|
||||
} log_levels[] = {
|
||||
{ "debug", UACPI_LOG_DEBUG },
|
||||
{ "trace", UACPI_LOG_TRACE },
|
||||
{ "info", UACPI_LOG_INFO },
|
||||
{ "warning", UACPI_LOG_WARN },
|
||||
{ "error", UACPI_LOG_ERROR },
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < UACPI_ARRAY_SIZE(log_levels); i++)
|
||||
if (strcmp(log_levels[i].str, arg) == 0)
|
||||
return log_levels[i].level;
|
||||
|
||||
error("invalid log level %s", arg);
|
||||
return UACPI_LOG_INFO;
|
||||
}
|
||||
|
||||
static arg_spec_t DSDT_PATH_ARG = ARG_POS(
|
||||
"dsdt-path-or-keyword",
|
||||
"path to the DSDT to run or \"resource-tests\" to run the resource tests"
|
||||
);
|
||||
|
||||
static arg_spec_t EXPECT_ARG = ARG_LIST(
|
||||
"expect", 'r',
|
||||
"test mode, evaluate \\MAIN and expect <expected-type> <expected-value>"
|
||||
);
|
||||
static arg_spec_t EXTRA_TABLES_ARG = ARG_LIST(
|
||||
"extra-tables", 'x', "a list of extra SSDTs to load"
|
||||
);
|
||||
static arg_spec_t ENUMERATE_NAMESPACE_ARG = ARG_FLAG(
|
||||
"enumerate-namespace", 'd', "dump the entire namespace after loading it"
|
||||
);
|
||||
static arg_spec_t WHILE_LOOP_TIMEOUT_ARG = ARG_PARAM(
|
||||
"while-loop-timeout", 't',
|
||||
"number of seconds to use for the while loop timeout"
|
||||
);
|
||||
static arg_spec_t LOG_LEVEL_ARG = ARG_PARAM(
|
||||
"log-level", 'l',
|
||||
"log level to set, one of: debug, trace, info, warning, error"
|
||||
);
|
||||
static arg_spec_t HELP_ARG = ARG_HELP(
|
||||
"help", 'h', "Display this menu and exit"
|
||||
);
|
||||
|
||||
static arg_spec_t *const POSITIONAL_ARGS[] = {
|
||||
&DSDT_PATH_ARG,
|
||||
};
|
||||
|
||||
static arg_spec_t *const OPTION_ARGS[] = {
|
||||
&EXPECT_ARG,
|
||||
&EXTRA_TABLES_ARG,
|
||||
&ENUMERATE_NAMESPACE_ARG,
|
||||
&WHILE_LOOP_TIMEOUT_ARG,
|
||||
&LOG_LEVEL_ARG,
|
||||
&HELP_ARG,
|
||||
};
|
||||
|
||||
static const arg_parser_t PARSER = {
|
||||
.positional_args = POSITIONAL_ARGS,
|
||||
.num_positional_args = UACPI_ARRAY_SIZE(POSITIONAL_ARGS),
|
||||
.option_args = OPTION_ARGS,
|
||||
.num_option_args = UACPI_ARRAY_SIZE(OPTION_ARGS),
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *dsdt_path_or_keyword;
|
||||
const char *expected_value = NULL;
|
||||
uacpi_object_type expected_type = UACPI_OBJECT_UNINITIALIZED;
|
||||
bool dump_namespace;
|
||||
uacpi_log_level log_level;
|
||||
|
||||
parse_args(&PARSER, argc, argv);
|
||||
|
||||
uacpi_context_set_loop_timeout(get_uint_or(&WHILE_LOOP_TIMEOUT_ARG, 3));
|
||||
|
||||
dsdt_path_or_keyword = get(&DSDT_PATH_ARG);
|
||||
if (strcmp(dsdt_path_or_keyword, "resource-tests") == 0) {
|
||||
run_resource_tests();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_set(&EXPECT_ARG)) {
|
||||
if (EXPECT_ARG.values.count != 2)
|
||||
error("bad --expect format");
|
||||
|
||||
expected_type = string_to_object_type(EXPECT_ARG.values.blobs[0].data);
|
||||
expected_value = EXPECT_ARG.values.blobs[1].data;
|
||||
}
|
||||
|
||||
dump_namespace = is_set(&ENUMERATE_NAMESPACE_ARG);
|
||||
// Don't spam the log with traces if enumeration is enabled
|
||||
log_level = dump_namespace ? UACPI_LOG_INFO : UACPI_LOG_TRACE;
|
||||
|
||||
if (is_set(&LOG_LEVEL_ARG))
|
||||
log_level = log_level_from_string(get(&LOG_LEVEL_ARG));
|
||||
|
||||
uacpi_context_set_log_level(log_level);
|
||||
|
||||
run_test(
|
||||
dsdt_path_or_keyword, &EXTRA_TABLES_ARG.values, expected_type,
|
||||
expected_value, dump_namespace
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user