1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef MSRTOOL_H 4 #define MSRTOOL_H 5 6 #include <stdio.h> 7 #include <stdint.h> 8 #if (defined(__MACH__) && defined(__APPLE__)) 9 /* DirectHW is available here: https://www.coreboot.org/DirectHW */ 10 #define __DARWIN__ 11 #include <DirectHW/DirectHW.h> 12 #endif 13 #if defined(__FreeBSD__) 14 #include <sys/ioctl.h> 15 #include <sys/cpuctl.h> 16 #endif 17 #include <pci/pci.h> 18 19 #define HEXCHARS "0123456789abcdefABCDEF" 20 21 typedef enum { 22 MSRTYPE_RDONLY, 23 MSRTYPE_RDWR, 24 MSRTYPE_WRONLY, 25 MSRTYPE_EOT 26 } MsrTypes; 27 28 typedef enum { 29 PRESENT_RSVD, 30 PRESENT_DEC, 31 PRESENT_BIN, 32 PRESENT_OCT, 33 PRESENT_HEX, 34 PRESENT_HEXDEC, 35 PRESENT_STR, 36 } PresentTypes; 37 38 struct msr { 39 uint32_t hi; 40 uint32_t lo; 41 }; 42 43 struct msrbitvalues { 44 const struct msr value; 45 const char *text; 46 }; 47 48 struct msrbits { 49 const uint8_t start; 50 const uint8_t size; 51 const char *name; 52 const char *desc; 53 const uint8_t present; 54 const struct msrbitvalues bitval[32]; 55 }; 56 57 struct msrdef { 58 const uint32_t addr; 59 const uint8_t type; 60 const struct msr resetval; 61 const char *symbol; 62 const char *desc; 63 const struct msrbits bits[65]; 64 }; 65 66 #define MSR1(lo) { 0, (lo) } 67 #define MSR2(hi,lo) { (hi), (lo) } 68 69 #define BITVAL_EOT .text = NULL 70 #define BITVAL_ISEOT(bv) (NULL == (bv).text) 71 72 #define BITS_EOT .size = 0 73 #define BITS_ISEOT(b) (0 == (b).size) 74 75 #define MSR_EOT .type = MSRTYPE_EOT 76 #define MSR_ISEOT(m) (MSRTYPE_EOT == (m).type) 77 78 #define NOBITS {{ BITVAL_EOT }} 79 #define RESERVED "RSVD", "Reserved", PRESENT_HEXDEC, NOBITS 80 81 #define MAX_CORES 8 82 83 typedef enum { 84 VENDOR_INTEL = 0x756e6547, 85 VENDOR_AMD = 0x68747541, 86 VENDOR_CENTAUR = 0x746e6543, 87 } vendor_t; 88 89 struct cpuid_t { 90 uint8_t family; 91 uint8_t model; 92 uint8_t stepping; 93 uint8_t ext_family; 94 uint8_t ext_model; 95 vendor_t vendor; 96 }; 97 98 struct targetdef { 99 const char *name; 100 const char *prettyname; 101 int (*probe)(const struct targetdef *target, const struct cpuid_t *id); 102 const struct msrdef *msrs; 103 }; 104 105 #define TARGET_EOT .name = NULL 106 #define TARGET_ISEOT(t) (NULL == (t).name) 107 108 109 enum SysModes { 110 SYS_RDONLY = 0, 111 SYS_WRONLY, 112 SYS_RDWR 113 }; 114 115 struct sysdef { 116 const char *name; 117 const char *prettyname; 118 int (*probe)(const struct sysdef *system); 119 int (*open)(uint8_t cpu, enum SysModes mode); 120 int (*close)(uint8_t cpu); 121 int (*rdmsr)(uint8_t cpu, uint32_t addr, struct msr *val); 122 }; 123 124 #define SYSTEM_EOT .name = NULL 125 #define SYSTEM_ISEOT(s) (NULL == (s).name) 126 127 extern const struct sysdef *sys; 128 129 extern uint8_t targets_found; 130 extern const struct targetdef **targets; 131 132 extern uint8_t reserved, verbose, quiet; 133 134 extern struct pci_access *pacc; 135 136 #define printf_quiet(x...) do { if (!quiet) fprintf(stderr,x); } while(0) 137 #define printf_verbose(x...) do { if (verbose && !quiet) fprintf(stderr,x); } while(0) 138 139 #define SYSERROR(call, addr) do { \ 140 const struct msrdef *m = findmsrdef(addr); \ 141 if (m) \ 142 fprintf(stderr, "%s: " #call "(0x%08x) %s: %s\n", __func__, addr, m->symbol, strerror(errno)); \ 143 else \ 144 fprintf(stderr, "%s: " #call "(0x%08x): %s\n", __func__, addr, strerror(errno)); \ 145 } while (0); 146 147 /* sys.c */ 148 struct cpuid_t *cpuid(void); 149 struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device); 150 151 /* msrutils.c */ 152 void hexprint(FILE *f, const struct msr val, const uint8_t bits); 153 void strprint(FILE *f, const struct msr val, const uint8_t bits); 154 int msr_eq(const struct msr a, const struct msr b); 155 struct msr msr_shl(const struct msr a, const uint8_t bits); 156 struct msr msr_shr(const struct msr a, const uint8_t bits); 157 void msr_and(struct msr *a, const struct msr b); 158 const struct msrdef *findmsrdef(const uint32_t addr); 159 uint32_t msraddrbyname(const char *name); 160 void dumpmsrdefs(const struct targetdef *t); 161 int dumpmsrdefsvals(FILE *f, const struct targetdef *t, const uint8_t cpu); 162 uint8_t str2msr(char *str, struct msr *msr, char **endptr); 163 void decodemsr(const uint8_t cpu, const uint32_t addr, const struct msr val); 164 uint8_t diff_msr(FILE *fout, const uint32_t addr, const struct msr a, const struct msr b); 165 166 167 168 /** system externs **/ 169 170 /* linux.c */ 171 extern int linux_probe(const struct sysdef *system); 172 extern int linux_open(uint8_t cpu, enum SysModes mode); 173 extern int linux_close(uint8_t cpu); 174 extern int linux_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val); 175 176 /* darwin.c */ 177 extern int darwin_probe(const struct sysdef *system); 178 extern int darwin_open(uint8_t cpu, enum SysModes mode); 179 extern int darwin_close(uint8_t cpu); 180 extern int darwin_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val); 181 182 /* freebsd.c */ 183 extern int freebsd_probe(const struct sysdef *system); 184 extern int freebsd_open(uint8_t cpu, enum SysModes mode); 185 extern int freebsd_close(uint8_t cpu); 186 extern int freebsd_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val); 187 188 /** target externs **/ 189 190 /* geodegx2.c */ 191 extern int geodegx2_probe(const struct targetdef *t, const struct cpuid_t *id); 192 extern const struct msrdef geodegx2_msrs[]; 193 194 /* geodelx.c */ 195 extern int geodelx_probe(const struct targetdef *t, const struct cpuid_t *id); 196 extern const struct msrdef geodelx_msrs[]; 197 198 /* cs5536.c */ 199 extern int cs5536_probe(const struct targetdef *t, const struct cpuid_t *id); 200 extern const struct msrdef cs5536_msrs[]; 201 202 /* k8.c */ 203 extern int k8_probe(const struct targetdef *t, const struct cpuid_t *id); 204 extern const struct msrdef k8_msrs[]; 205 206 /* via_c7.c */ 207 extern int via_c7_probe(const struct targetdef *t, const struct cpuid_t *id); 208 extern const struct msrdef via_c7_msrs[]; 209 210 /* intel_pentium3_early.c */ 211 extern int intel_pentium3_early_probe(const struct targetdef *t, const struct cpuid_t *id); 212 extern const struct msrdef intel_pentium3_early_msrs[]; 213 214 /* intel_pentium3.c */ 215 extern int intel_pentium3_probe(const struct targetdef *t, const struct cpuid_t *id); 216 extern const struct msrdef intel_pentium3_msrs[]; 217 218 /* intel_core1.c */ 219 extern int intel_core1_probe(const struct targetdef *t, const struct cpuid_t *id); 220 extern const struct msrdef intel_core1_msrs[]; 221 222 /* intel_core2_early.c */ 223 extern int intel_core2_early_probe(const struct targetdef *t, const struct cpuid_t *id); 224 extern const struct msrdef intel_core2_early_msrs[]; 225 226 /* intel_core2_later.c */ 227 extern int intel_core2_later_probe(const struct targetdef *t, const struct cpuid_t *id); 228 extern const struct msrdef intel_core2_later_msrs[]; 229 230 /* intel_pentium4_early.c */ 231 extern int intel_pentium4_early_probe(const struct targetdef *t, const struct cpuid_t *id); 232 extern const struct msrdef intel_pentium4_early_msrs[]; 233 234 /* intel_pentium4_later.c */ 235 extern int intel_pentium4_later_probe(const struct targetdef *t, const struct cpuid_t *id); 236 extern const struct msrdef intel_pentium4_later_msrs[]; 237 238 /* intel_pentium_d.c */ 239 extern int intel_pentium_d_probe(const struct targetdef *t, const struct cpuid_t *id); 240 extern const struct msrdef intel_pentium_d_msrs[]; 241 242 /* intel_nehalem.c */ 243 extern int intel_nehalem_probe(const struct targetdef *t, const struct cpuid_t *id); 244 extern const struct msrdef intel_nehalem_msrs[]; 245 246 /* intel_atom.c */ 247 extern int intel_atom_probe(const struct targetdef *t, const struct cpuid_t *id); 248 extern const struct msrdef intel_atom_msrs[]; 249 250 #endif /* MSRTOOL_H */ 251