diff options
author | Bob Moore <robert.moore@intel.com> | 2005-11-02 00:00:00 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-10 00:26:05 -0500 |
commit | 96db255c8f014ae3497507104e8df809785a619f (patch) | |
tree | 79d2c506644370fd6c10d94bd40c419cd3bad148 | |
parent | 0897831bb54eb36fd9e2a22da7f0f64be1b20d09 (diff) |
[ACPI] ACPICA 20051102
Modified the subsystem initialization sequence to improve
GPE support. The GPE initialization has been split into
two parts in order to defer execution of the _PRW methods
(Power Resources for Wake) until after the hardware is
fully initialized and the SCI handler is installed. This
allows the _PRW methods to access fields protected by the
Global Lock. This will fix systems where a NO_GLOBAL_LOCK
exception has been seen during initialization.
Fixed a regression with the ConcatenateResTemplate()
ASL operator introduced in the 20051021 release.
Implemented support for "local" internal ACPI object
types within the debugger "Object" command and the
acpi_walk_namespace() external interfaces. These local
types include RegionFields, BankFields, IndexFields, Alias,
and reference objects.
Moved common AML resource handling code into a new file,
"utresrc.c". This code is shared by both the Resource
Manager and the AML Debugger.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/events/evevent.c | 42 | ||||
-rw-r--r-- | drivers/acpi/events/evgpeblk.c | 159 | ||||
-rw-r--r-- | drivers/acpi/events/evxfevnt.c | 7 | ||||
-rw-r--r-- | drivers/acpi/executer/exdump.c | 656 | ||||
-rw-r--r-- | drivers/acpi/executer/exmisc.c | 47 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfeval.c | 2 | ||||
-rw-r--r-- | drivers/acpi/resources/rscalc.c | 253 | ||||
-rw-r--r-- | drivers/acpi/resources/rsdump.c | 70 | ||||
-rw-r--r-- | drivers/acpi/resources/rsinfo.c | 97 | ||||
-rw-r--r-- | drivers/acpi/resources/rslist.c | 195 | ||||
-rw-r--r-- | drivers/acpi/resources/rsutils.c | 88 | ||||
-rw-r--r-- | drivers/acpi/utilities/Makefile | 5 | ||||
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 148 | ||||
-rw-r--r-- | drivers/acpi/utilities/utresrc.c | 428 | ||||
-rw-r--r-- | drivers/acpi/utilities/utstate.c | 2 | ||||
-rw-r--r-- | drivers/acpi/utilities/utxface.c | 52 | ||||
-rw-r--r-- | include/acpi/acconfig.h | 2 | ||||
-rw-r--r-- | include/acpi/acevents.h | 6 | ||||
-rw-r--r-- | include/acpi/acinterp.h | 46 | ||||
-rw-r--r-- | include/acpi/acresrc.h | 27 | ||||
-rw-r--r-- | include/acpi/acutils.h | 17 | ||||
-rw-r--r-- | include/acpi/amlresrc.h | 5 |
22 files changed, 1368 insertions, 986 deletions
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index 842d1e3fb37..9522c643b88 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -100,6 +100,48 @@ acpi_status acpi_ev_initialize_events(void) /******************************************************************************* * + * FUNCTION: acpi_ev_install_fadt_gpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks + * (0 and 1). This causes the _PRW methods to be run, so the HW + * must be fully initialized at this point, including global lock + * support. + * + ******************************************************************************/ + +acpi_status acpi_ev_install_fadt_gpes(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE("ev_install_fadt_gpes"); + + /* Namespace must be locked */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* FADT GPE Block 0 */ + + (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, + acpi_gbl_gpe_fadt_blocks[0]); + + /* FADT GPE Block 1 */ + + (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, + acpi_gbl_gpe_fadt_blocks[1]); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * * FUNCTION: acpi_ev_install_xrupt_handlers * * PARAMETERS: None diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 7ca10c5f291..8efca2eac27 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c @@ -78,7 +78,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block); * * RETURN: TRUE if the gpe_event is valid * - * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. + * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. * Should be called only when the GPE lists are semaphore locked * and not subject to change. * @@ -264,7 +264,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle, * 2) Edge/Level determination is based on the 2nd character * of the method name * - * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE + * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE * if a _PRW object is found that points to this GPE. */ switch (name[1]) { @@ -313,14 +313,14 @@ acpi_ev_save_method_info(acpi_handle obj_handle, /* * Now we can add this information to the gpe_event_info block - * for use during dispatch of this GPE. Default type is RUNTIME, although + * for use during dispatch of this GPE. Default type is RUNTIME, although * this may change when the _PRW methods are executed later. */ gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; - gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD | - ACPI_GPE_TYPE_RUNTIME); + gpe_event_info->flags = (u8) + (type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME); gpe_event_info->dispatch.method_node = (struct acpi_namespace_node *)obj_handle; @@ -341,11 +341,11 @@ acpi_ev_save_method_info(acpi_handle obj_handle, * * PARAMETERS: Callback from walk_namespace * - * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is + * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is * not aborted on a single _PRW failure. * * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a - * Device. Run the _PRW method. If present, extract the GPE + * Device. Run the _PRW method. If present, extract the GPE * number and mark the GPE as a WAKE GPE. * ******************************************************************************/ @@ -443,6 +443,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, gpe_event_info->flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED); + status = acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); if (ACPI_FAILURE(status)) { @@ -466,7 +467,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, * * RETURN: A GPE interrupt block * - * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt + * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt * block per unique interrupt level used for GPEs. * Should be called only when the GPE lists are semaphore locked * and not subject to change. @@ -566,8 +567,9 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) /* Disable this interrupt */ - status = acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number, - acpi_ev_gpe_xrupt_handler); + status = + acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number, + acpi_ev_gpe_xrupt_handler); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -750,7 +752,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) /* * Allocate the GPE event_info block. There are eight distinct GPEs - * per register. Initialization to zeros is sufficient. + * per register. Initialization to zeros is sufficient. */ gpe_event_info = ACPI_MEM_CALLOCATE(((acpi_size) gpe_block-> register_count * @@ -769,9 +771,9 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) gpe_block->event_info = gpe_event_info; /* - * Initialize the GPE Register and Event structures. A goal of these + * Initialize the GPE Register and Event structures. A goal of these * tables is to hide the fact that there are two separate GPE register sets - * in a given gpe hardware block, the status registers occupy the first half, + * in a given GPE hardware block, the status registers occupy the first half, * and the enable registers occupy the second half. */ this_register = gpe_register_info; @@ -812,11 +814,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) this_event++; } - /* - * Clear the status/enable registers. Note that status registers - * are cleared by writing a '1', while enable registers are cleared - * by writing a '0'. - */ + /* Disable all GPEs within this register */ + status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0x00, &this_register-> enable_address); @@ -824,6 +823,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) goto error_exit; } + /* Clear any pending GPE events within this register */ + status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0xFF, &this_register-> status_address); @@ -860,7 +861,9 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) * * RETURN: Status * - * DESCRIPTION: Create and Install a block of GPE registers + * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within + * the block are disabled at exit. + * Note: Assumes namespace is locked. * ******************************************************************************/ @@ -872,14 +875,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, u32 interrupt_number, struct acpi_gpe_block_info **return_gpe_block) { - struct acpi_gpe_block_info *gpe_block; - struct acpi_gpe_event_info *gpe_event_info; - acpi_native_uint i; - acpi_native_uint j; - u32 wake_gpe_count; - u32 gpe_enabled_count; acpi_status status; - struct acpi_gpe_walk_info gpe_info; + struct acpi_gpe_block_info *gpe_block; ACPI_FUNCTION_TRACE("ev_create_gpe_block"); @@ -896,22 +893,24 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, /* Initialize the new GPE block */ + gpe_block->node = gpe_device; gpe_block->register_count = register_count; gpe_block->block_base_number = gpe_block_base_number; - gpe_block->node = gpe_device; ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, sizeof(struct acpi_generic_address)); - /* Create the register_info and event_info sub-structures */ - + /* + * Create the register_info and event_info sub-structures + * Note: disables and clears all GPEs in the block + */ status = acpi_ev_create_gpe_info_blocks(gpe_block); if (ACPI_FAILURE(status)) { ACPI_MEM_FREE(gpe_block); return_ACPI_STATUS(status); } - /* Install the new block in the global list(s) */ + /* Install the new block in the global lists */ status = acpi_ev_install_gpe_block(gpe_block, interrupt_number); if (ACPI_FAILURE(status)) { @@ -926,16 +925,70 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, acpi_ev_save_method_info, gpe_block, NULL); + /* Return the new block */ + + if (return_gpe_block) { + (*return_gpe_block) = gpe_block; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INIT, + "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", + (u32) gpe_block->block_base_number, + (u32) (gpe_block->block_base_number + + ((gpe_block->register_count * + ACPI_GPE_REGISTER_WIDTH) - 1)), + gpe_device->name.ascii, gpe_block->register_count, + interrupt_number)); + + return_ACPI_STATUS(AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ev_initialize_gpe_block + * + * PARAMETERS: gpe_device - Handle to the parent GPE block + * gpe_block - Gpe Block info + * + * RETURN: Status + * + * DESCRIPTION: Initialize and enable a GPE block. First find and run any + * _PRT methods associated with the block, then enable the + * appropriate GPEs. + * Note: Assumes namespace is locked. + * + ******************************************************************************/ + +acpi_status +acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, + struct acpi_gpe_block_info *gpe_block) +{ + acpi_status status; + struct acpi_gpe_event_info *gpe_event_info; + struct acpi_gpe_walk_info gpe_info; + u32 wake_gpe_count; + u32 gpe_enabled_count; + acpi_native_uint i; + acpi_native_uint j; + + ACPI_FUNCTION_TRACE("ev_initialize_gpe_block"); + + /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ + + if (!gpe_block) { + return_ACPI_STATUS(AE_OK); + } + /* - * Runtime option: Should Wake GPEs be enabled at runtime? The default - * is No, they should only be enabled just as the machine goes to sleep. + * Runtime option: Should wake GPEs be enabled at runtime? The default + * is no, they should only be enabled just as the machine goes to sleep. */ if (acpi_gbl_leave_wake_gpes_disabled) { /* - * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods. - * (Each GPE that has one or more _PRWs that reference it is by - * definition a WAKE GPE and will not be enabled while the machine - * is running.) + * Differentiate runtime vs wake GPEs, via the _PRW control methods. + * Each GPE that has one or more _PRWs that reference it is by + * definition a wake GPE and will not be enabled while the machine + * is running. */ gpe_info.gpe_block = gpe_block; gpe_info.gpe_device = gpe_device; @@ -948,9 +1001,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, } /* - * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs, - * and 2) have a corresponding _Lxx or _Exx method. All other GPEs must - * be enabled via the acpi_enable_gpe() external interface. + * Enable all GPEs in this block that have these attributes: + * 1) are "runtime" or "run/wake" GPEs, and + * 2) have a corresponding _Lxx or _Exx method + * + * Any other GPEs within this block must be enabled via the acpi_enable_gpe() + * external interface. */ wake_gpe_count = 0; gpe_enabled_count = 0; @@ -976,32 +1032,19 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, } } - /* Dump info about this GPE block */ - - ACPI_DEBUG_PRINT((ACPI_DB_INIT, - "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", - (u32) gpe_block->block_base_number, - (u32) (gpe_block->block_base_number + - ((gpe_block->register_count * - ACPI_GPE_REGISTER_WIDTH) - 1)), - gpe_device->name.ascii, gpe_block->register_count, - interrupt_number)); - - /* Enable all valid GPEs found above */ - - status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); - ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Found %u Wake, Enabled %u Runtime GPEs in this block\n", wake_gpe_count, gpe_enabled_count)); - /* Return the new block */ + /* Enable all valid runtime GPEs found above */ - if (return_gpe_block) { - (*return_gpe_block) = gpe_block; + status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); + if (ACPI_FAILURE(status)) { + ACPI_REPORT_ERROR(("Could not enable GPEs in gpe_block %p\n", + gpe_block)); } - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(status); } /******************************************************************************* diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 887ff9f28a0..c1b89892825 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -626,6 +626,13 @@ acpi_install_gpe_block(acpi_handle gpe_device, goto unlock_and_exit; } + /* Run the _PRW methods and enable the GPEs */ + + status = acpi_ev_initialize_gpe_block(node, gpe_block); + if (ACPI_FAILURE(status)) { + goto unlock_and_exit; + } + /* Get the device_object attached to the node */ obj_desc = acpi_ns_get_attached_object(node); diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 4477a62fed5..5a4cca171af 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -55,20 +55,386 @@ ACPI_MODULE_NAME("exdump") */ #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* Local prototypes */ -#ifdef ACPI_FUTURE_USAGE static void acpi_ex_out_string(char *title, char *value); static void acpi_ex_out_pointer(char *title, void *value); -static void acpi_ex_out_integer(char *title, u32 value); - static void acpi_ex_out_address(char *title, acpi_physical_address value); -static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc); +static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc); static void -acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index); -#endif /* ACPI_FUTURE_USAGE */ +acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, + u32 level, u32 index); + +/******************************************************************************* + * + * Object Descriptor info tables + * + * Note: The first table entry must be an INIT opcode and must contain + * the table length (number of table entries) + * + ******************************************************************************/ + +static struct acpi_exdump_info acpi_ex_dump_integer[2] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_integer), NULL}, + {ACPI_EXD_UINT64, ACPI_EXD_OFFSET(integer.value), "Value"} +}; + +static struct acpi_exdump_info acpi_ex_dump_string[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_string), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(string.length), "Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(string.pointer), "Pointer"}, + {ACPI_EXD_STRING, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_buffer[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, + {ACPI_EXD_BUFFER, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_package[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_package), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(package.flags), "Flags"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(package.count), "Elements"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(package.elements), "Element List"}, + {ACPI_EXD_PACKAGE, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_device[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.handler), "Handler"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.device_notify), + "Device Notify"} +}; + +static struct acpi_exdump_info acpi_ex_dump_event[2] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_event), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.semaphore), "Semaphore"} +}; + +static struct acpi_exdump_info acpi_ex_dump_method[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "param_count"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.concurrency), "Concurrency"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.semaphore), "Semaphore"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(method.aml_length), "Aml Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} +}; + +static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, + {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), + "Acquire Depth"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.semaphore), "Semaphore"} +}; + +static struct acpi_exdump_info acpi_ex_dump_region[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.space_id), "Space Id"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.flags), "Flags"}, + {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(region.address), "Address"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(region.length), "Length"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.handler), "Handler"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.next), "Next"} +}; + +static struct acpi_exdump_info acpi_ex_dump_power[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_power), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.system_level), + "System Level"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.resource_order), + "Resource Order"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.device_notify), + "Device Notify"} +}; + +static struct acpi_exdump_info acpi_ex_dump_processor[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"}, + {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.device_notify), + "Device Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.handler), "Handler"} +}; + +static struct acpi_exdump_info acpi_ex_dump_thermal[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_thermal), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.system_notify), + "System Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.device_notify), + "Device Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.handler), "Handler"} +}; + +static struct acpi_exdump_info acpi_ex_dump_buffer_field[3] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer_field.buffer_obj), + "Buffer Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_region_field[3] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(bank_field.value), "Value"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.region_obj), + "Region Object"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.bank_obj), "Bank Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_index_field[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(index_field.value), "Value"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.index_obj), + "Index Object"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"} +}; + +static struct acpi_exdump_info acpi_ex_dump_reference[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"}, + {ACPI_EXD_REFERENCE, 0, NULL} +}; + +static struct acpi_exdump_info acpi_ex_dump_address_handler[6] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_address_handler), + NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(address_space.space_id), "Space Id"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.next), "Next"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.region_list), + "Region List"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.node), "Node"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"} +}; + +static struct acpi_exdump_info acpi_ex_dump_notify[3] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.node), "Node"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"} +}; + +/* Miscellaneous tables */ + +static struct acpi_exdump_info acpi_ex_dump_common[4] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_common), NULL}, + {ACPI_EXD_TYPE, 0, NULL}, + {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(common.reference_count), + "Reference Count"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common.flags), "Flags"} +}; + +static struct acpi_exdump_info acpi_ex_dump_field_common[7] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_field_common), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.field_flags), + "Field Flags"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.access_byte_width), + "Access Byte Width"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.bit_length), + "Bit Length"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.start_field_bit_offset), + "Field Bit Offset"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.base_byte_offset), + "Base Byte Offset"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(common_field.node), "Parent Node"} +}; + +static struct acpi_exdump_info acpi_ex_dump_node[6] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(flags), "Flags"}, + {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"}, + {ACPI_EXD_UINT16, ACPI_EXD_NSOFFSET(reference_count), + "Reference Count"}, + {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(child), "Child List"}, + {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(peer), "Next Peer"} +}; + +/* Dispatch table, indexed by object type */ + +static struct acpi_exdump_info *acpi_ex_dump_info[] = { + NULL, + acpi_ex_dump_integer, + acpi_ex_dump_string, + acpi_ex_dump_buffer, + acpi_ex_dump_package, + NULL, + acpi_ex_dump_device, + acpi_ex_dump_event, + acpi_ex_dump_method, + acpi_ex_dump_mutex, + acpi_ex_dump_region, + acpi_ex_dump_power, + acpi_ex_dump_processor, + acpi_ex_dump_thermal, + acpi_ex_dump_buffer_field, + NULL, + NULL, + acpi_ex_dump_region_field, + acpi_ex_dump_bank_field, + acpi_ex_dump_index_field, + acpi_ex_dump_reference, + NULL, + NULL, + acpi_ex_dump_notify, + acpi_ex_dump_address_handler, + NULL, + NULL, + NULL +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ex_dump_object + * + * PARAMETERS: obj_desc - Descriptor to dump + * Info - Info table corresponding to this object + * type + * + * RETURN: None + * + * DESCRIPTION: Walk the info table for this object + * + ******************************************************************************/ + +static void +acpi_ex_dump_object(union acpi_operand_object *obj_desc, + struct acpi_exdump_info *info) +{ + u8 *target; + char *name; + u8 count; + + if (!info) { + acpi_os_printf + ("ex_dump_object: Display not implemented for object type %s\n", + acpi_ut_get_object_type_name(obj_desc)); + return; + } + + /* First table entry must contain the table length (# of table entries) */ + + count = info->offset; + + while (count) { + target = ((u8 *) obj_desc) + info->offset; + name = info->name; + + switch (info->opcode) { + case ACPI_EXD_INIT: + break; + + case ACPI_EXD_TYPE: + acpi_ex_out_string("Type", + acpi_ut_get_object_type_name + (obj_desc)); + break; + + case ACPI_EXD_UINT8: + + acpi_os_printf("%20s : %2.2X\n", name, *target); + break; + + case ACPI_EXD_UINT16: + + acpi_os_printf("%20s : %4.4X\n", name, + *ACPI_CAST_PTR(u16, target)); + break; + + case ACPI_EXD_UINT32: + + acpi_os_printf("%20s : %8.8X\n", name, + *ACPI_CAST_PTR(u32, target)); + break; + + case ACPI_EXD_UINT64: + + acpi_os_printf("%20s : %8.8X%8.8X\n", "Value", + ACPI_FORMAT_UINT64(*ACPI_CAST_PTR + (u64, target))); + break; + + case ACPI_EXD_POINTER: + + acpi_ex_out_pointer(name, + *ACPI_CAST_PTR(void *, target)); + break; + + case ACPI_EXD_ADDRESS: + + acpi_ex_out_address(name, + *ACPI_CAST_PTR + (acpi_physical_address, target)); + break; + + case ACPI_EXD_STRING: + + acpi_ut_print_string(obj_desc->string.pointer, + ACPI_UINT8_MAX); + acpi_os_printf("\n"); + break; + + case ACPI_EXD_BUFFER: + + ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, + obj_desc->buffer.length); + break; + + case ACPI_EXD_PACKAGE: + + /* Dump the package contents */ + + acpi_os_printf("\nPackage Contents:\n"); + acpi_ex_dump_package_obj(obj_desc, 0, 0); + break; + + case ACPI_EXD_FIELD: + + acpi_ex_dump_object(obj_desc, + acpi_ex_dump_field_common); + break; + + case ACPI_EXD_REFERENCE: + + acpi_ex_out_string("Opcode", + (acpi_ps_get_opcode_info + (obj_desc->reference.opcode))-> + name); + acpi_ex_dump_reference_obj(obj_desc); + break; + + default: + acpi_os_printf("**** Invalid table opcode [%X] ****\n", + info->opcode); + return; + } + + info++; + count--; + } +} /******************************************************************************* * @@ -441,7 +807,6 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, return; } -#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * * FUNCTION: acpi_ex_out* functions @@ -465,11 +830,6 @@ static void acpi_ex_out_pointer(char *title, void *value) acpi_os_printf("%20s : %p\n", title, value); } -static void acpi_ex_out_integer(char *title, u32 value) -{ - acpi_os_printf("%20s : %.2X\n", title, value); -} - static void acpi_ex_out_address(char *title, acpi_physical_address value) { @@ -482,16 +842,16 @@ static void acpi_ex_out_address(char *title, acpi_physical_address value) /******************************************************************************* * - * FUNCTION: acpi_ex_dump_node + * FUNCTION: acpi_ex_dump_namespace_node * - * PARAMETERS: *Node - Descriptor to dump + * PARAMETERS: Node - Descriptor to dump * Flags - Force display if TRUE * * DESCRIPTION: Dumps the members of the given.Node * ******************************************************************************/ -void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags) +void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags) { ACPI_FUNCTION_ENTRY(); @@ -506,19 +866,17 @@ void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags) acpi_os_printf("%20s : %4.4s\n", "Name", acpi_ut_get_node_name(node)); acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type)); - acpi_ex_out_integer("Flags", node->flags); - acpi_ex_out_integer("Owner Id", node->owner_id); - acpi_ex_out_integer("Reference Count", node->reference_count); acpi_ex_out_pointer("Attached Object", acpi_ns_get_attached_object(node)); - acpi_ex_out_pointer("child_list", node->child); - acpi_ex_out_pointer("next_peer", node->peer); acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node)); + + acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node), + acpi_ex_dump_node); } /******************************************************************************* * - * FUNCTION: acpi_ex_dump_reference + * FUNCTION: acpi_ex_dump_reference_obj * * PARAMETERS: Object - Descriptor to dump * @@ -526,14 +884,16 @@ void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags) * ******************************************************************************/ -static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc) +static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) { struct acpi_buffer ret_buf; acpi_status status; + ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; + if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { acpi_os_printf("Named Object %p ", obj_desc->reference.node); - ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_ns_handle_to_pathname(obj_desc->reference.node, &ret_buf); @@ -551,9 +911,9 @@ static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc) /******************************************************************************* * - * FUNCTION: acpi_ex_dump_package + * FUNCTION: acpi_ex_dump_package_obj * - * PARAMETERS: Object - Descriptor to dump + * PARAMETERS: obj_desc - Descriptor to dump * Level - Indentation Level * Index - Package index for this object * @@ -562,7 +922,8 @@ static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc) ******************************************************************************/ static void -acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index) +acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, + u32 level, u32 index) { u32 i; @@ -622,15 +983,15 @@ acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index) obj_desc->package.count); for (i = 0; i < obj_desc->package.count; i++) { - acpi_ex_dump_package(obj_desc->package.elements[i], - level + 1, i); + acpi_ex_dump_package_obj(obj_desc->package.elements[i], + level + 1, i); } break; case ACPI_TYPE_LOCAL_REFERENCE: acpi_os_printf("[Object Reference] "); - acpi_ex_dump_reference(obj_desc); + acpi_ex_dump_reference_obj(obj_desc); break; default: @@ -645,7 +1006,7 @@ acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index) * * FUNCTION: acpi_ex_dump_object_descriptor * - * PARAMETERS: Object - Descriptor to dump + * PARAMETERS: obj_desc - Descriptor to dump * Flags - Force display if TRUE * * DESCRIPTION: Dumps the members of the object descriptor given. @@ -670,11 +1031,13 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) { - acpi_ex_dump_node((struct acpi_namespace_node *)obj_desc, - flags); + acpi_ex_dump_namespace_node((struct acpi_namespace_node *) + obj_desc, flags); + acpi_os_printf("\nAttached Object (%p):\n", ((struct acpi_namespace_node *)obj_desc)-> object); + acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *) obj_desc)->object, flags); return_VOID; @@ -687,233 +1050,18 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) return_VOID; } - /* Common Fields */ - - acpi_ex_out_string("Type", acpi_ut_get_object_type_name(obj_desc)); - acpi_ex_out_integer("Reference Count", - obj_desc->common.reference_count); - acpi_ex_out_integer("Flags", obj_desc->common.flags); - - /* Object-specific Fields */ - - switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_INTEGER: - - acpi_os_printf("%20s : %8.8X%8.8X\n", "Value", - ACPI_FORMAT_UINT64(obj_desc->integer.value)); - break; - - case ACPI_TYPE_STRING: - - acpi_ex_out_integer("Length", obj_desc->string.length); - - acpi_os_printf("%20s : %p ", "Pointer", - obj_desc->string.pointer); - acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX); - acpi_os_printf("\n"); - break; - - case ACPI_TYPE_BUFFER: - - acpi_ex_out_integer("Length", obj_desc->buffer.length); - acpi_ex_out_pointer("Pointer", obj_desc->buffer.pointer); - ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, - obj_desc->buffer.length); - break; - - case ACPI_TYPE_PACKAGE: - - acpi_ex_out_integer("Flags", obj_desc->package.flags); - acpi_ex_out_integer("Elements", obj_desc->package.count); - acpi_ex_out_pointer("Element List", obj_desc->package.elements); - - /* Dump the package contents */ - - acpi_os_printf("\nPackage Contents:\n"); - acpi_ex_dump_package(obj_desc, 0, 0); - break; - - case ACPI_TYPE_DEVICE: - - acpi_ex_out_pointer("Handler", obj_desc->device.handler); - acpi_ex_out_pointer("system_notify", - obj_desc->device.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->device.device_notify); - break; - - case ACPI_TYPE_EVENT: - - acpi_ex_out_pointer("Semaphore", obj_desc->event.semaphore); - break; - - case ACPI_TYPE_METHOD: - - acpi_ex_out_integer("param_count", - obj_desc->method.param_count); - acpi_ex_out_integer("Concurrency", - obj_desc->method.concurrency); - acpi_ex_out_pointer("Semaphore", obj_desc->method.semaphore); - acpi_ex_out_integer("owner_id", obj_desc->method.owner_id); - acpi_ex_out_integer("aml_length", obj_desc->method.aml_length); - acpi_ex_out_pointer("aml_start", obj_desc->method.aml_start); - break; - - case ACPI_TYPE_MUTEX: - - acpi_ex_out_integer("sync_level", obj_desc->mutex.sync_level); - acpi_ex_out_pointer("owner_thread", - obj_desc->mutex.owner_thread); - acpi_ex_out_integer("acquire_depth", - obj_desc->mutex.acquisition_depth); - acpi_ex_out_pointer("Semaphore", obj_desc->mutex.semaphore); - break; - - case ACPI_TYPE_REGION: - - acpi_ex_out_integer("space_id", obj_desc->region.space_id); - acpi_ex_out_integer("Flags", obj_desc->region.flags); - acpi_ex_out_address("Address", obj_desc->region.address); - acpi_ex_out_integer("Length", obj_desc->region.length); - acpi_ex_out_pointer("Handler", obj_desc->region.handler); - acpi_ex_out_pointer("Next", obj_desc->region.next); - break; - - case ACPI_TYPE_POWER: - - acpi_ex_out_integer("system_level", - obj_desc->power_resource.system_level); - acpi_ex_out_integer("resource_order", - obj_desc->power_resource.resource_order); - acpi_ex_out_pointer("system_notify", - obj_desc->power_resource.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->power_resource.device_notify); - break; - - case ACPI_TYPE_PROCESSOR: - - acpi_ex_out_integer("Processor ID", - obj_desc->processor.proc_id); - acpi_ex_out_integer("Length", obj_desc->processor.length); - acpi_ex_out_address("Address", - (acpi_physical_address) obj_desc->processor. - address); - acpi_ex_out_pointer("system_notify", - obj_desc->processor.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->processor.device_notify); - acpi_ex_out_pointer("Handler", obj_desc->processor.handler); - break; - - case ACPI_TYPE_THERMAL: - - acpi_ex_out_pointer("system_notify", - obj_desc->thermal_zone.system_notify); - acpi_ex_out_pointer("device_notify", - obj_desc->thermal_zone.device_notify); - acpi_ex_out_pointer("Handler", obj_desc->thermal_zone.handler); - break; - - case ACPI_TYPE_BUFFER_FIELD: - case ACPI_TYPE_LOCAL_REGION_FIELD: - case ACPI_TYPE_LOCAL_BANK_FIELD: - case ACPI_TYPE_LOCAL_INDEX_FIELD: - - acpi_ex_out_integer("field_flags", - obj_desc->common_field.field_flags); - acpi_ex_out_integer("access_byte_width", - obj_desc->common_field.access_byte_width); - acpi_ex_out_integer("bit_length", - obj_desc->common_field.bit_length); - acpi_ex_out_integer("fld_bit_offset", - obj_desc->common_field. - start_field_bit_offset); - acpi_ex_out_integer("base_byte_offset", - obj_desc->common_field.base_byte_offset); - acpi_ex_out_pointer("parent_node", obj_desc->common_field.node); - - switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { - case ACPI_TYPE_BUFFER_FIELD: - acpi_ex_out_pointer("buffer_obj", - obj_desc->buffer_field.buffer_obj); - break; - - case ACPI_TYPE_LOCAL_REGION_FIELD: - acpi_ex_out_pointer("region_obj", - obj_desc->field.region_obj); - break; - - case ACPI_TYPE_LOCAL_BANK_FIELD: - acpi_ex_out_integer("Value", - obj_desc->bank_field.value); - acpi_ex_out_pointer("region_obj", - obj_desc->bank_field.region_obj); - acpi_ex_out_pointer("bank_obj", - obj_desc->bank_field.bank_obj); - break; - - case ACPI_TYPE_LOCAL_INDEX_FIELD: - acpi_ex_out_integer("Value", - obj_desc->index_field.value); - acpi_ex_out_pointer("Index", - obj_desc->index_field.index_obj); - acpi_ex_out_pointer("Data", - obj_desc->index_field.data_obj); - break; - - default: - /* All object types covered above */ - break; - } - break; - - case ACPI_TYPE_LOCAL_REFERENCE: - - acpi_ex_out_integer("target_type", - obj_desc->reference.target_type); - acpi_ex_out_string("Opcode", - (acpi_ps_get_opcode_info - (obj_desc->reference.opcode))->name); - acpi_ex_out_integer("Offset", obj_desc->reference.offset); - acpi_ex_out_pointer("obj_desc", obj_desc->reference.object); - acpi_ex_out_pointer("Node", obj_desc->reference.node); - acpi_ex_out_pointer("Where", obj_desc->reference.where); - - acpi_ex_dump_reference(obj_desc); - break; - - case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: - - acpi_ex_out_integer("space_id", - obj_desc->address_space.space_id); - acpi_ex_out_pointer("Next", obj_desc->address_space.next); - acpi_ex_out_pointer("region_list", - obj_desc->address_space.region_list); - acpi_ex_out_pointer("Node", obj_desc->address_space.node); - acpi_ex_out_pointer("Context", obj_desc->address_space.context); - break; + if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) { + return_VOID; + } - case ACPI_TYPE_LOCAL_NOTIFY: + /* Common Fields */ - acpi_ex_out_pointer("Node", obj_desc->notify.node); - acpi_ex_out_pointer("Context", obj_desc->notify.context); - break; + acpi_ex_dump_object(obj_desc, acpi_ex_dump_common); - case ACPI_TYPE_LOCAL_ALIAS: - case ACPI_TYPE_LOCAL_METHOD_ALIAS: - case ACPI_TYPE_LOCAL_EXTRA: - case ACPI_TYPE_LOCAL_DATA: - default: - - acpi_os_printf - ("ex_dump_object_descriptor: Display not implemented for object type %s\n", - acpi_ut_get_object_type_name(obj_desc)); - break; - } + /* Object-specific fields */ + acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]); return_VOID; } -#endif /* ACPI_FUTURE_USAGE */ #endif diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 1899ab25139..00a25f8188f 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -45,6 +45,7 @@ #include <acpi/acpi.h> #include <acpi/acinterp.h> #include <acpi/amlcode.h> +#include <acpi/amlresrc.h> #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exmisc") @@ -157,40 +158,52 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, union acpi_operand_object **actual_return_desc, struct acpi_walk_state *walk_state) { + acpi_status status; union acpi_operand_object *return_desc; u8 *new_buf; - u8 *end_tag1; - u8 *end_tag2; + u8 *end_tag; + acpi_size length0; acpi_size length1; - acpi_size length2; ACPI_FUNCTION_TRACE("ex_concat_template"); - /* Find the end_tags in each resource template */ + /* + * Find the end_tag descriptor in each resource template. + * Note: returned pointers point TO the end_tag, not past it. + * + * Compute the length of each resource template + */ + status = acpi_ut_get_resource_end_tag(operand0, &end_tag); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - end_tag1 = acpi_ut_get_resource_end_tag(operand0); - end_tag2 = acpi_ut_get_resource_end_tag(operand1); - if (!end_tag1 || !end_tag2) { - return_ACPI_STATUS(AE_AML_OPERAND_TYPE); + length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer); + + status = acpi_ut_get_resource_end_tag(operand1, &end_tag); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* Compute the length of each part */ + /* Include the end_tag in the second template length */ - length1 = ACPI_PTR_DIFF(end_tag1, operand0->buffer.pointer); - length2 = ACPI_PTR_DIFF(end_tag2, operand1->buffer.pointer) + 2; /* Size of END_TAG */ + length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer) + + sizeof(struct aml_resource_end_tag); /* Create a new buffer object for the result */ - return_desc = acpi_ut_create_buffer_object(length1 + length2); + return_desc = acpi_ut_create_buffer_object(length0 + length1); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } - /* Copy the templates to the new descriptor */ - + /* + * Copy the templates to the new buffer, 0 first, then 1 follows. One + * end_tag descriptor is copied from Operand1. + */ new_buf = return_desc->buffer.pointer; - ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length1); - ACPI_MEMCPY(new_buf + length1, operand1->buffer.pointer, length2); + ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0); + ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1); /* Compute the new checksum */ @@ -198,7 +211,7 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, acpi_ut_generate_checksum(return_desc->buffer.pointer, (return_desc->buffer.length - 1)); - /* Return the completed template descriptor */ + /* Return the completed resource template */ *actual_return_desc = return_desc; return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index c07b046659f..8167af1fa57 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -399,7 +399,7 @@ acpi_walk_namespace(acpi_object_type type, /* Parameter validation */ - if ((type > ACPI_TYPE_EXTERNAL_MAX) || (!max_depth) || (!user_function)) { + if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index c29d3a44727..eca7439ee9d 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -299,13 +299,14 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) /* Point to the next object */ - resource = ACPI_PTR_ADD(struct acpi_resource, - resource, resource->length); + resource = + ACPI_PTR_ADD(struct acpi_resource, resource, + resource->length); } - /* Did not find an END_TAG descriptor */ + /* Did not find an end_tag resource descriptor */ - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* @@ -328,185 +329,155 @@ acpi_status acpi_rs_get_list_length(u8 * aml_buffer, u32 aml_buffer_length, acpi_size * size_needed) { + acpi_status status; + u8 *end_aml; u8 *buffer; - struct acpi_resource_info *resource_info; u32 buffer_size = 0; - u32 bytes_parsed = 0; - u8 resource_type; u16 temp16; u16 resource_length; - u16 header_length; u32 extra_struct_bytes; + u8 resource_index; + u8 minimum_aml_resource_length; ACPI_FUNCTION_TRACE("rs_get_list_length"); - while (bytes_parsed < aml_buffer_length) { - /* The next byte in the stream is the resource descriptor type */ + end_aml = aml_buffer + aml_buffer_length; - resource_type = acpi_ut_get_resource_type(aml_buffer); + /* Walk the list of AML resource descriptors */ - /* Get the base stream size and structure sizes for the descriptor */ + while (aml_buffer < end_aml) { + /* Validate the Resource Type and Resource Length */ - resource_info = acpi_rs_get_resource_info(resource_type); - if (!resource_info) { - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); + status = acpi_ut_validate_resource(aml_buffer, &resource_index); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); } - /* Get the Length field from the input resource descriptor */ + /* Get the resource length and base (minimum) AML size */ resource_length = acpi_ut_get_resource_length(aml_buffer); + minimum_aml_resource_length = + acpi_gbl_resource_aml_sizes[resource_index]; - /* Augment the size for descriptors with optional fields */ - + /* + * Augment the size for descriptors with optional + * and/or variable length fields + */ extra_struct_bytes = 0; + buffer = + aml_buffer + acpi_ut_get_resource_header_length(aml_buffer); - if (!(resource_type & ACPI_RESOURCE_NAME_LARGE)) { + switch (acpi_ut_get_resource_type(aml_buffer)) { + case ACPI_RESOURCE_NAME_IRQ: /* - * Small resource descriptors + * IRQ Resource: + * Get the number of bits set in the 16-bit IRQ mask */ - header_length = - sizeof(struct aml_resource_small_header); - buffer = aml_buffer + header_length; - - switch (resource_type) { - case ACPI_RESOURCE_NAME_IRQ: - /* - * IRQ Resource: - * Get the number of bits set in the IRQ word - */ - ACPI_MOVE_16_TO_16(&temp16, buffer); - extra_struct_bytes = - (acpi_rs_count_set_bits(temp16) * - sizeof(u32)); - break; - - case ACPI_RESOURCE_NAME_DMA: - /* - * DMA Resource: - * Get the number of bits set in the DMA channels byte - */ - ACPI_MOVE_16_TO_16(&temp16, buffer); - extra_struct_bytes = - (acpi_rs_count_set_bits(temp16) * - sizeof(u32)); - break; - - case ACPI_RESOURCE_NAME_VENDOR_SMALL: - /* - * Vendor Specific Resource: - * Ensure a 32-bit boundary for the structure - */ - extra_struct_bytes = - ACPI_ROUND_UP_to_32_bITS(resource_length); - break; + ACPI_MOVE_16_TO_16(&temp16, buffer); + extra_struct_bytes = + acpi_rs_count_set_bits(temp16) * sizeof(u32); + break; - case ACPI_RESOURCE_NAME_END_TAG: - /* - * End Tag: - * Terminate the loop now - */ - aml_buffer_length = bytes_parsed; - break; + case ACPI_RESOURCE_NAME_DMA: + /* + * DMA Resource: + * Get the number of bits set in the 8-bit DMA mask + */ + extra_struct_bytes = + acpi_rs_count_set_bits(*buffer) * sizeof(u32); + break; - default: - break; - } - } else { + case ACPI_RESOURCE_NAME_VENDOR_SMALL: /* - * Large resource descriptors + * Vendor Resource: + * Ensure a 32-bit boundary for the structure */ - header_length = - sizeof(struct aml_resource_large_header); - buffer = aml_buffer + header_length; + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length) - + resource_length; + break; - switch (resource_type) { - case ACPI_RESOURCE_NAME_VENDOR_LARGE: - /* - * Vendor Defined Resource: - * Add vendor data and ensure a 32-bit boundary for the structure - */ - extra_struct_bytes = - ACPI_ROUND_UP_to_32_bITS(resource_length); - break; + case ACPI_RESOURCE_NAME_END_TAG: + /* + * End Tag: This is the normal exit + */ + *size_needed = buffer_size; + return_ACPI_STATUS(AE_OK); - case ACPI_RESOURCE_NAME_ADDRESS32: - case ACPI_RESOURCE_NAME_ADDRESS16: - /* - * 32-Bit or 16-bit Address Resource: - * Add the size of any optional data (resource_source) - */ - extra_struct_bytes = - acpi_rs_stream_option_length - (resource_length, - resource_info-> - minimum_aml_resource_length); - break; - - case ACPI_RESOURCE_NAME_EXTENDED_IRQ: - /* - * Extended IRQ: - * Point past the interrupt_vector_flags to get the - * interrupt_table_length. - */ - buffer++; + case ACPI_RESOURCE_NAME_VENDOR_LARGE: + /* + * Vendor Resource: + * Add vendor data and ensure a 32-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length) - + resource_length; + break; - /* - * Add 4 bytes for each additional interrupt. Note: at least one - * interrupt is required and is included in the minimum - * descriptor size - */ - extra_struct_bytes = - ((*buffer - 1) * sizeof(u32)); + case ACPI_RESOURCE_NAME_ADDRESS32: + case ACPI_RESOURCE_NAME_ADDRESS16: + /* + * 32-Bit or 16-bit Address Resource: + * Add the size of any optional data (resource_source) + */ + extra_struct_bytes = + acpi_rs_stream_option_length(resource_length, + minimum_aml_resource_length); + break; - /* Add the size of any optional data (resource_source) */ + case ACPI_RESOURCE_NAME_EXTENDED_IRQ: + /* + * Extended IRQ: + * Point past the interrupt_vector_flags to get the + * interrupt_table_length. + */ + buffer++; + + extra_struct_bytes = + /* + * Add 4 bytes for each additional interrupt. Note: at + * least one interrupt is required and is included in + * the minimum descriptor size + */ + ((*buffer - 1) * sizeof(u32)) + + /* Add the size of any optional data (resource_source) */ + acpi_rs_stream_option_length(resource_length - + extra_struct_bytes, + minimum_aml_resource_length); + break; - extra_struct_bytes += - acpi_rs_stream_option_length(resource_length - - - extra_struct_bytes, - resource_info-> - minimum_aml_resource_length); - break; + case ACPI_RESOURCE_NAME_ADDRESS64: + /* + * 64-Bit Address Resource: + * Add the size of any optional data (resource_source) + * Ensure a 64-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_64_bITS + (acpi_rs_stream_option_length + (resource_length, minimum_aml_resource_length)); + break; - case ACPI_RESOURCE_NAME_ADDRESS64: - /* - * 64-Bit Address Resource: - * Add the size of any optional data (resource_source) - * Ensure a 64-bit boundary for the structure - */ - extra_struct_bytes = - ACPI_ROUND_UP_to_64_bITS - (acpi_rs_stream_option_length - (resource_length, - resource_info-> - minimum_aml_resource_length)); - break; - - default: - break; - } + default: + break; } /* Update the required buffer size for the internal descriptor structs */ - temp16 = - (u16) (resource_info->minimum_internal_struct_length + - extra_struct_bytes); + temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + + extra_struct_bytes); buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16); /* - * Update byte count and point to the next resource within the stream + * Point to the next resource within the stream * using the size of the header plus the length contained in the header */ - temp16 = (u16) (header_length + resource_length); - bytes_parsed += temp16; - aml_buffer += temp16; + aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); } - /* This is the data the caller needs */ + /* Did not find an end_tag resource descriptor */ - *size_needed = buffer_size; - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 27172a3d55d..f617ca80c5a 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -324,7 +324,7 @@ static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = { static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags), - "Resource Type", "Memory Range"}, + "Resource Type", (void *)"Memory Range"}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect), "Write Protect", acpi_gbl_RWdecode}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching), @@ -337,7 +337,7 @@ static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = { {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags), - "Resource Type", "I/O Range"}, + "Resource Type", (void *)"I/O Range"}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type), "Range Type", acpi_gbl_RNGdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation), @@ -372,8 +372,8 @@ static struct acpi_rsdump_info acpi_rs_dump_prt[5] = { static void acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) { - void *target = NULL; - void *previous_target; + u8 *target = NULL; + u8 *previous_target; char *name; u8 count; @@ -399,43 +399,49 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) /* Strings */ case ACPI_RSD_LITERAL: - acpi_rs_out_string(name, (char *)table->pointer); + acpi_rs_out_string(name, + ACPI_CAST_PTR(char, table->pointer)); break; case ACPI_RSD_STRING: - acpi_rs_out_string(name, (char *)target); + acpi_rs_out_string(name, ACPI_CAST_PTR(char, target)); break; /* Data items, 8/16/32/64 bit */ case ACPI_RSD_UINT8: - acpi_rs_out_integer8(name, *(u8 *) target); + acpi_rs_out_integer8(name, *ACPI_CAST_PTR(u8, target)); break; case ACPI_RSD_UINT16: - acpi_rs_out_integer16(name, *(u16 *) target); + acpi_rs_out_integer16(name, + *ACPI_CAST_PTR(u16, target)); break; case ACPI_RSD_UINT32: - acpi_rs_out_integer32(name, *(u32 *) target); + acpi_rs_out_integer32(name, + *ACPI_CAST_PTR(u32, target)); break; case ACPI_RSD_UINT64: - acpi_rs_out_integer64(name, *(u64 *) target); + acpi_rs_out_integer64(name, + *ACPI_CAST_PTR(u64, target)); break; /* Flags: 1-bit and 2-bit flags supported */ case ACPI_RSD_1BITFLAG: - acpi_rs_out_string(name, (char *) - ((const char **)table-> - pointer)[(*(u8 *) target) & 0x01]); + acpi_rs_out_string(name, ACPI_CAST_PTR(char, + table-> + pointer[*target & + 0x01])); break; case ACPI_RSD_2BITFLAG: - acpi_rs_out_string(name, (char *) - ((const char **)table-> - pointer)[(*(u8 *) target) & 0x03]); + acpi_rs_out_string(name, ACPI_CAST_PTR(char, + table-> + pointer[*target & + 0x03])); break; case ACPI_RSD_SHORTLIST: @@ -445,10 +451,8 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) */ if (previous_target) { acpi_rs_out_title(name); - acpi_rs_dump_short_byte_list(* - ((u8 *) - previous_target), - (u8 *) target); + acpi_rs_dump_short_byte_list(*previous_target, + target); } break; @@ -458,10 +462,9 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) * Note: The list length is obtained from the previous table entry */ if (previous_target) { - acpi_rs_dump_byte_list(* - ((u16 *) - previous_target), - (u8 *) target); + acpi_rs_dump_byte_list(*ACPI_CAST_PTR + (u16, previous_target), + target); } break; @@ -471,10 +474,9 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) * Note: The list length is obtained from the previous table entry */ if (previous_target) { - acpi_rs_dump_dword_list(* - ((u8 *) - previous_target), - (u32 *) target); + acpi_rs_dump_dword_list(*previous_target, + ACPI_CAST_PTR(u32, + target)); } break; @@ -482,17 +484,19 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) /* * Common flags for all Address resources */ - acpi_rs_dump_address_common((union acpi_resource_data *) - target); + acpi_rs_dump_address_common(ACPI_CAST_PTR + (union acpi_resource_data, + target)); break; case ACPI_RSD_SOURCE: /* * Optional resource_source for Address resources */ - acpi_rs_dump_resource_source((struct - acpi_resource_source *) - target); + acpi_rs_dump_resource_source(ACPI_CAST_PTR + (struct + acpi_resource_source, + target)); break; default: diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c index 973fc2834cb..623b0668933 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/resources/rsinfo.c @@ -80,7 +80,9 @@ struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = { /* Dispatch tables for AML-to-resource (Get Resource) conversion functions */ -struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[] = { +struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[] = { + /* Small descriptors */ + NULL, /* 0x00, Reserved */ NULL, /* 0x01, Reserved */ NULL, /* 0x02, Reserved */ @@ -96,10 +98,10 @@ struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[] = { NULL, /* 0x0C, Reserved */ NULL, /* 0x0D, Reserved */ acpi_rs_get_vendor_small, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */ - acpi_rs_convert_end_tag /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ -}; + acpi_rs_convert_end_tag, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */ + + /* Large descriptors */ -struct acpi_rsconvert_info *acpi_gbl_lg_get_resource_dispatch[] = { NULL, /* 0x00, Reserved */ acpi_rs_convert_memory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */ acpi_rs_convert_generic_reg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */ @@ -138,7 +140,6 @@ struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = { acpi_rs_dump_ext_irq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ }; - #endif #endif /* ACPI_FUTURE_USAGE */ /* @@ -166,62 +167,38 @@ const u8 acpi_gbl_aml_resource_sizes[] = { sizeof(struct aml_resource_generic_register) /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ }; -/* Macros used in the tables below */ +const u8 acpi_gbl_resource_struct_sizes[] = { + /* Small descriptors */ -#define ACPI_RLARGE(r) (sizeof (r) - sizeof (struct aml_resource_large_header)) -#define ACPI_RSMALL(r) (sizeof (r) - sizeof (struct aml_resource_small_header)) + 0, + 0, + 0, + 0, + ACPI_RS_SIZE(struct acpi_resource_irq), + ACPI_RS_SIZE(struct acpi_resource_dma), + ACPI_RS_SIZE(struct acpi_resource_start_dependent), + ACPI_RS_SIZE_MIN, + ACPI_RS_SIZE(struct acpi_resource_io), + ACPI_RS_SIZE(struct acpi_resource_fixed_io), + 0, + 0, + 0, + 0, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RS_SIZE_MIN, -/* - * Base sizes of resource descriptors, both the AML stream resource length - * (minus size of header and length fields),and the size of the internal - * struct representation. - */ -struct acpi_resource_info acpi_gbl_sm_resource_info[] = { - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {2, ACPI_RSMALL(struct aml_resource_irq), - ACPI_RS_SIZE(struct acpi_resource_irq)}, - {0, ACPI_RSMALL(struct aml_resource_dma), - ACPI_RS_SIZE(struct acpi_resource_dma)}, - {2, ACPI_RSMALL(struct aml_resource_start_dependent), - ACPI_RS_SIZE(struct acpi_resource_start_dependent)}, - {0, ACPI_RSMALL(struct aml_resource_end_dependent), ACPI_RS_SIZE_MIN}, - {0, ACPI_RSMALL(struct aml_resource_io), - ACPI_RS_SIZE(struct acpi_resource_io)}, - {0, ACPI_RSMALL(struct aml_resource_fixed_io), - ACPI_RS_SIZE(struct acpi_resource_fixed_io)}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0}, - {1, ACPI_RSMALL(struct aml_resource_vendor_small), - ACPI_RS_SIZE(struct acpi_resource_vendor)}, - {0, ACPI_RSMALL(struct aml_resource_end_tag), ACPI_RS_SIZE_MIN} -}; + /* Large descriptors */ -struct acpi_resource_info acpi_gbl_lg_resource_info[] = { - {0, 0, 0}, - {0, ACPI_RLARGE(struct aml_resource_memory24), - ACPI_RS_SIZE(struct acpi_resource_memory24)}, - {0, ACPI_RLARGE(struct aml_resource_generic_register), - ACPI_RS_SIZE(struct acpi_resource_generic_register)}, - {0, 0, 0}, - {1, ACPI_RLARGE(struct aml_resource_vendor_large), - ACPI_RS_SIZE(struct acpi_resource_vendor)}, - {0, ACPI_RLARGE(struct aml_resource_memory32), - ACPI_RS_SIZE(struct acpi_resource_memory32)}, - {0, ACPI_RLARGE(struct aml_resource_fixed_memory32), - ACPI_RS_SIZE(struct acpi_resource_fixed_memory32)}, - {1, ACPI_RLARGE(struct aml_resource_address32), - ACPI_RS_SIZE(struct acpi_resource_address32)}, - {1, ACPI_RLARGE(struct aml_resource_address16), - ACPI_RS_SIZE(struct acpi_resource_address16)}, - {1, ACPI_RLARGE(struct aml_resource_extended_irq), - ACPI_RS_SIZE(struct acpi_resource_extended_irq)}, - {1, ACPI_RLARGE(struct aml_resource_address64), - ACPI_RS_SIZE(struct acpi_resource_address64)}, - {0, ACPI_RLARGE(struct aml_resource_extended_address64), - ACPI_RS_SIZE(struct acpi_resource_extended_address64)} + 0, + ACPI_RS_SIZE(struct acpi_resource_memory24), + ACPI_RS_SIZE(struct acpi_resource_generic_register), + 0, + ACPI_RS_SIZE(struct acpi_resource_vendor), + ACPI_RS_SIZE(struct acpi_resource_memory32), + ACPI_RS_SIZE(struct acpi_resource_fixed_memory32), + ACPI_RS_SIZE(struct acpi_resource_address32), + ACPI_RS_SIZE(struct acpi_resource_address16), + ACPI_RS_SIZE(struct acpi_resource_extended_irq), + ACPI_RS_SIZE(struct acpi_resource_address64), + ACPI_RS_SIZE(struct acpi_resource_extended_address64) }; diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index ee17ef3315f..b83996233c1 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -47,115 +47,12 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rslist") -/* Local prototypes */ -static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 - resource_type); - -static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); - -/******************************************************************************* - * - * FUNCTION: acpi_rs_validate_resource_length - * - * PARAMETERS: Aml - Pointer to the AML resource descriptor - * - * RETURN: Status - AE_OK if the resource length appears valid - * - * DESCRIPTION: Validate the resource_length. Fixed-length descriptors must - * have the exact length; variable-length descriptors must be - * at least as long as the minimum. Certain Small descriptors - * can vary in size by at most one byte. - * - ******************************************************************************/ - -static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) -{ - struct acpi_resource_info *resource_info; - u16 minimum_aml_resource_length; - u16 resource_length; - - ACPI_FUNCTION_ENTRY(); - - /* Get the size and type info about this resource descriptor */ - - resource_info = - acpi_rs_get_resource_info(aml->small_header.descriptor_type); - if (!resource_info) { - return (AE_AML_INVALID_RESOURCE_TYPE); - } - - resource_length = acpi_ut_get_resource_length(aml); - minimum_aml_resource_length = - resource_info->minimum_aml_resource_length; - - /* Validate based upon the type of resource, fixed length or variable */ - - if (resource_info->length_type == ACPI_FIXED_LENGTH) { - /* Fixed length resource, length must match exactly */ - - if (resource_length != minimum_aml_resource_length) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } else if (resource_info->length_type == ACPI_VARIABLE_LENGTH) { - /* Variable length resource, must be at least the minimum */ - - if (resource_length < minimum_aml_resource_length) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } else { - /* Small variable length resource, allowed to be (Min) or (Min-1) */ - - if ((resource_length > minimum_aml_resource_length) || - (resource_length < (minimum_aml_resource_length - 1))) { - return (AE_AML_BAD_RESOURCE_LENGTH); - } - } - - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_rs_get_conversion_info - * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor - * - * RETURN: Pointer to the resource conversion info table - * - * DESCRIPTION: Get the conversion table associated with this resource type - * - ******************************************************************************/ - -static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) -{ - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (resource_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { - return (NULL); - } - - return (acpi_gbl_lg_get_resource_dispatch[(resource_type & - ACPI_RESOURCE_NAME_LARGE_MASK)]); - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - return (acpi_gbl_sm_get_resource_dispatch[((resource_type & - ACPI_RESOURCE_NAME_SMALL_MASK) - >> 3)]); - } -} - /******************************************************************************* * * FUNCTION: acpi_rs_convert_aml_to_resources * - * PARAMETERS: aml_buffer - Pointer to the resource byte stream - * aml_buffer_length - Length of aml_buffer + * PARAMETERS: Aml - Pointer to the resource byte stream + * aml_length - Length of Aml * output_buffer - Pointer to the buffer that will * contain the output structures * @@ -165,42 +62,24 @@ static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) * linked list of resources in the caller's output buffer * ******************************************************************************/ - acpi_status -acpi_rs_convert_aml_to_resources(u8 * aml_buffer, - u32 aml_buffer_length, u8 * output_buffer) +acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) { - u8 *buffer = output_buffer; + struct acpi_resource *resource = (void *)output_buffer; acpi_status status; - acpi_size bytes_parsed = 0; - struct acpi_resource *resource; - acpi_rsdesc_size descriptor_length; - struct acpi_rsconvert_info *info; + u8 resource_index; + u8 *end_aml; ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); - /* Loop until end-of-buffer or an end_tag is found */ - - while (bytes_parsed < aml_buffer_length) { - /* Get the conversion table associated with this Descriptor Type */ - - info = acpi_rs_get_conversion_info(*aml_buffer); - if (!info) { - /* No table indicates an invalid resource type */ + end_aml = aml + aml_length; - return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); - } + /* Loop until end-of-buffer or an end_tag is found */ - descriptor_length = acpi_ut_get_descriptor_length(aml_buffer); + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ - /* - * Perform limited validation of the resource length, based upon - * what we know about the resource type - */ - status = - acpi_rs_validate_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + status = acpi_ut_validate_resource(aml, &resource_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -208,42 +87,36 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, /* Convert the AML byte stream resource to a local resource struct */ status = - acpi_rs_convert_aml_to_resource(ACPI_CAST_PTR - (struct acpi_resource, - buffer), + acpi_rs_convert_aml_to_resource(resource, ACPI_CAST_PTR(union aml_resource, - aml_buffer), - info); + aml), + acpi_gbl_get_resource_dispatch + [resource_index]); if (ACPI_FAILURE(status)) { - ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); + ACPI_REPORT_ERROR(("Could not convert AML resource (Type %X) to resource, %s\n", *aml, acpi_format_exception(status))); return_ACPI_STATUS(status); } - /* Set the aligned length of the new resource descriptor */ - - resource = ACPI_CAST_PTR(struct acpi_resource, buffer); - resource->length = - (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); - /* Normal exit on completion of an end_tag resource descriptor */ - if (acpi_ut_get_resource_type(aml_buffer) == + if (acpi_ut_get_resource_type(aml) == ACPI_RESOURCE_NAME_END_TAG) { return_ACPI_STATUS(AE_OK); } - /* Update counter and point to the next input resource */ + /* Point to the next input AML resource */ - bytes_parsed += descriptor_length; - aml_buffer += descriptor_length; + aml += acpi_ut_get_descriptor_length(aml); /* Point to the next structure in the output buffer */ - buffer += resource->length; + resource = + ACPI_PTR_ADD(struct acpi_resource, resource, + resource->length); } - /* Completed buffer, but did not find an end_tag resource descriptor */ + /* Did not find an end_tag resource descriptor */ return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } @@ -271,16 +144,16 @@ acpi_status acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, acpi_size aml_size_needed, u8 * output_buffer) { - u8 *aml_buffer = output_buffer; - u8 *end_aml_buffer = output_buffer + aml_size_needed; + u8 *aml = output_buffer; + u8 *end_aml = output_buffer + aml_size_needed; acpi_status status; ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); /* Walk the resource descriptor list, convert each descriptor */ - while (aml_buffer < end_aml_buffer) { - /* Validate the Resource Type */ + while (aml < end_aml) { + /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, @@ -294,7 +167,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union aml_resource, - aml_buffer), + aml), acpi_gbl_set_resource_dispatch [resource->type]); if (ACPI_FAILURE(status)) { @@ -305,9 +178,8 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Perform final sanity check on the new AML resource descriptor */ status = - acpi_rs_validate_resource_length(ACPI_CAST_PTR - (union aml_resource, - aml_buffer)); + acpi_ut_validate_resource(ACPI_CAST_PTR + (union aml_resource, aml), NULL); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -322,18 +194,15 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* * Extract the total length of the new descriptor and set the - * aml_buffer to point to the next (output) resource descriptor + * Aml to point to the next (output) resource descriptor */ - aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); + aml += acpi_ut_get_descriptor_length(aml); /* Point to the next input resource descriptor */ resource = ACPI_PTR_ADD(struct acpi_resource, resource, resource->length); - - /* Check for end-of-list, normal exit */ - } /* Completed buffer, but did not find an end_tag resource descriptor */ diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 7613033f5dc..a1eac0f1df5 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -65,6 +65,8 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) acpi_native_uint i; u8 bit_count; + ACPI_FUNCTION_ENTRY(); + /* Decode the mask bits */ for (i = 0, bit_count = 0; mask; i++) { @@ -97,6 +99,8 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count) acpi_native_uint i; u16 mask; + ACPI_FUNCTION_ENTRY(); + /* Encode the list into a single bitmask */ for (i = 0, mask = 0; i < count; i++) { @@ -128,6 +132,8 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) { acpi_native_uint i; + ACPI_FUNCTION_ENTRY(); + /* One move per item */ for (i = 0; i < item_count; i++) { @@ -168,53 +174,6 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) /******************************************************************************* * - * FUNCTION: acpi_rs_get_resource_info - * - * PARAMETERS: resource_type - Byte 0 of a resource descriptor - * - * RETURN: Pointer to the resource conversion handler - * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. - * - ******************************************************************************/ - -struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type) -{ - struct acpi_resource_info *size_info; - - ACPI_FUNCTION_ENTRY(); - - /* Determine if this is a small or large resource */ - - if (resource_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { - return (NULL); - } - - size_info = &acpi_gbl_lg_resource_info[(resource_type & - ACPI_RESOURCE_NAME_LARGE_MASK)]; - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - size_info = &acpi_gbl_sm_resource_info[((resource_type & - ACPI_RESOURCE_NAME_SMALL_MASK) - >> 3)]; - } - - /* Zero entry indicates an invalid resource type */ - - if (!size_info->minimum_internal_struct_length) { - return (NULL); - } - - return (size_info); -} - -/******************************************************************************* - * * FUNCTION: acpi_rs_set_resource_length * * PARAMETERS: total_length - Length of the AML descriptor, including @@ -238,25 +197,20 @@ acpi_rs_set_resource_length(acpi_rsdesc_size total_length, ACPI_FUNCTION_ENTRY(); - /* Determine if this is a small or large resource */ + /* Length is the total descriptor length minus the header length */ - if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource type -- bytes 1-2 contain the 16-bit length */ + resource_length = (acpi_rs_length) + (total_length - acpi_ut_get_resource_header_length(aml)); - resource_length = (acpi_rs_length) - (total_length - sizeof(struct aml_resource_large_header)); + /* Length is stored differently for large and small descriptors */ - /* Insert length into the Large descriptor length field */ + if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { + /* Large descriptor -- bytes 1-2 contain the 16-bit length */ ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, &resource_length); } else { - /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - - resource_length = (acpi_rs_length) - (total_length - sizeof(struct aml_resource_small_header)); - - /* Insert length into the descriptor type byte */ + /* Small descriptor -- bits 2:0 of byte 0 contain the length */ aml->small_header.descriptor_type = (u8) @@ -292,7 +246,7 @@ acpi_rs_set_resource_header(u8 descriptor_type, { ACPI_FUNCTION_ENTRY(); - /* Set the Descriptor Type */ + /* Set the Resource Type */ aml->small_header.descriptor_type = descriptor_type; @@ -409,14 +363,14 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length, (char *)&aml_resource_source[1]); return ((acpi_rs_length) total_length); - } else { - /* resource_source is not present */ - - resource_source->index = 0; - resource_source->string_length = 0; - resource_source->string_ptr = NULL; - return (0); } + + /* resource_source is not present */ + + resource_source->index = 0; + resource_source->string_length = 0; + resource_source->string_ptr = NULL; + return (0); } /******************************************************************************* diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile index e87108b7338..88eff14c489 100644 --- a/drivers/acpi/utilities/Makefile +++ b/drivers/acpi/utilities/Makefile @@ -2,7 +2,8 @@ # Makefile for all Linux ACPI interpreter subdirectories # -obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ - utcopy.o utdelete.o utglobal.o utmath.o utobject.o utstate.o utmutex.o utobject.o utcache.o +obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ + utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ + utstate.o utmutex.o utobject.o utcache.o utresrc.o EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index e9058d4da12..2a9110c0639 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -43,7 +43,6 @@ #include <acpi/acpi.h> #include <acpi/acnamesp.h> -#include <acpi/amlresrc.h> #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") @@ -791,153 +790,6 @@ u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) /******************************************************************************* * - * FUNCTION: acpi_ut_get_resource_type - * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor - * - * RETURN: The Resource Type with no extraneous bits (except the - * Large/Small descriptor bit -- this is left alone) - * - * DESCRIPTION: Extract the Resource Type/Name from the first byte of - * a resource descriptor. - * - ******************************************************************************/ - -u8 acpi_ut_get_resource_type(void *aml) -{ - ACPI_FUNCTION_ENTRY(); - - /* - * Byte 0 contains the descriptor name (Resource Type) - * Determine if this is a small or large resource - */ - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ - - return (*((u8 *) aml)); - } else { - /* Small Resource Type -- bits 6:3 contain the name */ - - return ((u8) (*((u8 *) aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_resource_length - * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor - * - * RETURN: Byte Length - * - * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By - * definition, this does not include the size of the descriptor - * header or the length field itself. - * - ******************************************************************************/ - -u16 acpi_ut_get_resource_length(void *aml) -{ - u16 resource_length; - - ACPI_FUNCTION_ENTRY(); - - /* - * Byte 0 contains the descriptor name (Resource Type) - * Determine if this is a small or large resource - */ - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource type -- bytes 1-2 contain the 16-bit length */ - - ACPI_MOVE_16_TO_16(&resource_length, &((u8 *) aml)[1]); - - } else { - /* Small Resource type -- bits 2:0 of byte 0 contain the length */ - - resource_length = (u16) (*((u8 *) aml) & - ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); - } - - return (resource_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_descriptor_length - * - * PARAMETERS: Aml - Pointer to the raw AML resource descriptor - * - * RETURN: Byte length - * - * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the - * length of the descriptor header and the length field itself. - * Used to walk descriptor lists. - * - ******************************************************************************/ - -u32 acpi_ut_get_descriptor_length(void *aml) -{ - u32 descriptor_length; - - ACPI_FUNCTION_ENTRY(); - - /* First get the Resource Length (Does not include header length) */ - - descriptor_length = acpi_ut_get_resource_length(aml); - - /* Determine if this is a small or large resource */ - - if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { - descriptor_length += sizeof(struct aml_resource_large_header); - } else { - descriptor_length += sizeof(struct aml_resource_small_header); - } - - return (descriptor_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_resource_end_tag - * - * PARAMETERS: obj_desc - The resource template buffer object - * - * RETURN: Pointer to the end tag - * - * DESCRIPTION: Find the END_TAG resource descriptor in an AML resource template - * - ******************************************************************************/ - -u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc) -{ - u8 *aml; - u8 *end_aml; - - aml = obj_desc->buffer.pointer; - end_aml = aml + obj_desc->buffer.length; - - /* Walk the resource template, one descriptor per loop */ - - while (aml < end_aml) { - if (acpi_ut_get_resource_type(aml) == - ACPI_RESOURCE_NAME_END_TAG) { - /* Found the end_tag descriptor, all done */ - - return (aml); - } - - /* Point to the next resource descriptor */ - - aml += acpi_ut_get_resource_length(aml); - } - - /* End tag was not found */ - - return (NULL); -} - -/******************************************************************************* - * * FUNCTION: acpi_ut_report_error * * PARAMETERS: module_name - Caller's module name (for error output) diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c new file mode 100644 index 00000000000..07a314c710d --- /dev/null +++ b/drivers/acpi/utilities/utresrc.c @@ -0,0 +1,428 @@ +/******************************************************************************* + * + * Module Name: utresrc - Resource managment utilities + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2005, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include <acpi/amlresrc.h> + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utmisc") + +/* + * Base sizes of the raw AML resource descriptors, indexed by resource type. + * Zero indicates a reserved (and therefore invalid) resource type. + */ +const u8 acpi_gbl_resource_aml_sizes[] = { + /* Small descriptors */ + + 0, + 0, + 0, + 0, + ACPI_AML_SIZE_SMALL(struct aml_resource_irq), + ACPI_AML_SIZE_SMALL(struct aml_resource_dma), + ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent), + ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent), + ACPI_AML_SIZE_SMALL(struct aml_resource_io), + ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io), + 0, + 0, + 0, + 0, + ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small), + ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag), + + /* Large descriptors */ + + 0, + ACPI_AML_SIZE_LARGE(struct aml_resource_memory24), + ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register), + 0, + ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large), + ACPI_AML_SIZE_LARGE(struct aml_resource_memory32), + ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32), + ACPI_AML_SIZE_LARGE(struct aml_resource_address32), + ACPI_AML_SIZE_LARGE(struct aml_resource_address16), + ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq), + ACPI_AML_SIZE_LARGE(struct aml_resource_address64), + ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64) +}; + +/* + * Resource types, used to validate the resource length field. + * The length of fixed-length types must match exactly, variable + * lengths must meet the minimum required length, etc. + * Zero indicates a reserved (and therefore invalid) resource type. + */ +static const u8 acpi_gbl_resource_types[] = { + /* Small descriptors */ + + 0, + 0, + 0, + 0, + ACPI_SMALL_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_SMALL_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + 0, + 0, + 0, + 0, + ACPI_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + + /* Large descriptors */ + + 0, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + 0, + ACPI_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_FIXED_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_VARIABLE_LENGTH, + ACPI_FIXED_LENGTH +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_validate_resource + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * return_index - Where the resource index is returned. NULL + * if the index is not required. + * + * RETURN: Status, and optionally the Index into the global resource tables + * + * DESCRIPTION: Validate an AML resource descriptor by checking the Resource + * Type and Resource Length. Returns an index into the global + * resource information/dispatch tables for later use. + * + ******************************************************************************/ + +acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index) +{ + u8 resource_type; + u8 resource_index; + acpi_rs_length resource_length; + acpi_rs_length minimum_resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* + * 1) Validate the resource_type field (Byte 0) + */ + resource_type = *((u8 *) aml); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Examine the large/small bit in the resource header + */ + if (resource_type & ACPI_RESOURCE_NAME_LARGE) { + /* Verify the large resource type (name) against the max */ + + if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { + return (AE_AML_INVALID_RESOURCE_TYPE); + } + + /* + * Large Resource Type -- bits 6:0 contain the name + * Translate range 0x80-0x8B to index range 0x10-0x1B + */ + resource_index = (u8) (resource_type - 0x70); + } else { + /* + * Small Resource Type -- bits 6:3 contain the name + * Shift range to index range 0x00-0x0F + */ + resource_index = (u8) + ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); + } + + /* Check validity of the resource type, zero indicates name is invalid */ + + if (!acpi_gbl_resource_types[resource_index]) { + return (AE_AML_INVALID_RESOURCE_TYPE); + } + + /* + * 2) Validate the resource_length field. This ensures that the length + * is at least reasonable, and guarantees that it is non-zero. + */ + resource_length = acpi_ut_get_resource_length(aml); + minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index]; + + /* Validate based upon the type of resource - fixed length or variable */ + + switch (acpi_gbl_resource_types[resource_index]) { + case ACPI_FIXED_LENGTH: + + /* Fixed length resource, length must match exactly */ + + if (resource_length != minimum_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + break; + + case ACPI_VARIABLE_LENGTH: + + /* Variable length resource, length must be at least the minimum */ + + if (resource_length < minimum_resource_length) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + break; + + case ACPI_SMALL_VARIABLE_LENGTH: + + /* Small variable length resource, length can be (Min) or (Min-1) */ + + if ((resource_length > minimum_resource_length) || + (resource_length < (minimum_resource_length - 1))) { + return (AE_AML_BAD_RESOURCE_LENGTH); + } + break; + + default: + + /* Shouldn't happen (because of validation earlier), but be sure */ + + return (AE_AML_INVALID_RESOURCE_TYPE); + } + + /* Optionally return the resource table index */ + + if (return_index) { + *return_index = resource_index; + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_type + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: The Resource Type with no extraneous bits (except the + * Large/Small descriptor bit -- this is left alone) + * + * DESCRIPTION: Extract the Resource Type/Name from the first byte of + * a resource descriptor. + * + ******************************************************************************/ + +u8 acpi_ut_get_resource_type(void *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Examine the large/small bit in the resource header + */ + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource Type -- bits 6:0 contain the name */ + + return (*((u8 *) aml)); + } else { + /* Small Resource Type -- bits 6:3 contain the name */ + + return ((u8) (*((u8 *) aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte Length + * + * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By + * definition, this does not include the size of the descriptor + * header or the length field itself. + * + ******************************************************************************/ + +u16 acpi_ut_get_resource_length(void *aml) +{ + acpi_rs_length resource_length; + + ACPI_FUNCTION_ENTRY(); + + /* + * Byte 0 contains the descriptor name (Resource Type) + * Examine the large/small bit in the resource header + */ + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + /* Large Resource type -- bytes 1-2 contain the 16-bit length */ + + ACPI_MOVE_16_TO_16(&resource_length, &((u8 *) aml)[1]); + + } else { + /* Small Resource type -- bits 2:0 of byte 0 contain the length */ + + resource_length = (u16) (*((u8 *) aml) & + ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); + } + + return (resource_length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_header_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Length of the AML header (depends on large/small descriptor) + * + * DESCRIPTION: Get the length of the header for this resource. + * + ******************************************************************************/ + +u8 acpi_ut_get_resource_header_length(void *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* Examine the large/small bit in the resource header */ + + if (*((u8 *) aml) & ACPI_RESOURCE_NAME_LARGE) { + return (sizeof(struct aml_resource_large_header)); + } else { + return (sizeof(struct aml_resource_small_header)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_descriptor_length + * + * PARAMETERS: Aml - Pointer to the raw AML resource descriptor + * + * RETURN: Byte length + * + * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the + * length of the descriptor header and the length field itself. + * Used to walk descriptor lists. + * + ******************************************************************************/ + +u32 acpi_ut_get_descriptor_length(void *aml) +{ + ACPI_FUNCTION_ENTRY(); + + /* + * Get the Resource Length (does not include header length) and add + * the header length (depends on if this is a small or large resource) + */ + return (acpi_ut_get_resource_length(aml) + + acpi_ut_get_resource_header_length(aml)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_resource_end_tag + * + * PARAMETERS: obj_desc - The resource template buffer object + * + * RETURN: Pointer to the end tag + * + * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template + * + ******************************************************************************/ + +acpi_status +acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, + u8 ** end_tag) +{ + acpi_status status; + u8 *aml; + u8 *end_aml; + + ACPI_FUNCTION_TRACE("ut_get_resource_end_tag"); + + /* Get start and end pointers */ + + aml = obj_desc->buffer.pointer; + end_aml = aml + obj_desc->buffer.length; + + /* Walk the resource template, one descriptor per iteration */ + + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ + + status = acpi_ut_validate_resource(aml, NULL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* end_tag resource indicates the end of the resource template */ + + if (acpi_ut_get_resource_type(aml) == + ACPI_RESOURCE_NAME_END_TAG) { + /* Return the pointer to the end_tag */ + + *end_tag = aml; + return_ACPI_STATUS(AE_OK); + } + + /* + * Point to the next resource descriptor in the AML buffer. The + * descriptor length is guaranteed to be non-zero by resource + * validation above. + */ + aml += acpi_ut_get_descriptor_length(aml); + } + + /* Did not find an end_tag resource descriptor */ + + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); +} diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c index c1cb27583be..6ff1d707334 100644 --- a/drivers/acpi/utilities/utstate.c +++ b/drivers/acpi/utilities/utstate.c @@ -63,7 +63,7 @@ acpi_status acpi_ut_create_pkg_state_and_push(void *internal_object, void *external_object, u16 index, - union acpi_generic_state ** state_list) + union acpi_generic_state **state_list) { union acpi_generic_state *state; diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index f06bd5e5e9d..57adc5bc02f 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c @@ -178,10 +178,14 @@ acpi_status acpi_enable_subsystem(u32 flags) /* * Initialize ACPI Event handling (Fixed and General Purpose) * - * NOTE: We must have the hardware AND events initialized before we can - * execute ANY control methods SAFELY. Any control method can require - * ACPI hardware support, so the hardware MUST be initialized before - * execution! + * Note1: We must have the hardware and events initialized before we can + * execute any control methods safely. Any control method can require + * ACPI hardware support, so the hardware must be fully initialized before + * any method execution! + * + * Note2: Fixed events are initialized and enabled here. GPEs are + * initialized, but cannot be enabled until after the hardware is + * completely initialized (SCI and global_lock activated) */ if (!(flags & ACPI_NO_EVENT_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -193,8 +197,10 @@ acpi_status acpi_enable_subsystem(u32 flags) } } - /* Install the SCI handler and Global Lock handler */ - + /* + * Install the SCI handler and Global Lock handler. This completes the + * hardware initialization. + */ if (!(flags & ACPI_NO_HANDLER_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n")); @@ -205,6 +211,24 @@ acpi_status acpi_enable_subsystem(u32 flags) } } + /* + * Complete the GPE initialization for the GPE blocks defined in the FADT + * (GPE block 0 and 1). + * + * Note1: This is where the _PRW methods are executed for the GPEs. These + * methods can only be executed after the SCI and Global Lock handlers are + * installed and initialized. + * + * Note2: Currently, there seems to be no need to run the _REG methods + * before execution of the _PRW methods and enabling of the GPEs. + */ + if (!(flags & ACPI_NO_EVENT_INIT)) { + status = acpi_ev_install_fadt_gpes(); + if (ACPI_FAILURE(status)) { + return (status); + } + } + return_ACPI_STATUS(status); } @@ -230,9 +254,9 @@ acpi_status acpi_initialize_objects(u32 flags) /* * Run all _REG methods * - * NOTE: Any objects accessed - * by the _REG methods will be automatically initialized, even if they - * contain executable AML (see call to acpi_ns_initialize_objects below). + * Note: Any objects accessed by the _REG methods will be automatically + * initialized, even if they contain executable AML (see the call to + * acpi_ns_initialize_objects below). */ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -245,9 +269,9 @@ acpi_status acpi_initialize_objects(u32 flags) } /* - * Initialize the objects that remain uninitialized. This - * runs the executable AML that may be part of the declaration of these - * objects: operation_regions, buffer_fields, Buffers, and Packages. + * Initialize the objects that remain uninitialized. This runs the + * executable AML that may be part of the declaration of these objects: + * operation_regions, buffer_fields, Buffers, and Packages. */ if (!(flags & ACPI_NO_OBJECT_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -260,8 +284,8 @@ acpi_status acpi_initialize_objects(u32 flags) } /* - * Initialize all device objects in the namespace - * This runs the _STA and _INI methods. + * Initialize all device objects in the namespace. This runs the device + * _STA and _INI methods. */ if (!(flags & ACPI_NO_DEVICE_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 7676afec09a..d371ec6b981 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20051021 +#define ACPI_CA_VERSION 0x20051102 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h index bfa54600ecd..b40062c3ba7 100644 --- a/include/acpi/acevents.h +++ b/include/acpi/acevents.h @@ -51,6 +51,8 @@ acpi_status acpi_ev_initialize_events(void); acpi_status acpi_ev_install_xrupt_handlers(void); +acpi_status acpi_ev_install_fadt_gpes(void); + u32 acpi_ev_fixed_event_detect(void); /* @@ -105,6 +107,10 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, u32 interrupt_number, struct acpi_gpe_block_info **return_gpe_block); +acpi_status +acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, + struct acpi_gpe_block_info *gpe_block); + acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); u32 diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index 2c9c1a1d1b7..87e5e44572c 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h @@ -44,7 +44,49 @@ #ifndef __ACINTERP_H__ #define __ACINTERP_H__ -#define ACPI_WALK_OPERANDS (&(walk_state->operands [walk_state->num_operands -1])) +#define ACPI_WALK_OPERANDS (&(walk_state->operands [walk_state->num_operands -1])) + +/* Macros for tables used for debug output */ + +#define ACPI_EXD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_operand_object,f) +#define ACPI_EXD_NSOFFSET(f) (u8) ACPI_OFFSET (struct acpi_namespace_node,f) +#define ACPI_EXD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_exdump_info)) + +/* + * If possible, pack the following structure to byte alignment, since we + * don't care about performance for debug output + */ +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED +#pragma pack(1) +#endif + +typedef const struct acpi_exdump_info { + u8 opcode; + u8 offset; + char *name; + +} acpi_exdump_info; + +/* Values for the Opcode field above */ + +#define ACPI_EXD_INIT 0 +#define ACPI_EXD_TYPE 1 +#define ACPI_EXD_UINT8 2 +#define ACPI_EXD_UINT16 3 +#define ACPI_EXD_UINT32 4 +#define ACPI_EXD_UINT64 5 +#define ACPI_EXD_LITERAL 6 +#define ACPI_EXD_POINTER 7 +#define ACPI_EXD_ADDRESS 8 +#define ACPI_EXD_STRING 9 +#define ACPI_EXD_BUFFER 10 +#define ACPI_EXD_PACKAGE 11 +#define ACPI_EXD_FIELD 12 +#define ACPI_EXD_REFERENCE 13 + +/* restore default alignment */ + +#pragma pack() /* * exconvrt - object conversion @@ -327,7 +369,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, void acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags); -void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags); +void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags); #endif /* ACPI_FUTURE_USAGE */ /* diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index 25cff0d5ba5..2bf53940f25 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h @@ -101,27 +101,11 @@ typedef const struct acpi_rsconvert_info { #define ACPI_RS_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_resource,f) #define AML_OFFSET(f) (u8) ACPI_OFFSET (union aml_resource,f) -/* - * Resource dispatch and info tables - */ -typedef const struct acpi_resource_info { - u8 length_type; - u8 minimum_aml_resource_length; - u8 minimum_internal_struct_length; - -} acpi_resource_info; - -/* Types for length_type above */ - -#define ACPI_FIXED_LENGTH 0 -#define ACPI_VARIABLE_LENGTH 1 -#define ACPI_SMALL_VARIABLE_LENGTH 2 - typedef const struct acpi_rsdump_info { u8 opcode; u8 offset; char *name; - const void *pointer; + const char **pointer; } acpi_rsdump_info; @@ -153,10 +137,9 @@ extern struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[]; /* Resource tables indexed by raw AML resource descriptor type */ -extern struct acpi_resource_info acpi_gbl_sm_resource_info[]; -extern struct acpi_resource_info acpi_gbl_lg_resource_info[]; -extern struct acpi_rsconvert_info *acpi_gbl_sm_get_resource_dispatch[]; -extern struct acpi_rsconvert_info *acpi_gbl_lg_get_resource_dispatch[]; +extern struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[]; + +extern const u8 acpi_gbl_resource_struct_sizes[]; /* * rscreate @@ -272,8 +255,6 @@ void acpi_rs_set_resource_length(acpi_rsdesc_size total_length, union aml_resource *aml); -struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type); - /* * rsdump */ diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 7386eb81bd2..4ff963323de 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -44,6 +44,15 @@ #ifndef _ACUTILS_H #define _ACUTILS_H +extern const u8 acpi_gbl_resource_aml_sizes[]; + +/* Types for Resource descriptor entries */ + +#define ACPI_INVALID_RESOURCE 0 +#define ACPI_FIXED_LENGTH 1 +#define ACPI_VARIABLE_LENGTH 2 +#define ACPI_SMALL_VARIABLE_LENGTH 3 + typedef acpi_status(*acpi_pkg_callback) (u8 object_type, union acpi_operand_object * source_object, @@ -418,13 +427,19 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); #define ACPI_ANY_BASE 0 +acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index); + u32 acpi_ut_get_descriptor_length(void *aml); u16 acpi_ut_get_resource_length(void *aml); +u8 acpi_ut_get_resource_header_length(void *aml); + u8 acpi_ut_get_resource_type(void *aml); -u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc); +acpi_status +acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, + u8 ** end_tag); u8 acpi_ut_generate_checksum(u8 * buffer, u32 length); diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index 3112be52773..2e3382c1e5e 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h @@ -92,6 +92,11 @@ struct asl_resource_node { struct asl_resource_node *next; }; +/* Macros used to generate AML resource length fields */ + +#define ACPI_AML_SIZE_LARGE(r) (sizeof (r) - sizeof (struct aml_resource_large_header)) +#define ACPI_AML_SIZE_SMALL(r) (sizeof (r) - sizeof (struct aml_resource_small_header)) + /* * Resource descriptors defined in the ACPI specification. * |