Commit c67b09bd authored by Soby Mathew's avatar Soby Mathew
Browse files

Introduce crash console APIs for crash reporting

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
parent 462c8350
......@@ -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
-------------
......
......@@ -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
......@@ -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
......
......@@ -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
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment