Stefan Reinauer (stefan.reinauer@coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4304
-gerrit
commit 9d6230d299aff1289571448b24747f9c181efc3a Author: Stefan Reinauer reinauer@chromium.org Date: Mon Dec 2 15:47:13 2013 -0800
filo: initial ARM support
Change-Id: I058340985d3aad6ff408f3d0db7d52a45e35a21a --- Config.in | 17 +++- Makefile | 37 ++++++-- arm/Makefile.inc | 23 +++++ arm/include/arch/elf.h | 5 + arm/include/arch/timer.h | 32 +++++++ arm/ldscript | 93 ++++++++++++++++++ main/grub/builtins.c | 6 ++ util/xcompile/xcompile | 242 ++++++++++++++++++++++++++++++++++------------- 8 files changed, 378 insertions(+), 77 deletions(-)
diff --git a/Config.in b/Config.in index cc48bd3..67766fd 100644 --- a/Config.in +++ b/Config.in @@ -5,12 +5,21 @@ mainmenu "FILO Configuration"
# When (if) we support multiple architectures, this will become an option. +choice + prompt "Build for architecture" + default TARGET_I386 + config TARGET_I386 - bool - default y + bool "x86" + +config TARGET_ARM + bool "ARM" + +endchoice
config MULTIBOOT_IMAGE bool "Include a MultiBoot header" + depends on TARGET_I386 default y help Including a MultiBoot header makes FILO chainloadable by MultiBoot @@ -104,6 +113,7 @@ menu "Drivers" config IDE_DISK bool "IDE DISK support" default y + depends on TARGET_I386 help Driver for hard disk, CompactFlash, and CD-ROM on IDE bus
@@ -140,6 +150,7 @@ config IDE_NEW_DISK bool "New IDE driver" default n depends on !IDE_DISK + depends on TARGET_I386 help Jens Axboe's fine IDE driver
@@ -234,7 +245,7 @@ config FSYS_ISO9660 config ELTORITO bool "El Torito bootable CDROMs" default y - depends on FSYS_ISO9660 + depends on FSYS_ISO9660 && TARGET_I386 help Support for boot disk image in bootable CD-ROM (El Torito)
diff --git a/Makefile b/Makefile index a860236..a0aa552 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ export obj := $(src)/build export objk := $(src)/build/util/kconfig
ifndef LIBCONFIG_PATH - LIBCONFIG_PATH := $(src)/../libpayload + LIBCONFIG_PATH := $(src)/../coreboot/payloads/libpayload endif export LIBCONFIG_PATH
@@ -57,17 +57,9 @@ try-run = $(shell set -e; \ fi; \ rm -rf "$$TMP")
-cc-option = $(call try-run,$(CC) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2)) - $(if $(wildcard .xcompile),,$(shell bash util/xcompile/xcompile > .xcompile)) include .xcompile
-CROSS_PREFIX ?= -CC ?= $(CROSS_PREFIX)gcc -m32 -AS ?= $(CROSS_PREFIX)as --32 -LD ?= $(CROSS_PREFIX)ld -belf32-i386 -NM ?= $(CROSS_PREFIX)nm -STRIP ?= $(CROSS_PREFIX)strip HOSTCC ?= gcc HOSTCXX ?= g++ HOSTCFLAGS := -I$(srck) -I$(objk) -pipe @@ -81,6 +73,30 @@ include util/kconfig/Makefile else
include $(src)/.config +ARCH-$(CONFIG_TARGET_I386) := x86 +ARCH-$(CONFIG_TARGET_ARM) := arm + +CC := $(CC_$(ARCH-y)) +AS := $(AS_$(ARCH-y)) +LD := $(LD_$(ARCH-y)) +NM := $(NM_$(ARCH-y)) +OBJCOPY := $(OBJCOPY_$(ARCH-y)) +OBJDUMP := $(OBJDUMP_$(ARCH-y)) +READELF := $(READELF_$(ARCH-y)) +STRIP := $(STRIP_$(ARCH-y)) +AR := $(AR_$(ARCH-y)) + +CFLAGS += $(CFLAGS_$(ARCH-y)) + +cc-option = $(call try-run,$(CC) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2)) + +CROSS_PREFIX ?= + +CC ?= $(CROSS_PREFIX)gcc -m32 +AS ?= $(CROSS_PREFIX)as --32 +LD ?= $(CROSS_PREFIX)ld -belf32-i386 +NM ?= $(CROSS_PREFIX)nm +STRIP ?= $(CROSS_PREFIX)strip
LIBPAYLOAD_PREFIX ?= $(obj)/libpayload LIBPAYLOAD = $(LIBPAYLOAD_PREFIX)/lib/libpayload.a @@ -89,6 +105,7 @@ LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) GCCINCDIR = $(shell $(CC) -print-search-dirs | head -n 1 | cut -d' ' -f2)include
ARCHDIR-$(CONFIG_TARGET_I386) := x86 +ARCHDIR-$(CONFIG_TARGET_ARM) := arm
CPPFLAGS := -nostdinc -imacros $(obj)/config.h CPPFLAGS += -I$(INCPAYLOAD) -I$(INCPAYLOAD)/$(ARCHDIR-y) @@ -120,7 +137,7 @@ else libpayload: $(LIBPAYLOAD) $(LIBPAYLOAD): $(src)/$(LIB_CONFIG) @printf "Building libpayload...\n" - $(MAKE) -C $(LIBCONFIG_PATH) obj=$(obj)/libpayload-build distclean + CROSS_COMPILE_$(ARCH-y)=$(CROSS_COMPILE_$(ARCH-y)) $(MAKE) -C $(LIBCONFIG_PATH) obj=$(obj)/libpayload-build distclean cp lib.config $(LIBCONFIG_PATH)/.config mkdir -p $(LIBCONFIG_PATH)/build $(MAKE) -C $(LIBCONFIG_PATH) obj=$(obj)/libpayload-build oldconfig diff --git a/arm/Makefile.inc b/arm/Makefile.inc new file mode 100644 index 0000000..4ccb409 --- /dev/null +++ b/arm/Makefile.inc @@ -0,0 +1,23 @@ +# +# 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; 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +#TARGETS-$(CONFIG_TARGET_I386) += x86/context.o x86/switch.S.o x86/segment.o +#TARGETS-$(CONFIG_TARGET_I386) += x86/timer.o x86/sys_info.o +#TARGETS-$(CONFIG_LINUX_LOADER) += x86/linux_load.o +#TARGETS-$(CONFIG_WINCE_LOADER) += x86/wince_load.o +#TARGETS-$(CONFIG_ARTEC_BOOT) += x86/artecboot.o diff --git a/arm/include/arch/elf.h b/arm/include/arch/elf.h new file mode 100644 index 0000000..2a5bbbf --- /dev/null +++ b/arm/include/arch/elf.h @@ -0,0 +1,5 @@ +#define ARCH_ELF_CLASS ELFCLASS32 +#define ARCH_ELF_DATA ELFDATA2LSB +#define ARCH_ELF_MACHINE_OK(x) ((x)==EM_ARM) +typedef Elf32_Ehdr Elf_ehdr; +typedef Elf32_Phdr Elf_phdr; diff --git a/arm/include/arch/timer.h b/arm/include/arch/timer.h new file mode 100644 index 0000000..3cdd9b4 --- /dev/null +++ b/arm/include/arch/timer.h @@ -0,0 +1,32 @@ +/* + * This file is part of FILO. + * + * (C) 2004-2008 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 + */ + +#ifndef TIMER_H +#define TIMER_H + +extern u32 cpu_khz; + +u64 currticks(void); +int getrtsecs (void); + +#define TICKS_PER_SEC (cpu_khz * 1000) +#define TICKS_PER_USEC (cpu_khz / 1000) + + +#endif /* TIMER_H */ diff --git a/arm/ldscript b/arm/ldscript new file mode 100644 index 0000000..a6c7e11 --- /dev/null +++ b/arm/ldscript @@ -0,0 +1,93 @@ +/* + * This file is part of FILO. + * + * 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 + */ + +/* When started from General Software BIOS */ +/* BASE_ADDR = 0x40000; */ +/* When started from coreboot */ +BASE_ADDR = 0x100000; + + +OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +ENTRY(entry) + +/* 1024KB heap and 64KB stack */ +HEAP_SIZE = 1 * 1024 * 1024; +STACK_SIZE = 64 * 1024; + +SECTIONS +{ + . = BASE_ADDR; + + /* Put Multiboot header near beginning of file, if any. */ + .hdr : { *(.hdr) *(.hdr.*) } + + /* Start of the program. + * Now the version string is in the note, we must include it + * in the program. Otherwise we lose the string after relocation. */ + . = ALIGN(4096); + _start = .; + + /* Putting ELF notes near beginning of file might help bootloaders. + * We discard .note sections other than .note.ELFBoot and .note.pinfo, + * because some versions of GCC generates useless ones. */ + .note : { *(.note.ELFBoot) *(note.pinfo) } + + /* Normal sections */ + .boot : { *(.boot) *(.boot.*) } + .text : { *(.text) *(.text.*) } + .rodata : { + . = ALIGN(4); + drivers_start = .; + *(.rodata.drivers) + drivers_end = .; + *(.rodata) + *(.rodata.*) + } + .data : { *(.data) *(.data.*) } + + .bss : { + *(.sbss) + *(.sbss.*) + *(.bss) + *(.bss.*) + *(COMMON) + + /* heap and stack */ + + . = ALIGN(16); + _heap = .; + . += HEAP_SIZE; + . = ALIGN(16); + _eheap = .; + + _stack = .; + . += STACK_SIZE; + . = ALIGN(16); + _estack = .; + } + + .initctx : { + /* Initial contents of stack. This MUST BE just after the stack. */ + *(.initctx) + } + + _end = .; + + /DISCARD/ : { *(.comment) *(.note) } +} diff --git a/main/grub/builtins.c b/main/grub/builtins.c index cd079d1..a2385c5 100644 --- a/main/grub/builtins.c +++ b/main/grub/builtins.c @@ -461,6 +461,7 @@ static struct builtin builtin_dumpmem = { /* dumppm */ static int dumppm_func(char *arg, int flags) { +#if CONFIG_TARGET_I386 u16 pmbase;
pmbase = pci_read_config16(PCI_DEV(0,0x1f, 0), 0x40) & 0xfffe; @@ -495,6 +496,7 @@ static int dumppm_func(char *arg, int flags) grub_printf("pmbase+0x0070: 0x%02x (TCO_SW_IRQ_GEN)\n", inb(pmbase+0x0070)); grub_printf("pmbase+0x0072: 0x%04x (TCO_TMR)\n", inw(pmbase+0x0072)); #endif +#endif return 0; }
@@ -857,6 +859,7 @@ static struct builtin builtin_initrd = {
#ifdef CONFIG_DEVELOPER_TOOLS +#ifdef CONFIG_TARGET_I386 /* io */ static int io_func(char *arg, int flags) { @@ -964,6 +967,7 @@ static struct builtin builtin_io = { "Read/write IO ports." }; #endif +#endif
/* kernel */ static int kernel_func(char *arg, int flags) @@ -1931,8 +1935,10 @@ struct builtin *builtin_table[] = { &builtin_hiddenmenu, &builtin_initrd, #ifdef CONFIG_DEVELOPER_TOOLS +#ifdef CONFIG_TARGET_I386 &builtin_io, #endif +#endif &builtin_kernel, &builtin_keymap, &builtin_lock, diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile index 7c1adf3..9019788 100644 --- a/util/xcompile/xcompile +++ b/util/xcompile/xcompile @@ -3,6 +3,7 @@ # This file is part of the coreboot project. # # Copyright (C) 2007-2010 coresystems GmbH +# Copyright (C) 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 @@ -15,89 +16,202 @@ # # 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 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #
-testcc() -{ - echo "_start(void) {}" > .$$$$.c - $1 -nostdlib $2 .$$$$.c -o .$$$$.tmp 2>/dev/null >/dev/null - ret=$? - rm -f .$$$$.c .$$$$.tmp - return $ret +TMPFILE="" + +die() { + echo "ERROR: $*" >&2 + exit 1 }
-for make in make gmake gnumake; do - if [ "`$make --version 2>/dev/null | grep -c GNU`" -gt 0 ]; then - MAKE=$make - break +clean_up() { + if [ -n "$TMPFILE" ]; then + rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o" fi -done +} + +program_exists() { + type "$1" >/dev/null 2>&1 +}
-GCCPREFIX=invalid -TMPFILE=`mktemp /tmp/temp.XXXXXX 2>/dev/null || echo /tmp/temp.78gOIUGz` -touch $TMPFILE +testcc() { + local tmp_c="$TMPFILE.c" + local tmp_o="$TMPFILE.o" + rm -f "$tmp_c" "$tmp_o" + echo "void _start(void) {}" >"$tmp_c" + "$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1 +} + +testas() { + local gccprefixes="$1" + local twidth="$2" + local arch="$3" + local use_dash_twidth="$4" + local obj_file="$TMPFILE.o" + local full_arch="elf$twidth-$arch" + + rm -f "$obj_file" + [ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth" + ${gccprefixes}as $use_dash_twidth -o "$obj_file" $TMPFILE 2>/dev/null || + return 1 + + # Check output content type. + local obj_type="$(${gccprefixes}objdump -p $obj_file)" + local obj_arch="$(expr "$obj_type" : '.*format (.[a-z0-9-]*)')" + [ "$obj_arch" = "$full_arch" ] || return 1 + + # Architecture matched. + GCCPREFIX="$gccprefixes" + + if [ -z "$use_dash_twidth" ]; then + ASFLAGS="" + CFLAGS="" + LDFLAGS="" + else + ASFLAGS="--$twidth" + CFLAGS="-m$twidth" + LDFLAGS="-b $full_arch"
-# This should be a loop over all supported architectures -TARCH=i386 -TWIDTH=32 -for gccprefixes in `pwd`/../../util/crossgcc/xgcc/bin/${TARCH}-elf- ${TARCH}-elf- ""; do - if ! which ${gccprefixes}as 2>/dev/null >/dev/null; then - continue - fi - rm -f ${TMPFILE}.o - if ${gccprefixes}as -o ${TMPFILE}.o ${TMPFILE}; then - TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o` - if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then - GCCPREFIX=$gccprefixes - ASFLAGS= - CFLAGS= - LDFLAGS= - break - fi fi - if ${gccprefixes}as --32 -o ${TMPFILE}.o ${TMPFILE}; then - TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o` - if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then - GCCPREFIX=$gccprefixes - ASFLAGS=--32 - CFLAGS="-m32 " - LDFLAGS="-b elf32-i386" - break - fi + + # Special parameters only available in dash_twidth mode. + [ -n "$use_dash_twidth" ] && case "$full_arch" in + "elf32-i386" ) + LDFLAGS="$LDFLAGS -melf_i386" + CFLAGS="$CFLAGS -Wl,-b,elf32-i386 -Wl,-melf_i386" + ;; + esac + + return 0 +} + +detect_special_flags() { + local architecture="$1" + # GCC 4.6 is much more picky about unused variables. + # Turn off it's warnings for now: + testcc "$CC" "$CFLAGS -Wno-unused-but-set-variable " && + CFLAGS="$CFLAGS -Wno-unused-but-set-variable " + + testcc "$CC" "$CFLAGS -Wa,--divide" && + CFLAGS="$CFLAGS -Wa,--divide" + testcc "$CC" "$CFLAGS -fno-stack-protector"&& + CFLAGS="$CFLAGS -fno-stack-protector" + testcc "$CC" "$CFLAGS -Wl,--build-id=none" && + CFLAGS="$CFLAGS -Wl,--build-id=none" + + case "$architecture" in + x86 ) + # Use bfd linker instead of gold if available: + testcc "$CC" "$CFLAGS -fuse-ld=bfd" && + CFLAGS="$CFLAGS -fuse-ld=bfd" && LINKER_SUFFIX_i386='.bfd' + # Always build for i686 -- no sse/mmx instructions since SMM + # modules are compiled using these flags. Note that this + # doesn't prevent a project using xcompile to explicitly + # specify -mmsse, etc flags. + CFLAGS="$CFLAGS -march=i686" + ;; + arm ) + ARMFLAGS="" + testcc "$CC" "$CFLAGS $ARMFLAGS" && CFLAGS="$CFLAGS $ARMFLAGS" + ;; + esac +} + +report_arch_toolchain() { + cat <<EOF +# elf${TWIDTH}-${TBFDARCH} toolchain (${GCCPREFIX}gcc) +CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS} +AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS} +LD_${TARCH}:=${GCCPREFIX}ld$(eval echo ${LINKER_SUFFIX_${TARCH}}) ${LDFLAGS} +NM_${TARCH}:=${GCCPREFIX}nm +OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy +OBJDUMP_${TARCH}:=${GCCPREFIX}objdump +READELF_${TARCH}:=${GCCPREFIX}readelf +STRIP_${TARCH}:=${GCCPREFIX}strip +AR_${TARCH}:=${GCCPREFIX}ar + +EOF +} + +# Create temporary file(s). +TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)" +touch "$TMPFILE" +trap clean_up EXIT + +# Architecture definition +SUPPORTED_ARCHITECTURE="x86 arm" + +# ARM Architecture +TARCH_arm="arm" +TBFDARCH_arm="littlearm" +TCLIST_arm="armv7a" +TWIDTH_arm="32" + +# X86 Architecture +TARCH_x86="i386" +TBFDARCH_x86="i386" +TCLIST_x86="i386 x86_64" +TWIDTH_x86="32" +XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"} + +# This loops over all supported architectures. +for architecture in $SUPPORTED_ARCHITECTURE; do + GCCPREFIX="invalid" + TARCH="$(eval echo $TARCH_$architecture)" + TBFDARCH="$(eval echo $TBFDARCH_$architecture)" + TCLIST="$(eval echo $TCLIST_$architecture)" + TWIDTH="$(eval echo $TWIDTH_$architecture)" + [ -z "$TARCH" -o -z "$TCLIST" -o -z "$TWIDTH" ] && + die "Missing architecture definition for $architecture." + + # To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as + # environment variable. + # Ex: CROSS_COMPILE_arm="armv7a-cros-linux-gnueabi-" + # CROSS_COMPILE_x86="i686-pc-linux-gnu-" + search="$(eval echo $CROSS_COMPILE_$architecture 2>/dev/null)" + search="$search $CROSS_COMPILE" + for toolchain in $TCLIST; do + search="$search $XGCCPATH$toolchain-elf-" + search="$search $toolchain-elf-" + search="$search $XGCCPATH$toolchain-eabi-" + search="$search $toolchain-eabi-" + done + echo "# $architecture TARCH_SEARCH=$search" + + # Search toolchain by checking assembler capability. + for gccprefixes in $search ""; do + program_exists "${gccprefixes}as" || continue + testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break + testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break + done + + if [ "$GCCPREFIX" = "invalid" ]; then + echo "Warning: no suitable GCC for $architecture." >&2 + continue fi + CC="${GCCPREFIX}"gcc + + detect_special_flags "$architecture" + report_arch_toolchain done -rm -f $TMPFILE ${TMPFILE}.o
-if [ "$GCCPREFIX" = "invalid" ]; then - echo '$(error no suitable gcc found)' - exit 1 +if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then + IASL=${XGCCPATH}iasl +else + IASL=iasl fi
-CC="${GCCPREFIX}gcc" -testcc "$CC" "$CFLAGS-Wa,--divide " && CFLAGS="$CFLAGS-Wa,--divide " -testcc "$CC" "$CFLAGS-fno-stack-protector " && CFLAGS="$CFLAGS-fno-stack-protector " -testcc "$CC" "$CFLAGS-Wl,--build-id=none " && CFLAGS="$CFLAGS-Wl,--build-id=none " - -if which gcc 2>/dev/null >/dev/null; then +if program_exists gcc; then HOSTCC=gcc else HOSTCC=cc fi
-cat << EOF -# elf${TWIDTH}-${TARCH} toolchain -AS:=${GCCPREFIX}as ${ASFLAGS} -CC:=${GCCPREFIX}gcc ${CFLAGS} -CPP:=${GCCPREFIX}cpp -AR:=${GCCPREFIX}ar -LD:=${GCCPREFIX}ld ${LDFLAGS} -STRIP:=${GCCPREFIX}strip -NM:=${GCCPREFIX}nm -OBJCOPY:=${GCCPREFIX}objcopy -OBJDUMP:=${GCCPREFIX}objdump +cat <<EOF +IASL:=${IASL}
# native toolchain HOSTCC:=${HOSTCC} EOF -