b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * CDDL HEADER START
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * The contents of this file are subject to the terms of the
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Common Development and Distribution License (the "License").
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * You may not use this file except in compliance with the License.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * or http://www.opensolaris.org/os/licensing.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * See the License for the specific language governing permissions
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * and limitations under the License.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * When distributing Covered Code, include this CDDL HEADER in each
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * If applicable, add the following below this CDDL HEADER, with the
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * fields enclosed by brackets "[]" replaced with your own identifying
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * information: Portions Copyright [yyyy] [name of copyright owner]
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * CDDL HEADER END
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Use is subject to license terms.
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright (c) 2009-2010, Intel Corporation.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * All rights reserved.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * [Support of X2APIC]
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * According to the ACPI Spec, when using the X2APIC interrupt model, logical
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * processors with APIC ID values of 255 and greater are required to have a
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Processor Device object and must convey the Processor's APIC information to
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * OSPM using the Processor Local X2APIC structure. Logical Processors with APIC
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * ID values less than 255 must use the Processor Local XAPIC structure to
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * convey their APIC information to OSPM.
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld *
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld * Some systems ignore that requirement of ACPI Spec and use Processor Local
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld * X2APIC structures even for Logical Processors with APIC ID values less than
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld * 255.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/types.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/atomic.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/bootconf.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/cpuvar.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/machsystm.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/note.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/psm_types.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/x86_archext.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/sunddi.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/sunndi.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/acpi/acpi.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/acpica.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/acpidev.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran#include <sys/acpidev_impl.h>
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstruct acpidev_cpu_map_item {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t proc_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t apic_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran};
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstruct acpidev_cpu_MAT_arg {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran boolean_t found;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran boolean_t enabled;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t proc_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t apic_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran};
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS acpidev_cpu_pre_probe(acpidev_walk_info_t *infop);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS acpidev_cpu_post_probe(acpidev_walk_info_t *infop);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS acpidev_cpu_probe(acpidev_walk_info_t *infop);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic acpidev_filter_result_t acpidev_cpu_filter(acpidev_walk_info_t *infop,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran char *devname, int maxlen);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS acpidev_cpu_init(acpidev_walk_info_t *infop);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void acpidev_cpu_fini(ACPI_HANDLE hdl, acpidev_data_handle_t dhdl,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu acpidev_class_t *clsp);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic acpidev_filter_result_t acpidev_cpu_filter_func(
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_walk_info_t *infop, ACPI_HANDLE hdl, acpidev_filter_rule_t *afrp,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran char *devname, int len);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int acpidev_cpu_create_dip(cpu_t *, dev_info_t **);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int acpidev_cpu_get_dip(cpu_t *, dev_info_t **);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Default class driver for ACPI processor/CPU objects.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_class_t acpidev_class_cpu = {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran 0, /* adc_refcnt */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_CLASS_REV1, /* adc_version */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_CLASS_ID_CPU, /* adc_class_id */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "ACPI CPU", /* adc_class_name */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_TYPE_CPU, /* adc_dev_type */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NULL, /* adc_private */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_pre_probe, /* adc_pre_probe */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_post_probe, /* adc_post_probe */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_probe, /* adc_probe */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_filter, /* adc_filter */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_init, /* adc_init */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu acpidev_cpu_fini, /* adc_fini */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran};
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * List of class drivers which will be called in order when handling
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * children of ACPI cpu/processor objects.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_class_list_t *acpidev_class_list_cpu = NULL;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/* Filter rule table for the first probe at boot time. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic acpidev_filter_rule_t acpidev_cpu_filters[] = {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran { /* Skip all processors under root node, should be there. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NULL,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran 0,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_FILTER_SKIP,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NULL,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran 1,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran 1,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NULL,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NULL,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran },
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran { /* Create and scan other processor objects */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_filter_func,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran 0,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_FILTER_DEFAULT,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran &acpidev_class_list_cpu,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran 2,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran INT_MAX,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NULL,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_NODE_NAME_CPU,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran};
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/* ACPI/PNP hardware id for processor. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic char *acpidev_processor_device_ids[] = {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_HID_CPU,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran};
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic char *acpidev_cpu_uid_formats[] = {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "SCK%x-CPU%x",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran};
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic ACPI_HANDLE acpidev_cpu_map_hdl;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic uint32_t acpidev_cpu_map_count;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic struct acpidev_cpu_map_item *acpidev_cpu_map;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranextern int (*psm_cpu_create_devinfo)(cpu_t *, dev_info_t **);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int (*psm_cpu_create_devinfo_old)(cpu_t *, dev_info_t **);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuextern int (*psm_cpu_get_devinfo)(cpu_t *, dev_info_t **);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int (*psm_cpu_get_devinfo_old)(cpu_t *, dev_info_t **);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/* Count how many enabled CPUs are in the MADT table. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_count_MADT(ACPI_SUBTABLE_HEADER *ap, void *context)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t *cntp;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_MADT_LOCAL_APIC *mpa;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_MADT_LOCAL_X2APIC *mpx2a;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran cntp = (uint32_t *)context;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran switch (ap->Type) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_APIC:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran mpa = (ACPI_MADT_LOCAL_APIC *)ap;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (mpa->LapicFlags & ACPI_MADT_ENABLED) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(mpa->Id != 255);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (*cntp)++;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_X2APIC:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran mpx2a = (ACPI_MADT_LOCAL_X2APIC *)ap;
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld if ((mpx2a->LapicFlags & ACPI_MADT_ENABLED)) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (*cntp)++;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran default:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/* Extract information from the enabled CPUs using the MADT table. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_parse_MADT(ACPI_SUBTABLE_HEADER *ap, void *context)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t *cntp;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_MADT_LOCAL_APIC *mpa;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_MADT_LOCAL_X2APIC *mpx2a;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran cntp = (uint32_t *)context;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran switch (ap->Type) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_APIC:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran mpa = (ACPI_MADT_LOCAL_APIC *)ap;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (mpa->LapicFlags & ACPI_MADT_ENABLED) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(mpa->Id != 255);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(*cntp < acpidev_cpu_map_count);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map[*cntp].proc_id = mpa->ProcessorId;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map[*cntp].apic_id = mpa->Id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (*cntp)++;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_X2APIC:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran mpx2a = (ACPI_MADT_LOCAL_X2APIC *)ap;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* See comment at beginning about 255 limitation. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (mpx2a->LocalApicId < 255) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_WARN,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: encountered CPU with X2APIC Id < 255.");
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld }
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld if (mpx2a->LapicFlags & ACPI_MADT_ENABLED) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(*cntp < acpidev_cpu_map_count);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map[*cntp].proc_id = mpx2a->Uid;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map[*cntp].apic_id = mpx2a->LocalApicId;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (*cntp)++;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran default:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_get_apicid(uint32_t procid, uint32_t *apicidp)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t i;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran for (i = 0; i < acpidev_cpu_map_count; i++) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (acpidev_cpu_map[i].proc_id == procid) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *apicidp = acpidev_cpu_map[i].apic_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_NOT_FOUND);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Extract information for enabled CPUs from the buffer returned
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * by the _MAT method.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_query_MAT(ACPI_SUBTABLE_HEADER *ap, void *context)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_MADT_LOCAL_APIC *mpa;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_MADT_LOCAL_X2APIC *mpx2a;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran struct acpidev_cpu_MAT_arg *rp;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rp = (struct acpidev_cpu_MAT_arg *)context;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran switch (ap->Type) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_APIC:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran mpa = (ACPI_MADT_LOCAL_APIC *)ap;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rp->found = B_TRUE;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rp->proc_id = mpa->ProcessorId;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rp->apic_id = mpa->Id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (mpa->LapicFlags & ACPI_MADT_ENABLED) {
e2af1b53c69207cf8b36451b3a8c8f800ee9855eRobert Mustacchi ASSERT(mpa->Id != 255);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rp->enabled = B_TRUE;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rp->enabled = B_FALSE;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_CTRL_TERMINATE);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_X2APIC:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran mpx2a = (ACPI_MADT_LOCAL_X2APIC *)ap;
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld if (mpx2a->LocalApicId < 255) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_DEBUG(CE_WARN, "!acpidev: encountered CPU "
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "with X2APIC Id < 255 in _MAT.");
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld rp->found = B_TRUE;
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld rp->proc_id = mpx2a->Uid;
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld rp->apic_id = mpx2a->LocalApicId;
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld if (mpx2a->LapicFlags & ACPI_MADT_ENABLED) {
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld rp->enabled = B_TRUE;
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld } else {
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld rp->enabled = B_FALSE;
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld }
c67b1bdc42c9c8c104b7c28c14222c006aa56b1eHans Rosenfeld return (AE_CTRL_TERMINATE);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* UNIMPLEMENTED */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* UNIMPLEMENTED */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran default:
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * According to the ACPI Spec, the buffer returned by _MAT
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * for a processor object should only contain Local APIC,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Local SAPIC, and local APIC NMI entries.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * x2APIC Specification extends it to support Processor
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * x2APIC and x2APIC NMI Structure.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_NOTE,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: unknown APIC entry type %u in _MAT.", ap->Type);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran break;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran/*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Query ACPI processor ID by evaluating ACPI _MAT, _UID, and PROCESSOR
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * objects.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_get_procid(acpidev_walk_info_t *infop, uint32_t *idp)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran int id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_HANDLE hdl;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran struct acpidev_cpu_MAT_arg mat;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_info->Type != ACPI_TYPE_PROCESSOR &&
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_info->Type != ACPI_TYPE_DEVICE) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_WARN,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: object %s is not PROCESSOR or DEVICE.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_BAD_PARAMETER);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran hdl = infop->awi_hdl;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * First try to evaluate _MAT.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * According to the ACPI Spec3.0b, it's legal for ACPI PROCESSOR objects
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * to have ACPI method objects.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran bzero(&mat, sizeof (mat));
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (void) acpidev_walk_apic(NULL, hdl, ACPIDEV_METHOD_NAME_MAT,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_query_MAT, &mat);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (mat.found) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *idp = mat.proc_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* Then evalute PROCESSOR object. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_info->Type == ACPI_TYPE_PROCESSOR) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_BUFFER rb;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rb.Pointer = NULL;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rb.Length = ACPI_ALLOCATE_BUFFER;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ACPI_SUCCESS(AcpiEvaluateObjectTyped(hdl, NULL, NULL, &rb,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_TYPE_PROCESSOR))) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *idp = ((ACPI_OBJECT *)rb.Pointer)->Processor.ProcId;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran AcpiOsFree(rb.Pointer);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_WARN,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: failed to evaluate ACPI object %s.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Finally, try to evalute the _UID method.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * According to the ACPI Spec3.0b, it's legal for ACPI PROCESSOR objects
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * to have ACPI method objects.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * The CPU _UID method should return Processor Id as an integer on x86.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ACPI_SUCCESS(acpica_eval_int(hdl, METHOD_NAME__UID, &id))) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *idp = id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_NOT_FOUND);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic ACPI_STATUS
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpidev_cpu_get_proximity_id(ACPI_HANDLE hdl, uint32_t apicid, uint32_t *pxmidp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int len, off;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPI_SUBTABLE_HEADER *sp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPI_SRAT_CPU_AFFINITY *xp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPI_SRAT_X2APIC_CPU_AFFINITY *x2p;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT(hdl != NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT(pxmidp != NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *pxmidp = UINT32_MAX;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ACPI_SUCCESS(acpidev_eval_pxm(hdl, pxmidp))) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (AE_OK);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (acpidev_srat_tbl_ptr == NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (AE_NOT_FOUND);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Search the static ACPI SRAT table for proximity domain id. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sp = (ACPI_SUBTABLE_HEADER *)(acpidev_srat_tbl_ptr + 1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu len = acpidev_srat_tbl_ptr->Header.Length;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu off = sizeof (*acpidev_srat_tbl_ptr);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu while (off < len) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (sp->Type) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case ACPI_SRAT_TYPE_CPU_AFFINITY:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu xp = (ACPI_SRAT_CPU_AFFINITY *)sp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((xp->Flags & ACPI_SRAT_CPU_ENABLED) &&
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu xp->ApicId == apicid) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *pxmidp = xp->ProximityDomainLo;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *pxmidp |= xp->ProximityDomainHi[0] << 8;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *pxmidp |= xp->ProximityDomainHi[1] << 16;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *pxmidp |= xp->ProximityDomainHi[2] << 24;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (AE_OK);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu x2p = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)sp;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((x2p->Flags & ACPI_SRAT_CPU_ENABLED) &&
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu x2p->ApicId == apicid) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *pxmidp = x2p->ProximityDomain;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (AE_OK);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu off += sp->Length;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sp = (ACPI_SUBTABLE_HEADER *)(((char *)sp) + sp->Length);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (AE_NOT_FOUND);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_pre_probe(acpidev_walk_info_t *infop)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t count = 0;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* Parse and cache APIC info in MADT on the first probe at boot time. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE &&
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map_hdl == NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Parse CPU relative information in the ACPI MADT table. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (void) acpidev_walk_apic(NULL, NULL, NULL,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_count_MADT, &acpidev_cpu_map_count);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map = kmem_zalloc(sizeof (acpidev_cpu_map[0])
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * acpidev_cpu_map_count, KM_SLEEP);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (void) acpidev_walk_apic(NULL, NULL, NULL,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_parse_MADT, &count);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(count == acpidev_cpu_map_count);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map_hdl = infop->awi_hdl;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Cache pointer to the ACPI SRAT table. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ACPI_FAILURE(AcpiGetTable(ACPI_SIG_SRAT, 1,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (ACPI_TABLE_HEADER **)&acpidev_srat_tbl_ptr))) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu acpidev_srat_tbl_ptr = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_post_probe(acpidev_walk_info_t *infop)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* Free cached APIC info on the second probe at boot time. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE &&
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map_hdl != NULL &&
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_hdl == acpidev_cpu_map_hdl) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (acpidev_cpu_map != NULL && acpidev_cpu_map_count != 0) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran kmem_free(acpidev_cpu_map, sizeof (acpidev_cpu_map[0])
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * acpidev_cpu_map_count);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map = NULL;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map_count = 0;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_map_hdl = NULL;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* replace psm_cpu_create_devinfo with local implementation. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran psm_cpu_create_devinfo_old = psm_cpu_create_devinfo;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu psm_cpu_create_devinfo = acpidev_cpu_create_dip;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu psm_cpu_get_devinfo_old = psm_cpu_get_devinfo;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu psm_cpu_get_devinfo = acpidev_cpu_get_dip;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_probe(acpidev_walk_info_t *infop)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_STATUS rc = AE_OK;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran int flags;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop->awi_hdl != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop->awi_info != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop->awi_class_curr == &acpidev_class_cpu);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_info->Type != ACPI_TYPE_PROCESSOR &&
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (infop->awi_info->Type != ACPI_TYPE_DEVICE ||
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_match_device_id(infop->awi_info,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_ARRAY_PARAM(acpidev_processor_device_ids)) == 0)) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu flags = ACPIDEV_PROCESS_FLAG_SCAN;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (infop->awi_op_type) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case ACPIDEV_OP_BOOT_PROBE:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Mark device as offline. It will be changed to online state
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * when the corresponding CPU starts up.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (acpica_get_devcfg_feature(ACPI_DEVCFG_CPU)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu flags |= ACPIDEV_PROCESS_FLAG_CREATE |
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_PROCESS_FLAG_OFFLINE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case ACPIDEV_OP_BOOT_REPROBE:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case ACPIDEV_OP_HOTPLUG_PROBE:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (acpica_get_devcfg_feature(ACPI_DEVCFG_CPU)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu flags |= ACPIDEV_PROCESS_FLAG_CREATE |
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_PROCESS_FLAG_OFFLINE |
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_PROCESS_FLAG_SYNCSTATUS |
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_PROCESS_FLAG_HOLDBRANCH;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu default:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_DEBUG(CE_WARN, "!acpidev: unknown operation type %u in "
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "acpidev_cpu_probe().", infop->awi_op_type);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rc = AE_BAD_PARAMETER;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (rc == AE_OK) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = acpidev_process_object(infop, flags);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ACPI_FAILURE(rc) && rc != AE_NOT_EXIST && rc != AE_ALREADY_EXISTS) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran cmn_err(CE_WARN,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "!acpidev: failed to process processor object %s.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran rc = AE_OK;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (rc);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic acpidev_filter_result_t
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_filter_func(acpidev_walk_info_t *infop, ACPI_HANDLE hdl,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_filter_rule_t *afrp, char *devname, int len)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_filter_result_t res;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(afrp != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE ||
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t procid;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t apicid;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (acpidev_cpu_get_procid(infop, &procid) != 0) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_WARN,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: failed to query processor id for %s.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (ACPIDEV_FILTER_SKIP);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else if (acpidev_cpu_get_apicid(procid, &apicid) != 0) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_WARN,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: failed to query apic id for %s.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (ACPIDEV_FILTER_SKIP);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_scratchpad[0] = procid;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_scratchpad[1] = apicid;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else if (infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran struct acpidev_cpu_MAT_arg mat;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran bzero(&mat, sizeof (mat));
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (void) acpidev_walk_apic(NULL, hdl, ACPIDEV_METHOD_NAME_MAT,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_cpu_query_MAT, &mat);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (!mat.found) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran cmn_err(CE_WARN,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "!acpidev: failed to walk apic resource for %s.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (ACPIDEV_FILTER_SKIP);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else if (!mat.enabled) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_NOTE,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: CPU %s has been disabled.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (ACPIDEV_FILTER_SKIP);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* Save processor id and APIC id in scratchpad memory. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_scratchpad[0] = mat.proc_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_scratchpad[1] = mat.apic_id;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran res = acpidev_filter_default(infop, hdl, afrp, devname, len);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (res);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic acpidev_filter_result_t
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_filter(acpidev_walk_info_t *infop, char *devname, int maxlen)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpidev_filter_result_t res;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(devname == NULL || maxlen >= ACPIDEV_MAX_NAMELEN);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE ||
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE ||
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran res = acpidev_filter_device(infop, infop->awi_hdl,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_ARRAY_PARAM(acpidev_cpu_filters), devname, maxlen);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran res = ACPIDEV_FILTER_FAILED;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (res);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic ACPI_STATUS
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranacpidev_cpu_init(acpidev_walk_info_t *infop)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran int count;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu uint32_t pxmid;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran dev_info_t *dip;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_HANDLE hdl;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran char unitaddr[64];
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran char **compatpp;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran static char *compatible[] = {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_HID_PROCESSOR,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_TYPE_CPU,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "cpu"
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran };
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(infop != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran dip = infop->awi_dip;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran hdl = infop->awi_hdl;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Create "apic_id", "processor_id" and "proximity_id" properties. */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_PROP_NAME_PROCESSOR_ID, infop->awi_scratchpad[0]) !=
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NDI_SUCCESS) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran cmn_err(CE_WARN,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "!acpidev: failed to set processor_id property for %s.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_ERROR);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_PROP_NAME_LOCALAPIC_ID, infop->awi_scratchpad[1]) !=
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran NDI_SUCCESS) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran cmn_err(CE_WARN,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "!acpidev: failed to set apic_id property for %s.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_ERROR);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ACPI_SUCCESS(acpidev_cpu_get_proximity_id(infop->awi_hdl,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu infop->awi_scratchpad[1], &pxmid))) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_PROP_NAME_PROXIMITY_ID, pxmid) != NDI_SUCCESS) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cmn_err(CE_WARN, "!acpidev: failed to set proximity id "
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "property for %s.", infop->awi_name);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (AE_ERROR);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /* Set "compatible" property for CPU dip */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran count = sizeof (compatible) / sizeof (compatible[0]);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_info->Type == ACPI_TYPE_PROCESSOR) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran compatpp = compatible;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else if (infop->awi_info->Type == ACPI_TYPE_DEVICE) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * skip first item for pseudo processor HID.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * acpidev_set_compatible() will handle HID/CID for CPU device.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran compatpp = &compatible[1];
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran count--;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_BAD_PARAMETER);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ACPI_FAILURE(acpidev_set_compatible(infop, compatpp, count))) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_ERROR);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Set device unit-address property.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * First try to generate meaningful unit address from _UID,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * then use Processor Id if that fails.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if ((infop->awi_info->Valid & ACPI_VALID_UID) == 0 ||
571909175b4f9a1ef15ec4afead6d6d463dbe760Dana Myers acpidev_generate_unitaddr(infop->awi_info->UniqueId.String,
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_ARRAY_PARAM(acpidev_cpu_uid_formats),
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran unitaddr, sizeof (unitaddr)) == NULL) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (void) snprintf(unitaddr, sizeof (unitaddr), "%u",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (uint32_t)infop->awi_scratchpad[0]);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ACPI_FAILURE(acpidev_set_unitaddr(infop, NULL, 0, unitaddr))) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_ERROR);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran /*
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran * Build binding information for CPUs.
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE ||
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE ||
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ACPI_FAILURE(acpica_add_processor_to_map(
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_scratchpad[0], hdl, infop->awi_scratchpad[1]))) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran cmn_err(CE_WARN, "!acpidev: failed to bind processor "
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran "id/object handle for %s.", infop->awi_name);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_ERROR);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPIDEV_DEBUG(CE_WARN,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: unknown operation type %u in acpidev_cpu_init.",
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran infop->awi_op_type);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_BAD_PARAMETER);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (AE_OK);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpidev_cpu_fini(ACPI_HANDLE hdl, acpidev_data_handle_t dhdl,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu acpidev_class_t *clsp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu _NOTE(ARGUNUSED(clsp, dhdl));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu uint32_t procid;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = acpica_get_procid_by_object(hdl, &procid);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT(ACPI_SUCCESS(rc));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ACPI_SUCCESS(rc)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = acpica_remove_processor_from_map(procid);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ASSERT(ACPI_SUCCESS(rc));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ACPI_FAILURE(rc)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cmn_err(CE_WARN, "!acpidev: failed to remove "
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "processor from ACPICA.");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Lookup the dip for a CPU if ACPI CPU autoconfig is enabled.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoranstatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpidev_cpu_lookup_dip(cpu_t *cp, dev_info_t **dipp)
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran{
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran uint32_t apicid;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ACPI_HANDLE hdl;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran dev_info_t *dip = NULL;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *dipp = NULL;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (acpica_get_devcfg_feature(ACPI_DEVCFG_CPU)) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran apicid = cpuid_get_apicid(cp);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (acpica_get_cpu_object_by_cpuid(cp->cpu_id, &hdl) == 0 ||
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran (apicid != UINT32_MAX &&
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran acpica_get_cpu_object_by_apicid(apicid, &hdl) == 0)) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(hdl != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (ACPI_SUCCESS(acpica_get_devinfo(hdl, &dip))) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran ASSERT(dip != NULL);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran *dipp = dip;
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (PSM_SUCCESS);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ACPIDEV_DEBUG(CE_WARN,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "!acpidev: failed to lookup dip for cpu %d(%p).",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu cp->cpu_id, (void *)cp);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (PSM_FAILURE);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpidev_cpu_create_dip(cpu_t *cp, dev_info_t **dipp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (acpidev_cpu_lookup_dip(cp, dipp) == PSM_SUCCESS) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu ndi_hold_devi(*dipp);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (PSM_SUCCESS);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran if (psm_cpu_create_devinfo_old != NULL) {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (psm_cpu_create_devinfo_old(cp, dipp));
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran } else {
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran return (PSM_FAILURE);
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran }
b72d5b75fd6f5bb08d29f65652d60058fc3a2608Michael Corcoran}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpidev_cpu_get_dip(cpu_t *cp, dev_info_t **dipp)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (acpidev_cpu_lookup_dip(cp, dipp) == PSM_SUCCESS) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (PSM_SUCCESS);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (psm_cpu_get_devinfo_old != NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (psm_cpu_get_devinfo_old(cp, dipp));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (PSM_FAILURE);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}