Merge pull request #584 from soby-mathew/sm/enable_scr_sif
Enable SCR_EL3.SIF bit
diff --git a/.gitignore b/.gitignore
index cc5cbfb..7447227 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,12 @@
# Ignore build products from tools
tools/**/*.o
tools/fip_create/fip_create
+tools/fip_create/fip_create.exe
tools/cert_create/src/*.o
tools/cert_create/src/**/*.o
tools/cert_create/cert_create
+tools/cert_create/cert_create.exe
+
+# Ignore header files copied.
+tools/fip_create/firmware_image_package.h
+tools/fip_create/uuid.h
diff --git a/Makefile b/Makefile
index d7a7a36..b2ca916 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,9 @@
# Default goal is build all images
.DEFAULT_GOAL := all
-include make_helpers/build_macros.mk
+MAKE_HELPERS_DIRECTORY := make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
################################################################################
# Default values for build configurations
@@ -111,9 +113,10 @@
CHECKPATCH_ARGS := --no-tree --no-signoff ${CHECK_IGNORE}
CHECKCODE_ARGS := --no-patch --no-tree --no-signoff ${CHECK_IGNORE}
# Do not check the coding style on C library files
-CHECK_PATHS := $(shell ls -I include -I lib) \
- $(addprefix include/,$(shell ls -I stdlib include)) \
- $(addprefix lib/,$(shell ls -I stdlib lib))
+INCLUDE_DIRS_TO_CHECK := $(sort $(filter-out include/stdlib, $(wildcard include/*)))
+LIB_DIRS_TO_CHECK := $(sort $(filter-out lib/stdlib, $(wildcard lib/*)))
+ROOT_DIRS_TO_CHECK := $(sort $(filter-out lib include, $(wildcard *))))
+CHECK_PATHS := ${ROOT_DIRS_TO_CHECK} ${INCLUDE_DIRS_TO_CHECK} ${LIB_DIRS_TO_CHECK}
################################################################################
@@ -122,10 +125,10 @@
# Verbose flag
ifeq (${V},0)
- Q=@
+ Q:=@
CHECKCODE_ARGS += --no-summary --terse
else
- Q=
+ Q:=
endif
export Q
@@ -234,17 +237,12 @@
# Generic definitions
################################################################################
+include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
+
BUILD_BASE := ./build
BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${BUILD_TYPE}
-PLAT_MAKEFILE := platform.mk
-# Generate the platforms list by recursively searching for all directories
-# under /plat containing a PLAT_MAKEFILE. Append each platform with a `|`
-# char and strip out the final '|'.
-PLATFORMS := $(shell find plat/ -name '${PLAT_MAKEFILE}' -print0 | \
- sed -r 's%[^\x00]*\/([^/]*)\/${PLAT_MAKEFILE}\x00%\1|%g' | \
- sed -r 's/\|$$//')
-SPDS := $(shell ls -I none services/spd)
+SPDS := $(sort $(filter-out none, $(patsubst services/spd/%,%,$(wildcard services/spd/*))))
# Platforms providing their own TBB makefile may override this value
INCLUDE_TBBR_MK := 1
@@ -260,7 +258,7 @@
$(warning "The SPD and its BL32 companion will be present but ignored.")
endif
# We expect to locate an spd.mk under the specified SPD directory
- SPD_MAKE := $(shell m="services/spd/${SPD}/${SPD}.mk"; [ -f "$$m" ] && echo "$$m")
+ SPD_MAKE := $(wildcard services/spd/${SPD}/${SPD}.mk)
ifeq (${SPD_MAKE},)
$(error Error: No services/spd/${SPD}/${SPD}.mk located)
@@ -285,14 +283,6 @@
# makefile may use all previous definitions in this file)
################################################################################
-ifeq (${PLAT},)
- $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
-endif
-PLAT_MAKEFILE_FULL := $(shell find plat/ -wholename '*/${PLAT}/${PLAT_MAKEFILE}')
-ifeq ($(PLAT_MAKEFILE_FULL),)
- $(error "Error: Invalid platform. The following platforms are available: ${PLATFORMS}")
-endif
-
include ${PLAT_MAKEFILE_FULL}
# If the platform has not defined ENABLE_PLAT_COMPAT, then enable it by default
@@ -386,11 +376,11 @@
# Variables for use with Certificate Generation Tool
CRTTOOLPATH ?= tools/cert_create
-CRTTOOL ?= ${CRTTOOLPATH}/cert_create
+CRTTOOL ?= ${CRTTOOLPATH}/cert_create${BIN_EXT}
# Variables for use with Firmware Image Package
FIPTOOLPATH ?= tools/fip_create
-FIPTOOL ?= ${FIPTOOLPATH}/fip_create
+FIPTOOL ?= ${FIPTOOLPATH}/fip_create${BIN_EXT}
################################################################################
@@ -545,14 +535,14 @@
clean:
@echo " CLEAN"
- ${Q}rm -rf ${BUILD_PLAT}
+ $(call SHELL_REMOVE_DIR,${BUILD_PLAT})
${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
realclean distclean:
@echo " REALCLEAN"
- ${Q}rm -rf ${BUILD_BASE}
- ${Q}rm -f ${CURDIR}/cscope.*
+ $(call SHELL_REMOVE_DIR,${BUILD_BASE})
+ $(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
@@ -573,24 +563,24 @@
.PHONY: ${CRTTOOL}
${CRTTOOL}:
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH}
- @echo
+ @${ECHO_BLANK_LINE}
@echo "Built $@ successfully"
- @echo
+ @${ECHO_BLANK_LINE}
ifneq (${GENERATE_COT},0)
certificates: ${CRT_DEPS} ${CRTTOOL}
${Q}${CRTTOOL} ${CRT_ARGS}
- @echo
+ @${ECHO_BLANK_LINE}
@echo "Built $@ successfully"
@echo "Certificates can be found in ${BUILD_PLAT}"
- @echo
+ @${ECHO_BLANK_LINE}
endif
${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL}
${Q}${FIPTOOL} --dump ${FIP_ARGS} $@
- @echo
+ @${ECHO_BLANK_LINE}
@echo "Built $@ successfully"
- @echo
+ @${ECHO_BLANK_LINE}
ifneq (${GENERATE_COT},0)
fwu_certificates: ${FWU_CRT_DEPS} ${CRTTOOL}
@@ -621,7 +611,7 @@
${Q}cscope -b -q -k
help:
- @echo "usage: ${MAKE} PLAT=<${PLATFORMS}> [OPTIONS] [TARGET]"
+ @echo "usage: ${MAKE} PLAT=<${PLATFORM_LIST}> [OPTIONS] [TARGET]"
@echo ""
@echo "PLAT is used to specify which platform you wish to build."
@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index 9919fe4..a502428 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -52,8 +52,8 @@
# Include the platform-specific TSP Makefile
# If no platform-specific TSP Makefile exists, it means TSP is not supported
# on this platform.
-TSP_PLAT_MAKEFILE := $(shell find plat/ -wholename '*/${PLAT}/tsp/tsp-${PLAT}.mk')
-ifeq (,$(wildcard ${TSP_PLAT_MAKEFILE}))
+TSP_PLAT_MAKEFILE := $(wildcard ${PLAT_DIR}/tsp/tsp-${PLAT}.mk)
+ifeq (,${TSP_PLAT_MAKEFILE})
$(error TSP is not supported on platform ${PLAT})
else
include ${TSP_PLAT_MAKEFILE}
diff --git a/common/tf_printf.c b/common/tf_printf.c
index c1d4188..9a7667a 100644
--- a/common/tf_printf.c
+++ b/common/tf_printf.c
@@ -69,6 +69,7 @@
* %ld and %lld - signed 64 bit decimal format
* %lu and %llu - unsigned 64 bit decimal format
* %p - pointer format
+ * %z - size_t format
* Exits on all other formats.
*******************************************************************/
@@ -124,6 +125,11 @@
unsigned_num_print(unum, 16);
break;
+ case 'z':
+ if (sizeof(size_t) == 8)
+ bit64 = 1;
+ fmt++;
+ goto loop;
case 'l':
bit64 = 1;
fmt++;
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index f8d0ff3..3b6e242 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -633,6 +633,35 @@
to the ROTPK in the flags parameter.
+### Function: plat_get_nv_ctr()
+
+ Argument : void *, unsigned int *
+ Return : int
+
+This function is mandatory when Trusted Board Boot is enabled. It returns the
+non-volatile counter value stored in the platform in the second argument. The
+cookie in the first argument may be used to select the counter in case the
+platform provides more than one (for example, on platforms that use the default
+TBBR CoT, the cookie will correspond to the OID values defined in
+TRUSTED_FW_NVCOUNTER_OID or NON_TRUSTED_FW_NVCOUNTER_OID).
+
+The function returns 0 on success. Any other value means the counter value could
+not be retrieved from the platform.
+
+
+### Function: plat_set_nv_ctr()
+
+ Argument : void *, unsigned int
+ Return : int
+
+This function is mandatory when Trusted Board Boot is enabled. It sets a new
+counter value in the platform. The cookie in the first argument may be used to
+select the counter (as explained in plat_get_nv_ctr()).
+
+The function returns 0 on success. Any other value means the counter value could
+not be updated.
+
+
2.3 Common mandatory modifications
---------------------------------
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 37e2034..8d7376d 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -42,6 +42,9 @@
building the software were installed from that distribution unless otherwise
specified.
+The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
+Cygwin, and Msys (MinGW) shells, using version 4.9.1 of the GNU toolchain.
+
3. Tools
---------
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
new file mode 100644
index 0000000..ee6bf8d
--- /dev/null
+++ b/drivers/arm/tzc/tzc400.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 <assert.h>
+#include <debug.h>
+#include <mmio.h>
+#include <stddef.h>
+#include <tzc400.h>
+#include "tzc_common_private.c"
+
+/*
+ * Macros which will be used by common core functions.
+ */
+#define TZC_400_REGION_BASE_LOW_0_OFFSET 0x100
+#define TZC_400_REGION_BASE_HIGH_0_OFFSET 0x104
+#define TZC_400_REGION_TOP_LOW_0_OFFSET 0x108
+#define TZC_400_REGION_TOP_HIGH_0_OFFSET 0x10c
+#define TZC_400_REGION_ATTR_0_OFFSET 0x110
+#define TZC_400_REGION_ID_ACCESS_0_OFFSET 0x114
+
+/*
+ * Implementation defined values used to validate inputs later.
+ * Filters : max of 4 ; 0 to 3
+ * Regions : max of 9 ; 0 to 8
+ * Address width : Values between 32 to 64
+ */
+typedef struct tzc400_instance {
+ uintptr_t base;
+ uint8_t addr_width;
+ uint8_t num_filters;
+ uint8_t num_regions;
+} tzc400_instance_t;
+
+tzc400_instance_t tzc400;
+
+static inline unsigned int _tzc400_read_build_config(uintptr_t base)
+{
+ return mmio_read_32(base + BUILD_CONFIG_OFF);
+}
+
+static inline unsigned int _tzc400_read_gate_keeper(uintptr_t base)
+{
+ return mmio_read_32(base + GATE_KEEPER_OFF);
+}
+
+static inline void _tzc400_write_gate_keeper(uintptr_t base, unsigned int val)
+{
+ mmio_write_32(base + GATE_KEEPER_OFF, val);
+}
+
+/*
+ * Get the open status information for all filter units.
+ */
+#define get_gate_keeper_os(base) ((_tzc400_read_gate_keeper(base) >> \
+ GATE_KEEPER_OS_SHIFT) & \
+ GATE_KEEPER_OS_MASK)
+
+
+/* Define common core functions used across different TZC peripherals. */
+DEFINE_TZC_COMMON_WRITE_ACTION(400, 400)
+DEFINE_TZC_COMMON_WRITE_REGION_BASE(400, 400)
+DEFINE_TZC_COMMON_WRITE_REGION_TOP(400, 400)
+DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(400, 400)
+DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(400, 400)
+DEFINE_TZC_COMMON_CONFIGURE_REGION0(400)
+DEFINE_TZC_COMMON_CONFIGURE_REGION(400)
+
+static unsigned int _tzc400_get_gate_keeper(uintptr_t base,
+ unsigned int filter)
+{
+ unsigned int open_status;
+
+ open_status = get_gate_keeper_os(base);
+
+ return (open_status >> filter) & GATE_KEEPER_FILTER_MASK;
+}
+
+/* This function is not MP safe. */
+static void _tzc400_set_gate_keeper(uintptr_t base,
+ unsigned int filter,
+ int val)
+{
+ unsigned int open_status;
+
+ /* Upper half is current state. Lower half is requested state. */
+ open_status = get_gate_keeper_os(base);
+
+ if (val)
+ open_status |= (1 << filter);
+ else
+ open_status &= ~(1 << filter);
+
+ _tzc400_write_gate_keeper(base, (open_status & GATE_KEEPER_OR_MASK) <<
+ GATE_KEEPER_OR_SHIFT);
+
+ /* Wait here until we see the change reflected in the TZC status. */
+ while ((get_gate_keeper_os(base)) != open_status)
+ ;
+}
+
+void tzc400_set_action(tzc_action_t action)
+{
+ assert(tzc400.base);
+ assert(action <= TZC_ACTION_ERR_INT);
+
+ /*
+ * - Currently no handler is provided to trap an error via interrupt
+ * or exception.
+ * - The interrupt action has not been tested.
+ */
+ _tzc400_write_action(tzc400.base, action);
+}
+
+void tzc400_init(uintptr_t base)
+{
+#if DEBUG
+ unsigned int tzc400_id;
+#endif
+ unsigned int tzc400_build;
+
+ assert(base);
+ tzc400.base = base;
+
+#if DEBUG
+ tzc400_id = _tzc_read_peripheral_id(base);
+ if (tzc400_id != TZC_400_PERIPHERAL_ID) {
+ ERROR("TZC-400 : Wrong device ID (0x%x).\n", tzc400_id);
+ panic();
+ }
+#endif
+
+ /* Save values we will use later. */
+ tzc400_build = _tzc400_read_build_config(tzc400.base);
+ tzc400.num_filters = ((tzc400_build >> BUILD_CONFIG_NF_SHIFT) &
+ BUILD_CONFIG_NF_MASK) + 1;
+ tzc400.addr_width = ((tzc400_build >> BUILD_CONFIG_AW_SHIFT) &
+ BUILD_CONFIG_AW_MASK) + 1;
+ tzc400.num_regions = ((tzc400_build >> BUILD_CONFIG_NR_SHIFT) &
+ BUILD_CONFIG_NR_MASK) + 1;
+}
+
+/*
+ * `tzc400_configure_region0` is used to program region 0 into the TrustZone
+ * controller. Region 0 covers the whole address space that is not mapped
+ * to any other region, and is enabled on all filters; this cannot be
+ * changed. This function only changes the access permissions.
+ */
+void tzc400_configure_region0(tzc_region_attributes_t sec_attr,
+ unsigned int ns_device_access)
+{
+ assert(tzc400.base);
+ assert(sec_attr <= TZC_REGION_S_RDWR);
+
+ _tzc400_configure_region0(tzc400.base, sec_attr, ns_device_access);
+}
+
+/*
+ * `tzc400_configure_region` is used to program regions into the TrustZone
+ * controller. A region can be associated with more than one filter. The
+ * associated filters are passed in as a bitmap (bit0 = filter0).
+ * NOTE:
+ * Region 0 is special; it is preferable to use tzc400_configure_region0
+ * for this region (see comment for that function).
+ */
+void tzc400_configure_region(unsigned int filters,
+ int region,
+ uintptr_t region_base,
+ uintptr_t region_top,
+ tzc_region_attributes_t sec_attr,
+ unsigned int nsaid_permissions)
+{
+ assert(tzc400.base);
+
+ /* Do range checks on filters and regions. */
+ assert(((filters >> tzc400.num_filters) == 0) &&
+ (region >= 0) && (region < tzc400.num_regions));
+
+ /*
+ * Do address range check based on TZC configuration. A 64bit address is
+ * the max and expected case.
+ */
+ assert(((region_top <= (UINT64_MAX >> (64 - tzc400.addr_width))) &&
+ (region_base < region_top)));
+
+ /* region_base and (region_top + 1) must be 4KB aligned */
+ assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0);
+
+ assert(sec_attr <= TZC_REGION_S_RDWR);
+
+ _tzc400_configure_region(tzc400.base, filters, region, region_base,
+ region_top,
+ sec_attr, nsaid_permissions);
+}
+
+void tzc400_enable_filters(void)
+{
+ unsigned int state;
+ unsigned int filter;
+
+ assert(tzc400.base);
+
+ for (filter = 0; filter < tzc400.num_filters; filter++) {
+ state = _tzc400_get_gate_keeper(tzc400.base, filter);
+ if (state) {
+ /* The TZC filter is already configured. Changing the
+ * programmer's view in an active system can cause
+ * unpredictable behavior therefore panic for now rather
+ * than try to determine whether this is safe in this
+ * instance. See:
+ * http://infocenter.arm.com/help/index.jsp?\
+ * topic=/com.arm.doc.ddi0504c/CJHHECBF.html */
+ ERROR("TZC-400 : Filter %d Gatekeeper already"
+ " enabled.\n", filter);
+ panic();
+ }
+ _tzc400_set_gate_keeper(tzc400.base, filter, 1);
+ }
+}
+
+void tzc400_disable_filters(void)
+{
+ unsigned int filter;
+
+ assert(tzc400.base);
+
+ /*
+ * We don't do the same state check as above as the Gatekeepers are
+ * disabled after reset.
+ */
+ for (filter = 0; filter < tzc400.num_filters; filter++)
+ _tzc400_set_gate_keeper(tzc400.base, filter, 0);
+}
diff --git a/drivers/arm/tzc/tzc_common_private.c b/drivers/arm/tzc/tzc_common_private.c
new file mode 100644
index 0000000..f570daf
--- /dev/null
+++ b/drivers/arm/tzc/tzc_common_private.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 <mmio.h>
+#include <tzc_common.h>
+
+#define DEFINE_TZC_COMMON_WRITE_ACTION(fn_name, macro_name) \
+ static inline void _tzc##fn_name##_write_action( \
+ uintptr_t base, \
+ tzc_action_t action) \
+ { \
+ mmio_write_32(base + TZC_##macro_name##_ACTION_OFF, \
+ action); \
+ }
+
+#define DEFINE_TZC_COMMON_WRITE_REGION_BASE(fn_name, macro_name) \
+ static inline void _tzc##fn_name##_write_region_base( \
+ uintptr_t base, \
+ int region_no, \
+ uintptr_t region_base) \
+ { \
+ mmio_write_32(base + \
+ TZC_REGION_OFFSET( \
+ TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_BASE_LOW_0_OFFSET, \
+ (unsigned int)region_base); \
+ mmio_write_32(base + \
+ TZC_REGION_OFFSET( \
+ TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_BASE_HIGH_0_OFFSET, \
+ (unsigned int)(region_base >> 32)); \
+ }
+
+#define DEFINE_TZC_COMMON_WRITE_REGION_TOP(fn_name, macro_name) \
+ static inline void _tzc##fn_name##_write_region_top( \
+ uintptr_t base, \
+ int region_no, \
+ uintptr_t region_top) \
+ { \
+ mmio_write_32(base + \
+ TZC_REGION_OFFSET \
+ (TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_TOP_LOW_0_OFFSET, \
+ (unsigned int)region_top); \
+ mmio_write_32(base + \
+ TZC_REGION_OFFSET( \
+ TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_TOP_HIGH_0_OFFSET, \
+ (unsigned int)(region_top >> 32)); \
+ }
+
+#define DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(fn_name, macro_name) \
+ static inline void _tzc##fn_name##_write_region_attributes( \
+ uintptr_t base, \
+ int region_no, \
+ unsigned int attr) \
+ { \
+ mmio_write_32(base + \
+ TZC_REGION_OFFSET( \
+ TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_ATTR_0_OFFSET, \
+ attr); \
+ }
+
+#define DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(fn_name, macro_name) \
+ static inline void _tzc##fn_name##_write_region_id_access( \
+ uintptr_t base, \
+ int region_no, \
+ unsigned int val) \
+ { \
+ mmio_write_32(base + \
+ TZC_REGION_OFFSET( \
+ TZC_##macro_name##_REGION_SIZE, \
+ region_no) + \
+ TZC_##macro_name##_REGION_ID_ACCESS_0_OFFSET, \
+ val); \
+ }
+
+/*
+ * It is used to program region 0 ATTRIBUTES and ACCESS register.
+ */
+#define DEFINE_TZC_COMMON_CONFIGURE_REGION0(fn_name) \
+ void _tzc##fn_name##_configure_region0(uintptr_t base, \
+ tzc_region_attributes_t sec_attr, \
+ unsigned int ns_device_access) \
+ { \
+ assert(base); \
+ VERBOSE("TrustZone : Configuring region 0 " \
+ "(TZC Interface Base=%p sec_attr=0x%x," \
+ " ns_devs=0x%x)\n", (void *)base, \
+ sec_attr, ns_device_access); \
+ \
+ /* Set secure attributes on region 0 */ \
+ _tzc##fn_name##_write_region_attributes(base, 0, \
+ sec_attr << TZC_REGION_ATTR_SEC_SHIFT); \
+ \
+ /***************************************************/ \
+ /* Specify which non-secure devices have permission*/ \
+ /* to access region 0. */ \
+ /***************************************************/ \
+ _tzc##fn_name##_write_region_id_access(base, \
+ 0, \
+ ns_device_access); \
+ }
+
+/*
+ * It is used to program a region from 1 to 8 in the TrustZone controller.
+ * NOTE:
+ * Region 0 is special; it is preferable to use
+ * ##fn_name##_configure_region0 for this region (see comment for
+ * that function).
+ */
+#define DEFINE_TZC_COMMON_CONFIGURE_REGION(fn_name) \
+ void _tzc##fn_name##_configure_region(uintptr_t base, \
+ unsigned int filters, \
+ int region_no, \
+ uintptr_t region_base, \
+ uintptr_t region_top, \
+ tzc_region_attributes_t sec_attr, \
+ unsigned int nsaid_permissions) \
+ { \
+ assert(base); \
+ VERBOSE("TrustZone : Configuring region " \
+ "(TZC Interface Base: %p, region_no = %d)" \
+ "...\n", (void *)base, region_no); \
+ VERBOSE("TrustZone : ... base = %p, top = %p," \
+ "\n", (void *)region_base, (void *)region_top);\
+ VERBOSE("TrustZone : ... sec_attr = 0x%x," \
+ " ns_devs = 0x%x)\n", \
+ sec_attr, nsaid_permissions); \
+ \
+ /***************************************************/ \
+ /* Inputs look ok, start programming registers. */ \
+ /* All the address registers are 32 bits wide and */ \
+ /* have a LOW and HIGH */ \
+ /* component used to construct an address up to a */ \
+ /* 64bit. */ \
+ /***************************************************/ \
+ _tzc##fn_name##_write_region_base(base, \
+ region_no, region_base); \
+ _tzc##fn_name##_write_region_top(base, \
+ region_no, region_top); \
+ \
+ /* Enable filter to the region and set secure attributes */\
+ _tzc##fn_name##_write_region_attributes(base, \
+ region_no, \
+ (sec_attr << TZC_REGION_ATTR_SEC_SHIFT) |\
+ (filters << TZC_REGION_ATTR_F_EN_SHIFT));\
+ \
+ /***************************************************/ \
+ /* Specify which non-secure devices have permission*/ \
+ /* to access this region. */ \
+ /***************************************************/ \
+ _tzc##fn_name##_write_region_id_access(base, \
+ region_no, \
+ nsaid_permissions); \
+ }
+
+#if DEBUG
+static unsigned int _tzc_read_peripheral_id(uintptr_t base)
+{
+ unsigned int id;
+
+ id = mmio_read_32(base + PID0_OFF);
+ /* Masks DESC part in PID1 */
+ id |= ((mmio_read_32(base + PID1_OFF) & 0xF) << 8);
+
+ return id;
+}
+#endif
diff --git a/drivers/arm/tzc/tzc_dmc500.c b/drivers/arm/tzc/tzc_dmc500.c
new file mode 100644
index 0000000..16a53a4
--- /dev/null
+++ b/drivers/arm/tzc/tzc_dmc500.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 <assert.h>
+#include <debug.h>
+#include <mmio.h>
+#include <tzc_dmc500.h>
+#include "tzc_common.h"
+#include "tzc_common_private.c"
+
+/*
+ * Macros which will be used by common core functions.
+ */
+#define TZC_DMC500_REGION_BASE_LOW_0_OFFSET 0x054
+#define TZC_DMC500_REGION_BASE_HIGH_0_OFFSET 0x058
+#define TZC_DMC500_REGION_TOP_LOW_0_OFFSET 0x05C
+#define TZC_DMC500_REGION_TOP_HIGH_0_OFFSET 0x060
+#define TZC_DMC500_REGION_ATTR_0_OFFSET 0x064
+#define TZC_DMC500_REGION_ID_ACCESS_0_OFFSET 0x068
+
+#define TZC_DMC500_ACTION_OFF 0x50
+
+/* Pointer to the tzc_dmc500_driver_data structure populated by the platform */
+static const tzc_dmc500_driver_data_t *g_driver_data;
+
+#define verify_region_attr(region, attr) \
+ ((g_conf_regions[(region)].sec_attr == \
+ ((attr) >> TZC_REGION_ATTR_SEC_SHIFT)) \
+ && ((attr) & (0x1 << TZC_REGION_ATTR_F_EN_SHIFT)))
+
+/*
+ * Structure for configured regions attributes in DMC500.
+ */
+typedef struct tzc_dmc500_regions {
+ tzc_region_attributes_t sec_attr;
+ int is_enabled;
+} tzc_dmc500_regions_t;
+
+/*
+ * Array storing the attributes of the configured regions. This array
+ * will be used by the `tzc_dmc500_verify_complete` to verify the flush
+ * completion.
+ */
+static tzc_dmc500_regions_t g_conf_regions[MAX_REGION_VAL + 1];
+
+/* Helper Macros for making the code readable */
+#define DMC_INST_BASE_ADDR(instance) (g_driver_data->dmc_base[instance])
+#define DMC_INST_SI_BASE(instance, interface) \
+ (DMC_INST_BASE_ADDR(instance) + IFACE_OFFSET(interface))
+
+DEFINE_TZC_COMMON_WRITE_ACTION(_dmc500, DMC500)
+DEFINE_TZC_COMMON_WRITE_REGION_BASE(_dmc500, DMC500)
+DEFINE_TZC_COMMON_WRITE_REGION_TOP(_dmc500, DMC500)
+DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(_dmc500, DMC500)
+DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(_dmc500, DMC500)
+
+DEFINE_TZC_COMMON_CONFIGURE_REGION0(_dmc500)
+DEFINE_TZC_COMMON_CONFIGURE_REGION(_dmc500)
+
+static inline unsigned int _tzc_dmc500_read_region_attr_0(
+ uintptr_t dmc_si_base,
+ int region_no)
+{
+ return mmio_read_32(dmc_si_base +
+ TZC_REGION_OFFSET(TZC_DMC500_REGION_SIZE, region_no) +
+ TZC_DMC500_REGION_ATTR_0_OFFSET);
+}
+
+static inline void _tzc_dmc500_write_flush_control(uintptr_t dmc_si_base)
+{
+ mmio_write_32(dmc_si_base + SI_FLUSH_CTRL_OFFSET, 1);
+}
+
+/*
+ * Sets the Flush controls for all the DMC Instances and System Interfaces.
+ * This initiates the flush of configuration settings from the shadow
+ * registers to the actual configuration register. The caller should poll
+ * changed register to confirm update.
+ */
+void tzc_dmc500_config_complete(void)
+{
+ int dmc_inst, sys_if;
+
+ assert(g_driver_data);
+
+ for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
+ assert(DMC_INST_BASE_ADDR(dmc_inst));
+ for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+ _tzc_dmc500_write_flush_control(
+ DMC_INST_SI_BASE(dmc_inst, sys_if));
+ }
+}
+
+/*
+ * This function reads back the secure attributes from the configuration
+ * register for each DMC Instance and System Interface and compares it with
+ * the configured value. The successful verification of the region attributes
+ * confirms that the flush operation has completed.
+ * If the verification fails, the caller is expected to invoke this API again
+ * till it succeeds.
+ * Returns 0 on success and 1 on failure.
+ */
+int tzc_dmc500_verify_complete(void)
+{
+ int dmc_inst, sys_if, region_no;
+ unsigned int attr;
+
+ assert(g_driver_data);
+ /* Region 0 must be configured */
+ assert(g_conf_regions[0].is_enabled);
+
+ /* Iterate over all configured regions */
+ for (region_no = 0; region_no <= MAX_REGION_VAL; region_no++) {
+ if (!g_conf_regions[region_no].is_enabled)
+ continue;
+ for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count;
+ dmc_inst++) {
+ assert(DMC_INST_BASE_ADDR(dmc_inst));
+ for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT;
+ sys_if++) {
+ attr = _tzc_dmc500_read_region_attr_0(
+ DMC_INST_SI_BASE(dmc_inst, sys_if),
+ region_no);
+ VERBOSE("Verifying DMC500 region:%d"
+ " dmc_inst:%d sys_if:%d attr:%x\n",
+ region_no, dmc_inst, sys_if, attr);
+ if (!verify_region_attr(region_no, attr))
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * `tzc_dmc500_configure_region0` is used to program region 0 in both the
+ * system interfaces of all the DMC-500 instances. Region 0 covers the whole
+ * address space that is not mapped to any other region for a system interface,
+ * and is always enabled; this cannot be changed. This function only changes
+ * the access permissions.
+ */
+void tzc_dmc500_configure_region0(tzc_region_attributes_t sec_attr,
+ unsigned int nsaid_permissions)
+{
+ int dmc_inst, sys_if;
+
+ /* Assert if DMC-500 is not initialized */
+ assert(g_driver_data);
+
+ /* Configure region_0 in all DMC instances */
+ for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
+ assert(DMC_INST_BASE_ADDR(dmc_inst));
+ for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+ _tzc_dmc500_configure_region0(
+ DMC_INST_SI_BASE(dmc_inst, sys_if),
+ sec_attr, nsaid_permissions);
+ }
+
+ g_conf_regions[0].sec_attr = sec_attr;
+ g_conf_regions[0].is_enabled = 1;
+}
+
+/*
+ * `tzc_dmc500_configure_region` is used to program a region into all system
+ * interfaces of all the DMC instances.
+ * NOTE:
+ * Region 0 is special; it is preferable to use tzc_dmc500_configure_region0
+ * for this region (see comment for that function).
+ */
+void tzc_dmc500_configure_region(int region_no,
+ uintptr_t region_base,
+ uintptr_t region_top,
+ tzc_region_attributes_t sec_attr,
+ unsigned int nsaid_permissions)
+{
+ int dmc_inst, sys_if;
+
+ assert(g_driver_data);
+ /* Do range checks on regions. */
+ assert(region_no >= 0 && region_no <= MAX_REGION_VAL);
+
+ /*
+ * Do address range check based on DMC-TZ configuration. A 43bit address
+ * is the max and expected case.
+ */
+ assert(((region_top <= (UINT64_MAX >> (64 - 43))) &&
+ (region_base < region_top)));
+
+ /* region_base and (region_top + 1) must be 4KB aligned */
+ assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0);
+
+ for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
+ assert(DMC_INST_BASE_ADDR(dmc_inst));
+ for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+ _tzc_dmc500_configure_region(
+ DMC_INST_SI_BASE(dmc_inst, sys_if),
+ TZC_DMC500_REGION_ATTR_F_EN_MASK,
+ region_no, region_base, region_top,
+ sec_attr, nsaid_permissions);
+ }
+
+ g_conf_regions[region_no].sec_attr = sec_attr;
+ g_conf_regions[region_no].is_enabled = 1;
+}
+
+/* Sets the action value for all the DMC instances */
+void tzc_dmc500_set_action(tzc_action_t action)
+{
+ int dmc_inst;
+
+ assert(g_driver_data);
+
+ for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
+ assert(DMC_INST_BASE_ADDR(dmc_inst));
+ /*
+ * - Currently no handler is provided to trap an error via
+ * interrupt or exception.
+ * - The interrupt action has not been tested.
+ */
+ _tzc_dmc500_write_action(DMC_INST_BASE_ADDR(dmc_inst), action);
+ }
+}
+
+/*
+ * A DMC-500 instance must be present at each base address provided by the
+ * platform. It also expects platform to pass at least one instance of
+ * DMC-500.
+ */
+static void validate_plat_driver_data(
+ const tzc_dmc500_driver_data_t *plat_driver_data)
+{
+#if DEBUG
+ int i;
+ unsigned int dmc_id;
+ uintptr_t dmc_base;
+
+ assert(plat_driver_data);
+ assert(plat_driver_data->dmc_count > 0 &&
+ (plat_driver_data->dmc_count <= MAX_DMC_COUNT));
+
+ for (i = 0; i < plat_driver_data->dmc_count; i++) {
+ dmc_base = plat_driver_data->dmc_base[i];
+ assert(dmc_base);
+
+ dmc_id = _tzc_read_peripheral_id(dmc_base);
+ assert(dmc_id == DMC500_PERIPHERAL_ID);
+ }
+#endif /* DEBUG */
+}
+
+
+/*
+ * Initializes the base address and count of DMC instances.
+ *
+ * Note : Only pointer to plat_driver_data is saved, so it is caller's
+ * responsibility to keep it valid until the driver is used.
+ */
+void tzc_dmc500_driver_init(const tzc_dmc500_driver_data_t *plat_driver_data)
+{
+ /* Check valid pointer is passed */
+ assert(plat_driver_data);
+
+ /*
+ * NOTE: This driver expects the DMC-500 controller is already in
+ * READY state. Hence, it uses the reconfiguration method for
+ * programming TrustZone regions
+ */
+ /* Validates the information passed by platform */
+ validate_plat_driver_data(plat_driver_data);
+ g_driver_data = plat_driver_data;
+}
diff --git a/drivers/arm/tzc400/tzc400.c b/drivers/arm/tzc400/tzc400.c
index 7194443..97adf81 100644
--- a/drivers/arm/tzc400/tzc400.c
+++ b/drivers/arm/tzc400/tzc400.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -28,313 +28,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <assert.h>
-#include <debug.h>
-#include <mmio.h>
-#include <stddef.h>
-#include <tzc400.h>
-
-/*
- * Implementation defined values used to validate inputs later.
- * Filters : max of 4 ; 0 to 3
- * Regions : max of 9 ; 0 to 8
- * Address width : Values between 32 to 64
- */
-typedef struct tzc_instance {
- uintptr_t base;
- uint8_t addr_width;
- uint8_t num_filters;
- uint8_t num_regions;
-} tzc_instance_t;
-
-tzc_instance_t tzc;
-
-
-static inline uint32_t tzc_read_build_config(uintptr_t base)
-{
- return mmio_read_32(base + BUILD_CONFIG_OFF);
-}
-
-static inline uint32_t tzc_read_gate_keeper(uintptr_t base)
-{
- return mmio_read_32(base + GATE_KEEPER_OFF);
-}
-
-static inline void tzc_write_gate_keeper(uintptr_t base, uint32_t val)
-{
- mmio_write_32(base + GATE_KEEPER_OFF, val);
-}
-
-static inline void tzc_write_action(uintptr_t base, tzc_action_t action)
-{
- mmio_write_32(base + ACTION_OFF, action);
-}
-
-static inline void tzc_write_region_base_low(uintptr_t base,
- uint32_t region,
- uint32_t val)
-{
- mmio_write_32(base + REGION_BASE_LOW_OFF +
- REGION_NUM_OFF(region), val);
-}
-
-static inline void tzc_write_region_base_high(uintptr_t base,
- uint32_t region,
- uint32_t val)
-{
- mmio_write_32(base + REGION_BASE_HIGH_OFF +
- REGION_NUM_OFF(region), val);
-}
-
-static inline void tzc_write_region_top_low(uintptr_t base,
- uint32_t region,
- uint32_t val)
-{
- mmio_write_32(base + REGION_TOP_LOW_OFF +
- REGION_NUM_OFF(region), val);
-}
-
-static inline void tzc_write_region_top_high(uintptr_t base,
- uint32_t region,
- uint32_t val)
-{
- mmio_write_32(base + REGION_TOP_HIGH_OFF +
- REGION_NUM_OFF(region), val);
-}
-
-static inline void tzc_write_region_attributes(uintptr_t base,
- uint32_t region,
- uint32_t val)
-{
- mmio_write_32(base + REGION_ATTRIBUTES_OFF +
- REGION_NUM_OFF(region), val);
-}
-
-static inline void tzc_write_region_id_access(uintptr_t base,
- uint32_t region,
- uint32_t val)
-{
- mmio_write_32(base + REGION_ID_ACCESS_OFF +
- REGION_NUM_OFF(region), val);
-}
-
-static unsigned int tzc_read_peripheral_id(uintptr_t base)
-{
- unsigned int id;
-
- id = mmio_read_8(base + PID0_OFF);
- /* Masks jep106_id_3_0 part in PID1 */
- id |= ((mmio_read_8(base + PID1_OFF) & 0xF) << 8);
-
- return id;
-}
-
-static uint32_t tzc_get_gate_keeper(uintptr_t base, uint8_t filter)
-{
- uint32_t tmp;
-
- tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
- GATE_KEEPER_OS_MASK;
-
- return (tmp >> filter) & GATE_KEEPER_FILTER_MASK;
-}
-
-/* This function is not MP safe. */
-static void tzc_set_gate_keeper(uintptr_t base, uint8_t filter, uint32_t val)
-{
- uint32_t tmp;
-
- /* Upper half is current state. Lower half is requested state. */
- tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
- GATE_KEEPER_OS_MASK;
-
- if (val)
- tmp |= (1 << filter);
- else
- tmp &= ~(1 << filter);
-
- tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) <<
- GATE_KEEPER_OR_SHIFT);
-
- /* Wait here until we see the change reflected in the TZC status. */
- while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
- GATE_KEEPER_OS_MASK) != tmp)
- ;
-}
-
-
-void tzc_init(uintptr_t base)
-{
- unsigned int tzc_id;
- unsigned int tzc_build;
-
- assert(base);
-
- tzc.base = base;
-
- /*
- * We expect to see a tzc400. Check peripheral ID.
- */
- tzc_id = tzc_read_peripheral_id(tzc.base);
- if (tzc_id != TZC400_PERIPHERAL_ID) {
- ERROR("TZC : Wrong device ID (0x%x).\n", tzc_id);
- panic();
- }
-
- /* Save values we will use later. */
- tzc_build = tzc_read_build_config(tzc.base);
- tzc.num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) &
- BUILD_CONFIG_NF_MASK) + 1;
- tzc.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
- BUILD_CONFIG_AW_MASK) + 1;
- tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
- BUILD_CONFIG_NR_MASK) + 1;
-}
-
-/*
- * `tzc_configure_region0` is used to program region 0 into the TrustZone
- * controller. Region 0 covers the whole address space that is not mapped
- * to any other region, and is enabled on all filters; this cannot be
- * changed. This function only changes the access permissions.
- */
-void tzc_configure_region0(tzc_region_attributes_t sec_attr,
- uint32_t ns_device_access)
-{
- assert(tzc.base);
-
- VERBOSE("TZC : Configuring region 0 (sec_attr=0x%x, ns_devs=0x%x)\n",
- sec_attr, ns_device_access);
-
- assert(sec_attr <= TZC_REGION_S_RDWR);
-
- /* Set secure attributes on region 0 */
- tzc_write_region_attributes(tzc.base, 0,
- sec_attr << REG_ATTR_SEC_SHIFT);
-
- /*
- * Specify which non-secure devices have permission to access
- * region 0.
- */
- tzc_write_region_id_access(tzc.base, 0, ns_device_access);
-}
-
-
-/*
- * `tzc_configure_region` is used to program regions into the TrustZone
- * controller. A region can be associated with more than one filter. The
- * associated filters are passed in as a bitmap (bit0 = filter0).
- * NOTE:
- * Region 0 is special; it is preferable to use tzc_configure_region0
- * for this region (see comment for that function).
- */
-void tzc_configure_region(uint32_t filters,
- uint8_t region,
- uint64_t region_base,
- uint64_t region_top,
- tzc_region_attributes_t sec_attr,
- uint32_t ns_device_access)
-{
- assert(tzc.base);
-
- VERBOSE("TZC : Configuring region (filters=0x%x, region=%d, ...\n",
- filters, region);
- VERBOSE("TZC : ... base=0x%lx, top=0x%lx, ...\n",
- region_base, region_top);
- VERBOSE("TZC : ... sec_attr=0x%x, ns_devs=0x%x)\n",
- sec_attr, ns_device_access);
-
- /* Do range checks on filters and regions. */
- assert(((filters >> tzc.num_filters) == 0) &&
- (region < tzc.num_regions));
-
- /*
- * Do address range check based on TZC configuration. A 64bit address is
- * the max and expected case.
- */
- assert(((region_top <= (UINT64_MAX >> (64 - tzc.addr_width))) &&
- (region_base < region_top)));
-
- /* region_base and (region_top + 1) must be 4KB aligned */
- assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0);
-
- assert(sec_attr <= TZC_REGION_S_RDWR);
-
- /*
- * Inputs look ok, start programming registers.
- * All the address registers are 32 bits wide and have a LOW and HIGH
- * component used to construct a up to a 64bit address.
- */
- tzc_write_region_base_low(tzc.base, region,
- (uint32_t)(region_base));
- tzc_write_region_base_high(tzc.base, region,
- (uint32_t)(region_base >> 32));
-
- tzc_write_region_top_low(tzc.base, region,
- (uint32_t)(region_top));
- tzc_write_region_top_high(tzc.base, region,
- (uint32_t)(region_top >> 32));
-
- /* Assign the region to a filter and set secure attributes */
- tzc_write_region_attributes(tzc.base, region,
- (sec_attr << REG_ATTR_SEC_SHIFT) | filters);
-
- /*
- * Specify which non-secure devices have permission to access this
- * region.
- */
- tzc_write_region_id_access(tzc.base, region, ns_device_access);
-}
-
-
-void tzc_set_action(tzc_action_t action)
-{
- assert(tzc.base);
-
- /*
- * - Currently no handler is provided to trap an error via interrupt
- * or exception.
- * - The interrupt action has not been tested.
- */
- tzc_write_action(tzc.base, action);
-}
-
-
-void tzc_enable_filters(void)
-{
- uint32_t state;
- uint32_t filter;
-
- assert(tzc.base);
-
- for (filter = 0; filter < tzc.num_filters; filter++) {
- state = tzc_get_gate_keeper(tzc.base, filter);
- if (state) {
- /* The TZC filter is already configured. Changing the
- * programmer's view in an active system can cause
- * unpredictable behavior therefore panic for now rather
- * than try to determine whether this is safe in this
- * instance. See:
- * http://infocenter.arm.com/help/index.jsp?\
- * topic=/com.arm.doc.ddi0504c/CJHHECBF.html */
- ERROR("TZC : Filter %d Gatekeeper already enabled.\n",
- filter);
- panic();
- }
- tzc_set_gate_keeper(tzc.base, filter, 1);
- }
-}
-
-
-void tzc_disable_filters(void)
-{
- uint32_t filter;
-
- assert(tzc.base);
-
- /*
- * We don't do the same state check as above as the Gatekeepers are
- * disabled after reset.
- */
- for (filter = 0; filter < tzc.num_filters; filter++)
- tzc_set_gate_keeper(tzc.base, filter, 0);
-}
+#if ERROR_DEPRECATED
+#error "Using deprecated TZC-400 source file"
+#else
+#include "../tzc/tzc400.c"
+#endif /* ERROR_DEPRECATED */
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index bdd3c5a..4184556 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -40,6 +40,9 @@
#include <stdint.h>
#include <string.h>
+/* ASN.1 tags */
+#define ASN1_INTEGER 0x02
+
#define return_if_error(rc) \
do { \
if (rc != 0) { \
@@ -227,6 +230,83 @@
}
/*
+ * Authenticate by Non-Volatile counter
+ *
+ * To protect the system against rollback, the platform includes a non-volatile
+ * counter whose value can only be increased. All certificates include a counter
+ * value that should not be lower than the value stored in the platform. If the
+ * value is larger, the counter in the platform must be updated to the new
+ * value.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int auth_nvctr(const auth_method_param_nv_ctr_t *param,
+ const auth_img_desc_t *img_desc,
+ void *img, unsigned int img_len)
+{
+ char *p;
+ void *data_ptr = NULL;
+ unsigned int data_len, len, i;
+ unsigned int cert_nv_ctr, plat_nv_ctr;
+ int rc = 0;
+
+ /* Get the counter value from current image. The AM expects the IPM
+ * to return the counter value as a DER encoded integer */
+ rc = img_parser_get_auth_param(img_desc->img_type, param->cert_nv_ctr,
+ img, img_len, &data_ptr, &data_len);
+ return_if_error(rc);
+
+ /* Parse the DER encoded integer */
+ assert(data_ptr);
+ p = (char *)data_ptr;
+ if (*p != ASN1_INTEGER) {
+ /* Invalid ASN.1 integer */
+ return 1;
+ }
+ p++;
+
+ /* NV-counters are unsigned integers up to 32-bit */
+ len = (unsigned int)(*p & 0x7f);
+ if ((*p & 0x80) || (len > 4)) {
+ return 1;
+ }
+ p++;
+
+ /* Check the number is not negative */
+ if (*p & 0x80) {
+ return 1;
+ }
+
+ /* Convert to unsigned int. This code is for a little-endian CPU */
+ cert_nv_ctr = 0;
+ for (i = 0; i < len; i++) {
+ cert_nv_ctr = (cert_nv_ctr << 8) | *p++;
+ }
+
+ /* Get the counter from the platform */
+ rc = plat_get_nv_ctr(param->plat_nv_ctr->cookie, &plat_nv_ctr);
+ return_if_error(rc);
+
+ if (cert_nv_ctr < plat_nv_ctr) {
+ /* Invalid NV-counter */
+ return 1;
+ } else if (cert_nv_ctr > plat_nv_ctr) {
+ if (img_desc->parent == NULL) {
+ /* This certificate has been signed with the ROT key.
+ * Update the platform counter value */
+ rc = plat_set_nv_ctr(param->plat_nv_ctr->cookie,
+ cert_nv_ctr);
+ return_if_error(rc);
+ } else {
+ /* Secondary certificates cannot modify the counter */
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
* Return the parent id in the output parameter '*parent_id'
*
* Return value:
@@ -310,6 +390,10 @@
rc = auth_signature(&auth_method->param.sig,
img_desc, img_ptr, img_len);
break;
+ case AUTH_METHOD_NV_CTR:
+ rc = auth_nvctr(&auth_method->param.nv_ctr,
+ img_desc, img_ptr, img_len);
+ break;
default:
/* Unknown authentication method */
rc = 1;
diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index 52e6971..1a6a9a7 100644
--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c
+++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c
@@ -405,6 +405,13 @@
/*
* Extract an authentication parameter from an X509v3 certificate
+ *
+ * This function returns a pointer to the extracted data and its length.
+ * Depending on the type of parameter, a pointer to the data stored in the
+ * certificate may be returned (i.e. an octet string containing a hash). Other
+ * data may need to be copied and formatted (i.e. integers). In the later case,
+ * a buffer of the correct type needs to be statically allocated, filled and
+ * returned.
*/
static int get_auth_param(const auth_param_type_desc_t *type_desc,
void *img, unsigned int img_len,
@@ -422,6 +429,7 @@
*param_len = (unsigned int)tbs.len;
break;
case AUTH_PARAM_HASH:
+ case AUTH_PARAM_NV_CTR:
/* All these parameters are included as X509v3 extensions */
rc = get_ext(type_desc->cookie, param, param_len);
break;
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index 6023c78..dae35d1 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -56,6 +56,11 @@
/*
* Parameter type descriptors
*/
+static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
+
static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
AUTH_PARAM_PUB_KEY, 0);
static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
@@ -116,6 +121,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -158,6 +170,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -193,6 +212,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -218,6 +244,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -260,6 +293,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -285,6 +325,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -327,6 +374,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -352,6 +406,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -394,6 +455,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
}
},
.authenticated_data = {
@@ -419,6 +487,13 @@
.alg = &sig_alg,
.data = &raw_data,
}
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
}
},
.authenticated_data = {
diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h
index f8e1664..3085688 100644
--- a/include/drivers/arm/tzc400.h
+++ b/include/drivers/arm/tzc400.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -31,178 +31,179 @@
#ifndef __TZC400_H__
#define __TZC400_H__
+#include <tzc_common.h>
-#define BUILD_CONFIG_OFF 0x000
-#define ACTION_OFF 0x004
-#define GATE_KEEPER_OFF 0x008
-#define SPECULATION_CTRL_OFF 0x00c
-#define INT_STATUS 0x010
-#define INT_CLEAR 0x014
+#define BUILD_CONFIG_OFF 0x000
+#define GATE_KEEPER_OFF 0x008
+#define SPECULATION_CTRL_OFF 0x00c
+#define INT_STATUS 0x010
+#define INT_CLEAR 0x014
-#define FAIL_ADDRESS_LOW_OFF 0x020
-#define FAIL_ADDRESS_HIGH_OFF 0x024
-#define FAIL_CONTROL_OFF 0x028
-#define FAIL_ID 0x02c
+#define FAIL_ADDRESS_LOW_OFF 0x020
+#define FAIL_ADDRESS_HIGH_OFF 0x024
+#define FAIL_CONTROL_OFF 0x028
+#define FAIL_ID 0x02c
-#define REGION_BASE_LOW_OFF 0x100
-#define REGION_BASE_HIGH_OFF 0x104
-#define REGION_TOP_LOW_OFF 0x108
-#define REGION_TOP_HIGH_OFF 0x10c
-#define REGION_ATTRIBUTES_OFF 0x110
-#define REGION_ID_ACCESS_OFF 0x114
-#define REGION_NUM_OFF(region) (0x20 * region)
+/* ID registers not common across different varieties of TZC */
+#define PID5 0xFD4
+#define PID6 0xFD8
+#define PID7 0xFDC
-/* ID Registers */
-#define PID0_OFF 0xfe0
-#define PID1_OFF 0xfe4
-#define PID2_OFF 0xfe8
-#define PID3_OFF 0xfec
-#define PID4_OFF 0xfd0
-#define PID5_OFF 0xfd4
-#define PID6_OFF 0xfd8
-#define PID7_OFF 0xfdc
-#define CID0_OFF 0xff0
-#define CID1_OFF 0xff4
-#define CID2_OFF 0xff8
-#define CID3_OFF 0xffc
-
-#define BUILD_CONFIG_NF_SHIFT 24
-#define BUILD_CONFIG_NF_MASK 0x3
-#define BUILD_CONFIG_AW_SHIFT 8
-#define BUILD_CONFIG_AW_MASK 0x3f
-#define BUILD_CONFIG_NR_SHIFT 0
-#define BUILD_CONFIG_NR_MASK 0x1f
-
-/* Not describing the case where regions 1 to 8 overlap */
-#define ACTION_RV_SHIFT 0
-#define ACTION_RV_MASK 0x3
-#define ACTION_RV_LOWOK 0x0
-#define ACTION_RV_LOWERR 0x1
-#define ACTION_RV_HIGHOK 0x2
-#define ACTION_RV_HIGHERR 0x3
+#define BUILD_CONFIG_NF_SHIFT 24
+#define BUILD_CONFIG_NF_MASK 0x3
+#define BUILD_CONFIG_AW_SHIFT 8
+#define BUILD_CONFIG_AW_MASK 0x3f
+#define BUILD_CONFIG_NR_SHIFT 0
+#define BUILD_CONFIG_NR_MASK 0x1f
/*
* Number of gate keepers is implementation defined. But we know the max for
* this device is 4. Get implementation details from BUILD_CONFIG.
*/
-#define GATE_KEEPER_OS_SHIFT 16
-#define GATE_KEEPER_OS_MASK 0xf
-#define GATE_KEEPER_OR_SHIFT 0
-#define GATE_KEEPER_OR_MASK 0xf
-#define GATE_KEEPER_FILTER_MASK 0x1
+#define GATE_KEEPER_OS_SHIFT 16
+#define GATE_KEEPER_OS_MASK 0xf
+#define GATE_KEEPER_OR_SHIFT 0
+#define GATE_KEEPER_OR_MASK 0xf
+#define GATE_KEEPER_FILTER_MASK 0x1
/* Speculation is enabled by default. */
-#define SPECULATION_CTRL_WRITE_DISABLE (1 << 1)
-#define SPECULATION_CTRL_READ_DISABLE (1 << 0)
+#define SPECULATION_CTRL_WRITE_DISABLE (1 << 1)
+#define SPECULATION_CTRL_READ_DISABLE (1 << 0)
/* Max number of filters allowed is 4. */
-#define INT_STATUS_OVERLAP_SHIFT 16
-#define INT_STATUS_OVERLAP_MASK 0xf
-#define INT_STATUS_OVERRUN_SHIFT 8
-#define INT_STATUS_OVERRUN_MASK 0xf
-#define INT_STATUS_STATUS_SHIFT 0
-#define INT_STATUS_STATUS_MASK 0xf
+#define INT_STATUS_OVERLAP_SHIFT 16
+#define INT_STATUS_OVERLAP_MASK 0xf
+#define INT_STATUS_OVERRUN_SHIFT 8
+#define INT_STATUS_OVERRUN_MASK 0xf
+#define INT_STATUS_STATUS_SHIFT 0
+#define INT_STATUS_STATUS_MASK 0xf
-#define INT_CLEAR_CLEAR_SHIFT 0
-#define INT_CLEAR_CLEAR_MASK 0xf
+#define INT_CLEAR_CLEAR_SHIFT 0
+#define INT_CLEAR_CLEAR_MASK 0xf
-#define FAIL_CONTROL_DIR_SHIFT (1 << 24)
-#define FAIL_CONTROL_DIR_READ 0x0
-#define FAIL_CONTROL_DIR_WRITE 0x1
-#define FAIL_CONTROL_NS_SHIFT (1 << 21)
-#define FAIL_CONTROL_NS_SECURE 0x0
-#define FAIL_CONTROL_NS_NONSECURE 0x1
-#define FAIL_CONTROL_PRIV_SHIFT (1 << 20)
-#define FAIL_CONTROL_PRIV_PRIV 0x0
-#define FAIL_CONTROL_PRIV_UNPRIV 0x1
+#define FAIL_CONTROL_DIR_SHIFT (1 << 24)
+#define FAIL_CONTROL_DIR_READ 0x0
+#define FAIL_CONTROL_DIR_WRITE 0x1
+#define FAIL_CONTROL_NS_SHIFT (1 << 21)
+#define FAIL_CONTROL_NS_SECURE 0x0
+#define FAIL_CONTROL_NS_NONSECURE 0x1
+#define FAIL_CONTROL_PRIV_SHIFT (1 << 20)
+#define FAIL_CONTROL_PRIV_PRIV 0x0
+#define FAIL_CONTROL_PRIV_UNPRIV 0x1
/*
* FAIL_ID_ID_MASK depends on AID_WIDTH which is platform specific.
* Platform should provide the value on initialisation.
*/
-#define FAIL_ID_VNET_SHIFT 24
-#define FAIL_ID_VNET_MASK 0xf
-#define FAIL_ID_ID_SHIFT 0
-
-/* Used along with 'tzc_region_attributes_t' below */
-#define REG_ATTR_SEC_SHIFT 30
-#define REG_ATTR_F_EN_SHIFT 0
-#define REG_ATTR_F_EN_MASK 0xf
-#define REG_ATTR_FILTER_BIT(x) ((1 << x) << REG_ATTR_F_EN_SHIFT)
-#define REG_ATTR_FILTER_BIT_ALL (REG_ATTR_F_EN_MASK << \
- REG_ATTR_F_EN_SHIFT)
+#define FAIL_ID_VNET_SHIFT 24
+#define FAIL_ID_VNET_MASK 0xf
+#define FAIL_ID_ID_SHIFT 0
-#define REGION_ID_ACCESS_NSAID_WR_EN_SHIFT 16
-#define REGION_ID_ACCESS_NSAID_RD_EN_SHIFT 0
-#define REGION_ID_ACCESS_NSAID_ID_MASK 0xf
+#define TZC_400_PERIPHERAL_ID 0x460
+/* Filter enable bits in a TZC */
+#define TZC_400_REGION_ATTR_F_EN_MASK 0xf
+#define TZC_400_REGION_ATTR_FILTER_BIT(x) ((1 << x) \
+ << TZC_REGION_ATTR_F_EN_SHIFT)
+#define TZC_400_REGION_ATTR_FILTER_BIT_ALL \
+ (TZC_400_REGION_ATTR_F_EN_MASK << \
+ TZC_REGION_ATTR_F_EN_SHIFT)
-/* Macros for setting Region ID access permissions based on NSAID */
-#define TZC_REGION_ACCESS_RD(id) \
- ((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) << \
- REGION_ID_ACCESS_NSAID_RD_EN_SHIFT)
-#define TZC_REGION_ACCESS_WR(id) \
- ((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) << \
- REGION_ID_ACCESS_NSAID_WR_EN_SHIFT)
-#define TZC_REGION_ACCESS_RDWR(id) \
- (TZC_REGION_ACCESS_RD(id) | TZC_REGION_ACCESS_WR(id))
-
-/* Consist of part_number_1 and part_number_0 */
-#define TZC400_PERIPHERAL_ID 0x0460
-
+/*
+ * Define some macros for backward compatibility with existing tzc400 clients.
+ */
+#if !ERROR_DEPRECATED
+#define REG_ATTR_FILTER_BIT(x) ((1 << x) \
+ << TZC_REGION_ATTR_F_EN_SHIFT)
+#define REG_ATTR_FILTER_BIT_ALL (TZC_400_REGION_ATTR_F_EN_MASK << \
+ TZC_REGION_ATTR_F_EN_SHIFT)
+#endif /* __ERROR_DEPRECATED__ */
+/*
+ * All TZC region configuration registers are placed one after another. It
+ * depicts size of block of registers for programming each region.
+ */
+#define TZC_400_REGION_SIZE 0x20
+#define TZC_400_ACTION_OFF 0x4
#ifndef __ASSEMBLY__
+#include <cdefs.h>
#include <stdint.h>
/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
+void tzc400_init(uintptr_t base);
+void tzc400_configure_region0(tzc_region_attributes_t sec_attr,
+ unsigned int ns_device_access);
+void tzc400_configure_region(unsigned int filters,
+ int region,
+ uintptr_t region_base,
+ uintptr_t region_top,
+ tzc_region_attributes_t sec_attr,
+ unsigned int ns_device_access);
+void tzc400_set_action(tzc_action_t action);
+void tzc400_enable_filters(void);
+void tzc400_disable_filters(void);
/*
- * What type of action is expected when an access violation occurs.
- * The memory requested is zeroed. But we can also raise and event to
- * let the system know it happened.
- * We can raise an interrupt(INT) and/or cause an exception(ERR).
- * TZC_ACTION_NONE - No interrupt, no Exception
- * TZC_ACTION_ERR - No interrupt, raise exception -> sync external
- * data abort
- * TZC_ACTION_INT - Raise interrupt, no exception
- * TZC_ACTION_ERR_INT - Raise interrupt, raise exception -> sync
- * external data abort
+ * Deprecated APIs
*/
-typedef enum {
- TZC_ACTION_NONE = 0,
- TZC_ACTION_ERR = 1,
- TZC_ACTION_INT = 2,
- TZC_ACTION_ERR_INT = (TZC_ACTION_ERR | TZC_ACTION_INT)
-} tzc_action_t;
-
-/*
- * Controls secure access to a region. If not enabled secure access is not
- * allowed to region.
- */
-typedef enum {
- TZC_REGION_S_NONE = 0,
- TZC_REGION_S_RD = 1,
- TZC_REGION_S_WR = 2,
- TZC_REGION_S_RDWR = (TZC_REGION_S_RD | TZC_REGION_S_WR)
-} tzc_region_attributes_t;
+static inline void tzc_init(uintptr_t base) __deprecated;
+static inline void tzc_configure_region0(
+ tzc_region_attributes_t sec_attr,
+ unsigned int ns_device_access) __deprecated;
+static inline void tzc_configure_region(
+ unsigned int filters,
+ int region,
+ uintptr_t region_base,
+ uintptr_t region_top,
+ tzc_region_attributes_t sec_attr,
+ unsigned int ns_device_access) __deprecated;
+static inline void tzc_set_action(tzc_action_t action) __deprecated;
+static inline void tzc_enable_filters(void) __deprecated;
+static inline void tzc_disable_filters(void) __deprecated;
+static inline void tzc_init(uintptr_t base)
+{
+ tzc400_init(base);
+}
-void tzc_init(uintptr_t base);
-void tzc_configure_region0(tzc_region_attributes_t sec_attr,
- uint32_t ns_device_access);
-void tzc_configure_region(uint32_t filters,
- uint8_t region,
- uint64_t region_base,
- uint64_t region_top,
+static inline void tzc_configure_region0(
tzc_region_attributes_t sec_attr,
- uint32_t ns_device_access);
-void tzc_enable_filters(void);
-void tzc_disable_filters(void);
-void tzc_set_action(tzc_action_t action);
+ unsigned int ns_device_access)
+{
+ tzc400_configure_region0(sec_attr, ns_device_access);
+}
+
+static inline void tzc_configure_region(
+ unsigned int filters,
+ int region,
+ uintptr_t region_base,
+ uintptr_t region_top,
+ tzc_region_attributes_t sec_attr,
+ unsigned int ns_device_access)
+{
+ tzc400_configure_region(filters, region, region_base,
+ region_top, sec_attr, ns_device_access);
+}
+
+static inline void tzc_set_action(tzc_action_t action)
+{
+ tzc400_set_action(action);
+}
+
+
+static inline void tzc_enable_filters(void)
+{
+ tzc400_enable_filters();
+}
+
+static inline void tzc_disable_filters(void)
+{
+ tzc400_disable_filters();
+}
#endif /* __ASSEMBLY__ */
diff --git a/include/drivers/arm/tzc_common.h b/include/drivers/arm/tzc_common.h
new file mode 100644
index 0000000..9b73c3f
--- /dev/null
+++ b/include/drivers/arm/tzc_common.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 __TZC_COMMON_H__
+#define __TZC_COMMON_H__
+
+/*
+ * Offset of core registers from the start of the base of configuration
+ * registers for each region.
+ */
+
+/* ID Registers */
+#define PID0_OFF 0xfe0
+#define PID1_OFF 0xfe4
+#define PID2_OFF 0xfe8
+#define PID3_OFF 0xfec
+#define PID4_OFF 0xfd0
+#define CID0_OFF 0xff0
+#define CID1_OFF 0xff4
+#define CID2_OFF 0xff8
+#define CID3_OFF 0xffc
+
+/* Bit positions of TZC_ACTION registers */
+#define TZC_ACTION_RV_SHIFT 0
+#define TZC_ACTION_RV_MASK 0x3
+#define TZC_ACTION_RV_LOWOK 0x0
+#define TZC_ACTION_RV_LOWERR 0x1
+#define TZC_ACTION_RV_HIGHOK 0x2
+#define TZC_ACTION_RV_HIGHERR 0x3
+
+/* Used along with 'tzc_region_attributes_t' below */
+#define TZC_REGION_ATTR_S_RD_SHIFT 30
+#define TZC_REGION_ATTR_S_WR_SHIFT 31
+#define TZC_REGION_ATTR_F_EN_SHIFT 0
+#define TZC_REGION_ATTR_SEC_SHIFT 30
+#define TZC_REGION_ATTR_S_RD_MASK 0x1
+#define TZC_REGION_ATTR_S_WR_MASK 0x1
+#define TZC_REGION_ATTR_SEC_MASK 0x3
+
+#define TZC_REGION_ACCESS_WR_EN_SHIFT 16
+#define TZC_REGION_ACCESS_RD_EN_SHIFT 0
+#define TZC_REGION_ACCESS_ID_MASK 0xf
+
+/* Macros for allowing Non-Secure access to a region based on NSAID */
+#define TZC_REGION_ACCESS_RD(nsaid) \
+ ((1 << (nsaid & TZC_REGION_ACCESS_ID_MASK)) << \
+ TZC_REGION_ACCESS_RD_EN_SHIFT)
+#define TZC_REGION_ACCESS_WR(nsaid) \
+ ((1 << (nsaid & TZC_REGION_ACCESS_ID_MASK)) << \
+ TZC_REGION_ACCESS_WR_EN_SHIFT)
+#define TZC_REGION_ACCESS_RDWR(nsaid) \
+ (TZC_REGION_ACCESS_RD(nsaid) | \
+ TZC_REGION_ACCESS_WR(nsaid))
+
+#ifndef __ASSEMBLY__
+
+/* Returns offset of registers to program for a given region no */
+#define TZC_REGION_OFFSET(region_size, region_no) \
+ ((region_size) * (region_no))
+
+/*
+ * What type of action is expected when an access violation occurs.
+ * The memory requested is returned as zero. But we can also raise an event to
+ * let the system know it happened.
+ * We can raise an interrupt(INT) and/or cause an exception(ERR).
+ * TZC_ACTION_NONE - No interrupt, no Exception
+ * TZC_ACTION_ERR - No interrupt, raise exception -> sync external
+ * data abort
+ * TZC_ACTION_INT - Raise interrupt, no exception
+ * TZC_ACTION_ERR_INT - Raise interrupt, raise exception -> sync
+ * external data abort
+ */
+typedef enum {
+ TZC_ACTION_NONE = 0,
+ TZC_ACTION_ERR = 1,
+ TZC_ACTION_INT = 2,
+ TZC_ACTION_ERR_INT = (TZC_ACTION_ERR | TZC_ACTION_INT)
+} tzc_action_t;
+
+/*
+ * Controls secure access to a region. If not enabled secure access is not
+ * allowed to region.
+ */
+typedef enum {
+ TZC_REGION_S_NONE = 0,
+ TZC_REGION_S_RD = 1,
+ TZC_REGION_S_WR = 2,
+ TZC_REGION_S_RDWR = (TZC_REGION_S_RD | TZC_REGION_S_WR)
+} tzc_region_attributes_t;
+
+#endif /* __ASSEMBLY__ */
+#endif /* __TZC_COMMON_H__ */
diff --git a/include/drivers/arm/tzc_dmc500.h b/include/drivers/arm/tzc_dmc500.h
new file mode 100644
index 0000000..70f8ad2
--- /dev/null
+++ b/include/drivers/arm/tzc_dmc500.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 __TZC_DMC500_H__
+#define __TZC_DMC500_H__
+
+#include <tzc_common.h>
+
+#define SI_STATUS_OFFSET 0x000
+#define SI_STATE_CTRL_OFFSET 0x030
+#define SI_FLUSH_CTRL_OFFSET 0x034
+#define SI_INT_CONTROL_OFFSET 0x048
+
+#define SI_INT_STATUS_OFFSET 0x004
+#define SI_TZ_FAIL_ADDRESS_LOW_OFFSET 0x008
+#define SI_TZ_FAIL_ADDRESS_HIGH_OFFSET 0x00c
+#define SI_FAIL_CONTROL_OFFSET 0x010
+#define SI_FAIL_ID_OFFSET 0x014
+#define SI_INT_CLR_OFFSET 0x04c
+
+/*
+ * DMC-500 has 2 system interfaces each having a similar set of regs
+ * to configure each interface.
+ */
+#define SI0_BASE 0x0000
+#define SI1_BASE 0x0200
+
+/* Bit positions of SIx_SI_STATUS */
+#define SI_EMPTY_SHIFT 0x01
+#define SI_STALL_ACK_SHIFT 0x00
+#define SI_EMPTY_MASK 0x01
+#define SI_STALL_ACK_MASK 0x01
+
+/* Bit positions of SIx_SI_INT_STATUS */
+#define PMU_REQ_INT_OVERFLOW_STATUS_SHIFT 18
+#define FAILED_ACCESS_INT_OVERFLOW_STATUS_SHIFT 16
+#define PMU_REQ_INT_STATUS_SHIFT 2
+#define FAILED_ACCESS_INT_INFO_TZ_OVERLAP_STATUS_SHIFT 1
+#define FAILED_ACCESS_INT_STATUS_SHIFT 0
+#define PMU_REQ_INT_OVERFLOW_STATUS_MASK 0x1
+#define FAILED_ACCESS_INT_OVERFLOW_STATUS_MASK 0x1
+#define PMU_REQ_INT_STATUS_MASK 0x1
+#define FAILED_ACCESS_INT_INFO_TZ_OVERLAP_STATUS_MASK 0x1
+#define FAILED_ACCESS_INT_STATUS_MASK 0x1
+
+/* Bit positions of SIx_TZ_FAIL_CONTROL */
+#define DIRECTION_SHIFT 24
+#define NON_SECURE_SHIFT 21
+#define PRIVILEGED_SHIFT 20
+#define FAILED_ACCESS_INT_INFO_RANK_MASKED_SHIFT 3
+#define FAILED_ACCESS_INT_INFO_UNMAPPED_SHIFT 2
+#define FAILED_ACCESS_INT_TZ_FAIL_SHIFT 0x1
+#define FAILED_ACCESS_INT_INFO_OUTSIDE_DEFAULT_SHIFT 0
+#define DIRECTION_MASK 0x1
+#define NON_SECURE_MASK 0x1
+#define PRIVILEGED_MASK 0x1
+#define FAILED_ACCESS_INT_INFO_RANK_MASKED_MASK 0x1
+#define FAILED_ACCESS_INT_INFO_UNMAPPED_MASK 0x1
+#define FAILED_ACCESS_INT_TZ_FAIL_MASK 1
+#define FAILED_ACCESS_INT_INFO_OUTSIDE_DEFAULT_MASK 0x1
+
+/* Bit positions of SIx_FAIL_STATUS */
+#define FAIL_ID_VNET_SHIFT 24
+#define FAIL_ID_ID_SHIFT 0
+#define FAIL_ID_VNET_MASK 0xf
+#define FAIL_ID_ID_MASK 0xffffff
+
+/* Bit positions of SIx_SI_STATE_CONTRL */
+#define SI_STALL_REQ_GO 0x0
+#define SI_STALL_REQ_STALL 0x1
+
+/* Bit positions of SIx_SI_FLUSH_CONTROL */
+#define SI_FLUSH_REQ_INACTIVE 0x0
+#define SI_FLUSH_REQ_ACTIVE 0x1
+#define SI_FLUSH_REQ_MASK 0x1
+
+/* Bit positions of SIx_SI_INT_CONTROL */
+#define PMU_REQ_INT_EN_SHIFT 2
+#define OVERLAP_DETECT_INT_EN_SHIFT 1
+#define FAILED_ACCESS_INT_EN_SHIFT 0
+#define PMU_REQ_INT_EN_MASK 0x1
+#define OVERLAP_DETECT_INT_EN_MASK 0x1
+#define FAILED_ACCESS_INT_EN_MASK 0x1
+#define PMU_REQ_INT_EN 0x1
+#define OVERLAP_DETECT_INT_EN 0x1
+#define FAILED_ACCESS_INT_EN 0x1
+
+/* Bit positions of SIx_SI_INT_CLR */
+#define PMU_REQ_OFLOW_CLR_SHIFT 18
+#define FAILED_ACCESS_OFLOW_CLR_SHIFT 16
+#define PMU_REQ_INT_CLR_SHIFT 2
+#define FAILED_ACCESS_INT_CLR_SHIFT 0
+#define PMU_REQ_OFLOW_CLR_MASK 0x1
+#define FAILED_ACCESS_OFLOW_CLR_MASK 0x1
+#define PMU_REQ_INT_CLR_MASK 0x1
+#define FAILED_ACCESS_INT_CLR_MASK 0x1
+#define PMU_REQ_OFLOW_CLR 0x1
+#define FAILED_ACCESS_OFLOW_CLR 0x1
+#define PMU_REQ_INT_CLR 0x1
+#define FAILED_ACCESS_INT_CLR 0x1
+
+/* Macro to get the correct base register for a system interface */
+#define IFACE_OFFSET(sys_if) ((sys_if) ? SI1_BASE : SI0_BASE)
+
+#define MAX_SYS_IF_COUNT 2
+#define MAX_REGION_VAL 8
+
+/* DMC-500 supports striping across a max of 4 DMC instances */
+#define MAX_DMC_COUNT 4
+
+/* Consist of part_number_1 and part_number_0 */
+#define DMC500_PERIPHERAL_ID 0x0450
+
+/* Filter enable bits in a TZC */
+#define TZC_DMC500_REGION_ATTR_F_EN_MASK 0x1
+
+/* Length of registers for configuring each region */
+#define TZC_DMC500_REGION_SIZE 0x018
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+/*
+ * Contains the base addresses of all the DMC instances.
+ */
+typedef struct tzc_dmc500_driver_data {
+ uintptr_t dmc_base[MAX_DMC_COUNT];
+ int dmc_count;
+} tzc_dmc500_driver_data_t;
+
+void tzc_dmc500_driver_init(const tzc_dmc500_driver_data_t *plat_driver_data);
+void tzc_dmc500_configure_region0(tzc_region_attributes_t sec_attr,
+ unsigned int nsaid_permissions);
+void tzc_dmc500_configure_region(int region_no,
+ uintptr_t region_base,
+ uintptr_t region_top,
+ tzc_region_attributes_t sec_attr,
+ unsigned int nsaid_permissions);
+void tzc_dmc500_set_action(tzc_action_t action);
+void tzc_dmc500_config_complete(void);
+int tzc_dmc500_verify_complete(void);
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* __TZC_DMC500_H__ */
+
diff --git a/include/drivers/auth/auth_common.h b/include/drivers/auth/auth_common.h
index 52a895e..456f69f 100644
--- a/include/drivers/auth/auth_common.h
+++ b/include/drivers/auth/auth_common.h
@@ -46,6 +46,7 @@
AUTH_PARAM_SIG_ALG, /* The image signature algorithm */
AUTH_PARAM_HASH, /* A hash (including the algorithm) */
AUTH_PARAM_PUB_KEY, /* A public key */
+ AUTH_PARAM_NV_CTR, /* A non-volatile counter */
} auth_param_type_t;
/*
@@ -80,6 +81,7 @@
AUTH_METHOD_NONE = 0,
AUTH_METHOD_HASH, /* Authenticate by hash matching */
AUTH_METHOD_SIG, /* Authenticate by PK operation */
+ AUTH_METHOD_NV_CTR, /* Authenticate by Non-Volatile Counter */
AUTH_METHOD_NUM /* Number of methods */
} auth_method_type_t;
@@ -105,7 +107,8 @@
* Parameters for authentication by NV counter
*/
typedef struct auth_method_param_nv_ctr_s {
- auth_param_type_desc_t *nv_ctr; /* NV counter value */
+ auth_param_type_desc_t *cert_nv_ctr; /* NV counter in certificate */
+ auth_param_type_desc_t *plat_nv_ctr; /* NV counter in platform */
} auth_method_param_nv_ctr_t;
/*
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index e9eebaa..2fe0a69 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -130,7 +130,9 @@
void arm_io_setup(void);
/* Security utility functions */
-void arm_tzc_setup(void);
+void arm_tzc400_setup(void);
+struct tzc_dmc500_driver_data;
+void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data);
/* Systimer utility function */
void arm_configure_sys_timer(void);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index f92126b..636daf2 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -143,7 +143,7 @@
#define PLAT_ARM_NS_IMAGE_OFFSET 0xE0000000
/* TZC related constants */
-#define PLAT_ARM_TZC_FILTERS REG_ATTR_FILTER_BIT_ALL
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
/* Trusted mailbox base address common to all CSS */
#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
diff --git a/include/plat/arm/soc/common/soc_css_def.h b/include/plat/arm/soc/common/soc_css_def.h
index 428df4d..f1396a6 100644
--- a/include/plat/arm/soc/common/soc_css_def.h
+++ b/include/plat/arm/soc/common/soc_css_def.h
@@ -65,6 +65,13 @@
*/
#define SOC_CSS_NIC400_APB4_BRIDGE 4
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE 0x7fe70000
+#define TFW_NVCTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0000)
+#define TFW_NVCTR_SIZE 4
+#define NTFW_CTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE 4
+
/* Keys */
#define SOC_KEYS_BASE 0x7fe80000
#define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + 0x0000)
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 6f0a8a0..5857501 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -249,6 +249,8 @@
******************************************************************************/
int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
unsigned int *flags);
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr);
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
#if ENABLE_PLAT_COMPAT
/*
diff --git a/make_helpers/build_env.mk b/make_helpers/build_env.mk
new file mode 100644
index 0000000..62c7f68
--- /dev/null
+++ b/make_helpers/build_env.mk
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 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.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+#
+
+# This file contains the logic to identify and include any relevant
+# build environment specific make include files.
+
+ifndef BUILD_ENV_MK
+ BUILD_ENV_MK := $(lastword $(MAKEFILE_LIST))
+
+ # Block possible built-in command definitions that are not fully portable.
+ # This traps occurences that need replacing with our OS portable macros
+ COPY := $$(error "Replace COPY with call to SHELL_COPY or SHELL_COPY_TREE.")
+ CP := $$(error "Replace CP with call to SHELL_COPY or SHELL_COPY_TREE.")
+ DEL := $$(error "Replace DEL with call to SHELL_DELETE.")
+ MD := $$(error "Replace MD with call to MAKE_PREREQ_DIR.")
+ MKDIR := $$(error "Replace MKDIR with call to MAKE_PREREQ_DIR.")
+ RD := $$(error "Replace RD with call to SHELL_REMOVE_DIR.")
+ RM := $$(error "Replace RM with call to SHELL_DELETE.")
+ RMDIR := $$(error "Replace RMDIR with call to SHELL_REMOVE_DIR.")
+
+ ENV_FILE_TO_INCLUDE := unix.mk
+ ifdef OSTYPE
+ ifneq ($(findstring ${OSTYPE}, cygwin),)
+ ENV_FILE_TO_INCLUDE := cygwin.mk
+ else
+ ifneq ($(findstring ${OSTYPE}, MINGW32 mingw msys),)
+ ENV_FILE_TO_INCLUDE := msys.mk
+ endif
+ endif
+ else
+ ifdef MSYSTEM
+ # Although the MINGW MSYS shell sets OSTYPE as msys in its environment,
+ # it does not appear in the GNU make view of environment variables.
+ # We use MSYSTEM as an alternative, as that is seen by make
+ ifneq ($(findstring ${MSYSTEM}, MINGW32 mingw msys),)
+ OSTYPE ?= msys
+ ENV_FILE_TO_INCLUDE := msys.mk
+ endif
+ else
+ ifdef OS
+ ifneq ($(findstring ${OS}, Windows_NT),)
+ ENV_FILE_TO_INCLUDE := windows.mk
+ endif
+ endif
+ endif
+ endif
+ include ${MAKE_HELPERS_DIRECTORY}${ENV_FILE_TO_INCLUDE}
+ ENV_FILE_TO_INCLUDE :=
+
+ ifndef SHELL_COPY
+ $(error "SHELL_COPY not defined for build environment.")
+ endif
+ ifndef SHELL_COPY_TREE
+ $(error "SHELL_COPY_TREE not defined for build environment.")
+ endif
+ ifndef SHELL_DELETE_ALL
+ $(error "SHELL_DELETE_ALL not defined for build environment.")
+ endif
+ ifndef SHELL_DELETE
+ $(error "SHELL_DELETE not defined for build environment.")
+ endif
+ ifndef MAKE_PREREQ_DIR
+ $(error "MAKE_PREREQ_DIR not defined for build environment.")
+ endif
+ ifndef SHELL_REMOVE_DIR
+ $(error "SHELL_REMOVE_DIR not defined for build environment.")
+ endif
+
+endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index b22eaf9..5171ff0 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -28,6 +28,23 @@
# POSSIBILITY OF SUCH DAMAGE.
#
+# Report an error if the eval make function is not available.
+$(eval eval_available := T)
+ifneq (${eval_available},T)
+ $(error This makefile only works with a Make program that supports $$(eval))
+endif
+
+# Some utility macros for manipulating awkward (whitespace) characters.
+blank :=
+space :=${blank} ${blank}
+
+# A user defined function to recursively search for a filename below a directory
+# $1 is the directory root of the recursive search (blank for current directory).
+# $2 is the file name to search for.
+define rwildcard
+$(strip $(foreach d,$(wildcard ${1}*),$(call rwildcard,${d}/,${2}) $(filter $(subst *,%,%${2}),${d})))
+endef
+
# This table is used in converting lower case to upper case.
uppercase_table:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
@@ -193,10 +210,8 @@
@echo " CC $$<"
$$(Q)$$(CC) $$(CFLAGS) -D$(IMAGE) -c $$< -o $$@
-
-$(PREREQUISITES): $(2)
+$(PREREQUISITES): $(2) | bl$(3)_dirs
@echo " DEPS $$@"
- @mkdir -p $(1)
$$(Q)$$(CC) $$(CFLAGS) -M -MT $(OBJ) -MF $$@ $$<
ifdef IS_ANYTHING_TO_BUILD
@@ -220,9 +235,8 @@
@echo " AS $$<"
$$(Q)$$(AS) $$(ASFLAGS) -D$(IMAGE) -c $$< -o $$@
-$(PREREQUISITES): $(2)
+$(PREREQUISITES): $(2) | bl$(3)_dirs
@echo " DEPS $$@"
- @mkdir -p $(1)
$$(Q)$$(AS) $$(ASFLAGS) -M -MT $(OBJ) -MF $$@ $$<
ifdef IS_ANYTHING_TO_BUILD
@@ -243,9 +257,8 @@
@echo " PP $$<"
$$(Q)$$(AS) $$(ASFLAGS) -P -E -D__LINKER__ -o $$@ $$<
-$(PREREQUISITES): $(2)
+$(PREREQUISITES): $(2) | $(dir ${1})
@echo " DEPS $$@"
- @mkdir -p $$(dir $$@)
$$(Q)$$(AS) $$(ASFLAGS) -M -MT $(1) -MF $$@ $$<
ifdef IS_ANYTHING_TO_BUILD
@@ -274,7 +287,7 @@
# NOTE: The line continuation '\' is required in the next define otherwise we
# end up with a line-feed characer at the end of the last c filename.
-# Also bare this issue in mind if extending the list of supported filetypes.
+# Also bear this issue in mind if extending the list of supported filetypes.
define SOURCES_TO_OBJS
$(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
$(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
@@ -310,18 +323,36 @@
$(eval DUMP := $(call IMG_DUMP,$(1)))
$(eval BIN := $(call IMG_BIN,$(1)))
$(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE))
+ # We use sort only to get a list of unique object directory names.
+ # ordering is not relevant but sort removes duplicates.
+ $(eval TEMP_OBJ_DIRS := $(sort $(BUILD_DIR)/ $(dir ${OBJS})))
+ # The $(dir ) function leaves a trailing / on the directory names
+ # We append a . then strip /. from each, to remove the trailing / characters
+ # This gives names suitable for use as make rule targets.
+ $(eval OBJ_DIRS := $(subst /.,,$(addsuffix .,$(TEMP_OBJ_DIRS))))
+
+# Create generators for object directory structure
- $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
- $(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE)))
+$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},)))
-$(BUILD_DIR):
- $$(Q)mkdir -p "$$@"
+.PHONY : bl${1}_dirs
-$(ELF): $(OBJS) $(LINKERFILE)
+# We use order-only prerequisites to ensure that directories are created,
+# but do not cause re-builds every time a file is written.
+bl${1}_dirs: | ${OBJ_DIRS}
+
+$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+$(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE)))
+
+$(ELF): $(OBJS) $(LINKERFILE) | bl$(1)_dirs
@echo " LD $$@"
+ifdef MAKE_BUILD_STRINGS
+ $(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
+else
@echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP); \
const char version_string[] = "${VERSION_STRING}";' | \
$$(CC) $$(CFLAGS) -xc - -o $(BUILD_DIR)/build_message.o
+endif
$$(Q)$$(LD) -o $$@ $$(LDFLAGS) -Map=$(MAPFILE) --script $(LINKERFILE) \
$(BUILD_DIR)/build_message.o $(OBJS)
@@ -337,7 +368,7 @@
@echo
.PHONY: bl$(1)
-bl$(1): $(BUILD_DIR) $(BIN) $(DUMP)
+bl$(1): $(BIN) $(DUMP)
all: bl$(1)
diff --git a/make_helpers/cygwin.mk b/make_helpers/cygwin.mk
new file mode 100644
index 0000000..e69c0b1
--- /dev/null
+++ b/make_helpers/cygwin.mk
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 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.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+#
+#
+
+# OS specific definitions for builds in a Cygwin environment.
+# Cygwin allows us to use unix style commands on a windows platform.
+
+ifndef CYGWIN_MK
+ CYGWIN_MK := $(lastword $(MAKEFILE_LIST))
+
+ include ${MAKE_HELPERS_DIRECTORY}unix.mk
+
+ # In cygwin executable files have the Windows .exe extension type.
+ BIN_EXT := .exe
+
+endif
diff --git a/make_helpers/msys.mk b/make_helpers/msys.mk
new file mode 100644
index 0000000..188dc6c
--- /dev/null
+++ b/make_helpers/msys.mk
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 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.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+#
+#
+
+# OS specific definitions for builds in a Mingw32 MSYS environment.
+# Mingw32 allows us to use some unix style commands on a windows platform.
+
+ifndef MSYS_MK
+ MSYS_MK := $(lastword $(MAKEFILE_LIST))
+
+ include ${MAKE_HELPERS_DIRECTORY}unix.mk
+
+ # In MSYS executable files have the Windows .exe extension type.
+ BIN_EXT := .exe
+
+endif
+
diff --git a/make_helpers/plat_helpers.mk b/make_helpers/plat_helpers.mk
new file mode 100644
index 0000000..85ba84f
--- /dev/null
+++ b/make_helpers/plat_helpers.mk
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 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.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+#
+
+################################################################################
+# Helpers for finding and referencing platform directories
+################################################################################
+
+ifndef PLAT_HELPERS_MK
+ PLAT_HELPERS_MK := $(lastword $(MAKEFILE_LIST))
+
+ ifeq (${PLAT},)
+ $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
+ endif
+
+ # PLATFORM_ROOT can be overridden for when building tools directly
+ PLATFORM_ROOT ?= plat/
+ PLAT_MAKEFILE := platform.mk
+
+ # Generate the platforms list by recursively searching for all directories
+ # under /plat containing a PLAT_MAKEFILE. Append each platform with a `|`
+ # char and strip out the final '|'.
+ ALL_PLATFORM_MK_FILES := $(call rwildcard,${PLATFORM_ROOT},${PLAT_MAKEFILE})
+ ALL_PLATFORM_DIRS := $(patsubst %/,%,$(dir ${ALL_PLATFORM_MK_FILES}))
+ ALL_PLATFORMS := $(sort $(notdir ${ALL_PLATFORM_DIRS}))
+
+ PLAT_MAKEFILE_FULL := $(filter %/${PLAT}/${PLAT_MAKEFILE},${ALL_PLATFORM_MK_FILES})
+ PLATFORM_LIST := $(subst ${space},|,${ALL_PLATFORMS})
+ ifeq ($(PLAT_MAKEFILE_FULL),)
+ $(error "Error: Invalid platform. The following platforms are available: ${PLATFORM_LIST}")
+ endif
+
+ # Record the directory where the platform make file was found.
+ PLAT_DIR := $(dir ${PLAT_MAKEFILE_FULL})
+
+endif
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index e934d72..71d9747 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -58,6 +58,14 @@
TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt
FWU_CERT := ${BUILD_PLAT}/fwu_cert.crt
+# Default non-volatile counter values (overridable by the platform)
+TFW_NVCTR_VAL ?= 0
+NTFW_NVCTR_VAL ?= 0
+
+# Pass the non-volatile counters to the cert_create tool
+$(eval $(call CERT_ADD_CMD_OPT,${TFW_NVCTR_VAL},--tfw-nvctr))
+$(eval $(call CERT_ADD_CMD_OPT,${NTFW_NVCTR_VAL},--ntfw-nvctr))
+
# Add Trusted Key certificate to the fip_create and cert_create command line options
$(eval $(call FIP_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert))
$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_KEY_CERT},--trusted-key-cert))
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
new file mode 100644
index 0000000..ab60435
--- /dev/null
+++ b/make_helpers/unix.mk
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 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.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+#
+#
+
+# Trusted Firmware shell command definitions for a Unix style environment.
+
+ifndef UNIX_MK
+ UNIX_MK := $(lastword $(MAKEFILE_LIST))
+
+ ECHO_BLANK_LINE := echo
+
+ DIR_DELIM := /
+ PATH_SEP := :
+
+ # These defines provide Unix style equivalents of the shell commands
+ # required by the Trusted Firmware build environment.
+
+ # ${1} is the file to be copied.
+ # ${2} is the destination file name.
+ define SHELL_COPY
+ ${Q}cp -f "${1}" "${2}"
+ endef
+
+ # ${1} is the directory to be copied.
+ # ${2} is the destination directory path.
+ define SHELL_COPY_TREE
+ ${Q}cp -rf "${1}" "${2}"
+ endef
+
+ # ${1} is the file to be deleted.
+ define SHELL_DELETE
+ -${Q}rm -f "${1}"
+ endef
+
+ # ${1} is a space delimited list of files to be deleted.
+ # Note that we do not quote ${1}, as multiple parameters may be passed.
+ define SHELL_DELETE_ALL
+ -${Q}rm -rf ${1}
+ endef
+
+ # ${1} is the directory to be generated.
+ # ${2} is optional, and allows a prerequisite to be specified.
+ define MAKE_PREREQ_DIR
+
+${1} : ${2}
+ ${Q}mkdir -p "${1}"
+
+ endef
+
+ define SHELL_REMOVE_DIR
+ -${Q}rm -rf "${1}"
+ endef
+
+endif
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
new file mode 100644
index 0000000..8ac8246
--- /dev/null
+++ b/make_helpers/windows.mk
@@ -0,0 +1,109 @@
+#
+# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 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.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+#
+#
+
+# OS specific parts for builds in a Windows_NT environment. The
+# environment variable OS is set to Windows_NT on all modern Windows platforms
+
+# Include generic windows command definitions.
+
+ifndef WINDOWS_MK
+ WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
+
+ ECHO_BLANK_LINE := @cmd /c echo.
+ DIR_DELIM := $(strip \)
+ BIN_EXT := .exe
+ PATH_SEP := ;
+
+ # For some Windows native commands there is a problem with the directory delimiter.
+ # Make uses / (slash) and the commands expect \ (backslash)
+ # We have to provide a means of translating these, so we define local functions.
+
+ # ${1} is the file to be copied.
+ # ${2} is the destination file name.
+ define SHELL_COPY
+ $(eval tmp_from_file:=$(subst /,\,${1}))
+ $(eval tmp_to_file:=$(subst /,\,${2}))
+ copy "${tmp_from_file}" "${tmp_to_file}"
+ endef
+
+ # ${1} is the directory to be copied.
+ # ${2} is the destination directory path.
+ define SHELL_COPY_TREE
+ $(eval tmp_from_dir:=$(subst /,\,${1}))
+ $(eval tmp_to_dir:=$(subst /,\,${2}))
+ xcopy /HIVE "${tmp_from_dir}" "${tmp_to_dir}"
+ endef
+
+ # ${1} is the file to be deleted.
+ define SHELL_DELETE
+ $(eval tmp_del_file:=$(subst /,\,${*}))
+ -@if exist $(tmp_del_file) del /Q $(tmp_del_file)
+ endef
+
+ # ${1} is a space delimited list of files to be deleted.
+ define SHELL_DELETE_ALL
+ $(eval $(foreach filename,$(wildcard ${1}),$(call DELETE_IF_THERE,${filename})))
+ endef
+
+ # ${1} is the directory to be generated.
+ # ${2} is optional, and allows prerequisites to be specified.
+ define MAKE_PREREQ_DIR
+
+${1} : ${2}
+ $(eval tmp_dir:=$(subst /,\,${1}))
+ -@if not exist "$(tmp_dir)" mkdir "${tmp_dir}"
+
+ endef
+
+ # ${1} is the directory to be removed.
+ define SHELL_REMOVE_DIR
+ $(eval tmp_dir:=$(subst /,\,${1}))
+ -@if exist "$(tmp_dir)" rd /Q /S "$(tmp_dir)"
+ endef
+
+endif
+
+# Because git is not available from CMD.EXE, we need to avoid
+# the BUILD_STRING generation which uses git.
+# For now we use "development build".
+# This can be overridden from the command line or environment.
+BUILD_STRING ?= development build
+
+# The DOS echo shell command does not strip ' characters from the command
+# parameters before printing. We therefore use an alternative method invoked
+# by defining the MAKE_BUILD_STRINGS macro.
+BUILT_TIME_DATE_STRING = const char build_message[] = "Built : "${BUILD_MESSAGE_TIMESTAMP};
+VERSION_STRING_MESSAGE = const char version_string[] = "${VERSION_STRING}";
+define MAKE_BUILD_STRINGS
+ @echo $$(BUILT_TIME_DATE_STRING) $$(VERSION_STRING_MESSAGE) | \
+ $$(CC) $$(CFLAGS) -x c - -o $1
+endef
+
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 103aafb..7ae00cc 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -31,11 +31,14 @@
#include <arm_def.h>
#include <assert.h>
#include <platform.h>
+#include <platform_oid.h>
#include <stdint.h>
#include <string.h>
/* Weak definition may be overridden in specific platform */
#pragma weak plat_match_rotpk
+#pragma weak plat_get_nv_ctr
+#pragma weak plat_set_nv_ctr
/* SHA256 algorithm */
#define SHA256_BYTES 32
@@ -148,3 +151,43 @@
return 0;
}
+/*
+ * Return the non-volatile counter value stored in the platform. The cookie
+ * will contain the OID of the counter in the certificate.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ const char *oid;
+ uint32_t *nv_ctr_addr;
+
+ assert(cookie != NULL);
+ assert(nv_ctr != NULL);
+
+ oid = (const char *)cookie;
+ if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
+ } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
+ } else {
+ return 1;
+ }
+
+ *nv_ctr = (unsigned int)(*nv_ctr_addr);
+
+ return 0;
+}
+
+/*
+ * Store a new non-volatile counter value. On Juno and FVP, the non-volatile
+ * counters are RO and cannot be modified. We expect the values in the
+ * certificates to always match the RO values so that this function is never
+ * called.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 1;
+}
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index da6beec..6ddc0c9 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -51,6 +51,11 @@
endif
$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+ # Certificate NV-Counters. Use values corresponding to tied off values in
+ # ARM development platforms
+ TFW_NVCTR_VAL ?= 31
+ NTFW_NVCTR_VAL ?= 223
+
BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
endif
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index dbca280..b0f07ef 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -69,7 +69,13 @@
#define PCIE_EXP_BASE 0x40000000
#define TZRNG_BASE 0x7fe60000
-#define TZNVCTR_BASE 0x7fe70000
+
+/* Non-volatile counters */
+#define TRUSTED_NVCTR_BASE 0x7fe70000
+#define TFW_NVCTR_BASE (TRUSTED_NVCTR_BASE + 0x0000)
+#define TFW_NVCTR_SIZE 4
+#define NTFW_CTR_BASE (TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE 4
/* Keys */
#define SOC_KEYS_BASE 0x7fe80000
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 0cf8450..b1de977 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -46,5 +46,5 @@
*/
if (get_arm_config()->flags & ARM_CONFIG_HAS_TZC)
- arm_tzc_setup();
+ arm_tzc400_setup();
}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 3428cb5..ca8e35e 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -113,7 +113,7 @@
* would normally use the default ID so allow that too.
*/
#define PLAT_ARM_TZC_BASE 0x2a4a0000
-#define PLAT_ARM_TZC_FILTERS REG_ATTR_FILTER_BIT(0)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
#define PLAT_ARM_TZC_NS_DEV_ACCESS ( \
TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) | \
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index aad2e2e..afd939d 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -65,7 +65,7 @@
FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \
plat/arm/common/arm_cci.c
-FVP_SECURITY_SOURCES := drivers/arm/tzc400/tzc400.c \
+FVP_SECURITY_SOURCES := drivers/arm/tzc/tzc400.c \
plat/arm/board/fvp/fvp_security.c \
plat/arm/common/arm_tzc400.c
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index f9386ca..202342a 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -65,7 +65,7 @@
void plat_arm_security_setup(void)
{
/* Initialize the TrustZone Controller */
- arm_tzc_setup();
+ arm_tzc400_setup();
/* Do ARM CSS internal NIC setup */
css_init_nic400();
/* Do ARM CSS SoC security setup */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 0a2244d..4fda4ca 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -37,7 +37,7 @@
JUNO_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \
plat/arm/common/arm_cci.c
-JUNO_SECURITY_SOURCES := drivers/arm/tzc400/tzc400.c \
+JUNO_SECURITY_SOURCES := drivers/arm/tzc/tzc400.c \
plat/arm/board/juno/juno_security.c \
plat/arm/common/arm_tzc400.c
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 8b46aae..3962940 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -48,53 +48,53 @@
* When booting an EL3 payload, this is simplified: we configure region 0 with
* secure access only and do not enable any other region.
******************************************************************************/
-void arm_tzc_setup(void)
+void arm_tzc400_setup(void)
{
INFO("Configuring TrustZone Controller\n");
- tzc_init(PLAT_ARM_TZC_BASE);
+ tzc400_init(PLAT_ARM_TZC_BASE);
/* Disable filters. */
- tzc_disable_filters();
+ tzc400_disable_filters();
#ifndef EL3_PAYLOAD_BASE
/* Region 0 set to no access by default */
- tzc_configure_region0(TZC_REGION_S_NONE, 0);
+ tzc400_configure_region0(TZC_REGION_S_NONE, 0);
/* Region 1 set to cover Secure part of DRAM */
- tzc_configure_region(PLAT_ARM_TZC_FILTERS, 1,
+ tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 1,
ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END,
TZC_REGION_S_RDWR,
0);
/* Region 2 set to cover Non-Secure access to 1st DRAM address range.
* Apply the same configuration to given filters in the TZC. */
- tzc_configure_region(PLAT_ARM_TZC_FILTERS, 2,
+ tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 2,
ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END,
TZC_REGION_S_NONE,
PLAT_ARM_TZC_NS_DEV_ACCESS);
/* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
- tzc_configure_region(PLAT_ARM_TZC_FILTERS, 3,
+ tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 3,
ARM_DRAM2_BASE, ARM_DRAM2_END,
TZC_REGION_S_NONE,
PLAT_ARM_TZC_NS_DEV_ACCESS);
#else
/* Allow secure access only to DRAM for EL3 payloads. */
- tzc_configure_region0(TZC_REGION_S_RDWR, 0);
+ tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
#endif /* EL3_PAYLOAD_BASE */
/*
* Raise an exception if a NS device tries to access secure memory
* TODO: Add interrupt handling support.
*/
- tzc_set_action(TZC_ACTION_ERR);
+ tzc400_set_action(TZC_ACTION_ERR);
/* Enable filters. */
- tzc_enable_filters();
+ tzc400_enable_filters();
}
void plat_arm_security_setup(void)
{
- arm_tzc_setup();
+ arm_tzc400_setup();
}
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
new file mode 100644
index 0000000..f0ed9a6
--- /dev/null
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 <arm_def.h>
+#include <assert.h>
+#include <debug.h>
+#include <platform_def.h>
+#include <tzc_dmc500.h>
+
+/*******************************************************************************
+ * Initialize the DMC500-TrustZone Controller for ARM standard platforms.
+ * Configure both the interfaces on Region 0 with no access, Region 1 with
+ * secure access only, and the remaining DRAM regions access from the
+ * given Non-Secure masters.
+ *
+ * When booting an EL3 payload, this is simplified: we configure region 0 with
+ * secure access only and do not enable any other region.
+ ******************************************************************************/
+void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data)
+{
+ assert(plat_driver_data);
+
+ INFO("Configuring DMC-500 TZ Settings\n");
+
+ tzc_dmc500_driver_init(plat_driver_data);
+
+#ifndef EL3_PAYLOAD_BASE
+ /* Region 0 set to no access by default */
+ tzc_dmc500_configure_region0(TZC_REGION_S_NONE, 0);
+
+ /* Region 1 set to cover Secure part of DRAM */
+ tzc_dmc500_configure_region(1, ARM_AP_TZC_DRAM1_BASE,
+ ARM_AP_TZC_DRAM1_END,
+ TZC_REGION_S_RDWR,
+ 0);
+
+ /* Region 2 set to cover Non-Secure access to 1st DRAM address range.*/
+ tzc_dmc500_configure_region(2,
+ ARM_NS_DRAM1_BASE,
+ ARM_NS_DRAM1_END,
+ TZC_REGION_S_NONE,
+ PLAT_ARM_TZC_NS_DEV_ACCESS);
+
+ /* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
+ tzc_dmc500_configure_region(3,
+ ARM_DRAM2_BASE,
+ ARM_DRAM2_END,
+ TZC_REGION_S_NONE,
+ PLAT_ARM_TZC_NS_DEV_ACCESS);
+#else
+ /* Allow secure access only to DRAM for EL3 payloads */
+ tzc_dmc500_configure_region0(TZC_REGION_S_RDWR, 0);
+#endif
+ /*
+ * Raise an exception if a NS device tries to access secure memory
+ * TODO: Add interrupt handling support.
+ */
+ tzc_dmc500_set_action(TZC_ACTION_RV_LOWERR);
+
+ /*
+ * Flush the configuration settings to have an affect. Validate
+ * flush by checking FILTER_EN is set on region 1 attributes
+ * register.
+ */
+ tzc_dmc500_config_complete();
+
+ /*
+ * Wait for the flush to complete.
+ * TODO: Have a timeout for this loop
+ */
+ while (tzc_dmc500_verify_complete())
+ ;
+}
diff --git a/plat/mediatek/mt8173/drivers/spm/spm.c b/plat/mediatek/mt8173/drivers/spm/spm.c
index f28b264..75eb61a 100644
--- a/plat/mediatek/mt8173/drivers/spm/spm.c
+++ b/plat/mediatek/mt8173/drivers/spm/spm.c
@@ -49,10 +49,6 @@
#define SPM_SYSCLK_SETTLE 128 /* 3.9ms */
-#if DEBUG
-static int spm_dormant_sta = CPU_DORMANT_RESET;
-#endif
-
DEFINE_BAKERY_LOCK(spm_lock);
static int spm_hotplug_ready __section("tzfw_coherent_mem");
@@ -378,7 +374,6 @@
wakesta->raw_sta, wakesta->idle_sta, wakesta->event_reg,
wakesta->isr);
- INFO("dormant state = %d\n", spm_dormant_sta);
return wr;
}
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 8d7b8a5..27545ba 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -32,7 +32,7 @@
PLAT := none
V := 0
DEBUG := 0
-BINARY := ${PROJECT}
+BINARY := ${PROJECT}${BIN_EXT}
OPENSSL_DIR := /usr
OBJECTS := src/cert.o \
@@ -47,15 +47,17 @@
CFLAGS := -Wall -std=c99
-# Check the platform
-ifeq (${PLAT},none)
- $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
-endif
-PLAT_MAKEFILE := platform.mk
-PLAT_INCLUDE := $(shell find ../../plat/ -wholename '*/${PLAT}/${PLAT_MAKEFILE}' | \
- sed 's/${PLAT_MAKEFILE}/include/')
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+
+PLATFORM_ROOT := ../../plat/
+include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
+
+PLAT_INCLUDE := $(wildcard ${PLAT_DIR}include)
+
ifeq ($(PLAT_INCLUDE),)
- $(error "Error: Invalid platform '${PLAT}'")
+ $(error "Error: Invalid platform '${PLAT}' has no include directory.")
endif
ifeq (${DEBUG},1)
@@ -76,9 +78,8 @@
LIB := -lssl -lcrypto
CC := gcc
-RM := rm -rf
-.PHONY: all clean
+.PHONY: all clean realclean
all: clean ${BINARY}
@@ -94,7 +95,8 @@
${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@
clean:
- ${Q}${RM} -f src/build_msg.o ${OBJECTS}
+ $(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
realclean: clean
- ${Q}${RM} -f ${BINARY}
+ $(call SHELL_DELETE, ${BINARY})
+
diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h
index 82a4bcb..95bde6c 100644
--- a/tools/cert_create/include/ext.h
+++ b/tools/cert_create/include/ext.h
@@ -35,12 +35,18 @@
#include <openssl/x509v3.h>
/* Extension types supported */
-enum {
+enum ext_type_e {
EXT_TYPE_NVCOUNTER,
EXT_TYPE_PKEY,
EXT_TYPE_HASH
};
+/* NV-Counter types */
+enum nvctr_type_e {
+ NVCTR_TYPE_TFW,
+ NVCTR_TYPE_NTFW
+};
+
/*
* This structure contains the relevant information to create the extensions
* to be included in the certificates. This extensions will be used to
@@ -50,20 +56,21 @@
const char *oid; /* OID of the extension */
const char *sn; /* Short name */
const char *ln; /* Long description */
+ const char *opt; /* Command line option to specify data */
const char *help_msg; /* Help message */
+ const char *arg; /* Argument passed from command line */
int asn1_type; /* OpenSSL ASN1 type of the extension data.
* Supported types are:
* - V_ASN1_INTEGER
* - V_ASN1_OCTET_STRING
*/
- int type;
- const char *opt; /* Command line option to specify data */
- /* Extension data (depends on extension type) */
+ int type; /* See ext_type_e */
+
+ /* Extension attributes (depends on extension type) */
union {
- const char *fn; /* File with extension data */
- int nvcounter; /* Non volatile counter */
- int key; /* Public key */
- } data;
+ int nvctr_type; /* See nvctr_type_e */
+ int key; /* Index into array of registered public keys */
+ } attr;
int alias; /* In case OpenSSL provides an standard
* extension of the same type, add the new
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index 3d2b4ba..c87d988 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -196,9 +196,17 @@
for (j = 0; j < cert->num_ext; j++) {
ext = &extensions[cert->ext[j]];
switch (ext->type) {
+ case EXT_TYPE_NVCOUNTER:
+ /* Counter value must be specified */
+ if ((!ext->optional) && (ext->arg == NULL)) {
+ ERROR("Value for '%s' not specified\n",
+ ext->ln);
+ exit(1);
+ }
+ break;
case EXT_TYPE_PKEY:
/* Key filename must be specified */
- key = &keys[ext->data.key];
+ key = &keys[ext->attr.key];
if (!new_keys && key->fn == NULL) {
ERROR("Key '%s' required by '%s' not "
"specified\n", key->desc,
@@ -211,15 +219,15 @@
* Binary image must be specified
* unless it is explicitly made optional.
*/
- if ((!ext->optional) && (ext->data.fn == NULL)) {
+ if ((!ext->optional) && (ext->arg == NULL)) {
ERROR("Image for '%s' not specified\n",
ext->ln);
exit(1);
}
break;
default:
- ERROR("Unknown extension type in '%s'\n",
- ext->ln);
+ ERROR("Unknown extension type '%d' in '%s'\n",
+ ext->type, ext->ln);
exit(1);
break;
}
@@ -259,7 +267,7 @@
key_t *key = NULL;
cert_t *cert = NULL;
FILE *file = NULL;
- int i, j, ext_nid;
+ int i, j, ext_nid, nvctr;
int c, opt_idx = 0;
const struct option *cmd_opt;
const char *cur_opt;
@@ -331,7 +339,7 @@
case CMD_OPT_EXT:
cur_opt = cmd_opt_get_name(opt_idx);
ext = ext_get_by_opt(cur_opt);
- ext->data.fn = strdup(optarg);
+ ext->arg = strdup(optarg);
break;
case CMD_OPT_KEY:
cur_opt = cmd_opt_get_name(opt_idx);
@@ -420,11 +428,12 @@
*/
switch (ext->type) {
case EXT_TYPE_NVCOUNTER:
+ nvctr = atoi(ext->arg);
CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid,
- EXT_CRIT, ext->data.nvcounter));
+ EXT_CRIT, nvctr));
break;
case EXT_TYPE_HASH:
- if (ext->data.fn == NULL) {
+ if (ext->arg == NULL) {
if (ext->optional) {
/* Include a hash filled with zeros */
memset(md, 0x0, SHA256_DIGEST_LENGTH);
@@ -434,9 +443,9 @@
}
} else {
/* Calculate the hash of the file */
- if (!sha_file(ext->data.fn, md)) {
+ if (!sha_file(ext->arg, md)) {
ERROR("Cannot calculate hash of %s\n",
- ext->data.fn);
+ ext->arg);
exit(1);
}
}
@@ -446,11 +455,11 @@
break;
case EXT_TYPE_PKEY:
CHECK_NULL(cert_ext, ext_new_key(ext_nid,
- EXT_CRIT, keys[ext->data.key].key));
+ EXT_CRIT, keys[ext->attr.key].key));
break;
default:
- ERROR("Unknown extension type in %s\n",
- cert->cn);
+ ERROR("Unknown extension type '%d' in %s\n",
+ ext->type, cert->cn);
exit(1);
}
diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c
index 7a50ab3..8f7feb5 100644
--- a/tools/cert_create/src/tbbr/tbb_cert.c
+++ b/tools/cert_create/src/tbbr/tbb_cert.c
@@ -49,9 +49,10 @@
.key = ROT_KEY,
.issuer = TRUSTED_BOOT_FW_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_BOOT_FW_HASH_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[TRUSTED_KEY_CERT] = {
.id = TRUSTED_KEY_CERT,
@@ -62,10 +63,11 @@
.key = ROT_KEY,
.issuer = TRUSTED_KEY_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_WORLD_PK_EXT,
NON_TRUSTED_WORLD_PK_EXT
},
- .num_ext = 2
+ .num_ext = 3
},
[SCP_FW_KEY_CERT] = {
.id = SCP_FW_KEY_CERT,
@@ -76,9 +78,10 @@
.key = TRUSTED_WORLD_KEY,
.issuer = SCP_FW_KEY_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
SCP_FW_CONTENT_CERT_PK_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[SCP_FW_CONTENT_CERT] = {
.id = SCP_FW_CONTENT_CERT,
@@ -89,9 +92,10 @@
.key = SCP_FW_CONTENT_CERT_KEY,
.issuer = SCP_FW_CONTENT_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
SCP_FW_HASH_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[SOC_FW_KEY_CERT] = {
.id = SOC_FW_KEY_CERT,
@@ -102,9 +106,10 @@
.key = TRUSTED_WORLD_KEY,
.issuer = SOC_FW_KEY_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
SOC_FW_CONTENT_CERT_PK_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[SOC_FW_CONTENT_CERT] = {
.id = SOC_FW_CONTENT_CERT,
@@ -115,9 +120,10 @@
.key = SOC_FW_CONTENT_CERT_KEY,
.issuer = SOC_FW_CONTENT_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
SOC_AP_FW_HASH_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[TRUSTED_OS_FW_KEY_CERT] = {
.id = TRUSTED_OS_FW_KEY_CERT,
@@ -128,9 +134,10 @@
.key = TRUSTED_WORLD_KEY,
.issuer = TRUSTED_OS_FW_KEY_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_OS_FW_CONTENT_CERT_PK_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[TRUSTED_OS_FW_CONTENT_CERT] = {
.id = TRUSTED_OS_FW_CONTENT_CERT,
@@ -141,9 +148,10 @@
.key = TRUSTED_OS_FW_CONTENT_CERT_KEY,
.issuer = TRUSTED_OS_FW_CONTENT_CERT,
.ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_OS_FW_HASH_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[NON_TRUSTED_FW_KEY_CERT] = {
.id = NON_TRUSTED_FW_KEY_CERT,
@@ -154,9 +162,10 @@
.key = NON_TRUSTED_WORLD_KEY,
.issuer = NON_TRUSTED_FW_KEY_CERT,
.ext = {
+ NON_TRUSTED_FW_NVCOUNTER_EXT,
NON_TRUSTED_FW_CONTENT_CERT_PK_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[NON_TRUSTED_FW_CONTENT_CERT] = {
.id = NON_TRUSTED_FW_CONTENT_CERT,
@@ -167,9 +176,10 @@
.key = NON_TRUSTED_FW_CONTENT_CERT_KEY,
.issuer = NON_TRUSTED_FW_CONTENT_CERT,
.ext = {
+ NON_TRUSTED_FW_NVCOUNTER_EXT,
NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT
},
- .num_ext = 1
+ .num_ext = 2
},
[FWU_CERT] = {
.id = FWU_CERT,
diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c
index 8bcb070..5304bd5 100644
--- a/tools/cert_create/src/tbbr/tbb_ext.c
+++ b/tools/cert_create/src/tbbr/tbb_ext.c
@@ -44,19 +44,23 @@
static ext_t tbb_ext[] = {
[TRUSTED_FW_NVCOUNTER_EXT] = {
.oid = TRUSTED_FW_NVCOUNTER_OID,
+ .opt = "tfw-nvctr",
+ .help_msg = "Trusted Firmware Non-Volatile counter value",
.sn = "TrustedWorldNVCounter",
.ln = "Trusted World Non-Volatile counter",
.asn1_type = V_ASN1_INTEGER,
.type = EXT_TYPE_NVCOUNTER,
- .data.nvcounter = TRUSTED_WORLD_NVCTR_VALUE
+ .attr.nvctr_type = NVCTR_TYPE_TFW
},
[NON_TRUSTED_FW_NVCOUNTER_EXT] = {
.oid = NON_TRUSTED_FW_NVCOUNTER_OID,
+ .opt = "ntfw-nvctr",
+ .help_msg = "Non-Trusted Firmware Non-Volatile counter value",
.sn = "NormalWorldNVCounter",
- .ln = "Normal World Non-Volatile counter",
+ .ln = "Non-Trusted Firmware Non-Volatile counter",
.asn1_type = V_ASN1_INTEGER,
.type = EXT_TYPE_NVCOUNTER,
- .data.nvcounter = NORMAL_WORLD_NVCTR_VALUE
+ .attr.nvctr_type = NVCTR_TYPE_NTFW
},
[TRUSTED_BOOT_FW_HASH_EXT] = {
.oid = TRUSTED_BOOT_FW_HASH_OID,
@@ -73,7 +77,7 @@
.ln = "Trusted World Public Key",
.asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY,
- .data.key = TRUSTED_WORLD_KEY
+ .attr.key = TRUSTED_WORLD_KEY
},
[NON_TRUSTED_WORLD_PK_EXT] = {
.oid = NON_TRUSTED_WORLD_PK_OID,
@@ -81,7 +85,7 @@
.ln = "Non-Trusted World Public Key",
.asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY,
- .data.key = NON_TRUSTED_WORLD_KEY
+ .attr.key = NON_TRUSTED_WORLD_KEY
},
[SCP_FW_CONTENT_CERT_PK_EXT] = {
.oid = SCP_FW_CONTENT_CERT_PK_OID,
@@ -89,7 +93,7 @@
.ln = "SCP Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY,
- .data.key = SCP_FW_CONTENT_CERT_KEY
+ .attr.key = SCP_FW_CONTENT_CERT_KEY
},
[SCP_FW_HASH_EXT] = {
.oid = SCP_FW_HASH_OID,
@@ -106,7 +110,7 @@
.ln = "SoC Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY,
- .data.key = SOC_FW_CONTENT_CERT_KEY
+ .attr.key = SOC_FW_CONTENT_CERT_KEY
},
[SOC_AP_FW_HASH_EXT] = {
.oid = SOC_AP_FW_HASH_OID,
@@ -123,7 +127,7 @@
.ln = "Trusted OS Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY,
- .data.key = TRUSTED_OS_FW_CONTENT_CERT_KEY
+ .attr.key = TRUSTED_OS_FW_CONTENT_CERT_KEY
},
[TRUSTED_OS_FW_HASH_EXT] = {
.oid = TRUSTED_OS_FW_HASH_OID,
@@ -140,7 +144,7 @@
.ln = "Non-Trusted Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY,
- .data.key = NON_TRUSTED_FW_CONTENT_CERT_KEY
+ .attr.key = NON_TRUSTED_FW_CONTENT_CERT_KEY
},
[NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT] = {
.oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID,
diff --git a/tools/fip_create/Makefile b/tools/fip_create/Makefile
index c72bae5..2e367c2 100644
--- a/tools/fip_create/Makefile
+++ b/tools/fip_create/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -28,38 +28,56 @@
# POSSIBILITY OF SUCH DAMAGE.
#
-PROJECT = fip_create
-OBJECTS = fip_create.o
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
-CFLAGS = -Wall -Werror -pedantic -std=c99
+PROJECT := fip_create${BIN_EXT}
+OBJECTS := fip_create.o
+COPIED_H_FILES := uuid.h firmware_image_package.h
+
+CFLAGS := -Wall -Werror -pedantic -std=c99
ifeq (${DEBUG},1)
CFLAGS += -g -O0 -DDEBUG
else
CFLAGS += -O2
endif
-# Make soft links and include from local directory otherwise wrong headers
-# could get pulled in from firmware tree.
-INCLUDE_PATHS = -I.
+# Only include from local directory (see comment below).
+INCLUDE_PATHS := -I.
CC := gcc
-RM := rm -rf
-.PHONY: all clean
+.PHONY: all clean distclean
all: ${PROJECT}
${PROJECT}: ${OBJECTS} Makefile
@echo " LD $@"
${Q}${CC} ${OBJECTS} -o $@
- @echo
+ @${ECHO_BLANK_LINE}
@echo "Built $@ successfully"
- @echo
+ @${ECHO_BLANK_LINE}
-%.o: %.c %.h Makefile
+%.o: %.c %.h ${COPIED_H_FILES} Makefile
@echo " CC $<"
${Q}${CC} -c ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
+#
+# Copy required library headers to a local directory so they can be included
+# by this project without adding the library directories to the system include
+# path. This avoids conflicts with definitions in the compiler standard
+# include path.
+#
+uuid.h : ../../include/stdlib/sys/uuid.h
+ $(call SHELL_COPY,$<,$@)
+
+firmware_image_package.h : ../../include/common/firmware_image_package.h
+ $(call SHELL_COPY,$<,$@)
+
clean:
- ${Q}${RM} ${PROJECT}
- ${Q}${RM} ${OBJECTS}
+ $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+
+distclean: clean
+ $(call SHELL_DELETE_ALL, ${COPIED_H_FILES})
+
diff --git a/tools/fip_create/fip_create.c b/tools/fip_create/fip_create.c
index 19afc74..7bce348 100644
--- a/tools/fip_create/fip_create.c
+++ b/tools/fip_create/fip_create.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -40,12 +40,19 @@
/* Values returned by getopt() as part of the command line parsing */
#define OPT_TOC_ENTRY 0
-#define OPT_DUMP 1
-#define OPT_HELP 2
+#define OPT_DUMP 'd'
+#define OPT_HELP 'h'
+#define OPT_UNPACK 'u'
+#define OPT_FORCE 'f'
+#define OPT_STR "dfhu"
-file_info_t files[MAX_FILES];
-unsigned file_info_count = 0;
-uuid_t uuid_null = {0};
+static file_info_t files[MAX_FILES];
+static unsigned file_info_count;
+static uuid_t uuid_null = {0};
+static int do_dump;
+static int do_pack;
+static int do_unpack;
+static int do_force;
/*
* TODO: Add ability to specify and flag different file types.
@@ -118,12 +125,15 @@
{
entry_lookup_list_t *entry = toc_entry_lookup_list;
- printf("Usage: fip_create [options] FIP_FILENAME\n\n");
- printf("\tThis tool is used to create a Firmware Image Package.\n\n");
+ printf("\nThis tool is used to create a Firmware Image Package.\n\n");
+ printf("Usage:\n");
+ printf("\tfip_create [options] FIP_FILENAME\n\n");
printf("Options:\n");
- printf("\t--help: Print this help message and exit\n");
- printf("\t--dump: Print contents of FIP\n\n");
- printf("\tComponents that can be added/updated:\n");
+ printf("\t-h,--help: Print this help message and exit\n");
+ printf("\t-d,--dump: Print contents of FIP after update\n");
+ printf("\t-u,--unpack: Unpack images from an existing FIP\n");
+ printf("\t-f,--force: Overwrite existing files when unpacking images\n\n");
+ printf("Components that can be added/updated:\n");
for (; entry->command_line_name != NULL; entry++) {
printf("\t--%s%s\t\t%s",
entry->command_line_name,
@@ -131,6 +141,7 @@
entry->name);
printf("\n");
}
+ printf("\n");
}
@@ -371,6 +382,109 @@
}
+/*
+ * Unpack all images from an existing FIP
+ *
+ * Images will be unpacked into the working directory using filenames as
+ * specified by the corresponding command line option plus the 'bin' extension.
+ * For example, the image specified by the --soc-fw option will be unpacked as
+ * 'soc-fw.bin'
+ */
+static int unpack_images(void)
+{
+ FILE *stream;
+ size_t bytes_written;
+ file_info_t *file_info;
+ char *filename[MAX_FILES];
+ int status, ret = 0;
+ unsigned int i, idx, num_img;
+ struct stat st;
+ size_t len;
+
+ /* Make the output filenames */
+ for (idx = 0; idx < file_info_count; idx++) {
+ filename[idx] = NULL;
+ file_info = &files[idx];
+ if (file_info->image_buffer == NULL) {
+ continue;
+ }
+ len = strlen(file_info->entry->command_line_name);
+ filename[idx] = malloc(len + 5); /* ".bin" + '\0' */
+ if (filename[idx] == NULL) {
+ printf("ERROR: out of memory\n");
+ for (i = 0; i < idx; i++) {
+ free(filename[i]);
+ }
+ return ENOMEM;
+ }
+ strcpy(filename[idx], file_info->entry->command_line_name);
+ strcat(filename[idx], ".bin");
+ }
+
+
+ /* Check if output files already exist in the filesystem. We perform
+ * this check before any other action, so if any of the files
+ * exists, nothing is unpacked. If force overwrite is enabled, we skip
+ * this check */
+ if (!do_force) {
+ for (idx = 0; idx < file_info_count; idx++) {
+ file_info = &files[idx];
+ if (file_info->image_buffer == NULL) {
+ continue;
+ }
+ status = stat(filename[idx], &st);
+ if (!status) {
+ printf("File '%s' exists. Use --force to overwrite.\n",
+ filename[idx]);
+ printf("Process aborted.\n");
+ ret = EEXIST;
+ goto unpack_images_free;
+ }
+ }
+ }
+
+ printf("Unpacking images...\n");
+
+ /* Write the images to files */
+ num_img = 0;
+ for (idx = 0; idx < file_info_count; idx++) {
+ file_info = &files[idx];
+ if (file_info->image_buffer == NULL) {
+ continue;
+ }
+ /* Unpack the image to a file */
+ stream = fopen(filename[idx], "w");
+ if (!stream) {
+ printf("ERROR: cannot open '%s' for writing\n",
+ filename[idx]);
+ ret = EIO;
+ goto unpack_images_free;
+ }
+ bytes_written = fwrite(file_info->image_buffer, sizeof(uint8_t),
+ file_info->size, stream);
+ fclose(stream);
+
+ if (bytes_written != file_info->size) {
+ printf("ERROR: Incorrect write for file \"%s\": Size=%u,"
+ "Written=%lu bytes.\n", filename[idx], file_info->size,
+ bytes_written);
+ ret = EIO;
+ goto unpack_images_free;
+ }
+ num_img++;
+ }
+
+ printf("Done. %u images unpacked\n", num_img);
+
+unpack_images_free:
+ for (idx = 0; idx < file_info_count; idx++) {
+ free(filename[idx]);
+ }
+
+ return ret;
+}
+
+
static void dump_toc(void)
{
unsigned int index = 0;
@@ -528,7 +642,7 @@
*/
optind = 1;
while (1) {
- c = getopt_long(argc, argv, "", options, NULL);
+ c = getopt_long(argc, argv, OPT_STR, options, NULL);
if (c == -1)
break;
@@ -549,19 +663,17 @@
/* Work through command-line options */
-static int parse_cmdline(int argc, char **argv, struct option *options,
- int *do_pack)
+static int parse_cmdline(int argc, char **argv, struct option *options)
{
int c;
int status = 0;
int option_index = 0;
entry_lookup_list_t *lookup_entry;
- int do_dump = 0;
/* restart parse to process all options. starts at 1. */
optind = 1;
while (1) {
- c = getopt_long(argc, argv, "", options, &option_index);
+ c = getopt_long(argc, argv, OPT_STR, options, &option_index);
if (c == -1)
break;
@@ -578,7 +690,7 @@
return status;
} else {
/* Update package */
- *do_pack = 1;
+ do_pack = 1;
}
}
}
@@ -586,24 +698,26 @@
case OPT_DUMP:
do_dump = 1;
- continue;
+ break;
case OPT_HELP:
print_usage();
exit(0);
+ case OPT_UNPACK:
+ do_unpack = 1;
+ break;
+
+ case OPT_FORCE:
+ do_force = 1;
+ break;
+
default:
/* Unrecognised options are caught in get_filename() */
break;
}
}
-
- /* Do not dump toc if we have an error as it could hide the error */
- if ((status == 0) && (do_dump)) {
- dump_toc();
- }
-
return status;
}
@@ -613,17 +727,17 @@
int i;
int status;
char *fip_filename;
- int do_pack = 0;
+ struct stat st;
/* Clear file list table. */
memset(files, 0, sizeof(files));
/* Initialise for getopt_long().
* Use image table as defined at top of file to get options.
- * Add 'dump' option, 'help' option and end marker.
+ * Add common options and end marker.
*/
static struct option long_options[(sizeof(toc_entry_lookup_list)/
- sizeof(entry_lookup_list_t)) + 2];
+ sizeof(entry_lookup_list_t)) + 4];
for (i = 0;
/* -1 because we dont want to process end marker in toc table */
@@ -648,6 +762,18 @@
long_options[i].flag = 0;
long_options[i].val = OPT_HELP;
+ /* Add '--unpack' option */
+ long_options[++i].name = "unpack";
+ long_options[i].has_arg = 0;
+ long_options[i].flag = 0;
+ long_options[i].val = OPT_UNPACK;
+
+ /* Add '--force' option */
+ long_options[++i].name = "force";
+ long_options[i].has_arg = 0;
+ long_options[i].flag = 0;
+ long_options[i].val = OPT_FORCE;
+
/* Zero the last entry (required) */
long_options[++i].name = 0;
long_options[i].has_arg = 0;
@@ -677,7 +803,7 @@
}
/* Work through provided program arguments and perform actions */
- status = parse_cmdline(argc, argv, long_options, &do_pack);
+ status = parse_cmdline(argc, argv, long_options);
if (status != 0) {
return status;
};
@@ -688,10 +814,28 @@
return 0;
}
- /* Processed all command line options. Create/update the package if
- * required.
- */
- if (do_pack) {
+ /* Unpack images from FIP always takes precedence over packaging. In
+ * the future, there will be different commands for each action and
+ * only one will be specified in the command line */
+ if (do_unpack) {
+ status = stat(fip_filename, &st);
+ if (status != 0) {
+ printf("ERROR: cannot open %s\n", fip_filename);
+ return status;
+ }
+ /* Warning if user has specified images */
+ if (do_pack) {
+ printf("WARNING: Unpack option specified. Input images "
+ "will be ignored.\n");
+ }
+ status = unpack_images();
+ if (status != 0) {
+ printf("ERROR: failed to unpack package (status = %d).\n",
+ status);
+ return status;
+ }
+ } else if (do_pack) {
+ /* Create/update FIP */
status = pack_images(fip_filename);
if (status != 0) {
printf("Failed to create package (status = %d).\n",
@@ -699,5 +843,10 @@
}
}
+ /* Do not dump toc if we have an error as it could hide the error */
+ if ((status == 0) && (do_dump)) {
+ dump_toc();
+ }
+
return status;
}
diff --git a/tools/fip_create/firmware_image_package.h b/tools/fip_create/firmware_image_package.h
deleted file mode 120000
index cc61903..0000000
--- a/tools/fip_create/firmware_image_package.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/common/firmware_image_package.h
\ No newline at end of file
diff --git a/tools/fip_create/uuid.h b/tools/fip_create/uuid.h
deleted file mode 120000
index c77762f..0000000
--- a/tools/fip_create/uuid.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/stdlib/sys/uuid.h
\ No newline at end of file