Commit c54c53d9 authored by Kan Liang's avatar Kan Liang Committed by Peter Zijlstra

perf/x86/intel/uncore: Add Sapphire Rapids server framework

Intel Sapphire Rapids supports a discovery mechanism, that allows an
uncore driver to discover the different components ("boxes") of the
chip.

All the generic information of the uncore boxes should be retrieved from
the discovery tables. This has been enabled with the commit edae1f06
("perf/x86/intel/uncore: Parse uncore discovery tables"). Add
use_discovery to indicate the case. The uncore driver doesn't need to
hard code the generic information for each uncore box.
But we still need to enable various functionality that cannot be
directly discovered.

To support these functionalities, the Sapphire Rapids server framework
is introduced here. Each specific uncore unit will be added into the
framework in the following patches.

Add use_discovery to indicate that the discovery mechanism is required
for the platform. Currently, Intel Sapphire Rapids is one of the
platforms.

The box ID from the discovery table is the accurate index. Use it if
applicable.

All the undiscovered platform-specific features will be hard code in the
spr_uncores[]. Add uncore_type_customized_copy(), instead of the memcpy,
to only overwrite these features.

The specific uncore unit hasn't been added here. From user's
perspective, there is nothing changed for now.
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarAndi Kleen <ak@linux.intel.com>
Link: https://lore.kernel.org/r/1625087320-194204-2-git-send-email-kan.liang@linux.intel.com
parent 012669c7
......@@ -865,9 +865,13 @@ static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu)
sprintf(pmu->name, "uncore_%s", type->name);
else
sprintf(pmu->name, "uncore");
} else
sprintf(pmu->name, "uncore_%s_%d", type->name, pmu->pmu_idx);
} else {
/*
* Use the box ID from the discovery table if applicable.
*/
sprintf(pmu->name, "uncore_%s_%d", type->name,
type->box_ids ? type->box_ids[pmu->pmu_idx] : pmu->pmu_idx);
}
}
static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
......@@ -1663,6 +1667,7 @@ struct intel_uncore_init_fun {
void (*cpu_init)(void);
int (*pci_init)(void);
void (*mmio_init)(void);
bool use_discovery;
};
static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
......@@ -1765,6 +1770,13 @@ static const struct intel_uncore_init_fun snr_uncore_init __initconst = {
.mmio_init = snr_uncore_mmio_init,
};
static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
.cpu_init = spr_uncore_cpu_init,
.pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init,
.use_discovery = true,
};
static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
......@@ -1809,6 +1821,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &rkl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &adl_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &spr_uncore_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &snr_uncore_init),
{},
};
......@@ -1832,8 +1845,13 @@ static int __init intel_uncore_init(void)
uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
else
return -ENODEV;
} else
} else {
uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
if (uncore_no_discover && uncore_init->use_discovery)
return -ENODEV;
if (uncore_init->use_discovery && !intel_uncore_has_discovery_tables())
return -ENODEV;
}
if (uncore_init->pci_init) {
pret = uncore_init->pci_init();
......
......@@ -608,6 +608,9 @@ void snr_uncore_mmio_init(void);
int icx_uncore_pci_init(void);
void icx_uncore_cpu_init(void);
void icx_uncore_mmio_init(void);
int spr_uncore_pci_init(void);
void spr_uncore_cpu_init(void);
void spr_uncore_mmio_init(void);
/* uncore_nhmex.c */
void nhmex_uncore_cpu_init(void);
......@@ -568,7 +568,7 @@ static bool uncore_update_uncore_type(enum uncore_access_type type_id,
return true;
}
static struct intel_uncore_type **
struct intel_uncore_type **
intel_uncore_generic_init_uncores(enum uncore_access_type type_id)
{
struct intel_uncore_discovery_type *type;
......
......@@ -129,3 +129,6 @@ void intel_uncore_clear_discovery_tables(void);
void intel_uncore_generic_uncore_cpu_init(void);
int intel_uncore_generic_uncore_pci_init(void);
void intel_uncore_generic_uncore_mmio_init(void);
struct intel_uncore_type **
intel_uncore_generic_init_uncores(enum uncore_access_type type_id);
// SPDX-License-Identifier: GPL-2.0
/* SandyBridge-EP/IvyTown uncore support */
#include "uncore.h"
#include "uncore_discovery.h"
/* SNB-EP pci bus to socket mapping */
#define SNBEP_CPUNODEID 0x40
......@@ -5504,3 +5505,89 @@ void icx_uncore_mmio_init(void)
}
/* end of ICX uncore support */
/* SPR uncore support */
#define UNCORE_SPR_NUM_UNCORE_TYPES 12
static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
struct intel_uncore_type *from_type)
{
if (!to_type || !from_type)
return;
if (from_type->name)
to_type->name = from_type->name;
if (from_type->fixed_ctr_bits)
to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
if (from_type->event_mask)
to_type->event_mask = from_type->event_mask;
if (from_type->event_mask_ext)
to_type->event_mask_ext = from_type->event_mask_ext;
if (from_type->fixed_ctr)
to_type->fixed_ctr = from_type->fixed_ctr;
if (from_type->fixed_ctl)
to_type->fixed_ctl = from_type->fixed_ctl;
if (from_type->fixed_ctr_bits)
to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
if (from_type->num_shared_regs)
to_type->num_shared_regs = from_type->num_shared_regs;
if (from_type->constraints)
to_type->constraints = from_type->constraints;
if (from_type->ops)
to_type->ops = from_type->ops;
if (from_type->event_descs)
to_type->event_descs = from_type->event_descs;
if (from_type->format_group)
to_type->format_group = from_type->format_group;
}
static struct intel_uncore_type **
uncore_get_uncores(enum uncore_access_type type_id)
{
struct intel_uncore_type **types, **start_types;
start_types = types = intel_uncore_generic_init_uncores(type_id);
/* Only copy the customized features */
for (; *types; types++) {
if ((*types)->type_id >= UNCORE_SPR_NUM_UNCORE_TYPES)
continue;
uncore_type_customized_copy(*types, spr_uncores[(*types)->type_id]);
}
return start_types;
}
void spr_uncore_cpu_init(void)
{
uncore_msr_uncores = uncore_get_uncores(UNCORE_ACCESS_MSR);
}
int spr_uncore_pci_init(void)
{
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI);
return 0;
}
void spr_uncore_mmio_init(void)
{
uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO);
}
/* end of SPR uncore support */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment