Introduce crash console APIs for crash reporting
authorSoby Mathew <soby.mathew@arm.com>
Mon, 14 Jul 2014 15:57:23 +0000 (16:57 +0100)
committerSoby Mathew <soby.mathew@arm.com>
Mon, 28 Jul 2014 09:44:04 +0000 (10:44 +0100)
This patch introduces platform APIs to initialise and
print a character on a designated crash console.
For the FVP platform, PL011_UART0 is the designated
crash console. The platform porting guide is also updated
to document the new APIs.

Change-Id: I5e97d8762082e0c88c8c9bbb479353eac8f11a66

docs/porting-guide.md
include/common/asm_macros.S
include/plat/common/platform.h
plat/common/aarch64/platform_helpers.S
plat/fvp/aarch64/fvp_helpers.S

index 813d0be6c83ff73f2edbd00e9740221e5a2f1c26..9002a99922d33288d5351c4d7885f3c32940dff2 100644 (file)
@@ -15,6 +15,7 @@ Contents
     *   Boot Loader stage 3-1 (BL3-1)
     *   PSCI implementation (in BL3-1)
     *   Interrupt Management framework (in BL3-1)
+    *   Crash Reporting mechanism (in BL3-1)
 4.  C Library
 5.  Storage abstraction layer
 
@@ -1316,6 +1317,41 @@ interrupts as Group1 interrupts. It reads the group value corresponding to the
 interrupt id from the relevant _Interrupt Group Register_ (`GICD_IGROUPRn`). It
 uses the group value to determine the type of interrupt.
 
+3.5  Crash Reporting mechanism (in BL3-1)
+----------------------------------------------
+BL3-1 implements a crash reporting mechanism which prints the various registers
+of the CPU to enable quick crash analysis and debugging. It requires that a console
+is designated as the crash console by the platform which will used to print the
+register dump.
+
+The following functions must be implemented by the platform if it wants crash reporting
+mechanism in BL3-1. The functions are implemented in assembly so that they can be
+invoked without a C Runtime stack.
+
+### Function : plat_crash_console_init
+
+    Argument : void
+    Return   : int
+
+This API is used by the crash reporting mechanism to intialize the crash console.
+It should only use the general purpose registers x0 to x2 to do the initiaization
+and returns 1 on success.
+
+The FVP port designates the PL011_UART0 as the crash console and calls the
+console_core_init() to initialize the console.
+
+### Function : plat_crash_console_putc
+
+    Argument : int
+    Return   : int
+
+This API is used by the crash reporting mechanism to print a character on the
+designated crash console. It should only use general purpose registers x1 and
+x2 to do its work. The parameter and the return value are in general purpose
+register x0.
+
+The FVP port designates the PL011_UART0 as the crash console and calls the
+console_core_putc() to print the character on the console.
 
 4.  C Library
 -------------
index 2bccf58172213ed6f940897c51f7cac365734adb..238fa82a8efce215a11e65771d78fbeeafd98280 100644 (file)
@@ -162,3 +162,36 @@ wait_for_entrypoint:
        .macro get_up_stack _name, _size
        ldr x0, =(\_name + \_size)
        .endm
+
+       /*
+        * Helper macro to generate the best mov/movk combinations according
+        * the value to be moved. The 16 bits from '_shift' are tested and
+        * if not zero, they are moved into '_reg' without affecting
+        * other bits.
+        */
+       .macro _mov_imm16 _reg, _val, _shift
+               .if (\_val >> \_shift) & 0xffff
+                       .if (\_val & (1 << \_shift - 1))
+                               movk    \_reg, (\_val >> \_shift) & 0xffff, LSL \_shift
+                       .else
+                               mov     \_reg, \_val & (0xffff << \_shift)
+                       .endif
+               .endif
+       .endm
+
+       /*
+        * Helper macro to load arbitrary values into 32 or 64-bit registers
+        * which generates the best mov/movk combinations. Many base addresses
+        * are 64KB aligned the macro will eliminate updating bits 15:0 in
+        * that case
+        */
+       .macro mov_imm _reg, _val
+               .if (\_val) == 0
+                       mov     \_reg, #0
+               .else
+                       _mov_imm16      \_reg, (\_val), 0
+                       _mov_imm16      \_reg, (\_val), 16
+                       _mov_imm16      \_reg, (\_val), 32
+                       _mov_imm16      \_reg, (\_val), 48
+               .endif
+       .endm
index 1eeaac2784a2fbfc07c2b2b0b433597863e28589..76cc3c5ff468b03f209a4cb568dbf364d2060807 100644 (file)
@@ -72,6 +72,8 @@ uint32_t plat_interrupt_type_to_line(uint32_t type,
 unsigned int platform_get_core_pos(unsigned long mpidr);
 unsigned long platform_get_stack(unsigned long mpidr);
 void plat_report_exception(unsigned long);
+void plat_crash_console_init(unsigned long base_addr);
+int plat_crash_console_putc(int c);
 
 /*******************************************************************************
  * Mandatory BL1 functions
index f6ac13ebb03a97a4e8f6627a563233368665af89..5e2d1b114672fb521b4e1eb18de6c5e6f0976a28 100644 (file)
@@ -37,6 +37,8 @@
        .weak   platform_is_primary_cpu
        .weak   platform_check_mpidr
        .weak   plat_report_exception
+       .weak   plat_crash_console_init
+       .weak   plat_crash_console_putc
 
        /* -----------------------------------------------------
         *  int platform_get_core_pos(int mpidr);
@@ -79,3 +81,20 @@ func platform_check_mpidr
         */
 func plat_report_exception
        ret
+
+       /* -----------------------------------------------------
+        * Placeholder function which should be redefined by
+        * each platform.
+        * -----------------------------------------------------
+        */
+func plat_crash_console_init
+       mov     x0, #0
+       ret
+
+       /* -----------------------------------------------------
+        * Placeholder function which should be redefined by
+        * each platform.
+        * -----------------------------------------------------
+        */
+func plat_crash_console_putc
+       ret
index 3cd0b465d99cd4f691d9ffedd103da848c03467c..823588e46d8f90c6a12c1e3c94bc928c91ddecb4 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm_macros.S>
 #include <bl_common.h>
 #include <gic_v2.h>
+#include <pl011.h>
 #include "../drivers/pwrc/fvp_pwrc.h"
 #include "../fvp_def.h"
 
@@ -39,6 +40,8 @@
        .globl  plat_secondary_cold_boot_setup
        .globl  platform_mem_init
        .globl  plat_report_exception
+       .globl  plat_crash_console_init
+       .globl  plat_crash_console_putc
 
        .macro  fvp_choose_gicmmap  param1, param2, x_tmp, w_tmp, res
        ldr     \x_tmp, =VE_SYSREGS_BASE + V2M_SYS_ID
@@ -187,3 +190,30 @@ func plat_report_exception
        add     x1, x1, #V2M_SYS_LED
        str     w0, [x1]
        ret
+
+       /* Define a crash console for the plaform */
+#define FVP_CRASH_CONSOLE_BASE         PL011_UART0_BASE
+
+       /* ---------------------------------------------
+        * int plat_crash_console_init(void)
+        * Function to initialize the crash console
+        * without a C Runtime to print crash report.
+        * Clobber list : x0, x1, x2
+        * ---------------------------------------------
+        */
+func plat_crash_console_init
+       mov_imm x0, FVP_CRASH_CONSOLE_BASE
+       mov_imm x1, PL011_UART0_CLK_IN_HZ
+       mov_imm x2, PL011_BAUDRATE
+       b       console_core_init
+
+       /* ---------------------------------------------
+        * int plat_crash_console_putc(void)
+        * Function to print a character on the crash
+        * console without a C Runtime.
+        * Clobber list : x1, x2
+        * ---------------------------------------------
+        */
+func plat_crash_console_putc
+       mov_imm x1, FVP_CRASH_CONSOLE_BASE
+       b       console_core_putc