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