diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index f020ec9..10a6da7 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -1846,12 +1846,8 @@ The purpose of this function is allow the platform to perform any BL31 runtime setup just prior to BL31 exit during cold boot. The default weak -implementation of this function will invoke ``console_uninit()`` which will -suppress any BL31 runtime logs. - -In ARM Standard platforms, this function will initialize the BL31 runtime -console which will cause all further BL31 logs to be output to the -runtime console. +implementation of this function will invoke ``console_switch_state()`` to switch +console output to consoles marked for use in the ``runtime`` state. Function : bl31\_get\_next\_image\_info() [mandatory] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2619,14 +2615,20 @@ Crash Reporting mechanism (in BL31) ----------------------------------- -BL31 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 be used to -print the register dump. +NOTE: This section assumes that your platform is enabling the MULTI_CONSOLE_API +flag in its platform.mk. Not using this flag is deprecated for new platforms. -The following functions must be implemented by the platform if it wants crash -reporting mechanism in BL31. The functions are implemented in assembly so that -they can be invoked without a C Runtime stack. +BL31 implements a crash reporting mechanism which prints the various registers +of the CPU to enable quick crash analysis and debugging. By default, the +definitions in ``plat/common/aarch64/platform\_helpers.S`` will cause the crash +output to be routed over the normal console infrastructure and get printed on +consoles configured to output in crash state. ``console_set_scope()`` can be +used to control whether a console is used for crash output. + +In some cases (such as debugging very early crashes that happen before the +normal boot console can be set up), platforms may want to control crash output +more explicitly. For these, the following functions can be overridden by +platform code. They are executed outside of a C environment and without a stack. Function : plat\_crash\_console\_init ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2637,9 +2639,30 @@ Return : int This API is used by the crash reporting mechanism to initialize the crash -console. It must only use the general purpose registers x0 to x4 to do the +console. It must only use the general purpose registers x0 through x7 to do the initialization and returns 1 on success. +If you are trying to debug crashes before the console driver would normally get +registered, you can use this to register a driver from assembly with hardcoded +parameters. For example, you could register the 16550 driver like this: + +:: + + .section .data.crash_console /* Reserve space for console structure */ + crash_console: + .zero 6 * 8 /* console_16550_t has 6 8-byte words */ + func plat_crash_console_init + ldr x0, =YOUR_16550_BASE_ADDR + ldr x1, =YOUR_16550_SRCCLK_IN_HZ + ldr x2, =YOUR_16550_TARGET_BAUD_RATE + adrp x3, crash_console + add x3, x3, :lo12:crash_console + b console_16550_register /* tail call, returns 1 on success */ + endfunc plat_crash_console_init + +If you're trying to debug crashes in BL1, you can call the console_xxx_core_init +function exported by some console drivers from here. + Function : plat\_crash\_console\_putc ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2653,6 +2676,12 @@ x2 to do its work. The parameter and the return value are in general purpose register x0. +If you have registered a normal console driver in ``plat_crash_console_init``, +you can keep the default implementation here (which calls ``console_putc()``). + +If you're trying to debug crashes in BL1, you can call the console_xxx_core_putc +function exported by some console drivers from here. + Function : plat\_crash\_console\_flush ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2663,9 +2692,15 @@ This API is used by the crash reporting mechanism to force write of all buffered data on the designated crash console. It should only use general purpose -registers x0 and x1 to do its work. The return value is 0 on successful +registers x0 through x5 to do its work. The return value is 0 on successful completion; otherwise the return value is -1. +If you have registered a normal console driver in ``plat_crash_console_init``, +you can keep the default implementation here (which calls ``console_flush()``). + +If you're trying to debug crashes in BL1, you can call the console_xx_core_flush +function exported by some console drivers from here. + Build flags ----------- diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S index 797a936..8526752 100644 --- a/plat/common/aarch64/platform_helpers.S +++ b/plat/common/aarch64/platform_helpers.S @@ -6,6 +6,7 @@ #include #include +#include #include .weak plat_report_exception @@ -56,9 +57,63 @@ ret endfunc plat_report_exception +#if MULTI_CONSOLE_API /* ----------------------------------------------------- - * Placeholder function which should be redefined by - * each platform. + * int plat_crash_console_init(void) + * Use normal console by default. Switch it to crash + * mode so serial consoles become active again. + * NOTE: This default implementation will only work for + * crashes that occur after a normal console (marked + * valid for the crash state) has been registered with + * the console framework. To debug crashes that occur + * earlier, the platform has to override these functions + * with an implementation that initializes a console + * driver with hardcoded parameters. See + * docs/porting-guide.rst for more information. + * ----------------------------------------------------- + */ +func plat_crash_console_init +#if defined(IMAGE_BL1) + /* + * BL1 code can possibly crash so early that the data segment is not yet + * accessible. Don't risk undefined behavior by trying to run the normal + * console framework. Platforms that want to debug BL1 will need to + * override this with custom functions that can run from registers only. + */ + mov x0, #0 + ret +#else /* IMAGE_BL1 */ + mov x3, x30 + mov x0, #CONSOLE_FLAG_CRASH + bl console_switch_state + mov x0, #1 + ret x3 +#endif +endfunc plat_crash_console_init + + /* ----------------------------------------------------- + * void plat_crash_console_putc(int character) + * Output through the normal console by default. + * ----------------------------------------------------- + */ +func plat_crash_console_putc + b console_putc +endfunc plat_crash_console_putc + + /* ----------------------------------------------------- + * void plat_crash_console_flush(void) + * Flush normal console by default. + * ----------------------------------------------------- + */ +func plat_crash_console_flush + b console_flush +endfunc plat_crash_console_flush + +#else /* MULTI_CONSOLE_API */ + + /* ----------------------------------------------------- + * In the old API these are all no-op stubs that need to + * be overridden by the platform to be useful. * ----------------------------------------------------- */ func plat_crash_console_init @@ -66,23 +121,14 @@ ret endfunc plat_crash_console_init - /* ----------------------------------------------------- - * Placeholder function which should be redefined by - * each platform. - * ----------------------------------------------------- - */ func plat_crash_console_putc ret endfunc plat_crash_console_putc - /* ----------------------------------------------------- - * Placeholder function which should be redefined by - * each platform. - * ----------------------------------------------------- - */ func plat_crash_console_flush ret endfunc plat_crash_console_flush +#endif /* ----------------------------------------------------- * Placeholder function which should be redefined by