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 <acpi/acpi_pm.h>
4 #include <bootstate.h>
5 #include <commonlib/helpers.h>
6 #include <device/mmio.h>
7 #include <device/pci_ops.h>
8 #include <stdint.h>
9 #include <elog.h>
10 #include <intelblocks/pmclib.h>
11 #include <intelblocks/xhci.h>
12 #include <soc/pci_devs.h>
13 #include <soc/pm.h>
14 #include <soc/smbus.h>
15 
16 static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
17 {
18  int i;
19 
20  gpe0_sts &= gpe0_en;
21 
22  for (i = 0; i <= 31; i++) {
23  if (gpe0_sts & (1 << i))
25  }
26 }
27 
28 struct pme_status_info {
29  unsigned int devfn;
32 };
33 
34 #define PME_STS_BIT (1 << 15)
35 
37 {
38  size_t i;
39  uint16_t val;
40  bool dev_found = false;
41 
42  const struct pme_status_info pme_status_info[] = {
48  };
49  const struct xhci_wake_info xhci_wake_info[] = {
51  };
52 
53  for (i = 0; i < ARRAY_SIZE(pme_status_info); i++) {
54  pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(pme_status_info[i].devfn),
55  PCI_FUNC(pme_status_info[i].devfn));
56 
57  val = pci_s_read_config16(dev, pme_status_info[i].reg_offset);
58 
59  if ((val == 0xFFFF) || !(val & PME_STS_BIT))
60  continue;
61 
62  elog_add_event_wake(pme_status_info[i].elog_event, 0);
63  dev_found = true;
64  }
65 
66  /*
67  * Check the XHCI controllers' USB2 & USB3 ports for wake events. There
68  * are cases (GSMI logging for S0ix clears PME_STS_BIT) where the XHCI
69  * controller's PME_STS_BIT may have already been cleared, so the host
70  * controller wake wouldn't get logged here; therefore, the host
71  * controller wake event is logged before its corresponding port wake
72  * event is logged.
73  */
76 
77  if (!dev_found)
79 }
80 
81 #define RP_PME_STS_BIT (1 << 16)
82 static void pch_log_rp_wake_source(void)
83 {
84  size_t i, maxports;
85  uint32_t val;
86 
87  struct pme_status_info pme_status_info[] = {
112  };
113 
114  maxports = MIN(CONFIG_MAX_ROOT_PORTS, ARRAY_SIZE(pme_status_info));
115 
116  for (i = 0; i < maxports; i++) {
119 
121 
122  if ((val == 0xFFFFFFFF) || !(val & RP_PME_STS_BIT))
123  continue;
124 
125  /*
126  * Linux kernel uses PME STS bit information. So do not clear
127  * this bit.
128  */
130  }
131 }
132 
133 static void pch_log_wake_source(const struct chipset_power_state *ps)
134 {
135  /* Power Button */
136  if (ps->pm1_sts & PWRBTN_STS)
138 
139  /* RTC */
140  if (ps->pm1_sts & RTC_STS)
142 
143  /* PCI Express (TODO: determine wake device) */
144  if (ps->pm1_sts & PCIEXPWAK_STS)
146 
147  /*
148  * PCIE Root Port .
149  * This should be done when PCIEXPWAK_STS bit is set.
150  * In SPT, this bit isn't getting set due to known bug.
151  * So scan all PCIe RP for PME status bit.
152  */
154 
155  /* PME (TODO: determine wake device) */
156  if (ps->gpe0_sts[GPE_STD] & PME_STS)
158 
159  /* Internal PME (TODO: determine wake device) */
160  if (ps->gpe0_sts[GPE_STD] & PME_B0_STS)
162 
163  /* SMBUS Wake */
164  if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)
166 
167  /* Log GPIO events in set 1-3 */
171  /* Treat the STD as an extension of GPIO to obtain visibility. */
173 }
174 
175 static void pch_log_power_and_resets(const struct chipset_power_state *ps)
176 {
177  bool deep_sx;
178 
179  /*
180  * Platform entered deep Sx if:
181  * 1. Prev sleep state was Sx and deep_sx_enabled() is true
182  * 2. SUS well power was lost
183  */
184  deep_sx = ((((ps->prev_sleep_state == ACPI_S3) && deep_s3_enabled()) ||
185  ((ps->prev_sleep_state == ACPI_S5) && deep_s5_enabled())) &&
186  (ps->gen_pmcon_b & SUS_PWR_FLR));
187 
188  /* Thermal Trip */
191 
192  /* PWR_FLR Power Failure */
193  if (ps->gen_pmcon_b & PWR_FLR)
195 
196  /* SUS Well Power Failure */
197  if (ps->gen_pmcon_b & SUS_PWR_FLR) {
198  /* Do not log SUS_PWR_FLR if waking from deep Sx */
199  if (!deep_sx)
201  }
202 
203  /* TCO Timeout */
204  if (ps->prev_sleep_state != ACPI_S3 &&
207 
208  /* Power Button Override */
209  if (ps->pm1_sts & PRBTNOR_STS)
211 
212  /* RTC reset */
213  if (ps->gen_pmcon_b & RTC_BATTERY_DEAD)
215 
216  /* Host Reset Status */
217  if (ps->gen_pmcon_b & HOST_RST_STS)
219 
220  /* ACPI Wake Event */
221  if (ps->prev_sleep_state != ACPI_S0) {
222  if (deep_sx)
224  ps->prev_sleep_state);
225  else
227  ps->prev_sleep_state);
228  }
229 }
230 
231 static void pch_log_state(void *unused)
232 {
233  const struct chipset_power_state *ps;
234 
235  if (acpi_pm_state_for_elog(&ps) < 0)
236  return;
237 
238  /* Power and Reset */
240 
241  /* Wake Sources */
242  if (ps->prev_sleep_state > 0)
244 }
245 
247 
249 {
250  struct chipset_power_state ps;
252  pch_log_wake_source(&ps);
253 }
int acpi_pm_state_for_elog(const struct chipset_power_state **ps)
Definition: acpi_pm.c:41
#define GPE_63_32
Definition: pm.h:83
#define GPE_31_0
Definition: pm.h:82
#define GPE_STD
Definition: pm.h:85
#define SMB_WAK_STS
Definition: pm.h:95
#define GPE_95_64
Definition: pm.h:84
#define PME_STS
Definition: pm.h:92
#define PRBTNOR_STS
Definition: pm.h:15
#define PME_B0_STS
Definition: pm.h:90
@ BS_DEV_INIT
Definition: bootstate.h:83
@ BS_ON_EXIT
Definition: bootstate.h:96
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define MIN(a, b)
Definition: helpers.h:37
#define PWRBTN_STS
Definition: southbridge.h:30
#define PCIEXPWAK_STS
Definition: southbridge.h:28
#define RTC_STS
Definition: southbridge.h:29
#define ELOG_WAKE_SOURCE_PME_PCIE23
Definition: elog.h:193
#define ELOG_WAKE_SOURCE_PME_PCIE2
Definition: elog.h:163
#define ELOG_WAKE_SOURCE_RTC
Definition: elog.h:154
#define ELOG_WAKE_SOURCE_PME_PCIE19
Definition: elog.h:189
#define ELOG_WAKE_SOURCE_PME_GBE
Definition: elog.h:159
#define ELOG_WAKE_SOURCE_PME_PCIE18
Definition: elog.h:188
#define ELOG_WAKE_SOURCE_PME_PCIE7
Definition: elog.h:168
#define ELOG_WAKE_SOURCE_PME_PCIE5
Definition: elog.h:166
#define ELOG_WAKE_SOURCE_PME_PCIE16
Definition: elog.h:186
#define ELOG_WAKE_SOURCE_PME_PCIE10
Definition: elog.h:171
#define ELOG_WAKE_SOURCE_PCIE
Definition: elog.h:151
#define ELOG_WAKE_SOURCE_PME_PCIE14
Definition: elog.h:184
#define ELOG_WAKE_SOURCE_PME_PCIE13
Definition: elog.h:183
#define ELOG_TYPE_SUS_POWER_FAIL
Definition: elog.h:129
#define ELOG_WAKE_SOURCE_PME_PCIE20
Definition: elog.h:190
#define ELOG_TYPE_THERM_TRIP
Definition: elog.h:277
#define ELOG_TYPE_POWER_FAIL
Definition: elog.h:128
#define ELOG_WAKE_SOURCE_PME_PCIE21
Definition: elog.h:191
#define ELOG_WAKE_SOURCE_PME_CSE
Definition: elog.h:175
#define ELOG_WAKE_SOURCE_PME_PCIE11
Definition: elog.h:172
#define ELOG_WAKE_SOURCE_PME_PCIE17
Definition: elog.h:187
#define ELOG_WAKE_SOURCE_PME_PCIE22
Definition: elog.h:192
#define ELOG_WAKE_SOURCE_PME_XDCI
Definition: elog.h:179
#define ELOG_TYPE_ACPI_DEEP_WAKE
Definition: elog.h:283
#define ELOG_TYPE_ACPI_WAKE
Definition: elog.h:149
#define ELOG_WAKE_SOURCE_PME_PCIE15
Definition: elog.h:185
#define ELOG_WAKE_SOURCE_PME
Definition: elog.h:152
#define ELOG_WAKE_SOURCE_PME_SATA
Definition: elog.h:174
#define ELOG_WAKE_SOURCE_PME_PCIE24
Definition: elog.h:194
#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_WAKE_SOURCE_PME_PCIE1
Definition: elog.h:162
#define ELOG_TYPE_SYSTEM_RESET
Definition: elog.h:138
#define ELOG_WAKE_SOURCE_PME_PCIE9
Definition: elog.h:170
#define ELOG_WAKE_SOURCE_PME_PCIE3
Definition: elog.h:164
#define ELOG_TYPE_RTC_RESET
Definition: elog.h:139
#define ELOG_WAKE_SOURCE_PME_PCIE6
Definition: elog.h:167
#define ELOG_TYPE_TCO_RESET
Definition: elog.h:140
#define ELOG_WAKE_SOURCE_PME_XHCI
Definition: elog.h:178
#define ELOG_WAKE_SOURCE_PME_PCIE8
Definition: elog.h:169
#define ELOG_WAKE_SOURCE_PME_PCIE4
Definition: elog.h:165
#define ELOG_WAKE_SOURCE_PME_HDA
Definition: elog.h:158
#define ELOG_WAKE_SOURCE_SMBUS
Definition: elog.h:156
#define ELOG_WAKE_SOURCE_PME_PCIE12
Definition: elog.h:173
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY, elog_bs_init, NULL)
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
@ ACPI_S5
Definition: acpi.h:1385
@ ACPI_S3
Definition: acpi.h:1383
@ ACPI_S0
Definition: acpi.h:1380
#define PWR_FLR
Definition: pmc.h:30
#define HOST_RST_STS
Definition: pmc.h:38
#define GBLRST_CAUSE0_THERMTRIP
Definition: pmc.h:132
#define RTC_BATTERY_DEAD
Definition: pmc.h:61
#define SUS_PWR_FLR
Definition: pmc.h:28
#define PCI_FUNC(devfn)
Definition: pci_def.h:550
#define PCI_SLOT(devfn)
Definition: pci_def.h:549
static __always_inline uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
Definition: pci_io_cfg.h:92
static __always_inline uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
Definition: pci_io_cfg.h:86
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
u32 pci_devfn_t
Definition: pci_type.h:8
static int deep_s5_enabled(void)
Definition: pm.h:181
void elog_gsmi_cb_platform_log_wake_source(void)
Definition: elog.c:212
#define PCH_DEVFN_PCIE12
Definition: pci_devs.h:197
#define PCH_DEVFN_PCIE2
Definition: pci_devs.h:177
#define PCH_DEVFN_PCIE11
Definition: pci_devs.h:196
#define PCH_DEVFN_PCIE5
Definition: pci_devs.h:180
#define PCH_DEVFN_PCIE9
Definition: pci_devs.h:194
#define PCH_DEVFN_USBOTG
Definition: pci_devs.h:125
#define PCH_DEVFN_SATA
Definition: pci_devs.h:158
#define PCH_DEVFN_GBE
Definition: pci_devs.h:221
#define PCH_DEVFN_XHCI
Definition: pci_devs.h:124
#define PCH_DEVFN_HDA
Definition: pci_devs.h:218
#define PCH_DEVFN_PCIE6
Definition: pci_devs.h:181
#define PCH_DEVFN_PCIE3
Definition: pci_devs.h:178
#define PCH_DEVFN_PCIE7
Definition: pci_devs.h:182
#define PCH_DEVFN_PCIE4
Definition: pci_devs.h:179
#define PCH_DEVFN_PCIE10
Definition: pci_devs.h:195
#define PCH_DEVFN_PCIE8
Definition: pci_devs.h:183
#define PCH_DEVFN_PCIE1
Definition: pci_devs.h:176
#define PCH_DEVFN_CSE
Definition: pci_devs.h:144
static int deep_s3_enabled(void)
Definition: pmutil.c:189
void pch_log_state(void)
Definition: elog.c:88
#define TCO_STS_SECOND_TO
Definition: smbus.h:10
#define PCH_DEVFN_PCIE15
Definition: pci_devs.h:138
#define PCH_DEVFN_PCIE20
Definition: pci_devs.h:153
#define PCH_DEVFN_PCIE22
Definition: pci_devs.h:155
#define PCH_DEVFN_PCIE14
Definition: pci_devs.h:137
#define PCH_DEVFN_PCIE19
Definition: pci_devs.h:152
#define PCH_DEVFN_PCIE21
Definition: pci_devs.h:154
#define PCH_DEVFN_PCIE13
Definition: pci_devs.h:136
#define PCH_DEVFN_PCIE23
Definition: pci_devs.h:156
#define PCH_DEVFN_PCIE17
Definition: pci_devs.h:150
#define PCH_DEVFN_PCIE16
Definition: pci_devs.h:139
#define PCH_DEVFN_PCIE18
Definition: pci_devs.h:151
#define PCH_DEVFN_PCIE24
Definition: pci_devs.h:157
void pmc_fill_pm_reg_info(struct chipset_power_state *ps)
Definition: pmclib.c:413
bool xhci_update_wake_event(const struct xhci_wake_info *wake_info, size_t wake_info_count)
Definition: elog.c:98
static void pch_log_pme_internal_wake_source(void)
Definition: elog.c:36
static void pch_log_wake_source(const struct chipset_power_state *ps)
Definition: elog.c:133
static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
Definition: elog.c:16
#define PME_STS_BIT
Definition: elog.c:34
#define RP_PME_STS_BIT
Definition: elog.c:81
static void pch_log_rp_wake_source(void)
Definition: elog.c:82
static void pch_log_power_and_resets(const struct chipset_power_state *ps)
Definition: elog.c:175
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned char uint8_t
Definition: stdint.h:8
uint16_t tco2_sts
Definition: pm.h:146
uint32_t gpe0_en[4]
Definition: pm.h:148
uint32_t prev_sleep_state
Definition: pm.h:153
uint32_t gpe0_sts[4]
Definition: pm.h:147
uint32_t gen_pmcon_b
Definition: pm.h:150
uint16_t pm1_sts
Definition: pm.h:142
uint32_t gblrst_cause[2]
Definition: pm.h:151
pci_devfn_t dev
Definition: elog.c:16
unsigned int devfn
Definition: elog.c:29
uint32_t elog_event
Definition: elog.c:18
uint8_t reg_offset
Definition: elog.c:17
u8 val
Definition: sys.c:300