Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14503
-gerrit
commit d1cb051891bfe6e3bf1f2a16ba95b5739fc7005d
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>
---
src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
index abf40a1..c0ae440 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
@@ -2,7 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson(a)raptorengineeringinc.com>, Raptor Engineering
+ * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
*
* 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
@@ -137,10 +137,6 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
/* Clear MC4 error status */
pci_write_config32(pDCTstat->dev_nbmisc, 0x48, 0x0);
pci_write_config32(pDCTstat->dev_nbmisc, 0x4c, 0x0);
-
- /* Clear the RAM before enabling ECC to prevent MCE-related lockups */
- DCTMemClr_Init_D(pMCTstat, pDCTstat);
- DCTMemClr_Sync_D(pMCTstat, pDCTstat);
}
}
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14561
-gerrit
commit 47cb24a0c9b75d99e82dad530ec19e6cd28bc15b
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Sat Apr 30 15:14:18 2016 -0500
cpu/x86: remove BACKUP_DEFAULT_SMM_REGION option
Almost all boards utilizing PARALLEL_MP were already selecting this
option. There already is logic in backup_default_smm.c which guards
checks HAVE_ACPI_RESUME to determine if it should actually take
action. Though having SMM also benefits from backup_default_smm_area()
the MP library places the SIPI vector there. Therefore, a platform
which doesn't utilize SMM but does have ACPI resume should backup
this memory region as well.
Change-Id: I14cf1318136a17f48ba5ae119507918190e25387
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/intel/haswell/Kconfig | 1 -
src/cpu/x86/Kconfig | 6 ----
src/cpu/x86/Makefile.inc | 1 +
src/cpu/x86/backup_default_smm.c | 64 ++++++++++++++++++++++++++++++++++++
src/cpu/x86/smm/Makefile.inc | 1 -
src/cpu/x86/smm/backup_default_smm.c | 64 ------------------------------------
src/soc/intel/baytrail/Kconfig | 1 -
src/soc/intel/braswell/Kconfig | 1 -
src/soc/intel/broadwell/Kconfig | 1 -
src/soc/intel/skylake/Kconfig | 1 -
10 files changed, 65 insertions(+), 76 deletions(-)
diff --git a/src/cpu/intel/haswell/Kconfig b/src/cpu/intel/haswell/Kconfig
index 779f1d6..ec75391 100644
--- a/src/cpu/intel/haswell/Kconfig
+++ b/src/cpu/intel/haswell/Kconfig
@@ -10,7 +10,6 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
- select BACKUP_DEFAULT_SMM_REGION
select HAVE_MONOTONIC_TIMER
select SMP
select MMX
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 6cd65cc..e80f02b 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -127,12 +127,6 @@ config PLATFORM_USES_FSP1_0
Selected for Intel processors/platform combinations that use the
Intel Firmware Support Package (FSP) 1.0 for initialization.
-config BACKUP_DEFAULT_SMM_REGION
- def_bool n
- help
- The CPU support will select this option if the default SMM region
- needs to be backed up for suspend/resume purposes.
-
config MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING
def_bool n
help
diff --git a/src/cpu/x86/Makefile.inc b/src/cpu/x86/Makefile.inc
index 0efbdd7..142b954 100644
--- a/src/cpu/x86/Makefile.inc
+++ b/src/cpu/x86/Makefile.inc
@@ -5,6 +5,7 @@ endif
subdirs-$(CONFIG_PARALLEL_MP) += name
ramstage-$(CONFIG_PARALLEL_MP) += mp_init.c
ramstage-$(CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING) += mirror_payload.c
+ramstage-$(CONFIG_PARALLEL_MP) += backup_default_smm.c
additional-dirs += $(obj)/cpu/x86
diff --git a/src/cpu/x86/backup_default_smm.c b/src/cpu/x86/backup_default_smm.c
new file mode 100644
index 0000000..2023aed
--- /dev/null
+++ b/src/cpu/x86/backup_default_smm.c
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc
+ *
+ * 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.
+ */
+
+#include <string.h>
+#include <arch/acpi.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <cpu/x86/smm.h>
+
+void *backup_default_smm_area(void)
+{
+ void *save_area;
+ const void *default_smm = (void *)SMM_DEFAULT_BASE;
+
+ if (!IS_ENABLED(CONFIG_HAVE_ACPI_RESUME))
+ return NULL;
+
+ /*
+ * The buffer needs to be preallocated regardless. In the non-resume
+ * path it will be allocated for handling resume. Note that cbmem_add()
+ * does a find before the addition.
+ */
+ save_area = cbmem_add(CBMEM_ID_SMM_SAVE_SPACE, SMM_DEFAULT_SIZE);
+
+ if (save_area == NULL) {
+ printk(BIOS_DEBUG, "SMM save area not added.\n");
+ return NULL;
+ }
+
+ /* Only back up the area on S3 resume. */
+ if (acpi_is_wakeup_s3()) {
+ memcpy(save_area, default_smm, SMM_DEFAULT_SIZE);
+ return save_area;
+ }
+
+ /*
+ * Not the S3 resume path. No need to restore memory contents after
+ * SMM relocation.
+ */
+ return NULL;
+}
+
+void restore_default_smm_area(void *smm_save_area)
+{
+ void *default_smm = (void *)SMM_DEFAULT_BASE;
+
+ if (smm_save_area == NULL)
+ return;
+
+ memcpy(default_smm, smm_save_area, SMM_DEFAULT_SIZE);
+}
diff --git a/src/cpu/x86/smm/Makefile.inc b/src/cpu/x86/smm/Makefile.inc
index 72c9796..32f5ea7 100644
--- a/src/cpu/x86/smm/Makefile.inc
+++ b/src/cpu/x86/smm/Makefile.inc
@@ -13,7 +13,6 @@
## GNU General Public License for more details.
##
-ramstage-$(CONFIG_BACKUP_DEFAULT_SMM_REGION) += backup_default_smm.c
ramstage-y += smm_module_loader.c
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
diff --git a/src/cpu/x86/smm/backup_default_smm.c b/src/cpu/x86/smm/backup_default_smm.c
deleted file mode 100644
index 2023aed..0000000
--- a/src/cpu/x86/smm/backup_default_smm.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2014 Google Inc
- *
- * 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.
- */
-
-#include <string.h>
-#include <arch/acpi.h>
-#include <console/console.h>
-#include <cbmem.h>
-#include <cpu/x86/smm.h>
-
-void *backup_default_smm_area(void)
-{
- void *save_area;
- const void *default_smm = (void *)SMM_DEFAULT_BASE;
-
- if (!IS_ENABLED(CONFIG_HAVE_ACPI_RESUME))
- return NULL;
-
- /*
- * The buffer needs to be preallocated regardless. In the non-resume
- * path it will be allocated for handling resume. Note that cbmem_add()
- * does a find before the addition.
- */
- save_area = cbmem_add(CBMEM_ID_SMM_SAVE_SPACE, SMM_DEFAULT_SIZE);
-
- if (save_area == NULL) {
- printk(BIOS_DEBUG, "SMM save area not added.\n");
- return NULL;
- }
-
- /* Only back up the area on S3 resume. */
- if (acpi_is_wakeup_s3()) {
- memcpy(save_area, default_smm, SMM_DEFAULT_SIZE);
- return save_area;
- }
-
- /*
- * Not the S3 resume path. No need to restore memory contents after
- * SMM relocation.
- */
- return NULL;
-}
-
-void restore_default_smm_area(void *smm_save_area)
-{
- void *default_smm = (void *)SMM_DEFAULT_BASE;
-
- if (smm_save_area == NULL)
- return;
-
- memcpy(default_smm, smm_save_area, SMM_DEFAULT_SIZE);
-}
diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig
index 8de32de..fcf382e 100644
--- a/src/soc/intel/baytrail/Kconfig
+++ b/src/soc/intel/baytrail/Kconfig
@@ -11,7 +11,6 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
- select BACKUP_DEFAULT_SMM_REGION
select CACHE_MRC_SETTINGS
select CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
select SUPPORT_CPU_UCODE_IN_CBFS
diff --git a/src/soc/intel/braswell/Kconfig b/src/soc/intel/braswell/Kconfig
index 053aa29..3c6f788 100644
--- a/src/soc/intel/braswell/Kconfig
+++ b/src/soc/intel/braswell/Kconfig
@@ -11,7 +11,6 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_RAMSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_VERSTAGE_X86_32
- select BACKUP_DEFAULT_SMM_REGION
select CACHE_MRC_SETTINGS
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
select COLLECT_TIMESTAMPS
diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig
index 33644e8..1c29d77 100644
--- a/src/soc/intel/broadwell/Kconfig
+++ b/src/soc/intel/broadwell/Kconfig
@@ -11,7 +11,6 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
- select BACKUP_DEFAULT_SMM_REGION
select CACHE_MRC_SETTINGS
select MRC_SETTINGS_PROTECT
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index 302b575..0b7dc8c 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -12,7 +12,6 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_ROMSTAGE_X86_32
select ARCH_VERSTAGE_X86_32
select ACPI_NHLT
- select BACKUP_DEFAULT_SMM_REGION
select CACHE_MRC_SETTINGS
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
select COLLECT_TIMESTAMPS
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14560
-gerrit
commit a60a2ca4beb94b0bb0dd4385a9c513974065eae0
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Sat Apr 30 14:56:20 2016 -0500
cpu/x86/smm_module_loader: always build with SMM module support
The SMM module loader code was guarded by CONFIG_SMM_TSEG,
however that's not necessary. It's up to the chipset to take
advantage of the SMM module loading. It'll get optimized out
if the code isn't used anyway so just expose the declarations.
Change-Id: I6ba1b91d0c84febd4f1a92737b3d7303ab61b343
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/x86/smm/Makefile.inc | 3 +--
src/include/cpu/x86/smm.h | 6 +-----
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/src/cpu/x86/smm/Makefile.inc b/src/cpu/x86/smm/Makefile.inc
index c912a8f..72c9796 100644
--- a/src/cpu/x86/smm/Makefile.inc
+++ b/src/cpu/x86/smm/Makefile.inc
@@ -14,6 +14,7 @@
##
ramstage-$(CONFIG_BACKUP_DEFAULT_SMM_REGION) += backup_default_smm.c
+ramstage-y += smm_module_loader.c
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
$(eval $(call create_class_compiler,smm,x86_32))
@@ -42,8 +43,6 @@ smmstub-y += smm_stub.S
smm-y += smm_module_handler.c
-ramstage-y += smm_module_loader.c
-
ramstage-srcs += $(obj)/cpu/x86/smm/smm.manual
ramstage-srcs += $(obj)/cpu/x86/smm/smmstub.manual
diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h
index 64759b0..2b13f8c 100644
--- a/src/include/cpu/x86/smm.h
+++ b/src/include/cpu/x86/smm.h
@@ -488,8 +488,6 @@ void smi_release_lock(void);
/* Get PMBASE address */
u16 smm_get_pmbase(void);
-#if CONFIG_SMM_TSEG
-
struct smm_runtime {
u32 smbase;
u32 save_state_size;
@@ -520,8 +518,8 @@ void asmlinkage smm_handler_start(void *params);
/* Retrieve SMM save state for a given CPU. WARNING: This does not take into
* account CPUs which are configured to not save their state to RAM. */
void *smm_get_save_state(int cpu);
+#endif /* __SMM__ */
-#else
/* SMM Module Loading API */
/* The smm_loader_params structure provides direction to the SMM loader:
@@ -559,8 +557,6 @@ struct smm_loader_params {
/* Both of these return 0 on success, < 0 on failure. */
int smm_setup_relocation_handler(struct smm_loader_params *params);
int smm_load_module(void *smram, int size, struct smm_loader_params *params);
-#endif /* __SMM__ */
-#endif /* CONFIG_SMM_TSEG */
/* Backup and restore default SMM region. */
void *backup_default_smm_area(void);
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 b9da65a9cbc02b05bc185b740b2356ce6171fc66
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 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 | 238 +++++++++++++++++++++++++++++++++++++++++++++++
src/include/cpu/x86/mp.h | 86 +++++++++++++++++
2 files changed, 324 insertions(+)
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c
index 2180d98..72e1e2c 100644
--- a/src/cpu/x86/mp_init.c
+++ b/src/cpu/x86/mp_init.c
@@ -607,3 +607,241 @@ 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..a7100f6 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
the following patch was just integrated into master:
commit ac6bd5b037269a85eb67f444b81818618c88b33f
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Fri Apr 29 01:40:30 2016 -0500
nb/amd/mct_ddr3: Warn if MaxRdLatency training fails on Family 15h
Change-Id: Idb948acd1a508379f600fbd2fd40fb26b7571d7c
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14545
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply(a)raptorengineeringinc.com>
Reviewed-by: Martin Roth <martinroth(a)google.com>
See https://review.coreboot.org/14545 for details.
-gerrit
the following patch was just integrated into master:
commit 2bb1d30d69d807ee70d005b70f8ea5e9caa74fae
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Fri Apr 29 01:38:58 2016 -0500
nb/amd/mct_ddr3: Stop receiver enable cycle training after window found
During receiver enable cycle training on Family 15h the entire range
of possible delays is searched, even though the single passing window
is often found nearly immediately. Skip the remainder of the delay
range after the passing window has been located.
Change-Id: If98217fa8e7de77366762d3c7bb01049a1dc080f
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14544
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply(a)raptorengineeringinc.com>
Reviewed-by: Martin Roth <martinroth(a)google.com>
See https://review.coreboot.org/14544 for details.
-gerrit
the following patch was just integrated into master:
commit 29dd5da1dc577bf97cb85998b17b2e163a5ab86e
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Fri Apr 29 01:35:21 2016 -0500
nb/amd/mct_ddr3: Do not constantly reset read data timing registers to 0
During DQS receiver enable cycle training on Family 15h platforms the
read data timing registers were inadvertently set to zero on every
lane training attempt.
Ensure that the read data timing registers are correctly set after
each lane is trained in receiver enable cycle training. This allows
more than one RDIMM to function on a given DCT channel.
Change-Id: I87d732f0383e9785a73b57e6f48855f3e872f1f9
Tested-On: ASUS KGPE-D16
Tested-With: 1x Opteron 6262HE
Tested-With: 4x Crucial 36KSF1G72PZ-1G6M1 (slots A2 / A1 / B2 / B1)
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14543
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply(a)raptorengineeringinc.com>
Reviewed-by: Martin Roth <martinroth(a)google.com>
See https://review.coreboot.org/14543 for details.
-gerrit
the following patch was just integrated into master:
commit 263c679075816a0db146ff5fa6b94689837ff696
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Fri Apr 29 01:34:08 2016 -0500
nb/amd/mct_ddr3: Skip nibble training when current DIMM is not x4
Change-Id: I1f5b024606093dc81de3f3d69b7a43e20141b709
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14542
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply(a)raptorengineeringinc.com>
Reviewed-by: Martin Roth <martinroth(a)google.com>
See https://review.coreboot.org/14542 for details.
-gerrit
the following patch was just integrated into master:
commit 7f731f8d4f0d4dbc109869032f4e993995eac045
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Fri Apr 29 00:38:29 2016 -0500
nb/amd/mct_ddr3: Fix x4 DIMM receiver enable training on Fam15h
The existing Family 15h receiver enable training code stored
temporary delay values in the wrong variables, leading to
the requisite averaging of delays across nibbles not being
applied. This in turn made x4 DIMMs less stable than they
should have been.
Store temporary nibble delay values in a dedicated array.
Change-Id: Ic5da898af7d689db4110211f89b886ccdbb5f78f
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14541
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply(a)raptorengineeringinc.com>
Reviewed-by: Martin Roth <martinroth(a)google.com>
See https://review.coreboot.org/14541 for details.
-gerrit
Jonathan Neuschäfer (j.neuschaefer(a)gmx.net) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14559
-gerrit
commit caf5ffa3d97b7c49af8fb2582b35dec2726c76dc
Author: Jonathan Neuschäfer <j.neuschaefer(a)gmx.net>
Date: Sat Apr 30 21:11:48 2016 +0200
board_status/towiki: Link to CGit instead of Gitweb
Gitweb isn't online anymore, so fix a few broken links.
Change-Id: I7fdfcb60f83a718c9a5b6c7f7ef4df9206451d95
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer(a)gmx.net>
---
util/board_status/to-wiki/foreword.wiki | 4 ++--
util/board_status/to-wiki/towiki.sh | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/util/board_status/to-wiki/foreword.wiki b/util/board_status/to-wiki/foreword.wiki
index 5b1875c..631cca4 100644
--- a/util/board_status/to-wiki/foreword.wiki
+++ b/util/board_status/to-wiki/foreword.wiki
@@ -19,9 +19,9 @@ id, so it is possible to reproduce the build.
We encourage developers and users to contribute reports so we know which
devices are well-tested. We have
-[http://review.coreboot.org/gitweb?p=coreboot.git;a=tree;f=util/board_status;hb=HEAD a tool in the coreboot repository]
+[https://review.coreboot.org/gitweb/cgit/coreboot.git/tree/util/board_status a tool in the coreboot repository]
to make contributing easy. The data resides in the
-[http://review.coreboot.org/gitweb?p=board-status.git board status repository].
+[https://review.coreboot.org/gitweb/cgit/board-status.git/ board status repository].
Contributing requires an account on review.coreboot.org
Sometimes the same board is sold under different names, we've tried to
diff --git a/util/board_status/to-wiki/towiki.sh b/util/board_status/to-wiki/towiki.sh
index 3fec386..2e458c6 100755
--- a/util/board_status/to-wiki/towiki.sh
+++ b/util/board_status/to-wiki/towiki.sh
@@ -1,8 +1,8 @@
#!/bin/sh
export COREBOOT_DIR="../coreboot"
export GIT_DIR="$COREBOOT_DIR/.git"
-CODE_GITWEB="http://review.coreboot.org/gitweb?p=coreboot.git;a=commitdiff;h="
-STATUS_GITWEB="http://review.coreboot.org/gitweb?p=board-status.git;a=blob;hb=HEAD;f="
+CODE_GITWEB="https://review.coreboot.org/gitweb/cgit/coreboot.git/commit/?id="
+STATUS_GITWEB="https://review.coreboot.org/gitweb/cgit/board-status.git/tree/"
if [ -f `dirname $0`/foreword.wiki ]; then
cat `dirname $0`/foreword.wiki
fi