summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/io/mp_platform_common.c3
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c69
-rw-r--r--usr/src/uts/i86pc/os/mp_machdep.c99
-rw-r--r--usr/src/uts/i86pc/os/mp_startup.c3
-rw-r--r--usr/src/uts/i86pc/os/startup.c3
-rw-r--r--usr/src/uts/i86pc/sys/machsystm.h1
-rw-r--r--usr/src/uts/intel/io/acpica/acpica.c73
-rw-r--r--usr/src/uts/intel/io/acpica/osl.c672
-rw-r--r--usr/src/uts/intel/sys/acpica.h44
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h4
10 files changed, 750 insertions, 221 deletions
diff --git a/usr/src/uts/i86pc/io/mp_platform_common.c b/usr/src/uts/i86pc/io/mp_platform_common.c
index 3a7877ec47..f92619ccd2 100644
--- a/usr/src/uts/i86pc/io/mp_platform_common.c
+++ b/usr/src/uts/i86pc/io/mp_platform_common.c
@@ -909,6 +909,9 @@ acpi_probe(char *modname)
if (apic_acpi_enter_apicmode() != PSM_FAILURE) {
build_reserved_irqlist((uchar_t *)apic_reserved_irqlist);
apic_enable_acpi = 1;
+ if (apic_sci_vect > 0) {
+ acpica_set_core_feature(ACPI_FEATURE_SCI_EVENT);
+ }
if (apic_use_acpi_madt_only) {
cmn_err(CE_CONT,
"?Using ACPI for CPU/IOAPIC information ONLY\n");
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index b87c5f9887..8bb00a1018 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -2535,6 +2535,17 @@ cpuid_get_clogid(cpu_t *cpu)
return (cpu->cpu_m.mcpu_cpi->cpi_clogid);
}
+uint32_t
+cpuid_get_apicid(cpu_t *cpu)
+{
+ ASSERT(cpuid_checkpass(cpu, 1));
+ if (cpu->cpu_m.mcpu_cpi->cpi_maxeax < 1) {
+ return (UINT32_MAX);
+ } else {
+ return (cpu->cpu_m.mcpu_cpi->cpi_apicid);
+ }
+}
+
void
cpuid_get_addrsize(cpu_t *cpu, uint_t *pabits, uint_t *vabits)
{
@@ -3466,84 +3477,43 @@ x86_which_cacheinfo(struct cpuid_info *cpi)
return (-1);
}
-/*
- * create a node for the given cpu under the prom root node.
- * Also, create a cpu node in the device tree.
- */
-static dev_info_t *cpu_nex_devi = NULL;
-static kmutex_t cpu_node_lock;
-
-/*
- * Called from post_startup() and mp_startup()
- */
void
-add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
+cpuid_set_cpu_properties(void *dip, processorid_t cpu_id,
+ struct cpuid_info *cpi)
{
dev_info_t *cpu_devi;
int create;
- mutex_enter(&cpu_node_lock);
-
- /*
- * create a nexus node for all cpus identified as 'cpu_id' under
- * the root node.
- */
- if (cpu_nex_devi == NULL) {
- if (ndi_devi_alloc(ddi_root_node(), "cpus",
- (pnode_t)DEVI_SID_NODEID, &cpu_nex_devi) != NDI_SUCCESS) {
- mutex_exit(&cpu_node_lock);
- return;
- }
- (void) ndi_devi_online(cpu_nex_devi, 0);
- }
-
- /*
- * create a child node for cpu identified as 'cpu_id'
- */
- cpu_devi = ddi_add_child(cpu_nex_devi, "cpu", DEVI_SID_NODEID,
- cpu_id);
- if (cpu_devi == NULL) {
- mutex_exit(&cpu_node_lock);
- return;
- }
+ cpu_devi = (dev_info_t *)dip;
/* device_type */
-
(void) ndi_prop_update_string(DDI_DEV_T_NONE, cpu_devi,
"device_type", "cpu");
/* reg */
-
(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
"reg", cpu_id);
/* cpu-mhz, and clock-frequency */
-
if (cpu_freq > 0) {
long long mul;
(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
"cpu-mhz", cpu_freq);
-
if ((mul = cpu_freq * 1000000LL) <= INT_MAX)
(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
"clock-frequency", (int)mul);
}
- (void) ndi_devi_online(cpu_devi, 0);
-
if ((x86_feature & X86_CPUID) == 0) {
- mutex_exit(&cpu_node_lock);
return;
}
/* vendor-id */
-
(void) ndi_prop_update_string(DDI_DEV_T_NONE, cpu_devi,
"vendor-id", cpi->cpi_vendorstr);
if (cpi->cpi_maxeax == 0) {
- mutex_exit(&cpu_node_lock);
return;
}
@@ -3558,7 +3528,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
"stepping-id", CPI_STEP(cpi));
/* type */
-
switch (cpi->cpi_vendor) {
case X86_VENDOR_Intel:
create = 1;
@@ -3572,7 +3541,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
"type", CPI_TYPE(cpi));
/* ext-family */
-
switch (cpi->cpi_vendor) {
case X86_VENDOR_Intel:
case X86_VENDOR_AMD:
@@ -3587,7 +3555,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
"ext-family", CPI_FAMILY_XTD(cpi));
/* ext-model */
-
switch (cpi->cpi_vendor) {
case X86_VENDOR_Intel:
create = IS_EXTENDED_MODEL_INTEL(cpi);
@@ -3604,7 +3571,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
"ext-model", CPI_MODEL_XTD(cpi));
/* generation */
-
switch (cpi->cpi_vendor) {
case X86_VENDOR_AMD:
/*
@@ -3621,7 +3587,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
"generation", BITX((cpi)->cpi_extd[1].cp_eax, 11, 8));
/* brand-id */
-
switch (cpi->cpi_vendor) {
case X86_VENDOR_Intel:
/*
@@ -3644,7 +3609,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
}
/* chunks, and apic-id */
-
switch (cpi->cpi_vendor) {
/*
* first available on Pentium IV and Opteron (K8)
@@ -3673,13 +3637,11 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
}
/* cpuid-features */
-
(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
"cpuid-features", CPI_FEATURES_EDX(cpi));
/* cpuid-features-ecx */
-
switch (cpi->cpi_vendor) {
case X86_VENDOR_Intel:
create = IS_NEW_F6(cpi) || cpi->cpi_family >= 0xf;
@@ -3693,7 +3655,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
"cpuid-features-ecx", CPI_FEATURES_ECX(cpi));
/* ext-cpuid-features */
-
switch (cpi->cpi_vendor) {
case X86_VENDOR_Intel:
case X86_VENDOR_AMD:
@@ -3738,8 +3699,6 @@ add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
default:
break;
}
-
- mutex_exit(&cpu_node_lock);
}
struct l2info {
diff --git a/usr/src/uts/i86pc/os/mp_machdep.c b/usr/src/uts/i86pc/os/mp_machdep.c
index 6c9cc3aec3..250c686c5d 100644
--- a/usr/src/uts/i86pc/os/mp_machdep.c
+++ b/usr/src/uts/i86pc/os/mp_machdep.c
@@ -22,6 +22,10 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2009, Intel Corporation.
+ * All rights reserved.
+ */
#define PSMI_1_6
#include <sys/smp_impldefs.h>
@@ -55,6 +59,8 @@
#include <sys/kdi_machimpl.h>
#include <sys/sdt.h>
#include <sys/hpet.h>
+#include <sys/sunddi.h>
+#include <sys/sunndi.h>
#define OFFSETOF(s, m) (size_t)(&(((s *)0)->m))
@@ -85,6 +91,8 @@ static void cpu_wakeup(cpu_t *, int);
void cpu_idle_mwait(void);
static void cpu_wakeup_mwait(cpu_t *, int);
#endif
+static int mach_cpu_create_devinfo(cpu_t *cp, dev_info_t **dipp);
+
/*
* External reference functions
*/
@@ -144,6 +152,8 @@ int (*psm_state)(psm_state_request_t *) = (int (*)(psm_state_request_t *))
void (*notify_error)(int, char *) = (void (*)(int, char *))return_instr;
void (*hrtime_tick)(void) = return_instr;
+int (*psm_cpu_create_devinfo)(cpu_t *, dev_info_t **) = mach_cpu_create_devinfo;
+
/*
* True if the generic TSC code is our source of hrtime, rather than whatever
* the PSM can provide.
@@ -1459,6 +1469,95 @@ mach_cpuid_start(processorid_t id, void *ctx)
return ((*pops->psm_cpu_start)(id, ctx));
}
+/*
+ * Default handler to create device node for CPU.
+ * One reference count will be held on created device node.
+ */
+static int
+mach_cpu_create_devinfo(cpu_t *cp, dev_info_t **dipp)
+{
+ int rv, circ;
+ dev_info_t *dip;
+ static kmutex_t cpu_node_lock;
+ static dev_info_t *cpu_nex_devi = NULL;
+
+ ASSERT(cp != NULL);
+ ASSERT(dipp != NULL);
+ *dipp = NULL;
+
+ if (cpu_nex_devi == NULL) {
+ mutex_enter(&cpu_node_lock);
+ /* First check whether cpus exists. */
+ cpu_nex_devi = ddi_find_devinfo("cpus", -1, 0);
+ /* Create cpus if it doesn't exist. */
+ if (cpu_nex_devi == NULL) {
+ ndi_devi_enter(ddi_root_node(), &circ);
+ rv = ndi_devi_alloc(ddi_root_node(), "cpus",
+ (pnode_t)DEVI_SID_NODEID, &dip);
+ if (rv != NDI_SUCCESS) {
+ mutex_exit(&cpu_node_lock);
+ cmn_err(CE_CONT,
+ "?failed to create cpu nexus device.\n");
+ return (PSM_FAILURE);
+ }
+ ASSERT(dip != NULL);
+ (void) ndi_devi_online(dip, 0);
+ ndi_devi_exit(ddi_root_node(), circ);
+ cpu_nex_devi = dip;
+ }
+ mutex_exit(&cpu_node_lock);
+ }
+
+ /*
+ * create a child node for cpu identified as 'cpu_id'
+ */
+ ndi_devi_enter(cpu_nex_devi, &circ);
+ dip = ddi_add_child(cpu_nex_devi, "cpu", DEVI_SID_NODEID, cp->cpu_id);
+ if (dip == NULL) {
+ cmn_err(CE_CONT,
+ "?failed to create device node for cpu%d.\n", cp->cpu_id);
+ rv = PSM_FAILURE;
+ } else {
+ *dipp = dip;
+ (void) ndi_hold_devi(dip);
+ rv = PSM_SUCCESS;
+ }
+ ndi_devi_exit(cpu_nex_devi, circ);
+
+ return (rv);
+}
+
+/*
+ * Create cpu device node in device tree and online it.
+ * Return created dip with reference count held if requested.
+ */
+int
+mach_cpu_create_device_node(struct cpu *cp, dev_info_t **dipp)
+{
+ int rv;
+ dev_info_t *dip = NULL;
+
+ ASSERT(psm_cpu_create_devinfo != NULL);
+ rv = psm_cpu_create_devinfo(cp, &dip);
+ if (rv == PSM_SUCCESS) {
+ cpuid_set_cpu_properties(dip, cp->cpu_id, cp->cpu_m.mcpu_cpi);
+ /* Recursively attach driver for parent nexus device. */
+ if (i_ddi_attach_node_hierarchy(ddi_get_parent(dip)) ==
+ DDI_SUCCESS) {
+ /* Configure cpu itself and descendants. */
+ (void) ndi_devi_online(dip,
+ NDI_ONLINE_ATTACH | NDI_CONFIG);
+ }
+ if (dipp != NULL) {
+ *dipp = dip;
+ } else {
+ (void) ndi_rele_devi(dip);
+ }
+ }
+
+ return (rv);
+}
+
/*ARGSUSED*/
static int
mach_translate_irq(dev_info_t *dip, int irqno)
diff --git a/usr/src/uts/i86pc/os/mp_startup.c b/usr/src/uts/i86pc/os/mp_startup.c
index 683f8942e4..c03eb141cb 100644
--- a/usr/src/uts/i86pc/os/mp_startup.c
+++ b/usr/src/uts/i86pc/os/mp_startup.c
@@ -1607,7 +1607,6 @@ mp_startup(void)
#ifndef __xpv
cpupm_init(cp);
#endif
- add_cpunode2devtree(cp->cpu_id, cp->cpu_m.mcpu_cpi);
/*
* Processor group initialization for this CPU is dependent on the
@@ -1665,6 +1664,8 @@ mp_startup(void)
cmn_err(CE_CONT, "!cpu%d initialization complete - online\n",
cp->cpu_id);
+ (void) mach_cpu_create_device_node(cp, NULL);
+
/*
* Now we are done with the startup thread, so free it up.
*/
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c
index ef6b28fdbc..e640283a23 100644
--- a/usr/src/uts/i86pc/os/startup.c
+++ b/usr/src/uts/i86pc/os/startup.c
@@ -2193,8 +2193,7 @@ post_startup(void)
cpu_event_init_cpu(CPU);
cpupm_init(CPU);
-
- add_cpunode2devtree(CPU->cpu_id, CPU->cpu_m.mcpu_cpi);
+ (void) mach_cpu_create_device_node(CPU, NULL);
pg_init();
}
diff --git a/usr/src/uts/i86pc/sys/machsystm.h b/usr/src/uts/i86pc/sys/machsystm.h
index 928f0b0d12..b98a48326e 100644
--- a/usr/src/uts/i86pc/sys/machsystm.h
+++ b/usr/src/uts/i86pc/sys/machsystm.h
@@ -55,6 +55,7 @@ extern void mach_cpu_idle(void);
extern void mach_cpu_halt(char *);
extern int mach_cpu_start(cpu_t *, void *);
extern int mach_cpuid_start(processorid_t, void *);
+extern int mach_cpu_create_device_node(cpu_t *, dev_info_t **);
extern int Cpudelay;
extern void setcpudelay(void);
diff --git a/usr/src/uts/intel/io/acpica/acpica.c b/usr/src/uts/intel/io/acpica/acpica.c
index 7ac54fb936..d7a830a3c0 100644
--- a/usr/src/uts/intel/io/acpica/acpica.c
+++ b/usr/src/uts/intel/io/acpica/acpica.c
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
/*
+ * Copyright (c) 2009, Intel Corporation.
+ * All rights reserved.
+ */
+/*
* Solaris x86 ACPI CA services
*/
@@ -208,7 +212,8 @@ acpica_check_bios_date(int yy, int mm, int dd)
int bios_year, bios_month, bios_day;
/* If firmware has no bios, skip the check */
- if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), 0, "bios-free"))
+ if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS,
+ "bios-free"))
return (TRUE);
/*
@@ -321,8 +326,8 @@ acpica_process_user_options()
/*
* fetch the optional options property
*/
- acpi_user_options = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(), 0,
- "acpi-user-options", 0);
+ acpi_user_options = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(),
+ DDI_PROP_DONTPASS, "acpi-user-options", 0);
/*
* Note that 'off' has precedence over 'on'
@@ -388,40 +393,40 @@ acpica_init()
return (AE_ERROR);
mutex_enter(&acpica_module_lock);
+ if (acpica_init_state == ACPICA_INITIALIZED) {
+ mutex_exit(&acpica_module_lock);
+ return (AE_OK);
+ }
+
+ if (ACPI_FAILURE(status = AcpiLoadTables()))
+ goto error;
- if (acpica_init_state == ACPICA_NOT_INITIALIZED) {
- if (ACPI_FAILURE(status = AcpiLoadTables()))
- goto error;
+ if (ACPI_FAILURE(status = acpica_install_handlers()))
+ goto error;
- if (ACPI_FAILURE(status = acpica_install_handlers()))
- goto error;
+ if (ACPI_FAILURE(status = AcpiEnableSubsystem(acpi_init_level)))
+ goto error;
- if (ACPI_FAILURE(status = AcpiEnableSubsystem(
- acpi_init_level)))
- goto error;
+ /* do after AcpiEnableSubsystem() so GPEs are initialized */
+ acpica_ec_init(); /* initialize EC if present */
- /* do after AcpiEnableSubsystem() so GPEs are initialized */
- acpica_ec_init(); /* initialize EC if present */
+ if (ACPI_FAILURE(status = AcpiInitializeObjects(0)))
+ goto error;
- if (ACPI_FAILURE(status = AcpiInitializeObjects(0)))
- goto error;
+ acpica_init_state = ACPICA_INITIALIZED;
- acpica_init_state = ACPICA_INITIALIZED;
- /*
- * If we are running on the Xen hypervisor as dom0 we need to
- * find the ioapics so we can prevent ACPI from trying to
- * access them.
- */
- if (get_hwenv() == HW_XEN_PV && is_controldom())
- acpica_find_ioapics();
- acpica_init_kstats();
+ /*
+ * If we are running on the Xen hypervisor as dom0 we need to
+ * find the ioapics so we can prevent ACPI from trying to
+ * access them.
+ */
+ if (get_hwenv() == HW_XEN_PV && is_controldom())
+ acpica_find_ioapics();
+ acpica_init_kstats();
error:
- if (acpica_init_state != ACPICA_INITIALIZED) {
- cmn_err(CE_NOTE, "!failed to initialize"
- " ACPI services");
- }
- } else
- status = AE_OK;
+ if (acpica_init_state != ACPICA_INITIALIZED) {
+ cmn_err(CE_NOTE, "!failed to initialize ACPI services");
+ }
/*
* Set acpi-status to 13 if acpica has been initialized successfully.
@@ -429,9 +434,15 @@ error:
* and value were chosen in order to remain compatible with acpi_intp.
*/
e_ddi_prop_update_int(DDI_DEV_T_NONE, ddi_root_node(), "acpi-status",
- (status == AE_OK) ? (ACPI_BOOT_INIT | ACPI_BOOT_ENABLE |
+ (ACPI_SUCCESS(status)) ? (ACPI_BOOT_INIT | ACPI_BOOT_ENABLE |
ACPI_BOOT_BOOTCONF) : 0);
+ /* Mark acpica subsystem as fully initialized. */
+ if (ACPI_SUCCESS(status) &&
+ acpi_init_level == ACPI_FULL_INITIALIZATION) {
+ acpica_set_core_feature(ACPI_FEATURE_FULL_INIT);
+ }
+
mutex_exit(&acpica_module_lock);
return (status);
}
diff --git a/usr/src/uts/intel/io/acpica/osl.c b/usr/src/uts/intel/io/acpica/osl.c
index ce8f40aaa3..33e06d0724 100644
--- a/usr/src/uts/intel/io/acpica/osl.c
+++ b/usr/src/uts/intel/io/acpica/osl.c
@@ -24,6 +24,10 @@
* Use is subject to license terms.
*/
/*
+ * Copyright (c) 2009, Intel Corporation.
+ * All rights reserved.
+ */
+/*
* ACPI CA OSL for Solaris x86
*/
@@ -52,12 +56,12 @@ static int CompressEisaID(char *np);
static void scan_d2a_map(void);
static void scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus);
-static void acpica_tag_devinfo(dev_info_t *dip, ACPI_HANDLE acpiobj);
static int acpica_query_bbn_problem(void);
static int acpica_find_pcibus(int busno, ACPI_HANDLE *rh);
static int acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint);
static ACPI_STATUS acpica_set_devinfo(ACPI_HANDLE, dev_info_t *);
+static ACPI_STATUS acpica_unset_devinfo(ACPI_HANDLE);
static void acpica_devinfo_handler(ACPI_HANDLE, UINT32, void *);
/*
@@ -94,16 +98,24 @@ static char *acpi_table_path = "/boot/acpi/tables/";
static int scanning_d2a_map = 0;
static int d2a_done = 0;
+/* features supported by ACPICA and ACPI device configuration. */
+uint64_t acpica_core_features = 0;
+static uint64_t acpica_devcfg_features = 0;
+
/* set by acpi_poweroff() in PSMs and appm_ioctl() in acpippm for S3 */
int acpica_use_safe_delay = 0;
/* CPU mapping data */
struct cpu_map_item {
+ processorid_t cpu_id;
UINT32 proc_id;
+ UINT32 apic_id;
ACPI_HANDLE obj;
};
+static kmutex_t cpu_map_lock;
static struct cpu_map_item **cpu_map = NULL;
+static int cpu_map_count_max = 0;
static int cpu_map_count = 0;
static int cpu_map_built = 0;
@@ -1058,10 +1070,36 @@ AcpiOsGetTimer(void)
return ((gethrtime() + 50) / 100);
}
+static struct AcpiOSIFeature_s {
+ uint64_t control_flag;
+ const char *feature_name;
+} AcpiOSIFeatures[] = {
+ { ACPI_FEATURE_OSI_MODULE, "Module Device" },
+ { 0, "Processor Device" }
+};
+
/*ARGSUSED*/
ACPI_STATUS
-AcpiOsValidateInterface(char *interface)
+AcpiOsValidateInterface(char *feature)
{
+ int i;
+
+ ASSERT(feature != NULL);
+ for (i = 0; i < sizeof (AcpiOSIFeatures) / sizeof (AcpiOSIFeatures[0]);
+ i++) {
+ if (strcmp(feature, AcpiOSIFeatures[i].feature_name) != 0) {
+ continue;
+ }
+ /* Check whether required core features are available. */
+ if (AcpiOSIFeatures[i].control_flag != 0 &&
+ acpica_get_core_feature(AcpiOSIFeatures[i].control_flag) !=
+ AcpiOSIFeatures[i].control_flag) {
+ break;
+ }
+ /* Feature supported. */
+ return (AE_OK);
+ }
+
return (AE_SUPPORT);
}
@@ -1184,62 +1222,126 @@ AcpiOsGetLine(char *Buffer)
return (0);
}
-
-
-
/*
* Device tree binding
*/
+static ACPI_STATUS
+acpica_find_pcibus_walker(ACPI_HANDLE hdl, UINT32 lvl, void *ctxp, void **rvpp)
+{
+ _NOTE(ARGUNUSED(lvl));
+
+ int sta, hid, bbn;
+ int busno = (intptr_t)ctxp;
+ ACPI_HANDLE *hdlp = (ACPI_HANDLE *)rvpp;
+
+ /* Check whether device exists. */
+ if (ACPI_SUCCESS(acpica_eval_int(hdl, "_STA", &sta)) &&
+ !(sta & (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_FUNCTIONING))) {
+ /*
+ * Skip object if device doesn't exist.
+ * According to ACPI Spec,
+ * 1) setting either bit 0 or bit 3 means that device exists.
+ * 2) Absence of _STA method means all status bits set.
+ */
+ return (AE_CTRL_DEPTH);
+ }
+
+ if (ACPI_FAILURE(acpica_eval_hid(hdl, "_HID", &hid)) ||
+ (hid != HID_PCI_BUS && hid != HID_PCI_EXPRESS_BUS)) {
+ /* Non PCI/PCIe host bridge. */
+ return (AE_OK);
+ }
+
+ if (acpi_has_broken_bbn) {
+ ACPI_BUFFER rb;
+ rb.Pointer = NULL;
+ rb.Length = ACPI_ALLOCATE_BUFFER;
+
+ /* Decree _BBN == n from PCI<n> */
+ if (AcpiGetName(hdl, ACPI_SINGLE_NAME, &rb) != AE_OK) {
+ return (AE_CTRL_TERMINATE);
+ }
+ bbn = ((char *)rb.Pointer)[3] - '0';
+ AcpiOsFree(rb.Pointer);
+ if (bbn == busno || busno == 0) {
+ *hdlp = hdl;
+ return (AE_CTRL_TERMINATE);
+ }
+ } else if (ACPI_SUCCESS(acpica_eval_int(hdl, "_BBN", &bbn))) {
+ if (bbn == busno) {
+ *hdlp = hdl;
+ return (AE_CTRL_TERMINATE);
+ }
+ } else if (busno == 0) {
+ *hdlp = hdl;
+ return (AE_CTRL_TERMINATE);
+ }
+
+ return (AE_CTRL_DEPTH);
+}
static int
acpica_find_pcibus(int busno, ACPI_HANDLE *rh)
{
ACPI_HANDLE sbobj, busobj;
- int hid, bbn;
/* initialize static flag by querying ACPI namespace for bug */
if (acpi_has_broken_bbn == -1)
acpi_has_broken_bbn = acpica_query_bbn_problem();
- busobj = NULL;
- AcpiGetHandle(NULL, "\\_SB", &sbobj);
- while (AcpiGetNextObject(ACPI_TYPE_DEVICE, sbobj, busobj,
- &busobj) == AE_OK) {
- if (acpica_eval_hid(busobj, "_HID", &hid) == AE_OK &&
- (hid == HID_PCI_BUS || hid == HID_PCI_EXPRESS_BUS)) {
- if (acpi_has_broken_bbn) {
- ACPI_BUFFER rb;
- rb.Pointer = NULL;
- rb.Length = ACPI_ALLOCATE_BUFFER;
-
- /* Decree _BBN == n from PCI<n> */
- if (AcpiGetName(busobj, ACPI_SINGLE_NAME, &rb)
- != AE_OK) {
- return (AE_ERROR);
- }
- bbn = ((char *)rb.Pointer)[3] - '0';
- AcpiOsFree(rb.Pointer);
- if (bbn == busno || busno == 0) {
- *rh = busobj;
- return (AE_OK);
- }
- } else {
- if (acpica_eval_int(busobj, "_BBN", &bbn) ==
- AE_OK) {
- if (bbn == busno) {
- *rh = busobj;
- return (AE_OK);
- }
- } else if (busno == 0) {
- *rh = busobj;
- return (AE_OK);
- }
- }
+ if (ACPI_SUCCESS(AcpiGetHandle(NULL, "\\_SB", &sbobj))) {
+ busobj = NULL;
+ (void) AcpiWalkNamespace(ACPI_TYPE_DEVICE, sbobj, UINT32_MAX,
+ acpica_find_pcibus_walker, (void *)(intptr_t)busno,
+ (void **)&busobj);
+ if (busobj != NULL) {
+ *rh = busobj;
+ return (AE_OK);
}
}
+
return (AE_ERROR);
}
+static ACPI_STATUS
+acpica_query_bbn_walker(ACPI_HANDLE hdl, UINT32 lvl, void *ctxp, void **rvpp)
+{
+ _NOTE(ARGUNUSED(lvl));
+ _NOTE(ARGUNUSED(rvpp));
+
+ int sta, hid, bbn;
+ int *cntp = (int *)ctxp;
+
+ /* Check whether device exists. */
+ if (ACPI_SUCCESS(acpica_eval_int(hdl, "_STA", &sta)) &&
+ !(sta & (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_FUNCTIONING))) {
+ /*
+ * Skip object if device doesn't exist.
+ * According to ACPI Spec,
+ * 1) setting either bit 0 or bit 3 means that device exists.
+ * 2) Absence of _STA method means all status bits set.
+ */
+ return (AE_CTRL_DEPTH);
+ }
+
+ if (ACPI_FAILURE(acpica_eval_hid(hdl, "_HID", &hid)) ||
+ (hid != HID_PCI_BUS && hid != HID_PCI_EXPRESS_BUS)) {
+ /* Non PCI/PCIe host bridge. */
+ return (AE_OK);
+ } else if (ACPI_SUCCESS(acpica_eval_int(hdl, "_BBN", &bbn)) &&
+ bbn == 0 && ++(*cntp) > 1) {
+ /*
+ * If we find more than one bus with a 0 _BBN
+ * we have the problem that BigBear's BIOS shows
+ */
+ return (AE_CTRL_TERMINATE);
+ } else {
+ /*
+ * Skip children of PCI/PCIe host bridge.
+ */
+ return (AE_CTRL_DEPTH);
+ }
+}
/*
* Look for ACPI problem where _BBN is zero for multiple PCI buses
@@ -1249,31 +1351,17 @@ acpica_find_pcibus(int busno, ACPI_HANDLE *rh)
static int
acpica_query_bbn_problem(void)
{
- ACPI_HANDLE sbobj, busobj;
- int hid, bbn;
+ ACPI_HANDLE sbobj;
int zerobbncnt;
+ void *rv;
- busobj = NULL;
zerobbncnt = 0;
-
- AcpiGetHandle(NULL, "\\_SB", &sbobj);
-
- while (AcpiGetNextObject(ACPI_TYPE_DEVICE, sbobj, busobj,
- &busobj) == AE_OK) {
- if ((acpica_eval_hid(busobj, "_HID", &hid) == AE_OK) &&
- (hid == HID_PCI_BUS || hid == HID_PCI_EXPRESS_BUS) &&
- (acpica_eval_int(busobj, "_BBN", &bbn) == AE_OK)) {
- if (bbn == 0) {
- /*
- * If we find more than one bus with a 0 _BBN
- * we have the problem that BigBear's BIOS shows
- */
- if (++zerobbncnt > 1)
- return (1);
- }
- }
+ if (ACPI_SUCCESS(AcpiGetHandle(NULL, "\\_SB", &sbobj))) {
+ (void) AcpiWalkNamespace(ACPI_TYPE_DEVICE, sbobj, UINT32_MAX,
+ acpica_query_bbn_walker, &zerobbncnt, &rv);
}
- return (0);
+
+ return (zerobbncnt > 1 ? 1 : 0);
}
static const char hextab[] = "0123456789ABCDEF";
@@ -1381,61 +1469,45 @@ acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint)
/*
* Create linkage between devinfo nodes and ACPI nodes
*/
-static void
+ACPI_STATUS
acpica_tag_devinfo(dev_info_t *dip, ACPI_HANDLE acpiobj)
{
ACPI_STATUS status;
ACPI_BUFFER rb;
/*
- * Tag the ACPI node with the dip
- */
- status = acpica_set_devinfo(acpiobj, dip);
- ASSERT(status == AE_OK);
-
- /*
* Tag the devinfo node with the ACPI name
*/
rb.Pointer = NULL;
rb.Length = ACPI_ALLOCATE_BUFFER;
- if (AcpiGetName(acpiobj, ACPI_FULL_PATHNAME, &rb) == AE_OK) {
+ status = AcpiGetName(acpiobj, ACPI_FULL_PATHNAME, &rb);
+ if (ACPI_FAILURE(status)) {
+ cmn_err(CE_WARN, "acpica: could not get ACPI path!");
+ } else {
(void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
"acpi-namespace", (char *)rb.Pointer);
AcpiOsFree(rb.Pointer);
- } else {
- cmn_err(CE_WARN, "acpica: could not get ACPI path!");
- }
-}
-
-static void
-acpica_add_processor_to_map(UINT32 acpi_id, ACPI_HANDLE obj)
-{
- int cpu_id;
- /*
- * Special case: if we're a uppc system, there won't be
- * a CPU map yet. So we create one and use the passed-in
- * processor as CPU 0
- */
- if (cpu_map == NULL) {
- cpu_map = kmem_zalloc(sizeof (cpu_map[0]) * NCPU, KM_SLEEP);
- cpu_map[0] = kmem_zalloc(sizeof (*cpu_map[0]), KM_SLEEP);
- cpu_map[0]->obj = obj;
- cpu_map_count = 1;
- return;
+ /*
+ * Tag the ACPI node with the dip
+ */
+ status = acpica_set_devinfo(acpiobj, dip);
+ ASSERT(ACPI_SUCCESS(status));
}
- for (cpu_id = 0; cpu_id < NCPU; cpu_id++) {
- if (cpu_map[cpu_id] == NULL)
- continue;
+ return (status);
+}
- if (cpu_map[cpu_id]->proc_id == acpi_id) {
- if (cpu_map[cpu_id]->obj == NULL)
- cpu_map[cpu_id]->obj = obj;
- break;
- }
- }
+/*
+ * Destroy linkage between devinfo nodes and ACPI nodes
+ */
+ACPI_STATUS
+acpica_untag_devinfo(dev_info_t *dip, ACPI_HANDLE acpiobj)
+{
+ (void) acpica_unset_devinfo(acpiobj);
+ (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "acpi-namespace");
+ return (AE_OK);
}
/*
@@ -1444,6 +1516,8 @@ acpica_add_processor_to_map(UINT32 acpi_id, ACPI_HANDLE obj)
ACPI_STATUS
acpica_get_handle_cpu(int cpu_id, ACPI_HANDLE *rh)
{
+ int i;
+
/*
* if cpu_map itself is NULL, we're a uppc system and
* acpica_build_processor_map() hasn't been called yet.
@@ -1455,11 +1529,26 @@ acpica_get_handle_cpu(int cpu_id, ACPI_HANDLE *rh)
return (AE_ERROR);
}
- if ((cpu_id < 0) || (cpu_map[cpu_id] == NULL) ||
- (cpu_map[cpu_id]->obj == NULL))
+ if (cpu_id < 0) {
return (AE_ERROR);
+ }
+ /*
+ * search object with cpuid in cpu_map
+ */
+ mutex_enter(&cpu_map_lock);
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->cpu_id == cpu_id) {
+ break;
+ }
+ }
+ if (i >= cpu_map_count || (cpu_map[i]->obj == NULL)) {
+ mutex_exit(&cpu_map_lock);
+ return (AE_ERROR);
+ }
*rh = cpu_map[cpu_id]->obj;
+ mutex_exit(&cpu_map_lock);
+
return (AE_OK);
}
@@ -1512,12 +1601,11 @@ acpica_probe_processor(ACPI_HANDLE obj, UINT32 level, void *ctx, void **rv)
}
AcpiOsFree(rb.Pointer);
}
+ (void) acpica_add_processor_to_map(acpi_id, obj, UINT32_MAX);
- acpica_add_processor_to_map(acpi_id, obj);
return (AE_OK);
}
-
static void
scan_d2a_map(void)
{
@@ -1543,7 +1631,8 @@ scan_d2a_map(void)
dip = ddi_get_next_sibling(dip)) {
/* prune non-PCI nodes */
- if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
+ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
+ DDI_PROP_DONTPASS,
"device_type", &device_type_prop) != DDI_PROP_SUCCESS)
continue;
@@ -1632,9 +1721,9 @@ scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus)
acpica_tag_devinfo(dcld, acld);
/* if we find a bridge, recurse from here */
- if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dcld, 0,
- "device_type", &device_type_prop) ==
- DDI_PROP_SUCCESS) {
+ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dcld,
+ DDI_PROP_DONTPASS, "device_type",
+ &device_type_prop) == DDI_PROP_SUCCESS) {
if ((strcmp("pci", device_type_prop) == 0) ||
(strcmp("pciex", device_type_prop) == 0))
scan_d2a_subtree(dcld, acld, bus);
@@ -1731,37 +1820,26 @@ acpica_set_devinfo(ACPI_HANDLE obj, dev_info_t *dip)
return (status);
}
-
/*
- *
+ * Unset the dev_info_t associated with the ACPI node.
*/
-void
-acpica_devinfo_handler(ACPI_HANDLE obj, UINT32 func, void *data)
+static ACPI_STATUS
+acpica_unset_devinfo(ACPI_HANDLE obj)
{
- /* noop */
+ return (AcpiDetachData(obj, acpica_devinfo_handler));
}
-
/*
*
*/
void
-acpica_map_cpu(processorid_t cpuid, UINT32 proc_id)
+acpica_devinfo_handler(ACPI_HANDLE obj, UINT32 func, void *data)
{
- struct cpu_map_item *item;
-
- if (cpu_map == NULL)
- cpu_map = kmem_zalloc(sizeof (item) * NCPU, KM_SLEEP);
-
- item = kmem_zalloc(sizeof (*item), KM_SLEEP);
- item->proc_id = proc_id;
- item->obj = NULL;
- cpu_map[cpuid] = item;
- cpu_map_count++;
+ /* noop */
}
-void
-acpica_build_processor_map()
+ACPI_STATUS
+acpica_build_processor_map(void)
{
ACPI_STATUS status;
void *rv;
@@ -1770,7 +1848,16 @@ acpica_build_processor_map()
* shouldn't be called more than once anyway
*/
if (cpu_map_built)
- return;
+ return (AE_OK);
+
+ /*
+ * ACPI device configuration driver has built mapping information
+ * among processor id and object handle, no need to probe again.
+ */
+ if (acpica_get_devcfg_feature(ACPI_DEVCFG_CPU)) {
+ cpu_map_built = 1;
+ return (AE_OK);
+ }
/*
* Look for Processor objects
@@ -1792,6 +1879,339 @@ acpica_build_processor_map()
&rv);
ASSERT(status == AE_OK);
cpu_map_built = 1;
+
+ return (status);
+}
+
+/*
+ * Grow cpu map table on demand.
+ */
+static void
+acpica_grow_cpu_map(void)
+{
+ if (cpu_map_count == cpu_map_count_max) {
+ size_t sz;
+ struct cpu_map_item **new_map;
+
+ ASSERT(cpu_map_count_max < INT_MAX / 2);
+ cpu_map_count_max += max_ncpus;
+ new_map = kmem_zalloc(sizeof (cpu_map[0]) * cpu_map_count_max,
+ KM_SLEEP);
+ if (cpu_map_count != 0) {
+ ASSERT(cpu_map != NULL);
+ sz = sizeof (cpu_map[0]) * cpu_map_count;
+ kcopy(cpu_map, new_map, sz);
+ kmem_free(cpu_map, sz);
+ }
+ cpu_map = new_map;
+ }
+}
+
+/*
+ * Maintain mapping information among (cpu id, ACPI processor id, APIC id,
+ * ACPI handle). The mapping table will be setup in two steps:
+ * 1) acpica_add_processor_to_map() builds mapping among APIC id, ACPI
+ * processor id and ACPI object handle.
+ * 2) acpica_map_cpu() builds mapping among cpu id and ACPI processor id.
+ * On system with ACPI device configuration for CPU enabled, acpica_map_cpu()
+ * will be called before acpica_add_processor_to_map(), otherwise
+ * acpica_map_cpu() will be called after acpica_add_processor_to_map().
+ */
+ACPI_STATUS
+acpica_add_processor_to_map(UINT32 acpi_id, ACPI_HANDLE obj, UINT32 apic_id)
+{
+ int i;
+ ACPI_STATUS rc = AE_OK;
+ struct cpu_map_item *item = NULL;
+
+ ASSERT(obj != NULL);
+ if (obj == NULL) {
+ return (AE_ERROR);
+ }
+
+ mutex_enter(&cpu_map_lock);
+
+ /*
+ * Special case for uppc
+ * If we're a uppc system and ACPI device configuration for CPU has
+ * been disabled, there won't be a CPU map yet because uppc psm doesn't
+ * call acpica_map_cpu(). So create one and use the passed-in processor
+ * as CPU 0
+ */
+ if (cpu_map == NULL &&
+ !acpica_get_devcfg_feature(ACPI_DEVCFG_CPU)) {
+ acpica_grow_cpu_map();
+ ASSERT(cpu_map != NULL);
+ item = kmem_zalloc(sizeof (*item), KM_SLEEP);
+ item->cpu_id = 0;
+ item->proc_id = acpi_id;
+ item->apic_id = apic_id;
+ item->obj = obj;
+ cpu_map[0] = item;
+ cpu_map_count = 1;
+ mutex_exit(&cpu_map_lock);
+ return (AE_OK);
+ }
+
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->obj == obj) {
+ rc = AE_ALREADY_EXISTS;
+ break;
+ } else if (cpu_map[i]->proc_id == acpi_id) {
+ ASSERT(item == NULL);
+ item = cpu_map[i];
+ }
+ }
+
+ if (rc == AE_OK) {
+ if (item != NULL) {
+ /*
+ * ACPI alias objects may cause more than one objects
+ * with the same ACPI processor id, only remember the
+ * the first object encountered.
+ */
+ if (item->obj == NULL) {
+ item->obj = obj;
+ item->apic_id = apic_id;
+ } else {
+ rc = AE_ALREADY_EXISTS;
+ }
+ } else if (cpu_map_count >= INT_MAX / 2) {
+ rc = AE_NO_MEMORY;
+ } else {
+ acpica_grow_cpu_map();
+ ASSERT(cpu_map != NULL);
+ ASSERT(cpu_map_count < cpu_map_count_max);
+ item = kmem_zalloc(sizeof (*item), KM_SLEEP);
+ item->cpu_id = -1;
+ item->proc_id = acpi_id;
+ item->apic_id = apic_id;
+ item->obj = obj;
+ cpu_map[cpu_map_count] = item;
+ cpu_map_count++;
+ }
+ }
+
+ mutex_exit(&cpu_map_lock);
+
+ return (rc);
+}
+
+ACPI_STATUS
+acpica_remove_processor_from_map(UINT32 acpi_id)
+{
+ int i;
+ ACPI_STATUS rc = AE_NOT_EXIST;
+
+ mutex_enter(&cpu_map_lock);
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->proc_id != acpi_id) {
+ continue;
+ }
+ cpu_map[i]->obj = NULL;
+ /* Free item if no more reference to it. */
+ if (cpu_map[i]->cpu_id == -1) {
+ kmem_free(cpu_map[i], sizeof (struct cpu_map_item));
+ cpu_map[i] = NULL;
+ cpu_map_count--;
+ if (i != cpu_map_count) {
+ cpu_map[i] = cpu_map[cpu_map_count];
+ cpu_map[cpu_map_count] = NULL;
+ }
+ }
+ rc = AE_OK;
+ break;
+ }
+ mutex_exit(&cpu_map_lock);
+
+ return (rc);
+}
+
+ACPI_STATUS
+acpica_map_cpu(processorid_t cpuid, UINT32 acpi_id)
+{
+ int i;
+ ACPI_STATUS rc = AE_OK;
+ struct cpu_map_item *item = NULL;
+
+ ASSERT(cpuid != -1);
+ if (cpuid == -1) {
+ return (AE_ERROR);
+ }
+
+ mutex_enter(&cpu_map_lock);
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->cpu_id == cpuid) {
+ rc = AE_ALREADY_EXISTS;
+ break;
+ } else if (cpu_map[i]->proc_id == acpi_id) {
+ ASSERT(item == NULL);
+ item = cpu_map[i];
+ }
+ }
+ if (rc == AE_OK) {
+ if (item != NULL) {
+ if (item->cpu_id == -1) {
+ item->cpu_id = cpuid;
+ } else {
+ rc = AE_ALREADY_EXISTS;
+ }
+ } else if (cpu_map_count >= INT_MAX / 2) {
+ rc = AE_NO_MEMORY;
+ } else {
+ acpica_grow_cpu_map();
+ ASSERT(cpu_map != NULL);
+ ASSERT(cpu_map_count < cpu_map_count_max);
+ item = kmem_zalloc(sizeof (*item), KM_SLEEP);
+ item->cpu_id = cpuid;
+ item->proc_id = acpi_id;
+ item->apic_id = UINT32_MAX;
+ item->obj = NULL;
+ cpu_map[cpu_map_count] = item;
+ cpu_map_count++;
+ }
+ }
+ mutex_exit(&cpu_map_lock);
+
+ return (rc);
+}
+
+ACPI_STATUS
+acpica_unmap_cpu(processorid_t cpuid)
+{
+ int i;
+ ACPI_STATUS rc = AE_NOT_EXIST;
+
+ ASSERT(cpuid != -1);
+ if (cpuid == -1) {
+ return (rc);
+ }
+
+ mutex_enter(&cpu_map_lock);
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->cpu_id != cpuid) {
+ continue;
+ }
+ cpu_map[i]->cpu_id = -1;
+ /* Free item if no more reference. */
+ if (cpu_map[i]->obj == NULL) {
+ kmem_free(cpu_map[i], sizeof (struct cpu_map_item));
+ cpu_map[i] = NULL;
+ cpu_map_count--;
+ if (i != cpu_map_count) {
+ cpu_map[i] = cpu_map[cpu_map_count];
+ cpu_map[cpu_map_count] = NULL;
+ }
+ }
+ rc = AE_OK;
+ break;
+ }
+ mutex_exit(&cpu_map_lock);
+
+ return (rc);
+}
+
+ACPI_STATUS
+acpica_get_cpu_object_by_cpuid(processorid_t cpuid, ACPI_HANDLE *hdlp)
+{
+ int i;
+ ACPI_STATUS rc = AE_NOT_EXIST;
+
+ ASSERT(cpuid != -1);
+ if (cpuid == -1) {
+ return (rc);
+ }
+
+ mutex_enter(&cpu_map_lock);
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->cpu_id == cpuid && cpu_map[i]->obj != NULL) {
+ *hdlp = cpu_map[i]->obj;
+ rc = AE_OK;
+ break;
+ }
+ }
+ mutex_exit(&cpu_map_lock);
+
+ return (rc);
+}
+
+ACPI_STATUS
+acpica_get_cpu_object_by_procid(UINT32 procid, ACPI_HANDLE *hdlp)
+{
+ int i;
+ ACPI_STATUS rc = AE_NOT_EXIST;
+
+ mutex_enter(&cpu_map_lock);
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->proc_id == procid && cpu_map[i]->obj != NULL) {
+ *hdlp = cpu_map[i]->obj;
+ rc = AE_OK;
+ break;
+ }
+ }
+ mutex_exit(&cpu_map_lock);
+
+ return (rc);
+}
+
+ACPI_STATUS
+acpica_get_cpu_object_by_apicid(UINT32 apicid, ACPI_HANDLE *hdlp)
+{
+ int i;
+ ACPI_STATUS rc = AE_NOT_EXIST;
+
+ ASSERT(apicid != UINT32_MAX);
+ if (apicid == UINT32_MAX) {
+ return (rc);
+ }
+
+ mutex_enter(&cpu_map_lock);
+ for (i = 0; i < cpu_map_count; i++) {
+ if (cpu_map[i]->apic_id == apicid && cpu_map[i]->obj != NULL) {
+ *hdlp = cpu_map[i]->obj;
+ rc = AE_OK;
+ break;
+ }
+ }
+ mutex_exit(&cpu_map_lock);
+
+ return (rc);
+}
+
+void
+acpica_set_core_feature(uint64_t features)
+{
+ atomic_or_64(&acpica_core_features, features);
+}
+
+void
+acpica_clear_core_feature(uint64_t features)
+{
+ atomic_and_64(&acpica_core_features, ~features);
+}
+
+uint64_t
+acpica_get_core_feature(uint64_t features)
+{
+ return (acpica_core_features & features);
+}
+
+void
+acpica_set_devcfg_feature(uint64_t features)
+{
+ atomic_or_64(&acpica_devcfg_features, features);
+}
+
+void
+acpica_clear_devcfg_feature(uint64_t features)
+{
+ atomic_and_64(&acpica_devcfg_features, ~features);
+}
+
+uint64_t
+acpica_get_devcfg_feature(uint64_t features)
+{
+ return (acpica_devcfg_features & features);
}
void
diff --git a/usr/src/uts/intel/sys/acpica.h b/usr/src/uts/intel/sys/acpica.h
index dddcc9bf78..27482fc5f3 100644
--- a/usr/src/uts/intel/sys/acpica.h
+++ b/usr/src/uts/intel/sys/acpica.h
@@ -22,6 +22,10 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2009, Intel Corporation.
+ * All rights reserved.
+ */
#ifndef _SYS_ACPICA_H
#define _SYS_ACPICA_H
@@ -116,21 +120,51 @@ typedef struct iflag {
#define HID_PCI_BUS 0x30AD041
#define HID_PCI_EXPRESS_BUS 0x080AD041
+/* ACPICA subsystem has been fully initialized except SCI interrupt. */
+#define ACPI_FEATURE_FULL_INIT 0x1
+/* ACPI SCI interrupt has been enabled. */
+#define ACPI_FEATURE_SCI_EVENT 0x2
+/* ACPI device configuration has been enabled. */
+#define ACPI_FEATURE_DEVCFG 0x4
+/* ACPI _OSI method should report support of ACPI Module Device. */
+#define ACPI_FEATURE_OSI_MODULE 0x8
+
+/* ACPI device configuration features. */
+#define ACPI_DEVCFG_CPU 0x1
+#define ACPI_DEVCFG_MEMORY 0x2
+#define ACPI_DEVCFG_CONTAINER 0x4
+
/*
* Function prototypes
*/
extern ACPI_STATUS acpica_get_sci(int *, iflag_t *);
extern int acpica_get_bdf(dev_info_t *, int *, int *, int *);
-extern ACPI_STATUS acpica_get_devinfo(ACPI_HANDLE, dev_info_t **);
-extern ACPI_STATUS acpica_get_handle(dev_info_t *, ACPI_HANDLE *);
-extern ACPI_STATUS acpica_get_handle_cpu(int, ACPI_HANDLE *);
extern ACPI_STATUS acpica_eval_int(ACPI_HANDLE, char *, int *);
-extern void acpica_map_cpu(processorid_t, UINT32);
-extern void acpica_build_processor_map();
extern void acpica_ddi_save_resources(dev_info_t *);
extern void acpica_ddi_restore_resources(dev_info_t *);
extern void acpica_get_global_FADT(ACPI_TABLE_FADT **);
+extern ACPI_STATUS acpica_tag_devinfo(dev_info_t *, ACPI_HANDLE);
+extern ACPI_STATUS acpica_untag_devinfo(dev_info_t *, ACPI_HANDLE);
+extern ACPI_STATUS acpica_get_devinfo(ACPI_HANDLE, dev_info_t **);
+extern ACPI_STATUS acpica_get_handle(dev_info_t *, ACPI_HANDLE *);
+extern ACPI_STATUS acpica_get_handle_cpu(int, ACPI_HANDLE *);
+extern ACPI_STATUS acpica_build_processor_map(void);
+extern ACPI_STATUS acpica_add_processor_to_map(UINT32, ACPI_HANDLE, UINT32);
+extern ACPI_STATUS acpica_remove_processor_from_map(UINT32);
+extern ACPI_STATUS acpica_map_cpu(processorid_t, UINT32);
+extern ACPI_STATUS acpica_unmap_cpu(processorid_t);
+extern ACPI_STATUS acpica_get_cpu_object_by_cpuid(processorid_t, ACPI_HANDLE *);
+extern ACPI_STATUS acpica_get_cpu_object_by_procid(UINT32, ACPI_HANDLE *);
+extern ACPI_STATUS acpica_get_cpu_object_by_apicid(UINT32, ACPI_HANDLE *);
+
+extern uint64_t acpica_get_core_feature(uint64_t);
+extern void acpica_set_core_feature(uint64_t);
+extern void acpica_clear_core_feature(uint64_t);
+extern uint64_t acpica_get_devcfg_feature(uint64_t);
+extern void acpica_set_devcfg_feature(uint64_t);
+extern void acpica_clear_devcfg_feature(uint64_t);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index 667b4cc3e2..46f4be3c07 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -619,6 +619,7 @@ extern int cpuid_get_chipid(struct cpu *);
extern id_t cpuid_get_coreid(struct cpu *);
extern int cpuid_get_pkgcoreid(struct cpu *);
extern int cpuid_get_clogid(struct cpu *);
+extern uint32_t cpuid_get_apicid(struct cpu *);
extern int cpuid_is_cmt(struct cpu *);
extern int cpuid_syscall32_insn(struct cpu *);
extern int getl2cacheinfo(struct cpu *, int *, int *, int *);
@@ -639,7 +640,8 @@ extern uint_t cpuid_pass1(struct cpu *);
extern void cpuid_pass2(struct cpu *);
extern void cpuid_pass3(struct cpu *);
extern uint_t cpuid_pass4(struct cpu *);
-extern void add_cpunode2devtree(processorid_t, struct cpuid_info *);
+extern void cpuid_set_cpu_properties(void *, processorid_t,
+ struct cpuid_info *);
extern void cpuid_get_addrsize(struct cpu *, uint_t *, uint_t *);
extern uint_t cpuid_get_dtlb_nent(struct cpu *, size_t);