the following patch was just integrated into master:
commit 27198ac2e3efaf45177909d35d1dab5f82c114fd
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Fri Dec 2 14:38:13 2016 +0200
MMCONF_SUPPORT: Drop redundant logging
Resource is actually stored even before read_resources, but
that's where we currently log this resource.
For Intel, use PCI config register offset as the resource
index, while AMD side uses MSR address.
Change-Id: I6eeef1883c5d1ee5bbcebd1731c0e356af3fd781
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Reviewed-on: https://review.coreboot.org/17696
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/17696 for details.
-gerrit
the following patch was just integrated into master:
commit 3d15e10aef5811e8c7146e5defb0e36b848547ed
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Tue Nov 29 16:46:56 2016 +0200
MMCONF_SUPPORT: Flip default to enabled
Also remove separate MMCONF_SUPPORT_DEFAULT flag.
Change-Id: Idf1accdb93843a8fe2ee9c09fb984968652476e0
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Reviewed-on: https://review.coreboot.org/17694
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/17694 for details.
-gerrit
the following patch was just integrated into master:
commit 6f66f414a0907f79abf492cd9eca839c0849c7f6
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Thu Dec 1 22:08:18 2016 +0200
PCI ops: MMCONF_SUPPORT_DEFAULT is required
Doing PCI config operations via MMIO window by default is a
requirement, if supported by the platform. This means chipset
or CPU code must enable MMCONF operations early in bootblock
already, or before platform-specific romstage entry.
Platforms are allowed to have NO_MMCONF_SUPPORT only in the
case it is actually not implemented in the silicon.
Change-Id: Id4d9029dec2fe195f09373320de800fcdf88c15d
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Reviewed-on: https://review.coreboot.org/17693
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/17693 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/17745
-gerrit
commit 48586ebcf74531ca2a9e21c2f16eb946689eeee2
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Wed Dec 7 00:32:19 2016 -0600
cpu/x86: allow AP callbacks after MP init
There are circumstances where the APs need to run a piece of
code later in the boot flow. The current MP init just parks
the APs after MP init is completed so there's not an opportunity
to target running a piece of code on all the APs at a later time.
Therefore, provide an option, PARALLEL_MP_AP_WORK, that allows
the APs to perform callbacks.
BUG=chrome-os-partner:60657
BRANCH=reef
Change-Id: I849ecfdd6641dd9424943e246317cd1996ef1ba6
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/x86/Kconfig | 6 +++
src/cpu/x86/mp_init.c | 101 +++++++++++++++++++++++++++++++++++++++++++----
src/include/cpu/x86/mp.h | 14 +++++++
3 files changed, 114 insertions(+), 7 deletions(-)
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 3e56d72..2e233cc 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -10,6 +10,12 @@ config PARALLEL_MP
in parallel. It additionally provides a more flexible mechanism
for sequencing the steps of bringing up the APs.
+config PARALLEL_MP_AP_WORK
+ def_bool n
+ depends on PARALLEL_MP
+ help
+ Allow APs to do other work after initialization instead of going
+ to sleep.
config UDELAY_IO
bool
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c
index baa3599..905f9d0 100644
--- a/src/cpu/x86/mp_init.c
+++ b/src/cpu/x86/mp_init.c
@@ -127,6 +127,7 @@ struct mp_flight_plan {
struct mp_flight_record *records;
};
+static int global_num_aps;
static struct mp_flight_plan mp_info;
struct cpu_map {
@@ -185,6 +186,11 @@ static void ap_do_flight_plan(void)
}
}
+static void park_this_cpu(void)
+{
+ stop_this_cpu();
+}
+
/* By the time APs call ap_init() caching has been setup, and microcode has
* been loaded. */
static void asmlinkage ap_init(unsigned int cpu)
@@ -210,7 +216,7 @@ static void asmlinkage ap_init(unsigned int cpu)
ap_do_flight_plan();
/* Park the AP. */
- stop_this_cpu();
+ park_this_cpu();
}
static void setup_default_sipi_vector_params(struct sipi_params *sp)
@@ -587,7 +593,6 @@ static void init_bsp(struct bus *cpu_bus)
static int mp_init(struct bus *cpu_bus, struct mp_params *p)
{
int num_cpus;
- int num_aps;
atomic_t *ap_count;
init_bsp(cpu_bus);
@@ -621,11 +626,11 @@ static int mp_init(struct bus *cpu_bus, struct mp_params *p)
wbinvd();
/* Start the APs providing number of APs and the cpus_entered field. */
- num_aps = p->num_cpus - 1;
- if (start_aps(cpu_bus, num_aps, ap_count) < 0) {
+ global_num_aps = p->num_cpus - 1;
+ if (start_aps(cpu_bus, global_num_aps, ap_count) < 0) {
mdelay(1000);
printk(BIOS_DEBUG, "%d/%d eventually checked in?\n",
- atomic_read(ap_count), num_aps);
+ atomic_read(ap_count), global_num_aps);
return -1;
}
@@ -838,6 +843,88 @@ static void trigger_smm_relocation(void)
mp_state.ops.per_cpu_smm_trigger();
}
+static mp_callback_t ap_callbacks[CONFIG_MAX_CPUS];
+
+static mp_callback_t read_callback(mp_callback_t *slot)
+{
+ return *(volatile mp_callback_t *)slot;
+}
+
+static void store_callback(mp_callback_t *slot, mp_callback_t value)
+{
+ *(volatile mp_callback_t *)slot = value;
+}
+
+static int run_ap_work(mp_callback_t func, long expire_us)
+{
+ int i;
+ int cpus_accepted;
+ struct stopwatch sw;
+ int cur_cpu = cpu_index();
+
+ if (!IS_ENABLED(CONFIG_PARALLEL_MP_AP_WORK)) {
+ printk(BIOS_ERR, "APs already parked. PARALLEL_MP_AP_WORK not selected.\n");
+ return -1;
+ }
+
+ /* Signal to all the APs to run the func. */
+ for (i = 0; i < ARRAY_SIZE(ap_callbacks); i++) {
+ if (cur_cpu == i)
+ continue;
+ store_callback(&ap_callbacks[i], func);
+ }
+ mfence();
+
+ /* Wait for all the APs to signal back that call has been accepted. */
+ stopwatch_init_usecs_expire(&sw, expire_us);
+ while (!stopwatch_expired(&sw)) {
+ cpus_accepted = 0;
+ for (i = 0; i < ARRAY_SIZE(ap_callbacks); i++) {
+ if (cur_cpu == i)
+ continue;
+ if (read_callback(&ap_callbacks[i]) == NULL)
+ cpus_accepted++;
+ }
+ if (cpus_accepted == global_num_aps)
+ return 0;
+ }
+
+ printk(BIOS_ERR, "AP call expired. %d/%d CPUs accepted.\n",
+ cpus_accepted, global_num_aps);
+ return -1;
+}
+
+static void ap_wait_for_instruction(void)
+{
+ int cur_cpu = cpu_index();
+
+ if (!IS_ENABLED(CONFIG_PARALLEL_MP_AP_WORK))
+ return;
+
+ while (1) {
+ mp_callback_t func = read_callback(&ap_callbacks[cur_cpu]);
+
+ if (func == NULL) {
+ asm ("pause");
+ continue;
+ }
+
+ store_callback(&ap_callbacks[cur_cpu], NULL);
+ mfence();
+ func();
+ }
+}
+
+int mp_run_on_aps(void (*func)(void), long expire_us)
+{
+ return run_ap_work(func, expire_us);
+}
+
+int mp_park_aps(void)
+{
+ return mp_run_on_aps(park_this_cpu, 10 * USECS_PER_MSEC);
+}
+
static struct mp_flight_record mp_steps[] = {
/* Once the APs are up load the SMM handlers. */
MP_FR_BLOCK_APS(NULL, load_smm_handlers),
@@ -845,8 +932,8 @@ static struct mp_flight_record mp_steps[] = {
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),
+ /* Wait for APs to finish then optionally start looking for work. */
+ MP_FR_BLOCK_APS(ap_wait_for_instruction, NULL),
};
static void fill_mp_state(struct mp_state *state, const struct mp_ops *ops)
diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h
index 6d51d7b..5c2887f 100644
--- a/src/include/cpu/x86/mp.h
+++ b/src/include/cpu/x86/mp.h
@@ -124,6 +124,20 @@ struct mp_ops {
*/
int mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops *mp_ops);
+
+/*
+ * After APs are up and PARALLEL_MP_AP_WORK is enabled one can issue work
+ * to all the APs to perform. Currently the BSP is the only CPU that is allowed
+ * to issue work. i.e. the APs should not call any of these functions.
+ * All functions return < 0 on error, 0 on success.
+ */
+int mp_run_on_aps(void (*func)(void), long expire_us);
+
+/*
+ * Park all APs to prepare for OS boot.
+ */
+int mp_park_aps(void);
+
/*
* SMM helpers to use with initializing CPUs.
*/
the following patch was just integrated into master:
commit 891b6c4d199418a08ba88e42d6c8945ce05205f1
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Dec 5 22:06:23 2016 -0600
mainboard/google/reef: adjust chromeos.fmd regions
- Drastically reduced RW_MRC_CACHE size to hold one update. Now
that this area isn't changing after every S5 entry there's no
need make it so large.
- ELOG area reduced by 4KiB for subsequent area alignment. In practice
this doesn't matter because the elog library only uses 4KiB bytes.
16KiB->12KiB is a nop.
- Moved RW_NVRAM for subsequent alignment.
- Most importantly, RW_SECTION_(A|B) are aligned to 64KiB boundaries
and sized to 64KiB multiples. This ensures updates don't need a
read-modify-write that could force a system into recovery if
an inopportune power event occurred.
BUG=chrome-os-partner:60492
BRANCH=reef
Change-Id: I2a2e2797897c934db1a3f9627c6c13a9b2aad540
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Reviewed-on: https://review.coreboot.org/17727
Tested-by: build bot (Jenkins)
Reviewed-by: Furquan Shaikh <furquan(a)google.com>
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
See https://review.coreboot.org/17727 for details.
-gerrit