/*
 * Contributed by Stephane Eranian <eranian@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * This file is part of libpfm, a performance monitoring support library for
 * applications on Linux.
 *
 * PMU: spr_unc_imc (SapphireRapids Uncore IMC)
 * Based on Intel JSON event table version   : 1.17
 * Based on Intel JSON event table published : 11/09/2023
 */
static const intel_x86_umask_t spr_unc_m_act_count[]={
  { .uname   = "ALL",
    .udesc   = "Activate due to read, write, underfill, or bypass",
    .ucode   = 0xff00ull,
    .uflags  = INTEL_X86_DFL,
  },
};

static const intel_x86_umask_t spr_unc_m_cas_count[]={
  { .uname   = "ALL",
    .udesc   = "All DRAM CAS commands issued",
    .ucode   = 0xff00ull,
    .uflags  = INTEL_X86_NCOMBO | INTEL_X86_DFL,
  },
  { .uname   = "PCH0",
    .udesc   = "Pseudo Channel 0 (experimental)",
    .ucode   = 0x4000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PCH1",
    .udesc   = "Pseudo Channel 1 (experimental)",
    .ucode   = 0x8000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD",
    .udesc   = "All DRAM read CAS commands issued (including underfills)",
    .ucode   = 0xcf00ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_PRE_REG",
    .udesc   = "DRAM RD_CAS and WR_CAS Commands. (experimental)",
    .ucode   = 0xc200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_PRE_UNDERFILL",
    .udesc   = "DRAM RD_CAS and WR_CAS Commands. (experimental)",
    .ucode   = 0xc800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_REG",
    .udesc   = "All DRAM read CAS commands issued (does not include underfills) (experimental)",
    .ucode   = 0xc100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_UNDERFILL",
    .udesc   = "DRAM underfill read CAS commands issued (experimental)",
    .ucode   = 0xc400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR",
    .udesc   = "All DRAM write CAS commands issued",
    .ucode   = 0xf000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_NONPRE",
    .udesc   = "DRAM WR_CAS commands w/o auto-pre (experimental)",
    .ucode   = 0xd000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_PRE",
    .udesc   = "DRAM RD_CAS and WR_CAS Commands. (experimental)",
    .ucode   = 0xe000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_cas_issued_req_len[]={
  { .uname   = "PCH0",
    .udesc   = "Pseudo Channel 0 (experimental)",
    .ucode   = 0x4000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PCH1",
    .udesc   = "Pseudo Channel 1 (experimental)",
    .ucode   = 0x8000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_32B",
    .udesc   = "Read CAS Command in Interleaved Mode (32B) (experimental)",
    .ucode   = 0xc800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_64B",
    .udesc   = "Read CAS Command in Regular Mode (64B) in Pseudochannel 0 (experimental)",
    .ucode   = 0xc100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_UFILL_32B",
    .udesc   = "Underfill Read CAS Command in Interleaved Mode (32B) (experimental)",
    .ucode   = 0xd000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_UFILL_64B",
    .udesc   = "Underfill Read CAS Command in Regular Mode (64B) in Pseudochannel 1 (experimental)",
    .ucode   = 0xc200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_32B",
    .udesc   = "Write CAS Command in Interleaved Mode (32B) (experimental)",
    .ucode   = 0xe000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_64B",
    .udesc   = "Write CAS Command in Regular Mode (64B) in Pseudochannel 0 (experimental)",
    .ucode   = 0xc400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_pcls[]={
  { .uname   = "RD",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x0500ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "TOTAL",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x0f00ull,
    .uflags  = INTEL_X86_NCOMBO | INTEL_X86_DFL,
  },
  { .uname   = "WR",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x0a00ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_pmm_rpq_occupancy[]={
  { .uname   = "ALL_SCH0",
    .udesc   = "PMM Read Pending Queue occupancy",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "ALL_SCH1",
    .udesc   = "PMM Read Pending Queue occupancy",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "GNT_WAIT_SCH0",
    .udesc   = "PMM Read Pending Queue Occupancy (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "GNT_WAIT_SCH1",
    .udesc   = "PMM Read Pending Queue Occupancy (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NO_GNT_SCH0",
    .udesc   = "PMM Read Pending Queue Occupancy (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NO_GNT_SCH1",
    .udesc   = "PMM Read Pending Queue Occupancy (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_pmm_wpq_occupancy[]={
  { .uname   = "ALL",
    .udesc   = "PMM Write Pending Queue Occupancy",
    .ucode   = 0x0300ull,
    .uflags  = INTEL_X86_NCOMBO | INTEL_X86_DFL,
  },
  { .uname   = "ALL_SCH0",
    .udesc   = "PMM Write Pending Queue Occupancy",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "ALL_SCH1",
    .udesc   = "PMM Write Pending Queue Occupancy",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "CAS",
    .udesc   = "PMM (for IXP) Write Pending Queue Occupancy (experimental)",
    .ucode   = 0x0c00ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PWR",
    .udesc   = "PMM (for IXP) Write Pending Queue Occupancy (experimental)",
    .ucode   = 0x3000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_power_cke_cycles[]={
  { .uname   = "LOW_0",
    .udesc   = "DIMM ID (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "LOW_1",
    .udesc   = "DIMM ID (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "LOW_2",
    .udesc   = "DIMM ID (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "LOW_3",
    .udesc   = "DIMM ID (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_power_crit_throttle_cycles[]={
  { .uname   = "SLOT0",
    .udesc   = "Throttle Cycles for Rank 0 (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "SLOT1",
    .udesc   = "Throttle Cycles for Rank 0 (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_pre_count[]={
  { .uname   = "ALL",
    .udesc   = "Precharge due to read, write, underfill, or PGT.",
    .ucode   = 0xff00ull,
    .uflags  = INTEL_X86_NCOMBO | INTEL_X86_DFL,
  },
  { .uname   = "PGT",
    .udesc   = "DRAM Precharge commands",
    .ucode   = 0x8800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PGT_PCH0",
    .udesc   = "Precharges from Page Table (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PGT_PCH1",
    .udesc   = "DRAM Precharge commands. (experimental)",
    .ucode   = 0x8000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD",
    .udesc   = "Precharge due to read on page miss",
    .ucode   = 0x1100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_PCH0",
    .udesc   = "Precharge due to read (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_PCH1",
    .udesc   = "DRAM Precharge commands. (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "UFILL",
    .udesc   = "DRAM Precharge commands. (experimental)",
    .ucode   = 0x4400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "UFILL_PCH0",
    .udesc   = "DRAM Precharge commands. (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "UFILL_PCH1",
    .udesc   = "DRAM Precharge commands. (experimental)",
    .ucode   = 0x4000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR",
    .udesc   = "Precharge due to write on page miss",
    .ucode   = 0x2200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_PCH0",
    .udesc   = "Precharge due to write (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_PCH1",
    .udesc   = "DRAM Precharge commands. (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_rdb_inserts[]={
  { .uname   = "PCH0",
    .udesc   = "Pseudo-channel 0",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PCH1",
    .udesc   = "Pseudo-channel 1",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_rdb_ne[]={
  { .uname   = "PCH0",
    .udesc   = "Pseudo-channel 0 (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PCH1",
    .udesc   = "Pseudo-channel 1 (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "ANY",
    .udesc   = "Read Data Buffer Not Empty any channel (experimental)",
    .ucode   = 0x0300ull,
    .uflags  = INTEL_X86_NCOMBO | INTEL_X86_DFL,
  },
};

static const intel_x86_umask_t spr_unc_m_rpq_inserts[]={
  { .uname   = "PCH0",
    .udesc   = "Pseudo-channel 0",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PCH1",
    .udesc   = "Pseudo-channel 1",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_accesses[]={
  { .uname   = "ACCEPTS",
    .udesc   = "Scoreboard accepts (experimental)",
    .ucode   = 0x0500ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_RD_CMPS",
    .udesc   = "Write Accepts (experimental)",
    .ucode   = 0x4000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_WR_CMPS",
    .udesc   = "Write Rejects (experimental)",
    .ucode   = 0x8000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_RD_CMPS",
    .udesc   = "FM read completions (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_WR_CMPS",
    .udesc   = "FM write completions (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_ACCEPTS",
    .udesc   = "Read Accepts (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_REJECTS",
    .udesc   = "Read Rejects (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "REJECTS",
    .udesc   = "Scoreboard rejects (experimental)",
    .ucode   = 0x0a00ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_ACCEPTS",
    .udesc   = "NM read completions (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WR_REJECTS",
    .udesc   = "NM write completions (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_canary[]={
  { .uname   = "ALLOC",
    .udesc   = "Alloc (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "DEALLOC",
    .udesc   = "Dealloc (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_RD_STARVED",
    .udesc   = "Near Mem Write Starved (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_TGR_WR_STARVED",
    .udesc   = "Far Mem Write Starved (experimental)",
    .ucode   = 0x8000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_WR_STARVED",
    .udesc   = "Far Mem Read Starved (experimental)",
    .ucode   = 0x4000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_RD_STARVED",
    .udesc   = "Valid (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_WR_STARVED",
    .udesc   = "Near Mem Read Starved (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "VLD",
    .udesc   = "Reject (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_inserts[]={
  { .uname   = "BLOCK_RDS",
    .udesc   = "Block region reads (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "BLOCK_WRS",
    .udesc   = "Block region writes (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM_RDS",
    .udesc   = "Persistent Mem reads (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM_WRS",
    .udesc   = "Persistent Mem writes (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RDS",
    .udesc   = "Reads (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "WRS",
    .udesc   = "Writes (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_occupancy[]={
  { .uname   = "BLOCK_RDS",
    .udesc   = "Block region reads (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "BLOCK_WRS",
    .udesc   = "Block region writes (experimental)",
    .ucode   = 0x4000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM_RDS",
    .udesc   = "Persistent Mem reads (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM_WRS",
    .udesc   = "Persistent Mem writes (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RDS",
    .udesc   = "Reads (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_pref_inserts[]={
  { .uname   = "ALL",
    .udesc   = "All (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO | INTEL_X86_DFL,
  },
  { .uname   = "DDR",
    .udesc   = "DDR4 (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM",
    .udesc   = "PMM (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_pref_occupancy[]={
  { .uname   = "ALL",
    .udesc   = "All (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "DDR",
    .udesc   = "DDR4 (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM",
    .udesc   = "Persistent Mem (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_reject[]={
  { .uname   = "CANARY",
    .udesc   = "Number of Scoreboard Requests Rejected (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "DDR_EARLY_CMP",
    .udesc   = "Number of Scoreboard Requests Rejected (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_ADDR_CNFLT",
    .udesc   = "FM requests rejected due to full address conflict (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_SET_CNFLT",
    .udesc   = "NM requests rejected due to set conflict (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PATROL_SET_CNFLT",
    .udesc   = "Patrol requests rejected due to set conflict (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_strv_dealloc[]={
  { .uname   = "FM_RD",
    .udesc   = "Far Mem Read - Set (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_TGR",
    .udesc   = "Near Mem Read - Clear (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_WR",
    .udesc   = "Far Mem Write - Set (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_RD",
    .udesc   = "Near Mem Read - Set (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_WR",
    .udesc   = "Near Mem Write - Set (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_strv_occ[]={
  { .uname   = "FM_RD",
    .udesc   = "Far Mem Read (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_TGR",
    .udesc   = "Near Mem Read - Clear (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "FM_WR",
    .udesc   = "Far Mem Write (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_RD",
    .udesc   = "Near Mem Read (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_WR",
    .udesc   = "Near Mem Write (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_sb_tagged[]={
  { .uname   = "DDR4_CMP",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NEW",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "OCC",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x8000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM0_CMP",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM1_CMP",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x2000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PMM2_CMP",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x4000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_HIT",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "RD_MISS",
    .udesc   = "TBD (experimental)",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_tagchk[]={
  { .uname   = "HIT",
    .udesc   = "2LM Tag check hit in near memory cache (DDR4)",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "MISS_CLEAN",
    .udesc   = "2LM Tag check miss, no data at this line",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "MISS_DIRTY",
    .udesc   = "2LM Tag check miss, existing data may be evicted to PMM",
    .ucode   = 0x0400ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_RD_HIT",
    .udesc   = "2LM Tag check hit due to memory read",
    .ucode   = 0x0800ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "NM_WR_HIT",
    .udesc   = "2LM Tag check hit due to memory write",
    .ucode   = 0x1000ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

static const intel_x86_umask_t spr_unc_m_wpq_inserts[]={
  { .uname   = "PCH0",
    .udesc   = "Pseudo-channel 0",
    .ucode   = 0x0100ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
  { .uname   = "PCH1",
    .udesc   = "Pseudo-channel 1",
    .ucode   = 0x0200ull,
    .uflags  = INTEL_X86_NCOMBO,
  },
};

#define RDB_E(n) \
  { .uname   = "RDB_"#n"_ELEM", \
    .udesc   = "Read buffer has "#n" element(s)", \
    .ucode   = 1ull << (n+8), \
    .uflags  = INTEL_X86_NCOMBO, \
  }
static const intel_x86_umask_t spr_unc_m_rdb_full[]={
	RDB_E(1),
	RDB_E(2),
	RDB_E(3),
	RDB_E(4),
	RDB_E(5),
	RDB_E(6),
	RDB_E(7),
	RDB_E(8),
	RDB_E(9),
	RDB_E(10),
	RDB_E(11),
	RDB_E(12),
	RDB_E(13),
	RDB_E(14),
	RDB_E(15),
	RDB_E(16),
	RDB_E(17),
	RDB_E(18),
	RDB_E(19),
	RDB_E(20),
	RDB_E(21),
	RDB_E(22),
	RDB_E(23),
	RDB_E(24),
};

static const intel_x86_entry_t intel_spr_unc_imc_pe[]={
  { .name   = "UNC_M_ACT_COUNT",
    .desc   = "Count Activation",
    .code   = 0x0002,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_act_count),
    .umasks = spr_unc_m_act_count,
  },
  { .name   = "UNC_M_CAS_COUNT",
    .desc   = "DRAM CAS commands issued",
    .code   = 0x0005,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_cas_count),
    .umasks = spr_unc_m_cas_count,
  },
  { .name   = "UNC_M_CAS_ISSUED_REQ_LEN",
    .desc   = "CAS Command in Regular Mode issued",
    .code   = 0x0006,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_cas_issued_req_len),
    .umasks = spr_unc_m_cas_issued_req_len,
  },
  { .name   = "UNC_M_CLOCKTICKS",
    .desc   = "IMC Clockticks at DCLK frequency",
    .code   = 0x0101,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_DRAM_PRE_ALL",
    .desc   = "DRAM Precharge All Commands (experimental)",
    .code   = 0x0044,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_HCLOCKTICKS",
    .desc   = "IMC Clockticks at HCLK frequency",
    .code   = 0x0001,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_PCLS",
    .desc   = "TBD",
    .code   = 0x00a0,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_pcls),
    .umasks = spr_unc_m_pcls,
  },
  { .name   = "UNC_M_PMM_RPQ_INSERTS",
    .desc   = "PMM Read Pending Queue inserts",
    .code   = 0x00e3,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_PMM_RPQ_OCCUPANCY",
    .desc   = "PMM Read Pending Queue occupancy",
    .code   = 0x00e0,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_pmm_rpq_occupancy),
    .umasks = spr_unc_m_pmm_rpq_occupancy,
  },
  { .name   = "UNC_M_PMM_WPQ_CYCLES_NE",
    .desc   = "PMM (for IXP) Write Queue Cycles Not Empty (experimental)",
    .code   = 0x00e5,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_PMM_WPQ_INSERTS",
    .desc   = "PMM Write Pending Queue inserts",
    .code   = 0x00e7,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_PMM_WPQ_OCCUPANCY",
    .desc   = "PMM Write Pending Queue Occupancy",
    .code   = 0x00e4,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_pmm_wpq_occupancy),
    .umasks = spr_unc_m_pmm_wpq_occupancy,
  },
  { .name   = "UNC_M_POWER_CHANNEL_PPD",
    .desc   = "Channel PPD Cycles (experimental)",
    .code   = 0x0085,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_POWER_CKE_CYCLES",
    .desc   = "Cycles in CKE mode",
    .code   = 0x0047,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_power_cke_cycles),
    .umasks = spr_unc_m_power_cke_cycles,
  },
  { .name   = "UNC_M_POWER_CRIT_THROTTLE_CYCLES",
    .desc   = "Throttled Cycles",
    .code   = 0x0086,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_power_crit_throttle_cycles),
    .umasks = spr_unc_m_power_crit_throttle_cycles,
  },
  { .name   = "UNC_M_POWER_SELF_REFRESH",
    .desc   = "Clock-Enabled Self-Refresh (experimental)",
    .code   = 0x0043,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_PRE_COUNT",
    .desc   = "Count number of DRAM Precharge",
    .code   = 0x0003,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_pre_count),
    .umasks = spr_unc_m_pre_count,
  },
  { .name   = "UNC_M_RDB_FULL",
    .desc   = "Counts the number of cycles where the read buffer has greater than UMASK elements.  This includes reads to both DDR and PMEM.  NOTE: Umask must be set to the maximum number of elements in the queue (24 entries for SPR). (experimental)",
    .code   = 0x0019,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_rdb_full),
    .umasks = spr_unc_m_rdb_full,
  },
  { .name   = "UNC_M_RDB_INSERTS",
    .desc   = "Read Data Buffer Inserts",
    .code   = 0x0017,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_rdb_inserts),
    .umasks = spr_unc_m_rdb_inserts,
  },
  { .name   = "UNC_M_RDB_NE",
    .desc   = "Counts the number of cycles where there is at least one element in the read buffer.  This includes reads to both DDR and PMEM.",
    .code   = 0x0018,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_rdb_ne),
    .umasks = spr_unc_m_rdb_ne,
  },
  { .name   = "UNC_M_RDB_OCCUPANCY",
    .desc   = "Counts the number of elements in the read buffer, including reads to both DDR and PMEM. (experimental)",
    .code   = 0x001a,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_RPQ_INSERTS",
    .desc   = "Read Pending Queue Allocations",
    .code   = 0x0010,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_rpq_inserts),
    .umasks = spr_unc_m_rpq_inserts,
  },
  { .name   = "UNC_M_RPQ_OCCUPANCY_PCH0",
    .desc   = "Read Pending Queue Occupancy pseudo-channel 0",
    .code   = 0x0080,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_RPQ_OCCUPANCY_PCH1",
    .desc   = "Read Pending Queue Occupancy pseudo-channel 0",
    .code   = 0x0081,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_SB_ACCESSES",
    .desc   = "Scoreboard accesses",
    .code   = 0x00d2,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_accesses),
    .umasks = spr_unc_m_sb_accesses,
  },
  { .name   = "UNC_M_SB_CANARY",
    .desc   = "TBD",
    .code   = 0x00d9,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_canary),
    .umasks = spr_unc_m_sb_canary,
  },
  { .name   = "UNC_M_SB_CYCLES_FULL",
    .desc   = "Scoreboard Cycles Full (experimental)",
    .code   = 0x00d1,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_SB_CYCLES_NE",
    .desc   = "Scoreboard Cycles Not-Empty (experimental)",
    .code   = 0x00d0,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_SB_INSERTS",
    .desc   = "Scoreboard Inserts",
    .code   = 0x00d6,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_inserts),
    .umasks = spr_unc_m_sb_inserts,
  },
  { .name   = "UNC_M_SB_OCCUPANCY",
    .desc   = "Scoreboard Occupancy",
    .code   = 0x00d5,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_occupancy),
    .umasks = spr_unc_m_sb_occupancy,
  },
  { .name   = "UNC_M_SB_PREF_INSERTS",
    .desc   = "Scoreboard Prefetch Inserts",
    .code   = 0x00da,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_pref_inserts),
    .umasks = spr_unc_m_sb_pref_inserts,
  },
  { .name   = "UNC_M_SB_PREF_OCCUPANCY",
    .desc   = "Scoreboard Prefetch Occupancy",
    .code   = 0x00db,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_pref_occupancy),
    .umasks = spr_unc_m_sb_pref_occupancy,
  },
  { .name   = "UNC_M_SB_REJECT",
    .desc   = "Number of Scoreboard Requests Rejected",
    .code   = 0x00d4,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_reject),
    .umasks = spr_unc_m_sb_reject,
  },
  { .name   = "UNC_M_SB_STRV_ALLOC",
    .desc   = "TBD",
    .code   = 0x00d7,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_strv_dealloc), /* shared */
    .umasks = spr_unc_m_sb_strv_dealloc,
  },
  { .name   = "UNC_M_SB_STRV_DEALLOC",
    .desc   = "TBD",
    .code   = 0x00de,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_strv_dealloc),
    .umasks = spr_unc_m_sb_strv_dealloc,
  },
  { .name   = "UNC_M_SB_STRV_OCC",
    .desc   = "TBD",
    .code   = 0x00d8,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_strv_occ),
    .umasks = spr_unc_m_sb_strv_occ,
  },
  { .name   = "UNC_M_SB_TAGGED",
    .desc   = "TBD",
    .code   = 0x00dd,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_sb_tagged),
    .umasks = spr_unc_m_sb_tagged,
  },
  { .name   = "UNC_M_TAGCHK",
    .desc   = "2LM Tag check",
    .code   = 0x00d3,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_tagchk),
    .umasks = spr_unc_m_tagchk,
  },
  { .name   = "UNC_M_WPQ_INSERTS",
    .desc   = "Write Pending Queue Allocations",
    .code   = 0x0020,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
    .ngrp   = 1,
    .numasks= LIBPFM_ARRAY_SIZE(spr_unc_m_wpq_inserts),
    .umasks = spr_unc_m_wpq_inserts,
  },
  { .name   = "UNC_M_WPQ_OCCUPANCY_PCH0",
    .desc   = "Write Pending Queue Occupancy pseudo channel 0",
    .code   = 0x0082,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_WPQ_OCCUPANCY_PCH1",
    .desc   = "Write Pending Queue Occupancy pseudo channel 1",
    .code   = 0x0083,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_WPQ_READ_HIT",
    .desc   = "Write Pending Queue CAM Match (experimental)",
    .code   = 0x0023,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
  { .name   = "UNC_M_WPQ_WRITE_HIT",
    .desc   = "Write Pending Queue CAM Match (experimental)",
    .code   = 0x0024,
    .modmsk = SPR_UNC_IMC_ATTRS,
    .cntmsk = 0xfull,
  },
};
/* 44 events available */
