From b8028f1425b1ade18939a19bccf07aae6d820a60 Mon Sep 17 00:00:00 2001
From: Yang Hamo Bai <hamo.by@gmail.com>
Date: Thu, 30 Jun 2011 20:33:08 +0800
Subject: [PATCH 12/12] ARM: added code for creating rom with bootblock

Till now, we can create rom file only with bootblock now.

Signed-off-by: Yang Hamo Bai <hamo.by@gmail.com>
---
 src/arch/arm/Kconfig                              |   23 +++
 src/arch/arm/Makefile.inc                         |  115 ++++++++++++++++
 src/arch/arm/bootblock.ld                         |   37 +++++
 src/arch/arm/lib/walkcbfs.S                       |  150 +++++++++++++++++++++
 src/mainboard/armltd/versatile_pb/lowlevel_init.S |   28 ++++
 5 files changed, 353 insertions(+), 0 deletions(-)
 create mode 100644 src/arch/arm/Makefile.inc
 create mode 100644 src/arch/arm/bootblock.ld
 create mode 100644 src/arch/arm/lib/walkcbfs.S
 create mode 100644 src/mainboard/armltd/versatile_pb/lowlevel_init.S

diff --git a/src/arch/arm/Kconfig b/src/arch/arm/Kconfig
index 7a7f42f..c1bb8a5 100644
--- a/src/arch/arm/Kconfig
+++ b/src/arch/arm/Kconfig
@@ -1,3 +1,26 @@
 menu "Architecture (ARM)"
 
+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
+
+config ARCH
+       string
+       default arm
+       depends on ARCH_ARM
+
+config IOBASE
+       hex
+
+config ROMBASE
+       hex
+
+config RAMBASE
+       hex
+
diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc
new file mode 100644
index 0000000..e24c8dd
--- /dev/null
+++ b/src/arch/arm/Makefile.inc
@@ -0,0 +1,115 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2010 Google Inc.
+## Copyright (C) 2011 Yang Bai <hamo.by@gmail.com>
+##
+## 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
+##
+
+#######################################################################
+# Take care of subdirectories
+
+subdirs-y += lib
+
+#######################################################################
+# Build the final rom image
+COREBOOT_ROM_DEPENDENCIES:=
+ifneq ($(CONFIG_PAYLOAD_NONE),y)
+COREBOOT_ROM_DEPENDENCIES+=$(CONFIG_FALLBACK_PAYLOAD_FILE)
+endif
+ifeq ($(CONFIG_VGA_BIOS),y)
+COREBOOT_ROM_DEPENDENCIES+=$(CONFIG_FALLBACK_VGA_BIOS_FILE)
+endif
+ifeq ($(CONFIG_BOOTSPLASH),y)
+COREBOOT_ROM_DEPENDENCIES+=$(CONFIG_FALLBACK_BOOTSPLASH_FILE)
+endif
+
+$(obj)/coreboot.rom: $(obj)/coreboot.pre1
+
+
+#######################################################################
+# ARM specific tools
+
+
+#######################################################################
+# Build the coreboot_ram (stage 2)
+
+
+#######################################################################
+# done
+
+
+#######################################################################
+# Build the final rom image
+
+ifneq ($(CONFIG_UPDATE_IMAGE),y)
+$(obj)/coreboot.pre1: $(obj)/coreboot.bootblock $(CBFSTOOL)
+	rm -f $@
+	@printf "    CBFSCREATE $(subst $(obj)/,,$(@))\n"
+	$(CBFSTOOL) $@ create ARM $(CONFIG_COREBOOT_ROMSIZE_KB)K $(obj)/coreboot.bootblock
+else
+$(obj)/coreboot.pre1: $(CBFSTOOL)
+	mv $(obj)/coreboot.rom $@
+endif
+
+$(obj)/coreboot.pre: $(obj)/coreboot.romstage $(obj)/coreboot.pre1 $(CBFSTOOL)
+	@printf "    CBFS       $(subst $(obj)/,,$(@))\n"
+	rm -f $@
+	cp $(obj)/coreboot.pre1 $@
+	$(CBFSTOOL) $@ add-stage $(obj)/romstage.elf $(CONFIG_CBFS_PREFIX)/romstage x 0x$(shell cat $(obj)/location.txt)
+#FIXME: location.txt might require an offset of header size
+
+#######################################################################
+# Build the bootblock
+
+$(obj)/coreboot.bootblock: $(obj)/bootblock.elf
+	@printf "    OBJCOPY    $(subst $(obj)/,,$(@))\n"
+	$(OBJCOPY) -O binary $< $@
+
+bootblock_lds = $(src)/arch/arm/bootblock.ld
+
+bootblock_inc =  $(src)/cpu/arm/$(CPUDIR)/start.S
+bootblock_inc += $(src)/mainboard/$(MAINBOARDDIR)/lowlevel_init.S
+bootblock_inc += $(src)/arch/arm/lib/walkcbfs.S
+
+$(obj)/bootblock/ldscript.ld: $$(bootblock_lds) $(obj)/ldoptions
+	@printf "    GEN        $(subst $(obj)/,,$(@))\n"
+	mkdir -p $(obj)/bootblock
+	printf '$(foreach ldscript,ldoptions $(bootblock_lds),INCLUDE "$(ldscript)"\n)' > $@
+
+$(obj)/bootblock/bootblock.S: $$(bootblock_inc)
+	@printf "    GEN        $(subst $(obj)/,,$(@))\n"
+	mkdir -p $(obj)/bootblock
+	printf '$(foreach crt0,config.h $(bootblock_inc),#include "$(crt0)"\n)' > $@
+
+$(obj)/bootblock/bootblock.o: $(obj)/bootblock/bootblock.s
+	@printf "    CC         $(subst $(obj)/,,$(@))\n"
+	$(CC) -I$(obj) -Wa,-acdlns -c -o $@ $<  > $(dir $@)/crt0.disasm
+
+$(obj)/bootblock/bootblock.s: $(obj)/bootblock/bootblock.S
+	@printf "    CC         $(subst $(obj)/,,$(@))\n"
+	$(CC) -MMD -DASSEMBLY -E -I$(src)/include -I$(src)/arch/arm/include -I$(obj) -I$(obj)/bootblock -include $(obj)/config.h -I. -I$(src) $< -o $@
+
+$(obj)/bootblock.elf: $(obj)/bootblock/bootblock.o $(obj)/bootblock/ldscript.ld
+	@printf "    LINK       $(subst $(obj)/,,$(@))\n"
+	$(CC) -nostdlib -nostartfiles -static -o $@ -L$(obj) -T $(obj)/bootblock/ldscript.ld $<  $(LIBGCC_FILE_NAME)
+	$(NM) -n $(obj)/bootblock.elf | sort > $(obj)/bootblock.map
+	$(OBJCOPY) --only-keep-debug $@ $(obj)/bootblock.debug
+	$(OBJCOPY) --strip-debug $@
+	$(OBJCOPY) --add-gnu-debuglink=$(obj)/bootblock.debug $@
+
+#######################################################################
+# Build the romstage
+
diff --git a/src/arch/arm/bootblock.ld b/src/arch/arm/bootblock.ld
new file mode 100644
index 0000000..403b086
--- /dev/null
+++ b/src/arch/arm/bootblock.ld
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ *  Copyright (C) 2011 Yang Bai <hamo.by@gmail.com>
+ *
+ * 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("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = CONFIG_ROMBASE;
+
+	. = ALIGN(4);
+	.text :
+	{
+		*(.text)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+}
diff --git a/src/arch/arm/lib/walkcbfs.S b/src/arch/arm/lib/walkcbfs.S
new file mode 100644
index 0000000..73c0ece
--- /dev/null
+++ b/src/arch/arm/lib/walkcbfs.S
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ *  Copyright (C) 2011 Yang Bai <hamo.by@gmail.com>
+ *
+ * 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
+ *
+ */
+
+#define CBFS_HEADER 0x20
+
+#define CBFS_HEADER_MAGIC 0
+#define CBFS_HEADER_VERSION (CBFS_HEADER_MAGIC + 4)
+#define CBFS_HEADER_ROMSIZE (CBFS_HEADER_VERSION + 4)
+#define CBFS_HEADER_BOOTBLOCKSIZE (CBFS_HEADER_ROMSIZE + 4)
+#define CBFS_HEADER_ALIGN (CBFS_HEADER_BOOTBLOCKSIZE + 4)
+#define CBFS_HEADER_OFFSET (CBFS_HEADER_ALIGN + 4)
+
+#define CBFS_FILE_MAGIC 0
+#define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8)
+#define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4)
+#define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4)
+#define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4)
+
+#define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4)
+
+/*
+ * input r0: filename
+ * input lr: return address
+ * output r1: entry point
+ */
+	
+.globl walkcbfs_asm
+walkcbfs_asm:
+	ldr r2, =(CONFIG_ROMBASE + CBFS_HEADER)
+	ldr r3, [r2, #CBFS_HEADER_OFFSET]
+#ifdef ARMv6
+	rev r3, r3
+#else
+	eor r8, r3, r3, ror #16
+	bic r8, r8, #0xFF0000
+	mov r3, r3, ror #8
+	eor r3, r3, r8, lsr #8
+#endif
+	add r3, r3, #CONFIG_ROMBASE        /* address where we start looking for LARCHIVEs */
+
+	ldr r7, [r2, #CBFS_HEADER_ROMSIZE]
+#ifdef ARMv6
+	rev r7, r7
+#else
+	eor r8, r7, r7, ror #16
+	bic r8, r8, #0xFF0000
+	mov r7, r7, ror #8
+	eor r7, r7, r8, lsr #8
+#endif
+	add r7, r7, #CONFIG_ROMBASE /* end of ROM address */
+
+	/* determine filename length */
+	mov r1, r0  /* Save filename pointer */
+	ldr r2, =0
+1:	ldrb r4, [r1], #1
+	cmp r4, #0
+	beq 2f
+	add r2, r2, #1
+	b 1b
+2:
+	add r2, r2, #1
+	
+walker:
+	ldr r1, [r3]
+	ldr r4, =filemagic
+	ldr r4, [r4]
+	cmp r1, r4
+	bne searchfile
+	ldr r1, [r3, #4]
+	ldr r4, =(filemagic+4)
+	ldr r4, [r4]
+	cmp r1, r4
+	bne searchfile
+
+	/*LARCHIVE header found */
+	mov r1, r3
+	add r1, r1, #CBFS_FILE_STRUCTSIZE  /* r1 = address of first byte after struct cbfs_file */
+	/* compare file name */
+	ldr r6, =0
+1:	ldrb r4, [r1, r6]
+	ldrb r5, [r0, r6]
+	cmp  r4, r5
+	bne tryharder
+	add r6, r6, #1
+	cmp r6, r2
+	bne  1b
+
+	/* we found it! */
+	ldr r1, [r3, #CBFS_FILE_OFFSET]
+#ifdef ARMv6
+	rev r1, r1
+#else
+	eor r8, r1, r1, ror #16
+	bic r8, r8, #0xFF0000
+	mov r1, r1, ror #8
+	eor r1, r1, r8, lsr #8
+#endif
+
+	add r1, r3, r1
+	mov pc, lr
+
+	// TODO
+tryharder:
+	b searchfile
+
+
+check_for_exit:
+	/* look if we should exit: did we pass out the whole rom already? */
+	cmp r3, r7
+	blt walker
+
+out:
+	ldr r1, =0
+	mov pc, lr
+	
+searchfile:
+	/* if filemagic isn't found, move forward cbfs_header->align bytes */
+	ldr r2, =(CONFIG_ROMBASE + CBFS_HEADER)
+	ldr r2, [r2, #CBFS_HEADER_ALIGN]
+#ifdef ARMv6
+	rev r2, r2
+#else
+	eor r8, r2, r2, ror #16
+	bic r8, r8, #0xFF0000
+	mov r2, r2, ror #8
+	eor r2, r2, r8, lsr #8
+#endif
+	add r3, r3, r2
+	b check_for_exit
+
+.section ".rodata"	
+filemagic:
+	.ascii "LARCHIVE"
diff --git a/src/mainboard/armltd/versatile_pb/lowlevel_init.S b/src/mainboard/armltd/versatile_pb/lowlevel_init.S
new file mode 100644
index 0000000..8bf6a26
--- /dev/null
+++ b/src/mainboard/armltd/versatile_pb/lowlevel_init.S
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * (C) Copyright 2003, ARM Ltd.
+ * Philippe Robin, <philippe.robin@arm.com>
+ *
+ * Copyright (C) 2011 Yang Bai <hamo.by@gmail.com>
+ *
+ * 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
+ */
+
+/* Set up the platform, once the cpu has been initialized */
+.globl lowlevel_init
+lowlevel_init:
+
+	/* All done by Versatile's boot monitor! */
+	mov pc, lr
-- 
1.7.6

