diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/i86pc/io/mp_platform_common.c | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/cpuid.c | 69 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/mp_machdep.c | 99 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/mp_startup.c | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/startup.c | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/machsystm.h | 1 | ||||
-rw-r--r-- | usr/src/uts/intel/io/acpica/acpica.c | 73 | ||||
-rw-r--r-- | usr/src/uts/intel/io/acpica/osl.c | 672 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/acpica.h | 44 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/x86_archext.h | 4 |
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); |