ACPI 5.0: Support for all new resource descriptors
FixedDMA, GPIO descriptors, SerialBus descriptors Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
@@ -83,6 +83,10 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
|
||||
|
||||
ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource);
|
||||
|
||||
if (!info) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
if (((acpi_size) resource) & 0x3) {
|
||||
|
||||
/* Each internal resource struct is expected to be 32-bit aligned */
|
||||
@@ -101,7 +105,6 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
|
||||
* table length (# of table entries)
|
||||
*/
|
||||
count = INIT_TABLE_LENGTH(info);
|
||||
|
||||
while (count) {
|
||||
/*
|
||||
* Source is the external AML byte stream buffer,
|
||||
@@ -145,6 +148,14 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
|
||||
((ACPI_GET8(source) >> info->value) & 0x03);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_3BITFLAG:
|
||||
/*
|
||||
* Mask and shift the flag bits
|
||||
*/
|
||||
ACPI_SET8(destination) = (u8)
|
||||
((ACPI_GET8(source) >> info->value) & 0x07);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT:
|
||||
|
||||
item_count = ACPI_GET8(source);
|
||||
@@ -163,6 +174,69 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
|
||||
(info->value * (item_count - 1));
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_GPIO_PIN:
|
||||
|
||||
target = ACPI_ADD_PTR(void, aml, info->value);
|
||||
item_count = ACPI_GET16(target) - ACPI_GET16(source);
|
||||
|
||||
resource->length = resource->length + item_count;
|
||||
item_count = item_count / 2;
|
||||
ACPI_SET16(destination) = item_count;
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_GPIO_VEN:
|
||||
|
||||
item_count = ACPI_GET8(source);
|
||||
ACPI_SET8(destination) = (u8)item_count;
|
||||
|
||||
resource->length = resource->length +
|
||||
(info->value * item_count);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_GPIO_RES:
|
||||
|
||||
/*
|
||||
* Vendor data is optional (length/offset may both be zero)
|
||||
* Examine vendor data length field first
|
||||
*/
|
||||
target = ACPI_ADD_PTR(void, aml, (info->value + 2));
|
||||
if (ACPI_GET16(target)) {
|
||||
|
||||
/* Use vendor offset to get resource source length */
|
||||
|
||||
target = ACPI_ADD_PTR(void, aml, info->value);
|
||||
item_count =
|
||||
ACPI_GET16(target) - ACPI_GET16(source);
|
||||
} else {
|
||||
/* No vendor data to worry about */
|
||||
|
||||
item_count = aml->large_header.resource_length +
|
||||
sizeof(struct aml_resource_large_header) -
|
||||
ACPI_GET16(source);
|
||||
}
|
||||
|
||||
resource->length = resource->length + item_count;
|
||||
ACPI_SET16(destination) = item_count;
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_SERIAL_VEN:
|
||||
|
||||
item_count = ACPI_GET16(source) - info->value;
|
||||
|
||||
resource->length = resource->length + item_count;
|
||||
ACPI_SET16(destination) = item_count;
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_SERIAL_RES:
|
||||
|
||||
item_count = (aml_resource_length +
|
||||
sizeof(struct aml_resource_large_header))
|
||||
- ACPI_GET16(source) - info->value;
|
||||
|
||||
resource->length = resource->length + item_count;
|
||||
ACPI_SET16(destination) = item_count;
|
||||
break;
|
||||
|
||||
case ACPI_RSC_LENGTH:
|
||||
|
||||
resource->length = resource->length + info->value;
|
||||
@@ -183,6 +257,72 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_GPIO_PIN:
|
||||
|
||||
/* Generate and set the PIN data pointer */
|
||||
|
||||
target = (char *)ACPI_ADD_PTR(void, resource,
|
||||
(resource->length -
|
||||
item_count * 2));
|
||||
*(u16 **)destination = ACPI_CAST_PTR(u16, target);
|
||||
|
||||
/* Copy the PIN data */
|
||||
|
||||
source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source));
|
||||
acpi_rs_move_data(target, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_GPIO_RES:
|
||||
|
||||
/* Generate and set the resource_source string pointer */
|
||||
|
||||
target = (char *)ACPI_ADD_PTR(void, resource,
|
||||
(resource->length -
|
||||
item_count));
|
||||
*(u8 **)destination = ACPI_CAST_PTR(u8, target);
|
||||
|
||||
/* Copy the resource_source string */
|
||||
|
||||
source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source));
|
||||
acpi_rs_move_data(target, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_SERIAL_VEN:
|
||||
|
||||
/* Generate and set the Vendor Data pointer */
|
||||
|
||||
target = (char *)ACPI_ADD_PTR(void, resource,
|
||||
(resource->length -
|
||||
item_count));
|
||||
*(u8 **)destination = ACPI_CAST_PTR(u8, target);
|
||||
|
||||
/* Copy the Vendor Data */
|
||||
|
||||
source = ACPI_ADD_PTR(void, aml, info->value);
|
||||
acpi_rs_move_data(target, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_SERIAL_RES:
|
||||
|
||||
/* Generate and set the resource_source string pointer */
|
||||
|
||||
target = (char *)ACPI_ADD_PTR(void, resource,
|
||||
(resource->length -
|
||||
item_count));
|
||||
*(u8 **)destination = ACPI_CAST_PTR(u8, target);
|
||||
|
||||
/* Copy the resource_source string */
|
||||
|
||||
source =
|
||||
ACPI_ADD_PTR(void, aml,
|
||||
(ACPI_GET16(source) + info->value));
|
||||
acpi_rs_move_data(target, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_SET8:
|
||||
|
||||
ACPI_MEMSET(destination, info->aml_offset, info->value);
|
||||
@@ -219,13 +359,18 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
|
||||
* Optional resource_source (Index and String). This is the more
|
||||
* complicated case used by the Interrupt() macro
|
||||
*/
|
||||
target =
|
||||
ACPI_ADD_PTR(char, resource,
|
||||
info->aml_offset + (item_count * 4));
|
||||
target = ACPI_ADD_PTR(char, resource,
|
||||
info->aml_offset +
|
||||
(item_count * 4));
|
||||
|
||||
resource->length +=
|
||||
acpi_rs_get_resource_source(aml_resource_length,
|
||||
(acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target);
|
||||
(acpi_rs_length)
|
||||
(((item_count -
|
||||
1) * sizeof(u32)) +
|
||||
info->value),
|
||||
destination, aml,
|
||||
target);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_BITMASK:
|
||||
@@ -327,6 +472,7 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
|
||||
{
|
||||
void *source = NULL;
|
||||
void *destination;
|
||||
char *target;
|
||||
acpi_rsdesc_size aml_length = 0;
|
||||
u8 count;
|
||||
u16 temp16 = 0;
|
||||
@@ -334,6 +480,10 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
|
||||
|
||||
ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml);
|
||||
|
||||
if (!info) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
/*
|
||||
* First table entry must be ACPI_RSC_INITxxx and must contain the
|
||||
* table length (# of table entries)
|
||||
@@ -383,6 +533,14 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
|
||||
((ACPI_GET8(source) & 0x03) << info->value);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_3BITFLAG:
|
||||
/*
|
||||
* Mask and shift the flag bits
|
||||
*/
|
||||
ACPI_SET8(destination) |= (u8)
|
||||
((ACPI_GET8(source) & 0x07) << info->value);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT:
|
||||
|
||||
item_count = ACPI_GET8(source);
|
||||
@@ -400,6 +558,63 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
|
||||
acpi_rs_set_resource_length(aml_length, aml);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_GPIO_PIN:
|
||||
|
||||
item_count = ACPI_GET16(source);
|
||||
ACPI_SET16(destination) = (u16)aml_length;
|
||||
|
||||
aml_length = (u16)(aml_length + item_count * 2);
|
||||
target = ACPI_ADD_PTR(void, aml, info->value);
|
||||
ACPI_SET16(target) = (u16)aml_length;
|
||||
acpi_rs_set_resource_length(aml_length, aml);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_GPIO_VEN:
|
||||
|
||||
item_count = ACPI_GET16(source);
|
||||
ACPI_SET16(destination) = (u16)item_count;
|
||||
|
||||
aml_length =
|
||||
(u16)(aml_length + (info->value * item_count));
|
||||
acpi_rs_set_resource_length(aml_length, aml);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_GPIO_RES:
|
||||
|
||||
/* Set resource source string length */
|
||||
|
||||
item_count = ACPI_GET16(source);
|
||||
ACPI_SET16(destination) = (u16)aml_length;
|
||||
|
||||
/* Compute offset for the Vendor Data */
|
||||
|
||||
aml_length = (u16)(aml_length + item_count);
|
||||
target = ACPI_ADD_PTR(void, aml, info->value);
|
||||
|
||||
/* Set vendor offset only if there is vendor data */
|
||||
|
||||
if (resource->data.gpio.vendor_length) {
|
||||
ACPI_SET16(target) = (u16)aml_length;
|
||||
}
|
||||
|
||||
acpi_rs_set_resource_length(aml_length, aml);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_SERIAL_VEN:
|
||||
|
||||
item_count = ACPI_GET16(source);
|
||||
ACPI_SET16(destination) = item_count + info->value;
|
||||
aml_length = (u16)(aml_length + item_count);
|
||||
acpi_rs_set_resource_length(aml_length, aml);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_COUNT_SERIAL_RES:
|
||||
|
||||
item_count = ACPI_GET16(source);
|
||||
aml_length = (u16)(aml_length + item_count);
|
||||
acpi_rs_set_resource_length(aml_length, aml);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_LENGTH:
|
||||
|
||||
acpi_rs_set_resource_length(info->value, aml);
|
||||
@@ -417,6 +632,48 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_GPIO_PIN:
|
||||
|
||||
destination = (char *)ACPI_ADD_PTR(void, aml,
|
||||
ACPI_GET16
|
||||
(destination));
|
||||
source = *(u16 **)source;
|
||||
acpi_rs_move_data(destination, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_GPIO_RES:
|
||||
|
||||
/* Used for both resource_source string and vendor_data */
|
||||
|
||||
destination = (char *)ACPI_ADD_PTR(void, aml,
|
||||
ACPI_GET16
|
||||
(destination));
|
||||
source = *(u8 **)source;
|
||||
acpi_rs_move_data(destination, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_SERIAL_VEN:
|
||||
|
||||
destination = (char *)ACPI_ADD_PTR(void, aml,
|
||||
(aml_length -
|
||||
item_count));
|
||||
source = *(u8 **)source;
|
||||
acpi_rs_move_data(destination, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_MOVE_SERIAL_RES:
|
||||
|
||||
destination = (char *)ACPI_ADD_PTR(void, aml,
|
||||
(aml_length -
|
||||
item_count));
|
||||
source = *(u8 **)source;
|
||||
acpi_rs_move_data(destination, source, item_count,
|
||||
info->opcode);
|
||||
break;
|
||||
|
||||
case ACPI_RSC_ADDRESS:
|
||||
|
||||
/* Set the Resource Type, General Flags, and Type-Specific Flags */
|
||||
|
Reference in New Issue
Block a user