|
@@ -1,3 +1,4 @@
|
|
|
|
+#include <asm/cpu_device_id.h>
|
|
#include "uncore.h"
|
|
#include "uncore.h"
|
|
|
|
|
|
static struct intel_uncore_type *empty_uncore[] = { NULL, };
|
|
static struct intel_uncore_type *empty_uncore[] = { NULL, };
|
|
@@ -21,6 +22,8 @@ static struct event_constraint uncore_constraint_fixed =
|
|
struct event_constraint uncore_constraint_empty =
|
|
struct event_constraint uncore_constraint_empty =
|
|
EVENT_CONSTRAINT(0, 0, 0);
|
|
EVENT_CONSTRAINT(0, 0, 0);
|
|
|
|
|
|
|
|
+MODULE_LICENSE("GPL");
|
|
|
|
+
|
|
static int uncore_pcibus_to_physid(struct pci_bus *bus)
|
|
static int uncore_pcibus_to_physid(struct pci_bus *bus)
|
|
{
|
|
{
|
|
struct pci2phy_map *map;
|
|
struct pci2phy_map *map;
|
|
@@ -754,7 +757,7 @@ static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu)
|
|
pmu->registered = false;
|
|
pmu->registered = false;
|
|
}
|
|
}
|
|
|
|
|
|
-static void __init __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
|
|
|
|
|
|
+static void __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
|
|
{
|
|
{
|
|
struct intel_uncore_pmu *pmu = type->pmus;
|
|
struct intel_uncore_pmu *pmu = type->pmus;
|
|
struct intel_uncore_box *box;
|
|
struct intel_uncore_box *box;
|
|
@@ -770,7 +773,7 @@ static void __init __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void __init uncore_exit_boxes(void *dummy)
|
|
|
|
|
|
+static void uncore_exit_boxes(void *dummy)
|
|
{
|
|
{
|
|
struct intel_uncore_type **types;
|
|
struct intel_uncore_type **types;
|
|
|
|
|
|
@@ -787,7 +790,7 @@ static void uncore_free_boxes(struct intel_uncore_pmu *pmu)
|
|
kfree(pmu->boxes);
|
|
kfree(pmu->boxes);
|
|
}
|
|
}
|
|
|
|
|
|
-static void __init uncore_type_exit(struct intel_uncore_type *type)
|
|
|
|
|
|
+static void uncore_type_exit(struct intel_uncore_type *type)
|
|
{
|
|
{
|
|
struct intel_uncore_pmu *pmu = type->pmus;
|
|
struct intel_uncore_pmu *pmu = type->pmus;
|
|
int i;
|
|
int i;
|
|
@@ -804,7 +807,7 @@ static void __init uncore_type_exit(struct intel_uncore_type *type)
|
|
type->events_group = NULL;
|
|
type->events_group = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-static void __init uncore_types_exit(struct intel_uncore_type **types)
|
|
|
|
|
|
+static void uncore_types_exit(struct intel_uncore_type **types)
|
|
{
|
|
{
|
|
for (; *types; types++)
|
|
for (; *types; types++)
|
|
uncore_type_exit(*types);
|
|
uncore_type_exit(*types);
|
|
@@ -989,46 +992,6 @@ static int __init uncore_pci_init(void)
|
|
size_t size;
|
|
size_t size;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- switch (boot_cpu_data.x86_model) {
|
|
|
|
- case 45: /* Sandy Bridge-EP */
|
|
|
|
- ret = snbep_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 62: /* Ivy Bridge-EP */
|
|
|
|
- ret = ivbep_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 63: /* Haswell-EP */
|
|
|
|
- ret = hswep_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 79: /* BDX-EP */
|
|
|
|
- case 86: /* BDX-DE */
|
|
|
|
- ret = bdx_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 42: /* Sandy Bridge */
|
|
|
|
- ret = snb_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 58: /* Ivy Bridge */
|
|
|
|
- ret = ivb_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 60: /* Haswell */
|
|
|
|
- case 69: /* Haswell Celeron */
|
|
|
|
- ret = hsw_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 61: /* Broadwell */
|
|
|
|
- ret = bdw_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 87: /* Knights Landing */
|
|
|
|
- ret = knl_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- case 94: /* SkyLake */
|
|
|
|
- ret = skl_uncore_pci_init();
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- return -ENODEV;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
-
|
|
|
|
size = max_packages * sizeof(struct pci_extra_dev);
|
|
size = max_packages * sizeof(struct pci_extra_dev);
|
|
uncore_extra_pci_dev = kzalloc(size, GFP_KERNEL);
|
|
uncore_extra_pci_dev = kzalloc(size, GFP_KERNEL);
|
|
if (!uncore_extra_pci_dev) {
|
|
if (!uncore_extra_pci_dev) {
|
|
@@ -1060,7 +1023,7 @@ err:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static void __init uncore_pci_exit(void)
|
|
|
|
|
|
+static void uncore_pci_exit(void)
|
|
{
|
|
{
|
|
if (pcidrv_registered) {
|
|
if (pcidrv_registered) {
|
|
pcidrv_registered = false;
|
|
pcidrv_registered = false;
|
|
@@ -1287,46 +1250,6 @@ static int __init uncore_cpu_init(void)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- switch (boot_cpu_data.x86_model) {
|
|
|
|
- case 26: /* Nehalem */
|
|
|
|
- case 30:
|
|
|
|
- case 37: /* Westmere */
|
|
|
|
- case 44:
|
|
|
|
- nhm_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- case 42: /* Sandy Bridge */
|
|
|
|
- case 58: /* Ivy Bridge */
|
|
|
|
- case 60: /* Haswell */
|
|
|
|
- case 69: /* Haswell */
|
|
|
|
- case 70: /* Haswell */
|
|
|
|
- case 61: /* Broadwell */
|
|
|
|
- case 71: /* Broadwell */
|
|
|
|
- snb_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- case 45: /* Sandy Bridge-EP */
|
|
|
|
- snbep_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- case 46: /* Nehalem-EX */
|
|
|
|
- case 47: /* Westmere-EX aka. Xeon E7 */
|
|
|
|
- nhmex_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- case 62: /* Ivy Bridge-EP */
|
|
|
|
- ivbep_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- case 63: /* Haswell-EP */
|
|
|
|
- hswep_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- case 79: /* BDX-EP */
|
|
|
|
- case 86: /* BDX-DE */
|
|
|
|
- bdx_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- case 87: /* Knights Landing */
|
|
|
|
- knl_uncore_cpu_init();
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- return -ENODEV;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
ret = uncore_types_init(uncore_msr_uncores, true);
|
|
ret = uncore_types_init(uncore_msr_uncores, true);
|
|
if (ret)
|
|
if (ret)
|
|
goto err;
|
|
goto err;
|
|
@@ -1376,11 +1299,105 @@ static int __init uncore_cpumask_init(bool msr)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#define X86_UNCORE_MODEL_MATCH(model, init) \
|
|
|
|
+ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init }
|
|
|
|
+
|
|
|
|
+struct intel_uncore_init_fun {
|
|
|
|
+ void (*cpu_init)(void);
|
|
|
|
+ int (*pci_init)(void);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = nhm_uncore_cpu_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun snb_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = snb_uncore_cpu_init,
|
|
|
|
+ .pci_init = snb_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun ivb_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = snb_uncore_cpu_init,
|
|
|
|
+ .pci_init = ivb_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun hsw_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = snb_uncore_cpu_init,
|
|
|
|
+ .pci_init = hsw_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun bdw_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = snb_uncore_cpu_init,
|
|
|
|
+ .pci_init = bdw_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun snbep_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = snbep_uncore_cpu_init,
|
|
|
|
+ .pci_init = snbep_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun nhmex_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = nhmex_uncore_cpu_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun ivbep_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = ivbep_uncore_cpu_init,
|
|
|
|
+ .pci_init = ivbep_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun hswep_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = hswep_uncore_cpu_init,
|
|
|
|
+ .pci_init = hswep_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun bdx_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = bdx_uncore_cpu_init,
|
|
|
|
+ .pci_init = bdx_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun knl_uncore_init __initconst = {
|
|
|
|
+ .cpu_init = knl_uncore_cpu_init,
|
|
|
|
+ .pci_init = knl_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct intel_uncore_init_fun skl_uncore_init __initconst = {
|
|
|
|
+ .pci_init = skl_uncore_pci_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct x86_cpu_id intel_uncore_match[] __initconst = {
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(26, nhm_uncore_init), /* Nehalem */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(30, nhm_uncore_init),
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(37, nhm_uncore_init), /* Westmere */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(44, nhm_uncore_init),
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(42, snb_uncore_init), /* Sandy Bridge */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(58, ivb_uncore_init), /* Ivy Bridge */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(60, hsw_uncore_init), /* Haswell */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(69, hsw_uncore_init), /* Haswell Celeron */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(70, hsw_uncore_init), /* Haswell */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(61, bdw_uncore_init), /* Broadwell */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(71, bdw_uncore_init), /* Broadwell */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(45, snbep_uncore_init), /* Sandy Bridge-EP */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(46, nhmex_uncore_init), /* Nehalem-EX */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(47, nhmex_uncore_init), /* Westmere-EX aka. Xeon E7 */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(62, ivbep_uncore_init), /* Ivy Bridge-EP */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(63, hswep_uncore_init), /* Haswell-EP */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(79, bdx_uncore_init), /* BDX-EP */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(86, bdx_uncore_init), /* BDX-DE */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(87, knl_uncore_init), /* Knights Landing */
|
|
|
|
+ X86_UNCORE_MODEL_MATCH(94, skl_uncore_init), /* SkyLake */
|
|
|
|
+ {},
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
|
|
|
|
+
|
|
static int __init intel_uncore_init(void)
|
|
static int __init intel_uncore_init(void)
|
|
{
|
|
{
|
|
- int pret, cret, ret;
|
|
|
|
|
|
+ const struct x86_cpu_id *id;
|
|
|
|
+ struct intel_uncore_init_fun *uncore_init;
|
|
|
|
+ int pret = 0, cret = 0, ret;
|
|
|
|
|
|
- if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
|
|
|
|
|
+ id = x86_match_cpu(intel_uncore_match);
|
|
|
|
+ if (!id)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
if (cpu_has_hypervisor)
|
|
if (cpu_has_hypervisor)
|
|
@@ -1388,8 +1405,17 @@ static int __init intel_uncore_init(void)
|
|
|
|
|
|
max_packages = topology_max_packages();
|
|
max_packages = topology_max_packages();
|
|
|
|
|
|
- pret = uncore_pci_init();
|
|
|
|
- cret = uncore_cpu_init();
|
|
|
|
|
|
+ uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
|
|
|
|
+ if (uncore_init->pci_init) {
|
|
|
|
+ pret = uncore_init->pci_init();
|
|
|
|
+ if (!pret)
|
|
|
|
+ pret = uncore_pci_init();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (uncore_init->cpu_init) {
|
|
|
|
+ uncore_init->cpu_init();
|
|
|
|
+ cret = uncore_cpu_init();
|
|
|
|
+ }
|
|
|
|
|
|
if (cret && pret)
|
|
if (cret && pret)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
@@ -1409,4 +1435,14 @@ err:
|
|
cpu_notifier_register_done();
|
|
cpu_notifier_register_done();
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
-device_initcall(intel_uncore_init);
|
|
|
|
|
|
+module_init(intel_uncore_init);
|
|
|
|
+
|
|
|
|
+static void __exit intel_uncore_exit(void)
|
|
|
|
+{
|
|
|
|
+ cpu_notifier_register_begin();
|
|
|
|
+ __unregister_cpu_notifier(&uncore_cpu_nb);
|
|
|
|
+ uncore_types_exit(uncore_msr_uncores);
|
|
|
|
+ uncore_pci_exit();
|
|
|
|
+ cpu_notifier_register_done();
|
|
|
|
+}
|
|
|
|
+module_exit(intel_uncore_exit);
|