Iru Cai | ab5cac2 | 2019-07-14 23:04:05 +0800 | [diff] [blame] | 1 | /* inteltool - dump all registers on an Intel CPU + chipset based system */ |
| 2 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 3 | |
| 4 | #include <stdio.h> |
| 5 | #include <stdlib.h> |
| 6 | #include "inteltool.h" |
| 7 | |
| 8 | #define RCBA16(rcba, x) (*((volatile u16 *)((rcba) + (x)))) |
| 9 | #define RCBA32(rcba, x) (*((volatile u32 *)((rcba) + (x)))) |
| 10 | /* IO Buffer Programming */ |
| 11 | #define IOBPIRI 0x2330 |
| 12 | #define IOBPD 0x2334 |
| 13 | #define IOBPS 0x2338 |
| 14 | #define IOBPS_READY 0x0001 |
| 15 | #define IOBPS_TX_MASK 0x0006 |
| 16 | #define IOBPS_MASK 0xff00 |
| 17 | #define IOBPS_READ 0x0600 |
| 18 | #define IOBPS_WRITE 0x0700 |
| 19 | #define IOBPU 0x233a |
| 20 | #define IOBPU_MAGIC 0xf000 |
| 21 | |
| 22 | #define IOBP_RETRY 1000 |
| 23 | static inline int iobp_poll(volatile uint8_t *rcba) |
| 24 | { |
| 25 | for (int try = IOBP_RETRY; try > 0; try--) { |
| 26 | u16 status = RCBA16(rcba, IOBPS); |
| 27 | if ((status & IOBPS_READY) == 0) |
| 28 | return 1; |
| 29 | // udelay(10); |
| 30 | } |
| 31 | |
| 32 | printf("IOBP: timeout waiting for transaction to complete\n"); |
| 33 | return 0; |
| 34 | } |
| 35 | |
| 36 | static u32 pch_iobp_read(volatile uint8_t *rcba, u32 address) |
| 37 | { |
| 38 | u16 status; |
| 39 | |
| 40 | if (!iobp_poll(rcba)) |
| 41 | return 0; |
| 42 | |
| 43 | /* Set the address */ |
| 44 | RCBA32(rcba, IOBPIRI) = address; |
| 45 | |
| 46 | /* READ OPCODE */ |
| 47 | status = RCBA16(rcba, IOBPS); |
| 48 | status &= ~IOBPS_MASK; |
| 49 | status |= IOBPS_READ; |
| 50 | RCBA16(rcba, IOBPS) = status; |
| 51 | |
| 52 | /* Undocumented magic */ |
| 53 | RCBA16(rcba, IOBPU) = IOBPU_MAGIC; |
| 54 | |
| 55 | /* Set ready bit */ |
| 56 | status = RCBA16(rcba, IOBPS); |
| 57 | status |= IOBPS_READY; |
| 58 | RCBA16(rcba, IOBPS) = status; |
| 59 | |
| 60 | if (!iobp_poll(rcba)) |
| 61 | return 0; |
| 62 | |
| 63 | /* Check for successful transaction */ |
| 64 | status = RCBA16(rcba, IOBPS); |
| 65 | if (status & IOBPS_TX_MASK) { |
| 66 | printf("IOBP: read 0x%08x failed\n", address); |
| 67 | return 0; |
| 68 | } |
| 69 | |
| 70 | /* Read IOBP data */ |
| 71 | return RCBA32(rcba, IOBPD); |
| 72 | } |
| 73 | |
| 74 | struct iobp_register { |
| 75 | u32 addr; |
| 76 | const char *name; |
| 77 | }; |
| 78 | |
| 79 | static const struct iobp_register lynxpoint_iobp_registers[] = { |
| 80 | /* SATA Electrical Control Register */ |
| 81 | {0xea002488, "SECRT88P0"}, |
| 82 | {0xea00248c, "SECRT8CP0"}, |
| 83 | {0xea002490, "SECRT90P0"}, |
| 84 | {0xea002498, "SECRT98P0"}, |
| 85 | {0xea00251c, "SECRR1CP0"}, |
| 86 | {0xea002550, "SECRR50P0"}, |
| 87 | {0xea002554, "SECRR54P0"}, |
| 88 | {0xea002558, "SECRR58P0"}, |
| 89 | |
| 90 | {0xea002688, "SECRT88P1"}, |
| 91 | {0xea00268c, "SECRT8CP1"}, |
| 92 | {0xea002690, "SECRT90P1"}, |
| 93 | {0xea002698, "SECRT98P1"}, |
| 94 | {0xea00271c, "SECRR1CP1"}, |
| 95 | {0xea002750, "SECRR50P1"}, |
| 96 | {0xea002754, "SECRR54P1"}, |
| 97 | {0xea002758, "SECRR58P1"}, |
| 98 | |
| 99 | {0xea000888, "SECRT88P2"}, |
| 100 | {0xea00088c, "SECRT8CP2"}, |
| 101 | {0xea000890, "SECRT90P2"}, |
| 102 | {0xea000898, "SECRT98P2"}, |
| 103 | {0xea00091c, "SECRR1CP2"}, |
| 104 | {0xea000950, "SECRR50P2"}, |
| 105 | {0xea000954, "SECRR54P2"}, |
| 106 | {0xea000958, "SECRR58P2"}, |
| 107 | |
| 108 | {0xea000a88, "SECRT88P3"}, |
| 109 | {0xea000a8c, "SECRT8CP3"}, |
| 110 | {0xea000a90, "SECRT90P3"}, |
| 111 | {0xea000a98, "SECRT98P3"}, |
| 112 | {0xea000b1c, "SECRR1CP3"}, |
| 113 | {0xea000b50, "SECRR50P3"}, |
| 114 | {0xea000b54, "SECRR54P3"}, |
| 115 | {0xea000b58, "SECRR58P3"}, |
| 116 | |
| 117 | {0xea002088, "SECRT88P4"}, |
| 118 | {0xea00208c, "SECRT8CP4"}, |
| 119 | {0xea002090, "SECRT90P4"}, |
| 120 | {0xea002098, "SECRT98P4"}, |
| 121 | {0xea00211c, "SECRR1CP4"}, |
| 122 | {0xea002150, "SECRR50P4"}, |
| 123 | {0xea002154, "SECRR54P4"}, |
| 124 | {0xea002158, "SECRR58P4"}, |
| 125 | |
| 126 | {0xea002288, "SECRT88P5"}, |
| 127 | {0xea00228c, "SECRT8CP5"}, |
| 128 | {0xea002290, "SECRT90P5"}, |
| 129 | {0xea002298, "SECRT98P5"}, |
| 130 | {0xea00231c, "SECRR1CP5"}, |
| 131 | {0xea002350, "SECRR50P5"}, |
| 132 | {0xea002354, "SECRR54P5"}, |
| 133 | {0xea002358, "SECRR58P5"}, |
| 134 | |
| 135 | {0xea008100, "SECRF00"}, |
| 136 | {0xea008104, "SECRF04"}, |
| 137 | |
| 138 | /* USB 2.0 Electrical Control Register */ |
| 139 | {0xe5004100, "U2ECRP01"}, |
| 140 | {0xe5004200, "U2ECRP02"}, |
| 141 | {0xe5004300, "U2ECRP03"}, |
| 142 | {0xe5004400, "U2ECRP04"}, |
| 143 | {0xe5004500, "U2ECRP05"}, |
| 144 | {0xe5004600, "U2ECRP06"}, |
| 145 | {0xe5004700, "U2ECRP07"}, |
| 146 | {0xe5004800, "U2ECRP08"}, |
| 147 | {0xe5004900, "U2ECRP09"}, |
| 148 | {0xe5004a00, "U2ECRP10"}, |
| 149 | {0xe5004b00, "U2ECRP11"}, |
| 150 | {0xe5004c00, "U2ECRP12"}, |
| 151 | {0xe5004d00, "U2ECRP13"}, |
| 152 | {0xe5004e00, "U2ECRP14"}, |
| 153 | |
| 154 | /* IOBP related to USB 3.0 ports */ |
| 155 | /* port 1 */ |
| 156 | {0xe900175c, ""}, |
| 157 | {0xe9001760, ""}, |
| 158 | {0xe9001768, ""}, |
| 159 | {0xe9001770, ""}, |
| 160 | {0xe90017cc, ""}, |
| 161 | /* port 2 */ |
| 162 | {0xe900155c, ""}, |
| 163 | {0xe9001560, ""}, |
| 164 | {0xe9001568, ""}, |
| 165 | {0xe9001570, ""}, |
| 166 | {0xe90015cc, ""}, |
| 167 | /* port 3 */ |
| 168 | {0xe9002f5c, ""}, |
| 169 | {0xe9002f60, ""}, |
| 170 | {0xe9002f68, ""}, |
| 171 | {0xe9002f70, ""}, |
| 172 | {0xe9002fcc, ""}, |
| 173 | /* port 4 */ |
| 174 | {0xe9002d5c, ""}, |
| 175 | {0xe9002d60, ""}, |
| 176 | {0xe9002d68, ""}, |
| 177 | {0xe9002d70, ""}, |
| 178 | {0xe9002dcc, ""}, |
| 179 | /* port 5 */ |
| 180 | {0xe900335c, ""}, |
| 181 | {0xe9003360, ""}, |
| 182 | {0xe9003368, ""}, |
| 183 | {0xe9003370, ""}, |
| 184 | {0xe90033cc, ""}, |
| 185 | /* port 6 */ |
| 186 | {0xe900315c, ""}, |
| 187 | {0xe9003160, ""}, |
| 188 | {0xe9003168, ""}, |
| 189 | {0xe9003170, ""}, |
| 190 | {0xe90031cc, ""}, |
| 191 | }; |
| 192 | |
| 193 | static const struct iobp_register lynxpoint_lp_iobp_registers[] = { |
| 194 | /* SATA Electrical Control Register */ |
| 195 | {0xea002688, "SECRT88P0"}, |
| 196 | {0xea00268c, "SECRT8CP0"}, |
| 197 | {0xea002690, "SECRT90P0"}, |
| 198 | {0xea002698, "SECRT98P0"}, |
| 199 | {0xea00271c, "SECRR1CP0"}, |
| 200 | {0xea002750, "SECRR50P0"}, |
| 201 | {0xea002754, "SECRR54P0"}, |
| 202 | {0xea002758, "SECRR58P0"}, |
| 203 | |
| 204 | {0xea002488, "SECRT88P1"}, |
| 205 | {0xea00248c, "SECRT8CP1"}, |
| 206 | {0xea002490, "SECRT90P1"}, |
| 207 | {0xea002498, "SECRT98P1"}, |
| 208 | {0xea00251c, "SECRR1CP1"}, |
| 209 | {0xea002550, "SECRR50P1"}, |
| 210 | {0xea002554, "SECRR54P1"}, |
| 211 | {0xea002558, "SECRR58P1"}, |
| 212 | |
| 213 | {0xea002288, "SECRT88P2"}, |
| 214 | {0xea00228c, "SECRT8CP2"}, |
| 215 | {0xea002290, "SECRT90P2"}, |
| 216 | {0xea002298, "SECRT98P2"}, |
| 217 | {0xea00231c, "SECRR1CP2"}, |
| 218 | {0xea002350, "SECRR50P2"}, |
| 219 | {0xea002354, "SECRR54P2"}, |
| 220 | {0xea002358, "SECRR58P2"}, |
| 221 | |
| 222 | {0xea002088, "SECRT88P3"}, |
| 223 | {0xea00208c, "SECRT8CP3"}, |
| 224 | {0xea002090, "SECRT90P3"}, |
| 225 | {0xea002098, "SECRT98P3"}, |
| 226 | {0xea00211c, "SECRR1CP3"}, |
| 227 | {0xea002150, "SECRR50P3"}, |
| 228 | {0xea002154, "SECRR54P3"}, |
| 229 | {0xea002158, "SECRR58P3"}, |
| 230 | |
| 231 | {0xea008100, "SECRF00"}, |
| 232 | {0xea008104, "SECRF04"}, |
| 233 | |
| 234 | /* USB 2.0 Electrical Control Register, 8 for -U SoC and 10 for Core-M */ |
| 235 | {0xe5004100, "U2ECRP01"}, |
| 236 | {0xe5004200, "U2ECRP02"}, |
| 237 | {0xe5004300, "U2ECRP03"}, |
| 238 | {0xe5004400, "U2ECRP04"}, |
| 239 | {0xe5004500, "U2ECRP05"}, |
| 240 | {0xe5004600, "U2ECRP06"}, |
| 241 | {0xe5004700, "U2ECRP07"}, |
| 242 | {0xe5004800, "U2ECRP08"}, |
| 243 | {0xe5004900, "U2ECRP09"}, |
| 244 | {0xe5004a00, "U2ECRP10"}, |
| 245 | |
| 246 | /* IOBP related to USB 3.0 ports */ |
| 247 | /* port 1 */ |
| 248 | {0xe900215c, ""}, |
| 249 | {0xe9002160, ""}, |
| 250 | {0xe9002168, ""}, |
| 251 | {0xe9002170, ""}, |
| 252 | {0xe90021cc, ""}, |
| 253 | /* port 2 */ |
| 254 | {0xe900235c, ""}, |
| 255 | {0xe9002360, ""}, |
| 256 | {0xe9002368, ""}, |
| 257 | {0xe9002370, ""}, |
| 258 | {0xe90023cc, ""}, |
| 259 | /* port 3 */ |
| 260 | {0xe900255c, ""}, |
| 261 | {0xe9002560, ""}, |
| 262 | {0xe9002568, ""}, |
| 263 | {0xe9002570, ""}, |
| 264 | {0xe90025cc, ""}, |
| 265 | /* port 4 */ |
| 266 | {0xe900275c, ""}, |
| 267 | {0xe9002760, ""}, |
| 268 | {0xe9002768, ""}, |
| 269 | {0xe9002770, ""}, |
| 270 | {0xe90027cc, ""}, |
| 271 | }; |
| 272 | |
| 273 | void print_iobp(struct pci_dev *sb, volatile uint8_t *rcba) |
| 274 | { |
| 275 | const struct iobp_register *iobp_registers = NULL; |
| 276 | size_t iobp_size = 0; |
| 277 | |
| 278 | switch (sb->device_id) { |
| 279 | case PCI_DEVICE_ID_INTEL_C8_MOBILE: |
| 280 | case PCI_DEVICE_ID_INTEL_C8_DESKTOP: |
| 281 | case PCI_DEVICE_ID_INTEL_Z87: |
| 282 | case PCI_DEVICE_ID_INTEL_Z85: |
| 283 | case PCI_DEVICE_ID_INTEL_HM86: |
| 284 | case PCI_DEVICE_ID_INTEL_H87: |
| 285 | case PCI_DEVICE_ID_INTEL_HM87: |
| 286 | case PCI_DEVICE_ID_INTEL_Q85: |
| 287 | case PCI_DEVICE_ID_INTEL_Q87: |
| 288 | case PCI_DEVICE_ID_INTEL_QM87: |
| 289 | case PCI_DEVICE_ID_INTEL_B85: |
| 290 | case PCI_DEVICE_ID_INTEL_C222: |
| 291 | case PCI_DEVICE_ID_INTEL_C224: |
| 292 | case PCI_DEVICE_ID_INTEL_C226: |
| 293 | case PCI_DEVICE_ID_INTEL_H81: |
| 294 | iobp_registers = lynxpoint_iobp_registers; |
| 295 | iobp_size = ARRAY_SIZE(lynxpoint_iobp_registers); |
| 296 | break; |
| 297 | case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_FULL: |
| 298 | case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_PREM: |
| 299 | case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_BASE: |
| 300 | case PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_PREM: |
| 301 | case PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP: |
| 302 | iobp_registers = lynxpoint_lp_iobp_registers; |
| 303 | iobp_size = ARRAY_SIZE(lynxpoint_lp_iobp_registers); |
| 304 | break; |
| 305 | default: |
| 306 | break; |
| 307 | } |
| 308 | |
| 309 | if (iobp_size == 0) |
| 310 | return; |
| 311 | |
| 312 | printf("\n============= IOBP ==============\n\n"); |
| 313 | |
| 314 | for (size_t i = 0; i < iobp_size; i++) { |
| 315 | u32 address = iobp_registers[i].addr; |
| 316 | const char *name = iobp_registers[i].name; |
| 317 | u32 v = pch_iobp_read(rcba, address); |
| 318 | printf("0x%08x: 0x%08x (%s)\n", address, v, name); |
| 319 | } |
| 320 | } |