Unverified Commit 040f1e69 authored by davidcunado-arm's avatar davidcunado-arm Committed by GitHub
Browse files

Merge pull request #1193 from jwerner-chromium/JW_coreboot

New console API and coreboot support [v4]
parents d2184052 1c5f5031
Showing with 268 additions and 48 deletions
+268 -48
#
# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
COREBOOT := 0
$(eval $(call assert_boolean,COREBOOT))
$(eval $(call add_define,COREBOOT))
ifeq (${COREBOOT},1)
ifneq (${ARCH},aarch64)
$(error "coreboot only supports Trusted Firmware on AArch64.")
endif
BL31_SOURCES += $(addprefix lib/coreboot/, \
coreboot_table.c)
BL31_SOURCES += drivers/coreboot/cbmem_console/${ARCH}/cbmem_console.S
INCLUDES += -Iinclude/drivers/coreboot
endif # COREBOOT
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <cbmem_console.h>
#include <coreboot.h>
#include <debug.h>
#include <mmio.h>
#include <string.h>
#include <xlat_tables_v2.h>
/*
* Structures describing coreboot's in-memory descriptor tables. See
* <coreboot>/src/commonlib/include/commonlib/coreboot_tables.h for
* canonical implementation.
*/
typedef struct {
char signature[4];
uint32_t header_bytes;
uint32_t header_checksum;
uint32_t table_bytes;
uint32_t table_checksum;
uint32_t table_entries;
} cb_header_t;
typedef enum {
CB_TAG_SERIAL = 0xf,
CB_TAG_CBMEM_CONSOLE = 0x17,
} cb_tag_t;
typedef struct {
uint32_t tag;
uint32_t size;
union {
coreboot_serial_t serial;
uint64_t uint64;
};
} cb_entry_t;
coreboot_serial_t coreboot_serial;
/*
* The coreboot table is parsed before the MMU is enabled (i.e. with strongly
* ordered memory), so we cannot make unaligned accesses. The table entries
* immediately follow one another without padding, so nothing after the header
* is guaranteed to be naturally aligned. Therefore, we need to define safety
* functions that can read unaligned integers.
*/
static uint32_t read_le32(uint32_t *p)
{
uintptr_t addr = (uintptr_t)p;
return mmio_read_8(addr) |
mmio_read_8(addr + 1) << 8 |
mmio_read_8(addr + 2) << 16 |
mmio_read_8(addr + 3) << 24;
}
static uint64_t read_le64(uint64_t *p)
{
return read_le32((void *)p) | (uint64_t)read_le32((void *)p + 4) << 32;
}
static void expand_and_mmap(uintptr_t baseaddr, size_t size)
{
uintptr_t pageaddr = round_down(baseaddr, PAGE_SIZE);
size_t expanded = round_up(baseaddr - pageaddr + size, PAGE_SIZE);
mmap_add_region(pageaddr, pageaddr, expanded,
MT_MEMORY | MT_RW | MT_NS | MT_EXECUTE_NEVER);
}
static void setup_cbmem_console(uintptr_t baseaddr)
{
static console_cbmc_t console;
assert(!console.base); /* should only have one CBMEM console */
/* CBMEM console structure stores its size in first header field. */
uint32_t size = *(uint32_t *)baseaddr;
expand_and_mmap(baseaddr, size);
console_cbmc_register(baseaddr, &console);
console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME |
CONSOLE_FLAG_CRASH);
}
void coreboot_table_setup(void *base)
{
cb_header_t *header = base;
void *ptr;
int i;
if (strncmp(header->signature, "LBIO", 4)) {
ERROR("coreboot table signature corrupt!\n");
return;
}
ptr = base + header->header_bytes;
for (i = 0; i < header->table_entries; i++) {
cb_entry_t *entry = ptr;
if (ptr - base >= header->header_bytes + header->table_bytes) {
ERROR("coreboot table exceeds its bounds!\n");
break;
}
switch (read_le32(&entry->tag)) {
case CB_TAG_SERIAL:
memcpy(&coreboot_serial, &entry->serial,
sizeof(coreboot_serial));
break;
case CB_TAG_CBMEM_CONSOLE:
setup_cbmem_console(read_le64(&entry->uint64));
break;
default:
/* There are many tags TF doesn't need to care about. */
break;
}
ptr += read_le32(&entry->size);
}
}
...@@ -34,6 +34,10 @@ BL2_AT_EL3 := 0 ...@@ -34,6 +34,10 @@ BL2_AT_EL3 := 0
# The platform Makefile is free to override this value. # The platform Makefile is free to override this value.
COLD_BOOT_SINGLE_CPU := 0 COLD_BOOT_SINGLE_CPU := 0
# Flag to compile in coreboot support code. Exclude by default. The coreboot
# Makefile system will set this when compiling TF as part of a coreboot image.
COREBOOT := 0
# For Chain of Trust # For Chain of Trust
CREATE_KEYS := 1 CREATE_KEYS := 1
...@@ -94,6 +98,10 @@ KEY_ALG := rsa ...@@ -94,6 +98,10 @@ KEY_ALG := rsa
# Flag to enable new version of image loading # Flag to enable new version of image loading
LOAD_IMAGE_V2 := 0 LOAD_IMAGE_V2 := 0
# Use the new console API that allows registering more than one console instance
# at once. Use = instead of := to dynamically default to ERROR_DEPRECATED.
MULTI_CONSOLE_API = $(ERROR_DEPRECATED)
# NS timer register save and restore # NS timer register save and restore
NS_TIMER_SWITCH := 0 NS_TIMER_SWITCH := 0
......
...@@ -39,11 +39,11 @@ void bl32_plat_enable_mmu(uint32_t flags) ...@@ -39,11 +39,11 @@ void bl32_plat_enable_mmu(uint32_t flags)
void bl31_plat_runtime_setup(void) void bl31_plat_runtime_setup(void)
{ {
/* #if MULTI_CONSOLE_API
* Finish the use of console driver in BL31 so that any runtime logs console_switch_state(CONSOLE_FLAG_RUNTIME);
* from BL31 will be suppressed. #else
*/
console_uninit(); console_uninit();
#endif
} }
#if !ENABLE_PLAT_COMPAT #if !ENABLE_PLAT_COMPAT
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <arch.h> #include <arch.h>
#include <asm_macros.S> #include <asm_macros.S>
#include <console.h>
#include <platform_def.h> #include <platform_def.h>
.weak plat_report_exception .weak plat_report_exception
...@@ -56,33 +57,78 @@ func plat_report_exception ...@@ -56,33 +57,78 @@ func plat_report_exception
ret ret
endfunc plat_report_exception endfunc plat_report_exception
#if MULTI_CONSOLE_API
/* ----------------------------------------------------- /* -----------------------------------------------------
* Placeholder function which should be redefined by * int plat_crash_console_init(void)
* each platform. * 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 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 mov x0, #0
ret 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 endfunc plat_crash_console_init
/* ----------------------------------------------------- /* -----------------------------------------------------
* Placeholder function which should be redefined by * void plat_crash_console_putc(int character)
* each platform. * Output through the normal console by default.
* ----------------------------------------------------- * -----------------------------------------------------
*/ */
func plat_crash_console_putc func plat_crash_console_putc
ret b console_putc
endfunc plat_crash_console_putc endfunc plat_crash_console_putc
/* ----------------------------------------------------- /* -----------------------------------------------------
* Placeholder function which should be redefined by * void plat_crash_console_flush(void)
* each platform. * 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
mov x0, #0
ret
endfunc plat_crash_console_init
func plat_crash_console_putc
ret
endfunc plat_crash_console_putc
func plat_crash_console_flush func plat_crash_console_flush
ret ret
endfunc plat_crash_console_flush endfunc plat_crash_console_flush
#endif
/* ----------------------------------------------------- /* -----------------------------------------------------
* Placeholder function which should be redefined by * Placeholder function which should be redefined by
......
...@@ -19,10 +19,9 @@ ...@@ -19,10 +19,9 @@
.globl plat_secondary_cold_boot_setup .globl plat_secondary_cold_boot_setup
.globl plat_report_exception .globl plat_report_exception
.globl platform_is_primary_cpu .globl platform_is_primary_cpu
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_my_core_pos .globl plat_my_core_pos
.globl plat_reset_handler .globl plat_reset_handler
.globl plat_panic_handler
/* /*
* void plat_reset_handler(void); * void plat_reset_handler(void);
...@@ -82,30 +81,17 @@ func platform_is_primary_cpu ...@@ -82,30 +81,17 @@ func platform_is_primary_cpu
endfunc platform_is_primary_cpu endfunc platform_is_primary_cpu
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* int plat_crash_console_init(void) * void plat_panic_handler(void)
* Function to initialize the crash console * Call system reset function on panic. Set up an emergency stack so we
* without a C Runtime to print crash report. * can run C functions (it only needs to last for a few calls until we
* Clobber list : x0, x1, x2 * reboot anyway).
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
func plat_crash_console_init func plat_panic_handler
mov_imm x0, PLAT_RK_UART_BASE msr spsel, #0
mov_imm x1, PLAT_RK_UART_CLOCK bl plat_set_my_stack
mov_imm x2, PLAT_RK_UART_BAUDRATE b rockchip_soc_soft_reset
b console_core_init endfunc plat_panic_handler
endfunc plat_crash_console_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, PLAT_RK_UART_BASE
b console_core_putc
endfunc plat_crash_console_putc
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* void platform_cpu_warmboot (void); * void platform_cpu_warmboot (void);
......
...@@ -8,12 +8,14 @@ ...@@ -8,12 +8,14 @@
#include <assert.h> #include <assert.h>
#include <bl_common.h> #include <bl_common.h>
#include <console.h> #include <console.h>
#include <coreboot.h>
#include <debug.h> #include <debug.h>
#include <generic_delay_timer.h> #include <generic_delay_timer.h>
#include <mmio.h> #include <mmio.h>
#include <plat_private.h> #include <plat_private.h>
#include <platform.h> #include <platform.h>
#include <platform_def.h> #include <platform_def.h>
#include <uart_16550.h>
/******************************************************************************* /*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout * Declarations of linker defined symbols which will help us find the layout
...@@ -69,8 +71,20 @@ void params_early_setup(void *plat_param_from_bl2) ...@@ -69,8 +71,20 @@ void params_early_setup(void *plat_param_from_bl2)
void bl31_early_platform_setup(bl31_params_t *from_bl2, void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *plat_params_from_bl2) void *plat_params_from_bl2)
{ {
console_init(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK, static console_16550_t console;
PLAT_RK_UART_BAUDRATE);
params_early_setup(plat_params_from_bl2);
#if COREBOOT
if (coreboot_serial.type)
console_16550_register(coreboot_serial.baseaddr,
coreboot_serial.input_hertz,
coreboot_serial.baud,
&console);
#else
console_16550_register(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
PLAT_RK_UART_BAUDRATE, &console);
#endif
VERBOSE("bl31_setup\n"); VERBOSE("bl31_setup\n");
...@@ -82,9 +96,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, ...@@ -82,9 +96,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
bl32_ep_info = *from_bl2->bl32_ep_info; bl32_ep_info = *from_bl2->bl32_ep_info;
bl33_ep_info = *from_bl2->bl33_ep_info; bl33_ep_info = *from_bl2->bl33_ep_info;
/* there may have some board sepcific message need to initialize */
params_early_setup(plat_params_from_bl2);
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -38,14 +38,14 @@ cci_iface_regs: ...@@ -38,14 +38,14 @@ cci_iface_regs:
* The below utility macro prints out relevant GIC * The below utility macro prints out relevant GIC
* and CCI registers whenever an unhandled * and CCI registers whenever an unhandled
* exception is taken in BL31. * exception is taken in BL31.
* Expects: GICD base in x16, GICC base in x17 * Expects: GICD base in x26, GICC base in x27
* Clobbers: x0 - x10, sp * Clobbers: x0 - x10, sp
* --------------------------------------------- * ---------------------------------------------
*/ */
.macro plat_crash_print_regs .macro plat_crash_print_regs
mov_imm x16, PLAT_RK_GICD_BASE mov_imm x26, PLAT_RK_GICD_BASE
mov_imm x17, PLAT_RK_GICC_BASE mov_imm x27, PLAT_RK_GICC_BASE
/* Check for GICv3 system register access */ /* Check for GICv3 system register access */
mrs x7, id_aa64pfr0_el1 mrs x7, id_aa64pfr0_el1
...@@ -72,19 +72,19 @@ print_gicv2: ...@@ -72,19 +72,19 @@ print_gicv2:
/* Load the gicc reg list to x6 */ /* Load the gicc reg list to x6 */
adr x6, gicc_regs adr x6, gicc_regs
/* Load the gicc regs to gp regs used by str_in_crash_buf_print */ /* Load the gicc regs to gp regs used by str_in_crash_buf_print */
ldr w8, [x17, #GICC_HPPIR] ldr w8, [x27, #GICC_HPPIR]
ldr w9, [x17, #GICC_AHPPIR] ldr w9, [x27, #GICC_AHPPIR]
ldr w10, [x17, #GICC_CTLR] ldr w10, [x27, #GICC_CTLR]
/* Store to the crash buf and print to console */ /* Store to the crash buf and print to console */
bl str_in_crash_buf_print bl str_in_crash_buf_print
print_gic_common: print_gic_common:
/* Print the GICD_ISPENDR regs */ /* Print the GICD_ISPENDR regs */
add x7, x16, #GICD_ISPENDR add x7, x26, #GICD_ISPENDR
adr x4, gicd_pend_reg adr x4, gicd_pend_reg
bl asm_print_str bl asm_print_str
gicd_ispendr_loop: gicd_ispendr_loop:
sub x4, x7, x16 sub x4, x7, x26
cmp x4, #0x280 cmp x4, #0x280
b.eq exit_print_gic_regs b.eq exit_print_gic_regs
bl asm_print_hex bl asm_print_hex
......
...@@ -56,6 +56,7 @@ enum { ...@@ -56,6 +56,7 @@ enum {
PARAM_POWEROFF, PARAM_POWEROFF,
PARAM_SUSPEND_GPIO, PARAM_SUSPEND_GPIO,
PARAM_SUSPEND_APIO, PARAM_SUSPEND_APIO,
PARAM_COREBOOT_TABLE,
}; };
struct apio_info { struct apio_info {
...@@ -89,4 +90,9 @@ struct bl31_apio_param { ...@@ -89,4 +90,9 @@ struct bl31_apio_param {
struct apio_info apio; struct apio_info apio;
}; };
struct bl31_u64_param {
struct bl31_plat_param h;
uint64_t value;
};
#endif /* __PLAT_PARAMS_H__ */ #endif /* __PLAT_PARAMS_H__ */
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <assert.h> #include <assert.h>
#include <bl_common.h> #include <bl_common.h>
#include <console.h> #include <console.h>
#include <coreboot.h>
#include <debug.h> #include <debug.h>
#include <gpio.h> #include <gpio.h>
#include <mmio.h> #include <mmio.h>
...@@ -84,6 +85,12 @@ void params_early_setup(void *plat_param_from_bl2) ...@@ -84,6 +85,12 @@ void params_early_setup(void *plat_param_from_bl2)
sizeof(struct bl31_apio_param)); sizeof(struct bl31_apio_param));
suspend_apio = &param_apio.apio; suspend_apio = &param_apio.apio;
break; break;
#if COREBOOT
case PARAM_COREBOOT_TABLE:
coreboot_table_setup((void *)
((struct bl31_u64_param *)bl2_param)->value);
break;
#endif
default: default:
ERROR("not expected type found %ld\n", ERROR("not expected type found %ld\n",
bl2_param->type); bl2_param->type);
......
...@@ -49,6 +49,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ...@@ -49,6 +49,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/soc/soc.c ${RK_PLAT_SOC}/drivers/soc/soc.c
ENABLE_PLAT_COMPAT := 0 ENABLE_PLAT_COMPAT := 0
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER)) $(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
......
...@@ -49,6 +49,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ...@@ -49,6 +49,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/ddr/ddr_rk3368.c \ ${RK_PLAT_SOC}/drivers/ddr/ddr_rk3368.c \
ENABLE_PLAT_COMPAT := 0 ENABLE_PLAT_COMPAT := 0
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
......
...@@ -64,6 +64,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ...@@ -64,6 +64,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/dram/suspend.c ${RK_PLAT_SOC}/drivers/dram/suspend.c
ENABLE_PLAT_COMPAT := 0 ENABLE_PLAT_COMPAT := 0
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
......
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