Platform: Corstone-310: Add NPU driver

- Fetch Ethos-U core driver from external repository.
- Use driver to configure NPU as non-secure privilege peripheral.
- Patch driver to make configuration architecture independent and remove
  heap usage.
- Change Ethos-U55 naming to NPU0 following documentation.

Signed-off-by: Gabor Toth <gabor.toth@arm.com>
Change-Id: I04c90b75e1290a94bacd4c11086d4c1e653c8647
diff --git a/docs/platform/arm/mps3/corstone310/README.rst b/docs/platform/arm/mps3/corstone310/README.rst
index a3bd0e4..4515ea2 100644
--- a/docs/platform/arm/mps3/corstone310/README.rst
+++ b/docs/platform/arm/mps3/corstone310/README.rst
@@ -1,12 +1,12 @@
-Corstone SSE-310 with Ethos-U55 Example Subsystem for Arm Virtual Hardware, and for MPS3 (AN555)
-================================================================================================
+Corstone SSE-310 with Ethos-U55/U65 Example Subsystem for Arm Virtual Hardware, and for MPS3 (AN555)
+====================================================================================================
 
 Introduction
 ------------
 
 Corstone-310 (formerly Corstone-Polaris) is an Arm reference subsystem for
 secure System on Chips containing an Armv8.1-M Cortex-M85 processor and an
-Ethos-U55 neural network processor. It is an MPS3 based platform with the
+Ethos-U55/U65 neural network processor. It is an MPS3 based platform with the
 usual MPS3 peripherals.
 
 This platform port supports all TF-M regression tests (Secure and Non-secure)
@@ -14,7 +14,7 @@
 
 .. note::
 
-   This platform support does not provide software for Ethos-U55 IP, only
+   This platform support does not provide software for Ethos-U55/U65 IP, only
    contains base address and interrupt number for it.
 
 .. note::
@@ -26,7 +26,7 @@
 
 Follow the instructions in :doc:`Building instructions </building/tfm_build_instruction>`.
 
-For Corstone-310 Ethos-U55 Arm Virtual Hardware use the following platform name:
+For Corstone-310 Ethos-U55/U65 Arm Virtual Hardware use the following platform name:
 
 ``-DTFM_PLATFORM=arm/mps3/corstone310/fvp``
 
@@ -39,8 +39,8 @@
 
 ``-DTFM_PLATFORM=arm/mps3/corstone310/an555``
 
-To run the example code on Corstone-310 Ethos-U55 Arm Virtual Hardware
-----------------------------------------------------------------------
+To run the example code on Corstone-310 Ethos-U55/U65 Arm Virtual Hardware
+--------------------------------------------------------------------------
 
 To utilize the `Arm Virtual Hardware (AVH) <https://arm-software.github.io/AVH/main/simulation/html/Using.html>`_, you will need to create an `AWS Account <https://aws.amazon.com/>`_ if you don’t already have one.
 
diff --git a/docs/platform/platform_introduction.rst b/docs/platform/platform_introduction.rst
index 2cc103a..c18c71b 100644
--- a/docs/platform/platform_introduction.rst
+++ b/docs/platform/platform_introduction.rst
@@ -4,7 +4,7 @@
 
     - Cortex-M85 system:
 
-        - `Corstone-310 Ethos-U55 FVP.
+        - `Corstone-310 Ethos-U55/U65 FVP.
           <https://arm-software.github.io/AVH/main/simulation/html/Using.html>`_
         - `FPGA image loaded on MPS3 board (AN555).
           <https://developer.arm.com/tools-and-software/development-boards/fpga-prototyping-boards/download-fpga-images>`_
diff --git a/lib/ext/CMakeLists.txt b/lib/ext/CMakeLists.txt
index b0c60df..f50061a 100644
--- a/lib/ext/CMakeLists.txt
+++ b/lib/ext/CMakeLists.txt
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,5 +19,8 @@
 if (${PLATFORM_PSA_ADAC_SECURE_DEBUG})
     add_subdirectory(psa-adac)
 endif()
+if(DEFINED ETHOSU_ARCH)
+    add_subdirectory(ethos_u_core_driver)
+endif()
 
 add_subdirectory(tf-m-extras)
diff --git a/lib/ext/ethos_u_core_driver/001-Remove-malloc-usage.patch b/lib/ext/ethos_u_core_driver/001-Remove-malloc-usage.patch
new file mode 100644
index 0000000..3f5fb6b
--- /dev/null
+++ b/lib/ext/ethos_u_core_driver/001-Remove-malloc-usage.patch
@@ -0,0 +1,65 @@
+diff --git a/src/ethosu_device.h b/src/ethosu_device.h
+index 02942b1..28506b8 100644
+--- a/src/ethosu_device.h
++++ b/src/ethosu_device.h
+@@ -59,12 +59,12 @@ struct ethosu_device
+ /**
+  * Initialize the device.
+  */
+-struct ethosu_device *ethosu_dev_init(void *const base_address, uint32_t secure_enable, uint32_t privilege_enable);
++enum ethosu_error_codes ethosu_dev_init(struct ethosu_device *dev);
+ 
+ /**
+  * Deinitialize the device.
+  */
+-void ethosu_dev_deinit(struct ethosu_device *dev);
++enum ethosu_error_codes ethosu_dev_deinit(struct ethosu_device *dev);
+ 
+ /**
+  * Initialize AXI settings for device.
+diff --git a/src/ethosu_device_u55_u65.c b/src/ethosu_device_u55_u65.c
+index 50b78af..22ea067 100644
+--- a/src/ethosu_device_u55_u65.c
++++ b/src/ethosu_device_u55_u65.c
+@@ -67,19 +67,8 @@ uint64_t __attribute__((weak)) ethosu_address_remap(uint64_t address, int index)
+     return address;
+ }
+ 
+-struct ethosu_device *ethosu_dev_init(void *const base_address, uint32_t secure_enable, uint32_t privilege_enable)
++enum ethosu_error_codes ethosu_dev_init(struct ethosu_device *dev)
+ {
+-    struct ethosu_device *dev = malloc(sizeof(struct ethosu_device));
+-    if (!dev)
+-    {
+-        LOG_ERR("Failed to allocate memory for Ethos-U device");
+-        return NULL;
+-    }
+-
+-    dev->reg        = (volatile struct NPU_REG *)base_address;
+-    dev->secure     = secure_enable;
+-    dev->privileged = privilege_enable;
+-
+ #ifdef ETHOSU55
+     if (dev->reg->CONFIG.product != ETHOSU_PRODUCT_U55)
+ #else
+@@ -96,16 +85,15 @@ struct ethosu_device *ethosu_dev_init(void *const base_address, uint32_t secure_
+         goto err;
+     }
+ 
+-    return dev;
++    return ETHOSU_SUCCESS;
+ 
+ err:
+-    free(dev);
+-    return NULL;
++    return ETHOSU_GENERIC_FAILURE;
+ }
+ 
+-void ethosu_dev_deinit(struct ethosu_device *dev)
++enum ethosu_error_codes ethosu_dev_deinit(struct ethosu_device *dev)
+ {
+-    free(dev);
++    return ETHOSU_SUCCESS;
+ }
+ 
+ enum ethosu_error_codes ethosu_dev_axi_init(struct ethosu_device *dev)
diff --git a/lib/ext/ethos_u_core_driver/002-Remove-product-check.patch b/lib/ext/ethos_u_core_driver/002-Remove-product-check.patch
new file mode 100644
index 0000000..4580bf7
--- /dev/null
+++ b/lib/ext/ethos_u_core_driver/002-Remove-product-check.patch
@@ -0,0 +1,21 @@
+diff --git a/src/ethosu_device_u55_u65.c b/src/ethosu_device_u55_u65.c
+index 22ea067..09dfc9e 100644
+--- a/src/ethosu_device_u55_u65.c
++++ b/src/ethosu_device_u55_u65.c
+@@ -69,16 +69,6 @@ uint64_t __attribute__((weak)) ethosu_address_remap(uint64_t address, int index)
+ 
+ enum ethosu_error_codes ethosu_dev_init(struct ethosu_device *dev)
+ {
+-#ifdef ETHOSU55
+-    if (dev->reg->CONFIG.product != ETHOSU_PRODUCT_U55)
+-#else
+-    if (dev->reg->CONFIG.product != ETHOSU_PRODUCT_U65)
+-#endif
+-    {
+-        LOG_ERR("Failed to initialize device. Driver has not been compiled for this product");
+-        goto err;
+-    }
+-
+     // Make sure the NPU is in a known state
+     if (ethosu_dev_soft_reset(dev) != ETHOSU_SUCCESS)
+     {
diff --git a/lib/ext/ethos_u_core_driver/CMakeLists.txt b/lib/ext/ethos_u_core_driver/CMakeLists.txt
new file mode 100644
index 0000000..7a8ad3d
--- /dev/null
+++ b/lib/ext/ethos_u_core_driver/CMakeLists.txt
@@ -0,0 +1,16 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+fetch_remote_library(
+    LIB_NAME                ethos_u_core_driver
+    LIB_SOURCE_PATH_VAR     ETHOS_DRIVER_PATH
+    LIB_PATCH_DIR           ${CMAKE_CURRENT_LIST_DIR}
+    FETCH_CONTENT_ARGS
+        GIT_REPOSITORY      https://git.mlplatform.org/ml/ethos-u/ethos-u-core-driver.git
+        GIT_TAG             "23.05"
+        GIT_PROGRESS        TRUE
+)
diff --git a/platform/ext/target/arm/mps3/corstone310/common/common.cmake b/platform/ext/target/arm/mps3/corstone310/common/common.cmake
index 727c409..2a5e1d4 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/common.cmake
+++ b/platform/ext/target/arm/mps3/corstone310/common/common.cmake
@@ -75,6 +75,8 @@
         ${PLATFORM_DIR}/ext/target/arm/drivers/mpu/armv8m
         ${PLATFORM_DIR}/ext/target/arm/drivers/counter/armv8m
         ${PLATFORM_DIR}/ext/target/arm/drivers/timer/armv8m
+        ${ETHOS_DRIVER_PATH}/src
+        ${ETHOS_DRIVER_PATH}/include
         ${CMAKE_CURRENT_SOURCE_DIR}/device/config
         ${CMAKE_SOURCE_DIR}
 )
@@ -194,6 +196,7 @@
         ${PLATFORM_DIR}/ext/target/arm/drivers/mpc_sie/mpc_sie_drv.c
         ${PLATFORM_DIR}/ext/target/arm/drivers/mpu/armv8m/mpu_armv8m_drv.c
         ${PLATFORM_DIR}/ext/target/arm/drivers/counter/armv8m/syscounter_armv8-m_cntrl_drv.c
+        ${ETHOS_DRIVER_PATH}/src/ethosu_device_u55_u65.c
         $<$<OR:$<BOOL:${TEST_NS_SLIH_IRQ}>,$<BOOL:${TEST_NS_FLIH_IRQ}>>:${CORSTONE310_COMMON_DIR}/plat_test.c>
         $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CORSTONE310_COMMON_DIR}/services/src/tfm_platform_system.c>
 )
@@ -210,6 +213,13 @@
         ${COMPILER_CMSE_FLAG}
 )
 
+target_compile_definitions(platform_s
+    PUBLIC
+        ETHOSU_ARCH=$<LOWER_CASE:${ETHOSU_ARCH}>
+        ETHOS$<UPPER_CASE:${ETHOSU_ARCH}>
+        ETHOSU_LOG_SEVERITY=${ETHOSU_LOG_SEVERITY}
+)
+
 #========================= Platform Non-Secure ================================#
 
 target_sources(platform_ns
diff --git a/platform/ext/target/arm/mps3/corstone310/common/config.cmake b/platform/ext/target/arm/mps3/corstone310/common/config.cmake
index bd9dce1..6a684a5 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/config.cmake
+++ b/platform/ext/target/arm/mps3/corstone310/common/config.cmake
@@ -28,3 +28,8 @@
 
 set(PLATFORM_SLIH_IRQ_TEST_SUPPORT    ON)
 set(PLATFORM_FLIH_IRQ_TEST_SUPPORT    ON)
+
+# Ethos-U NPU configurations
+set(ETHOSU_ARCH                       "U55")
+set(ETHOS_DRIVER_PATH                 "DOWNLOAD"  CACHE PATH      "Path to Ethos-U Core Driver (or DOWNLOAD to fetch automatically")
+set(ETHOSU_LOG_SEVERITY               "-1"        CACHE STRING    "Ethos-U Core Driver log severity")
diff --git a/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_irq.h b/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_irq.h
index 913b083..1df17ba 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_irq.h
+++ b/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_irq.h
@@ -48,7 +48,7 @@
     /* Reserved                        = 13,      Reserved */
     Combined_PPU_IRQn                  = 14,   /* Combined PPU */
     /* Reserved                        = 15,      Reserved */
-    ETHOS_U55_IRQn                     = 16,   /* NPU0 */
+    NPU0_IRQn                          = 16,   /* NPU0 */
     /* Reserved                        = 17,      Reserved */
     /* Reserved                        = 18,      Reserved */
     /* Reserved                        = 19,      Reserved */
diff --git a/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_s_device_definition.h b/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_s_device_definition.h
index 3043c0e..bc3bb3c 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_s_device_definition.h
+++ b/platform/ext/target/arm/mps3/corstone310/common/device/include/platform_s_device_definition.h
@@ -93,6 +93,9 @@
 extern struct tgu_armv8_m_dev_t TGU_ARMV8_M_ITCM_DEV_S;
 extern struct tgu_armv8_m_dev_t TGU_ARMV8_M_DTCM_DEV_S;
 
+#include "ethosu_device.h"
+extern struct ethosu_device NPU0_S;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/ext/target/arm/mps3/corstone310/common/device/source/platform_s_device_definition.c b/platform/ext/target/arm/mps3/corstone310/common/device/source/platform_s_device_definition.c
index ba1b5eb..79de2bd 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/device/source/platform_s_device_definition.c
+++ b/platform/ext/target/arm/mps3/corstone310/common/device/source/platform_s_device_definition.c
@@ -566,3 +566,9 @@
 struct mpc_sie_dev_t MPC_DDR4_DEV_S = {
     &(MPC_DDR4_DEV_CFG_S),
     &(MPC_DDR4_DEV_DATA_S)};
+
+struct ethosu_device NPU0_S = {
+    .reg = (struct NPU_REG *)NPU0_APB_BASE_S,
+    .secure = 0,
+    .privileged = 1,
+};
diff --git a/platform/ext/target/arm/mps3/corstone310/common/device/source/startup_corstone310.c b/platform/ext/target/arm/mps3/corstone310/common/device/source/startup_corstone310.c
index 9bbb9e7..0210ff2 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/device/source/startup_corstone310.c
+++ b/platform/ext/target/arm/mps3/corstone310/common/device/source/startup_corstone310.c
@@ -117,7 +117,7 @@
 DEFAULT_IRQ_HANDLER(DMA_Ch_3_Terminal_Count_Handler)
 DEFAULT_IRQ_HANDLER(DMA_Ch_3_Combined_Handler)
 #endif
-DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler)
+DEFAULT_IRQ_HANDLER(NPU0_Handler)
 DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler)
 DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler)
 DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler)
@@ -232,7 +232,7 @@
   0,                                 /*  13: Reserved */
   COMBINED_PPU_Handler,              /*  14: Combined PPU Handler */
   0,                                 /*  15: Reserved */
-  ETHOS_U55_Handler,                 /*  16: Ethos-U55 Handler */
+  NPU0_Handler,                      /*  16: NPU0 Handler */
   0,                                 /*  17: Reserved */
   0,                                 /*  18: Reserved */
   0,                                 /*  19: Reserved */
diff --git a/platform/ext/target/arm/mps3/corstone310/common/partition/platform_base_address.h b/platform/ext/target/arm/mps3/corstone310/common/partition/platform_base_address.h
index 81cfa90..0e0e7c3 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/partition/platform_base_address.h
+++ b/platform/ext/target/arm/mps3/corstone310/common/partition/platform_base_address.h
@@ -37,7 +37,7 @@
 #ifdef CORSTONE310_FVP
 #define DMA_350_BASE_NS                  0x40002000 /* DMA350 register block Non-Secure base address */
 #endif
-#define ETHOS_U55_APB_BASE_NS            0x40004000 /* Ethos-U55 APB Non-Secure base address */
+#define NPU0_APB_BASE_NS                 0x40004000 /* NPU0 APB Non-Secure base address */
 #define CPU0_PWRCTRL_BASE_NS             0x40012000 /* CPU 0 Power Control Block Non-Secure base address */
 #define CPU0_IDENTITY_BASE_NS            0x4001F000 /* CPU 0 Identity Block Non-Secure base address */
 #define CORSTONE310_NSACFG_BASE_NS       0x40080000 /* Corstone-310 Non-Secure Access Configuration Register Block Non-Secure base address */
@@ -75,8 +75,6 @@
 #define SYSWDOG_ARMV8_M_REFRESH_BASE_NS  0x48041000 /* Non-Secure Watchdog Timer refresh frame Non-Secure base address */
 #define SYSCNTR_READ_BASE_NS             0x48101000 /* System Counter Read Secure base address */
 /* Non-Secure MSTEXPPIHL Peripheral region */
-#define U55_TIMING_ADAPTER_0_BASE_NS     0x48103000 /* Ethos-U55 Timing Adapter 0 APB registers Non-Secure base address */
-#define U55_TIMING_ADAPTER_1_BASE_NS     0x48103200 /* Ethos-U55 Timing Adapter 1 APB registers Non-Secure base address */
 #define FPGA_SBCon_I2C_TOUCH_BASE_NS     0x49200000 /* FPGA - SBCon I2C (Touch) Non-Secure base address */
 #define FPGA_SBCon_I2C_AUDIO_BASE_NS     0x49201000 /* FPGA - SBCon I2C (Audio Conf) Non-Secure base address */
 #define FPGA_SPI_ADC_BASE_NS             0x49202000 /* FPGA - PL022 (SPI ADC) Non-Secure base address */
@@ -130,7 +128,7 @@
 #ifdef CORSTONE310_FVP
 #define DMA_350_BASE_S                   0x50002000 /* DMA350 register block Secure base address */
 #endif
-#define ETHOS_U55_APB_BASE_S             0x50004000 /* Ethos-U55 APB Secure base address */
+#define NPU0_APB_BASE_S                  0x50004000 /* NPU0 APB Secure base address */
 #define CPU0_SECCTRL_BASE_S              0x50011000 /* CPU 0 Local Security Control Block Secure base address */
 #define CPU0_PWRCTRL_BASE_S              0x50012000 /* CPU 0 Power Control Block Secure base address */
 #define CPU0_IDENTITY_BASE_S             0x5001F000 /* CPU 0 Identity Block Secure base address */
@@ -182,8 +180,6 @@
 #define SYSCNTR_CNTRL_BASE_S             0x58100000 /* System Counter Control Secure base address */
 #define SYSCNTR_READ_BASE_S              0x58101000 /* System Counter Read Secure base address */
 /* Secure MSTEXPPIHL Peripheral region */
-#define U55_TIMING_ADAPTER_0_BASE_S      0x58103000 /* Ethos-U55 Timing Adapter 0 APB registers Secure base address */
-#define U55_TIMING_ADAPTER_1_BASE_S      0x58103200 /* Ethos-U55 Timing Adapter 1 APB registers Secure base address */
 #define FPGA_SBCon_I2C_TOUCH_BASE_S      0x59200000 /* FPGA - SBCon I2C (Touch) Secure base address */
 #define FPGA_SBCon_I2C_AUDIO_BASE_S      0x59201000 /* FPGA - SBCon I2C (Audio Conf) Secure base address */
 #define FPGA_SPI_ADC_BASE_S              0x59202000 /* FPGA - PL022 (SPI ADC) Secure base address */
diff --git a/platform/ext/target/arm/mps3/corstone310/common/target_cfg.c b/platform/ext/target/arm/mps3/corstone310/common/target_cfg.c
index c812b9e..c533f3a 100644
--- a/platform/ext/target/arm/mps3/corstone310/common/target_cfg.c
+++ b/platform/ext/target/arm/mps3/corstone310/common/target_cfg.c
@@ -26,6 +26,7 @@
 #include "syscounter_armv8-m_cntrl_drv.h"
 #include "uart_stdout.h"
 #include "tfm_peripherals_def.h"
+#include "ethosu_device.h"
 
 #ifdef PSA_API_TEST_IPC
 #define PSA_FF_TEST_SECURE_UART2
@@ -70,6 +71,9 @@
 extern ARM_DRIVER_PPC_CORSTONE310 Driver_PERIPH_EXP2_PPC_CORSTONE310;
 extern ARM_DRIVER_PPC_CORSTONE310 Driver_PERIPH_EXP3_PPC_CORSTONE310;
 
+/* Import NPU driver */
+extern struct ethosu_device NPU0_S;
+
 /* Define Peripherals NS address range for the platform */
 #define PERIPHERALS_BASE_NS_START      (0x40000000)
 #define PERIPHERALS_BASE_NS_END        (0x4FFFFFFF)
@@ -767,6 +771,9 @@
     err |= Driver_PERIPH_EXP1_PPC_CORSTONE310.Initialize();
     err |= Driver_PERIPH_EXP3_PPC_CORSTONE310.Initialize();
 
+    /* initialize and config NPU */
+    err |= ethosu_dev_init(&NPU0_S);
+
     /*
      * Configure the response to a security violation as a
      * bus error instead of RAZ/WI