Ejemplo n.º 1
0
/* TODO: Change code to take advantage of driver model more */
static void acpi_os_derive_pci_id_2(acpi_handle rhandle,	/* upper bound  */
				    acpi_handle chandle,	/* current node */
				    struct acpi_pci_id **id,
				    int *is_bridge, u8 * bus_number)
{
	acpi_handle handle;
	struct acpi_pci_id *pci_id = *id;
	acpi_status status;
	unsigned long temp;
	acpi_object_type type;
	u8 tu8;

	acpi_get_parent(chandle, &handle);
	if (handle != rhandle) {
		acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge,
					bus_number);

		status = acpi_get_type(handle, &type);
		if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
			return;

		status =
		    acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
					  &temp);
		if (ACPI_SUCCESS(status)) {
			pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp));
			pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp));

			if (*is_bridge)
				pci_id->bus = *bus_number;

			/* any nicer way to get bus number of bridge ? */
			status =
			    acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8,
							   8);
			if (ACPI_SUCCESS(status)
			    && ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
				status =
				    acpi_os_read_pci_configuration(pci_id, 0x18,
								   &tu8, 8);
				if (!ACPI_SUCCESS(status)) {
					/* Certainly broken...  FIX ME */
					return;
				}
				*is_bridge = 1;
				pci_id->bus = tu8;
				status =
				    acpi_os_read_pci_configuration(pci_id, 0x19,
								   &tu8, 8);
				if (ACPI_SUCCESS(status)) {
					*bus_number = tu8;
				}
			} else
				*is_bridge = 0;
		}
	}
}
Ejemplo n.º 2
0
acpi_status
acpi_tb_get_table_header (
	struct acpi_pointer             *address,
	struct acpi_table_header        *return_header)
{
	acpi_status                     status = AE_OK;
	struct acpi_table_header        *header = NULL;


	ACPI_FUNCTION_TRACE ("tb_get_table_header");


	/*
	 * Flags contains the current processor mode (Virtual or Physical addressing)
	 * The pointer_type is either Logical or Physical
	 */
	switch (address->pointer_type) {
	case ACPI_PHYSMODE_PHYSPTR:
	case ACPI_LOGMODE_LOGPTR:

		/* Pointer matches processor mode, copy the header */

		ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (struct acpi_table_header));
		break;


	case ACPI_LOGMODE_PHYSPTR:

		/* Create a logical address for the physical pointer*/

		status = acpi_os_map_memory (address->pointer.physical, sizeof (struct acpi_table_header),
				  (void **) &header);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
				ACPI_HIDWORD (address->pointer.physical),
				ACPI_LODWORD (address->pointer.physical),
				sizeof (struct acpi_table_header)));
			return_ACPI_STATUS (status);
		}

		/* Copy header and delete mapping */

		ACPI_MEMCPY (return_header, header, sizeof (struct acpi_table_header));
		acpi_os_unmap_memory (header, sizeof (struct acpi_table_header));
		break;


	default:

		ACPI_REPORT_ERROR (("Invalid address flags %X\n",
			address->pointer_type));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 3
0
void
AcpiRsDumpIrqList (
    UINT8                   *RouteTable)
{
    UINT8                   *Buffer = RouteTable;
    UINT8                   Count = 0;
    BOOLEAN                 Done = FALSE;
    ACPI_PCI_ROUTING_TABLE  *PrtElement;


    ACPI_FUNCTION_ENTRY ();


    if (AcpiDbgLevel & ACPI_LV_RESOURCES && _COMPONENT & AcpiDbgLayer)
    {
        PrtElement = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, Buffer);

        while (!Done)
        {
            AcpiOsPrintf ("PCI IRQ Routing Table structure %X.\n", Count++);

            AcpiOsPrintf ("    Address: %8.8X%8.8X\n",
                        ACPI_HIDWORD (PrtElement->Address),
                        ACPI_LODWORD (PrtElement->Address));

            AcpiOsPrintf ("    Pin: %X\n", PrtElement->Pin);

            AcpiOsPrintf ("    Source: %s\n", PrtElement->Source);

            AcpiOsPrintf ("    SourceIndex: %X\n",
                        PrtElement->SourceIndex);

            Buffer += PrtElement->Length;

            PrtElement = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, Buffer);

            if(0 == PrtElement->Length)
            {
                Done = TRUE;
            }
        }
    }

    return;
}
Ejemplo n.º 4
0
void
acpi_rs_dump_irq_list (
	u8                              *route_table)
{
	u8                              *buffer = route_table;
	u8                              count = 0;
	u8                              done = FALSE;
	struct acpi_pci_routing_table   *prt_element;


	ACPI_FUNCTION_ENTRY ();


	if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) {
		prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);

		while (!done) {
			acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);

			acpi_os_printf ("  Address: %8.8X%8.8X\n",
					 ACPI_HIDWORD (prt_element->address),
					 ACPI_LODWORD (prt_element->address));

			acpi_os_printf ("  Pin: %X\n", prt_element->pin);

			acpi_os_printf ("  Source: %s\n", prt_element->source);

			acpi_os_printf ("  source_index: %X\n",
					 prt_element->source_index);

			buffer += prt_element->length;

			prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);

			if(0 == prt_element->length) {
				done = TRUE;
			}
		}
	}
Ejemplo n.º 5
0
acpi_status
acpi_ex_write_with_update_rule (
	union acpi_operand_object       *obj_desc,
	acpi_integer                    mask,
	acpi_integer                    field_value,
	u32                             field_datum_byte_offset)
{
	acpi_status                     status = AE_OK;
	acpi_integer                    merged_value;
	acpi_integer                    current_value;


	ACPI_FUNCTION_TRACE_U32 ("ex_write_with_update_rule", mask);


	/* Start with the new bits  */

	merged_value = field_value;

	/* If the mask is all ones, we don't need to worry about the update rule */

	if (mask != ACPI_INTEGER_MAX) {
		/* Decode the update rule */

		switch (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK) {
		case AML_FIELD_UPDATE_PRESERVE:
			/*
			 * Check if update rule needs to be applied (not if mask is all
			 * ones)  The left shift drops the bits we want to ignore.
			 */
			if ((~mask << (ACPI_MUL_8 (sizeof (mask)) -
					 ACPI_MUL_8 (obj_desc->common_field.access_byte_width))) != 0) {
				/*
				 * Read the current contents of the byte/word/dword containing
				 * the field, and merge with the new field value.
				 */
				status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
						  &current_value, ACPI_READ);
				if (ACPI_FAILURE (status)) {
					return_ACPI_STATUS (status);
				}

				merged_value |= (current_value & ~mask);
			}
			break;

		case AML_FIELD_UPDATE_WRITE_AS_ONES:

			/* Set positions outside the field to all ones */

			merged_value |= ~mask;
			break;

		case AML_FIELD_UPDATE_WRITE_AS_ZEROS:

			/* Set positions outside the field to all zeros */

			merged_value &= mask;
			break;

		default:

			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"write_with_update_rule: Unknown update_rule setting: %X\n",
				(obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK)));
			return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
		}
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
		"Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
		ACPI_HIDWORD (mask), ACPI_LODWORD (mask),
		field_datum_byte_offset,
		obj_desc->common_field.access_byte_width,
		ACPI_HIDWORD (field_value), ACPI_LODWORD (field_value),
		ACPI_HIDWORD (merged_value),ACPI_LODWORD (merged_value)));

	/* Write the merged value */

	status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
			  &merged_value, ACPI_WRITE);

	return_ACPI_STATUS (status);
}
Ejemplo n.º 6
0
acpi_status
acpi_ex_field_datum_io (
	union acpi_operand_object       *obj_desc,
	u32                             field_datum_byte_offset,
	acpi_integer                    *value,
	u32                             read_write)
{
	acpi_status                     status;
	acpi_integer                    local_value;


	ACPI_FUNCTION_TRACE_U32 ("ex_field_datum_io", field_datum_byte_offset);


	if (read_write == ACPI_READ) {
		if (!value) {
			local_value = 0;
			value = &local_value; /* To support reads without saving return value */
		}

		/* Clear the entire return buffer first, [Very Important!] */

		*value = 0;
	}

	/*
	 * The four types of fields are:
	 *
	 * buffer_field - Read/write from/to a Buffer
	 * region_field - Read/write from/to a Operation Region.
	 * bank_field  - Write to a Bank Register, then read/write from/to an op_region
	 * index_field - Write to an Index Register, then read/write from/to a Data Register
	 */
	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
	case ACPI_TYPE_BUFFER_FIELD:
		/*
		 * If the buffer_field arguments have not been previously evaluated,
		 * evaluate them now and save the results.
		 */
		if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
			status = acpi_ds_get_buffer_field_arguments (obj_desc);
			if (ACPI_FAILURE (status)) {
				return_ACPI_STATUS (status);
			}
		}

		if (read_write == ACPI_READ) {
			/*
			 * Copy the data from the source buffer.
			 * Length is the field width in bytes.
			 */
			ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer
					  + obj_desc->buffer_field.base_byte_offset
					  + field_datum_byte_offset,
					  obj_desc->common_field.access_byte_width);
		}
		else {
			/*
			 * Copy the data to the target buffer.
			 * Length is the field width in bytes.
			 */
			ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer
					+ obj_desc->buffer_field.base_byte_offset
					+ field_datum_byte_offset,
					value, obj_desc->common_field.access_byte_width);
		}

		status = AE_OK;
		break;


	case ACPI_TYPE_LOCAL_BANK_FIELD:

		/* Ensure that the bank_value is not beyond the capacity of the register */

		if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj,
				  (acpi_integer) obj_desc->bank_field.value)) {
			return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
		}

		/*
		 * For bank_fields, we must write the bank_value to the bank_register
		 * (itself a region_field) before we can access the data.
		 */
		status = acpi_ex_insert_into_field (obj_desc->bank_field.bank_obj,
				 &obj_desc->bank_field.value,
				 sizeof (obj_desc->bank_field.value));
		if (ACPI_FAILURE (status)) {
			return_ACPI_STATUS (status);
		}

		/*
		 * Now that the Bank has been selected, fall through to the
		 * region_field case and write the datum to the Operation Region
		 */

		/*lint -fallthrough */


	case ACPI_TYPE_LOCAL_REGION_FIELD:
		/*
		 * For simple region_fields, we just directly access the owning
		 * Operation Region.
		 */
		status = acpi_ex_access_region (obj_desc, field_datum_byte_offset, value,
				  read_write);
		break;


	case ACPI_TYPE_LOCAL_INDEX_FIELD:


		/* Ensure that the index_value is not beyond the capacity of the register */

		if (acpi_ex_register_overflow (obj_desc->index_field.index_obj,
				  (acpi_integer) obj_desc->index_field.value)) {
			return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
		}

		/* Write the index value to the index_register (itself a region_field) */

		field_datum_byte_offset += obj_desc->index_field.value;

		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
				"Write to Index Register: Value %8.8X\n",
				field_datum_byte_offset));

		status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj,
				 &field_datum_byte_offset,
				 sizeof (field_datum_byte_offset));
		if (ACPI_FAILURE (status)) {
			return_ACPI_STATUS (status);
		}

		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
				"I/O to Data Register: value_ptr %p\n",
				value));

		if (read_write == ACPI_READ) {
			/* Read the datum from the data_register */

			status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj,
					  value, sizeof (acpi_integer));
		}
		else {
			/* Write the datum to the data_register */

			status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj,
					  value, sizeof (acpi_integer));
		}
		break;


	default:

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p, Wrong object type - %s\n",
			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
		status = AE_AML_INTERNAL;
		break;
	}

	if (ACPI_SUCCESS (status)) {
		if (read_write == ACPI_READ) {
			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n",
					   ACPI_HIDWORD (*value), ACPI_LODWORD (*value),
					   obj_desc->common_field.access_byte_width));
		}
		else {
			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n",
					   ACPI_HIDWORD (*value), ACPI_LODWORD (*value),
					   obj_desc->common_field.access_byte_width));
		}
	}

	return_ACPI_STATUS (status);
}
Ejemplo n.º 7
0
acpi_status
acpi_ex_access_region (
	union acpi_operand_object       *obj_desc,
	u32                             field_datum_byte_offset,
	acpi_integer                    *value,
	u32                             function)
{
	acpi_status                     status;
	union acpi_operand_object       *rgn_desc;
	acpi_physical_address           address;


	ACPI_FUNCTION_TRACE ("ex_access_region");


	/*
	 * Ensure that the region operands are fully evaluated and verify
	 * the validity of the request
	 */
	status = acpi_ex_setup_region (obj_desc, field_datum_byte_offset);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/*
	 * The physical address of this field datum is:
	 *
	 * 1) The base of the region, plus
	 * 2) The base offset of the field, plus
	 * 3) The current offset into the field
	 */
	rgn_desc = obj_desc->common_field.region_obj;
	address = rgn_desc->region.address
			 + obj_desc->common_field.base_byte_offset
			 + field_datum_byte_offset;

	if ((function & ACPI_IO_MASK) == ACPI_READ) {
		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
	}
	else {
		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
	}

	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
		" Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n",
		acpi_ut_get_region_name (rgn_desc->region.space_id),
		rgn_desc->region.space_id,
		obj_desc->common_field.access_byte_width,
		obj_desc->common_field.base_byte_offset,
		field_datum_byte_offset,
		ACPI_HIDWORD (address), ACPI_LODWORD (address)));

	/* Invoke the appropriate address_space/op_region handler */

	status = acpi_ev_address_space_dispatch (rgn_desc, function,
			  address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);

	if (ACPI_FAILURE (status)) {
		if (status == AE_NOT_IMPLEMENTED) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Region %s(%X) not implemented\n",
				acpi_ut_get_region_name (rgn_desc->region.space_id),
				rgn_desc->region.space_id));
		}
		else if (status == AE_NOT_EXIST) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Region %s(%X) has no handler\n",
				acpi_ut_get_region_name (rgn_desc->region.space_id),
				rgn_desc->region.space_id));
		}
	}

	return_ACPI_STATUS (status);
}
Ejemplo n.º 8
0
void
AcpiDbDecodeInternalObject (
    ACPI_OPERAND_OBJECT     *ObjDesc)
{
    UINT32                  i;


    if (!ObjDesc)
    {
        AcpiOsPrintf (" Uninitialized");
        return;
    }

    if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
    {
        AcpiOsPrintf (" %p", ObjDesc);
        return;
    }

    AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc));

    switch (ACPI_GET_OBJECT_TYPE (ObjDesc))
    {
    case ACPI_TYPE_INTEGER:

        AcpiOsPrintf (" %8.8X%8.8X", ACPI_HIDWORD (ObjDesc->Integer.Value),
                                     ACPI_LODWORD (ObjDesc->Integer.Value));
        break;


    case ACPI_TYPE_STRING:

        AcpiOsPrintf ("(%d) \"%.24s",
                ObjDesc->String.Length, ObjDesc->String.Pointer);

        if (ObjDesc->String.Length > 24)
        {
            AcpiOsPrintf ("...");
        }
        else
        {
            AcpiOsPrintf ("\"");
        }
        break;


    case ACPI_TYPE_BUFFER:

        AcpiOsPrintf ("(%d)", ObjDesc->Buffer.Length);
        for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++)
        {
            AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]);
        }
        break;


    default:

        AcpiOsPrintf (" %p", ObjDesc);
        break;
    }
}
Ejemplo n.º 9
0
static ACPI_STATUS
AcpiHwGetPciDeviceInfo (
    ACPI_PCI_ID             *PciId,
    ACPI_HANDLE             PciDevice,
    UINT16                  *BusNumber,
    BOOLEAN                 *IsBridge)
{
    ACPI_STATUS             Status;
    ACPI_OBJECT_TYPE        ObjectType;
    UINT64                  ReturnValue;
    UINT64                  PciValue;


    /* We only care about objects of type Device */

    Status = AcpiGetType (PciDevice, &ObjectType);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    if (ObjectType != ACPI_TYPE_DEVICE)
    {
        return (AE_OK);
    }

    /* We need an _ADR. Ignore device if not present */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
        PciDevice, &ReturnValue);
    if (ACPI_FAILURE (Status))
    {
        return (AE_OK);
    }

    /*
     * From _ADR, get the PCI Device and Function and
     * update the PCI ID.
     */
    PciId->Device = ACPI_HIWORD (ACPI_LODWORD (ReturnValue));
    PciId->Function = ACPI_LOWORD (ACPI_LODWORD (ReturnValue));

    /*
     * If the previous device was a bridge, use the previous
     * device bus number
     */
    if (*IsBridge)
    {
        PciId->Bus = *BusNumber;
    }

    /*
     * Get the bus numbers from PCI Config space:
     *
     * First, get the PCI HeaderType
     */
    *IsBridge = FALSE;
    Status = AcpiOsReadPciConfiguration (PciId,
        PCI_CFG_HEADER_TYPE_REG, &PciValue, 8);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* We only care about bridges (1=PciBridge, 2=CardBusBridge) */

    PciValue &= PCI_HEADER_TYPE_MASK;

    if ((PciValue != PCI_TYPE_BRIDGE) &&
        (PciValue != PCI_TYPE_CARDBUS_BRIDGE))
    {
        return (AE_OK);
    }

    /* Bridge: Get the Primary BusNumber */

    Status = AcpiOsReadPciConfiguration (PciId,
        PCI_CFG_PRIMARY_BUS_NUMBER_REG, &PciValue, 8);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    *IsBridge = TRUE;
    PciId->Bus = (UINT16) PciValue;

    /* Bridge: Get the Secondary BusNumber */

    Status = AcpiOsReadPciConfiguration (PciId,
        PCI_CFG_SECONDARY_BUS_NUMBER_REG, &PciValue, 8);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    *BusNumber = (UINT16) PciValue;
    return (AE_OK);
}
Ejemplo n.º 10
0
acpi_status
acpi_ev_create_gpe_block (
	struct acpi_namespace_node      *gpe_device,
	struct acpi_generic_address     *gpe_block_address,
	u32                             register_count,
	u8                              gpe_block_base_number,
	u32                             interrupt_level,
	struct acpi_gpe_block_info      **return_gpe_block)
{
	struct acpi_gpe_block_info      *gpe_block;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ev_create_gpe_block");


	if (!register_count) {
		return_ACPI_STATUS (AE_OK);
	}

	/* Allocate a new GPE block */

	gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info));
	if (!gpe_block) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Initialize the new GPE block */

	gpe_block->register_count = register_count;
	gpe_block->block_base_number = gpe_block_base_number;

	ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));

	/* Create the register_info and event_info sub-structures */

	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) */

	status = acpi_ev_install_gpe_block (gpe_block, interrupt_level);
	if (ACPI_FAILURE (status)) {
		ACPI_MEM_FREE (gpe_block);
		return_ACPI_STATUS (status);
	}

	/* Dump info about this GPE block */

	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
		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,
		ACPI_HIDWORD (gpe_block->block_address.address),
		ACPI_LODWORD (gpe_block->block_address.address),
		interrupt_level));

	/* Find all GPE methods (_Lxx, _Exx) for this block */

	status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
			  ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info,
			  gpe_block, NULL);

	/* Return the new block */

	if (return_gpe_block) {
		(*return_gpe_block) = gpe_block;
	}

	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 11
0
ACPI_STATUS
AcpiGetFirmwareTable (
    ACPI_STRING             Signature,
    UINT32                  Instance,
    UINT32                  Flags,
    ACPI_TABLE_HEADER       **TablePointer)
{
    ACPI_POINTER            RsdpAddress;
    ACPI_POINTER            Address;
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       Header;
    ACPI_TABLE_DESC         TableInfo;
    ACPI_TABLE_DESC         RsdtInfo;
    UINT32                  TableCount;
    UINT32                  i;
    UINT32                  j;


    ACPI_FUNCTION_TRACE ("AcpiGetFirmwareTable");


    /*
     * Ensure that at least the table manager is initialized.  We don't
     * require that the entire ACPI subsystem is up for this interface
     */

    /*
     *  If we have a buffer, we must have a length too
     */
    if ((Instance == 0)                 ||
        (!Signature)                    ||
        (!TablePointer))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    RsdtInfo.Pointer = NULL;

    if (!AcpiGbl_RSDP)
    {
        /* Get the RSDP */

        Status = AcpiOsGetRootPointer (Flags, &RsdpAddress);
        if (ACPI_FAILURE (Status))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP  not found\n"));
            return_ACPI_STATUS (AE_NO_ACPI_TABLES);
        }

        /* Map and validate the RSDP */

        if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)
        {
            Status = AcpiOsMapMemory (RsdpAddress.Pointer.Physical, sizeof (RSDP_DESCRIPTOR),
                                        (void **) &AcpiGbl_RSDP);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }
        }
        else
        {
            AcpiGbl_RSDP = RsdpAddress.Pointer.Logical;
        }

        /*
         *  The signature and checksum must both be correct
         */
        if (ACPI_STRNCMP ((char *) AcpiGbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0)
        {
            /* Nope, BAD Signature */

            return_ACPI_STATUS (AE_BAD_SIGNATURE);
        }

        if (AcpiTbChecksum (AcpiGbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
        {
            /* Nope, BAD Checksum */

            return_ACPI_STATUS (AE_BAD_CHECKSUM);
        }
    }

    /* Get the RSDT and validate it */

    AcpiTbGetRsdtAddress (&Address);

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
        "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
        AcpiGbl_RSDP,
        ACPI_HIDWORD (Address.Pointer.Value),
        ACPI_LODWORD (Address.Pointer.Value)));

    /* Insert ProcessorMode flags */

    Address.PointerType |= Flags;

    Status = AcpiTbGetTable (&Address, &RsdtInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiTbValidateRsdt (RsdtInfo.Pointer);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Get the number of table pointers within the RSDT */

    TableCount = AcpiTbGetTableCount (AcpiGbl_RSDP, RsdtInfo.Pointer);

    Address.PointerType = AcpiGbl_TableFlags | Flags;

    /*
     * Search the RSDT/XSDT for the correct instance of the
     * requested table
     */
    for (i = 0, j = 0; i < TableCount; i++)
    {
        /* Get the next table pointer, handle RSDT vs. XSDT */

        if (AcpiGbl_RSDP->Revision < 2)
        {
            Address.Pointer.Value = ((RSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i];
        }
        else
        {
            Address.Pointer.Value = ACPI_GET_ADDRESS (
                ((XSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i]);
        }

        /* Get the table header */

        Status = AcpiTbGetTableHeader (&Address, &Header);
        if (ACPI_FAILURE (Status))
        {
            goto Cleanup;
        }

        /* Compare table signatures and table instance */

        if (!ACPI_STRNCMP (Header.Signature, Signature, ACPI_NAME_SIZE))
        {
            /* An instance of the table was found */

            j++;
            if (j >= Instance)
            {
                /* Found the correct instance, get the entire table */

                Status = AcpiTbGetTableBody (&Address, &Header, &TableInfo);
                if (ACPI_FAILURE (Status))
                {
                    goto Cleanup;
                }

                *TablePointer = TableInfo.Pointer;
                goto Cleanup;
            }
        }
    }

    /* Did not find the table */

    Status = AE_NOT_EXIST;


Cleanup:
    AcpiOsUnmapMemory (RsdtInfo.Pointer, (ACPI_SIZE) RsdtInfo.Pointer->Length);
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 12
0
ACPI_STATUS
AcpiEvAddressSpaceDispatch (
    ACPI_OPERAND_OBJECT     *RegionObj,
    UINT32                  Function,
    ACPI_PHYSICAL_ADDRESS   Address,
    UINT32                  BitWidth,
    void                    *Value)
{
    ACPI_STATUS             Status;
    ACPI_STATUS             Status2;
    ACPI_ADR_SPACE_HANDLER  Handler;
    ACPI_ADR_SPACE_SETUP    RegionSetup;
    ACPI_OPERAND_OBJECT     *HandlerDesc;
    ACPI_OPERAND_OBJECT     *RegionObj2;
    void                    *RegionContext = NULL;


    ACPI_FUNCTION_TRACE ("EvAddressSpaceDispatch");


    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
    if (!RegionObj2)
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /*
     * Ensure that there is a handler associated with this region
     */
    HandlerDesc = RegionObj->Region.AddrHandler;
    if (!HandlerDesc)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n",
            RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));

        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /*
     * It may be the case that the region has never been initialized
     * Some types of regions require special init code
     */
    if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
    {
        /*
         * This region has not been initialized yet, do it
         */
        RegionSetup = HandlerDesc->AddrHandler.Setup;
        if (!RegionSetup)
        {
            /*
             *  Bad news, no init routine and not init'd
             */
            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
                RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
            return_ACPI_STATUS (AE_UNKNOWN_STATUS);
        }

        /*
         * We must exit the interpreter because the region setup will potentially
         * execute control methods
         */
        AcpiExExitInterpreter ();

        Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
                        HandlerDesc->AddrHandler.Context, &RegionContext);

        /* Re-enter the interpreter */

        Status2 = AcpiExEnterInterpreter ();
        if (ACPI_FAILURE (Status2))
        {
            return_ACPI_STATUS (Status2);
        }

        /*
         *  Init routine may fail
         */
        if (ACPI_FAILURE (Status))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
                AcpiFormatException (Status),
                AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
            return_ACPI_STATUS (Status);
        }

        RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;

        /*
         *  Save the returned context for use in all accesses to
         *  this particular region.
         */
        RegionObj2->Extra.RegionContext = RegionContext;
    }

    /*
     *  We have everything we need, begin the process
     */
    Handler = HandlerDesc->AddrHandler.Handler;

    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "Addrhandler %p (%p), Address %8.8X%8.8X\n",
        &RegionObj->Region.AddrHandler->AddrHandler, Handler,
        ACPI_HIDWORD (Address), ACPI_LODWORD (Address)));

    if (!(HandlerDesc->AddrHandler.Flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
    {
        /*
         *  For handlers other than the default (supplied) handlers, we must
         *  exit the interpreter because the handler *might* block -- we don't
         *  know what it will do, so we can't hold the lock on the intepreter.
         */
        AcpiExExitInterpreter();
    }

    /*
     *  Invoke the handler.
     */
    Status = Handler (Function, Address, BitWidth, Value,
                      HandlerDesc->AddrHandler.Context,
                      RegionObj2->Extra.RegionContext);

    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Handler for [%s] returned %s\n",
            AcpiUtGetRegionName (RegionObj->Region.SpaceId),
            AcpiFormatException (Status)));
    }

    if (!(HandlerDesc->AddrHandler.Flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
    {
        /*
         * We just returned from a non-default handler, we must re-enter the
         * interpreter
         */
        Status2 = AcpiExEnterInterpreter ();
        if (ACPI_FAILURE (Status2))
        {
            return_ACPI_STATUS (Status2);
        }
    }

    return_ACPI_STATUS (Status);
}
Ejemplo n.º 13
0
acpi_status
acpi_ev_address_space_dispatch (
	union acpi_operand_object       *region_obj,
	u32                             function,
	acpi_physical_address           address,
	u32                             bit_width,
	void                            *value)
{
	acpi_status                     status;
	acpi_status                     status2;
	acpi_adr_space_handler          handler;
	acpi_adr_space_setup            region_setup;
	union acpi_operand_object       *handler_desc;
	union acpi_operand_object       *region_obj2;
	void                            *region_context = NULL;


	ACPI_FUNCTION_TRACE ("ev_address_space_dispatch");


	region_obj2 = acpi_ns_get_secondary_object (region_obj);
	if (!region_obj2) {
		return_ACPI_STATUS (AE_NOT_EXIST);
	}

	/* Ensure that there is a handler associated with this region */

	handler_desc = region_obj->region.address_space;
	if (!handler_desc) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n",
			region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));

		return_ACPI_STATUS (AE_NOT_EXIST);
	}

	/*
	 * It may be the case that the region has never been initialized
	 * Some types of regions require special init code
	 */
	if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
		/*
		 * This region has not been initialized yet, do it
		 */
		region_setup = handler_desc->address_space.setup;
		if (!region_setup) {
			/* No initialization routine, exit with error */

			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
				region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
			return_ACPI_STATUS (AE_NOT_EXIST);
		}

		/*
		 * We must exit the interpreter because the region setup will potentially
		 * execute control methods (e.g., _REG method for this region)
		 */
		acpi_ex_exit_interpreter ();

		status = region_setup (region_obj, ACPI_REGION_ACTIVATE,
				  handler_desc->address_space.context, &region_context);

		/* Re-enter the interpreter */

		status2 = acpi_ex_enter_interpreter ();
		if (ACPI_FAILURE (status2)) {
			return_ACPI_STATUS (status2);
		}

		/* Check for failure of the Region Setup */

		if (ACPI_FAILURE (status)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
				acpi_format_exception (status),
				acpi_ut_get_region_name (region_obj->region.space_id)));
			return_ACPI_STATUS (status);
		}

		/*
		 * Region initialization may have been completed by region_setup
		 */
		if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
			region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;

			if (region_obj2->extra.region_context) {
				/* The handler for this region was already installed */

				ACPI_MEM_FREE (region_context);
			}
			else {
				/*
				 * Save the returned context for use in all accesses to
				 * this particular region
				 */
				region_obj2->extra.region_context = region_context;
			}
		}
	}

	/* We have everything we need, we can invoke the address space handler */

	handler = handler_desc->address_space.handler;

	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
		"Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
		&region_obj->region.address_space->address_space, handler,
		ACPI_HIDWORD (address), ACPI_LODWORD (address),
		acpi_ut_get_region_name (region_obj->region.space_id)));

	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
		/*
		 * For handlers other than the default (supplied) handlers, we must
		 * exit the interpreter because the handler *might* block -- we don't
		 * know what it will do, so we can't hold the lock on the intepreter.
		 */
		acpi_ex_exit_interpreter();
	}

	/* Call the handler */

	status = handler (function, address, bit_width, value,
			 handler_desc->address_space.context,
			 region_obj2->extra.region_context);

	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Handler for [%s] returned %s\n",
			acpi_ut_get_region_name (region_obj->region.space_id),
			acpi_format_exception (status)));
	}

	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
		/*
		 * We just returned from a non-default handler, we must re-enter the
		 * interpreter
		 */
		status2 = acpi_ex_enter_interpreter ();
		if (ACPI_FAILURE (status2)) {
			return_ACPI_STATUS (status2);
		}
	}

	return_ACPI_STATUS (status);
}
Ejemplo n.º 14
0
u32
acpi_ev_gpe_detect (
	struct acpi_gpe_xrupt_info      *gpe_xrupt_list)
{
	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
	u8                              enabled_status_byte;
	u8                              bit_mask;
	struct acpi_gpe_register_info   *gpe_register_info;
	u32                             in_value;
	acpi_status                     status;
	struct acpi_gpe_block_info      *gpe_block;
	u32                             gpe_number;
	u32                             i;
	u32                             j;


	ACPI_FUNCTION_NAME ("ev_gpe_detect");


	/* Examine all GPE blocks attached to this interrupt level */

	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR);
	gpe_block = gpe_xrupt_list->gpe_block_list_head;
	while (gpe_block) {
		/*
		 * Read all of the 8-bit GPE status and enable registers
		 * in this GPE block, saving all of them.
		 * Find all currently active GP events.
		 */
		for (i = 0; i < gpe_block->register_count; i++) {
			/* Get the next status/enable pair */

			gpe_register_info = &gpe_block->register_info[i];

			/* Read the Status Register */

			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
					 &gpe_register_info->status_address);
			gpe_register_info->status = (u8) in_value;
			if (ACPI_FAILURE (status)) {
				goto unlock_and_exit;
			}

			/* Read the Enable Register */

			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
					 &gpe_register_info->enable_address);
			gpe_register_info->enable = (u8) in_value;
			if (ACPI_FAILURE (status)) {
				goto unlock_and_exit;
			}

			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
				"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
				ACPI_HIDWORD (gpe_register_info->status_address.address),
				ACPI_LODWORD (gpe_register_info->status_address.address),
				gpe_register_info->status,
				ACPI_HIDWORD (gpe_register_info->enable_address.address),
				ACPI_LODWORD (gpe_register_info->enable_address.address),
				gpe_register_info->enable));

			/* First check if there is anything active at all in this register */

			enabled_status_byte = (u8) (gpe_register_info->status &
					   gpe_register_info->enable);
			if (!enabled_status_byte) {
				/* No active GPEs in this register, move on */

				continue;
			}

			/* Now look at the individual GPEs in this byte register */

			for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
				/* Examine one GPE bit */

				if (enabled_status_byte & bit_mask) {
					/*
					 * Found an active GPE. Dispatch the event to a handler
					 * or method.
					 */
					gpe_number = (i * ACPI_GPE_REGISTER_WIDTH) + j;

					int_status |= acpi_ev_gpe_dispatch (
							  &gpe_block->event_info[gpe_number],
							  gpe_number + gpe_block->register_info[gpe_number].base_gpe_number);
				}
			}
		}

		gpe_block = gpe_block->next;
	}

unlock_and_exit:

	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR);
	return (int_status);
}
Ejemplo n.º 15
0
ACPI_STATUS
AcpiDsEvalRegionOperands (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_STATUS             Status;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_OPERAND_OBJECT     *OperandDesc;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_PARSE_OBJECT       *NextOp;


    ACPI_FUNCTION_TRACE_PTR ("DsEvalRegionOperands", Op);


    /*
     * This is where we evaluate the address and length fields of the OpRegion declaration
     */
    Node =  Op->Common.Node;

    /* NextOp points to the op that holds the SpaceID */

    NextOp = Op->Common.Value.Arg;

    /* NextOp points to address op */

    NextOp = NextOp->Common.Next;

    /* Evaluate/create the address and length operands */

    Status = AcpiDsCreateOperands (WalkState, NextOp);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Resolve the length and address operands to numbers */

    Status = AcpiExResolveOperands (Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
                    AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
                    1, "after AcpiExResolveOperands");

    ObjDesc = AcpiNsGetAttachedObject (Node);
    if (!ObjDesc)
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /*
     * Get the length operand and save it
     * (at Top of stack)
     */
    OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];

    ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
    AcpiUtRemoveReference (OperandDesc);

    /*
     * Get the address and save it
     * (at top of stack - 1)
     */
    OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];

    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) OperandDesc->Integer.Value;
    AcpiUtRemoveReference (OperandDesc);

    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
        ObjDesc,
        ACPI_HIDWORD (ObjDesc->Region.Address), ACPI_LODWORD (ObjDesc->Region.Address),
        ObjDesc->Region.Length));

    /* Now the address and length are valid for this opregion */

    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;

    return_ACPI_STATUS (Status);
}
Ejemplo n.º 16
0
void
acpi_rs_dump_address64 (
	union acpi_resource_data        *data)
{
	struct acpi_resource_address64 *address64_data = (struct acpi_resource_address64 *) data;


	ACPI_FUNCTION_ENTRY ();


	acpi_os_printf ("64-Bit Address Space Resource\n");

	switch (address64_data->resource_type) {
	case ACPI_MEMORY_RANGE:

		acpi_os_printf ("  Resource Type: Memory Range\n");

		switch (address64_data->attribute.memory.cache_attribute) {
		case ACPI_NON_CACHEABLE_MEMORY:
			acpi_os_printf ("  Type Specific: "
					  "Noncacheable memory\n");
			break;

		case ACPI_CACHABLE_MEMORY:
			acpi_os_printf ("  Type Specific: "
					  "Cacheable memory\n");
			break;

		case ACPI_WRITE_COMBINING_MEMORY:
			acpi_os_printf ("  Type Specific: "
					  "Write-combining memory\n");
			break;

		case ACPI_PREFETCHABLE_MEMORY:
			acpi_os_printf ("  Type Specific: "
					  "Prefetchable memory\n");
			break;

		default:
			acpi_os_printf ("  Type Specific: "
					  "Invalid cache attribute\n");
			break;
		}

		acpi_os_printf ("  Type Specific: Read%s\n",
			ACPI_READ_WRITE_MEMORY ==
			address64_data->attribute.memory.read_write_attribute ?
			"/Write" : " Only");
		break;

	case ACPI_IO_RANGE:

		acpi_os_printf ("  Resource Type: Io Range\n");

		switch (address64_data->attribute.io.range_attribute) {
		case ACPI_NON_ISA_ONLY_RANGES:
			acpi_os_printf ("  Type Specific: "
					  "Non-ISA Io Addresses\n");
			break;

		case ACPI_ISA_ONLY_RANGES:
			acpi_os_printf ("  Type Specific: "
					  "ISA Io Addresses\n");
			break;

		case ACPI_ENTIRE_RANGE:
			acpi_os_printf ("  Type Specific: "
					  "ISA and non-ISA Io Addresses\n");
			break;

		default:
			acpi_os_printf ("  Type Specific: "
					  "Invalid Range attribute");
			break;
		}

		acpi_os_printf (" Type Specific: %s Translation\n",
			ACPI_SPARSE_TRANSLATION ==
			address64_data->attribute.io.translation_attribute ?
			"Sparse" : "Dense");
		break;

	case ACPI_BUS_NUMBER_RANGE:

		acpi_os_printf ("  Resource Type: Bus Number Range\n");
		break;

	default:

		acpi_os_printf ("  Invalid Resource Type..exiting.\n");
		return;
	}

	acpi_os_printf ("  Resource %s\n",
			 ACPI_CONSUMER == address64_data->producer_consumer ?
			 "Consumer" : "Producer");

	acpi_os_printf ("  %s decode\n",
			 ACPI_SUB_DECODE == address64_data->decode ?
			 "Subtractive" : "Positive");

	acpi_os_printf ("  Min address is %s fixed\n",
			 ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
			 "" : "not ");

	acpi_os_printf ("  Max address is %s fixed\n",
			 ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
			 "" : "not ");

	acpi_os_printf ("  Granularity: %8.8X%8.8X\n",
			 ACPI_HIDWORD (address64_data->granularity),
			 ACPI_LODWORD (address64_data->granularity));

	acpi_os_printf ("  Address range min: %8.8X%8.8X\n",
			 ACPI_HIDWORD (address64_data->min_address_range),
			 ACPI_HIDWORD (address64_data->min_address_range));

	acpi_os_printf ("  Address range max: %8.8X%8.8X\n",
			 ACPI_HIDWORD (address64_data->max_address_range),
			 ACPI_HIDWORD (address64_data->max_address_range));

	acpi_os_printf ("  Address translation offset: %8.8X%8.8X\n",
			 ACPI_HIDWORD (address64_data->address_translation_offset),
			 ACPI_HIDWORD (address64_data->address_translation_offset));

	acpi_os_printf ("  Address Length: %8.8X%8.8X\n",
			 ACPI_HIDWORD (address64_data->address_length),
			 ACPI_HIDWORD (address64_data->address_length));

	if(0xFF != address64_data->resource_source.index) {
		acpi_os_printf ("  Resource Source Index: %X\n",
				 address64_data->resource_source.index);
		acpi_os_printf ("  Resource Source: %s\n",
				 address64_data->resource_source.string_ptr);
	}

	return;
}
Ejemplo n.º 17
0
ACPI_STATUS
AcpiNsDumpOneObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    ACPI_NAMESPACE_NODE     *ThisNode;
    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
    ACPI_OBJECT_TYPE        ObjType;
    ACPI_OBJECT_TYPE        Type;
    UINT32                  BytesToDump;
    UINT32                  DbgLevel;
    UINT32                  i;


    ACPI_FUNCTION_NAME ("NsDumpOneObject");


    /* Is output enabled? */

    if (!(AcpiDbgLevel & Info->DebugLevel))
    {
        return (AE_OK);
    }

    if (!ObjHandle)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
        return (AE_OK);
    }

    ThisNode = AcpiNsMapHandleToNode (ObjHandle);
    Type = ThisNode->Type;

    /* Check if the owner matches */

    if ((Info->OwnerId != ACPI_UINT32_MAX) &&
        (Info->OwnerId != ThisNode->OwnerId))
    {
        return (AE_OK);
    }

    /* Indent the object according to the level */

    AcpiOsPrintf ("%2d%*s", (UINT32) Level - 1, (int) Level * 2, " ");

    /* Check the node type and name */

    if (Type > ACPI_TYPE_LOCAL_MAX)
    {
        ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", Type));
    }

    if (!AcpiUtValidAcpiName (ThisNode->Name.Integer))
    {
        ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n", ThisNode->Name.Integer));
    }

    /*
     * Now we can print out the pertinent information
     */
    AcpiOsPrintf ("%4.4s %-12s %p ",
            ThisNode->Name.Ascii, AcpiUtGetTypeName (Type), ThisNode);

    DbgLevel = AcpiDbgLevel;
    AcpiDbgLevel = 0;
    ObjDesc = AcpiNsGetAttachedObject (ThisNode);
    AcpiDbgLevel = DbgLevel;

    switch (Info->DisplayType)
    {
    case ACPI_DISPLAY_SUMMARY:

        if (!ObjDesc)
        {
            /* No attached object, we are done */

            AcpiOsPrintf ("\n");
            return (AE_OK);
        }

        switch (Type)
        {
        case ACPI_TYPE_PROCESSOR:

            AcpiOsPrintf ("ID %X Len %.4X Addr %p\n",
                        ObjDesc->Processor.ProcId,
                        ObjDesc->Processor.Length,
                        (char *) ObjDesc->Processor.Address);
            break;


        case ACPI_TYPE_DEVICE:

            AcpiOsPrintf ("Notify object: %p", ObjDesc);
            break;


        case ACPI_TYPE_METHOD:

            AcpiOsPrintf ("Args %X Len %.4X Aml %p\n",
                        (UINT32) ObjDesc->Method.ParamCount,
                        ObjDesc->Method.AmlLength,
                        ObjDesc->Method.AmlStart);
            break;


        case ACPI_TYPE_INTEGER:

            AcpiOsPrintf ("= %8.8X%8.8X\n",
                        ACPI_HIDWORD (ObjDesc->Integer.Value),
                        ACPI_LODWORD (ObjDesc->Integer.Value));
            break;


        case ACPI_TYPE_PACKAGE:

            if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf ("Elements %.2X\n",
                            ObjDesc->Package.Count);
            }
            else
            {
                AcpiOsPrintf ("[Length not yet evaluated]\n");
            }
            break;


        case ACPI_TYPE_BUFFER:

            if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf ("Len %.2X",
                            ObjDesc->Buffer.Length);

                /* Dump some of the buffer */

                if (ObjDesc->Buffer.Length > 0)
                {
                    AcpiOsPrintf (" =");
                    for (i = 0; (i < ObjDesc->Buffer.Length && i < 12); i++)
                    {
                        AcpiOsPrintf (" %.2hX", ObjDesc->Buffer.Pointer[i]);
                    }
                }
                AcpiOsPrintf ("\n");
            }
            else
            {
                AcpiOsPrintf ("[Length not yet evaluated]\n");
            }
            break;


        case ACPI_TYPE_STRING:

            AcpiOsPrintf ("Len %.2X ", ObjDesc->String.Length);
            AcpiUtPrintString (ObjDesc->String.Pointer, 32);
            AcpiOsPrintf ("\n");
            break;


        case ACPI_TYPE_REGION:

            AcpiOsPrintf ("[%s]", AcpiUtGetRegionName (ObjDesc->Region.SpaceId));
            if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf (" Addr %8.8X%8.8X Len %.4X\n",
                            ACPI_HIDWORD (ObjDesc->Region.Address),
                            ACPI_LODWORD (ObjDesc->Region.Address),
                            ObjDesc->Region.Length);
            }
            else
            {
                AcpiOsPrintf (" [Address/Length not yet evaluated]\n");
            }
            break;


        case ACPI_TYPE_LOCAL_REFERENCE:

            AcpiOsPrintf ("[%s]\n",
                    AcpiPsGetOpcodeName (ObjDesc->Reference.Opcode));
            break;


        case ACPI_TYPE_BUFFER_FIELD:

            if (ObjDesc->BufferField.BufferObj &&
                ObjDesc->BufferField.BufferObj->Buffer.Node)
            {
                AcpiOsPrintf ("Buf [%4.4s]",
                        ObjDesc->BufferField.BufferObj->Buffer.Node->Name.Ascii);
            }
            break;


        case ACPI_TYPE_LOCAL_REGION_FIELD:

            AcpiOsPrintf ("Rgn [%4.4s]",
                    ObjDesc->CommonField.RegionObj->Region.Node->Name.Ascii);
            break;


        case ACPI_TYPE_LOCAL_BANK_FIELD:

            AcpiOsPrintf ("Rgn [%4.4s] Bnk [%4.4s]",
                    ObjDesc->CommonField.RegionObj->Region.Node->Name.Ascii,
                    ObjDesc->BankField.BankObj->CommonField.Node->Name.Ascii);
            break;


        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            AcpiOsPrintf ("Idx [%4.4s] Dat [%4.4s]",
                    ObjDesc->IndexField.IndexObj->CommonField.Node->Name.Ascii,
                    ObjDesc->IndexField.DataObj->CommonField.Node->Name.Ascii);
            break;


        case ACPI_TYPE_LOCAL_ALIAS:

            AcpiOsPrintf ("Target %4.4s (%p)\n", ((ACPI_NAMESPACE_NODE *) ObjDesc)->Name.Ascii, ObjDesc);
            break;

        default:

            AcpiOsPrintf ("Object %p\n", ObjDesc);
            break;
        }

        /* Common field handling */

        switch (Type)
        {
        case ACPI_TYPE_BUFFER_FIELD:
        case ACPI_TYPE_LOCAL_REGION_FIELD:
        case ACPI_TYPE_LOCAL_BANK_FIELD:
        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            AcpiOsPrintf (" Off %.2X Len %.2X Acc %.2hd\n",
                    (ObjDesc->CommonField.BaseByteOffset * 8)
                        + ObjDesc->CommonField.StartFieldBitOffset,
                    ObjDesc->CommonField.BitLength,
                    ObjDesc->CommonField.AccessByteWidth);
            break;

        default:
            break;
        }
        break;


    case ACPI_DISPLAY_OBJECTS:

        AcpiOsPrintf ("O:%p", ObjDesc);
        if (!ObjDesc)
        {
            /* No attached object, we are done */

            AcpiOsPrintf ("\n");
            return (AE_OK);
        }

        AcpiOsPrintf ("(R%d)",
                ObjDesc->Common.ReferenceCount);

        switch (Type)
        {
        case ACPI_TYPE_METHOD:

            /* Name is a Method and its AML offset/length are set */

            AcpiOsPrintf (" M:%p-%X\n", ObjDesc->Method.AmlStart,
                                        ObjDesc->Method.AmlLength);
            break;

        case ACPI_TYPE_INTEGER:

            AcpiOsPrintf (" N:%X%X\n", ACPI_HIDWORD(ObjDesc->Integer.Value),
                                       ACPI_LODWORD(ObjDesc->Integer.Value));
            break;

        case ACPI_TYPE_STRING:

            AcpiOsPrintf (" S:%p-%X\n", ObjDesc->String.Pointer,
                                        ObjDesc->String.Length);
            break;

        case ACPI_TYPE_BUFFER:

            AcpiOsPrintf (" B:%p-%X\n", ObjDesc->Buffer.Pointer,
                                        ObjDesc->Buffer.Length);
            break;

        default:

            AcpiOsPrintf ("\n");
            break;
        }
        break;


    default:
        AcpiOsPrintf ("\n");
        break;
    }

    /* If debug turned off, done */

    if (!(AcpiDbgLevel & ACPI_LV_VALUES))
    {
        return (AE_OK);
    }


    /* If there is an attached object, display it */

    DbgLevel     = AcpiDbgLevel;
    AcpiDbgLevel = 0;
    ObjDesc      = AcpiNsGetAttachedObject (ThisNode);
    AcpiDbgLevel = DbgLevel;

    /* Dump attached objects */

    while (ObjDesc)
    {
        ObjType = ACPI_TYPE_INVALID;
        AcpiOsPrintf ("        Attached Object %p: ", ObjDesc);

        /* Decode the type of attached object and dump the contents */

        switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
        {
        case ACPI_DESC_TYPE_NAMED:

            AcpiOsPrintf ("(Ptr to Node)\n");
            BytesToDump = sizeof (ACPI_NAMESPACE_NODE);
            break;


        case ACPI_DESC_TYPE_OPERAND:

            ObjType = ACPI_GET_OBJECT_TYPE (ObjDesc);

            if (ObjType > ACPI_TYPE_LOCAL_MAX)
            {
                AcpiOsPrintf ("(Ptr to ACPI Object type %X [UNKNOWN])\n", ObjType);
                BytesToDump = 32;
            }
            else
            {
                AcpiOsPrintf ("(Ptr to ACPI Object type %s, %X)\n",
                                    AcpiUtGetTypeName (ObjType), ObjType);
                BytesToDump = sizeof (ACPI_OPERAND_OBJECT);
            }
            break;


        default:

            AcpiOsPrintf ("(String or Buffer ptr - not an object descriptor)\n");
            BytesToDump = 16;
            break;
        }

        ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);

        /* If value is NOT an internal object, we are done */

        if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
        {
            goto Cleanup;
        }

        /*
         * Valid object, get the pointer to next level, if any
         */
        switch (ObjType)
        {
        case ACPI_TYPE_STRING:
            ObjDesc = (void *) ObjDesc->String.Pointer;
            break;

        case ACPI_TYPE_BUFFER:
            ObjDesc = (void *) ObjDesc->Buffer.Pointer;
            break;

        case ACPI_TYPE_BUFFER_FIELD:
            ObjDesc = (ACPI_OPERAND_OBJECT *) ObjDesc->BufferField.BufferObj;
            break;

        case ACPI_TYPE_PACKAGE:
            ObjDesc = (void *) ObjDesc->Package.Elements;
            break;

        case ACPI_TYPE_METHOD:
            ObjDesc = (void *) ObjDesc->Method.AmlStart;
            break;

        case ACPI_TYPE_LOCAL_REGION_FIELD:
            ObjDesc = (void *) ObjDesc->Field.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_BANK_FIELD:
            ObjDesc = (void *) ObjDesc->BankField.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_INDEX_FIELD:
            ObjDesc = (void *) ObjDesc->IndexField.IndexObj;
            break;

        default:
            goto Cleanup;
        }

        ObjType = ACPI_TYPE_INVALID;   /* Terminate loop after next pass */
    }

Cleanup:
    AcpiOsPrintf ("\n");
    return (AE_OK);
}
Ejemplo n.º 18
0
static acpi_status
acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id,
			    acpi_handle pci_device,
			    u16 *bus_number, u8 *is_bridge)
{
	acpi_status status;
	acpi_object_type object_type;
	u64 return_value;
	u64 pci_value;

	/* We only care about objects of type Device */

	status = acpi_get_type(pci_device, &object_type);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	if (object_type != ACPI_TYPE_DEVICE) {
		return (AE_OK);
	}

	/* We need an _ADR. Ignore device if not present */

	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
						 pci_device, &return_value);
	if (ACPI_FAILURE(status)) {
		return (AE_OK);
	}

	/*
	 * From _ADR, get the PCI Device and Function and
	 * update the PCI ID.
	 */
	pci_id->device = ACPI_HIWORD(ACPI_LODWORD(return_value));
	pci_id->function = ACPI_LOWORD(ACPI_LODWORD(return_value));

	/*
	 * If the previous device was a bridge, use the previous
	 * device bus number
	 */
	if (*is_bridge) {
		pci_id->bus = *bus_number;
	}

	/*
	 * Get the bus numbers from PCI Config space:
	 *
	 * First, get the PCI header_type
	 */
	*is_bridge = FALSE;
	status = acpi_os_read_pci_configuration(pci_id,
						PCI_CFG_HEADER_TYPE_REG,
						&pci_value, 8);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	/* We only care about bridges (1=pci_bridge, 2=card_bus_bridge) */

	pci_value &= PCI_HEADER_TYPE_MASK;

	if ((pci_value != PCI_TYPE_BRIDGE) &&
	    (pci_value != PCI_TYPE_CARDBUS_BRIDGE)) {
		return (AE_OK);
	}

	/* Bridge: Get the Primary bus_number */

	status = acpi_os_read_pci_configuration(pci_id,
						PCI_CFG_PRIMARY_BUS_NUMBER_REG,
						&pci_value, 8);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	*is_bridge = TRUE;
	pci_id->bus = (u16)pci_value;

	/* Bridge: Get the Secondary bus_number */

	status = acpi_os_read_pci_configuration(pci_id,
						PCI_CFG_SECONDARY_BUS_NUMBER_REG,
						&pci_value, 8);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	*bus_number = (u16)pci_value;
	return (AE_OK);
}
Ejemplo n.º 19
0
void
AcpiRsDumpAddress64 (
    ACPI_RESOURCE_DATA      *Data)
{
    ACPI_RESOURCE_ADDRESS64 *Address64Data = (ACPI_RESOURCE_ADDRESS64 *) Data;


    ACPI_FUNCTION_ENTRY ();


    AcpiOsPrintf ("64-Bit Address Space Resource\n");

    switch (Address64Data->ResourceType)
    {
    case ACPI_MEMORY_RANGE:

        AcpiOsPrintf ("    Resource Type: Memory Range\n");

        switch (Address64Data->Attribute.Memory.CacheAttribute)
        {
        case ACPI_NON_CACHEABLE_MEMORY:
            AcpiOsPrintf ("    Type Specific: "
                            "Noncacheable memory\n");
            break;

        case ACPI_CACHABLE_MEMORY:
            AcpiOsPrintf ("    Type Specific: "
                            "Cacheable memory\n");
            break;

        case ACPI_WRITE_COMBINING_MEMORY:
            AcpiOsPrintf ("    Type Specific: "
                            "Write-combining memory\n");
            break;

        case ACPI_PREFETCHABLE_MEMORY:
            AcpiOsPrintf ("    Type Specific: "
                            "Prefetchable memory\n");
            break;

        default:
            AcpiOsPrintf ("    Type Specific: "
                            "Invalid cache attribute\n");
            break;
        }

        AcpiOsPrintf ("    Type Specific: Read%s\n",
            ACPI_READ_WRITE_MEMORY ==
            Address64Data->Attribute.Memory.ReadWriteAttribute ?
            "/Write" : " Only");
        break;

    case ACPI_IO_RANGE:

        AcpiOsPrintf ("    Resource Type: Io Range\n");

        switch (Address64Data->Attribute.Io.RangeAttribute)
        {
        case ACPI_NON_ISA_ONLY_RANGES:
            AcpiOsPrintf ("    Type Specific: "
                            "Non-ISA Io Addresses\n");
            break;

        case ACPI_ISA_ONLY_RANGES:
            AcpiOsPrintf ("    Type Specific: "
                            "ISA Io Addresses\n");
            break;

        case ACPI_ENTIRE_RANGE:
            AcpiOsPrintf ("    Type Specific: "
                            "ISA and non-ISA Io Addresses\n");
            break;

        default:
            AcpiOsPrintf ("    Type Specific: "
                            "Invalid Range attribute");
            break;
        }

        AcpiOsPrintf ("  Type Specific: %s Translation\n",
            ACPI_SPARSE_TRANSLATION ==
            Address64Data->Attribute.Io.TranslationAttribute ?
            "Sparse" : "Dense");
        break;

    case ACPI_BUS_NUMBER_RANGE:

        AcpiOsPrintf ("    Resource Type: Bus Number Range\n");
        break;

    default:

        AcpiOsPrintf ("    Invalid Resource Type..exiting.\n");
        return;
    }

    AcpiOsPrintf ("    Resource %s\n",
                ACPI_CONSUMER == Address64Data->ProducerConsumer ?
                "Consumer" : "Producer");

    AcpiOsPrintf ("    %s decode\n",
                ACPI_SUB_DECODE == Address64Data->Decode ?
                "Subtractive" : "Positive");

    AcpiOsPrintf ("    Min address is %s fixed\n",
                ACPI_ADDRESS_FIXED == Address64Data->MinAddressFixed ?
                "" : "not ");

    AcpiOsPrintf ("    Max address is %s fixed\n",
                ACPI_ADDRESS_FIXED == Address64Data->MaxAddressFixed ?
                "" : "not ");

    AcpiOsPrintf ("    Granularity: %8.8X%8.8X\n",
                ACPI_HIDWORD (Address64Data->Granularity),
                ACPI_LODWORD (Address64Data->Granularity));

    AcpiOsPrintf ("    Address range min: %8.8X%8.8X\n",
                ACPI_HIDWORD (Address64Data->MinAddressRange),
                ACPI_HIDWORD (Address64Data->MinAddressRange));

    AcpiOsPrintf ("    Address range max: %8.8X%8.8X\n",
                ACPI_HIDWORD (Address64Data->MaxAddressRange),
                ACPI_HIDWORD (Address64Data->MaxAddressRange));

    AcpiOsPrintf ("    Address translation offset: %8.8X%8.8X\n",
                ACPI_HIDWORD (Address64Data->AddressTranslationOffset),
                ACPI_HIDWORD (Address64Data->AddressTranslationOffset));

    AcpiOsPrintf ("    Address Length: %8.8X%8.8X\n",
                ACPI_HIDWORD (Address64Data->AddressLength),
                ACPI_HIDWORD (Address64Data->AddressLength));

    if(0xFF != Address64Data->ResourceSource.Index)
    {
        AcpiOsPrintf ("    Resource Source Index: %X\n",
                    Address64Data->ResourceSource.Index);
        AcpiOsPrintf ("    Resource Source: %s\n",
                    Address64Data->ResourceSource.StringPtr);
    }

    return;
}
Ejemplo n.º 20
0
ACPI_STATUS
AcpiEvPciConfigRegionSetup (
    ACPI_HANDLE             Handle,
    UINT32                  Function,
    void                    *HandlerContext,
    void                    **RegionContext)
{
    ACPI_STATUS             Status = AE_OK;
    UINT64                  PciValue;
    ACPI_PCI_ID             *PciId = *RegionContext;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_NAMESPACE_NODE     *ParentNode;
    ACPI_NAMESPACE_NODE     *PciRootNode;
    ACPI_NAMESPACE_NODE     *PciDeviceNode;
    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;


    ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);


    HandlerObj = RegionObj->Region.Handler;
    if (!HandlerObj)
    {
        /*
         * No installed handler. This shouldn't happen because the dispatch
         * routine checks before we get here, but we check again just in case.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
            "Attempting to init a region %p, with no handler\n", RegionObj));
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    *RegionContext = NULL;
    if (Function == ACPI_REGION_DEACTIVATE)
    {
        if (PciId)
        {
            ACPI_FREE (PciId);
        }
        return_ACPI_STATUS (Status);
    }

    ParentNode = RegionObj->Region.Node->Parent;

    /*
     * Get the _SEG and _BBN values from the device upon which the handler
     * is installed.
     *
     * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
     * This is the device the handler has been registered to handle.
     */

    /*
     * If the AddressSpace.Node is still pointing to the root, we need
     * to scan upward for a PCI Root bridge and re-associate the OpRegion
     * handlers with that device.
     */
    if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
    {
        /* Start search from the parent object */

        PciRootNode = ParentNode;
        while (PciRootNode != AcpiGbl_RootNode)
        {
            /* Get the _HID/_CID in order to detect a RootBridge */

            if (AcpiEvIsPciRootBridge (PciRootNode))
            {
                /* Install a handler for this PCI root bridge */

                Status = AcpiInstallAddressSpaceHandler (
                    (ACPI_HANDLE) PciRootNode,
                    ACPI_ADR_SPACE_PCI_CONFIG,
                    ACPI_DEFAULT_HANDLER, NULL, NULL);
                if (ACPI_FAILURE (Status))
                {
                    if (Status == AE_SAME_HANDLER)
                    {
                        /*
                         * It is OK if the handler is already installed on the
                         * root bridge. Still need to return a context object
                         * for the new PCI_Config operation region, however.
                         */
                        Status = AE_OK;
                    }
                    else
                    {
                        ACPI_EXCEPTION ((AE_INFO, Status,
                            "Could not install PciConfig handler "
                            "for Root Bridge %4.4s",
                            AcpiUtGetNodeName (PciRootNode)));
                    }
                }
                break;
            }

            PciRootNode = PciRootNode->Parent;
        }

        /* PCI root bridge not found, use namespace root node */
    }
    else
    {
        PciRootNode = HandlerObj->AddressSpace.Node;
    }

    /*
     * If this region is now initialized, we are done.
     * (InstallAddressSpaceHandler could have initialized it)
     */
    if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Region is still not initialized. Create a new context */

    PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
    if (!PciId)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * For PCI_Config space access, we need the segment, bus, device and
     * function numbers. Acquire them here.
     *
     * Find the parent device object. (This allows the operation region to be
     * within a subscope under the device, such as a control method.)
     */
    PciDeviceNode = RegionObj->Region.Node;
    while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
    {
        PciDeviceNode = PciDeviceNode->Parent;
    }

    if (!PciDeviceNode)
    {
        ACPI_FREE (PciId);
        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }

    /*
     * Get the PCI device and function numbers from the _ADR object
     * contained in the parent's scope.
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
        PciDeviceNode, &PciValue);

    /*
     * The default is zero, and since the allocation above zeroed the data,
     * just do nothing on failure.
     */
    if (ACPI_SUCCESS (Status))
    {
        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
    }

    /* The PCI segment number comes from the _SEG method */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
        PciRootNode, &PciValue);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Segment = ACPI_LOWORD (PciValue);
    }

    /* The PCI bus number comes from the _BBN method */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
        PciRootNode, &PciValue);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Bus = ACPI_LOWORD (PciValue);
    }

    /* Complete/update the PCI ID for this device */

    Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (PciId);
        return_ACPI_STATUS (Status);
    }

    *RegionContext = PciId;
    return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 21
0
acpi_status
acpi_tb_get_this_table (
	struct acpi_pointer             *address,
	struct acpi_table_header        *header,
	struct acpi_table_desc          *table_info)
{
	struct acpi_table_header        *full_table = NULL;
	u8                              allocation;
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("tb_get_this_table");


	/*
	 * Flags contains the current processor mode (Virtual or Physical addressing)
	 * The pointer_type is either Logical or Physical
	 */
	switch (address->pointer_type) {
	case ACPI_PHYSMODE_PHYSPTR:
	case ACPI_LOGMODE_LOGPTR:

		/* Pointer matches processor mode, copy the table to a new buffer */

		full_table = ACPI_MEM_ALLOCATE (header->length);
		if (!full_table) {
			ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
				header->signature, header->length));
			return_ACPI_STATUS (AE_NO_MEMORY);
		}

		/* Copy the entire table (including header) to the local buffer */

		ACPI_MEMCPY (full_table, address->pointer.logical, header->length);

		/* Save allocation type */

		allocation = ACPI_MEM_ALLOCATED;
		break;


	case ACPI_LOGMODE_PHYSPTR:

		/*
		 * Just map the table's physical memory
		 * into our address space.
		 */
		status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length,
				  (void **) &full_table);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
				header->signature,
				ACPI_HIDWORD (address->pointer.physical),
				ACPI_LODWORD (address->pointer.physical), header->length));
			return (status);
		}

		/* Save allocation type */

		allocation = ACPI_MEM_MAPPED;
		break;


	default:

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
			address->pointer_type));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/*
	 * Validate checksum for _most_ tables,
	 * even the ones whose signature we don't recognize
	 */
	if (table_info->type != ACPI_TABLE_FACS) {
		status = acpi_tb_verify_table_checksum (full_table);

#if (!ACPI_CHECKSUM_ABORT)
		if (ACPI_FAILURE (status)) {
			/* Ignore the error if configuration says so */

			status = AE_OK;
		}
#endif
	}

	/* Return values */

	table_info->pointer     = full_table;
	table_info->length      = (acpi_size) header->length;
	table_info->allocation  = allocation;

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
		full_table->signature,
		ACPI_HIDWORD (address->pointer.physical),
		ACPI_LODWORD (address->pointer.physical), full_table));

	return_ACPI_STATUS (status);
}
Ejemplo n.º 22
0
acpi_status
acpi_ev_pci_config_region_setup(acpi_handle handle,
				u32 function,
				void *handler_context, void **region_context)
{
	acpi_status status = AE_OK;
	acpi_integer pci_value;
	struct acpi_pci_id *pci_id = *region_context;
	union acpi_operand_object *handler_obj;
	struct acpi_namespace_node *parent_node;
	struct acpi_namespace_node *pci_root_node;
	union acpi_operand_object *region_obj =
	    (union acpi_operand_object *)handle;
	struct acpi_device_id object_hID;

	ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);

	handler_obj = region_obj->region.handler;
	if (!handler_obj) {
		/*
		 * No installed handler. This shouldn't happen because the dispatch
		 * routine checks before we get here, but we check again just in case.
		 */
		ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
				  "Attempting to init a region %p, with no handler\n",
				  region_obj));
		return_ACPI_STATUS(AE_NOT_EXIST);
	}

	*region_context = NULL;
	if (function == ACPI_REGION_DEACTIVATE) {
		if (pci_id) {
			ACPI_FREE(pci_id);
		}
		return_ACPI_STATUS(status);
	}

	parent_node = acpi_ns_get_parent_node(region_obj->region.node);

	/*
	 * Get the _SEG and _BBN values from the device upon which the handler
	 * is installed.
	 *
	 * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
	 * This is the device the handler has been registered to handle.
	 */

	/*
	 * If the address_space.Node is still pointing to the root, we need
	 * to scan upward for a PCI Root bridge and re-associate the op_region
	 * handlers with that device.
	 */
	if (handler_obj->address_space.node == acpi_gbl_root_node) {

		/* Start search from the parent object */

		pci_root_node = parent_node;
		while (pci_root_node != acpi_gbl_root_node) {
			status =
			    acpi_ut_execute_HID(pci_root_node, &object_hID);
			if (ACPI_SUCCESS(status)) {
				/*
				 * Got a valid _HID string, check if this is a PCI root.
				 * New for ACPI 3.0: check for a PCI Express root also.
				 */
				if (!
				    (ACPI_STRNCMP
				     (object_hID.value, PCI_ROOT_HID_STRING,
				      sizeof(PCI_ROOT_HID_STRING))
				     ||
				     !(ACPI_STRNCMP
				       (object_hID.value,
					PCI_EXPRESS_ROOT_HID_STRING,
					sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
				{

					/* Install a handler for this PCI root bridge */

					status =
					    acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
					if (ACPI_FAILURE(status)) {
						if (status == AE_SAME_HANDLER) {
							/*
							 * It is OK if the handler is already installed on the root
							 * bridge.  Still need to return a context object for the
							 * new PCI_Config operation region, however.
							 */
							status = AE_OK;
						} else {
							ACPI_EXCEPTION((AE_INFO,
									status,
									"Could not install PciConfig handler for Root Bridge %4.4s",
									acpi_ut_get_node_name
									(pci_root_node)));
						}
					}
					break;
				}
			}

			pci_root_node = acpi_ns_get_parent_node(pci_root_node);
		}

		/* PCI root bridge not found, use namespace root node */
	} else {
		pci_root_node = handler_obj->address_space.node;
	}

	/*
	 * If this region is now initialized, we are done.
	 * (install_address_space_handler could have initialized it)
	 */
	if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
		return_ACPI_STATUS(AE_OK);
	}

	/* Region is still not initialized. Create a new context */

	pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id));
	if (!pci_id) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/*
	 * For PCI_Config space access, we need the segment, bus,
	 * device and function numbers.  Acquire them here.
	 */

	/*
	 * Get the PCI device and function numbers from the _ADR object
	 * contained in the parent's scope.
	 */
	status =
	    acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node,
					    &pci_value);

	/*
	 * The default is zero, and since the allocation above zeroed
	 * the data, just do nothing on failure.
	 */
	if (ACPI_SUCCESS(status)) {
		pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
		pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
	}

	/* The PCI segment number comes from the _SEG method */

	status =
	    acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
					    &pci_value);
	if (ACPI_SUCCESS(status)) {
		pci_id->segment = ACPI_LOWORD(pci_value);
	}

	/* The PCI bus number comes from the _BBN method */

	status =
	    acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
					    &pci_value);
	if (ACPI_SUCCESS(status)) {
		pci_id->bus = ACPI_LOWORD(pci_value);
	}

	/* Complete this device's pci_id */

	acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id);

	*region_context = pci_id;
	return_ACPI_STATUS(AE_OK);
}
Ejemplo n.º 23
0
acpi_status
acpi_get_firmware_table (
	acpi_string                     signature,
	u32                             instance,
	u32                             flags,
	struct acpi_table_header        **table_pointer)
{
	struct acpi_pointer             rsdp_address;
	struct acpi_pointer             address;
	acpi_status                     status;
	struct acpi_table_header        header;
	struct acpi_table_desc          table_info;
	struct acpi_table_desc          rsdt_info;
	u32                             table_count;
	u32                             i;
	u32                             j;


	ACPI_FUNCTION_TRACE ("acpi_get_firmware_table");


	/*
	 * Ensure that at least the table manager is initialized.  We don't
	 * require that the entire ACPI subsystem is up for this interface
	 */

	/*
	 *  If we have a buffer, we must have a length too
	 */
	if ((instance == 0)                 ||
		(!signature)                    ||
		(!table_pointer)) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	rsdt_info.pointer = NULL;

	if (!acpi_gbl_RSDP) {
		/* Get the RSDP */

		status = acpi_os_get_root_pointer (flags, &rsdp_address);
		if (ACPI_FAILURE (status)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP  not found\n"));
			return_ACPI_STATUS (AE_NO_ACPI_TABLES);
		}

		/* Map and validate the RSDP */

		if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
			status = acpi_os_map_memory (rsdp_address.pointer.physical, sizeof (struct rsdp_descriptor),
					  (void *) &acpi_gbl_RSDP);
			if (ACPI_FAILURE (status)) {
				return_ACPI_STATUS (status);
			}
		}
		else {
			acpi_gbl_RSDP = rsdp_address.pointer.logical;
		}

		/*
		 *  The signature and checksum must both be correct
		 */
		if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
			/* Nope, BAD Signature */

			return_ACPI_STATUS (AE_BAD_SIGNATURE);
		}

		if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
			/* Nope, BAD Checksum */

			return_ACPI_STATUS (AE_BAD_CHECKSUM);
		}
	}

	/* Get the RSDT and validate it */

	acpi_tb_get_rsdt_address (&address);

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
		acpi_gbl_RSDP,
		ACPI_HIDWORD (address.pointer.value),
		ACPI_LODWORD (address.pointer.value)));

	/* Insert processor_mode flags */

	address.pointer_type |= flags;

	status = acpi_tb_get_table (&address, &rsdt_info);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	status = acpi_tb_validate_rsdt (rsdt_info.pointer);
	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	/* Get the number of table pointers within the RSDT */

	table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info.pointer);

	address.pointer_type = acpi_gbl_table_flags | flags;

	/*
	 * Search the RSDT/XSDT for the correct instance of the
	 * requested table
	 */
	for (i = 0, j = 0; i < table_count; i++) {
		/* Get the next table pointer, handle RSDT vs. XSDT */

		if (acpi_gbl_RSDP->revision < 2) {
			address.pointer.value = ((RSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i];
		}
		else {
			address.pointer.value =
				((XSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i];
		}

		/* Get the table header */

		status = acpi_tb_get_table_header (&address, &header);
		if (ACPI_FAILURE (status)) {
			goto cleanup;
		}

		/* Compare table signatures and table instance */

		if (!ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
			/* An instance of the table was found */

			j++;
			if (j >= instance) {
				/* Found the correct instance, get the entire table */

				status = acpi_tb_get_table_body (&address, &header, &table_info);
				if (ACPI_FAILURE (status)) {
					goto cleanup;
				}

				*table_pointer = table_info.pointer;
				goto cleanup;
			}
		}
	}

	/* Did not find the table */

	status = AE_NOT_EXIST;


cleanup:
	acpi_os_unmap_memory (rsdt_info.pointer, (acpi_size) rsdt_info.pointer->length);
	return_ACPI_STATUS (status);
}
Ejemplo n.º 24
0
ACPI_STATUS
AcpiTbGetRequiredTables (
    void)
{
    ACPI_STATUS             Status = AE_OK;
    UINT32                  i;
    ACPI_TABLE_DESC         TableInfo;
    ACPI_POINTER            Address;


    ACPI_FUNCTION_TRACE ("TbGetRequiredTables");

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
        AcpiGbl_RsdtTableCount));


    Address.PointerType   = AcpiGbl_TableFlags | ACPI_LOGICAL_ADDRESSING;

    /*
     * Loop through all table pointers found in RSDT.
     * This will NOT include the FACS and DSDT - we must get
     * them after the loop.
     *
     * The only tables we are interested in getting here is the FADT and
     * any SSDTs.
     */
    for (i = 0; i < AcpiGbl_RsdtTableCount; i++)
    {
        /* Get the table addresss from the common internal XSDT */

        Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_XSDT->TableOffsetEntry[i]);

        /*
         * Get the tables needed by this subsystem (FADT and any SSDTs).
         * NOTE: All other tables are completely ignored at this time.
         */
        Status = AcpiTbGetPrimaryTable (&Address, &TableInfo);
        if ((Status != AE_OK) && (Status != AE_TABLE_NOT_SUPPORTED))
        {
            ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
                AcpiFormatException (Status),
                ACPI_HIDWORD (Address.Pointer.Value),
                ACPI_LODWORD (Address.Pointer.Value)));
        }
    }

    /* We must have a FADT to continue */

    if (!AcpiGbl_FADT)
    {
        ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
        return_ACPI_STATUS (AE_NO_ACPI_TABLES);
    }

    /*
     * Convert the FADT to a common format.  This allows earlier revisions of the
     * table to coexist with newer versions, using common access code.
     */
    Status = AcpiTbConvertTableFadt ();
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
        return_ACPI_STATUS (Status);
    }

    /*
     * Get the FACS (Pointed to by the FADT)
     */
    Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XFirmwareCtrl);

    Status = AcpiTbGetSecondaryTable (&Address, FACS_SIG, &TableInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
            AcpiFormatException (Status)));
        return_ACPI_STATUS (Status);
    }

    /*
     * Create the common FACS pointer table
     * (Contains pointers to the original table)
     */
    Status = AcpiTbBuildCommonFacs (&TableInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Get/install the DSDT (Pointed to by the FADT)
     */
    Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XDsdt);

    Status = AcpiTbGetSecondaryTable (&Address, DSDT_SIG, &TableInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
        return_ACPI_STATUS (Status);
    }

    /* Set Integer Width (32/64) based upon DSDT revision */

    AcpiUtSetIntegerWidth (AcpiGbl_DSDT->Revision);

    /* Dump the entire DSDT */

    ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
        "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
        AcpiGbl_DSDT->Length, AcpiGbl_DSDT->Length, AcpiGbl_IntegerBitWidth));
    ACPI_DUMP_BUFFER ((UINT8 *) AcpiGbl_DSDT, AcpiGbl_DSDT->Length);

    /* Always delete the RSDP mapping, we are done with it */

    AcpiTbDeleteAcpiTable (ACPI_TABLE_RSDP);
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 25
0
ACPI_STATUS
AcpiEvPciConfigRegionSetup (
    ACPI_HANDLE             Handle,
    UINT32                  Function,
    void                    *HandlerContext,
    void                    **RegionContext)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_INTEGER            Temp;
    ACPI_PCI_ID             *PciId = *RegionContext;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
    ACPI_DEVICE_ID          ObjectHID;


    ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup");


    HandlerObj = RegionObj->Region.AddrHandler;
    if (!HandlerObj)
    {
        /*
         * No installed handler. This shouldn't happen because the dispatch
         * routine checks before we get here, but we check again just in case.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
            "Attempting to init a region %p, with no handler\n", RegionObj));
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    if (Function == ACPI_REGION_DEACTIVATE)
    {
        if (PciId)
        {
            ACPI_MEM_FREE (PciId);
            *RegionContext = NULL;
        }

        return_ACPI_STATUS (Status);
    }

    /* Create a new context */

    PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
    if (!PciId)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * For PCI Config space access, we have to pass the segment, bus,
     * device and function numbers.  This routine must acquire those.
     */

    /*
     * First get device and function numbers from the _ADR object
     * in the parent's scope.
     */
    Node = AcpiNsGetParentNode (RegionObj->Region.Node);

    /* Evaluate the _ADR object */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Temp);

    /*
     * The default is zero, and since the allocation above zeroed
     * the data, just do nothing on failure.
     */
    if (ACPI_SUCCESS (Status))
    {
        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (Temp));
        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (Temp));
    }

    /*
     * Get the _SEG and _BBN values from the device upon which the handler
     * is installed.
     *
     * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
     * This is the device the handler has been registered to handle.
     */

    /*
     * If the AddrHandler.Node is still pointing to the root, we need
     * to scan upward for a PCI Root bridge and re-associate the OpRegion
     * handlers with that device.
     */
    if (HandlerObj->AddrHandler.Node == AcpiGbl_RootNode)
    {
        /*
         * Node is currently the parent object
         */
        while (Node != AcpiGbl_RootNode)
        {
            Status = AcpiUtExecute_HID (Node, &ObjectHID);
            if (ACPI_SUCCESS (Status))
            {
                /* Got a valid _HID, check if this is a PCI root */

                if (!(ACPI_STRNCMP (ObjectHID.Buffer, PCI_ROOT_HID_STRING,
                                    sizeof (PCI_ROOT_HID_STRING))))
                {
                    /* Install a handler for this PCI root bridge */

                    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) Node,
                                        ACPI_ADR_SPACE_PCI_CONFIG,
                                        ACPI_DEFAULT_HANDLER, NULL, NULL);
                    if (ACPI_FAILURE (Status))
                    {
                        ACPI_REPORT_ERROR (("Could not install PciConfig handler for %4.4s, %s\n",
                            Node->Name.Ascii, AcpiFormatException (Status)));
                    }
                    break;
                }
            }

            Node = AcpiNsGetParentNode (Node);
        }
    }
    else
    {
        Node = HandlerObj->AddrHandler.Node;
    }

    /*
     * The PCI segment number comes from the _SEG method
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Segment = ACPI_LOWORD (Temp);
    }

    /*
     * The PCI bus number comes from the _BBN method
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Bus = ACPI_LOWORD (Temp);
    }

    /*
     * Complete this device's PciId
     */
    AcpiOsDerivePciId (Node, RegionObj->Region.Node, &PciId);

    *RegionContext = PciId;
    return_ACPI_STATUS (AE_OK);
}