aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/apollolake/car.c
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@google.com>2016-04-21 08:10:02 -0700
committerMartin Roth <martinroth@google.com>2016-04-22 17:27:34 +0200
commit0b6ff7834238a18258028faa686ef15162ea5d36 (patch)
tree33c90404a71dcf07f7d7c194ac69965630c394ab /src/soc/intel/apollolake/car.c
parentd255744dba28565cf61b7318678ccf5f19170028 (diff)
soc/intel/apollolake: Flush L1D to L2 only if loaded segment is in CAR
In program_segment_loaded, flush L1D to L2 only if the address of the loaded segment lies in the CAR region. Add an assert to ensure that the loaded segment does not cross CAR boundaries. Change-Id: Ie43e99299ed82f01518c8a1c1fd2bc64747d0c7b Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://review.coreboot.org/14449 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/soc/intel/apollolake/car.c')
-rw-r--r--src/soc/intel/apollolake/car.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/soc/intel/apollolake/car.c b/src/soc/intel/apollolake/car.c
index ff4603ca48..68bcb31eb1 100644
--- a/src/soc/intel/apollolake/car.c
+++ b/src/soc/intel/apollolake/car.c
@@ -16,6 +16,7 @@
*/
#include <arch/cpu.h>
+#include <assert.h>
#include <program_loading.h>
#include <soc/cpu.h>
@@ -31,11 +32,27 @@ static void flush_l1d_to_l2(void)
wrmsr(MSR_POWER_MISC, msr);
}
+static inline int is_car_addr(uintptr_t addr)
+{
+ return ((addr >= CONFIG_DCACHE_RAM_BASE) &&
+ (addr < (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)));
+}
+
void platform_segment_loaded(uintptr_t start, size_t size, int flags)
{
- /* TODO: filter on address to see if L1D flushing required. */
+ /* Bail out if this is not the final segment. */
+ if (!(flags & SEG_FINAL))
+ return;
+
+ char start_car_check = is_car_addr(start);
+ char end_car_check = is_car_addr(start + size - 1);
+
+ /* Bail out if loaded program segment does not lie in CAR region. */
+ if (!start_car_check && !end_car_check)
+ return;
+
+ /* Loaded program segment should lie entirely within CAR region. */
+ assert (start_car_check && end_car_check);
- /* Flush L1D cache to L2 on final segment loaded */
- if (flags & SEG_FINAL)
- flush_l1d_to_l2();
+ flush_l1d_to_l2();
}