Patrick Georgi | ea063cb | 2020-05-08 19:28:13 +0200 | [diff] [blame] | 1 | /* inteltool - dump all registers on an Intel CPU + chipset based system */ |
Patrick Georgi | 7333a11 | 2020-05-08 20:48:04 +0200 | [diff] [blame] | 2 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 3 | |
| 4 | #include <stdio.h> |
| 5 | #include <stdlib.h> |
| 6 | #include <stddef.h> |
| 7 | #include <stdint.h> |
| 8 | #include <assert.h> |
| 9 | #include <inttypes.h> |
| 10 | #include "inteltool.h" |
| 11 | #include "pcr.h" |
| 12 | |
Johanna Schander | f80c5d9 | 2020-01-29 09:20:23 +0100 | [diff] [blame] | 13 | #include "gpio_names/apollolake.h" |
Johanna Schander | d5a6530 | 2020-01-29 09:16:06 +0100 | [diff] [blame] | 14 | #include "gpio_names/cannonlake.h" |
Matt DeVillier | 3c78445 | 2019-06-11 23:23:46 -0500 | [diff] [blame] | 15 | #include "gpio_names/cannonlake_lp.h" |
Johanna Schander | 7da602f | 2020-01-29 09:51:25 +0100 | [diff] [blame] | 16 | #include "gpio_names/denverton.h" |
Sean Rhodes | 645dde7 | 2021-10-22 09:31:22 +0100 | [diff] [blame] | 17 | #include "gpio_names/geminilake.h" |
Johanna Schander | dca20cd | 2020-01-29 09:14:18 +0100 | [diff] [blame] | 18 | #include "gpio_names/icelake.h" |
Johanna Schander | aff7d1f | 2020-01-29 09:29:39 +0100 | [diff] [blame] | 19 | #include "gpio_names/lewisburg.h" |
Johanna Schander | e98af86 | 2020-01-29 09:25:45 +0100 | [diff] [blame] | 20 | #include "gpio_names/sunrise.h" |
Michał Żygowski | 8ac40f3 | 2021-07-09 16:00:16 +0200 | [diff] [blame] | 21 | #include "gpio_names/tigerlake.h" |
Michał Kopeć | 2d8edeb | 2022-04-05 10:40:03 +0200 | [diff] [blame] | 22 | #include "gpio_names/alderlake_h.h" |
Johanna Schander | dca20cd | 2020-01-29 09:14:18 +0100 | [diff] [blame] | 23 | |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 24 | #define SBBAR_SIZE (16 * MiB) |
| 25 | #define PCR_PORT_SIZE (64 * KiB) |
| 26 | |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 27 | static const char *decode_pad_mode(const struct gpio_group *const group, |
| 28 | const size_t pad, const uint32_t dw0) |
| 29 | { |
| 30 | const size_t pad_mode = dw0 >> 10 & 7; |
Nico Huber | 8a95c6c | 2018-11-27 12:27:22 +0100 | [diff] [blame] | 31 | const char *const pad_name = |
| 32 | group->pad_names[pad * group->func_count + pad_mode]; |
| 33 | |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 34 | if (!pad_mode) |
Nico Huber | 8a95c6c | 2018-11-27 12:27:22 +0100 | [diff] [blame] | 35 | return pad_name[0] == '*' ? "*GPIO" : "GPIO"; |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 36 | else if (pad_mode < group->func_count) |
| 37 | return group->pad_names[pad * group->func_count + pad_mode]; |
| 38 | else |
| 39 | return "RESERVED"; |
| 40 | } |
| 41 | |
| 42 | static void print_gpio_group(const uint8_t pid, size_t pad_cfg, |
Thomas Heijligen | 725369f | 2019-02-19 10:51:34 +0000 | [diff] [blame] | 43 | const struct gpio_group *const group, |
| 44 | size_t pad_stepping) |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 45 | { |
| 46 | size_t p; |
| 47 | |
| 48 | printf("%s\n", group->display); |
| 49 | |
Thomas Heijligen | 725369f | 2019-02-19 10:51:34 +0000 | [diff] [blame] | 50 | for (p = 0; p < group->pad_count; ++p, pad_cfg += pad_stepping) { |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 51 | const uint32_t dw0 = read_pcr32(pid, pad_cfg); |
| 52 | const uint32_t dw1 = read_pcr32(pid, pad_cfg + 4); |
Nico Huber | 8a95c6c | 2018-11-27 12:27:22 +0100 | [diff] [blame] | 53 | const char *const pad_name = |
| 54 | group->pad_names[p * group->func_count]; |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 55 | |
Nico Huber | 8a95c6c | 2018-11-27 12:27:22 +0100 | [diff] [blame] | 56 | printf("0x%04zx: 0x%016"PRIx64" %-12s %-20s\n", pad_cfg, |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 57 | (uint64_t)dw1 << 32 | dw0, |
Nico Huber | 8a95c6c | 2018-11-27 12:27:22 +0100 | [diff] [blame] | 58 | pad_name[0] == '*' ? &pad_name[1] : pad_name, |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 59 | decode_pad_mode(group, p, dw0)); |
| 60 | } |
| 61 | } |
| 62 | |
Thomas Heijligen | 725369f | 2019-02-19 10:51:34 +0000 | [diff] [blame] | 63 | static void print_gpio_community(const struct gpio_community *const community, |
| 64 | size_t pad_stepping) |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 65 | { |
| 66 | size_t group, pad_count; |
| 67 | size_t pad_cfg; /* offset in bytes under this communities PCR port */ |
| 68 | |
| 69 | printf("%s\n\nPCR Port ID: 0x%06zx\n\n", |
| 70 | community->name, (size_t)community->pcr_port_id << 16); |
| 71 | |
| 72 | for (group = 0, pad_count = 0; group < community->group_count; ++group) |
| 73 | pad_count += community->groups[group]->pad_count; |
| 74 | assert(pad_count * 8 <= PCR_PORT_SIZE - 0x10); |
| 75 | |
| 76 | pad_cfg = read_pcr32(community->pcr_port_id, 0x0c); |
| 77 | if (pad_cfg + pad_count * 8 > PCR_PORT_SIZE) { |
| 78 | fprintf(stderr, "Bad Pad Base Address: 0x%08zx\n", pad_cfg); |
| 79 | return; |
| 80 | } |
| 81 | |
| 82 | for (group = 0; group < community->group_count; ++group) { |
| 83 | print_gpio_group(community->pcr_port_id, |
Thomas Heijligen | 725369f | 2019-02-19 10:51:34 +0000 | [diff] [blame] | 84 | pad_cfg, community->groups[group], |
| 85 | pad_stepping); |
| 86 | pad_cfg += community->groups[group]->pad_count * pad_stepping; |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 87 | } |
| 88 | } |
| 89 | |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 90 | const struct gpio_community *const *get_gpio_communities(struct pci_dev *const sb, |
| 91 | size_t* community_count, |
| 92 | size_t* pad_stepping) |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 93 | { |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 94 | *pad_stepping = 8; |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 95 | |
| 96 | switch (sb->device_id) { |
Pavel Sayekat | 9429b70 | 2019-07-28 23:09:08 +0600 | [diff] [blame] | 97 | case PCI_DEVICE_ID_INTEL_H110: |
Felix Singer | f98dc48 | 2019-07-29 21:53:14 +0200 | [diff] [blame] | 98 | case PCI_DEVICE_ID_INTEL_H170: |
| 99 | case PCI_DEVICE_ID_INTEL_Z170: |
| 100 | case PCI_DEVICE_ID_INTEL_Q170: |
| 101 | case PCI_DEVICE_ID_INTEL_Q150: |
Nico Huber | 54fe32f | 2017-10-03 16:03:07 +0200 | [diff] [blame] | 102 | case PCI_DEVICE_ID_INTEL_B150: |
Christian Walter | 9a8c5e7 | 2019-05-06 17:50:57 +0200 | [diff] [blame] | 103 | case PCI_DEVICE_ID_INTEL_C236: |
Felix Singer | f98dc48 | 2019-07-29 21:53:14 +0200 | [diff] [blame] | 104 | case PCI_DEVICE_ID_INTEL_C232: |
| 105 | case PCI_DEVICE_ID_INTEL_QM170: |
| 106 | case PCI_DEVICE_ID_INTEL_HM170: |
| 107 | case PCI_DEVICE_ID_INTEL_CM236: |
Timofey Komarov | 6c80082 | 2021-06-25 12:07:32 +0300 | [diff] [blame] | 108 | case PCI_DEVICE_ID_INTEL_H270: |
| 109 | case PCI_DEVICE_ID_INTEL_Z270: |
| 110 | case PCI_DEVICE_ID_INTEL_Q270: |
| 111 | case PCI_DEVICE_ID_INTEL_Q250: |
| 112 | case PCI_DEVICE_ID_INTEL_B250: |
| 113 | case PCI_DEVICE_ID_INTEL_Z370: |
| 114 | case PCI_DEVICE_ID_INTEL_H310C: |
| 115 | case PCI_DEVICE_ID_INTEL_X299: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 116 | *community_count = ARRAY_SIZE(sunrise_communities); |
| 117 | return sunrise_communities; |
Felix Singer | 0a7543d | 2019-02-19 23:49:11 +0100 | [diff] [blame] | 118 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: |
| 119 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: |
| 120 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: |
| 121 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: |
| 122 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: |
| 123 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: |
| 124 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: |
Matthew Garrett | 2bf28e5 | 2018-07-23 21:09:47 -0700 | [diff] [blame] | 125 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: |
| 126 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: |
| 127 | case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 128 | *community_count = ARRAY_SIZE(sunrise_lp_communities); |
| 129 | return sunrise_lp_communities; |
Maxim Polyakov | b89ce2e | 2019-08-17 14:54:02 +0300 | [diff] [blame] | 130 | case PCI_DEVICE_ID_INTEL_C621: |
| 131 | case PCI_DEVICE_ID_INTEL_C622: |
| 132 | case PCI_DEVICE_ID_INTEL_C624: |
| 133 | case PCI_DEVICE_ID_INTEL_C625: |
| 134 | case PCI_DEVICE_ID_INTEL_C626: |
| 135 | case PCI_DEVICE_ID_INTEL_C627: |
| 136 | case PCI_DEVICE_ID_INTEL_C628: |
| 137 | case PCI_DEVICE_ID_INTEL_C629: |
Maxim Polyakov | de7092b | 2020-07-17 00:19:41 +0300 | [diff] [blame] | 138 | case PCI_DEVICE_ID_INTEL_C621A: |
| 139 | case PCI_DEVICE_ID_INTEL_C627A: |
| 140 | case PCI_DEVICE_ID_INTEL_C629A: |
Maxim Polyakov | b89ce2e | 2019-08-17 14:54:02 +0300 | [diff] [blame] | 141 | case PCI_DEVICE_ID_INTEL_C624_SUPER: |
| 142 | case PCI_DEVICE_ID_INTEL_C627_SUPER_1: |
| 143 | case PCI_DEVICE_ID_INTEL_C621_SUPER: |
| 144 | case PCI_DEVICE_ID_INTEL_C627_SUPER_2: |
| 145 | case PCI_DEVICE_ID_INTEL_C628_SUPER: |
Maxim Polyakov | de7092b | 2020-07-17 00:19:41 +0300 | [diff] [blame] | 146 | case PCI_DEVICE_ID_INTEL_C621A_SUPER: |
| 147 | case PCI_DEVICE_ID_INTEL_C627A_SUPER: |
| 148 | case PCI_DEVICE_ID_INTEL_C629A_SUPER: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 149 | *community_count = ARRAY_SIZE(lewisburg_communities); |
| 150 | return lewisburg_communities; |
Thomas Heijligen | da02719 | 2019-01-12 19:20:50 +0100 | [diff] [blame] | 151 | case PCI_DEVICE_ID_INTEL_DNV_LPC: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 152 | *community_count = ARRAY_SIZE(denverton_communities); |
| 153 | return denverton_communities; |
Nico Huber | 8a95c6c | 2018-11-27 12:27:22 +0100 | [diff] [blame] | 154 | case PCI_DEVICE_ID_INTEL_APL_LPC: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 155 | *community_count = ARRAY_SIZE(apl_communities); |
| 156 | return apl_communities; |
Sean Rhodes | 645dde7 | 2021-10-22 09:31:22 +0100 | [diff] [blame] | 157 | case PCI_DEVICE_ID_INTEL_GLK_LPC: |
| 158 | *community_count = ARRAY_SIZE(glk_communities); |
| 159 | *pad_stepping = 16; |
| 160 | return glk_communities; |
Matt DeVillier | 3c78445 | 2019-06-11 23:23:46 -0500 | [diff] [blame] | 161 | case PCI_DEVICE_ID_INTEL_CANNONPOINT_LP_U_PREM: |
Matt DeVillier | 62e883d | 2020-08-08 11:17:31 -0500 | [diff] [blame] | 162 | case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_PREM: |
| 163 | case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_BASE: |
Matt DeVillier | 3c78445 | 2019-06-11 23:23:46 -0500 | [diff] [blame] | 164 | *community_count = ARRAY_SIZE(cannonlake_pch_lp_communities); |
| 165 | *pad_stepping = 16; |
| 166 | return cannonlake_pch_lp_communities; |
Thomas Heijligen | 725369f | 2019-02-19 10:51:34 +0000 | [diff] [blame] | 167 | case PCI_DEVICE_ID_INTEL_H310: |
| 168 | case PCI_DEVICE_ID_INTEL_H370: |
| 169 | case PCI_DEVICE_ID_INTEL_Z390: |
| 170 | case PCI_DEVICE_ID_INTEL_Q370: |
| 171 | case PCI_DEVICE_ID_INTEL_B360: |
| 172 | case PCI_DEVICE_ID_INTEL_C246: |
| 173 | case PCI_DEVICE_ID_INTEL_C242: |
| 174 | case PCI_DEVICE_ID_INTEL_QM370: |
| 175 | case PCI_DEVICE_ID_INTEL_HM370: |
| 176 | case PCI_DEVICE_ID_INTEL_CM246: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 177 | *community_count = ARRAY_SIZE(cannonlake_pch_h_communities); |
| 178 | *pad_stepping = 16; |
| 179 | return cannonlake_pch_h_communities; |
Johanna Schander | 0174ea7 | 2020-01-04 15:14:59 +0100 | [diff] [blame] | 180 | case PCI_DEVICE_ID_INTEL_ICELAKE_LP_U: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 181 | *community_count = ARRAY_SIZE(icelake_pch_h_communities); |
| 182 | *pad_stepping = 16; |
| 183 | return icelake_pch_h_communities; |
Michał Żygowski | 8ac40f3 | 2021-07-09 16:00:16 +0200 | [diff] [blame] | 184 | case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_SUPER: |
| 185 | case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_PREM: |
| 186 | case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_BASE: |
| 187 | case PCI_DEVICE_ID_INTEL_TIGERPOINT_Y_SUPER: |
| 188 | case PCI_DEVICE_ID_INTEL_TIGERPOINT_Y_PREM: |
| 189 | *community_count = ARRAY_SIZE(tigerlake_pch_lp_communities); |
| 190 | *pad_stepping = 16; |
| 191 | return tigerlake_pch_lp_communities; |
| 192 | case PCI_DEVICE_ID_INTEL_Q570: |
| 193 | case PCI_DEVICE_ID_INTEL_Z590: |
| 194 | case PCI_DEVICE_ID_INTEL_H570: |
| 195 | case PCI_DEVICE_ID_INTEL_B560: |
| 196 | case PCI_DEVICE_ID_INTEL_H510: |
| 197 | case PCI_DEVICE_ID_INTEL_WM590: |
| 198 | case PCI_DEVICE_ID_INTEL_QM580: |
| 199 | case PCI_DEVICE_ID_INTEL_HM570: |
| 200 | case PCI_DEVICE_ID_INTEL_C252: |
| 201 | case PCI_DEVICE_ID_INTEL_C256: |
| 202 | case PCI_DEVICE_ID_INTEL_W580: |
| 203 | *community_count = ARRAY_SIZE(tigerlake_pch_h_communities); |
| 204 | *pad_stepping = 16; |
| 205 | return tigerlake_pch_h_communities; |
Michał Kopeć | 2d8edeb | 2022-04-05 10:40:03 +0200 | [diff] [blame] | 206 | case PCI_DEVICE_ID_INTEL_H610: |
| 207 | case PCI_DEVICE_ID_INTEL_B660: |
| 208 | case PCI_DEVICE_ID_INTEL_H670: |
| 209 | case PCI_DEVICE_ID_INTEL_Q670: |
| 210 | case PCI_DEVICE_ID_INTEL_Z690: |
| 211 | case PCI_DEVICE_ID_INTEL_W680: |
| 212 | case PCI_DEVICE_ID_INTEL_W685: |
| 213 | case PCI_DEVICE_ID_INTEL_WM690: |
| 214 | case PCI_DEVICE_ID_INTEL_HM670: |
| 215 | case PCI_DEVICE_ID_INTEL_WM790: |
| 216 | case PCI_DEVICE_ID_INTEL_HM770: |
| 217 | *community_count = ARRAY_SIZE(alderlake_pch_h_communities); |
| 218 | *pad_stepping = 16; |
| 219 | return alderlake_pch_h_communities; |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 220 | default: |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 221 | return NULL; |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 222 | } |
Johanna Schander | e32ded8 | 2020-01-29 10:08:17 +0100 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | void print_gpio_groups(struct pci_dev *const sb) |
| 226 | { |
| 227 | size_t community_count; |
| 228 | const struct gpio_community *const *communities; |
| 229 | size_t pad_stepping; |
| 230 | |
| 231 | communities = get_gpio_communities(sb, &community_count, &pad_stepping); |
| 232 | |
| 233 | if (!communities) |
| 234 | return; |
| 235 | |
| 236 | pcr_init(sb); |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 237 | |
| 238 | printf("\n============= GPIOS =============\n\n"); |
| 239 | |
| 240 | for (; community_count; --community_count) |
Thomas Heijligen | 725369f | 2019-02-19 10:51:34 +0000 | [diff] [blame] | 241 | print_gpio_community(*communities++, pad_stepping); |
Nico Huber | 1898023 | 2017-04-07 12:26:07 +0200 | [diff] [blame] | 242 | } |