summaryrefslogtreecommitdiff
path: root/framework
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2017-06-23 09:28:32 +0100
committerSoby Mathew <soby.mathew@arm.com>2017-06-29 11:04:43 +0100
commit186628ee07724a8e1dd6b5cc3c38d7a035c80dea (patch)
treec44765c5d10c94e1002608cacbc74883075eb26d /framework
parentc8fe48a2e86131b439fd60088907cda2810099aa (diff)
Fix sequencing issues in TFTF
The migration to the latest model exposed some sequencing issues in TFTF hotplug and Timer frameworks. The details are as follows: 1. The `tftf_try_cpu_on` function in the hotplug framwork invokes the CPU_ON and then updated the `cpus_status_map[core_pos].state` based the return of CPU_ON call. The spin lock protecting the access to the `state` was acquired after the CPU_ON call which allowed the turned ON cpu to warm boot and execute hotplug framework functions which depends on the state of this variable. This resulted in assertion failures because the caller CPU still has not had a chance to update the variable. This could be solved acquiring the spin lock prior to making the CPU_ON call, but this solution is not adopted because some of the CPU_ON Stress test requires to make concurrent calls to PSCI_CPU_ON to trigger race conditions. Hence the solution is to delay the woken up CPU till the caller CPU has had a chance to update the variable. 2. The timer handler function in timer framework had a similar problem wherein `tftf_send_sgi` wokeup the target CPU and it accessed the `interrupt_req_time` in `tftf_program_timer` prior to the update by the timer handler. This is resolved by doing the update prior to the `tftf_send_sgi`. Also a dsbish() is added in the `tftf_send_sgi` so as to ensure that all memory accesses are completed prior to triggering the SGI. Change-Id: I7afe99653032fc3ec4a799e58436f5efc4d844a9 Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Diffstat (limited to 'framework')
-rw-r--r--framework/timer/timer_framework.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/framework/timer/timer_framework.c b/framework/timer/timer_framework.c
index 7928378..90073ec 100644
--- a/framework/timer/timer_framework.c
+++ b/framework/timer/timer_framework.c
@@ -61,7 +61,7 @@ static const plat_timer_t *plat_timer_info;
/*
* Interrupt requested time by cores in terms of absolute time.
*/
-static unsigned long long interrupt_req_time[PLATFORM_CORE_COUNT];
+static volatile unsigned long long interrupt_req_time[PLATFORM_CORE_COUNT];
/*
* Contains the target core number of the timer interrupt.
*/
@@ -472,8 +472,8 @@ int tftf_timer_framework_handler(void *data)
for (int i = 0; i < PLATFORM_CORE_COUNT; i++) {
if ((interrupt_req_time[i] <=
(current_time + TIMER_STEP_VALUE))) {
- tftf_send_sgi(IRQ_WAKE_SGI, i);
interrupt_req_time[i] = INVALID_TIME;
+ tftf_send_sgi(IRQ_WAKE_SGI, i);
}
}