Bora Guvendik (bora.guvendik@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17986
-gerrit
commit eaaf23b76c0b3c2657dfede852bf364417d22409 Author: Bora Guvendik bora.guvendik@intel.com Date: Wed Dec 28 14:46:11 2016 -0800
WIP:cpu/x86: allow the number of APs to be specified for running code in parallel to BSP.
Allow the number of APs,that will run a piece of code, to be specified. In some cases, a single AP needs to run the code alone.
BUG=chrome-os-partner:56656 BRANCH=reef TEST=None
Change-Id: I39d0210886428187cd7c6e75b3473dd5c733842c Signed-off-by: Bora Guvendik bora.guvendik@intel.com --- src/cpu/x86/mp_init.c | 22 ++++++++++++++++++---- src/include/cpu/x86/mp.h | 3 +++ 2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index c989963..57f670b 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -855,10 +855,11 @@ 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) +static int run_ap_work(mp_callback_t func, long expire_us, int num_aps_needed) { int i; int cpus_accepted; + int cpus_signaled = 0; struct stopwatch sw; int cur_cpu = cpu_index();
@@ -867,11 +868,17 @@ static int run_ap_work(mp_callback_t func, long expire_us) return -1; }
+ if ( num_aps_needed > ARRAY_SIZE(ap_callbacks) ) + 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); + cpus_signaled++; + if ( cpus_signaled == num_aps_needed ) + break; } mfence();
@@ -883,13 +890,15 @@ static int run_ap_work(mp_callback_t func, long expire_us) continue; if (read_callback(&ap_callbacks[i]) == NULL) cpus_accepted++; + if ( cpus_accepted == num_aps_needed ) + break; } - if (cpus_accepted == global_num_aps) + if (cpus_accepted == num_aps_needed) return 0; }
printk(BIOS_ERR, "AP call expired. %d/%d CPUs accepted.\n", - cpus_accepted, global_num_aps); + cpus_accepted, num_aps_needed); return -1; }
@@ -916,7 +925,12 @@ static void ap_wait_for_instruction(void)
int mp_run_on_aps(void (*func)(void), long expire_us) { - return run_ap_work(func, expire_us); + return run_ap_work(func, expire_us, ARRAY_SIZE(ap_callbacks)); +} + +int mp_run_on_single_ap(void (*func)(void), long expire_us) +{ + return run_ap_work(func, expire_us, 1); }
int mp_run_on_all_cpus(void (*func)(void), long expire_us) diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h index b9b4d57..8220530 100644 --- a/src/include/cpu/x86/mp.h +++ b/src/include/cpu/x86/mp.h @@ -133,6 +133,9 @@ int mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops *mp_ops); */ int mp_run_on_aps(void (*func)(void), long expire_us);
+/* Like mp_run_on_aps() but runs func on only one ap */ +int mp_run_on_single_ap(void (*func)(void), long expire_us); + /* Like mp_run_on_aps() but also runs func on BSP. */ int mp_run_on_all_cpus(void (*func)(void), long expire_us);