the following patch was just integrated into master:
commit 7905f9254ebc865cbd78e4ade3e5d795957be4a6
Author: Vladimir Serbinenko <phcoder(a)gmail.com>
Date: Mon Nov 25 11:20:20 2013 +0100
qemu: cirrus native video init
Recent commit proposal by Ron Minnich proposes to move to native gfx init for
qemu. Unfortunately we didn't have native init for default qemu video (cirrus)
Here is one extracted from GRUB one which I wrote couple of years ago.
Change-Id: Icb89cf918ef5d276bcc703c48c568e7b9c1be756
Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com>
Reviewed-on: http://review.coreboot.org/4270
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich(a)gmail.com>
See http://review.coreboot.org/4270 for details.
-gerrit
the following patch was just integrated into master:
commit c6f6be0929ccef4c551f9640300972e7bc8600ec
Author: Vladimir Serbinenko <phcoder(a)gmail.com>
Date: Tue Nov 12 22:32:08 2013 +0100
Support for nehalem northbridge
Including raminit
Change-Id: If1dd3855181481b8b928adf0fdb40b29d15897db
Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com>
Reviewed-on: http://review.coreboot.org/4044
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
See http://review.coreboot.org/4044 for details.
-gerrit
the following patch was just integrated into master:
commit 888d559b0373cb956314b8087439378c14a16918
Author: Vladimir Serbinenko <phcoder(a)gmail.com>
Date: Wed Nov 13 17:53:38 2013 +0100
Support for Ibexpeak southbridge
Part of X201 port.
Change-Id: If17d707004aba9f08459dbd8f3a146fa3c076aa9
Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com>
Reviewed-on: http://review.coreboot.org/4052
Reviewed-by: Ronald G. Minnich <rminnich(a)gmail.com>
Tested-by: build bot (Jenkins)
See http://review.coreboot.org/4052 for details.
-gerrit
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4271
-gerrit
commit e1c6b038a5a2fed77d0f64ea04747c468c6dc8da
Author: Ronald G. Minnich <rminnich(a)google.com>
Date: Mon Nov 25 09:44:16 2013 -0800
Add initial aarch64 support
This is for the aarch64 architecture. A followon patch will be for the
ARM Ltd. v8 cpu implementation, followed by a mainboard.
This builds but will require the two follow on patches and my recently submitted
cbfstool patch if you wish to see what it looks like.
It is missing critical support for functions such as memcpy, etc. but my goal
is to get an early view of where it is going to the community.
The initial test will be getting it to halt correctly.
Change-Id: I2f5e727e65cd7ffc8bba3eb1491011cf179af905
Signed-off-by: Ronald G. Minnich <rminnich(a)google.com>
---
src/arch/aarch64/Kconfig | 29 +++
src/arch/aarch64/Makefile.inc | 266 ++++++++++++++++++++++++
src/arch/aarch64/boot.c | 27 +++
src/arch/aarch64/bootblock.inc | 66 ++++++
src/arch/aarch64/bootblock.lds | 55 +++++
src/arch/aarch64/bootblock_simple.c | 75 +++++++
src/arch/aarch64/coreboot_ram.ld | 136 ++++++++++++
src/arch/aarch64/exception.c | 130 ++++++++++++
src/arch/aarch64/id.inc | 18 ++
src/arch/aarch64/include/arch/boot/boot.h | 8 +
src/arch/aarch64/include/arch/byteorder.h | 27 +++
src/arch/aarch64/include/arch/cpu.h | 51 +++++
src/arch/aarch64/include/arch/early_variables.h | 59 ++++++
src/arch/aarch64/include/arch/exception.h | 38 ++++
src/arch/aarch64/include/arch/hlt.h | 9 +
src/arch/aarch64/include/arch/io.h | 59 ++++++
src/arch/aarch64/include/arch/pci_ops.h | 25 +++
src/arch/aarch64/include/arch/rules.h | 34 +++
src/arch/aarch64/include/arch/stages.h | 29 +++
src/arch/aarch64/include/assembler.h | 48 +++++
src/arch/aarch64/include/bootblock_common.h | 11 +
src/arch/aarch64/include/clocks.h | 44 ++++
src/arch/aarch64/include/smp/spinlock.h | 52 +++++
src/arch/aarch64/include/stdint.h | 60 ++++++
src/arch/aarch64/include/utils.h | 56 +++++
src/arch/aarch64/romstage.ld | 78 +++++++
src/arch/aarch64/stages.c | 60 ++++++
src/arch/aarch64/tables.c | 75 +++++++
28 files changed, 1625 insertions(+)
diff --git a/src/arch/aarch64/Kconfig b/src/arch/aarch64/Kconfig
new file mode 100644
index 0000000..0b17bec
--- /dev/null
+++ b/src/arch/aarch64/Kconfig
@@ -0,0 +1,29 @@
+menu "Architecture (aarch64)"
+
+config ARM_AARCH64_OPTIONS
+ bool
+ default y
+# select HAVE_ARCH_MEMSET
+# select HAVE_ARCH_MEMCPY
+# select HAVE_ARCH_MEMMOVE
+
+# Maximum reboot count
+# TODO: Improve description.
+config MAX_REBOOT_CNT
+ int
+ default 3
+
+config BOOTBLOCK_SOURCE
+ string
+ default "bootblock_simple.c"
+
+config UPDATE_IMAGE
+ bool "Update existing coreboot.rom image"
+ default n
+ help
+ If this option is enabled, no new coreboot.rom file
+ is created. Instead it is expected that there already
+ is a suitable file for further processing.
+ The bootblock will not be modified.
+
+endmenu
diff --git a/src/arch/aarch64/Makefile.inc b/src/arch/aarch64/Makefile.inc
new file mode 100644
index 0000000..44c516e
--- /dev/null
+++ b/src/arch/aarch64/Makefile.inc
@@ -0,0 +1,266 @@
+################################################################################
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2012 The ChromiumOS Authors
+### Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
+## Copyright (C) 2009-2010 coresystems GmbH
+## Copyright (C) 2009 Ronald G. Minnich
+##
+## 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
+##
+################################################################################
+
+################################################################################
+# Build the final rom image
+COREBOOT_ROM_DEPENDENCIES:=
+ifeq ($(CONFIG_PAYLOAD_ELF),y)
+COREBOOT_ROM_DEPENDENCIES+=$(CONFIG_PAYLOAD_FILE)
+endif
+
+extract_nth=$(word $(1), $(subst |, ,$(2)))
+
+ifneq ($(CONFIG_UPDATE_IMAGE),y)
+prebuild-files = \
+ $(foreach file,$(cbfs-files), \
+ $(CBFSTOOL) $@.tmp \
+ add$(if $(filter stage,$(call extract_nth,3,$(file))),-stage)$(if $(filter payload,$(call extract_nth,3,$(file))),-payload) \
+ -f $(call extract_nth,1,$(file)) \
+ -n $(call extract_nth,2,$(file)) $(if $(filter-out stage,$(call extract_nth,3,$(file))),-t $(call extract_nth,3,$(file))) \
+ $(if $(call extract_nth,4,$(file)),-b $(call extract_nth,4,$(file))) &&)
+prebuilt-files = $(foreach file,$(cbfs-files), $(call extract_nth,1,$(file)))
+
+# TODO Change -b to Kconfig variable.
+$(obj)/coreboot.pre: $(objcbfs)/bootblock.bin $(objcbfs)/romstage.elf $$(prebuilt-files) $(CBFSTOOL) $$(cpu_ucode_cbfs_file)
+ $(CBFSTOOL) $@.tmp create -m aarch64 -s $(CONFIG_COREBOOT_ROMSIZE_KB)K \
+ -B $(objcbfs)/bootblock.bin -a 64 \
+ -b $(CONFIG_BOOTBLOCK_ROM_OFFSET) \
+ -H $(CONFIG_CBFS_HEADER_ROM_OFFSET) \
+ -o $(CONFIG_CBFS_ROM_OFFSET)
+ @printf " CBFS $(subst $(obj)/,,$(@))\n"
+ $(CBFSTOOL) $@.tmp add-stage \
+ -f $(objcbfs)/romstage.elf -b 0 \
+ -n $(CONFIG_CBFS_PREFIX)/romstage -c none
+ $(prebuild-files) true
+ $(call add-cpu-microcode-to-cbfs,$@.tmp)
+ mv $@.tmp $@
+else
+.PHONY: $(obj)/coreboot.pre
+$(obj)/coreboot.pre: $(CBFSTOOL)
+ mv $(obj)/coreboot.rom $@
+endif
+
+$(obj)/coreboot.rom: $(obj)/coreboot.pre $(objcbfs)/coreboot_ram.elf $(CBFSTOOL) $(call strip_quotes,$(COREBOOT_ROM_DEPENDENCIES)) $$(INTERMEDIATE)
+ @printf " CBFS $(subst $(obj)/,,$(@))\n"
+ cp $(obj)/coreboot.pre $@.tmp
+ $(CBFSTOOL) $@.tmp add-stage -f $(objcbfs)/coreboot_ram.elf -n $(CONFIG_CBFS_PREFIX)/coreboot_ram -c $(CBFS_COMPRESS_FLAG)
+ifeq ($(CONFIG_PAYLOAD_NONE),y)
+ @printf " PAYLOAD none (as specified by user)\n"
+endif
+ifeq ($(CONFIG_PAYLOAD_ELF),y)
+ @printf " PAYLOAD $(CONFIG_PAYLOAD_FILE) (compression: $(CBFS_PAYLOAD_COMPRESS_NAME))\n"
+ $(CBFSTOOL) $@.tmp add-payload -f $(CONFIG_PAYLOAD_FILE) -n $(CONFIG_CBFS_PREFIX)/payload -c $(CBFS_PAYLOAD_COMPRESS_FLAG)
+endif
+ifeq ($(CONFIG_INCLUDE_CONFIG_FILE),y)
+ @printf " CONFIG $(DOTCONFIG)\n"
+ if [ -f $(DOTCONFIG) ]; then \
+ echo "# This image was built using git revision" `git rev-parse HEAD` > $(obj)/config.tmp ; \
+ sed -e '/^#/d' -e '/^ *$$/d' $(DOTCONFIG) >> $(obj)/config.tmp ; \
+ $(CBFSTOOL) $@.tmp add -f $(obj)/config.tmp -n config -t raw; rm -f $(obj)/config.tmp ; fi
+endif
+ mv $@.tmp $@
+ @printf " CBFSPRINT $(subst $(obj)/,,$(@))\n\n"
+ $(CBFSTOOL) $@ print
+
+bootsplash.jpg-file := $(call strip_quotes,$(CONFIG_BOOTSPLASH_FILE))
+bootsplash.jpg-type := bootsplash
+
+################################################################################
+# aarch64 specific tools
+
+################################################################################
+# Common recipes for all stages
+
+$(objcbfs)/%.bin: $(objcbfs)/%.elf
+ @printf " OBJCOPY $(subst $(obj)/,,$(@))\n"
+ $(OBJCOPY) -O binary $< $@
+
+$(objcbfs)/%.elf: $(objcbfs)/%.debug
+ @printf " OBJCOPY $(subst $(obj)/,,$(@))\n"
+ cp $< $@.tmp
+ $(NM) -n $@.tmp | sort > $(basename $(a)).map
+ $(OBJCOPY) --strip-debug $@.tmp
+ $(OBJCOPY) --add-gnu-debuglink=$< $@.tmp
+ mv $@.tmp $@
+
+stages_c = $(src)/arch/aarch64/stages.c
+stages_o = $(obj)/arch/aarch64/stages.o
+
+$(stages_o): $(stages_c) $(obj)/config.h
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ $(CC) -I. $(INCLUDES) -c -o $@ $<
+
+
+################################################################################
+# Build the coreboot_ram (stage 2)
+
+$(objcbfs)/coreboot_ram.debug: $(objgenerated)/coreboot_ram.o $(src)/arch/aarch64/coreboot_ram.ld
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
+ $(LD) -m armelf_linux_eabi -o $@ -L$(obj) $< -T $(src)/arch/aarch64/coreboot_ram.ld
+else
+ $(CC) -nostdlib -nostartfiles -static -o $@ -L$(obj) -T $(src)/arch/aarch64/coreboot_ram.ld $<
+endif
+
+$(objgenerated)/coreboot_ram.o: $(stages_o) $$(ramstage-objs) $(LIBGCC_FILE_NAME)
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
+ $(LD) -m -m armelf_linux_eabi -r -o $@ --wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3 --wrap __uidiv --start-group $(ramstage-objs) $(LIBGCC_FILE_NAME) --end-group
+else
+ $(CC) $(CFLAGS) -nostdlib -r -o $@ -Wl,--start-group $(stages_o) $(ramstage-objs) $(LIBGCC_FILE_NAME) -Wl,--end-group
+endif
+
+CFLAGS += \
+
+ldscripts =
+ldscripts += $(src)/arch/aarch64/romstage.ld
+
+#crt0s += $(src)/cpu/arm/fpu_enable.inc
+
+crt0s += $(cpu_incs)
+crt0s += $(cpu_incs-y)
+
+$(obj)/mainboard/$(MAINBOARDDIR)/romstage.pre.inc: $(src)/mainboard/$(MAINBOARDDIR)/romstage.c $(OPTION_TABLE_H) $(obj)/build.h $(obj)/config.h
+ @printf " CC romstage.inc\n"
+ $(CC) -MMD $(CFLAGS) -D__PRE_RAM__ -I$(src) -I. -I$(obj) -c -S $< -o $@
+
+# Things that appear in every board
+ramstage-y += exception.c
+#ramstage-y += exception_asm.S
+
+#bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += early_console.c
+#bootblock-y += cache.c
+
+#romstage-y += cache.c
+#romstage-y += div0.c
+#romstage-$(CONFIG_EARLY_CONSOLE) += early_console.c
+
+#ramstage-y += div0.c
+#ramstage-y += interrupts.c
+#ramstage-y += cache.c
+#ramstage-y += mmu.c
+
+#romstage-y += eabi_compat.c
+#ramstage-y += eabi_compat.c
+#bootblock-y += eabi_compat.c
+
+ramstage-y += boot.c
+ramstage-y += tables.c
+
+#romstage-y += memset.S
+#ramstage-y += memset.S
+#bootblock-y += memset.S
+#romstage-y += memcpy.S
+#ramstage-y += memcpy.S
+#bootblock-y += memcpy.S
+#romstage-y += memmove.S
+#ramstage-y += memmove.S
+#bootblock-y += memmove.S
+
+$(obj)/arch/aarch64/coreboot_table.ramstage.o : $(OPTION_TABLE_H)
+
+romstage-srcs += $(objgenerated)/crt0.s
+#ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
+
+ifeq ($(CONFIG_BOARD_HAS_HARD_RESET),y)
+#ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/reset.c
+endif
+
+ifeq ($(CONFIG_HAVE_BUS_CONFIG),y)
+#ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/get_bus_conf.c
+endif
+
+################################################################################
+# Build the bootblock
+
+bootblock_lds = $(src)/arch/aarch64/bootblock.lds
+bootblock_lds += $(chipset_bootblock_lds)
+
+bootblock_inc += $(src)/arch/aarch64/bootblock.inc
+bootblock_inc += $(chipset_bootblock_inc)
+bootblock_inc += $(objgenerated)/bootblock.inc
+
+bootblock_custom = $(src)/$(call strip_quotes,$(CONFIG_BOOTBLOCK_CPU_INIT))
+bootblock_custom += $(src)/$(call strip_quotes,$(CONFIG_BOOTBLOCK_MAINBOARD_INIT))
+
+$(objgenerated)/bootblock.ld: $$(bootblock_lds) $(obj)/ldoptions
+ @printf " GEN $(subst $(obj)/,,$(@))\n"
+ printf '$(foreach ldscript,ldoptions $(bootblock_lds),INCLUDE "$(ldscript)"\n)' > $@
+
+$(objgenerated)/bootblock_inc.S: $$(bootblock_inc)
+ @printf " GEN $(subst $(obj)/,,$(@))\n"
+ printf '$(foreach crt0,$(bootblock_inc),#include "$(crt0)"\n)' > $@
+
+$(objgenerated)/bootblock.o: $(objgenerated)/bootblock.s
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ $(CC) $(bootblock-S-ccopts) -Wa,-acdlns -c -o $@ $< > $(basename $(a)).disasm
+
+$(objgenerated)/bootblock.s: $(objgenerated)/bootblock_inc.S $(obj)/config.h $(obj)/build.h
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ $(CC) $(bootblock-S-ccopts) -MMD -x assembler-with-cpp -E -I$(src)/include -I$(src)/arch/aarch64/include -I$(obj) -include $(obj)/build.h -include $(obj)/config.h -I. -I$(src) $< -o $@
+
+$(objgenerated)/bootblock.inc: $(src)/arch/aarch64/$(subst ",,$(CONFIG_BOOTBLOCK_SOURCE)) $(bootblock_custom) $(OPTION_TABLE_H) $(obj)/config.h
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ $(CC) $(bootblock-c-ccopts) $(INCLUDES) -MM \
+ -MT$(objgenerated)/bootblock.inc \
+ $< > $(objgenerated)/bootblock.inc.d
+ $(CC) $(bootblock-c-ccopts) -c -S $(CFLAGS) -I. $(INCLUDES) $< -o $@
+
+$(objcbfs)/bootblock.debug: $(objgenerated)/bootblock.o $(objgenerated)/bootblock.ld $$(bootblock-objs) $(stages) $(obj)/config.h
+ @printf " LINK $(subst $(obj)/,,$(@))\n"
+ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
+ $(LD) -m armelf_linux_eabi -include $(obj)/config.h -static -o $@.tmp -L$(obj) $< -T $(objgenerated)/bootblock.ld
+else
+ $(CC) -nostdlib -nostartfiles -include $(obj)/config.h -static -o $@ -L$(obj) -T $(objgenerated)/bootblock.ld -Wl,--start-group $(objgenerated)/bootblock.o $(bootblock-objs) $(stages) $(LIBGCC_FILE_NAME) -Wl,--end-group
+endif
+
+################################################################################
+# Build the romstage
+
+$(objcbfs)/romstage.debug: $$(romstage-objs) $(stages_o) $(objgenerated)/romstage.ld
+ @printf " LINK $(subst $(obj)/,,$(@))\n"
+ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
+ $(LD) -nostdlib -nostartfiles -static -o $@ -L$(obj) $(romstage-objs) -T $(objgenerated)/romstage.ld
+else
+ $(CC) -nostdlib -nostartfiles -static -o $@ -L$(obj) -T $(objgenerated)/romstage.ld -Wl,--start-group $(romstage-objs) $(stages_o) $(LIBGCC_FILE_NAME) -Wl,--end-group
+endif
+
+$(objgenerated)/romstage.ld: $$(ldscripts) $(obj)/ldoptions
+ @printf " GEN $(subst $(obj)/,,$(@))\n"
+ rm -f $@
+ printf '$(foreach ldscript,ldoptions $(ldscripts),INCLUDE "$(ldscript:$(obj)/%=%)"\n)' >> $@.tmp
+ mv $@.tmp $@
+
+$(objgenerated)/crt0.romstage.S: $$(crt0s)
+ @printf " GEN $(subst $(obj)/,,$(@))\n"
+ printf '$(foreach crt0,$(crt0s),#include "$(crt0:$(obj)/%=%)"\n)' > $@
+
+$(objgenerated)/crt0.romstage.o: $(objgenerated)/crt0.s
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ $(CC) -Wa,-acdlns -c -o $@ $< > $(basename $(a)).disasm
+
+$(objgenerated)/crt0.s: $(objgenerated)/crt0.romstage.S $(obj)/config.h $(obj)/build.h
+ @printf " CC $(subst $(obj)/,,$(@))\n"
+ $(CC) -MMD -x assembler-with-cpp -E -I$(src)/include -I$(src)/arch/aarch64/include -I$(obj) -include $(obj)/config.h -include $(obj)/build.h -I. -I$(src) $< -o $@
+
diff --git a/src/arch/aarch64/boot.c b/src/arch/aarch64/boot.c
new file mode 100644
index 0000000..6774802
--- /dev/null
+++ b/src/arch/aarch64/boot.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * 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
+ */
+
+#include <console/console.h>
+#include <arch/stages.h>
+
+void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size)
+{
+ printk(BIOS_SPEW, "entry = %p\n", entry);
+ stage_exit(entry);
+}
diff --git a/src/arch/aarch64/bootblock.inc b/src/arch/aarch64/bootblock.inc
new file mode 100644
index 0000000..dfa0fc9
--- /dev/null
+++ b/src/arch/aarch64/bootblock.inc
@@ -0,0 +1,66 @@
+/*
+ * Early initialization code for aarch64 (a.k.a. armv8)
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+.section ".start", "a", %progbits
+.globl _start
+_start: b reset
+ .balignl 16,0xdeadbeef
+
+_cbfs_master_header:
+ /* The CBFS master header is inserted by cbfstool at the first
+ * aligned offset after the above anchor string is found.
+ * Hence, we leave some space for it.
+ * Assumes 64-byte alignment.
+ */
+ .skip 128
+
+reset:
+ /*
+ * Set the cpu to SVC32 mode and unmask aborts. Aborts might happen
+ * before logging is turned on and may crash the machine, but at least
+ * the problem will show up near the code that causes it.
+ */
+ b reset
+
+.align 3
+.Stack:
+ .word CONFIG_STACK_TOP
+.align 3
+.Stack_size:
+ .word CONFIG_STACK_SIZE
+ .section ".id", "a", %progbits
+
+ .globl __id_start
+__id_start:
+ver:
+ .asciz COREBOOT_VERSION
+vendor:
+ .asciz CONFIG_MAINBOARD_VENDOR
+part:
+ .asciz CONFIG_MAINBOARD_PART_NUMBER
+.long __id_end - ver /* Reverse offset to the vendor id */
+.long __id_end - vendor /* Reverse offset to the vendor id */
+.long __id_end - part /* Reverse offset to the part number */
+.long CONFIG_ROM_SIZE /* Size of this romimage */
+ .globl __id_end
+
+__id_end:
+.previous
diff --git a/src/arch/aarch64/bootblock.lds b/src/arch/aarch64/bootblock.lds
new file mode 100644
index 0000000..2f7532c
--- /dev/null
+++ b/src/arch/aarch64/bootblock.lds
@@ -0,0 +1,55 @@
+/*
+ * 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
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+TARGET(binary)
+SECTIONS
+{
+ ROMLOC = CONFIG_BOOTBLOCK_BASE;
+
+ /* This section might be better named .setup */
+ .rom ROMLOC : {
+ _rom = .;
+ *(.start);
+ *(.id);
+ *(.text);
+ *(.text.*);
+ *(.rom.text);
+ *(.rom.data);
+ *(.rom.data.*);
+ *(.rodata.*);
+ _erom = .;
+ } : to_load = 0xff
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.ARM.*)
+ }
+}
diff --git a/src/arch/aarch64/bootblock_simple.c b/src/arch/aarch64/bootblock_simple.c
new file mode 100644
index 0000000..b279928
--- /dev/null
+++ b/src/arch/aarch64/bootblock_simple.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2010 Google Inc.
+ *
+ * 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
+ */
+
+#include <bootblock_common.h>
+//#include <arch/cache.h>
+#include <arch/hlt.h>
+#include <arch/stages.h>
+#include <cbfs.h>
+#include <console/console.h>
+
+//#include "stages.c"
+
+static int boot_cpu(void)
+{
+ /*
+ * FIXME: This is a stub for now. All non-boot CPUs should be
+ * waiting for an interrupt. We could move the chunk of assembly
+ * which puts them to sleep in here...
+ */
+ return 1;
+}
+
+void main(void)
+{
+ const char *stage_name = "fallback/romstage";
+ void *entry = NULL;
+
+ /* Globally disable MMU, caches, and branch prediction (these should
+ * be disabled by default on reset) */
+
+ /*
+ * Re-enable icache and branch prediction. MMU and dcache will be
+ * set up later.
+ *
+ * Note: If booting from USB, we need to disable branch prediction
+ * before copying from USB into RAM (FIXME: why?)
+ */
+
+ if (boot_cpu()) {
+ //bootblock_cpu_init();
+ //bootblock_mainboard_init();
+ }
+
+#ifdef CONFIG_BOOTBLOCK_CONSOLE
+ console_init();
+#endif
+
+#if 0
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, stage_name);
+
+#endif
+ printk(BIOS_SPEW, "stage_name %s, entry %p\n", stage_name, entry);
+#if 0
+ if (entry) stage_exit(entry);
+ hlt();
+#endif
+}
diff --git a/src/arch/aarch64/coreboot_ram.ld b/src/arch/aarch64/coreboot_ram.ld
new file mode 100644
index 0000000..cf5d945
--- /dev/null
+++ b/src/arch/aarch64/coreboot_ram.ld
@@ -0,0 +1,136 @@
+/*
+ * Memory map:
+ *
+ * CONFIG_RAMBASE : text segment
+ * : rodata segment
+ * : data segment
+ * : bss segment
+ * : stack
+ * : heap
+ */
+/*
+ * Copyright 2013 Google Inc.
+ * Bootstrap code for the STPC Consumer
+ * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
+ */
+
+/*
+ * Written by Johan Rydberg, based on work by Daniel Kahlin.
+ * Rewritten by Eric Biederman
+ * 2005.12 yhlu add coreboot_ram cross the vga font buffer handling
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+INCLUDE ldoptions
+
+ENTRY(stage_entry)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+SECTIONS
+{
+ . = CONFIG_SYS_SDRAM_BASE;
+ /* First we place the code and read only data (typically const declared).
+ * This could theoretically be placed in rom.
+ */
+ .text : {
+ _text = .;
+ _start = .;
+ *(.text.stage_entry.armv7);
+ *(.text);
+ *(.text.*);
+ . = ALIGN(16);
+ _etext = .;
+ } : to_load
+
+ .ctors : {
+ . = ALIGN(0x100);
+ __CTOR_LIST__ = .;
+ *(.ctors);
+ LONG(0);
+ __CTOR_END__ = .;
+ }
+
+ .rodata : {
+ _rodata = .;
+ . = ALIGN(4);
+ console_drivers = .;
+ *(.rodata.console_drivers)
+ econsole_drivers = . ;
+ . = ALIGN(4);
+ pci_drivers = . ;
+ *(.rodata.pci_driver)
+ epci_drivers = . ;
+ cpu_drivers = . ;
+ *(.rodata.cpu_driver)
+ ecpu_drivers = . ;
+ _bs_init_begin = .;
+ *(.bs_init)
+ _bs_init_end = .;
+ *(.rodata)
+ *(.rodata.*)
+ /* kevinh/Ispiri - Added an align, because the objcopy tool
+ * incorrectly converts sections that are not long word aligned.
+ */
+ . = ALIGN(4);
+
+ _erodata = .;
+ }
+ /* After the code we place initialized data (typically initialized
+ * global variables). This gets copied into ram by startup code.
+ * __data_start and __data_end shows where in ram this should be placed,
+ * whereas __data_loadstart and __data_loadend shows where in rom to
+ * copy from.
+ */
+ .data : {
+ _data = .;
+ *(.data)
+ _edata = .;
+ }
+
+ /* bss does not contain data, it is just a space that should be zero
+ * initialized on startup. (typically uninitialized global variables)
+ * crt0.S fills between _bss and _ebss with zeroes.
+ */
+ _bss = .;
+ .bss . : {
+ *(.bss)
+ *(.sbss)
+ *(COMMON)
+ }
+ _ebss = .;
+ _end = .;
+
+ /* coreboot really "ends" here. Only heap and stack are placed after
+ * this line.
+ */
+
+ _heap = .;
+ .heap . : {
+ /* Reserve CONFIG_HEAP_SIZE bytes for the heap */
+ . = CONFIG_HEAP_SIZE ;
+ . = ALIGN(4);
+ }
+ _eheap = .;
+
+ _stack = CONFIG_STACK_BOTTOM;
+ _estack = CONFIG_STACK_TOP;
+
+ /* The ram segment. This includes all memory used by the memory
+ * resident copy of coreboot, except the tables that are produced on
+ * the fly, but including stack and heap.
+ */
+ _ram_seg = _text;
+ _eram_seg = _eheap;
+
+ /* Discard the sections we don't need/want */
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.note.*)
+ }
+}
diff --git a/src/arch/aarch64/exception.c b/src/arch/aarch64/exception.c
new file mode 100644
index 0000000..db95de2
--- /dev/null
+++ b/src/arch/aarch64/exception.c
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <console/console.h>
+#include <arch/exception.h>
+#include <stdint.h>
+
+void exception_test(void);
+
+static int test_abort;
+
+void exception_undefined_instruction(uint32_t *);
+void exception_software_interrupt(uint32_t *);
+void exception_prefetch_abort(uint32_t *);
+void exception_data_abort(uint32_t *);
+void exception_not_used(uint32_t *);
+void exception_irq(uint32_t *);
+void exception_fiq(uint32_t *);
+
+static void print_regs(uint32_t *regs)
+{
+ int i;
+ // XXX
+ for (i = 0; i < 16; i++) {
+ if (i == 15)
+ printk(BIOS_ERR, "PC");
+ else if (i == 14)
+ continue; /* LR */
+ else if (i == 13)
+ continue; /* SP */
+ else if (i == 12)
+ printk(BIOS_ERR, "IP");
+ else
+ printk(BIOS_ERR, "R%d", i);
+ printk(BIOS_ERR, " = 0x%08x\n", regs[i]);
+ }
+}
+
+void exception_undefined_instruction(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _undefined_instruction\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_software_interrupt(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _software_interrupt\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_prefetch_abort(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _prefetch_abort\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_data_abort(uint32_t *regs)
+{
+ if (test_abort) {
+ regs[15] = regs[0];
+ return;
+ } else {
+ printk(BIOS_ERR, "exception _data_abort\n");
+ print_regs(regs);
+ }
+ die("exception");
+}
+
+void exception_not_used(uint32_t *regs)
+{
+ printk(BIOS_ERR, "exception _not_used\n");
+ print_regs(regs);
+ die("exception");
+}
+
+void exception_irq(uint32_t *regs)
+{
+}
+
+void exception_fiq(uint32_t *regs)
+{
+}
+
+static inline uint32_t get_sctlr(void)
+{
+ return 0;
+}
+
+static inline void set_sctlr(uint32_t val)
+{
+}
+
+void exception_init(void)
+{
+ test_abort = 1;
+ printk(BIOS_ERR, "Testing exceptions\n");
+ //exception_test();
+ //test_abort = 0;
+ printk(BIOS_ERR, "Testing exceptions: DONE\n");
+
+}
diff --git a/src/arch/aarch64/id.inc b/src/arch/aarch64/id.inc
new file mode 100644
index 0000000..ffe547d
--- /dev/null
+++ b/src/arch/aarch64/id.inc
@@ -0,0 +1,18 @@
+ .section ".id", "a", %progbits
+
+ .globl __id_start
+__id_start:
+ver:
+ .asciz COREBOOT_VERSION
+vendor:
+ .asciz CONFIG_MAINBOARD_VENDOR
+part:
+ .asciz CONFIG_MAINBOARD_PART_NUMBER
+.long __id_end - ver /* Reverse offset to the vendor id */
+.long __id_end - vendor /* Reverse offset to the vendor id */
+.long __id_end - part /* Reverse offset to the part number */
+.long CONFIG_ROM_SIZE /* Size of this romimage */
+ .globl __id_end
+
+__id_end:
+.previous
diff --git a/src/arch/aarch64/include/arch/boot/boot.h b/src/arch/aarch64/include/arch/boot/boot.h
new file mode 100644
index 0000000..2051d9a
--- /dev/null
+++ b/src/arch/aarch64/include/arch/boot/boot.h
@@ -0,0 +1,8 @@
+#ifndef ASM_ARM_BOOT_H
+#define ASM_ARM_BOOT_H
+
+#define ELF_CLASS ELFCLASS64
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_AARCH64
+
+#endif /* ASM_ARM_BOOT_H */
diff --git a/src/arch/aarch64/include/arch/byteorder.h b/src/arch/aarch64/include/arch/byteorder.h
new file mode 100644
index 0000000..8dc069f
--- /dev/null
+++ b/src/arch/aarch64/include/arch/byteorder.h
@@ -0,0 +1,27 @@
+#ifndef _BYTEORDER_H
+#define _BYTEORDER_H
+
+#define __LITTLE_ENDIAN 1234
+
+#include <stdint.h>
+#include <swab.h>
+
+#define cpu_to_le64(x) ((uint64_t)(x))
+#define le64_to_cpu(x) ((uint64_t)(x))
+#define cpu_to_le32(x) ((uint32_t)(x))
+#define le32_to_cpu(x) ((uint32_t)(x))
+#define cpu_to_le16(x) ((uint16_t)(x))
+#define le16_to_cpu(x) ((uint16_t)(x))
+#define cpu_to_be64(x) swab64(x)
+#define be64_to_cpu(x) swab64(x)
+#define cpu_to_be32(x) swab32((x))
+#define be32_to_cpu(x) swab32((x))
+#define cpu_to_be16(x) swab16((x))
+#define be16_to_cpu(x) swab16((x))
+
+#define ntohll(x) be64_to_cpu(x)
+#define htonll(x) cpu_to_be64(x)
+#define ntohl(x) be32_to_cpu(x)
+#define htonl(x) cpu_to_be32(x)
+
+#endif /* _BYTEORDER_H */
diff --git a/src/arch/aarch64/include/arch/cpu.h b/src/arch/aarch64/include/arch/cpu.h
new file mode 100644
index 0000000..f8b3005
--- /dev/null
+++ b/src/arch/aarch64/include/arch/cpu.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2012 Google Inc.
+ *
+ * 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 __ARCH_CPU_H__
+#define __ARCH_CPU_H__
+
+#define asmlinkage
+
+#if !defined(__PRE_RAM__)
+#include <device/device.h>
+
+struct cpu_driver {
+ struct device_operations *ops;
+ struct cpu_device_id *id_table;
+};
+
+struct thread;
+
+struct cpu_info {
+ device_t cpu;
+ unsigned long index;
+#if CONFIG_COOP_MULTITASKING
+ struct thread *thread;
+#endif
+};
+
+struct cpuinfo_arm {
+ uint8_t arm; /* CPU family */
+ uint8_t arm_vendor; /* CPU vendor */
+ uint8_t arm_model;
+};
+
+#endif
+
+#endif /* __ARCH_CPU_H__ */
diff --git a/src/arch/aarch64/include/arch/early_variables.h b/src/arch/aarch64/include/arch/early_variables.h
new file mode 100644
index 0000000..90ead9d
--- /dev/null
+++ b/src/arch/aarch64/include/arch/early_variables.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 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 ARCH_EARLY_VARIABLES_H
+#define ARCH_EARLY_VARIABLES_H
+
+#ifdef __PRE_RAM__
+#define CAR_GLOBAL __attribute__((section(".car.global_data,\"w\",%nobits@")))
+#define CAR_CBMEM __attribute__((section(".car.cbmem_console,\"w\",%nobits@")))
+#else
+#define CAR_GLOBAL
+#define CAR_CBMEM
+#endif
+
+#if defined(__PRE_RAM__)
+#define CAR_MIGRATE_ATTR __attribute__ ((used,section (".car.migrate")))
+
+/* Call migrate_fn_() when CAR globals are migrated. */
+#define CAR_MIGRATE(migrate_fn_) \
+ static void (* const migrate_fn_ ## _ptr)(void) CAR_MIGRATE_ATTR = \
+ migrate_fn_;
+
+/* Get the correct pointer for the CAR global variable. */
+void *car_get_var_ptr(void *var);
+
+/* Get and set a primitive type global variable. */
+#define car_get_var(var) \
+ *(typeof(var) *)car_get_var_ptr(&(var))
+#define car_set_var(var, val) \
+ do { car_get_var(var) = (val); } while(0)
+
+/* Migrate the CAR variables to memory. */
+void car_migrate_variables(void);
+
+#else
+#define CAR_MIGRATE(migrate_fn_)
+static inline void *car_get_var_ptr(void *var) { return var; }
+#define car_get_var(var) (var)
+#define car_set_var(var, val) do { (var) = (val); } while (0)
+static inline void car_migrate_variables(void) { }
+#endif
+
+#endif
diff --git a/src/arch/aarch64/include/arch/exception.h b/src/arch/aarch64/include/arch/exception.h
new file mode 100644
index 0000000..5987d85
--- /dev/null
+++ b/src/arch/aarch64/include/arch/exception.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARCH_EXCEPTION_H
+#define _ARCH_EXCEPTION_H
+
+#include <stdint.h>
+
+void exception_init(void);
+void set_vbar(uint64_t vbar);
+
+#endif
diff --git a/src/arch/aarch64/include/arch/hlt.h b/src/arch/aarch64/include/arch/hlt.h
new file mode 100644
index 0000000..285b6f8
--- /dev/null
+++ b/src/arch/aarch64/include/arch/hlt.h
@@ -0,0 +1,9 @@
+#ifndef ARCH_HLT_H
+#define ARCH_HLT_H
+
+static inline __attribute__((always_inline)) void hlt(void)
+{
+ for (;;) ;
+}
+
+#endif /* ARCH_HLT_H */
diff --git a/src/arch/aarch64/include/arch/io.h b/src/arch/aarch64/include/arch/io.h
new file mode 100644
index 0000000..2935a35
--- /dev/null
+++ b/src/arch/aarch64/include/arch/io.h
@@ -0,0 +1,59 @@
+/*
+ * Originally imported from linux/include/asm-arm/io.h. This file has changed
+ * substantially since then.
+ *
+ * Copyright 2013 Google Inc.
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 08-Apr-2013 G Replaced several macros with inlines for type safety.
+ * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both
+ * constant addresses and variable addresses.
+ * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture
+ * specific IO header files.
+ * 27-Mar-1999 PJB Second parameter of memcpy_toio is const..
+ * 04-Apr-1999 PJB Added check_signature.
+ * 12-Dec-1999 RMK More cleanups
+ * 18-Jun-2000 RMK Removed virt_to_* and friends definitions
+ */
+#ifndef __ASM_ARM_IO_H
+#define __ASM_ARM_IO_H
+
+#include <types.h>
+#include <arch/byteorder.h>
+
+static inline uint8_t read8(const void *addr)
+{
+ return *(volatile uint8_t *)addr;
+}
+
+static inline uint16_t read16(const void *addr)
+{
+ return *(volatile uint16_t *)addr;
+}
+
+static inline uint32_t read32(const void *addr)
+{
+ return *(volatile uint32_t *)addr;
+}
+
+static inline void write8(uint8_t val, const void *addr)
+{
+ *(volatile uint8_t *)addr = val;
+}
+
+static inline void write16(uint16_t val, const void *addr)
+{
+ *(volatile uint16_t *)addr = val;
+}
+
+static inline void write32(uint32_t val, const void *addr)
+{
+ *(volatile uint32_t *)addr = val;
+}
+
+#endif /* __ASM_ARM_IO_H */
diff --git a/src/arch/aarch64/include/arch/pci_ops.h b/src/arch/aarch64/include/arch/pci_ops.h
new file mode 100644
index 0000000..05bfc11
--- /dev/null
+++ b/src/arch/aarch64/include/arch/pci_ops.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * 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 ARCH_AARCH64_PCI_OPS_H
+#define ARCH_AARCH64_PCI_OPS_H
+
+/* V8 has PCI in some form. We will need to fill this in. */
+
+#endif
diff --git a/src/arch/aarch64/include/arch/rules.h b/src/arch/aarch64/include/arch/rules.h
new file mode 100644
index 0000000..a790365
--- /dev/null
+++ b/src/arch/aarch64/include/arch/rules.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ *
+ * 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 _ARCH_RULES_H
+#define _ARCH_RULES_H
+
+/* For romstage and ramstage always build with simple device model, ie.
+ * PCI, PNP and CPU functions operate without use of devicetree.
+ *
+ * For ramstage individual source file may define __SIMPLE_DEVICE__
+ * before including any header files to force that particular source
+ * be built with simple device model.
+ */
+
+#if defined(__PRE_RAM__)
+#define __SIMPLE_DEVICE__
+#endif
+
+#endif /* _ARCH_RULES_H */
diff --git a/src/arch/aarch64/include/arch/stages.h b/src/arch/aarch64/include/arch/stages.h
new file mode 100644
index 0000000..e7a2401
--- /dev/null
+++ b/src/arch/aarch64/include/arch/stages.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 The ChromiumOS Authors
+ *
+ * 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 __ARCH_STAGES_H
+#define __ARCH_STAGES_H
+
+extern void main(void);
+
+void stage_entry(void) __attribute__((section(".text.stage_entry.aarch64")));
+void stage_exit(void *);
+void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size);
+
+#endif
diff --git a/src/arch/aarch64/include/assembler.h b/src/arch/aarch64/include/assembler.h
new file mode 100644
index 0000000..3c10684
--- /dev/null
+++ b/src/arch/aarch64/include/assembler.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/include/asm/assembler.h
+ *
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains arm architecture specific defines
+ * for the different processors.
+ *
+ * Do not include any C declarations in this file - it is included by
+ * assembler source.
+ */
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull lsr
+#define push lsl
+#define get_byte_0 lsl #0
+#define get_byte_1 lsr #8
+#define get_byte_2 lsr #16
+#define get_byte_3 lsr #24
+#define put_byte_0 lsl #0
+#define put_byte_1 lsl #8
+#define put_byte_2 lsl #16
+#define put_byte_3 lsl #24
+#else
+#define pull lsl
+#define push lsr
+#define get_byte_0 lsr #24
+#define get_byte_1 lsr #16
+#define get_byte_2 lsr #8
+#define get_byte_3 lsl #0
+#define put_byte_0 lsl #24
+#define put_byte_1 lsl #16
+#define put_byte_2 lsl #8
+#define put_byte_3 lsl #0
+#endif
+
+/*
+ * Cache aligned
+ */
+#define CALGN(code...) code
+
diff --git a/src/arch/aarch64/include/bootblock_common.h b/src/arch/aarch64/include/bootblock_common.h
new file mode 100644
index 0000000..2fa705f
--- /dev/null
+++ b/src/arch/aarch64/include/bootblock_common.h
@@ -0,0 +1,11 @@
+#ifdef CONFIG_BOOTBLOCK_CPU_INIT
+#include CONFIG_BOOTBLOCK_CPU_INIT
+#endif
+
+#ifdef CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#include CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#else
+static void bootblock_mainboard_init(void)
+{
+}
+#endif
diff --git a/src/arch/aarch64/include/clocks.h b/src/arch/aarch64/include/clocks.h
new file mode 100644
index 0000000..8f35303
--- /dev/null
+++ b/src/arch/aarch64/include/clocks.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* Standard clock speeds */
+
+/*
+ * We define some commonly-used clock speeds to avoid error since long
+ * numbers are hard to read.
+ *
+ * The format of the label is
+ * CLK_x_yU where:
+ * x is the integer speed
+ * y is the fractional part which can be omitted if 0
+ * U is the units (blank for Hz, K or M for KHz and MHz)
+ *
+ * Please order the items by increasing Hz
+ */
+enum {
+ CLK_32768 = 32768,
+ CLK_20M = 20000000,
+ CLK_24M = 24000000,
+ CLK_144M = 144000000,
+ CLK_216M = 216000000,
+ CLK_300M = 300000000,
+};
+
diff --git a/src/arch/aarch64/include/smp/spinlock.h b/src/arch/aarch64/include/smp/spinlock.h
new file mode 100644
index 0000000..1dc397c
--- /dev/null
+++ b/src/arch/aarch64/include/smp/spinlock.h
@@ -0,0 +1,52 @@
+#ifndef ARCH_SMP_SPINLOCK_H
+#define ARCH_SMP_SPINLOCK_H
+
+/* FIXME: implement this for ARM */
+#error "implement this for ARM"
+#if 0
+/*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+ */
+
+typedef struct {
+ volatile unsigned int lock;
+} spinlock_t;
+
+
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
+#define DECLARE_SPIN_LOCK(x) static spinlock_t x = SPIN_LOCK_UNLOCKED;
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) != 0)
+#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
+
+static inline __attribute__((always_inline)) void spin_lock(spinlock_t *lock)
+{
+ unsigned long tmp;
+ __asm__ __volatile__ (
+ "1: ldrex %0, [%1]\n"
+ " teq %0, #0\n"
+ " strexeq %0, %2, [%1]\n"
+ " teqeq %0, #0\n"
+ " bne 1b\n"
+ : "=&r" (tmp)
+ : "r" (&lock->lock), "r" (1)
+ : "cc"
+ );
+ barrier();
+}
+
+static inline __attribute__((always_inline)) void spin_unlock(spinlock_t *lock)
+{
+ __asm__ __volatile__(
+ " str %1, [%0]\n"
+ :
+ : "r" (&lock->lock), "r" (0)
+ : "cc"
+ );
+}
+
+#define cpu_relax() barrier()
+
+#endif
+#endif /* ARCH_SMP_SPINLOCK_H */
diff --git a/src/arch/aarch64/include/stdint.h b/src/arch/aarch64/include/stdint.h
new file mode 100644
index 0000000..f192346
--- /dev/null
+++ b/src/arch/aarch64/include/stdint.h
@@ -0,0 +1,60 @@
+#ifndef ARM_STDINT_H
+#define ARM_STDINT_H
+
+/* Exact integral types */
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+
+/* Small types */
+typedef unsigned char uint_least8_t;
+typedef signed char int_least8_t;
+
+typedef unsigned short uint_least16_t;
+typedef signed short int_least16_t;
+
+typedef unsigned int uint_least32_t;
+typedef signed int int_least32_t;
+
+typedef unsigned long long uint_least64_t;
+typedef signed long long int_least64_t;
+
+/* Fast Types */
+typedef unsigned char uint_fast8_t;
+typedef signed char int_fast8_t;
+
+typedef unsigned int uint_fast16_t;
+typedef signed int int_fast16_t;
+
+typedef unsigned int uint_fast32_t;
+typedef signed int int_fast32_t;
+
+typedef unsigned long long uint_fast64_t;
+typedef signed long long int_fast64_t;
+
+typedef long long int intmax_t;
+typedef unsigned long long uintmax_t;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+
+/* Types for `void *' pointers. */
+typedef s64 intptr_t;
+typedef u64 uintptr_t;
+
+#endif /* ARM_STDINT_H */
diff --git a/src/arch/aarch64/include/utils.h b/src/arch/aarch64/include/utils.h
new file mode 100644
index 0000000..828b86c
--- /dev/null
+++ b/src/arch/aarch64/include/utils.h
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh(a)ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+static inline s32 log_2_n_round_up(u32 n)
+{
+ s32 log2n = -1;
+ u32 temp = n;
+
+ while (temp) {
+ log2n++;
+ temp >>= 1;
+ }
+
+ if (n & (n - 1))
+ return log2n + 1; /* not power of 2 - round up */
+ else
+ return log2n; /* power of 2 */
+}
+
+static inline s32 log_2_n_round_down(u32 n)
+{
+ s32 log2n = -1;
+ u32 temp = n;
+
+ while (temp) {
+ log2n++;
+ temp >>= 1;
+ }
+
+ return log2n;
+}
+
+#endif
diff --git a/src/arch/aarch64/romstage.ld b/src/arch/aarch64/romstage.ld
new file mode 100644
index 0000000..7ebe53f
--- /dev/null
+++ b/src/arch/aarch64/romstage.ld
@@ -0,0 +1,78 @@
+/*
+ * Memory map:
+ *
+ * CONFIG_RAMBASE : text segment
+ * : rodata segment
+ * : data segment
+ * : bss segment
+ * : stack
+ * : heap
+ */
+/*
+ * Bootstrap code for the STPC Consumer
+ * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
+ */
+
+/*
+ * Written by Johan Rydberg, based on work by Daniel Kahlin.
+ * Rewritten by Eric Biederman
+ * 2005.12 yhlu add coreboot_ram cross the vga font buffer handling
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+ENTRY(stage_entry)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+SECTIONS
+{
+ /* TODO make this a configurable option (per chipset). */
+ . = CONFIG_ROMSTAGE_BASE;
+
+ .romtext . : {
+ _rom = .;
+ _start = .;
+ *(.text.stage_entry.aarch64);
+ *(.text.startup);
+ *(.text);
+ } : to_load
+
+ .romdata . : {
+ *(.rodata);
+ *(.machine_param);
+ *(.data);
+ . = ALIGN(8);
+ _erom = .;
+ }
+
+ __image_copy_end = .;
+
+ /* bss does not contain data, it is just a space that should be zero
+ * initialized on startup. (typically uninitialized global variables)
+ * crt0.S fills between _bss and _ebss with zeroes.
+ */
+ .bss . : {
+ . = ALIGN(8);
+ _bss = .;
+ *(.bss)
+ *(.sbss)
+ *(COMMON)
+ }
+ _ebss = .;
+ _end = .;
+
+ /* Discard the sections we don't need/want */
+ /DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.eh_frame);
+ }
+}
diff --git a/src/arch/aarch64/stages.c b/src/arch/aarch64/stages.c
new file mode 100644
index 0000000..f8d4dc3
--- /dev/null
+++ b/src/arch/aarch64/stages.c
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2012 Google Inc.
+ *
+ * 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
+ */
+
+/*
+ * This file contains entry/exit functions for each stage during coreboot
+ * execution (bootblock entry and ramstage exit will depend on external
+ * loading.
+ *
+ * Unlike other files, this one should be compiled with a -m option to
+ * specify a pre-determined instruction set. This is to ensure consistency
+ * in the CPU operating mode (ARM or Thumb) when hand-off between stages
+ * occurs.
+ *
+ * Entry points must be placed at the location the previous stage jumps
+ * to (the lowest address in the stage image). This is done by giving
+ * stage_entry() its own section in .text and placing it first in the
+ * linker script.
+ */
+
+#include <arch/stages.h>
+
+void stage_entry(void)
+{
+ main();
+}
+
+/* we had marked 'doit' as 'noreturn'.
+ * There is no apparent harm in leaving it as something we can return from, and in the one
+ * case where we call a payload, the payload is allowed to return.
+ * Hence, leave it as something we can return from.
+ */
+void stage_exit(void *addr)
+{
+ void (*doit)(void) = addr;
+ /* make sure any code we installed is written to memory. Not all ARM have
+ * unified caches.
+ */
+
+ /* Because most stages copy code to memory, it's a safe and hygienic thing
+ * to flush the icache here.
+ */
+ //icache_invalidate_all();
+ doit();
+}
diff --git a/src/arch/aarch64/tables.c b/src/arch/aarch64/tables.c
new file mode 100644
index 0000000..b566ff6
--- /dev/null
+++ b/src/arch/aarch64/tables.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Eric Biederman
+ * Copyright (C) 2005 Steve Magnani
+ * Copyright (C) 2008-2009 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
+ */
+
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <boot/tables.h>
+#include <boot/coreboot_tables.h>
+#include <string.h>
+#include <cbmem.h>
+#include <lib.h>
+
+#define MAX_COREBOOT_TABLE_SIZE (8 * 1024)
+
+void __attribute__((weak)) get_cbmem_table(uint64_t *base, uint64_t *size)
+{
+ printk(BIOS_WARNING, "WARNING: you need to define get_cbmem_table for your board\n");
+ *base = 0;
+ *size = 0;
+}
+
+void cbmem_arch_init(void)
+{
+}
+
+struct lb_memory *write_tables(void)
+{
+ unsigned long table_pointer, new_table_pointer;
+
+ cbmem_base_check();
+
+ post_code(0x9d);
+
+ table_pointer = (unsigned long)cbmem_add(CBMEM_ID_CBTABLE,
+ MAX_COREBOOT_TABLE_SIZE);
+ if (!table_pointer) {
+ printk(BIOS_ERR, "Could not add CBMEM for coreboot table.\n");
+ return NULL;
+ }
+
+ new_table_pointer = write_coreboot_table(0UL, 0UL,
+ table_pointer, table_pointer);
+
+ if (new_table_pointer > (table_pointer + MAX_COREBOOT_TABLE_SIZE)) {
+ printk(BIOS_ERR, "coreboot table didn't fit (%lx/%x bytes)\n",
+ new_table_pointer - table_pointer, MAX_COREBOOT_TABLE_SIZE);
+ }
+
+ printk(BIOS_DEBUG, "coreboot table: %ld bytes.\n",
+ new_table_pointer - table_pointer);
+
+ post_code(0x9e);
+
+ /* Print CBMEM sections */
+ cbmem_list();
+
+ return get_lb_mem();
+}
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4262
-gerrit
commit 486fd50028d41c2415a7e9ebf05c447689d0080a
Author: Ronald G. Minnich <rminnich(a)google.com>
Date: Fri Nov 22 09:28:48 2013 -0800
cbfs: fix issues with word size and endianness.
Add xdr functions and use them to convert the ELF headers
to native headers, using the Elf64 structs to ensure we accomodate
all word sizes.
This may seem overly complex but it turned out to be much the easiest
way to do this. Note that the basic elf parsing function
in cbfs-mkstage.c now works over all ELF files.
Change-Id: I3457b1782f27cb930a2101d1c53f58e2488ed8a1
Signed-off-by: Ronald G. Minnich <rminnich(a)google.com>
---
util/cbfstool/Makefile | 2 +-
util/cbfstool/Makefile.inc | 1 +
util/cbfstool/cbfs-mkstage.c | 293 +++++++++++++++++++++++++++++++++++--------
util/cbfstool/common.h | 11 ++
util/cbfstool/xdr.c | 141 +++++++++++++++++++++
5 files changed, 393 insertions(+), 55 deletions(-)
diff --git a/util/cbfstool/Makefile b/util/cbfstool/Makefile
index 3aa5edc..281d75c 100644
--- a/util/cbfstool/Makefile
+++ b/util/cbfstool/Makefile
@@ -7,7 +7,7 @@ CFLAGS += -D_7ZIP_ST
BINARY:=$(obj)/cbfstool
COMMON:=cbfstool.o common.o cbfs_image.o compress.o fit.o
-COMMON+=cbfs-mkstage.o cbfs-mkpayload.o
+COMMON+=cbfs-mkstage.o cbfs-mkpayload.o xdr.o
# LZMA
COMMON+=lzma/lzma.o
COMMON+=lzma/C/LzFind.o lzma/C/LzmaDec.o lzma/C/LzmaEnc.o
diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc
index fc120f3..4270d75 100644
--- a/util/cbfstool/Makefile.inc
+++ b/util/cbfstool/Makefile.inc
@@ -5,6 +5,7 @@ cbfsobj += compress.o
cbfsobj += cbfs_image.o
cbfsobj += cbfs-mkstage.o
cbfsobj += cbfs-mkpayload.o
+cbfsobj += xdr.o
cbfsobj += fit.o
# LZMA
cbfsobj += lzma.o
diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c
index dfc93c2..4d74522 100644
--- a/util/cbfstool/cbfs-mkstage.c
+++ b/util/cbfstool/cbfs-mkstage.c
@@ -28,90 +28,270 @@
#include "cbfs.h"
#include "elf.h"
-static unsigned int idemp(unsigned int x)
+/*
+ * Short form: this is complicated, but we've tried making it simple
+ * and we keep hitting problems with our ELF parsing.
+ *
+ * The ELF parsing situation has always been a bit tricky. In fact,
+ * we (and most others) have been getting it wrong in small ways for
+ * years. Recently this has caused real trouble for the ARM V8 build.
+ * In this file we attempt to finally get it right for all variations
+ * of endian-ness and word size and target architectures and
+ * architectures we might get run on. Phew!. To do this we borrow a
+ * page from the FreeBSD NFS xdr model (see elf_ehdr and elf_phdr),
+ * the Plan 9 endianness functions (see xdr.c), and Go interfaces (see
+ * how we use buffer structs in this file). This ends up being a bit
+ * wordy at the lowest level, but greatly simpplifies the elf parsing
+ * code aad removes a common source of bugs, namely, forgetting to
+ * flip type endianness when referencing a struct member.
+ *
+ * ELF files can have four combinations of data layout: 32/64, and
+ * big/little endian. Further, to add to the fun, depending on the
+ * word size, the size of the ELF structs varies. The coreboot SELF
+ * format is simpler in theory: it's supposed to be always BE, and the
+ * various struct members allow room for growth: the entry point is
+ * always 64 bits, for example, so the size of a SELF struct is
+ * constant, regardless of target architecture word size. Hence, we
+ * need to do some transformation of the ELF files.
+ *
+ * A given architecture, realistically, only supports one of the four
+ * combinations at a time as the 'native' formst. Hence, our code has
+ * been sprinkled with every variation of [nh]to[hn][sll] over the
+ * years. We've never quite gotten it all right, however, and a quick
+ * pass over this code revealed another bug. It's all worked because,
+ * until now, all the working platforms that had CBFS were 32 LE. Even then,
+ * however, bugs crept in: we recently realized that we're not
+ * transforming the entry point to big format when we store into the
+ * SELF image.
+ *
+ * The problem is essentially an XDR operation:
+ * we have something in a foreign format and need to transform it.
+ * It's most like XDR because:
+ * 1) the byte order can be wrong
+ * 2) the word size can be wrong
+ * 3) the size of elements in the stream depends on the value
+ * of other elements in the stream
+ * it's not like XDR because:
+ * 1) the byte order can be right
+ * 2) the word size can be right
+ * 3) the struct members are all on a natural alignment
+ *
+ * Hence, this new approach.
+ * To cover word size issues, we *always* transform the two structs we care about,
+ * the file header and program header, into a native struct in the 64 bit format:
+ * [32,little] -> [Elf64_Ehdr, Elf64_Phdr]
+ * [64,little] -> [Elf64_Ehdr, Elf64_Phdr]
+ * [32,big] -> [Elf64_Ehdr, Elf64_Phdr]
+ * [64,big] -> [Elf64_Ehdr, Elf64_Phdr]
+ * Then we just use those structs, and all the need for inline ntoh* goes away,
+ * as well as all the chances for error.
+ * This works because all the SELF structs have fields large enough for
+ * the largest ELF 64 struct members, and all the Elf64 struct members
+ * are at least large enough for all ELF 32 struct members.
+ * We end up with one function to do all our ELF parsing, and two functions
+ * to transform the headers. For the put case, we also have
+ * XDR functions, and hopefully we'll never again spend 5 years with the
+ * wrong endian-ness on an output value :-)
+ * This should work for all word sizes and endianness we hope to target.
+ * I *really* don't want to be here for 128 bit addresses.
+ *
+ * The parse functions are called with a pointer to an input buffer
+ * struct. One might ask: are there enough bytes in the input buffer?
+ * We know there need to be at *least* sizeof(Elf32_Ehdr) +
+ * sizeof(Elf32_Phdr) bytes. Realistically, there has to be some data
+ * too. If we start to worry, though we have not in the past, we
+ * might apply the simple test: the input buffer needs to be at least
+ * sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) bytes because, even if it's
+ * ELF 32, there's got to be *some* data! This is not theoretically
+ * accurate but it is actually good enough in practice. It allows the
+ * header transformation code to ignore the possibility of underrun.
+ *
+ * We also must accomodate different ELF files, and hence formats,
+ * in the same cbfs invocation. We might load a 64-bit payload
+ * on a 32-bit machine; we might even have a mixed armv7/armv8
+ * SOC or even a system with an x86/ARM!
+ *
+ * A possibly problematic (though unlikely to be so) assumption
+ * is that we expect the BIOS to remain in the lowest 32 bits
+ * of the physical address space. Since ARMV8 has standardized
+ * on that, and x86_64 also has, this seems a safe assumption.
+ *
+ * To repeat, ELF structs are different sizes because ELF struct
+ * members are different sizes, depending on values in the ELF file
+ * header. For this we use the functions defined in xdr.c, which
+ * consume bytes, convert the endianness, and advance the data pointer
+ * in the buffer struct.
+ */
+
+/* Get the ident array, so we can figure out
+ * endian-ness, word size, and in future other useful
+ * parameters
+ */
+static void
+elf_eident(struct buffer *input, Elf64_Ehdr *ehdr)
{
- return x;
+ memmove(ehdr->e_ident, input->data, sizeof(ehdr->e_ident));
+ input->data += sizeof(ehdr->e_ident);
+ input->size -= sizeof(ehdr->e_ident);
}
-/* This is a wrapper around the swab32() macro to make it
- * usable for the current implementation of parse_elf_to_stage()
- */
-static unsigned int swap32(unsigned int x)
+static void
+elf_ehdr(struct buffer *input, Elf64_Ehdr *ehdr, struct xdr *xdr, int bit64)
+{
+ ehdr->e_type = xdr->get16(input);
+ ehdr->e_machine = xdr->get16(input);
+ ehdr->e_version = xdr->get32(input);
+ if (bit64){
+ ehdr->e_entry = xdr->get64(input);
+ ehdr->e_phoff = xdr->get64(input);
+ ehdr->e_shoff = xdr->get64(input);
+ } else {
+ ehdr->e_entry = xdr->get32(input);
+ ehdr->e_phoff = xdr->get32(input);
+ ehdr->e_shoff = xdr->get32(input);
+ }
+ ehdr->e_flags = xdr->get32(input);
+ ehdr->e_ehsize = xdr->get16(input);
+ ehdr->e_phentsize = xdr->get16(input);
+ ehdr->e_phnum = xdr->get16(input);
+ ehdr->e_shentsize = xdr->get16(input);
+ ehdr->e_shnum = xdr->get16(input);
+ ehdr->e_shstrndx = xdr->get16(input);
+}
+
+void
+elf_phdr(struct buffer *pinput, Elf64_Phdr *phdr, int entsize, struct xdr *xdr, int bit64)
{
- return swab32(x);
+ /*
+ * The entsize need not be sizeof(*phdr).
+ * Hence, it is easier to keep a copy of the input,
+ * as the xdr functions may not advance the input
+ * pointer the full entsize; rather than get tricky
+ * we just advance it below.
+ */
+ struct buffer input = *pinput;
+ if (bit64){
+ phdr->p_type = xdr->get32(&input);
+ phdr->p_flags = xdr->get32(&input);
+ phdr->p_offset = xdr->get64(&input);
+ phdr->p_vaddr = xdr->get64(&input);
+ phdr->p_paddr = xdr->get64(&input);
+ phdr->p_filesz = xdr->get64(&input);
+ phdr->p_memsz = xdr->get64(&input);
+ phdr->p_align = xdr->get64(&input);
+ } else {
+ phdr->p_type = xdr->get32(&input);
+ phdr->p_offset = xdr->get32(&input);
+ phdr->p_vaddr = xdr->get32(&input);
+ phdr->p_paddr = xdr->get32(&input);
+ phdr->p_filesz = xdr->get32(&input);
+ phdr->p_memsz = xdr->get32(&input);
+ phdr->p_flags = xdr->get32(&input);
+ phdr->p_align = xdr->get32(&input);
+ }
+ pinput->size -= entsize;
+ pinput->data += entsize;
}
-unsigned int (*elf32_to_native) (unsigned int) = idemp;
+/* Get the headers from the buffer.
+ * Return -1 in the event of an error.
+ */
+int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr)
+{
+ int i;
+ struct xdr *xdr = &xdr_le;
+ int bit64 = 0;
+ struct buffer input = *(struct buffer *)pinput;
+ struct buffer phdr_buf;
+ Elf64_Phdr *phdr;
-/* returns size of result, or -1 if error */
+ if (!iself((unsigned char *)pinput->data)) {
+ ERROR("The stage file is not in ELF format!\n");
+ return -1;
+ }
+
+ elf_eident(&input, ehdr);
+ bit64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
+ /* Assume LE unless we are sure otherwise.
+ * We're not going to take on the task of
+ * fully validating the ELF file. That way
+ * lies madness.
+ */
+ if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+ xdr = &xdr_be;
+
+ elf_ehdr(&input, ehdr, xdr, bit64);
+
+ /* cons up an input buffer for the headers.
+ * Note that the program headers can be anywhere,
+ * per the ELF spec, You'd be surprised how many ELF
+ * readers miss this little detail.
+ */
+ phdr_buf.data = &pinput->data[ehdr->e_phoff];
+ phdr_buf.size = ehdr->e_phentsize * ehdr->e_phnum;
+ if (phdr_buf.size > (pinput->size - ehdr->e_phoff)){
+ ERROR("The file is not large enough for the program headers."
+ "%d bytes left, %d bytes of headers\n",
+ pinput->size - ehdr->e_phoff, phdr_buf.size);
+ return -1;
+ }
+ /* gather up all the phdrs.
+ * We do them all at once because there is more
+ * than one loop over all the phdrs.
+ */
+ phdr = calloc(sizeof(*phdr), ehdr->e_phnum);
+ for (i = 0; i < ehdr->e_phnum; i++)
+ elf_phdr(&phdr_buf, &phdr[i], ehdr->e_phentsize, xdr, bit64);
+ *pphdr = phdr;
+ return 0;
+}
+/* returns size of result, or -1 if error.
+ * Note that, with the new code, this function
+ * works for all elf files, not just the restricted set.
+ */
int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
comp_algo algo, uint32_t *location)
{
- Elf32_Phdr *phdr;
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)input->data;
- char *header, *buffer;
+ Elf64_Phdr *phdr;
+ Elf64_Ehdr ehdr;
+ char *buffer;
int headers;
int i;
struct cbfs_stage *stage;
- unsigned int data_start, data_end, mem_end;
-
- int elf_bigendian = 0;
+ uint32_t data_start, data_end, mem_end;
comp_func_ptr compress = compression_function(algo);
if (!compress)
return -1;
DEBUG("start: parse_elf_to_stage(location=0x%x)\n", *location);
- if (!iself((unsigned char *)input->data)) {
- ERROR("The stage file is not in ELF format!\n");
- return -1;
- }
- // The tool may work in architecture-independent way.
- if (arch != CBFS_ARCHITECTURE_UNKNOWN &&
- !((ehdr->e_machine == EM_ARM) && (arch == CBFS_ARCHITECTURE_ARMV7)) &&
- !((ehdr->e_machine == EM_386) && (arch == CBFS_ARCHITECTURE_X86))) {
- ERROR("The stage file has the wrong architecture\n");
+ if (elf_headers(input, &ehdr, &phdr) < 0)
return -1;
- }
-
- if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
- elf_bigendian = 1;
- }
- if (elf_bigendian != is_big_endian()) {
- elf32_to_native = swap32;
- }
-
- headers = ehdr->e_phnum;
- header = (char *)ehdr;
- phdr = (Elf32_Phdr *) & header[elf32_to_native(ehdr->e_phoff)];
+ headers = ehdr.e_phnum;
- /* Now, regular headers - we only care about PT_LOAD headers,
- * because thats what we're actually going to load
- */
-
- data_start = 0xFFFFFFFF;
+ data_start = ~0;
data_end = 0;
mem_end = 0;
for (i = 0; i < headers; i++) {
unsigned int start, mend, rend;
- if (elf32_to_native(phdr[i].p_type) != PT_LOAD)
+ if (phdr[i].p_type != PT_LOAD)
continue;
/* Empty segments are never interesting */
- if (elf32_to_native(phdr[i].p_memsz) == 0)
+ if (phdr[i].p_memsz == 0)
continue;
/* BSS */
- start = elf32_to_native(phdr[i].p_paddr);
+ start = phdr[i].p_paddr;
- mend = start + elf32_to_native(phdr[i].p_memsz);
- rend = start + elf32_to_native(phdr[i].p_filesz);
+ mend = start + phdr[i].p_memsz;
+ rend = start + phdr[i].p_filesz;
if (start < data_start)
data_start = start;
@@ -128,8 +308,9 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
}
if (data_end <= data_start) {
- ERROR("data ends before it starts. Make sure the "
- "ELF file is correct and resides in ROM space.\n");
+ ERROR("data ends (%08lx) before it starts(%08lx). Make sure the "
+ "ELF file is correct and resides in ROM space.\n",
+ data_end, data_start);
exit(1);
}
@@ -146,21 +327,21 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
for (i = 0; i < headers; i++) {
unsigned int l_start, l_offset = 0;
- if (elf32_to_native(phdr[i].p_type) != PT_LOAD)
+ if (phdr[i].p_type != PT_LOAD)
continue;
- if (elf32_to_native(phdr[i].p_memsz) == 0)
+ if (phdr[i].p_memsz == 0)
continue;
- l_start = elf32_to_native(phdr[i].p_paddr);
+ l_start = phdr[i].p_paddr;
if (l_start < *location) {
l_offset = *location - l_start;
l_start = *location;
}
memcpy(buffer + (l_start - data_start),
- &header[elf32_to_native(phdr[i].p_offset)+l_offset],
- elf32_to_native(phdr[i].p_filesz)-l_offset);
+ &input->data[phdr[i].p_offset + l_offset],
+ phdr[i].p_filesz - l_offset);
}
/* Now make the output buffer */
@@ -172,12 +353,16 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
}
memset(output->data, 0, output->size);
+ /* N.B. The original plan was that SELF data was B.E.
+ * but: this is all L.E.
+ * Maybe we should just change the spec.
+ */
stage = (struct cbfs_stage *)output->data;
stage->load = data_start; /* FIXME: htonll */
stage->memlen = mem_end - data_start;
stage->compression = algo;
- stage->entry = ehdr->e_entry; /* FIXME: htonll */
+ stage->entry = ehdr.e_entry;
compress(buffer, data_end - data_start, (output->data + sizeof(*stage)),
(int *)&stage->len);
diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h
index 6e12fcb..c68f0ff 100644
--- a/util/cbfstool/common.h
+++ b/util/cbfstool/common.h
@@ -131,6 +131,17 @@ uint32_t cbfs_find_location(const char *romfile, uint32_t filesize,
void print_supported_filetypes(void);
+/* xdr.c */
+struct xdr {
+ uint16_t (*get16)(struct buffer *input);
+ uint32_t (*get32)(struct buffer *input);
+ uint64_t (*get64)(struct buffer *input);
+ void (*put16)(struct buffer *input, uint16_t val);
+ void (*put32)(struct buffer *input, uint32_t val);
+ void (*put64)(struct buffer *input, uint64_t val);
+};
+
+extern struct xdr xdr_le, xdr_be;
#define ARRAY_SIZE(a) (int)(sizeof(a) / sizeof((a)[0]))
#endif
diff --git a/util/cbfstool/xdr.c b/util/cbfstool/xdr.c
new file mode 100644
index 0000000..ab4ed70
--- /dev/null
+++ b/util/cbfstool/xdr.c
@@ -0,0 +1,141 @@
+ /*
+ * cbfstool, CLI utility for CBFS file manipulation
+ *
+ * Copyright 2013 Google Inc.
+ *
+ * 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
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdint.h>
+#include "common.h"
+
+/* The assumption in all this code is that we're given a pointer to enough data.
+ * Hence, we do not check for underflow.
+ */
+uint8_t get8(struct buffer *input)
+{
+ uint8_t ret = *input->data++;
+ input->size--;
+ return ret;
+}
+
+uint16_t get16be(struct buffer *input)
+{
+ uint16_t ret;
+ ret = get8(input)<<8;
+ ret |= get8(input);
+ return ret;
+}
+
+uint32_t get32be(struct buffer *input)
+{
+ uint32_t ret;
+ ret = get16be(input)<<16;
+ ret |= get16be(input);
+ return ret;
+}
+
+uint64_t get64be(struct buffer *input)
+{
+ uint64_t ret;
+ ret = get32be(input);
+ ret <<= 32;
+ ret |= get32be(input);
+ return ret;
+}
+
+void put8(struct buffer *input, uint8_t val)
+{
+ input->data[size] = val;
+ input->size++;
+}
+
+void put16be(struct buffer *input, uint16_t val)
+{
+ put8(input, val>>8);
+ put8(input, val);
+}
+
+void put32be(struct buffer *input, uint32_t val)
+{
+ put16be(input, val>>16);
+ put16be(input, val);
+}
+
+void put64be(struct buffer *input, uint64_t val)
+{
+ put32be(input, val>>32);
+ put32be(input, val);
+}
+
+uint16_t get16le(struct buffer *input)
+{
+ uint16_t ret;
+ ret = get8(input);
+ ret |= get8(input) << 8;
+ return ret;
+}
+
+uint32_t get32le(struct buffer *input)
+{
+ uint32_t ret;
+ ret = get16le(input);
+ ret |= get16le(input) << 16;
+ return ret;
+}
+
+uint64_t get64le(struct buffer *input)
+{
+ uint64_t ret;
+ uint32_t low;
+ low = get32le(input);
+ ret = get32le(input);
+ ret <<= 32;
+ ret |= low;
+ return ret;
+}
+
+void put16le(struct buffer *input, uint16_t val)
+{
+ put8(input, val);
+ put8(input, val>>8);
+}
+
+void put32le(struct buffer *input, uint32_t val)
+{
+ put16le(input, val);
+ put16le(input, val>>16);
+}
+
+void put64le(struct buffer *input, uint64_t val)
+{
+ put32le(input, val);
+ put32le(input, val>>32);
+}
+
+struct xdr xdr_be = {
+ get16le, get32le, get64le,
+ put16be, put32be, put64be
+};
+
+struct xdr xdr_le = {
+ get16le, get32le, get64le,
+ put16le, put32le, put64le
+};
+
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4273
-gerrit
commit 724f9f524c0e47bc20cf27336710147df4736124
Author: Ronald G. Minnich <rminnich(a)google.com>
Date: Mon Nov 25 10:05:16 2013 -0800
emulation/foundation-armv8: add support for armv8 mainboard
This is a cpu supported by the foundation emulator. This will not build
at all without my cbfstool changes.
Change-Id: I2dee4741081b041b93fd538d61d29760b9e2ffbf
Signed-off-by: Ronald G. Minnich <rminnich(a)google.com>
---
src/mainboard/emulation/Kconfig | 4 +
src/mainboard/emulation/foundation-armv8/Kconfig | 106 +++++++++++++++++++++
.../emulation/foundation-armv8/Makefile.inc | 27 ++++++
.../emulation/foundation-armv8/bootblock.c | 23 +++++
.../emulation/foundation-armv8/devicetree.cb | 20 ++++
.../emulation/foundation-armv8/mainboard.c | 27 ++++++
src/mainboard/emulation/foundation-armv8/media.c | 57 +++++++++++
.../emulation/foundation-armv8/romstage.c | 29 ++++++
src/mainboard/emulation/foundation-armv8/timer.c | 24 +++++
src/mainboard/emulation/foundation-armv8/uart.c | 58 +++++++++++
10 files changed, 375 insertions(+)
diff --git a/src/mainboard/emulation/Kconfig b/src/mainboard/emulation/Kconfig
index 3fbc415..452bfd6 100644
--- a/src/mainboard/emulation/Kconfig
+++ b/src/mainboard/emulation/Kconfig
@@ -3,6 +3,9 @@ if VENDOR_EMULATION
choice
prompt "Mainboard model"
+config BOARD_EMULATION_FOUNDATION_ARMV8
+ bool "Foundation ARMV8 (may also work in qemu)"
+
config BOARD_EMULATION_QEMU_X86_I440FX
bool "QEMU x86 i440fx/piix4 (aka qemu -M pc)"
@@ -22,6 +25,7 @@ config BOARD_EMULATION_QEMU_X86
source "src/mainboard/emulation/qemu-i440fx/Kconfig"
source "src/mainboard/emulation/qemu-q35/Kconfig"
source "src/mainboard/emulation/qemu-armv7/Kconfig"
+source "src/mainboard/emulation/foundation-armv8/Kconfig"
config MAINBOARD_VENDOR
string
diff --git a/src/mainboard/emulation/foundation-armv8/Kconfig b/src/mainboard/emulation/foundation-armv8/Kconfig
new file mode 100644
index 0000000..0448f91
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/Kconfig
@@ -0,0 +1,106 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2013 Google Inc.
+##
+## This software is licensed under the terms of the GNU General Public
+## License version 2, as published by the Free Software Foundation, and
+## may be copied, distributed, and modified under those terms.
+##
+## 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.
+
+if BOARD_EMULATION_FOUNDATION_ARMV8
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select ARCH_AARCH64
+ select CPU_ARMLTD_ARMV8
+ select HAVE_UART_MEMORY_MAPPED
+ select HAVE_UART_SPECIAL
+ select BOARD_ROMSIZE_KB_4096
+
+config MAINBOARD_DIR
+ string
+ default emulation/foundation-armv8
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "FOUNDATION ARMV8"
+
+config MAX_CPUS
+ int
+ default 1
+
+config MAINBOARD_VENDOR
+ string
+ default "ARM Ltd."
+
+config BOOTBLOCK_MAINBOARD_INIT
+ string
+ default "mainboard/emulation/foundation-armv8/bootblock.c"
+
+config DRAM_SIZE_MB
+ int
+ default 1024
+
+# Memory map
+#
+# 0xA000_0000: first instruction (called from BL3)
+
+config BOOTBLOCK_BASE
+ hex
+ default 0xA0000000
+
+config ID_SECTION_BASE
+ hex
+ default 0xA001f000
+
+config ROMSTAGE_BASE
+ hex
+ default 0xA0020000
+
+config ROMSTAGE_SIZE
+ hex
+ default 0x20000
+
+config BOOTBLOCK_ROM_OFFSET
+ hex
+ default 0x0
+
+config CBFS_HEADER_ROM_OFFSET
+ hex
+ default 0x0100000
+
+config CBFS_ROM_OFFSET
+ hex
+ default 0x0110000
+
+config IRAM_STACK
+ hex
+ default 0x0007ff00
+
+config XIP_ROM_SIZE
+ hex
+ default ROMSTAGE_SIZE
+
+config SYS_SDRAM_BASE
+ hex "SDRAM base address"
+ default 0x01000000
+
+config SYS_TEXT_BASE
+ hex "Executable code section"
+ default 0x04e00000
+
+config RAMBASE
+ hex
+ default SYS_SDRAM_BASE
+
+# according to stefan, this is RAMBASE + 1M.
+config RAMTOP
+ hex
+ default 0x01100000
+
+endif # BOARD_EMULATION_FOUNDATION_ARMV8
diff --git a/src/mainboard/emulation/foundation-armv8/Makefile.inc b/src/mainboard/emulation/foundation-armv8/Makefile.inc
new file mode 100644
index 0000000..431d9ab
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/Makefile.inc
@@ -0,0 +1,27 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2013 Google Inc.
+##
+## This software is licensed under the terms of the GNU General Public
+## License version 2, as published by the Free Software Foundation, and
+## may be copied, distributed, and modified under those terms.
+##
+## 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.
+
+romstage-y += romstage.c
+
+bootblock-y += media.c
+romstage-y += media.c
+ramstage-y += media.c
+
+bootblock-y += timer.c
+romstage-y += timer.c
+ramstage-y += timer.c
+
+bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c
+romstage-$(CONFIG_EARLY_CONSOLE) += uart.c
+ramstage-y += uart.c
diff --git a/src/mainboard/emulation/foundation-armv8/bootblock.c b/src/mainboard/emulation/foundation-armv8/bootblock.c
new file mode 100644
index 0000000..5654667
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/bootblock.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+
+void bootblock_mainboard_init(void);
+void bootblock_mainboard_init(void)
+{
+ console_init();
+ printk(BIOS_INFO, "\n\n\n%s: ARMv7 Emulation Started.\n", __func__);
+}
diff --git a/src/mainboard/emulation/foundation-armv8/devicetree.cb b/src/mainboard/emulation/foundation-armv8/devicetree.cb
new file mode 100644
index 0000000..9153442
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/devicetree.cb
@@ -0,0 +1,20 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2013 Google, Inc.
+##
+## This software is licensed under the terms of the GNU General Public
+## License version 2, as published by the Free Software Foundation, and
+## may be copied, distributed, and modified under those terms.
+##
+## 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.
+
+# TODO fill with Versatile Express board data in QEMU.
+chip cpu/armltd/cortex-a9
+ chip drivers/generic/generic # I2C0 controller
+ device i2c 6 on end # Fake component for testing
+ end
+end
diff --git a/src/mainboard/emulation/foundation-armv8/mainboard.c b/src/mainboard/emulation/foundation-armv8/mainboard.c
new file mode 100644
index 0000000..eda93c5
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/mainboard.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+
+static void mainboard_enable(device_t dev)
+{
+ printk(BIOS_INFO, "Enable foundation/armv8 device...\n");
+}
+
+struct chip_operations mainboard_ops = {
+ .enable_dev = mainboard_enable,
+};
+
diff --git a/src/mainboard/emulation/foundation-armv8/media.c b/src/mainboard/emulation/foundation-armv8/media.c
new file mode 100644
index 0000000..d024b5d
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/media.c
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+#include <cbfs.h>
+#include <string.h>
+#include <console/console.h>
+
+/* Simple memory-mapped ROM emulation. */
+
+static int emu_rom_open(struct cbfs_media *media) {
+ return 0;
+}
+
+static void *emu_rom_map(struct cbfs_media *media, size_t offset, size_t count) {
+ return (void*)(offset + CONFIG_BOOTBLOCK_BASE);
+}
+
+static void *emu_rom_unmap(struct cbfs_media *media, const void *address) {
+ return NULL;
+}
+
+static size_t emu_rom_read(struct cbfs_media *media, void *dest, size_t offset,
+ size_t count) {
+ void *ptr = emu_rom_map(media, offset, count);
+ memcpy(dest, ptr, count);
+ emu_rom_unmap(media, ptr);
+ return count;
+}
+
+static int emu_rom_close(struct cbfs_media *media) {
+ return 0;
+}
+
+int init_emu_rom_cbfs_media(struct cbfs_media *media);
+int init_emu_rom_cbfs_media(struct cbfs_media *media) {
+ media->open = emu_rom_open;
+ media->close = emu_rom_close;
+ media->map = emu_rom_map;
+ media->unmap = emu_rom_unmap;
+ media->read = emu_rom_read;
+ return 0;
+}
+
+int init_default_cbfs_media(struct cbfs_media *media) {
+ return init_emu_rom_cbfs_media(media);
+}
diff --git a/src/mainboard/emulation/foundation-armv8/romstage.c b/src/mainboard/emulation/foundation-armv8/romstage.c
new file mode 100644
index 0000000..4a16436
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/romstage.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <cbfs.h>
+#include <console/console.h>
+#include <arch/stages.h>
+
+void main(void)
+{
+ void *entry;
+
+ console_init();
+
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
+
+ stage_exit(entry);
+}
diff --git a/src/mainboard/emulation/foundation-armv8/timer.c b/src/mainboard/emulation/foundation-armv8/timer.c
new file mode 100644
index 0000000..53c3789
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/timer.c
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+void udelay(unsigned int n);
+void udelay(unsigned int n) {
+ /* TODO provide delay here. */
+}
+
+int init_timer(void);
+int init_timer(void) {
+ return 0;
+}
diff --git a/src/mainboard/emulation/foundation-armv8/uart.c b/src/mainboard/emulation/foundation-armv8/uart.c
new file mode 100644
index 0000000..26cd4ef
--- /dev/null
+++ b/src/mainboard/emulation/foundation-armv8/uart.c
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <uart.h>
+
+static void pl011_init_dev(void) {
+}
+
+static void pl011_uart_tx_byte(unsigned char data) {
+ static volatile unsigned int *uart0_address = (void *)0;
+
+ *uart0_address = (unsigned int)data;
+}
+
+static void pl011_uart_tx_flush(void) {
+}
+
+#if !defined(__PRE_RAM__)
+
+static const struct console_driver pl011_uart_console __console = {
+ .init = pl011_init_dev,
+ .tx_byte = pl011_uart_tx_byte,
+ .tx_flush = pl011_uart_tx_flush,
+};
+
+uint32_t uartmem_getbaseaddr(void)
+{
+ return 0;
+}
+
+#else
+void uart_init(void)
+{
+ pl011_init_dev();
+}
+
+void uart_tx_byte(unsigned char data)
+{
+ pl011_uart_tx_byte(data);
+}
+
+void uart_tx_flush(void) {
+ pl011_uart_tx_flush();
+}
+#endif