the following patch was just integrated into master:
commit a6e9051bc6843bb8f42df9c29cd254914ece93b4
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Apr 21 14:06:17 2016 -0500
lib/coreboot_table: use the architecture dependent table size
Utilize the architecture dependent coreboot table size value
from <arch/cbconfig.h>
Change-Id: I80d51a5caf7c455b0b47c380e1d79cf522502a4c
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Reviewed-on: https://review.coreboot.org/14455
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Tested-by: build bot (Jenkins)
See https://review.coreboot.org/14455 for details.
-gerrit
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14455
-gerrit
commit 44aaca6a852347be954ca6dfb1ed1211647e95ff
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Apr 21 14:06:17 2016 -0500
lib/coreboot_table: use the architecture dependent table size
Utilize the architecture dependent coreboot table size value
from <arch/cbconfig.h>
Change-Id: I80d51a5caf7c455b0b47c380e1d79cf522502a4c
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/Kconfig | 9 ---------
src/arch/arm/include/arch/cbconfig.h | 2 ++
src/arch/arm64/include/arch/cbconfig.h | 2 ++
src/arch/mips/include/arch/cbconfig.h | 2 ++
src/arch/power8/include/arch/cbconfig.h | 2 ++
src/arch/riscv/include/arch/cbconfig.h | 2 ++
src/arch/x86/include/arch/cbconfig.h | 2 ++
src/lib/coreboot_table.c | 3 ++-
8 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index b656bbf..f9bd661 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -658,15 +658,6 @@ config ACPI_NHLT
help
Build support for NHLT (non HD Audio) ACPI table generation.
-
-config COREBOOT_TABLE_SIZE
- hex
- default 0x8000 if ARCH_X86
- default 0x2000 if !ARCH_X86
- help
- The amount of memory to reserve for the coreboot tables in
- cbmem.
-
#These Options are here to avoid "undefined" warnings.
#The actual selection and help texts are in the following menu.
diff --git a/src/arch/arm/include/arch/cbconfig.h b/src/arch/arm/include/arch/cbconfig.h
index 7bf9452..9467f52 100644
--- a/src/arch/arm/include/arch/cbconfig.h
+++ b/src/arch/arm/include/arch/cbconfig.h
@@ -23,4 +23,6 @@
* to have the same name across all architectures.
*/
+#define COREBOOT_TABLE_SIZE 0x2000
+
#endif
diff --git a/src/arch/arm64/include/arch/cbconfig.h b/src/arch/arm64/include/arch/cbconfig.h
index 7bf9452..9467f52 100644
--- a/src/arch/arm64/include/arch/cbconfig.h
+++ b/src/arch/arm64/include/arch/cbconfig.h
@@ -23,4 +23,6 @@
* to have the same name across all architectures.
*/
+#define COREBOOT_TABLE_SIZE 0x2000
+
#endif
diff --git a/src/arch/mips/include/arch/cbconfig.h b/src/arch/mips/include/arch/cbconfig.h
index 7bf9452..9467f52 100644
--- a/src/arch/mips/include/arch/cbconfig.h
+++ b/src/arch/mips/include/arch/cbconfig.h
@@ -23,4 +23,6 @@
* to have the same name across all architectures.
*/
+#define COREBOOT_TABLE_SIZE 0x2000
+
#endif
diff --git a/src/arch/power8/include/arch/cbconfig.h b/src/arch/power8/include/arch/cbconfig.h
index 7bf9452..9467f52 100644
--- a/src/arch/power8/include/arch/cbconfig.h
+++ b/src/arch/power8/include/arch/cbconfig.h
@@ -23,4 +23,6 @@
* to have the same name across all architectures.
*/
+#define COREBOOT_TABLE_SIZE 0x2000
+
#endif
diff --git a/src/arch/riscv/include/arch/cbconfig.h b/src/arch/riscv/include/arch/cbconfig.h
index 7bf9452..9467f52 100644
--- a/src/arch/riscv/include/arch/cbconfig.h
+++ b/src/arch/riscv/include/arch/cbconfig.h
@@ -23,4 +23,6 @@
* to have the same name across all architectures.
*/
+#define COREBOOT_TABLE_SIZE 0x2000
+
#endif
diff --git a/src/arch/x86/include/arch/cbconfig.h b/src/arch/x86/include/arch/cbconfig.h
index 7bf9452..78a5940 100644
--- a/src/arch/x86/include/arch/cbconfig.h
+++ b/src/arch/x86/include/arch/cbconfig.h
@@ -23,4 +23,6 @@
* to have the same name across all architectures.
*/
+#define COREBOOT_TABLE_SIZE 0x8000
+
#endif
diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
index 58c6f48..4dbac19 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/
+#include <arch/cbconfig.h>
#include <console/console.h>
#include <console/uart.h>
#include <ip_checksum.h>
@@ -560,7 +561,7 @@ void write_tables(void)
uintptr_t cbtable_start;
uintptr_t cbtable_end;
size_t cbtable_size;
- const size_t max_table_size = CONFIG_COREBOOT_TABLE_SIZE;
+ const size_t max_table_size = COREBOOT_TABLE_SIZE;
cbtable_start = (uintptr_t)cbmem_add(CBMEM_ID_CBTABLE, max_table_size);
the following patch was just integrated into master:
commit a2118a21c9e6a65bd90481f222cb436509b3e0bb
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Apr 21 14:02:40 2016 -0500
arch: introduce architecture dependent common variables
Stefan and others have discussed their interest in only
including options in Kconfig that are directly associated
with building a coreboot image. There are variables that
are architecture dependent that are utilized in the
coreboot infrastructure. To meet that goal, introduce
<arch/cbconfig.h> header file which defines variables
for the coreboot infrastructure that are architecture
dependent but utilized in common infrastructure.
Change-Id: Ic4cb9e81bab042797539dce004db0f7ee8526ea6
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Reviewed-on: https://review.coreboot.org/14454
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Tested-by: build bot (Jenkins)
See https://review.coreboot.org/14454 for details.
-gerrit
the following patch was just integrated into master:
commit 394041b149b578507df7a037c858acbb99918dc4
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Apr 24 20:56:31 2016 -0500
nb/amd/mct_ddr3: Only initialize ECC bits once
The ECC check bits of all ECC DIMMS were inadvertently initialized
twice in the same routine, significantly delaying startup. Part
of this was related to an obsolete MCA workaround that has been
fixed through multiple commits, therefore the workaround is no
longer needed.
Only initialize the ECC check bits once.
Change-Id: I90ac1147d9b006794d29b866a9cb5b7ead8f01e7
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14503
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply(a)raptorengineeringinc.com>
Reviewed-by: Martin Roth <martinroth(a)google.com>
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
See https://review.coreboot.org/14503 for details.
-gerrit
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14557
-gerrit
commit f1fae2a3d8c0f2b6586cba60f60400a396111ebb
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Apr 29 22:55:49 2016 -0500
cpu/x86: combine multiprocessor and SMM initialization
In order to reduce code duplication provide a common flow
through callback functions that performs the multiprocessor
and optionally SMM initialization. The existing MP flight
records are utilized but a common flow is provided such
that the chipset/cpu only needs to provide a mp_ops
structure which has callbacks to gather info and provide
hooks at certain points in the sequence.
All current users of the MP code can be switched over to
this flow since there haven't been any flight records that
are overly complicated and long. After the conversion
has taken place most of the surface area of the MP
API can be hidden away within the compilation unit proper.
Change-Id: I6f70969631012982126f0d0d76e5fac6880c24f0
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/x86/mp_init.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++
src/include/cpu/x86/mp.h | 86 +++++++++++++++++
2 files changed, 325 insertions(+)
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c
index 2180d98..c3da6e2 100644
--- a/src/cpu/x86/mp_init.c
+++ b/src/cpu/x86/mp_init.c
@@ -607,3 +607,242 @@ void smm_initiate_relocation(void)
smm_initiate_relocation_parallel();
spin_unlock(&smm_relocation_lock);
}
+
+struct mp_state {
+ struct mp_ops ops;
+ int cpu_count;
+ uintptr_t perm_smbase;
+ size_t perm_smsize;
+ size_t smm_save_state_size;
+ int do_smm;
+} mp_state;
+
+static int is_smm_enabled(void)
+{
+ return IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) && mp_state.do_smm;
+}
+
+static void smm_disable(void)
+{
+ mp_state.do_smm = 0;
+}
+
+static void smm_enable(void)
+{
+ if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER))
+ mp_state.do_smm = 1;
+}
+
+static void asmlinkage smm_do_relocation(void *arg)
+{
+ const struct smm_module_params *p;
+ const struct smm_runtime *runtime;
+ int cpu;
+ uintptr_t curr_smbase;
+ uintptr_t perm_smbase;
+
+ p = arg;
+ runtime = p->runtime;
+ cpu = p->cpu;
+ curr_smbase = runtime->smbase;
+
+ if (cpu >= CONFIG_MAX_CPUS) {
+ printk(BIOS_CRIT,
+ "Invalid CPU number assigned in SMM stub: %d\n", cpu);
+ return;
+ }
+
+ /*
+ * The permanent handler runs with all cpus concurrently. Precalculate
+ * the location of the new SMBASE. If using SMM modules then this
+ * calculation needs to match that of the module loader.
+ */
+ perm_smbase = mp_state.perm_smbase;
+ perm_smbase -= cpu * runtime->save_state_size;
+
+ printk(BIOS_DEBUG, "New SMBASE 0x%08lx\n", perm_smbase);
+
+ /* Setup code checks this callback for validity. */
+ mp_state.ops.relocation_handler(cpu, curr_smbase, perm_smbase);
+}
+
+static void adjust_smm_apic_id_map(struct smm_loader_params *smm_params)
+{
+ int i;
+ struct smm_runtime *runtime = smm_params->runtime;
+
+ for (i = 0; i < CONFIG_MAX_CPUS; i++)
+ runtime->apic_id_to_cpu[i] = mp_get_apic_id(i);
+}
+
+static int install_relocation_handler(int num_cpus, size_t save_state_size)
+{
+ struct smm_loader_params smm_params = {
+ .per_cpu_stack_size = save_state_size,
+ .num_concurrent_stacks = num_cpus,
+ .per_cpu_save_state_size = save_state_size,
+ .num_concurrent_save_states = 1,
+ .handler = smm_do_relocation,
+ };
+
+ /* Allow callback to override parameters. */
+ if (mp_state.ops.adjust_smm_params != NULL)
+ mp_state.ops.adjust_smm_params(&smm_params, 0);
+
+ if (smm_setup_relocation_handler(&smm_params))
+ return -1;
+
+ adjust_smm_apic_id_map(&smm_params);
+
+ return 0;
+}
+
+static int install_permanent_handler(int num_cpus, uintptr_t smbase,
+ size_t smsize, size_t save_state_size)
+{
+ /* There are num_cpus concurrent stacks and num_cpus concurrent save
+ * state areas. Lastly, set the stack size to the save state size. */
+ struct smm_loader_params smm_params = {
+ .per_cpu_stack_size = save_state_size,
+ .num_concurrent_stacks = num_cpus,
+ .per_cpu_save_state_size = save_state_size,
+ .num_concurrent_save_states = num_cpus,
+ };
+
+ /* Allow callback to override parameters. */
+ if (mp_state.ops.adjust_smm_params != NULL)
+ mp_state.ops.adjust_smm_params(&smm_params, 0);
+
+ printk(BIOS_DEBUG, "Installing SMM handler to 0x%08lx\n", smbase);
+
+ if (smm_load_module((void *)smbase, smsize, &smm_params))
+ return -1;
+
+ adjust_smm_apic_id_map(&smm_params);
+
+ return 0;
+}
+
+/* Load SMM handlers as part of MP flight record. */
+static void load_smm_handlers(void)
+{
+ size_t smm_save_state_size = mp_state.smm_save_state_size;
+
+ /* Do nothing if SMM is disabled.*/
+ if (!is_smm_enabled())
+ return;
+
+ /* Install handlers. */
+ if (install_relocation_handler(mp_state.cpu_count,
+ smm_save_state_size) < 0) {
+ printk(BIOS_ERR, "Unable to install SMM relocation handler.\n");
+ smm_disable();
+ }
+
+ if (install_permanent_handler(mp_state.cpu_count, mp_state.perm_smbase,
+ mp_state.perm_smsize, smm_save_state_size) < 0) {
+ printk(BIOS_ERR, "Unable to install SMM permanent handler.\n");
+ smm_disable();
+ }
+
+ /* Ensure the SMM handlers hit DRAM before performing first SMI. */
+ wbinvd();
+
+ /*
+ * Indicate that the SMM handlers have been loaded and MP
+ * initialization is about to start.
+ */
+ if (is_smm_enabled() && mp_state.ops.pre_mp_init != NULL)
+ mp_state.ops.pre_mp_init();
+}
+
+/* Trigger SMM as part of MP flight record. */
+static void trigger_smm_relocation(void)
+{
+ /* Do nothing if SMM is disabled.*/
+ if (!is_smm_enabled() || mp_state.ops.per_cpu_smm_trigger == NULL)
+ return;
+ /* Trigger SMM mode for the currently running processor. */
+ mp_state.ops.per_cpu_smm_trigger();
+}
+
+static struct mp_flight_record mp_steps[] = {
+ /* Once the APs are up load the SMM handlers. */
+ MP_FR_BLOCK_APS(NULL, load_smm_handlers),
+ /* Perform SMM relocation. */
+ MP_FR_NOBLOCK_APS(trigger_smm_relocation, trigger_smm_relocation),
+ /* Initialize each cpu through the driver framework. */
+ MP_FR_BLOCK_APS(mp_initialize_cpu, mp_initialize_cpu),
+ /* Wait for APs to finish everything else then let them park. */
+ MP_FR_BLOCK_APS(NULL, NULL),
+};
+
+static void fill_mp_state(struct mp_state *state, const struct mp_ops *ops)
+{
+ /*
+ * Make copy of the ops so that defaults can be set in the non-const
+ * structure if needed.
+ */
+ memcpy(&state->ops, ops, sizeof(*ops));
+
+ if (ops->get_cpu_count != NULL)
+ state->cpu_count = ops->get_cpu_count();
+
+ if (ops->get_smm_info != NULL)
+ ops->get_smm_info(&state->perm_smbase, &state->perm_smsize,
+ &state->smm_save_state_size);
+
+ /*
+ * Default to smm_initiate_relocation() if trigger callback isn't
+ * provided.
+ */
+ if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) &&
+ ops->per_cpu_smm_trigger == NULL)
+ mp_state.ops.per_cpu_smm_trigger = smm_initiate_relocation;
+}
+
+int mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops *mp_ops)
+{
+ int ret;
+ void *default_smm_area;
+ struct mp_params mp_params;
+
+ fill_mp_state(&mp_state, mp_ops);
+
+ memset(&mp_params, 0, sizeof(mp_params));
+
+ if (mp_state.cpu_count <= 0) {
+ printk(BIOS_ERR, "Invalid cpu_count: %d\n", mp_state.cpu_count);
+ return -1;
+ }
+
+ /* Sanity check SMM state. */
+ if (mp_state.perm_smsize != 0 && mp_state.smm_save_state_size != 0 &&
+ mp_state.ops.relocation_handler != NULL)
+ smm_enable();
+
+ if (is_smm_enabled())
+ printk(BIOS_INFO, "Will perform SMM setup.\n");
+
+ mp_params.num_cpus = mp_state.cpu_count;
+ /* Gather microcode information. */
+ if (mp_state.ops.get_microcode_info != NULL)
+ mp_state.ops.get_microcode_info(&mp_params.microcode_pointer,
+ &mp_params.parallel_microcode_load);
+ mp_params.adjust_apic_id = mp_state.ops.adjust_cpu_apic_entry;
+ mp_params.flight_plan = &mp_steps[0];
+ mp_params.num_records = ARRAY_SIZE(mp_steps);
+
+ /* Perform backup of default SMM area. */
+ default_smm_area = backup_default_smm_area();
+
+ ret = mp_init(cpu_bus, &mp_params);
+
+ restore_default_smm_area(default_smm_area);
+
+ /* Signal callback on success if it's provided. */
+ if (ret == 0 && mp_state.ops.post_mp_init != NULL)
+ mp_state.ops.post_mp_init();
+
+ return ret;
+}
diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h
index 3227975..24c4afe 100644
--- a/src/include/cpu/x86/mp.h
+++ b/src/include/cpu/x86/mp.h
@@ -17,6 +17,7 @@
#define _X86_MP_H_
#include <arch/smp/atomic.h>
+#include <cpu/x86/smm.h>
#define CACHELINE_SIZE 64
@@ -78,6 +79,91 @@ struct mp_params {
int num_records;
};
+struct mp_ops {
+ /*
+ * Return the number of logical x86 execution contexts that
+ * need to be brought out of SIPI state as well as have SMM
+ * handlers installed.
+ */
+ int (*get_cpu_count)(void);
+ /*
+ * Optionally fill in permanent SMM region and save state size. If
+ * this callback is not present no SMM handlers will be installed.
+ * The perm_smsize is the size available to house the permanent SMM
+ * handler.
+ */
+ void (*get_smm_info)(uintptr_t *perm_smbase, size_t *perm_smsize,
+ size_t *smm_save_state_size);
+ /*
+ * Optionally provide a function which adjusts the APIC id
+ * map to cpu number. By default the cpu number and APIC id
+ * are 1:1. To change the APIC id for a given cpu return the
+ * new APIC id. It's called for each cpu as indicated by
+ * get_cpu_count().
+ */
+ int (*adjust_cpu_apic_entry)(int cpu, int cur_apic_id);
+ /*
+ * Optionally fill in pointer to microcode and indicate if the APs
+ * can load the microcode in parallel.
+ */
+ void (*get_microcode_info)(const void **microcode, int *parallel);
+ /*
+ * Optionally adjust SMM handler parameters to override the default
+ * values. The is_perm variable indicates if the parameters to adjust
+ * are for the relocation handler or the permanent handler. This
+ * function is therefore called twice -- once for each handler.
+ * By default the parameters for each SMM handler are:
+ * stack_size num_concurrent_stacks num_concurrent_save_states
+ * relo: save_state_size get_cpu_count() 1
+ * perm: save_state_size get_cpu_count() get_cpu_count()
+ */
+ void (*adjust_smm_params)(struct smm_loader_params *slp, int is_perm);
+ /*
+ * This function is called while each cpu is in the SMM relocation
+ * handler. Its primary purpose is to adjust the SMBASE for the
+ * permanent handler. The parameters passed are the current cpu
+ * running the relocation handler, current SMBASE of relocation handler,
+ * and the pre-calculated staggered cpu SMBASE address of the permanent
+ * SMM handler.
+ */
+ void (*relocation_handler)(int cpu, uintptr_t curr_smbase,
+ uintptr_t staggered_smbase);
+ /*
+ * Optional function to use to trigger SMM to perform relocation. If
+ * not provided, smm_initiate_relocation() is used.
+ */
+ void (*per_cpu_smm_trigger)(void);
+ /*
+ * Optionally provide a callback prior to the APs starting SMM
+ * relocation or cpu driver initialization. However, note that
+ * This callback is called after SMM handlers have been loaded.
+ */
+ void (*pre_mp_init)(void);
+ /*
+ * Optionally provide a callback that is called after the APs
+ * and the BSP have gone through the initialion sequence.
+ */
+ void (*post_mp_init)(void);
+};
+
+/*
+ * mp_init_with_smm() returns < 0 on failure and 0 on success. The mp_ops
+ * argument is used to drive the multiprocess initialization. The sequence of
+ * operations is the following:
+ * 1. get_cpu_count()
+ * 2. get_smm_info()
+ * 3. adjust_cpu_apic_entry()
+ * 4. get_microcode_info()
+ * 5. adjust_smm_params(is_perm=0)
+ * 6. adjust_smm_params(is_perm=1)
+ * 7. pre_mp_init()
+ * 8. per_cpu_smm_trigger() in parallel for all cpus which calls
+ * relocation_handler() in SMM.
+ * 9. mp_initialize_cpu() for each cpu
+ * 10. post_mp_init()
+ */
+int mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops *mp_ops);
+
/*
* mp_init() will set up the SIPI vector and bring up the APs according to
* mp_params. Each flight record will be executed according to the plan. Note
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14573
-gerrit
commit ed8c748748e172ed9d429e70d24677837ec1d31d
Author: Patrick Georgi <pgeorgi(a)chromium.org>
Date: Mon May 2 17:27:01 2016 +0800
intel/baytrail: use fmap information for code caching
Instead of using CBFS_SIZE from Kconfig, use values generated from fmap.
While at it, make sure that the cached region size is a power of two.
Change-Id: I03a919e1381ca3d0e972780b2c7d76c590aaa994
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
---
src/soc/intel/baytrail/romstage/cache_as_ram.inc | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/soc/intel/baytrail/romstage/cache_as_ram.inc b/src/soc/intel/baytrail/romstage/cache_as_ram.inc
index 9ae10af..46bcc03 100644
--- a/src/soc/intel/baytrail/romstage/cache_as_ram.inc
+++ b/src/soc/intel/baytrail/romstage/cache_as_ram.inc
@@ -19,6 +19,8 @@
#include <cpu/x86/post_code.h>
#include <cbmem.h>
+#include "fmap_config.h"
+
/* The full cache-as-ram size includes the cache-as-ram portion from coreboot
* and the space used by the reference code. These 2 values combined should
* be a power of 2 because the MTRR setup assumes that. */
@@ -27,7 +29,7 @@
#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
/* Cache all of CBFS just below 4GiB as Write-Protect type. */
-#define CODE_CACHE_SIZE (CONFIG_CBFS_SIZE)
+#define CODE_CACHE_SIZE _ALIGN_UP_POW2(___FMAP__COREBOOT_SIZE)
#define CODE_CACHE_BASE (-CODE_CACHE_SIZE)
#define CODE_CACHE_MASK (~(CODE_CACHE_SIZE - 1))
#define CPU_PHYSMASK_HI ((1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1)