[coreboot-gerrit] Patch set updated for coreboot: 2737627 baytrail: snapshot power state in romstage

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Mon May 12 22:20:13 CEST 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5032

-gerrit

commit 27376276e30956c7bb77f5d0ad35615c2182bfc2
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Jan 9 10:33:23 2014 -0600

    baytrail: snapshot power state in romstage
    
    The memory reference code doesn't maintain some of
    the registers which contain valuable information in order
    to log correct reset and wake events in the eventlog. Therefore
    snapshot the registers which matter in this area so that
    they can be consumed by ramstage.
    
    BUG=chrome-os-partner:24907
    BRANCH=rambi,squawks
    TEST=Did various resets/wakes with logging patch which
         consumes this structure. Eventlog can pick up reset
         events and power failures.
    
    Change-Id: Id8d2d782dd4e1133113f5308c4ccfe79bc6d3e03
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/181982
    Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/include/cbmem.h                        |  1 +
 src/lib/cbmem_info.c                       |  1 +
 src/soc/intel/baytrail/baytrail/pmc.h      | 66 +++++++++++++++++++++++++-
 src/soc/intel/baytrail/romstage/romstage.c | 76 +++++++++++++++++++++---------
 4 files changed, 121 insertions(+), 23 deletions(-)

diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index f103b30..beb626b 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -61,6 +61,7 @@
 #define CBMEM_ID_EHCI_DEBUG	0xe4c1deb9
 #define CBMEM_ID_REFCODE	0x04efc0de
 #define CBMEM_ID_REFCODE_CACHE	0x4efc0de5
+#define CBMEM_ID_POWER_STATE	0x50535454
 #define CBMEM_ID_SMM_SAVE_SPACE	0x07e9acee
 #define CBMEM_ID_RAM_OOPS	0x05430095
 #define CBMEM_ID_NONE		0x00000000
diff --git a/src/lib/cbmem_info.c b/src/lib/cbmem_info.c
index 42348e4..49724d6 100644
--- a/src/lib/cbmem_info.c
+++ b/src/lib/cbmem_info.c
@@ -52,6 +52,7 @@ static struct cbmem_id_to_name {
 	{ CBMEM_ID_REFCODE,		"REFCODE    " },
 	{ CBMEM_ID_SMM_SAVE_SPACE,	"SMM BACKUP " },
 	{ CBMEM_ID_REFCODE_CACHE,	"REFCODE $  " },
+	{ CBMEM_ID_POWER_STATE,		"POWER STATE" },
 	{ CBMEM_ID_RAM_OOPS,		"RAMOOPS    " },
 };
 
diff --git a/src/soc/intel/baytrail/baytrail/pmc.h b/src/soc/intel/baytrail/baytrail/pmc.h
index ab2e169..5013db8 100644
--- a/src/soc/intel/baytrail/baytrail/pmc.h
+++ b/src/soc/intel/baytrail/baytrail/pmc.h
@@ -24,11 +24,51 @@
 #define IOCOM1		0x3f8
 
 /* Memory mapped IO registers behind PMC_BASE_ADDRESS */
+#define PRSTS		0x00
+#	define PMC_WDT_STS	(1 << 15)
+#	define SEC_GBLRST_STS	(1 <<  7)
+#	define SEC_WDT_STS	(1 <<  6)
+#	define WOL_OVR_WK_STS	(1 <<  5)
+#	define PMC_WAKE_STS	(1 <<  4)
+#define PMC_CFG		0x08
+#	define SPS		(1 <<  5)
+#	define NO_REBOOT	(1 <<  4)
+#	define SX_ENT_TO_EN	(1 <<  3)
+#	define TIMING_T581_SHIFT (0)
+#	define TIMING_T581_MASK	(3 <<  TIMING_T581_SHIFT)
+#	define TIMING_T581_10uS  (0 << TIMING_T581_SHIFT)
+#	define TIMING_T581_100uS (1 << TIMING_T581_SHIFT)
+#	define TIMING_T581_1mS   (2 << TIMING_T581_SHIFT)
+#	define TIMING_T581_10mS  (3 << TIMING_T581_SHIFT)
+#define VLV_PM_STS	0x0c
+#	define PMC_MSG_FULL_STS		(1 << 24)
+#	define PMC_MSG_4_FULL_STS	(1 << 23)
+#	define PMC_MSG_3_FULL_STS	(1 << 22)
+#	define PMC_MSG_2_FULL_STS	(1 << 21)
+#	define PMC_MSG_1_FULL_STS	(1 << 20)
+#	define CODE_REQ			(1 <<  8)
+#	define HPR_ENT_TO		(1 <<  2)
+#	define SX_ENT_TO		(1 <<  1)
 #define GEN_PMCON1	0x20
-#	define AFTERG3_EN	(1 <<  0)
 #	define UART_EN		(1 << 24)
+#	define DISB		(1 << 23)
+#	define MEM_SR		(1 << 21)
+#	define SRS		(1 << 20)
+#	define CTS		(1 << 19)
+#	define MS4V		(1 << 18)
 #	define PWR_FLR		(1 << 16)
+#	define PME_B0_S5_DIS	(1 << 15)
 #	define SUS_PWR_FLR	(1 << 14)
+#	define WOL_EN_OVRD	(1 << 13)
+#	define DIS_SLP_X_STRCH_SUS_UP (1 << 12)
+#	define GEN_RST_STS	(1 <<  9)
+#	define RPS		(1 <<  2)
+#	define AFTERG3_EN	(1 <<  0)
+#define GEN_PMCON2	0x24
+#	define SLPSX_STR_POL_LOCK	(1 << 18)
+#	define BIOS_PCI_EXP_EN		(1 << 10)
+#	define PWRBTN_LVL		(1 <<  9)
+#	define SMI_LOCK			(1 <<  4)
 #define ETR			0x48
 #	define CF9LOCK		(1 << 31)
 #	define LTR_DEF		(1 << 22)
@@ -84,6 +124,14 @@
 #	define CLK_CTL_D3_LPE	(0x0 << 0)
 #	define CLK_CTL_ON	(0x1 << 0)
 #	define CLK_CTL_OFF	(0x2 << 0)
+#define PME_STS		0xc0
+#define GPE_LEVEL_EDGE  0xc4
+#	define GPE_EDGE		0
+#	define GPE_LEVEL	1
+#define GPE_POLARITY	0xc8
+#	define GPE_ACTIVE_HIGH	1
+#	define GPE_ACTIVE_LOW	0
+#define LOCK		0xcc
 
 /* IO Mapped registers behind ACPI_BASE_ADDRESS */
 #define PM1_STS			0x00
@@ -202,6 +250,18 @@
 #	define RST_CPU		(1 << 2)
 #	define SYS_RST		(1 << 1)
 
+/* Track power state from reset to log events. */
+struct chipset_power_state {
+	uint16_t pm1_sts;
+	uint16_t pm1_en;
+	uint32_t pm1_cnt;
+	uint32_t gpe0_sts;
+	uint32_t gpe0_en;
+	uint32_t tco_sts;
+	uint32_t prsts;
+	uint32_t gen_pmcon1;
+	uint32_t gen_pmcon2;
+} __attribute__((packed));
 
 /* Power Management Utility Functions. */
 uint16_t get_pmbase(void);
@@ -219,6 +279,10 @@ void enable_gpe(uint32_t mask);
 void disable_gpe(uint32_t mask);
 void disable_all_gpe(void);
 
+#if CONFIG_ELOG
+void southcluster_log_state(void);
+#else
 static inline void southcluster_log_state(void) {}
+#endif
 
 #endif /* _BAYTRAIL_PMC_H_ */
diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c
index cb884bd..baa62a5 100644
--- a/src/soc/intel/baytrail/romstage/romstage.c
+++ b/src/soc/intel/baytrail/romstage/romstage.c
@@ -22,6 +22,7 @@
 #include <arch/io.h>
 #include <arch/cbfs.h>
 #include <arch/stages.h>
+#include <arch/early_variables.h>
 #include <console/console.h>
 #include <cbmem.h>
 #include <cpu/x86/mtrr.h>
@@ -151,20 +152,56 @@ void * asmlinkage romstage_main(unsigned long bist,
 	return setup_stack_and_mttrs();
 }
 
+static struct chipset_power_state power_state CAR_GLOBAL;
+
+static void migrate_power_state(void)
+{
+	struct chipset_power_state *ps_cbmem;
+	struct chipset_power_state *ps_car;
+
+	ps_car = car_get_var_ptr(&power_state);
+	ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
+
+	if (ps_cbmem == NULL) {
+		printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
+		return;
+	}
+	memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
+}
+CAR_MIGRATE(migrate_power_state);
+
+static struct chipset_power_state *fill_power_state(void)
+{
+	struct chipset_power_state *ps = car_get_var_ptr(&power_state);
+
+	ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
+	ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN);
+	ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+	ps->gpe0_sts = inl(ACPI_BASE_ADDRESS + GPE0_STS);
+	ps->gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN);
+	ps->tco_sts = inl(ACPI_BASE_ADDRESS + TCO_STS);
+	ps->prsts = read32(PMC_BASE_ADDRESS + PRSTS);
+	ps->gen_pmcon1 = read32(PMC_BASE_ADDRESS + GEN_PMCON1);
+	ps->gen_pmcon2 = read32(PMC_BASE_ADDRESS + GEN_PMCON2);
+
+	printk(BIOS_DEBUG, "pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n",
+		ps->pm1_sts, ps->pm1_en, ps->pm1_cnt);
+	printk(BIOS_DEBUG, "gpe0_sts: %08x gpe0_en: %08x tco_sts: %08x\n",
+		ps->gpe0_sts, ps->gpe0_en, ps->tco_sts);
+	printk(BIOS_DEBUG, "prsts: %08x gen_pmcon1: %08x gen_pmcon2: %08x\n",
+		ps->prsts, ps->gen_pmcon1, ps->gen_pmcon2);
+
+	return ps;
+}
+
 /* Return 0, 3, or 5 to indicate the previous sleep state. */
-static int chipset_prev_sleep_state(void)
+static int chipset_prev_sleep_state(struct chipset_power_state *ps)
 {
-	uint16_t pm1_sts;
-	uint32_t pm1_cnt;
-	uint32_t gen_pmcon1;
 	/* Default to S0. */
 	int prev_sleep_state = 0;
 
-	pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
-	pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
-
-	if (pm1_sts & WAK_STS) {
-		switch ((pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) {
+	if (ps->pm1_sts & WAK_STS) {
+		switch ((ps->pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) {
 	#if CONFIG_HAVE_ACPI_RESUME
 		case SLP_TYP_S3:
 			prev_sleep_state = 3;
@@ -172,38 +209,32 @@ static int chipset_prev_sleep_state(void)
 	#endif
 		case SLP_TYP_S5:
 			prev_sleep_state = 5;
+			break;
 		}
 		/* Clear SLP_TYP. */
-		outl(pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
+		outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
 	}
 
-	gen_pmcon1 = read32(PMC_BASE_ADDRESS + GEN_PMCON1);
-	if (gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) {
-		/* Clear power failure bits. */
-		write32(PMC_BASE_ADDRESS + GEN_PMCON1, gen_pmcon1);
+	if (ps->gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) {
 		prev_sleep_state = 5;
 	}
 
-	printk(BIOS_DEBUG, "pm1_sts = %04x pm1_cnt = %08x gen_pmcon1 = %08x\n",
-	       pm1_sts, pm1_cnt, gen_pmcon1);
-
 	return prev_sleep_state;
 }
 
-#if CONFIG_CHROMEOS
 static inline void chromeos_init(int prev_sleep_state)
 {
+#if CONFIG_CHROMEOS
 	/* Normalize the sleep state to what init_chromeos() wants for S3: 2. */
 	init_chromeos(prev_sleep_state == 3 ? 2 : 0);
-}
-#else
-static inline void chromeos_init(int prev_sleep_state) {}
 #endif
+}
 
 /* Entry from the mainboard. */
 void romstage_common(struct romstage_params *params)
 {
 	struct romstage_handoff *handoff;
+	struct chipset_power_state *ps;
 	int prev_sleep_state;
 
 	mark_ts(params, timestamp_get());
@@ -212,7 +243,8 @@ void romstage_common(struct romstage_params *params)
 	boot_count_increment();
 #endif
 
-	prev_sleep_state = chipset_prev_sleep_state();
+	ps = fill_power_state();
+	prev_sleep_state = chipset_prev_sleep_state(ps);
 
 	printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state);
 



More information about the coreboot-gerrit mailing list