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
# The platform Makefile is free to override this value.
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
CREATE_KEYS := 1
......@@ -94,6 +98,10 @@ KEY_ALG := rsa
# Flag to enable new version of image loading
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_SWITCH := 0
......
......@@ -39,11 +39,11 @@ void bl32_plat_enable_mmu(uint32_t flags)
void bl31_plat_runtime_setup(void)
{
/*
* Finish the use of console driver in BL31 so that any runtime logs
* from BL31 will be suppressed.
*/
#if MULTI_CONSOLE_API
console_switch_state(CONSOLE_FLAG_RUNTIME);
#else
console_uninit();
#endif
}
#if !ENABLE_PLAT_COMPAT
......
......@@ -6,6 +6,7 @@
#include <arch.h>
#include <asm_macros.S>
#include <console.h>
#include <platform_def.h>
.weak plat_report_exception
......@@ -56,33 +57,78 @@ func plat_report_exception
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
/* -----------------------------------------------------
* Placeholder function which should be redefined by
* each platform.
* void plat_crash_console_putc(int character)
* Output through the normal console by default.
* -----------------------------------------------------
*/
func plat_crash_console_putc
ret
b console_putc
endfunc plat_crash_console_putc
/* -----------------------------------------------------
* Placeholder function which should be redefined by
* each platform.
* 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
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
ret
endfunc plat_crash_console_flush
#endif
/* -----------------------------------------------------
* Placeholder function which should be redefined by
......
......@@ -19,10 +19,9 @@
.globl plat_secondary_cold_boot_setup
.globl plat_report_exception
.globl platform_is_primary_cpu
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_my_core_pos
.globl plat_reset_handler
.globl plat_panic_handler
/*
* void plat_reset_handler(void);
......@@ -82,30 +81,17 @@ func platform_is_primary_cpu
endfunc platform_is_primary_cpu
/* --------------------------------------------------------------------
* 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
* void plat_panic_handler(void)
* Call system reset function on panic. Set up an emergency stack so we
* can run C functions (it only needs to last for a few calls until we
* reboot anyway).
* --------------------------------------------------------------------
*/
func plat_crash_console_init
mov_imm x0, PLAT_RK_UART_BASE
mov_imm x1, PLAT_RK_UART_CLOCK
mov_imm x2, PLAT_RK_UART_BAUDRATE
b console_core_init
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
func plat_panic_handler
msr spsel, #0
bl plat_set_my_stack
b rockchip_soc_soft_reset
endfunc plat_panic_handler
/* --------------------------------------------------------------------
* void platform_cpu_warmboot (void);
......
......@@ -8,12 +8,14 @@
#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <coreboot.h>
#include <debug.h>
#include <generic_delay_timer.h>
#include <mmio.h>
#include <plat_private.h>
#include <platform.h>
#include <platform_def.h>
#include <uart_16550.h>
/*******************************************************************************
* 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)
void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *plat_params_from_bl2)
{
console_init(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
PLAT_RK_UART_BAUDRATE);
static console_16550_t console;
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");
......@@ -82,9 +96,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
bl32_ep_info = *from_bl2->bl32_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:
* The below utility macro prints out relevant GIC
* and CCI registers whenever an unhandled
* 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
* ---------------------------------------------
*/
.macro plat_crash_print_regs
mov_imm x16, PLAT_RK_GICD_BASE
mov_imm x17, PLAT_RK_GICC_BASE
mov_imm x26, PLAT_RK_GICD_BASE
mov_imm x27, PLAT_RK_GICC_BASE
/* Check for GICv3 system register access */
mrs x7, id_aa64pfr0_el1
......@@ -72,19 +72,19 @@ print_gicv2:
/* Load the gicc reg list to x6 */
adr x6, gicc_regs
/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
ldr w8, [x17, #GICC_HPPIR]
ldr w9, [x17, #GICC_AHPPIR]
ldr w10, [x17, #GICC_CTLR]
ldr w8, [x27, #GICC_HPPIR]
ldr w9, [x27, #GICC_AHPPIR]
ldr w10, [x27, #GICC_CTLR]
/* Store to the crash buf and print to console */
bl str_in_crash_buf_print
print_gic_common:
/* Print the GICD_ISPENDR regs */
add x7, x16, #GICD_ISPENDR
add x7, x26, #GICD_ISPENDR
adr x4, gicd_pend_reg
bl asm_print_str
gicd_ispendr_loop:
sub x4, x7, x16
sub x4, x7, x26
cmp x4, #0x280
b.eq exit_print_gic_regs
bl asm_print_hex
......
......@@ -56,6 +56,7 @@ enum {
PARAM_POWEROFF,
PARAM_SUSPEND_GPIO,
PARAM_SUSPEND_APIO,
PARAM_COREBOOT_TABLE,
};
struct apio_info {
......@@ -89,4 +90,9 @@ struct bl31_apio_param {
struct apio_info apio;
};
struct bl31_u64_param {
struct bl31_plat_param h;
uint64_t value;
};
#endif /* __PLAT_PARAMS_H__ */
......@@ -8,6 +8,7 @@
#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <coreboot.h>
#include <debug.h>
#include <gpio.h>
#include <mmio.h>
......@@ -84,6 +85,12 @@ void params_early_setup(void *plat_param_from_bl2)
sizeof(struct bl31_apio_param));
suspend_apio = &param_apio.apio;
break;
#if COREBOOT
case PARAM_COREBOOT_TABLE:
coreboot_table_setup((void *)
((struct bl31_u64_param *)bl2_param)->value);
break;
#endif
default:
ERROR("not expected type found %ld\n",
bl2_param->type);
......
......@@ -49,6 +49,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/soc/soc.c
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_SKIP_OPTEE_S_EL1_INT_REGISTER))
......
......@@ -49,6 +49,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/ddr/ddr_rk3368.c \
ENABLE_PLAT_COMPAT := 0
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
......
......@@ -64,6 +64,9 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/dram/suspend.c
ENABLE_PLAT_COMPAT := 0
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
$(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