Attention is currently required from: Arthur Heymans. Hello Arthur Heymans,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/63553
to review the following change.
Change subject: cpu/x86/mp_init.c: Add wait_finished_mp_run_on_all_cpus ......................................................................
cpu/x86/mp_init.c: Add wait_finished_mp_run_on_all_cpus
This functions makes sure that all APs finish executing their call before continuing to execute code on the BSP.
Change-Id: I70244557bb384739e3bd06de3d8414ec9f4d5f62 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/x86/mp_init.c M src/include/cpu/x86/mp.h 2 files changed, 25 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/53/63553/1
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 81c987b..656bc63 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -1009,6 +1009,27 @@ return mp_run_on_aps(func, arg, MP_RUN_ON_ALL_CPUS, 1000 * USECS_PER_MSEC); }
+/* + * mp_run_on_all_cpus() only waits for all APs accept to start + * running a function call but does not wait for them to finish it. + * APs only accept a new task when the the previous one is finished + * so to make sure that the post_cpus_add_romcache() is not overwritten + * by an AP thread we do a NOOP call on the APs which will ensure the + * previous function actually finished running. + */ +static void noop(void *unused) +{ +} + +enum cb_err wait_finished_mp_run_on_all_cpus(void (*func)(void *), void *arg) +{ + enum cb_err err = mp_run_on_all_cpus(func, arg); + if (err != CB_SUCCESS) + return err; + err = mp_run_on_all_cpus(noop, NULL); + return err; +} + enum cb_err mp_park_aps(void) { struct stopwatch sw; diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h index 1b4c956..5a1e927 100644 --- a/src/include/cpu/x86/mp.h +++ b/src/include/cpu/x86/mp.h @@ -117,6 +117,10 @@ /* Like mp_run_on_aps() but also runs func on BSP. */ enum cb_err mp_run_on_all_cpus(void (*func)(void *), void *arg);
+/* Like mp_run_on_all_cpus but make sure all APs finish executing the + function call. The time limit on a function call is 1 second. */ +enum cb_err wait_finished_mp_run_on_all_cpus(void (*func)(void *), void *arg); + /* * Park all APs to prepare for OS boot. This is handled automatically * by the coreboot infrastructure.