Ronald G. Minnich (rminnich@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4271
-gerrit
commit 696cacfb22e4d5746ca681f11d41322b05cca533 Author: Ronald G. Minnich rminnich@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@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 | 62 ++++++ 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, 1639 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@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 $@).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 $@).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 $@).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..10363c4 --- /dev/null +++ b/src/arch/aarch64/include/assembler.h @@ -0,0 +1,62 @@ +/* + * 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 + +/* + * Data preload for architectures that support it + */ +#if defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \ + defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ + defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || \ + defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__) +#define PLD(code...) code +#else +#define PLD(code...) +#endif + +/* + * Cache aligned + */ +#define CALGN(code...) code + +#define W(instr) instr 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@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(); +}