coreboot/util/inteltool/powermgt.c
<<
>>
Prefs
   1/*
   2 * inteltool - dump all registers on an Intel CPU + chipset based system.
   3 *
   4 * Copyright (C) 2008-2010 by coresystems GmbH
   5 *  written by Stefan Reinauer <stepan@coresystems.de>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; version 2 of the License.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20
  21#include <stdio.h>
  22#include "inteltool.h"
  23
  24static const io_register_t ich10_pm_registers[] = {
  25        { 0x00, 2, "PM1_STS" }, // PM1 Status; ACPI pointer: PM1a_EVT_BLK
  26        { 0x02, 2, "PM1_EN" },  // PM1 Enables; ACPI pointer: PM1a_EVT_BLK+2
  27        { 0x04, 4, "PM1_CNT" }, // PM1 Control; ACPI pointer: PM1a_CNT_BLK
  28        { 0x08, 4, "PM1_TMR" }, // PM1 Timer; ACPI pointer: PMTMR_BLK
  29        { 0x0c, 4, "RESERVED" },
  30        { 0x10, 4, "PROC_CNT" }, // Processor Control; ACPI pointer: P_BLK
  31#if DANGEROUS_REGISTERS
  32        /* These registers return 0 on read, but reading them may cause
  33         * the system to enter Cx states, which might hang the system.
  34         */
  35        { 0x14, 1, "LV2 (Mobile)" },
  36        { 0x15, 1, "LV3 (Mobile)" },
  37        { 0x16, 1, "LV4 (Mobile)" },
  38#endif
  39        { 0x17, 2, "RESERVED" },
  40        { 0x19, 1, "RESERVED" },
  41        { 0x1a, 2, "RESERVED" },
  42        { 0x1c, 4, "RESERVED" },
  43        { 0x20, 8, "GPE0_STS" }, // General Purpose Event 0 Status; ACPI pointer: GPE0_BLK
  44        { 0x2C, 4, "GPE0_EN" },  // General Purpose Event 0 Enables; ACPI pointer: GPE0_BLK+8
  45        { 0x30, 4, "SMI_EN" },
  46        { 0x34, 4, "SMI_STS" },
  47        { 0x38, 2, "ALT_GP_SMI_EN" },
  48        { 0x3a, 2, "ALT_GP_SMI_STS" },
  49        { 0x3c, 1, "UPRWC" },   // USB Per-Port registers write control;
  50        { 0x3d, 2, "RESERVED" },
  51        { 0x3f, 1, "RESERVED" },
  52        { 0x40, 2, "RESERVED" },
  53        { 0x42, 1, "GPE_CNTL" },
  54        { 0x43, 1, "RESERVED" },
  55        { 0x44, 2, "DEVACT_STS" }, // Device Activity Status
  56        { 0x46, 2, "RESERVED" },
  57        { 0x48, 4, "RESERVED" },
  58        { 0x4c, 4, "RESERVED" },
  59        { 0x50, 1, "PM2_CNT (Mobile)" }, // PM2 Control (Mobile only); ACPI pointer: PM2a_CNT_BLK
  60        { 0x51, 1, "RESERVED" },
  61        { 0x52, 2, "RESERVED" },
  62        { 0x54, 4, "C3_RES (Mobile)" },
  63        { 0x58, 4, "RESERVED" },
  64        { 0x5c, 4, "RESERVED" },
  65        /* Here start the TCO registers */
  66        { 0x60, 2, "TCO_RLD" },
  67        { 0x62, 1, "TCO_DAT_IN" },
  68        { 0x63, 1, "TCO_DAT_OUT" },
  69        { 0x64, 2, "TCO1_STS" },
  70        { 0x66, 2, "TCO2_STS" },
  71        { 0x68, 2, "TCO1_CNT" },
  72        { 0x6a, 2, "TCO2_CNT" },
  73        { 0x6c, 2, "TCO_MESSAGE" },
  74        { 0x6e, 1, "TCO_WDCNT" },
  75        { 0x6f, 1, "RESERVED" },
  76        { 0x70, 1, "SW_IRQ_GEN" },
  77        { 0x71, 1, "RESERVED" },
  78        { 0x72, 2, "TCO_TMR" },
  79        { 0x74, 4, "RESERVED" },
  80        { 0x78, 4, "RESERVED" },
  81        { 0x7c, 4, "RESERVED" },
  82};
  83
  84static const io_register_t ich9_pm_registers[] = {
  85        { 0x00, 2, "PM1_STS" }, // PM1 Status; ACPI pointer: PM1a_EVT_BLK
  86        { 0x02, 2, "PM1_EN" },  // PM1 Enables; ACPI pointer: PM1a_EVT_BLK+2
  87        { 0x04, 4, "PM1_CNT" }, // PM1 Control; ACPI pointer: PM1a_CNT_BLK
  88        { 0x08, 4, "PM1_TMR" }, // PM1 Timer; ACPI pointer: PMTMR_BLK
  89        { 0x0c, 4, "RESERVED" },
  90        { 0x10, 4, "PROC_CNT" }, // Processor Control; ACPI pointer: P_BLK
  91#if DANGEROUS_REGISTERS
  92        /* These registers return 0 on read, but reading them may cause
  93         * the system to enter Cx states, which might hang the system.
  94         */
  95        { 0x14, 1, "LV2 (Mobile)" },
  96        { 0x15, 1, "LV3 (Mobile)" },
  97        { 0x16, 1, "LV4 (Mobile)" },
  98        { 0x17, 1, "LV5 (Mobile)" },
  99        { 0x18, 1, "LV6 (Mobile)" },
 100#endif
 101        { 0x19, 1, "RESERVED" },
 102        { 0x1a, 2, "RESERVED" },
 103        { 0x1c, 4, "RESERVED" },
 104        { 0x20, 8, "GPE0_STS" }, // General Purpose Event 0 Status; ACPI pointer: GPE0_BLK
 105        { 0x2C, 4, "GPE0_EN" },  // General Purpose Event 0 Enables; ACPI pointer: GPE0_BLK+8
 106        { 0x30, 4, "SMI_EN" },
 107        { 0x34, 4, "SMI_STS" },
 108        { 0x38, 2, "ALT_GP_SMI_EN" },
 109        { 0x3a, 2, "ALT_GP_SMI_STS" },
 110        { 0x3c, 1, "UPRWC" },   // USB Per-Port registers write control;
 111        { 0x3d, 2, "RESERVED" },
 112        { 0x3f, 1, "RESERVED" },
 113        { 0x40, 2, "RESERVED" },
 114        { 0x42, 1, "GPE_CNTL" },
 115        { 0x43, 1, "RESERVED" },
 116        { 0x44, 2, "DEVACT_STS" }, // Device Activity Status
 117        { 0x46, 2, "RESERVED" },
 118        { 0x48, 4, "RESERVED" },
 119        { 0x4c, 4, "RESERVED" },
 120        { 0x50, 1, "PM2_CNT (Mobile)" }, // PM2 Control (Mobile only); ACPI pointer: PM2a_CNT_BLK
 121        { 0x51, 1, "RESERVED" },
 122        { 0x52, 2, "RESERVED" },
 123        { 0x54, 4, "C3_RES (Mobile)" },
 124        { 0x58, 4, "C5_RES (Mobile)" },
 125        { 0x5c, 4, "RESERVED" },
 126        /* Here start the TCO registers */
 127        { 0x60, 2, "TCO_RLD" },
 128        { 0x62, 1, "TCO_DAT_IN" },
 129        { 0x63, 1, "TCO_DAT_OUT" },
 130        { 0x64, 2, "TCO1_STS" },
 131        { 0x66, 2, "TCO2_STS" },
 132        { 0x68, 2, "TCO1_CNT" },
 133        { 0x6a, 2, "TCO2_CNT" },
 134        { 0x6c, 2, "TCO_MESSAGE" },
 135        { 0x6e, 1, "TCO_WDCNT" },
 136        { 0x6f, 1, "RESERVED" },
 137        { 0x70, 1, "SW_IRQ_GEN" },
 138        { 0x71, 1, "RESERVED" },
 139        { 0x72, 2, "TCO_TMR" },
 140        { 0x74, 4, "RESERVED" },
 141        { 0x78, 4, "RESERVED" },
 142        { 0x7c, 4, "RESERVED" },
 143};
 144
 145static const io_register_t ich8_pm_registers[] = {
 146        { 0x00, 2, "PM1_STS" },
 147        { 0x02, 2, "PM1_EN" },
 148        { 0x04, 4, "PM1_CNT" },
 149        { 0x08, 4, "PM1_TMR" },
 150        { 0x0c, 4, "RESERVED" },
 151        { 0x10, 4, "PROC_CNT" },
 152#if DANGEROUS_REGISTERS
 153        /* These registers return 0 on read, but reading them may cause
 154         * the system to enter Cx states, which might hang the system.
 155         */
 156        { 0x14, 1, "LV2 (Mobile)" },
 157        { 0x15, 1, "LV3 (Mobile)" },
 158        { 0x16, 1, "LV4 (Mobile)" },
 159        { 0x17, 1, "LV5 (Mobile)" },
 160        { 0x18, 1, "LV6 (Mobile)" },
 161#endif
 162        { 0x19, 1, "RESERVED" },
 163        { 0x1a, 2, "RESERVED" },
 164        { 0x1c, 4, "RESERVED" },
 165        { 0x20, 1, "PM2_CNT (Mobile)" },
 166        { 0x21, 1, "RESERVED" },
 167        { 0x22, 2, "RESERVED" },
 168        { 0x24, 4, "RESERVED" },
 169        { 0x28, 4, "GPE0_STS" },
 170        { 0x2C, 4, "GPE0_EN" },
 171        { 0x30, 4, "SMI_EN" },
 172        { 0x34, 4, "SMI_STS" },
 173        { 0x38, 2, "ALT_GP_SMI_EN" },
 174        { 0x3a, 2, "ALT_GP_SMI_STS" },
 175        { 0x3c, 4, "RESERVED" },
 176        { 0x40, 2, "RESERVED" },
 177        { 0x42, 1, "GPE_CNTL" },
 178        { 0x43, 1, "RESERVED" },
 179        { 0x44, 2, "DEVACT_STS" },
 180        { 0x46, 2, "RESERVED" },
 181        { 0x48, 4, "RESERVED" },
 182        { 0x4c, 4, "RESERVED" },
 183        { 0x50, 1, "SS_CNT (Mobile)" },
 184        { 0x51, 1, "RESERVED" },
 185        { 0x52, 2, "RESERVED" },
 186        { 0x54, 4, "C3_RES (Mobile)" },
 187        { 0x58, 4, "C5_RES (Mobile)" },
 188        { 0x5c, 4, "RESERVED" },
 189        /* Here start the TCO registers */
 190        { 0x60, 2, "TCO_RLD" },
 191        { 0x62, 1, "TCO_DAT_IN" },
 192        { 0x63, 1, "TCO_DAT_OUT" },
 193        { 0x64, 2, "TCO1_STS" },
 194        { 0x66, 2, "TCO2_STS" },
 195        { 0x68, 2, "TCO1_CNT" },
 196        { 0x6a, 2, "TCO2_CNT" },
 197        { 0x6c, 2, "TCO_MESSAGE" },
 198        { 0x6e, 1, "TCO_WDCNT" },
 199        { 0x6f, 1, "RESERVED" },
 200        { 0x70, 1, "SW_IRQ_GEN" },
 201        { 0x71, 1, "RESERVED" },
 202        { 0x72, 2, "TCO_TMR" },
 203        { 0x74, 4, "RESERVED" },
 204        { 0x78, 4, "RESERVED" },
 205        { 0x7c, 4, "RESERVED" },
 206};
 207
 208static const io_register_t ich7_pm_registers[] = {
 209        { 0x00, 2, "PM1_STS" },
 210        { 0x02, 2, "PM1_EN" },
 211        { 0x04, 4, "PM1_CNT" },
 212        { 0x08, 4, "PM1_TMR" },
 213        { 0x0c, 4, "RESERVED" },
 214        { 0x10, 4, "PROC_CNT" },
 215#if DANGEROUS_REGISTERS
 216        /* These registers return 0 on read, but reading them may cause
 217         * the system to enter C2/C3/C4 state, which might hang the system.
 218         */
 219        { 0x14, 1, "LV2 (Mobile/Ultra Mobile)" },
 220        { 0x15, 1, "LV3 (Mobile/Ultra Mobile)" },
 221        { 0x16, 1, "LV4 (Mobile/Ultra Mobile)" },
 222#endif
 223        { 0x17, 1, "RESERVED" },
 224        { 0x18, 4, "RESERVED" },
 225        { 0x1c, 4, "RESERVED" },
 226        { 0x20, 1, "PM2_CNT (Mobile/Ultra Mobile)" },
 227        { 0x21, 1, "RESERVED" },
 228        { 0x22, 2, "RESERVED" },
 229        { 0x24, 4, "RESERVED" },
 230        { 0x28, 4, "GPE0_STS" },
 231        { 0x2C, 4, "GPE0_EN" },
 232        { 0x30, 4, "SMI_EN" },
 233        { 0x34, 4, "SMI_STS" },
 234        { 0x38, 2, "ALT_GP_SMI_EN" },
 235        { 0x3a, 2, "ALT_GP_SMI_STS" },
 236        { 0x3c, 4, "RESERVED" },
 237        { 0x40, 2, "RESERVED" },
 238        { 0x42, 1, "GPE_CNTL" },
 239        { 0x43, 1, "RESERVED" },
 240        { 0x44, 2, "DEVACT_STS" },
 241        { 0x46, 2, "RESERVED" },
 242        { 0x48, 4, "RESERVED" },
 243        { 0x4c, 4, "RESERVED" },
 244        { 0x50, 1, "SS_CNT (Mobile/Ultra Mobile)" },
 245        { 0x51, 1, "RESERVED" },
 246        { 0x52, 2, "RESERVED" },
 247        { 0x54, 4, "C3_RES (Mobile/Ultra Mobile)" },
 248        { 0x58, 4, "RESERVED" },
 249        { 0x5c, 4, "RESERVED" },
 250        /* Here start the TCO registers */
 251        { 0x60, 2, "TCO_RLD" },
 252        { 0x62, 1, "TCO_DAT_IN" },
 253        { 0x63, 1, "TCO_DAT_OUT" },
 254        { 0x64, 2, "TCO1_STS" },
 255        { 0x66, 2, "TCO2_STS" },
 256        { 0x68, 2, "TCO1_CNT" },
 257        { 0x6a, 2, "TCO2_CNT" },
 258        { 0x6c, 2, "TCO_MESSAGE" },
 259        { 0x6e, 1, "TCO_WDCNT" },
 260        { 0x6f, 1, "RESERVED" },
 261        { 0x70, 1, "SW_IRQ_GEN" },
 262        { 0x71, 1, "RESERVED" },
 263        { 0x72, 2, "TCO_TMR" },
 264        { 0x74, 4, "RESERVED" },
 265        { 0x78, 4, "RESERVED" },
 266        { 0x7c, 4, "RESERVED" },
 267};
 268
 269/*
 270 * INTEL I/O Controller Hub 6 Family
 271 * http://www.intel.com/assets/pdf/datasheet/301473.pdf
 272 */
 273static const io_register_t ich6_pm_registers[] = {
 274        /* 10.8.3 */
 275        { 0x00, 2, "PM1_STS" },
 276        { 0x02, 2, "PM1_EN" },
 277        { 0x04, 4, "PM1_CNT" },
 278        { 0x08, 4, "PM1_TMR" },
 279        { 0x10, 4, "PROC_CNT" },
 280#if DANGEROUS_REGISTERS
 281        /* These registers return 0 on read, but reading them may cause
 282         * the system to enter C2/C3/C4 state, which might hang the system.
 283         */
 284        { 0x14, 1, "LV2" },
 285        { 0x15, 1, "LV3 (Mobile Only)" },
 286        { 0x16, 1, "LV4 (Mobile Only)" },
 287#endif
 288        { 0x20, 1, "PM2_CNT (Mobile Only)" },
 289        { 0x28, 4, "GPE0_STS" },
 290        { 0x2c, 4, "GPE0_EN" },
 291        { 0x30, 4, "SMI_EN" },
 292        { 0x34, 4, "SMI_STS" },
 293        { 0x38, 2, "ALT_GP_SMI_EN" },
 294        { 0x3a, 2, "ALT_GP_SMI_STS" },
 295        { 0x44, 2, "DEVACT_STS" },
 296        { 0x50, 1, "SS_CNT (Mobile Only)" },
 297        { 0x54, 4, "C3_RES (Mobile Only)" },
 298};
 299
 300static const io_register_t ich5_pm_registers[] = {
 301        { 0x00, 2, "PM1_STS" },
 302        { 0x02, 2, "PM1_EN" },
 303        { 0x04, 4, "PM1_CNT" },
 304        { 0x08, 4, "PM1_TMR" },
 305        { 0x0c, 4, "RESERVED" },
 306        { 0x10, 4, "PROC_CNT" },
 307        { 0x14, 3, "RESERVED" },
 308        { 0x17, 9, "RESERVED" },
 309        { 0x20, 1, "RESERVED" },
 310        { 0x28, 4, "GPE0_STS" },
 311        { 0x2c, 4, "GPE0_EN" },
 312        { 0x30, 4, "SMI_EN" },
 313        { 0x34, 4, "SMI_STS" },
 314        { 0x38, 2, "ALT_GP_SMI_EN" },
 315        { 0x3a, 2, "ALT_GP_SMI_STS" },
 316        { 0x3c, 4, "RESERVED" },
 317        { 0x40, 1, "MON_SMI" },
 318        { 0x42, 2, "RESERVED" },
 319        { 0x44, 1, "DEVACT_STS" },
 320        { 0x48, 1, "DEVTRAP_EN" },
 321        { 0x50, 1, "RESERVED" },
 322        { 0x51, 15, "RESERVED" },
 323        { 0x60, 16, "RESERVED" },
 324};
 325
 326static const io_register_t ich4_pm_registers[] = {
 327        { 0x00, 2, "PM1_STS" },
 328        { 0x02, 2, "PM1_EN" },
 329        { 0x04, 4, "PM1_CNT" },
 330        { 0x08, 4, "PM1_TMR" },
 331        { 0x0c, 4, "RESERVED" },
 332        { 0x10, 4, "PROC_CNT" },
 333#if DANGEROUS_REGISTERS
 334        /* These registers return 0 on read, but reading them may cause
 335         * the system to enter C2/C3/C4 state, which might hang the system.
 336         */
 337        { 0x14, 1, "LV2 (Mobile)" },
 338        { 0x15, 1, "LV3 (Mobile)" },
 339        { 0x16, 1, "LV4 (Mobile)" },
 340#endif
 341        { 0x17, 1, "RESERVED" },
 342        { 0x18, 4, "RESERVED" },
 343        { 0x1c, 4, "RESERVED" },
 344        { 0x20, 1, "PM2_CNT (Mobile)" },
 345        { 0x21, 1, "RESERVED" },
 346        { 0x22, 2, "RESERVED" },
 347        { 0x24, 4, "RESERVED" },
 348        { 0x28, 4, "GPE0_STS" },
 349        { 0x2C, 4, "GPE0_EN" },
 350        { 0x30, 4, "SMI_EN" },
 351        { 0x34, 4, "SMI_STS" },
 352        { 0x38, 2, "ALT_GP_SMI_EN" },
 353        { 0x3a, 2, "ALT_GP_SMI_STS" },
 354        { 0x3c, 4, "RESERVED" },
 355        { 0x40, 2, "MON_SMI" },
 356        { 0x42, 2, "RESERVED" },
 357        { 0x44, 2, "DEVACT_STS" },
 358        { 0x46, 2, "RESERVED" },
 359        { 0x48, 4, "DEVTRAP_EN" },
 360        { 0x4c, 2, "BUS_ADDR_TRACK" },
 361        { 0x4e, 2, "BUS_CYC_TRACK" },
 362        { 0x50, 1, "SS_CNT (Mobile/Ultra Mobile)" },
 363        { 0x51, 1, "RESERVED" },
 364        { 0x52, 2, "RESERVED" },
 365        { 0x54, 4, "RESERVED" },
 366        { 0x58, 4, "RESERVED" },
 367        { 0x5c, 4, "RESERVED" },
 368        /* Here start the TCO registers */
 369        { 0x60, 1, "TCO_RLD" },
 370        { 0x61, 1, "TCO_TMR" },
 371        { 0x62, 1, "TCO_DAT_IN" },
 372        { 0x63, 1, "TCO_DAT_OUT" },
 373        { 0x64, 2, "TCO1_STS" },
 374        { 0x66, 2, "TCO2_STS" },
 375        { 0x68, 2, "TCO1_CNT" },
 376        { 0x6a, 2, "TCO2_CNT" },
 377        { 0x6c, 2, "TCO_MESSAGE" },
 378        { 0x6e, 1, "TCO_WDSTATUS" },
 379        { 0x6f, 1, "RESERVED" },
 380        { 0x70, 1, "SW_IRQ_GEN" },
 381        { 0x71, 1, "RESERVED" },
 382        { 0x72, 2, "RESERVED" },
 383        { 0x74, 4, "RESERVED" },
 384        { 0x78, 4, "RESERVED" },
 385        { 0x7c, 4, "RESERVED" },
 386};
 387
 388static const io_register_t ich2_pm_registers[] = {
 389        { 0x00, 2, "PM1_STS" },
 390        { 0x02, 2, "PM1_EN" },
 391        { 0x04, 4, "PM1_CNT" },
 392        { 0x08, 4, "PM1_TMR" },
 393        { 0x0c, 4, "RESERVED" },
 394        { 0x10, 4, "PROC_CNT" },
 395#if DANGEROUS_REGISTERS
 396        /* This register returns 0 on read, but reading it may cause
 397         * the system to enter C2 state, which might hang the system.
 398         */
 399        { 0x14, 1, "LV2" },
 400        { 0x15, 1, "RESERVED" },
 401        { 0x16, 2, "RESERVED" },
 402#endif
 403        { 0x18, 4, "RESERVED" },
 404        { 0x1c, 4, "RESERVED" },
 405        { 0x20, 4, "RESERVED" },
 406        { 0x24, 4, "RESERVED" },
 407        { 0x28, 2, "GPE0_STS" },
 408        { 0x2a, 2, "GPE0_EN" },
 409        { 0x2c, 2, "GPE1_STS" },
 410        { 0x2e, 2, "GPE1_EN" },
 411        { 0x30, 2, "SMI_EN" },
 412        { 0x32, 2, "RESERVED" },
 413        { 0x34, 2, "SMI_STS" },
 414        { 0x36, 2, "RESERVED" },
 415        { 0x38, 4, "RESERVED" },
 416        { 0x3c, 4, "RESERVED" },
 417        { 0x40, 2, "MON_SMI_STS" },
 418        { 0x42, 2, "RESERVED" },
 419        { 0x44, 2, "DEV_TRP_STS" },
 420        { 0x46, 2, "RESERVED" },
 421        { 0x48, 2, "TRP_EN" },
 422        { 0x4A, 2, "RESERVED" },
 423        { 0x4c, 2, "BUS_ADDR_TRACK" },
 424        { 0x4e, 1, "BUS_CYC_TRACK" },
 425        { 0x4f, 1, "RESERVED" },
 426        { 0x50, 4, "RESERVED" },
 427        { 0x54, 4, "RESERVED" },
 428        { 0x58, 4, "RESERVED" },
 429        { 0x5c, 4, "RESERVED" },
 430        /* Here start the TCO registers */
 431        { 0x60, 1, "TCO_RLD" },
 432        { 0x61, 1, "TCO_TMR" },
 433        { 0x62, 1, "TCO_DAT_IN" },
 434        { 0x63, 1, "TCO_DAT_OUT" },
 435        { 0x64, 2, "TCO1_STS" },
 436        { 0x66, 2, "TCO2_STS" },
 437        { 0x68, 2, "TCO1_CNT" },
 438        { 0x6a, 2, "TCO2_CNT" },
 439        { 0x6c, 1, "TCO_MESSAGE1" },
 440        { 0x6d, 1, "TCO_MESSAGE2" },
 441        { 0x6e, 1, "TCO_WDSTATUS" },
 442        { 0x6f, 1, "RESERVED" },
 443        { 0x70, 1, "SW_IRQ_GEN" },
 444        { 0x71, 1, "RESERVED" },
 445        { 0x72, 2, "RESERVED" },
 446        { 0x74, 4, "RESERVED" },
 447        { 0x78, 4, "RESERVED" },
 448        { 0x7c, 4, "RESERVED" },
 449};
 450
 451static const io_register_t ich0_pm_registers[] = {
 452        { 0x00, 2, "PM1_STS" },
 453        { 0x02, 2, "PM1_EN" },
 454        { 0x04, 4, "PM1_CNT" },
 455        { 0x08, 4, "PM1_TMR" },
 456        { 0x0c, 4, "RESERVED" },
 457        { 0x10, 4, "PROC_CNT" },
 458#if DANGEROUS_REGISTERS
 459        /* This register returns 0 on read, but reading it may cause
 460         * the system to enter C2 state, which might hang the system.
 461         */
 462        { 0x14, 1, "LV2" },
 463        { 0x15, 1, "RESERVED" },
 464        { 0x16, 2, "RESERVED" },
 465#endif
 466        { 0x18, 4, "RESERVED" },
 467        { 0x1c, 4, "RESERVED" },
 468        { 0x20, 4, "RESERVED" },
 469        { 0x24, 4, "RESERVED" },
 470        { 0x28, 4, "GPE0_STS" },
 471        { 0x2C, 4, "GPE0_EN" },
 472        { 0x30, 2, "SMI_EN" },
 473        { 0x32, 2, "RESERVED" },
 474        { 0x34, 2, "SMI_STS" },
 475        { 0x36, 2, "RESERVED" },
 476        { 0x38, 4, "RESERVED" },
 477        { 0x3c, 4, "RESERVED" },
 478        { 0x40, 2, "IOMON_STS_EN" },
 479        { 0x42, 2, "RESERVED" },
 480        { 0x44, 2, "DEVACT_STS" },
 481        { 0x46, 2, "RESERVED" },
 482        { 0x48, 4, "RESERVED" },
 483        { 0x4c, 2, "BUS_ADDR_TRACK" },
 484        { 0x4e, 1, "BUS_CYC_TRACK" },
 485        { 0x4f, 1, "RESERVED" },
 486        { 0x50, 4, "RESERVED" },
 487        { 0x54, 4, "RESERVED" },
 488        { 0x58, 4, "RESERVED" },
 489        { 0x5c, 4, "RESERVED" },
 490        /* Here start the TCO registers */
 491        { 0x60, 1, "TCO_RLD" },
 492        { 0x61, 1, "TCO_TMR" },
 493        { 0x62, 1, "TCO_DAT_IN" },
 494        { 0x63, 1, "TCO_DAT_OUT" },
 495        { 0x64, 2, "TCO1_STS" },
 496        { 0x66, 2, "TCO2_STS" },
 497        { 0x68, 2, "TCO1_CNT" },
 498        { 0x6a, 2, "TCO2_CNT" },
 499        { 0x6c, 1, "TCO_MESSAGE1" },
 500        { 0x6d, 1, "TCO_MESSAGE2" },
 501        { 0x6e, 1, "TCO_WDSTATUS" },
 502        { 0x6f, 1, "RESERVED" },
 503        { 0x70, 4, "RESERVED" },
 504        { 0x74, 4, "RESERVED" },
 505        { 0x78, 4, "RESERVED" },
 506        { 0x7c, 4, "RESERVED" },
 507};
 508
 509static const io_register_t i82371xx_pm_registers[] = {
 510        { 0x00, 2, "PMSTS" },
 511        { 0x02, 2, "PMEN" },
 512        { 0x04, 2, "PMCNTRL" },
 513        { 0x06, 2, "RESERVED" },
 514        { 0x08, 1, "PMTMR" },
 515        { 0x09, 1, "RESERVED" },
 516        { 0x0A, 1, "RESERVED" },
 517        { 0x0B, 1, "RESERVED" },
 518        { 0x0C, 2, "GPSTS" },
 519        { 0x0E, 2, "GPEN" },
 520        { 0x10, 4, "PCNTRL" },
 521#if DANGEROUS_REGISTERS
 522        /*
 523         * This register returns 0 on read, but reading it may cause
 524         * the system to enter C2 state, which might hang the system.
 525         */
 526        { 0x14, 1, "PLVL2" },
 527        { 0x15, 1, "PLVL3" },
 528        { 0x16, 2, "RESERVED" },
 529#endif
 530        { 0x18, 2, "GLBSTS" },
 531        { 0x1A, 2, "RESERVED" },
 532        { 0x1c, 4, "DEVSTS" },
 533        { 0x20, 2, "GLBEN" },
 534        { 0x22, 1, "RESERVED" },
 535        { 0x23, 1, "RESERVED" },
 536        { 0x24, 1, "RESERVED" },
 537        { 0x25, 1, "RESERVED" },
 538        { 0x26, 1, "RESERVED" },
 539        { 0x27, 1, "RESERVED" },
 540        { 0x28, 4, "GLBCTL" },
 541        { 0x2C, 4, "DEVCTL" },
 542        /* The registers 0x30-0x33 and 0x34-0x37 allow byte-wise reads only. */
 543        { 0x30, 1, "GPIREG 0" },
 544        { 0x31, 1, "GPIREG 1" },
 545        { 0x32, 1, "GPIREG 2" },
 546        { 0x33, 1, "GPIREG 3" },
 547        { 0x34, 1, "GPOREG 0" },
 548        { 0x35, 1, "GPOREG 1" },
 549        { 0x36, 1, "GPOREG 2" },
 550        { 0x37, 1, "GPOREG 3" },
 551};
 552
 553int print_pmbase(struct pci_dev *sb, struct pci_access *pacc)
 554{
 555        int i, size;
 556        uint16_t pmbase;
 557        const io_register_t *pm_registers;
 558        struct pci_dev *acpi;
 559
 560        printf("\n============= PMBASE ============\n\n");
 561
 562        switch (sb->device_id) {
 563        case PCI_DEVICE_ID_INTEL_ICH10R:
 564                pmbase = pci_read_word(sb, 0x40) & 0xff80;
 565                pm_registers = ich10_pm_registers;
 566                size = ARRAY_SIZE(ich10_pm_registers);
 567                break;
 568        case PCI_DEVICE_ID_INTEL_ICH7:
 569        case PCI_DEVICE_ID_INTEL_ICH7M:
 570        case PCI_DEVICE_ID_INTEL_ICH7DH:
 571        case PCI_DEVICE_ID_INTEL_ICH7MDH:
 572        case PCI_DEVICE_ID_INTEL_NM10:
 573                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 574                pm_registers = ich7_pm_registers;
 575                size = ARRAY_SIZE(ich7_pm_registers);
 576                break;
 577        case PCI_DEVICE_ID_INTEL_ICH9DH:
 578        case PCI_DEVICE_ID_INTEL_ICH9DO:
 579        case PCI_DEVICE_ID_INTEL_ICH9R:
 580        case PCI_DEVICE_ID_INTEL_ICH9:
 581        case PCI_DEVICE_ID_INTEL_ICH9M:
 582        case PCI_DEVICE_ID_INTEL_ICH9ME:
 583                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 584                pm_registers = ich9_pm_registers;
 585                size = ARRAY_SIZE(ich9_pm_registers);
 586                break;
 587        case PCI_DEVICE_ID_INTEL_ICH8:
 588        case PCI_DEVICE_ID_INTEL_ICH8M:
 589                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 590                pm_registers = ich8_pm_registers;
 591                size = ARRAY_SIZE(ich8_pm_registers);
 592                break;
 593        case PCI_DEVICE_ID_INTEL_ICH6:
 594                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 595                pm_registers = ich6_pm_registers;
 596                size = ARRAY_SIZE(ich6_pm_registers);
 597                break;
 598        case PCI_DEVICE_ID_INTEL_ICH5:
 599                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 600                pm_registers = ich5_pm_registers;
 601                size = ARRAY_SIZE(ich5_pm_registers);
 602                break;
 603        case PCI_DEVICE_ID_INTEL_ICH4:
 604                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 605                pm_registers = ich4_pm_registers;
 606                size = ARRAY_SIZE(ich4_pm_registers);
 607                break;
 608        case PCI_DEVICE_ID_INTEL_ICH2:
 609                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 610                pm_registers = ich2_pm_registers;
 611                size = ARRAY_SIZE(ich2_pm_registers);
 612                break;
 613        case PCI_DEVICE_ID_INTEL_ICH0:
 614                pmbase = pci_read_word(sb, 0x40) & 0xfffc;
 615                pm_registers = ich0_pm_registers;
 616                size = ARRAY_SIZE(ich0_pm_registers);
 617                break;
 618        case PCI_DEVICE_ID_INTEL_82371XX:
 619                acpi = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 3);
 620                if (!acpi) {
 621                        printf("Southbridge function 3 not found.\n");
 622                        return 1;
 623                }
 624                pmbase = pci_read_word(acpi, 0x40) & 0xfffc;
 625                pm_registers = i82371xx_pm_registers;
 626                size = ARRAY_SIZE(i82371xx_pm_registers);
 627                break;
 628        case 0x1234: // Dummy for non-existent functionality
 629                printf("This southbridge does not have PMBASE.\n");
 630                return 1;
 631        default:
 632                printf("Error: Dumping PMBASE on this southbridge is not (yet) supported.\n");
 633                return 1;
 634        }
 635
 636        printf("PMBASE = 0x%04x (IO)\n\n", pmbase);
 637
 638        for (i = 0; i < size; i++) {
 639                switch (pm_registers[i].size) {
 640                case 4:
 641                        printf("pmbase+0x%04x: 0x%08x (%s)\n",
 642                                pm_registers[i].addr,
 643                                inl(pmbase+pm_registers[i].addr),
 644                                pm_registers[i].name);
 645                        break;
 646                case 2:
 647                        printf("pmbase+0x%04x: 0x%04x     (%s)\n",
 648                                pm_registers[i].addr,
 649                                inw(pmbase+pm_registers[i].addr),
 650                                pm_registers[i].name);
 651                        break;
 652                case 1:
 653                        printf("pmbase+0x%04x: 0x%02x       (%s)\n",
 654                                pm_registers[i].addr,
 655                                inb(pmbase+pm_registers[i].addr),
 656                                pm_registers[i].name);
 657                        break;
 658                }
 659        }
 660
 661        return 0;
 662}
 663
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.