ARM bootblock approach
This lays out the groundwork for using a proper bootblock on ARM. Currently we bypass the bootblock entirely and go straight to romstage. However we want to utilize CBFS to maximize flexibility of placing code without relying on a lot of magic numbers which will break depending on the SoC in use. Change-Id: I9cc2a8191d2db38b27b6363ba673e5a360de9684 Signed-off-by: Stefan Reinauer <reinauer@google.com> Signed-off-by: David Hendricks <dhendrix@chromium.org> Reviewed-on: http://review.coreboot.org/2118 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
09574d5c3c
commit
3d7344a7a1
|
@ -149,7 +149,6 @@ CFLAGS += \
|
||||||
# For various headers imported from Linux
|
# For various headers imported from Linux
|
||||||
CFLAGS += -D__LINUX_ARM_ARCH__=7
|
CFLAGS += -D__LINUX_ARM_ARCH__=7
|
||||||
|
|
||||||
crt0s = $(src)/arch/armv7/bootblock.inc
|
|
||||||
ldscripts =
|
ldscripts =
|
||||||
ldscripts += $(src)/arch/armv7/romstage.ld
|
ldscripts += $(src)/arch/armv7/romstage.ld
|
||||||
|
|
||||||
|
@ -223,19 +222,14 @@ $(obj)/coreboot.pre: $(objcbfs)/romstage_xip.elf $(obj)/coreboot.pre1 $(CBFSTOOL
|
||||||
################################################################################
|
################################################################################
|
||||||
# Build the bootblock
|
# Build the bootblock
|
||||||
|
|
||||||
#bootblock_lds = $(src)/arch/armv7/ldscript_fallback_cbfs.lb
|
bootblock_lds = $(src)/arch/armv7/bootblock.lds
|
||||||
bootblock_lds = $(src)/arch/armv7/lib/id.lds
|
bootblock_lds += $(src)/arch/armv7/lib/id.lds
|
||||||
#bootblock_lds = $(src)/arch/armv7/romstage.ld
|
|
||||||
bootblock_lds += $(chipset_bootblock_lds)
|
bootblock_lds += $(chipset_bootblock_lds)
|
||||||
|
|
||||||
|
bootblock_inc += $(src)/arch/armv7/bootblock.inc
|
||||||
bootblock_inc += $(src)/arch/armv7/lib/id.inc
|
bootblock_inc += $(src)/arch/armv7/lib/id.inc
|
||||||
bootblock_inc += $(chipset_bootblock_inc)
|
bootblock_inc += $(chipset_bootblock_inc)
|
||||||
|
bootblock_inc += $(objgenerated)/bootblock.inc
|
||||||
# FIXME: CONFIG_NEON or something similar for ARM?
|
|
||||||
#ifeq ($(CONFIG_SSE),y)
|
|
||||||
#bootblock_inc += $(src)/cpu/x86/sse_enable.inc
|
|
||||||
#endif
|
|
||||||
#bootblock_inc += $(objgenerated)/bootblock.inc
|
|
||||||
|
|
||||||
$(objgenerated)/bootblock.ld: $$(bootblock_lds) $(obj)/ldoptions
|
$(objgenerated)/bootblock.ld: $$(bootblock_lds) $(obj)/ldoptions
|
||||||
@printf " GEN $(subst $(obj)/,,$(@))\n"
|
@printf " GEN $(subst $(obj)/,,$(@))\n"
|
||||||
|
@ -253,11 +247,11 @@ $(objgenerated)/bootblock.s: $(objgenerated)/bootblock_inc.S $(obj)/config.h $(o
|
||||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||||
$(CC) -MMD -x assembler-with-cpp -E -I$(src)/include -I$(src)/arch/armv7/include -I$(obj) -include $(obj)/build.h -include $(obj)/config.h -I. -I$(src) $< -o $@
|
$(CC) -MMD -x assembler-with-cpp -E -I$(src)/include -I$(src)/arch/armv7/include -I$(obj) -include $(obj)/build.h -include $(obj)/config.h -I. -I$(src) $< -o $@
|
||||||
|
|
||||||
#$(objgenerated)/bootblock.inc: $(src)/arch/armv7/init/$(subst ",,$(CONFIG_BOOTBLOCK_SOURCE)) $(objutil)/romcc/romcc $(OPTION_TABLE_H)
|
$(objgenerated)/bootblock.inc: $(src)/arch/armv7/$(subst ",,$(CONFIG_BOOTBLOCK_SOURCE)) $(OPTION_TABLE_H)
|
||||||
# @printf " ROMCC $(subst $(obj)/,,$(@))\n"
|
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||||
# $(CC) $(INCLUDES) -MM -MT$(objgenerated)/bootblock.inc \
|
$(CC) $(INCLUDES) -MM -MT$(objgenerated)/bootblock.inc \
|
||||||
# $< > $(objgenerated)/bootblock.inc.d
|
$< > $(objgenerated)/bootblock.inc.d
|
||||||
# $(ROMCC) -c -S $(bootblock_romccflags) $(ROMCCFLAGS) -I. $(INCLUDES) $< -o $@
|
$(CC) -c -S $(CFLAGS) -I. $(INCLUDES) $< -o $@
|
||||||
|
|
||||||
$(objcbfs)/bootblock.debug: $(objgenerated)/bootblock.o $(objgenerated)/bootblock.ld
|
$(objcbfs)/bootblock.debug: $(objgenerated)/bootblock.o $(objgenerated)/bootblock.ld
|
||||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||||
|
|
|
@ -36,8 +36,7 @@ _bl1:
|
||||||
* on ARM, which is 8KB in size and it is prepended to the
|
* on ARM, which is 8KB in size and it is prepended to the
|
||||||
* reset vector
|
* reset vector
|
||||||
*/
|
*/
|
||||||
/* this comes a bit later. */
|
.skip 8192
|
||||||
// .skip 8192
|
|
||||||
|
|
||||||
.globl _start
|
.globl _start
|
||||||
_start: b reset
|
_start: b reset
|
||||||
|
@ -81,10 +80,6 @@ call_bootblock:
|
||||||
* Thumb. However, "b" will not and GCC may attempt to create a
|
* Thumb. However, "b" will not and GCC may attempt to create a
|
||||||
* wrapper which is currently broken.
|
* wrapper which is currently broken.
|
||||||
*/
|
*/
|
||||||
/* for now call board_init_f; change later. We're trying to get as much into ToT as
|
|
||||||
* we can
|
|
||||||
*/
|
|
||||||
bl board_init_f
|
|
||||||
bl main
|
bl main
|
||||||
|
|
||||||
wait_for_interrupt:
|
wait_for_interrupt:
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Advanced Micro Devices, Inc.
|
||||||
|
* Copyright (C) 2008-2010 coresystems GmbH
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* We use ELF as output format. So that we can debug the code in some form. */
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
|
||||||
|
TARGET(binary)
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
ROMLOC = 0x2023400 - 8192;
|
||||||
|
|
||||||
|
/* This section might be better named .setup */
|
||||||
|
.rom ROMLOC : {
|
||||||
|
_rom = .;
|
||||||
|
*(.text);
|
||||||
|
*(.text.*);
|
||||||
|
*(.rom.text);
|
||||||
|
*(.rom.data);
|
||||||
|
*(.rom.data.*);
|
||||||
|
*(.rodata.*);
|
||||||
|
_erom = .;
|
||||||
|
} = 0xff
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.comment)
|
||||||
|
*(.note)
|
||||||
|
*(.comment.*)
|
||||||
|
*(.note.*)
|
||||||
|
*(.ARM.*)
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,33 +19,31 @@
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <bootblock_common.h>
|
#include <bootblock_common.h>
|
||||||
|
#include <arch/cbfs.h>
|
||||||
|
#include <arch/hlt.h>
|
||||||
|
|
||||||
|
static int boot_cpu(void)
|
||||||
#include "../../lib/uart8250.c"
|
{
|
||||||
#include "lib/div.c"
|
/*
|
||||||
|
* FIXME: This is a stub for now. All non-boot CPUs should be
|
||||||
struct uart8250 uart = {
|
* waiting for an interrupt. We could move the chunk of assembly
|
||||||
115200
|
* which puts them to sleep in here...
|
||||||
};
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void main(unsigned long bist)
|
void main(unsigned long bist)
|
||||||
{
|
{
|
||||||
init_uart8250(CONFIG_TTYS0_BASE, &uart);
|
|
||||||
uart8250_tx_byte(CONFIG_TTYS0_BASE, '@');
|
|
||||||
|
|
||||||
if (boot_cpu()) {
|
|
||||||
bootblock_cpu_init();
|
|
||||||
bootblock_northbridge_init();
|
|
||||||
bootblock_southbridge_init();
|
|
||||||
}
|
|
||||||
const char *target1 = "fallback/romstage";
|
const char *target1 = "fallback/romstage";
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
|
|
||||||
|
if (boot_cpu()) {
|
||||||
|
bootblock_mainboard_init();
|
||||||
|
}
|
||||||
|
|
||||||
entry = findstage(target1);
|
entry = findstage(target1);
|
||||||
if (entry) call(entry, bist);
|
if (entry) call(entry);
|
||||||
|
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_ARCH_CBFS__
|
||||||
|
#define __INCLUDE_ARCH_CBFS__
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <types.h>
|
||||||
|
#include <cbfs_core.h>
|
||||||
|
#include <arch/byteorder.h>
|
||||||
|
#include <arch/cbfs.h>
|
||||||
|
|
||||||
|
static int cbfs_check_magic(struct cbfs_file *file)
|
||||||
|
{
|
||||||
|
return !strcmp(file->magic, CBFS_FILE_MAGIC) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long findstage(const char* target)
|
||||||
|
{
|
||||||
|
unsigned long offset, align;
|
||||||
|
/* FIXME: magic offsets */
|
||||||
|
struct cbfs_header *header = (struct cbfs_header *)(0x02023400 + 0x40);
|
||||||
|
// if (ntohl(header->magic) != CBFS_HEADER_MAGIC)
|
||||||
|
// printk(BIOS_ERR, "ERROR: No valid CBFS header found!\n");
|
||||||
|
|
||||||
|
offset = ntohl(header->offset);
|
||||||
|
align = ntohl(header->align);
|
||||||
|
while(1) {
|
||||||
|
struct cbfs_file *file;
|
||||||
|
file = (struct cbfs_file *)(offset + CONFIG_ROMSTAGE_BASE);
|
||||||
|
if (!cbfs_check_magic(file))
|
||||||
|
return 0;
|
||||||
|
if (!strcmp(CBFS_NAME(file), target))
|
||||||
|
return (unsigned long)CBFS_SUBHEADER(file);
|
||||||
|
int flen = ntohl(file->len);
|
||||||
|
int foffset = ntohl(file->offset);
|
||||||
|
unsigned long oldoffset = offset;
|
||||||
|
offset = ALIGN(offset + foffset + flen, align);
|
||||||
|
if (offset <= oldoffset)
|
||||||
|
return 0;
|
||||||
|
if (offset < CONFIG_ROMSTAGE_BASE + ntohl(header->romsize));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void call(unsigned long addr)
|
||||||
|
{
|
||||||
|
void (*doit)(void) = (void *)addr;
|
||||||
|
doit();
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -1,69 +1,14 @@
|
||||||
#include <types.h>
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <arch/byteorder.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define boot_cpu(x) 1
|
|
||||||
|
|
||||||
#ifdef CONFIG_BOOTBLOCK_CPU_INIT
|
#ifdef CONFIG_BOOTBLOCK_CPU_INIT
|
||||||
#include CONFIG_BOOTBLOCK_CPU_INIT
|
#include CONFIG_BOOTBLOCK_CPU_INIT
|
||||||
#else
|
|
||||||
static void bootblock_cpu_init(void) { }
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
|
|
||||||
#include CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
|
|
||||||
#else
|
|
||||||
static void bootblock_northbridge_init(void) { }
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
|
|
||||||
#include CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
|
|
||||||
#else
|
|
||||||
static void bootblock_southbridge_init(void) { }
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int cbfs_check_magic(struct cbfs_file *file)
|
#ifdef CONFIG_BOOTBLOCK_MAINBOARD_INIT
|
||||||
|
#include CONFIG_BOOTBLOCK_MAINBOARD_INIT
|
||||||
|
#else
|
||||||
|
static void bootblock_mainboard_init(void)
|
||||||
{
|
{
|
||||||
return !strcmp(file->magic, CBFS_FILE_MAGIC) ? 1 : 0;
|
#ifdef CONFIG_BOOTBLOCK_CPU_INIT
|
||||||
}
|
bootblock_cpu_init();
|
||||||
|
#endif
|
||||||
static unsigned long findstage(const char* target)
|
|
||||||
{
|
|
||||||
unsigned long offset;
|
|
||||||
|
|
||||||
void *ptr = (void *)*((unsigned long *) CBFS_HEADPTR_ADDR);
|
|
||||||
struct cbfs_header *header = (struct cbfs_header *) ptr;
|
|
||||||
// if (ntohl(header->magic) != CBFS_HEADER_MAGIC)
|
|
||||||
// printk(BIOS_ERR, "ERROR: No valid CBFS header found!\n");
|
|
||||||
|
|
||||||
offset = 0 - ntohl(header->romsize) + ntohl(header->offset);
|
|
||||||
int align = ntohl(header->align);
|
|
||||||
while(1) {
|
|
||||||
struct cbfs_file *file = (struct cbfs_file *) offset;
|
|
||||||
if (!cbfs_check_magic(file))
|
|
||||||
return 0;
|
|
||||||
if (!strcmp(CBFS_NAME(file), target))
|
|
||||||
return (unsigned long)CBFS_SUBHEADER(file);
|
|
||||||
int flen = ntohl(file->len);
|
|
||||||
int foffset = ntohl(file->offset);
|
|
||||||
unsigned long oldoffset = offset;
|
|
||||||
offset = ALIGN(offset + foffset + flen, align);
|
|
||||||
if (offset <= oldoffset)
|
|
||||||
return 0;
|
|
||||||
if (offset < 0xFFFFFFFF - ntohl(header->romsize))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void call(unsigned long addr, unsigned long bist)
|
|
||||||
{
|
|
||||||
asm volatile ("mov r0, %1\nbx %0\n" : : "r" (addr), "r" (bist));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hlt(void)
|
|
||||||
{
|
|
||||||
/* is there such a thing as hlt on ARM? */
|
|
||||||
// asm volatile ("1:\n\thlt\n\tjmp 1b\n\t");
|
|
||||||
asm volatile ("1:\nb 1b\n\t");
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = (0x100000000 - CONFIG_ID_SECTION_OFFSET) - (__id_end - __id_start);
|
/* FIXME: determine a sensible location... */
|
||||||
|
. = (0x2024000) - (__id_end - __id_start);
|
||||||
.id (.): {
|
.id (.): {
|
||||||
*(.id)
|
*(.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
config BOOTBLOCK_OFFSET
|
|
||||||
hex "Bootblock offset"
|
|
||||||
default 0x3400
|
|
||||||
help
|
|
||||||
This is where the Coreboot bootblock resides. For Exynos5250,
|
|
||||||
this value is pre-determined by the vendor-provided BL1.
|
|
||||||
|
|
||||||
config EXYNOS_ACE_SHA
|
config EXYNOS_ACE_SHA
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
Loading…
Reference in New Issue