Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1318
-gerrit
commit 81a02a12b1f4a1fb9be6217f3249debb34ed7043
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 17:02:29 2012 -0700
SMM: Skip locking SPI registers in finalize step
This is a temporary workaround so the SPI bus can be accessed
at runtime in SMM code until the SPI opcode menu is used
properly.
Change-Id: I93d188c55b66d8dce49fa91a1de53ee195944b30
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/southbridge/intel/bd82x6x/finalize.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/southbridge/intel/bd82x6x/finalize.c b/src/southbridge/intel/bd82x6x/finalize.c
index ed1ebf7..d62600f 100644
--- a/src/southbridge/intel/bd82x6x/finalize.c
+++ b/src/southbridge/intel/bd82x6x/finalize.c
@@ -31,8 +31,11 @@ void intel_pch_finalize_smm(void)
RCBA32(0x3898) = SPI_OPMENU_LOWER;
RCBA32(0x389c) = SPI_OPMENU_UPPER;
+/* Need to fix SMI driver use of opcode menu */
+#if !CONFIG_ELOG_GSMI
/* Lock SPIBAR */
RCBA32_OR(0x3804, (1 << 15));
+#endif
/* TCLOCKDN: TC Lockdown */
RCBA32_OR(0x0050, (1 << 31));
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1317
-gerrit
commit d66dc4e5e6d8b4c227a78a973ba3b057824fbb22
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 17:25:29 2012 -0700
ELOG: Support GSMI in CPT/PPT southbridge SMI handler
In order to support the GSMI interface the SMI handler needs
to find and use the state save area from the same CPU that
initiated the SMI. In this case it is a synchronous SMI
resulting form an IO write to port 0xB2.
To find the right CPU state save area iterate over the region
until the "IO Misc Info" field reports the expected value and
then proceed to use that state save area.
This is needed because the coreboot SMI handler only executes on
one core, and that core is non-deterministic. It is likely that
the core executing the C SMM handler is not the same one that
actually did the IO write to 0xB2 and generated the SMI.
The GSMI parameter buffer is passed as a pointer to EBX in the
tate save area, and the GSMI command is extracted from EAX before
it is used as the return value.
This interface is tested by enabling CONFIG_GOOGLE_GSMI in the
kernel and generating events and verifying that they end up
in the event log.
159 | 2012-06-23 16:22:45 | Kernl Event | Clean Shutdown
184 | 2012-06-23 17:14:05 | Kernl Event | Oops
185 | 2012-06-23 17:14:05 | Kernl Event | Panic
Change-Id: Ic121ea69e9f50c88467c435e095c3e3629989806
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/southbridge/intel/bd82x6x/smihandler.c | 53 ++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/src/southbridge/intel/bd82x6x/smihandler.c b/src/southbridge/intel/bd82x6x/smihandler.c
index 2c3bf67..715a82f 100644
--- a/src/southbridge/intel/bd82x6x/smihandler.c
+++ b/src/southbridge/intel/bd82x6x/smihandler.c
@@ -28,6 +28,7 @@
#include <cpu/x86/smm.h>
#include <device/pci_def.h>
#include <cpu/x86/smm.h>
+#include <elog.h>
#include "pch.h"
#include "nvs.h"
@@ -405,6 +406,53 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat
}
}
+#if CONFIG_ELOG_GSMI
+static void southbridge_smi_gsmi(void)
+{
+ em64t101_smm_state_save_area_t *io_smi;
+ u32 base = smi_get_tseg_base() + 0x8000;
+ u32 *ret, *param;
+ u8 sub_command, node;
+
+ /*
+ * Check for Synchronous IO SMI and use save state from that
+ * core in case we are not running on the same core that
+ * initiated the IO transaction.
+ */
+ for (node = 0; node < CONFIG_MAX_CPUS; node++) {
+ /*
+ * Look for IO Misc Info:
+ * Synchronous bit[0]=1
+ * Byte bit[3:1]=1
+ * Output bit[7:4]=0
+ * APMC port bit[31:16]=0xb2
+ * RAX[7:0] == 0xEF
+ */
+ u32 io_want_info = (APM_CNT << 16) | 0x3;
+ io_smi = (em64t101_smm_state_save_area_t *)
+ (base + 0x7d00 - (node * 0x400));
+
+ if (io_smi->io_misc_info == io_want_info &&
+ ((u8)io_smi->rax == ELOG_GSMI_APM_CNT))
+ break;
+ }
+
+ /* Did not find matching CPU Save State */
+ if (node == CONFIG_MAX_CPUS)
+ return;
+
+ /* Command and return value in EAX */
+ ret = (u32*)&io_smi->rax;
+ sub_command = (u8)(*ret >> 8);
+
+ /* Parameter buffer in EBX */
+ param = (u32*)&io_smi->rbx;
+
+ /* drivers/elog/gsmi.c */
+ *ret = gsmi_exec(sub_command, param);
+}
+#endif
+
static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
{
u32 pmctrl;
@@ -452,6 +500,11 @@ static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state
smm_initialized = 1;
printk(BIOS_DEBUG, "SMI#: Setting up structures to %p, %p, %p\n", gnvs, tcg, smi1);
break;
+#if CONFIG_ELOG_GSMI
+ case ELOG_GSMI_APM_CNT:
+ southbridge_smi_gsmi();
+ break;
+#endif
}
tseg_relocate((void **)&mainboard_apmc);
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1316
-gerrit
commit e5b0852cb546d30252dbec1f323f2ce3292a6c89
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 16:48:38 2012 -0700
ELOG: Add support for SMM and kernel GSMI driver
The linux kernel contains an SMI driver that was written by
me (Duncan) and upstreamed a couple years ago called GSMI.
This driver will format a parameter buffer and pass pointers
to this parameter buffer to the SMI handler. It uses this to
generate events for kernel shutdown reasons: Clean, Panic, Oops,
etc.
This function expects to be passed pointers into the SMM state
save area that correspond to the prameter buffer and the return
code, which are typically EAX and EBX.
The format of the parameter buffer is defined in the kernel
driver so we implement the same interface here in order to be
compatible.
GSMI_CMD_HANDSHAKE: this is an early call that it does to try
and detect what kind of BIOS is running.
GSMI_CMD_SET_EVENT_LOG: this contains a parameter buffer that
has event type and data. The kernel-specific events are
translated here and raw events are passed through as well which
allows any run-time event to be added for testing.
GSMI_CMD_CLEAR_EVENT_LOG: this command clears the event log.
First the gsmi driver must be enabled in the kernel with
CONFIG_GOOGLE_GSMI and then events can be added via sysfs
and events are automatically generated for various kernel
shutdown reasons.
These can be seen in the event log as the 'Kernel Event' type:
169 | 2012-06-23 15:03:04 | Kernl Event | Clean Shutdown
181 | 2012-06-23 16:26:32 | Kernl Event | Oops
181 | 2012-06-23 16:26:32 | Kernl Event | Panic
Change-Id: Ic0a3916401f0d9811e4aa8b2c560657dccc920c1
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/drivers/elog/Kconfig | 9 +++
src/drivers/elog/Makefile.inc | 2 +
src/drivers/elog/gsmi.c | 117 +++++++++++++++++++++++++++++++++++++++++
src/include/elog.h | 4 ++
4 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/src/drivers/elog/Kconfig b/src/drivers/elog/Kconfig
index 867416c..7912ab8 100644
--- a/src/drivers/elog/Kconfig
+++ b/src/drivers/elog/Kconfig
@@ -68,6 +68,15 @@ config ELOG_SHRINK_SIZE
endif
+config ELOG_GSMI
+ depends on ELOG && SPI_FLASH_SMM && SMM_TSEG
+ bool "SMI interface to write and clear event log"
+ default n
+ help
+ This interface is compatible with the linux kernel driver
+ available with CONFIG_GOOGLE_GSMI and can be used to write
+ kernel reset/shutdown messages to the event log.
+
config ELOG_BOOT_COUNT
depends on ELOG
bool "Maintain a monotonic boot number in CMOS"
diff --git a/src/drivers/elog/Makefile.inc b/src/drivers/elog/Makefile.inc
index 32509c8..79a7cc0 100644
--- a/src/drivers/elog/Makefile.inc
+++ b/src/drivers/elog/Makefile.inc
@@ -1,4 +1,6 @@
ramstage-$(CONFIG_ELOG) += elog.c
+smm-$(CONFIG_ELOG_GSMI) += elog.c gsmi.c
+
romstage-$(CONFIG_ELOG_BOOT_COUNT) += boot_count.c
ramstage-$(CONFIG_ELOG_BOOT_COUNT) += boot_count.c
diff --git a/src/drivers/elog/gsmi.c b/src/drivers/elog/gsmi.c
new file mode 100644
index 0000000..dac1af4
--- /dev/null
+++ b/src/drivers/elog/gsmi.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <elog.h>
+
+#define GSMI_RET_SUCCESS 0x00
+#define GSMI_RET_INVALID_PARAMETER 0x82
+#define GSMI_RET_UNSUPPORTED 0x83
+
+#define GSMI_CMD_SET_EVENT_LOG 0x08
+#define GSMI_CMD_CLEAR_EVENT_LOG 0x09
+#define GSMI_CMD_HANDSHAKE_TYPE 0xc1
+
+#define GSMI_HANDSHAKE_NONE 0x7f
+#define GSMI_LOG_ENTRY_TYPE_KERNEL 0xDEAD
+
+struct gsmi_set_eventlog_param {
+ u32 data_ptr;
+ u32 data_len;
+ u32 type;
+} __attribute__ ((packed));
+
+struct gsmi_set_eventlog_type1 {
+ u16 type;
+ u32 instance;
+} __attribute__ ((packed));
+
+struct gsmi_clear_eventlog_param {
+ u32 percentage;
+ u32 data_type;
+} __attribute__ ((packed));
+
+/* Param is usually EBX, ret in EAX */
+u32 gsmi_exec(u8 command, u32 *param)
+{
+ struct gsmi_set_eventlog_param *sel;
+ struct gsmi_set_eventlog_type1 *type1;
+ struct gsmi_clear_eventlog_param *cel;
+ u32 ret = GSMI_RET_UNSUPPORTED;
+
+ switch (command) {
+ case GSMI_CMD_HANDSHAKE_TYPE:
+ /* Used by kernel to verify basic SMI functionality */
+ printk(BIOS_DEBUG, "GSMI Handshake\n");
+ ret = GSMI_HANDSHAKE_NONE;
+ break;
+
+ case GSMI_CMD_SET_EVENT_LOG:
+ /* Look for a type1 event */
+ sel = (struct gsmi_set_eventlog_param *)(*param);
+ if (!sel)
+ break;
+
+ /* Make sure the input is usable */
+ if (sel->type != 1 && sel->data_ptr != 0 &&
+ sel->data_len != sizeof(struct gsmi_set_eventlog_type1))
+ break;
+
+ /* Event structure within the data buffer */
+ type1 = (struct gsmi_set_eventlog_type1 *)(sel->data_ptr);
+ if (!type1)
+ break;
+
+ printk(BIOS_DEBUG, "GSMI Set Event Log "
+ "(type=0x%x instance=0x%x)\n",
+ type1->type, type1->instance);
+
+ if (type1->type == GSMI_LOG_ENTRY_TYPE_KERNEL) {
+ /* Special case for linux kernel shutdown reason */
+ elog_add_event_dword(ELOG_TYPE_OS_EVENT,
+ type1->instance);
+ } else {
+ /* Add other events that may be used for testing */
+ elog_add_event_dword(type1->type, type1->instance);
+ }
+ ret = GSMI_RET_SUCCESS;
+ break;
+
+ case GSMI_CMD_CLEAR_EVENT_LOG:
+ /* Get paramter buffer even though we don't use it */
+ cel = (struct gsmi_clear_eventlog_param *)(*param);
+ if (!cel)
+ break;
+
+ printk(BIOS_DEBUG, "GSMI Clear Event Log (%u%% type=%u)\n",
+ cel->percentage, cel->data_type);
+
+ if (elog_clear() == 0)
+ ret = GSMI_RET_SUCCESS;
+ break;
+
+ default:
+ printk(BIOS_DEBUG, "GSMI Unknown: 0x%02x\n", command);
+ break;
+ }
+
+ return ret;
+}
diff --git a/src/include/elog.h b/src/include/elog.h
index 0542f68..7d89f45 100644
--- a/src/include/elog.h
+++ b/src/include/elog.h
@@ -115,6 +115,10 @@ extern void elog_add_event_dword(u8 event_type, u32 data);
extern void elog_add_event_wake(u8 source, u32 instance);
extern int elog_smbios_write_type15(unsigned long *current, int handle);
+#if CONFIG_ELOG_GSMI
+extern u32 gsmi_exec(u8 command, u32 *param);
+#endif
+
#if CONFIG_ELOG_BOOT_COUNT
u32 boot_count_read(void);
u32 boot_count_increment(void);
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1315
-gerrit
commit 4f4dda816d74613c463838fde8a4abb1da19c4e8
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 16:37:45 2012 -0700
ELOG: Add support for a monotonic boot counter in CMOS
This maintains a 32bit monotonically increasing boot counter
that is stored in CMOS and logged on every non-S3 boot when
the event log is initialized.
In CMOS the count is prefixed with a 16bit signature and
appended with a 16bit checksum.
This counter is incremented in sandybridge early_init which is
called by romstage. It is incremented early in order notice
when reboots happen after memory init.
The counter is then logged when ELOG is initialized and will
store the boot count as part of a 'System boot; event.
Reboot a few times and look for 'System boot' events in the
event log and check that they are increasing. Also verify
that the counter does NOT increase when resuming from S3.
171 | 2012-06-23 16:02:55 | System boot | 285
176 | 2012-06-23 16:26:00 | System boot | 286
182 | 2012-06-23 16:27:04 | System boot | 287
189 | 2012-06-23 16:31:10 | System boot | 288
Change-Id: I23faeafcf155edfd10aa6882598b3883575f8a33
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/drivers/elog/Kconfig | 17 ++++
src/drivers/elog/Makefile.inc | 3 +
src/drivers/elog/boot_count.c | 122 ++++++++++++++++++++++++
src/drivers/elog/elog.c | 6 +
src/include/elog.h | 5 +
src/northbridge/intel/sandybridge/early_init.c | 8 ++
6 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/src/drivers/elog/Kconfig b/src/drivers/elog/Kconfig
index d61dd10..867416c 100644
--- a/src/drivers/elog/Kconfig
+++ b/src/drivers/elog/Kconfig
@@ -67,3 +67,20 @@ config ELOG_SHRINK_SIZE
Default is 1K.
endif
+
+config ELOG_BOOT_COUNT
+ depends on ELOG
+ bool "Maintain a monotonic boot number in CMOS"
+ default n
+ help
+ Store a monotonic boot number in CMOS and provide an interface
+ to read the current value and increment the counter. This boot
+ counter will be logged as part of the System Boot event.
+
+config ELOG_BOOT_COUNT_CMOS_OFFSET
+ depends on ELOG && ELOG_BOOT_COUNT && !USE_OPTION_TABLE
+ int "Offset in CMOS to store the boot count"
+ default 0
+ help
+ This value must be greater than 16 bytes so as not to interfere
+ with the standard RTC region. Requires 8 bytes.
diff --git a/src/drivers/elog/Makefile.inc b/src/drivers/elog/Makefile.inc
index a01841d..32509c8 100644
--- a/src/drivers/elog/Makefile.inc
+++ b/src/drivers/elog/Makefile.inc
@@ -1 +1,4 @@
ramstage-$(CONFIG_ELOG) += elog.c
+
+romstage-$(CONFIG_ELOG_BOOT_COUNT) += boot_count.c
+ramstage-$(CONFIG_ELOG_BOOT_COUNT) += boot_count.c
diff --git a/src/drivers/elog/boot_count.c b/src/drivers/elog/boot_count.c
new file mode 100644
index 0000000..9ea828d
--- /dev/null
+++ b/src/drivers/elog/boot_count.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <ip_checksum.h>
+#include <pc80/mc146818rtc.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <elog.h>
+
+/*
+ * We need a region in CMOS to store the boot counter.
+ *
+ * This can either be declared as part of the option
+ * table or statically defined in the board config.
+ */
+#if CONFIG_USE_OPTION_TABLE
+# include "option_table.h"
+# define BOOT_COUNT_CMOS_OFFSET (CMOS_VSTART_boot_count_offset >> 3)
+#else
+# if defined(CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET)
+# define BOOT_COUNT_CMOS_OFFSET CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET
+# else
+# error "Must define CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET"
+# endif
+#endif
+
+#define BOOT_COUNT_SIGNATURE 0x4342 /* 'BC' */
+
+struct boot_count {
+ u16 signature;
+ u32 count;
+ u16 checksum;
+} __attribute__ ((packed));
+
+/* Read and validate boot count structure from CMOS */
+static int boot_count_cmos_read(struct boot_count *bc)
+{
+ u8 i, *p;
+ u16 csum;
+
+ for (p = (u8*)bc, i = 0; i < sizeof(*bc); i++, p++)
+ *p = cmos_read(BOOT_COUNT_CMOS_OFFSET + i);
+
+ /* Verify signature */
+ if (bc->signature != BOOT_COUNT_SIGNATURE) {
+ printk(BIOS_DEBUG, "Boot Count invalid signature\n");
+ return -1;
+ }
+
+ /* Verify checksum over signature and counter only */
+ csum = compute_ip_checksum(bc, offsetof(struct boot_count, checksum));
+
+ if (csum != bc->checksum) {
+ printk(BIOS_DEBUG, "Boot Count checksum mismatch\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Write boot count structure to CMOS */
+static void boot_count_cmos_write(struct boot_count *bc)
+{
+ u8 i, *p;
+
+ /* Checksum over signature and counter only */
+ bc->checksum = compute_ip_checksum(
+ bc, offsetof(struct boot_count, checksum));
+
+ for (p = (u8*)bc, i = 0; i < sizeof(*bc); i++, p++)
+ cmos_write(*p, BOOT_COUNT_CMOS_OFFSET + i);
+}
+
+/* Increment boot count and return the new value */
+u32 boot_count_increment(void)
+{
+ struct boot_count bc;
+
+ /* Read and increment boot count */
+ if (boot_count_cmos_read(&bc) < 0) {
+ /* Structure invalid, re-initialize */
+ bc.signature = BOOT_COUNT_SIGNATURE;
+ bc.count = 0;
+ }
+
+ /* Increment boot counter */
+ bc.count++;
+
+ /* Write the new count to CMOS */
+ boot_count_cmos_write(&bc);
+
+ printk(BIOS_DEBUG, "Boot Count incremented to %u\n", bc.count);
+ return bc.count;
+}
+
+/* Return the current boot count */
+u32 boot_count_read(void)
+{
+ struct boot_count bc;
+
+ if (boot_count_cmos_read(&bc) < 0)
+ return 0;
+
+ return bc.count;
+}
diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c
index 9c0fa93..1219883 100644
--- a/src/drivers/elog/elog.c
+++ b/src/drivers/elog/elog.c
@@ -780,6 +780,12 @@ int elog_init(void)
elog_add_event_word(ELOG_TYPE_LOG_CLEAR,
elog_get_flash()->total_size);
+#if CONFIG_ELOG_BOOT_COUNT && !defined(__SMM__)
+ /* Log boot count event except in S3 resume */
+ if (acpi_slp_type != 3)
+ elog_add_event_dword(ELOG_TYPE_BOOT, boot_count_read());
+#endif
+
return 0;
}
diff --git a/src/include/elog.h b/src/include/elog.h
index 897a90b..0542f68 100644
--- a/src/include/elog.h
+++ b/src/include/elog.h
@@ -115,6 +115,11 @@ extern void elog_add_event_dword(u8 event_type, u32 data);
extern void elog_add_event_wake(u8 source, u32 instance);
extern int elog_smbios_write_type15(unsigned long *current, int handle);
+#if CONFIG_ELOG_BOOT_COUNT
+u32 boot_count_read(void);
+u32 boot_count_increment(void);
+#endif
+
#endif /* !CONFIG_ELOG */
#endif /* ELOG_H_ */
diff --git a/src/northbridge/intel/sandybridge/early_init.c b/src/northbridge/intel/sandybridge/early_init.c
index c7afa11..6bd774b 100644
--- a/src/northbridge/intel/sandybridge/early_init.c
+++ b/src/northbridge/intel/sandybridge/early_init.c
@@ -24,6 +24,7 @@
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <device/pci_def.h>
+#include <elog.h>
#include "sandybridge.h"
#include "pcie_config.c"
@@ -63,6 +64,13 @@ static void sandybridge_setup_bars(void)
pci_write_config8(PCI_DEV(0, 0x00, 0), PAM5, 0x33);
pci_write_config8(PCI_DEV(0, 0x00, 0), PAM6, 0x33);
+#if CONFIG_ELOG_BOOT_COUNT
+ /* Increment Boot Counter for non-S3 resume */
+ if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) &&
+ ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) != SLP_TYP_S3)
+ boot_count_increment();
+#endif
+
printk(BIOS_DEBUG, " done.\n");
}
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1312
-gerrit
commit c3c95f4dd8516b21a68193072f21418517a8a06f
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 13:33:32 2012 -0700
SMM: Add support for malloc in SMM if using TSEG
This is used by the SPI driver and ELOG.
It requires SMM TSEG and a _heap/_eheap region defined in the
linker script. The first time malloc is called in SMM the
start and end pointers to the heap region will be relocated
for the TSEG region.
Enable SPI flash and ELOG in SMM and successfully
allocate memory. The allocated addresses are verified
to be sure they are within the TSEG heap region:
smm.elf:00014000 B _eheap
smm.elf:00010000 B _heap
TSEG base is 0xad000000
Memory allocated in ELOG:
ELOG: MEM @0xad018030
Change-Id: I5cca38e4888d597cbbfcd9983cd6a7ae3600c2a3
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/console/Makefile.inc | 1 +
src/lib/Makefile.inc | 1 +
src/lib/malloc.c | 9 +++++++++
3 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/src/console/Makefile.inc b/src/console/Makefile.inc
index f3b8758..f8928ad 100644
--- a/src/console/Makefile.inc
+++ b/src/console/Makefile.inc
@@ -7,6 +7,7 @@ ramstage-y += die.c
smm-y += printk.c
smm-y += vtxprintf.c
+smm-$(CONFIG_SMM_TSEG) += die.c
romstage-y += vtxprintf.c
romstage-$(CONFIG_CACHE_AS_RAM) += console.c
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index a3235a2..ec57bc2 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -32,6 +32,7 @@ endif
ramstage-y += memcmp.c
ramstage-y += memmove.c
ramstage-y += malloc.c
+smm-$(CONFIG_SMM_TSEG) += malloc.c
ramstage-y += delay.c
ramstage-y += fallback_boot.c
ramstage-y += compute_ip_checksum.c
diff --git a/src/lib/malloc.c b/src/lib/malloc.c
index d2011a1..43e514a 100644
--- a/src/lib/malloc.c
+++ b/src/lib/malloc.c
@@ -1,5 +1,8 @@
#include <stdlib.h>
#include <console/console.h>
+#ifdef __SMM__
+#include <cpu/x86/smm.h>
+#endif
#if CONFIG_DEBUG_MALLOC
#define MALLOCDBG(x...) printk(BIOS_SPEW, x)
@@ -43,5 +46,11 @@ void *memalign(size_t boundary, size_t size)
void *malloc(size_t size)
{
+#if CONFIG_SMM_TSEG && defined(__SMM__)
+ if (!free_mem_ptr) {
+ free_mem_ptr = &_heap + smi_get_tseg_base();
+ free_mem_end_ptr = &_eheap + smi_get_tseg_base();
+ }
+#endif
return memalign(sizeof(u64), size);
}
the following patch was just integrated into master:
commit 6a757558cd940fa2ed98b7ede00296f6dff6a6c8
Author: Walter Murphy <wmurphy(a)google.com>
Date: Mon Apr 23 11:08:03 2012 -0700
SandyBridge: Add another PCI device ID for northbridge
Change-Id: I153579561f7eed6d4befd74ff39e1a5e778d0e46
Signed-off-by: Walter Murphy <wmurphy(a)google.com>
Build-Tested: build bot (Jenkins) at Tue Jul 24 00:02:42 2012, giving +1
Reviewed-By: Ronald G. Minnich <rminnich(a)gmail.com> at Tue Jul 24 00:01:58 2012, giving +2
See http://review.coreboot.org/1269 for details.
-gerrit