linux/arch/x86/events/intel/uncore_discovery.h

155 lines
4.7 KiB
C
Raw Normal View History

perf/x86/intel/uncore: Parse uncore discovery tables A self-describing mechanism for the uncore PerfMon hardware has been introduced with the latest Intel platforms. By reading through an MMIO page worth of information, perf can 'discover' all the standard uncore PerfMon registers in a machine. The discovery mechanism relies on BIOS's support. With a proper BIOS, a PCI device with the unique capability ID 0x23 can be found on each die. Perf can retrieve the information of all available uncore PerfMons from the device via MMIO. The information is composed of one global discovery table and several unit discovery tables. - The global discovery table includes global uncore information of the die, e.g., the address of the global control register, the offset of the global status register, the number of uncore units, the offset of unit discovery tables, etc. - The unit discovery table includes generic uncore unit information, e.g., the access type, the counter width, the address of counters, the address of the counter control, the unit ID, the unit type, etc. The unit is also called "box" in the code. Perf can provide basic uncore support based on this information with the following patches. To locate the PCI device with the discovery tables, check the generic PCI ID first. If it doesn't match, go through the entire PCI device tree and locate the device with the unique capability ID. The uncore information is similar among dies. To save parsing time and space, only completely parse and store the discovery tables on the first die and the first box of each die. The parsed information is stored in an RB tree structure, intel_uncore_discovery_type. The size of the stored discovery tables varies among platforms. It's around 4KB for a Sapphire Rapids server. If a BIOS doesn't support the 'discovery' mechanism, the uncore driver will exit with -ENODEV. There is nothing changed. Add a module parameter to disable the discovery feature. If a BIOS gets the discovery tables wrong, users can have an option to disable the feature. For the current patchset, the uncore driver will exit with -ENODEV. In the future, it may fall back to the hardcode uncore driver on a known platform. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/1616003977-90612-2-git-send-email-kan.liang@linux.intel.com
2021-03-17 17:59:33 +00:00
/* SPDX-License-Identifier: GPL-2.0-only */
/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
/* Capability ID for a discovery table device */
#define UNCORE_EXT_CAP_ID_DISCOVERY 0x23
/* First DVSEC offset */
#define UNCORE_DISCOVERY_DVSEC_OFFSET 0x8
/* Mask of the supported discovery entry type */
#define UNCORE_DISCOVERY_DVSEC_ID_MASK 0xffff
/* PMON discovery entry type ID */
#define UNCORE_DISCOVERY_DVSEC_ID_PMON 0x1
/* Second DVSEC offset */
#define UNCORE_DISCOVERY_DVSEC2_OFFSET 0xc
/* Mask of the discovery table BAR offset */
#define UNCORE_DISCOVERY_DVSEC2_BIR_MASK 0x7
/* Discovery table BAR base offset */
#define UNCORE_DISCOVERY_BIR_BASE 0x10
/* Discovery table BAR step */
#define UNCORE_DISCOVERY_BIR_STEP 0x4
/* Mask of the discovery table offset */
#define UNCORE_DISCOVERY_MASK 0xf
/* Global discovery table size */
#define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE 0x20
#define UNCORE_DISCOVERY_PCI_DOMAIN(data) ((data >> 28) & 0x7)
#define UNCORE_DISCOVERY_PCI_BUS(data) ((data >> 20) & 0xff)
#define UNCORE_DISCOVERY_PCI_DEVFN(data) ((data >> 12) & 0xff)
#define UNCORE_DISCOVERY_PCI_BOX_CTRL(data) (data & 0xfff)
perf/x86/intel/uncore: Parse uncore discovery tables A self-describing mechanism for the uncore PerfMon hardware has been introduced with the latest Intel platforms. By reading through an MMIO page worth of information, perf can 'discover' all the standard uncore PerfMon registers in a machine. The discovery mechanism relies on BIOS's support. With a proper BIOS, a PCI device with the unique capability ID 0x23 can be found on each die. Perf can retrieve the information of all available uncore PerfMons from the device via MMIO. The information is composed of one global discovery table and several unit discovery tables. - The global discovery table includes global uncore information of the die, e.g., the address of the global control register, the offset of the global status register, the number of uncore units, the offset of unit discovery tables, etc. - The unit discovery table includes generic uncore unit information, e.g., the access type, the counter width, the address of counters, the address of the counter control, the unit ID, the unit type, etc. The unit is also called "box" in the code. Perf can provide basic uncore support based on this information with the following patches. To locate the PCI device with the discovery tables, check the generic PCI ID first. If it doesn't match, go through the entire PCI device tree and locate the device with the unique capability ID. The uncore information is similar among dies. To save parsing time and space, only completely parse and store the discovery tables on the first die and the first box of each die. The parsed information is stored in an RB tree structure, intel_uncore_discovery_type. The size of the stored discovery tables varies among platforms. It's around 4KB for a Sapphire Rapids server. If a BIOS doesn't support the 'discovery' mechanism, the uncore driver will exit with -ENODEV. There is nothing changed. Add a module parameter to disable the discovery feature. If a BIOS gets the discovery tables wrong, users can have an option to disable the feature. For the current patchset, the uncore driver will exit with -ENODEV. In the future, it may fall back to the hardcode uncore driver on a known platform. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/1616003977-90612-2-git-send-email-kan.liang@linux.intel.com
2021-03-17 17:59:33 +00:00
#define uncore_discovery_invalid_unit(unit) \
(!unit.table1 || !unit.ctl || \
perf/x86/intel/uncore: Parse uncore discovery tables A self-describing mechanism for the uncore PerfMon hardware has been introduced with the latest Intel platforms. By reading through an MMIO page worth of information, perf can 'discover' all the standard uncore PerfMon registers in a machine. The discovery mechanism relies on BIOS's support. With a proper BIOS, a PCI device with the unique capability ID 0x23 can be found on each die. Perf can retrieve the information of all available uncore PerfMons from the device via MMIO. The information is composed of one global discovery table and several unit discovery tables. - The global discovery table includes global uncore information of the die, e.g., the address of the global control register, the offset of the global status register, the number of uncore units, the offset of unit discovery tables, etc. - The unit discovery table includes generic uncore unit information, e.g., the access type, the counter width, the address of counters, the address of the counter control, the unit ID, the unit type, etc. The unit is also called "box" in the code. Perf can provide basic uncore support based on this information with the following patches. To locate the PCI device with the discovery tables, check the generic PCI ID first. If it doesn't match, go through the entire PCI device tree and locate the device with the unique capability ID. The uncore information is similar among dies. To save parsing time and space, only completely parse and store the discovery tables on the first die and the first box of each die. The parsed information is stored in an RB tree structure, intel_uncore_discovery_type. The size of the stored discovery tables varies among platforms. It's around 4KB for a Sapphire Rapids server. If a BIOS doesn't support the 'discovery' mechanism, the uncore driver will exit with -ENODEV. There is nothing changed. Add a module parameter to disable the discovery feature. If a BIOS gets the discovery tables wrong, users can have an option to disable the feature. For the current patchset, the uncore driver will exit with -ENODEV. In the future, it may fall back to the hardcode uncore driver on a known platform. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/1616003977-90612-2-git-send-email-kan.liang@linux.intel.com
2021-03-17 17:59:33 +00:00
unit.table1 == -1ULL || unit.ctl == -1ULL || \
unit.table3 == -1ULL)
#define GENERIC_PMON_CTL_EV_SEL_MASK 0x000000ff
#define GENERIC_PMON_CTL_UMASK_MASK 0x0000ff00
#define GENERIC_PMON_CTL_EDGE_DET (1 << 18)
#define GENERIC_PMON_CTL_INVERT (1 << 23)
#define GENERIC_PMON_CTL_TRESH_MASK 0xff000000
#define GENERIC_PMON_RAW_EVENT_MASK (GENERIC_PMON_CTL_EV_SEL_MASK | \
GENERIC_PMON_CTL_UMASK_MASK | \
GENERIC_PMON_CTL_EDGE_DET | \
GENERIC_PMON_CTL_INVERT | \
GENERIC_PMON_CTL_TRESH_MASK)
#define GENERIC_PMON_BOX_CTL_FRZ (1 << 0)
#define GENERIC_PMON_BOX_CTL_RST_CTRL (1 << 8)
#define GENERIC_PMON_BOX_CTL_RST_CTRS (1 << 9)
#define GENERIC_PMON_BOX_CTL_INT (GENERIC_PMON_BOX_CTL_RST_CTRL | \
GENERIC_PMON_BOX_CTL_RST_CTRS)
perf/x86/intel/uncore: Parse uncore discovery tables A self-describing mechanism for the uncore PerfMon hardware has been introduced with the latest Intel platforms. By reading through an MMIO page worth of information, perf can 'discover' all the standard uncore PerfMon registers in a machine. The discovery mechanism relies on BIOS's support. With a proper BIOS, a PCI device with the unique capability ID 0x23 can be found on each die. Perf can retrieve the information of all available uncore PerfMons from the device via MMIO. The information is composed of one global discovery table and several unit discovery tables. - The global discovery table includes global uncore information of the die, e.g., the address of the global control register, the offset of the global status register, the number of uncore units, the offset of unit discovery tables, etc. - The unit discovery table includes generic uncore unit information, e.g., the access type, the counter width, the address of counters, the address of the counter control, the unit ID, the unit type, etc. The unit is also called "box" in the code. Perf can provide basic uncore support based on this information with the following patches. To locate the PCI device with the discovery tables, check the generic PCI ID first. If it doesn't match, go through the entire PCI device tree and locate the device with the unique capability ID. The uncore information is similar among dies. To save parsing time and space, only completely parse and store the discovery tables on the first die and the first box of each die. The parsed information is stored in an RB tree structure, intel_uncore_discovery_type. The size of the stored discovery tables varies among platforms. It's around 4KB for a Sapphire Rapids server. If a BIOS doesn't support the 'discovery' mechanism, the uncore driver will exit with -ENODEV. There is nothing changed. Add a module parameter to disable the discovery feature. If a BIOS gets the discovery tables wrong, users can have an option to disable the feature. For the current patchset, the uncore driver will exit with -ENODEV. In the future, it may fall back to the hardcode uncore driver on a known platform. Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/1616003977-90612-2-git-send-email-kan.liang@linux.intel.com
2021-03-17 17:59:33 +00:00
enum uncore_access_type {
UNCORE_ACCESS_MSR = 0,
UNCORE_ACCESS_MMIO,
UNCORE_ACCESS_PCI,
UNCORE_ACCESS_MAX,
};
struct uncore_global_discovery {
union {
u64 table1;
struct {
u64 type : 8,
stride : 8,
max_units : 10,
__reserved_1 : 36,
access_type : 2;
};
};
u64 ctl; /* Global Control Address */
union {
u64 table3;
struct {
u64 status_offset : 8,
num_status : 16,
__reserved_2 : 40;
};
};
};
struct uncore_unit_discovery {
union {
u64 table1;
struct {
u64 num_regs : 8,
ctl_offset : 8,
bit_width : 8,
ctr_offset : 8,
status_offset : 8,
__reserved_1 : 22,
access_type : 2;
};
};
u64 ctl; /* Unit Control Address */
union {
u64 table3;
struct {
u64 box_type : 16,
box_id : 16,
__reserved_2 : 32;
};
};
};
struct intel_uncore_discovery_type {
struct rb_node node;
enum uncore_access_type access_type;
u64 box_ctrl; /* Unit ctrl addr of the first box */
u64 *box_ctrl_die; /* Unit ctrl addr of the first box of each die */
u16 type; /* Type ID of the uncore block */
u8 num_counters;
u8 counter_width;
u8 ctl_offset; /* Counter Control 0 offset */
u8 ctr_offset; /* Counter 0 offset */
u16 num_boxes; /* number of boxes for the uncore block */
unsigned int *ids; /* Box IDs */
unsigned int *box_offset; /* Box offset */
};
bool intel_uncore_has_discovery_tables(void);
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);
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 edae1f06c2cd ("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: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Andi Kleen <ak@linux.intel.com> Link: https://lore.kernel.org/r/1625087320-194204-2-git-send-email-kan.liang@linux.intel.com
2021-06-30 21:08:25 +00:00
void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box,
struct perf_event *event);
void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
struct perf_event *event);
void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box);
void intel_generic_uncore_pci_disable_event(struct intel_uncore_box *box,
struct perf_event *event);
u64 intel_generic_uncore_pci_read_counter(struct intel_uncore_box *box,
struct perf_event *event);
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 edae1f06c2cd ("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: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Andi Kleen <ak@linux.intel.com> Link: https://lore.kernel.org/r/1625087320-194204-2-git-send-email-kan.liang@linux.intel.com
2021-06-30 21:08:25 +00:00
struct intel_uncore_type **
intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra);