#ifndef _INTEL_IMC_H
#define _INTEL_IMC_H
#include <sys/types.h>
#include <sys/bitmap.h>
#include <sys/list.h>
#include <sys/sunddi.h>
#ifdef __cplusplus
extern "C" {
#endif
#define IMC_MAX_SOCKETS 8
#define IMC_MAX_IMCPERSOCK 2
#define IMC_MAX_CHANPERMC 4
#define IMC_MAX_DIMMPERCHAN 3
#define IMC_MAX_RANK_DISABLE 4
#define IMC_MAX_PCIBUSES 3
#define IMC_NODEID_UBOX_MASK(x) ((x) & 0x7)
#define IMC_NODEID_IVY_BRD_UPPER(x) BITX(x, 3, 3)
#define IMC_NODEID_IVY_BRD_LOWER(x) BITX(x, 1, 0)
#define IMC_NODEID_IVY_BRD_HA(x) BITX(x, 2, 2)
#define IMC_MCMTR_CLOSED_PAGE(x) BITX(x, 0, 0)
#define IMC_MCMTR_LOCKSTEP(x) BITX(x, 1, 1)
#define IMC_MCMTR_ECC_ENABLED(x) BITX(x, 2, 2)
#define IMC_MCMTR_DDR4_HAS_BRD(x) BITX(x, 14, 14)
#define IMC_REG_MC_MTR0 0x80
#define IMC_REG_MC_MTR1 0x84
#define IMC_REG_MC_MTR2 0x88
#define IMC_MTR_CA_WIDTH(x) BITX(x, 1, 0)
#define IMC_MTR_CA_BASE 10
#define IMC_MTR_CA_MIN 10
#define IMC_MTR_CA_MAX 12
#define IMC_MTR_RA_WIDTH(x) BITX(x, 4, 2)
#define IMC_MTR_RA_BASE 12
#define IMC_MTR_RA_MIN 13
#define IMC_MTR_RA_MAX 18
#define IMC_MTR_DENSITY_IVY_BRD(x) BITX(x, 6, 5)
#define IMC_MTR_DENSITY_SKX(x) BITX(x, 7, 5)
#define IMC_MTR_WIDTH_IVB_HAS(x) BITX(x, 8, 7)
#define IMC_MTR_WIDTH_BRD_SKX(x) BITX(x, 9, 8)
#define IMC_MTR_DDR_RANKS(x) BITX(x, 13, 12)
#define IMC_MTR_DDR_RANKS_MAX 4
#define IMC_MTR_DDR_RANKS_MAX_HAS_SKX 8
#define IMC_MTR_PRESENT_SNB_BRD(x) BITX(x, 14, 14)
#define IMC_MTR_PRESENT_SKYLAKE(x) BITX(x, 15, 15)
#define IMC_MTR_RANK_DISABLE(x) BITX(x, 19, 16)
#define IMC_MTR_DDR4_ENABLE_HAS_BRD(x) BITX(x, 20, 20)
#define IMC_MTR_HDRL_HAS_SKX(x) BITX(x, 21, 21)
#define IMC_MTR_HDRL_PARITY_HAS_SKX(x) BITX(x, 22, 22)
#define IMC_MTR_3DSRANKS_HAS_SKX(x) BITX(x, 24, 23)
#define IMC_MC_MIRROR_SNB_BRD(x) BITX(x, 0, 0)
#define IMC_MAX_SAD_RULES 24
#define IMC_MAX_SAD_INTERLEAVE 8
#define IMC_MAX_SAD_MCROUTES 6
#define IMC_REG_SKX_SAD_MC_ROUTE_TABLE 0xb4
#define IMC_MC_ROUTE_RING_BITS 3
#define IMC_MC_ROUTE_RING_MASK 0x7
#define IMC_MC_ROUTE_CHAN_BITS 2
#define IMC_MC_ROUTE_CHAN_MASK 0x3
#define IMC_MC_ROUTE_CHAN_OFFSET 18
#define IMC_TOLM_SNB_IVY_MASK 0xf
#define IMC_TOLM_SNB_IVY_SHIFT 28
#define IMC_TOHM_SNB_IVY_MASK 0x1fffff
#define IMC_TOHM_SNB_IVY_SHIFT 25
#define IMC_TOLM_HAS_SKX_MASK 0xfc000000
#define IMC_TOLM_HAS_SKY_EXCL (1 << 26)
#define IMC_TOHM_LOW_HAS_SKX_MASK 0xfc000000
#define IMC_TOHM_HAS_SKY_EXCL (1 << 26)
#define IMC_SAD_DRAM_RULE_ENABLE(x) BITX(x, 0, 0)
#define IMC_SAD_DRAM_INTERLEAVE_SNB_BRD(x) BITX(x, 1, 1)
#define IMC_SAD_DRAM_INTERLEAVE_SNB_BRD_8t6XOR 0
#define IMC_SAD_DRAM_INTERLEAVE_SNB_BRD_8t6 1
#define IMC_SAD_DRAM_INTERLEAVE_SKX(x) BITX(x, 2, 1)
#define IMC_SAD_DRAM_INTERLEAVE_SKX_8t6 0
#define IMC_SAD_DRAM_INTERLEAVE_SKX_10t8 1
#define IMC_SAD_DRAM_INTERLEAVE_SKX_14t12 2
#define IMC_SAD_DRAM_INTERLEAVE_SKX_32t30 3
#define IMC_SAD_DRAM_ATTR_SNB_BRD(x) BITX(x, 3, 2)
#define IMC_SAD_DRAM_ATTR_SKX(x) BITX(x, 4, 3)
#define IMC_SAD_DRAM_ATTR_DRAM 0
#define IMC_SAD_DRAM_ATTR_MMCFG 1
#define IMC_SAD_DRAM_ATTR_NXM 2
#define IMC_SAD_DRAM_MOD23_SKX(x) BITX(x, 6, 5)
#define IMC_SAD_DRAM_MOD23_MOD3 0
#define IMC_SAD_DRAM_MOD23_MOD2_C01 1
#define IMC_SAD_DRAM_MOD23_MOD2_C12 2
#define IMC_SAD_DRAM_MOD23_MOD2_C02 3
#define IMC_SAD_DRAM_LIMIT_SNB_BRD(x) BITX(x, 25, 6)
#define IMC_SAD_DRAM_LIMIT_SKX(x) BITX(x, 26, 7)
#define IMC_SAD_DRAM_LIMIT_SHIFT 26
#define IMC_SAD_DRAM_LIMIT_EXCLUSIVE (1 << IMC_SAD_DRAM_LIMIT_SHIFT)
#define IMC_SAD_DRAM_A7_IVB_BRD(x) BITX(x, 26, 26)
#define IMC_SAD_DRAM_MOD3_SKX(x) BITX(x, 27, 27)
#define IMC_SAD_DRAM_MOD3_MODE_SKX(x) BITX(x, 31, 30)
#define IMC_SAD_DRAM_MOD3_MODE_45t6 0
#define IMC_SAD_DRAM_MOD3_MODE_45t8 1
#define IMC_SAD_DRAM_MOD3_MODE_45t12 2
#define IMC_SAD_ILEAVE_SNB_MASK 0x7
#define IMC_SAD_ILEAVE_SNB_LEN 3
#define IMC_SAD_ILEAVE_IVB_SKX_MASK 0xf
#define IMC_SAD_ILEAVE_IVB_SKX_LEN 4
#define IMC_SAD_ILEAVE_SKX_LOCAL(x) BITX(x, 3, 3)
#define IMC_SAD_ILEAVE_SKX_TARGET(x) BITX(x, 2, 0)
#define IMC_SAD_ILEAVE_SKX_MAX 0xf
#define IMC_MAX_TAD 2
#define IMC_MAX_TAD_RULES 12
#define IMC_MAX_TAD_TARGETS 4
#define IMC_SKX_WAYNESS_OFFSET 0x30
#define IMC_TAD_LIMIT(x) BITX(x, 31, 12)
#define IMC_TAD_LIMIT_SHIFT 26
#define IMC_TAD_LIMIT_EXCLUSIVE (1 << IMC_TAD_LIMIT_SHIFT)
#define IMC_TAD_SOCK_WAY(x) BITX(x, 11, 10)
#define IMC_TAD_SOCK_WAY_1 0
#define IMC_TAD_SOCK_WAY_2 1
#define IMC_TAD_SOCK_WAY_4 2
#define IMC_TAD_SOCK_WAY_8 3
#define IMC_TAD_CHAN_WAY(x) BITX(x, 9, 8)
#define IMC_TAD_TARG3(x) BITX(x, 7, 6)
#define IMC_TAD_TARG2(x) BITX(x, 5, 4)
#define IMC_TAD_TARG1(x) BITX(x, 3, 2)
#define IMC_TAD_TARG0(x) BITX(x, 1, 0)
#define IMC_TAD_SNB_BRD_NTARGETS 4
#define IMC_TAD_BASE_BASE(x) BITX(x, 31, 12)
#define IMC_TAD_BASE_SHIFT 26
#define IMC_TAD_BASE_CHAN_GRAN(x) BITX(x, 7, 6)
#define IMC_TAD_BASE_CHAN_GRAN_64B 0
#define IMC_TAD_BASE_CHAN_GRAN_256B 1
#define IMC_TAD_BASE_CHAN_GRAN_4KB 2
#define IMC_TAD_BASE_SOCK_GRAN(x) BITX(x, 5, 4)
#define IMC_TAD_BASE_SOCK_GRAN_64B 0
#define IMC_TAD_BASE_SOCK_GRAN_256B 1
#define IMC_TAD_BASE_SOCK_GRAN_4KB 2
#define IMC_TAD_BASE_SOCK_GRAN_1GB 3
#define IMC_TADCHAN_OFFSET_SNB_BRD(x) BITX(x, 25, 6)
#define IMC_TADCHAN_OFFSET_SKX(x) BITX(x, 23, 4)
#define IMC_TADCHAN_OFFSET_SHIFT 26
#define IMC_TAD_SYSDEF_LOCKSTEP(x) BITX(x, 7, 7)
#define IMC_TAD_SYSDEF2_SHIFTUP(x) BITX(x, 22, 22)
#define IMC_TAD_SYSDEF2_CHANHASH(x) BITX(x, 21, 21)
#define IMC_MAX_RANK_WAYS 5
#define IMC_MAX_RANK_INTERLEAVES 8
#define IMC_RIR_WAYNESS_ENABLED(x) BITX(x, 31, 31)
#define IMC_RIR_WAYNESS_WAY(x) BITX(x, 29, 28)
#define IMC_RIR_LIMIT_HAS_SKX(x) BITX(x, 11, 1)
#define IMC_RIR_LIMIT_SNB_IVB(x) BITX(x, 10, 1)
#define IMC_RIR_LIMIT_SHIFT 29
#define IMC_RIR_LIMIT_EXCLUSIVE (1 << IMC_RIR_LIMIT_SHIFT)
#define IMC_RIR_OFFSET_TARGET_BRD(x) BITX(x, 23, 20)
#define IMC_RIR_OFFSET_TARGET(x) BITX(x, 19, 16)
#define IMC_RIR_OFFSET_OFFSET_HAS_SKX(x) BITX(x, 15, 2)
#define IMC_RIR_OFFSET_OFFSET_SNB_IVB(x) BITX(x, 14, 2)
#define IMC_RIR_OFFSET_SHIFT 29
#define IMC_PAGE_BITS_CLOSED 6
#define IMC_PAGE_BITS_OPEN 13
#define IMC_UBOX_CPUBUSNO_0(x) BITX(x, 7, 0)
#define IMC_UBOX_CPUBUSNO_1(x) BITX(x, 15, 8)
#define IMC_UBOX_CPUBUSNO_2(x) BITX(x, 23, 16)
typedef enum {
IMC_GEN_UNKNOWN = 0,
IMC_GEN_SANDY,
IMC_GEN_IVY,
IMC_GEN_HASWELL,
IMC_GEN_BROADWELL,
IMC_GEN_SKYLAKE
} imc_gen_t;
typedef struct imc_gen_data {
uint_t igd_max_sockets;
uint_t igd_max_imcs;
uint_t igd_max_channels;
uint_t igd_max_dimms;
uint_t igd_max_ranks;
uint_t igd_mtr_offsets[IMC_MAX_DIMMPERCHAN];
uint_t igd_mcmtr_offset;
uint_t igd_topo_offset;
uint_t igd_num_mcroutes;
uint_t igd_tolm_offset;
uint_t igd_tohm_low_offset;
uint_t igd_tohm_hi_offset;
uint_t igd_sad_dram_offset;
uint_t igd_sad_ndram_rules;
uint_t igd_sad_nodeid_offset;
uint_t igd_tad_nrules;
uint_t igd_tad_rule_offset;
uint_t igd_tad_chan_offset;
uint_t igd_tad_sysdef;
uint_t igd_tad_sysdef2;
uint_t igd_mc_mirror;
uint_t igd_rir_nways;
uint_t igd_rir_way_offset;
uint_t igd_rir_nileaves;
uint_t igd_rir_ileave_offset;
uint_t igd_ubox_cpubusno_offset;
} imc_gen_data_t;
typedef enum {
IMC_TYPE_UNKNOWN = 0,
IMC_TYPE_MC0_M2M,
IMC_TYPE_MC1_M2M,
IMC_TYPE_MC0_MAIN0,
IMC_TYPE_MC0_MAIN1,
IMC_TYPE_MC1_MAIN0,
IMC_TYPE_MC1_MAIN1,
IMC_TYPE_MC0_CHANNEL0,
IMC_TYPE_MC0_CHANNEL1,
IMC_TYPE_MC0_CHANNEL2,
IMC_TYPE_MC0_CHANNEL3,
IMC_TYPE_MC1_CHANNEL0,
IMC_TYPE_MC1_CHANNEL1,
IMC_TYPE_MC1_CHANNEL2,
IMC_TYPE_MC1_CHANNEL3,
IMC_TYPE_SAD_DRAM,
IMC_TYPE_SAD_MMIO,
IMC_TYPE_SAD_MISC,
IMC_TYPE_VTD_MISC,
IMC_TYPE_SAD_MCROUTE,
IMC_TYPE_UBOX,
IMC_TYPE_UBOX_CPUBUSNO,
IMC_TYPE_HA0,
IMC_TYPE_HA1,
} imc_type_t;
#ifdef _KERNEL
typedef struct imc_stub_table {
imc_gen_t imcs_gen;
imc_type_t imcs_type;
uint16_t imcs_devid;
uint16_t imcs_pcidev;
uint16_t imcs_pcifunc;
const char *imcs_desc;
} imc_stub_table_t;
typedef struct imc_stub {
avl_node_t istub_link;
dev_info_t *istub_dip;
uint16_t istub_vid;
uint16_t istub_did;
uint16_t istub_bus;
uint16_t istub_dev;
uint16_t istub_func;
ddi_acc_handle_t istub_cfgspace;
const imc_stub_table_t *istub_table;
} imc_stub_t;
#else
typedef struct imc_stub {
void *istub_unused;
} imc_stub_t;
#endif
typedef enum {
IMC_F_UNSUP_PLATFORM = (1 << 0),
IMC_F_SCAN_DISPATCHED = (1 << 1),
IMC_F_SCAN_COMPLETE = (1 << 2),
IMC_F_ATTACH_DISPATCHED = (1 << 3),
IMC_F_ATTACH_COMPLETE = (1 << 4),
IMC_F_MCREG_FAILED = (1 << 5),
IMC_F_VALIDATE_FAILED = (1 << 6)
} imc_flags_t;
#define IMC_F_ALL_FLAGS (IMC_F_UNSUP_PLATFORM | IMC_F_SCAN_DISPATCHED | \
IMC_F_SCAN_COMPLETE | IMC_F_ATTACH_DISPATCHED | IMC_F_ATTACH_COMPLETE | \
IMC_F_MCREG_FAILED | IMC_F_VALIDATE_FAILED)
typedef enum imc_dimm_type {
IMC_DIMM_UNKNOWN,
IMC_DIMM_DDR3,
IMC_DIMM_DDR4,
IMC_DIMM_NVDIMM
} imc_dimm_type_t;
typedef enum imc_dimm_valid {
IMC_DIMM_V_VALID = 0,
IMC_DIMM_V_BAD_PCI_READ = (1 << 0),
IMC_DIMM_V_BAD_ROWS = (1 << 1),
IMC_DIMM_V_BAD_COLUMNS = (1 << 2),
IMC_DIMM_V_BAD_DENSITY = (1 << 3),
IMC_DIMM_V_BAD_WIDTH = (1 << 4),
IMC_DIMM_V_BAD_RANKS = (1 << 5)
} imc_dimm_valid_t;
typedef struct imc_dimm {
imc_dimm_valid_t idimm_valid;
boolean_t idimm_present;
uint8_t idimm_3dsranks;
boolean_t idimm_hdrl_parity;
boolean_t idimm_hdrl;
boolean_t idimm_ranks_disabled[IMC_MAX_RANK_DISABLE];
uint8_t idimm_nbanks;
uint8_t idimm_nranks;
uint8_t idimm_width;
uint8_t idimm_density;
uint8_t idimm_nrows;
uint8_t idimm_ncolumns;
uint64_t idimm_size;
uint32_t idimm_mtr;
} imc_dimm_t;
typedef struct imc_rank_ileave_entry {
uint8_t irle_target;
uint64_t irle_offset;
} imc_rank_ileave_entry_t;
typedef struct imc_rank_ileave {
boolean_t irle_enabled;
uint32_t irle_raw;
uint8_t irle_nways;
uint8_t irle_nwaysbits;
uint64_t irle_limit;
uint_t irle_nentries;
imc_rank_ileave_entry_t irle_entries[IMC_MAX_RANK_INTERLEAVES];
} imc_rank_ileave_t;
typedef enum imc_channel_valid {
IMC_CHANNEL_V_VALID = 0,
IMC_CHANNEL_V_BAD_PCI_READ = 1 << 0,
} imc_channel_valid_t;
typedef struct imc_channel {
imc_channel_valid_t ich_valid;
imc_stub_t *ich_desc;
uint_t ich_ndimms;
imc_dimm_t ich_dimms[IMC_MAX_DIMMPERCHAN];
uint_t ich_ntad_offsets;
uint32_t ich_tad_offsets_raw[IMC_MAX_TAD_RULES];
uint64_t ich_tad_offsets[IMC_MAX_TAD_RULES];
uint_t ich_nrankileaves;
imc_rank_ileave_t ich_rankileaves[IMC_MAX_RANK_WAYS];
} imc_channel_t;
typedef struct imc_controller {
imc_stub_t *icn_main0;
imc_stub_t *icn_main1;
imc_stub_t *icn_m2m;
boolean_t icn_invalid;
imc_dimm_type_t icn_dimm_type;
boolean_t icn_ecc;
boolean_t icn_lockstep;
boolean_t icn_closed;
uint32_t icn_topo;
uint_t icn_nchannels;
imc_channel_t icn_channels[IMC_MAX_CHANPERMC];
} imc_mc_t;
typedef enum imc_sad_rule_type {
IMC_SAD_TYPE_DRAM,
IMC_SAD_TYPE_MMCFG,
IMC_SAD_TYPE_NXM
} imc_sad_rule_type_t;
typedef enum imc_sad_rule_imode {
IMC_SAD_IMODE_8t6,
IMC_SAD_IMODE_8t6XOR,
IMC_SAD_IMODE_10t8,
IMC_SAD_IMODE_14t12,
IMC_SAD_IMODE_32t30
} imc_sad_rule_imode_t;
typedef enum imc_sad_rule_mod_mode {
IMC_SAD_MOD_MODE_NONE,
IMC_SAD_MOD_MODE_45t6,
IMC_SAD_MOD_MODE_45t8,
IMC_SAD_MOD_MODE_45t12
} imc_sad_rule_mod_mode_t;
typedef enum imc_sad_rule_mod_type {
IMC_SAD_MOD_TYPE_NONE,
IMC_SAD_MOD_TYPE_MOD3,
IMC_SAD_MOD_TYPE_MOD2_01,
IMC_SAD_MOD_TYPE_MOD2_12,
IMC_SAD_MOD_TYPE_MOD2_02
} imc_sad_rule_mod_type_t;
typedef struct imc_sad_mcroute_entry {
uint8_t ismce_imc;
uint8_t ismce_pchannel;
} imc_sad_mcroute_entry_t;
typedef struct imc_sad_mcroute_table {
uint32_t ismc_raw_mcroute;
uint_t ismc_nroutes;
imc_sad_mcroute_entry_t ismc_mcroutes[IMC_MAX_SAD_MCROUTES];
} imc_sad_mcroute_table_t;
typedef struct imc_sad_rule {
uint32_t isr_raw_dram;
uint32_t isr_raw_interleave;
boolean_t isr_enable;
boolean_t isr_a7mode;
boolean_t isr_need_mod3;
uint64_t isr_limit;
imc_sad_rule_type_t isr_type;
imc_sad_rule_imode_t isr_imode;
imc_sad_rule_mod_mode_t isr_mod_mode;
imc_sad_rule_mod_type_t isr_mod_type;
uint_t isr_ntargets;
uint8_t isr_targets[IMC_MAX_SAD_INTERLEAVE];
} imc_sad_rule_t;
typedef enum imc_sad_flags {
IMC_SAD_MCROUTE_VALID = 1 << 0,
} imc_sad_flags_t;
typedef enum imc_sad_valid {
IMC_SAD_V_VALID = 0,
IMC_SAD_V_BAD_PCI_READ = 1 << 0,
IMC_SAD_V_BAD_MCROUTE = 1 << 1,
IMC_SAD_V_BAD_DRAM_ATTR = 1 << 2,
IMC_SAD_V_BAD_MOD3 = 1 << 3,
} imc_sad_valid_t;
typedef struct imc_sad {
imc_sad_flags_t isad_flags;
imc_sad_valid_t isad_valid;
imc_stub_t *isad_dram;
imc_stub_t *isad_mmio;
imc_stub_t *isad_tolh;
uint64_t isad_tolm;
uint64_t isad_tohm;
uint_t isad_nrules;
imc_sad_rule_t isad_rules[IMC_MAX_SAD_RULES];
imc_sad_mcroute_table_t isad_mcroute;
} imc_sad_t;
typedef enum imc_tad_gran {
IMC_TAD_GRAN_64B = 0,
IMC_TAD_GRAN_256B,
IMC_TAD_GRAN_4KB,
IMC_TAD_GRAN_1GB
} imc_tad_gran_t;
typedef struct imc_tad_rule {
uint64_t itr_base;
uint64_t itr_limit;
uint32_t itr_raw;
uint32_t itr_raw_gran;
uint8_t itr_sock_way;
uint8_t itr_chan_way;
imc_tad_gran_t itr_sock_gran;
imc_tad_gran_t itr_chan_gran;
uint_t itr_ntargets;
uint8_t itr_targets[IMC_MAX_TAD_TARGETS];
} imc_tad_rule_t;
typedef enum imc_tad_valid {
IMC_TAD_V_VALID = 1 << 0,
IMC_TAD_V_BAD_PCI_READ = 1 << 1,
IMC_TAD_V_BAD_CHAN_GRAN = 1 << 2
} imc_tad_valid_t;
typedef enum imc_tad_flags {
IMC_TAD_FLAG_CHANSHIFT = 1 << 0,
IMC_TAD_FLAG_CHANHASH = 1 << 1,
IMC_TAD_FLAG_MIRROR = 1 << 2,
IMC_TAD_FLAG_LOCKSTEP = 1 << 3
} imc_tad_flags_t;
typedef struct imc_tad {
imc_tad_valid_t itad_valid;
imc_stub_t *itad_stub;
imc_tad_flags_t itad_flags;
uint_t itad_nrules;
imc_tad_rule_t itad_rules[IMC_MAX_TAD_RULES];
} imc_tad_t;
typedef enum imc_socket_valid {
IMC_SOCKET_V_VALID = 0,
IMC_SOCKET_V_BAD_NODEID = 1 << 0
} imc_socket_valid_t;
typedef struct imc_socket {
imc_socket_valid_t isock_valid;
uint_t isock_bus[IMC_MAX_PCIBUSES];
uint_t isock_nbus;
uint_t isock_gen;
nvlist_t *isock_nvl;
char *isock_buf;
size_t isock_buflen;
imc_sad_t isock_sad;
uint_t isock_ntad;
imc_tad_t isock_tad[IMC_MAX_TAD];
imc_stub_t *isock_ubox;
imc_stub_t *isock_cpubusno;
uint32_t isock_nodeid;
uint_t isock_nimc;
imc_mc_t isock_imcs[IMC_MAX_IMCPERSOCK];
} imc_socket_t;
typedef struct imc {
#ifdef _KERNEL
dev_info_t *imc_dip;
kmutex_t imc_lock;
imc_flags_t imc_flags;
const imc_gen_data_t *imc_gen_data;
ddi_taskq_t *imc_taskq;
uint_t imc_nscanned;
avl_tree_t imc_stubs;
nvlist_t *imc_decoder_dump;
char *imc_decoder_buf;
size_t imc_decoder_len;
#endif
imc_gen_t imc_gen;
uint_t imc_nsockets;
imc_socket_t imc_sockets[IMC_MAX_SOCKETS];
#ifdef _KERNEL
imc_socket_t *imc_spointers[IMC_MAX_SOCKETS];
imc_stub_t *imc_gvtd_misc;
#endif
} imc_t;
typedef enum imc_decode_failure {
IMC_DECODE_F_NONE = 0,
IMC_DECODE_F_LEGACY_RANGE,
IMC_DECODE_F_BAD_SOCKET,
IMC_DECODE_F_BAD_SAD,
IMC_DECODE_F_OUTSIDE_DRAM,
IMC_DECODE_F_NO_SAD_RULE,
IMC_DECODE_F_BAD_SAD_INTERLEAVE,
IMC_DECODE_F_BAD_REMOTE_MC_ROUTE,
IMC_DECODE_F_SAD_SEARCH_LOOP,
IMC_DECODE_F_SAD_BAD_MOD,
IMC_DECODE_F_SAD_BAD_SOCKET,
IMC_DECODE_F_SAD_BAD_TAD,
IMC_DECODE_F_NO_TAD_RULE,
IMC_DECODE_F_TAD_3_ILEAVE,
IMC_DECODE_F_TAD_BAD_TARGET_INDEX,
IMC_DECODE_F_BAD_CHANNEL_ID,
IMC_DECODE_F_BAD_CHANNEL_TAD_OFFSET,
IMC_DECODE_F_NO_RIR_RULE,
IMC_DECODE_F_BAD_RIR_ILEAVE_TARGET,
IMC_DECODE_F_BAD_DIMM_INDEX,
IMC_DECODE_F_DIMM_NOT_PRESENT,
IMC_DECODE_F_BAD_DIMM_RANK,
IMC_DECODE_F_CHANOFF_UNDERFLOW,
IMC_DECODE_F_RANKOFF_UNDERFLOW,
} imc_decode_failure_t;
typedef struct imc_decode_state {
imc_decode_failure_t ids_fail;
uint64_t ids_fail_data;
uint64_t ids_pa;
uint64_t ids_chanaddr;
uint64_t ids_rankaddr;
uint32_t ids_nodeid;
uint32_t ids_tadid;
uint32_t ids_channelid;
uint32_t ids_physrankid;
uint32_t ids_dimmid;
uint32_t ids_rankid;
const imc_socket_t *ids_socket;
const imc_sad_t *ids_sad;
const imc_sad_rule_t *ids_sad_rule;
const imc_tad_t *ids_tad;
const imc_tad_rule_t *ids_tad_rule;
const imc_mc_t *ids_mc;
const imc_channel_t *ids_chan;
const imc_rank_ileave_t *ids_rir;
const imc_dimm_t *ids_dimm;
} imc_decode_state_t;
#ifdef _KERNEL
extern int imc_attach_stub(dev_info_t *, ddi_attach_cmd_t);
extern int imc_detach_stub(dev_info_t *, ddi_detach_cmd_t);
extern void imc_decoder_init(imc_t *);
extern nvlist_t *imc_dump_decoder(imc_t *);
#else
extern boolean_t imc_restore_decoder(nvlist_t *, imc_t *);
#endif
extern boolean_t imc_decode_pa(const imc_t *, uint64_t, imc_decode_state_t *);
#ifdef __cplusplus
}
#endif
#endif