coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
elog.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <acpi/acpi.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ops.h>
8 #include <stdint.h>
9 #include <elog.h>
10 #include "pch.h"
11 
12 static void pch_log_standard_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg)
13 {
14  u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
15  u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;
16 
17  /* PME (TODO: determine wake device) */
18  if (gpe0_sts & PME_STS)
20 
21  /* Internal PME (TODO: determine wake device) */
22  if (gpe0_sts & PME_B0_STS)
24 
25  /* SMBUS Wake */
26  if (gpe0_sts & SMB_WAK_STS)
28 }
29 
30 static void pch_log_gpio_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg, int start)
31 {
32  /* GPE Bank 1 is GPIO 0-31 */
33  u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
34  u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;
35  int i;
36 
37  for (i = 0; i <= 31; i++) {
38  if (gpe0_sts & (1 << i))
40  }
41 }
42 
43 static void pch_log_gpe(void)
44 {
45  int i;
46  u16 pmbase = get_pmbase();
47  u32 gpe0_sts, gpe0_en;
48  int gpe0_high_gpios[] = {
49  [0] = 27,
50  [24] = 17,
51  [25] = 19,
52  [26] = 21,
53  [27] = 22,
54  [28] = 43,
55  [29] = 56,
56  [30] = 57,
57  [31] = 60
58  };
59 
61 
62  /* GPIO 0-15 */
63  gpe0_en = inw(pmbase + GPE0_EN + 2);
64  gpe0_sts = inw(pmbase + GPE0_STS + 2) & gpe0_en;
65  for (i = 0; i <= 15; i++) {
66  if (gpe0_sts & (1 << i))
68  }
69 
70  /*
71  * Now check and log upper status bits
72  */
73 
74  gpe0_en = inl(pmbase + GPE0_EN_2);
75  gpe0_sts = inl(pmbase + GPE0_STS_2) & gpe0_en;
76 
77  for (i = 0; i <= 31; i++) {
78  if (!gpe0_high_gpios[i])
79  continue;
80  if (gpe0_sts & (1 << i))
82  gpe0_high_gpios[i]);
83  }
84 }
85 
86 static void pch_lp_log_gpe(void)
87 {
88  /* Standard GPE are in GPE set 4 */
90 
91  /* Log GPIO events in set 1-3 */
95 }
96 
97 void pch_log_state(void)
98 {
99  u16 pm1_sts, gen_pmcon_3, tco2_sts;
100  u8 gen_pmcon_2;
101  struct device *lpc = pcidev_on_root(0x1f, 0);
102  if (!lpc)
103  return;
104 
105  pm1_sts = inw(get_pmbase() + PM1_STS);
106  tco2_sts = inw(get_pmbase() + TCO2_STS);
107  gen_pmcon_2 = pci_read_config8(lpc, GEN_PMCON_2);
108  gen_pmcon_3 = pci_read_config16(lpc, GEN_PMCON_3);
109 
110  /* PWR_FLR Power Failure */
111  if (gen_pmcon_2 & PWROK_FLR)
113 
114  /* SUS Well Power Failure */
115  if (gen_pmcon_3 & SUS_PWR_FLR)
117 
118  /* SYS_PWROK Failure */
119  if (gen_pmcon_2 & SYSPWR_FLR)
121 
122  /* PWROK Failure */
123  if (gen_pmcon_2 & PWROK_FLR)
125 
126  /* Second TCO Timeout */
127  if (tco2_sts & SECOND_TO_STS)
129 
130  /* Power Button Override */
131  if (pm1_sts & PRBTNOR_STS)
133 
134  /* System Reset Status (reset button pushed) */
135  if (gen_pmcon_2 & SYSTEM_RESET_STS)
137 
138  /* General Reset Status */
139  if (gen_pmcon_3 & GEN_RST_STS)
141 
142  /* ACPI Wake */
143  if (pm1_sts & WAK_STS)
145  acpi_is_wakeup_s3() ? 3 : 5);
146 
147  /*
148  * Wake sources
149  */
150 
151  /* Power Button */
152  if (pm1_sts & PWRBTN_STS)
154 
155  /* RTC */
156  if (pm1_sts & RTC_STS)
158 
159  /* PCI Express (TODO: determine wake device) */
160  if (pm1_sts & PCIEXPWAK_STS)
162 
163  /* GPE */
164  if (pch_is_lp())
165  pch_lp_log_gpe();
166  else
167  pch_log_gpe();
168 }
uint16_t get_pmbase(void)
Definition: pmutil.c:254
#define GPE0_STS(x)
Definition: pm.h:81
#define PM1_STS
Definition: pm.h:12
#define GPE0_EN(x)
Definition: pm.h:99
#define SMB_WAK_STS
Definition: pm.h:95
#define PME_STS
Definition: pm.h:92
#define PRBTNOR_STS
Definition: pm.h:15
#define PME_B0_STS
Definition: pm.h:90
static int acpi_is_wakeup_s3(void)
Definition: acpi.h:9
#define SECOND_TO_STS
Definition: pm.h:227
#define GEN_RST_STS
Definition: pm.h:48
#define PWRBTN_STS
Definition: southbridge.h:30
#define PCIEXPWAK_STS
Definition: southbridge.h:28
#define WAK_STS
Definition: southbridge.h:27
#define RTC_STS
Definition: southbridge.h:29
#define ELOG_WAKE_SOURCE_RTC
Definition: elog.h:154
#define ELOG_TYPE_RESET_BUTTON
Definition: elog.h:137
#define ELOG_WAKE_SOURCE_PCIE
Definition: elog.h:151
#define ELOG_TYPE_PWROK_FAIL
Definition: elog.h:130
#define ELOG_TYPE_SUS_POWER_FAIL
Definition: elog.h:129
#define ELOG_TYPE_POWER_FAIL
Definition: elog.h:128
#define ELOG_TYPE_SYS_PWROK_FAIL
Definition: elog.h:131
#define ELOG_TYPE_ACPI_WAKE
Definition: elog.h:149
#define ELOG_WAKE_SOURCE_PME
Definition: elog.h:152
#define ELOG_WAKE_SOURCE_GPE
Definition: elog.h:155
#define ELOG_WAKE_SOURCE_PWRBTN
Definition: elog.h:157
#define ELOG_WAKE_SOURCE_PME_INTERNAL
Definition: elog.h:153
#define ELOG_TYPE_POWER_BUTTON_OVERRIDE
Definition: elog.h:134
#define ELOG_TYPE_SYSTEM_RESET
Definition: elog.h:138
#define ELOG_TYPE_TCO_RESET
Definition: elog.h:140
#define ELOG_WAKE_SOURCE_SMBUS
Definition: elog.h:156
u16 inw(u16 port)
u32 inl(u16 port)
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
int elog_add_event_byte(u8 event_type, u8 data)
Definition: elog.c:868
int elog_add_event_wake(u8 source, u32 instance)
Definition: elog.c:883
int elog_add_event(u8 event_type)
Definition: elog.c:863
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
#define SUS_PWR_FLR
Definition: pmc.h:28
void pch_log_state(void)
Definition: elog.c:88
#define TCO2_STS
Definition: smbus.h:9
#define PWROK_FLR
Definition: lpc.h:62
#define GEN_PMCON_3
Definition: lpc.h:63
#define GEN_PMCON_2
Definition: lpc.h:58
#define SYSPWR_FLR
Definition: lpc.h:61
#define SYSTEM_RESET_STS
Definition: lpc.h:59
static u16 pmbase
Definition: smi.c:27
static void pch_lp_log_gpe(void)
Definition: elog.c:86
static void pch_log_gpe(void)
Definition: elog.c:43
static void pch_log_gpio_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg, int start)
Definition: elog.c:30
static void pch_log_standard_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg)
Definition: elog.c:12
static int pch_is_lp(void)
Definition: pch.h:104
#define LP_GPE0_EN_2
Definition: pch.h:636
#define LP_GPE0_EN_4
Definition: pch.h:638
#define GPE0_EN_2
Definition: pch.h:601
#define LP_GPE0_STS_1
Definition: pch.h:631
#define LP_GPE0_STS_4
Definition: pch.h:634
#define LP_GPE0_STS_2
Definition: pch.h:632
#define LP_GPE0_EN_3
Definition: pch.h:637
#define LP_GPE0_STS_3
Definition: pch.h:633
#define LP_GPE0_EN_1
Definition: pch.h:635
#define GPE0_STS_2
Definition: pch.h:596
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
Definition: device.h:107