Add support for romlib in the build system

Romlib is a new image that is stored in ROM and contains the code of
several libraries that can be shared between different images. All
the functions within in the library are accessed using a jump table
which allows to update the romlib image whithout changing the binary
compatibility. This jump table can be also stored in RAM and it can
allow to patch a romlib with potential bugs fixes..

Change-Id: If980ccdaca24b7aaca900e32acc68baf6f94ab35
Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
diff --git a/Makefile b/Makefile
index 8a1ff94..18c4873 100644
--- a/Makefile
+++ b/Makefile
@@ -505,6 +505,9 @@
 FIPTOOLPATH		?=	tools/fiptool
 FIPTOOL			?=	${FIPTOOLPATH}/fiptool${BIN_EXT}
 
+# Variables for use with ROMLIB
+ROMLIBPATH		?=	lib/romlib
+
 ################################################################################
 # Include BL specific makefiles
 ################################################################################
@@ -573,6 +576,7 @@
 $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
 $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
 $(eval $(call assert_boolean,USE_COHERENT_MEM))
+$(eval $(call assert_boolean,USE_ROMLIB))
 $(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
 $(eval $(call assert_boolean,BL2_AT_EL3))
@@ -625,6 +629,7 @@
 $(eval $(call add_define,SPIN_ON_BL1_EXIT))
 $(eval $(call add_define,TRUSTED_BOARD_BOOT))
 $(eval $(call add_define,USE_COHERENT_MEM))
+$(eval $(call add_define,USE_ROMLIB))
 $(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
 $(eval $(call add_define,BL2_AT_EL3))
@@ -669,7 +674,7 @@
     CPPFLAGS		+= 	-Wno-error=deprecated-declarations -Wno-error=cpp
 endif
 
-$(eval $(call MAKE_LIB_DIR))
+$(eval $(call MAKE_LIB_DIRS))
 $(eval $(call MAKE_LIB,c))
 
 # Expand build macros for the different images
@@ -736,6 +741,7 @@
 	$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
 	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
 
 realclean distclean:
 	@echo "  REALCLEAN"
@@ -743,6 +749,7 @@
 	$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
 	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
 
 checkcodebase:		locate-checkpatch
 	@echo "  CHECKING STYLE"
@@ -821,6 +828,10 @@
 ${FIPTOOL}:
 	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${FIPTOOLPATH}
 
+.PHONY: libraries
+romlib.bin: libraries
+	${Q}${MAKE} BUILD_PLAT=${BUILD_PLAT} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
+
 cscope:
 	@echo "  CSCOPE"
 	${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
diff --git a/include/common/romlib.h b/include/common/romlib.h
new file mode 100644
index 0000000..81a6f5c
--- /dev/null
+++ b/include/common/romlib.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROMLIB_H_
+
+#define ROMLIB_MAJOR   0
+#define ROMLIB_MINOR   1
+#define ROMLIB_VERSION ((ROMLIB_MAJOR << 8) | ROMLIB_MINOR)
+
+int rom_lib_init(int version);
+
+#endif
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
new file mode 100644
index 0000000..46b9206
--- /dev/null
+++ b/lib/romlib/Makefile
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+AS          = $(CROSS_COMPILE)as
+LD          = $(CROSS_COMPILE)ld
+OC          = $(CROSS_COMPILE)objcopy
+CPP         = $(CROSS_COMPILE)cpp
+BUILD_DIR   = ../../$(BUILD_PLAT)/romlib
+LIB_DIR     = ../../$(BUILD_PLAT)/lib
+WRAPPER_DIR = ../../$(BUILD_PLAT)/libwrapper
+LIBS        = -lmbedtls -lfdt -lc
+INC         = $(INCLUDES:-I%=-I../../%)
+PPFLAGS     = $(INC) $(DEFINES) -P -D__ASSEMBLY__ -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld
+OBJS        = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o
+
+V ?= 0
+ifeq ($(V),0)
+  Q := @
+else
+  Q :=
+endif
+
+ifeq ($(DEBUG),1)
+   CFLAGS  := -g
+   LDFLAGS := -g
+endif
+
+
+.PHONY: all clean distclean
+
+all: $(BUILD_DIR)/romlib.bin $(LIB_DIR)/libwrappers.a
+
+%.o: %.s
+	@echo "  AS      $@"
+	$(Q)$(AS) $(ASFLAGS) -o $@ $<
+
+$(BUILD_DIR)/%.o: %.s
+	@echo "  AS      $@"
+	$(Q)$(AS) $(ASFLAGS) -o $@ $<
+
+$(BUILD_DIR)/romlib.ld: romlib.ld.S
+	@echo "  PP      $@"
+	$(Q)$(CPP) $(PPFLAGS) -o $@ romlib.ld.S
+
+$(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld
+	@echo "  LD      $@"
+	$(Q)$(LD) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+$(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf
+	@echo "  BIN     $@"
+	$(Q)$(OC) -O binary $(BUILD_DIR)/romlib.elf $@
+
+$(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf
+	@echo "  VAR     $@"
+	$(Q)./genvar.sh -o $@ $(BUILD_DIR)/romlib.elf
+
+$(LIB_DIR)/libwrappers.a: jmptbl.i $(WRAPPER_DIR)/jmpvar.o
+	@echo "  AR      $@"
+	$(Q)./genwrappers.sh -b $(WRAPPER_DIR) -o $@ jmptbl.i
+
+$(BUILD_DIR)/jmptbl.s: jmptbl.i
+	@echo "  TBL     $@"
+	$(Q)./gentbl.sh -o $@ jmptbl.i
+
+clean:
+	@rm -f $(BUILD_DIR)/*
+
+-include $(BUILD_DIR)/romlib.d
diff --git a/lib/romlib/gentbl.sh b/lib/romlib/gentbl.sh
new file mode 100755
index 0000000..0695f6e
--- /dev/null
+++ b/lib/romlib/gentbl.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -e
+
+output=jmptbl.s
+
+for i
+do
+	case $i in
+	-o)
+		output=$2
+		shift 2
+		;;
+	--)
+		shift
+		break
+		;;
+	-*)
+		echo usage: gentbl.sh [-o output]  file ... >&2
+		exit 1
+		;;
+	esac
+done
+
+tmp=`mktemp`
+trap "rm -f $tmp" EXIT INT QUIT
+
+rm -f $output
+
+awk -v OFS="\n" '
+BEGIN {print "\t.text",
+             "\t.globl\tjmptbl",
+             "jmptbl:"}
+      {sub(/[:blank:]*#.*/,"")}
+!/^$/ {print "\tb\t" $3}' "$@" > $tmp
+
+mv $tmp $output
diff --git a/lib/romlib/genvar.sh b/lib/romlib/genvar.sh
new file mode 100755
index 0000000..a3e2cdf
--- /dev/null
+++ b/lib/romlib/genvar.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -e
+
+output=jmpvar.s
+for i
+do
+	case $i in
+	-o)
+		output=$2
+		shift 2
+		;;
+	--)
+		shift
+		break
+		;;
+	-*)
+		echo usage: genvar.sh [-o output] file... >&2
+		;;
+	esac
+done
+
+tmp=`mktemp`
+trap "rm -f $tmp" EXIT INT QUIT
+
+nm -a "$@" |
+awk -v OFS="\n" '
+$3 == ".text" {print "\t.data",
+                     "\t.globl\tjmptbl",
+                     "\t.align\t4",
+                     "jmptbl:\t.quad\t0x" $1}' > $tmp
+
+mv $tmp $output
diff --git a/lib/romlib/genwrappers.sh b/lib/romlib/genwrappers.sh
new file mode 100755
index 0000000..bcf670b
--- /dev/null
+++ b/lib/romlib/genwrappers.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -e
+
+build=.
+out=output.a
+
+for i
+do
+	case $i in
+	-o)
+		out=$2
+		shift 2
+		;;
+	-b)
+		build=$2
+		shift 2
+		;;
+	--)
+		shift
+		break
+		;;
+	-*)
+		echo usage: genwrappers.sh [-o output] [-b dir] file ... >&2
+		exit 1
+		;;
+	esac
+done
+
+awk  '{sub(/[:blank:]*#.*/,"")}
+!/^$/ {print $1*4, $2, $3}' "$@" |
+while read idx lib sym
+do
+	file=$build/${lib}_$sym
+
+	cat <<EOF > $file.s
+	.globl	$sym
+$sym:
+	ldr	x17, =jmptbl
+	ldr	x17, [x17]
+	mov	x16, $idx
+	add	x16, x16, x17
+	br	x16
+EOF
+
+	${CROSS_COMPILE}as -o $file.o $file.s
+done
+
+${CROSS_COMPILE}ar -rc $out $build/*.o
diff --git a/lib/romlib/init.s b/lib/romlib/init.s
new file mode 100644
index 0000000..5cf2aca
--- /dev/null
+++ b/lib/romlib/init.s
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.globl	rom_lib_init
+	.extern	__DATA_RAM_START__, __DATA_ROM_START__, __DATA_SIZE__
+	.extern	memset, memcpy
+
+rom_lib_init:
+	cmp	w0, #1
+	mov	w0, #0
+	b.le	1f
+	ret
+
+1:	stp	x29, x30, [sp, #-16]!
+	adrp	x0, __DATA_RAM_START__
+	ldr	x1,= __DATA_ROM_START__
+	ldr	x2, =__DATA_SIZE__
+	bl	memcpy
+
+	ldr	x0, =__BSS_START__
+	mov	x1, #0
+	ldr	x2, =__BSS_SIZE__
+	bl	memset
+	ldp	x29, x30, [sp], #16
+
+	mov	w0, #1
+	ret
diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i
new file mode 100644
index 0000000..338cd8a
--- /dev/null
+++ b/lib/romlib/jmptbl.i
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+0	rom	rom_lib_init
+1	fdt	fdt_getprop_namelen
+2	fdt	fdt_setprop_inplace
+3	fdt	fdt_check_header
+4	fdt	fdt_node_offset_by_compatible
+5	mbedtls	mbedtls_asn1_get_alg
+6	mbedtls	mbedtls_asn1_get_alg_null
+7	mbedtls	mbedtls_asn1_get_bitstring_null
+8	mbedtls	mbedtls_asn1_get_bool
+9	mbedtls	mbedtls_asn1_get_int
+10	mbedtls	mbedtls_asn1_get_tag
+11	mbedtls	mbedtls_free
+12	mbedtls	mbedtls_md
+13	mbedtls	mbedtls_md_get_size
+14	mbedtls	mbedtls_memory_buffer_alloc_init
+15	mbedtls	mbedtls_oid_get_md_alg
+16	mbedtls	mbedtls_oid_get_numeric_string
+17	mbedtls	mbedtls_oid_get_pk_alg
+18	mbedtls	mbedtls_oid_get_sig_alg
+19	mbedtls	mbedtls_pk_free
+20	mbedtls	mbedtls_pk_init
+21	mbedtls	mbedtls_pk_parse_subpubkey
+22	mbedtls	mbedtls_pk_verify_ext
+23	mbedtls	mbedtls_platform_set_snprintf
+24	mbedtls	mbedtls_x509_get_rsassa_pss_params
+25	mbedtls	mbedtls_x509_get_sig_alg
+26	mbedtls	mbedtls_md_info_from_type
+27	c	exit
+28	c	atexit
diff --git a/lib/romlib/romlib.ld.S b/lib/romlib/romlib.ld.S
new file mode 100644
index 0000000..8f0bc62
--- /dev/null
+++ b/lib/romlib/romlib.ld.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+#include <xlat_tables_defs.h>
+
+MEMORY {
+	ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
+	RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
+}
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(jmptbl)
+
+SECTIONS
+{
+	. = ROMLIB_RO_BASE;
+	.text : {
+		*jmptbl.o(.text)
+		*(.text*)
+		*(.rodata*)
+	} >ROM
+
+	__DATA_ROM_START__ = LOADADDR(.data);
+
+	.data : {
+		__DATA_RAM_START__ = .;
+		*(.data*)
+		__DATA_RAM_END__ = .;
+	} >RAM AT>ROM
+
+	__DATA_SIZE__ = SIZEOF(.data);
+
+	.bss : {
+		__BSS_START__ = .;
+		*(.bss*)
+		__BSS_END__ = .;
+	 } >RAM
+	__BSS_SIZE__ = SIZEOF(.bss);
+}
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index ca82694..92a0f6e 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -306,12 +306,15 @@
 
 .PHONY: libraries
 
-
-# MAKE_LIB_DIR macro defines the target for the directory where
+# MAKE_LIB_DIRS macro defines the target for the directory where
 # libraries are created
-define MAKE_LIB_DIR
+define MAKE_LIB_DIRS
         $(eval LIB_DIR    := ${BUILD_PLAT}/lib)
-	$(eval $(call MAKE_PREREQ_DIR,${LIB_DIR},${BUILD_PLAT}))
+        $(eval ROMLIB_DIR    := ${BUILD_PLAT}/romlib)
+        $(eval LIBWRAPPER_DIR := ${BUILD_PLAT}/libwrapper)
+        $(eval $(call MAKE_PREREQ_DIR,${LIB_DIR},${BUILD_PLAT}))
+        $(eval $(call MAKE_PREREQ_DIR,${ROMLIB_DIR},${BUILD_PLAT}))
+        $(eval $(call MAKE_PREREQ_DIR,${LIBWRAPPER_DIR},${BUILD_PLAT}))
 endef
 
 # MAKE_LIB macro defines the targets and options to build each BL image.
@@ -320,6 +323,7 @@
 define MAKE_LIB
         $(eval BUILD_DIR  := ${BUILD_PLAT}/lib$(1))
         $(eval LIB_DIR    := ${BUILD_PLAT}/lib)
+        $(eval ROMLIB_DIR    := ${BUILD_PLAT}/romlib)
         $(eval SOURCES    := $(LIB$(call uppercase,$(1))_SRCS))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
 
@@ -327,11 +331,15 @@
 $(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
 
 .PHONY : lib${1}_dirs
-lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR}
+lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR}  ${ROMLIB_DIR} ${LIBWRAPPER_DIR}
 libraries: ${LIB_DIR}/lib$(1).a
 LDPATHS = -L${LIB_DIR}
 LDLIBS += -l$(1)
 
+ifeq ($(USE_ROMLIB),1)
+LDLIBS := -lwrappers -lc
+endif
+
 all: ${LIB_DIR}/lib$(1).a
 
 ${LIB_DIR}/lib$(1).a: $(OBJS)
@@ -378,6 +386,10 @@
 $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
 $(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE),$(1)))
 
+ifeq ($(USE_ROMLIB),1)
+$(ELF): romlib.bin
+endif
+
 $(ELF): $(OBJS) $(LINKERFILE) | bl$(1)_dirs libraries $(BL_LIBS)
 	@echo "  LD      $$@"
 ifdef MAKE_BUILD_STRINGS
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index cea8533..e4b5bdc 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -166,6 +166,9 @@
 # Build option to choose whether Trusted firmware uses Coherent memory or not.
 USE_COHERENT_MEM		:= 1
 
+# Build option to choose wheter Trusted firmware uses library at ROM
+USE_ROMLIB				:= 0
+
 # Use tbbr_oid.h instead of platform_oid.h
 USE_TBBR_DEFS			= $(ERROR_DEPRECATED)