aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/diagrams/Makefile74
-rwxr-xr-xdocs/diagrams/generate_reset_images.sh41
-rwxr-xr-xdocs/diagrams/generate_xlat_images.sh26
-rw-r--r--docs/diagrams/int_handling.diabin0 -> 10623 bytes
-rw-r--r--docs/diagrams/non-sec-int-handling.pngbin249672 -> 218768 bytes
-rw-r--r--docs/diagrams/sec-int-handling.pngbin191026 -> 173315 bytes
-rw-r--r--docs/firmware-design.rst8
-rw-r--r--include/plat/arm/board/common/drivers/norflash.h8
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c2
-rw-r--r--lib/psci/psci_common.c7
-rw-r--r--plat/arm/board/common/drivers/norflash/norflash.c170
-rw-r--r--plat/arm/board/fvp/fvp_common.c11
-rw-r--r--plat/qemu/include/platform_def.h8
-rw-r--r--plat/qemu/platform.mk16
-rw-r--r--plat/qemu/qemu_bl2_mem_params_desc.c37
-rw-r--r--plat/qemu/qemu_bl2_setup.c27
-rw-r--r--plat/qemu/qemu_io_storage.c28
-rw-r--r--services/spd/opteed/opteed_common.c3
-rw-r--r--services/spd/opteed/opteed_main.c7
-rw-r--r--services/spd/opteed/opteed_pm.c2
-rw-r--r--services/spd/opteed/opteed_private.h1
21 files changed, 354 insertions, 122 deletions
diff --git a/docs/diagrams/Makefile b/docs/diagrams/Makefile
new file mode 100644
index 000000000..de7d8f3ff
--- /dev/null
+++ b/docs/diagrams/Makefile
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+# This Makefile generates the image files used in the ARM Trusted Firmware
+# document from the dia file.
+#
+# The PNG files in the present directory have been generated using Dia version
+# 0.97.2, which can be obtained from https://wiki.gnome.org/Apps/Dia/Download
+#
+
+# generate_image use the tool dia generate png from dia file
+# $(1) = layers
+# $(2) = image file name
+# $(3) = image file format
+# $(4) = addition opts
+# $(5) = dia source file
+define generate_image
+ dia --show-layers=$(1) --filter=$(3) --export=$(2) $(4) $(5)
+endef
+
+RESET_DIA = reset_code_flow.dia
+RESET_PNGS = \
+ default_reset_code.png \
+ reset_code_no_cpu_check.png \
+ reset_code_no_boot_type_check.png \
+ reset_code_no_checks.png \
+
+# The $(RESET_DIA) file is organized in several layers.
+# Each image is generated by combining and exporting the appropriate set of
+# layers.
+default_reset_code_layers = "Frontground,Background,cpu_type_check,boot_type_check"
+reset_code_no_cpu_check_layers = "Frontground,Background,no_cpu_type_check,boot_type_check"
+reset_code_no_boot_type_check_layers= "Frontground,Background,cpu_type_check,no_boot_type_check"
+reset_code_no_checks_layers = "Frontground,Background,no_cpu_type_check,no_boot_type_check"
+
+default_reset_code_opts =
+reset_code_no_cpu_check_opts =
+reset_code_no_boot_type_check_opts =
+reset_code_no_checks_opts =
+
+INT_DIA = int_handling.dia
+INT_PNGS = \
+ sec-int-handling.png \
+ non-sec-int-handling.png
+
+# The $(INT_DIA) file is organized in several layers.
+# Each image is generated by combining and exporting the appropriate set of
+# layers.
+non-sec-int-handling_layers = "non_sec_int_bg,legend,non_sec_int_note,non_sec_int_handling"
+sec-int-handling_layers = "sec_int_bg,legend,sec_int_note,sec_int_handling"
+
+non-sec-int-handling_opts = --size=1692x
+sec-int-handling_opts = --size=1570x
+
+XLAT_DIA = xlat_align.dia
+XLAT_PNG = xlat_align.png
+
+xlat_align_layers = "bg,translations"
+xlat_align_opts =
+
+all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG)
+
+$(RESET_PNGS):$(RESET_DIA)
+ $(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(INT_PNGS):$(INT_DIA)
+ $(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(XLAT_PNG):$(XLAT_DIA)
+ $(call generate_image,$($(patsubst %.png,%_layers,$@)),$(patsubst %.png,%.svg,$@),svg,$($(patsubst %.png,%_opts,$@)),$<)
+ inkscape -z $(patsubst %.png,%.svg,$@) -e $@ -d 45
diff --git a/docs/diagrams/generate_reset_images.sh b/docs/diagrams/generate_reset_images.sh
deleted file mode 100755
index eef5648d4..000000000
--- a/docs/diagrams/generate_reset_images.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#! /bin/bash
-
-#
-# This script generates the image files used in the ARM Trusted Firmware Reset
-# Design document from the 'reset_code_flow.dia' file.
-#
-# The PNG files in the present directory have been generated using Dia version
-# 0.97.2, which can be obtained from https://wiki.gnome.org/Apps/Dia/Download
-#
-
-set -e
-
-# Usage: generate_image <layers> <image_filename>
-function generate_image
-{
- dia \
- --show-layers=$1 \
- --filter=png \
- --export=$2 \
- reset_code_flow.dia
-
-}
-
-# The 'reset_code_flow.dia' file is organized in several layers.
-# Each image is generated by combining and exporting the appropriate set of
-# layers.
-generate_image \
- Frontground,Background,cpu_type_check,boot_type_check \
- default_reset_code.png
-
-generate_image \
- Frontground,Background,no_cpu_type_check,boot_type_check \
- reset_code_no_cpu_check.png
-
-generate_image \
- Frontground,Background,cpu_type_check,no_boot_type_check \
- reset_code_no_boot_type_check.png
-
-generate_image \
- Frontground,Background,no_cpu_type_check,no_boot_type_check \
- reset_code_no_checks.png
diff --git a/docs/diagrams/generate_xlat_images.sh b/docs/diagrams/generate_xlat_images.sh
deleted file mode 100755
index 9daef5f4c..000000000
--- a/docs/diagrams/generate_xlat_images.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /bin/bash
-
-#
-# This script generates the image file used in the ARM Trusted Firmware
-# Translation Tables Library V2 Design document from the 'xlat_align.dia' file.
-#
-
-set -e
-
-# Usage: generate_image <dia_filename> <layers> <image_filename>
-function generate_image
-{
- dia \
- --show-layers=$2 \
- --filter=svg \
- --export=$3 \
- $1
-
-}
-
-generate_image \
- xlat_align.dia \
- bg,translations \
- xlat_align.svg
-
-inkscape -z xlat_align.svg -e xlat_align.png -d 45
diff --git a/docs/diagrams/int_handling.dia b/docs/diagrams/int_handling.dia
new file mode 100644
index 000000000..12aa186c0
--- /dev/null
+++ b/docs/diagrams/int_handling.dia
Binary files differ
diff --git a/docs/diagrams/non-sec-int-handling.png b/docs/diagrams/non-sec-int-handling.png
index 1a5f62955..64082c952 100644
--- a/docs/diagrams/non-sec-int-handling.png
+++ b/docs/diagrams/non-sec-int-handling.png
Binary files differ
diff --git a/docs/diagrams/sec-int-handling.png b/docs/diagrams/sec-int-handling.png
index 2ebbca442..fa5c340af 100644
--- a/docs/diagrams/sec-int-handling.png
+++ b/docs/diagrams/sec-int-handling.png
Binary files differ
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 3bca7643f..36038ad6d 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -1045,8 +1045,8 @@ before returning through EL3 and running the non-trusted firmware (BL33):
``bl31_main()`` will set up the return to the normal world firmware BL33 and
continue the boot process in the normal world.
-#. .. rubric:: Crash Reporting in BL31
- :name: crash-reporting-in-bl31
+Crash Reporting in BL31
+-----------------------
BL31 implements a scheme for reporting the processor state when an unhandled
exception is encountered. The reporting mechanism attempts to preserve all the
@@ -2333,8 +2333,8 @@ PMF code structure
#. ``pmf_helpers.h`` is an internal header used by ``pmf.h``.
-#. .. rubric:: ARMv8 Architecture Extensions
- :name: armv8-architecture-extensions
+ARMv8 Architecture Extensions
+-----------------------------
ARM Trusted Firmware makes use of ARMv8 Architecture Extensions where
applicable. This section lists the usage of Architecture Extensions, and build
diff --git a/include/plat/arm/board/common/drivers/norflash.h b/include/plat/arm/board/common/drivers/norflash.h
index e74635ecc..5763b36df 100644
--- a/include/plat/arm/board/common/drivers/norflash.h
+++ b/include/plat/arm/board/common/drivers/norflash.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,6 +19,7 @@
#define NOR_CMD_WORD_PROGRAM 0x40
#define NOR_CMD_BLOCK_ERASE 0x20
#define NOR_CMD_LOCK_UNLOCK 0x60
+#define NOR_CMD_BLOCK_ERASE_ACK 0xD0
/* Second bus cycle */
#define NOR_LOCK_BLOCK 0x01
@@ -37,8 +38,9 @@
/* Public API */
void nor_send_cmd(uintptr_t base_addr, unsigned long cmd);
int nor_word_program(uintptr_t base_addr, unsigned long data);
-void nor_lock(uintptr_t base_addr);
-void nor_unlock(uintptr_t base_addr);
+int nor_lock(uintptr_t base_addr);
+int nor_unlock(uintptr_t base_addr);
+int nor_erase(uintptr_t base_addr);
#endif /* __NORFLASH_H_ */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 5257bf1c5..3d26056a3 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -229,7 +229,7 @@ void cm_prepare_el3_exit(uint32_t security_state)
/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
sctlr_elx = read_ctx_reg(get_sysregs_ctx(ctx),
CTX_SCTLR_EL1);
- sctlr_elx &= ~SCTLR_EE_BIT;
+ sctlr_elx &= SCTLR_EE_BIT;
sctlr_elx |= SCTLR_EL2_RES1;
write_sctlr_el2(sctlr_elx);
} else if (EL_IMPLEMENTED(2)) {
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index f31b32386..4502c24b5 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -194,8 +194,15 @@ static void psci_set_req_local_pwr_state(unsigned int pwrlvl,
unsigned int cpu_idx,
plat_local_state_t req_pwr_state)
{
+ /*
+ * This should never happen, we have this here to avoid
+ * "array subscript is above array bounds" errors in GCC.
+ */
assert(pwrlvl > PSCI_CPU_PWR_LVL);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
psci_req_local_pwr_states[pwrlvl - 1][cpu_idx] = req_pwr_state;
+#pragma GCC diagnostic pop
}
/******************************************************************************
diff --git a/plat/arm/board/common/drivers/norflash/norflash.c b/plat/arm/board/common/drivers/norflash/norflash.c
index cc63d758e..722cf33ee 100644
--- a/plat/arm/board/common/drivers/norflash/norflash.c
+++ b/plat/arm/board/common/drivers/norflash/norflash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,8 +8,6 @@
#include <mmio.h>
#include <norflash.h>
-/* Helper macros to access two flash banks in parallel */
-#define NOR_2X16(d) ((d << 16) | (d & 0xffff))
/*
* DWS ready poll retries. The number of retries in this driver have been
@@ -17,32 +15,72 @@
* model
*/
#define DWS_WORD_PROGRAM_RETRIES 1000
+#define DWS_WORD_ERASE_RETRIES 3000000
+#define DWS_WORD_LOCK_RETRIES 1000
+
+/* Helper macro to detect end of command */
+#define NOR_CMD_END (NOR_DWS | NOR_DWS << 16l)
/*
- * Poll Write State Machine. Return values:
+ * This file supplies a low level interface to the vexpress NOR flash
+ * memory of juno and fvp. This memory is organized as an interleaved
+ * memory of two chips with a 16 bit word. It means that every 32 bit
+ * access is going to access to two different chips. This is very
+ * important when we send commands or read status of the chips
+ */
+
+/* Helper macros to access two flash banks in parallel */
+#define NOR_2X16(d) ((d << 16) | (d & 0xffff))
+
+static unsigned int nor_status(uintptr_t base_addr)
+{
+ unsigned long status;
+
+ nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
+ status = mmio_read_32(base_addr);
+ status |= status >> 16; /* merge status from both flash banks */
+
+ return status & 0xFFFF;
+}
+
+/*
+ * Poll Write State Machine.
+ * Return values:
* 0 = WSM ready
* -EBUSY = WSM busy after the number of retries
*/
-static int nor_poll_dws(uintptr_t base_addr, unsigned int retries)
+static int nor_poll_dws(uintptr_t base_addr, unsigned long int retries)
{
- uint32_t status;
- int ret;
+ unsigned long status;
- for (;;) {
+ do {
nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
status = mmio_read_32(base_addr);
- if ((status & NOR_DWS) &&
- (status & (NOR_DWS << 16))) {
- ret = 0;
- break;
- }
- if (retries-- == 0) {
- ret = -EBUSY;
- break;
- }
- }
+ if ((status & NOR_CMD_END) == NOR_CMD_END)
+ return 0;
+ } while (retries-- > 0);
- return ret;
+ return -EBUSY;
+}
+
+/*
+ * Return values:
+ * 0 = success
+ * -EPERM = Device protected or Block locked
+ * -EIO = General I/O error
+ */
+static int nor_full_status_check(uintptr_t base_addr)
+{
+ unsigned long status;
+
+ /* Full status check */
+ status = nor_status(base_addr);
+
+ if (status & (NOR_PS | NOR_BLS | NOR_ESS | NOR_PSS))
+ return -EPERM;
+ if (status & (NOR_VPPS | NOR_ES))
+ return -EIO;
+ return 0;
}
void nor_send_cmd(uintptr_t base_addr, unsigned long cmd)
@@ -51,50 +89,108 @@ void nor_send_cmd(uintptr_t base_addr, unsigned long cmd)
}
/*
+ * This function programs a word in the flash. Be aware that it only
+ * can reset bits that were previously set. It cannot set bits that
+ * were previously reset. The resulting bits = old_bits & new bits.
* Return values:
- * 0 = success
- * -EBUSY = WSM not ready
- * -EPERM = Device protected or Block locked
+ * 0 = success
+ * otherwise it returns a negative value
*/
int nor_word_program(uintptr_t base_addr, unsigned long data)
{
uint32_t status;
int ret;
+ nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
+
/* Set the device in write word mode */
nor_send_cmd(base_addr, NOR_CMD_WORD_PROGRAM);
mmio_write_32(base_addr, data);
ret = nor_poll_dws(base_addr, DWS_WORD_PROGRAM_RETRIES);
- if (ret != 0) {
- goto word_program_end;
+ if (ret == 0) {
+ /* Full status check */
+ nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
+ status = mmio_read_32(base_addr);
+
+ if (status & (NOR_PS | NOR_BLS)) {
+ nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
+ ret = -EPERM;
+ }
}
- /* Full status check */
- nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
- status = mmio_read_32(base_addr);
+ if (ret == 0)
+ ret = nor_full_status_check(base_addr);
+ nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
- if (status & (NOR_PS | NOR_BLS)) {
- nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
- ret = -EPERM;
- }
+ return ret;
+}
-word_program_end:
+/*
+ * Erase a full 256K block
+ * Return values:
+ * 0 = success
+ * otherwise it returns a negative value
+ */
+int nor_erase(uintptr_t base_addr)
+{
+ int ret;
+
+ nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
+
+ nor_send_cmd(base_addr, NOR_CMD_BLOCK_ERASE);
+ nor_send_cmd(base_addr, NOR_CMD_BLOCK_ERASE_ACK);
+
+ ret = nor_poll_dws(base_addr, DWS_WORD_ERASE_RETRIES);
+ if (ret == 0)
+ ret = nor_full_status_check(base_addr);
nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
+
return ret;
}
-void nor_lock(uintptr_t base_addr)
+/*
+ * Lock a full 256 block
+ * Return values:
+ * 0 = success
+ * otherwise it returns a negative value
+ */
+int nor_lock(uintptr_t base_addr)
{
+ int ret;
+
+ nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
+
nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
- mmio_write_32(base_addr, NOR_2X16(NOR_LOCK_BLOCK));
+ nor_send_cmd(base_addr, NOR_LOCK_BLOCK);
+
+ ret = nor_poll_dws(base_addr, DWS_WORD_LOCK_RETRIES);
+ if (ret == 0)
+ ret = nor_full_status_check(base_addr);
nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
+
+ return ret;
}
-void nor_unlock(uintptr_t base_addr)
+/*
+ * unlock a full 256 block
+ * Return values:
+ * 0 = success
+ * otherwise it returns a negative value
+ */
+int nor_unlock(uintptr_t base_addr)
{
+ int ret;
+
+ nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
+
nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
- mmio_write_32(base_addr, NOR_2X16(NOR_UNLOCK_BLOCK));
+ nor_send_cmd(base_addr, NOR_UNLOCK_BLOCK);
+
+ ret = nor_poll_dws(base_addr, DWS_WORD_LOCK_RETRIES);
+ if (ret == 0)
+ ret = nor_full_status_check(base_addr);
nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
-}
+ return ret;
+}
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 44e9ce67c..d97a04920 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -222,8 +222,7 @@ void fvp_config_setup(void)
arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
break;
case REV_BASE_FVP_REVC:
- arm_config.flags |= (ARM_CONFIG_FVP_SHIFTED_AFF |
- ARM_CONFIG_FVP_HAS_SMMUV3 |
+ arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 |
ARM_CONFIG_FVP_HAS_CCI5XX);
break;
default:
@@ -235,6 +234,14 @@ void fvp_config_setup(void)
ERROR("Unsupported board HBI number 0x%x\n", hbi);
panic();
}
+
+ /*
+ * We assume that the presence of MT bit, and therefore shifted
+ * affinities, is uniform across the platform: either all CPUs, or no
+ * CPUs implement it.
+ */
+ if (read_mpidr_el1() & MPIDR_MT_MASK)
+ arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
}
diff --git a/plat/qemu/include/platform_def.h b/plat/qemu/include/platform_def.h
index ceb0539b5..e91a7db9f 100644
--- a/plat/qemu/include/platform_def.h
+++ b/plat/qemu/include/platform_def.h
@@ -73,6 +73,11 @@
#define SEC_DRAM_BASE 0x0e100000
#define SEC_DRAM_SIZE 0x00f00000
+/* Load pageable part of OP-TEE at end of secure DRAM */
+#define QEMU_OPTEE_PAGEABLE_LOAD_BASE (SEC_DRAM_BASE + SEC_DRAM_SIZE - \
+ QEMU_OPTEE_PAGEABLE_LOAD_SIZE)
+#define QEMU_OPTEE_PAGEABLE_LOAD_SIZE 0x00400000
+
/*
* ARM-TF lives in SRAM, partition it here
*/
@@ -154,7 +159,8 @@
#define NS_IMAGE_OFFSET 0x60000000
-#define ADDR_SPACE_SIZE (1ull << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
#define MAX_MMAP_REGIONS 8
#define MAX_XLAT_TABLES 6
#define MAX_IO_DEVICES 3
diff --git a/plat/qemu/platform.mk b/plat/qemu/platform.mk
index dc3b5d933..ed197a1d1 100644
--- a/plat/qemu/platform.mk
+++ b/plat/qemu/platform.mk
@@ -65,6 +65,10 @@ BL2_SOURCES += plat/qemu/qemu_bl2_mem_params_desc.c \
plat/qemu/qemu_image_load.c \
common/desc_image_load.c
endif
+ifeq (${SPD},opteed)
+BL2_SOURCES += lib/optee/optee_utils.c
+endif
+
BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \
lib/cpus/aarch64/cortex_a53.S \
@@ -72,13 +76,23 @@ BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \
drivers/arm/gic/v2/gicv2_helpers.c \
drivers/arm/gic/v2/gicv2_main.c \
drivers/arm/gic/common/gic_common.c \
- plat/common/aarch64/plat_psci_common.c \
+ plat/common/plat_psci_common.c \
plat/qemu/qemu_pm.c \
plat/qemu/topology.c \
plat/qemu/aarch64/plat_helpers.S \
plat/qemu/qemu_bl31_setup.c \
plat/qemu/qemu_gic.c
+
+# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
+# in the FIP if the platform requires.
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call FIP_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call FIP_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+
# Disable the PSCI platform compatibility layer
ENABLE_PLAT_COMPAT := 0
diff --git a/plat/qemu/qemu_bl2_mem_params_desc.c b/plat/qemu/qemu_bl2_mem_params_desc.c
index 3396140a1..47f88acb9 100644
--- a/plat/qemu/qemu_bl2_mem_params_desc.c
+++ b/plat/qemu/qemu_bl2_mem_params_desc.c
@@ -72,6 +72,43 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
.next_handoff_image_id = BL33_IMAGE_ID,
},
+
+ /*
+ * Fill BL32 external 1 related information.
+ * A typical use for extra1 image is with OP-TEE where it is the
+ * pager image.
+ */
+ { .image_id = BL32_EXTRA1_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t, SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+ image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+
+ /*
+ * Fill BL32 external 2 related information.
+ * A typical use for extra2 image is with OP-TEE where it is the
+ * paged image.
+ */
+ { .image_id = BL32_EXTRA2_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+ entry_point_info_t, SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+ image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+#ifdef SPD_opteed
+ .image_info.image_base = QEMU_OPTEE_PAGEABLE_LOAD_BASE,
+ .image_info.image_max_size = QEMU_OPTEE_PAGEABLE_LOAD_SIZE,
+#endif
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
# endif /* QEMU_LOAD_BL32 */
/* Fill BL33 related information */
diff --git a/plat/qemu/qemu_bl2_setup.c b/plat/qemu/qemu_bl2_setup.c
index 1306f34bd..60d96233d 100644
--- a/plat/qemu/qemu_bl2_setup.c
+++ b/plat/qemu/qemu_bl2_setup.c
@@ -9,6 +9,9 @@
#include <console.h>
#include <debug.h>
#include <desc_image_load.h>
+#ifdef SPD_opteed
+#include <optee_utils.h>
+#endif
#include <libfdt.h>
#include <platform_def.h>
#include <string.h>
@@ -225,12 +228,36 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
{
int err = 0;
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+#ifdef SPD_opteed
+ bl_mem_params_node_t *pager_mem_params = NULL;
+ bl_mem_params_node_t *paged_mem_params = NULL;
+#endif
assert(bl_mem_params);
switch (image_id) {
# ifdef AARCH64
case BL32_IMAGE_ID:
+#ifdef SPD_opteed
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params);
+
+ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ assert(paged_mem_params);
+
+ err = parse_optee_header(&bl_mem_params->ep_info,
+ &pager_mem_params->image_info,
+ &paged_mem_params->image_info);
+ if (err != 0) {
+ WARN("OPTEE header parse error.\n");
+ }
+
+ /*
+ * OP-TEE expect to receive DTB address in x2.
+ * This will be copied into x2 by dispatcher.
+ */
+ bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE;
+#endif
bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
break;
# endif
diff --git a/plat/qemu/qemu_io_storage.c b/plat/qemu/qemu_io_storage.c
index 19baf21d6..e0f7e8abe 100644
--- a/plat/qemu/qemu_io_storage.c
+++ b/plat/qemu/qemu_io_storage.c
@@ -21,6 +21,8 @@
#define BL2_IMAGE_NAME "bl2.bin"
#define BL31_IMAGE_NAME "bl31.bin"
#define BL32_IMAGE_NAME "bl32.bin"
+#define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin"
+#define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin"
#define BL33_IMAGE_NAME "bl33.bin"
#if TRUSTED_BOARD_BOOT
@@ -61,6 +63,14 @@ static const io_uuid_spec_t bl32_uuid_spec = {
.uuid = UUID_SECURE_PAYLOAD_BL32,
};
+static const io_uuid_spec_t bl32_extra1_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
+};
+
+static const io_uuid_spec_t bl32_extra2_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
+};
+
static const io_uuid_spec_t bl33_uuid_spec = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
@@ -112,6 +122,14 @@ static const io_file_spec_t sh_file_spec[] = {
.path = BL32_IMAGE_NAME,
.mode = FOPEN_MODE_RB
},
+ [BL32_EXTRA1_IMAGE_ID] = {
+ .path = BL32_EXTRA1_IMAGE_NAME,
+ .mode = FOPEN_MODE_RB
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ .path = BL32_EXTRA2_IMAGE_NAME,
+ .mode = FOPEN_MODE_RB
+ },
[BL33_IMAGE_ID] = {
.path = BL33_IMAGE_NAME,
.mode = FOPEN_MODE_RB
@@ -185,6 +203,16 @@ static const struct plat_io_policy policies[] = {
(uintptr_t)&bl32_uuid_spec,
open_fip
},
+ [BL32_EXTRA1_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_extra1_uuid_spec,
+ open_fip
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_extra2_uuid_spec,
+ open_fip
+ },
[BL33_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_uuid_spec,
diff --git a/services/spd/opteed/opteed_common.c b/services/spd/opteed/opteed_common.c
index a0cd86cb3..2693e7d1d 100644
--- a/services/spd/opteed/opteed_common.c
+++ b/services/spd/opteed/opteed_common.c
@@ -20,7 +20,7 @@
void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
uint32_t rw, uint64_t pc,
uint64_t pageable_part, uint64_t mem_limit,
- optee_context_t *optee_ctx)
+ uint64_t dt_addr, optee_context_t *optee_ctx)
{
uint32_t ep_attr;
@@ -54,6 +54,7 @@ void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
zeromem(&optee_entry_point->args, sizeof(optee_entry_point->args));
optee_entry_point->args.arg0 = pageable_part;
optee_entry_point->args.arg1 = mem_limit;
+ optee_entry_point->args.arg2 = dt_addr;
}
/*******************************************************************************
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index b3031e402..13a307a2a 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -96,6 +96,7 @@ int32_t opteed_setup(void)
uint32_t linear_id;
uint64_t opteed_pageable_part;
uint64_t opteed_mem_limit;
+ uint64_t dt_addr;
linear_id = plat_my_core_pos();
@@ -120,19 +121,17 @@ int32_t opteed_setup(void)
if (!optee_ep_info->pc)
return 1;
- /*
- * We could inspect the SP image and determine it's execution
- * state i.e whether AArch32 or AArch64.
- */
opteed_rw = optee_ep_info->args.arg0;
opteed_pageable_part = optee_ep_info->args.arg1;
opteed_mem_limit = optee_ep_info->args.arg2;
+ dt_addr = optee_ep_info->args.arg3;
opteed_init_optee_ep_state(optee_ep_info,
opteed_rw,
optee_ep_info->pc,
opteed_pageable_part,
opteed_mem_limit,
+ dt_addr,
&opteed_sp_context[linear_id]);
/*
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index 5a1dd4fd6..2420b1e8f 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -99,7 +99,7 @@ static void opteed_cpu_on_finish_handler(uint64_t unused)
opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
(uint64_t)&optee_vectors->cpu_on_entry,
- 0, 0, optee_ctx);
+ 0, 0, 0, optee_ctx);
/* Initialise this cpu's secure context */
cm_init_my_context(&optee_on_entrypoint);
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index 11c1a1fa1..6cda2c8e9 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -149,6 +149,7 @@ void opteed_init_optee_ep_state(struct entry_point_info *optee_ep,
uint64_t pc,
uint64_t pageable_part,
uint64_t mem_limit,
+ uint64_t dt_addr,
optee_context_t *optee_ctx);
extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];