android_kernel_modules_leno.../debug_tools/vtunedk/include/lwpmudrv_struct.h

1086 lines
49 KiB
C

/*COPYRIGHT**
* -------------------------------------------------------------------------
* INTEL CORPORATION PROPRIETARY INFORMATION
* This software is supplied under the terms of the accompanying license
* agreement or nondisclosure agreement with Intel Corporation and may not
* be copied or disclosed except in accordance with the terms of that
* agreement.
* Copyright (C) 2007-2014 Intel Corporation. All Rights Reserved.
* -------------------------------------------------------------------------
**COPYRIGHT*/
#ifndef _LWPMUDRV_STRUCT_H_
#define _LWPMUDRV_STRUCT_H_
#if defined(__cplusplus)
extern "C" {
#endif
// processor execution modes
#define MODE_UNKNOWN 99
// the following defines must start at 0
#define MODE_64BIT 3
#define MODE_32BIT 2
#define MODE_16BIT 1
#define MODE_V86 0
// sampling methods
#define SM_RTC 2020 // real time clock
#define SM_VTD 2021 // OS Virtual Timer Device
#define SM_NMI 2022 // non-maskable interrupt time based
#define SM_EBS 2023 // event based
// sampling mechanism bitmap definitions
#define INTERRUPT_RTC 0x1
#define INTERRUPT_VTD 0x2
#define INTERRUPT_NMI 0x4
#define INTERRUPT_EBS 0x8
// eflags defines
#define EFLAGS_VM 0x00020000 // V86 mode
#define EFLAGS_IOPL0 0
#define EFLAGS_IOPL1 0x00001000
#define EFLAGS_IOPL2 0x00002000
#define EFLAGS_IOPL3 0x00003000
#define MAX_DEVICES 30
#define MAX_EMON_GROUPS 1000
#define MAX_PCI_BUSNO 256
#define MAX_PCI_DEVNO 32
#define MAX_PCI_FUNCNO 8
extern float freq_multiplier;
// Enumeration for invoking dispatch on multiple cpus or not
typedef enum {
DRV_MULTIPLE_INSTANCE = 0,
DRV_SINGLE_INSTANCE
} DRV_PROG_TYPE;
typedef struct DRV_CONFIG_NODE_S DRV_CONFIG_NODE;
typedef DRV_CONFIG_NODE *DRV_CONFIG;
struct DRV_CONFIG_NODE_S {
U32 size;
U32 num_events;
DRV_BOOL start_paused;
DRV_BOOL counting_mode;
U32 dispatch_id;
DRV_BOOL enable_chipset;
U32 num_chipset_events;
U32 chipset_offset;
DRV_BOOL enable_gfx;
DRV_BOOL enable_pwr;
DRV_BOOL emon_mode;
#if defined(DRV_IA32) || defined(DRV_EM64T)
U32 pebs_mode;
U32 pebs_capture;
DRV_BOOL collect_lbrs;
DRV_BOOL collect_callstacks;
DRV_BOOL debug_inject;
DRV_BOOL virt_phys_translation;
DRV_BOOL latency_capture;
U32 max_gp_counters;
DRV_BOOL htoff_mode;
DRV_BOOL power_capture;
U32 results_offset; // this is to store the offset for this device's results
DRV_BOOL eventing_ip_capture;
DRV_BOOL hle_capture;
U32 emon_unc_offset[MAX_EMON_GROUPS];
DRV_BOOL enable_p_state; // adding MPERF and APERF values at the end of the samples
DRV_BOOL enable_cp_mode; // enabling continuous profiling mode
#else
DRV_BOOL collect_ro;
#endif
S32 seed_name_len;
#if defined(DRV_IA32) || defined(DRV_EM64T)
U32 padding1;
#endif
U64 target_pid;
DRV_BOOL use_pcl;
DRV_BOOL enable_ebc;
DRV_BOOL enable_tbc;
#if defined(DRV_IA32) || defined(DRV_EM64T)
U32 ebc_group_id_offset;
#endif
union {
S8 *seed_name;
U64 dummy1;
} u1;
union {
S8 *cpu_mask;
U64 dummy2;
} u2;
U32 device_type;
DRV_BOOL ds_area_available;
#if defined(DRV_IA32) || defined(DRV_EM64T)
DRV_BOOL precise_ip_lbrs;
DRV_BOOL store_lbrs;
#endif
DRV_BOOL tsc_capture;
#if defined(DRV_IA32) || defined(DRV_EM64T)
U32 padding2;
#endif
};
#define DRV_CONFIG_size(cfg) (cfg)->size
#define DRV_CONFIG_num_events(cfg) (cfg)->num_events
#define DRV_CONFIG_start_paused(cfg) (cfg)->start_paused
#define DRV_CONFIG_counting_mode(cfg) (cfg)->counting_mode
#define DRV_CONFIG_dispatch_id(cfg) (cfg)->dispatch_id
#define DRV_CONFIG_enable_chipset(cfg) (cfg)->enable_chipset
#define DRV_CONFIG_num_chipset_events(cfg) (cfg)->num_chipset_events
#define DRV_CONFIG_chipset_offset(cfg) (cfg)->chipset_offset
#define DRV_CONFIG_enable_gfx(cfg) (cfg)->enable_gfx
#define DRV_CONFIG_enable_pwr(cfg) (cfg)->enable_pwr
#define DRV_CONFIG_emon_mode(cfg) (cfg)->emon_mode
#if defined(DRV_IA32) || defined(DRV_EM64T)
#define DRV_CONFIG_pebs_mode(cfg) (cfg)->pebs_mode
#define DRV_CONFIG_pebs_capture(cfg) (cfg)->pebs_capture
#define DRV_CONFIG_collect_lbrs(cfg) (cfg)->collect_lbrs
#define DRV_CONFIG_collect_callstacks(cfg) (cfg)->collect_callstacks
#define DRV_CONFIG_debug_inject(cfg) (cfg)->debug_inject
#define DRV_CONFIG_virt_phys_translation(cfg) (cfg)->virt_phys_translation
#define DRV_CONFIG_latency_capture(cfg) (cfg)->latency_capture
#define DRV_CONFIG_max_gp_counters(cfg) (cfg)->max_gp_counters
#define DRV_CONFIG_htoff_mode(cfg) (cfg)->htoff_mode
#define DRV_CONFIG_power_capture(cfg) (cfg)->power_capture
#define DRV_CONFIG_results_offset(cfg) (cfg)->results_offset
#define DRV_CONFIG_eventing_ip_capture(cfg) (cfg)->eventing_ip_capture
#define DRV_CONFIG_hle_capture(cfg) (cfg)->hle_capture
#define DRV_CONFIG_emon_unc_offset(cfg,grp_num) (cfg)->emon_unc_offset[grp_num]
#define DRV_CONFIG_enable_p_state(cfg) (cfg)->enable_p_state
#define DRV_CONFIG_enable_cp_mode(cfg) (cfg)->enable_cp_mode
#else
#define DRV_CONFIG_collect_ro(cfg) (cfg)->collect_ro
#endif
#define DRV_CONFIG_seed_name(cfg) (cfg)->u1.seed_name
#define DRV_CONFIG_seed_name_len(cfg) (cfg)->seed_name_len
#define DRV_CONFIG_cpu_mask(cfg) (cfg)->u2.cpu_mask
#define DRV_CONFIG_target_pid(cfg) (cfg)->target_pid
#define DRV_CONFIG_use_pcl(cfg) (cfg)->use_pcl
#define DRV_CONFIG_event_based_counts(cfg) (cfg)->enable_ebc
#define DRV_CONFIG_ebc_group_id_offset(cfg) (cfg)->ebc_group_id_offset
#define DRV_CONFIG_timer_based_counts(cfg) (cfg)->enable_tbc
#define DRV_CONFIG_device_type(cfg) (cfg)->device_type
#define DRV_CONFIG_ds_area_available(cfg) (cfg)->ds_area_available
#if defined(DRV_IA32) || defined(DRV_EM64T)
#define DRV_CONFIG_precise_ip_lbrs(cfg) (cfg)->precise_ip_lbrs
#define DRV_CONFIG_store_lbrs(cfg) (cfg)->store_lbrs
#endif
#define DRV_CONFIG_tsc_capture(cfg) (cfg)->tsc_capture
/*
* X86 processor code descriptor
*/
typedef struct CodeDescriptor_s {
union {
U32 lowWord; // low dword of descriptor
struct { // low broken out by fields
U16 limitLow; // segment limit 15:00
U16 baseLow; // segment base 15:00
} s1;
} u1;
union {
U32 highWord; // high word of descriptor
struct { // high broken out by bit fields
U32 baseMid : 8; // base 23:16
U32 accessed : 1; // accessed
U32 readable : 1; // readable
U32 conforming : 1; // conforming code segment
U32 oneOne : 2; // always 11
U32 dpl : 2; // Dpl
U32 pres : 1; // present bit
U32 limitHi : 4; // limit 19:16
U32 sys : 1; // available for use by system
U32 reserved_0 : 1; // reserved, always 0
U32 default_size : 1; // default operation size (1=32bit, 0=16bit)
U32 granularity : 1; // granularity (1=32 bit, 0=20 bit)
U32 baseHi : 8; // base hi 31:24
} s2;
} u2;
} CodeDescriptor;
/*
* Sample record. Size can be determined by looking at the header record.
* There can be up to 3 sections. The SampleFileHeader defines the presence
* of sections and their offsets. Within a sample file, all of the sample
* records have the same number of sections and the same size. However,
* different sample record sections and sizes can exist in different
* sample files. Since recording counters and the time stamp counter for
* each sample can be space consuming, the user can determine whether or not
* this information is kept at sample collection time.
*/
typedef struct SampleRecordPC_s { // Program Counter section
U64 descriptor_id;
union {
struct {
U64 iip; // IA64 interrupt instruction pointer
U64 ipsr; // IA64 interrupt processor status register
} s1;
struct {
U32 eip; // IA32 instruction pointer
U32 eflags; // IA32 eflags
CodeDescriptor csd; // IA32 code seg descriptor (8 bytes)
} s2;
} u1;
U16 cs; // IA32 cs (0 for IA64)
union {
U16 cpuAndOS; // cpu and OS info as one word
struct { // cpu and OS info broken out
U16 cpuNum : 12; // cpu number (0 - 4096)
U16 notVmid0 : 1; // win95, vmid0 flag (1 means NOT vmid 0)
U16 codeMode : 2; // processor mode, see MODE_ defines
U16 uncore_valid : 1; // identifies if the uncore count is valid
} s3;
} u2;
U32 tid; // OS thread ID (may get reused, see tidIsRaw)
U32 pidRecIndex; // process ID rec index (index into start of pid
// record section) .. can validly be 0 if not raw
// (array index). Use ReturnPid() to
// ..access this field .. (see pidRecIndexRaw)
union {
U32 bitFields2;
struct {
U32 mrIndex : 20; // module record index (index into start of
// module rec section) .. (see mrIndexNone)
U32 eventIndex : 8; // index into the Events section
U32 tidIsRaw : 1; // tid is raw OS tid
U32 IA64PC : 1; // TRUE=this is a IA64 PC sample record
U32 pidRecIndexRaw : 1; // pidRecIndex is raw OS pid
U32 mrIndexNone : 1; // no mrIndex (unknown module)
} s4;
} u3;
U64 tsc; // processor timestamp counter
} SampleRecordPC, *PSampleRecordPC;
#define SAMPLE_RECORD_descriptor_id(x) (x)->descriptor_id
#define SAMPLE_RECORD_iip(x) (x)->u1.s1.iip
#define SAMPLE_RECORD_ipsr(x) (x)->u1.s1.ipsr
#define SAMPLE_RECORD_eip(x) (x)->u1.s2.eip
#define SAMPLE_RECORD_eflags(x) (x)->u1.s2.eflags
#define SAMPLE_RECORD_csd(x) (x)->u1.s2.csd
#define SAMPLE_RECORD_cs(x) (x)->cs
#define SAMPLE_RECORD_cpu_and_os(x) (x)->u2.cpuAndOS
#define SAMPLE_RECORD_cpu_num(x) (x)->u2.s3.cpuNum
#define SAMPLE_RECORD_uncore_valid(x) (x)->u2.s3.uncore_valid
#define SAMPLE_RECORD_not_vmid0(x) (x)->u2.s3.notVmid0
#define SAMPLE_RECORD_code_mode(x) (x)->u2.s3.codeMode
#define SAMPLE_RECORD_tid(x) (x)->tid
#define SAMPLE_RECORD_pid_rec_index(x) (x)->pidRecIndex
#define SAMPLE_RECORD_bit_fields2(x) (x)->u3.bitFields2
#define SAMPLE_RECORD_mr_index(x) (x)->u3.s4.mrIndex
#define SAMPLE_RECORD_event_index(x) (x)->u3.s4.eventIndex
#define SAMPLE_RECORD_tid_is_raw(x) (x)->u3.s4.tidIsRaw
#define SAMPLE_RECORD_ia64_pc(x) (x)->u3.s4.IA64PC
#define SAMPLE_RECORD_pid_rec_index_raw(x) (x)->u3.s4.pidRecIndexRaw
#define SAMPLE_RECORD_mr_index_none(x) (x)->u3.s4.mrIndexNone
#define SAMPLE_RECORD_tsc(x) (x)->tsc
// end of SampleRecord sections
/*
* Module record. These are emitted whenever a DLL or EXE is loaded or unloaded.
* The filename fields may be 0 on an unload. The records reperesent a module for a
* certain span of time, delineated by the load / unload samplecounts.
* Note:
* The structure contains 64 bit fields which may cause the compiler to pad the
* length of the structure to an 8 byte boundary.
*/
typedef struct ModuleRecord_s {
U16 recLength; // total length of this record (including this length,
// always U32 multiple) output from sampler is variable
// length (pathname at end of record) sampfile builder moves
// path names to a separate "literal pool" area
// so that these records become fixed length, and can be treated
// as an array see modrecFixedLen in header
U16 segmentType : 2; // V86, 16, 32, 64 (see MODE_ defines), maybe inaccurate for Win95
// .. a 16 bit module may become a 32 bit module, inferred by
// ..looking at 1st sample record that matches the module selector
U16 loadEvent : 1; // 0 for load, 1 for unload
U16 processed : 1; // 0 for load, 1 for unload
U16 reserved0 : 12;
U16 selector; // code selector or V86 segment
U16 segmentNameLength; // length of the segment name if the segmentNameSet bit is set
U32 segmentNumber; // segment number, Win95 (and now Java) can have multiple pieces for one module
union {
U32 flags; // all the flags as one dword
struct {
U32 exe : 1; // this module is an exe
U32 globalModule : 1; // globally loaded module. There may be multiple
// module records for a global module, but the samples
// will only point to the 1st one, the others will be
// ignored. NT's Kernel32 is an example of this.
// REVISIT this??
U32 bogusWin95 : 1; // "bogus" win95 module. By bogus, we mean a
// module that has a pid of 0, no length and no base.
// Selector actually used as a 32 bit module.
U32 pidRecIndexRaw : 1; // pidRecIndex is raw OS pid
U32 sampleFound : 1; // at least one sample referenced this module
U32 tscUsed : 1; // tsc set when record written
U32 duplicate : 1; // 1st pass analysis has determined this is a
// duplicate load
U32 globalModuleTB5 : 1; // module mapped into all processes on system
U32 segmentNameSet : 1; // set if the segment name was collected
// (initially done for xbox collections)
U32 firstModuleRecInProcess : 1; // if the pidCreatesTrackedInModuleRecs flag is set
// in the SampleHeaderEx struct and this flag
// is set, the associated module indicates
// the beginning of a new process
U32 source : 1; // 0 for path in target system, 1 for path in host system (offloaded)
U32 reserved1 : 21;
} s1;
} u2;
U64 length64; // module length
U64 loadAddr64; // load address
U32 pidRecIndex; // process ID rec index (index into start of pid record section).
// .. (see pidRecIndexRaw). If pidRecIndex == 0 and pidRecIndexRaw == 1
// ..then this is a kernel or global module. Can validly
// ..be 0 if not raw (array index). Use ReturnPid() to access this
// ..field
U32 reserved2;
U64 unloadTsc; // TSC collected on an unload event
U32 path; // module path name (section offset on disk)
// ..when initally written by sampler name is at end of this
// ..struct, when merged with main file names are pooled at end
// ..of ModuleRecord Section so ModulesRecords can be
// ..fixed length
U16 pathLength; // path name length (inludes terminating \0)
U16 filenameOffset; // offset into path name of base filename
U32 segmentName; // offset to the segmentName from the beginning of the
// module section in a processed module section
// (s/b 0 in a raw module record)
// in a raw module record, the segment name will follow the
// module name and the module name's terminating NULL char
U32 reserved3;
U64 tsc; // time stamp counter module event occurred
U32 parent_pid; // Parent PID of the process
U32 reserved4;
} ModuleRecord;
#define MR_unloadTscSet(x,y) (x)->unloadTsc = (y)
#define MR_unloadTscGet(x) (x)->unloadTsc
// Accessor macros for ModuleRecord
#define MODULE_RECORD_rec_length(x) (x)->recLength
#define MODULE_RECORD_segment_type(x) (x)->segmentType
#define MODULE_RECORD_load_event(x) (x)->loadEvent
#define MODULE_RECORD_processed(x) (x)->processed
#define MODULE_RECORD_selector(x) (x)->selector
#define MODULE_RECORD_segment_name_length(x) (x)->segmentNameLength
#define MODULE_RECORD_segment_number(x) (x)->segmentNumber
#define MODULE_RECORD_flags(x) (x)->u2.flags
#define MODULE_RECORD_exe(x) (x)->u2.s1.exe
#define MODULE_RECORD_global_module(x) (x)->u2.s1.globalModule
#define MODULE_RECORD_bogus_win95(x) (x)->u2.s1.bogusWin95
#define MODULE_RECORD_pid_rec_index_raw(x) (x)->u2.s1.pidRecIndexRaw
#define MODULE_RECORD_sample_found(x) (x)->u2.s1.sampleFound
#define MODULE_RECORD_tsc_used(x) (x)->u2.s1.tscUsed
#define MODULE_RECORD_duplicate(x) (x)->u2.s1.duplicate
#define MODULE_RECORD_global_module_tb5(x) (x)->u2.s1.globalModuleTB5
#define MODULE_RECORD_segment_name_set(x) (x)->u2.s1.segmentNameSet
#define MODULE_RECORD_first_module_rec_in_process(x) (x)->u2.s1.firstModuleRecInProcess
#define MODULE_RECORD_source(x) (x)->u2.s1.source
#define MODULE_RECORD_length64(x) (x)->length64
#define MODULE_RECORD_load_addr64(x) (x)->loadAddr64
#define MODULE_RECORD_pid_rec_index(x) (x)->pidRecIndex
#define MODULE_RECORD_load_sample_count(x) (x)->u5.s2.loadSampleCount
#define MODULE_RECORD_unload_sample_count(x) (x)->u5.s2.unloadSampleCount
#define MODULE_RECORD_unload_tsc(x) (x)->unloadTsc
#define MODULE_RECORD_path(x) (x)->path
#define MODULE_RECORD_path_length(x) (x)->pathLength
#define MODULE_RECORD_filename_offset(x) (x)->filenameOffset
#define MODULE_RECORD_segment_name(x) (x)->segmentName
#define MODULE_RECORD_tsc(x) (x)->tsc
#define MODULE_RECORD_parent_pid(x) (x)->parent_pid
/*
* The VTSA_SYS_INFO_STRUCT information that is shared across kernel mode
* and user mode code, very specifically for tb5 file generation
*/
typedef enum {
GT_UNK = 0,
GT_PER_CPU,
GT_PER_CHIPSET,
GT_CPUID,
GT_NODE,
GT_SYSTEM,
GT_SAMPLE_RECORD_INFO
} GEN_ENTRY_TYPES;
typedef enum {
GST_UNK = 0,
GST_X86,
GST_ITANIUM,
GST_SA,//strong arm
GST_XSC,
GST_EM64T,
GST_CS860
} GEN_ENTRY_SUBTYPES;
typedef struct __fixed_size_pointer {
union {
U64 fs_force_alignment;
struct {
U32 fs_unused;
U32 is_ptr:1;
} s1;
} u1;
union {
U64 fs_offset;
void *fs_ptr;
} u2;
} VTSA_FIXED_SIZE_PTR;
#define VTSA_FIXED_SIZE_PTR_is_ptr(fsp) (fsp)->u1.s1.is_ptr
#define VTSA_FIXED_SIZE_PTR_fs_offset(fsp) (fsp)->u2.fs_offset
#define VTSA_FIXED_SIZE_PTR_fs_ptr(fsp) (fsp)->u2.fs_ptr
typedef struct __generic_array_header {
//
// Information realted to the generic header
//
U32 hdr_size; // size of this generic header
// (for versioning and real data starts
// after the header)
U32 next_field_hdr_padding; // make sure the next field is 8-byte aligned
//
// VTSA_FIXED_SIZE_PTR should always be on an 8-byte boundary...
//
// pointer to the next generic header if there is one
//
VTSA_FIXED_SIZE_PTR hdr_next_gen_hdr;
U32 hdr_reserved[7]; // padding for future use - force to 64 bytes...
//
// Information related to the array this header is describing
//
U32 array_num_entries;
U32 array_entry_size;
U16 array_type; // from the GEN_ENTRY_TYPES enumeration
U16 array_subtype; // from the GEN_ENTRY_SUBTYPES enumeration
} VTSA_GEN_ARRAY_HDR;
#define VTSA_GEN_ARRAY_HDR_hdr_size(gah) (gah)->hdr_size
#define VTSA_GEN_ARRAY_HDR_hdr_next_gen_hdr(gah) (gah)->hdr_next_gen_hdr
#define VTSA_GEN_ARRAY_HDR_array_num_entries(gah) (gah)->array_num_entries
#define VTSA_GEN_ARRAY_HDR_array_entry_size(gah) (gah)->array_entry_size
#define VTSA_GEN_ARRAY_HDR_array_type(gah) (gah)->array_type
#define VTSA_GEN_ARRAY_HDR_array_subtype(gah) (gah)->array_subtype
typedef struct __cpuid_x86 {
U32 cpuid_eax_input;
U32 cpuid_eax;
U32 cpuid_ebx;
U32 cpuid_ecx;
U32 cpuid_edx;
} VTSA_CPUID_X86;
#define VTSA_CPUID_X86_cpuid_eax_input(cid) (cid)->cpuid_eax_input
#define VTSA_CPUID_X86_cpuid_eax(cid) (cid)->cpuid_eax
#define VTSA_CPUID_X86_cpuid_ebx(cid) (cid)->cpuid_ebx
#define VTSA_CPUID_X86_cpuid_ecx(cid) (cid)->cpuid_ecx
#define VTSA_CPUID_X86_cpuid_edx(cid) (cid)->cpuid_edx
typedef struct __cpuid_ipf {
U64 cpuid_select;
U64 cpuid_val;
} VTSA_CPUID_IPF;
#define VTSA_CPUID_IPF_cpuid_select(cid) (cid)->cpuid_select
#define VTSA_CPUID_IPF_cpuid_val(cid) (cid)->cpuid_val
typedef struct __generic_per_cpu {
//
// per cpu information
//
U32 cpu_number; // cpu number (as defined by the OS)
U32 cpu_speed_mhz; // cpu speed (in Mhz)
U32 cpu_fsb_mhz; // Front Side Bus speed (in Mhz) (if known)
U32 cpu_cache_L2; // ??? USER: cpu L2 (marketing definition) cache size (if known)
//
// And pointer to other structures. Keep this on an 8-byte boundary
//
// "pointer" to generic array header that should contain
// cpuid information for this cpu
//
VTSA_FIXED_SIZE_PTR cpu_cpuid_array;
S64 cpu_tsc_offset; // TSC offset from CPU 0 computed as (TSC CPU N - TSC CPU 0)
//
// intel processor number (from mkting).
// Currently 3 decimal digits (3xx, 5xx and 7xx)
//
U32 cpu_intel_processor_number;
U32 cpu_cache_L3; // ??? USER: cpu L3 (marketing definition) cache size (if known)
U64 platform_id;
//
// package/mapping information
//
// The hierarchy for uniquely identifying a logical processor
// in a system is node number/id (from the node structure),
// package number, core number, and thread number.
// Core number is for identifying a core within a package.
//
// Actually, on Itanium getting all this information is
// pretty involved with complicated algorithm using PAL calls.
// I don't know how important all this stuff is to the user.
// Maybe we can just have the place holder now and figure out
// how to fill them later.
//
U16 cpu_package_num; // package number for this cpu (if known)
U16 cpu_core_num; // core number (if known)
U16 cpu_hw_thread_num; // hw thread number inside the core (if known)
U16 cpu_threads_per_core; // total number of h/w threads per core (if known)
U16 cpu_module_id; // Processor module number
U16 cpu_num_modules; // Number of processor modules
U32 reserved;
} VTSA_GEN_PER_CPU;
#define VTSA_GEN_PER_CPU_cpu_number(p_cpu) (p_cpu)->cpu_number
#define VTSA_GEN_PER_CPU_cpu_speed_mhz(p_cpu) (p_cpu)->cpu_speed_mhz
#define VTSA_GEN_PER_CPU_cpu_fsb_mhz(p_cpu) (p_cpu)->cpu_fsb_mhz
#define VTSA_GEN_PER_CPU_cpu_cache_L2(p_cpu) (p_cpu)->cpu_cache_L2
#define VTSA_GEN_PER_CPU_cpu_cpuid_array(p_cpu) (p_cpu)->cpu_cpuid_array
#define VTSA_GEN_PER_CPU_cpu_tsc_offset(p_cpu) (p_cpu)->cpu_tsc_offset
#define VTSA_GEN_PER_CPU_cpu_intel_processor_number(p_cpu) (p_cpu)->cpu_intel_processor_number
#define VTSA_GEN_PER_CPU_cpu_cache_L3(p_cpu) (p_cpu)->cpu_cache_L3
#define VTSA_GEN_PER_CPU_platform_id(p_cpu) (p_cpu)->platform_id
#define VTSA_GEN_PER_CPU_cpu_package_num(p_cpu) (p_cpu)->cpu_package_num
#define VTSA_GEN_PER_CPU_cpu_core_num(p_cpu) (p_cpu)->cpu_core_num
#define VTSA_GEN_PER_CPU_cpu_hw_thread_num(p_cpu) (p_cpu)->cpu_hw_thread_num
#define VTSA_GEN_PER_CPU_cpu_threads_per_core(p_cpu) (p_cpu)->cpu_threads_per_core
#define VTSA_GEN_PER_CPU_cpu_module_num(p_cpu) (p_cpu)->cpu_module_id
#define VTSA_GEN_PER_CPU_cpu_num_modules(p_cpu) (p_cpu)->cpu_num_modules
typedef struct __node_info {
U32 node_type_from_shell;
U32 node_id; // The node number/id (if known)
U32 node_num_available; // total number cpus on this node
U32 node_num_used; // USER: number used based on cpu mask at time of run
U64 node_physical_memory; // amount of physical memory (bytes) on this node
//
// pointer to the first generic header that
// contains the per-cpu information
//
// Keep the VTSA_FIXED_SIZE_PTR on an 8-byte boundary...
//
VTSA_FIXED_SIZE_PTR node_percpu_array;
U32 node_reserved[2]; // leave some space
} VTSA_NODE_INFO;
#define VTSA_NODE_INFO_node_type_from_shell(vni) (vni)->node_type_from_shell
#define VTSA_NODE_INFO_node_id(vni) (vni)->node_id
#define VTSA_NODE_INFO_node_num_available(vni) (vni)->node_num_available
#define VTSA_NODE_INFO_node_num_used(vni) (vni)->node_num_used
#define VTSA_NODE_INFO_node_physical_memory(vni) (vni)->node_physical_memory
#define VTSA_NODE_INFO_node_percpu_array(vni) (vni)->node_percpu_array
typedef struct __sys_info {
//
// Keep this on an 8-byte boundary
//
VTSA_FIXED_SIZE_PTR node_array; // the per-node information
U64 min_app_address; // USER: lower allowed user space address (if known)
U64 max_app_address; // USER: upper allowed user space address (if known)
U32 page_size; // Current page size
U32 allocation_granularity; // USER: Granularity of allocation requests (if known)
U32 reserved1; // added for future fields
U32 reserved2; // alignment purpose
U64 reserved3[3]; // added for future fields
} VTSA_SYS_INFO;
#define VTSA_SYS_INFO_node_array(sys_info) (sys_info)->node_array
#define VTSA_SYS_INFO_min_app_address(sys_info) (sys_info)->min_app_address
#define VTSA_SYS_INFO_max_app_address(sys_info) (sys_info)->max_app_address
#define VTSA_SYS_INFO_page_size(sys_info) (sys_info)->page_size
#define VTSA_SYS_INFO_allocation_granularity(sys_info) (sys_info)->allocation_granularity
typedef struct DRV_TOPOLOGY_INFO_NODE_S DRV_TOPOLOGY_INFO_NODE;
typedef DRV_TOPOLOGY_INFO_NODE *DRV_TOPOLOGY_INFO;
struct DRV_TOPOLOGY_INFO_NODE_S {
U32 cpu_number; // cpu number (as defined by the OS)
U16 cpu_package_num; // package number for this cpu (if known)
U16 cpu_core_num; // core number (if known)
U16 cpu_hw_thread_num; // T0 or T1 if HT enabled
S32 socket_master;
S32 core_master;
S32 thr_master;
U32 cpu_module_num;
U32 cpu_module_master;
U32 cpu_num_modules;
} ;
#define DRV_TOPOLOGY_INFO_cpu_number(dti) (dti)->cpu_number
#define DRV_TOPOLOGY_INFO_cpu_package_num(dti) (dti)->cpu_package_num
#define DRV_TOPOLOGY_INFO_cpu_core_num(dti) (dti)->cpu_core_num
#define DRV_TOPOLOGY_INFO_socket_master(dti) (dti)->socket_master
#define DRV_TOPOLOGY_INFO_core_master(dti) (dti)->core_master
#define DRV_TOPOLOGY_INFO_thr_master(dti) (dti)->thr_master
#define DRV_TOPOLOGY_INFO_cpu_hw_thread_num(dti) (dti)->cpu_hw_thread_num
#define DRV_TOPOLOGY_INFO_cpu_module_num(dti) (dti)->cpu_module_num
#define DRV_TOPOLOGY_INFO_cpu_module_master(dti) (dti)->cpu_module_master
#define DRV_TOPOLOGY_INFO_cpu_num_modules(dti) (dti)->cpu_num_modules
// dimm information
typedef struct DRV_DIMM_INFO_NODE_S DRV_DIMM_INFO_NODE;
typedef DRV_DIMM_INFO_NODE *DRV_DIMM_INFO;
struct DRV_DIMM_INFO_NODE_S {
U32 platform_id;
U32 channel_num;
U32 rank_num;
U32 value;
};
#define DRV_DIMM_INFO_platform_id(di) (di)->platform_id
#define DRV_DIMM_INFO_channel_num(di) (di)->channel_num
#define DRV_DIMM_INFO_rank_num(di) (di)->rank_num
#define DRV_DIMM_INFO_value(di) (di)->value
//platform information. need to get from driver
#define MAX_PACKAGES 4
#define MAX_CHANNELS 8
#define MAX_RANKS 3
typedef struct DRV_PLATFORM_INFO_NODE_S DRV_PLATFORM_INFO_NODE;
typedef DRV_PLATFORM_INFO_NODE *DRV_PLATFORM_INFO;
struct DRV_PLATFORM_INFO_NODE_S {
U64 info; // platform info
U64 ddr_freq_index; // freq table index
U8 misc_valid; // misc enabled valid bit
U8 reserved1; // added for alignment purpose
U16 reserved2; // added for alignment purpose
U32 reserved3; // added for alignment purpose
U64 misc_info; // misc enabled info
U64 ufs_freq; // ufs frequency (HSX only)
DRV_DIMM_INFO_NODE dimm_info[MAX_PACKAGES * MAX_CHANNELS * MAX_RANKS];
U64 energy_multiplier; // Value of energy multiplier
};
#define DRV_PLATFORM_INFO_info(data) (data)->info
#define DRV_PLATFORM_INFO_ddr_freq_index(data) (data)->ddr_freq_index
#define DRV_PLATFORM_INFO_misc_valid(data) (data)->misc_valid
#define DRV_PLATFORM_INFO_misc_info(data) (data)->misc_info
#define DRV_PLATFORM_INFO_ufs_freq(data) (data)->ufs_freq
#define DRV_PLATFORM_INFO_dimm_info(data) (data)->dimm_info
#define DRV_PLATFORM_INFO_energy_multiplier(data) (data)->energy_multiplier
//platform information. need to get from Platform picker
typedef struct PLATFORM_FREQ_INFO_NODE_S PLATFORM_FREQ_INFO_NODE;
typedef PLATFORM_FREQ_INFO_NODE *PLATFORM_FREQ_INFO;
struct PLATFORM_FREQ_INFO_NODE_S {
float multiplier; // freq multiplier
double *table; // freq table
U32 table_size; // freq table size
};
#define PLATFORM_FREQ_INFO_multiplier(data) (data)->multiplier
#define PLATFORM_FREQ_INFO_table(data) (data)->table
#define PLATFORM_FREQ_INFO_table_size(data) (data)->table_size
// Definitions for user markers data
// The instances of these structures will be written to the user markers temp file.
#define MARKER_DEFAULT_TYPE "Default_Marker"
#define MARKER_DEFAULT_ID 0
#define MAX_MARKER_LENGTH 136
#define MARK_ID 4
#define MARK_DATA 2
#define THREAD_INFO 8
/* do not use it at ths moment
typedef enum {
SMRK_USER_DEFINED = 0,
SMRK_THREAD_NAME,
SMRK_WALLCLOCK,
SMRK_TEXT,
SMRK_TYPE_ID
} SMRK_TYPE;
*/
#define OSSNAMELEN 64
#define OSNAMELEN 128
typedef struct _SOFTWARE_INFO_NODE_S SOFTWARE_INFO_NODE;
typedef SOFTWARE_INFO_NODE *SOFTWARE_INFO;
struct _SOFTWARE_INFO_NODE_S {
char sysname[OSSNAMELEN];
char hostname[OSSNAMELEN];
char ipaddr[OSSNAMELEN];
char osname[OSNAMELEN];
char release[OSSNAMELEN];
char machine[OSSNAMELEN];
};
#define SOFTWARE_INFO_sysname(info) (info)->sysname
#define SOFTWARE_INFO_hostname(info) (info)->hostname
#define SOFTWARE_INFO_ipaddr(info) (info)->ipaddr
#define SOFTWARE_INFO_osname(info) (info)->osname
#define SOFTWARE_INFO_release(info) (info)->release
#define SOFTWARE_INFO_machine(info) (info)->machine
/*
* Common Register descriptions
*/
#if defined(DRV_IA32) || defined(DRV_EM64T)
/*
* Bits used in the debug control register
*/
#define DEBUG_CTL_LBR 0x0000001
#define DEBUG_CTL_BTF 0x0000002
#define DEBUG_CTL_TR 0x0000040
#define DEBUG_CTL_BTS 0x0000080
#define DEBUG_CTL_BTINT 0x0000100
#define DEBUG_CTL_BT_OFF_OS 0x0000200
#define DEBUG_CTL_BTS_OFF_USR 0x0000400
#define DEBUG_CTL_FRZ_LBR_ON_PMI 0x0000800
#define DEBUG_CTL_FRZ_PMON_ON_PMI 0x0001000
#define DEBUG_CTL_ENABLE_UNCORE_PMI_BIT 0x0002000
#define DEBUG_CTL_NODE_lbr_get(reg) (reg) & DEBUG_CTL_LBR
#define DEBUG_CTL_NODE_lbr_set(reg) (reg) |= DEBUG_CTL_LBR
#define DEBUG_CTL_NODE_lbr_clear(reg) (reg) &= ~DEBUG_CTL_LBR
#define DEBUG_CTL_NODE_btf_get(reg) (reg) & DEBUG_CTL_BTF
#define DEBUG_CTL_NODE_btf_set(reg) (reg) |= DEBUG_CTL_BTF
#define DEBUG_CTL_NODE_btf_clear(reg) (reg) &= ~DEBUG_CTL_BTF
#define DEBUG_CTL_NODE_tr_get(reg) (reg) & DEBUG_CTL_TR
#define DEBUG_CTL_NODE_tr_set(reg) (reg) |= DEBUG_CTL_TR
#define DEBUG_CTL_NODE_tr_clear(reg) (reg) &= ~DEBUG_CTL_TR
#define DEBUG_CTL_NODE_bts_get(reg) (reg) & DEBUG_CTL_BTS
#define DEBUG_CTL_NODE_bts_set(reg) (reg) |= DEBUG_CTL_BTS
#define DEBUG_CTL_NODE_bts_clear(reg) (reg) &= ~DEBUG_CTL_BTS
#define DEBUG_CTL_NODE_btint_get(reg) (reg) & DEBUG_CTL_BTINT
#define DEBUG_CTL_NODE_btint_set(reg) (reg) |= DEBUG_CTL_BTINT
#define DEBUG_CTL_NODE_btint_clear(reg) (reg) &= ~DEBUG_CTL_BTINT
#define DEBUG_CTL_NODE_bts_off_os_get(reg) (reg) & DEBUG_CTL_BTS_OFF_OS
#define DEBUG_CTL_NODE_bts_off_os_set(reg) (reg) |= DEBUG_CTL_BTS_OFF_OS
#define DEBUG_CTL_NODE_bts_off_os_clear(reg) (reg) &= ~DEBUG_CTL_BTS_OFF_OS
#define DEBUG_CTL_NODE_bts_off_usr_get(reg) (reg) & DEBUG_CTL_BTS_OFF_USR
#define DEBUG_CTL_NODE_bts_off_usr_set(reg) (reg) |= DEBUG_CTL_BTS_OFF_USR
#define DEBUG_CTL_NODE_bts_off_usr_clear(reg) (reg) &= ~DEBUG_CTL_BTS_OFF_USR
#define DEBUG_CTL_NODE_frz_lbr_on_pmi_get(reg) (reg) & DEBUG_CTL_FRZ_LBR_ON_PMI
#define DEBUG_CTL_NODE_frz_lbr_on_pmi_set(reg) (reg) |= DEBUG_CTL_FRZ_LBR_ON_PMI
#define DEBUG_CTL_NODE_frz_lbr_on_pmi_clear(reg) (reg) &= ~DEBUG_CTL_FRZ_LBR_ON_PMI
#define DEBUG_CTL_NODE_frz_pmon_on_pmi_get(reg) (reg) & DEBUG_CTL_FRZ_PMON_ON_PMI
#define DEBUG_CTL_NODE_frz_pmon_on_pmi_set(reg) (reg) |= DEBUG_CTL_FRZ_PMON_ON_PMI
#define DEBUG_CTL_NODE_frz_pmon_on_pmi_clear(reg) (reg) &= ~DEBUG_CTL_FRZ_PMON_ON_PMI
#define DEBUG_CTL_NODE_enable_uncore_pmi_get(reg) (reg) & DEBUG_CTL_ENABLE_UNCORE_PMI
#define DEBUG_CTL_NODE_enable_uncore_pmi_set(reg) (reg) |= DEBUG_CTL_ENABLE_UNCORE_PMI
#define DEBUG_CTL_NODE_enable_uncore_pmi_clear(reg) (reg) &= ~DEBUG_CTL_ENABLE_UNCORE_PMI
#endif /* defined(DRV_IA32) || defined(DRV_EM64T) */
/*
* @macro SEP_VERSION_NODE_S
* @brief
* This structure supports versioning in Sep. The field major indicates the major version,
* minor indicates the minor version and api indicates the api version for the current
* sep build. This structure is initialized at the time when the driver is loaded.
*/
typedef struct SEP_VERSION_NODE_S SEP_VERSION_NODE;
typedef SEP_VERSION_NODE *SEP_VERSION;
struct SEP_VERSION_NODE_S {
union {
U32 sep_version;
struct {
S32 major :8;
S32 minor :8;
S32 api :8;
S32 update:8;
}s1;
}u1;
};
#define SEP_VERSION_NODE_sep_version(version) (version)->u1.sep_version
#define SEP_VERSION_NODE_major(version) (version)->u1.s1.major
#define SEP_VERSION_NODE_minor(version) (version)->u1.s1.minor
#define SEP_VERSION_NODE_api(version) (version)->u1.s1.api
#define SEP_VERSION_NODE_update(version) (version)->u1.s1.update
typedef struct DEVICE_INFO_NODE_S DEVICE_INFO_NODE;
typedef DEVICE_INFO_NODE *DEVICE_INFO;
struct DEVICE_INFO_NODE_S {
S8 *dll_name;
PVOID dll_handle;
S8 *cpu_name;
S8 *pmu_name;
S8 *event_db_file_name;
//PLATFORM_IDENTITY plat_identity; // this is undefined right now. Please take this as structure containing U64
U32 plat_type; // device type (e.g., DEVICE_INFO_CORE, etc. ... see enum below)
U32 plat_sub_type; // cti_type (e.g., CTI_Sandybridge, etc., ... see env_info_types.h)
S32 dispatch_id; // this will be set in user mode dlls and will be unique across all IPF, IA32 (including MIDS).
ECB *ecb;
EVENT_CONFIG ec;
DRV_CONFIG pcfg;
U32 num_of_groups;
U32 size_of_alloc; // size of each event control block
PVOID drv_event;
U32 num_events;
U32 event_id_index; // event id index of device (basically how many events processed before this device)
U32 num_counters;
U32 group_index;
U32 num_packages;
U32 num_units;
};
#define MAX_EVENT_NAME_LENGTH 64
#define DEVICE_INFO_dll_name(pdev) (pdev)->dll_name
#define DEVICE_INFO_dll_handle(pdev) (pdev)->dll_handle
#define DEVICE_INFO_cpu_name(pdev) (pdev)->cpu_name
#define DEVICE_INFO_pmu_name(pdev) (pdev)->pmu_name
#define DEVICE_INFO_event_db_file_name(pdev) (pdev)->event_db_file_name
#define DEVICE_INFO_plat_type(pdev) (pdev)->plat_type
#define DEVICE_INFO_plat_sub_type(pdev) (pdev)->plat_sub_type
#define DEVICE_INFO_dispatch_id(pdev) (pdev)->dispatch_id
#define DEVICE_INFO_ecb(pdev) (pdev)->ecb
#define DEVICE_INFO_ec(pdev) (pdev)->ec
#define DEVICE_INFO_pcfg(pdev) (pdev)->pcfg
#define DEVICE_INFO_num_groups(pdev) (pdev)->num_of_groups
#define DEVICE_INFO_size_of_alloc(pdev) (pdev)->size_of_alloc
#define DEVICE_INFO_drv_event(pdev) (pdev)->drv_event
#define DEVICE_INFO_num_events(pdev) (pdev)->num_events
#define DEVICE_INFO_event_id_index(pdev) (pdev)->event_id_index
#define DEVICE_INFO_num_counters(pdev) (pdev)->num_counters
#define DEVICE_INFO_group_index(pdev) (pdev)->group_index
#define DEVICE_INFO_num_packages(pdev) (pdev)->num_packages
#define DEVICE_INFO_num_units(pdev) (pdev)->num_units
typedef struct DEVICE_INFO_DATA_NODE_S DEVICE_INFO_DATA_NODE;
typedef DEVICE_INFO_DATA_NODE *DEVICE_INFO_DATA;
struct DEVICE_INFO_DATA_NODE_S {
DEVICE_INFO pdev_info;
U32 num_elements;
U32 num_allocated;
};
#define DEVICE_INFO_DATA_pdev_info(d) (d)->pdev_info
#define DEVICE_INFO_DATA_num_elements(d) (d)->num_elements
#define DEVICE_INFO_DATA_num_allocated(d) (d)->num_allocated
typedef enum
{
DEVICE_INFO_CORE = 0,
DEVICE_INFO_UNCORE = 1,
DEVICE_INFO_CHIPSET = 2,
DEVICE_INFO_GFX = 3,
DEVICE_INFO_PWR = 4,
DEVICE_INFO_TELEMETRY = 5
} DEVICE_INFO_TYPE;
#if defined(__cplusplus)
}
#endif
typedef struct DRV_EVENT_MASK_NODE_S DRV_EVENT_MASK_NODE;
typedef DRV_EVENT_MASK_NODE *DRV_EVENT_MASK;
struct DRV_EVENT_MASK_NODE_S {
U8 event_idx; // 0 <= index < MAX_EVENTS
union {
U8 bitFields1;
struct {
U8 precise : 1;
U8 lbr_capture : 1;
U8 dear_capture : 1; // Indicates which events need to have additional registers read
// because they are DEAR events.
U8 iear_capture : 1; // Indicates which events need to have additional registers read
// because they are IEAR events.
U8 btb_capture : 1; // Indicates which events need to have additional registers read
// because they are BTB events.
U8 ipear_capture : 1; // Indicates which events need to have additional registers read
// because they are IPEAR events.
U8 uncore_capture : 1;
U8 branch : 1; // Indicates whether the event is related to branch opertion or
// not
} s1;
} u1;
};
#define DRV_EVENT_MASK_event_idx(d) (d)->event_idx
#define DRV_EVENT_MASK_bitFields1(d) (d)->u1.bitFields1
#define DRV_EVENT_MASK_precise(d) (d)->u1.s1.precise
#define DRV_EVENT_MASK_lbr_capture(d) (d)->u1.s1.lbr_capture
#define DRV_EVENT_MASK_dear_capture(d) (d)->u1.s1.dear_capture
#define DRV_EVENT_MASK_iear_capture(d) (d)->u1.s1.iear_capture
#define DRV_EVENT_MASK_btb_capture(d) (d)->u1.s1.btb_capture
#define DRV_EVENT_MASK_ipear_capture(d) (d)->u1.s1.ipear_capture
#define DRV_EVENT_MASK_uncore_capture(d) (d)->u1.s1.uncore_capture
#define DRV_EVENT_MASK_branch(d) (d)->u1.s1.branch
#define MAX_OVERFLOW_EVENTS 11 // This defines the maximum number of overflow events per interrupt.
// In order to reduce memory footprint, the value should be at least
// the number of fixed and general PMU registers.
// Sandybridge with HT off has 11 PMUs(3 fixed and 8 generic)
typedef struct DRV_MASKS_NODE_S DRV_MASKS_NODE;
typedef DRV_MASKS_NODE *DRV_MASKS;
/*
* @macro DRV_EVENT_MASK_NODE_S
* @brief
* The structure is used to store overflow events when handling PMU interrupt.
* This approach should be more efficient than checking all event masks
* if there are many events to be monitored
* and only a few events among them have overflow per interrupt.
*/
struct DRV_MASKS_NODE_S {
DRV_EVENT_MASK_NODE eventmasks[MAX_OVERFLOW_EVENTS];
U8 masks_num; // 0 <= mask_num <= MAX_OVERFLOW_EVENTS
U8 padding; // data structure alignment
};
#define DRV_MASKS_masks_num(d) (d)->masks_num
#define DRV_MASKS_eventmasks(d) (d)->eventmasks
typedef struct EMON_SCHED_INFO_NODE_S EMON_SCHED_INFO_NODE;
typedef EMON_SCHED_INFO_NODE *EMON_SCHED_INFO;
struct EMON_SCHED_INFO_NODE_S {
U32 max_counters_for_all_pmus;
U32 num_cpus;
U32 group_index[MAX_EMON_GROUPS];
U32 offset_for_next_device[MAX_EMON_GROUPS];
U32 device_id;
U32 num_packages;
U32 num_units;
U32 user_scheduled;
};
#define EMON_SCHED_INFO_max_counters_for_all_pmus(x) (x)->max_counters_for_all_pmus
#define EMON_SCHED_INFO_num_cpus(x) (x)->num_cpus
#define EMON_SCHED_INFO_group_index(x,grp_num) (x)->group_index[grp_num]
#define EMON_SCHED_INFO_offset_for_next_device(x, grp_num) (x)->offset_for_next_device[grp_num]
#define EMON_SCHED_INFO_device_id(x) (x)->device_id
#define EMON_SCHED_INFO_num_packages(x) (x)->num_packages
#define EMON_SCHED_INFO_num_units(x) (x)->num_units
#define EMON_SCHED_INFO_user_scheduled(x) (x)->user_scheduled
#define INITIALIZE_Emon_Sched_Info(x,j) \
for((j) =0; (j) < MAX_EMON_GROUPS; (j)++) { \
EMON_SCHED_INFO_group_index((x),(j)) = 0; \
EMON_SCHED_INFO_offset_for_next_device((x), (j)) = 0; \
}
typedef struct PCIFUNC_INFO_NODE_S PCIFUNC_INFO_NODE;
typedef PCIFUNC_INFO_NODE *PCIFUNC_INFO;
struct PCIFUNC_INFO_NODE_S {
U32 valid;
U64 deviceId;
U32 is_found_in_platform;
};
#define PCIFUNC_INFO_NODE_funcno(x) (x)->funcno
#define PCIFUNC_INFO_NODE_valid(x) (x)->valid
#define PCIFUNC_INFO_NODE_deviceId(x) (x)->deviceId
typedef struct PCIDEV_INFO_NODE_S PCIDEV_INFO_NODE;
typedef PCIDEV_INFO_NODE *PCIDEV_INFO;
struct PCIDEV_INFO_NODE_S {
PCIFUNC_INFO_NODE func_info[MAX_PCI_FUNCNO];
U32 valid;
U32 dispatch_id;
};
#define PCIDEV_INFO_NODE_func_info(x,i) (x).func_info[i]
#define PCIDEV_INFO_NODE_valid(x) (x).valid
typedef struct UNCORE_PCIDEV_NODE_S UNCORE_PCIDEV_NODE;
struct UNCORE_PCIDEV_NODE_S {
PCIDEV_INFO_NODE pcidev[MAX_PCI_DEVNO];
U32 dispatch_id;
U32 scan;
};
typedef struct UNCORE_TOPOLOGY_INFO_NODE_S UNCORE_TOPOLOGY_INFO_NODE;
typedef UNCORE_TOPOLOGY_INFO_NODE *UNCORE_TOPOLOGY_INFO;
struct UNCORE_TOPOLOGY_INFO_NODE_S {
UNCORE_PCIDEV_NODE device[MAX_DEVICES];
};
#define UNCORE_TOPOLOGY_INFO_device(x, dev_index) (x)->device[dev_index]
#define UNCORE_TOPOLOGY_INFO_device_dispatch_id(x, dev_index) (x)->device[dev_index].dispatch_id
#define UNCORE_TOPOLOGY_INFO_device_scan(x, dev_index) (x)->device[dev_index].scan
#define UNCORE_TOPOLOGY_INFO_pcidev_valid(x, dev_index, devno) (x)->device[dev_index].pcidev[devno].valid
#define UNCORE_TOPOLOGY_INFO_pcidev_dispatch_id(x, dev_index, devno) (x)->device[dev_index].pcidev[devno].dispatch_id
#define UNCORE_TOPOLOGY_INFO_pcidev(x, dev_index, devno) (x)->device[dev_index].pcidev[devno]
#define UNCORE_TOPOLOGY_INFO_pcidev_set_funcno_valid(x, dev_index, devno, funcno) (x)->device[dev_index].pcidev[devno].func_info[funcno].valid = 1
#define UNCORE_TOPOLOGY_INFO_pcidev_is_found_in_platform(x, dev_index, devno, funcno) (x)->device[dev_index].pcidev[devno].func_info[funcno].is_found_in_platform
#define UNCORE_TOPOLOGY_INFO_pcidev_is_devno_funcno_valid(x, dev_index, devno, funcno) ((x)->device[dev_index].pcidev[devno].func_info[funcno].valid ? TRUE : FALSE)
#define UNCORE_TOPOLOGY_INFO_pcidev_is_device_found(x, dev_index, devno, funcno) ((x)->device[dev_index].pcidev[devno].func_info[funcno].is_found_in_platform ? TRUE : FALSE)
#define GET_NUM_UNITS(x, dev_index, d, f, num_units) \
for((d) =0; (d) < MAX_PCI_DEVNO; (d)++) { \
if (!(UNCORE_TOPOLOGY_INFO_pcidev_valid((x), (dev_index), (d)))) continue; \
for ( (f)=0; (f) < MAX_PCI_FUNCNO; (f)++) { \
if (!(UNCORE_TOPOLOGY_INFO_pcidev_is_devno_funcno_valid((x), (dev_index), (d),(f)))) continue; \
if (!(UNCORE_TOPOLOGY_INFO_pcidev_is_device_found((x), (dev_index), (d),(f)))) continue; \
(num_units)++; \
} \
}
typedef enum
{
UNCORE_TOPOLOGY_INFO_NODE_IMC = 0,
UNCORE_TOPOLOGY_INFO_NODE_QPILL = 1,
UNCORE_TOPOLOGY_INFO_NODE_HA = 2,
UNCORE_TOPOLOGY_INFO_NODE_R3 = 3,
UNCORE_TOPOLOGY_INFO_NODE_R2 = 4,
UNCORE_TOPOLOGY_INFO_NODE_IRP = 5
} UNCORE_TOPOLOGY_INFO_NODE_INDEX_TYPE;
#endif