summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/coreboot/coreboot.mk24
-rw-r--r--lib/coreboot/coreboot_table.c123
-rw-r--r--lib/cpus/aarch32/cortex_a72.S2
-rw-r--r--lib/cpus/aarch32/cpu_helpers.S4
-rw-r--r--lib/cpus/aarch64/cpu_helpers.S6
-rw-r--r--lib/cpus/errata_report.c2
6 files changed, 155 insertions, 6 deletions
diff --git a/lib/coreboot/coreboot.mk b/lib/coreboot/coreboot.mk
new file mode 100644
index 00000000..bbaa3329
--- /dev/null
+++ b/lib/coreboot/coreboot.mk
@@ -0,0 +1,24 @@
+#
+# 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
diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c
new file mode 100644
index 00000000..64f8879e
--- /dev/null
+++ b/lib/coreboot/coreboot_table.c
@@ -0,0 +1,123 @@
+/*
+ * 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);
+ }
+}
diff --git a/lib/cpus/aarch32/cortex_a72.S b/lib/cpus/aarch32/cortex_a72.S
index 878e6b19..56e91f5c 100644
--- a/lib/cpus/aarch32/cortex_a72.S
+++ b/lib/cpus/aarch32/cortex_a72.S
@@ -113,7 +113,7 @@ func cortex_a72_reset_func
orr64_imm r0, r1, CORTEX_A72_ECTLR_SMP_BIT
stcopr16 r0, r1, CORTEX_A72_ECTLR
isb
- bx lr
+ bx r5
endfunc cortex_a72_reset_func
/* ----------------------------------------------------
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index bfdc1e4f..72e42c67 100644
--- a/lib/cpus/aarch32/cpu_helpers.S
+++ b/lib/cpus/aarch32/cpu_helpers.S
@@ -10,7 +10,7 @@
#include <cpu_data.h>
#include <cpu_macros.S>
-#if defined(IMAGE_BL1) || defined(IMAGE_BL32)
+#if defined(IMAGE_BL1) || defined(IMAGE_BL32) || (defined(IMAGE_BL2) && BL2_AT_EL3)
/*
* The reset handler common to all platforms. After a matching
* cpu_ops structure entry is found, the correponding reset_handler
@@ -42,7 +42,7 @@ func reset_handler
bx lr
endfunc reset_handler
-#endif /* IMAGE_BL1 || IMAGE_BL32 */
+#endif
#ifdef IMAGE_BL32 /* The power down core and cluster is needed only in BL32 */
/*
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 23845534..ae1c3c25 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -7,7 +7,7 @@
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
-#ifdef IMAGE_BL31
+#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
#include <cpu_data.h>
#endif
#include <cpu_macros.S>
@@ -15,7 +15,7 @@
#include <errata_report.h>
/* Reset fn is needed in BL at reset vector */
-#if defined(IMAGE_BL1) || defined(IMAGE_BL31)
+#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
/*
* The reset handler common to all platforms. After a matching
* cpu_ops structure entry is found, the correponding reset_handler
@@ -47,7 +47,7 @@ func reset_handler
ret
endfunc reset_handler
-#endif /* IMAGE_BL1 || IMAGE_BL31 */
+#endif
#ifdef IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */
/*
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index c0306791..c679336c 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -20,6 +20,8 @@
# define BL_STRING "BL31"
#elif defined(AARCH32) && defined(IMAGE_BL32)
# define BL_STRING "BL32"
+#elif defined(IMAGE_BL2) && BL2_AT_EL3
+# define BL_STRING "BL2"
#else
# error This image should not be printing errata status
#endif