Example #1
0
static ACPI_STATUS
acpidev_memory_init(acpidev_walk_info_t *infop)
{
	char *compatible[] = {
		ACPIDEV_TYPE_MEMORY,
		"mem"
	};

	ASSERT(infop != NULL);
	ASSERT(infop->awi_hdl != NULL);
	ASSERT(infop->awi_dip != NULL);
	if (ACPI_FAILURE(acpidev_resource_process(infop, B_TRUE))) {
		cmn_err(CE_WARN, "!acpidev: failed to process resources of "
		    "memory device %s.", infop->awi_name);
		return (AE_ERROR);
	}

	if (ACPI_FAILURE(acpidev_set_compatible(infop,
	    ACPIDEV_ARRAY_PARAM(compatible)))) {
		return (AE_ERROR);
	}

	if (ACPI_FAILURE(acpidev_set_unitaddr(infop,
	    ACPIDEV_ARRAY_PARAM(acpidev_memory_uid_formats), NULL))) {
		return (AE_ERROR);
	}

	return (AE_OK);
}
/*ARGSUSED*/
static ACPI_STATUS
acpidev_scope_init(acpidev_walk_info_t *infop)
{
	char unitaddr[32];
	char *compatible[] = {
		ACPIDEV_HID_SCOPE,
		ACPIDEV_TYPE_SCOPE,
		ACPIDEV_HID_VIRTNEX,
		ACPIDEV_TYPE_VIRTNEX,
	};

	ASSERT(infop != NULL);
	ASSERT(infop->awi_hdl != NULL);
	ASSERT(infop->awi_dip != NULL);
	if (ACPI_FAILURE(acpidev_set_compatible(infop,
	    ACPIDEV_ARRAY_PARAM(compatible)))) {
		return (AE_ERROR);
	}
	(void) snprintf(unitaddr, sizeof (unitaddr), "%u",
	    atomic_inc_32_nv(&acpidev_scope_unitaddr) - 1);
	if (ACPI_FAILURE(acpidev_set_unitaddr(infop, NULL, 0, unitaddr))) {
		return (AE_ERROR);
	}

	return (AE_OK);
}
Example #3
0
static ACPI_STATUS
acpidev_memory_probe(acpidev_walk_info_t *infop)
{
	ACPI_STATUS rc = AE_OK;
	int flags;

	ASSERT(infop != NULL);
	ASSERT(infop->awi_hdl != NULL);
	ASSERT(infop->awi_info != NULL);
	if (infop->awi_info->Type != ACPI_TYPE_DEVICE ||
	    acpidev_match_device_id(infop->awi_info,
	    ACPIDEV_ARRAY_PARAM(acpidev_memory_device_ids)) == 0) {
		return (AE_OK);
	}

	flags = ACPIDEV_PROCESS_FLAG_SCAN;
	switch (infop->awi_op_type) {
	case ACPIDEV_OP_BOOT_PROBE:
		if (acpica_get_devcfg_feature(ACPI_DEVCFG_MEMORY)) {
			flags |= ACPIDEV_PROCESS_FLAG_CREATE;
			acpidev_dr_check(infop);
		}
		break;

	case ACPIDEV_OP_BOOT_REPROBE:
		break;

	case ACPIDEV_OP_HOTPLUG_PROBE:
		if (acpica_get_devcfg_feature(ACPI_DEVCFG_MEMORY)) {
			flags |= ACPIDEV_PROCESS_FLAG_CREATE |
			    ACPIDEV_PROCESS_FLAG_SYNCSTATUS |
			    ACPIDEV_PROCESS_FLAG_HOLDBRANCH;
		}
		break;

	default:
		ACPIDEV_DEBUG(CE_WARN, "!acpidev: unknown operation type %u "
		    "in acpidev_memory_probe.", infop->awi_op_type);
		rc = AE_BAD_PARAMETER;
		break;
	}

	if (rc == AE_OK) {
		rc = acpidev_process_object(infop, flags);
	}
	if (ACPI_FAILURE(rc) && rc != AE_NOT_EXIST && rc != AE_ALREADY_EXISTS) {
		cmn_err(CE_WARN,
		    "!acpidev: failed to process memory object %s.",
		    infop->awi_name);
	} else {
		rc = AE_OK;
	}

	return (rc);
}
Example #4
0
static acpidev_filter_result_t
acpidev_memory_filter(acpidev_walk_info_t *infop, char *devname, int maxlen)
{
	acpidev_filter_result_t res;

	ASSERT(infop != NULL);
	if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE ||
	    infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE ||
	    infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) {
		res = acpidev_filter_device(infop, infop->awi_hdl,
		    ACPIDEV_ARRAY_PARAM(acpidev_memory_filters),
		    devname, maxlen);
	} else {
		res = ACPIDEV_FILTER_FAILED;
	}

	return (res);
}
static acpidev_filter_result_t
acpidev_scope_filter(acpidev_walk_info_t *infop, char *devname, int maxlen)
{
	acpidev_filter_result_t res;

	ASSERT(infop != NULL);
	if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE ||
	    infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE ||
	    infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) {
		res = acpidev_filter_device(infop, infop->awi_hdl,
		    ACPIDEV_ARRAY_PARAM(acpidev_scope_filters),
		    devname, maxlen);
	} else {
		ACPIDEV_DEBUG(CE_WARN, "acpidev: unknown operation type %u "
		    "in acpidev_scope_filter().", infop->awi_op_type);
		res = ACPIDEV_FILTER_FAILED;
	}

	return (res);
}
Example #6
0
static ACPI_STATUS
acpidev_cpu_init(acpidev_walk_info_t *infop)
{
	int count;
	uint32_t pxmid;
	dev_info_t *dip;
	ACPI_HANDLE hdl;
	char unitaddr[64];
	char **compatpp;
	static char *compatible[] = {
		ACPIDEV_HID_PROCESSOR,
		ACPIDEV_TYPE_CPU,
		"cpu"
	};

	ASSERT(infop != NULL);
	dip = infop->awi_dip;
	hdl = infop->awi_hdl;

	/* Create "apic_id", "processor_id" and "proximity_id" properties. */
	if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
	    ACPIDEV_PROP_NAME_PROCESSOR_ID, infop->awi_scratchpad[0]) !=
	    NDI_SUCCESS) {
		cmn_err(CE_WARN,
		    "!acpidev: failed to set processor_id property for %s.",
		    infop->awi_name);
		return (AE_ERROR);
	}
	if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
	    ACPIDEV_PROP_NAME_LOCALAPIC_ID, infop->awi_scratchpad[1]) !=
	    NDI_SUCCESS) {
		cmn_err(CE_WARN,
		    "!acpidev: failed to set apic_id property for %s.",
		    infop->awi_name);
		return (AE_ERROR);
	}
	if (ACPI_SUCCESS(acpidev_cpu_get_proximity_id(infop->awi_hdl,
	    infop->awi_scratchpad[1], &pxmid))) {
		if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
		    ACPIDEV_PROP_NAME_PROXIMITY_ID, pxmid) != NDI_SUCCESS) {
			cmn_err(CE_WARN, "!acpidev: failed to set proximity id "
			    "property for %s.", infop->awi_name);
			return (AE_ERROR);
		}
	}

	/* Set "compatible" property for CPU dip */
	count = sizeof (compatible) / sizeof (compatible[0]);
	if (infop->awi_info->Type == ACPI_TYPE_PROCESSOR) {
		compatpp = compatible;
	} else if (infop->awi_info->Type == ACPI_TYPE_DEVICE) {
		/*
		 * skip first item for pseudo processor HID.
		 * acpidev_set_compatible() will handle HID/CID for CPU device.
		 */
		compatpp = &compatible[1];
		count--;
	} else {
		return (AE_BAD_PARAMETER);
	}
	if (ACPI_FAILURE(acpidev_set_compatible(infop, compatpp, count))) {
		return (AE_ERROR);
	}

	/*
	 * Set device unit-address property.
	 * First try to generate meaningful unit address from _UID,
	 * then use Processor Id if that fails.
	 */
	if ((infop->awi_info->Valid & ACPI_VALID_UID) == 0 ||
	    acpidev_generate_unitaddr(infop->awi_info->UniqueId.String,
	    ACPIDEV_ARRAY_PARAM(acpidev_cpu_uid_formats),
	    unitaddr, sizeof (unitaddr)) == NULL) {
		(void) snprintf(unitaddr, sizeof (unitaddr), "%u",
		    (uint32_t)infop->awi_scratchpad[0]);
	}
	if (ACPI_FAILURE(acpidev_set_unitaddr(infop, NULL, 0, unitaddr))) {
		return (AE_ERROR);
	}

	/*
	 * Build binding information for CPUs.
	 */
	if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE ||
	    infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE ||
	    infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) {
		if (ACPI_FAILURE(acpica_add_processor_to_map(
		    infop->awi_scratchpad[0], hdl, infop->awi_scratchpad[1]))) {
			cmn_err(CE_WARN, "!acpidev: failed to bind processor "
			    "id/object handle for %s.", infop->awi_name);
			return (AE_ERROR);
		}
	} else {
		ACPIDEV_DEBUG(CE_WARN,
		    "!acpidev: unknown operation type %u in acpidev_cpu_init.",
		    infop->awi_op_type);
		return (AE_BAD_PARAMETER);
	}

	return (AE_OK);
}
Example #7
0
static ACPI_STATUS
acpidev_cpu_probe(acpidev_walk_info_t *infop)
{
	ACPI_STATUS rc = AE_OK;
	int flags;

	ASSERT(infop != NULL);
	ASSERT(infop->awi_hdl != NULL);
	ASSERT(infop->awi_info != NULL);
	ASSERT(infop->awi_class_curr == &acpidev_class_cpu);
	if (infop->awi_info->Type != ACPI_TYPE_PROCESSOR &&
	    (infop->awi_info->Type != ACPI_TYPE_DEVICE ||
	    acpidev_match_device_id(infop->awi_info,
	    ACPIDEV_ARRAY_PARAM(acpidev_processor_device_ids)) == 0)) {
		return (AE_OK);
	}

	flags = ACPIDEV_PROCESS_FLAG_SCAN;
	switch (infop->awi_op_type) {
	case  ACPIDEV_OP_BOOT_PROBE:
		/*
		 * Mark device as offline. It will be changed to online state
		 * when the corresponding CPU starts up.
		 */
		if (acpica_get_devcfg_feature(ACPI_DEVCFG_CPU)) {
			flags |= ACPIDEV_PROCESS_FLAG_CREATE |
			    ACPIDEV_PROCESS_FLAG_OFFLINE;
		}
		break;

	case ACPIDEV_OP_BOOT_REPROBE:
		break;

	case ACPIDEV_OP_HOTPLUG_PROBE:
		if (acpica_get_devcfg_feature(ACPI_DEVCFG_CPU)) {
			flags |= ACPIDEV_PROCESS_FLAG_CREATE |
			    ACPIDEV_PROCESS_FLAG_OFFLINE |
			    ACPIDEV_PROCESS_FLAG_SYNCSTATUS |
			    ACPIDEV_PROCESS_FLAG_HOLDBRANCH;
		}
		break;

	default:
		ACPIDEV_DEBUG(CE_WARN, "!acpidev: unknown operation type %u in "
		    "acpidev_cpu_probe().", infop->awi_op_type);
		rc = AE_BAD_PARAMETER;
		break;
	}

	if (rc == AE_OK) {
		rc = acpidev_process_object(infop, flags);
	}
	if (ACPI_FAILURE(rc) && rc != AE_NOT_EXIST && rc != AE_ALREADY_EXISTS) {
		cmn_err(CE_WARN,
		    "!acpidev: failed to process processor object %s.",
		    infop->awi_name);
	} else {
		rc = AE_OK;
	}

	return (rc);
}