]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(cpus): make cache ops conditional
authorOkash Khawaja <okash@google.com>
Fri, 4 Nov 2022 12:38:01 +0000 (12:38 +0000)
committerOkash Khawaja <okash@google.com>
Thu, 10 Nov 2022 12:14:05 +0000 (12:14 +0000)
When a core is in debug recovery mode its caches are not invalidated
upon reset, so the L1 and L2 cache contents from before reset are
observable after reset. Similarly, debug recovery mode of DynamIQ
cluster ensures that contents of the shared L3 cache are also not
invalidated upon transition to On mode.

Booting cores in debug recovery mode means booting with caches disabled
and preserving the caches until a point where software can dump the
caches and retrieve their contents. TF-A however unconditionally cleans
and invalidates caches at multiple points during boot. This can lead to
memory corruption as well as loss of cache contents to be used for
debugging.

This patch fixes this by calling a platform hook before performing CMOs
in helper routines in cache_helpers.S. The platform hook plat_can_cmo is
an assembly routine which must not clobber x2 and x3, and avoid using
stack. The whole checking is conditional upon `CONDITIONAL_CMO` which
can be set at compile time.

Signed-off-by: Okash Khawaja <okash@google.com>
Change-Id: I172e999e4acd0f872c24056e647cc947ee54b193

Makefile
docs/getting_started/build-options.rst
docs/getting_started/porting-guide.rst
lib/aarch32/cache_helpers.S
lib/aarch64/cache_helpers.S
make_helpers/defaults.mk

index 70d5338eb846ddf7958545c24c47e36f70184c15..b664ac0af9c4b82dbf6a02a2e6c965671fbdd794 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1080,6 +1080,7 @@ $(eval $(call assert_booleans,\
         SIMICS_BUILD \
         FEATURE_DETECTION \
        TRNG_SUPPORT \
+       CONDITIONAL_CMO \
 )))
 
 $(eval $(call assert_numerics,\
@@ -1241,6 +1242,7 @@ $(eval $(call add_defines,\
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
+       CONDITIONAL_CMO \
 )))
 
 ifeq (${SANITIZE_UB},trap)
index 68ef4cefd16395b920a88852dbca7faaf85f80ab..d1acf4f4e16a147e3d90cfb12b8149427b7a0a8f 100644 (file)
@@ -1031,6 +1031,12 @@ Common build options
   functionalities). When enabled (``1``), a mocked version of the APIs are used.
   The default value is 0.
 
+- ``CONDITIONAL_CMO``: Boolean option to enable call to platform-defined routine
+  ``plat_can_cmo`` which will return zero if cache management operations should
+  be skipped and non-zero otherwise. By default, this option is disabled which
+  means platform hook won't be checked and CMOs will always be performed when
+  related functions are called.
+
 GICv3 driver options
 --------------------
 
index 668af57142a01e4caa9fb46c5fd91468e3fba8f9..4639fd5fd14cd32d25635cc76e9a3b249785c5e0 100644 (file)
@@ -1461,6 +1461,22 @@ When the MEASURED_BOOT flag is enabled:
 
 When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
 
+Function : plat_can_cmo()
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+When CONDITIONAL_CMO flag is enabled:
+
+- This function indicates whether cache management operations should be
+  performed. It returns 0 if CMOs should be skipped and non-zero
+  otherwise.
+- The function must not clobber x2 and x3. It's also not safe to rely on stack.
+  Otherwise obey AAPCS.
+
 Modifications specific to a Boot Loader stage
 ---------------------------------------------
 
index 13d1872f84a91af2d195030ab93f2c2b0c5ab1c3..fd9b33f2d5547c2ac5eac747a4e473bdcfa87ae5 100644 (file)
@@ -37,12 +37,27 @@ exit_loop_\op:
        bx      lr
 .endm
 
+.macro check_plat_can_cmo
+#if CONDITIONAL_CMO
+       mov     r3, lr
+       mov     r2, r0
+       bl      plat_can_cmo
+       mov     lr, r3
+       cmp     r0, #0
+       bne     1f
+       bx      lr
+1:
+       mov     r0, r2
+#endif
+.endm
+
        /* ------------------------------------------
         * Clean+Invalidate from base address till
         * size. 'r0' = addr, 'r1' = size
         * ------------------------------------------
         */
 func flush_dcache_range
+       check_plat_can_cmo
        do_dcache_maintenance_by_mva cimvac, DCCIMVAC
 endfunc flush_dcache_range
 
@@ -52,6 +67,7 @@ endfunc flush_dcache_range
         * ------------------------------------------
         */
 func clean_dcache_range
+       check_plat_can_cmo
        do_dcache_maintenance_by_mva cmvac, DCCMVAC
 endfunc clean_dcache_range
 
@@ -61,6 +77,7 @@ endfunc clean_dcache_range
         * ------------------------------------------
         */
 func inv_dcache_range
+       check_plat_can_cmo
        do_dcache_maintenance_by_mva imvac, DCIMVAC
 endfunc inv_dcache_range
 
@@ -168,6 +185,7 @@ endfunc do_dcsw_op
         * ---------------------------------------------------------------
         */
 func dcsw_op_louis
+       check_plat_can_cmo
        dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
 endfunc        dcsw_op_louis
 
@@ -180,6 +198,7 @@ endfunc     dcsw_op_louis
         * ---------------------------------------------------------------
         */
 func dcsw_op_all
+       check_plat_can_cmo
        dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
 endfunc        dcsw_op_all
 
@@ -205,6 +224,7 @@ endfunc     dcsw_op_all
         * ---------------------------------------------------------------
         */
 func dcsw_op_level1
+       check_plat_can_cmo
        dcsw_op_level #(1 << LEVEL_SHIFT)
 endfunc dcsw_op_level1
 
@@ -217,6 +237,7 @@ endfunc dcsw_op_level1
         * ---------------------------------------------------------------
         */
 func dcsw_op_level2
+       check_plat_can_cmo
        dcsw_op_level #(2 << LEVEL_SHIFT)
 endfunc dcsw_op_level2
 
@@ -229,5 +250,6 @@ endfunc dcsw_op_level2
         * ---------------------------------------------------------------
         */
 func dcsw_op_level3
+       check_plat_can_cmo
        dcsw_op_level #(3 << LEVEL_SHIFT)
 endfunc dcsw_op_level3
index 6faf545a142dbc29a542f4f24a58da8d07743cea..67fafb1e7a07b78c28b836733f77ed337fda42ca 100644 (file)
@@ -35,6 +35,19 @@ loop_\op:
        dsb     sy
 exit_loop_\op:
        ret
+.endm
+
+.macro check_plat_can_cmo
+#if CONDITIONAL_CMO
+       mov     x3, x30
+       mov     x2, x0
+       bl      plat_can_cmo
+       mov     x30, x3
+       cbnz    x0, 1f
+       ret
+1:
+       mov      x0, x2
+#endif
 .endm
        /* ------------------------------------------
         * Clean+Invalidate from base address till
@@ -42,6 +55,7 @@ exit_loop_\op:
         * ------------------------------------------
         */
 func flush_dcache_range
+       check_plat_can_cmo
        do_dcache_maintenance_by_mva civac
 endfunc flush_dcache_range
 
@@ -51,6 +65,7 @@ endfunc flush_dcache_range
         * ------------------------------------------
         */
 func clean_dcache_range
+       check_plat_can_cmo
        do_dcache_maintenance_by_mva cvac
 endfunc clean_dcache_range
 
@@ -60,6 +75,7 @@ endfunc clean_dcache_range
         * ------------------------------------------
         */
 func inv_dcache_range
+       check_plat_can_cmo
        do_dcache_maintenance_by_mva ivac
 endfunc inv_dcache_range
 
@@ -79,6 +95,7 @@ endfunc inv_dcache_range
 func flush_dcache_to_popa_range
        /* Exit early if size is zero */
        cbz     x1, exit_loop_dc_cipapa
+       check_plat_can_cmo
        dcache_line_size x2, x3
        sub     x3, x2, #1
        bic     x0, x0, x3
@@ -205,6 +222,7 @@ endfunc dcsw_op_louis
 
 
 func dcsw_op_all
+       check_plat_can_cmo
        dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
 endfunc dcsw_op_all
 
@@ -228,6 +246,7 @@ endfunc dcsw_op_all
         * ---------------------------------------------------------------
         */
 func dcsw_op_level1
+       check_plat_can_cmo
        dcsw_op_level #(1 << LEVEL_SHIFT)
 endfunc dcsw_op_level1
 
@@ -239,6 +258,7 @@ endfunc dcsw_op_level1
         * ---------------------------------------------------------------
         */
 func dcsw_op_level2
+       check_plat_can_cmo
        dcsw_op_level #(2 << LEVEL_SHIFT)
 endfunc dcsw_op_level2
 
@@ -250,5 +270,6 @@ endfunc dcsw_op_level2
         * ---------------------------------------------------------------
         */
 func dcsw_op_level3
+       check_plat_can_cmo
        dcsw_op_level #(3 << LEVEL_SHIFT)
 endfunc dcsw_op_level3
index 772b28de035889403e3eaaf8f2cd44d5ec935fc4..4b238e34676237ba27cb7aceac4cf1b80abcd2d0 100644 (file)
@@ -480,3 +480,7 @@ PLAT_RSS_NOT_SUPPORTED              := 0
 
 # Dynamic Root of Trust for Measurement support
 DRTM_SUPPORT                   := 0
+
+# Check platform if cache management operations should be performed.
+# Disabled by default.
+CONDITIONAL_CMO                        := 0