]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
Implement an assert() callable from assembly code
authorSoby Mathew <soby.mathew@arm.com>
Mon, 14 Jul 2014 15:58:03 +0000 (16:58 +0100)
committerSoby Mathew <soby.mathew@arm.com>
Mon, 28 Jul 2014 10:01:49 +0000 (11:01 +0100)
The patch implements a macro ASM_ASSERT() which can
be invoked from assembly code. When assertion happens,
file name and line number of the check is written
to the crash console.

Fixes ARM-software/tf-issues#95

Change-Id: I6f905a068e1c0fa4f746d723f18df60daaa00a86

Makefile
common/aarch64/assert.S [new file with mode: 0644]
docs/user-guide.md
include/common/assert_macros.S [new file with mode: 0644]
lib/aarch64/misc_helpers.S

index 39496fb738835e3e47e3034d0ff45667a83f0cf8..f8a7da8b80ce23bb776ee1c40f7746245059bfa7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -60,7 +60,9 @@ CTX_INCLUDE_FPREGS            := 0
 # Determine the version of ARM GIC architecture to use for interrupt management
 # in EL3. The platform port can change this value if needed.
 ARM_GIC_ARCH           :=      2
-
+# Flag used to indicate if ASM_ASSERTION should be enabled for the build.
+# This defaults to being present in DEBUG builds only.
+ASM_ASSERTION          :=      ${DEBUG}
 
 # Checkpatch ignores
 CHECK_IGNORE           =       --ignore COMPLEX_MACRO
@@ -92,6 +94,7 @@ VERSION_STRING                :=      v${VERSION_MAJOR}.${VERSION_MINOR}(${BUILD_TYPE}):${BUILD_STR
 BL_COMMON_SOURCES      :=      common/bl_common.c                      \
                                common/debug.c                          \
                                common/tf_printf.c                      \
+                               common/aarch64/assert.S                 \
                                lib/aarch64/cache_helpers.S             \
                                lib/aarch64/misc_helpers.S              \
                                lib/aarch64/xlat_helpers.c              \
@@ -207,6 +210,9 @@ $(eval $(call add_define,CTX_INCLUDE_FPREGS))
 # Process ARM_GIC_ARCH flag
 $(eval $(call add_define,ARM_GIC_ARCH))
 
+# Process ASM_ASSERTION flag
+$(eval $(call assert_boolean,ASM_ASSERTION))
+$(eval $(call add_define,ASM_ASSERTION))
 
 ASFLAGS                        +=      -nostdinc -ffreestanding -Wa,--fatal-warnings   \
                                -Werror -Wmissing-include-dirs                  \
diff --git a/common/aarch64/assert.S b/common/aarch64/assert.S
new file mode 100644 (file)
index 0000000..a62c8f5
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+       .globl  asm_print_str
+       .globl  asm_print_hex
+       .globl  asm_assert
+       .globl  do_panic
+
+/* Since the max decimal input number is 65536 */
+#define MAX_DEC_DIVISOR                10000
+/* The offset to add to get ascii for numerals '0 - 9' */
+#define ASCII_OFFSET_NUM       0x30
+
+#if ASM_ASSERTION
+.section .rodata.assert_str, "aS"
+assert_msg1:
+       .asciz "ASSERT: File "
+assert_msg2:
+       .asciz " Line "
+
+       /*
+        * This macro is intended to be used to print the
+        * line number in decimal. Used by asm_assert macro.
+        * The max number expected is 65536.
+        * In: x4 = the decimal to print.
+        * Clobber: x30, x0, x1, x2, x5, x6
+        */
+       .macro asm_print_line_dec
+       mov     x6, #10         /* Divide by 10 after every loop iteration */
+       mov     x5, #MAX_DEC_DIVISOR
+1:
+       udiv    x0, x4, x5              /* Get the quotient */
+       msub    x4, x0, x5, x4          /* Find the remainder */
+       add     x0, x0, #ASCII_OFFSET_NUM               /* Convert to ascii */
+       bl      plat_crash_console_putc
+       udiv    x5, x5, x6              /* Reduce divisor */
+       cbnz    x5, 1b
+       .endm
+
+
+/* ---------------------------------------------------------------------------
+ * Assertion support in assembly.
+ * The below function helps to support assertions in assembly where we do not
+ * have a C runtime stack. Arguments to the function are :
+ * x0 - File name
+ * x1 - Line no
+ * Clobber list : x30, x0, x1, x2, x3, x4, x5, x6.
+ * ---------------------------------------------------------------------------
+ */
+func asm_assert
+       mov     x5, x0
+       mov     x6, x1
+       /* Ensure the console is initialized */
+       bl      plat_crash_console_init
+       /* Check if the console is initialized */
+       cbz     x0, _assert_loop
+       /* The console is initialized */
+       adr     x4, assert_msg1
+       bl      asm_print_str
+       mov     x4, x5
+       bl      asm_print_str
+       adr     x4, assert_msg2
+       bl      asm_print_str
+       /* Check if line number higher than max permitted */
+       tst     x6, #~0xffff
+       b.ne    _assert_loop
+       mov     x4, x6
+       asm_print_line_dec
+_assert_loop:
+       b       _assert_loop
+#endif
+
+/*
+ * This function prints a string from address in x4.
+ * In: x4 = pointer to string.
+ * Clobber: x30, x0, x1, x2, x3
+ */
+func asm_print_str
+       mov     x3, x30
+1:
+       ldrb    w0, [x4], #0x1
+       cbz     x0, 2f
+       bl      plat_crash_console_putc
+       b       1b
+2:
+       ret     x3
+
+/*
+ * This function prints a hexadecimal number in x4.
+ * In: x4 = the hexadecimal to print.
+ * Clobber: x30, x0, x5, x1, x2, x3
+ */
+func asm_print_hex
+       mov     x3, x30
+       mov     x5, #64  /* No of bits to convert to ascii */
+1:
+       sub     x5, x5, #4
+       lsrv    x0, x4, x5
+       and     x0, x0, #0xf
+       cmp     x0, #0xA
+       b.lo    2f
+       /* Add by 0x27 in addition to ASCII_OFFSET_NUM
+        * to get ascii for characters 'a - f'.
+        */
+       add     x0, x0, #0x27
+2:
+       add     x0, x0, #ASCII_OFFSET_NUM
+       bl      plat_crash_console_putc
+       cbnz    x5, 1b
+       ret     x3
+
index a4d7f46450ab0f15637cb411fe6e16ffdb4848e7..41e760643ecaba09f5fcfde261cb9c8a0bac8035 100644 (file)
@@ -181,6 +181,11 @@ performed.
     BL3-1. This option defaults to the value of `DEBUG` - i.e. by default
     this is only enabled for a debug build of the firmware.
 
+*   `ASM_ASSERTION`: This flag determines whether the assertion checks within
+    assembly source files are enabled or not. This option defaults to the
+    value of `DEBUG` - i.e. by default this is only enabled for a debug
+    build of the firmware.
+
 ### Creating a Firmware Image Package
 
 FIPs are automatically created as part of the build instructions described in
diff --git a/include/common/assert_macros.S b/include/common/assert_macros.S
new file mode 100644 (file)
index 0000000..45d699b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+       /*
+        * Assembler macro to enable asm_assert. Use this macro wherever
+        * assert is required in assembly.
+        */
+#define ASM_ASSERT(_cc) \
+.ifndef .L_assert_filename ;\
+       .pushsection .rodata.str1.1, "aS" ;\
+       .L_assert_filename: ;\
+                       .string __FILE__ ;\
+       .popsection ;\
+.endif ;\
+       b._cc   1f ;\
+       adr     x0, .L_assert_filename ;\
+       mov     x1, __LINE__ ;\
+       b       asm_assert ;\
+1:
index 439ca28570ff103b0f6eb5e99b624b62c835df2d..f605bf408a76858c3495bf9231dd85896e8d93d9 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <assert_macros.S>
 
        .globl  get_afflvl_shift
        .globl  mpidr_mask_lower_afflvls
@@ -46,7 +47,6 @@
        .globl  enable_vfp
 #endif
 
-
 func get_afflvl_shift
        cmp     x0, #3
        cinc    x0, x0, eq
@@ -79,6 +79,10 @@ func smc
  * -----------------------------------------------------------------------
  */
 func zeromem16
+#if ASM_ASSERTION
+       tst     x0, #0xf
+       ASM_ASSERT(eq)
+#endif
        add     x2, x0, x1
 /* zero 16 bytes at a time */
 z_loop16:
@@ -105,6 +109,11 @@ z_end:     ret
  * --------------------------------------------------------------------------
  */
 func memcpy16
+#if ASM_ASSERTION
+       orr     x3, x0, x1
+       tst     x3, #0xf
+       ASM_ASSERT(eq)
+#endif
 /* copy 16 bytes at a time */
 m_loop16:
        cmp     x2, #16
@@ -145,7 +154,6 @@ func disable_mmu_icache_el3
        mov     x1, #(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT)
        b       do_disable_mmu
 
-
 /* ---------------------------------------------------------------------------
  * Enable the use of VFP at EL3
  * ---------------------------------------------------------------------------