Exemple #1
0
void
npe_enable_htmsi_children(dev_info_t *dip)
{
	dev_info_t *cdip = ddi_get_child(dip);
	ddi_acc_handle_t cfg_hdl;

	if (!npe_enable_htmsi_flag)
		return;

	/*
	 * Hypertransport MSI remapping only applies to AMD CPUs using
	 * Hypertransport (K8 and above) and not other platforms with non-AMD
	 * CPUs that may be using Hypertransport internally in the chipset(s)
	 */
	if (!(cpuid_getvendor(CPU) == X86_VENDOR_AMD &&
	    cpuid_getfamily(CPU) >= 0xf))
		return;

	for (; cdip != NULL; cdip = ddi_get_next_sibling(cdip)) {
		if (pci_config_setup(cdip, &cfg_hdl) != DDI_SUCCESS) {
			cmn_err(CE_NOTE, "!npe_enable_htmsi_children: "
			    "pci_config_setup failed for %s",
			    ddi_node_name(cdip));
			return;
		}

		(void) npe_enable_htmsi(cfg_hdl);
		pci_config_teardown(&cfg_hdl);
	}
}
/*
 * Examine the processor and load an appropriate PCBE.
 */
int
kcpc_hw_load_pcbe(void)
{
	return (kcpc_pcbe_tryload(cpuid_getvendorstr(CPU), cpuid_getfamily(CPU),
	    cpuid_getmodel(CPU), cpuid_getstep(CPU)));
}
boolean_t
cpupm_intel_init(cpu_t *cp)
{
	cpupm_mach_state_t *mach_state =
	    (cpupm_mach_state_t *)(cp->cpu_m.mcpu_pm_mach_state);
	uint_t family;
	uint_t model;

	if (x86_vendor != X86_VENDOR_Intel)
		return (B_FALSE);

	family = cpuid_getfamily(CPU);
	model = cpuid_getmodel(CPU);

	cpupm_intel_pdccap = CPUPM_INTEL_PDC_MP;

	/*
	 * If we support SpeedStep on this processor, then set the
	 * correct cma_ops for the processor and enable appropriate
	 * _PDC bits.
	 */
	if (speedstep_supported(family, model)) {
		mach_state->ms_pstate.cma_ops = &speedstep_ops;
		cpupm_intel_pdccap |= CPUPM_INTEL_PDC_PS_MSR |
		    CPUPM_INTEL_PDC_C1_HALT | CPUPM_INTEL_PDC_SW_PSD |
		    CPUPM_INTEL_PDC_HW_PSD;
	} else {
		mach_state->ms_pstate.cma_ops = NULL;
	}

	/*
	 * Set the correct tstate_ops for the processor and
	 * enable appropriate _PDC bits.
	 */
	mach_state->ms_tstate.cma_ops = &cpupm_throttle_ops;
	cpupm_intel_pdccap |= CPUPM_INTEL_PDC_TS_MSR |
	    CPUPM_INTEL_PDC_TSD;

	/*
	 * If we support deep cstates on this processor, then set the
	 * correct cstate_ops for the processor and enable appropriate
	 * _PDC bits.
	 */
	mach_state->ms_cstate.cma_ops = &cpu_idle_ops;
	cpupm_intel_pdccap |= CPUPM_INTEL_PDC_C1_HALT |
	    CPUPM_INTEL_PDC_C2C3_MP | CPUPM_INTEL_PDC_C1_FFH;

	/*
	 * _PDC support is optional and the driver should
	 * function even if the _PDC write fails.
	 */
	(void) cpu_acpi_write_pdc(mach_state->ms_acpi_handle,
	    CPUPM_INTEL_PDC_REVISION, 1, &cpupm_intel_pdccap);

	/*
	 * If Intel ENERGY PERFORMANCE BIAS feature is supported,
	 * provides input to the HW, based on user power-policy.
	 */
	if (cpuid_iepb_supported(cp)) {
		cpupm_iepb_set_policy(cpupm_iepb_policy);
	}

	return (B_TRUE);
}
static int
opt_pcbe_init(void)
{
	amd_event_t		*evp;
	amd_generic_event_t	*gevp;

	amd_family = cpuid_getfamily(CPU);

	/*
	 * Make sure this really _is_ an Opteron or Athlon 64 system. The kernel
	 * loads this module based on its name in the module directory, but it
	 * could have been renamed.
	 */
	if (cpuid_getvendor(CPU) != X86_VENDOR_AMD || amd_family < 0xf)
		return (-1);

	if (amd_family == 0xf)
		/* Some tools expect this string for family 0fh */
		snprintf(amd_pcbe_impl_name, sizeof (amd_pcbe_impl_name),
		    "AMD Opteron & Athlon64");
	else
		snprintf(amd_pcbe_impl_name, sizeof (amd_pcbe_impl_name),
		    "AMD Family %02xh%s", amd_family,
		    AMD_PCBE_SUPPORTED(amd_family) ? "" :" (unsupported)");

	/*
	 * Figure out processor revision here and assign appropriate
	 * event configuration.
	 */

	if (amd_family == 0xf) {
		uint32_t rev;

		rev = cpuid_getchiprev(CPU);

		if (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F))
			amd_pcbe_cpuref = amd_fam_f_NPT_bkdg;
		else
			amd_pcbe_cpuref = amd_fam_f_rev_ae_bkdg;
		amd_events = family_f_events;
		amd_generic_events = opt_generic_events;
	} else if (amd_family == 0x10) {
		amd_pcbe_cpuref = amd_fam_10h_bkdg;
		amd_events = family_10h_events;
		amd_generic_events = family_10h_generic_events;
	} else if (amd_family == 0x11) {
		amd_pcbe_cpuref = amd_fam_11h_bkdg;
		amd_events = family_11h_events;
		amd_generic_events = opt_generic_events;
	} else {

		amd_pcbe_cpuref = amd_generic_bkdg;
		snprintf(amd_pcbe_cpuref, AMD_CPUREF_SIZE,
		    "See BIOS and Kernel Developer's Guide "    \
		    "(BKDG) For AMD Family %02xh Processors. "  \
		    "(Note that this pcbe does not explicitly " \
		    "support this family)", amd_family);

		/*
		 * For families that are not explicitly supported we'll use
		 * events for family 0xf. Even if they are not quite right,
		 * it's OK --- we state that pcbe is unsupported.
		 */
		amd_events = family_f_events;
		amd_generic_events = opt_generic_events;
	}

	/*
	 * Construct event list.
	 *
	 * First pass:  Calculate size needed. We'll need an additional byte
	 *		for the NULL pointer during the last strcat.
	 *
	 * Second pass: Copy strings.
	 */
	for (evp = amd_events; evp->name != NULL; evp++)
		evlist_sz += strlen(evp->name) + 1;

	for (gevp = amd_generic_events; gevp->name != NULL; gevp++)
		evlist_sz += strlen(gevp->name) + 1;

	evlist = kmem_alloc(evlist_sz + 1, KM_SLEEP);
	evlist[0] = '\0';

	for (evp = amd_events; evp->name != NULL; evp++) {
		(void) strcat(evlist, evp->name);
		(void) strcat(evlist, ",");
	}

	for (gevp = amd_generic_events; gevp->name != NULL; gevp++) {
		(void) strcat(evlist, gevp->name);
		(void) strcat(evlist, ",");
	}

	/*
	 * Remove trailing comma.
	 */
	evlist[evlist_sz - 1] = '\0';

	return (0);
}