Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
@@ -0,0 +1,213 @@
From 5ce8bf4ad1aeb2657a7ab83c46eeb2cdaa56cfd4 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Fri, 29 Jul 2022 13:06:19 +0100
Subject: [PATCH 01/42] arm64: smccc: add support for SMCCCv1.2 x0-x17
registers
add support for x0-x17 registers used by the SMC calls
In SMCCC v1.2 [1] arguments are passed in registers x1-x17.
Results are returned in x0-x17.
This work is inspired from the following kernel commit:
arm64: smccc: Add support for SMCCCv1.2 extended input/output registers
[1]: https://documentation-service.arm.com/static/5f8edaeff86e16515cdbe4c6?token=
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v7:
* improve indentation of ARM_SMCCC_1_2_REGS_Xn_OFFS
v4:
* rename the commit title and improve description
new commit title: the current
v3:
* port x0-x17 registers support from linux kernel as defined by SMCCCv1.2
commit title:
arm64: smccc: add Xn registers support used by SMC calls
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
arch/arm/cpu/armv8/smccc-call.S | 53 +++++++++++++++++++++++++++++++++
arch/arm/lib/asm-offsets.c | 14 +++++++++
include/linux/arm-smccc.h | 43 ++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
index dc92b28777..ec6f299bc9 100644
--- a/arch/arm/cpu/armv8/smccc-call.S
+++ b/arch/arm/cpu/armv8/smccc-call.S
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2015, Linaro Limited
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#include <linux/linkage.h>
#include <linux/arm-smccc.h>
@@ -45,3 +47,54 @@ ENDPROC(__arm_smccc_smc)
ENTRY(__arm_smccc_hvc)
SMCCC hvc
ENDPROC(__arm_smccc_hvc)
+
+#ifdef CONFIG_ARM64
+
+ .macro SMCCC_1_2 instr
+ /* Save `res` and free a GPR that won't be clobbered */
+ stp x1, x19, [sp, #-16]!
+
+ /* Ensure `args` won't be clobbered while loading regs in next step */
+ mov x19, x0
+
+ /* Load the registers x0 - x17 from the struct arm_smccc_1_2_regs */
+ ldp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS]
+ ldp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS]
+ ldp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS]
+ ldp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS]
+ ldp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS]
+ ldp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS]
+ ldp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS]
+ ldp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS]
+ ldp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS]
+
+ \instr #0
+
+ /* Load the `res` from the stack */
+ ldr x19, [sp]
+
+ /* Store the registers x0 - x17 into the result structure */
+ stp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS]
+ stp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS]
+ stp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS]
+ stp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS]
+ stp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS]
+ stp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS]
+ stp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS]
+ stp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS]
+ stp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS]
+
+ /* Restore original x19 */
+ ldp xzr, x19, [sp], #16
+ ret
+ .endm
+
+/*
+ * void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
+ * struct arm_smccc_1_2_regs *res);
+ */
+ENTRY(arm_smccc_1_2_smc)
+ SMCCC_1_2 smc
+ENDPROC(arm_smccc_1_2_smc)
+
+#endif
diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c
index 22fd541f9a..db6d7ed234 100644
--- a/arch/arm/lib/asm-offsets.c
+++ b/arch/arm/lib/asm-offsets.c
@@ -9,6 +9,9 @@
* generate asm statements containing #defines,
* compile this file to assembler, and then extract the
* #defines from the assembly-language output.
+ *
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#include <common.h>
@@ -117,6 +120,17 @@ int main(void)
DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2));
DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id));
DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state));
+#ifdef CONFIG_ARM64
+ DEFINE(ARM_SMCCC_1_2_REGS_X0_OFFS, offsetof(struct arm_smccc_1_2_regs, a0));
+ DEFINE(ARM_SMCCC_1_2_REGS_X2_OFFS, offsetof(struct arm_smccc_1_2_regs, a2));
+ DEFINE(ARM_SMCCC_1_2_REGS_X4_OFFS, offsetof(struct arm_smccc_1_2_regs, a4));
+ DEFINE(ARM_SMCCC_1_2_REGS_X6_OFFS, offsetof(struct arm_smccc_1_2_regs, a6));
+ DEFINE(ARM_SMCCC_1_2_REGS_X8_OFFS, offsetof(struct arm_smccc_1_2_regs, a8));
+ DEFINE(ARM_SMCCC_1_2_REGS_X10_OFFS, offsetof(struct arm_smccc_1_2_regs, a10));
+ DEFINE(ARM_SMCCC_1_2_REGS_X12_OFFS, offsetof(struct arm_smccc_1_2_regs, a12));
+ DEFINE(ARM_SMCCC_1_2_REGS_X14_OFFS, offsetof(struct arm_smccc_1_2_regs, a14));
+ DEFINE(ARM_SMCCC_1_2_REGS_X16_OFFS, offsetof(struct arm_smccc_1_2_regs, a16));
+#endif
#endif
return 0;
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index e1d09884a1..9105031d55 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2015, Linaro Limited
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#ifndef __LINUX_ARM_SMCCC_H
#define __LINUX_ARM_SMCCC_H
@@ -70,6 +72,47 @@ struct arm_smccc_res {
unsigned long a3;
};
+#ifdef CONFIG_ARM64
+/**
+ * struct arm_smccc_1_2_regs - Arguments for or Results from SMC call
+ * @a0-a17 argument values from registers 0 to 17
+ */
+struct arm_smccc_1_2_regs {
+ unsigned long a0;
+ unsigned long a1;
+ unsigned long a2;
+ unsigned long a3;
+ unsigned long a4;
+ unsigned long a5;
+ unsigned long a6;
+ unsigned long a7;
+ unsigned long a8;
+ unsigned long a9;
+ unsigned long a10;
+ unsigned long a11;
+ unsigned long a12;
+ unsigned long a13;
+ unsigned long a14;
+ unsigned long a15;
+ unsigned long a16;
+ unsigned long a17;
+};
+
+/**
+ * arm_smccc_1_2_smc() - make SMC calls
+ * @args: arguments passed via struct arm_smccc_1_2_regs
+ * @res: result values via struct arm_smccc_1_2_regs
+ *
+ * This function is used to make SMC calls following SMC Calling Convention
+ * v1.2 or above. The content of the supplied param are copied from the
+ * structure to registers prior to the SMC instruction. The return values
+ * are updated with the content from registers on return from the SMC
+ * instruction.
+ */
+asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
+ struct arm_smccc_1_2_regs *res);
+#endif
+
/**
* struct arm_smccc_quirk - Contains quirk information
* @id: quirk identification
--
2.25.1
@@ -0,0 +1,134 @@
From 1dcebf6f57e3490f7b3e2464b4114b993dd70c7c Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Thu, 4 Aug 2022 16:46:47 +0100
Subject: [PATCH 02/42] lib: uuid: introduce uuid_str_to_le_bin function
convert UUID string to little endian binary data
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v8:
* use simple_strtoull() in uuid_str_to_le_bin() to support 32-bit platforms
v7:
* rename be_uuid_str_to_le_bin() to uuid_str_to_le_bin()
* make uuid_str_to_le_bin() implementation similar to uuid_str_to_bin()
by using same APIs
v4:
* rename ffa_uuid_str_to_bin to be_uuid_str_to_le_bin and put in
a standalone commit (the current)
v3:
* introduce ffa_uuid_str_to_bin (provided by
arm_ffa: introduce Arm FF-A low-level driver)
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
include/uuid.h | 8 ++++++++
lib/uuid.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/include/uuid.h b/include/uuid.h
index 4a4883d3b5..293a8eb0a5 100644
--- a/include/uuid.h
+++ b/include/uuid.h
@@ -2,6 +2,8 @@
/*
* Copyright (C) 2014 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#ifndef __UUID_H__
#define __UUID_H__
@@ -44,4 +46,10 @@ int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin);
const char *uuid_guid_get_str(const unsigned char *guid_bin);
void gen_rand_uuid(unsigned char *uuid_bin);
void gen_rand_uuid_str(char *uuid_str, int str_format);
+
+/**
+ * uuid_str_to_le_bin - Converts a UUID string to little endian binary data
+ */
+int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin);
+
#endif
diff --git a/lib/uuid.c b/lib/uuid.c
index 465e1ac38f..d29f561a70 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2011 Calxeda, Inc.
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#include <common.h>
@@ -346,6 +348,50 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
return 0;
}
+/**
+ * uuid_str_to_le_bin() - Convert string UUID to little endian binary data.
+ * @uuid_str: pointer to UUID string
+ * @uuid_bin: pointer to allocated array for little endian output [16B]
+ *
+ * UUID string is 36 characters (36 bytes):
+ *
+ * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+ *
+ * where x is a hexadecimal character. Fields are separated by '-'s.
+ * When converting to a little endian binary UUID, the string fields are reversed.
+ *
+ * Return:
+ *
+ * uuid_bin filled with little endian UUID data
+ * On success 0 is returned. Otherwise, failure code.
+ */
+int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin)
+{
+ u16 tmp16;
+ u32 tmp32;
+ u64 tmp64;
+
+ if (!uuid_str_valid(uuid_str) || !uuid_bin)
+ return -EINVAL;
+
+ tmp32 = cpu_to_le32(hextoul(uuid_str, NULL));
+ memcpy(uuid_bin, &tmp32, 4);
+
+ tmp16 = cpu_to_le16(hextoul(uuid_str + 9, NULL));
+ memcpy(uuid_bin + 4, &tmp16, 2);
+
+ tmp16 = cpu_to_le16(hextoul(uuid_str + 14, NULL));
+ memcpy(uuid_bin + 6, &tmp16, 2);
+
+ tmp16 = cpu_to_le16(hextoul(uuid_str + 19, NULL));
+ memcpy(uuid_bin + 8, &tmp16, 2);
+
+ tmp64 = cpu_to_le64(simple_strtoull(uuid_str + 24, NULL, 16));
+ memcpy(uuid_bin + 10, &tmp64, 6);
+
+ return 0;
+}
+
/*
* uuid_bin_to_str() - convert big endian binary data to string UUID or GUID.
*
--
2.25.1
@@ -0,0 +1,74 @@
From b09b391e33e024a18842dfdc99282d0050cc5fcb Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Thu, 6 Oct 2022 15:04:25 +0100
Subject: [PATCH 04/42] arm_ffa: efi: unmap RX/TX buffers
unmap RX/TX buffers at ExitBootServices()
Unmapping the RX/TX buffers created by u-boot is needed before EFI
runtime.
At EFI runtime the linux kernel takes care of allocating its own RX/TX
buffers and registering them with the secure world.
Secure world should be using the RX/TX buffers created by the kernel.
So, RX/TX buffers created by u-boot must be unmapped.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v8: pass NULL device pointer to the FF-A bus operation
v7: replace debug() by log_err()
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
lib/efi_loader/efi_boottime.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index e65ca6a4cb..3481f2afe7 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -3,6 +3,9 @@
* EFI application boot time services
*
* Copyright (c) 2016 Alexander Graf
+ *
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#include <common.h>
@@ -23,6 +26,10 @@
#include <asm/setjmp.h>
#include <linux/libfdt_env.h>
+#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
+#include <arm_ffa.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
/* Task priority level */
@@ -2178,6 +2185,12 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
}
+#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
+ /* unmap FF-A RX/TX buffers */
+ if (ffa_bus_ops_get()->rxtx_unmap(NULL))
+ log_err("Can't unmap FF-A RX/TX buffers\n");
+#endif
+
/* Patch out unsupported runtime function */
efi_runtime_detach();
--
2.25.1
@@ -0,0 +1,364 @@
From f3bc86a7ec63c0454577cb6712395c577b2cfd66 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Mon, 6 Jun 2022 12:46:38 +0100
Subject: [PATCH 05/42] arm_ffa: introduce armffa command
Provide armffa command showcasing the use of the FF-A driver
The armffa command allows to query secure partitions data from
the secure world and exchanging messages with the partitions
using 64-bit FF-A direct messaging.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v8:
* update partition_info_get() second argument to be an SP count
* pass NULL device pointer to the FF-A bus discovery and operations
v7:
* adapt do_ffa_dev_list() following the recent update on
uclass_first_device/uclass_next_device functions (they return void now)
* set armffa command to use 64-bit direct messaging
v4:
* remove pattern data in do_ffa_msg_send_direct_req
v3:
* use the new driver interfaces (partition_info_get, sync_send_receive)
in armffa command
v2:
* replace use of ffa_helper_init_device function by
ffa_helper_bus_discover
v1:
* introduce armffa command
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
MAINTAINERS | 1 +
cmd/Kconfig | 10 ++
cmd/Makefile | 2 +
cmd/armffa.c | 237 +++++++++++++++++++++++++++++++
drivers/firmware/arm-ffa/Kconfig | 1 +
5 files changed, 251 insertions(+)
create mode 100644 cmd/armffa.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 509619d31c..61ce6c436f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -267,6 +267,7 @@ F: configs/cortina_presidio-asic-pnand_defconfig
ARM FF-A
M: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
S: Maintained
+F: cmd/armffa.c
F: doc/arch/arm64.ffa.rst
F: drivers/firmware/arm-ffa/
F: include/arm_ffa.h
diff --git a/cmd/Kconfig b/cmd/Kconfig
index b2d7598717..7d0a40e8ac 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -924,6 +924,16 @@ endmenu
menu "Device access commands"
+config CMD_ARMFFA
+ bool "Arm FF-A test command"
+ depends on ARM_FFA_TRANSPORT
+ help
+ Provides a test command for the Arm FF-A driver
+ supported options:
+ - Listing the partition(s) info
+ - Sending a data pattern to the specified partition
+ - Displaying the arm_ffa device info
+
config CMD_ARMFLASH
#depends on FLASH_CFI_DRIVER
bool "armflash"
diff --git a/cmd/Makefile b/cmd/Makefile
index 0b6a96c1d9..c757f1647d 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -12,6 +12,8 @@ obj-y += panic.o
obj-y += version.o
# command
+
+obj-$(CONFIG_CMD_ARMFFA) += armffa.o
obj-$(CONFIG_CMD_ACPI) += acpi.o
obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
obj-$(CONFIG_CMD_AES) += aes.o
diff --git a/cmd/armffa.c b/cmd/armffa.c
new file mode 100644
index 0000000000..d2e8687bfb
--- /dev/null
+++ b/cmd/armffa.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <arm_ffa.h>
+#include <asm/io.h>
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <stdlib.h>
+
+/**
+ * do_ffa_get_singular_partition_info - implementation of the getpart subcommand
+ * @cmdtp: Command Table
+ * @flag: flags
+ * @argc: number of arguments
+ * @argv: arguments
+ *
+ * This function queries the secure partition information which the UUID is provided
+ * as an argument. The function uses the arm_ffa driver partition_info_get operation
+ * to retrieve the data.
+ * The input UUID string is expected to be in big endian format.
+ *
+ * Return:
+ *
+ * CMD_RET_SUCCESS: on success, otherwise failure
+ */
+static int do_ffa_get_singular_partition_info(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ u32 count = 0;
+ int ret;
+ struct ffa_partition_info *parts_info;
+ u32 info_idx;
+
+ if (argc != 1)
+ return -EINVAL;
+
+ /* Mode 1: getting the number of secure partitions */
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, argv[0], &count, NULL);
+ if (ret != 0) {
+ ffa_err("Failure in querying partitions count (error code: %d)", ret);
+ return ret;
+ }
+
+ if (!count) {
+ ffa_info("No secure partition found");
+ return ret;
+ }
+
+ /*
+ * pre-allocate a buffer to be filled by the driver
+ * with ffa_partition_info structs
+ */
+
+ ffa_info("Pre-allocating %d partition(s) info structures", count);
+
+ parts_info = calloc(count, sizeof(struct ffa_partition_info));
+ if (!parts_info)
+ return -EINVAL;
+
+ /*
+ * ask the driver to fill the buffer with the SPs info
+ */
+
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, argv[0], &count, parts_info);
+ if (ret != 0) {
+ ffa_err("Failure in querying partition(s) info (error code: %d)", ret);
+ free(parts_info);
+ return ret;
+ }
+
+ /*
+ * SPs found , show the partition information
+ */
+ for (info_idx = 0; info_idx < count ; info_idx++) {
+ ffa_info("Partition: id = 0x%x , exec_ctxt 0x%x , properties 0x%x",
+ parts_info[info_idx].id,
+ parts_info[info_idx].exec_ctxt,
+ parts_info[info_idx].properties);
+ }
+
+ free(parts_info);
+
+ return 0;
+}
+
+/**
+ * do_ffa_msg_send_direct_req - implementation of the ping subcommand
+ * @cmdtp: Command Table
+ * @flag: flags
+ * @argc: number of arguments
+ * @argv: arguments
+ *
+ * This function sends data to the secure partition which the ID is provided
+ * as an argument. The function uses the arm_ffa driver sync_send_receive operation
+ * to send data.
+ *
+ * Return:
+ *
+ * CMD_RET_SUCCESS: on success, otherwise failure
+ */
+int do_ffa_msg_send_direct_req(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct ffa_send_direct_data msg = {
+ .data0 = 0xaaaaaaaa,
+ .data1 = 0xbbbbbbbb,
+ .data2 = 0xcccccccc,
+ .data3 = 0xdddddddd,
+ .data4 = 0xeeeeeeee,
+ };
+ u16 part_id;
+ int ret;
+
+ if (argc != 1)
+ return -EINVAL;
+
+ errno = 0;
+ part_id = strtoul(argv[0], NULL, 16);
+
+ if (errno) {
+ ffa_err("Invalid partition ID");
+ return -EINVAL;
+ }
+
+ ret = ffa_bus_ops_get()->sync_send_receive(NULL, part_id, &msg, 1);
+ if (ret == 0) {
+ u8 cnt;
+
+ ffa_info("SP response:\n[LSB]");
+ for (cnt = 0;
+ cnt < sizeof(struct ffa_send_direct_data) / sizeof(u64);
+ cnt++)
+ ffa_info("0x%llx", ((u64 *)&msg)[cnt]);
+ } else {
+ ffa_err("Sending direct request error (%d)", ret);
+ }
+
+ return ret;
+}
+
+/**
+ *do_ffa_dev_list - implementation of the devlist subcommand
+ * @cmdtp: [in] Command Table
+ * @flag: flags
+ * @argc: number of arguments
+ * @argv: arguments
+ *
+ * This function queries the devices belonging to the UCLASS_FFA
+ * class. Currently, one device is expected to show up: the arm_ffa device
+ *
+ * Return:
+ *
+ * CMD_RET_SUCCESS: on success, otherwise failure
+ */
+int do_ffa_dev_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ struct udevice *dev = NULL;
+ int i;
+
+ ffa_info("arm_ffa uclass entries:");
+
+ for (i = 0, uclass_first_device(UCLASS_FFA, &dev);
+ dev;
+ uclass_next_device(&dev), i++) {
+ ffa_info("entry %d - instance %08x, ops %08x, plat %08x",
+ i,
+ (u32)map_to_sysmem(dev),
+ (u32)map_to_sysmem(dev->driver->ops),
+ (u32)map_to_sysmem(dev_get_plat(dev)));
+ }
+
+ return 0;
+}
+
+static struct cmd_tbl armffa_commands[] = {
+ U_BOOT_CMD_MKENT(getpart, 1, 1, do_ffa_get_singular_partition_info, "", ""),
+ U_BOOT_CMD_MKENT(ping, 1, 1, do_ffa_msg_send_direct_req, "", ""),
+ U_BOOT_CMD_MKENT(devlist, 0, 1, do_ffa_dev_list, "", ""),
+};
+
+/**
+ * do_armffa - the armffa command main function
+ * @cmdtp: Command Table
+ * @flag: flags
+ * @argc: number of arguments
+ * @argv: arguments
+ *
+ * This function identifies which armffa subcommand to run.
+ * Then, it makes sure the arm_ffa device is probed and
+ * ready for use.
+ * Then, it runs the subcommand.
+ *
+ * Return:
+ *
+ * CMD_RET_SUCCESS: on success, otherwise failure
+ */
+static int do_armffa(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ struct cmd_tbl *armffa_cmd;
+ int ret;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ armffa_cmd = find_cmd_tbl(argv[1], armffa_commands, ARRAY_SIZE(armffa_commands));
+
+ argc -= 2;
+ argv += 2;
+
+ if (!armffa_cmd || argc > armffa_cmd->maxargs)
+ return CMD_RET_USAGE;
+
+ ret = ffa_bus_discover(NULL);
+ if (ret != 0)
+ return cmd_process_error(cmdtp, ret);
+
+ if (!ffa_bus_ops_get())
+ return -EINVAL;
+
+ ret = armffa_cmd->cmd(armffa_cmd, flag, argc, argv);
+
+ return cmd_process_error(armffa_cmd, ret);
+}
+
+U_BOOT_CMD(armffa, 4, 1, do_armffa,
+ "Arm FF-A operations test command",
+ "getpart <partition UUID>\n"
+ " - lists the partition(s) info\n"
+ "ping <partition ID>\n"
+ " - sends a data pattern to the specified partition\n"
+ "devlist\n"
+ " - displays the arm_ffa device info\n");
diff --git a/drivers/firmware/arm-ffa/Kconfig b/drivers/firmware/arm-ffa/Kconfig
index e4914b9bc7..be4df89d23 100644
--- a/drivers/firmware/arm-ffa/Kconfig
+++ b/drivers/firmware/arm-ffa/Kconfig
@@ -4,6 +4,7 @@ config ARM_FFA_TRANSPORT
bool "Enable Arm Firmware Framework for Armv8-A driver"
depends on DM && ARM64
select ARM_SMCCC
+ select CMD_ARMFFA
select LIB_UUID
select DEVRES
help
--
2.25.1
@@ -0,0 +1,472 @@
From 3664fe7503cbc4348bbd7bcb8fbf7e1db332ac5d Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Mon, 6 Jun 2022 17:26:06 +0100
Subject: [PATCH 07/42] arm_ffa: introduce Sandbox test cases for UCLASS_FFA
Add functional test cases for the FF-A core driver
These tests rely on the FF-A Sandbox driver which helps in
inspecting the FF-A core driver.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v8:
* update partition_info_get() second argument to be an SP count
* pass NULL device pointer to the FF-A bus discovery and operations
v7: set the tests to use 64-bit direct messaging
v4: align sandbox tests with the new FF-A driver interfaces
and new way of error handling
v1: introduce sandbox tests
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
MAINTAINERS | 1 +
test/dm/Makefile | 2 +
test/dm/ffa.c | 392 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 395 insertions(+)
create mode 100644 test/dm/ffa.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 297d165f84..c1d3d4ae1c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -272,6 +272,7 @@ F: doc/arch/arm64.ffa.rst
F: drivers/firmware/arm-ffa/
F: include/arm_ffa.h
F: include/sandbox_arm_ffa.h
+F: test/dm/ffa.c
ARM FREESCALE IMX
M: Stefano Babic <sbabic@denx.de>
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 7a79b6e1a2..85e99e1c12 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2013 Google, Inc
+# (C) Copyright 2022 ARM Limited
obj-$(CONFIG_UT_DM) += test-dm.o
@@ -85,6 +86,7 @@ obj-$(CONFIG_POWER_DOMAIN) += power-domain.o
obj-$(CONFIG_ACPI_PMC) += pmc.o
obj-$(CONFIG_DM_PMIC) += pmic.o
obj-$(CONFIG_DM_PWM) += pwm.o
+obj-$(CONFIG_SANDBOX_FFA) += ffa.o
obj-$(CONFIG_QFW) += qfw.o
obj-$(CONFIG_RAM) += ram.o
obj-y += regmap.o
diff --git a/test/dm/ffa.c b/test/dm/ffa.c
new file mode 100644
index 0000000000..128d8626a7
--- /dev/null
+++ b/test/dm/ffa.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Functional tests for UCLASS_FFA class
+ *
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <common.h>
+#include <console.h>
+#include <dm.h>
+#include <dm/test.h>
+#include "../../drivers/firmware/arm-ffa/sandbox_arm_ffa_prv.h"
+#include <sandbox_arm_ffa.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+/* Macros */
+
+#define LOG_MSG_SZ (100)
+#define LOG_CMD_SZ (LOG_MSG_SZ * 2)
+
+/* Functional tests for the UCLASS_FFA */
+
+static int dm_test_ffa_log(struct unit_test_state *uts, char *msg)
+{
+ char cmd[LOG_CMD_SZ] = {0};
+
+ console_record_reset();
+
+ snprintf(cmd, LOG_CMD_SZ, "echo \"%s\"", msg);
+ run_command(cmd, 0);
+
+ ut_assert_console_end();
+
+ return CMD_RET_SUCCESS;
+}
+
+static int check_fwk_version(struct ffa_prvdata *prvdata, struct sandbox_ffa_prvdata *sdx_prvdata,
+ struct unit_test_state *uts)
+{
+ if (prvdata->fwk_version != sdx_prvdata->fwk_version) {
+ char msg[LOG_MSG_SZ] = {0};
+
+ snprintf(msg, LOG_MSG_SZ,
+ "[%s]: Error: framework version: core = 0x%x , sandbox = 0x%x", __func__,
+ prvdata->fwk_version,
+ sdx_prvdata->fwk_version);
+
+ dm_test_ffa_log(uts, msg);
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int check_endpoint_id(struct ffa_prvdata *prvdata, struct unit_test_state *uts)
+{
+ if (prvdata->id) {
+ char msg[LOG_MSG_SZ] = {0};
+
+ snprintf(msg, LOG_MSG_SZ,
+ "[%s]: Error: endpoint id: core = 0x%x", __func__, prvdata->id);
+ dm_test_ffa_log(uts, msg);
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int check_core_dev(struct ffa_prvdata *prvdata, struct unit_test_state *uts)
+{
+ if (!prvdata->dev) {
+ char msg[LOG_MSG_SZ] = {0};
+
+ snprintf(msg, LOG_MSG_SZ, "[%s]: Error: core device NULL", __func__);
+ dm_test_ffa_log(uts, msg);
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int check_sandbox_dev(struct sandbox_ffa_prvdata *sdx_prvdata, struct unit_test_state *uts)
+{
+ if (!sdx_prvdata->dev) {
+ char msg[LOG_MSG_SZ] = {0};
+
+ snprintf(msg, LOG_MSG_SZ, "[%s]: Error: sandbox device NULL", __func__);
+ dm_test_ffa_log(uts, msg);
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int check_rxtxbuf(struct ffa_prvdata *prvdata, struct unit_test_state *uts)
+{
+ if (!prvdata->pair.rxbuf && prvdata->pair.txbuf) {
+ char msg[LOG_MSG_SZ] = {0};
+
+ snprintf(msg, LOG_MSG_SZ, "[%s]: Error: rxbuf = 0x%llx txbuf = 0x%llx", __func__,
+ prvdata->pair.rxbuf,
+ prvdata->pair.txbuf);
+ dm_test_ffa_log(uts, msg);
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int check_features(struct ffa_prvdata *prvdata, struct unit_test_state *uts)
+{
+ char msg[LOG_MSG_SZ] = {0};
+
+ if (prvdata->pair.rxtx_min_pages != RXTX_4K &&
+ prvdata->pair.rxtx_min_pages != RXTX_16K &&
+ prvdata->pair.rxtx_min_pages != RXTX_64K) {
+ snprintf(msg,
+ LOG_MSG_SZ,
+ "[%s]: Error: FFA_RXTX_MAP features = 0x%lx",
+ __func__,
+ prvdata->pair.rxtx_min_pages);
+ dm_test_ffa_log(uts, msg);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int check_rxbuf_mapped_flag(u32 queried_func_id,
+ u8 rxbuf_mapped,
+ struct unit_test_state *uts)
+{
+ char msg[LOG_MSG_SZ] = {0};
+
+ switch (queried_func_id) {
+ case FFA_RXTX_MAP:
+ {
+ if (rxbuf_mapped)
+ return CMD_RET_SUCCESS;
+ break;
+ }
+ case FFA_RXTX_UNMAP:
+ {
+ if (!rxbuf_mapped)
+ return CMD_RET_SUCCESS;
+ break;
+ }
+ default:
+ return CMD_RET_FAILURE;
+ }
+
+ snprintf(msg, LOG_MSG_SZ, "[%s]: Error: %s mapping issue", __func__,
+ (queried_func_id == FFA_RXTX_MAP ? "FFA_RXTX_MAP" : "FFA_RXTX_UNMAP"));
+ dm_test_ffa_log(uts, msg);
+
+ return CMD_RET_FAILURE;
+}
+
+static int check_rxbuf_release_flag(u8 rxbuf_owned, struct unit_test_state *uts)
+{
+ if (rxbuf_owned) {
+ char msg[LOG_MSG_SZ] = {0};
+
+ snprintf(msg, LOG_MSG_SZ, "[%s]: Error: RX buffer not released", __func__);
+ dm_test_ffa_log(uts, msg);
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int test_ffa_msg_send_direct_req(u16 part_id, struct unit_test_state *uts)
+{
+ struct ffa_send_direct_data msg = {0};
+ u8 cnt;
+
+ ut_assertok(ffa_bus_ops_get()->sync_send_receive(NULL, part_id, &msg, 1));
+
+ for (cnt = 0; cnt < sizeof(struct ffa_send_direct_data) / sizeof(u64); cnt++)
+ ut_assertok(((u64 *)&msg)[cnt] != 0xffffffffffffffff);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int test_partitions_and_comms(const char *service_uuid,
+ struct sandbox_ffa_prvdata *sdx_prvdata,
+ struct unit_test_state *uts)
+{
+ u32 count = 0;
+ struct ffa_partition_info *parts_info;
+ u32 info_idx, exp_info_idx;
+ int ret;
+
+ /*
+ * get from the driver the count of the SPs matching the UUID
+ */
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, service_uuid, &count, NULL);
+ /* make sure partitions are detected */
+ ut_assertok(ret != 0);
+ ut_assertok(count != SANDBOX_SP_COUNT_PER_VALID_SERVICE);
+
+ /*
+ * pre-allocate a buffer to be filled by the driver
+ * with ffa_partition_info structs
+ */
+
+ parts_info = calloc(count, sizeof(struct ffa_partition_info));
+ ut_assertok(!parts_info);
+
+ /*
+ * ask the driver to fill the buffer with the SPs info
+ */
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, service_uuid, &count, parts_info);
+ if (ret != 0) {
+ free(parts_info);
+ ut_assertok(ret != 0);
+ }
+
+ /*
+ * SPs found , verify the partitions information
+ */
+
+ ret = CMD_RET_FAILURE;
+
+ for (info_idx = 0; info_idx < count ; info_idx++) {
+ for (exp_info_idx = 0;
+ exp_info_idx < sdx_prvdata->partitions.count;
+ exp_info_idx++) {
+ if (parts_info[info_idx].id ==
+ sdx_prvdata->partitions.descs[exp_info_idx].info.id) {
+ ret = memcmp(&parts_info[info_idx],
+ &sdx_prvdata->partitions.descs[exp_info_idx]
+ .info,
+ sizeof(struct ffa_partition_info));
+ if (ret)
+ free(parts_info);
+ ut_assertok(ret != 0);
+ /* send and receive data from the current partition */
+ test_ffa_msg_send_direct_req(parts_info[info_idx].id, uts);
+ }
+ ret = CMD_RET_SUCCESS;
+ }
+ }
+
+ free(parts_info);
+
+ /* Verify expected partitions found in the emulated secure world*/
+ ut_assertok(ret != CMD_RET_SUCCESS);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int dm_test_ffa_ack(struct unit_test_state *uts)
+{
+ struct ffa_prvdata *prvdata = NULL;
+ struct sandbox_ffa_prvdata *sdx_prvdata = NULL;
+ struct ffa_sandbox_data func_data = {0};
+ u8 rxbuf_flag = 0;
+ const char *svc1_uuid = SANDBOX_SERVICE1_UUID;
+ const char *svc2_uuid = SANDBOX_SERVICE2_UUID;
+ int ret;
+
+ /* test probing FF-A devices */
+ ut_assertok(ffa_bus_discover(NULL));
+
+ /* get a pointer to the FF-A core and sandbox drivers private data */
+ func_data.data0 = &prvdata;
+ func_data.data0_size = sizeof(prvdata);
+ func_data.data1 = &sdx_prvdata;
+ func_data.data1_size = sizeof(sdx_prvdata);
+
+ ut_assertok(sandbox_ffa_query_core_state(FFA_VERSION, &func_data));
+
+ /* make sure private data pointers are retrieved */
+ ut_assertok(prvdata == 0);
+ ut_assertok(sdx_prvdata == 0);
+
+ /* make sure dev devices created */
+ ut_assertok(check_core_dev(prvdata, uts));
+ ut_assertok(check_sandbox_dev(sdx_prvdata, uts));
+
+ /* test FFA_VERSION */
+ ut_assertok(check_fwk_version(prvdata, sdx_prvdata, uts));
+
+ /* test FFA_ID_GET */
+ ut_assertok(check_endpoint_id(prvdata, uts));
+
+ /* test FFA_FEATURES */
+ ut_assertok(check_features(prvdata, uts));
+
+ /* test core RX/TX buffers */
+ ut_assertok(check_rxtxbuf(prvdata, uts));
+
+ /* test FFA_RXTX_MAP */
+ func_data.data0 = &rxbuf_flag;
+ func_data.data0_size = sizeof(rxbuf_flag);
+
+ rxbuf_flag = 0;
+ ut_assertok(sandbox_ffa_query_core_state(FFA_RXTX_MAP, &func_data));
+ ut_assertok(check_rxbuf_mapped_flag(FFA_RXTX_MAP, rxbuf_flag, uts));
+
+ /* FFA_PARTITION_INFO_GET / FFA_MSG_SEND_DIRECT_REQ */
+ ret = test_partitions_and_comms(svc1_uuid, sdx_prvdata, uts);
+ ut_assertok(ret != CMD_RET_SUCCESS);
+
+ /* test FFA_RX_RELEASE */
+ rxbuf_flag = 1;
+ ut_assertok(sandbox_ffa_query_core_state(FFA_RX_RELEASE, &func_data));
+ ut_assertok(check_rxbuf_release_flag(rxbuf_flag, uts));
+
+ /* FFA_PARTITION_INFO_GET / FFA_MSG_SEND_DIRECT_REQ */
+ ret = test_partitions_and_comms(svc2_uuid, sdx_prvdata, uts);
+ ut_assertok(ret != CMD_RET_SUCCESS);
+
+ /* test FFA_RX_RELEASE */
+ rxbuf_flag = 1;
+ ut_assertok(sandbox_ffa_query_core_state(FFA_RX_RELEASE, &func_data));
+ ut_assertok(check_rxbuf_release_flag(rxbuf_flag, uts));
+
+ /* test FFA_RXTX_UNMAP */
+ ut_assertok(ffa_bus_ops_get()->rxtx_unmap(NULL));
+
+ rxbuf_flag = 1;
+ ut_assertok(sandbox_ffa_query_core_state(FFA_RXTX_UNMAP, &func_data));
+ ut_assertok(check_rxbuf_mapped_flag(FFA_RXTX_UNMAP, rxbuf_flag, uts));
+
+ return CMD_RET_SUCCESS;
+}
+
+DM_TEST(dm_test_ffa_ack, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);
+
+static int dm_test_ffa_nack(struct unit_test_state *uts)
+{
+ struct ffa_prvdata *prvdata = NULL;
+ struct sandbox_ffa_prvdata *sdx_prvdata = NULL;
+ struct ffa_sandbox_data func_data = {0};
+ const char *valid_svc_uuid = SANDBOX_SERVICE1_UUID;
+ const char *unvalid_svc_uuid = SANDBOX_SERVICE3_UUID;
+ const char *unvalid_svc_uuid_str = SANDBOX_SERVICE4_UUID;
+ struct ffa_send_direct_data msg = {0};
+ int ret;
+ u32 count = 0;
+ u16 part_id = 0;
+
+ /* test probing FF-A devices */
+ ut_assertok(ffa_bus_discover(NULL));
+
+ /* get a pointer to the FF-A core and sandbox drivers private data */
+ func_data.data0 = &prvdata;
+ func_data.data0_size = sizeof(prvdata);
+ func_data.data1 = &sdx_prvdata;
+ func_data.data1_size = sizeof(sdx_prvdata);
+
+ ut_assertok(sandbox_ffa_query_core_state(FFA_VERSION, &func_data));
+
+ /* make sure private data pointers are retrieved */
+ ut_assertok(prvdata == 0);
+ ut_assertok(sdx_prvdata == 0);
+
+ /* make sure dev devices created */
+ ut_assertok(check_core_dev(prvdata, uts));
+ ut_assertok(check_sandbox_dev(sdx_prvdata, uts));
+
+ /* query partitions count using invalid arguments */
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, unvalid_svc_uuid, NULL, NULL);
+ ut_assertok(ret != -EINVAL);
+
+ /* query partitions count using an invalid UUID string */
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, unvalid_svc_uuid_str, &count, NULL);
+ ut_assertok(ret != -EINVAL);
+
+ /* query partitions count using an invalid UUID (no matching SP) */
+ count = 0;
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, unvalid_svc_uuid, &count, NULL);
+ ut_assertok(count != 0);
+
+ /* query partitions count using a valid UUID */
+ count = 0;
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, valid_svc_uuid, &count, NULL);
+ /* make sure partitions are detected */
+ ut_assertok(ret != 0);
+ ut_assertok(count != SANDBOX_SP_COUNT_PER_VALID_SERVICE);
+
+ /* send data to an invalid partition */
+ ret = ffa_bus_ops_get()->sync_send_receive(NULL, part_id, &msg, 1);
+ ut_assertok(ret != -EINVAL);
+
+ /* send data to a valid partition */
+ part_id = prvdata->partitions.descs[0].info.id;
+ ret = ffa_bus_ops_get()->sync_send_receive(NULL, part_id, &msg, 1);
+ ut_assertok(ret != 0);
+
+ return CMD_RET_SUCCESS;
+}
+
+DM_TEST(dm_test_ffa_nack, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);
--
2.25.1
@@ -0,0 +1,108 @@
From 5af272d2bb2a7a8c8a4732c8d598dd1713856949 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Tue, 29 Nov 2022 14:48:34 +0000
Subject: [PATCH 08/42] arm_ffa: introduce armffa command Sandbox test
Add Sandbox test for the armffa command
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v4: drop use of helper APIs
v1: introduce armffa command sandbox test
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
MAINTAINERS | 1 +
test/cmd/Makefile | 2 ++
test/cmd/armffa.c | 39 +++++++++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+)
create mode 100644 test/cmd/armffa.c
diff --git a/MAINTAINERS b/MAINTAINERS
index c1d3d4ae1c..a2f60a3b93 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -272,6 +272,7 @@ F: doc/arch/arm64.ffa.rst
F: drivers/firmware/arm-ffa/
F: include/arm_ffa.h
F: include/sandbox_arm_ffa.h
+F: test/cmd/armffa.c
F: test/dm/ffa.c
ARM FREESCALE IMX
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index bc961df3dc..21aa6d740e 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2013 Google, Inc
+# (C) Copyright 2022 ARM Limited
ifdef CONFIG_HUSH_PARSER
obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o
@@ -18,6 +19,7 @@ obj-$(CONFIG_CMD_PINMUX) += pinmux.o
obj-$(CONFIG_CMD_PWM) += pwm.o
ifdef CONFIG_SANDBOX
obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
+obj-$(CONFIG_SANDBOX_FFA) += armffa.o
endif
obj-$(CONFIG_CMD_TEMPERATURE) += temperature.o
obj-$(CONFIG_CMD_WGET) += wget.o
diff --git a/test/cmd/armffa.c b/test/cmd/armffa.c
new file mode 100644
index 0000000000..e04363ba63
--- /dev/null
+++ b/test/cmd/armffa.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for armffa command
+ *
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <common.h>
+#include <dm/test.h>
+#include <sandbox_arm_ffa.h>
+#include <string.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+#define PING_CMD_SIZE 19
+
+/* Basic test of 'armffa' command */
+static int dm_test_armffa_cmd(struct unit_test_state *uts)
+{
+ char ping_cmd[PING_CMD_SIZE] = {0};
+
+ ut_assertok(ffa_bus_discover(NULL));
+
+ /* armffa getpart <UUID> */
+ ut_assertok(run_command("armffa getpart " SANDBOX_SERVICE1_UUID, 0));
+
+ snprintf(ping_cmd, PING_CMD_SIZE, "armffa ping 0x%x", SANDBOX_SP1_ID);
+
+ /* armffa ping <ID> */
+ ut_assertok(run_command(ping_cmd, 0));
+
+ /* armffa devlist */
+ ut_assertok(run_command("armffa devlist", 0));
+
+ return CMD_RET_SUCCESS;
+}
+
+DM_TEST(dm_test_armffa_cmd, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);
--
2.25.1
@@ -0,0 +1,500 @@
From ca1ae0e78ee3476090919459ec5d08187d5eefbc Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Mon, 15 Aug 2022 15:12:49 +0100
Subject: [PATCH 09/42] arm_ffa: efi: introduce FF-A MM communication
Add MM communication support using FF-A transport
This feature allows accessing MM partitions services through
EFI MM communication protocol. MM partitions such as StandAlonneMM
or smm-gateway secure partitions which reside in secure world.
An MM shared buffer and a door bell event are used to exchange
the data.
The data is used by EFI services such as GetVariable()/SetVariable()
and copied from the communication buffer to the MM shared buffer.
The secure partition is notified about availability of data in the
MM shared buffer by an FF-A message (door bell).
On such event, MM SP can read the data and updates the MM shared
buffer with the response data.
The response data is copied back to the communication buffer and
consumed by the EFI subsystem.
MM communication protocol supports FF-A 64-bit direct messaging.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v8:
* isolate the compilation choices between FF-A and OP-TEE
* update partition_info_get() second argument to be an SP count
* pass NULL device pointer to the FF-A bus discovery and operations
v7:
* set the MM door bell event to use 64-bit direct messaging
* issue a compile time error when one of these macros are not found :
FFA_SHARED_MM_BUFFER_SIZE, FFA_SHARED_MM_BUFFER_OFFSET, FFA_SHARED_MM_BUFFER_ADDR
* make mm_sp_svc_uuid static
* replace EINVAL with ENOMEM in ffa_discover_mm_sp_id() when calloc() fails
* improve use of unmap_sysmem() in ffa_mm_communicate()
v6:
* add FF-A runtime discovery at MM communication level
* drop EFI runtime support for FF-A MM communication
* revert the changes in include/mm_communication.h for
efi_mm_communicate_header and smm_variable_access structures
v4:
* use the new FF-A driver interfaces
* discover MM partitions at runtime
* copy FF-A driver private data to EFI runtime section at
ExitBootServices()
* drop use of FFA_ERR_STAT_SUCCESS error code
* replace EFI_BUFFER_TOO_SMALL with EFI_OUT_OF_RESOURCES
in ffa_mm_communicate(). No need for efi_memcpy_runtime() anymore
* revert the error log in mm_communicate() in case of failure
* remove packed attribute from efi_mm_communicate_header and
smm_variable_communicate_header
v2:
* set default values to 0 for FFA_SHARED_MM_BUFFER_SIZE, FFA_SHARED_MM_BUFFER_ADDR and MM_SP_UUID_DATA and add warnings
v1:
* introduce FF-A MM communication
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
include/mm_communication.h | 5 +
lib/efi_loader/Kconfig | 14 +-
lib/efi_loader/efi_variable_tee.c | 294 +++++++++++++++++++++++++++++-
3 files changed, 307 insertions(+), 6 deletions(-)
diff --git a/include/mm_communication.h b/include/mm_communication.h
index e65fbde60d..d409bed777 100644
--- a/include/mm_communication.h
+++ b/include/mm_communication.h
@@ -6,6 +6,8 @@
* Copyright (c) 2017, Intel Corporation. All rights reserved.
* Copyright (C) 2020 Linaro Ltd. <sughosh.ganu@linaro.org>
* Copyright (C) 2020 Linaro Ltd. <ilias.apalodimas@linaro.org>
+ * (C) Copyright 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#ifndef _MM_COMMUNICATION_H_
@@ -13,6 +15,9 @@
#include <part_efi.h>
+/* MM service UUID string (big-endian format). This UUID is common across all MM SPs */
+#define MM_SP_UUID "33d532ed-e699-0942-c09c-a798d9cd722d"
+
/*
* Interface to the pseudo Trusted Application (TA), which provides a
* communication channel with the Standalone MM (Management Mode)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index b498c72206..ca73908481 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -55,13 +55,23 @@ config EFI_VARIABLE_FILE_STORE
stored as file /ubootefi.var on the EFI system partition.
config EFI_MM_COMM_TEE
- bool "UEFI variables storage service via OP-TEE"
- depends on OPTEE
+ bool "UEFI variables storage service via the trusted world"
+ depends on OPTEE || ARM_FFA_TRANSPORT
help
+ Allowing access to the MM SP services (SPs such as StandAlonneMM, smm-gateway).
+ When using the u-boot OP-TEE driver, StandAlonneMM is supported.
+ When using the u-boot FF-A driver any MM SP is supported.
+
If OP-TEE is present and running StandAloneMM, dispatch all UEFI
variable related operations to that. The application will verify,
authenticate and store the variables on an RPMB.
+ When ARM_FFA_TRANSPORT is used, dispatch all UEFI variable related
+ operations to the MM SP running in the secure world.
+ A door bell mechanism is used to notify the SP when there is data in the shared
+ MM buffer. The data is copied by u-boot to the shared buffer before issuing
+ the door bell event.
+
config EFI_VARIABLE_NO_STORE
bool "Don't persist non-volatile UEFI variables"
help
diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c
index dfef18435d..3933a24e8c 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -4,9 +4,12 @@
*
* Copyright (C) 2019 Linaro Ltd. <sughosh.ganu@linaro.org>
* Copyright (C) 2019 Linaro Ltd. <ilias.apalodimas@linaro.org>
+ * Copyright (C) 2022 ARM Limited
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#include <common.h>
+#include <dm.h>
#include <efi.h>
#include <efi_api.h>
#include <efi_loader.h>
@@ -15,6 +18,36 @@
#include <malloc.h>
#include <mm_communication.h>
+#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
+
+#include <arm_ffa.h>
+#include <cpu_func.h>
+#include <mapmem.h>
+
+#ifndef FFA_SHARED_MM_BUFFER_SIZE
+#error "FFA_SHARED_MM_BUFFER_SIZE must be defined in include/configs/<board>.h"
+#define FFA_SHARED_MM_BUFFER_SIZE 0
+#endif
+
+#ifndef FFA_SHARED_MM_BUFFER_OFFSET
+#error "FFA_SHARED_MM_BUFFER_OFFSET must be defined in include/configs/<board>.h"
+#define FFA_SHARED_MM_BUFFER_OFFSET 0
+#endif
+
+#ifndef FFA_SHARED_MM_BUFFER_ADDR
+#error "FFA_SHARED_MM_BUFFER_ADDR must be defined in include/configs/<board>.h"
+#define FFA_SHARED_MM_BUFFER_ADDR 0
+#endif
+
+/* MM return codes */
+#define MM_SUCCESS (0)
+
+static const char *mm_sp_svc_uuid = MM_SP_UUID;
+
+static u16 mm_sp_id;
+
+#endif
+
extern struct efi_var_file __efi_runtime_data *efi_var_buf;
static efi_uintn_t max_buffer_size; /* comm + var + func + data */
static efi_uintn_t max_payload_size; /* func + data */
@@ -24,6 +57,7 @@ struct mm_connection {
u32 session;
};
+#if (IS_ENABLED(CONFIG_OPTEE))
/**
* get_connection() - Retrieve OP-TEE session for a specific UUID.
*
@@ -143,13 +177,248 @@ static efi_status_t optee_mm_communicate(void *comm_buf, ulong dsize)
return ret;
}
+#endif
+
+#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
/**
- * mm_communicate() - Adjust the cmonnucation buffer to StandAlonneMM and send
+ * ffa_notify_mm_sp() - Announce there is data in the shared buffer
+ *
+ * Notifies the MM partition in the trusted world that
+ * data is available in the shared buffer.
+ * This is a blocking call during which trusted world has exclusive access
+ * to the MM shared buffer.
+ *
+ * Return:
+ *
+ * 0 on success
+ */
+static int ffa_notify_mm_sp(void)
+{
+ struct ffa_send_direct_data msg = {0};
+ int ret;
+ int sp_event_ret = -1;
+
+ if (!ffa_bus_ops_get())
+ return -EINVAL;
+
+ msg.data0 = FFA_SHARED_MM_BUFFER_OFFSET; /* x3 */
+
+ ret = ffa_bus_ops_get()->sync_send_receive(NULL, mm_sp_id, &msg, 1);
+ if (ret != 0)
+ return ret;
+
+ sp_event_ret = msg.data0; /* x3 */
+
+ if (sp_event_ret == MM_SUCCESS)
+ return 0;
+
+ /*
+ * Failure to notify the MM SP
+ */
+
+ return -EACCES;
+}
+
+/**
+ * ffa_discover_mm_sp_id() - Query the MM partition ID
+ *
+ * Use the FF-A driver to get the MM partition ID.
+ * If multiple partitions are found, use the first one.
+ * This is a boot time function.
+ *
+ * Return:
+ *
+ * 0 on success
+ */
+static int ffa_discover_mm_sp_id(void)
+{
+ u32 count = 0;
+ int ret;
+ struct ffa_partition_info *parts_info;
+
+ if (!ffa_bus_ops_get())
+ return -EINVAL;
+
+ /*
+ * get from the driver the count of the SPs matching the UUID
+ */
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, mm_sp_svc_uuid, &count, NULL);
+ if (ret != 0) {
+ log_err("EFI: Failure in querying partitions count (error code: %d)\n", ret);
+ return ret;
+ }
+
+ if (!count) {
+ log_info("EFI: No MM partition found\n");
+ return ret;
+ }
+
+ /*
+ * pre-allocate a buffer to be filled by the driver
+ * with ffa_partition_info structs
+ */
+
+ log_info("EFI: Pre-allocating %d partition(s) info structures\n", count);
+
+ parts_info = calloc(count, sizeof(*parts_info));
+ if (!parts_info)
+ return -ENOMEM;
+
+ /*
+ * ask the driver to fill the
+ * buffer with the SPs info
+ */
+ ret = ffa_bus_ops_get()->partition_info_get(NULL, mm_sp_svc_uuid, &count, parts_info);
+ if (ret) {
+ log_err("EFI: Failure in querying partition(s) info (error code: %d)\n", ret);
+ free(parts_info);
+ return ret;
+ }
+
+ /*
+ * MM SPs found , use the first one
+ */
+
+ mm_sp_id = parts_info[0].id;
+
+ log_info("EFI: MM partition ID 0x%x\n", mm_sp_id);
+
+ free(parts_info);
+
+ return 0;
+}
+
+/**
+ * ffa_mm_communicate() - Exchange EFI services data with the MM partition using FF-A
+ * @comm_buf: locally allocated communication buffer used for rx/tx
+ * @dsize: communication buffer size
+ *
+ * Issues a door bell event to notify the MM partition (SP) running in OP-TEE
+ * that there is data to read from the shared buffer.
+ * Communication with the MM SP is performed using FF-A transport.
+ * On the event, MM SP can read the data from the buffer and
+ * update the MM shared buffer with response data.
+ * The response data is copied back to the communication buffer.
+ *
+ * Return:
+ *
+ * EFI status code
+ */
+static efi_status_t ffa_mm_communicate(void *comm_buf, ulong comm_buf_size)
+{
+ ulong tx_data_size;
+ int ffa_ret;
+ efi_status_t efi_ret;
+ struct efi_mm_communicate_header *mm_hdr;
+ void *virt_shared_buf;
+
+ if (!comm_buf)
+ return EFI_INVALID_PARAMETER;
+
+ /* Discover MM partition ID at boot time */
+ if (!mm_sp_id && ffa_discover_mm_sp_id() != 0) {
+ log_err("EFI: Failure to discover MM partition ID at boot time\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
+ tx_data_size = mm_hdr->message_len + sizeof(efi_guid_t) + sizeof(size_t);
+
+ if (comm_buf_size != tx_data_size || tx_data_size > FFA_SHARED_MM_BUFFER_SIZE)
+ return EFI_INVALID_PARAMETER;
+
+ /* Copy the data to the shared buffer */
+
+ virt_shared_buf = (void *)map_sysmem((phys_addr_t)FFA_SHARED_MM_BUFFER_ADDR, 0);
+ memcpy(virt_shared_buf, comm_buf, tx_data_size);
+
+ /*
+ * The secure world might have cache disabled for
+ * the device region used for shared buffer (which is the case for Optee).
+ * In this case, the secure world reads the data from DRAM.
+ * Let's flush the cache so the DRAM is updated with the latest data.
+ */
+ #ifdef CONFIG_ARM64
+ invalidate_dcache_all();
+ #endif
+
+ /* Announce there is data in the shared buffer */
+
+ ffa_ret = ffa_notify_mm_sp();
+
+ switch (ffa_ret) {
+ case 0:
+ {
+ ulong rx_data_size;
+ /* Copy the MM SP response from the shared buffer to the communication buffer */
+ rx_data_size = ((struct efi_mm_communicate_header *)virt_shared_buf)->message_len +
+ sizeof(efi_guid_t) +
+ sizeof(size_t);
+
+ if (rx_data_size > comm_buf_size) {
+ efi_ret = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ memcpy(comm_buf, virt_shared_buf, rx_data_size);
+ efi_ret = EFI_SUCCESS;
+ break;
+ }
+ case -EINVAL:
+ efi_ret = EFI_DEVICE_ERROR;
+ break;
+ case -EPERM:
+ efi_ret = EFI_INVALID_PARAMETER;
+ break;
+ case -EACCES:
+ efi_ret = EFI_ACCESS_DENIED;
+ break;
+ case -EBUSY:
+ efi_ret = EFI_OUT_OF_RESOURCES;
+ break;
+ default:
+ efi_ret = EFI_ACCESS_DENIED;
+ }
+
+ unmap_sysmem(virt_shared_buf);
+ return efi_ret;
+}
+#endif
+
+/**
+ * select_ffa_mm_comms() - checks FF-A support availability
+ *
+ * Making sure FF-A is compiled in. If that's the case try to discover
+ * the FF-A bus.
+ *
+ * Return:
+ *
+ * 0: FF-A ready for use. Otherwise, failure
+ */
+static efi_status_t select_ffa_mm_comms(void)
+{
+ efi_status_t ret = EFI_UNSUPPORTED;
+#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
+ ret = ffa_bus_discover(NULL);
+ if (ret)
+ ret = EFI_NOT_READY;
+#endif
+ return ret;
+}
+
+/**
+ * mm_communicate() - Adjust the communication buffer to the MM SP and send
* it to OP-TEE
*
- * @comm_buf: locally allocted communcation buffer
+ * @comm_buf: locally allocated communication buffer
* @dsize: buffer size
+ *
+ * The SP (also called partition) can be any MM SP such as StandAlonneMM or smm-gateway.
+ * The comm_buf format is the same for both partitions.
+ * When using the u-boot OP-TEE driver, StandAlonneMM is supported.
+ * When using the u-boot FF-A driver, any MM SP is supported.
+ *
* Return: status code
*/
static efi_status_t mm_communicate(u8 *comm_buf, efi_uintn_t dsize)
@@ -162,7 +431,17 @@ static efi_status_t mm_communicate(u8 *comm_buf, efi_uintn_t dsize)
mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
var_hdr = (struct smm_variable_communicate_header *)mm_hdr->data;
- ret = optee_mm_communicate(comm_buf, dsize);
+ ret = select_ffa_mm_comms();
+ if (ret != EFI_SUCCESS) {
+#if (IS_ENABLED(CONFIG_OPTEE))
+ ret = optee_mm_communicate(comm_buf, dsize);
+#endif
+ } else {
+#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
+ ret = ffa_mm_communicate(comm_buf, dsize);
+#endif
+ }
+
if (ret != EFI_SUCCESS) {
log_err("%s failed!\n", __func__);
return ret;
@@ -258,6 +537,13 @@ efi_status_t EFIAPI get_max_payload(efi_uintn_t *size)
goto out;
}
*size = var_payload->size;
+
+ #if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
+ if (*size > FFA_SHARED_MM_BUFFER_SIZE)
+ *size = FFA_SHARED_MM_BUFFER_SIZE - MM_COMMUNICATE_HEADER_SIZE -
+ MM_VARIABLE_COMMUNICATE_SIZE;
+ #endif
+
/*
* There seems to be a bug in EDK2 miscalculating the boundaries and
* size checks, so deduct 2 more bytes to fulfill this requirement. Fix
@@ -697,7 +983,7 @@ void efi_variables_boot_exit_notify(void)
ret = EFI_NOT_FOUND;
if (ret != EFI_SUCCESS)
- log_err("Unable to notify StMM for ExitBootServices\n");
+ log_err("Unable to notify the MM partition for ExitBootServices\n");
free(comm_buf);
/*
--
2.25.1
@@ -0,0 +1,86 @@
From a595dfd91d3e226eaa39e324673871c73ae0aa29 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Fri, 23 Sep 2022 15:17:21 +0100
Subject: [PATCH 10/42] arm_ffa: efi: corstone1000: enable MM communication
turn on EFI MM communication
On corstone1000 platform MM communication between u-boot
and the secure world (Optee) is done using the FF-A bus.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20221122131751.22747-1-abdellatif.elkhlifi@arm.com/]
Changelog:
===============
v8:
* drop OP-TEE configs from Corstone-1000 defconfig
v7:
* improve the definition of FFA_SHARED_MM_BUFFER_ADDR and
FFA_SHARED_MM_BUFFER_OFFSET
* update FFA_SHARED_MM_BUFFER_ADDR value
v6:
* corstone-1000: enable optee driver
* corstone-1000: remove CONFIG_ARM_FFA_EFI_RUNTIME_MODE from the defconfig
v4:
* corstone-1000: turn on EFI MM communication
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
configs/corstone1000_defconfig | 2 ++
include/configs/corstone1000.h | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index dddfa27507..d1dc06c86c 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -52,3 +52,5 @@ CONFIG_DM_SERIAL=y
CONFIG_USB=y
CONFIG_USB_ISP1760=y
CONFIG_ERRNO_STR=y
+CONFIG_EFI_MM_COMM_TEE=y
+CONFIG_ARM_FFA_TRANSPORT=y
diff --git a/include/configs/corstone1000.h b/include/configs/corstone1000.h
index 8e0230c135..b6226fa12a 100644
--- a/include/configs/corstone1000.h
+++ b/include/configs/corstone1000.h
@@ -14,6 +14,15 @@
#include <linux/sizes.h>
+#define FFA_SHARED_MM_BUFFER_SIZE SZ_4K /* 4 KB */
+
+/*
+ * shared buffer physical address used for communication between
+ * u-boot and the MM SP
+ */
+#define FFA_SHARED_MM_BUFFER_ADDR 0x02000000UL
+#define FFA_SHARED_MM_BUFFER_OFFSET 0
+
#define V2M_BASE 0x80000000
#define CONFIG_PL011_CLOCK 50000000
@@ -22,6 +31,7 @@
#define PHYS_SDRAM_1 (V2M_BASE)
#define PHYS_SDRAM_1_SIZE 0x80000000
+#define CFG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define BOOT_TARGET_DEVICES(func) \
--
2.25.1
@@ -0,0 +1,366 @@
From b9c44c396f9ad9588184272cdc5ed98e19e82c0a Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Tue, 29 Nov 2022 15:11:27 +0000
Subject: [PATCH 11/42] efi: corstone1000: introduce EFI capsule update
This commit provides capsule update feature for Corstone1000.
This feature is available before and after ExitBootServices().
A platform specific capsule buffer is allocated. This buffer
is physically contiguous and allocated at the start of the DDR
memory after u-boot relocation to the end of DDR.
The capsule buffer is shared between u-boot and the secure world.
On UpdateCapsule() , capsule data is copied to the buffer
and a buffer ready event is generated using FF-A transport.
On ExitBootServices() a kernel started event is sent to the
SE Proxy FW update service. This event is generated on each boot.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
board/armltd/corstone1000/corstone1000.c | 4 +
configs/corstone1000_defconfig | 3 +
include/configs/corstone1000.h | 18 ++++
include/efi_loader.h | 4 +-
lib/efi_loader/efi_boottime.c | 36 +++++++
lib/efi_loader/efi_capsule.c | 124 ++++++++++++++++++++++-
lib/efi_loader/efi_setup.c | 15 +++
7 files changed, 200 insertions(+), 4 deletions(-)
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index 4f4b96a095..76816f8f4e 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -66,6 +66,10 @@ static struct mm_region corstone1000_mem_map[] = {
struct mm_region *mem_map = corstone1000_mem_map;
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+}
+
int board_init(void)
{
return 0;
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index d1dc06c86c..06eac3e041 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -54,3 +54,6 @@ CONFIG_USB_ISP1760=y
CONFIG_ERRNO_STR=y
CONFIG_EFI_MM_COMM_TEE=y
CONFIG_ARM_FFA_TRANSPORT=y
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
diff --git a/include/configs/corstone1000.h b/include/configs/corstone1000.h
index b6226fa12a..cd30499e3c 100644
--- a/include/configs/corstone1000.h
+++ b/include/configs/corstone1000.h
@@ -14,6 +14,24 @@
#include <linux/sizes.h>
+/* The SE Proxy partition ID*/
+#define CORSTONE1000_SEPROXY_PART_ID (0x8002)
+
+/* Update service ID provided by the SE Proxy secure partition*/
+#define CORSTONE1000_SEPROXY_UPDATE_SVC_ID (0x4)
+
+/* Notification events used with SE Proxy update service */
+#define CORSTONE1000_BUFFER_READY_EVT (0x1)
+#define CORSTONE1000_KERNEL_STARTED_EVT (0x2)
+
+/* Size in 4KB pages of the EFI capsule buffer */
+#define CORSTONE1000_CAPSULE_BUFFER_SIZE (8192) /* 32 MB */
+
+/* Capsule GUID */
+#define EFI_CORSTONE1000_CAPSULE_ID_GUID \
+ EFI_GUID(0x3a770ddc, 0x409b, 0x48b2, 0x81, 0x41, \
+ 0x93, 0xb7, 0xc6, 0x0b, 0x20, 0x9e)
+
#define FFA_SHARED_MM_BUFFER_SIZE SZ_4K /* 4 KB */
/*
diff --git a/include/efi_loader.h b/include/efi_loader.h
index f9e427f090..26981141c2 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -1032,11 +1032,11 @@ extern const struct efi_firmware_management_protocol efi_fmp_fit;
extern const struct efi_firmware_management_protocol efi_fmp_raw;
/* Capsule update */
-efi_status_t EFIAPI efi_update_capsule(
+efi_status_t __efi_runtime EFIAPI efi_update_capsule(
struct efi_capsule_header **capsule_header_array,
efi_uintn_t capsule_count,
u64 scatter_gather_list);
-efi_status_t EFIAPI efi_query_capsule_caps(
+efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
struct efi_capsule_header **capsule_header_array,
efi_uintn_t capsule_count,
u64 *maximum_capsule_size,
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index fea4eb7a34..faab74474d 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2103,6 +2103,33 @@ static void efi_exit_caches(void)
#endif
}
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+/**
+ * efi_corstone1000_kernel_started_event - notifies SE Proxy FW update service
+ *
+ * This function notifies the SE Proxy update service that the kernel has already started
+ *
+ * Return:
+ *
+ * 0: on success, otherwise failure
+ */
+static int efi_corstone1000_kernel_started_event(void)
+{
+ struct ffa_send_direct_data msg = {0};
+
+ log_debug("[%s]\n", __func__);
+
+ /*
+ * setting the kernel started event arguments
+ */
+ msg.data0 = CORSTONE1000_SEPROXY_UPDATE_SVC_ID; /* x3 */
+ msg.data2 = CORSTONE1000_KERNEL_STARTED_EVT; /* x5 */
+
+ return ffa_bus_ops_get()->sync_send_receive(CORSTONE1000_SEPROXY_PART_ID, &msg, 0);
+}
+
+#endif
+
/**
* efi_exit_boot_services() - stop all boot services
* @image_handle: handle of the loaded image
@@ -2209,6 +2236,15 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
/* Recalculate CRC32 */
efi_update_table_header_crc32(&systab.hdr);
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+ /* Notifying SE Proxy FW update service */
+ ffa_ret = efi_corstone1000_kernel_started_event();
+ if (ffa_ret)
+ debug("[efi_boottime][ERROR]: Failure to notify SE Proxy FW update service\n");
+ else
+ debug("[efi_boottime][INFO]: SE Proxy FW update service notified\n");
+#endif
+
/* Give the payload some time to boot */
efi_set_watchdog(0);
schedule();
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 0997cd248f..9e8ddaac7f 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -26,6 +26,14 @@
#include <crypto/pkcs7_parser.h>
#include <linux/err.h>
+#ifdef CONFIG_TARGET_CORSTONE1000
+#include <arm_ffa.h>
+#include <cpu_func.h>
+
+void *__efi_runtime_data corstone1000_capsule_buf; /* capsule shared buffer virtual address */
+efi_guid_t corstone1000_capsule_guid = EFI_CORSTONE1000_CAPSULE_ID_GUID;
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
@@ -696,6 +704,78 @@ static efi_status_t efi_capsule_update_firmware(
}
#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+
+/**
+ * efi_corstone1000_alloc_capsule_shared_buf - allocate capsule shared buffer
+ * @capsule_image_size: The capsule data (header + payload)
+ *
+ * This function allocates the physically contiguous buffer shared between u-boot
+ * and the secure world. On UpdateCapsule() capsule data is copied to the buffer
+ * and a door bell event is generated.
+ * The buffer is allocated at the start of the DDR memory after u-boot has been relocated
+ * to the end of DDR.
+ *
+ * Return:
+ *
+ * 0: on success, otherwise failure
+ */
+efi_status_t efi_corstone1000_alloc_capsule_shared_buf(void)
+{
+ efi_status_t efi_ret;
+ u64 ram_base = CFG_SYS_SDRAM_BASE;
+
+ log_debug("[%s]\n", __func__);
+
+ efi_ret = efi_allocate_pages(EFI_ALLOCATE_ADDRESS,
+ EFI_RUNTIME_SERVICES_DATA,
+ CORSTONE1000_CAPSULE_BUFFER_SIZE,
+ &ram_base);
+
+ if (efi_ret != EFI_SUCCESS) {
+ corstone1000_capsule_buf = NULL;
+ log_err("EFI: Corstone1000: Allocating capsule shared buffer error (%d)\n"
+ , (int)efi_ret);
+ return efi_ret;
+ }
+
+ log_info("EFI: Corstone1000: Capsule shared buffer at 0x%x , size %d pages\n"
+ , (unsigned int)ram_base,
+ CORSTONE1000_CAPSULE_BUFFER_SIZE);
+
+ corstone1000_capsule_buf = (void *)map_sysmem((phys_addr_t)ram_base, 0);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_corstone1000_buffer_ready_event - issue door bell event
+ * @capsule_image_size: The capsule data (header + payload)
+ *
+ * This function notifies the SE Proxy update service that capsule data is available
+ * in the capsule shared buffer.
+ *
+ * Return:
+ *
+ * 0: on success, otherwise failure
+ */
+static int __efi_runtime efi_corstone1000_buffer_ready_event(u32 capsule_image_size)
+{
+ struct ffa_send_direct_data msg = {0};
+
+ log_debug("[%s]\n", __func__);
+
+ /*
+ * setting the buffer ready event arguments
+ */
+ msg.data0 = CORSTONE1000_SEPROXY_UPDATE_SVC_ID; /* x3 */
+ msg.data1 = capsule_image_size; /* x4 */
+ msg.data2 = CORSTONE1000_BUFFER_READY_EVT; /* x5 */
+
+ return ffa_bus_ops_get()->sync_send_receive(NULL, CORSTONE1000_SEPROXY_PART_ID, &msg, 0);
+}
+#endif
+
/**
* efi_update_capsule() - process information from operating system
* @capsule_header_array: Array of virtual address pointers
@@ -709,7 +789,7 @@ static efi_status_t efi_capsule_update_firmware(
*
* Return: status code
*/
-efi_status_t EFIAPI efi_update_capsule(
+efi_status_t __efi_runtime EFIAPI efi_update_capsule(
struct efi_capsule_header **capsule_header_array,
efi_uintn_t capsule_count,
u64 scatter_gather_list)
@@ -726,6 +806,13 @@ efi_status_t EFIAPI efi_update_capsule(
goto out;
}
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+ if (capsule_count != 1 || !corstone1000_capsule_buf) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+#endif
+
ret = EFI_SUCCESS;
for (i = 0, capsule = *capsule_header_array; i < capsule_count;
i++, capsule = *(++capsule_header_array)) {
@@ -738,6 +825,39 @@ efi_status_t EFIAPI efi_update_capsule(
log_debug("Capsule[%d] (guid:%pUs)\n",
i, &capsule->capsule_guid);
+
+#if CONFIG_IS_ENABLED(TARGET_CORSTONE1000)
+ if (guidcmp(&corstone1000_capsule_guid, &capsule->capsule_guid)) {
+ ret = EFI_INVALID_PARAMETER;
+ log_err("Corstone1000: Invalid capsule GUID\n");
+ goto out;
+ }
+
+ if (efi_size_in_pages(capsule->capsule_image_size) >
+ CORSTONE1000_CAPSULE_BUFFER_SIZE) {
+ log_err("Corstone1000: Capsule data size exceeds the shared buffer size\n");
+ ret = EFI_BUFFER_TOO_SMALL;
+ goto out;
+ }
+
+ /* copy the data to the contiguous buffer */
+ efi_memcpy_runtime(corstone1000_capsule_buf, capsule, capsule->capsule_image_size);
+
+ /* invalidate the data cache */
+ invalidate_dcache_all();
+
+ /* issue buffer ready event */
+ ret = efi_corstone1000_buffer_ready_event(capsule->capsule_image_size);
+ if (ret) {
+ log_err("EFI: Corstone1000: Buffer ready event error (%d)\n", (int)ret);
+ ret = EFI_DEVICE_ERROR;
+ } else {
+ ret = EFI_SUCCESS;
+ }
+
+ goto out;
+#endif
+
if (!guidcmp(&capsule->capsule_guid,
&efi_guid_firmware_management_capsule_id)) {
ret = efi_capsule_update_firmware(capsule);
@@ -776,7 +896,7 @@ out:
*
* Return: status code
*/
-efi_status_t EFIAPI efi_query_capsule_caps(
+efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
struct efi_capsule_header **capsule_header_array,
efi_uintn_t capsule_count,
u64 *maximum_capsule_size,
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 5437641135..1ad2fa52d7 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -16,6 +16,13 @@
efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+/**
+ * efi_corstone1000_alloc_capsule_shared_buf - allocate capsule shared buffer
+ */
+extern efi_status_t efi_corstone1000_alloc_capsule_shared_buf(void);
+#endif
+
/*
* Allow unaligned memory access.
*
@@ -128,6 +135,14 @@ static efi_status_t efi_init_capsule(void)
{
efi_status_t ret = EFI_SUCCESS;
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+ ret = efi_corstone1000_alloc_capsule_shared_buf();
+ if (ret != EFI_SUCCESS) {
+ printf("EFI: Corstone-1000: cannot allocate caspsule shared buffer\n");
+ return ret;
+ }
+#endif
+
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_UPDATE)) {
ret = efi_set_variable_int(u"CapsuleMax",
&efi_guid_capsule_report,
--
2.25.1
@@ -0,0 +1,31 @@
From ac738fa33edec9ff712dee6d10491cb2eb7cfe3a Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Fri, 4 Mar 2022 15:56:09 +0000
Subject: [PATCH 12/42] arm: corstone1000: fix unrecognized filesystem type
Some usb sticks are not recognized by usb, just add a
delay before checking status.
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
common/usb_storage.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/common/usb_storage.c b/common/usb_storage.c
index ac64275773..1d2680c3cd 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -785,6 +785,9 @@ static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us)
st:
retry = 0;
again:
+ if (srb->cmd[0] == SCSI_TST_U_RDY)
+ mdelay(100);
+
debug("STATUS phase\n");
result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
&actlen, USB_CNTL_TIMEOUT*5);
--
2.25.1
@@ -0,0 +1,74 @@
From baa961b6050508710e1c6b572f2e93ac5c488201 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 10 Dec 2021 20:03:35 +0000
Subject: [PATCH 13/42] efi_capsule: corstone1000: pass interface id and buffer
event id using register w4
Initially the interface/event IDs are passed to the SP using register
w3 and w5.
Now the SE proxy SP requires this arguments to be in register w4.
This change is to pass interface ID(31:16) and event ID(15:0)
to SE proxy SP to trigger an event to secure enclave about
firmware update.
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
include/configs/corstone1000.h | 6 ++++++
lib/efi_loader/efi_capsule.c | 11 +++++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/configs/corstone1000.h b/include/configs/corstone1000.h
index cd30499e3c..e4c7bcb96f 100644
--- a/include/configs/corstone1000.h
+++ b/include/configs/corstone1000.h
@@ -24,6 +24,12 @@
#define CORSTONE1000_BUFFER_READY_EVT (0x1)
#define CORSTONE1000_KERNEL_STARTED_EVT (0x2)
+#define PREP_SEPROXY_SVC_ID_MASK GENMASK(31, 16)
+#define PREP_SEPROXY_SVC_ID(x) (FIELD_PREP(PREP_SEPROXY_SVC_ID_MASK, (x)))
+
+#define PREP_SEPROXY_EVT_MASK GENMASK(15, 0)
+#define PREP_SEPROXY_EVT(x) (FIELD_PREP(PREP_SEPROXY_EVT_MASK, (x)))
+
/* Size in 4KB pages of the EFI capsule buffer */
#define CORSTONE1000_CAPSULE_BUFFER_SIZE (8192) /* 32 MB */
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 9e8ddaac7f..bd4cc8d272 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -29,6 +29,8 @@
#ifdef CONFIG_TARGET_CORSTONE1000
#include <arm_ffa.h>
#include <cpu_func.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
void *__efi_runtime_data corstone1000_capsule_buf; /* capsule shared buffer virtual address */
efi_guid_t corstone1000_capsule_guid = EFI_CORSTONE1000_CAPSULE_ID_GUID;
@@ -766,11 +768,12 @@ static int __efi_runtime efi_corstone1000_buffer_ready_event(u32 capsule_image_s
log_debug("[%s]\n", __func__);
/*
- * setting the buffer ready event arguments
+ * setting the buffer ready event arguments in register w4:
+ * - capsule update interface ID (31:16)
+ * - the buffer ready event ID (15:0)
*/
- msg.data0 = CORSTONE1000_SEPROXY_UPDATE_SVC_ID; /* x3 */
- msg.data1 = capsule_image_size; /* x4 */
- msg.data2 = CORSTONE1000_BUFFER_READY_EVT; /* x5 */
+ msg.data1 = PREP_SEPROXY_SVC_ID(CORSTONE1000_SEPROXY_UPDATE_SVC_ID) |
+ PREP_SEPROXY_EVT(CORSTONE1000_BUFFER_READY_EVT); /* w4 */
return ffa_bus_ops_get()->sync_send_receive(NULL, CORSTONE1000_SEPROXY_PART_ID, &msg, 0);
}
--
2.25.1
@@ -0,0 +1,58 @@
From d761d59dd251ae93980f659d253576fc872f2c5f Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 10 Dec 2021 20:10:41 +0000
Subject: [PATCH 14/42] efi_boottime: corstone1000: pass interface id and
kernel event id using register w4
Initially the interface/event IDs are passed to the SP using register
w3 and w5.
Now the SE proxy SP requires this arguments to be in register w4.
This change is to pass interface ID(31:16) and kernel started
event ID(15:0) to SE proxy SP to trigger an event to
secure enclave just before ExitbootService().
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
lib/efi_loader/efi_boottime.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index faab74474d..36a0be7ba1 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -30,6 +30,11 @@
#include <arm_ffa.h>
#endif
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
/* Task priority level */
@@ -2120,10 +2125,12 @@ static int efi_corstone1000_kernel_started_event(void)
log_debug("[%s]\n", __func__);
/*
- * setting the kernel started event arguments
+ * setting the kernel started event arguments:
+ * setting capsule update interface ID(31:16)
+ * the kernel started event ID(15:0)
*/
- msg.data0 = CORSTONE1000_SEPROXY_UPDATE_SVC_ID; /* x3 */
- msg.data2 = CORSTONE1000_KERNEL_STARTED_EVT; /* x5 */
+ msg.data1 = PREP_SEPROXY_SVC_ID(CORSTONE1000_SEPROXY_UPDATE_SVC_ID) |
+ PREP_SEPROXY_EVT(CORSTONE1000_KERNEL_STARTED_EVT); /* w4 */
return ffa_bus_ops_get()->sync_send_receive(CORSTONE1000_SEPROXY_PART_ID, &msg, 0);
}
--
2.25.1
@@ -0,0 +1,53 @@
From 5e09d349ec8af6585bce777acbfd2d218fc2e8d4 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Sat, 11 Dec 2021 13:23:55 +0000
Subject: [PATCH 15/42] efi_loader: corstone1000: remove guid check from
corstone1000 config option
Use generic fmp guid and no separte check is required for
CORSTONE1000 target.
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
lib/efi_loader/efi_capsule.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index bd4cc8d272..ef7b358ddb 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -830,12 +830,6 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule(
i, &capsule->capsule_guid);
#if CONFIG_IS_ENABLED(TARGET_CORSTONE1000)
- if (guidcmp(&corstone1000_capsule_guid, &capsule->capsule_guid)) {
- ret = EFI_INVALID_PARAMETER;
- log_err("Corstone1000: Invalid capsule GUID\n");
- goto out;
- }
-
if (efi_size_in_pages(capsule->capsule_image_size) >
CORSTONE1000_CAPSULE_BUFFER_SIZE) {
log_err("Corstone1000: Capsule data size exceeds the shared buffer size\n");
@@ -861,15 +855,7 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule(
goto out;
#endif
- if (!guidcmp(&capsule->capsule_guid,
- &efi_guid_firmware_management_capsule_id)) {
- ret = efi_capsule_update_firmware(capsule);
- } else {
- log_err("Unsupported capsule type: %pUs\n",
- &capsule->capsule_guid);
- ret = EFI_UNSUPPORTED;
- }
-
+ ret = efi_capsule_update_firmware(capsule);
if (ret != EFI_SUCCESS)
goto out;
}
--
2.25.1
@@ -0,0 +1,37 @@
From e3ccad1cf9e905ec15ff772dcf53972fafcf54ee Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 17 Dec 2021 19:49:02 +0000
Subject: [PATCH 16/42] efi_loader: populate ESRT table if EFI_ESRT config
option is set
This change is to call efi_esrt_populate function if CONFIG_EFI_ESRT
is set. This will populte esrt table with firmware image info
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
lib/efi_loader/efi_capsule.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index ef7b358ddb..8eb8fc406a 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -852,6 +852,13 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule(
ret = EFI_SUCCESS;
}
+ if (IS_ENABLED(CONFIG_EFI_ESRT)) {
+ /* Rebuild the ESRT to reflect any updated FW images. */
+ ret = efi_esrt_populate();
+ if (ret != EFI_SUCCESS)
+ log_warning("EFI Capsule: failed to update ESRT\n");
+ }
+
goto out;
#endif
--
2.25.1
@@ -0,0 +1,123 @@
From d8f79ab37bae283599e40018055ff9d5648fb647 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 17 Dec 2021 19:50:25 +0000
Subject: [PATCH 17/42] efi_firmware: add get_image_info for corstone1000
This change is to populate get_image_info which eventually
will be populated in ESRT table
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
lib/efi_loader/efi_firmware.c | 72 ++++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 93e2b01c07..0a38a96351 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -18,11 +18,69 @@
#define FMP_PAYLOAD_HDR_SIGNATURE SIGNATURE_32('M', 'S', 'S', '1')
+#if CONFIG_IS_ENABLED(TARGET_CORSTONE1000)
+#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \
+ EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \
+ 0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f)
+
+ const efi_guid_t efi_firmware_image_type_uboot_raw =
+ EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID;
+
+static efi_status_t efi_corstone1000_img_info_get (
+ efi_uintn_t *image_info_size,
+ struct efi_firmware_image_descriptor *image_info,
+ u32 *descriptor_version,
+ u8 *descriptor_count,
+ efi_uintn_t *descriptor_size,
+ u32 *package_version,
+ u16 **package_version_name,
+ const efi_guid_t *image_type)
+{
+ int i = 0;
+
+ *image_info_size = sizeof(*image_info);
+ *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
+ *descriptor_count = 1;//dfu_num;
+ *descriptor_size = sizeof(*image_info);
+ if (package_version)
+ *package_version = 0xffffffff; /* not supported */
+ if(package_version_name)
+ *package_version_name = NULL; /* not supported */
+
+ if(image_info == NULL) {
+ log_warning("image_info is null\n");
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ image_info[i].image_index = i;
+ image_info[i].image_type_id = *image_type;
+ image_info[i].image_id = 0;
+ image_info[i].image_id_name = "wic";
+ image_info[i].version = 1;
+ image_info[i].version_name = NULL;
+ image_info[i].size = 0x1000;
+ image_info[i].attributes_supported = IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
+ image_info[i].attributes_setting = IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+ /* Check if the capsule authentication is enabled */
+ if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE))
+ image_info[0].attributes_setting |=
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
+ image_info[i].lowest_supported_image_version = 0;
+ image_info[i].last_attempt_version = 0;
+ image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
+ image_info[i].hardware_instance = 1;
+ image_info[i].dependencies = NULL;
+
+ return EFI_SUCCESS;
+}
+#endif
+
/**
* struct fmp_payload_header - EDK2 header for the FMP payload
*
* This structure describes the header which is preprended to the
- * FMP payload by the edk2 capsule generation scripts.
+ * FMP payload by the edk1 capsule generation scripts.
*
* @signature: Header signature used to identify the header
* @header_size: Size of the structure
@@ -286,10 +344,18 @@ efi_status_t EFIAPI efi_firmware_get_image_info(
!descriptor_size || !package_version || !package_version_name))
return EFI_EXIT(EFI_INVALID_PARAMETER);
+#if CONFIG_IS_ENABLED(TARGET_CORSTONE1000)
+ ret = efi_corstone1000_img_info_get(image_info_size, image_info,
+ descriptor_version, descriptor_count,
+ descriptor_size,
+ package_version, package_version_name,
+ &efi_firmware_image_type_uboot_raw);
+#else
ret = efi_fill_image_desc_array(image_info_size, image_info,
descriptor_version, descriptor_count,
descriptor_size, package_version,
package_version_name);
+#endif
return EFI_EXIT(ret);
}
@@ -415,6 +481,10 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
}
}
+#if CONFIG_IS_ENABLED(TARGET_CORSTONE1000)
+ return EFI_EXIT(EFI_SUCCESS);
+#endif
+
if (dfu_write_by_alt(image_index - 1, (void *)image, image_size,
NULL, NULL))
return EFI_EXIT(EFI_DEVICE_ERROR);
--
2.25.1
@@ -0,0 +1,183 @@
From a6fee840a411a6a7b6c276d0a7b1d5445039e6c2 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Mon, 15 Aug 2022 15:46:18 +0100
Subject: [PATCH 18/42] efi_loader: send bootcomplete message to secure enclave
On corstone1000 platform, Secure Enclave will be expecting
an event from uboot when it performs capsule update. Previously,
an event is sent at exitbootservice level. This will create a problem
when user wants to interrupt at UEFI shell, hence, it is required
to send an uboot efi initialized event at efi sub-system initialization
stage.
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
---
include/configs/corstone1000.h | 2 +-
lib/efi_loader/efi_boottime.c | 43 ----------------------------------
lib/efi_loader/efi_firmware.c | 2 +-
lib/efi_loader/efi_setup.c | 39 ++++++++++++++++++++++++++++++
4 files changed, 41 insertions(+), 45 deletions(-)
diff --git a/include/configs/corstone1000.h b/include/configs/corstone1000.h
index e4c7bcb96f..be13b98d48 100644
--- a/include/configs/corstone1000.h
+++ b/include/configs/corstone1000.h
@@ -22,7 +22,7 @@
/* Notification events used with SE Proxy update service */
#define CORSTONE1000_BUFFER_READY_EVT (0x1)
-#define CORSTONE1000_KERNEL_STARTED_EVT (0x2)
+#define CORSTONE1000_UBOOT_EFI_STARTED_EVT (0x2)
#define PREP_SEPROXY_SVC_ID_MASK GENMASK(31, 16)
#define PREP_SEPROXY_SVC_ID(x) (FIELD_PREP(PREP_SEPROXY_SVC_ID_MASK, (x)))
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 36a0be7ba1..fea4eb7a34 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -30,11 +30,6 @@
#include <arm_ffa.h>
#endif
-#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
-#include <linux/bitfield.h>
-#include <linux/bitops.h>
-#endif
-
DECLARE_GLOBAL_DATA_PTR;
/* Task priority level */
@@ -2108,35 +2103,6 @@ static void efi_exit_caches(void)
#endif
}
-#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
-/**
- * efi_corstone1000_kernel_started_event - notifies SE Proxy FW update service
- *
- * This function notifies the SE Proxy update service that the kernel has already started
- *
- * Return:
- *
- * 0: on success, otherwise failure
- */
-static int efi_corstone1000_kernel_started_event(void)
-{
- struct ffa_send_direct_data msg = {0};
-
- log_debug("[%s]\n", __func__);
-
- /*
- * setting the kernel started event arguments:
- * setting capsule update interface ID(31:16)
- * the kernel started event ID(15:0)
- */
- msg.data1 = PREP_SEPROXY_SVC_ID(CORSTONE1000_SEPROXY_UPDATE_SVC_ID) |
- PREP_SEPROXY_EVT(CORSTONE1000_KERNEL_STARTED_EVT); /* w4 */
-
- return ffa_bus_ops_get()->sync_send_receive(CORSTONE1000_SEPROXY_PART_ID, &msg, 0);
-}
-
-#endif
-
/**
* efi_exit_boot_services() - stop all boot services
* @image_handle: handle of the loaded image
@@ -2243,15 +2209,6 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
/* Recalculate CRC32 */
efi_update_table_header_crc32(&systab.hdr);
-#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
- /* Notifying SE Proxy FW update service */
- ffa_ret = efi_corstone1000_kernel_started_event();
- if (ffa_ret)
- debug("[efi_boottime][ERROR]: Failure to notify SE Proxy FW update service\n");
- else
- debug("[efi_boottime][INFO]: SE Proxy FW update service notified\n");
-#endif
-
/* Give the payload some time to boot */
efi_set_watchdog(0);
schedule();
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 0a38a96351..70568f2290 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -48,7 +48,7 @@ static efi_status_t efi_corstone1000_img_info_get (
*package_version_name = NULL; /* not supported */
if(image_info == NULL) {
- log_warning("image_info is null\n");
+ log_info("image_info is null\n");
return EFI_BUFFER_TOO_SMALL;
}
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 1ad2fa52d7..89f988b09c 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -17,6 +17,9 @@
efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <arm_ffa.h>
/**
* efi_corstone1000_alloc_capsule_shared_buf - allocate capsule shared buffer
*/
@@ -126,6 +129,34 @@ static efi_status_t efi_init_secure_boot(void)
}
#endif /* CONFIG_EFI_SECURE_BOOT */
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+/**
+ * efi_corstone1000_uboot-efi_started_event - notifies SE Proxy FW update service
+ *
+ * This function notifies the SE Proxy update service that uboot efi has already started
+ *
+ * Return:
+ *
+ * 0: on success, otherwise failure
+ * */
+static int efi_corstone1000_uboot_efi_started_event(void)
+{
+ struct ffa_send_direct_data msg = {0};
+
+ log_debug("[%s]\n", __func__);
+
+ /*
+ * setting the kernel started event arguments:
+ * setting capsule update interface ID(31:16)
+ * the kernel started event ID(15:0)
+ */
+ msg.data1 = PREP_SEPROXY_SVC_ID(CORSTONE1000_SEPROXY_UPDATE_SVC_ID) |
+ PREP_SEPROXY_EVT(CORSTONE1000_UBOOT_EFI_STARTED_EVT); /* w4 */
+
+ return ffa_bus_ops_get()->sync_send_receive(NULL, CORSTONE1000_SEPROXY_PART_ID, &msg, 0);
+}
+#endif
+
/**
* efi_init_capsule - initialize capsule update state
*
@@ -136,6 +167,14 @@ static efi_status_t efi_init_capsule(void)
efi_status_t ret = EFI_SUCCESS;
#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+ int ffa_ret;
+
+ ffa_ret = efi_corstone1000_uboot_efi_started_event();
+ if (ffa_ret)
+ debug("[efi_boottime][ERROR]: Failure to notify SE Proxy FW update service\n");
+ else
+ debug("[efi_boottime][INFO]: SE Proxy FW update service notified\n");
+
ret = efi_corstone1000_alloc_capsule_shared_buf();
if (ret != EFI_SUCCESS) {
printf("EFI: Corstone-1000: cannot allocate caspsule shared buffer\n");
--
2.25.1
@@ -0,0 +1,63 @@
From 3d28467e447f12c5aa276827aa742e7eed1d577a Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 14 Jan 2022 15:24:18 +0000
Subject: [PATCH 19/42] efi_loader: fix null pointer exception with
get_image_info
get_img_info API implemented for corstone1000 target does not
check the input attributes and as a result uboot crash's with
null pointer access. This change is to fix the null pointer
exception.
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
lib/efi_loader/efi_firmware.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 70568f2290..c883e2ff0a 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -39,26 +39,29 @@ static efi_status_t efi_corstone1000_img_info_get (
int i = 0;
*image_info_size = sizeof(*image_info);
- *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
- *descriptor_count = 1;//dfu_num;
- *descriptor_size = sizeof(*image_info);
+ if(descriptor_version)
+ *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
+ if(descriptor_count)
+ *descriptor_count = 1;
+ if(descriptor_size)
+ *descriptor_size = sizeof(*image_info);
if (package_version)
*package_version = 0xffffffff; /* not supported */
if(package_version_name)
*package_version_name = NULL; /* not supported */
if(image_info == NULL) {
- log_info("image_info is null\n");
+ log_debug("image_info is null\n");
return EFI_BUFFER_TOO_SMALL;
}
- image_info[i].image_index = i;
+ image_info[i].image_index = 1;
image_info[i].image_type_id = *image_type;
image_info[i].image_id = 0;
- image_info[i].image_id_name = "wic";
- image_info[i].version = 1;
+ image_info[i].image_id_name = L"wic image";
+ image_info[i].version = 0;
image_info[i].version_name = NULL;
- image_info[i].size = 0x1000;
+ image_info[i].size = 0;
image_info[i].attributes_supported = IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
image_info[i].attributes_setting = IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
--
2.25.1
@@ -0,0 +1,99 @@
From d6c183a99a7d232ef5dbf886c49e7fb75b50ecf9 Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Wed, 30 Nov 2022 15:37:22 +0000
Subject: [PATCH 20/42] arm:corstone1000: add mmc for fvp
Enable support mmc/sdcard for the corstone1000 FVP.
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
---
board/armltd/corstone1000/corstone1000.c | 28 +++++++++++++++++++-----
configs/corstone1000_defconfig | 8 ++++++-
include/configs/corstone1000.h | 4 +++-
3 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index 76816f8f4e..d6ca6e8961 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -38,19 +38,35 @@ static struct mm_region corstone1000_mem_map[] = {
}, {
/* USB */
.virt = 0x40200000UL,
- .phys = 0x40200000UL,
+ .phys = 0x40200000UL,
+ .size = 0x00100000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* MMC0 */
+ .virt = 0x40300000UL,
+ .phys = 0x40300000UL,
.size = 0x00100000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
- PTE_BLOCK_NON_SHARE |
- PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* ethernet */
.virt = 0x40100000UL,
- .phys = 0x40100000UL,
+ .phys = 0x40100000UL,
+ .size = 0x00100000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* MMC1 */
+ .virt = 0x50000000UL,
+ .phys = 0x50000000UL,
.size = 0x00100000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
- PTE_BLOCK_NON_SHARE |
- PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* OCVM */
.virt = 0x80000000UL,
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index 06eac3e041..f7c276a10a 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -40,7 +40,13 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
CONFIG_MISC=y
-# CONFIG_MMC is not set
+CONFIG_CLK=y
+CONFIG_CMD_MMC=y
+CONFIG_DM_MMC=y
+CONFIG_ARM_PL180_MMCI=y
+CONFIG_MMC_SDHCI_ADMA_HELPERS=y
+CONFIG_MMC_WRITE=y
+CONFIG_DM_GPIO=y
CONFIG_PHYLIB=y
CONFIG_PHY_SMSC=y
CONFIG_SMC911X=y
diff --git a/include/configs/corstone1000.h b/include/configs/corstone1000.h
index be13b98d48..a015a1630e 100644
--- a/include/configs/corstone1000.h
+++ b/include/configs/corstone1000.h
@@ -59,7 +59,9 @@
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define BOOT_TARGET_DEVICES(func) \
- func(USB, usb, 0)
+ func(USB, usb, 0) \
+ func(MMC, mmc, 0) \
+ func(MMC, mmc, 1)
#include <config_distro_bootcmd.h>
--
2.25.1
@@ -0,0 +1,34 @@
From 155f20028ad5f3ba5d2362ec48abb7804eaade00 Mon Sep 17 00:00:00 2001
From: Jon Mason <jon.mason@arm.com>
Date: Wed, 30 Nov 2022 18:59:59 +0000
Subject: [PATCH 21/42] corstone1000: add compressed kernel support
The corstone1000 kernel has become too large to fit in the available
storage. Swtiching to a compressed kernel avoids the problem, but
requires uncompressing it. Add this decompression to the default boot
instructions.
Signed-off-by: Jon Mason <jon.mason@arm.com>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
configs/corstone1000_defconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index f7c276a10a..1179bf5f3b 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -15,7 +15,7 @@ CONFIG_FIT=y
CONFIG_BOOTDELAY=3
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0 loglevel=9 ip=dhcp earlyprintk"
-CONFIG_BOOTCOMMAND="run retrieve_kernel_load_addr; echo Loading kernel from $kernel_addr to memory ... ; loadm $kernel_addr $kernel_addr_r 0xc00000; usb start; usb reset; run distro_bootcmd; bootefi $kernel_addr_r $fdtcontroladdr;"
+CONFIG_BOOTCOMMAND="run retrieve_kernel_load_addr; echo Loading kernel from $kernel_addr to memory ... ; unzip $kernel_addr 0x90000000; loadm 0x90000000 $kernel_addr_r 0xf00000; usb start; usb reset; run distro_bootcmd; bootefi $kernel_addr_r $fdtcontroladdr;"
CONFIG_CONSOLE_RECORD=y
CONFIG_LOGLEVEL=7
# CONFIG_DISPLAY_CPUINFO is not set
--
2.25.1
@@ -0,0 +1,35 @@
From 984c431cd594c112d71ea1378bc1ac3b72806baa Mon Sep 17 00:00:00 2001
From: Emekcan <emekcan.aras@arm.com>
Date: Wed, 30 Nov 2022 19:02:26 +0000
Subject: [PATCH 22/42] Introduce external sys driver to device-tree
It adds external sys driver binding to u-boot
device tree.
Signed-off-by: Emekcan Aras <emekcan.aras@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
arch/arm/dts/corstone1000.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/dts/corstone1000.dtsi b/arch/arm/dts/corstone1000.dtsi
index 4e46826f88..2c7185e139 100644
--- a/arch/arm/dts/corstone1000.dtsi
+++ b/arch/arm/dts/corstone1000.dtsi
@@ -160,5 +160,12 @@
secure-status = "okay"; /* secure-world-only */
status = "disabled";
};
+
+ extsys0: extsys@1A010310 {
+ compatible = "arm,extsys_ctrl";
+ reg = <0x1A010310 0x4>,
+ <0x1A010314 0X4>;
+ reg-names = "rstreg", "streg";
+ };
};
};
--
2.25.1
@@ -0,0 +1,80 @@
From 4167fe9079b64aaaf3eefc53063d242af8d2badd Mon Sep 17 00:00:00 2001
From: Emekcan <emekcan.aras@arm.com>
Date: Mon, 12 Sep 2022 15:47:06 +0100
Subject: [PATCH 23/42] Add mhu and rpmsg client to u-boot device tree
Adds external system controller and mhu driver to u-boot
device tree. This enables communication between host and
the external system.
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
arch/arm/dts/corstone1000.dtsi | 50 ++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/arch/arm/dts/corstone1000.dtsi b/arch/arm/dts/corstone1000.dtsi
index 2c7185e139..61e0c33247 100644
--- a/arch/arm/dts/corstone1000.dtsi
+++ b/arch/arm/dts/corstone1000.dtsi
@@ -161,6 +161,56 @@
status = "disabled";
};
+ mbox_es0mhu0_tx: mhu@1b000000 {
+ compatible = "arm,mhuv2-tx","arm,primecell";
+ reg = <0x1b000000 0x1000>;
+ clocks = <&refclk100mhz>;
+ clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ arm,mhuv2-protocols = <1 1>;
+ mbox-name = "arm-es0-mhu0_tx";
+ };
+
+ mbox_es0mhu0_rx: mhu@1b010000 {
+ compatible = "arm,mhuv2-rx","arm,primecell";
+ reg = <0x1b010000 0x1000>;
+ clocks = <&refclk100mhz>;
+ clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ arm,mhuv2-protocols = <1 1>;
+ mbox-name = "arm-es0-mhu0_rx";
+ };
+
+ mbox_es0mhu1_tx: mhu@1b020000 {
+ compatible = "arm,mhuv2-tx","arm,primecell";
+ reg = <0x1b020000 0x1000>;
+ clocks = <&refclk100mhz>;
+ clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ arm,mhuv2-protocols = <1 1>;
+ mbox-name = "arm-es0-mhu1_tx";
+ };
+
+ mbox_es0mhu1_rx: mhu@1b030000 {
+ compatible = "arm,mhuv2-rx","arm,primecell";
+ reg = <0x1b030000 0x1000>;
+ clocks = <&refclk100mhz>;
+ clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ arm,mhuv2-protocols = <1 1>;
+ mbox-name = "arm-es0-mhu1_rx";
+ };
+
+ client {
+ compatible = "arm,client";
+ mboxes = <&mbox_es0mhu0_tx 0 0>, <&mbox_es0mhu1_tx 0 0>, <&mbox_es0mhu0_rx 0 0>, <&mbox_es0mhu1_rx 0 0>;
+ mbox-names = "es0mhu0_tx", "es0mhu1_tx", "es0mhu0_rx", "es0mhu1_rx";
+ };
+
extsys0: extsys@1A010310 {
compatible = "arm,extsys_ctrl";
reg = <0x1A010310 0x4>,
--
2.25.1
@@ -0,0 +1,225 @@
From f924535544515cdb350b2979b8c413cf221124b6 Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Wed, 30 Nov 2022 19:11:43 +0000
Subject: [PATCH 24/42] arm/corstone1000: esrt support
The implementation is platform specific and would require
change in future.
The patch should not be upstreamed as it is to the u-boot.
Redesign of FMP protocol for ESRT and Capsule Update interface
is to be considered in the future.
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Inappropriate [Redesign of FMP protocol for ESRT and Capsule update interface is required]
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
include/efi_api.h | 2 +-
lib/efi_loader/efi_firmware.c | 133 ++++++++++++++++++++++++++++++++++
lib/efi_loader/efi_setup.c | 17 +++--
3 files changed, 143 insertions(+), 9 deletions(-)
diff --git a/include/efi_api.h b/include/efi_api.h
index 9bd70b0f18..23e427236a 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -2030,7 +2030,7 @@ struct efi_firmware_image_descriptor {
u32 last_attempt_status;
u64 hardware_instance;
efi_firmware_image_dep_t *dependencies;
-};
+} __packed;
struct efi_firmware_management_protocol {
efi_status_t (EFIAPI *get_image_info)(
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index c883e2ff0a..c6ab6e2182 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -15,6 +15,7 @@
#include <signatures.h>
#include <linux/list.h>
+#include <efi_variable.h>
#define FMP_PAYLOAD_HDR_SIGNATURE SIGNATURE_32('M', 'S', 'S', '1')
@@ -417,8 +418,140 @@ efi_status_t EFIAPI efi_firmware_fit_set_image(
return EFI_EXIT(EFI_SUCCESS);
}
+#if CONFIG_IS_ENABLED(TARGET_CORSTONE1000)
+
+/**
+ * efi_firmware_corstone1000_get_image_info - return information about the current
+ firmware image
+ * @this: Protocol instance
+ * @image_info_size: Size of @image_info
+ * @image_info: Image information
+ * @descriptor_version: Pointer to version number
+ * @descriptor_count: Pointer to number of descriptors
+ * @descriptor_size: Pointer to descriptor size
+ * package_version: Package version
+ * package_version_name: Package version's name
+ *
+ * Return information bout the current firmware image in @image_info.
+ * @image_info will consist of a number of descriptors.
+ * Each descriptor will be created based on efi fetched variable.
+ *
+ * Return status code
+ */
+static
+efi_status_t EFIAPI efi_firmware_corstone1000_get_image_info(
+ struct efi_firmware_management_protocol *this,
+ efi_uintn_t *image_info_size,
+ struct efi_firmware_image_descriptor *image_info,
+ u32 *descriptor_version,
+ u8 *descriptor_count,
+ efi_uintn_t *descriptor_size,
+ u32 *package_version,
+ u16 **package_version_name)
+{
+ efi_uintn_t var_size;
+ efi_status_t ret = EFI_SUCCESS;
+ efi_uintn_t image_info_size_var = 0;
+ efi_uintn_t image_info_name_size_var;
+ efi_uintn_t image_info_version_size_var;
+ u8 *runner = (u8 *)image_info;
+ u16 fmp_image_name[14] = {'F', 'm', 'p', 'I', 'm', 'a', 'g', 'e', 'N', 'a', 'm', 'e', '1', '\0'};
+ u16 fmp_version_name[16] = {'F', 'm', 'p', 'V', 'e', 'r', 's', 'i', 'o', 'n', 'N', 'a', 'm', 'e', '1', '\0'};
+
+ EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this,
+ image_info_size, image_info,
+ descriptor_version, descriptor_count, descriptor_size,
+ package_version, package_version_name);
+
+ if (!image_info_size)
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+
+ if (*image_info_size &&
+ (!image_info || !descriptor_version || !descriptor_count ||
+ !descriptor_size || !package_version || !package_version_name))
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+
+ var_size = sizeof(*descriptor_version);
+ ret = efi_get_variable(u"FmpDescriptorVersion",
+ &efi_guid_firmware_management_protocol, NULL,
+ &var_size, descriptor_version);
+ if (ret != EFI_SUCCESS)
+ return EFI_EXIT(ret);
+
+ if (*descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
+ return EFI_EXIT(EFI_UNSUPPORTED);
+
+ var_size = sizeof(image_info_size_var);
+ ret = efi_get_variable(u"FmpImageInfoSize",
+ &efi_guid_firmware_management_protocol, NULL,
+ &var_size, &image_info_size_var);
+ if (ret != EFI_SUCCESS)
+ return EFI_EXIT(ret);
+
+ if (*image_info_size < image_info_size_var) {
+ *image_info_size = image_info_size_var;
+ return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
+ }
+
+ image_info_name_size_var = image_info_size_var;
+
+ var_size = sizeof(*descriptor_count);
+ ret = efi_get_variable(u"FmpDescriptorCount",
+ &efi_guid_firmware_management_protocol, NULL,
+ &var_size, descriptor_count);
+ if (ret != EFI_SUCCESS) {
+ return EFI_EXIT(ret);
+ }
+
+ ret = efi_get_variable(u"FmpImageInfo",
+ &efi_guid_firmware_management_protocol, NULL,
+ &image_info_size_var, image_info);
+ if (ret != EFI_SUCCESS)
+ return EFI_EXIT(ret);
+
+ runner += image_info_size_var;
+
+ image_info_name_size_var -= image_info_size_var;
+ image_info_version_size_var = image_info_name_size_var;
+
+ /* Consider changing the string modfication logic */
+ fmp_image_name[12] = '0' + (u16)image_info->image_id;
+ ret = efi_get_variable(fmp_image_name,
+ &efi_guid_firmware_management_protocol, NULL,
+ &image_info_name_size_var, runner);
+ if (ret != EFI_SUCCESS)
+ return EFI_EXIT(ret);
+
+ image_info_version_size_var -= image_info_name_size_var;
+ image_info->image_id_name = runner;
+ runner += image_info_name_size_var;
+
+ /* Consider changing the string modfication logic */
+ fmp_version_name[14] = '0' + (u16)image_info->image_id;
+ ret = efi_get_variable(fmp_version_name,
+ &efi_guid_firmware_management_protocol, NULL,
+ &image_info_version_size_var, runner);
+ if (ret != EFI_SUCCESS)
+ return EFI_EXIT(ret);
+
+ image_info->version_name = runner;
+
+ *image_info_size = image_info_size_var;
+
+ *package_version = 0xffffffff; /* not supported */
+ *package_version_name = NULL; /* not supported */
+
+ return EFI_EXIT(ret);
+}
+
+#endif
+
const struct efi_firmware_management_protocol efi_fmp_fit = {
+#if CONFIG_IS_ENABLED(TARGET_CORSTONE1000)
+ .get_image_info = efi_firmware_corstone1000_get_image_info,
+#else
.get_image_info = efi_firmware_get_image_info,
+#endif
.get_image = efi_firmware_get_image_unsupported,
.set_image = efi_firmware_fit_set_image,
.check_image = efi_firmware_check_image_unsupported,
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 89f988b09c..08c742edbd 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -167,14 +167,6 @@ static efi_status_t efi_init_capsule(void)
efi_status_t ret = EFI_SUCCESS;
#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
- int ffa_ret;
-
- ffa_ret = efi_corstone1000_uboot_efi_started_event();
- if (ffa_ret)
- debug("[efi_boottime][ERROR]: Failure to notify SE Proxy FW update service\n");
- else
- debug("[efi_boottime][INFO]: SE Proxy FW update service notified\n");
-
ret = efi_corstone1000_alloc_capsule_shared_buf();
if (ret != EFI_SUCCESS) {
printf("EFI: Corstone-1000: cannot allocate caspsule shared buffer\n");
@@ -288,6 +280,15 @@ efi_status_t efi_init_obj_list(void)
if (ret != EFI_SUCCESS)
goto out;
+#if IS_ENABLED(CONFIG_TARGET_CORSTONE1000)
+ int ffa_ret;
+ ffa_ret = efi_corstone1000_uboot_efi_started_event();
+ if (ffa_ret)
+ debug("[efi_boottime][ERROR]: Failure to notify SE Proxy FW update service\n");
+ else
+ debug("[efi_boottime][INFO]: SE Proxy FW update service notified\n");
+#endif
+
/* Initialize variable services */
ret = efi_init_variables();
if (ret != EFI_SUCCESS)
--
2.25.1
@@ -0,0 +1,51 @@
From 1f165f5b6e7d82611b55260b7254fee5fbebe539 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Wed, 30 Nov 2022 19:14:52 +0000
Subject: [PATCH 25/42] efi_setup: discover FF-A bus before raising EFI started
event
add FF-A discovery to efi_corstone1000_uboot_efi_started_event()
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
lib/efi_loader/efi_setup.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 08c742edbd..65bd626e49 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -142,9 +142,16 @@ static efi_status_t efi_init_secure_boot(void)
static int efi_corstone1000_uboot_efi_started_event(void)
{
struct ffa_send_direct_data msg = {0};
+ int ret;
log_debug("[%s]\n", __func__);
+ ret = ffa_bus_discover(NULL);
+ if (ret != 0) {
+ log_err("failure to discover FF-A bus\n");
+ return ret;
+ }
+
/*
* setting the kernel started event arguments:
* setting capsule update interface ID(31:16)
@@ -284,9 +291,9 @@ efi_status_t efi_init_obj_list(void)
int ffa_ret;
ffa_ret = efi_corstone1000_uboot_efi_started_event();
if (ffa_ret)
- debug("[efi_boottime][ERROR]: Failure to notify SE Proxy FW update service\n");
+ log_err("Failure to notify SE Proxy FW update service\n");
else
- debug("[efi_boottime][INFO]: SE Proxy FW update service notified\n");
+ debug("SE Proxy FW update service notified\n");
#endif
/* Initialize variable services */
--
2.25.1
@@ -0,0 +1,28 @@
From 2a281a45b7dfc5c0e78f6256bf0ac122d825ce82 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Mon, 5 Dec 2022 17:02:32 +0000
Subject: [PATCH 26/42] corstone1000: enable distro booting command
enable distro_bootcmd
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
include/configs/corstone1000.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/configs/corstone1000.h b/include/configs/corstone1000.h
index a015a1630e..c30a7bfa0c 100644
--- a/include/configs/corstone1000.h
+++ b/include/configs/corstone1000.h
@@ -65,5 +65,6 @@
#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS BOOTENV
#endif
--
2.25.1
@@ -0,0 +1,455 @@
From c7567aaf75a66e204d492a8f6e2a3b4bfb8a7e45 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Fri, 14 Apr 2023 13:23:25 +0100
Subject: [PATCH 27/42] drivers/mtd/nvmxip: introduce NVM XIP block storage
emulation
add block storage emulation for NVM XIP flash devices
Some paltforms such as Corstone-1000 need to see NVM XIP raw flash
as a block storage device with read only capability.
Here NVM flash devices are devices with addressable
memory (e.g: QSPI NOR flash).
The implementation is generic and can be used by different platforms.
Two drivers are provided as follows.
nvmxip-blk :
a generic block driver allowing to read from the XIP flash
nvmxip Uclass driver :
When a device is described in the DT and associated with
UCLASS_NVMXIP, the Uclass creates a block device and binds it with
the nvmxip-blk.
Platforms can use multiple NVM XIP devices at the same time by defining a
DT node for each one of them.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c]
---
MAINTAINERS | 6 ++
doc/develop/driver-model/index.rst | 1 +
doc/develop/driver-model/nvmxip.rst | 48 +++++++++++
drivers/block/blk-uclass.c | 1 +
drivers/mtd/Kconfig | 2 +
drivers/mtd/Makefile | 1 +
drivers/mtd/nvmxip/Kconfig | 13 +++
drivers/mtd/nvmxip/Makefile | 7 ++
drivers/mtd/nvmxip/nvmxip-uclass.c | 67 ++++++++++++++++
drivers/mtd/nvmxip/nvmxip.c | 119 ++++++++++++++++++++++++++++
drivers/mtd/nvmxip/nvmxip.h | 32 ++++++++
include/dm/uclass-id.h | 1 +
12 files changed, 298 insertions(+)
create mode 100644 doc/develop/driver-model/nvmxip.rst
create mode 100644 drivers/mtd/nvmxip/Kconfig
create mode 100644 drivers/mtd/nvmxip/Makefile
create mode 100644 drivers/mtd/nvmxip/nvmxip-uclass.c
create mode 100644 drivers/mtd/nvmxip/nvmxip.c
create mode 100644 drivers/mtd/nvmxip/nvmxip.h
diff --git a/MAINTAINERS b/MAINTAINERS
index a2f60a3b93..1dbfab5f43 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1202,6 +1202,12 @@ F: cmd/nvme.c
F: include/nvme.h
F: doc/develop/driver-model/nvme.rst
+NVMXIP
+M: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+S: Maintained
+F: doc/develop/driver-model/nvmxip.rst
+F: drivers/mtd/nvmxip/
+
NVMEM
M: Sean Anderson <seanga2@gmail.com>
S: Maintained
diff --git a/doc/develop/driver-model/index.rst b/doc/develop/driver-model/index.rst
index 7366ef818c..8e12bbd936 100644
--- a/doc/develop/driver-model/index.rst
+++ b/doc/develop/driver-model/index.rst
@@ -20,6 +20,7 @@ subsystems
livetree
migration
nvme
+ nvmxip
of-plat
pci-info
pmic-framework
diff --git a/doc/develop/driver-model/nvmxip.rst b/doc/develop/driver-model/nvmxip.rst
new file mode 100644
index 0000000000..fe087b13d2
--- /dev/null
+++ b/doc/develop/driver-model/nvmxip.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+NVM XIP Block Storage Emulation Driver
+=======================================
+
+Summary
+-------
+
+Non-Volatile Memory devices with addressable memory (e.g: QSPI NOR flash) could
+be used for block storage needs (e.g: parsing a GPT layout in a raw QSPI NOR flash).
+
+The NVMXIP Uclass provides this functionality and can be used for any 64-bit platform.
+
+The NVMXIP Uclass provides the following drivers:
+
+ nvmxip-blk block driver:
+
+ A generic block driver allowing to read from the XIP flash.
+ The driver belongs to UCLASS_BLK.
+ The driver implemented by drivers/mtd/nvmxip/nvmxip.c
+
+ nvmxip Uclass driver:
+
+ When a device is described in the DT and associated with UCLASS_NVMXIP,
+ the Uclass creates a block device and binds it with the nvmxip-blk.
+ The Uclass driver implemented by drivers/mtd/nvmxip/nvmxip-uclass.c
+
+ The implementation is generic and can be used by different platforms.
+
+Supported hardware
+--------------------------------
+
+Any 64-bit plaform.
+
+Configuration
+----------------------
+
+config NVMXIP
+ This option allows the emulation of a block storage device
+ on top of a direct access non volatile memory XIP flash devices.
+ This support provides the read operation.
+ This option provides the block storage driver nvmxip-blk which
+ handles the read operation. This driver is HW agnostic and can support
+ multiple flash devices at the same time.
+
+Contributors
+------------
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index c69fc4d518..e8ab576c32 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -28,6 +28,7 @@ static struct {
{ UCLASS_AHCI, "sata" },
{ UCLASS_HOST, "host" },
{ UCLASS_NVME, "nvme" },
+ { UCLASS_NVMXIP, "nvmxip" },
{ UCLASS_EFI_MEDIA, "efi" },
{ UCLASS_EFI_LOADER, "efiloader" },
{ UCLASS_VIRTIO, "virtio" },
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index fcdb450f77..0537ac64e3 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -224,4 +224,6 @@ source "drivers/mtd/spi/Kconfig"
source "drivers/mtd/ubi/Kconfig"
+source "drivers/mtd/nvmxip/Kconfig"
+
endmenu
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 3a78590aaa..c638980ea2 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -25,6 +25,7 @@ obj-y += nand/
obj-y += onenand/
obj-y += spi/
obj-$(CONFIG_MTD_UBI) += ubi/
+obj-$(CONFIG_NVMXIP) += nvmxip/
#SPL/TPL build
else
diff --git a/drivers/mtd/nvmxip/Kconfig b/drivers/mtd/nvmxip/Kconfig
new file mode 100644
index 0000000000..ef53fc3c79
--- /dev/null
+++ b/drivers/mtd/nvmxip/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# Authors:
+# Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+
+config NVMXIP
+ bool "NVM XIP devices support"
+ select BLK
+ help
+ This option allows the emulation of a block storage device
+ on top of a direct access non volatile memory XIP flash devices.
+ This support provides the read operation.
diff --git a/drivers/mtd/nvmxip/Makefile b/drivers/mtd/nvmxip/Makefile
new file mode 100644
index 0000000000..07890982c7
--- /dev/null
+++ b/drivers/mtd/nvmxip/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# Authors:
+# Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+
+obj-y += nvmxip-uclass.o nvmxip.o
diff --git a/drivers/mtd/nvmxip/nvmxip-uclass.c b/drivers/mtd/nvmxip/nvmxip-uclass.c
new file mode 100644
index 0000000000..9f96041e3d
--- /dev/null
+++ b/drivers/mtd/nvmxip/nvmxip-uclass.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <linux/bitops.h>
+#include "nvmxip.h"
+
+/* LBA Macros */
+
+#define DEFAULT_LBA_SHIFT 10 /* 1024 bytes per block */
+#define DEFAULT_LBA_COUNT 1024 /* block count */
+
+#define DEFAULT_LBA_SZ BIT(DEFAULT_LBA_SHIFT)
+
+/**
+ * nvmxip_post_bind() - post binding treatments
+ * @dev: the NVMXIP device
+ *
+ * Create and probe a child block device.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+static int nvmxip_post_bind(struct udevice *udev)
+{
+ int ret;
+ struct udevice *bdev = NULL;
+ char bdev_name[NVMXIP_BLKDEV_NAME_SZ + 1];
+ int devnum;
+
+ devnum = uclass_id_count(UCLASS_NVMXIP);
+ snprintf(bdev_name, NVMXIP_BLKDEV_NAME_SZ, "blk#%d", devnum);
+
+ ret = blk_create_devicef(udev, NVMXIP_BLKDRV_NAME, bdev_name, UCLASS_NVMXIP,
+ devnum, DEFAULT_LBA_SZ,
+ DEFAULT_LBA_COUNT, &bdev);
+ if (ret) {
+ log_err("[%s]: failure during creation of the block device %s, error %d\n",
+ udev->name, bdev_name, ret);
+ return ret;
+ }
+
+ ret = blk_probe_or_unbind(bdev);
+ if (ret) {
+ log_err("[%s]: failure during probing the block device %s, error %d\n",
+ udev->name, bdev_name, ret);
+ return ret;
+ }
+
+ log_info("[%s]: the block device %s ready for use\n", udev->name, bdev_name);
+
+ return 0;
+}
+
+UCLASS_DRIVER(nvmxip) = {
+ .name = "nvmxip",
+ .id = UCLASS_NVMXIP,
+ .post_bind = nvmxip_post_bind,
+};
diff --git a/drivers/mtd/nvmxip/nvmxip.c b/drivers/mtd/nvmxip/nvmxip.c
new file mode 100644
index 0000000000..a359e3b482
--- /dev/null
+++ b/drivers/mtd/nvmxip/nvmxip.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <mapmem.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include "nvmxip.h"
+
+/**
+ * nvmxip_mmio_rawread() - read from the XIP flash
+ * @address: address of the data
+ * @value: pointer to where storing the value read
+ *
+ * Read raw data from the XIP flash.
+ *
+ * Return:
+ *
+ * Always return 0.
+ */
+static int nvmxip_mmio_rawread(const phys_addr_t address, u64 *value)
+{
+ *value = readq(address);
+ return 0;
+}
+
+/**
+ * nvmxip_blk_read() - block device read operation
+ * @dev: the block device
+ * @blknr: first block number to read from
+ * @blkcnt: number of blocks to read
+ * @buffer: destination buffer
+ *
+ * Read data from the block storage device.
+ *
+ * Return:
+ *
+ * number of blocks read on success. Otherwise, failure
+ */
+static ulong nvmxip_blk_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
+{
+ struct nvmxip_plat *plat = dev_get_plat(dev->parent);
+ struct blk_desc *desc = dev_get_uclass_plat(dev);
+ /* number of the u64 words to read */
+ u32 qwords = (blkcnt * desc->blksz) / sizeof(u64);
+ /* physical address of the first block to read */
+ phys_addr_t blkaddr = plat->phys_base + blknr * desc->blksz;
+ u64 *virt_blkaddr;
+ u64 *pdst = buffer;
+ uint qdata_idx;
+
+ if (!pdst)
+ return -EINVAL;
+
+ log_debug("[%s]: reading from blknr: %lu , blkcnt: %lu\n", dev->name, blknr, blkcnt);
+
+ virt_blkaddr = map_sysmem(blkaddr, 0);
+
+ /* assumption: the data is virtually contiguous */
+
+ for (qdata_idx = 0 ; qdata_idx < qwords ; qdata_idx++)
+ nvmxip_mmio_rawread((phys_addr_t)(virt_blkaddr + qdata_idx), pdst++);
+
+ log_debug("[%s]: src[0]: 0x%llx , dst[0]: 0x%llx , src[-1]: 0x%llx , dst[-1]: 0x%llx\n",
+ dev->name,
+ *virt_blkaddr,
+ *(u64 *)buffer,
+ *(u64 *)((u8 *)virt_blkaddr + desc->blksz * blkcnt - sizeof(u64)),
+ *(u64 *)((u8 *)buffer + desc->blksz * blkcnt - sizeof(u64)));
+
+ unmap_sysmem(virt_blkaddr);
+
+ return blkcnt;
+}
+
+/**
+ * nvmxip_blk_probe() - block storage device probe
+ * @dev: the block storage device
+ *
+ * Initialize the block storage descriptor.
+ *
+ * Return:
+ *
+ * Always return 0.
+ */
+static int nvmxip_blk_probe(struct udevice *dev)
+{
+ struct nvmxip_plat *plat = dev_get_plat(dev->parent);
+ struct blk_desc *desc = dev_get_uclass_plat(dev);
+
+ desc->lba = plat->lba;
+ desc->log2blksz = plat->lba_shift;
+ desc->blksz = BIT(plat->lba_shift);
+ desc->bdev = dev;
+
+ log_debug("[%s]: block storage layout\n lbas: %lu , log2blksz: %d, blksz: %lu\n",
+ dev->name, desc->lba, desc->log2blksz, desc->blksz);
+
+ return 0;
+}
+
+static const struct blk_ops nvmxip_blk_ops = {
+ .read = nvmxip_blk_read,
+};
+
+U_BOOT_DRIVER(nvmxip_blk) = {
+ .name = NVMXIP_BLKDRV_NAME,
+ .id = UCLASS_BLK,
+ .probe = nvmxip_blk_probe,
+ .ops = &nvmxip_blk_ops,
+};
diff --git a/drivers/mtd/nvmxip/nvmxip.h b/drivers/mtd/nvmxip/nvmxip.h
new file mode 100644
index 0000000000..f4ef37725d
--- /dev/null
+++ b/drivers/mtd/nvmxip/nvmxip.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#ifndef __DRIVER_NVMXIP_H__
+#define __DRIVER_NVMXIP_H__
+
+#include <blk.h>
+
+#define NVMXIP_BLKDRV_NAME "nvmxip-blk"
+#define NVMXIP_BLKDEV_NAME_SZ 20
+
+/**
+ * struct nvmxip_plat - the NVMXIP driver plat
+ *
+ * @phys_base: NVM XIP device base address
+ * @lba_shift: block size shift count
+ * @lba: number of blocks
+ *
+ * The NVMXIP information read from the DT.
+ */
+struct nvmxip_plat {
+ phys_addr_t phys_base;
+ u32 lba_shift;
+ lbaint_t lba;
+};
+
+#endif /* __DRIVER_NVMXIP_H__ */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index fa08a66ac8..f3564a49d9 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -92,6 +92,7 @@ enum uclass_id {
UCLASS_NOP, /* No-op devices */
UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */
UCLASS_NVME, /* NVM Express device */
+ UCLASS_NVMXIP, /* NVM XIP devices */
UCLASS_P2SB, /* (x86) Primary-to-Sideband Bus */
UCLASS_PANEL, /* Display panel, such as an LCD */
UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */
--
2.25.1
@@ -0,0 +1,271 @@
From 4b71ade0e8e5ad3692b1decb5c1d0c9472827535 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Fri, 14 Apr 2023 13:44:25 +0100
Subject: [PATCH 28/42] drivers/mtd/nvmxip: introduce QSPI XIP driver
add nvmxip_qspi driver under UCLASS_NVMXIP
The device associated with this driver is the parent of the blk#<id> device
nvmxip_qspi can be reused by other platforms. If the platform
has custom settings to apply before using the flash, then the platform
can provide its own parent driver belonging to UCLASS_NVMXIP and reuse
nvmxip-blk driver. The custom driver can be implemented like nvmxip_qspi in
addition to the platform custom settings.
Platforms can use multiple NVM XIP devices at the same time by defining a
DT node for each one of them.
For more details please refer to doc/develop/driver-model/nvmxip_qspi.rst
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c]
---
MAINTAINERS | 1 +
doc/develop/driver-model/nvmxip.rst | 45 +++++++++++-
.../nvmxip/nvmxip_qspi.txt | 56 +++++++++++++++
drivers/mtd/nvmxip/Kconfig | 6 ++
drivers/mtd/nvmxip/Makefile | 1 +
drivers/mtd/nvmxip/nvmxip_qspi.c | 70 +++++++++++++++++++
6 files changed, 178 insertions(+), 1 deletion(-)
create mode 100644 doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
create mode 100644 drivers/mtd/nvmxip/nvmxip_qspi.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 1dbfab5f43..f81654346e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1206,6 +1206,7 @@ NVMXIP
M: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
S: Maintained
F: doc/develop/driver-model/nvmxip.rst
+F: doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
F: drivers/mtd/nvmxip/
NVMEM
diff --git a/doc/develop/driver-model/nvmxip.rst b/doc/develop/driver-model/nvmxip.rst
index fe087b13d2..09afdbcccf 100644
--- a/doc/develop/driver-model/nvmxip.rst
+++ b/doc/develop/driver-model/nvmxip.rst
@@ -25,7 +25,33 @@ The NVMXIP Uclass provides the following drivers:
the Uclass creates a block device and binds it with the nvmxip-blk.
The Uclass driver implemented by drivers/mtd/nvmxip/nvmxip-uclass.c
- The implementation is generic and can be used by different platforms.
+ nvmxip_qspi driver :
+
+ The driver probed with the DT and is the parent of the blk#<id> device.
+ nvmxip_qspi can be reused by other platforms. If the platform
+ has custom settings to apply before using the flash, then the platform
+ can provide its own parent driver belonging to UCLASS_NVMXIP and reuse
+ nvmxip-blk. The custom driver can be implemented like nvmxip_qspi in
+ addition to the platform custom settings.
+ The nvmxip_qspi driver belongs to UCLASS_NVMXIP.
+ The driver implemented by drivers/mtd/nvmxip/nvmxip_qspi.c
+
+ For example, if we have two NVMXIP devices described in the DT
+ The devices hierarchy is as follows:
+
+::
+
+ => dm tree
+
+ Class Index Probed Driver Name
+ -----------------------------------------------------------
+ ...
+ nvmxip 0 [ + ] nvmxip_qspi |-- nvmxip-qspi1@08000000
+ blk 3 [ + ] nvmxip-blk | `-- nvmxip-qspi1@08000000.blk#1
+ nvmxip 1 [ + ] nvmxip_qspi |-- nvmxip-qspi2@08200000
+ blk 4 [ + ] nvmxip-blk | `-- nvmxip-qspi2@08200000.blk#2
+
+The implementation is generic and can be used by different platforms.
Supported hardware
--------------------------------
@@ -43,6 +69,23 @@ config NVMXIP
handles the read operation. This driver is HW agnostic and can support
multiple flash devices at the same time.
+config NVMXIP_QSPI
+ This option allows the emulation of a block storage device on top of a QSPI XIP flash.
+ Any platform that needs to emulate one or multiple QSPI XIP flash devices can turn this
+ option on to enable the functionality. NVMXIP config is selected automatically.
+ Platforms that need to add custom treatments before accessing to the flash, can
+ write their own driver (same as nvmxip_qspi in addition to the custom settings).
+
+Device Tree nodes
+--------------------
+
+Multiple QSPI XIP flash devices can be used at the same time by describing them through DT
+nodes.
+
+Please refer to the documentation of the DT binding at:
+
+doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
+
Contributors
------------
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
diff --git a/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
new file mode 100644
index 0000000000..cc60e9efdc
--- /dev/null
+++ b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
@@ -0,0 +1,56 @@
+Specifying NVMXIP information for devices
+======================================
+
+QSPI XIP flash device nodes
+---------------------------
+
+Each flash device should have its own node.
+
+Each node must specify the following fields:
+
+1)
+ compatible = "nvmxip,qspi";
+
+This allows to bind the flash device with the nvmxip_qspi driver
+If a platform has its own driver, please provide your own compatible
+string.
+
+2)
+ reg = <0x0 0x08000000 0x0 0x00200000>;
+
+The start address and size of the flash device. The values give here are an
+example (when the cell size is 2).
+
+When cell size is 1, the reg field looks like this:
+
+ reg = <0x08000000 0x00200000>;
+
+3)
+
+ lba_shift = <9>;
+
+The number of bit shifts used to calculate the size in bytes of one block.
+In this example the block size is 1 << 9 = 2 ^ 9 = 512 bytes
+
+4)
+
+ lba = <4096>;
+
+The number of blocks.
+
+Example of multiple flash devices
+----------------------------------------------------
+
+ nvmxip-qspi1@08000000 {
+ compatible = "nvmxip,qspi";
+ reg = <0x0 0x08000000 0x0 0x00200000>;
+ lba_shift = <9>;
+ lba = <4096>;
+ };
+
+ nvmxip-qspi2@08200000 {
+ compatible = "nvmxip,qspi";
+ reg = <0x0 0x08200000 0x0 0x00100000>;
+ lba_shift = <9>;
+ lba = <2048>;
+ };
diff --git a/drivers/mtd/nvmxip/Kconfig b/drivers/mtd/nvmxip/Kconfig
index ef53fc3c79..3ef7105026 100644
--- a/drivers/mtd/nvmxip/Kconfig
+++ b/drivers/mtd/nvmxip/Kconfig
@@ -11,3 +11,9 @@ config NVMXIP
This option allows the emulation of a block storage device
on top of a direct access non volatile memory XIP flash devices.
This support provides the read operation.
+
+config NVMXIP_QSPI
+ bool "QSPI XIP support"
+ select NVMXIP
+ help
+ This option allows the emulation of a block storage device on top of a QSPI XIP flash
diff --git a/drivers/mtd/nvmxip/Makefile b/drivers/mtd/nvmxip/Makefile
index 07890982c7..54eacc102e 100644
--- a/drivers/mtd/nvmxip/Makefile
+++ b/drivers/mtd/nvmxip/Makefile
@@ -5,3 +5,4 @@
# Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
obj-y += nvmxip-uclass.o nvmxip.o
+obj-$(CONFIG_NVMXIP_QSPI) += nvmxip_qspi.o
diff --git a/drivers/mtd/nvmxip/nvmxip_qspi.c b/drivers/mtd/nvmxip/nvmxip_qspi.c
new file mode 100644
index 0000000000..7221fd1cb4
--- /dev/null
+++ b/drivers/mtd/nvmxip/nvmxip_qspi.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdt_support.h>
+#include <linux/errno.h>
+#include "nvmxip.h"
+
+#include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+#define NVMXIP_QSPI_DRV_NAME "nvmxip_qspi"
+
+/**
+ * nvmxip_qspi_of_to_plat() -read from DT
+ * @dev: the NVMXIP device
+ *
+ * Read from the DT the NVMXIP information.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+static int nvmxip_qspi_of_to_plat(struct udevice *dev)
+{
+ struct nvmxip_plat *plat = dev_get_plat(dev);
+ int ret;
+
+ plat->phys_base = (phys_addr_t)dev_read_addr(dev);
+ if (plat->phys_base == FDT_ADDR_T_NONE) {
+ log_err("[%s]: can not get base address from device tree\n", dev->name);
+ return -EINVAL;
+ }
+
+ ret = dev_read_u32(dev, "lba_shift", &plat->lba_shift);
+ if (ret) {
+ log_err("[%s]: can not get lba_shift from device tree\n", dev->name);
+ return -EINVAL;
+ }
+
+ ret = dev_read_u32(dev, "lba", (u32 *)&plat->lba);
+ if (ret) {
+ log_err("[%s]: can not get lba from device tree\n", dev->name);
+ return -EINVAL;
+ }
+
+ log_debug("[%s]: XIP device base addr: 0x%llx , lba_shift: %d , lbas: %lu\n",
+ dev->name, plat->phys_base, plat->lba_shift, plat->lba);
+
+ return 0;
+}
+
+static const struct udevice_id nvmxip_qspi_ids[] = {
+ { .compatible = "nvmxip,qspi" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(nvmxip_qspi) = {
+ .name = NVMXIP_QSPI_DRV_NAME,
+ .id = UCLASS_NVMXIP,
+ .of_match = nvmxip_qspi_ids,
+ .of_to_plat = nvmxip_qspi_of_to_plat,
+ .plat_auto = sizeof(struct nvmxip_plat),
+};
--
2.25.1
@@ -0,0 +1,45 @@
From 1b80dfbefd59c8ddff77960552d6c0cc2747758c Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Fri, 16 Dec 2022 17:20:58 +0000
Subject: [PATCH 29/42] sandbox64: fix: return unsigned long in readq()
make readq return unsigned long
readq should return 64-bit data
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c]
---
arch/sandbox/cpu/cpu.c | 2 +-
arch/sandbox/include/asm/io.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 636d3545b9..248d17a85c 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -230,7 +230,7 @@ phys_addr_t map_to_sysmem(const void *ptr)
return mentry->tag;
}
-unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size)
+unsigned long sandbox_read(const void *addr, enum sandboxio_size_t size)
{
struct sandbox_state *state = state_get_current();
diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index ad6c29a4e2..31ab7289b4 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -45,7 +45,7 @@ static inline void unmap_sysmem(const void *vaddr)
/* Map from a pointer to our RAM buffer */
phys_addr_t map_to_sysmem(const void *ptr);
-unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size);
+unsigned long sandbox_read(const void *addr, enum sandboxio_size_t size);
void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size);
#define readb(addr) sandbox_read((const void *)addr, SB_SIZE_8)
--
2.25.1
@@ -0,0 +1,161 @@
From 25467e433f02f40f5999ed6e6b0d3adb4c9cf16d Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Fri, 9 Jun 2023 13:08:37 +0100
Subject: [PATCH 30/42] sandbox64: add support for NVMXIP QSPI
enable NVMXIP QSPI for sandbox 64-bit
Adding two NVM XIP QSPI storage devices.
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c]
Changelog:
===============
v2:
* address nits
---
arch/sandbox/dts/sandbox64.dts | 13 +++++++++++++
arch/sandbox/dts/test.dts | 14 ++++++++++++++
configs/sandbox64_defconfig | 3 ++-
doc/develop/driver-model/nvmxip.rst | 2 +-
doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt | 6 +++---
drivers/mtd/nvmxip/nvmxip-uclass.c | 7 +++++++
6 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts
index 3eb0457089..c9a2f4b4a4 100644
--- a/arch/sandbox/dts/sandbox64.dts
+++ b/arch/sandbox/dts/sandbox64.dts
@@ -89,6 +89,19 @@
cs-gpios = <0>, <&gpio_a 0>;
};
+ nvmxip-qspi1@08000000 {
+ compatible = "nvmxip,qspi";
+ reg = /bits/ 64 <0x08000000 0x00200000>;
+ lba_shift = <9>;
+ lba = <4096>;
+ };
+
+ nvmxip-qspi2@08200000 {
+ compatible = "nvmxip,qspi";
+ reg = /bits/ 64 <0x08200000 0x00100000>;
+ lba_shift = <9>;
+ lba = <2048>;
+ };
};
#include "sandbox.dtsi"
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dffe10adbf..c3ba0a225e 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1745,6 +1745,20 @@
compatible = "u-boot,fwu-mdata-gpt";
fwu-mdata-store = <&mmc0>;
};
+
+ nvmxip-qspi1@08000000 {
+ compatible = "nvmxip,qspi";
+ reg = <0x08000000 0x00200000>;
+ lba_shift = <9>;
+ lba = <4096>;
+ };
+
+ nvmxip-qspi2@08200000 {
+ compatible = "nvmxip,qspi";
+ reg = <0x08200000 0x00100000>;
+ lba_shift = <9>;
+ lba = <2048>;
+ };
};
#include "sandbox_pmic.dtsi"
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 4b8a1ec42b..2dca176ae3 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -260,4 +260,5 @@ CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_ARM_FFA_TRANSPORT=y
-CONFIG_SANDBOX_FFA=y
\ No newline at end of file
+CONFIG_SANDBOX_FFA=y
+CONFIG_NVMXIP_QSPI=y
\ No newline at end of file
diff --git a/doc/develop/driver-model/nvmxip.rst b/doc/develop/driver-model/nvmxip.rst
index 09afdbcccf..e85dc220b9 100644
--- a/doc/develop/driver-model/nvmxip.rst
+++ b/doc/develop/driver-model/nvmxip.rst
@@ -56,7 +56,7 @@ The implementation is generic and can be used by different platforms.
Supported hardware
--------------------------------
-Any 64-bit plaform.
+Any plaform supporting readq().
Configuration
----------------------
diff --git a/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
index cc60e9efdc..882728d541 100644
--- a/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
+++ b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
@@ -16,7 +16,7 @@ If a platform has its own driver, please provide your own compatible
string.
2)
- reg = <0x0 0x08000000 0x0 0x00200000>;
+ reg = /bits/ 64 <0x08000000 0x00200000>;
The start address and size of the flash device. The values give here are an
example (when the cell size is 2).
@@ -43,14 +43,14 @@ Example of multiple flash devices
nvmxip-qspi1@08000000 {
compatible = "nvmxip,qspi";
- reg = <0x0 0x08000000 0x0 0x00200000>;
+ reg = /bits/ 64 <0x08000000 0x00200000>;
lba_shift = <9>;
lba = <4096>;
};
nvmxip-qspi2@08200000 {
compatible = "nvmxip,qspi";
- reg = <0x0 0x08200000 0x0 0x00100000>;
+ reg = /bits/ 64 <0x08200000 0x00100000>;
lba_shift = <9>;
lba = <2048>;
};
diff --git a/drivers/mtd/nvmxip/nvmxip-uclass.c b/drivers/mtd/nvmxip/nvmxip-uclass.c
index 9f96041e3d..6d8eb177b5 100644
--- a/drivers/mtd/nvmxip/nvmxip-uclass.c
+++ b/drivers/mtd/nvmxip/nvmxip-uclass.c
@@ -9,6 +9,9 @@
#include <common.h>
#include <dm.h>
#include <log.h>
+#if CONFIG_IS_ENABLED(SANDBOX64)
+#include <asm/test.h>
+#endif
#include <linux/bitops.h>
#include "nvmxip.h"
@@ -36,6 +39,10 @@ static int nvmxip_post_bind(struct udevice *udev)
char bdev_name[NVMXIP_BLKDEV_NAME_SZ + 1];
int devnum;
+#if CONFIG_IS_ENABLED(SANDBOX64)
+ sandbox_set_enable_memio(true);
+#endif
+
devnum = uclass_id_count(UCLASS_NVMXIP);
snprintf(bdev_name, NVMXIP_BLKDEV_NAME_SZ, "blk#%d", devnum);
--
2.25.1
@@ -0,0 +1,42 @@
From 635848c90343a1b8a268519e3fc78ef7af2e4819 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Mon, 19 Dec 2022 13:20:19 +0000
Subject: [PATCH 31/42] corstone1000: add NVM XIP QSPI device tree node
add QSPI flash device node for block storage access
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c]
---
arch/arm/dts/corstone1000.dtsi | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/corstone1000.dtsi b/arch/arm/dts/corstone1000.dtsi
index 61e0c33247..18c4d1e19a 100644
--- a/arch/arm/dts/corstone1000.dtsi
+++ b/arch/arm/dts/corstone1000.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 or MIT
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
* Copyright (c) 2022, Linaro Limited. All rights reserved.
*
*/
@@ -38,6 +38,13 @@
reg = <0x88200000 0x77e00000>;
};
+ nvmxip-qspi@08000000 {
+ compatible = "nvmxip,qspi";
+ reg = <0x08000000 0x2000000>;
+ lba_shift = <9>;
+ lba = <65536>;
+ };
+
gic: interrupt-controller@1c000000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
--
2.25.1
@@ -0,0 +1,219 @@
From 0ecb61da60febc66e589d6fbf439478af1c88283 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Mon, 12 Jun 2023 17:33:54 +0100
Subject: [PATCH 32/42] sandbox64: add a test case for UCLASS_NVMXIP
provide a test for NVM XIP devices
The test case allows to make sure of the following:
- The NVM XIP QSPI devices are probed
- The DT entries are read correctly
- the data read from the flash by the NVMXIP block driver is correct
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c]
Changelog:
===============
v2:
* address nits
---
MAINTAINERS | 1 +
test/dm/Makefile | 6 +-
test/dm/nvmxip.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 151 insertions(+), 1 deletion(-)
create mode 100644 test/dm/nvmxip.c
diff --git a/MAINTAINERS b/MAINTAINERS
index f81654346e..6692ce9974 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1208,6 +1208,7 @@ S: Maintained
F: doc/develop/driver-model/nvmxip.rst
F: doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
F: drivers/mtd/nvmxip/
+F: test/dm/nvmxip.c
NVMEM
M: Sean Anderson <seanga2@gmail.com>
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 85e99e1c12..963fa927f7 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2013 Google, Inc
-# (C) Copyright 2022 ARM Limited
+# Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
obj-$(CONFIG_UT_DM) += test-dm.o
@@ -18,6 +18,10 @@ obj-$(CONFIG_UT_DM) += test-uclass.o
obj-$(CONFIG_UT_DM) += core.o
obj-$(CONFIG_UT_DM) += read.o
obj-$(CONFIG_UT_DM) += phys2bus.o
+ifeq ($(CONFIG_NVMXIP_QSPI)$(CONFIG_SANDBOX64),yy)
+obj-y += nvmxip.o
+endif
+
ifneq ($(CONFIG_SANDBOX),)
ifeq ($(CONFIG_ACPIGEN),y)
obj-y += acpi.o
diff --git a/test/dm/nvmxip.c b/test/dm/nvmxip.c
new file mode 100644
index 0000000000..e934748eb5
--- /dev/null
+++ b/test/dm/nvmxip.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Functional tests for UCLASS_FFA class
+ *
+ * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <console.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <dm/test.h>
+#include <linux/bitops.h>
+#include <test/test.h>
+#include <test/ut.h>
+#include "../../drivers/mtd/nvmxip/nvmxip.h"
+
+/* NVMXIP devices described in the device tree */
+#define SANDBOX_NVMXIP_DEVICES 2
+
+/* reference device tree data for the probed devices */
+static struct nvmxip_plat nvmqspi_refdata[SANDBOX_NVMXIP_DEVICES] = {
+ {0x08000000, 9, 4096}, {0x08200000, 9, 2048}
+};
+
+#define NVMXIP_BLK_START_PATTERN 0x1122334455667788ULL
+#define NVMXIP_BLK_END_PATTERN 0xa1a2a3a4a5a6a7a8ULL
+
+/**
+ * dm_nvmxip_flash_sanity() - check flash data
+ * @uts: test state
+ * @device_idx: the NVMXIP device index
+ * @buffer: the user buffer where the blocks data is copied to
+ *
+ * Mode 1: When buffer is NULL, initialize the flash with pattern data at the start
+ * and at the end of each block. This pattern data will be used to check data consistency
+ * when verifying the data read.
+ * Mode 2: When the user buffer is provided in the argument (not NULL), compare the data
+ * of the start and the end of each block in the user buffer with the expected pattern data.
+ * Return an error when the check fails.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+static int dm_nvmxip_flash_sanity(struct unit_test_state *uts, u8 device_idx, void *buffer)
+{
+ int i;
+ u64 *ptr;
+ u8 *base;
+ unsigned long blksz;
+
+ blksz = BIT(nvmqspi_refdata[device_idx].lba_shift);
+
+ if (!buffer) {
+ /* Mode 1: point at the flash start address. Pattern data will be written */
+ base = map_sysmem(nvmqspi_refdata[device_idx].phys_base, 0);
+ } else {
+ /* Mode 2: point at the user buffer containing the data read and to be verified */
+ base = buffer;
+ }
+
+ for (i = 0; i < nvmqspi_refdata[device_idx].lba ; i++) {
+ ptr = (u64 *)(base + i * blksz);
+
+ /* write an 8 bytes pattern at the start of the current block */
+ if (!buffer)
+ *ptr = NVMXIP_BLK_START_PATTERN;
+ else
+ ut_asserteq_64(NVMXIP_BLK_START_PATTERN, *ptr);
+
+ ptr = (u64 *)((u8 *)ptr + blksz - sizeof(u64));
+
+ /* write an 8 bytes pattern at the end of the current block */
+ if (!buffer)
+ *ptr = NVMXIP_BLK_END_PATTERN;
+ else
+ ut_asserteq_64(NVMXIP_BLK_END_PATTERN, *ptr);
+ }
+
+ if (!buffer)
+ unmap_sysmem(base);
+
+ return 0;
+}
+
+/**
+ * dm_test_nvmxip() - check flash data
+ * @uts: test state
+ * Return:
+ *
+ * CMD_RET_SUCCESS on success. Otherwise, failure
+ */
+static int dm_test_nvmxip(struct unit_test_state *uts)
+{
+ struct nvmxip_plat *plat_data = NULL;
+ struct udevice *dev = NULL, *bdev = NULL;
+ u8 device_idx;
+ void *buffer = NULL;
+ unsigned long flashsz;
+
+ /* set the flash content first for both devices */
+ dm_nvmxip_flash_sanity(uts, 0, NULL);
+ dm_nvmxip_flash_sanity(uts, 1, NULL);
+
+ /* probing all NVM XIP QSPI devices */
+ for (device_idx = 0, uclass_first_device(UCLASS_NVMXIP, &dev);
+ dev;
+ uclass_next_device(&dev), device_idx++) {
+ plat_data = dev_get_plat(dev);
+
+ /* device tree entries checks */
+ ut_assertok(nvmqspi_refdata[device_idx].phys_base != plat_data->phys_base);
+ ut_assertok(nvmqspi_refdata[device_idx].lba_shift != plat_data->lba_shift);
+ ut_assertok(nvmqspi_refdata[device_idx].lba != plat_data->lba);
+
+ /* before reading all the flash blocks, let's calculate the flash size */
+ flashsz = plat_data->lba << plat_data->lba_shift;
+
+ /* allocate the user buffer where to copy the blocks data to */
+ buffer = calloc(flashsz, 1);
+ ut_assertok(!buffer);
+
+ /* the block device is the child of the parent device probed with DT */
+ ut_assertok(device_find_first_child(dev, &bdev));
+
+ /* reading all the flash blocks */
+ ut_asserteq(plat_data->lba, blk_read(bdev, 0, plat_data->lba, buffer));
+
+ /* compare the data read from flash with the expected data */
+ dm_nvmxip_flash_sanity(uts, device_idx, buffer);
+
+ free(buffer);
+ }
+
+ ut_assertok(device_idx != SANDBOX_NVMXIP_DEVICES);
+
+ return CMD_RET_SUCCESS;
+}
+
+DM_TEST(dm_test_nvmxip, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);
--
2.25.1
@@ -0,0 +1,42 @@
From e2fb90ab15babd146dd47b7c946674cd5a5260a1 Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Wed, 1 Feb 2023 15:58:07 +0000
Subject: [PATCH 33/42] corstone1000: add fwu-metadata store info
Add fwu-mdata node and handle for the reference
nvmxip-qspi.
Upstream-Status: Submitted
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
arch/arm/dts/corstone1000.dtsi | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/corstone1000.dtsi b/arch/arm/dts/corstone1000.dtsi
index 18c4d1e19a..25a032b6b3 100644
--- a/arch/arm/dts/corstone1000.dtsi
+++ b/arch/arm/dts/corstone1000.dtsi
@@ -38,7 +38,7 @@
reg = <0x88200000 0x77e00000>;
};
- nvmxip-qspi@08000000 {
+ nvmxip: nvmxip-qspi@08000000 {
compatible = "nvmxip,qspi";
reg = <0x08000000 0x2000000>;
lba_shift = <9>;
@@ -106,6 +106,11 @@
method = "smc";
};
+ fwu-mdata {
+ compatible = "u-boot,fwu-mdata-gpt";
+ fwu-mdata-store = <&nvmxip>;
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <1>;
--
2.25.1
@@ -0,0 +1,50 @@
From ac77679ffcb4b7fac01414c1492d3e1aae13f9be Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Wed, 1 Feb 2023 16:13:24 +0000
Subject: [PATCH 35/42] fwu_metadata: make sure structures are packed
The fwu metadata in the metadata partitions
should/are packed to guarantee that the info is
correct in all platforms. Also the size of them
are used to calculate the crc32 and that is important
to get it right.
Upstream-Status: Pending
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
include/fwu_mdata.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/fwu_mdata.h b/include/fwu_mdata.h
index 8fda4f4ac2..c61221a917 100644
--- a/include/fwu_mdata.h
+++ b/include/fwu_mdata.h
@@ -22,7 +22,7 @@ struct fwu_image_bank_info {
efi_guid_t image_uuid;
uint32_t accepted;
uint32_t reserved;
-};
+} __packed;
/**
* struct fwu_image_entry - information for a particular type of image
@@ -38,7 +38,7 @@ struct fwu_image_entry {
efi_guid_t image_type_uuid;
efi_guid_t location_uuid;
struct fwu_image_bank_info img_bank_info[CONFIG_FWU_NUM_BANKS];
-};
+} __packed;
/**
* struct fwu_mdata - FWU metadata structure for multi-bank updates
@@ -62,6 +62,6 @@ struct fwu_mdata {
uint32_t previous_active_index;
struct fwu_image_entry img_entry[CONFIG_FWU_NUM_IMAGES_PER_BANK];
-};
+} __packed;
#endif /* _FWU_MDATA_H_ */
--
2.25.1
@@ -0,0 +1,33 @@
From 92948559987d02baf9f690d9bbdc96d1179264ef Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Wed, 1 Feb 2023 16:15:30 +0000
Subject: [PATCH 36/42] corstone1000: add boot index
it is expected that the firmware that runs before
u-boot somehow provide the information of the bank
(index) of it is booting.
We will need to extend tf-a to pass that info,
meanwhile just set it to the default bank.
Upstream-Status: Pending
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
board/armltd/corstone1000/corstone1000.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index d6ca6e8961..0a58ccd99c 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -106,6 +106,7 @@ int dram_init_banksize(void)
return 0;
}
-void reset_cpu(ulong addr)
+void fwu_plat_get_bootidx(int *boot_idx)
{
+ *boot_idx = 0;
}
--
2.25.1
@@ -0,0 +1,36 @@
From 1a54c12aa6eed28a1a4e4f50d1aeb92a31cf6f52 Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Wed, 1 Feb 2023 16:17:21 +0000
Subject: [PATCH 37/42] corstone1000: adjust boot bank and kernel location
Adjust in the env boot script the address of the
bootbank with the new gpt layout, and also the
kernel partition address. Please be aware that
this is hack and needs a proper fix, since the
offset of the kernel partition is not fixed,
but for the propose of PoC it is enough for testing.
Upstream-Status: Pending
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
board/armltd/corstone1000/corstone1000.env | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/board/armltd/corstone1000/corstone1000.env b/board/armltd/corstone1000/corstone1000.env
index b24ff07fc6..a6ee496221 100644
--- a/board/armltd/corstone1000/corstone1000.env
+++ b/board/armltd/corstone1000/corstone1000.env
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0+ */
usb_pgood_delay=250
-boot_bank_flag=0x08002000
-kernel_addr_bank_0=0x083EE000
+boot_bank_flag=0x08005006
+kernel_addr_bank_0=0x08280000
kernel_addr_bank_1=0x0936E000
retrieve_kernel_load_addr=
if itest.l *${boot_bank_flag} == 0; then
--
2.25.1
@@ -0,0 +1,100 @@
From 5e0b7e40c4702d5494378d3e120fce0136f69a79 Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Fri, 9 Jun 2023 13:28:06 +0100
Subject: [PATCH 38/42] corstone1000: add nvmxip, fwu-mdata and gpt options
Enable the newest features: nvmxip, fwu-metadata and
gpt. Commands to print the partition info, gpt info
and fwu metadata will be available.
Upstream-Status: Pending
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
configs/corstone1000_defconfig | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index 1179bf5f3b..c38113ce95 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -4,18 +4,20 @@ CONFIG_TARGET_CORSTONE1000=y
CONFIG_TEXT_BASE=0x80000000
CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x83f00000
+CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="corstone1000-mps3"
CONFIG_SYS_PROMPT="corstone1000# "
CONFIG_IDENT_STRING=" corstone1000 aarch64 "
CONFIG_SYS_LOAD_ADDR=0x82100000
+CONFIG_FWU_NUM_IMAGES_PER_BANK=4
CONFIG_DISTRO_DEFAULTS=y
-CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x83f00000
CONFIG_FIT=y
CONFIG_BOOTDELAY=3
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0 loglevel=9 ip=dhcp earlyprintk"
-CONFIG_BOOTCOMMAND="run retrieve_kernel_load_addr; echo Loading kernel from $kernel_addr to memory ... ; unzip $kernel_addr 0x90000000; loadm 0x90000000 $kernel_addr_r 0xf00000; usb start; usb reset; run distro_bootcmd; bootefi $kernel_addr_r $fdtcontroladdr;"
+CONFIG_BOOTCOMMAND="echo Loading kernel from $kernel_addr to memory ... ; unzip $kernel_addr 0x90000000; loadm 0x90000000 $kernel_addr_r 0xf00000; usb start; usb reset; run distro_bootcmd; bootefi $kernel_addr_r $fdtcontroladdr;"
CONFIG_CONSOLE_RECORD=y
CONFIG_LOGLEVEL=7
# CONFIG_DISPLAY_CPUINFO is not set
@@ -23,11 +25,15 @@ CONFIG_LOGLEVEL=7
CONFIG_SYS_MAXARGS=64
CONFIG_SYS_CBSIZE=512
# CONFIG_CMD_CONSOLE is not set
+CONFIG_CMD_FWU_METADATA=y
CONFIG_CMD_BOOTZ=y
CONFIG_SYS_BOOTM_LEN=0x800000
# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_GPT=y
+# CONFIG_RANDOM_UUID is not set
CONFIG_CMD_LOADM=y
# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
# CONFIG_CMD_NFS is not set
@@ -39,27 +45,30 @@ CONFIG_OF_CONTROL=y
CONFIG_VERSION_VARIABLE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
-CONFIG_MISC=y
+CONFIG_ARM_FFA_TRANSPORT=y
CONFIG_CLK=y
-CONFIG_CMD_MMC=y
-CONFIG_DM_MMC=y
+CONFIG_FWU_MDATA=y
+CONFIG_FWU_MDATA_GPT_BLK=y
+CONFIG_MISC=y
CONFIG_ARM_PL180_MMCI=y
-CONFIG_MMC_SDHCI_ADMA_HELPERS=y
-CONFIG_MMC_WRITE=y
-CONFIG_DM_GPIO=y
CONFIG_PHYLIB=y
CONFIG_PHY_SMSC=y
CONFIG_SMC911X=y
+CONFIG_NVMXIP_QSPI=y
CONFIG_PHY=y
CONFIG_RAM=y
CONFIG_DM_RTC=y
CONFIG_RTC_EMULATION=y
CONFIG_DM_SERIAL=y
+CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_ISP1760=y
CONFIG_ERRNO_STR=y
CONFIG_EFI_MM_COMM_TEE=y
CONFIG_ARM_FFA_TRANSPORT=y
CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_IGNORE_OSINDICATIONS=y
CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y
-CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+CONFIG_FWU_MULTI_BANK_UPDATE=y
+# CONFIG_TOOLS_MKEFICAPSULE is not set
--
2.25.1
@@ -0,0 +1,42 @@
From d280414229d7bbee368f40be6cde17e4f251dd0f Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Fri, 9 Jun 2023 13:31:53 +0100
Subject: [PATCH 39/42] nvmxip: move header to include
Move header to include to allow external code
to get the internal bdev structures to access
block device operations.
as at it, just add the UCLASS_NVMXIP string
so we get the correct output in partitions
listing.
Upstream-Status: Pending
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
disk/part.c | 3 +++
{drivers/mtd/nvmxip => include}/nvmxip.h | 0
2 files changed, 3 insertions(+)
rename {drivers/mtd/nvmxip => include}/nvmxip.h (100%)
diff --git a/disk/part.c b/disk/part.c
index 5ee60a7fb5..593dd0004f 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -270,6 +270,9 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc)
case UCLASS_NVME:
puts ("NVMe");
break;
+ case UCLASS_NVMXIP:
+ puts ("NVMXIP");
+ break;
case UCLASS_PVBLOCK:
puts("PV BLOCK");
break;
diff --git a/drivers/mtd/nvmxip/nvmxip.h b/include/nvmxip.h
similarity index 100%
rename from drivers/mtd/nvmxip/nvmxip.h
rename to include/nvmxip.h
--
2.25.1
@@ -0,0 +1,133 @@
From e7cb997fd59c883572994b504dbc77bc670de8f7 Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Thu, 23 Feb 2023 10:35:00 +0000
Subject: [PATCH 40/42] corstone1000: set kernel_addr based on boot_idx
We need to distinguish between boot banks and from which
partition to load the kernel+initramfs to memory.
For that, fetch the boot index, fetch the correspondent
partition, calculate the correct kernel address and
then set the env variable kernel_addr with that value.
Upstream-Status: Pending
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
board/armltd/corstone1000/corstone1000.c | 58 +++++++++++++++++++++-
board/armltd/corstone1000/corstone1000.env | 8 ---
configs/corstone1000_defconfig | 1 +
3 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index 0a58ccd99c..b767195ccc 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -5,13 +5,23 @@
* Rui Miguel Silva <rui.silva@linaro.org>
*/
+#include <blk.h>
#include <common.h>
#include <dm.h>
+#include <env.h>
#include <netdev.h>
+#include <nvmxip.h>
+#include <part.h>
#include <dm/platform_data/serial_pl01x.h>
#include <asm/armv8/mmu.h>
#include <asm/global_data.h>
+#define CORSTONE1000_KERNEL_PARTS 2
+#define CORSTONE1000_KERNEL_PRIMARY "kernel_primary"
+#define CORSTONE1000_KERNEL_SECONDARY "kernel_secondary"
+
+static int corstone1000_boot_idx;
+
static struct mm_region corstone1000_mem_map[] = {
{
/* CVM */
@@ -108,5 +118,51 @@ int dram_init_banksize(void)
void fwu_plat_get_bootidx(int *boot_idx)
{
- *boot_idx = 0;
+ *boot_idx = corstone1000_boot_idx;
+}
+
+int board_late_init(void)
+{
+ struct disk_partition part_info;
+ struct udevice *dev, *bdev;
+ struct nvmxip_plat *plat;
+ struct blk_desc *desc;
+ int ret;
+
+ ret = uclass_first_device_err(UCLASS_NVMXIP, &dev);
+ if (ret < 0) {
+ log_err("Cannot find kernel device\n");
+ return ret;
+ }
+
+ plat = dev_get_plat(dev);
+ device_find_first_child(dev, &bdev);
+ desc = dev_get_uclass_plat(bdev);
+ ret = fwu_get_active_index(&corstone1000_boot_idx);
+ if (ret < 0)
+ log_err("corstone1000: failed to read boot index\n");
+
+ if (!corstone1000_boot_idx)
+ ret = part_get_info_by_name(desc, CORSTONE1000_KERNEL_PRIMARY,
+ &part_info);
+ else
+ ret = part_get_info_by_name(desc, CORSTONE1000_KERNEL_SECONDARY,
+ &part_info);
+
+ if (ret < 0) {
+ log_err("failed to fetch kernel partition index: %d\n",
+ corstone1000_boot_idx);
+ return ret;
+ }
+
+ ret = 0;
+
+ ret |= env_set_hex("kernel_addr", plat->phys_base +
+ (part_info.start * part_info.blksz));
+ ret |= env_set_hex("kernel_size", part_info.size * part_info.blksz);
+
+ if (ret < 0)
+ log_err("failed to setup kernel addr and size\n");
+
+ return ret;
}
diff --git a/board/armltd/corstone1000/corstone1000.env b/board/armltd/corstone1000/corstone1000.env
index a6ee496221..ee318b1b1c 100644
--- a/board/armltd/corstone1000/corstone1000.env
+++ b/board/armltd/corstone1000/corstone1000.env
@@ -2,12 +2,4 @@
usb_pgood_delay=250
boot_bank_flag=0x08005006
-kernel_addr_bank_0=0x08280000
-kernel_addr_bank_1=0x0936E000
-retrieve_kernel_load_addr=
- if itest.l *${boot_bank_flag} == 0; then
- setenv kernel_addr $kernel_addr_bank_0;
- else
- setenv kernel_addr $kernel_addr_bank_1;
- fi;
kernel_addr_r=0x88200000
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index c38113ce95..20359cb181 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -22,6 +22,7 @@ CONFIG_CONSOLE_RECORD=y
CONFIG_LOGLEVEL=7
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_BOARD_LATE_INIT=y
CONFIG_SYS_MAXARGS=64
CONFIG_SYS_CBSIZE=512
# CONFIG_CMD_CONSOLE is not set
--
2.25.1
@@ -0,0 +1,42 @@
From ab07a26290e44fb198403b658b8f1550e959a0cc Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Mon, 27 Feb 2023 14:40:13 +0000
Subject: [PATCH 41/42] corstone1000: boot index from active
In our platform, the Secure Enclave is the one who control
all the boot tries and status, so, every time we get here
we know that the we are booting from the active index.
Upstream-Status: Pending
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
board/armltd/corstone1000/corstone1000.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index b767195ccc..db508ac3cb 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -118,7 +118,18 @@ int dram_init_banksize(void)
void fwu_plat_get_bootidx(int *boot_idx)
{
- *boot_idx = corstone1000_boot_idx;
+ int ret;
+
+ /*
+ * in our platform, the Secure Enclave is the one who control
+ * all the boot tries and status, so, every time we get here
+ * we know that the we are booting from the active index
+ */
+ ret = fwu_get_active_index(boot_idx);
+ if (ret < 0)
+ log_err("corstone1000: failed to read active index\n");
+
+ return ret;
}
int board_late_init(void)
--
2.25.1
@@ -0,0 +1,30 @@
From 8bf48a56aa014146a8950532906b06e191754daa Mon Sep 17 00:00:00 2001
From: Emekcan Aras <emekcan.aras@arm.com>
Date: Wed, 24 May 2023 09:12:11 +0100
Subject: [PATCH 42/42] corstone1000: enable PSCI reset
Even though corstone1000 does not implement entire PSCI APIs,it relies on
PSCI reset interface for the system reset. U-boot change the config name, so we
need to enable it again.
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <emekcan.aras@arm.com>
---
configs/corstone1000_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index 20359cb181..19fe1432ae 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -62,6 +62,7 @@ CONFIG_DM_RTC=y
CONFIG_RTC_EMULATION=y
CONFIG_DM_SERIAL=y
CONFIG_SYSRESET=y
+CONFIG_SYSRESET_PSCI=y
CONFIG_USB=y
CONFIG_USB_ISP1760=y
CONFIG_ERRNO_STR=y
--
2.25.1
@@ -0,0 +1,32 @@
From 9f326f0db8aa13fde93e2ed79055b920c8598a28 Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Mon, 12 Jun 2023 15:14:52 +0000
Subject: [PATCH] Enable EFI set/get time services
SetTime_Conf and SetTime_Func tests in UEFI SCT test suite of ACS
fails with unsupported return value. CONFIG_EFI_SET_TIME and
CONFIG_EFI_GET_TIME config values are added to enable these EFI
services.
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
configs/corstone1000_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index c692cc91bd..f1901dfe8b 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -7,6 +7,8 @@ CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x83f00000
CONFIG_DM_GPIO=y
+CONFIG_EFI_SET_TIME=y
+CONFIG_EFI_GET_TIME=y
CONFIG_DEFAULT_DEVICE_TREE="corstone1000-mps3"
CONFIG_SYS_PROMPT="corstone1000# "
CONFIG_IDENT_STRING=" corstone1000 aarch64 "
--
2.17.1
@@ -0,0 +1,47 @@
From dfebda98ce08d0cab411521ab3d9e832ed1b4608 Mon Sep 17 00:00:00 2001
From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Date: Thu, 15 Jun 2023 16:51:49 +0100
Subject: [PATCH] corstone1000: fix compilation warnings in
fwu_plat_get_bootidx()
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
---
board/armltd/corstone1000/corstone1000.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index db508ac3cb..2e1ace5d04 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -9,6 +9,7 @@
#include <common.h>
#include <dm.h>
#include <env.h>
+#include <fwu.h>
#include <netdev.h>
#include <nvmxip.h>
#include <part.h>
@@ -116,7 +117,7 @@ int dram_init_banksize(void)
return 0;
}
-void fwu_plat_get_bootidx(int *boot_idx)
+void fwu_plat_get_bootidx(uint *boot_idx)
{
int ret;
@@ -127,9 +128,7 @@ void fwu_plat_get_bootidx(int *boot_idx)
*/
ret = fwu_get_active_index(boot_idx);
if (ret < 0)
- log_err("corstone1000: failed to read active index\n");
-
- return ret;
+ log_err("corstone1000: failed to read active index err %d\n", ret);
}
int board_late_init(void)
--
2.25.1
@@ -0,0 +1,140 @@
From 2bb9fb8414b8ad35ed5fc6c91a34c21cef285a01 Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Wed, 18 Dec 2019 21:52:34 +0000
Subject: [PATCH 1/2] armv7: adding generic timer access through MMIO
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
This driver enables the ARMv7 generic timer.
The access to the timer registers is through memory mapping (MMIO).
This driver can be used by u-boot to access to the timer through MMIO
when arch_timer is not available in the core (access using system
instructions not possible), for example, in case of Cortex-A5.
This driver configures and enables the generic timer at
the u-boot initcall level (timer_init) before u-boot relocation.
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
%% original patch: 0001-armv7-adding-generic-timer-access-through-MMIO.patch
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
arch/arm/cpu/armv7/Makefile | 1 +
arch/arm/cpu/armv7/mmio_timer.c | 75 +++++++++++++++++++++++++++++++++
scripts/config_whitelist.txt | 1 +
3 files changed, 77 insertions(+)
create mode 100644 arch/arm/cpu/armv7/mmio_timer.c
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index bfbd85ae64ef..1a0a24e53110 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o
obj-$(CONFIG_IPROC) += iproc-common/
obj-$(CONFIG_KONA) += kona-common/
obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o
+obj-$(CONFIG_SYS_MMIO_TIMER) += mmio_timer.o
ifneq (,$(filter s5pc1xx exynos,$(SOC)))
obj-y += s5p-common/
diff --git a/arch/arm/cpu/armv7/mmio_timer.c b/arch/arm/cpu/armv7/mmio_timer.c
new file mode 100644
index 000000000000..edd806e06e42
--- /dev/null
+++ b/arch/arm/cpu/armv7/mmio_timer.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <bootstage.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CNTCTLBASE 0x1a020000UL
+#define CNTREADBASE 0x1a030000UL
+#define CNTEN (1 << 0)
+#define CNTFCREQ (1 << 8)
+
+static inline uint32_t mmio_read32(uintptr_t addr)
+{
+ return *(volatile uint32_t*)addr;
+}
+
+static inline void mmio_write32(uintptr_t addr, uint32_t data)
+{
+ *(volatile uint32_t*)addr = data;
+}
+
+int timer_init(void)
+{
+ /* calculate the frequency in ms */
+ gd->arch.timer_rate_hz = COUNTER_FREQUENCY / CONFIG_SYS_HZ;
+
+ /* configure CNTFID0 register: set the base frequency */
+ mmio_write32(CNTCTLBASE + 0x20, COUNTER_FREQUENCY);
+
+ /*
+ * configure CNTCR register:
+ * enable the generic counter and;
+ * select the first frequency entry
+ */
+ mmio_write32(CNTCTLBASE, CNTFCREQ | CNTEN);
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ return (((u64)(mmio_read32(CNTREADBASE + 0x4)) << 32) |
+ mmio_read32(CNTREADBASE));
+}
+
+ulong get_timer(ulong base)
+{
+ return lldiv(get_ticks(), gd->arch.timer_rate_hz) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ unsigned long endtime;
+
+ endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz,
+ 1000UL);
+
+ endtime += get_ticks();
+
+ while (get_ticks() < endtime)
+ ;
+}
+
+ulong get_tbclk(void)
+{
+ return gd->arch.timer_rate_hz;
+}
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index ea71f9d23449..1496d9b88233 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -610,6 +610,7 @@ CONFIG_SYS_MMC_U_BOOT_DST
CONFIG_SYS_MMC_U_BOOT_OFFS
CONFIG_SYS_MMC_U_BOOT_SIZE
CONFIG_SYS_MMC_U_BOOT_START
+CONFIG_SYS_MMIO_TIMER
CONFIG_SYS_MOR_VAL
CONFIG_SYS_MRAM_BASE
CONFIG_SYS_NAND_AMASK
--
2.39.1
@@ -0,0 +1,299 @@
From 376e7cc533e27f943191d44c112e3812885b8fd1 Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Wed, 8 Jan 2020 09:48:11 +0000
Subject: [PATCH 2/2] board: arm: add corstone500 board
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Add support for the Arm corstone500 platform, with a cortex-a5
chip, add the default configuration, initialization and
makefile for this system.
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
arch/arm/Kconfig | 10 +++
board/armltd/corstone500/Kconfig | 12 +++
board/armltd/corstone500/Makefile | 8 ++
board/armltd/corstone500/corstone500.c | 48 ++++++++++++
configs/corstone500_defconfig | 41 ++++++++++
include/configs/corstone500.h | 102 +++++++++++++++++++++++++
6 files changed, 221 insertions(+)
create mode 100644 board/armltd/corstone500/Kconfig
create mode 100644 board/armltd/corstone500/Makefile
create mode 100644 board/armltd/corstone500/corstone500.c
create mode 100644 configs/corstone500_defconfig
create mode 100644 include/configs/corstone500.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cac4fa09fd32..b875c1ef3d32 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1309,6 +1309,15 @@ config TARGET_CORSTONE1000
select PL01X_SERIAL
select DM
+config TARGET_CORSTONE500
+ bool "Support Corstone500"
+ select CPU_V7A
+ select SEMIHOSTING
+ select PL01X_SERIAL
+ help
+ This enables support for Corstone500 ARM which is a
+ Cortex-A5 system
+
config TARGET_TOTAL_COMPUTE
bool "Support Total Compute Platform"
select ARM64
@@ -2264,6 +2273,7 @@ source "board/bosch/shc/Kconfig"
source "board/bosch/guardian/Kconfig"
source "board/Marvell/octeontx/Kconfig"
source "board/Marvell/octeontx2/Kconfig"
+source "board/armltd/corstone500/Kconfig"
source "board/armltd/vexpress/Kconfig"
source "board/armltd/vexpress64/Kconfig"
source "board/cortina/presidio-asic/Kconfig"
diff --git a/board/armltd/corstone500/Kconfig b/board/armltd/corstone500/Kconfig
new file mode 100644
index 000000000000..8e689bd1fdc8
--- /dev/null
+++ b/board/armltd/corstone500/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_CORSTONE500
+
+config SYS_BOARD
+ default "corstone500"
+
+config SYS_VENDOR
+ default "armltd"
+
+config SYS_CONFIG_NAME
+ default "corstone500"
+
+endif
diff --git a/board/armltd/corstone500/Makefile b/board/armltd/corstone500/Makefile
new file mode 100644
index 000000000000..6598fdd3ae0d
--- /dev/null
+++ b/board/armltd/corstone500/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2022 ARM Limited
+# (C) Copyright 2022 Linaro
+# Rui Miguel Silva <rui.silva@linaro.org>
+#
+
+obj-y := corstone500.o
diff --git a/board/armltd/corstone500/corstone500.c b/board/armltd/corstone500/corstone500.c
new file mode 100644
index 000000000000..e878f5c6a521
--- /dev/null
+++ b/board/armltd/corstone500/corstone500.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 ARM Limited
+ * (C) Copyright 2022 Linaro
+ * Rui Miguel Silva <rui.silva@linaro.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/platform_data/serial_pl01x.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+
+static const struct pl01x_serial_plat serial_platdata = {
+ .base = V2M_UART0,
+ .type = TYPE_PL011,
+ .clock = CONFIG_PL011_CLOCK,
+};
+
+U_BOOT_DRVINFO(corstone500_serials) = {
+ .name = "serial_pl01x",
+ .plat = &serial_platdata,
+};
+
+int board_init(void)
+{
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+}
+
diff --git a/configs/corstone500_defconfig b/configs/corstone500_defconfig
new file mode 100644
index 000000000000..91661beb8d8d
--- /dev/null
+++ b/configs/corstone500_defconfig
@@ -0,0 +1,41 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_TARGET_CORSTONE500=y
+CONFIG_TEXT_BASE=0x88000000
+CONFIG_SYS_MALLOC_LEN=0x840000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x40000
+CONFIG_SYS_PROMPT="corstone500# "
+CONFIG_IDENT_STRING=" corstone500 aarch32"
+CONFIG_SYS_LOAD_ADDR=0x90000000
+CONFIG_SYS_MEMTEST_START=0x80000000
+CONFIG_SYS_MEMTEST_END=0xff000000
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x83f00000
+CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_BOOTDELAY=1
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0 earlycon=pl011,0x1a200000 root=/dev/ram0 rw loglevel=9"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_CONSOLE is not set
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_ARMFLASH=y
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_FAT=y
+CONFIG_DM=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_DM_SERIAL=y
+CONFIG_OF_LIBFDT=y
diff --git a/include/configs/corstone500.h b/include/configs/corstone500.h
new file mode 100644
index 000000000000..416f5fa4399d
--- /dev/null
+++ b/include/configs/corstone500.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2022 ARM Limited
+ * (C) Copyright 2022 Linaro
+ * Rui Miguel Silva <rui.silva@linaro.org>
+ *
+ * Configuration for Cortex-A5 Corstone500. Parts were derived from other ARM
+ * configurations.
+ */
+
+#ifndef __CORSTONE500_H
+#define __CORSTONE500_H
+
+/* Generic Timer Definitions */
+#define CONFIG_SYS_HZ_CLOCK 7500000
+#define CONFIG_SYS_HZ 1000
+#define COUNTER_FREQUENCY CONFIG_SYS_HZ_CLOCK
+
+#ifdef CONFIG_CORSTONE500_MEMORY_MAP_EXTENDED
+#define V2M_SRAM0 0x00010000
+#define V2M_SRAM1 0x02200000
+#define V2M_QSPI 0x0a800000
+#else
+#define V2M_SRAM0 0x00000000
+#define V2M_SRAM1 0x02000000
+#define V2M_QSPI 0x08000000
+#endif
+
+#define V2M_DEBUG 0x10000000
+#define V2M_BASE_PERIPH 0x1a000000
+#define V2M_A5_PERIPH 0x1c000000
+#define V2M_L2CC_PERIPH 0x1c010000
+
+#define V2M_MASTER_EXPANSION0 0x40000000
+#define V2M_MASTER_EXPANSION1 0x60000000
+
+#define V2M_BASE 0x80000000
+
+#define V2M_PERIPH_OFFSET(x) (x << 16)
+
+#define V2M_SYSID (V2M_BASE_PERIPH)
+#define V2M_SYCTL (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(1))
+#define V2M_COUNTER_CTL (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(2))
+#define V2M_COUNTER_READ (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(3))
+#define V2M_TIMER_CTL (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(4))
+#define V2M_TIMER0 (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(5))
+
+#define V2M_WATCHDOG_CTL (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(16))
+#define V2M_WATCHDOG_REFRESH (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(17))
+
+#define V2M_UART0 (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(32))
+#define V2M_UART1 (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(33))
+
+#define V2M_RTC (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(34))
+#define V2M_TRNG (V2M_BASE_PERIPH + V2M_PERIPH_OFFSET(35))
+
+/* PL011 Serial Configuration */
+#define CONFIG_CONS_INDEX 0
+#define CONFIG_PL011_CLOCK 7500000
+
+/* Physical Memory Map */
+#define PHYS_SDRAM_1 (V2M_BASE)
+
+/* Top 16MB reserved for secure world use */
+#define DRAM_SEC_SIZE 0x01000000
+#define PHYS_SDRAM_1_SIZE (0x80000000 - DRAM_SEC_SIZE)
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+
+#define CONFIG_SYS_MMIO_TIMER
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "kernel_name=Image\0" \
+ "kernel_addr=0x80f00000\0" \
+ "initrd_name=ramdisk.img\0" \
+ "initrd_addr=0x84000000\0" \
+ "fdt_name=devtree.dtb\0" \
+ "fdt_addr=0x83000000\0" \
+ "fdt_high=0xffffffff\0" \
+ "initrd_high=0xffffffff\0"
+
+#define CONFIG_BOOTCOMMAND "echo copy to RAM...; " \
+ "cp.b 0x80100000 $kernel_addr 0xb00000; " \
+ "cp.b 0x80d00000 $initrd_addr 0x800000; " \
+ "bootz $kernel_addr $initrd_addr:0x800000 $fdt_addr"
+
+/* Monitor Command Prompt */
+#define CONFIG_SYS_FLASH_BASE 0x80000000
+/* Store environment at top of flash */
+#define CONFIG_ENV_ADDR 0x0a7c0000
+#define CONFIG_ENV_SECT_SIZE 0x0040000
+
+#define CONFIG_SYS_FLASH_CFI 1
+#define CONFIG_FLASH_CFI_DRIVER 1
+#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_32BIT
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+
+#define CONFIG_SYS_FLASH_EMPTY_INFO /* flinfo indicates empty blocks */
+#define FLASH_MAX_SECTOR_SI 0x00040000
+#define CONFIG_ENV_IS_IN_FLASH 1
+#endif
--
2.39.1
@@ -0,0 +1,44 @@
From 4f649e0a3e0f9ed1f0d6efdff5b14cdc40d84201 Mon Sep 17 00:00:00 2001
From: Jon Mason <jon.mason@arm.com
Date: Thu, 2 Mar 2023 15:22:08 +0000
Subject: [PATCH] Revert "vexpress64: pick DRAM size from DT"
This reverts commit 1a1143a45457161e90ea4cd5f3b0561d924ed8fe.
DRAM is determined via dtb in recent versions. Since fvp isn't
reading and specifying a dtb, this fails and hangs u-boot. Remove this
and go back to the way things were.
Signed-off-by: Jon Mason <jon.mason@arm.com>
Upstream-Status: Inappropriate
---
board/armltd/vexpress64/vexpress64.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
index af326dc6f453..e8ce88b22c5a 100644
--- a/board/armltd/vexpress64/vexpress64.c
+++ b/board/armltd/vexpress64/vexpress64.c
@@ -88,12 +88,20 @@ int board_init(void)
int dram_init(void)
{
- return fdtdec_setup_mem_size_base();
+ gd->ram_size = PHYS_SDRAM_1_SIZE;
+ return 0;
}
int dram_init_banksize(void)
{
- return fdtdec_setup_memory_banksize();
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+#ifdef PHYS_SDRAM_2
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+#endif
+
+ return 0;
}
/* Assigned in lowlevel_init.S
@@ -0,0 +1,4 @@
CONFIG_BOOTARGS="console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda1 rw rootwait"
CONFIG_BOOTCOMMAND="booti $kernel_addr_r - $fdt_addr_r"
# Our FVP support CRC instructions
CONFIG_ARM64_CRC32=y
@@ -0,0 +1,259 @@
From e90aa7853ae32cb03c86249a6c572ec88cdebaa2 Mon Sep 17 00:00:00 2001
From: Peter Hoyes <Peter.Hoyes@arm.com>
Date: Wed, 26 May 2021 17:41:10 +0100
Subject: [PATCH 1/9] armv8: Add ARMv8 MPU configuration logic
Detect whether an MMU is present at the current exception level. If
not, initialize the MPU instead of the MMU during init, and clear the
MPU regions before transition to Linux.
The MSA in use at EL1&0 may be configurable but can only by determined
by inspecting VTCR_EL2 at EL2, so assume that there is an MMU for
backwards compatibility.
Provide a default (blank) MPU memory map, which can be overridden by
board configurations.
Issue-Id: SCM-2443
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Change-Id: I0ee3879f9d7f03fe940664b3551c68eeaa458d17
---
arch/arm/cpu/armv8/cache_v8.c | 101 ++++++++++++++++++++++++++++++-
arch/arm/include/asm/armv8/mpu.h | 59 ++++++++++++++++++
arch/arm/include/asm/system.h | 19 ++++++
3 files changed, 176 insertions(+), 3 deletions(-)
create mode 100644 arch/arm/include/asm/armv8/mpu.h
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index e4736e5643..798aed8058 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -15,6 +15,7 @@
#include <asm/global_data.h>
#include <asm/system.h>
#include <asm/armv8/mmu.h>
+#include <asm/armv8/mpu.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -385,6 +386,91 @@ __weak u64 get_page_table_size(void)
return size;
}
+static void mpu_clear_regions(void)
+{
+ int i;
+
+ for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
+ setup_el2_mpu_region(i, 0, 0);
+ }
+}
+
+static struct mpu_region default_mpu_mem_map[] = {{0,}};
+__weak struct mpu_region *mpu_mem_map = default_mpu_mem_map;
+
+static void mpu_setup(void)
+{
+ int i;
+
+ if (current_el() != 2) {
+ panic("MPU configuration is only supported at EL2");
+ }
+
+ set_sctlr(get_sctlr() & ~(CR_M | CR_WXN));
+
+ asm volatile("msr MAIR_EL2, %0" : : "r" MEMORY_ATTRIBUTES);
+
+ for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
+ setup_el2_mpu_region(i,
+ PRBAR_ADDRESS(mpu_mem_map[i].start)
+ | PRBAR_OUTER_SH | PRBAR_AP_RW_ANY,
+ PRLAR_ADDRESS(mpu_mem_map[i].end)
+ | mpu_mem_map[i].attrs | PRLAR_EN_BIT
+ );
+ }
+
+ set_sctlr(get_sctlr() | CR_M);
+}
+
+static bool el_has_mmu(void)
+{
+ if (current_el() < 2) {
+ // We have no way of knowing, so assuming we have an MMU
+ return true;
+ }
+
+ uint64_t id_aa64mmfr0;
+ asm volatile("mrs %0, id_aa64mmfr0_el1"
+ : "=r" (id_aa64mmfr0) : : "cc");
+ uint64_t msa = id_aa64mmfr0 & ID_AA64MMFR0_EL1_MSA_MASK;
+ uint64_t msa_frac = id_aa64mmfr0 & ID_AA64MMFR0_EL1_MSA_FRAC_MASK;
+
+ switch (msa) {
+ case ID_AA64MMFR0_EL1_MSA_VMSA:
+ /*
+ * VMSA supported in all translation regimes.
+ * No support for PMSA.
+ */
+ return true;
+ case ID_AA64MMFR0_EL1_MSA_USE_FRAC:
+ /* See MSA_frac for the supported MSAs. */
+ switch (msa_frac) {
+ case ID_AA64MMFR0_EL1_MSA_FRAC_NO_PMSA:
+ /*
+ * PMSA not supported in any translation
+ * regime.
+ */
+ return true;
+ case ID_AA64MMFR0_EL1_MSA_FRAC_VMSA:
+ /*
+ * PMSA supported in all translation
+ * regimes. No support for VMSA.
+ */
+ case ID_AA64MMFR0_EL1_MSA_FRAC_PMSA:
+ /*
+ * PMSA supported in all translation
+ * regimes.
+ */
+ return false;
+ default:
+ panic("Unsupported id_aa64mmfr0_el1 " \
+ "MSA_frac value");
+ }
+ default:
+ panic("Unsupported id_aa64mmfr0_el1 MSA value");
+ }
+}
+
void setup_pgtables(void)
{
int i;
@@ -499,8 +585,13 @@ void dcache_enable(void)
/* The data cache is not active unless the mmu is enabled */
if (!(get_sctlr() & CR_M)) {
invalidate_dcache_all();
- __asm_invalidate_tlb_all();
- mmu_setup();
+
+ if (el_has_mmu()) {
+ __asm_invalidate_tlb_all();
+ mmu_setup();
+ } else {
+ mpu_setup();
+ }
}
set_sctlr(get_sctlr() | CR_C);
@@ -519,7 +610,11 @@ void dcache_disable(void)
set_sctlr(sctlr & ~(CR_C|CR_M));
flush_dcache_all();
- __asm_invalidate_tlb_all();
+
+ if (el_has_mmu())
+ __asm_invalidate_tlb_all();
+ else
+ mpu_clear_regions();
}
int dcache_status(void)
diff --git a/arch/arm/include/asm/armv8/mpu.h b/arch/arm/include/asm/armv8/mpu.h
new file mode 100644
index 0000000000..8de627cafd
--- /dev/null
+++ b/arch/arm/include/asm/armv8/mpu.h
@@ -0,0 +1,59 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * (C) Copyright 2021 Arm Limited
+ */
+
+#ifndef _ASM_ARMV8_MPU_H_
+#define _ASM_ARMV8_MPU_H_
+
+#include <asm/armv8/mmu.h>
+#include <linux/stringify.h>
+
+#define PRSELR_EL2 S3_4_c6_c2_1
+#define PRBAR_EL2 S3_4_c6_c8_0
+#define PRLAR_EL2 S3_4_c6_c8_1
+#define MPUIR_EL2 S3_4_c0_c0_4
+
+#define PRBAR_ADDRESS(addr) ((addr) & ~(0x3fULL))
+
+/* Access permissions */
+#define PRBAR_AP(val) (((val) & 0x3) << 2)
+#define PRBAR_AP_RW_HYP PRBAR_AP(0x0)
+#define PRBAR_AP_RW_ANY PRBAR_AP(0x1)
+#define PRBAR_AP_RO_HYP PRBAR_AP(0x2)
+#define PRBAR_AP_RO_ANY PRBAR_AP(0x3)
+
+/* Shareability */
+#define PRBAR_SH(val) (((val) & 0x3) << 4)
+#define PRBAR_NON_SH PRBAR_SH(0x0)
+#define PRBAR_OUTER_SH PRBAR_SH(0x2)
+#define PRBAR_INNER_SH PRBAR_SH(0x3)
+
+/* Memory attribute (MAIR idx) */
+#define PRLAR_ATTRIDX(val) (((val) & 0x7) << 1)
+#define PRLAR_EN_BIT (0x1)
+#define PRLAR_ADDRESS(addr) ((addr) & ~(0x3fULL))
+
+#ifndef __ASSEMBLY__
+
+static inline void setup_el2_mpu_region(uint8_t region, uint64_t base, uint64_t limit)
+{
+ asm volatile("msr " __stringify(PRSELR_EL2) ", %0" : : "r" (region));
+ asm volatile("msr " __stringify(PRBAR_EL2) ", %0" : : "r" (base));
+ asm volatile("msr " __stringify(PRLAR_EL2) ", %0" : : "r" (limit));
+
+ asm volatile("isb");
+}
+
+#endif
+
+struct mpu_region {
+ u64 start;
+ u64 end;
+ u64 attrs;
+};
+
+extern struct mpu_region *mpu_mem_map;
+
+#endif /* _ASM_ARMV8_MPU_H_ */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 87d1c77e8b..4510db98a2 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -95,6 +95,25 @@
auth algorithm */
#define ID_AA64ISAR1_EL1_APA (0xF << 4) /* QARMA address auth algorithm */
+/*
+ * ID_AA64MMFR0_EL1 bits definitions
+ */
+#define ID_AA64MMFR0_EL1_MSA_FRAC_MASK (0xFUL << 52) /* Memory system
+ architecture
+ frac */
+#define ID_AA64MMFR0_EL1_MSA_FRAC_VMSA (0x2UL << 52) /* EL1&0 supports
+ VMSA */
+#define ID_AA64MMFR0_EL1_MSA_FRAC_PMSA (0x1UL << 52) /* EL1&0 only
+ supports PMSA*/
+#define ID_AA64MMFR0_EL1_MSA_FRAC_NO_PMSA (0x0UL << 52) /* No PMSA
+ support */
+#define ID_AA64MMFR0_EL1_MSA_MASK (0xFUL << 48) /* Memory system
+ architecture */
+#define ID_AA64MMFR0_EL1_MSA_USE_FRAC (0xFUL << 48) /* Use MSA_FRAC */
+#define ID_AA64MMFR0_EL1_MSA_VMSA (0x0UL << 48) /* Memory system
+ architecture
+ is VMSA */
+
/*
* ID_AA64PFR0_EL1 bits definitions
*/
--
2.25.1
@@ -0,0 +1,61 @@
From 181f5efb401ffaa5ab0898b07a976796f75e502a Mon Sep 17 00:00:00 2001
From: Qi Feng <qi.feng@arm.com>
Date: Tue, 26 Jul 2022 18:13:23 +0800
Subject: [PATCH 2/9] vexpress64: add MPU memory map for the BASER_FVP
The previous patch added support for initializing an Armv8 MPU. There is only an
MPU at S-EL2 on the BASER_FVP, so add a platform-specific MPU memory map.
See https://developer.arm.com/documentation/100964/1117/Base-Platform/Base---memory/BaseR-Platform-memory-map
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Signed-off-by: Qi Feng <qi.feng@arm.com>
---
board/armltd/vexpress64/vexpress64.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
index af326dc6f4..2310d18eb7 100644
--- a/board/armltd/vexpress64/vexpress64.c
+++ b/board/armltd/vexpress64/vexpress64.c
@@ -19,6 +19,7 @@
#include <dm/platform_data/serial_pl01x.h>
#include "pcie.h"
#include <asm/armv8/mmu.h>
+#include <asm/armv8/mpu.h>
#ifdef CONFIG_VIRTIO_NET
#include <virtio_types.h>
#include <virtio.h>
@@ -37,6 +38,27 @@ U_BOOT_DRVINFO(vexpress_serials) = {
.plat = &serial_plat,
};
+static struct mpu_region vexpress64_aemv8r_mem_map[] = {
+ {
+ .start = 0x0UL,
+ .end = 0x7fffffffUL,
+ .attrs = PRLAR_ATTRIDX(MT_NORMAL)
+ }, {
+ .start = 0x80000000UL,
+ .end = 0xffffffffUL,
+ .attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE)
+ }, {
+ .start = 0x100000000UL,
+ .end = 0xffffffffffUL,
+ .attrs = PRLAR_ATTRIDX(MT_NORMAL)
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mpu_region *mpu_mem_map = vexpress64_aemv8r_mem_map;
+
static struct mm_region vexpress64_mem_map[] = {
{
.virt = V2M_PA_BASE,
--
2.25.1
@@ -0,0 +1,107 @@
From 07cc3e4af3def76d92faf39712d4fd8717b21d2b Mon Sep 17 00:00:00 2001
From: Peter Hoyes <Peter.Hoyes@arm.com>
Date: Fri, 10 Dec 2021 11:41:19 +0000
Subject: [PATCH 3/9] armv8: Allow disabling exception vectors on non-SPL
builds
On the BASER_FVP, U-Boot shares EL2 with another bootloader, so we do
not wish to overide the exception vector, but we are also not using an
SPL build.
Therefore, add ARMV8_EXCEPTION_VECTORS, which disables exception vectors
in a similar way to ARMV8_SPL_EXCEPTION_VECTORS.
Rename ARMV8_SPL_EXCEPTION_VECTORS -> SPL_ARMV8_EXCEPTION_VECTORS so
that both config flags be be targeted using CONFIG_IS_ENABLED.
Issue-Id: SCM-3728
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Change-Id: I0cf0fc6d7ef4d45791411cf1f67c65e198cc8b2b
---
arch/arm/cpu/armv8/Kconfig | 10 ++++++++--
arch/arm/cpu/armv8/Makefile | 6 ++----
arch/arm/cpu/armv8/start.S | 4 ++--
configs/vexpress_aemv8r_defconfig | 1 +
4 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index 1305238c9d..dec4be0e30 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -1,8 +1,8 @@
if ARM64
-config ARMV8_SPL_EXCEPTION_VECTORS
+config ARMV8_EXCEPTION_VECTORS
bool "Install crash dump exception vectors"
- depends on SPL
+ default y
help
The default exception vector table is only used for the crash
dump, but still takes quite a lot of space in the image size.
@@ -10,6 +10,12 @@ config ARMV8_SPL_EXCEPTION_VECTORS
Say N here if you are running out of code space in the image
and want to save some space at the cost of less debugging info.
+config SPL_ARMV8_EXCEPTION_VECTORS
+ bool "Install crash dump exception vectors in the SPL"
+ depends on SPL
+ help
+ Same as ARMV8_EXCEPTION_VECTORS, but for SPL builds
+
config ARMV8_MULTIENTRY
bool "Enable multiple CPUs to enter into U-Boot"
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index 2e4bf9e038..001a31cae7 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -13,10 +13,8 @@ ifndef CONFIG_$(SPL_)SYS_DCACHE_OFF
obj-y += cache_v8.o
obj-y += cache.o
endif
-ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o
-else
-obj-y += exceptions.o
+obj-$(CONFIG_$(SPL_)ARMV8_EXCEPTION_VECTORS) += exceptions.o
+ifndef CONFIG_SPL_BUILD
obj-y += exception_level.o
endif
obj-y += tlb.o
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index 28f0df13f0..f831e77af3 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -104,7 +104,7 @@ pie_skip_reloc:
pie_fixup_done:
#endif
-#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
+#if CONFIG_IS_ENABLED(ARMV8_EXCEPTION_VECTORS)
.macro set_vbar, regname, reg
msr \regname, \reg
.endm
@@ -354,7 +354,7 @@ ENDPROC(smp_kick_all_cpus)
/*-----------------------------------------------------------------------*/
ENTRY(c_runtime_cpu_setup)
-#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
+#if CONFIG_IS_ENABLED(ARMV8_EXCEPTION_VECTORS)
/* Relocate vBAR */
adr x0, vectors
switch_el x1, 3f, 2f, 1f
diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
index 495eb1dee3..683d983c36 100644
--- a/configs/vexpress_aemv8r_defconfig
+++ b/configs/vexpress_aemv8r_defconfig
@@ -16,3 +16,4 @@ CONFIG_SYS_CBSIZE=512
CONFIG_SYS_PBSIZE=541
# CONFIG_MMC is not set
CONFIG_VIRTIO_MMIO=y
+CONFIG_ARMV8_EXCEPTION_VECTORS=n
--
2.25.1
@@ -0,0 +1,142 @@
From 30405f59881c73946b6b0ffdbf25804f9fbf1585 Mon Sep 17 00:00:00 2001
From: Peter Hoyes <Peter.Hoyes@arm.com>
Date: Wed, 14 Jul 2021 12:44:27 +0100
Subject: [PATCH 4/9] armv8: ARMV8_SWITCH_TO_EL1 improvements
Convert CONFIG_ARMV8_SWITCH_TO_EL1 to a Kconfig variable.
Add support for switching to EL1 to bootefi.
Add the environment variable armv8_switch_to_el1 to allow configuring
whether to switch to EL1 at runtime. This overrides the compile-time
option.
Issue-Id: SCM-3728
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Change-Id: If98478148d6d8d1f732acac5439276700614815f
---
arch/arm/cpu/armv8/exception_level.c | 21 ++++++++++++++--
arch/arm/lib/bootm.c | 36 ++++++++++++++++------------
configs/vexpress_aemv8r_defconfig | 1 +
3 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
index b11936548f..4aad1550f4 100644
--- a/arch/arm/cpu/armv8/exception_level.c
+++ b/arch/arm/cpu/armv8/exception_level.c
@@ -40,19 +40,36 @@ static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
* trusted firmware being one embodiment). The operating system shall be
* started at exception level EL2. So here we check the exception level
* and switch it if necessary.
+ *
+ * If armv8_switch_to_el1 (config or env var) is enabled, also switch to EL1
+ * before booting the operating system.
*/
void switch_to_non_secure_mode(void)
{
struct jmp_buf_data non_secure_jmp;
/* On AArch64 we need to make sure we call our payload in < EL3 */
- if (current_el() == 3) {
+
+ int switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ if (switch_to_el1 == -1) {
+ switch_to_el1 = 1;
+ }
+#endif
+
+ if (current_el() > 2) {
if (setjmp(&non_secure_jmp))
return;
dcache_disable(); /* flush cache before switch to EL2 */
-
/* Move into EL2 and keep running there */
armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
(uintptr_t)entry_non_secure, ES_TO_AARCH64);
+ } else if (switch_to_el1 == 1 && current_el() > 1) {
+ if (setjmp(&non_secure_jmp))
+ return;
+ dcache_disable(); /* flush cache before switch to EL1 */
+ /* Move into EL1 and keep running there */
+ armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0,
+ (uintptr_t)entry_non_secure, ES_TO_AARCH64);
}
}
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 9f086f3b90..b044aeca88 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -270,7 +270,6 @@ __weak void update_os_arch_secondary_cores(uint8_t os_arch)
{
}
-#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
static void switch_to_el1(void)
{
if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
@@ -285,7 +284,6 @@ static void switch_to_el1(void)
ES_TO_AARCH64);
}
#endif
-#endif
/* Subcommand: GO */
static void boot_jump_linux(bootm_headers_t *images, int flag)
@@ -312,21 +310,29 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
update_os_arch_secondary_cores(images->os.arch);
+ int armv8_switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
- (u64)switch_to_el1, ES_TO_AARCH64);
-#else
- if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
- (images->os.arch == IH_ARCH_ARM))
- armv8_switch_to_el2(0, (u64)gd->bd->bi_arch_number,
- (u64)images->ft_addr, 0,
- (u64)images->ep,
- ES_TO_AARCH32);
- else
- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
- images->ep,
- ES_TO_AARCH64);
+ if (armv8_switch_to_el1 == -1) {
+ armv8_switch_to_el1 = 1;
+ }
#endif
+ if (armv8_switch_to_el1 == 1) {
+ armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
+ (u64)switch_to_el1, ES_TO_AARCH64);
+ } else {
+ if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+ (images->os.arch == IH_ARCH_ARM))
+ armv8_switch_to_el2(0,
+ (u64)gd->bd->bi_arch_number,
+ (u64)images->ft_addr, 0,
+ (u64)images->ep,
+ ES_TO_AARCH32);
+ else
+ armv8_switch_to_el2((u64)images->ft_addr,
+ 0, 0, 0,
+ images->ep,
+ ES_TO_AARCH64);
+ }
}
#else
unsigned long machid = gd->bd->bi_arch_number;
diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
index 683d983c36..6044f82b00 100644
--- a/configs/vexpress_aemv8r_defconfig
+++ b/configs/vexpress_aemv8r_defconfig
@@ -17,3 +17,4 @@ CONFIG_SYS_PBSIZE=541
# CONFIG_MMC is not set
CONFIG_VIRTIO_MMIO=y
CONFIG_ARMV8_EXCEPTION_VECTORS=n
+CONFIG_ARMV8_SWITCH_TO_EL1=y
--
2.25.1
@@ -0,0 +1,83 @@
From a6daca56b77d7f1b26483f10eb33ebdd6e157d3e Mon Sep 17 00:00:00 2001
From: Peter Hoyes <Peter.Hoyes@arm.com>
Date: Fri, 10 Dec 2021 16:37:26 +0000
Subject: [PATCH 5/9] armv8: Make disabling HVC configurable when switching to
EL1
On the BASER_FVP there is no EL3, so HVC is used to provide PSCI
services. Therefore we cannot disable hypercalls.
Create CONFIG_ARMV8_DISABLE_HVC (dependent on CONFIG_ARMV8_TO_EL1) to
control whether to disable HVC exceptions in HCR_EL2->HCD
Issue-Id: SCM-3728
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Change-Id: I463d82f1db8a3cafcab40a9c0c208753569cc300
---
arch/arm/cpu/armv8/Kconfig | 9 +++++++++
arch/arm/include/asm/macro.h | 10 ++++++++--
configs/vexpress_aemv8r_defconfig | 1 +
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index dec4be0e30..95c03487a2 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -208,4 +208,13 @@ config ARMV8_CE_SHA256
endif
+config ARMV8_DISABLE_HVC
+ bool "Disable HVC calls before switching to EL1"
+ depends on ARMV8_SWITCH_TO_EL1
+ default y
+ help
+ If switching to EL1 before loading the operating system, disable taking
+ hypercalls back to EL2. May be disabled if, for example, PSCI services are
+ running at EL2.
+
endif
diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h
index 1a1edc9870..7167739210 100644
--- a/arch/arm/include/asm/macro.h
+++ b/arch/arm/include/asm/macro.h
@@ -296,9 +296,12 @@ lr .req x30
ldr \tmp2, =(ID_AA64ISAR1_EL1_GPI | ID_AA64ISAR1_EL1_GPA | \
ID_AA64ISAR1_EL1_API | ID_AA64ISAR1_EL1_APA)
tst \tmp, \tmp2
- mov \tmp2, #(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS)
+ mov \tmp2, #(HCR_EL2_RW_AARCH64)
orr \tmp, \tmp2, #(HCR_EL2_APK | HCR_EL2_API)
csel \tmp, \tmp2, \tmp, eq
+#ifdef CONFIG_ARMV8_DISABLE_HVC
+ orr \tmp, \tmp, #(HCR_EL2_HCD_DIS)
+#endif
msr hcr_el2, \tmp
/* Return to the EL1_SP1 mode from EL2 */
@@ -311,7 +314,10 @@ lr .req x30
1:
/* Initialize HCR_EL2 */
- ldr \tmp, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS)
+ ldr \tmp, =(HCR_EL2_RW_AARCH32)
+#ifdef CONFIG_ARMV8_DISABLE_HVC
+ orr \tmp, \tmp, #(HCR_EL2_HCD_DIS)
+#endif
msr hcr_el2, \tmp
/* Return to AArch32 Supervisor mode from EL2 */
diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
index 6044f82b00..6226f6b2c1 100644
--- a/configs/vexpress_aemv8r_defconfig
+++ b/configs/vexpress_aemv8r_defconfig
@@ -18,3 +18,4 @@ CONFIG_SYS_PBSIZE=541
CONFIG_VIRTIO_MMIO=y
CONFIG_ARMV8_EXCEPTION_VECTORS=n
CONFIG_ARMV8_SWITCH_TO_EL1=y
+CONFIG_ARMV8_DISABLE_HVC=n
--
2.25.1
@@ -0,0 +1,32 @@
From 862d3f1ac66a75cdf48adbdebd8adbaf671a9366 Mon Sep 17 00:00:00 2001
From: Qi Feng <qi.feng@arm.com>
Date: Thu, 28 Jul 2022 17:47:18 +0800
Subject: [PATCH 6/9] vexpress64: Do not set COUNTER_FREQUENCY
VExpress boards normally run as a second-stage bootloader so should not
need to modify CNTFRQ_EL0. On the BASER_FVP, U-Boot can modify it if
running at EL2, but shouldn't because it might be different from the
value being used by the first-stage bootloader (which might be
providing PSCI services).
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Signed-off-by: Qi Feng <qi.feng@arm.com>
---
configs/vexpress_aemv8r_defconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
index 6226f6b2c1..b902a6a7d9 100644
--- a/configs/vexpress_aemv8r_defconfig
+++ b/configs/vexpress_aemv8r_defconfig
@@ -1,5 +1,4 @@
CONFIG_ARM=y
-CONFIG_COUNTER_FREQUENCY=24000000
CONFIG_ARCH_VEXPRESS64=y
CONFIG_NR_DRAM_BANKS=2
CONFIG_DEFAULT_DEVICE_TREE="arm_fvp"
--
2.25.1
@@ -0,0 +1,27 @@
From 32beea722c1167c9b33f1ecfdc28d360cabd6823 Mon Sep 17 00:00:00 2001
From: Peter Hoyes <Peter.Hoyes@arm.com>
Date: Tue, 22 Feb 2022 15:32:51 +0000
Subject: [PATCH 7/9] vexpress64: Enable LIBFDT_OVERLAY in the vexpress_aemv8r
defconfig
Issue-Id: SCM-3874
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Change-Id: Ide0532cf2de89f1bca9c8d4bd2ed0c1a1c57599f
---
configs/vexpress_aemv8r_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
index b902a6a7d9..a58a9db385 100644
--- a/configs/vexpress_aemv8r_defconfig
+++ b/configs/vexpress_aemv8r_defconfig
@@ -18,3 +18,4 @@ CONFIG_VIRTIO_MMIO=y
CONFIG_ARMV8_EXCEPTION_VECTORS=n
CONFIG_ARMV8_SWITCH_TO_EL1=y
CONFIG_ARMV8_DISABLE_HVC=n
+CONFIG_OF_LIBFDT_OVERLAY=y
--
2.25.1
@@ -0,0 +1,105 @@
From 01490ab8deb0f0b61eeb55a02ee5ea430cfe7eee Mon Sep 17 00:00:00 2001
From: Peter Hoyes <Peter.Hoyes@arm.com>
Date: Wed, 18 May 2022 15:24:19 +0100
Subject: [PATCH 8/9] armv8: Allow PRBAR MPU attributes to be configured
In a previous patch, support was added to initialize an S-EL2 MPU on
armv8r64 machines. This implementation allowed the PRLAR attribute
index to be configured, but not the shareability and access permission
attributes in PRBAR. These attributes were hard-coded as "outer
shareable" and "read/write at EL1 and EL0".
Add separate prlar_attrs and prbar_attrs to the MPU region struct so
that these attributes can be configured on a per-region basis.
For the BASER_FVP, ensure the MPU memory attributes match those in the
existing vexpress64 board MMU configuration ("non shareable" for device
memory and "inner shareable" for normal memory).
Issue-Id: SCM-4641
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Change-Id: I6b72aead91ad12412262aa32c61a53e12eab3984
---
arch/arm/cpu/armv8/cache_v8.c | 12 ++++++++----
arch/arm/include/asm/armv8/mpu.h | 3 ++-
board/armltd/vexpress64/vexpress64.c | 9 ++++++---
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 798aed8058..e336339281 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -390,7 +390,9 @@ static void mpu_clear_regions(void)
{
int i;
- for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
+ for (i = 0; mpu_mem_map[i].end ||
+ mpu_mem_map[i].prbar_attrs ||
+ mpu_mem_map[i].prlar_attrs; i++) {
setup_el2_mpu_region(i, 0, 0);
}
}
@@ -410,12 +412,14 @@ static void mpu_setup(void)
asm volatile("msr MAIR_EL2, %0" : : "r" MEMORY_ATTRIBUTES);
- for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
+ for (i = 0; mpu_mem_map[i].end ||
+ mpu_mem_map[i].prbar_attrs ||
+ mpu_mem_map[i].prlar_attrs; i++) {
setup_el2_mpu_region(i,
PRBAR_ADDRESS(mpu_mem_map[i].start)
- | PRBAR_OUTER_SH | PRBAR_AP_RW_ANY,
+ | mpu_mem_map[i].prbar_attrs,
PRLAR_ADDRESS(mpu_mem_map[i].end)
- | mpu_mem_map[i].attrs | PRLAR_EN_BIT
+ | mpu_mem_map[i].prlar_attrs | PRLAR_EN_BIT
);
}
diff --git a/arch/arm/include/asm/armv8/mpu.h b/arch/arm/include/asm/armv8/mpu.h
index 8de627cafd..dd4c689ea6 100644
--- a/arch/arm/include/asm/armv8/mpu.h
+++ b/arch/arm/include/asm/armv8/mpu.h
@@ -51,7 +51,8 @@ static inline void setup_el2_mpu_region(uint8_t region, uint64_t base, uint64_t
struct mpu_region {
u64 start;
u64 end;
- u64 attrs;
+ u64 prbar_attrs;
+ u64 prlar_attrs;
};
extern struct mpu_region *mpu_mem_map;
diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
index 2310d18eb7..531fa4d618 100644
--- a/board/armltd/vexpress64/vexpress64.c
+++ b/board/armltd/vexpress64/vexpress64.c
@@ -42,15 +42,18 @@ static struct mpu_region vexpress64_aemv8r_mem_map[] = {
{
.start = 0x0UL,
.end = 0x7fffffffUL,
- .attrs = PRLAR_ATTRIDX(MT_NORMAL)
+ .prbar_attrs = PRBAR_INNER_SH | PRBAR_AP_RW_ANY,
+ .prlar_attrs = PRLAR_ATTRIDX(MT_NORMAL)
}, {
.start = 0x80000000UL,
.end = 0xffffffffUL,
- .attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE)
+ .prbar_attrs = PRBAR_OUTER_SH | PRBAR_AP_RW_ANY,
+ .prlar_attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE)
}, {
.start = 0x100000000UL,
.end = 0xffffffffffUL,
- .attrs = PRLAR_ATTRIDX(MT_NORMAL)
+ .prbar_attrs = PRBAR_INNER_SH | PRBAR_AP_RW_ANY,
+ .prlar_attrs = PRLAR_ATTRIDX(MT_NORMAL)
}, {
/* List terminator */
0,
--
2.25.1
@@ -0,0 +1,63 @@
From 0f15f6b02825b042ddc1d753f62cf87f30b1fe12 Mon Sep 17 00:00:00 2001
From: Peter Hoyes <Peter.Hoyes@arm.com>
Date: Thu, 19 May 2022 09:02:32 +0100
Subject: [PATCH 9/9] armv8: Enable icache when switching exception levels in
bootefi
bootefi calls the function switch_to_non_secure_mode before calling the
UEFI payload to handle the case where U-Boot is running at EL3.
For AArch64, the UEFI specification states that:
The core will be configured as follows:
* MMU enabled
* Instruction and data caches enabled
These requirements should be followed when switching exception levels
for EFI applications.
This function already disables and re-enables the data cache prior to
switching exception levels, but omits the instruction cache, meaning
the function returns with the instruction cache disabled at the new
exception level. Fix this by calling icache_disable prior to switching
exception levels and icache_enable afterwards.
Issue-Id: SCM-4641
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Upstream-Status: Inappropriate [other]
Implementation pending further discussion
Change-Id: I678cd5ba39b56e124ab7854608289cd14651ce65
---
arch/arm/cpu/armv8/exception_level.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
index 4aad1550f4..0a3e5428e7 100644
--- a/arch/arm/cpu/armv8/exception_level.c
+++ b/arch/arm/cpu/armv8/exception_level.c
@@ -27,6 +27,7 @@
static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
{
dcache_enable();
+ icache_enable();
debug("Reached non-secure mode\n");
/* Restore stack and registers saved in switch_to_non_secure_mode() */
@@ -61,6 +62,7 @@ void switch_to_non_secure_mode(void)
if (setjmp(&non_secure_jmp))
return;
dcache_disable(); /* flush cache before switch to EL2 */
+ icache_disable();
/* Move into EL2 and keep running there */
armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
(uintptr_t)entry_non_secure, ES_TO_AARCH64);
@@ -68,6 +70,7 @@ void switch_to_non_secure_mode(void)
if (setjmp(&non_secure_jmp))
return;
dcache_disable(); /* flush cache before switch to EL1 */
+ icache_disable();
/* Move into EL1 and keep running there */
armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0,
(uintptr_t)entry_non_secure, ES_TO_AARCH64);
--
2.25.1
@@ -0,0 +1,27 @@
From 726f8b4dbd3c5b1873aad531d5e26af3acd9b9ca Mon Sep 17 00:00:00 2001
From: Jon Mason <jdmason@kudzu.us>
Date: Mon, 19 Dec 2022 11:36:04 -0500
Subject: [PATCH] configs: vexpress: modify to boot compressed initramfs
Signed-off-by: Jon Mason <jdmason@kudzu.us>
Upstream-Status: Inappropriate
---
include/configs/vexpress_aemv8.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/configs/vexpress_aemv8.h b/include/configs/vexpress_aemv8.h
index 0c11b6b3331e..4ba4bebfbbae 100644
--- a/include/configs/vexpress_aemv8.h
+++ b/include/configs/vexpress_aemv8.h
@@ -192,8 +192,10 @@
#define VEXPRESS_RAMDISK_ADDR 0x8fe00000
#define EXTRA_ENV_NAMES \
+ "kernel_comp_addr_r=0x90000000\0" \
+ "kernel_comp_size=0x3000000\0" \
"kernel_name=norkern\0" \
- "kernel_alt_name=Image\0" \
+ "kernel_alt_name=Image.gz\0" \
"ramdisk_name=ramdisk.img\0" \
"fdtfile=board.dtb\0" \
"fdt_alt_name=juno\0"
@@ -0,0 +1,3 @@
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0 debug earlycon=pl011,0x7ff80000"
CONFIG_BOOTDELAY=0
@@ -0,0 +1,100 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
#
# Corstone-500 MACHINE
#
SRC_URI:append:corstone500 = " \
file://0001-armv7-adding-generic-timer-access-through-MMIO.patch \
file://0002-board-arm-add-corstone500-board.patch"
#
# Corstone1000 64-bit machines
#
DEPENDS:append:corstone1000 = " gnutls-native"
CORSTONE1000_DEVICE_TREE:corstone1000-mps3 = "corstone1000-mps3"
CORSTONE1000_DEVICE_TREE:corstone1000-fvp = "corstone1000-fvp"
EXTRA_OEMAKE:append:corstone1000 = ' DEVICE_TREE=${CORSTONE1000_DEVICE_TREE}'
SYSROOT_DIRS:append:corstone1000 = " /boot"
SRC_URI:append:corstone1000 = " \
file://0001-arm64-smccc-add-support-for-SMCCCv1.2-x0-x17-registe.patch \
file://0002-lib-uuid-introduce-uuid_str_to_le_bin-function.patch \
file://0003-arm_ffa-introduce-Arm-FF-A-low-level-driver.patch \
file://0004-arm_ffa-efi-unmap-RX-TX-buffers.patch \
file://0005-arm_ffa-introduce-armffa-command.patch \
file://0006-arm_ffa-introduce-the-FF-A-Sandbox-driver.patch \
file://0007-arm_ffa-introduce-Sandbox-test-cases-for-UCLASS_FFA.patch \
file://0008-arm_ffa-introduce-armffa-command-Sandbox-test.patch \
file://0009-arm_ffa-efi-introduce-FF-A-MM-communication.patch \
file://0010-arm_ffa-efi-corstone1000-enable-MM-communication.patch \
file://0011-efi-corstone1000-introduce-EFI-capsule-update.patch \
file://0012-arm-corstone1000-fix-unrecognized-filesystem-type.patch \
file://0013-efi_capsule-corstone1000-pass-interface-id-and-buffe.patch \
file://0014-efi_boottime-corstone1000-pass-interface-id-and-kern.patch \
file://0015-efi_loader-corstone1000-remove-guid-check-from-corst.patch \
file://0016-efi_loader-populate-ESRT-table-if-EFI_ESRT-config-op.patch \
file://0017-efi_firmware-add-get_image_info-for-corstone1000.patch \
file://0018-efi_loader-send-bootcomplete-message-to-secure-encla.patch \
file://0019-efi_loader-fix-null-pointer-exception-with-get_image.patch \
file://0020-arm-corstone1000-add-mmc-for-fvp.patch \
file://0021-corstone1000-add-compressed-kernel-support.patch \
file://0022-Introduce-external-sys-driver-to-device-tree.patch \
file://0023-Add-mhu-and-rpmsg-client-to-u-boot-device-tree.patch \
file://0024-arm-corstone1000-esrt-support.patch \
file://0025-efi_setup-discover-FF-A-bus-before-raising-EFI-start.patch \
file://0026-corstone1000-enable-distro-booting-command.patch \
file://0027-drivers-mtd-nvmxip-introduce-NVM-XIP-block-storage-e.patch \
file://0028-drivers-mtd-nvmxip-introduce-QSPI-XIP-driver.patch \
file://0029-sandbox64-fix-return-unsigned-long-in-readq.patch \
file://0030-sandbox64-add-support-for-NVMXIP-QSPI.patch \
file://0031-corstone1000-add-NVM-XIP-QSPI-device-tree-node.patch \
file://0032-sandbox64-add-a-test-case-for-UCLASS_NVMXIP.patch \
file://0033-corstone1000-add-fwu-metadata-store-info.patch \
file://0034-fwu_metadata-make-sure-structures-are-packed.patch \
file://0035-corstone1000-add-boot-index.patch \
file://0036-corstone1000-adjust-boot-bank-and-kernel-location.patch \
file://0037-corstone1000-add-nvmxip-fwu-mdata-and-gpt-options.patch \
file://0038-nvmxip-move-header-to-include.patch \
file://0039-corstone1000-set-kernel_addr-based-on-boot_idx.patch \
file://0040-corstone1000-boot-index-from-active.patch \
file://0041-corstone1000-enable-PSCI-reset.patch \
file://0042-Enable-EFI-set-get-time-services.patch \
file://0043-corstone1000-fix-compilation-warnings-in-fwu_plat_get_bootidx.patch \
"
#
# FVP BASE
#
SRC_URI:append:fvp-base = " file://bootargs.cfg \
file://0001-Revert-vexpress64-pick-DRAM-size-from-DT.patch \
"
#
# FVP BASER
#
SRC_URI:append:fvp-baser-aemv8r64 = " \
file://0001-armv8-Add-ARMv8-MPU-configuration-logic.patch \
file://0002-vexpress64-add-MPU-memory-map-for-the-BASER_FVP.patch \
file://0003-armv8-Allow-disabling-exception-vectors-on-non-SPL-b.patch \
file://0004-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch \
file://0005-armv8-Make-disabling-HVC-configurable-when-switching.patch \
file://0006-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch \
file://0007-vexpress64-Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch \
file://0008-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch \
file://0009-armv8-Enable-icache-when-switching-exception-levels-.patch \
"
#
# Juno Machines
#
SRC_URI:append:juno = " file://0001-configs-vexpress-modify-to-boot-compressed-initramfs.patch"
#
# TC0 and TC1 MACHINES
#
SRC_URI:append:tc = " \
file://bootargs.cfg \
"
@@ -0,0 +1,26 @@
HOMEPAGE = "http://www.denx.de/wiki/U-Boot/WebHome"
DESCRIPTION = "U-Boot, a boot loader for Embedded boards based on PowerPC, \
ARM, MIPS and several other processors, which can be installed in a boot \
ROM and used to initialize and test the hardware or to download and run \
application code."
SECTION = "bootloaders"
DEPENDS += "flex-native bison-native"
LICENSE = "GPL-2.0-or-later"
LIC_FILES_CHKSUM = "file://Licenses/README;md5=2ca5f2c35c8cc335f0a19756634782f1"
PE = "1"
# We use the revision in order to avoid having to fetch it from the
# repo during parse
SRCREV = "4debc57a3da6c3f4d3f89a637e99206f4cea0a96"
SRC_URI = "git://git.denx.de/u-boot.git;branch=master \
"
S = "${WORKDIR}/git"
B = "${WORKDIR}/build"
do_configure[cleandirs] = "${B}"
require recipes-bsp/u-boot/u-boot.inc
DEPENDS += "bc-native dtc-native gnutls-native"
@@ -0,0 +1,4 @@
require recipes-bsp/u-boot/u-boot-common.inc
require recipes-bsp/u-boot/u-boot.inc
SRCREV = "62e2ad1ceafbfdf2c44d3dc1b6efc81e768a96b9"