Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1308
-gerrit
commit 83a49f79e7339b011063e346b9f96765b2805160
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 15:09:34 2012 -0700
SMM: Add heap region and move C handler higher in region
In order to support SPI and ELOG drivers the SMM region
needs to be able to be larger than the previous allocation
below 0x7400. Now that we have support for 4M TSEG we do
not need to live in this region.
This change adds a 16KB heap region abofe the save state area
at TSEG+64KB and moves the C handler above this.
The heap region is then available for malloc and the C handler
can grow to support flash and event log features.
While updating the memory map comment in assembly stub I also
added a pause instruction to the cpu spin lock as this was
added to the C code in latest upstream rebase.
Dump sympbols from smm.elf binary to see the new regions:
00010000 B _heap
00014000 B _eheap
00014000 T _smm_c_handler_start
0001b240 T _smm_c_handler_end
Change-Id: I45f0ab4df1fdef3b626f877094a58587476ac634
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/cpu/x86/smm/smm_tseg.ld | 45 +++++++++++++++++++++++-------------
src/cpu/x86/smm/smmhandler_tseg.S | 9 +++++-
2 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/src/cpu/x86/smm/smm_tseg.ld b/src/cpu/x86/smm/smm_tseg.ld
index 016b5a0..6def972 100644
--- a/src/cpu/x86/smm/smm_tseg.ld
+++ b/src/cpu/x86/smm/smm_tseg.ld
@@ -10,6 +10,34 @@ SECTIONS
.handler (.): {
/* Assembler stub */
*(.handler)
+ }
+
+ /* We are using the TSEG interleaved to stuff the SMM handlers
+ * for all CPU cores in there. The jump table redirects the execution
+ * to the actual SMM handler
+ */
+ . = 0x8000 - (( CPUS - 1) * 0x400);
+ .jumptable : {
+ *(.jumptable)
+ }
+
+ /* Data used in early SMM TSEG handler. */
+ . = 0x8400;
+ .earlydata : {
+ *(.earlydata)
+ }
+
+ /* 16KB for the heap at 64KB */
+ . = 0x10000;
+ .heap : {
+ _heap = .;
+ . = 0x4000;
+ _eheap = .;
+ }
+
+ . = ALIGN(0x4000);
+ .smm_c_handler : {
+ _smm_c_handler_start = .;
/* C code of the SMM handler */
*(.text);
@@ -29,25 +57,10 @@ SECTIONS
. = ALIGN(4);
*(.bss)
*(.sbss)
-
- /* What is this? */
*(COMMON)
. = ALIGN(4);
- }
- /* We are using the TSEG interleaved to stuff the SMM handlers
- * for all CPU cores in there. The jump table redirects the execution
- * to the actual SMM handler
- */
- . = 0x8000 - (( CPUS - 1) * 0x400);
- .jumptable : {
- *(.jumptable)
- }
-
- /* Data used in early SMM TSEG handler. */
- . = 0x8400;
- .earlydata : {
- *(.earlydata)
+ _smm_c_handler_end = .;
}
/DISCARD/ : {
diff --git a/src/cpu/x86/smm/smmhandler_tseg.S b/src/cpu/x86/smm/smmhandler_tseg.S
index 8fdd75f..c61a611 100644
--- a/src/cpu/x86/smm/smmhandler_tseg.S
+++ b/src/cpu/x86/smm/smmhandler_tseg.S
@@ -20,7 +20,11 @@
*/
/*
- * +--------------------------------+ 0xffff
+ * +--------------------------------+
+ * | SMM Handler C Code |
+ * +--------------------------------+ 0x14000
+ * | SMM Handler Heap |
+ * +--------------------------------+ 0x10000
* | Save State Map Node 0 |
* | Save State Map Node 1 |
* | Save State Map Node 2 |
@@ -39,7 +43,7 @@
* | ... |
* +--------------------------------+ 0x7400
* | |
- * | SMM Handler |
+ * | SMM Handler Assembly Stub |
* | |
* +--------------------------------+ TSEG
*
@@ -91,6 +95,7 @@ smm_handler_start:
/* If we did not get the lock, wait for release */
wait_for_unlock:
+ pause
addr32 movw (%ebx), %ax
cmpw $SMI_LOCKED, %ax
je wait_for_unlock
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1306
-gerrit
commit e6f8608ce93f8b923a65ff2378174c3587b1236e
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 15:43:41 2012 -0700
RTC: Enable extended CMOS in the bootblock
This makes it available early in romstage without having to
worry when the different romstagse enable it.
Check for extended CMOS to be enabled in early romstage.
This is used by a later commit which uses the extended
CMOS region for stoage.
Change-Id: I9e026d48499c63d6503c2b020d4cc3047126fa93
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/southbridge/intel/bd82x6x/bootblock.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/southbridge/intel/bd82x6x/bootblock.c b/src/southbridge/intel/bd82x6x/bootblock.c
index d6cba5f..0191bbf 100644
--- a/src/southbridge/intel/bd82x6x/bootblock.c
+++ b/src/southbridge/intel/bd82x6x/bootblock.c
@@ -72,4 +72,7 @@ static void bootblock_southbridge_init(void)
#endif
enable_spi_prefetch();
enable_port80_on_lpc();
+
+ /* Enable upper 128bytes of CMOS */
+ RCBA32(RC) = (1 << 2);
}
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1304
-gerrit
commit 364dbdd0177ff1fb5bbf398217fcae01ef296d1e
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Mon Jun 25 09:51:59 2012 -0700
CPU: Add basic support for Nominal Configurable TDP
Ivybridge B0+ CPUs are capable of supporting multiple TDP levels.
This complicates the default case because now the registers that
were reporting max non-turbo ratio are reporting that value for
the highest possible TDP level.
For now this change just forces everything to use the Nominal TDP
values instead of the higher (or lower) levels.
- When building P-state tables, determine the P[1] (max non turbo)
ratio based on the Nominal ratio if available.
- Set the turbo activation ratio to the Nominal max ratio.
- Mirror the power level settings in new MCHBAR register after
they are written, which happens after BIOS_RESET_CPL is set.
- Set the current ratio to Nominal ratio at boot.
1) Verify that P-state table is generated properly with
P[0]=1801MHz (ratio 0x1C) and P[1]=1800MHz (ratio 0x12)
PSS: 1801MHz power 17000 control 0x1c00 status 0x1c00
PSS: 1800MHz power 17000 control 0x1200 status 0x1200
2) Verify power limits in MCHBAR match PKG_POWER_LIMIT:
> rdmsr 0 0x610
0x800080aa00dc8088
> mmio_read32 0xfed159a4
0x000080aa
> mmio_read32 0xfed159a0
0x00dc8088
3) Verify turbo activation ratio is set to nominal ratio:
> rdmsr 0 0x64c
0x0000000000000012
4) Check that proper ratio was set at boot on one core only:
> grep 'frequency set to' /sys/firmware/log
model_x06ax: frequency set to 1800
model_x06ax: frequency set to 1800
model_x06ax: frequency set to 1800
model_x06ax: frequency set to 1800
Change-Id: I592e60a7740f31b140986a8269dca91b4adbb270
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/cpu/intel/model_206ax/acpi.c | 11 +++++-
src/cpu/intel/model_206ax/model_206ax.h | 8 ++++
src/cpu/intel/model_206ax/model_206ax_init.c | 45 +++++++++++++++++++----
src/northbridge/intel/sandybridge/northbridge.c | 11 ++++++
4 files changed, 66 insertions(+), 9 deletions(-)
diff --git a/src/cpu/intel/model_206ax/acpi.c b/src/cpu/intel/model_206ax/acpi.c
index 5d3f3a0..7b49555 100644
--- a/src/cpu/intel/model_206ax/acpi.c
+++ b/src/cpu/intel/model_206ax/acpi.c
@@ -229,7 +229,16 @@ static int generate_P_state_entries(int core, int cores_per_package)
/* Get bus ratio limits and calculate clock speeds */
msr = rdmsr(MSR_PLATFORM_INFO);
ratio_min = (msr.hi >> (40-32)) & 0xff; /* Max Efficiency Ratio */
- ratio_max = (msr.lo >> 8) & 0xff; /* Max Non-Turbo Ratio */
+
+ /* Determine if this CPU has configurable TDP */
+ if (cpu_config_tdp_levels()) {
+ /* Set max ratio to nominal TDP ratio */
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ ratio_max = msr.lo & 0xff;
+ } else {
+ /* Max Non-Turbo Ratio */
+ ratio_max = (msr.lo >> 8) & 0xff;
+ }
clock_max = ratio_max * SANDYBRIDGE_BCLK;
/* Calculate CPU TDP in mW */
diff --git a/src/cpu/intel/model_206ax/model_206ax.h b/src/cpu/intel/model_206ax/model_206ax.h
index 3343d11..d482ff0 100644
--- a/src/cpu/intel/model_206ax/model_206ax.h
+++ b/src/cpu/intel/model_206ax/model_206ax.h
@@ -81,6 +81,13 @@
#define MSR_PP0_POWER_LIMIT 0x638
#define MSR_PP1_POWER_LIMIT 0x640
+#define IVB_CONFIG_TDP_MIN_CPUID 0x306a2
+#define MSR_CONFIG_TDP_NOMINAL 0x648
+#define MSR_CONFIG_TDP_LEVEL1 0x649
+#define MSR_CONFIG_TDP_LEVEL2 0x64a
+#define MSR_CONFIG_TDP_CONTROL 0x64b
+#define MSR_TURBO_ACTIVATION_RATIO 0x64c
+
/* P-state configuration */
#define PSS_MAX_ENTRIES 8
#define PSS_RATIO_STEP 2
@@ -93,6 +100,7 @@ void intel_model_206ax_finalize_smm(void);
#else
/* Configure power limits for turbo mode */
void set_power_limits(u8 power_limit_1_time);
+int cpu_config_tdp_levels(void);
#endif
#endif
diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c
index 87bc585..0958fe3 100644
--- a/src/cpu/intel/model_206ax/model_206ax_init.c
+++ b/src/cpu/intel/model_206ax/model_206ax_init.c
@@ -179,6 +179,19 @@ static const u8 power_limit_time_msr_to_sec[] = {
[0x11] = 128,
};
+int cpu_config_tdp_levels(void)
+{
+ msr_t platform_info;
+
+ /* Minimum CPU revision */
+ if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
+ return 0;
+
+ /* Bits 34:33 indicate how many levels supported */
+ platform_info = rdmsr(MSR_PLATFORM_INFO);
+ return (platform_info.hi >> 1) & 3;
+}
+
/*
* Configure processor power limits if possible
* This must be done AFTER set of BIOS_RESET_CPL
@@ -235,6 +248,14 @@ void set_power_limits(u8 power_limit_1_time)
/* Power limit 2 time is only programmable on SNB EP/EX */
wrmsr(MSR_PKG_POWER_LIMIT, limit);
+
+ /* Use nominal TDP values for CPUs with configurable TDP */
+ if (cpu_config_tdp_levels()) {
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ limit.hi = 0;
+ limit.lo = msr.lo & 0xff;
+ wrmsr(MSR_TURBO_ACTIVATION_RATIO, limit);
+ }
}
static void configure_c_states(void)
@@ -340,16 +361,24 @@ static void configure_dca_cap(void)
static void set_max_ratio(void)
{
- msr_t msr;
-
- /* Platform Info bits 15:8 give max ratio */
- msr = rdmsr(MSR_PLATFORM_INFO);
- msr.hi = 0;
- msr.lo &= 0xff00;
- wrmsr(IA32_PERF_CTL, msr);
+ msr_t msr, perf_ctl;
+
+ perf_ctl.hi = 0;
+
+ /* Check for configurable TDP option */
+ if (cpu_config_tdp_levels()) {
+ /* Set to nominal TDP ratio */
+ msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+ perf_ctl.lo = (msr.lo & 0xff) << 8;
+ } else {
+ /* Platform Info bits 15:8 give max ratio */
+ msr = rdmsr(MSR_PLATFORM_INFO);
+ perf_ctl.lo = msr.lo & 0xff00;
+ }
+ wrmsr(IA32_PERF_CTL, perf_ctl);
printk(BIOS_DEBUG, "model_x06ax: frequency set to %d\n",
- ((msr.lo >> 8) & 0xff) * 100);
+ ((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
}
static void set_energy_perf_bias(u8 policy)
diff --git a/src/northbridge/intel/sandybridge/northbridge.c b/src/northbridge/intel/sandybridge/northbridge.c
index 2fa3504..bfb2166 100644
--- a/src/northbridge/intel/sandybridge/northbridge.c
+++ b/src/northbridge/intel/sandybridge/northbridge.c
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <delay.h>
#include <cpu/intel/model_206ax/model_206ax.h>
+#include <cpu/x86/msr.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
@@ -422,6 +423,16 @@ static void northbridge_init(struct device *dev)
mdelay(1);
set_power_limits(28);
+ /*
+ * CPUs with configurable TDP also need power limits set
+ * in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT.
+ */
+ if (cpu_config_tdp_levels()) {
+ msr_t msr = rdmsr(MSR_PKG_POWER_LIMIT);
+ MCHBAR32(0x59A0) = msr.lo;
+ MCHBAR32(0x59A4) = msr.hi;
+ }
+
/* Set here before graphics PM init */
MCHBAR32(0x5500) = 0x00100001;
}
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1302
-gerrit
commit 0bcdec8a18ce4061710fa212adabc4fdc63b2f4b
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Sat Jun 23 13:22:25 2012 -0700
RTC: Add defines for standard clock offsets
ELOG reads from RTC to build timestamp structure,
the resulting timestamp is decoded when printing events.
Change-Id: If26552074f18de5095b967b875a0ac1d815a5b31
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/include/pc80/mc146818rtc.h | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/src/include/pc80/mc146818rtc.h b/src/include/pc80/mc146818rtc.h
index a1f06e7..9f18ba4 100644
--- a/src/include/pc80/mc146818rtc.h
+++ b/src/include/pc80/mc146818rtc.h
@@ -76,6 +76,18 @@
# define RTC_VRT 0x80 /* valid RAM and time */
/**********************************************************************/
+/* Date and Time in RTC CMOS */
+#define RTC_CLK_SECOND 0
+#define RTC_CLK_SECOND_ALARM 1
+#define RTC_CLK_MINUTE 2
+#define RTC_CLK_MINUTE_ALARM 3
+#define RTC_CLK_HOUR 4
+#define RTC_CLK_HOUR_ALARM 5
+#define RTC_CLK_DAYOFWEEK 6
+#define RTC_CLK_DAYOFMONTH 7
+#define RTC_CLK_MONTH 8
+#define RTC_CLK_YEAR 9
+
/* On PCs, the checksum is built only over bytes 16..45 */
#define PC_CKS_RANGE_START 16
#define PC_CKS_RANGE_END 45