Platform: Add support for Corstone-Polaris

Change-Id: I26b5baf9fea8105f25e877f7ed253b991528a7f0
Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>
diff --git a/platform/ext/platform_introduction.rst b/platform/ext/platform_introduction.rst
index eec3328..ebb06c0 100644
--- a/platform/ext/platform_introduction.rst
+++ b/platform/ext/platform_introduction.rst
@@ -2,6 +2,10 @@
 Platforms introduction
 ######################
 
+    - Olympus system
+
+        - Corstone-Polaris Ethos-U55 FVP (Olympus CPU plus Ethos-U55)
+
     - Cortex-M55 system:
 
         - `FPGA image loaded on MPS3 board (AN547).
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/CMakeLists.txt b/platform/ext/target/arm/mps3/corstone_polaris/CMakeLists.txt
new file mode 100644
index 0000000..fa7d3b6
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/CMakeLists.txt
@@ -0,0 +1,187 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_policy(SET CMP0076 NEW)
+set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+#========================= Platform region defs ===============================#
+
+target_include_directories(platform_region_defs
+    INTERFACE
+        partition
+)
+
+#========================= Platform common defs ===============================#
+
+if (${CMAKE_C_COMPILER_ID} STREQUAL IAR)
+    message(FATAL_ERROR "IAR is currently not supported on the mps3/corstone_polaris due to a lack of scatter files")
+endif()
+
+if (${CMAKE_C_COMPILER_ID} STREQUAL ARMClang)
+    if (${CMAKE_C_COMPILER_VERSION} VERSION_LESS "6.14")
+        message(FATAL_ERROR "Architecture (Armv8.1-M) is only supported in ARMCLANG version 6.14 or newer.")
+    endif()
+endif()
+
+# Specify the location of platform specific build dependencies.
+target_sources(tfm_s
+    PRIVATE
+    ${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_corstone_polaris_s.c
+)
+target_add_scatter_file(tfm_s
+    $<$<C_COMPILER_ID:ARMClang>:${CMAKE_SOURCE_DIR}/platform/ext/common/armclang/tfm_common_s.sct>
+    $<$<C_COMPILER_ID:GNU>:${CMAKE_SOURCE_DIR}/platform/ext/common/gcc/tfm_common_s.ld>
+)
+
+if(NS)
+    target_sources(tfm_ns
+        PRIVATE
+            ${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_corstone_polaris_ns.c
+    )
+    target_add_scatter_file(tfm_ns
+        $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/armclang/corstone_polaris_ns.sct>
+        $<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/gcc/corstone_polaris_ns.ld>
+    )
+    target_link_libraries(CMSIS_5_tfm_ns
+        INTERFACE
+            CMSIS_5_RTX_V8MMN
+    )
+endif()
+
+if(BL2)
+    target_sources(bl2
+        PRIVATE
+            ${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_corstone_polaris_bl2.c
+    )
+    target_add_scatter_file(bl2
+            $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/armclang/corstone_polaris_bl2.sct>
+            $<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/gcc/corstone_polaris_bl2.ld>
+    )
+endif()
+
+#========================= Platform Secure ====================================#
+
+target_include_directories(platform_s
+    PUBLIC
+        .
+        ../common
+        cmsis_drivers
+        cmsis_drivers/config
+        device
+        device/config
+        device/include
+        device/source/armclang
+        native_drivers
+        partition
+        services/src
+        ${PLATFORM_DIR}/..
+)
+
+target_sources(platform_s
+    PRIVATE
+        cmsis_drivers/Driver_Flash.c
+        cmsis_drivers/Driver_MPC.c
+        cmsis_drivers/Driver_PPC.c
+        cmsis_drivers/Driver_USART.c
+        device/source/device_definition.c
+        device/source/system_core_init.c
+        native_drivers/mpc_sie_drv.c
+        native_drivers/mpu_armv8m_drv.c
+        native_drivers/ppc_polaris_drv.c
+        native_drivers/syscounter_armv8-m_cntrl_drv.c
+        native_drivers/uart_cmsdk_drv.c
+        spm_hal.c
+        tfm_interrupts.c
+        target_cfg.c
+        tfm_hal_isolation.c
+        tfm_hal_platform.c
+        ${CMAKE_SOURCE_DIR}/platform/ext/common/tfm_hal_nvic.c
+        ${CMAKE_SOURCE_DIR}/platform/ext/common/tfm_hal_isolation_mpu_v8m.c
+        $<$<OR:$<BOOL:${TEST_NS_SLIH_IRQ}>,$<BOOL:${TEST_NS_FLIH_IRQ}>>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c>
+        $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c>
+)
+
+target_sources(tfm_sprt
+    PRIVATE
+        # SLIH test Partition and FLIH test Partition access the timer as ARoT Partitions.
+        # Put the driver to SPRT so that both SLIH and FLIH tests can access it.
+        $<$<OR:$<BOOL:${TEST_NS_SLIH_IRQ}>,$<BOOL:${TEST_NS_FLIH_IRQ}>>:${CMAKE_CURRENT_SOURCE_DIR}/native_drivers/systimer_armv8-m_drv.c>
+)
+
+target_link_libraries(platform_s
+    PRIVATE
+        tfm_utilities
+)
+
+target_compile_options(platform_s
+    PUBLIC
+        ${COMPILER_CMSE_FLAG}
+)
+
+#========================= Platform Non-Secure ================================#
+
+target_sources(platform_ns
+    PRIVATE
+        cmsis_drivers/Driver_Flash.c
+        cmsis_drivers/Driver_USART.c
+        device/source/device_definition.c
+        device/source/system_core_init.c
+        native_drivers/uart_cmsdk_drv.c
+)
+
+target_include_directories(platform_ns
+    PUBLIC
+        .
+        ../common
+        ${PLATFORM_DIR}/..
+        cmsis_drivers
+        cmsis_drivers/config
+        device
+        device/config
+        device/include
+        device/source/armclang
+        native_drivers
+        partition
+)
+
+# TODO: For some reason this is needed
+target_link_libraries(platform_ns
+    PRIVATE
+        psa_interface
+)
+
+#========================= Platform BL2 =======================================#
+
+if(BL2)
+    target_sources(platform_bl2
+        PRIVATE
+            cmsis_drivers/Driver_Flash.c
+            cmsis_drivers/Driver_USART.c
+            device/source/device_definition.c
+            device/source/system_core_init.c
+            native_drivers/uart_cmsdk_drv.c
+            boot_hal.c
+    )
+
+    target_include_directories(platform_bl2
+        PUBLIC
+            cmsis_drivers
+            cmsis_drivers/config
+            device
+            device/config
+            device/include
+            device/source/armclang
+            native_drivers
+            partition
+            services/src
+
+        PRIVATE
+            .
+            ${PLATFORM_DIR}/..
+            native_drivers
+    )
+endif()
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/README.rst b/platform/ext/target/arm/mps3/corstone_polaris/README.rst
new file mode 100644
index 0000000..9005d78
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/README.rst
@@ -0,0 +1,21 @@
+Corstone-Polaris
+================
+
+Introduction
+------------
+
+Corstone-Polaris is an Arm reference subsystem for secure System on
+Chips containing an Armv8.1-M Olympus processor and an Ethos-U55 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)
+with Isolation Level 1 and 2, but building without BL2 is not supported.
+
+Building TF-M
+-------------
+
+Follow the instructions in :doc:`Building instructions </docs/technical_references/instructions/tfm_build_instruction>`.
+Build instructions with platform name: arm/mps3/corstone_polaris (-DTFM_PLATFORM=arm/mps3/corstone_polaris).
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/boot_hal.c b/platform/ext/target/arm/mps3/corstone_polaris/boot_hal.c
new file mode 100644
index 0000000..9e93972
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/boot_hal.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis.h"
+#include "region.h"
+#include "target_cfg.h"
+#include "boot_hal.h"
+#include "Driver_Flash.h"
+#include "flash_layout.h"
+
+/* Flash device name must be specified by target */
+extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
+
+REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
+REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+__attribute__((naked)) void boot_clear_bl2_ram_area(void)
+{
+    __ASM volatile(
+        "mov     r0, #0                              \n"
+        "subs    %1, %1, %0                          \n"
+        "Loop:                                       \n"
+        "subs    %1, #4                              \n"
+        "itt     ge                                  \n"
+        "strge   r0, [%0, %1]                        \n"
+        "bge     Loop                                \n"
+        "bx      lr                                  \n"
+        :
+        : "r" (REGION_NAME(Image$$, ER_DATA, $$Base)),
+          "r" (REGION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Limit))
+        : "r0", "memory"
+    );
+}
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+void boot_platform_quit(struct boot_arm_vector_table *vt)
+{
+    /* Clang at O0, stores variables on the stack with SP relative addressing.
+     * When manually set the SP then the place of reset vector is lost.
+     * Static variables are stored in 'data' or 'bss' section, change of SP has
+     * no effect on them.
+     */
+    static struct boot_arm_vector_table *vt_cpy;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_Flash.c b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_Flash.c
new file mode 100644
index 0000000..303848a
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_Flash.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2013-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include "Driver_Flash.h"
+#include "RTE_Device.h"
+#include "platform_base_address.h"
+
+#ifndef ARG_UNUSED
+#define ARG_UNUSED(arg)  ((void)arg)
+#endif
+
+#define FLASH0_BASE_S         SRAM_BASE_S
+#define FLASH0_BASE_NS        SRAM_BASE_NS
+#define FLASH0_SIZE           SRAM_SIZE
+#define FLASH0_SECTOR_SIZE    0x00001000 /* 4 kB */
+#define FLASH0_PAGE_SIZE      0x00001000 /* 4 kB */
+#define FLASH0_PROGRAM_UNIT   0x1        /* Minimum write size */
+
+/* Driver version */
+#define ARM_FLASH_DRV_VERSION      ARM_DRIVER_VERSION_MAJOR_MINOR(1, 1)
+#define ARM_FLASH_DRV_ERASE_VALUE  0xFF
+
+/*
+ * ARM FLASH device structure
+ *
+ * This driver just emulates a flash interface and behaviour on top of the SRAM
+ * memory.
+ */
+struct arm_flash_dev_t {
+    const uint32_t memory_base;   /*!< FLASH memory base address */
+    ARM_FLASH_INFO *data;         /*!< FLASH data */
+};
+
+/* Flash Status */
+static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
+
+/* Driver Version */
+static const ARM_DRIVER_VERSION DriverVersion = {
+    ARM_FLASH_API_VERSION,
+    ARM_FLASH_DRV_VERSION
+};
+
+/* Driver Capabilities */
+static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
+    0, /* event_ready */
+    0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
+    1  /* erase_chip */
+};
+
+static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev,
+                              uint32_t offset)
+{
+    uint32_t flash_limit = 0;
+    int32_t rc = 0;
+
+    flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size)
+                   - 1;
+
+    if (offset > flash_limit) {
+        rc = -1;
+    }
+    return rc;
+}
+
+static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev,
+                                uint32_t param)
+{
+    int32_t rc = 0;
+
+    if ((param % flash_dev->data->program_unit) != 0) {
+        rc = -1;
+    }
+    return rc;
+}
+
+static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev,
+                                 uint32_t offset)
+{
+    int32_t rc = 0;
+
+    if ((offset % flash_dev->data->sector_size) != 0) {
+        rc = -1;
+    }
+    return rc;
+}
+
+static int32_t is_flash_ready_to_write(const uint8_t *start_addr, uint32_t cnt)
+{
+    int32_t rc = 0;
+    uint32_t i;
+
+    for (i = 0; i < cnt; i++) {
+        if(start_addr[i] != ARM_FLASH_DRV_ERASE_VALUE) {
+            rc = -1;
+            break;
+        }
+    }
+
+    return rc;
+}
+
+#if (RTE_FLASH0)
+static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
+    .sector_info  = NULL,                  /* Uniform sector layout */
+    .sector_count = FLASH0_SIZE / FLASH0_SECTOR_SIZE,
+    .sector_size  = FLASH0_SECTOR_SIZE,
+    .page_size    = FLASH0_PAGE_SIZE,
+    .program_unit = FLASH0_PROGRAM_UNIT,
+    .erased_value = ARM_FLASH_DRV_ERASE_VALUE};
+
+static struct arm_flash_dev_t ARM_FLASH0_DEV = {
+#if (__DOMAIN_NS == 1)
+    .memory_base = FLASH0_BASE_NS,
+#else
+    .memory_base = FLASH0_BASE_S,
+#endif /* __DOMAIN_NS == 1 */
+    .data        = &(ARM_FLASH0_DEV_DATA)};
+
+struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV;
+
+/*
+ * Functions
+ */
+
+static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
+{
+    return DriverVersion;
+}
+
+static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
+{
+    return DriverCapabilities;
+}
+
+static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
+{
+    ARG_UNUSED(cb_event);
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
+{
+    switch (state) {
+    case ARM_POWER_FULL:
+        /* Nothing to be done */
+        return ARM_DRIVER_OK;
+        break;
+
+    case ARM_POWER_OFF:
+    case ARM_POWER_LOW:
+    default:
+        return ARM_DRIVER_ERROR_UNSUPPORTED;
+    }
+}
+
+static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
+{
+    uint32_t start_addr = FLASH0_DEV->memory_base + addr;
+    int32_t rc = 0;
+
+    /* Check flash memory boundaries */
+    rc = is_range_valid(FLASH0_DEV, addr + cnt);
+    if (rc != 0) {
+        return ARM_DRIVER_ERROR_PARAMETER;
+    }
+
+    /* Flash interface just emulated over SRAM, use memcpy */
+    memcpy(data, (void *)start_addr, cnt);
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data,
+                                     uint32_t cnt)
+{
+    uint32_t start_addr = FLASH0_DEV->memory_base + addr;
+    int32_t rc = 0;
+
+    /* Check flash memory boundaries and alignment with minimal write size */
+    rc  = is_range_valid(FLASH0_DEV, addr + cnt);
+    rc |= is_write_aligned(FLASH0_DEV, addr);
+    rc |= is_write_aligned(FLASH0_DEV, cnt);
+    if (rc != 0) {
+        return ARM_DRIVER_ERROR_PARAMETER;
+    }
+
+    /* Check if the flash area to write the data was erased previously */
+    rc = is_flash_ready_to_write((const uint8_t*)start_addr, cnt);
+    if (rc != 0) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    /* Flash interface just emulated over SRAM, use memcpy */
+    memcpy((void *)start_addr, data, cnt);
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_EraseSector(uint32_t addr)
+{
+    uint32_t start_addr = FLASH0_DEV->memory_base + addr;
+    uint32_t rc = 0;
+
+    rc  = is_range_valid(FLASH0_DEV, addr);
+    rc |= is_sector_aligned(FLASH0_DEV, addr);
+    if (rc != 0) {
+        return ARM_DRIVER_ERROR_PARAMETER;
+    }
+
+    /* Flash interface just emulated over SRAM, use memset */
+    memset((void *)start_addr,
+           FLASH0_DEV->data->erased_value,
+           FLASH0_DEV->data->sector_size);
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_EraseChip(void)
+{
+    uint32_t i;
+    uint32_t addr = FLASH0_DEV->memory_base;
+    int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED;
+
+    /* Check driver capability erase_chip bit */
+    if (DriverCapabilities.erase_chip == 1) {
+        for (i = 0; i < FLASH0_DEV->data->sector_count; i++) {
+            /* Flash interface just emulated over SRAM, use memset */
+            memset((void *)addr,
+                   FLASH0_DEV->data->erased_value,
+                   FLASH0_DEV->data->sector_size);
+
+            addr += FLASH0_DEV->data->sector_size;
+            rc = ARM_DRIVER_OK;
+        }
+    }
+    return rc;
+}
+
+static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
+{
+    return FlashStatus;
+}
+
+static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
+{
+    return FLASH0_DEV->data;
+}
+
+ARM_DRIVER_FLASH Driver_FLASH0 = {
+    ARM_Flash_GetVersion,
+    ARM_Flash_GetCapabilities,
+    ARM_Flash_Initialize,
+    ARM_Flash_Uninitialize,
+    ARM_Flash_PowerControl,
+    ARM_Flash_ReadData,
+    ARM_Flash_ProgramData,
+    ARM_Flash_EraseSector,
+    ARM_Flash_EraseChip,
+    ARM_Flash_GetStatus,
+    ARM_Flash_GetInfo
+};
+#endif /* RTE_FLASH0 */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_MPC.c b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_MPC.c
new file mode 100644
index 0000000..4b24631
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_MPC.c
@@ -0,0 +1,764 @@
+/*
+ * Copyright (c) 2016-2020 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Driver_MPC.h"
+
+#include "mpc_sie_drv.h"
+#include "cmsis_driver_config.h"
+#include "RTE_Device.h"
+
+/* Driver version */
+#define ARM_MPC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0)
+
+/* Driver Version */
+static const ARM_DRIVER_VERSION DriverVersion = {
+    ARM_MPC_API_VERSION,
+    ARM_MPC_DRV_VERSION
+};
+
+static ARM_DRIVER_VERSION ARM_MPC_GetVersion(void)
+{
+    return DriverVersion;
+}
+
+/*
+ * \brief Translates error codes from native API to CMSIS API.
+ *
+ * \param[in] err  Error code to translate (\ref mpc_sie_error_t).
+ *
+ * \return Returns CMSIS error code.
+ */
+static int32_t error_trans(enum mpc_sie_error_t err)
+{
+    switch(err) {
+    case MPC_SIE_ERR_NONE:
+        return ARM_DRIVER_OK;
+    case MPC_SIE_INVALID_ARG:
+        return ARM_DRIVER_ERROR_PARAMETER;
+    case MPC_SIE_NOT_INIT:
+        return ARM_MPC_ERR_NOT_INIT;
+    case MPC_SIE_ERR_NOT_IN_RANGE:
+        return ARM_MPC_ERR_NOT_IN_RANGE;
+    case MPC_SIE_ERR_NOT_ALIGNED:
+        return ARM_MPC_ERR_NOT_ALIGNED;
+    case MPC_SIE_ERR_INVALID_RANGE:
+        return ARM_MPC_ERR_INVALID_RANGE;
+    case MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE:
+        return ARM_MPC_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE;
+    default:
+        return ARM_MPC_ERR_UNSPECIFIED;
+    }
+}
+
+#if (RTE_SRAM_MPC)
+/* Ranges controlled by this SRAM_MPC */
+static const struct mpc_sie_memory_range_t MPC_SRAM_RANGE_S = {
+    .base         = MPC_SRAM_RANGE_BASE_S,
+    .limit        = MPC_SRAM_RANGE_LIMIT_S,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_SECURE
+};
+
+static const struct mpc_sie_memory_range_t MPC_SRAM_RANGE_NS = {
+    .base         = MPC_SRAM_RANGE_BASE_NS,
+    .limit        = MPC_SRAM_RANGE_LIMIT_NS,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_NONSECURE
+};
+
+#define MPC_SRAM_RANGE_LIST_LEN  2u
+static const struct mpc_sie_memory_range_t*
+    MPC_SRAM_RANGE_LIST[MPC_SRAM_RANGE_LIST_LEN] = {
+        &MPC_SRAM_RANGE_S,
+        &MPC_SRAM_RANGE_NS
+    };
+
+/* SRAM_MPC Driver wrapper functions */
+static int32_t SRAM_MPC_Initialize(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_init(&MPC_SRAM_DEV,
+                       MPC_SRAM_RANGE_LIST,
+                       MPC_SRAM_RANGE_LIST_LEN);
+
+    return error_trans(ret);
+}
+
+static int32_t SRAM_MPC_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t SRAM_MPC_GetBlockSize(uint32_t *blk_size)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_block_size(&MPC_SRAM_DEV, blk_size);
+
+    return error_trans(ret);
+}
+
+static int32_t SRAM_MPC_GetCtrlConfig(uint32_t *ctrl_val)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_ctrl(&MPC_SRAM_DEV, ctrl_val);
+
+    return error_trans(ret);
+}
+
+static int32_t SRAM_MPC_SetCtrlConfig(uint32_t ctrl)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_set_ctrl(&MPC_SRAM_DEV, ctrl);
+
+    return error_trans(ret);
+}
+
+static int32_t SRAM_MPC_GetRegionConfig(uintptr_t base,
+                                          uintptr_t limit,
+                                          ARM_MPC_SEC_ATTR *attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_region_config(&MPC_SRAM_DEV, base, limit,
+                                    (enum mpc_sie_sec_attr_t*)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t SRAM_MPC_ConfigRegion(uintptr_t base,
+                                       uintptr_t limit,
+                                       ARM_MPC_SEC_ATTR attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_config_region(&MPC_SRAM_DEV, base, limit,
+                                (enum mpc_sie_sec_attr_t)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t SRAM_MPC_EnableInterrupt(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_irq_enable(&MPC_SRAM_DEV);
+
+    return error_trans(ret);
+}
+
+static void SRAM_MPC_DisableInterrupt(void)
+{
+    mpc_sie_irq_disable(&MPC_SRAM_DEV);
+}
+
+
+static void SRAM_MPC_ClearInterrupt(void)
+{
+    mpc_sie_clear_irq(&MPC_SRAM_DEV);
+}
+
+static uint32_t SRAM_MPC_InterruptState(void)
+{
+    return mpc_sie_irq_state(&MPC_SRAM_DEV);
+}
+
+static int32_t SRAM_MPC_LockDown(void)
+{
+    return mpc_sie_lock_down(&MPC_SRAM_DEV);
+}
+
+/* SRAM_MPC Driver CMSIS access structure */
+ARM_DRIVER_MPC Driver_SRAM_MPC = {
+    .GetVersion       = ARM_MPC_GetVersion,
+    .Initialize       = SRAM_MPC_Initialize,
+    .Uninitialize     = SRAM_MPC_Uninitialize,
+    .GetBlockSize     = SRAM_MPC_GetBlockSize,
+    .GetCtrlConfig    = SRAM_MPC_GetCtrlConfig,
+    .SetCtrlConfig    = SRAM_MPC_SetCtrlConfig,
+    .ConfigRegion     = SRAM_MPC_ConfigRegion,
+    .GetRegionConfig  = SRAM_MPC_GetRegionConfig,
+    .EnableInterrupt  = SRAM_MPC_EnableInterrupt,
+    .DisableInterrupt = SRAM_MPC_DisableInterrupt,
+    .ClearInterrupt   = SRAM_MPC_ClearInterrupt,
+    .InterruptState   = SRAM_MPC_InterruptState,
+    .LockDown         = SRAM_MPC_LockDown,
+};
+#endif /* RTE_SRAM_MPC */
+
+#if (RTE_ISRAM0_MPC)
+/* Ranges controlled by this ISRAM0_MPC */
+static const struct mpc_sie_memory_range_t MPC_ISRAM0_RANGE_S = {
+    .base         = MPC_ISRAM0_RANGE_BASE_S,
+    .limit        = MPC_ISRAM0_RANGE_LIMIT_S,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_SECURE
+};
+
+static const struct mpc_sie_memory_range_t MPC_ISRAM0_RANGE_NS = {
+    .base         = MPC_ISRAM0_RANGE_BASE_NS,
+    .limit        = MPC_ISRAM0_RANGE_LIMIT_NS,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_NONSECURE
+};
+
+#define MPC_ISRAM0_RANGE_LIST_LEN  2u
+static const struct mpc_sie_memory_range_t*
+    MPC_ISRAM0_RANGE_LIST[MPC_ISRAM0_RANGE_LIST_LEN] = {
+        &MPC_ISRAM0_RANGE_S,
+        &MPC_ISRAM0_RANGE_NS
+    };
+
+/* ISRAM0_MPC Driver wrapper functions */
+static int32_t ISRAM0_MPC_Initialize(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_init(&MPC_ISRAM0_DEV,
+                       MPC_ISRAM0_RANGE_LIST,
+                       MPC_ISRAM0_RANGE_LIST_LEN);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM0_MPC_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ISRAM0_MPC_GetBlockSize(uint32_t *blk_size)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_block_size(&MPC_ISRAM0_DEV, blk_size);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM0_MPC_GetCtrlConfig(uint32_t *ctrl_val)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_ctrl(&MPC_ISRAM0_DEV, ctrl_val);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM0_MPC_SetCtrlConfig(uint32_t ctrl)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_set_ctrl(&MPC_ISRAM0_DEV, ctrl);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM0_MPC_GetRegionConfig(uintptr_t base,
+                                          uintptr_t limit,
+                                          ARM_MPC_SEC_ATTR *attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_region_config(&MPC_ISRAM0_DEV, base, limit,
+                                    (enum mpc_sie_sec_attr_t*)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM0_MPC_ConfigRegion(uintptr_t base,
+                                       uintptr_t limit,
+                                       ARM_MPC_SEC_ATTR attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_config_region(&MPC_ISRAM0_DEV, base, limit,
+                                (enum mpc_sie_sec_attr_t)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM0_MPC_EnableInterrupt(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_irq_enable(&MPC_ISRAM0_DEV);
+
+    return error_trans(ret);
+}
+
+static void ISRAM0_MPC_DisableInterrupt(void)
+{
+    mpc_sie_irq_disable(&MPC_ISRAM0_DEV);
+}
+
+
+static void ISRAM0_MPC_ClearInterrupt(void)
+{
+    mpc_sie_clear_irq(&MPC_ISRAM0_DEV);
+}
+
+static uint32_t ISRAM0_MPC_InterruptState(void)
+{
+    return mpc_sie_irq_state(&MPC_ISRAM0_DEV);
+}
+
+static int32_t ISRAM0_MPC_LockDown(void)
+{
+    return mpc_sie_lock_down(&MPC_ISRAM0_DEV);
+}
+
+/* ISRAM0_MPC Driver CMSIS access structure */
+ARM_DRIVER_MPC Driver_ISRAM0_MPC = {
+    .GetVersion       = ARM_MPC_GetVersion,
+    .Initialize       = ISRAM0_MPC_Initialize,
+    .Uninitialize     = ISRAM0_MPC_Uninitialize,
+    .GetBlockSize     = ISRAM0_MPC_GetBlockSize,
+    .GetCtrlConfig    = ISRAM0_MPC_GetCtrlConfig,
+    .SetCtrlConfig    = ISRAM0_MPC_SetCtrlConfig,
+    .ConfigRegion     = ISRAM0_MPC_ConfigRegion,
+    .GetRegionConfig  = ISRAM0_MPC_GetRegionConfig,
+    .EnableInterrupt  = ISRAM0_MPC_EnableInterrupt,
+    .DisableInterrupt = ISRAM0_MPC_DisableInterrupt,
+    .ClearInterrupt   = ISRAM0_MPC_ClearInterrupt,
+    .InterruptState   = ISRAM0_MPC_InterruptState,
+    .LockDown         = ISRAM0_MPC_LockDown,
+};
+#endif /* RTE_ISRAM0_MPC */
+
+#if (RTE_ISRAM1_MPC)
+/* Ranges controlled by this ISRAM1_MPC */
+static const struct mpc_sie_memory_range_t MPC_ISRAM1_RANGE_S = {
+    .base         = MPC_ISRAM1_RANGE_BASE_S,
+    .limit        = MPC_ISRAM1_RANGE_LIMIT_S,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_SECURE
+};
+
+static const struct mpc_sie_memory_range_t MPC_ISRAM1_RANGE_NS = {
+    .base         = MPC_ISRAM1_RANGE_BASE_NS,
+    .limit        = MPC_ISRAM1_RANGE_LIMIT_NS,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_NONSECURE
+};
+
+#define MPC_ISRAM1_RANGE_LIST_LEN  2u
+static const struct mpc_sie_memory_range_t*
+    MPC_ISRAM1_RANGE_LIST[MPC_ISRAM1_RANGE_LIST_LEN] = {
+        &MPC_ISRAM1_RANGE_S,
+        &MPC_ISRAM1_RANGE_NS
+    };
+
+/* ISRAM1_MPC Driver wrapper functions */
+static int32_t ISRAM1_MPC_Initialize(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_init(&MPC_ISRAM1_DEV,
+                       MPC_ISRAM1_RANGE_LIST,
+                       MPC_ISRAM1_RANGE_LIST_LEN);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM1_MPC_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ISRAM1_MPC_GetBlockSize(uint32_t *blk_size)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_block_size(&MPC_ISRAM1_DEV, blk_size);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM1_MPC_GetCtrlConfig(uint32_t *ctrl_val)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_ctrl(&MPC_ISRAM1_DEV, ctrl_val);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM1_MPC_SetCtrlConfig(uint32_t ctrl)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_set_ctrl(&MPC_ISRAM1_DEV, ctrl);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM1_MPC_GetRegionConfig(uintptr_t base,
+                                          uintptr_t limit,
+                                          ARM_MPC_SEC_ATTR *attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_region_config(&MPC_ISRAM1_DEV, base, limit,
+                                    (enum mpc_sie_sec_attr_t*)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM1_MPC_ConfigRegion(uintptr_t base,
+                                       uintptr_t limit,
+                                       ARM_MPC_SEC_ATTR attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_config_region(&MPC_ISRAM1_DEV, base, limit,
+                                (enum mpc_sie_sec_attr_t)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t ISRAM1_MPC_EnableInterrupt(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_irq_enable(&MPC_ISRAM1_DEV);
+
+    return error_trans(ret);
+}
+
+static void ISRAM1_MPC_DisableInterrupt(void)
+{
+    mpc_sie_irq_disable(&MPC_ISRAM1_DEV);
+}
+
+
+static void ISRAM1_MPC_ClearInterrupt(void)
+{
+    mpc_sie_clear_irq(&MPC_ISRAM1_DEV);
+}
+
+static uint32_t ISRAM1_MPC_InterruptState(void)
+{
+    return mpc_sie_irq_state(&MPC_ISRAM1_DEV);
+}
+
+static int32_t ISRAM1_MPC_LockDown(void)
+{
+    return mpc_sie_lock_down(&MPC_ISRAM1_DEV);
+}
+
+/* ISRAM1_MPC Driver CMSIS access structure */
+ARM_DRIVER_MPC Driver_ISRAM1_MPC = {
+    .GetVersion       = ARM_MPC_GetVersion,
+    .Initialize       = ISRAM1_MPC_Initialize,
+    .Uninitialize     = ISRAM1_MPC_Uninitialize,
+    .GetBlockSize     = ISRAM1_MPC_GetBlockSize,
+    .GetCtrlConfig    = ISRAM1_MPC_GetCtrlConfig,
+    .SetCtrlConfig    = ISRAM1_MPC_SetCtrlConfig,
+    .ConfigRegion     = ISRAM1_MPC_ConfigRegion,
+    .GetRegionConfig  = ISRAM1_MPC_GetRegionConfig,
+    .EnableInterrupt  = ISRAM1_MPC_EnableInterrupt,
+    .DisableInterrupt = ISRAM1_MPC_DisableInterrupt,
+    .ClearInterrupt   = ISRAM1_MPC_ClearInterrupt,
+    .InterruptState   = ISRAM1_MPC_InterruptState,
+    .LockDown         = ISRAM1_MPC_LockDown,
+};
+#endif /* RTE_ISRAM1_MPC */
+
+#if (RTE_QSPI_MPC)
+/* Ranges controlled by this QSPI_MPC */
+static const struct mpc_sie_memory_range_t MPC_QSPI_RANGE_S = {
+    .base         = MPC_QSPI_RANGE_BASE_S,
+    .limit        = MPC_QSPI_RANGE_LIMIT_S,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_SECURE
+};
+
+static const struct mpc_sie_memory_range_t MPC_QSPI_RANGE_NS = {
+    .base         = MPC_QSPI_RANGE_BASE_NS,
+    .limit        = MPC_QSPI_RANGE_LIMIT_NS,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_NONSECURE
+};
+
+#define MPC_QSPI_RANGE_LIST_LEN  2u
+static const struct mpc_sie_memory_range_t*
+    MPC_QSPI_RANGE_LIST[MPC_QSPI_RANGE_LIST_LEN] = {
+        &MPC_QSPI_RANGE_S,
+        &MPC_QSPI_RANGE_NS
+    };
+
+/* QSPI_MPC Driver wrapper functions */
+static int32_t QSPI_MPC_Initialize(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_init(&MPC_QSPI_DEV,
+                       MPC_QSPI_RANGE_LIST,
+                       MPC_QSPI_RANGE_LIST_LEN);
+
+    return error_trans(ret);
+}
+
+static int32_t QSPI_MPC_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t QSPI_MPC_GetBlockSize(uint32_t *blk_size)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_block_size(&MPC_QSPI_DEV, blk_size);
+
+    return error_trans(ret);
+}
+
+static int32_t QSPI_MPC_GetCtrlConfig(uint32_t *ctrl_val)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_ctrl(&MPC_QSPI_DEV, ctrl_val);
+
+    return error_trans(ret);
+}
+
+static int32_t QSPI_MPC_SetCtrlConfig(uint32_t ctrl)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_set_ctrl(&MPC_QSPI_DEV, ctrl);
+
+    return error_trans(ret);
+}
+
+static int32_t QSPI_MPC_GetRegionConfig(uintptr_t base,
+                                          uintptr_t limit,
+                                          ARM_MPC_SEC_ATTR *attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_region_config(&MPC_QSPI_DEV, base, limit,
+                                    (enum mpc_sie_sec_attr_t*)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t QSPI_MPC_ConfigRegion(uintptr_t base,
+                                       uintptr_t limit,
+                                       ARM_MPC_SEC_ATTR attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_config_region(&MPC_QSPI_DEV, base, limit,
+                                (enum mpc_sie_sec_attr_t)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t QSPI_MPC_EnableInterrupt(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_irq_enable(&MPC_QSPI_DEV);
+
+    return error_trans(ret);
+}
+
+static void QSPI_MPC_DisableInterrupt(void)
+{
+    mpc_sie_irq_disable(&MPC_QSPI_DEV);
+}
+
+
+static void QSPI_MPC_ClearInterrupt(void)
+{
+    mpc_sie_clear_irq(&MPC_QSPI_DEV);
+}
+
+static uint32_t QSPI_MPC_InterruptState(void)
+{
+    return mpc_sie_irq_state(&MPC_QSPI_DEV);
+}
+
+static int32_t QSPI_MPC_LockDown(void)
+{
+    return mpc_sie_lock_down(&MPC_QSPI_DEV);
+}
+
+/* QSPI_MPC Driver CMSIS access structure */
+ARM_DRIVER_MPC Driver_QSPI_MPC = {
+    .GetVersion       = ARM_MPC_GetVersion,
+    .Initialize       = QSPI_MPC_Initialize,
+    .Uninitialize     = QSPI_MPC_Uninitialize,
+    .GetBlockSize     = QSPI_MPC_GetBlockSize,
+    .GetCtrlConfig    = QSPI_MPC_GetCtrlConfig,
+    .SetCtrlConfig    = QSPI_MPC_SetCtrlConfig,
+    .ConfigRegion     = QSPI_MPC_ConfigRegion,
+    .GetRegionConfig  = QSPI_MPC_GetRegionConfig,
+    .EnableInterrupt  = QSPI_MPC_EnableInterrupt,
+    .DisableInterrupt = QSPI_MPC_DisableInterrupt,
+    .ClearInterrupt   = QSPI_MPC_ClearInterrupt,
+    .InterruptState   = QSPI_MPC_InterruptState,
+    .LockDown         = QSPI_MPC_LockDown,
+};
+#endif /* RTE_QSPI_MPC */
+
+#if (RTE_DDR4_MPC)
+/* Ranges controlled by this DDR4_MPC */
+static const struct mpc_sie_memory_range_t MPC_DDR4_RANGE_S = {
+    .base         = MPC_DDR4_RANGE_BASE_S,
+    .limit        = MPC_DDR4_RANGE_LIMIT_S,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_SECURE
+};
+
+static const struct mpc_sie_memory_range_t MPC_DDR4_RANGE_NS = {
+    .base         = MPC_DDR4_RANGE_BASE_NS,
+    .limit        = MPC_DDR4_RANGE_LIMIT_NS,
+    .range_offset = 0,
+    .attr         = MPC_SIE_SEC_ATTR_NONSECURE
+};
+
+#define MPC_DDR4_RANGE_LIST_LEN  2u
+static const struct mpc_sie_memory_range_t*
+    MPC_DDR4_RANGE_LIST[MPC_DDR4_RANGE_LIST_LEN] = {
+        &MPC_DDR4_RANGE_S,
+        &MPC_DDR4_RANGE_NS
+    };
+
+/* DDR4_MPC Driver wrapper functions */
+static int32_t DDR4_MPC_Initialize(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_init(&MPC_DDR4_DEV,
+                       MPC_DDR4_RANGE_LIST,
+                       MPC_DDR4_RANGE_LIST_LEN);
+
+    return error_trans(ret);
+}
+
+static int32_t DDR4_MPC_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t DDR4_MPC_GetBlockSize(uint32_t *blk_size)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_block_size(&MPC_DDR4_DEV, blk_size);
+
+    return error_trans(ret);
+}
+
+static int32_t DDR4_MPC_GetCtrlConfig(uint32_t *ctrl_val)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_ctrl(&MPC_DDR4_DEV, ctrl_val);
+
+    return error_trans(ret);
+}
+
+static int32_t DDR4_MPC_SetCtrlConfig(uint32_t ctrl)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_set_ctrl(&MPC_DDR4_DEV, ctrl);
+
+    return error_trans(ret);
+}
+
+static int32_t DDR4_MPC_GetRegionConfig(uintptr_t base,
+                                          uintptr_t limit,
+                                          ARM_MPC_SEC_ATTR *attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_get_region_config(&MPC_DDR4_DEV, base, limit,
+                                    (enum mpc_sie_sec_attr_t*)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t DDR4_MPC_ConfigRegion(uintptr_t base,
+                                       uintptr_t limit,
+                                       ARM_MPC_SEC_ATTR attr)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_config_region(&MPC_DDR4_DEV, base, limit,
+                                (enum mpc_sie_sec_attr_t)attr);
+
+    return error_trans(ret);
+}
+
+static int32_t DDR4_MPC_EnableInterrupt(void)
+{
+    enum mpc_sie_error_t ret;
+
+    ret = mpc_sie_irq_enable(&MPC_DDR4_DEV);
+
+    return error_trans(ret);
+}
+
+static void DDR4_MPC_DisableInterrupt(void)
+{
+    mpc_sie_irq_disable(&MPC_DDR4_DEV);
+}
+
+
+static void DDR4_MPC_ClearInterrupt(void)
+{
+    mpc_sie_clear_irq(&MPC_DDR4_DEV);
+}
+
+static uint32_t DDR4_MPC_InterruptState(void)
+{
+    return mpc_sie_irq_state(&MPC_DDR4_DEV);
+}
+
+static int32_t DDR4_MPC_LockDown(void)
+{
+    return mpc_sie_lock_down(&MPC_DDR4_DEV);
+}
+
+/* DDR4_MPC Driver CMSIS access structure */
+ARM_DRIVER_MPC Driver_DDR4_MPC = {
+    .GetVersion       = ARM_MPC_GetVersion,
+    .Initialize       = DDR4_MPC_Initialize,
+    .Uninitialize     = DDR4_MPC_Uninitialize,
+    .GetBlockSize     = DDR4_MPC_GetBlockSize,
+    .GetCtrlConfig    = DDR4_MPC_GetCtrlConfig,
+    .SetCtrlConfig    = DDR4_MPC_SetCtrlConfig,
+    .ConfigRegion     = DDR4_MPC_ConfigRegion,
+    .GetRegionConfig  = DDR4_MPC_GetRegionConfig,
+    .EnableInterrupt  = DDR4_MPC_EnableInterrupt,
+    .DisableInterrupt = DDR4_MPC_DisableInterrupt,
+    .ClearInterrupt   = DDR4_MPC_ClearInterrupt,
+    .InterruptState   = DDR4_MPC_InterruptState,
+    .LockDown         = DDR4_MPC_LockDown,
+};
+#endif /* RTE_DDR4_MPC */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_PPC.c b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_PPC.c
new file mode 100644
index 0000000..515d64a
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_PPC.c
@@ -0,0 +1,1305 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Driver_PPC.h"
+
+#include "Driver_Common.h"
+#include "cmsis.h"
+#include "cmsis_driver_config.h"
+#include "RTE_Device.h"
+#include "ppc_polaris_drv.h"
+
+/* Driver version */
+#define ARM_PPC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0)
+
+/* Driver Version */
+static const ARM_DRIVER_VERSION DriverVersion = {
+    ARM_PPC_API_VERSION,
+    ARM_PPC_DRV_VERSION
+};
+
+ARM_DRIVER_VERSION PPC_POLARIS_GetVersion(void)
+{
+    return DriverVersion;
+}
+
+typedef struct _POLARIS_PPC_Resources {
+    struct ppc_polaris_dev_t* dev;       /* PPC device structure */
+} POLARIS_PPC_Resources;
+
+#if (RTE_PPC_POLARIS_MAIN0)
+
+static POLARIS_PPC_Resources MAIN0_PPC_DEV = {
+    .dev = &PPC_POLARIS_MAIN0_DEV,
+};
+
+/* MAIN0 PPC Driver wrapper functions */
+static int32_t PPC_POLARIS_MAIN0_Initialize(void)
+{
+    ppc_polaris_init(MAIN0_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_MAIN0_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_MAIN0_ConfigPrivilege(uint32_t periph,
+                                 PPC_POLARIS_SecAttr sec_attr,
+                                 PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(MAIN0_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN0_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(MAIN0_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_MAIN0_ConfigSecurity(uint32_t periph, PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(MAIN0_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN0_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(MAIN0_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_MAIN0_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(MAIN0_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_MAIN0_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(MAIN0_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_MAIN0_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(MAIN0_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_MAIN0_InterruptState(void)
+{
+    return ppc_polaris_irq_state(MAIN0_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris MAIN0 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN0 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_MAIN0_Initialize,
+    .Uninitialize      = PPC_POLARIS_MAIN0_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_MAIN0_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_MAIN0_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_MAIN0_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_MAIN0_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_MAIN0_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_MAIN0_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_MAIN0_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_MAIN0_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_MAIN0 */
+
+#if (RTE_PPC_POLARIS_MAIN_EXP0)
+
+static POLARIS_PPC_Resources MAIN_EXP0_PPC_DEV = {
+    .dev = &PPC_POLARIS_MAIN_EXP0_DEV,
+};
+
+/* MAIN PPCEXP0 Driver wrapper functions */
+static int32_t PPC_POLARIS_MAIN_EXP0_Initialize(void)
+{
+    ppc_polaris_init(MAIN_EXP0_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP0_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_MAIN_EXP0_ConfigPrivilege(uint32_t periph,
+                                     PPC_POLARIS_SecAttr sec_attr,
+                                     PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(MAIN_EXP0_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP0_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(MAIN_EXP0_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_MAIN_EXP0_ConfigSecurity(uint32_t periph,
+                                    PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(MAIN_EXP0_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP0_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(MAIN_EXP0_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP0_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(MAIN_EXP0_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_MAIN_EXP0_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(MAIN_EXP0_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_MAIN_EXP0_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(MAIN_EXP0_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_MAIN_EXP0_InterruptState(void)
+{
+    return ppc_polaris_irq_state(MAIN_EXP0_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris MAIN EXP0 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP0 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_MAIN_EXP0_Initialize,
+    .Uninitialize      = PPC_POLARIS_MAIN_EXP0_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_MAIN_EXP0_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_MAIN_EXP0_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_MAIN_EXP0_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_MAIN_EXP0_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_MAIN_EXP0_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_MAIN_EXP0_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_MAIN_EXP0_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_MAIN_EXP0_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_MAIN_EXP0 */
+
+#if (RTE_PPC_POLARIS_MAIN_EXP1)
+
+static POLARIS_PPC_Resources MAIN_EXP1_PPC_DEV = {
+    .dev = &PPC_POLARIS_MAIN_EXP1_DEV,
+};
+
+/* MAIN PPCEXP1 Driver wrapper functions */
+static int32_t PPC_POLARIS_MAIN_EXP1_Initialize(void)
+{
+    ppc_polaris_init(MAIN_EXP1_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP1_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_MAIN_EXP1_ConfigPrivilege(uint32_t periph,
+                                     PPC_POLARIS_SecAttr sec_attr,
+                                     PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(MAIN_EXP1_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP1_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(MAIN_EXP1_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_MAIN_EXP1_ConfigSecurity(uint32_t periph,
+                                    PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(MAIN_EXP1_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP1_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(MAIN_EXP1_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP1_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(MAIN_EXP1_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_MAIN_EXP1_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(MAIN_EXP1_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_MAIN_EXP1_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(MAIN_EXP1_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_MAIN_EXP1_InterruptState(void)
+{
+    return ppc_polaris_irq_state(MAIN_EXP1_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris MAIN EXP1 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP1 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_MAIN_EXP1_Initialize,
+    .Uninitialize      = PPC_POLARIS_MAIN_EXP1_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_MAIN_EXP1_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_MAIN_EXP1_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_MAIN_EXP1_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_MAIN_EXP1_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_MAIN_EXP1_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_MAIN_EXP1_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_MAIN_EXP1_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_MAIN_EXP1_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_MAIN_EXP1 */
+
+#if (RTE_PPC_POLARIS_MAIN_EXP2)
+
+static POLARIS_PPC_Resources MAIN_EXP2_PPC_DEV = {
+    .dev = &PPC_POLARIS_MAIN_EXP2_DEV,
+};
+
+/* MAIN PPCEXP2 Driver wrapper functions */
+static int32_t PPC_POLARIS_MAIN_EXP2_Initialize(void)
+{
+    ppc_polaris_init(MAIN_EXP2_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP2_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_MAIN_EXP2_ConfigPrivilege(uint32_t periph,
+                                     PPC_POLARIS_SecAttr sec_attr,
+                                     PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(MAIN_EXP2_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP2_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(MAIN_EXP2_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_MAIN_EXP2_ConfigSecurity(uint32_t periph,
+                                    PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(MAIN_EXP2_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP2_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(MAIN_EXP2_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP2_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(MAIN_EXP2_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_MAIN_EXP2_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(MAIN_EXP2_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_MAIN_EXP2_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(MAIN_EXP2_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_MAIN_EXP2_InterruptState(void)
+{
+    return ppc_polaris_irq_state(MAIN_EXP2_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris MAIN EXP2 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP2 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_MAIN_EXP2_Initialize,
+    .Uninitialize      = PPC_POLARIS_MAIN_EXP2_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_MAIN_EXP2_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_MAIN_EXP2_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_MAIN_EXP2_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_MAIN_EXP2_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_MAIN_EXP2_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_MAIN_EXP2_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_MAIN_EXP2_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_MAIN_EXP2_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_MAIN_EXP2 */
+
+#if (RTE_PPC_POLARIS_MAIN_EXP3)
+
+static POLARIS_PPC_Resources MAIN_EXP3_PPC_DEV = {
+    .dev = &PPC_POLARIS_MAIN_EXP3_DEV,
+};
+
+/* MAIN PPCEXP3 Driver wrapper functions */
+static int32_t PPC_POLARIS_MAIN_EXP3_Initialize(void)
+{
+    ppc_polaris_init(MAIN_EXP3_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP3_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_MAIN_EXP3_ConfigPrivilege(uint32_t periph,
+                                     PPC_POLARIS_SecAttr sec_attr,
+                                     PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(MAIN_EXP3_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP3_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(MAIN_EXP3_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_MAIN_EXP3_ConfigSecurity(uint32_t periph,
+                                    PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(MAIN_EXP3_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_MAIN_EXP3_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(MAIN_EXP3_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_MAIN_EXP3_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(MAIN_EXP3_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_MAIN_EXP3_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(MAIN_EXP3_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_MAIN_EXP3_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(MAIN_EXP3_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_MAIN_EXP3_InterruptState(void)
+{
+    return ppc_polaris_irq_state(MAIN_EXP3_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris MAIN EXP3 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP3 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_MAIN_EXP3_Initialize,
+    .Uninitialize      = PPC_POLARIS_MAIN_EXP3_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_MAIN_EXP3_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_MAIN_EXP3_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_MAIN_EXP3_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_MAIN_EXP3_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_MAIN_EXP3_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_MAIN_EXP3_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_MAIN_EXP3_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_MAIN_EXP3_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_MAIN_EXP3 */
+
+#if (RTE_PPC_POLARIS_PERIPH0)
+
+static POLARIS_PPC_Resources PERIPH0_PPC_DEV = {
+    .dev = &PPC_POLARIS_PERIPH0_DEV,
+};
+
+/* PERIPH0 Driver wrapper functions */
+static int32_t PPC_POLARIS_PERIPH0_Initialize(void)
+{
+    ppc_polaris_init(PERIPH0_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_PERIPH0_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_PERIPH0_ConfigPrivilege(uint32_t periph,
+                                   PPC_POLARIS_SecAttr sec_attr,
+                                   PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(PERIPH0_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH0_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(PERIPH0_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_PERIPH0_ConfigSecurity(uint32_t periph,
+                                  PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(PERIPH0_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH0_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(PERIPH0_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_PERIPH0_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(PERIPH0_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_PERIPH0_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(PERIPH0_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_PERIPH0_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(PERIPH0_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_PERIPH0_InterruptState(void)
+{
+    return ppc_polaris_irq_state(PERIPH0_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris PERIPH0 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH0 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_PERIPH0_Initialize,
+    .Uninitialize      = PPC_POLARIS_PERIPH0_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_PERIPH0_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_PERIPH0_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_PERIPH0_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_PERIPH0_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_PERIPH0_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_PERIPH0_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_PERIPH0_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_PERIPH0_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_PERIPH0 */
+
+#if (RTE_PPC_POLARIS_PERIPH1)
+
+static POLARIS_PPC_Resources PERIPH1_PPC_DEV = {
+    .dev = &PPC_POLARIS_PERIPH1_DEV,
+};
+
+/* PERIPH1 Driver wrapper functions */
+static int32_t PPC_POLARIS_PERIPH1_Initialize(void)
+{
+    ppc_polaris_init(PERIPH1_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_PERIPH1_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_PERIPH1_ConfigPrivilege(uint32_t periph,
+                                   PPC_POLARIS_SecAttr sec_attr,
+                                   PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(PERIPH1_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH1_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(PERIPH1_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_PERIPH1_ConfigSecurity(uint32_t periph,
+                                  PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(PERIPH1_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH1_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(PERIPH1_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_PERIPH1_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(PERIPH1_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_PERIPH1_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(PERIPH1_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_PERIPH1_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(PERIPH1_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_PERIPH1_InterruptState(void)
+{
+    return ppc_polaris_irq_state(PERIPH1_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris PERIPH1 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH1 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_PERIPH1_Initialize,
+    .Uninitialize      = PPC_POLARIS_PERIPH1_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_PERIPH1_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_PERIPH1_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_PERIPH1_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_PERIPH1_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_PERIPH1_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_PERIPH1_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_PERIPH1_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_PERIPH1_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_PERIPH1 */
+
+#if (RTE_PPC_POLARIS_PERIPH_EXP0)
+
+static POLARIS_PPC_Resources PERIPH_EXP0_PPC_DEV = {
+    .dev = &PPC_POLARIS_PERIPH_EXP0_DEV,
+};
+
+/* PERIPH PPCEXP0 Driver wrapper functions */
+static int32_t PPC_POLARIS_PERIPH_EXP0_Initialize(void)
+{
+    ppc_polaris_init(PERIPH_EXP0_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP0_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP0_ConfigPrivilege(uint32_t periph,
+                                       PPC_POLARIS_SecAttr sec_attr,
+                                       PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(PERIPH_EXP0_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP0_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(PERIPH_EXP0_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP0_ConfigSecurity(uint32_t periph,
+                                      PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(PERIPH_EXP0_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP0_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(PERIPH_EXP0_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP0_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(PERIPH_EXP0_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_PERIPH_EXP0_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(PERIPH_EXP0_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_PERIPH_EXP0_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(PERIPH_EXP0_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_PERIPH_EXP0_InterruptState(void)
+{
+    return ppc_polaris_irq_state(PERIPH_EXP0_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris PERIPH EXP0 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP0 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_PERIPH_EXP0_Initialize,
+    .Uninitialize      = PPC_POLARIS_PERIPH_EXP0_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_PERIPH_EXP0_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_PERIPH_EXP0_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_PERIPH_EXP0_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_PERIPH_EXP0_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_PERIPH_EXP0_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_PERIPH_EXP0_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_PERIPH_EXP0_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_PERIPH_EXP0_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_PERIPH_EXP0 */
+
+#if (RTE_PPC_POLARIS_PERIPH_EXP1)
+
+static POLARIS_PPC_Resources PERIPH_EXP1_PPC_DEV = {
+    .dev = &PPC_POLARIS_PERIPH_EXP1_DEV,
+};
+
+/* PERIPH PPCEXP1 Driver wrapper functions */
+static int32_t PPC_POLARIS_PERIPH_EXP1_Initialize(void)
+{
+    ppc_polaris_init(PERIPH_EXP1_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP1_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP1_ConfigPrivilege(uint32_t periph,
+                                       PPC_POLARIS_SecAttr sec_attr,
+                                       PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(PERIPH_EXP1_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP1_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(PERIPH_EXP1_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP1_ConfigSecurity(uint32_t periph,
+                                      PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(PERIPH_EXP1_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP1_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(PERIPH_EXP1_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP1_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(PERIPH_EXP1_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_PERIPH_EXP1_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(PERIPH_EXP1_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_PERIPH_EXP1_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(PERIPH_EXP1_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_PERIPH_EXP1_InterruptState(void)
+{
+    return ppc_polaris_irq_state(PERIPH_EXP1_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris PERIPH EXP1 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP1 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_PERIPH_EXP1_Initialize,
+    .Uninitialize      = PPC_POLARIS_PERIPH_EXP1_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_PERIPH_EXP1_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_PERIPH_EXP1_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_PERIPH_EXP1_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_PERIPH_EXP1_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_PERIPH_EXP1_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_PERIPH_EXP1_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_PERIPH_EXP1_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_PERIPH_EXP1_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_PERIPH_EXP1 */
+
+#if (RTE_PPC_POLARIS_PERIPH_EXP2)
+
+static POLARIS_PPC_Resources PERIPH_EXP2_PPC_DEV = {
+    .dev = &PPC_POLARIS_PERIPH_EXP2_DEV,
+};
+
+/* PERIPH PPCEXP2 Driver wrapper functions */
+static int32_t PPC_POLARIS_PERIPH_EXP2_Initialize(void)
+{
+    ppc_polaris_init(PERIPH_EXP2_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP2_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP2_ConfigPrivilege(uint32_t periph,
+                                       PPC_POLARIS_SecAttr sec_attr,
+                                       PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(PERIPH_EXP2_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP2_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(PERIPH_EXP2_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP2_ConfigSecurity(uint32_t periph,
+                                      PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(PERIPH_EXP2_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP2_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(PERIPH_EXP2_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP2_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(PERIPH_EXP2_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_PERIPH_EXP2_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(PERIPH_EXP2_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_PERIPH_EXP2_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(PERIPH_EXP2_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_PERIPH_EXP2_InterruptState(void)
+{
+    return ppc_polaris_irq_state(PERIPH_EXP2_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris PERIPH EXP2 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP2 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_PERIPH_EXP2_Initialize,
+    .Uninitialize      = PPC_POLARIS_PERIPH_EXP2_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_PERIPH_EXP2_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_PERIPH_EXP2_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_PERIPH_EXP2_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_PERIPH_EXP2_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_PERIPH_EXP2_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_PERIPH_EXP2_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_PERIPH_EXP2_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_PERIPH_EXP2_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_PERIPH_EXP2 */
+
+#if (RTE_PPC_POLARIS_PERIPH_EXP3)
+
+static POLARIS_PPC_Resources PERIPH_EXP3_PPC_DEV = {
+    .dev = &PPC_POLARIS_PERIPH_EXP3_DEV,
+};
+
+/* PERIPH PPCEXP3 Driver wrapper functions */
+static int32_t PPC_POLARIS_PERIPH_EXP3_Initialize(void)
+{
+    ppc_polaris_init(PERIPH_EXP3_PPC_DEV.dev);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP3_Uninitialize(void)
+{
+    /* Nothing to do */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP3_ConfigPrivilege(uint32_t periph,
+                                       PPC_POLARIS_SecAttr sec_attr,
+                                       PPC_POLARIS_PrivAttr priv_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_privilege(PERIPH_EXP3_PPC_DEV.dev, periph,
+                                      (enum ppc_polaris_sec_attr_t)sec_attr,
+                                      (enum ppc_polaris_priv_attr_t)priv_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP3_IsPeriphPrivOnly(uint32_t periph)
+{
+    return ppc_polaris_is_periph_priv_only(PERIPH_EXP3_PPC_DEV.dev, periph);
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+static int32_t
+PPC_POLARIS_PERIPH_EXP3_ConfigSecurity(uint32_t periph,
+                                      PPC_POLARIS_SecAttr sec_attr)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_config_security(PERIPH_EXP3_PPC_DEV.dev, periph,
+                                     (enum ppc_polaris_sec_attr_t)sec_attr);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static bool PPC_POLARIS_PERIPH_EXP3_IsPeriphSecure(uint32_t periph)
+{
+    return ppc_polaris_is_periph_secure(PERIPH_EXP3_PPC_DEV.dev, periph);
+}
+
+static int32_t PPC_POLARIS_PERIPH_EXP3_EnableInterrupt(void)
+{
+    enum ppc_polaris_error_t ret;
+
+    ret = ppc_polaris_irq_enable(PERIPH_EXP3_PPC_DEV.dev);
+
+    if( ret != PPC_POLARIS_ERR_NONE) {
+        return ARM_DRIVER_ERROR;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static void PPC_POLARIS_PERIPH_EXP3_DisableInterrupt(void)
+{
+    ppc_polaris_irq_disable(PERIPH_EXP3_PPC_DEV.dev);
+}
+
+static void PPC_POLARIS_PERIPH_EXP3_ClearInterrupt(void)
+{
+    ppc_polaris_clear_irq(PERIPH_EXP3_PPC_DEV.dev);
+}
+
+static bool PPC_POLARIS_PERIPH_EXP3_InterruptState(void)
+{
+    return ppc_polaris_irq_state(PERIPH_EXP3_PPC_DEV.dev);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+/* PPC Polaris PERIPH EXP3 Driver CMSIS access structure */
+DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP3 = {
+    .GetVersion        = PPC_POLARIS_GetVersion,
+    .Initialize        = PPC_POLARIS_PERIPH_EXP3_Initialize,
+    .Uninitialize      = PPC_POLARIS_PERIPH_EXP3_Uninitialize,
+    .ConfigPrivilege   = PPC_POLARIS_PERIPH_EXP3_ConfigPrivilege,
+    .IsPeriphPrivOnly  = PPC_POLARIS_PERIPH_EXP3_IsPeriphPrivOnly,
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    .ConfigSecurity    = PPC_POLARIS_PERIPH_EXP3_ConfigSecurity,
+    .IsPeriphSecure    = PPC_POLARIS_PERIPH_EXP3_IsPeriphSecure,
+    .EnableInterrupt   = PPC_POLARIS_PERIPH_EXP3_EnableInterrupt,
+    .DisableInterrupt  = PPC_POLARIS_PERIPH_EXP3_DisableInterrupt,
+    .ClearInterrupt    = PPC_POLARIS_PERIPH_EXP3_ClearInterrupt,
+    .InterruptState    = PPC_POLARIS_PERIPH_EXP3_InterruptState
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+};
+#endif /* RTE_PPC_POLARIS_PERIPH_EXP3 */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_PPC.h b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_PPC.h
new file mode 100644
index 0000000..85a8daa
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_PPC.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PPC_POLARIS_DRIVER_H__
+#define __PPC_POLARIS_DRIVER_H__
+
+#include "Driver_Common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API version */
+#define ARM_PPC_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0)
+
+/* Security attribute used to configure the peripheral */
+typedef enum _PPC_POLARIS_SecAttr {
+    PPC_POLARIS_SECURE_CONFIG = 0,    /*!< Secure access */
+    PPC_POLARIS_NONSECURE_CONFIG,     /*!< Non-secure access */
+} PPC_POLARIS_SecAttr;
+
+/* Privilege attribute used to configure the peripheral */
+typedef enum _PPC_POLARIS_PrivAttr {
+    PPC_POLARIS_PRIV_AND_NONPRIV_CONFIG = 0, /*!< Privilege and non-privilege
+                                             * access */
+    PPC_POLARIS_PRIV_CONFIG,                 /*!< Privilege only access */
+} PPC_POLARIS_PrivAttr;
+
+/* Function descriptions */
+/**
+  SACFG  - Secure Privilege Control Block
+  NSACFG - Non-Secure Privilege Control Block
+
+  \fn          ARM_DRIVER_VERSION PPC_POLARIS_GetVersion(void)
+  \brief       Get driver version.
+  \return      \ref ARM_DRIVER_VERSION
+
+  \fn          int32_t PPC_POLARIS_Initialize(void)
+  \brief       Initializes PPC Interface.
+  \return      Returns Polaris PPC error code.
+
+  \fn          int32_t PPC_POLARIS_Uninitialize(void)
+  \brief       De-initializes PPC Interface.
+  \return      Returns Polaris PPC error code.
+
+  \fn          int32_t PPC_POLARIS_ConfigPrivilege(uint32_t periph,
+                                                  PPC_POLARIS_SecAttr sec_attr,
+                                                  PPC_POLARIS_PrivAttr priv_attr)
+  \brief       Configures privilege level with privileged and unprivileged
+               access or privileged access only in the given security domain
+               for a peripheral controlled by the given PPC.
+  \param[in]   periph:     Peripheral mask for SACFG and NSACFG registers.
+  \param[in]   sec_attr:   Specifies Secure or Non Secure domain.
+  \param[in]   priv_attr:  Privilege attribute value to set.
+  \return      Returns Polaris PPC error code.
+
+  \fn          bool PPC_POLARIS_IsPeriphPrivOnly (uint32_t periph)
+  \brief       Checks if the peripheral is configured to be privilege only
+                - with non-secure caller in the non-secure domain
+                - with secure caller in the configured security domain
+  \param[in]   periph:      Peripheral mask for SACFG and NSACFG registers.
+  \return      Returns true if the peripheral is configured as privilege access
+               only, false for privilege and unprivilege access mode.
+
+  Secure only functions:
+
+  \fn          int32_t PPC_POLARIS_ConfigSecurity(uint32_t periph,
+                                                 PPC_POLARIS_SecAttr sec_attr)
+  \brief       Configures security level for a peripheral controlled by the
+               given PPC with secure or non-secure access only.
+  \param[in]   periph:     Peripheral mask for SACFG and NSACFG registers.
+  \param[in]   sec_attr:   Secure attribute value to set.
+  \return      Returns Polaris PPC error code.
+
+  \fn          bool PPC_POLARIS_IsPeriphSecure (uint32_t periph)
+  \brief       Checks if the peripheral is configured to be secure.
+  \param[in]   periph:      Peripheral mask for SACFG  and NSACFG registers.
+  \return      Returns true if the peripheral is configured as secure,
+               false for non-secure.
+
+  \fn          int32_t PPC_POLARIS_EnableInterrupt (void)
+  \brief       Enables PPC interrupt.
+  \return      Returns Polaris PPC error code.
+
+  \fn          void PPC_POLARIS_DisableInterrupt (void)
+  \brief       Disables PPC interrupt.
+
+  \fn          void PPC_POLARIS_ClearInterrupt (void)
+  \brief       Clears PPC interrupt.
+
+  \fn          bool PPC_POLARIS_InterruptState (void)
+  \brief       Gets PPC interrupt state.
+  \return      Returns true if the interrupt is active, false otherwise.
+*/
+
+/**
+ * \brief Access structure of the PPC Driver.
+ */
+typedef struct _DRIVER_PPC_POLARIS {
+  ARM_DRIVER_VERSION  (*GetVersion)       (void);            ///< Pointer to \ref ARM_PPC_GetVersion   : Get driver version.
+  int32_t             (*Initialize)       (void);            ///< Pointer to \ref ARM_PPC_Initialize   : Initialize the PPC Interface.
+  int32_t             (*Uninitialize)     (void);            ///< Pointer to \ref ARM_PPC_Uninitialize : De-initialize the PPC Interface.
+  int32_t             (*ConfigPrivilege)  (uint32_t periph, PPC_POLARIS_SecAttr sec_attr, PPC_POLARIS_PrivAttr priv_attr);  ///< Pointer to \ref ARM_PPC_ConfigPeriph : Configure a peripheral controlled by the PPC.
+  bool                (*IsPeriphPrivOnly) (uint32_t periph);  ///< Pointer to \ref IsPeriphPrivOnly : Check if the peripheral is configured to be privilege only.
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+  int32_t             (*ConfigSecurity)   (uint32_t periph, PPC_POLARIS_SecAttr sec_attr);  ///< Pointer to \ref ARM_PPC_ConfigPeriph : Configure a peripheral controlled by the PPC.
+  bool                (*IsPeriphSecure)   (uint32_t periph);  ///< Pointer to \ref IsPeriphSecure :   Check if the peripheral is configured to be secure.
+  int32_t             (*EnableInterrupt)  (void);            ///< Pointer to \ref ARM_PPC_EnableInterrupt  : Enable PPC interrupt.
+  void                (*DisableInterrupt) (void);            ///< Pointer to \ref ARM_PPC_DisableInterrupt : Disable PPC interrupt.
+  void                (*ClearInterrupt)   (void);            ///< Pointer to \ref ARM_PPC_ClearInterrupt   : Clear PPC interrupt.
+  bool                (*InterruptState)   (void);            ///< Pointer to \ref ARM_PPC_InterruptState   : PPC interrupt State.
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+} const DRIVER_PPC_POLARIS;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __PPC_POLARIS_DRIVER_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_USART.c b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_USART.c
new file mode 100644
index 0000000..cb3a14a
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/Driver_USART.c
@@ -0,0 +1,700 @@
+/*
+ * Copyright (c) 2013-2019 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Driver_USART.h"
+
+#include "cmsis_driver_config.h"
+#include "RTE_Device.h"
+
+#ifndef ARG_UNUSED
+#define ARG_UNUSED(arg)  (void)arg
+#endif
+
+/* Driver version */
+#define ARM_USART_DRV_VERSION  ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2)
+
+/* Driver Version */
+static const ARM_DRIVER_VERSION DriverVersion = {
+    ARM_USART_API_VERSION,
+    ARM_USART_DRV_VERSION
+};
+
+/* Driver Capabilities */
+static const ARM_USART_CAPABILITIES DriverCapabilities = {
+    1, /* supports UART (Asynchronous) mode */
+    0, /* supports Synchronous Master mode */
+    0, /* supports Synchronous Slave mode */
+    0, /* supports UART Single-wire mode */
+    0, /* supports UART IrDA mode */
+    0, /* supports UART Smart Card mode */
+    0, /* Smart Card Clock generator available */
+    0, /* RTS Flow Control available */
+    0, /* CTS Flow Control available */
+    0, /* Transmit completed event: \ref ARM_USARTx_EVENT_TX_COMPLETE */
+    0, /* Signal receive character timeout event: \ref ARM_USARTx_EVENT_RX_TIMEOUT */
+    0, /* RTS Line: 0=not available, 1=available */
+    0, /* CTS Line: 0=not available, 1=available */
+    0, /* DTR Line: 0=not available, 1=available */
+    0, /* DSR Line: 0=not available, 1=available */
+    0, /* DCD Line: 0=not available, 1=available */
+    0, /* RI Line: 0=not available, 1=available */
+    0, /* Signal CTS change event: \ref ARM_USARTx_EVENT_CTS */
+    0, /* Signal DSR change event: \ref ARM_USARTx_EVENT_DSR */
+    0, /* Signal DCD change event: \ref ARM_USARTx_EVENT_DCD */
+    0, /* Signal RI change event: \ref ARM_USARTx_EVENT_RI */
+    0  /* Reserved */
+};
+
+static ARM_DRIVER_VERSION ARM_USART_GetVersion(void)
+{
+    return DriverVersion;
+}
+
+static ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void)
+{
+    return DriverCapabilities;
+}
+
+typedef struct {
+    struct uart_cmsdk_dev_t *dev;        /* UART device structure */
+    uint32_t tx_nbr_bytes;             /* Number of bytes transfered */
+    uint32_t rx_nbr_bytes;             /* Number of bytes recevied */
+    ARM_USART_SignalEvent_t cb_event;  /* Callback function for events */
+} UARTx_Resources;
+
+static int32_t ARM_USARTx_Initialize(UARTx_Resources *uart_dev)
+{
+    /* Initializes generic UART driver */
+    uart_cmsdk_init(uart_dev->dev, PeripheralClock);
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USARTx_PowerControl(UARTx_Resources *uart_dev,
+                                       ARM_POWER_STATE state)
+{
+    ARG_UNUSED(uart_dev);
+
+    switch (state) {
+    case ARM_POWER_OFF:
+    case ARM_POWER_LOW:
+        return ARM_DRIVER_ERROR_UNSUPPORTED;
+    case ARM_POWER_FULL:
+        /* Nothing to be done */
+        return ARM_DRIVER_OK;
+    /* default:  The default is not defined intentionally to force the
+     *           compiler to check that all the enumeration values are
+     *           covered in the switch.*/
+    }
+}
+
+static int32_t ARM_USARTx_Send(UARTx_Resources *uart_dev, const void *data,
+                               uint32_t num)
+{
+    const uint8_t *p_data = (const uint8_t *)data;
+
+    if ((data == NULL) || (num == 0U)) {
+        /* Invalid parameters */
+        return ARM_DRIVER_ERROR_PARAMETER;
+    }
+
+    /* Resets previous TX counter */
+    uart_dev->tx_nbr_bytes = 0;
+
+    while (uart_dev->tx_nbr_bytes != num) {
+        /* Waits until UART is ready to transmit */
+        while (!uart_cmsdk_tx_ready(uart_dev->dev)) {
+        };
+
+        /* As UART is ready to transmit at this point, the write function can
+         * not return any transmit error */
+        (void)uart_cmsdk_write(uart_dev->dev, *p_data);
+
+        uart_dev->tx_nbr_bytes++;
+        p_data++;
+    }
+
+    /* Waits until character is transmited */
+    while (!uart_cmsdk_tx_ready(uart_dev->dev)) {
+    };
+
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USARTx_Receive(UARTx_Resources *uart_dev,
+                                  void *data, uint32_t num)
+{
+    uint8_t *p_data = (uint8_t *)data;
+
+    if ((data == NULL) || (num == 0U)) {
+        // Invalid parameters
+        return ARM_DRIVER_ERROR_PARAMETER;
+    }
+
+    /* Resets previous RX counter */
+    uart_dev->rx_nbr_bytes = 0;
+
+    while (uart_dev->rx_nbr_bytes != num) {
+        /* Waits until one character is received */
+        while (!uart_cmsdk_rx_ready(uart_dev->dev)){};
+
+        /* As UART has received one byte, the read can not
+         * return any receive error at this point */
+        (void)uart_cmsdk_read(uart_dev->dev, p_data);
+
+        uart_dev->rx_nbr_bytes++;
+        p_data++;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+static uint32_t ARM_USARTx_GetTxCount(UARTx_Resources *uart_dev)
+{
+    return uart_dev->tx_nbr_bytes;
+}
+
+static uint32_t ARM_USARTx_GetRxCount(UARTx_Resources *uart_dev)
+{
+    return uart_dev->rx_nbr_bytes;
+}
+
+static int32_t ARM_USARTx_Control(UARTx_Resources *uart_dev, uint32_t control,
+                                  uint32_t arg)
+{
+    switch (control & ARM_USART_CONTROL_Msk) {
+        case ARM_USART_MODE_ASYNCHRONOUS:
+            if (uart_cmsdk_set_baudrate(uart_dev->dev, arg) != UART_CMSDK_ERR_NONE) {
+                return ARM_USART_ERROR_BAUDRATE;
+            }
+            break;
+        /* Unsupported command */
+        default:
+            return ARM_DRIVER_ERROR_UNSUPPORTED;
+    }
+
+    /* UART Data bits */
+    if (control & ARM_USART_DATA_BITS_Msk) {
+        /* Data bit is not configurable */
+        return ARM_DRIVER_ERROR_UNSUPPORTED;
+    }
+
+    /* UART Parity */
+    if (control & ARM_USART_PARITY_Msk) {
+        /* Parity is not configurable */
+        return ARM_USART_ERROR_PARITY;
+    }
+
+    /* USART Stop bits */
+    if (control & ARM_USART_STOP_BITS_Msk) {
+        /* Stop bit is not configurable */
+        return ARM_USART_ERROR_STOP_BITS;
+    }
+
+    return ARM_DRIVER_OK;
+}
+
+#if (RTE_USART0)
+/* USART0 Driver wrapper functions */
+static UARTx_Resources USART0_DEV = {
+    .dev = &UART0_CMSDK_DEV,
+    .tx_nbr_bytes = 0,
+    .rx_nbr_bytes = 0,
+    .cb_event = NULL,
+};
+
+static int32_t ARM_USART0_Initialize(ARM_USART_SignalEvent_t cb_event)
+{
+    USART0_DEV.cb_event = cb_event;
+
+    return ARM_USARTx_Initialize(&USART0_DEV);
+}
+
+static int32_t ARM_USART0_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USART0_PowerControl(ARM_POWER_STATE state)
+{
+    return ARM_USARTx_PowerControl(&USART0_DEV, state);
+}
+
+static int32_t ARM_USART0_Send(const void *data, uint32_t num)
+{
+    return ARM_USARTx_Send(&USART0_DEV, data, num);
+}
+
+static int32_t ARM_USART0_Receive(void *data, uint32_t num)
+{
+    return ARM_USARTx_Receive(&USART0_DEV, data, num);
+}
+
+static int32_t ARM_USART0_Transfer(const void *data_out, void *data_in,
+                                   uint32_t num)
+{
+    ARG_UNUSED(data_out);
+    ARG_UNUSED(data_in);
+    ARG_UNUSED(num);
+
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static uint32_t ARM_USART0_GetTxCount(void)
+{
+    return ARM_USARTx_GetTxCount(&USART0_DEV);
+}
+
+static uint32_t ARM_USART0_GetRxCount(void)
+{
+    return ARM_USARTx_GetRxCount(&USART0_DEV);
+}
+static int32_t ARM_USART0_Control(uint32_t control, uint32_t arg)
+{
+    return ARM_USARTx_Control(&USART0_DEV, control, arg);
+}
+
+static ARM_USART_STATUS ARM_USART0_GetStatus(void)
+{
+    ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0};
+    return status;
+}
+
+static int32_t ARM_USART0_SetModemControl(ARM_USART_MODEM_CONTROL control)
+{
+    ARG_UNUSED(control);
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static ARM_USART_MODEM_STATUS ARM_USART0_GetModemStatus(void)
+{
+    ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0};
+    return modem_status;
+}
+
+extern ARM_DRIVER_USART Driver_USART0;
+ARM_DRIVER_USART Driver_USART0 = {
+    ARM_USART_GetVersion,
+    ARM_USART_GetCapabilities,
+    ARM_USART0_Initialize,
+    ARM_USART0_Uninitialize,
+    ARM_USART0_PowerControl,
+    ARM_USART0_Send,
+    ARM_USART0_Receive,
+    ARM_USART0_Transfer,
+    ARM_USART0_GetTxCount,
+    ARM_USART0_GetRxCount,
+    ARM_USART0_Control,
+    ARM_USART0_GetStatus,
+    ARM_USART0_SetModemControl,
+    ARM_USART0_GetModemStatus
+};
+#endif /* RTE_USART0 */
+
+#if (RTE_USART1)
+/* USART1 Driver wrapper functions */
+static UARTx_Resources USART1_DEV = {
+    .dev = &UART1_CMSDK_DEV,
+    .tx_nbr_bytes = 0,
+    .rx_nbr_bytes = 0,
+    .cb_event = NULL,
+};
+
+static int32_t ARM_USART1_Initialize(ARM_USART_SignalEvent_t cb_event)
+{
+    USART1_DEV.cb_event = cb_event;
+
+    return ARM_USARTx_Initialize(&USART1_DEV);
+}
+
+static int32_t ARM_USART1_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USART1_PowerControl(ARM_POWER_STATE state)
+{
+    return ARM_USARTx_PowerControl(&USART1_DEV, state);
+}
+
+static int32_t ARM_USART1_Send(const void *data, uint32_t num)
+{
+    return ARM_USARTx_Send(&USART1_DEV, data, num);
+}
+
+static int32_t ARM_USART1_Receive(void *data, uint32_t num)
+{
+    return ARM_USARTx_Receive(&USART1_DEV, data, num);
+}
+
+static int32_t ARM_USART1_Transfer(const void *data_out, void *data_in,
+                                   uint32_t num)
+{
+    ARG_UNUSED(data_out);
+    ARG_UNUSED(data_in);
+    ARG_UNUSED(num);
+
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static uint32_t ARM_USART1_GetTxCount(void)
+{
+    return ARM_USARTx_GetTxCount(&USART1_DEV);
+}
+
+static uint32_t ARM_USART1_GetRxCount(void)
+{
+    return ARM_USARTx_GetRxCount(&USART1_DEV);
+}
+static int32_t ARM_USART1_Control(uint32_t control, uint32_t arg)
+{
+    return ARM_USARTx_Control(&USART1_DEV, control, arg);
+}
+
+static ARM_USART_STATUS ARM_USART1_GetStatus(void)
+{
+    ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0};
+    return status;
+}
+
+static int32_t ARM_USART1_SetModemControl(ARM_USART_MODEM_CONTROL control)
+{
+    ARG_UNUSED(control);
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static ARM_USART_MODEM_STATUS ARM_USART1_GetModemStatus(void)
+{
+    ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0};
+    return modem_status;
+}
+
+extern ARM_DRIVER_USART Driver_USART1;
+ARM_DRIVER_USART Driver_USART1 = {
+    ARM_USART_GetVersion,
+    ARM_USART_GetCapabilities,
+    ARM_USART1_Initialize,
+    ARM_USART1_Uninitialize,
+    ARM_USART1_PowerControl,
+    ARM_USART1_Send,
+    ARM_USART1_Receive,
+    ARM_USART1_Transfer,
+    ARM_USART1_GetTxCount,
+    ARM_USART1_GetRxCount,
+    ARM_USART1_Control,
+    ARM_USART1_GetStatus,
+    ARM_USART1_SetModemControl,
+    ARM_USART1_GetModemStatus
+};
+#endif /* RTE_USART1 */
+
+#if (RTE_USART2)
+/* USART2 Driver wrapper functions */
+static UARTx_Resources USART2_DEV = {
+    .dev = &UART2_CMSDK_DEV,
+    .tx_nbr_bytes = 0,
+    .rx_nbr_bytes = 0,
+    .cb_event = NULL,
+};
+
+static int32_t ARM_USART2_Initialize(ARM_USART_SignalEvent_t cb_event)
+{
+    USART2_DEV.cb_event = cb_event;
+
+    return ARM_USARTx_Initialize(&USART2_DEV);
+}
+
+static int32_t ARM_USART2_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USART2_PowerControl(ARM_POWER_STATE state)
+{
+    return ARM_USARTx_PowerControl(&USART2_DEV, state);
+}
+
+static int32_t ARM_USART2_Send(const void *data, uint32_t num)
+{
+    return ARM_USARTx_Send(&USART2_DEV, data, num);
+}
+
+static int32_t ARM_USART2_Receive(void *data, uint32_t num)
+{
+    return ARM_USARTx_Receive(&USART2_DEV, data, num);
+}
+
+static int32_t ARM_USART2_Transfer(const void *data_out, void *data_in,
+                                   uint32_t num)
+{
+    ARG_UNUSED(data_out);
+    ARG_UNUSED(data_in);
+    ARG_UNUSED(num);
+
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static uint32_t ARM_USART2_GetTxCount(void)
+{
+    return ARM_USARTx_GetTxCount(&USART2_DEV);
+}
+
+static uint32_t ARM_USART2_GetRxCount(void)
+{
+    return ARM_USARTx_GetRxCount(&USART2_DEV);
+}
+static int32_t ARM_USART2_Control(uint32_t control, uint32_t arg)
+{
+    return ARM_USARTx_Control(&USART2_DEV, control, arg);
+}
+
+static ARM_USART_STATUS ARM_USART2_GetStatus(void)
+{
+    ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0};
+    return status;
+}
+
+static int32_t ARM_USART2_SetModemControl(ARM_USART_MODEM_CONTROL control)
+{
+    ARG_UNUSED(control);
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static ARM_USART_MODEM_STATUS ARM_USART2_GetModemStatus(void)
+{
+    ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0};
+    return modem_status;
+}
+
+extern ARM_DRIVER_USART Driver_USART2;
+ARM_DRIVER_USART Driver_USART2 = {
+    ARM_USART_GetVersion,
+    ARM_USART_GetCapabilities,
+    ARM_USART2_Initialize,
+    ARM_USART2_Uninitialize,
+    ARM_USART2_PowerControl,
+    ARM_USART2_Send,
+    ARM_USART2_Receive,
+    ARM_USART2_Transfer,
+    ARM_USART2_GetTxCount,
+    ARM_USART2_GetRxCount,
+    ARM_USART2_Control,
+    ARM_USART2_GetStatus,
+    ARM_USART2_SetModemControl,
+    ARM_USART2_GetModemStatus
+};
+#endif /* RTE_USART2 */
+
+#if (RTE_USART3)
+/* USART3 Driver wrapper functions */
+static UARTx_Resources USART3_DEV = {
+    .dev = &UART3_CMSDK_DEV,
+    .tx_nbr_bytes = 0,
+    .rx_nbr_bytes = 0,
+    .cb_event = NULL,
+};
+
+static int32_t ARM_USART3_Initialize(ARM_USART_SignalEvent_t cb_event)
+{
+    USART3_DEV.cb_event = cb_event;
+
+    return ARM_USARTx_Initialize(&USART3_DEV);
+}
+
+static int32_t ARM_USART3_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USART3_PowerControl(ARM_POWER_STATE state)
+{
+    return ARM_USARTx_PowerControl(&USART3_DEV, state);
+}
+
+static int32_t ARM_USART3_Send(const void *data, uint32_t num)
+{
+    return ARM_USARTx_Send(&USART3_DEV, data, num);
+}
+
+static int32_t ARM_USART3_Receive(void *data, uint32_t num)
+{
+    return ARM_USARTx_Receive(&USART3_DEV, data, num);
+}
+
+static int32_t ARM_USART3_Transfer(const void *data_out, void *data_in,
+                                   uint32_t num)
+{
+    ARG_UNUSED(data_out);
+    ARG_UNUSED(data_in);
+    ARG_UNUSED(num);
+
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static uint32_t ARM_USART3_GetTxCount(void)
+{
+    return ARM_USARTx_GetTxCount(&USART3_DEV);
+}
+
+static uint32_t ARM_USART3_GetRxCount(void)
+{
+    return ARM_USARTx_GetRxCount(&USART3_DEV);
+}
+static int32_t ARM_USART3_Control(uint32_t control, uint32_t arg)
+{
+    return ARM_USARTx_Control(&USART3_DEV, control, arg);
+}
+
+static ARM_USART_STATUS ARM_USART3_GetStatus(void)
+{
+    ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0};
+    return status;
+}
+
+static int32_t ARM_USART3_SetModemControl(ARM_USART_MODEM_CONTROL control)
+{
+    ARG_UNUSED(control);
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static ARM_USART_MODEM_STATUS ARM_USART3_GetModemStatus(void)
+{
+    ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0};
+    return modem_status;
+}
+
+extern ARM_DRIVER_USART Driver_USART3;
+ARM_DRIVER_USART Driver_USART3 = {
+    ARM_USART_GetVersion,
+    ARM_USART_GetCapabilities,
+    ARM_USART3_Initialize,
+    ARM_USART3_Uninitialize,
+    ARM_USART3_PowerControl,
+    ARM_USART3_Send,
+    ARM_USART3_Receive,
+    ARM_USART3_Transfer,
+    ARM_USART3_GetTxCount,
+    ARM_USART3_GetRxCount,
+    ARM_USART3_Control,
+    ARM_USART3_GetStatus,
+    ARM_USART3_SetModemControl,
+    ARM_USART3_GetModemStatus
+};
+#endif /* RTE_USART3 */
+
+#if (RTE_USART4)
+/* USART4 Driver wrapper functions */
+static UARTx_Resources USART4_DEV = {
+    .dev = &UART4_CMSDK_DEV,
+    .tx_nbr_bytes = 0,
+    .rx_nbr_bytes = 0,
+    .cb_event = NULL,
+};
+
+static int32_t ARM_USART4_Initialize(ARM_USART_SignalEvent_t cb_event)
+{
+    USART4_DEV.cb_event = cb_event;
+
+    return ARM_USARTx_Initialize(&USART4_DEV);
+}
+
+static int32_t ARM_USART4_Uninitialize(void)
+{
+    /* Nothing to be done */
+    return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USART4_PowerControl(ARM_POWER_STATE state)
+{
+    return ARM_USARTx_PowerControl(&USART4_DEV, state);
+}
+
+static int32_t ARM_USART4_Send(const void *data, uint32_t num)
+{
+    return ARM_USARTx_Send(&USART4_DEV, data, num);
+}
+
+static int32_t ARM_USART4_Receive(void *data, uint32_t num)
+{
+    return ARM_USARTx_Receive(&USART4_DEV, data, num);
+}
+
+static int32_t ARM_USART4_Transfer(const void *data_out, void *data_in,
+                                   uint32_t num)
+{
+    ARG_UNUSED(data_out);
+    ARG_UNUSED(data_in);
+    ARG_UNUSED(num);
+
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static uint32_t ARM_USART4_GetTxCount(void)
+{
+    return ARM_USARTx_GetTxCount(&USART4_DEV);
+}
+
+static uint32_t ARM_USART4_GetRxCount(void)
+{
+    return ARM_USARTx_GetRxCount(&USART4_DEV);
+}
+static int32_t ARM_USART4_Control(uint32_t control, uint32_t arg)
+{
+    return ARM_USARTx_Control(&USART4_DEV, control, arg);
+}
+
+static ARM_USART_STATUS ARM_USART4_GetStatus(void)
+{
+    ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0};
+    return status;
+}
+
+static int32_t ARM_USART4_SetModemControl(ARM_USART_MODEM_CONTROL control)
+{
+    ARG_UNUSED(control);
+    return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static ARM_USART_MODEM_STATUS ARM_USART4_GetModemStatus(void)
+{
+    ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0};
+    return modem_status;
+}
+
+extern ARM_DRIVER_USART Driver_USART4;
+ARM_DRIVER_USART Driver_USART4 = {
+    ARM_USART_GetVersion,
+    ARM_USART_GetCapabilities,
+    ARM_USART4_Initialize,
+    ARM_USART4_Uninitialize,
+    ARM_USART4_PowerControl,
+    ARM_USART4_Send,
+    ARM_USART4_Receive,
+    ARM_USART4_Transfer,
+    ARM_USART4_GetTxCount,
+    ARM_USART4_GetRxCount,
+    ARM_USART4_Control,
+    ARM_USART4_GetStatus,
+    ARM_USART4_SetModemControl,
+    ARM_USART4_GetModemStatus
+};
+#endif /* RTE_USART4 */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/config/RTE_Device.h b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/config/RTE_Device.h
new file mode 100644
index 0000000..4c1c0cc
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/config/RTE_Device.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+
+#ifndef __RTE_DEVICE_H
+#define __RTE_DEVICE_H
+
+// <q> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0]
+// <i> Configuration settings for Driver_USART0 in component ::Drivers:USART
+#define   RTE_USART0                     1
+
+// <q> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1]
+// <i> Configuration settings for Driver_USART1 in component ::Drivers:USART
+#define   RTE_USART1                     0
+
+// <q> MPC (Memory Protection Controller) [Driver_ISRAM0_MPC]
+// <i> Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC
+#define   RTE_ISRAM0_MPC                 1
+
+// <q> MPC (Memory Protection Controller) [Driver_ISRAM1_MPC]
+// <i> Configuration settings for Driver_ISRAM1_MPC in component ::Drivers:MPC
+#define   RTE_ISRAM1_MPC                 1
+
+// <q> MPC (Memory Protection Controller) [Driver_SRAM_MPC]
+// <i> Configuration settings for Driver_SRAM_MPC in component ::Drivers:MPC
+#define   RTE_SRAM_MPC                   1
+
+// <q> MPC (Memory Protection Controller) [Driver_QSPI_MPC]
+// <i> Configuration settings for Driver_QSPI_MPC in component ::Drivers:MPC
+#define   RTE_QSPI_MPC                   1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_MAIN0]
+// <i> Configuration settings for Driver_PPC_POLARIS_MAIN0 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_MAIN0             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_MAIN_EXP0]
+// <i> Configuration settings for Driver_PPC_POLARIS_MAIN_EXP0 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_MAIN_EXP0             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_MAIN_EXP1]
+// <i> Configuration settings for Driver_PPC_POLARIS_MAIN_EXP1 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_MAIN_EXP1             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_MAIN_EXP2]
+// <i> Configuration settings for Driver_PPC_POLARIS_MAIN_EXP2 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_MAIN_EXP2             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_MAIN_EXP3]
+// <i> Configuration settings for Driver_PPC_POLARIS_MAIN_EXP3 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_MAIN_EXP3             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_PERIPH0]
+// <i> Configuration settings for Driver_PPC_POLARIS_PERIPH0 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_PERIPH0             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_PERIPH1]
+// <i> Configuration settings for Driver_PPC_POLARIS_PERIPH1 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_PERIPH1             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_PERIPH_EXP0]
+// <i> Configuration settings for Driver_PPC_POLARIS_PERIPH_EXP0 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_PERIPH_EXP0             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_PERIPH_EXP1]
+// <i> Configuration settings for Driver_PPC_POLARIS_PERIPH_EXP1 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_PERIPH_EXP1             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_PERIPH_EXP2]
+// <i> Configuration settings for Driver_PPC_POLARIS_PERIPH_EXP2 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_PERIPH_EXP2             1
+
+// <q> PPC (Peripheral Protection Controller) [PPC_POLARIS_PERIPH_EXP3]
+// <i> Configuration settings for Driver_PPC_POLARIS_PERIPH_EXP3 in component ::Drivers:PPC
+#define   RTE_PPC_POLARIS_PERIPH_EXP3             1
+
+// <q> Flash device emulated by SRAM [Driver_Flash0]
+// <i> Configuration settings for Driver_Flash0 in component ::Drivers:Flash
+#define   RTE_FLASH0                     1
+
+#endif  /* __RTE_DEVICE_H */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/config/cmsis_driver_config.h b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/config/cmsis_driver_config.h
new file mode 100644
index 0000000..281db89
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/cmsis_drivers/config/cmsis_driver_config.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMSIS_DRIVER_CONFIG_H__
+#define __CMSIS_DRIVER_CONFIG_H__
+
+#include "cmsis.h"
+#include "device_definition.h"
+#include "RTE_Device.h"
+
+#define UART0_CMSDK_DEV     UART0_CMSDK_DEV_NS
+
+#define MPC_ISRAM0_DEV      MPC_ISRAM0_DEV_S
+#define MPC_ISRAM1_DEV      MPC_ISRAM1_DEV_S
+#define MPC_SRAM_DEV        MPC_SRAM_DEV_S
+#define MPC_QSPI_DEV        MPC_QSPI_DEV_S
+
+#define PPC_POLARIS_MAIN0_DEV            PPC_POLARIS_MAIN0_DEV_S
+#define PPC_POLARIS_MAIN_EXP0_DEV        PPC_POLARIS_MAIN_EXP0_DEV_S
+#define PPC_POLARIS_MAIN_EXP1_DEV        PPC_POLARIS_MAIN_EXP1_DEV_S
+#define PPC_POLARIS_MAIN_EXP2_DEV        PPC_POLARIS_MAIN_EXP2_DEV_S
+#define PPC_POLARIS_MAIN_EXP3_DEV        PPC_POLARIS_MAIN_EXP3_DEV_S
+#define PPC_POLARIS_PERIPH0_DEV          PPC_POLARIS_PERIPH0_DEV_S
+#define PPC_POLARIS_PERIPH1_DEV          PPC_POLARIS_PERIPH1_DEV_S
+#define PPC_POLARIS_PERIPH_EXP0_DEV      PPC_POLARIS_PERIPH_EXP0_DEV_S
+#define PPC_POLARIS_PERIPH_EXP1_DEV      PPC_POLARIS_PERIPH_EXP1_DEV_S
+#define PPC_POLARIS_PERIPH_EXP2_DEV      PPC_POLARIS_PERIPH_EXP2_DEV_S
+#define PPC_POLARIS_PERIPH_EXP3_DEV      PPC_POLARIS_PERIPH_EXP3_DEV_S
+
+#endif  /* __CMSIS_DRIVER_CONFIG_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/config/device_cfg.h b/platform/ext/target/arm/mps3/corstone_polaris/device/config/device_cfg.h
new file mode 100644
index 0000000..6e4f197
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/config/device_cfg.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DEVICE_CFG_H__
+#define __DEVICE_CFG_H__
+
+/**
+ * \file device_cfg.h
+ * \brief
+ * This is the device configuration file with only used peripherals
+ * defined and configured via the secure and/or non-secure base address.
+ */
+
+/* ARM Memory Protection Controller (MPC) */
+#define MPC_ISRAM0_S
+#define MPC_ISRAM1_S
+#define MPC_SRAM_S
+#define MPC_QSPI_S
+
+/* ARM Peripheral Protection Controllers (PPC) */
+#define PPC_POLARIS_MAIN0_S
+#define PPC_POLARIS_MAIN_EXP0_S
+#define PPC_POLARIS_MAIN_EXP1_S
+#define PPC_POLARIS_MAIN_EXP2_S
+#define PPC_POLARIS_MAIN_EXP3_S
+#define PPC_POLARIS_PERIPH0_S
+#define PPC_POLARIS_PERIPH1_S
+#define PPC_POLARIS_PERIPH_EXP0_S
+#define PPC_POLARIS_PERIPH_EXP1_S
+#define PPC_POLARIS_PERIPH_EXP2_S
+#define PPC_POLARIS_PERIPH_EXP3_S
+
+/* ARM UART CMSDK */
+#define DEFAULT_UART_BAUDRATE  115200
+#define UART0_CMSDK_NS
+
+/** System Counter Armv8-M */
+#define SYSCOUNTER_CNTRL_ARMV8_M_S
+#define SYSCOUNTER_CNTRL_ARMV8_M_DEV    SYSCOUNTER_CNTRL_ARMV8_M_DEV_S
+
+/**
+ * Arbitrary scaling values for test purposes
+ */
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT           1u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT         0u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT           1u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT         0u
+
+
+/* System Timer Armv8-M */
+#define SYSTIMER0_ARMV8_M_S
+
+#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ    (32000000ul)
+
+#endif  /* __DEVICE_CFG_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/cmsis.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/cmsis.h
new file mode 100644
index 0000000..0712397
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/cmsis.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMSIS_H__
+#define __CMSIS_H__
+
+#include "corstone_polaris.h"
+
+#endif  /* __CMSIS_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/corstone_polaris.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/corstone_polaris.h
new file mode 100644
index 0000000..e078e83
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/corstone_polaris.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CORSTONE_POLARIS_H__
+#define __CORSTONE_POLARIS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ======================  Start of section using anonymous unions  ============== */
+#if   defined (__CC_ARM)
+  #pragma push
+  #pragma anon_unions
+#elif defined (__ICCARM__)
+  #pragma language=extended
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wc11-extensions"
+  #pragma clang diagnostic ignored "-Wreserved-id-macro"
+#elif defined (__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined (__TMS470__)
+  /* anonymous unions are enabled by default */
+#elif defined (__TASKING__)
+  #pragma warning 586
+#elif defined (__CSMC__)
+  /* anonymous unions are enabled by default */
+#else
+  #warning Not supported compiler type
+#endif
+
+
+/* ========  Configuration of Core Peripherals  ================================== */
+#define __SAUREGION_PRESENT       1U        /* SAU regions present */
+#define __MPU_PRESENT             1U        /* MPU present */
+#define __VTOR_PRESENT            1U        /* VTOR present */
+#define __NVIC_PRIO_BITS          3U        /* Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig    0U        /* Set to 1 if different SysTick Config is used */
+#define __FPU_PRESENT             1U        /* FPU present */
+#define __FPU_DP                  1U        /* double precision FPU */
+#define __DSP_PRESENT             1U        /* DSP extension present */
+#define __PMU_PRESENT             1U        /* PMU present */
+#define __PMU_NUM_EVENTCNT        8U        /* Number of PMU event counters */
+#define __ICACHE_PRESENT          1U        /* Instruction Cache present */
+#define __DCACHE_PRESENT          1U        /* Data Cache present */
+
+#include "platform_irq.h"
+#include "core_armv81mml.h"                 /* Architecture and core peripherals */
+#include "platform_base_address.h"
+#include "platform_regs.h"
+#include "platform_pins.h"
+#include "system_core_init.h"
+
+/* =====================  End of section using anonymous unions  ================ */
+#if   defined (__CC_ARM)
+  #pragma pop
+#elif defined (__ICCARM__)
+  /* leave anonymous unions enabled */
+#elif (__ARMCC_VERSION >= 6010050)
+  #pragma clang diagnostic pop
+#elif defined (__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined (__TMS470__)
+  /* anonymous unions are enabled by default */
+#elif defined (__TASKING__)
+  #pragma warning restore
+#elif defined (__CSMC__)
+  /* anonymous unions are enabled by default */
+#else
+  #warning Not supported compiler type
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORSTONE_POLARIS_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/device_definition.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/device_definition.h
new file mode 100644
index 0000000..db71b00
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/device_definition.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file device_definition.h
+ * \brief The structure definitions in this file are exported based on the
+ * peripheral definitions from device_cfg.h.
+ * This file is meant to be used as a helper for baremetal
+ * applications and/or as an example of how to configure the generic
+ * driver structures.
+ */
+
+#ifndef __DEVICE_DEFINITION_H__
+#define __DEVICE_DEFINITION_H__
+
+#include "device_cfg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ======= Defines peripheral configuration structures ======= */
+/* UART CMSDK driver structures */
+#ifdef UART0_CMSDK_S
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART0_CMSDK_DEV_S;
+#endif
+#ifdef UART0_CMSDK_NS
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART0_CMSDK_DEV_NS;
+#endif
+
+#ifdef UART1_CMSDK_S
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART1_CMSDK_DEV_S;
+#endif
+#ifdef UART1_CMSDK_NS
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART1_CMSDK_DEV_NS;
+#endif
+
+#ifdef UART2_CMSDK_S
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART2_CMSDK_DEV_S;
+#endif
+#ifdef UART2_CMSDK_NS
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART2_CMSDK_DEV_NS;
+#endif
+
+#ifdef UART3_CMSDK_S
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART3_CMSDK_DEV_S;
+#endif
+#ifdef UART3_CMSDK_NS
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART3_CMSDK_DEV_NS;
+#endif
+
+#ifdef UART4_CMSDK_S
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART4_CMSDK_DEV_S;
+#endif
+#ifdef UART4_CMSDK_NS
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART4_CMSDK_DEV_NS;
+#endif
+
+#ifdef UART5_CMSDK_S
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART5_CMSDK_DEV_S;
+#endif
+#ifdef UART5_CMSDK_NS
+#include "uart_cmsdk_drv.h"
+extern struct uart_cmsdk_dev_t UART5_CMSDK_DEV_NS;
+#endif
+
+/* ARM PPC driver structures */
+#ifdef PPC_POLARIS_MAIN0_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_MAIN0_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP0_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP0_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP1_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP1_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP2_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP2_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP3_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP3_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_PERIPH0_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_PERIPH0_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_PERIPH1_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_PERIPH1_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP0_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP0_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP1_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP1_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP2_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP2_DEV_S;
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP3_S
+#include "ppc_polaris_drv.h"
+extern struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP3_DEV_S;
+#endif
+
+/* System counters */
+#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S
+#include "syscounter_armv8-m_cntrl_drv.h"
+extern struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S;
+#endif
+
+#ifdef SYSCOUNTER_READ_ARMV8_M_S
+#include "syscounter_armv8-m_read_drv.h"
+extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S;
+#endif
+#ifdef SYSCOUNTER_READ_ARMV8_M_NS
+#include "syscounter_armv8-m_read_drv.h"
+extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS;
+#endif
+
+/* System timers */
+#ifdef SYSTIMER0_ARMV8_M_S
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_S;
+#endif
+#ifdef SYSTIMER0_ARMV8_M_NS
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_NS;
+#endif
+
+#ifdef SYSTIMER1_ARMV8_M_S
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_S;
+#endif
+#ifdef SYSTIMER1_ARMV8_M_NS
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_NS;
+#endif
+
+#ifdef SYSTIMER2_ARMV8_M_S
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_S;
+#endif
+#ifdef SYSTIMER2_ARMV8_M_NS
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_NS;
+#endif
+
+#ifdef SYSTIMER3_ARMV8_M_S
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_S;
+#endif
+#ifdef SYSTIMER3_ARMV8_M_NS
+#include "systimer_armv8-m_drv.h"
+extern struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_NS;
+#endif
+
+/* System Watchdogs */
+#ifdef SYSWDOG_ARMV8_M_S
+#include "syswdog_armv8-m_drv.h"
+extern struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_S;
+#endif
+#ifdef SYSWDOG_ARMV8_M_NS
+#include "syswdog_armv8-m_drv.h"
+extern struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_NS;
+#endif
+
+/* ARM MPC SIE 300 driver structures */
+#ifdef MPC_SRAM_S
+#include "mpc_sie_drv.h"
+extern struct mpc_sie_dev_t MPC_SRAM_DEV_S;
+#endif
+
+#ifdef MPC_QSPI_S
+#include "mpc_sie_drv.h"
+extern struct mpc_sie_dev_t MPC_QSPI_DEV_S;
+#endif
+
+#ifdef MPC_DDR4_S
+#include "mpc_sie_drv.h"
+extern struct mpc_sie_dev_t MPC_DDR4_DEV_S;
+#endif
+
+#ifdef MPC_ISRAM0_S
+#include "mpc_sie_drv.h"
+extern struct mpc_sie_dev_t MPC_ISRAM0_DEV_S;
+#endif
+
+#ifdef MPC_ISRAM1_S
+#include "mpc_sie_drv.h"
+extern struct mpc_sie_dev_t MPC_ISRAM1_DEV_S;
+#endif
+
+#ifdef MPS3_IO_S
+#include "arm_mps3_io_drv.h"
+extern struct arm_mps3_io_dev_t MPS3_IO_DEV_S;
+#endif
+
+#ifdef MPS3_IO_NS
+#include "arm_mps3_io_drv.h"
+extern struct arm_mps3_io_dev_t MPS3_IO_DEV_NS;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __DEVICE_DEFINITION_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_description.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_description.h
new file mode 100644
index 0000000..6800c05
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_description.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PLATFORM_DESCRIPTION_H__
+#define __PLATFORM_DESCRIPTION_H__
+
+#include "cmsis.h"
+#include "platform_base_address.h"
+#include "platform_regs.h"
+#include "platform_pins.h"
+#include "system_core_init.h"
+
+#endif  /* __PLATFORM_DESCRIPTION_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_irq.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_irq.h
new file mode 100644
index 0000000..f913696
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_irq.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PLATFORM_IRQ_H__
+#define __PLATFORM_IRQ_H__
+
+typedef enum _IRQn_Type {
+    NonMaskableInt_IRQn                = -14,  /* Non Maskable Interrupt */
+    HardFault_IRQn                     = -13,  /* HardFault Interrupt */
+    MemoryManagement_IRQn              = -12,  /* Memory Management Interrupt */
+    BusFault_IRQn                      = -11,  /* Bus Fault Interrupt */
+    UsageFault_IRQn                    = -10,  /* Usage Fault Interrupt */
+    SecureFault_IRQn                   = -9,   /* Secure Fault Interrupt */
+    SVCall_IRQn                        = -5,   /* SV Call Interrupt */
+    DebugMonitor_IRQn                  = -4,   /* Debug Monitor Interrupt */
+    PendSV_IRQn                        = -2,   /* Pend SV Interrupt */
+    SysTick_IRQn                       = -1,   /* System Tick Interrupt */
+    NONSEC_WATCHDOG_RESET_REQ_IRQn     = 0,    /* Non-Secure Watchdog Reset
+                                                * Request Interrupt
+                                                */
+    NONSEC_WATCHDOG_IRQn               = 1,    /* Non-Secure Watchdog Interrupt */
+    SLOWCLK_TIMER_IRQn                 = 2,    /* SLOWCLK Timer Interrupt */
+    TIMER0_IRQn                        = 3,    /* TIMER 0 Interrupt */
+    TIMER1_IRQn                        = 4,    /* TIMER 1 Interrupt */
+    TIMER2_IRQn                        = 5,    /* TIMER 2 Interrupt */
+    /* Reserved                        = 6,       Reserved */
+    /* Reserved                        = 7,       Reserved */
+    /* Reserved                        = 8,       Reserved */
+    MPC_IRQn                           = 9,    /* MPC Combined (Secure) Interrupt */
+    PPC_IRQn                           = 10,   /* PPC Combined (Secure) Interrupt */
+    MSC_IRQn                           = 11,   /* MSC Combined (Secure) Interrput */
+    BRIDGE_ERROR_IRQn                  = 12,   /* Bridge Error Combined
+                                                * (Secure) Interrupt
+                                                */
+    /* Reserved                        = 13,      Reserved */
+    Combined_PPU_IRQn                  = 14,   /* Combined PPU */
+    /* Reserved                        = 15,      Reserved */
+    ETHOS_U55_IRQn                     = 16,   /* NPU0 */
+    /* Reserved                        = 17,      Reserved */
+    /* Reserved                        = 18,      Reserved */
+    /* Reserved                        = 19,      Reserved */
+    /* Reserved                        = 20,      Reserved */
+    /* Reserved                        = 21,      Reserved */
+    /* Reserved                        = 22,      Reserved */
+    /* Reserved                        = 23,      Reserved */
+    /* Reserved                        = 24,      Reserved */
+    /* Reserved                        = 25,      Reserved */
+    /* Reserved                        = 26,      Reserved */
+    TIMER3_AON_IRQn                    = 27,   /* TIMER 3 AON Interrupt */
+    CPU0_CTI_0_IRQn                    = 28,   /* CPU0 CTI IRQ 0 */
+    CPU0_CTI_1_IRQn                    = 29,   /* CPU0 CTI IRQ 1 */
+    /* Reserved                        = 30,      Reserved */
+    /* Reserved                        = 31,      Reserved */
+    System_Timestamp_Counter_IRQn      = 32,   /* System timestamp counter Interrupt */
+    UARTRX0_IRQn                       = 33,   /* UART 0 RX Interrupt */
+    UARTTX0_IRQn                       = 34,   /* UART 0 TX Interrupt */
+    UARTRX1_IRQn                       = 35,   /* UART 1 RX Interrupt */
+    UARTTX1_IRQn                       = 36,   /* UART 1 TX Interrupt */
+    UARTRX2_IRQn                       = 37,   /* UART 2 RX Interrupt */
+    UARTTX2_IRQn                       = 38,   /* UART 2 TX Interrupt */
+    UARTRX3_IRQn                       = 39,   /* UART 3 RX Interrupt */
+    UARTTX3_IRQn                       = 40,   /* UART 3 TX Interrupt */
+    UARTRX4_IRQn                       = 41,   /* UART 4 RX Interrupt */
+    UARTTX4_IRQn                       = 42,   /* UART 4 TX Interrupt */
+    UART0_Combined_IRQn                = 43,   /* UART 0 Combined Interrupt */
+    UART1_Combined_IRQn                = 44,   /* UART 1 Combined Interrupt */
+    UART2_Combined_IRQn                = 45,   /* UART 2 Combined Interrupt */
+    UART3_Combined_IRQn                = 46,   /* UART 3 Combined Interrupt */
+    UART4_Combined_IRQn                = 47,   /* UART 4 Combined Interrupt */
+    UARTOVF_IRQn                       = 48,   /* UART 0, 1, 2, 3, 4 & 5 Overflow Interrupt */
+    ETHERNET_IRQn                      = 49,   /* Ethernet Interrupt */
+    I2S_IRQn                           = 50,   /* Audio I2S Interrupt */
+    TOUCH_SCREEN_IRQn                  = 51,   /* Touch Screen Interrupt */
+    USB_IRQn                           = 52,   /* USB Interrupt */
+    SPI_ADC_IRQn                       = 53,   /* SPI ADC Interrupt */
+    SPI_SHIELD0_IRQn                   = 54,   /* SPI (Shield 0) Interrupt */
+    SPI_SHIELD1_IRQn                   = 55,   /* SPI (Shield 1) Interrupt */
+    /* Reserved                        = 56:68    Reserved */
+    GPIO0_Combined_IRQn                = 69,   /* GPIO 0 Combined Interrupt */
+    GPIO1_Combined_IRQn                = 70,   /* GPIO 1 Combined Interrupt */
+    GPIO2_Combined_IRQn                = 71,   /* GPIO 2 Combined Interrupt */
+    GPIO3_Combined_IRQn                = 72,   /* GPIO 3 Combined Interrupt */
+    GPIO0_0_IRQn                       = 73, /* GPIO0 has 16 pins with IRQs */
+    GPIO0_1_IRQn                       = 74,
+    GPIO0_2_IRQn                       = 75,
+    GPIO0_3_IRQn                       = 76,
+    GPIO0_4_IRQn                       = 77,
+    GPIO0_5_IRQn                       = 78,
+    GPIO0_6_IRQn                       = 79,
+    GPIO0_7_IRQn                       = 80,
+    GPIO0_8_IRQn                       = 81,
+    GPIO0_9_IRQn                       = 82,
+    GPIO0_10_IRQn                      = 83,
+    GPIO0_11_IRQn                      = 84,
+    GPIO0_12_IRQn                      = 85,
+    GPIO0_13_IRQn                      = 86,
+    GPIO0_14_IRQn                      = 87,
+    GPIO0_15_IRQn                      = 88,
+    GPIO1_0_IRQn                       = 89,   /* GPIO1 has 16 pins with IRQs */
+    GPIO1_1_IRQn                       = 90,
+    GPIO1_2_IRQn                       = 91,
+    GPIO1_3_IRQn                       = 92,
+    GPIO1_4_IRQn                       = 93,
+    GPIO1_5_IRQn                       = 94,
+    GPIO1_6_IRQn                       = 95,
+    GPIO1_7_IRQn                       = 96,
+    GPIO1_8_IRQn                       = 97,
+    GPIO1_9_IRQn                       = 98,
+    GPIO1_10_IRQn                      = 99,
+    GPIO1_11_IRQn                      = 100,
+    GPIO1_12_IRQn                      = 101,
+    GPIO1_13_IRQn                      = 102,
+    GPIO1_14_IRQn                      = 103,
+    GPIO1_15_IRQn                      = 104,
+    GPIO2_0_IRQn                       = 105,   /* GPIO2 has 16 pins with IRQs */
+    GPIO2_1_IRQn                       = 106,
+    GPIO2_2_IRQn                       = 107,
+    GPIO2_3_IRQn                       = 108,
+    GPIO2_4_IRQn                       = 109,
+    GPIO2_5_IRQn                       = 110,
+    GPIO2_6_IRQn                       = 111,
+    GPIO2_7_IRQn                       = 112,
+    GPIO2_8_IRQn                       = 113,
+    GPIO2_9_IRQn                       = 114,
+    GPIO2_10_IRQn                      = 115,
+    GPIO2_11_IRQn                      = 116,
+    GPIO2_12_IRQn                      = 117,
+    GPIO2_13_IRQn                      = 118,
+    GPIO2_14_IRQn                      = 119,
+    GPIO2_15_IRQn                      = 120,
+    GPIO3_0_IRQn                       = 121,   /* GPIO3 has 4 pins with IRQs */
+    GPIO3_1_IRQn                       = 122,
+    GPIO3_2_IRQn                       = 123,
+    GPIO3_3_IRQn                       = 124,
+    UARTRX5_IRQn                       = 125,   /* UART 5 RX Interrupt */
+    UARTTX5_IRQn                       = 126,   /* UART 5 TX Interrupt */
+    UART5_IRQn                         = 127,   /* UART 5 combined Interrupt */
+    /* Reserved                        = 128:130   Reserved */
+} IRQn_Type;
+
+#endif  /* __PLATFORM_IRQ_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_pins.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_pins.h
new file mode 100644
index 0000000..f5eda8c
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_pins.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file platform_pins.h
+ * \brief This file defines all the pins for this platform.
+ */
+
+#ifndef __PLATFORM_PINS_H__
+#define __PLATFORM_PINS_H__
+
+/* AHB GPIO pin names */
+enum arm_gpio_pin_name_t {
+    AHB_GPIO0_0 = 0U,
+    AHB_GPIO0_1,
+    AHB_GPIO0_2,
+    AHB_GPIO0_3,
+    AHB_GPIO0_4,
+    AHB_GPIO0_5,
+    AHB_GPIO0_6,
+    AHB_GPIO0_7,
+    AHB_GPIO0_8,
+    AHB_GPIO0_9,
+    AHB_GPIO0_10,
+    AHB_GPIO0_11,
+    AHB_GPIO0_12,
+    AHB_GPIO0_13,
+    AHB_GPIO0_14,
+    AHB_GPIO0_15,
+    AHB_GPIO1_0 = 0U,
+    AHB_GPIO1_1,
+    AHB_GPIO1_2,
+    AHB_GPIO1_3,
+    AHB_GPIO1_4,
+    AHB_GPIO1_5,
+    AHB_GPIO1_6,
+    AHB_GPIO1_7,
+    AHB_GPIO1_8,
+    AHB_GPIO1_9,
+    AHB_GPIO1_10,
+    AHB_GPIO1_11,
+    AHB_GPIO1_12,
+    AHB_GPIO1_13,
+    AHB_GPIO1_14,
+    AHB_GPIO1_15,
+    AHB_GPIO2_0 = 0U,
+    AHB_GPIO2_1,
+    AHB_GPIO2_2,
+    AHB_GPIO2_3,
+    AHB_GPIO2_4,
+    AHB_GPIO2_5,
+    AHB_GPIO2_6,
+    AHB_GPIO2_7,
+    AHB_GPIO2_8,
+    AHB_GPIO2_9,
+    AHB_GPIO2_10,
+    AHB_GPIO2_11,
+    AHB_GPIO2_12,
+    AHB_GPIO2_13,
+    AHB_GPIO2_14,
+    AHB_GPIO2_15,
+    AHB_GPIO3_0 = 0U,
+    AHB_GPIO3_1,
+    AHB_GPIO3_2,
+    AHB_GPIO3_3,
+    AHB_GPIO3_4,
+    AHB_GPIO3_5,
+    AHB_GPIO3_6,
+    AHB_GPIO3_7,
+    AHB_GPIO3_8,
+    AHB_GPIO3_9,
+    AHB_GPIO3_10,
+    AHB_GPIO3_11,
+    AHB_GPIO3_12,
+    AHB_GPIO3_13,
+    AHB_GPIO3_14,
+    AHB_GPIO3_15,
+};
+
+/* GPIO shield 0 definition */
+#define SH0_UART_RX      AHB_GPIO0_0
+#define SH0_UART_TX      AHB_GPIO0_1
+#define SH0_SPI_SS       AHB_GPIO0_10
+#define SH0_SPI_MOSI     AHB_GPIO0_11
+#define SH0_SPI_MISO     AHB_GPIO0_12
+#define SH0_SPI_SCK      AHB_GPIO0_13
+#define SH0_I2C_SDA      AHB_GPIO0_14
+#define SH0_I2C_SCL      AHB_GPIO0_15
+
+/* GPIO shield 1 definition */
+#define SH1_UART_RX      AHB_GPIO1_0
+#define SH1_UART_TX      AHB_GPIO1_1
+
+#define SH1_SPI_SS       AHB_GPIO1_10
+#define SH1_SPI_MOSI     AHB_GPIO1_11
+#define SH1_SPI_MISO     AHB_GPIO1_12
+#define SH1_SPI_SCK      AHB_GPIO1_13
+#define SH1_I2C_SDA      AHB_GPIO1_14
+#define SH1_I2C_SCL      AHB_GPIO1_15
+
+#endif  /* __PLATFORM_PINS_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_regs.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_regs.h
new file mode 100644
index 0000000..eddbc64
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/platform_regs.h
@@ -0,0 +1,495 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PLATFORM_REGS_H__
+#define __PLATFORM_REGS_H__
+
+#include <stdint.h>
+
+/* Secure Access Configuration Register Block */
+struct polaris_sacfg_t {
+    volatile uint32_t spcsecctrl;     /* 0x000 (R/W) Secure Privilege Controller
+                                                     Secure Configuration Control
+                                                     register */
+    volatile uint32_t buswait;        /* 0x004 (R/W) Bus Access wait control */
+    volatile uint32_t reserved0[2];
+    volatile uint32_t secrespcfg;     /* 0x010 (R/W) Security Violation Response
+                                       *             Configuration register */
+    volatile uint32_t nsccfg;         /* 0x014 (R/W) Non Secure Callable
+                                       *             Configuration for IDAU */
+    volatile uint32_t reserved1;
+    volatile uint32_t secmpcintstat;  /* 0x01C (R/ ) Secure MPC IRQ Status */
+    volatile uint32_t secppcintstat;  /* 0x020 (R/ ) Secure PPC IRQ Status */
+    volatile uint32_t secppcintclr;   /* 0x024 (R/W) Secure PPC IRQ Clear */
+    volatile uint32_t secppcinten;    /* 0x028 (R/W) Secure PPC IRQ Enable */
+    volatile uint32_t reserved2;
+    volatile uint32_t secmscintstat;  /* 0x030 (R/ ) Secure MSC IRQ Status */
+    volatile uint32_t secmscintclr;   /* 0x034 (R/W) Secure MSC IRQ Clear */
+    volatile uint32_t secmscinten;    /* 0x038 (R/W) Secure MSC IRQ Enable */
+    volatile uint32_t reserved3;
+    volatile uint32_t brgintstat;     /* 0x040 (R/ ) Bridge Buffer Error IRQ
+                                       *             Status */
+    volatile uint32_t brgintclr;      /* 0x044 (R/W) Bridge Buffer Error IRQ
+                                       *             Clear */
+    volatile uint32_t brginten;       /* 0x048 (R/W) Bridge Buffer Error IRQ
+                                       *             Enable */
+    volatile uint32_t reserved4;
+    volatile uint32_t mainnsppc0;     /* 0x050 (R/W) Non-secure Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on the Main
+                                       *             Interconnect */
+    volatile uint32_t reserved5[3];
+    volatile uint32_t mainnsppcexp0;  /* 0x060 (R/W) Expansion 0 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t mainnsppcexp1;  /* 0x064 (R/W) Expansion 1 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t mainnsppcexp2;  /* 0x068 (R/W) Expansion 2 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t mainnsppcexp3;  /* 0x06C (R/W) Expansion 3 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t periphnsppc0;   /* 0x070 (R/W) Non-secure Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on the Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphnsppc1;   /* 0x074 (R/W) Non-secure Access
+                                       *             Peripheral Protection
+                                       *             Control 1 on the Peripheral
+                                       *             Interconnect */
+    volatile uint32_t reserved6[2];
+    volatile uint32_t periphnsppcexp0;/* 0x080 (R/W) Expansion 0 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t periphnsppcexp1;/* 0x084 (R/W) Expansion 1 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t periphnsppcexp2;/* 0x088 (R/W) Expansion 2 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t periphnsppcexp3;/* 0x08C (R/W) Expansion 3 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t mainspppc0;     /* 0x090 (R/W) Secure Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on Main
+                                       *             Interconnect */
+    volatile uint32_t reserved7[3];
+    volatile uint32_t mainspppcexp0;  /* 0x0A0 (R/W) Expansion 0 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t mainspppcexp1;  /* 0x0A4 (R/W) Expansion 1 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t mainspppcexp2;  /* 0x0A8 (R/W) Expansion 2 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t mainspppcexp3;  /* 0x0AC (R/W) Expansion 3 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t periphspppc0;   /* 0x0B0 (R/W) Secure Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on
+                                       *             Peripheral Interconnect */
+    volatile uint32_t periphspppc1;   /* 0x0B4 (R/W) Secure Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control 1 on
+                                       *             Peripheral Interconnect */
+    volatile uint32_t npuspporpl;     /* 0x0B8 (R/W) Secure Access NPU privilege
+                                       *             level reset state
+                                       *             control */
+    volatile uint32_t reserved8[1];
+    volatile uint32_t periphspppcexp0;/* 0x0C0 (R/W) Expansion 0 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphspppcexp1;/* 0x0C4 (R/W) Expansion 1 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphspppcexp2;/* 0x0C8 (R/W) Expansion 2 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphspppcexp3;/* 0x0CC (R/W) Expansion 3 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t nsmscexp;       /* 0x0D0 (R/W) Expansion MSC Non-Secure
+                                       *             Configuration */
+    volatile uint32_t reserved9[959];
+    volatile uint32_t pidr4;          /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved10[3];
+    volatile uint32_t pidr0;          /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;          /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;          /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;          /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;          /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;          /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;          /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;          /* 0xFFC (R/ ) Component ID 3 */
+};
+
+/* PPC interrupt position mask */
+#define PERIPH_PPC0_INT_POS_MASK     (1UL << 0)
+#define PERIPH_PPC1_INT_POS_MASK     (1UL << 1)
+#define PERIPH_PPCEXP0_INT_POS_MASK  (1UL << 4)
+#define PERIPH_PPCEXP1_INT_POS_MASK  (1UL << 5)
+#define PERIPH_PPCEXP2_INT_POS_MASK  (1UL << 6)
+#define PERIPH_PPCEXP3_INT_POS_MASK  (1UL << 7)
+#define MAIN_PPC0_INT_POS_MASK       (1UL << 16)
+#define MAIN_PPCEXP0_INT_POS_MASK    (1UL << 20)
+#define MAIN_PPCEXP1_INT_POS_MASK    (1UL << 21)
+#define MAIN_PPCEXP2_INT_POS_MASK    (1UL << 22)
+#define MAIN_PPCEXP3_INT_POS_MASK    (1UL << 23)
+
+/* Non-secure Access Configuration Register Block */
+struct polaris_nsacfg_t {
+    volatile uint32_t reserved0[36];
+    volatile uint32_t mainnspppc0;     /* 0x090 (R/W) Non-secure Unprivileged
+                                        *             Access Peripheral
+                                        *             Protection Control 0 on
+                                        *             Main Interconnect */
+    volatile uint32_t reserved1[3];
+
+    volatile uint32_t mainnspppcexp0;  /* 0x0A0 (R/W) Expansion 0 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t mainnspppcexp1;  /* 0x0A4 (R/W) Expansion 1 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t mainnspppcexp2;  /* 0x0A8 (R/W) Expansion 2 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t mainnspppcexp3;  /* 0x0AC (R/W) Expansion 3 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t periphnspppc0;   /* 0x0B0 (R/W) Non-secure Unprivileged
+                                        *             Access Peripheral
+                                        *             Protection Control 0 on
+                                        *             Peripheral Interconnect */
+    volatile uint32_t periphnspppc1;   /* 0x0B4 (R/W) Non-secure Unprivileged
+                                        *             Access Peripheral
+                                        *             Protection Control 1 on
+                                        *             Peripheral Interconnect */
+    volatile uint32_t npuspporpl;      /* 0x0B8 (R/W) Non-Secure Access NPU
+                                        *             privilege level reset
+                                        *             state control */
+    volatile uint32_t reserved2[1];
+    volatile uint32_t periphnspppcexp0;/* 0x0C0 (R/W) Expansion 0 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t periphnspppcexp1;/* 0x0C4 (R/W) Expansion 1 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t periphnspppcexp2;/* 0x0C8 (R/W) Expansion 2 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t periphnspppcexp3;/* 0x0CC (R/W) Expansion 3 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t reserved3[960];
+    volatile uint32_t pidr4;           /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved4[3];
+    volatile uint32_t pidr0;           /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;           /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;           /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;           /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;           /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;           /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;           /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;           /* 0xFFC (R/ ) Component ID 3 */
+};
+
+/* MAIN PPC0 peripherals definition */
+/* End MAIN PPC0 peripherals definition */
+
+/* MAIN PPCEXP0 peripherals definition */
+#define GPIO0_MAIN_PPCEXP0_POS_MASK             (1UL << 0)
+#define GPIO1_MAIN_PPCEXP0_POS_MASK             (1UL << 1)
+#define GPIO2_MAIN_PPCEXP0_POS_MASK             (1UL << 2)
+#define GPIO3_MAIN_PPCEXP0_POS_MASK             (1UL << 3)
+#define USER_AHB0_MAIN_PPCEXP0_POS_MASK         (1UL << 4)
+#define USER_AHB1_MAIN_PPCEXP0_POS_MASK         (1UL << 5)
+#define USER_AHB2_MAIN_PPCEXP0_POS_MASK         (1UL << 6)
+#define USER_AHB3_MAIN_PPCEXP0_POS_MASK         (1UL << 7)
+#define USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK  (1UL << 8)
+/* End MAIN PPCEXP0 peripherals definition */
+
+/* MAIN PPCEXP1 peripherals definition */
+#define DMA1_MAIN_PPCEXP1_POS_MASK                 (1UL << 1)
+#define DMA2_MAIN_PPCEXP1_POS_MASK                 (1UL << 2)
+#define DMA3_MAIN_PPCEXP1_POS_MASK                 (1UL << 3)
+/* End MAIN PPCEXP1 peripherals definition */
+
+/* MAIN PPCEXP2 peripherals definition */
+/* End MAIN PPCEXP2 peripherals definition */
+
+/* MAIN PPCEXP3 peripherals definition */
+/* End MAIN PPCEXP3 peripherals definition */
+
+/* PERIPH PPC0 peripherals definition */
+#define SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK         (1UL << 0)
+#define SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK         (1UL << 1)
+#define SYSTEM_TIMER2_PERIPH_PPC0_POS_MASK         (1UL << 2)
+#define SYSTEM_TIMER3_PERIPH_PPC0_POS_MASK         (1UL << 5)
+#define WATCHDOG_PERIPH_PPC0_POS_MASK              (1UL << 6)
+/* There are separate secure and non-secure watchdog peripherals, so this bit
+ * can only be used in the unprivileged access registers. */
+/* End PERIPH PPC0 peripherals definition */
+
+/* PERIPH PPC1 peripherals definition */
+#define SLOWCLK_TIMER_PERIPH_PPC1_POS_MASK         (1UL << 0)
+/* End PERIPH PPC1 peripherals definition */
+
+/* PERIPH PPCEXP0 peripherals definition */
+#define USER_MEM_APB0_PERIPH_PPCEXP0_POS_MASK      (1UL << 0)
+#define USER_MEM_APB1_PERIPH_PPCEXP0_POS_MASK      (1UL << 1)
+#define NPU_APB0_PERIPH_PPCEXP0_POS_MASK           (1UL << 4)
+#define NPU_APB1_PERIPH_PPCEXP0_POS_MASK           (1UL << 5)
+#define MPC_SRAM_PERIPH_PPCEXP0_POS_MASK           (1UL << 13)
+#define MPC_QSPI_PERIPH_PPCEXP0_POS_MASK           (1UL << 14)
+#define MPC_DDR4_PERIPH_PPCEXP0_POS_MASK           (1UL << 15)
+/* End PERIPH PPCEXP0 peripherals definition */
+
+/* PERIPH PPCEXP1 peripherals definition */
+#define FPGA_I2C_TOUCH_PERIPH_PPCEXP1_POS_MASK     (1UL << 0)
+#define FPGA_I2C_AUDIO_PERIPH_PPCEXP1_POS_MASK     (1UL << 1)
+#define FPGA_SPI_ADC_PERIPH_PPCEXP1_POS_MASK       (1UL << 2)
+#define FPGA_SPI_SHIELD0_PERIPH_PPCEXP1_POS_MASK   (1UL << 3)
+#define FPGA_SPI_SHIELD1_PERIPH_PPCEXP1_POS_MASK   (1UL << 4)
+#define SBCon_I2C_SHIELD0_PERIPH_PPCEXP1_POS_MASK  (1UL << 5)
+#define SBCon_I2C_SHIELD1_PERIPH_PPCEXP1_POS_MASK  (1UL << 6)
+#define FPGA_SBCon_I2C_PERIPH_PPCEXP1_POS_MASK     (1UL << 8)
+/* End PERIPH PPCEXP1 peripherals definition */
+
+/* PERIPH PPCEXP2 peripherals definition */
+#define FPGA_SCC_PERIPH_PPCEXP2_POS_MASK           (1UL << 0)
+#define FPGA_I2S_PERIPH_PPCEXP2_POS_MASK           (1UL << 1)
+#define FPGA_IO_PERIPH_PPCEXP2_POS_MASK            (1UL << 2)
+#define UART0_PERIPH_PPCEXP2_POS_MASK              (1UL << 3)
+#define UART1_PERIPH_PPCEXP2_POS_MASK              (1UL << 4)
+#define UART2_PERIPH_PPCEXP2_POS_MASK              (1UL << 5)
+#define UART3_PERIPH_PPCEXP2_POS_MASK              (1UL << 6)
+#define UART4_PERIPH_PPCEXP2_POS_MASK              (1UL << 7)
+#define UART5_PERIPH_PPCEXP2_POS_MASK              (1UL << 8)
+#define CLCD_PERIPH_PPCEXP2_POS_MASK               (1UL << 10)
+#define RTC_PERIPH_PPCEXP2_POS_MASK                (1UL << 11)
+/* End PERIPH PPCEXP2 peripherals definition */
+
+/* PERIPH PPCEXP3 peripherals definition */
+/* End PERIPH PPCEXP3 peripherals definition */
+
+struct cpu0_pwrctrl_t {
+    volatile uint32_t cpupwrcfg;      /* 0x000 (R/W) CPU 0 Local Power
+                                       *             Configuration */
+    volatile uint32_t reserved0[1011];
+    volatile uint32_t pidr4;          /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved1[3];
+    volatile uint32_t pidr0;          /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;          /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;          /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;          /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;          /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;          /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;          /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;          /* 0xFFC (R/ ) Component ID 3 */
+};
+
+struct cpu0_secctrl_t {
+    volatile uint32_t cpuseccfg;      /* 0x000 (R/W) CPU Local Security
+                                       *             Configuration */
+    volatile uint32_t reserved0[1011];
+    volatile uint32_t pidr4;          /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved1[3];
+    volatile uint32_t pidr0;          /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;          /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;          /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;          /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;          /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;          /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;          /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;          /* 0xFFC (R/ ) Component ID 3 */
+};
+
+struct polaris_sysinfo_t {
+    volatile uint32_t soc_identity;   /* 0x000 (R/ ) SoC Identity Register */
+    volatile uint32_t sys_config0;    /* 0x004 (R/ ) System Hardware
+                                       *             Configuration 0 */
+    volatile uint32_t sys_config1;    /* 0x008 (R/ ) System Hardware
+                                       *             Configuration 1 */
+    volatile uint32_t reserved0[1006];
+    volatile uint32_t iidr;           /* 0xFC8 (R/ ) Subsystem Implementation
+                                       *             Identity */
+    volatile uint32_t reserved1;
+    volatile uint32_t pidr4;          /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved2[3];
+    volatile uint32_t pidr0;          /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;          /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;          /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;          /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;          /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;          /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;          /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;          /* 0xFFC (R/ ) Component ID 3 */
+};
+
+struct polaris_sysctrl_t {
+    volatile uint32_t secdbgstat;        /* 0x000 (R/ ) Secure Debug
+                                          *             Configuration Status */
+    volatile uint32_t secdbgset;         /* 0x004 (R/W) Secure Debug
+                                          *             Configuration Set */
+    volatile uint32_t secdbgclr;         /* 0x008 ( /W) Secure Debug
+                                          *             Configuration Clear */
+    volatile uint32_t scsecctrl;         /* 0x00C (R/W) System Control Security
+                                          *             Controls */
+    volatile uint32_t clk_cfg0;          /* 0x010 (R/W) Clock Configuration 0 */
+    volatile uint32_t clk_cfg1;          /* 0x014 (R/W) Clock Configuration 1 */
+    volatile uint32_t clock_force;       /* 0x018 (R/W) Clock Forces */
+    volatile uint32_t reserved0[57];
+    volatile uint32_t reset_syndrome;    /* 0x100 (R/W) Reset syndrome */
+    volatile uint32_t reset_mask;        /* 0x104 (R/W) Reset mask */
+    volatile uint32_t swreset;           /* 0x108 ( /W) Software Reset */
+    volatile uint32_t gretreg;           /* 0x10C (R/W) General Purpose
+                                          *             Retention */
+    volatile uint32_t initsvtor0;        /* 0x110 (R/W) CPU 0 Initial Secure
+                                          *             Reset Vector Register */
+    volatile uint32_t reserved1[3];
+    volatile uint32_t cpuwait;           /* 0x120 (R/W) CPU Boot Wait Control */
+    volatile uint32_t nmi_enable;        /* 0x124 (R/W) Non Maskable Interrupts
+                                          *             Enable */
+    volatile uint32_t reserved2[53];
+    volatile uint32_t pwrctrl;           /* 0x1FC (R/W) Power Configuration and
+                                          *             Control */
+    volatile uint32_t pdcm_pd_sys_sense; /* 0x200 (R/W) PDCM PD_SYS
+                                          *             Sensitivity */
+    volatile uint32_t pdcm_pd_cpu0_sense;/* 0x204 (R/ ) PDCM PD_CPU0
+                                          *             Sensitivity */
+    volatile uint32_t reserved3[3];
+    volatile uint32_t pdcm_pd_vmr0_sense;/* 0x214 (R/W) PDCM PD_VMR0
+                                          *             Sensitivity */
+    volatile uint32_t pdcm_pd_vmr1_sense;/* 0x218 (R/W) PDCM PD_VMR1
+                                          *             Sensitivity */
+    volatile uint32_t reserved4[877];
+    volatile uint32_t pidr4;             /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved5[3];
+    volatile uint32_t pidr0;             /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;             /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;             /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;             /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;             /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;             /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;             /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;             /* 0xFFC (R/ ) Component ID 3 */
+};
+
+struct polaris_ewic_t {
+    volatile uint32_t ewic_cr;        /* 0x000 (R/W) EWIC Control */
+    volatile uint32_t ewic_ascr;      /* 0x004 (R/W) Automatic Sequence
+                                       *             Control */
+    volatile uint32_t ewic_clrmask;   /* 0x008 ( /W) Clear All Mask */
+    volatile uint32_t ewic_numid;     /* 0x00C (R/ ) ID Register for the number
+                                       *             of events supported */
+    volatile uint32_t reserved0[124];
+    volatile uint32_t ewic_maska;     /* 0x200 (R/W) Set which internal events
+                                       *             cause wakeup */
+    volatile uint32_t ewic_mask[15];  /* 0x204 (R/W) Set which external
+                                       *             interrupts cause wakeup
+                                       *             Only the first (total
+                                       *             system IRQ number)/32
+                                       *             registers are implemented
+                                       *             in array */
+    volatile uint32_t reserved1[112];
+    volatile uint32_t ewic_penda;     /* 0x400 (R/ ) Shows which internal
+                                       *             interrupts were pended
+                                       *             while the EWIC was
+                                       *             enabled */
+
+    volatile uint32_t ewic_pend[15];   /* 0x404 (R/W) Shows which external
+                                       *             interrupts were pended
+                                       *             while the EWIC was
+                                       *             enabled
+                                       *             Only the first (total
+                                       *             system IRQ number)/32
+                                       *             registers are implemented
+                                       *             in array */
+    volatile uint32_t reserved2[112];
+    volatile uint32_t ewic_psr;       /* 0x600 (R/ ) Pending Summary */
+    volatile uint32_t reserved3[575];
+    volatile uint32_t itctrl;         /* 0xF00 (R/ ) Integration Mode Control */
+    volatile uint32_t reserved4[39];
+    volatile uint32_t claimset;       /* 0xFA0 (R/W) Claim Tag Set */
+    volatile uint32_t claimclr;       /* 0xFA4 (R/W) Claim Tag Clear */
+    volatile uint32_t devaff0;        /* 0xFA8 (R/ ) Device Affinity 0 */
+    volatile uint32_t devaff1;        /* 0xFAC (R/ ) Device Affinity 1 */
+    volatile uint32_t lar;            /* 0xFB0 ( /W) Lock Access */
+    volatile uint32_t lsr;            /* 0xFB4 (R/ ) Lock Status */
+    volatile uint32_t authstatus;     /* 0xFB8 (R/ ) Authentication Status */
+    volatile uint32_t devarch;        /* 0xFBC (R/ ) Device Architecture */
+    volatile uint32_t devid2;         /* 0xFC0 (R/ ) Device Configuration 2 */
+    volatile uint32_t devid1;         /* 0xFC4 (R/ ) Device Configuration 1 */
+    volatile uint32_t devid;          /* 0xFC8 (R/ ) Device Configuration */
+    volatile uint32_t devtype;        /* 0xFCC (R/ ) Device Type */
+    volatile uint32_t pidr4;          /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved5[3];
+    volatile uint32_t pidr0;          /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;          /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;          /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;          /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;          /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;          /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;          /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;          /* 0xFFC (R/ ) Component ID 3 */
+};
+#endif /* __PLATFORM_REGS_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/include/system_core_init.h b/platform/ext/target/arm/mps3/corstone_polaris/device/include/system_core_init.h
new file mode 100644
index 0000000..feba5e9
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/include/system_core_init.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009-2020 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.h
+ * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b
+ */
+
+#ifndef __SYSTEM_CORE_INIT_H__
+#define __SYSTEM_CORE_INIT_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint32_t SystemCoreClock;  /*!< System Clock Frequency (Core Clock)  */
+extern uint32_t PeripheralClock;  /*!< Peripheral Clock Frequency */
+
+/**
+ * \brief  Initializes the system
+ */
+extern void SystemInit(void);
+
+/**
+ * \brief  Restores system core clock
+ */
+extern void SystemCoreClockUpdate(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSTEM_CORE_INIT_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/armclang/corstone_polaris_bl2.sct b/platform/ext/target/arm/mps3/corstone_polaris/device/source/armclang/corstone_polaris_bl2.sct
new file mode 100644
index 0000000..1f6a34a
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/armclang/corstone_polaris_bl2.sct
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017-2020 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "region_defs.h"
+
+LR_CODE BL2_CODE_START {
+    ER_CODE BL2_CODE_START BL2_CODE_SIZE {
+        *.o (RESET +First)
+        * (+RO)
+    }
+
+    TFM_SHARED_DATA BOOT_TFM_SHARED_DATA_BASE ALIGN 32 EMPTY BOOT_TFM_SHARED_DATA_SIZE {
+    }
+
+    ER_DATA +0 {
+        * (+ZI +RW)
+    }
+
+    /* MSP */
+    ARM_LIB_STACK +0 ALIGN 32 EMPTY BL2_MSP_STACK_SIZE {
+    }
+
+    ARM_LIB_HEAP +0 ALIGN 8 EMPTY BL2_HEAP_SIZE {
+    }
+
+    /* This empty, zero long execution region is here to mark the limit address
+     * of the last execution region that is allocated in SRAM.
+     */
+    SRAM_WATERMARK +0 EMPTY 0x0 {
+    }
+
+    /* Make sure that the sections allocated in the SRAM does not exceed the
+     * size of the SRAM available.
+     */
+    ScatterAssert(ImageLimit(SRAM_WATERMARK) <= BL2_DATA_START + BL2_DATA_SIZE)
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/armclang/corstone_polaris_ns.sct b/platform/ext/target/arm/mps3/corstone_polaris/device/source/armclang/corstone_polaris_ns.sct
new file mode 100644
index 0000000..92707b9
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/armclang/corstone_polaris_ns.sct
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017-2020 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "region_defs.h"
+
+LR_CODE NS_CODE_START {
+    ER_CODE NS_CODE_START NS_CODE_SIZE {
+        *.o (RESET +First)
+        * (+RO)
+    }
+
+    ER_DATA NS_DATA_START {
+        * (+ZI +RW)
+    }
+
+    /* MSP */
+    ARM_LIB_STACK_MSP +0 ALIGN 32 EMPTY NS_MSP_STACK_SIZE {
+    }
+
+    /* PSP */
+    ARM_LIB_STACK +0 ALIGN 32 EMPTY NS_PSP_STACK_SIZE {
+    }
+
+    ARM_LIB_HEAP +0 ALIGN 8 EMPTY NS_HEAP_SIZE {
+    }
+
+    /* This empty, zero long execution region is here to mark the limit address
+     * of the last execution region that is allocated in SRAM.
+     */
+    SRAM_WATERMARK +0 EMPTY 0x0 {
+    }
+    /* Make sure that the sections allocated in the SRAM does not exceed the
+     * size of the SRAM available.
+     */
+    ScatterAssert(ImageLimit(SRAM_WATERMARK) <= NS_DATA_START + NS_DATA_SIZE)
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/device_definition.c b/platform/ext/target/arm/mps3/corstone_polaris/device/source/device_definition.c
new file mode 100644
index 0000000..25baf63
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/device_definition.c
@@ -0,0 +1,694 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file device_definition.c
+ * \brief This file defines exports the structures based on the peripheral
+ * definitions from device_cfg.h.
+ * This file is meant to be used as a helper for baremetal
+ * applications and/or as an example of how to configure the generic
+ * driver structures.
+ */
+
+#include "device_definition.h"
+#include "platform_base_address.h"
+#include "platform/include/tfm_plat_defs.h"
+
+/* UART CMSDK driver structures */
+#ifdef UART0_CMSDK_S
+static const struct uart_cmsdk_dev_cfg_t UART0_CMSDK_DEV_CFG_S = {
+    .base = UART0_BASE_S,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART0_CMSDK_DEV_DATA_S = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART0_CMSDK_DEV_S = {
+    &(UART0_CMSDK_DEV_CFG_S),
+    &(UART0_CMSDK_DEV_DATA_S)
+};
+#endif
+#ifdef UART0_CMSDK_NS
+static const struct uart_cmsdk_dev_cfg_t UART0_CMSDK_DEV_CFG_NS = {
+    .base = UART0_BASE_NS,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART0_CMSDK_DEV_DATA_NS = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART0_CMSDK_DEV_NS = {
+    &(UART0_CMSDK_DEV_CFG_NS),
+    &(UART0_CMSDK_DEV_DATA_NS)
+};
+#endif
+
+#ifdef UART1_CMSDK_S
+static const struct uart_cmsdk_dev_cfg_t UART1_CMSDK_DEV_CFG_S = {
+    .base = UART1_BASE_S,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART1_CMSDK_DEV_DATA_S = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART1_CMSDK_DEV_S = {
+    &(UART1_CMSDK_DEV_CFG_S),
+    &(UART1_CMSDK_DEV_DATA_S)
+};
+#endif
+#ifdef UART1_CMSDK_NS
+static const struct uart_cmsdk_dev_cfg_t UART1_CMSDK_DEV_CFG_NS = {
+    .base = UART1_BASE_NS,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART1_CMSDK_DEV_DATA_NS = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART1_CMSDK_DEV_NS = {
+    &(UART1_CMSDK_DEV_CFG_NS),
+    &(UART1_CMSDK_DEV_DATA_NS)
+};
+#endif
+
+#ifdef UART2_CMSDK_S
+static const struct uart_cmsdk_dev_cfg_t UART2_CMSDK_DEV_CFG_S = {
+    .base = UART2_BASE_S,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART2_CMSDK_DEV_DATA_S = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART2_CMSDK_DEV_S = {
+    &(UART2_CMSDK_DEV_CFG_S),
+    &(UART2_CMSDK_DEV_DATA_S)
+};
+#endif
+#ifdef UART2_CMSDK_NS
+static const struct uart_cmsdk_dev_cfg_t UART2_CMSDK_DEV_CFG_NS = {
+    .base = UART2_BASE_NS,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART2_CMSDK_DEV_DATA_NS = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART2_CMSDK_DEV_NS = {
+    &(UART2_CMSDK_DEV_CFG_NS),
+    &(UART2_CMSDK_DEV_DATA_NS)
+};
+#endif
+
+#ifdef UART3_CMSDK_S
+static const struct uart_cmsdk_dev_cfg_t UART3_CMSDK_DEV_CFG_S = {
+    .base = UART3_BASE_S,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART3_CMSDK_DEV_DATA_S = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART3_CMSDK_DEV_S = {
+    &(UART3_CMSDK_DEV_CFG_S),
+    &(UART3_CMSDK_DEV_DATA_S)
+};
+#endif
+#ifdef UART3_CMSDK_NS
+static const struct uart_cmsdk_dev_cfg_t UART3_CMSDK_DEV_CFG_NS = {
+    .base = UART3_BASE_NS,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART3_CMSDK_DEV_DATA_NS = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART3_CMSDK_DEV_NS = {
+    &(UART3_CMSDK_DEV_CFG_NS),
+    &(UART3_CMSDK_DEV_DATA_NS)
+};
+#endif
+
+#ifdef UART4_CMSDK_S
+static const struct uart_cmsdk_dev_cfg_t UART4_CMSDK_DEV_CFG_S = {
+    .base = UART4_BASE_S,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART4_CMSDK_DEV_DATA_S = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART4_CMSDK_DEV_S = {
+    &(UART4_CMSDK_DEV_CFG_S),
+    &(UART4_CMSDK_DEV_DATA_S)
+};
+#endif
+#ifdef UART4_CMSDK_NS
+static const struct uart_cmsdk_dev_cfg_t UART4_CMSDK_DEV_CFG_NS = {
+    .base = UART4_BASE_NS,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART4_CMSDK_DEV_DATA_NS = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART4_CMSDK_DEV_NS = {
+    &(UART4_CMSDK_DEV_CFG_NS),
+    &(UART4_CMSDK_DEV_DATA_NS)
+};
+#endif
+
+#ifdef UART5_CMSDK_S
+static const struct uart_cmsdk_dev_cfg_t UART5_CMSDK_DEV_CFG_S = {
+    .base = UART5_BASE_S,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART5_CMSDK_DEV_DATA_S = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART5_CMSDK_DEV_S = {
+    &(UART5_CMSDK_DEV_CFG_S),
+    &(UART5_CMSDK_DEV_DATA_S)
+};
+#endif
+#ifdef UART5_CMSDK_NS
+static const struct uart_cmsdk_dev_cfg_t UART5_CMSDK_DEV_CFG_NS = {
+    .base = UART5_BASE_NS,
+    .default_baudrate = DEFAULT_UART_BAUDRATE
+};
+static struct uart_cmsdk_dev_data_t UART5_CMSDK_DEV_DATA_NS = {
+    .state = 0,
+    .system_clk = 0,
+    .baudrate = 0
+};
+struct uart_cmsdk_dev_t UART5_CMSDK_DEV_NS = {
+    &(UART5_CMSDK_DEV_CFG_NS),
+    &(UART5_CMSDK_DEV_DATA_NS)
+};
+#endif
+
+/* Polaris PPC driver structures */
+#ifdef PPC_POLARIS_MAIN0_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_MAIN0_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_MAIN0};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_MAIN0_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_MAIN0_DEV_S = {
+    &PPC_POLARIS_MAIN0_CFG_S,
+    &PPC_POLARIS_MAIN0_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP0_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_MAIN_EXP0_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_MAIN_EXP0};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_MAIN_EXP0_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP0_DEV_S = {
+    &PPC_POLARIS_MAIN_EXP0_CFG_S,
+    &PPC_POLARIS_MAIN_EXP0_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP1_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_MAIN_EXP1_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_MAIN_EXP1};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_MAIN_EXP1_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP1_DEV_S = {
+    &PPC_POLARIS_MAIN_EXP1_CFG_S,
+    &PPC_POLARIS_MAIN_EXP1_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP2_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_MAIN_EXP2_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_MAIN_EXP2};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_MAIN_EXP2_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP2_DEV_S = {
+    &PPC_POLARIS_MAIN_EXP2_CFG_S,
+    &PPC_POLARIS_MAIN_EXP2_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_MAIN_EXP3_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_MAIN_EXP3_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_MAIN_EXP3};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_MAIN_EXP3_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_MAIN_EXP3_DEV_S = {
+    &PPC_POLARIS_MAIN_EXP3_CFG_S,
+    &PPC_POLARIS_MAIN_EXP3_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_PERIPH0_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_PERIPH0_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_PERIPH0};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_PERIPH0_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_PERIPH0_DEV_S = {
+    &PPC_POLARIS_PERIPH0_CFG_S,
+    &PPC_POLARIS_PERIPH0_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_PERIPH1_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_PERIPH1_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_PERIPH1};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_PERIPH1_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_PERIPH1_DEV_S = {
+    &PPC_POLARIS_PERIPH1_CFG_S,
+    &PPC_POLARIS_PERIPH1_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP0_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_PERIPH_EXP0_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_PERIPH_EXP0};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_PERIPH_EXP0_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP0_DEV_S = {
+    &PPC_POLARIS_PERIPH_EXP0_CFG_S,
+    &PPC_POLARIS_PERIPH_EXP0_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP1_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_PERIPH_EXP1_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_PERIPH_EXP1};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_PERIPH_EXP1_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP1_DEV_S = {
+    &PPC_POLARIS_PERIPH_EXP1_CFG_S,
+    &PPC_POLARIS_PERIPH_EXP1_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP2_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_PERIPH_EXP2_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_PERIPH_EXP2};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_PERIPH_EXP2_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP2_DEV_S = {
+    &PPC_POLARIS_PERIPH_EXP2_CFG_S,
+    &PPC_POLARIS_PERIPH_EXP2_DATA_S };
+#endif
+
+#ifdef PPC_POLARIS_PERIPH_EXP3_S
+static struct ppc_polaris_dev_cfg_t PPC_POLARIS_PERIPH_EXP3_CFG_S = {
+    .sacfg_base  = POLARIS_SACFG_BASE_S,
+    .nsacfg_base = POLARIS_NSACFG_BASE_NS,
+    .ppc_name = PPC_POLARIS_PERIPH_EXP3};
+static struct ppc_polaris_dev_data_t PPC_POLARIS_PERIPH_EXP3_DATA_S = {
+    .sacfg_ns_ppc  = 0,
+    .sacfg_sp_ppc  = 0,
+    .nsacfg_nsp_ppc = 0,
+    .int_bit_mask = 0,
+    .is_initialized = false };
+struct ppc_polaris_dev_t PPC_POLARIS_PERIPH_EXP3_DEV_S = {
+    &PPC_POLARIS_PERIPH_EXP3_CFG_S,
+    &PPC_POLARIS_PERIPH_EXP3_DATA_S };
+#endif
+
+/* System counters */
+#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S
+
+#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT > \
+    SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX
+#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT is invalid.
+#endif
+#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT > \
+    SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX
+#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT is invalid.
+#endif
+#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT > \
+    SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX
+#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT is invalid.
+#endif
+#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT > \
+    SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX
+#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT is invalid.
+#endif
+
+static const struct syscounter_armv8_m_cntrl_dev_cfg_t
+SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S = {
+    .base = SYSCNTR_CNTRL_BASE_S,
+    .scale0.integer  = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT,
+    .scale0.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT,
+    .scale1.integer  = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT,
+    .scale1.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT
+};
+static struct syscounter_armv8_m_cntrl_dev_data_t
+SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S = {
+    .is_initialized = false
+};
+struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S = {
+    &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S),
+    &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S)
+};
+#endif
+
+#ifdef SYSCOUNTER_READ_ARMV8_M_S
+static const struct syscounter_armv8_m_read_dev_cfg_t
+SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S = {
+    .base = SYSCNTR_READ_BASE_S,
+};
+struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S = {
+    &(SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S),
+};
+#endif
+#ifdef SYSCOUNTER_READ_ARMV8_M_NS
+static const struct syscounter_armv8_m_read_dev_cfg_t
+SYSCOUNTER_READ_ARMV8_M_DEV_CFG_NS = {
+    .base = SYSCNTR_READ_BASE_NS,
+};
+struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS = {
+    &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_NS),
+};
+#endif
+
+/* System timers */
+#ifdef SYSTIMER0_ARMV8_M_S
+static const struct systimer_armv8_m_dev_cfg_t SYSTIMER0_ARMV8_M_DEV_CFG_S
+#ifdef TEST_NS_SLIH_IRQ
+    TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT")
+#elif defined(TEST_NS_FLIH_IRQ)
+    TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FLIH_TEST", "APP-ROT")
+#endif
+    = {
+    .base = SYSTIMER0_ARMV8_M_BASE_S,
+    .default_freq_hz = SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t SYSTIMER0_ARMV8_M_DEV_DATA_S
+#ifdef TEST_NS_SLIH_IRQ
+    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT")
+#elif defined(TEST_NS_FLIH_IRQ)
+    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FLIH_TEST", "APP-ROT")
+#endif
+    = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_S
+#ifdef TEST_NS_SLIH_IRQ
+    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT")
+#elif defined(TEST_NS_FLIH_IRQ)
+    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FLIH_TEST", "APP-ROT")
+#endif
+    = {
+    &(SYSTIMER0_ARMV8_M_DEV_CFG_S),
+    &(SYSTIMER0_ARMV8_M_DEV_DATA_S)
+};
+#endif
+
+#ifdef SYSTIMER0_ARMV8_M_NS
+static const struct systimer_armv8_m_dev_cfg_t
+SYSTIMER0_ARMV8_M_DEV_CFG_NS = {
+    .base = SYSTIMER0_ARMV8_M_BASE_NS,
+    .default_freq_hz = SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t
+SYSTIMER0_ARMV8_M_DEV_DATA_NS = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_NS = {
+    &(SYSTIMER0_ARMV8_M_DEV_CFG_NS),
+    &(SYSTIMER0_ARMV8_M_DEV_DATA_NS)
+};
+#endif
+
+#ifdef SYSTIMER1_ARMV8_M_S
+static const struct systimer_armv8_m_dev_cfg_t
+SYSTIMER1_ARMV8_M_DEV_CFG_S = {
+    .base = SYSTIMER1_ARMV8_M_BASE_S,
+    .default_freq_hz = SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t
+SYSTIMER1_ARMV8_M_DEV_DATA_S = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_S = {
+    &(SYSTIMER1_ARMV8_M_DEV_CFG_S),
+    &(SYSTIMER1_ARMV8_M_DEV_DATA_S)
+};
+#endif
+
+#ifdef SYSTIMER1_ARMV8_M_NS
+static const struct systimer_armv8_m_dev_cfg_t
+SYSTIMER1_ARMV8_M_DEV_CFG_NS = {
+    .base = SYSTIMER1_ARMV8_M_BASE_NS,
+    .default_freq_hz = SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t
+SYSTIMER1_ARMV8_M_DEV_DATA_NS = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_NS = {
+    &(SYSTIMER1_ARMV8_M_DEV_CFG_NS),
+    &(SYSTIMER1_ARMV8_M_DEV_DATA_NS)
+};
+#endif
+
+#ifdef SYSTIMER2_ARMV8_M_S
+static const struct systimer_armv8_m_dev_cfg_t
+SYSTIMER2_ARMV8_M_DEV_CFG_S = {
+    .base = SYSTIMER2_ARMV8_M_BASE_S,
+    .default_freq_hz = SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t
+SYSTIMER2_ARMV8_M_DEV_DATA_S = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_S = {
+    &(SYSTIMER2_ARMV8_M_DEV_CFG_S),
+    &(SYSTIMER2_ARMV8_M_DEV_DATA_S)
+};
+#endif
+
+#ifdef SYSTIMER2_ARMV8_M_NS
+static const struct systimer_armv8_m_dev_cfg_t
+SYSTIMER2_ARMV8_M_DEV_CFG_NS = {
+    .base = SYSTIMER2_ARMV8_M_BASE_NS,
+    .default_freq_hz = SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t
+SYSTIMER2_ARMV8_M_DEV_DATA_NS = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_NS = {
+    &(SYSTIMER2_ARMV8_M_DEV_CFG_NS),
+    &(SYSTIMER2_ARMV8_M_DEV_DATA_NS)
+};
+#endif
+
+#ifdef SYSTIMER3_ARMV8_M_S
+static const struct systimer_armv8_m_dev_cfg_t
+SYSTIMER3_ARMV8_M_DEV_CFG_S = {
+    .base = SYSTIMER3_ARMV8_M_BASE_S,
+    .default_freq_hz = SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t
+SYSTIMER3_ARMV8_M_DEV_DATA_S = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_S = {
+    &(SYSTIMER3_ARMV8_M_DEV_CFG_S),
+    &(SYSTIMER3_ARMV8_M_DEV_DATA_S)
+};
+#endif
+
+#ifdef SYSTIMER3_ARMV8_M_NS
+static const struct systimer_armv8_m_dev_cfg_t
+SYSTIMER3_ARMV8_M_DEV_CFG_NS = {
+    .base = SYSTIMER3_ARMV8_M_BASE_NS,
+    .default_freq_hz = SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ
+};
+static struct systimer_armv8_m_dev_data_t
+SYSTIMER3_ARMV8_M_DEV_DATA_NS = {
+    .is_initialized = false
+};
+struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_NS = {
+    &(SYSTIMER3_ARMV8_M_DEV_CFG_NS),
+    &(SYSTIMER3_ARMV8_M_DEV_DATA_NS)
+};
+#endif
+
+/* System Watchdogs */
+#ifdef SYSWDOG_ARMV8_M_S
+static const struct syswdog_armv8_m_dev_cfg_t
+SYSWDOG_ARMV8_M_DEV_CFG_S = {
+    .base = SYSWDOG_ARMV8_M_CNTRL_BASE_S
+};
+struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_S = {
+    &(SYSWDOG_ARMV8_M_DEV_CFG_S)
+};
+#endif
+
+#ifdef SYSWDOG_ARMV8_M_NS
+static const struct syswdog_armv8_m_dev_cfg_t
+SYSWDOG_ARMV8_M_DEV_CFG_NS = {
+    .base = SYSWDOG_ARMV8_M_CNTRL_BASE_NS
+};
+struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_NS = {
+    &(SYSWDOG_ARMV8_M_DEV_CFG_NS)
+};
+#endif
+
+/* ARM MPC SIE 300 driver structures */
+#ifdef MPC_SRAM_S
+static const struct mpc_sie_dev_cfg_t MPC_SRAM_DEV_CFG_S = {
+    .base = MPC_SRAM_BASE_S};
+static struct mpc_sie_dev_data_t MPC_SRAM_DEV_DATA_S = {
+    .range_list = 0,
+    .nbr_of_ranges = 0,
+    .is_initialized = false };
+struct mpc_sie_dev_t MPC_SRAM_DEV_S = {
+    &(MPC_SRAM_DEV_CFG_S),
+    &(MPC_SRAM_DEV_DATA_S)};
+#endif
+
+#ifdef MPC_QSPI_S
+static const struct mpc_sie_dev_cfg_t MPC_QSPI_DEV_CFG_S = {
+    .base = MPC_QSPI_BASE_S};
+static struct mpc_sie_dev_data_t MPC_QSPI_DEV_DATA_S = {
+    .range_list = 0,
+    .nbr_of_ranges = 0,
+    .is_initialized = false };
+struct mpc_sie_dev_t MPC_QSPI_DEV_S = {
+    &(MPC_QSPI_DEV_CFG_S),
+    &(MPC_QSPI_DEV_DATA_S)};
+#endif
+
+#ifdef MPC_DDR4_S
+static const struct mpc_sie_dev_cfg_t MPC_DDR4_DEV_CFG_S = {
+    .base = MPC_DDR4_BASE_S};
+static struct mpc_sie_dev_data_t MPC_DDR4_DEV_DATA_S = {
+    .range_list = 0,
+    .nbr_of_ranges = 0,
+    .is_initialized = false };
+struct mpc_sie_dev_t MPC_DDR4_DEV_S = {
+    &(MPC_DDR4_DEV_CFG_S),
+    &(MPC_DDR4_DEV_DATA_S)};
+#endif
+
+#ifdef MPC_ISRAM0_S
+static const struct mpc_sie_dev_cfg_t MPC_ISRAM0_DEV_CFG_S = {
+    .base = MPC_ISRAM0_BASE_S};
+static struct mpc_sie_dev_data_t MPC_ISRAM0_DEV_DATA_S = {
+    .range_list = 0,
+    .nbr_of_ranges = 0,
+    .is_initialized = false };
+struct mpc_sie_dev_t MPC_ISRAM0_DEV_S = {
+    &(MPC_ISRAM0_DEV_CFG_S),
+    &(MPC_ISRAM0_DEV_DATA_S)};
+#endif
+
+#ifdef MPC_ISRAM1_S
+static const struct mpc_sie_dev_cfg_t MPC_ISRAM1_DEV_CFG_S = {
+    .base = MPC_ISRAM1_BASE_S};
+static struct mpc_sie_dev_data_t MPC_ISRAM1_DEV_DATA_S = {
+    .range_list = 0,
+    .nbr_of_ranges = 0,
+    .is_initialized = false };
+struct mpc_sie_dev_t MPC_ISRAM1_DEV_S = {
+    &(MPC_ISRAM1_DEV_CFG_S),
+    &(MPC_ISRAM1_DEV_DATA_S)};
+#endif
+
+#ifdef MPS3_IO_S
+static struct arm_mps3_io_dev_cfg_t MPS3_IO_DEV_CFG_S = {
+    .base = FPGA_IO_BASE_S
+};
+struct arm_mps3_io_dev_t MPS3_IO_DEV_S = {
+    .cfg = &(MPS3_IO_DEV_CFG_S)
+};
+#endif
+
+#ifdef MPS3_IO_NS
+static struct arm_mps3_io_dev_cfg_t MPS3_IO_DEV_CFG_NS = {
+    .base = FPGA_IO_BASE_NS
+};
+struct arm_mps3_io_dev_t MPS3_IO_DEV_NS = {
+    .cfg = &(MPS3_IO_DEV_CFG_NS)
+};
+#endif
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/gcc/corstone_polaris_bl2.ld b/platform/ext/target/arm/mps3/corstone_polaris/device/source/gcc/corstone_polaris_bl2.ld
new file mode 100644
index 0000000..fac1656
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/gcc/corstone_polaris_bl2.ld
@@ -0,0 +1,191 @@
+;/*
+; * Copyright (c) 2021 Arm Limited. All rights reserved.
+; *
+; * Licensed under the Apache License, Version 2.0 (the "License");
+; * you may not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; *     http://www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an "AS IS" BASIS,
+; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; *
+; *
+; * This file is derivative of CMSIS V5.00 gcc_arm.ld
+; */
+
+/* Linker script to configure memory regions. */
+/* This file will be run trough the pre-processor. */
+
+#include "region_defs.h"
+
+MEMORY
+{
+    FLASH (rx)  : ORIGIN = BL2_CODE_START, LENGTH = BL2_CODE_SIZE
+    RAM   (rwx) : ORIGIN = BL2_DATA_START, LENGTH = BL2_DATA_SIZE
+}
+
+__heap_size__  = BL2_HEAP_SIZE;
+__msp_stack_size__ = BL2_MSP_STACK_SIZE;
+
+/* Library configurations */
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+    .text :
+    {
+        KEEP(*(.vectors))
+        __Vectors_End = .;
+        __Vectors_Size = __Vectors_End - __Vectors;
+        __end__ = .;
+
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+         *crtbegin.o(.dtors)
+         *crtbegin?.o(.dtors)
+         *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+         *(SORT(.dtors.*))
+         *(.dtors)
+
+        *(.rodata*)
+
+        KEEP(*(.eh_frame*))
+    } > FLASH
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > FLASH
+    __exidx_end = .;
+
+    /* To copy multiple ROM to RAM sections,
+     * define etext2/data2_start/data2_end and
+     * define __STARTUP_COPY_MULTIPLE in startup_cmsdk_mps3_an524_bl2.S */
+    .copy.table :
+    {
+        . = ALIGN(4);
+        __copy_table_start__ = .;
+        LONG (__etext)
+        LONG (__data_start__)
+        LONG (__data_end__ - __data_start__)
+        LONG (DEFINED(__etext2) ? __etext2 : 0)
+        LONG (DEFINED(__data2_start__) ? __data2_start__ : 0)
+        LONG (DEFINED(__data2_start__) ? __data2_end__ - __data2_start__ : 0)
+        __copy_table_end__ = .;
+    } > FLASH
+
+    /* To clear multiple BSS sections,
+     * uncomment .zero.table section and,
+     * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_cmsdk_mps3_an524_bl2.S */
+    .zero.table :
+    {
+        . = ALIGN(4);
+        __zero_table_start__ = .;
+        LONG (__bss_start__)
+        LONG (__bss_end__ - __bss_start__)
+        LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0)
+        LONG (DEFINED(__bss2_start__) ? __bss2_end__ - __bss2_start__ : 0)
+        __zero_table_end__ = .;
+    } > FLASH
+
+    __etext = .;
+
+    .tfm_bl2_shared_data : ALIGN(32)
+    {
+        . += BOOT_TFM_SHARED_DATA_SIZE;
+    } > RAM
+    Image$$SHARED_DATA$$RW$$Base = ADDR(.tfm_bl2_shared_data);
+    Image$$SHARED_DATA$$RW$$Limit = ADDR(.tfm_bl2_shared_data) + SIZEOF(.tfm_bl2_shared_data);
+
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+
+        . = ALIGN(4);
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        KEEP(*(.preinit_array))
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        KEEP(*(SORT(.init_array.*)))
+        KEEP(*(.init_array))
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        KEEP(*(SORT(.fini_array.*)))
+        KEEP(*(.fini_array))
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        KEEP(*(.jcr*))
+        . = ALIGN(4);
+        /* All data end */
+        __data_end__ = .;
+
+    } > RAM
+    Image$$ER_DATA$$Base = ADDR(.data);
+
+    .bss :
+    {
+        . = ALIGN(4);
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        __bss_end__ = .;
+    } > RAM
+
+    bss_size = __bss_end__ - __bss_start__;
+
+    .msp_stack : ALIGN(32)
+    {
+        . += __msp_stack_size__;
+    } > RAM
+    Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.msp_stack);
+    Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack);
+
+    .heap : ALIGN(8)
+    {
+        . = ALIGN(8);
+        __end__ = .;
+        PROVIDE(end = .);
+        __HeapBase = .;
+        . += __heap_size__;
+        __HeapLimit = .;
+        __heap_limit = .; /* Add for _sbrk */
+    } > RAM
+    Image$$ARM_LIB_HEAP$$ZI$$Limit = ADDR(.heap) + SIZEOF(.heap);
+
+    PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit);
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/gcc/corstone_polaris_ns.ld b/platform/ext/target/arm/mps3/corstone_polaris/device/source/gcc/corstone_polaris_ns.ld
new file mode 100644
index 0000000..66887d5
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/gcc/corstone_polaris_ns.ld
@@ -0,0 +1,190 @@
+;/*
+; * Copyright (c) 2021 Arm Limited. All rights reserved.
+; *
+; * Licensed under the Apache License, Version 2.0 (the "License");
+; * you may not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; *     http://www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an "AS IS" BASIS,
+; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; *
+; *
+; * This file is derivative of CMSIS V5.00 gcc_arm.ld
+; */
+
+/* Linker script to configure memory regions. */
+/* This file will be run trough the pre-processor. */
+
+#include "region_defs.h"
+
+MEMORY
+{
+  FLASH (rx)  : ORIGIN = NS_CODE_START, LENGTH = NS_CODE_SIZE
+  RAM   (rwx) : ORIGIN = NS_DATA_START, LENGTH = NS_DATA_SIZE
+}
+
+__heap_size__  = NS_HEAP_SIZE;
+__psp_stack_size__ = NS_PSP_STACK_SIZE;
+__msp_stack_size__ = NS_MSP_STACK_SIZE;
+
+/* Library configurations */
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+    .text :
+    {
+        KEEP(*(.vectors))
+        __Vectors_End = .;
+        __Vectors_Size = __Vectors_End - __Vectors;
+        __end__ = .;
+
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+         *crtbegin.o(.dtors)
+         *crtbegin?.o(.dtors)
+         *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+         *(SORT(.dtors.*))
+         *(.dtors)
+
+        *(.rodata*)
+
+        KEEP(*(.eh_frame*))
+    } > FLASH
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > FLASH
+    __exidx_end = .;
+
+    /* To copy multiple ROM to RAM sections,
+     * define etext2/data2_start/data2_end and
+     * define __STARTUP_COPY_MULTIPLE in startup_cmsdk_mps3_an524_ns.S */
+    .copy.table :
+    {
+        . = ALIGN(4);
+        __copy_table_start__ = .;
+        LONG (__etext)
+        LONG (__data_start__)
+        LONG (__data_end__ - __data_start__)
+        LONG (DEFINED(__etext2) ? __etext2 : 0)
+        LONG (DEFINED(__data2_start__) ? __data2_start__ : 0)
+        LONG (DEFINED(__data2_start__) ? __data2_end__ - __data2_start__ : 0)
+        __copy_table_end__ = .;
+    } > FLASH
+
+    /* To clear multiple BSS sections,
+     * uncomment .zero.table section and,
+     * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_cmsdk_mps3_an524_ns.S */
+    .zero.table :
+    {
+        . = ALIGN(4);
+        __zero_table_start__ = .;
+        LONG (__bss_start__)
+        LONG (__bss_end__ - __bss_start__)
+        LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0)
+        LONG (DEFINED(__bss2_start__) ? __bss2_end__ - __bss2_start__ : 0)
+        __zero_table_end__ = .;
+    } > FLASH
+
+    __etext = .;
+
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+
+        . = ALIGN(4);
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        KEEP(*(.preinit_array))
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        KEEP(*(SORT(.init_array.*)))
+        KEEP(*(.init_array))
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        KEEP(*(SORT(.fini_array.*)))
+        KEEP(*(.fini_array))
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        KEEP(*(.jcr*))
+        . = ALIGN(4);
+        /* All data end */
+        __data_end__ = .;
+
+    } > RAM
+
+    .bss :
+    {
+        . = ALIGN(4);
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        __bss_end__ = .;
+    } > RAM
+
+    bss_size = __bss_end__ - __bss_start__;
+
+    .msp_stack : ALIGN(32)
+    {
+        . += __msp_stack_size__;
+    } > RAM
+    Image$$ARM_LIB_STACK_MSP$$ZI$$Base = ADDR(.msp_stack);
+    Image$$ARM_LIB_STACK_MSP$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack);
+
+    .psp_stack : ALIGN(32)
+    {
+        . += __psp_stack_size__;
+    } > RAM
+    Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.psp_stack);
+    Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.psp_stack) + SIZEOF(.psp_stack);
+
+    .heap : ALIGN(8)
+    {
+        . = ALIGN(8);
+        __end__ = .;
+        PROVIDE(end = .);
+        __HeapBase = .;
+        . += __heap_size__;
+        __HeapLimit = .;
+        __heap_limit = .; /* Add for _sbrk */
+    } > RAM
+
+    PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit);
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_bl2.c b/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_bl2.c
new file mode 100644
index 0000000..e65837e
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_bl2.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c
+ * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b
+ */
+
+#include "cmsis.h"
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Handler Function Prototype
+ *----------------------------------------------------------------------------*/
+typedef void( *pFunc )( void );
+
+/*----------------------------------------------------------------------------
+  External References
+ *----------------------------------------------------------------------------*/
+extern uint32_t __INITIAL_SP;
+extern uint32_t __STACK_LIMIT;
+
+extern void __PROGRAM_START(void) __NO_RETURN;
+
+/*----------------------------------------------------------------------------
+  Internal References
+ *----------------------------------------------------------------------------*/
+void Reset_Handler  (void) __NO_RETURN;
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Handler
+ *----------------------------------------------------------------------------*/
+#define DEFAULT_IRQ_HANDLER(handler_name)  \
+void __WEAK handler_name(void) __NO_RETURN; \
+void handler_name(void) { \
+    while(1); \
+}
+
+/* Exceptions */
+DEFAULT_IRQ_HANDLER(NMI_Handler)
+DEFAULT_IRQ_HANDLER(HardFault_Handler)
+DEFAULT_IRQ_HANDLER(MemManage_Handler)
+DEFAULT_IRQ_HANDLER(BusFault_Handler)
+DEFAULT_IRQ_HANDLER(UsageFault_Handler)
+DEFAULT_IRQ_HANDLER(SecureFault_Handler)
+DEFAULT_IRQ_HANDLER(SVC_Handler)
+DEFAULT_IRQ_HANDLER(DebugMon_Handler)
+DEFAULT_IRQ_HANDLER(PendSV_Handler)
+DEFAULT_IRQ_HANDLER(SysTick_Handler)
+
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_REQ_Handler)
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler)
+DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler)
+DEFAULT_IRQ_HANDLER(TIMER0_Handler)
+DEFAULT_IRQ_HANDLER(TIMER1_Handler)
+DEFAULT_IRQ_HANDLER(TIMER2_Handler)
+DEFAULT_IRQ_HANDLER(MPC_Handler)
+DEFAULT_IRQ_HANDLER(PPC_Handler)
+DEFAULT_IRQ_HANDLER(MSC_Handler)
+DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler)
+DEFAULT_IRQ_HANDLER(COMBINED_PPU_Handler)
+DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler)
+DEFAULT_IRQ_HANDLER(TIMER3_AON_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_0_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_1_Handler)
+
+DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX4_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX4_Handler)
+DEFAULT_IRQ_HANDLER(UART0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART4_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UARTOVF_Handler)
+DEFAULT_IRQ_HANDLER(ETHERNET_Handler)
+DEFAULT_IRQ_HANDLER(I2S_Handler)
+DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler)
+DEFAULT_IRQ_HANDLER(USB_Handler)
+DEFAULT_IRQ_HANDLER(SPI_ADC_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler)
+DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX5_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX5_Handler)
+DEFAULT_IRQ_HANDLER(UART5_Handler)
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+extern const pFunc __VECTOR_TABLE[496];
+       const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = {
+  (pFunc)(&__INITIAL_SP),            /*      Initial Stack Pointer */
+  Reset_Handler,                     /*      Reset Handler */
+  NMI_Handler,                       /* -14: NMI Handler */
+  HardFault_Handler,                 /* -13: Hard Fault Handler */
+  MemManage_Handler,                 /* -12: MPU Fault Handler */
+  BusFault_Handler,                  /* -11: Bus Fault Handler */
+  UsageFault_Handler,                /* -10: Usage Fault Handler */
+  SecureFault_Handler,               /*  -9: Secure Fault Handler */
+  0,                                 /*      Reserved */
+  0,                                 /*      Reserved */
+  0,                                 /*      Reserved */
+  SVC_Handler,                       /*  -5: SVCall Handler */
+  DebugMon_Handler,                  /*  -4: Debug Monitor Handler */
+  0,                                 /*      Reserved */
+  PendSV_Handler,                    /*  -2: PendSV Handler */
+  SysTick_Handler,                   /*  -1: SysTick Handler */
+
+  NONSEC_WATCHDOG_RESET_REQ_Handler, /*   0: Non-Secure Watchdog Reset Request Handler */
+  NONSEC_WATCHDOG_Handler,           /*   1: Non-Secure Watchdog Handler */
+  SLOWCLK_Timer_Handler,             /*   2: SLOWCLK Timer Handler */
+  TIMER0_Handler,                    /*   3: TIMER 0 Handler */
+  TIMER1_Handler,                    /*   4: TIMER 1 Handler */
+  TIMER2_Handler,                    /*   5: TIMER 2 Handler */
+  0,                                 /*   6: Reserved */
+  0,                                 /*   7: Reserved */
+  0,                                 /*   8: Reserved */
+  MPC_Handler,                       /*   9: MPC Combined (Secure) Handler */
+  PPC_Handler,                       /*  10: PPC Combined (Secure) Handler */
+  MSC_Handler,                       /*  11: MSC Combined (Secure) Handler */
+  BRIDGE_ERROR_Handler,              /*  12: Bridge Error (Secure) Handler */
+  0,                                 /*  13: Reserved */
+  COMBINED_PPU_Handler,              /*  14: Combined PPU Handler */
+  0,                                 /*  15: Reserved */
+  ETHOS_U55_Handler,                 /*  16: Ethos-U55 Handler */
+  0,                                 /*  17: Reserved */
+  0,                                 /*  18: Reserved */
+  0,                                 /*  19: Reserved */
+  0,                                 /*  20: Reserved */
+  0,                                 /*  21: Reserved */
+  0,                                 /*  22: Reserved */
+  0,                                 /*  23: Reserved */
+  0,                                 /*  24: Reserved */
+  0,                                 /*  25: Reserved */
+  0,                                 /*  26: Reserved */
+  TIMER3_AON_Handler,                /*  27: TIMER 3 AON Handler */
+  CPU0_CTI_0_Handler,                /*  28: CPU0 CTI IRQ 0 Handler */
+  CPU0_CTI_1_Handler,                /*  29: CPU0 CTI IRQ 1 Handler */
+  0,                                 /*  30: Reserved */
+  0,                                 /*  31: Reserved */
+
+  /* External interrupts */
+  System_Timestamp_Counter_Handler,  /*  32: System timestamp counter Handler */
+  UARTRX0_Handler,                   /*  33: UART 0 RX Handler */
+  UARTTX0_Handler,                   /*  34: UART 0 TX Handler */
+  UARTRX1_Handler,                   /*  35: UART 1 RX Handler */
+  UARTTX1_Handler,                   /*  36: UART 1 TX Handler */
+  UARTRX2_Handler,                   /*  37: UART 2 RX Handler */
+  UARTTX2_Handler,                   /*  38: UART 2 TX Handler */
+  UARTRX3_Handler,                   /*  39: UART 3 RX Handler */
+  UARTTX3_Handler,                   /*  40: UART 3 TX Handler */
+  UARTRX4_Handler,                   /*  41: UART 4 RX Handler */
+  UARTTX4_Handler,                   /*  42: UART 4 TX Handler */
+  UART0_Combined_Handler,            /*  43: UART 0 Combined Handler */
+  UART1_Combined_Handler,            /*  44: UART 1 Combined Handler */
+  UART2_Combined_Handler,            /*  45: UART 2 Combined Handler */
+  UART3_Combined_Handler,            /*  46: UART 3 Combined Handler */
+  UART4_Combined_Handler,            /*  47: UART 4 Combined Handler */
+  UARTOVF_Handler,                   /*  48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */
+  ETHERNET_Handler,                  /*  49: Ethernet Handler */
+  I2S_Handler,                       /*  50: Audio I2S Handler */
+  TOUCH_SCREEN_Handler,              /*  51: Touch Screen Handler */
+  USB_Handler,                       /*  52: USB Handler */
+  SPI_ADC_Handler,                   /*  53: SPI ADC Handler */
+  SPI_SHIELD0_Handler,               /*  54: SPI (Shield 0) Handler */
+  SPI_SHIELD1_Handler,               /*  55: SPI (Shield 0) Handler */
+  0,                                 /*  56: Reserved */
+  0,                                 /*  57: Reserved */
+  0,                                 /*  58: Reserved */
+  0,                                 /*  59: Reserved */
+  0,                                 /*  60: Reserved */
+  0,                                 /*  61: Reserved */
+  0,                                 /*  62: Reserved */
+  0,                                 /*  63: Reserved */
+  0,                                 /*  64: Reserved */
+  0,                                 /*  65: Reserved */
+  0,                                 /*  66: Reserved */
+  0,                                 /*  67: Reserved */
+  0,                                 /*  68: Reserved */
+  GPIO0_Combined_Handler,            /*  69: GPIO 0 Combined Handler */
+  GPIO1_Combined_Handler,            /*  70: GPIO 1 Combined Handler */
+  GPIO2_Combined_Handler,            /*  71: GPIO 2 Combined Handler */
+  GPIO3_Combined_Handler,            /*  72: GPIO 3 Combined Handler */
+  GPIO0_0_Handler,                   /*  73: GPIO0 Pin 0 Handler */
+  GPIO0_1_Handler,                   /*  74: GPIO0 Pin 1 Handler */
+  GPIO0_2_Handler,                   /*  75: GPIO0 Pin 2 Handler */
+  GPIO0_3_Handler,                   /*  76: GPIO0 Pin 3 Handler */
+  GPIO0_4_Handler,                   /*  77: GPIO0 Pin 4 Handler */
+  GPIO0_5_Handler,                   /*  78: GPIO0 Pin 5 Handler */
+  GPIO0_6_Handler,                   /*  79: GPIO0 Pin 6 Handler */
+  GPIO0_7_Handler,                   /*  80: GPIO0 Pin 7 Handler */
+  GPIO0_8_Handler,                   /*  81: GPIO0 Pin 8 Handler */
+  GPIO0_9_Handler,                   /*  82: GPIO0 Pin 9 Handler */
+  GPIO0_10_Handler,                  /*  83: GPIO0 Pin 10 Handler */
+  GPIO0_11_Handler,                  /*  84: GPIO0 Pin 11 Handler */
+  GPIO0_12_Handler,                  /*  85: GPIO0 Pin 12 Handler */
+  GPIO0_13_Handler,                  /*  86: GPIO0 Pin 13 Handler */
+  GPIO0_14_Handler,                  /*  87: GPIO0 Pin 14 Handler */
+  GPIO0_15_Handler,                  /*  88: GPIO0 Pin 15 Handler */
+  GPIO1_0_Handler,                   /*  89: GPIO1 Pin 0 Handler */
+  GPIO1_1_Handler,                   /*  90: GPIO1 Pin 1 Handler */
+  GPIO1_2_Handler,                   /*  91: GPIO1 Pin 2 Handler */
+  GPIO1_3_Handler,                   /*  92: GPIO1 Pin 3 Handler */
+  GPIO1_4_Handler,                   /*  93: GPIO1 Pin 4 Handler */
+  GPIO1_5_Handler,                   /*  94: GPIO1 Pin 5 Handler */
+  GPIO1_6_Handler,                   /*  95: GPIO1 Pin 6 Handler */
+  GPIO1_7_Handler,                   /*  96: GPIO1 Pin 7 Handler */
+  GPIO1_8_Handler,                   /*  97: GPIO1 Pin 8 Handler */
+  GPIO1_9_Handler,                   /*  98: GPIO1 Pin 9 Handler */
+  GPIO1_10_Handler,                  /*  99: GPIO1 Pin 10 Handler */
+  GPIO1_11_Handler,                  /*  100: GPIO1 Pin 11 Handler */
+  GPIO1_12_Handler,                  /*  101: GPIO1 Pin 12 Handler */
+  GPIO1_13_Handler,                  /*  102: GPIO1 Pin 13 Handler */
+  GPIO1_14_Handler,                  /*  103: GPIO1 Pin 14 Handler */
+  GPIO1_15_Handler,                  /*  104: GPIO1 Pin 15 Handler */
+  GPIO2_0_Handler,                   /*  105: GPIO2 Pin 0 Handler */
+  GPIO2_1_Handler,                   /*  106: GPIO2 Pin 1 Handler */
+  GPIO2_2_Handler,                   /*  107: GPIO2 Pin 2 Handler */
+  GPIO2_3_Handler,                   /*  108: GPIO2 Pin 3 Handler */
+  GPIO2_4_Handler,                   /*  109: GPIO2 Pin 4 Handler */
+  GPIO2_5_Handler,                   /*  110: GPIO2 Pin 5 Handler */
+  GPIO2_6_Handler,                   /*  111: GPIO2 Pin 6 Handler */
+  GPIO2_7_Handler,                   /*  112: GPIO2 Pin 7 Handler */
+  GPIO2_8_Handler,                   /*  113: GPIO2 Pin 8 Handler */
+  GPIO2_9_Handler,                   /*  114: GPIO2 Pin 9 Handler */
+  GPIO2_10_Handler,                  /*  115: GPIO2 Pin 10 Handler */
+  GPIO2_11_Handler,                  /*  116: GPIO2 Pin 11 Handler */
+  GPIO2_12_Handler,                  /*  117: GPIO2 Pin 12 Handler */
+  GPIO2_13_Handler,                  /*  118: GPIO2 Pin 13 Handler */
+  GPIO2_14_Handler,                  /*  119: GPIO2 Pin 14 Handler */
+  GPIO2_15_Handler,                  /*  120: GPIO2 Pin 15 Handler */
+  GPIO3_0_Handler,                   /*  121: GPIO3 Pin 0 Handler */
+  GPIO3_1_Handler,                   /*  122: GPIO3 Pin 1 Handler */
+  GPIO3_2_Handler,                   /*  123: GPIO3 Pin 2 Handler */
+  GPIO3_3_Handler,                   /*  124: GPIO3 Pin 3 Handler */
+  UARTRX5_Handler,                   /*  125: UART 5 RX Interrupt */
+  UARTTX5_Handler,                   /*  126: UART 5 TX Interrupt */
+  UART5_Handler,                     /*  127: UART 5 combined Interrupt */
+  0,                                 /*  128: Reserved */
+  0,                                 /*  129: Reserved */
+  0,                                 /*  130: Reserved */
+};
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+/*----------------------------------------------------------------------------
+  Reset Handler called on controller reset
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void)
+{
+  __set_MSPLIM((uint32_t)(&__STACK_LIMIT));
+
+  SystemInit();                             /* CMSIS System Initialization */
+  __PROGRAM_START();                        /* Enter PreMain (C library entry point) */
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_ns.c b/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_ns.c
new file mode 100644
index 0000000..1efe8a7
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_ns.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c
+ * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b
+ */
+
+#include "cmsis.h"
+#include "region.h"
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Handler Function Prototype
+ *----------------------------------------------------------------------------*/
+typedef void( *pFunc )( void );
+
+/*----------------------------------------------------------------------------
+  External References
+ *----------------------------------------------------------------------------*/
+
+#define __MSP_INITIAL_SP              REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit)
+#define __MSP_STACK_LIMIT             REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Base)
+
+extern uint32_t __MSP_INITIAL_SP;
+extern uint32_t __MSP_STACK_LIMIT;
+
+extern uint32_t __INITIAL_SP;
+extern uint32_t __STACK_LIMIT;
+
+extern void __PROGRAM_START(void) __NO_RETURN;
+
+/*----------------------------------------------------------------------------
+  Internal References
+ *----------------------------------------------------------------------------*/
+void Reset_Handler  (void) __NO_RETURN;
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Handler
+ *----------------------------------------------------------------------------*/
+#define DEFAULT_IRQ_HANDLER(handler_name)  \
+void __WEAK handler_name(void) __NO_RETURN; \
+void handler_name(void) { \
+    while(1); \
+}
+
+/* Exceptions */
+DEFAULT_IRQ_HANDLER(NMI_Handler)
+DEFAULT_IRQ_HANDLER(HardFault_Handler)
+DEFAULT_IRQ_HANDLER(MemManage_Handler)
+DEFAULT_IRQ_HANDLER(BusFault_Handler)
+DEFAULT_IRQ_HANDLER(UsageFault_Handler)
+DEFAULT_IRQ_HANDLER(SecureFault_Handler)
+DEFAULT_IRQ_HANDLER(SVC_Handler)
+DEFAULT_IRQ_HANDLER(DebugMon_Handler)
+DEFAULT_IRQ_HANDLER(PendSV_Handler)
+DEFAULT_IRQ_HANDLER(SysTick_Handler)
+
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_REQ_Handler)
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler)
+DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler)
+DEFAULT_IRQ_HANDLER(TFM_TIMER0_IRQ_Handler)
+DEFAULT_IRQ_HANDLER(TIMER1_Handler)
+DEFAULT_IRQ_HANDLER(TIMER2_Handler)
+DEFAULT_IRQ_HANDLER(MPC_Handler)
+DEFAULT_IRQ_HANDLER(PPC_Handler)
+DEFAULT_IRQ_HANDLER(MSC_Handler)
+DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler)
+DEFAULT_IRQ_HANDLER(COMBINED_PPU_Handler)
+DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler)
+DEFAULT_IRQ_HANDLER(TIMER3_AON_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_0_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_1_Handler)
+
+DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX4_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX4_Handler)
+DEFAULT_IRQ_HANDLER(UART0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART4_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UARTOVF_Handler)
+DEFAULT_IRQ_HANDLER(ETHERNET_Handler)
+DEFAULT_IRQ_HANDLER(I2S_Handler)
+DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler)
+DEFAULT_IRQ_HANDLER(USB_Handler)
+DEFAULT_IRQ_HANDLER(SPI_ADC_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler)
+DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX5_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX5_Handler)
+DEFAULT_IRQ_HANDLER(UART5_Handler)
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+extern const pFunc __VECTOR_TABLE[496];
+       const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = {
+  (pFunc)(&__MSP_INITIAL_SP),        /*      Initial Stack Pointer */
+  Reset_Handler,                     /*      Reset Handler */
+  NMI_Handler,                       /* -14: NMI Handler */
+  HardFault_Handler,                 /* -13: Hard Fault Handler */
+  MemManage_Handler,                 /* -12: MPU Fault Handler */
+  BusFault_Handler,                  /* -11: Bus Fault Handler */
+  UsageFault_Handler,                /* -10: Usage Fault Handler */
+  SecureFault_Handler,               /*  -9: Secure Fault Handler */
+  0,                                 /*      Reserved */
+  0,                                 /*      Reserved */
+  0,                                 /*      Reserved */
+  SVC_Handler,                       /*  -5: SVCall Handler */
+  DebugMon_Handler,                  /*  -4: Debug Monitor Handler */
+  0,                                 /*      Reserved */
+  PendSV_Handler,                    /*  -2: PendSV Handler */
+  SysTick_Handler,                   /*  -1: SysTick Handler */
+
+  NONSEC_WATCHDOG_RESET_REQ_Handler, /*   0: Non-Secure Watchdog Reset Request Handler */
+  NONSEC_WATCHDOG_Handler,           /*   1: Non-Secure Watchdog Handler */
+  SLOWCLK_Timer_Handler,             /*   2: SLOWCLK Timer Handler */
+  TFM_TIMER0_IRQ_Handler,            /*   3: TIMER 0 Handler */
+  TIMER1_Handler,                    /*   4: TIMER 1 Handler */
+  TIMER2_Handler,                    /*   5: TIMER 2 Handler */
+  0,                                 /*   6: Reserved */
+  0,                                 /*   7: Reserved */
+  0,                                 /*   8: Reserved */
+  MPC_Handler,                       /*   9: MPC Combined (Secure) Handler */
+  PPC_Handler,                       /*  10: PPC Combined (Secure) Handler */
+  MSC_Handler,                       /*  11: MSC Combined (Secure) Handler */
+  BRIDGE_ERROR_Handler,              /*  12: Bridge Error (Secure) Handler */
+  0,                                 /*  13: Reserved */
+  COMBINED_PPU_Handler,              /*  14: Combined PPU Handler */
+  0,                                 /*  15: Reserved */
+  ETHOS_U55_Handler,                 /*  16: Ethos-U55 Handler */
+  0,                                 /*  17: Reserved */
+  0,                                 /*  18: Reserved */
+  0,                                 /*  19: Reserved */
+  0,                                 /*  20: Reserved */
+  0,                                 /*  21: Reserved */
+  0,                                 /*  22: Reserved */
+  0,                                 /*  23: Reserved */
+  0,                                 /*  24: Reserved */
+  0,                                 /*  25: Reserved */
+  0,                                 /*  26: Reserved */
+  TIMER3_AON_Handler,                /*  27: TIMER 3 AON Handler */
+  CPU0_CTI_0_Handler,                /*  28: CPU0 CTI IRQ 0 Handler */
+  CPU0_CTI_1_Handler,                /*  29: CPU0 CTI IRQ 1 Handler */
+  0,                                 /*  30: Reserved */
+  0,                                 /*  31: Reserved */
+
+  /* External interrupts */
+  System_Timestamp_Counter_Handler,  /*  32: System timestamp counter Handler */
+  UARTRX0_Handler,                   /*  33: UART 0 RX Handler */
+  UARTTX0_Handler,                   /*  34: UART 0 TX Handler */
+  UARTRX1_Handler,                   /*  35: UART 1 RX Handler */
+  UARTTX1_Handler,                   /*  36: UART 1 TX Handler */
+  UARTRX2_Handler,                   /*  37: UART 2 RX Handler */
+  UARTTX2_Handler,                   /*  38: UART 2 TX Handler */
+  UARTRX3_Handler,                   /*  39: UART 3 RX Handler */
+  UARTTX3_Handler,                   /*  40: UART 3 TX Handler */
+  UARTRX4_Handler,                   /*  41: UART 4 RX Handler */
+  UARTTX4_Handler,                   /*  42: UART 4 TX Handler */
+  UART0_Combined_Handler,            /*  43: UART 0 Combined Handler */
+  UART1_Combined_Handler,            /*  44: UART 1 Combined Handler */
+  UART2_Combined_Handler,            /*  45: UART 2 Combined Handler */
+  UART3_Combined_Handler,            /*  46: UART 3 Combined Handler */
+  UART4_Combined_Handler,            /*  47: UART 4 Combined Handler */
+  UARTOVF_Handler,                   /*  48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */
+  ETHERNET_Handler,                  /*  49: Ethernet Handler */
+  I2S_Handler,                       /*  50: Audio I2S Handler */
+  TOUCH_SCREEN_Handler,              /*  51: Touch Screen Handler */
+  USB_Handler,                       /*  52: USB Handler */
+  SPI_ADC_Handler,                   /*  53: SPI ADC Handler */
+  SPI_SHIELD0_Handler,               /*  54: SPI (Shield 0) Handler */
+  SPI_SHIELD1_Handler,               /*  55: SPI (Shield 0) Handler */
+  0,                                 /*  56: Reserved */
+  0,                                 /*  57: Reserved */
+  0,                                 /*  58: Reserved */
+  0,                                 /*  59: Reserved */
+  0,                                 /*  60: Reserved */
+  0,                                 /*  61: Reserved */
+  0,                                 /*  62: Reserved */
+  0,                                 /*  63: Reserved */
+  0,                                 /*  64: Reserved */
+  0,                                 /*  65: Reserved */
+  0,                                 /*  66: Reserved */
+  0,                                 /*  67: Reserved */
+  0,                                 /*  68: Reserved */
+  GPIO0_Combined_Handler,            /*  69: GPIO 0 Combined Handler */
+  GPIO1_Combined_Handler,            /*  70: GPIO 1 Combined Handler */
+  GPIO2_Combined_Handler,            /*  71: GPIO 2 Combined Handler */
+  GPIO3_Combined_Handler,            /*  72: GPIO 3 Combined Handler */
+  GPIO0_0_Handler,                   /*  73: GPIO0 Pin 0 Handler */
+  GPIO0_1_Handler,                   /*  74: GPIO0 Pin 1 Handler */
+  GPIO0_2_Handler,                   /*  75: GPIO0 Pin 2 Handler */
+  GPIO0_3_Handler,                   /*  76: GPIO0 Pin 3 Handler */
+  GPIO0_4_Handler,                   /*  77: GPIO0 Pin 4 Handler */
+  GPIO0_5_Handler,                   /*  78: GPIO0 Pin 5 Handler */
+  GPIO0_6_Handler,                   /*  79: GPIO0 Pin 6 Handler */
+  GPIO0_7_Handler,                   /*  80: GPIO0 Pin 7 Handler */
+  GPIO0_8_Handler,                   /*  81: GPIO0 Pin 8 Handler */
+  GPIO0_9_Handler,                   /*  82: GPIO0 Pin 9 Handler */
+  GPIO0_10_Handler,                  /*  83: GPIO0 Pin 10 Handler */
+  GPIO0_11_Handler,                  /*  84: GPIO0 Pin 11 Handler */
+  GPIO0_12_Handler,                  /*  85: GPIO0 Pin 12 Handler */
+  GPIO0_13_Handler,                  /*  86: GPIO0 Pin 13 Handler */
+  GPIO0_14_Handler,                  /*  87: GPIO0 Pin 14 Handler */
+  GPIO0_15_Handler,                  /*  88: GPIO0 Pin 15 Handler */
+  GPIO1_0_Handler,                   /*  89: GPIO1 Pin 0 Handler */
+  GPIO1_1_Handler,                   /*  90: GPIO1 Pin 1 Handler */
+  GPIO1_2_Handler,                   /*  91: GPIO1 Pin 2 Handler */
+  GPIO1_3_Handler,                   /*  92: GPIO1 Pin 3 Handler */
+  GPIO1_4_Handler,                   /*  93: GPIO1 Pin 4 Handler */
+  GPIO1_5_Handler,                   /*  94: GPIO1 Pin 5 Handler */
+  GPIO1_6_Handler,                   /*  95: GPIO1 Pin 6 Handler */
+  GPIO1_7_Handler,                   /*  96: GPIO1 Pin 7 Handler */
+  GPIO1_8_Handler,                   /*  97: GPIO1 Pin 8 Handler */
+  GPIO1_9_Handler,                   /*  98: GPIO1 Pin 9 Handler */
+  GPIO1_10_Handler,                  /*  99: GPIO1 Pin 10 Handler */
+  GPIO1_11_Handler,                  /*  100: GPIO1 Pin 11 Handler */
+  GPIO1_12_Handler,                  /*  101: GPIO1 Pin 12 Handler */
+  GPIO1_13_Handler,                  /*  102: GPIO1 Pin 13 Handler */
+  GPIO1_14_Handler,                  /*  103: GPIO1 Pin 14 Handler */
+  GPIO1_15_Handler,                  /*  104: GPIO1 Pin 15 Handler */
+  GPIO2_0_Handler,                   /*  105: GPIO2 Pin 0 Handler */
+  GPIO2_1_Handler,                   /*  106: GPIO2 Pin 1 Handler */
+  GPIO2_2_Handler,                   /*  107: GPIO2 Pin 2 Handler */
+  GPIO2_3_Handler,                   /*  108: GPIO2 Pin 3 Handler */
+  GPIO2_4_Handler,                   /*  109: GPIO2 Pin 4 Handler */
+  GPIO2_5_Handler,                   /*  110: GPIO2 Pin 5 Handler */
+  GPIO2_6_Handler,                   /*  111: GPIO2 Pin 6 Handler */
+  GPIO2_7_Handler,                   /*  112: GPIO2 Pin 7 Handler */
+  GPIO2_8_Handler,                   /*  113: GPIO2 Pin 8 Handler */
+  GPIO2_9_Handler,                   /*  114: GPIO2 Pin 9 Handler */
+  GPIO2_10_Handler,                  /*  115: GPIO2 Pin 10 Handler */
+  GPIO2_11_Handler,                  /*  116: GPIO2 Pin 11 Handler */
+  GPIO2_12_Handler,                  /*  117: GPIO2 Pin 12 Handler */
+  GPIO2_13_Handler,                  /*  118: GPIO2 Pin 13 Handler */
+  GPIO2_14_Handler,                  /*  119: GPIO2 Pin 14 Handler */
+  GPIO2_15_Handler,                  /*  120: GPIO2 Pin 15 Handler */
+  GPIO3_0_Handler,                   /*  121: GPIO3 Pin 0 Handler */
+  GPIO3_1_Handler,                   /*  122: GPIO3 Pin 1 Handler */
+  GPIO3_2_Handler,                   /*  123: GPIO3 Pin 2 Handler */
+  GPIO3_3_Handler,                   /*  124: GPIO3 Pin 3 Handler */
+  UARTRX5_Handler,                   /*  125: UART 5 RX Interrupt */
+  UARTTX5_Handler,                   /*  126: UART 5 TX Interrupt */
+  UART5_Handler,                     /*  127: UART 5 combined Interrupt */
+  0,                                 /*  128: Reserved */
+  0,                                 /*  129: Reserved */
+  0,                                 /*  130: Reserved */
+};
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+/*----------------------------------------------------------------------------
+  Reset Handler called on controller reset
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void)
+{
+  __set_MSPLIM((uint32_t)(&__MSP_STACK_LIMIT));
+
+  SystemInit();                             /* CMSIS System Initialization */
+  __ASM volatile("MRS     R0, control\n"    /* Get control value */
+                 "ORR     R0, R0, #2\n"     /* Select switch to PSP */
+                 "MSR     control, R0\n"    /* Load control register */
+                 :
+                 :
+                 : "r0");
+  __PROGRAM_START();                        /* Enter PreMain (C library entry point) */
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_s.c b/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_s.c
new file mode 100644
index 0000000..b76536b
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/startup_corstone_polaris_s.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c
+ * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b
+ */
+
+#include "cmsis.h"
+#include "region.h"
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Handler Function Prototype
+ *----------------------------------------------------------------------------*/
+typedef void( *pFunc )( void );
+
+/*----------------------------------------------------------------------------
+  External References
+ *----------------------------------------------------------------------------*/
+
+#define __MSP_INITIAL_SP              REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit)
+#define __MSP_STACK_LIMIT             REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base)
+
+extern uint32_t __MSP_INITIAL_SP;
+extern uint32_t __MSP_STACK_LIMIT;
+
+extern void __PROGRAM_START(void) __NO_RETURN;
+
+/*----------------------------------------------------------------------------
+  Internal References
+ *----------------------------------------------------------------------------*/
+void Reset_Handler  (void) __NO_RETURN;
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Handler
+ *----------------------------------------------------------------------------*/
+#define DEFAULT_IRQ_HANDLER(handler_name)  \
+void __WEAK handler_name(void) __NO_RETURN; \
+void handler_name(void) { \
+    while(1); \
+}
+
+/* Exceptions */
+DEFAULT_IRQ_HANDLER(NMI_Handler)
+DEFAULT_IRQ_HANDLER(HardFault_Handler)
+DEFAULT_IRQ_HANDLER(MemManage_Handler)
+DEFAULT_IRQ_HANDLER(BusFault_Handler)
+DEFAULT_IRQ_HANDLER(UsageFault_Handler)
+DEFAULT_IRQ_HANDLER(SecureFault_Handler)
+DEFAULT_IRQ_HANDLER(SVC_Handler)
+DEFAULT_IRQ_HANDLER(DebugMon_Handler)
+DEFAULT_IRQ_HANDLER(PendSV_Handler)
+DEFAULT_IRQ_HANDLER(SysTick_Handler)
+
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_REQ_Handler)
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler)
+DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler)
+DEFAULT_IRQ_HANDLER(TFM_TIMER0_IRQ_Handler)
+DEFAULT_IRQ_HANDLER(TIMER1_Handler)
+DEFAULT_IRQ_HANDLER(TIMER2_Handler)
+DEFAULT_IRQ_HANDLER(MPC_Handler)
+DEFAULT_IRQ_HANDLER(PPC_Handler)
+DEFAULT_IRQ_HANDLER(MSC_Handler)
+DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler)
+DEFAULT_IRQ_HANDLER(COMBINED_PPU_Handler)
+DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler)
+DEFAULT_IRQ_HANDLER(TIMER3_AON_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_0_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_1_Handler)
+
+DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX4_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX4_Handler)
+DEFAULT_IRQ_HANDLER(UART0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART4_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UARTOVF_Handler)
+DEFAULT_IRQ_HANDLER(ETHERNET_Handler)
+DEFAULT_IRQ_HANDLER(I2S_Handler)
+DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler)
+DEFAULT_IRQ_HANDLER(USB_Handler)
+DEFAULT_IRQ_HANDLER(SPI_ADC_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler)
+DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX5_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX5_Handler)
+DEFAULT_IRQ_HANDLER(UART5_Handler)
+
+/*----------------------------------------------------------------------------
+  Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+extern const pFunc __VECTOR_TABLE[496];
+       const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = {
+  (pFunc)(&__MSP_INITIAL_SP),        /*      Initial Stack Pointer */
+  Reset_Handler,                     /*      Reset Handler */
+  NMI_Handler,                       /* -14: NMI Handler */
+  HardFault_Handler,                 /* -13: Hard Fault Handler */
+  MemManage_Handler,                 /* -12: MPU Fault Handler */
+  BusFault_Handler,                  /* -11: Bus Fault Handler */
+  UsageFault_Handler,                /* -10: Usage Fault Handler */
+  SecureFault_Handler,               /*  -9: Secure Fault Handler */
+  0,                                 /*      Reserved */
+  0,                                 /*      Reserved */
+  0,                                 /*      Reserved */
+  SVC_Handler,                       /*  -5: SVCall Handler */
+  DebugMon_Handler,                  /*  -4: Debug Monitor Handler */
+  0,                                 /*      Reserved */
+  PendSV_Handler,                    /*  -2: PendSV Handler */
+  SysTick_Handler,                   /*  -1: SysTick Handler */
+
+  NONSEC_WATCHDOG_RESET_REQ_Handler, /*   0: Non-Secure Watchdog Reset Request Handler */
+  NONSEC_WATCHDOG_Handler,           /*   1: Non-Secure Watchdog Handler */
+  SLOWCLK_Timer_Handler,             /*   2: SLOWCLK Timer Handler */
+  TFM_TIMER0_IRQ_Handler,            /*   3: TIMER 0 Handler */
+  TIMER1_Handler,                    /*   4: TIMER 1 Handler */
+  TIMER2_Handler,                    /*   5: TIMER 2 Handler */
+  0,                                 /*   6: Reserved */
+  0,                                 /*   7: Reserved */
+  0,                                 /*   8: Reserved */
+  MPC_Handler,                       /*   9: MPC Combined (Secure) Handler */
+  PPC_Handler,                       /*  10: PPC Combined (Secure) Handler */
+  MSC_Handler,                       /*  11: MSC Combined (Secure) Handler */
+  BRIDGE_ERROR_Handler,              /*  12: Bridge Error (Secure) Handler */
+  0,                                 /*  13: Reserved */
+  COMBINED_PPU_Handler,              /*  14: Combined PPU Handler */
+  0,                                 /*  15: Reserved */
+  ETHOS_U55_Handler,                 /*  16: Ethos-U55 Handler */
+  0,                                 /*  17: Reserved */
+  0,                                 /*  18: Reserved */
+  0,                                 /*  19: Reserved */
+  0,                                 /*  20: Reserved */
+  0,                                 /*  21: Reserved */
+  0,                                 /*  22: Reserved */
+  0,                                 /*  23: Reserved */
+  0,                                 /*  24: Reserved */
+  0,                                 /*  25: Reserved */
+  0,                                 /*  26: Reserved */
+  TIMER3_AON_Handler,                /*  27: TIMER 3 AON Handler */
+  CPU0_CTI_0_Handler,                /*  28: CPU0 CTI IRQ 0 Handler */
+  CPU0_CTI_1_Handler,                /*  29: CPU0 CTI IRQ 1 Handler */
+  0,                                 /*  30: Reserved */
+  0,                                 /*  31: Reserved */
+
+  /* External interrupts */
+  System_Timestamp_Counter_Handler,  /*  32: System timestamp counter Handler */
+  UARTRX0_Handler,                   /*  33: UART 0 RX Handler */
+  UARTTX0_Handler,                   /*  34: UART 0 TX Handler */
+  UARTRX1_Handler,                   /*  35: UART 1 RX Handler */
+  UARTTX1_Handler,                   /*  36: UART 1 TX Handler */
+  UARTRX2_Handler,                   /*  37: UART 2 RX Handler */
+  UARTTX2_Handler,                   /*  38: UART 2 TX Handler */
+  UARTRX3_Handler,                   /*  39: UART 3 RX Handler */
+  UARTTX3_Handler,                   /*  40: UART 3 TX Handler */
+  UARTRX4_Handler,                   /*  41: UART 4 RX Handler */
+  UARTTX4_Handler,                   /*  42: UART 4 TX Handler */
+  UART0_Combined_Handler,            /*  43: UART 0 Combined Handler */
+  UART1_Combined_Handler,            /*  44: UART 1 Combined Handler */
+  UART2_Combined_Handler,            /*  45: UART 2 Combined Handler */
+  UART3_Combined_Handler,            /*  46: UART 3 Combined Handler */
+  UART4_Combined_Handler,            /*  47: UART 4 Combined Handler */
+  UARTOVF_Handler,                   /*  48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */
+  ETHERNET_Handler,                  /*  49: Ethernet Handler */
+  I2S_Handler,                       /*  50: Audio I2S Handler */
+  TOUCH_SCREEN_Handler,              /*  51: Touch Screen Handler */
+  USB_Handler,                       /*  52: USB Handler */
+  SPI_ADC_Handler,                   /*  53: SPI ADC Handler */
+  SPI_SHIELD0_Handler,               /*  54: SPI (Shield 0) Handler */
+  SPI_SHIELD1_Handler,               /*  55: SPI (Shield 0) Handler */
+  0,                                 /*  56: Reserved */
+  0,                                 /*  57: Reserved */
+  0,                                 /*  58: Reserved */
+  0,                                 /*  59: Reserved */
+  0,                                 /*  60: Reserved */
+  0,                                 /*  61: Reserved */
+  0,                                 /*  62: Reserved */
+  0,                                 /*  63: Reserved */
+  0,                                 /*  64: Reserved */
+  0,                                 /*  65: Reserved */
+  0,                                 /*  66: Reserved */
+  0,                                 /*  67: Reserved */
+  0,                                 /*  68: Reserved */
+  GPIO0_Combined_Handler,            /*  69: GPIO 0 Combined Handler */
+  GPIO1_Combined_Handler,            /*  70: GPIO 1 Combined Handler */
+  GPIO2_Combined_Handler,            /*  71: GPIO 2 Combined Handler */
+  GPIO3_Combined_Handler,            /*  72: GPIO 3 Combined Handler */
+  GPIO0_0_Handler,                   /*  73: GPIO0 Pin 0 Handler */
+  GPIO0_1_Handler,                   /*  74: GPIO0 Pin 1 Handler */
+  GPIO0_2_Handler,                   /*  75: GPIO0 Pin 2 Handler */
+  GPIO0_3_Handler,                   /*  76: GPIO0 Pin 3 Handler */
+  GPIO0_4_Handler,                   /*  77: GPIO0 Pin 4 Handler */
+  GPIO0_5_Handler,                   /*  78: GPIO0 Pin 5 Handler */
+  GPIO0_6_Handler,                   /*  79: GPIO0 Pin 6 Handler */
+  GPIO0_7_Handler,                   /*  80: GPIO0 Pin 7 Handler */
+  GPIO0_8_Handler,                   /*  81: GPIO0 Pin 8 Handler */
+  GPIO0_9_Handler,                   /*  82: GPIO0 Pin 9 Handler */
+  GPIO0_10_Handler,                  /*  83: GPIO0 Pin 10 Handler */
+  GPIO0_11_Handler,                  /*  84: GPIO0 Pin 11 Handler */
+  GPIO0_12_Handler,                  /*  85: GPIO0 Pin 12 Handler */
+  GPIO0_13_Handler,                  /*  86: GPIO0 Pin 13 Handler */
+  GPIO0_14_Handler,                  /*  87: GPIO0 Pin 14 Handler */
+  GPIO0_15_Handler,                  /*  88: GPIO0 Pin 15 Handler */
+  GPIO1_0_Handler,                   /*  89: GPIO1 Pin 0 Handler */
+  GPIO1_1_Handler,                   /*  90: GPIO1 Pin 1 Handler */
+  GPIO1_2_Handler,                   /*  91: GPIO1 Pin 2 Handler */
+  GPIO1_3_Handler,                   /*  92: GPIO1 Pin 3 Handler */
+  GPIO1_4_Handler,                   /*  93: GPIO1 Pin 4 Handler */
+  GPIO1_5_Handler,                   /*  94: GPIO1 Pin 5 Handler */
+  GPIO1_6_Handler,                   /*  95: GPIO1 Pin 6 Handler */
+  GPIO1_7_Handler,                   /*  96: GPIO1 Pin 7 Handler */
+  GPIO1_8_Handler,                   /*  97: GPIO1 Pin 8 Handler */
+  GPIO1_9_Handler,                   /*  98: GPIO1 Pin 9 Handler */
+  GPIO1_10_Handler,                  /*  99: GPIO1 Pin 10 Handler */
+  GPIO1_11_Handler,                  /*  100: GPIO1 Pin 11 Handler */
+  GPIO1_12_Handler,                  /*  101: GPIO1 Pin 12 Handler */
+  GPIO1_13_Handler,                  /*  102: GPIO1 Pin 13 Handler */
+  GPIO1_14_Handler,                  /*  103: GPIO1 Pin 14 Handler */
+  GPIO1_15_Handler,                  /*  104: GPIO1 Pin 15 Handler */
+  GPIO2_0_Handler,                   /*  105: GPIO2 Pin 0 Handler */
+  GPIO2_1_Handler,                   /*  106: GPIO2 Pin 1 Handler */
+  GPIO2_2_Handler,                   /*  107: GPIO2 Pin 2 Handler */
+  GPIO2_3_Handler,                   /*  108: GPIO2 Pin 3 Handler */
+  GPIO2_4_Handler,                   /*  109: GPIO2 Pin 4 Handler */
+  GPIO2_5_Handler,                   /*  110: GPIO2 Pin 5 Handler */
+  GPIO2_6_Handler,                   /*  111: GPIO2 Pin 6 Handler */
+  GPIO2_7_Handler,                   /*  112: GPIO2 Pin 7 Handler */
+  GPIO2_8_Handler,                   /*  113: GPIO2 Pin 8 Handler */
+  GPIO2_9_Handler,                   /*  114: GPIO2 Pin 9 Handler */
+  GPIO2_10_Handler,                  /*  115: GPIO2 Pin 10 Handler */
+  GPIO2_11_Handler,                  /*  116: GPIO2 Pin 11 Handler */
+  GPIO2_12_Handler,                  /*  117: GPIO2 Pin 12 Handler */
+  GPIO2_13_Handler,                  /*  118: GPIO2 Pin 13 Handler */
+  GPIO2_14_Handler,                  /*  119: GPIO2 Pin 14 Handler */
+  GPIO2_15_Handler,                  /*  120: GPIO2 Pin 15 Handler */
+  GPIO3_0_Handler,                   /*  121: GPIO3 Pin 0 Handler */
+  GPIO3_1_Handler,                   /*  122: GPIO3 Pin 1 Handler */
+  GPIO3_2_Handler,                   /*  123: GPIO3 Pin 2 Handler */
+  GPIO3_3_Handler,                   /*  124: GPIO3 Pin 3 Handler */
+  UARTRX5_Handler,                   /*  125: UART 5 RX Interrupt */
+  UARTTX5_Handler,                   /*  126: UART 5 TX Interrupt */
+  UART5_Handler,                     /*  127: UART 5 combined Interrupt */
+  0,                                 /*  128: Reserved */
+  0,                                 /*  129: Reserved */
+  0,                                 /*  130: Reserved */
+};
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+/*----------------------------------------------------------------------------
+  Reset Handler called on controller reset
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void)
+{
+  __set_MSPLIM((uint32_t)(&__MSP_STACK_LIMIT));
+
+  SystemInit();                             /* CMSIS System Initialization */
+
+  __PROGRAM_START();                        /* Enter PreMain (C library entry point) */
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/device/source/system_core_init.c b/platform/ext/target/arm/mps3/corstone_polaris/device/source/system_core_init.c
new file mode 100644
index 0000000..8f55046
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/device/source/system_core_init.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.c
+ * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b
+ */
+
+#include "cmsis.h"
+
+/*----------------------------------------------------------------------------
+  Define clocks
+ *----------------------------------------------------------------------------*/
+ #define  XTAL             (32000000UL)
+ #define  SYSTEM_CLOCK     (XTAL)
+ #define  PERIPHERAL_CLOCK (25000000UL)
+
+/*----------------------------------------------------------------------------
+  Externals
+ *----------------------------------------------------------------------------*/
+#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
+    extern uint32_t __VECTOR_TABLE;
+#endif
+
+/*----------------------------------------------------------------------------
+  System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = SYSTEM_CLOCK;
+uint32_t PeripheralClock = PERIPHERAL_CLOCK;
+
+/*----------------------------------------------------------------------------
+  System Core Clock update function
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)
+{
+    SystemCoreClock = SYSTEM_CLOCK;
+    PeripheralClock = PERIPHERAL_CLOCK;
+}
+
+/*----------------------------------------------------------------------------
+  System initialization function
+ *----------------------------------------------------------------------------*/
+void SystemInit (void)
+{
+
+#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
+    SCB->VTOR = (uint32_t)(&__VECTOR_TABLE);
+#endif
+
+#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \
+    (defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE >= 0U))
+    SCB->CPACR |= ((3U << 10U*2U) |           /* enable CP10 Full Access */
+                   (3U << 11U*2U)  );         /* enable CP11 Full Access */
+#endif
+
+#ifdef UNALIGNED_SUPPORT_DISABLE
+    SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
+#endif
+
+    /* Enable Loop and branch info cache */
+    SCB->CCR |= SCB_CCR_LOB_Msk;
+    __ISB();
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/mmio_defs.h b/platform/ext/target/arm/mps3/corstone_polaris/mmio_defs.h
new file mode 100644
index 0000000..30428b3
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/mmio_defs.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __MMIO_DEFS_H__
+#define __MMIO_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "tfm_peripherals_def.h"
+
+/* Boundary handle binding macros. */
+#define HANDLE_PER_ATTR_BITS            (0x4)
+#define HANDLE_ATTR_PRIV_MASK           ((1 << HANDLE_PER_ATTR_BITS) - 1)
+
+/* Allowed named MMIO of this platform */
+const uintptr_t partition_named_mmio_list[] = {
+    (uintptr_t)TFM_PERIPHERAL_TIMER0,
+    (uintptr_t)TFM_PERIPHERAL_STD_UART,
+};
+
+/*
+ * Platform Corstone-Polaris only has named MMIO.
+ * If the platform has numbered MMIO, define them in another list.
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MMIO_DEFS_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpc_sie_drv.c b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpc_sie_drv.c
new file mode 100644
index 0000000..23dbf50
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpc_sie_drv.c
@@ -0,0 +1,791 @@
+/*
+ * Copyright (c) 2016-2020 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mpc_sie_drv.h"
+
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "cmsis_compiler.h"
+
+/* Values for hardware version in PIDR0 reg */
+#define SIE200      0x60
+#define SIE300      0x65
+
+#define MPC_SIE_BLK_CFG_OFFSET  5U
+
+/* Defines with numbering (eg: SIE300) are only relevant to the given SIE
+ * version. Defines without the numbering are applicable to all SIE versions.
+ */
+
+/* CTRL register bit indexes */
+#define MPC_SIE200_CTRL_SEC_RESP      (1UL << 4UL)  /* MPC fault triggers a
+                                                     * bus error
+                                                     */
+#define MPC_SIE300_CTRL_GATE_REQ      (1UL << 6UL)  /* Request for gating
+                                                     * incoming transfers
+                                                     */
+#define MPC_SIE300_CTRL_GATE_ACK      (1UL << 7UL)  /* Acknowledge for gating
+                                                     * incoming transfers
+                                                     */
+#define MPC_SIE_CTRL_AUTOINCREMENT    (1UL << 8UL)  /* BLK_IDX auto increment */
+#define MPC_SIE300_CTRL_SEC_RESP      (1UL << 16UL) /* Response type when SW
+                                                     * asks to gate the transfer
+                                                     */
+#define MPC_SIE300_CTRL_GATE_PRESENT  (1UL << 23UL) /* Gating feature present */
+#define MPC_SIE_CTRL_SEC_LOCK_DOWN    (1UL << 31UL) /* MPC Security lock down */
+
+/* PIDR register bit masks */
+#define MPC_PIDR0_SIE_VERSION_MASK    ((1UL << 8UL) - 1UL)
+
+/* ARM MPC interrupt */
+#define MPC_SIE_INT_BIT               (1UL)
+
+/* Error code returned by the internal driver functions */
+enum mpc_sie_intern_error_t {
+    MPC_SIE_INTERN_ERR_NONE = MPC_SIE_ERR_NONE,
+    MPC_SIE_INTERN_ERR_NOT_IN_RANGE = MPC_SIE_ERR_NOT_IN_RANGE,
+    MPC_SIE_INTERN_ERR_NOT_ALIGNED = MPC_SIE_ERR_NOT_ALIGNED,
+    MPC_SIE_INTERN_ERR_INVALID_RANGE = MPC_SIE_ERR_INVALID_RANGE,
+    MPC_INTERN_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE =
+                                   MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE,
+    /* Calculated block index
+     * is higher than the maximum allowed by the MPC. It should never
+     * happen unless the controlled ranges of the MPC are misconfigured
+     * in the driver or if the IP has not enough LUTs to cover the
+     * range, due to wrong reported block size for example.
+     */
+    MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH = -1,
+
+};
+
+/* ARM MPC memory mapped register access structure */
+struct mpc_sie_reg_map_t {
+    volatile uint32_t ctrl;       /* (R/W) MPC Control */
+    volatile uint32_t reserved[3];/* Reserved */
+    volatile uint32_t blk_max;    /* (R/ ) Maximum value of block based index */
+    volatile uint32_t blk_cfg;    /* (R/ ) Block configuration */
+    volatile uint32_t blk_idx;    /* (R/W) Index value for accessing block
+                                   *       based look up table
+                                   */
+    volatile uint32_t blk_lutn;   /* (R/W) Block based gating
+                                   *       Look Up Table (LUT)
+                                   */
+    volatile uint32_t int_stat;   /* (R/ ) Interrupt state */
+    volatile uint32_t int_clear;  /* ( /W) Interrupt clear */
+    volatile uint32_t int_en;     /* (R/W) Interrupt enable */
+    volatile uint32_t int_info1;  /* (R/ ) Interrupt information 1 */
+    volatile uint32_t int_info2;  /* (R/ ) Interrupt information 2 */
+    volatile uint32_t int_set;    /* ( /W) Interrupt set. Debug purpose only */
+    volatile uint32_t reserved2[998]; /* Reserved */
+    volatile uint32_t pidr4;      /* (R/ ) Peripheral ID 4 */
+    volatile uint32_t pidr5;      /* (R/ ) Peripheral ID 5 */
+    volatile uint32_t pidr6;      /* (R/ ) Peripheral ID 6 */
+    volatile uint32_t pidr7;      /* (R/ ) Peripheral ID 7 */
+    volatile uint32_t pidr0;      /* (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;      /* (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;      /* (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;      /* (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;      /* (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;      /* (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;      /* (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;      /* (R/ ) Component ID 3 */
+};
+
+/*
+ * Checks if the address is controlled by the MPC and returns
+ * the range index in which it is contained.
+ *
+ * \param[in]  dev         MPC device to initialize \ref mpc_sie_dev_t
+ * \param[in]  addr        Address to check if it is controlled by MPC.
+ * \param[out] addr_range  Range index in which it is contained.
+ *
+ * \return True if the base is controller by the range list, false otherwise.
+ */
+static uint32_t is_ctrl_by_range_list(
+                            struct mpc_sie_dev_t* dev,
+                            uint32_t addr,
+                            const struct mpc_sie_memory_range_t** addr_range)
+{
+    uint32_t i;
+    const struct mpc_sie_memory_range_t* range;
+
+    for(i = 0; i < dev->data->nbr_of_ranges; i++) {
+        range = dev->data->range_list[i];
+        if(addr >= range->base && addr <= range->limit) {
+            *addr_range = range;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+/*
+ * Gets the masks selecting the bits in the LUT of the MPC corresponding
+ * to the base address (included) up to the limit address (included)
+ *
+ * \param[in]   mpc_dev          The MPC device.
+ * \param[in]   base             Address in a range controlled by this MPC
+ *                               (included), aligned on block size.
+ * \param[in]   limit            Address in a range controlled by this MPC
+ *                               (included), aligned on block size.
+ * \param[out]  range            Memory range in which the base address and
+ *                               limit are.
+ * \param[out]  first_word_idx   Index of the first touched word in the LUT.
+ * \param[out]  nr_words         Number of words used in the LUT. If 1, only
+ *                               first_word_mask is valid and limit_word_mask
+ *                               must not be used.
+ * \param[out]  first_word_mask  First word mask in the LUT will be stored here.
+ * \param[out]  limit_word_mask  Limit word mask in the LUT will be stored here.
+ *
+ * \return Returns error code as specified in \ref mpc_sie_intern_error_t
+ */
+static enum mpc_sie_intern_error_t get_lut_masks(
+                                 struct mpc_sie_dev_t* dev,
+                                 const uint32_t base, const uint32_t limit,
+                                 const struct mpc_sie_memory_range_t** range,
+                                 uint32_t *first_word_idx,
+                                 uint32_t *nr_words,
+                                 uint32_t *first_word_mask,
+                                 uint32_t *limit_word_mask)
+{
+    const struct mpc_sie_memory_range_t* base_range;
+    uint32_t block_size;
+    uint32_t base_block_idx;
+    uint32_t base_word_idx;
+    uint32_t blk_max;
+    const struct mpc_sie_memory_range_t* limit_range;
+    uint32_t limit_block_idx;
+    uint32_t limit_word_idx;
+    uint32_t mask;
+    uint32_t norm_base;
+    uint32_t norm_limit;
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    /*
+     * Check that the addresses are within the controlled regions
+     * of this MPC
+     */
+    if(!is_ctrl_by_range_list(dev, base, &base_range) ||
+       !is_ctrl_by_range_list(dev, limit, &limit_range)) {
+        return MPC_SIE_INTERN_ERR_NOT_IN_RANGE;
+    }
+
+    /* Base and limit should be part of the same range */
+    if(base_range != limit_range) {
+        return MPC_SIE_INTERN_ERR_INVALID_RANGE;
+    }
+    *range = base_range;
+
+    block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET));
+
+    /* Base and limit+1 addresses must be aligned on the MPC block size */
+    if(base % block_size || (limit+1) % block_size) {
+        return MPC_SIE_INTERN_ERR_NOT_ALIGNED;
+    }
+
+    /*
+     * Get a normalized address that is an offset from the beginning
+     * of the lowest range controlled by the MPC
+     */
+    norm_base  = (base - base_range->base) + base_range->range_offset;
+    norm_limit = (limit - base_range->base) + base_range->range_offset;
+
+    /*
+     * Calculate block index and to which 32 bits word it belongs
+     */
+    limit_block_idx = norm_limit/block_size;
+    limit_word_idx = limit_block_idx/32;
+
+    base_block_idx = norm_base/block_size;
+    base_word_idx = base_block_idx/32;
+
+    if(base_block_idx > limit_block_idx) {
+        return MPC_SIE_INTERN_ERR_INVALID_RANGE;
+    }
+
+    /* Transmit the information to the caller */
+    *nr_words = limit_word_idx - base_word_idx + 1;
+    *first_word_idx = base_word_idx;
+
+    /* Limit to the highest block that can be configured */
+    blk_max = p_mpc->blk_max;
+
+    if((limit_word_idx > blk_max) || (base_word_idx > blk_max)) {
+        return MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH;
+    }
+
+    /*
+     * Create the mask for the first word to only select the limit N bits
+     */
+    *first_word_mask = ~((1 << (base_block_idx % 32)) - 1);
+
+    /*
+     * Create the mask for the limit word to select only the first M bits.
+     */
+    *limit_word_mask = (1 << ((limit_block_idx+1) % 32)) - 1;
+    /*
+     * If limit_word_mask is 0, it means that the limit touched block index is
+     * the limit in its word, so the limit word mask has all its bits selected
+     */
+    if(*limit_word_mask == 0) {
+        *limit_word_mask = 0xFFFFFFFF;
+    }
+
+    /*
+     * If the blocks to configure are all packed in one word, only
+     * touch this word.
+     * Code using the computed masks should test if this mask
+     * is non-zero, and if so, only use this one instead of the limit_word_mask
+     * and first_word_mask.
+     * As the only bits that are the same in both masks are the 1 that we want
+     * to select, just use XOR to extract them.
+     */
+    if(base_word_idx == limit_word_idx) {
+        mask = ~(*first_word_mask ^ *limit_word_mask);
+        *first_word_mask = mask;
+        *limit_word_mask = mask;
+    }
+
+    return MPC_SIE_INTERN_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_init(struct mpc_sie_dev_t* dev,
+                            const struct mpc_sie_memory_range_t** range_list,
+                            uint8_t nbr_of_ranges)
+{
+    if((range_list == NULL) || (nbr_of_ranges == 0)) {
+        return MPC_SIE_INVALID_ARG;
+    }
+
+    dev->data->sie_version = get_sie_version(dev);
+
+    if ((dev->data->sie_version != SIE200) &&
+        (dev->data->sie_version != SIE300)) {
+        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
+    }
+
+    dev->data->range_list = range_list;
+    dev->data->nbr_of_ranges = nbr_of_ranges;
+    dev->data->is_initialized = true;
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t* dev,
+                                            uint32_t* blk_size)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    if(blk_size == 0) {
+        return MPC_SIE_INVALID_ARG;
+    }
+
+    /* Calculate the block size in byte according to the manual */
+    *blk_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET));
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t* dev,
+                                           const uint32_t base,
+                                           const uint32_t limit,
+                                           enum mpc_sie_sec_attr_t attr)
+{
+    enum mpc_sie_intern_error_t error;
+    uint32_t first_word_idx;
+    uint32_t first_word_mask;
+    uint32_t i;
+    uint32_t limit_word_mask;
+    uint32_t limit_word_idx;
+    uint32_t nr_words;
+    const struct mpc_sie_memory_range_t* range;
+    uint32_t word_value;
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    /* Get the bitmasks used to select the bits in the LUT */
+    error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words,
+                          &first_word_mask, &limit_word_mask);
+
+    limit_word_idx = first_word_idx + nr_words - 1;
+
+    if(error != MPC_SIE_INTERN_ERR_NONE) {
+        /* Map internal error code lower than 0 to a generic errpr */
+        if(error < 0) {
+            return MPC_SIE_ERR_INVALID_RANGE;
+        }
+        return (enum mpc_sie_error_t)error;
+    }
+
+    /*
+     * The memory range should allow accesses in with the wanted security
+     * attribute if it requires special attribute for successful accesses
+     */
+    if(range->attr != attr) {
+        return MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE;
+    }
+
+    /*
+     * Starts changing actual configuration so issue DMB to ensure every
+     * transaction has completed by now
+     */
+    __DMB();
+
+    /* Set the block index to the first word that will be updated */
+    p_mpc->blk_idx = first_word_idx;
+
+    /* If only one word needs to be touched in the LUT */
+    if(nr_words == 1) {
+        word_value = p_mpc->blk_lutn;
+        if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
+            word_value |= first_word_mask;
+        } else {
+            word_value &= ~first_word_mask;
+        }
+
+        /*
+         * Set the index again because full word read or write could have
+         * incremented it
+         */
+        p_mpc->blk_idx = first_word_idx;
+        p_mpc->blk_lutn = word_value;
+
+        /* Commit the configuration change */
+        __DSB();
+        __ISB();
+
+        return MPC_SIE_ERR_NONE;
+    }
+
+    /* First word */
+    word_value = p_mpc->blk_lutn;
+    if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
+        word_value |= first_word_mask;
+    } else {
+        word_value &= ~first_word_mask;
+    }
+    /*
+     * Set the index again because full word read or write could have
+     * incremented it
+     */
+    p_mpc->blk_idx = first_word_idx;
+    /* Partially configure the first word */
+    p_mpc->blk_lutn = word_value;
+
+    /* Fully configure the intermediate words if there are any */
+    for(i=first_word_idx+1; i<limit_word_idx; i++) {
+        p_mpc->blk_idx = i;
+        if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
+            p_mpc->blk_lutn = 0xFFFFFFFF;
+        } else {
+            p_mpc->blk_lutn = 0x00000000;
+        }
+    }
+
+    /* Partially configure the limit word */
+    p_mpc->blk_idx = limit_word_idx;
+    word_value = p_mpc->blk_lutn;
+    if(attr == MPC_SIE_SEC_ATTR_NONSECURE) {
+        word_value |= limit_word_mask;
+    } else {
+        word_value &= ~limit_word_mask;
+    }
+    p_mpc->blk_idx = limit_word_idx;
+    p_mpc->blk_lutn = word_value;
+
+    /* Commit the configuration change */
+    __DSB();
+    __ISB();
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_get_region_config(
+                                               struct mpc_sie_dev_t* dev,
+                                               uint32_t base, uint32_t limit,
+                                               enum mpc_sie_sec_attr_t* attr)
+{
+    enum mpc_sie_sec_attr_t attr_prev;
+    uint32_t block_size;
+    uint32_t block_size_mask;
+    enum mpc_sie_intern_error_t error;
+    uint32_t first_word_idx;
+    uint32_t first_word_mask;
+    uint32_t i;
+    uint32_t limit_word_idx;
+    uint32_t limit_word_mask;
+    uint32_t nr_words;
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+    const struct mpc_sie_memory_range_t* range;
+    uint32_t word_value;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    if(attr == 0) {
+        return MPC_SIE_INVALID_ARG;
+    }
+
+    /*
+     * Initialize the security attribute to mixed in case of early
+     * termination of this function. A caller that does not check the
+     * returned error will act as if it does not know anything about the
+     * region queried, which is the safest bet
+     */
+    *attr = MPC_SIE_SEC_ATTR_MIXED;
+
+    /*
+     * If the base and limit are not aligned, align them and make sure
+     * that the resulting region fully includes the original region
+     */
+    block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET));
+
+    block_size_mask = block_size - 1;
+    base &= ~(block_size_mask);
+    limit &= ~(block_size_mask);
+    limit += block_size - 1; /* Round to the upper block address,
+                              * and then remove one to get the preceding
+                              * address.
+                              */
+
+    /* Get the bitmasks used to select the bits in the LUT */
+    error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words,
+                          &first_word_mask, &limit_word_mask);
+
+    limit_word_idx = first_word_idx+nr_words - 1;
+
+    if(error != MPC_SIE_INTERN_ERR_NONE) {
+        /* Map internal error code lower than 0 to generic error */
+        if(error < 0) {
+            return MPC_SIE_ERR_INVALID_RANGE;
+        }
+        return (enum mpc_sie_error_t)error;
+    }
+
+    /* Set the block index to the first word that will be updated */
+    p_mpc->blk_idx = first_word_idx;
+
+    /* If only one word needs to be touched in the LUT */
+    if(nr_words == 1) {
+        word_value = p_mpc->blk_lutn;
+        word_value &= first_word_mask;
+        if(word_value == 0) {
+            *attr = MPC_SIE_SEC_ATTR_SECURE;
+        /*
+         * If there are differences between the mask and the word value,
+         * it means that the security attributes of blocks are mixed
+         */
+        } else if(word_value ^ first_word_mask) {
+            *attr = MPC_SIE_SEC_ATTR_MIXED;
+        } else {
+            *attr = MPC_SIE_SEC_ATTR_NONSECURE;
+        }
+        return MPC_SIE_ERR_NONE;
+    }
+
+    /* Get the partial configuration of the first word */
+    word_value = p_mpc->blk_lutn & first_word_mask;
+    if(word_value == 0x00000000) {
+        *attr = MPC_SIE_SEC_ATTR_SECURE;
+    } else if(word_value ^ first_word_mask) {
+        *attr = MPC_SIE_SEC_ATTR_MIXED;
+        /*
+         * Bail out as the security attribute will be the same regardless
+         * of the configuration of other blocks
+         */
+        return MPC_SIE_ERR_NONE;
+    } else {
+        *attr = MPC_SIE_SEC_ATTR_NONSECURE;
+    }
+    /*
+     * Store the current found attribute, to check that all the blocks indeed
+     * have the same security attribute.
+     */
+    attr_prev = *attr;
+
+    /* Get the configuration of the intermediate words if there are any */
+    for(i=first_word_idx+1; i<limit_word_idx; i++) {
+        p_mpc->blk_idx = i;
+        word_value = p_mpc->blk_lutn;
+        if(word_value == 0x00000000) {
+            *attr = MPC_SIE_SEC_ATTR_SECURE;
+        } else if(word_value == 0xFFFFFFFF) {
+            *attr = MPC_SIE_SEC_ATTR_NONSECURE;
+        } else {
+            *attr = MPC_SIE_SEC_ATTR_MIXED;
+            return MPC_SIE_ERR_NONE;
+        }
+
+        /* If the attribute is different than the one found before, bail out */
+        if(*attr != attr_prev) {
+            *attr = MPC_SIE_SEC_ATTR_MIXED;
+            return MPC_SIE_ERR_NONE;
+        }
+        attr_prev = *attr;
+    }
+
+    /* Get the partial configuration of the limit word */
+    p_mpc->blk_idx = limit_word_idx;
+    word_value = p_mpc->blk_lutn & limit_word_mask;
+    if(word_value == 0x00000000) {
+        *attr = MPC_SIE_SEC_ATTR_SECURE;
+    } else if(word_value ^ first_word_mask) {
+        *attr = MPC_SIE_SEC_ATTR_MIXED;
+        return MPC_SIE_ERR_NONE;
+    } else {
+        *attr = MPC_SIE_SEC_ATTR_NONSECURE;
+    }
+
+    if(*attr != attr_prev) {
+        *attr = MPC_SIE_SEC_ATTR_MIXED;
+        return MPC_SIE_ERR_NONE;
+    }
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t* dev,
+                                      uint32_t* ctrl_val)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    if(ctrl_val == 0) {
+        return MPC_SIE_INVALID_ARG;
+    }
+
+    *ctrl_val = p_mpc->ctrl;
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t* dev,
+                                      uint32_t mpc_ctrl)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    p_mpc->ctrl = mpc_ctrl;
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t* dev,
+                                          enum mpc_sie_sec_resp_t* sec_rep)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+    bool gating_present = false;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    if(sec_rep == NULL) {
+        return MPC_SIE_INVALID_ARG;
+    }
+
+    if (dev->data->sie_version == SIE200) {
+        if(p_mpc->ctrl & MPC_SIE200_CTRL_SEC_RESP) {
+            *sec_rep = MPC_SIE_RESP_BUS_ERROR;
+        } else {
+            *sec_rep = MPC_SIE_RESP_RAZ_WI;
+        }
+
+    } else if (dev->data->sie_version == SIE300) {
+        mpc_sie_is_gating_present(dev, &gating_present);
+        if (!gating_present) {
+            return MPC_SIE_ERR_GATING_NOT_PRESENT;
+        }
+
+        if(p_mpc->ctrl & MPC_SIE300_CTRL_SEC_RESP) {
+            /* MPC returns a BUS ERROR response */
+            *sec_rep = MPC_SIE_RESP_BUS_ERROR;
+        } else {
+            /* MPC sets the ready signals LOW, which stalls any transactions */
+            *sec_rep = MPC_SIE_RESP_WAIT_GATING_DISABLED;
+        }
+    } else {
+        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
+    }
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t  mpc_sie_set_sec_resp(struct mpc_sie_dev_t* dev,
+                                           enum mpc_sie_sec_resp_t sec_rep)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+    bool gating_present = false;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    if (dev->data->sie_version == SIE200) {
+        if (sec_rep == MPC_SIE_RESP_BUS_ERROR) {
+            p_mpc->ctrl |= MPC_SIE200_CTRL_SEC_RESP;
+        } else if (sec_rep == MPC_SIE_RESP_RAZ_WI) {
+            p_mpc->ctrl &= ~MPC_SIE200_CTRL_SEC_RESP;
+        } else {
+            return MPC_SIE_INVALID_ARG;
+        }
+
+    } else if (dev->data->sie_version == SIE300) {
+        mpc_sie_is_gating_present(dev, &gating_present);
+        if (!gating_present) {
+            return MPC_SIE_ERR_GATING_NOT_PRESENT;
+        }
+
+        if (sec_rep == MPC_SIE_RESP_BUS_ERROR) {
+            p_mpc->ctrl |= MPC_SIE300_CTRL_SEC_RESP;
+        } else if (sec_rep == MPC_SIE_RESP_WAIT_GATING_DISABLED) {
+            p_mpc->ctrl &= ~MPC_SIE300_CTRL_SEC_RESP;
+        } else {
+            return MPC_SIE_INVALID_ARG;
+        }
+
+    } else {
+        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
+    }
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    p_mpc->int_en |= MPC_SIE_INT_BIT;
+
+    return MPC_SIE_ERR_NONE;
+}
+
+void mpc_sie_irq_disable(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    p_mpc->int_en &= ~MPC_SIE_INT_BIT;
+}
+
+void mpc_sie_clear_irq(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    p_mpc->int_clear = MPC_SIE_INT_BIT;
+}
+
+uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    return (p_mpc->int_stat & MPC_SIE_INT_BIT);
+}
+
+enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    p_mpc->ctrl |= (MPC_SIE_CTRL_AUTOINCREMENT
+                    | MPC_SIE_CTRL_SEC_LOCK_DOWN);
+
+    return MPC_SIE_ERR_NONE;
+}
+
+enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t* dev,
+                                               bool* gating_present)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->is_initialized != true) {
+        return MPC_SIE_NOT_INIT;
+    }
+
+    if (dev->data->sie_version != SIE300) {
+        return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION;
+    }
+
+    *gating_present = (bool)(p_mpc->ctrl & MPC_SIE300_CTRL_GATE_PRESENT);
+
+    return MPC_SIE_ERR_NONE;
+}
+
+uint32_t get_sie_version(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    return p_mpc->pidr0 & MPC_PIDR0_SIE_VERSION_MASK;
+}
+
+bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    return (bool)(p_mpc->ctrl & MPC_SIE300_CTRL_GATE_ACK);
+}
+
+void mpc_sie_request_gating(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    p_mpc->ctrl |= MPC_SIE300_CTRL_GATE_REQ;
+}
+
+void mpc_sie_release_gating(struct mpc_sie_dev_t* dev)
+{
+    struct mpc_sie_reg_map_t* p_mpc =
+                                   (struct mpc_sie_reg_map_t*)dev->cfg->base;
+
+    p_mpc->ctrl &= ~MPC_SIE300_CTRL_GATE_REQ;
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpc_sie_drv.h b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpc_sie_drv.h
new file mode 100644
index 0000000..9e582fa
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpc_sie_drv.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2016-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file mpc_sie_drv.h
+ * \brief Generic driver for ARM SIE Memory Protection
+ *        Controllers (MPC).
+ */
+
+#ifndef __MPC_SIE_DRV_H__
+#define __MPC_SIE_DRV_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Error code returned by the driver functions */
+enum mpc_sie_error_t {
+    MPC_SIE_ERR_NONE,          /*!< No error */
+    MPC_SIE_INVALID_ARG,       /*!< MPC invalid input arguments */
+    MPC_SIE_NOT_INIT,          /*!< MPC not initialized */
+    MPC_SIE_ERR_NOT_IN_RANGE,  /*!< Address does not belong to a range
+                                   *   controlled by the MPC */
+    MPC_SIE_ERR_NOT_ALIGNED,   /*!< Address is not aligned on the block size
+                                   *   of this MPC
+                                   */
+    MPC_SIE_ERR_INVALID_RANGE, /*!< The given address range to configure
+                                   *   is invalid. This could be because:
+                                   *   - The base and limit swapped
+                                   *   - The base and limit addresses
+                                   *     are in different ranges
+                                   */
+    MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, /*!< The given range cannot be
+                                                   *   accessed with the wanted
+                                                   *   security attributes
+                                                   */
+    MPC_SIE_UNSUPPORTED_HARDWARE_VERSION, /*!< MPC hardware version read from
+                                              *   PIDR0 is not supported
+                                              */
+    MPC_SIE_ERR_GATING_NOT_PRESENT        /*!< MPC gating not present in HW */
+};
+
+/* Security attribute used in various place of the API */
+enum mpc_sie_sec_attr_t {
+    MPC_SIE_SEC_ATTR_SECURE,     /*!< Secure attribute */
+    MPC_SIE_SEC_ATTR_NONSECURE,  /*!< Non-secure attribute */
+    /*!< Used when getting the configuration of a memory range and some blocks
+     *   are secure whereas some other are non secure
+     */
+    MPC_SIE_SEC_ATTR_MIXED,
+};
+
+/* What can happen when trying to do an illegal memory access */
+enum mpc_sie_sec_resp_t {
+    MPC_SIE_RESP_RAZ_WI,    /*!< Read As Zero, Write Ignored */
+    MPC_SIE_RESP_BUS_ERROR, /*!< Bus error */
+    MPC_SIE_RESP_WAIT_GATING_DISABLED  /*!< Wait until gating is disabled */
+};
+
+/* Description of a memory range controlled by the MPC */
+struct mpc_sie_memory_range_t {
+    const uint32_t base;   /*!< Base address (included in the range) */
+    const uint32_t limit;  /*!< Limit address (included in the range) */
+    const uint32_t range_offset; /*!< Offset of current range area to the 0
+                                  *   point of the whole area (the sum of the
+                                  *   sizes of the previous memory ranges
+                                  *   covered by the same MPC)
+                                  */
+    const enum mpc_sie_sec_attr_t attr; /*!< Optional security attribute
+                                            *   needed to be matched when
+                                            *   accessing this range.
+                                            *   For example, the non-secure
+                                            *   alias of a memory region can not
+                                            *   be accessed using secure access,
+                                            *   and configuring the MPC to
+                                            *   secure using that range will not
+                                            *   be permitted by the driver.
+                                            */
+};
+
+/* ARM MPC SIE device configuration structure */
+struct mpc_sie_dev_cfg_t {
+    const uint32_t base;  /*!< MPC base address */
+};
+
+/* ARM MPC SIE device data structure */
+struct mpc_sie_dev_data_t {
+    /*!< Array of pointers to memory ranges controlled by the MPC */
+    const struct mpc_sie_memory_range_t** range_list;
+    uint8_t nbr_of_ranges;  /*!< Number of memory ranges in the list */
+    bool is_initialized;    /*!< Indicates if the MPC driver
+                             *   is initialized and enabled
+                             */
+    uint32_t sie_version;   /*!< SIE version */
+};
+
+/* ARM MPC SIE device structure */
+struct mpc_sie_dev_t {
+    const struct mpc_sie_dev_cfg_t* const cfg;  /*!< MPC configuration */
+    struct mpc_sie_dev_data_t* const data;      /*!< MPC data */
+};
+
+/**
+ * \brief Initializes a MPC device.
+ *
+ * \param[in] dev            MPC device \ref mpc_sie_dev_t
+ * \param[in] range_list     List of memory ranges controller by the MPC
+ *                           (\ref mpc_sie_memory_range_t). This list can not
+ *                           freed after the initializations.
+ * \param[in] nbr_of_ranges  Number of memory ranges
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_init(struct mpc_sie_dev_t* dev,
+                                  const struct mpc_sie_memory_range_t** range_list,
+                                  uint8_t nbr_of_ranges);
+
+/**
+ * \brief Gets MPC block size. All regions must be aligned on this block
+ *        size (base address and limit+1 address).
+ *
+ * \param[in]  dev       MPC device \ref mpc_sie_dev_t
+ * \param[out] blk_size  MPC block size
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t* dev,
+                                            uint32_t* blk_size);
+
+/**
+ * \brief Configures a memory region (base and limit included).
+ *
+ * \param[in] dev    MPC device \ref mpc_sie_dev_t
+ * \param[in] base   Base address of the region to poll. This bound is
+ *                   included. It does not need to be aligned in any way.
+ *
+ * \param[in] limit  Limit address of the region to poll. This bound is
+ *                   included. (limit+1) does not need to be aligned
+ *                   in any way.
+ * \param[in] attr   Security attribute of the region. If the region has mixed
+ *                   secure/non-secure, a special value is returned
+ *                   (\ref mpc_sie_sec_attr_t).
+ *
+ *            In case base and limit+1 addresses are not aligned on
+ *            the block size, the enclosing region with base and
+ *            limit+1 aligned on block size will be queried.
+ *            In case of early termination of the function (error), the
+ *            security attribute will be set to MPC_SIE_ATTR_MIXED.
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t* dev,
+                                           const uint32_t base,
+                                           const uint32_t limit,
+                                           enum mpc_sie_sec_attr_t attr);
+
+/**
+ * \brief Gets a memory region configuration(base and limit included).
+ *
+ * \param[in]  dev    MPC device \ref mpc_sie_dev_t
+ * \param[in]  base   Base address of the region to get the configuration.
+ * \param[in]  limit  Limit address of the region to get the configuration.
+ * \param[out] attr   Security attribute of the region
+ *                    \ref mpc_sie_sec_attr_t
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_get_region_config(struct mpc_sie_dev_t* dev,
+                                               uint32_t base,
+                                               uint32_t limit,
+                                               enum mpc_sie_sec_attr_t* attr);
+
+/**
+ * \brief Gets the MPC control value.
+ *
+ * \param[in]  dev       MPC device \ref mpc_sie_dev_t
+ * \param[out] ctrl_val  Current MPC control value.
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t* dev,
+                                      uint32_t* ctrl_val);
+
+/**
+ * \brief Sets the MPC control value.
+ *
+ * \param[in] dev       MPC device \ref mpc_sie_dev_t
+ * \param[in] mpc_ctrl  New MPC control value
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t* dev,
+                                      uint32_t mpc_ctrl);
+
+/**
+ * \brief Gets the configured secure response.
+ *
+ * \param[in]  dev      MPC device \ref mpc_sie_dev_t
+ * \param[out] sec_rep  Configured secure response (\ref mpc_sie_sec_resp_t).
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t* dev,
+                                          enum mpc_sie_sec_resp_t* sec_rep);
+
+/**
+ * \brief Sets the response type when SW asks to gate the incoming transfers.
+ *
+ * \param[in] dev     MPC device \ref mpc_sie_dev_t
+ * \param[in] sec_rep Secure response to configure (\ref mpc_sie_sec_resp_t).
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_set_sec_resp(struct mpc_sie_dev_t* dev,
+                                          enum mpc_sie_sec_resp_t sec_rep);
+
+/**
+ * \brief Enables MPC interrupt.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Disables MPC interrupt
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_irq_disable(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Clears MPC interrupt.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_clear_irq(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Returns the MPC interrupt state.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns 1 if the interrupt is active, 0 otherwise.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Locks down the MPC configuration.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Returns if gating is present in hardware.
+ *
+ * \param[in]  dev             MPC device \ref mpc_sie_dev_t
+ * \param[out] gating_present  Returns if gating is present in hardware.
+ *
+ * \return Returns error code as specified in \ref mpc_sie_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t* dev,
+                                               bool* gating_present);
+
+/**
+ * \brief Returns the value of Peripheral ID 0 register.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \return Returns the value of Peripheral ID 0 register.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t get_sie_version(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Reads bit indicating acknowledge for gating incoming transfers.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \return True if acknowledge is set.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Sets bit to request for gating incoming transfers.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_request_gating(struct mpc_sie_dev_t* dev);
+
+/**
+ * \brief Clears bit to request for gating incoming transfers.
+ *
+ * \param[in] dev  MPC device \ref mpc_sie_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void mpc_sie_release_gating(struct mpc_sie_dev_t* dev);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MPC_SIE_DRV_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpu_armv8m_drv.c b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpu_armv8m_drv.c
new file mode 100644
index 0000000..0caa024
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpu_armv8m_drv.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "mpu_armv8m_drv.h"
+#include "cmsis.h"
+
+/*
+ * FixMe:
+ * This is a beta quality driver for MPU in v8M. To be finalized.
+ */
+
+enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
+                                          uint32_t privdef_en,
+                                          uint32_t hfnmi_en)
+{
+    /*No error checking*/
+
+    MPU_Type *mpu = (MPU_Type *)dev->base;
+
+    /*
+     * FixMe: Set 3 pre-defined MAIR_ATTR for memory. The attributes come
+     * from default memory map, need to check if fine-tune is necessary.
+     *
+     * MAIR0_0: Peripheral, Device-nGnRE.
+     * MAIR0_1: Code, WT RA. Same attr for Outer and Inner.
+     * MAIR0_2: SRAM, WBWA RA. Same attr for Outer and Inner.
+     */
+    mpu->MAIR0 = (MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL << MPU_MAIR0_Attr0_Pos) |
+                 (MPU_ARMV8M_MAIR_ATTR_CODE_VAL << MPU_MAIR0_Attr1_Pos) |
+                 (MPU_ARMV8M_MAIR_ATTR_DATA_VAL << MPU_MAIR0_Attr2_Pos);
+
+    mpu->CTRL =
+            (privdef_en ? MPU_CTRL_PRIVDEFENA_Msk : 0) |
+            (hfnmi_en   ? MPU_CTRL_HFNMIENA_Msk   : 0);
+
+    /*Ensure all configuration is written before enable*/
+
+    mpu->CTRL |= MPU_CTRL_ENABLE_Msk;
+
+    /* Enable MPU before next instruction */
+    __DSB();
+    __ISB();
+    return MPU_ARMV8M_OK;
+}
+
+enum mpu_armv8m_error_t mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev)
+{
+    MPU_Type *mpu = (MPU_Type *)dev->base;
+
+    /* Reset all fields as enable does full setup */
+    mpu->CTRL = 0;
+
+    return MPU_ARMV8M_OK;
+}
+
+
+enum mpu_armv8m_error_t mpu_armv8m_region_enable(
+                                struct mpu_armv8m_dev_t *dev,
+                                struct mpu_armv8m_region_cfg_t *region_cfg)
+{
+    MPU_Type *mpu = (MPU_Type *)dev->base;
+
+    enum mpu_armv8m_error_t ret_val = MPU_ARMV8M_OK;
+    uint32_t ctrl_before;
+    uint32_t base_cfg;
+    uint32_t limit_cfg;
+
+    /*FIXME : Add complete error checking*/
+    if ((region_cfg->region_base & ~MPU_RBAR_BASE_Msk) != 0) {
+        return MPU_ARMV8M_ERROR;
+    }
+    /* region_limit doesn't need to be aligned but the scatter
+     * file needs to be setup to ensure that partitions do not overlap.
+     */
+
+    ctrl_before = mpu->CTRL;
+    mpu->CTRL = 0;
+
+    mpu->RNR  = region_cfg->region_nr & MPU_RNR_REGION_Msk;
+
+    /* This 0s the lower bits of the base address */
+    base_cfg = region_cfg->region_base & MPU_RBAR_BASE_Msk;
+    base_cfg |= (region_cfg->attr_sh << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk;
+    base_cfg |= (region_cfg->attr_access << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk;
+    base_cfg |= (region_cfg->attr_exec << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk;
+
+    mpu->RBAR = base_cfg;
+
+    /*This 0s the lower bits of base address but they are treated as 1 */
+    limit_cfg = (region_cfg->region_limit-1) & MPU_RLAR_LIMIT_Msk;
+
+    limit_cfg |= (region_cfg->region_attridx << MPU_RLAR_AttrIndx_Pos) &
+                 MPU_RLAR_AttrIndx_Msk;
+
+#ifdef TFM_PXN_ENABLE
+    limit_cfg |= (region_cfg->attr_pxn << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk;
+#endif
+
+    limit_cfg |= MPU_RLAR_EN_Msk;
+
+    mpu->RLAR = limit_cfg;
+
+    /*Restore main MPU control*/
+    mpu->CTRL = ctrl_before;
+
+    /* Enable MPU before the next instruction */
+    __DSB();
+    __ISB();
+
+    return ret_val;
+}
+
+
+enum mpu_armv8m_error_t mpu_armv8m_region_disable(
+                                struct mpu_armv8m_dev_t *dev,
+                                uint32_t region_nr)
+{
+
+    MPU_Type *mpu = (MPU_Type *)dev->base;
+
+    enum mpu_armv8m_error_t ret_val = MPU_ARMV8M_OK;
+    uint32_t ctrl_before;
+
+    /*FIXME : Add complete error checking*/
+
+    ctrl_before = mpu->CTRL;
+    mpu->CTRL = 0;
+
+    mpu->RNR  = region_nr & MPU_RNR_REGION_Msk;
+
+    mpu->RBAR = 0;
+    mpu->RLAR = 0;
+
+    /*Restore main MPU control*/
+    mpu->CTRL = ctrl_before;
+
+    return ret_val;
+}
+
+enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev)
+{
+    MPU_Type *mpu = (MPU_Type *)dev->base;
+    uint32_t i = (mpu->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
+
+    while (i > 0) {
+        mpu_armv8m_region_disable(dev, i-1);
+        i--;
+    }
+
+    return MPU_ARMV8M_OK;
+
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpu_armv8m_drv.h b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpu_armv8m_drv.h
new file mode 100644
index 0000000..6bfb0b2
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/mpu_armv8m_drv.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __MPU_ARMV8M_DRV_H__
+#define __MPU_ARMV8M_DRV_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PRIVILEGED_DEFAULT_ENABLE 1
+#define HARDFAULT_NMI_ENABLE      1
+
+/* MAIR_ATTR */
+#define MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL      0x04
+#define MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX      0
+#define MPU_ARMV8M_MAIR_ATTR_CODE_VAL        0xAA
+#define MPU_ARMV8M_MAIR_ATTR_CODE_IDX        1
+#define MPU_ARMV8M_MAIR_ATTR_DATA_VAL        0xFF
+#define MPU_ARMV8M_MAIR_ATTR_DATA_IDX        2
+
+struct mpu_armv8m_dev_t {
+    const uint32_t base;
+};
+
+enum mpu_armv8m_error_t {
+    MPU_ARMV8M_OK,
+    MPU_ARMV8M_ERROR
+};
+
+enum mpu_armv8m_attr_exec_t {
+    MPU_ARMV8M_XN_EXEC_OK,
+    MPU_ARMV8M_XN_EXEC_NEVER
+};
+
+enum mpu_armv8m_attr_access_t {
+    MPU_ARMV8M_AP_RW_PRIV_ONLY,
+    MPU_ARMV8M_AP_RW_PRIV_UNPRIV,
+    MPU_ARMV8M_AP_RO_PRIV_ONLY,
+    MPU_ARMV8M_AP_RO_PRIV_UNPRIV
+};
+
+enum mpu_armv8m_attr_shared_t {
+    MPU_ARMV8M_SH_NONE,
+    MPU_ARMV8M_SH_UNUSED,
+    MPU_ARMV8M_SH_OUTER,
+    MPU_ARMV8M_SH_INNER
+};
+
+#ifdef TFM_PXN_ENABLE
+enum mpu_armv8m_attr_priv_exec_t {
+    MPU_ARMV8M_PRIV_EXEC_OK,
+    MPU_ARMV8M_PRIV_EXEC_NEVER
+};
+#endif
+
+struct mpu_armv8m_region_cfg_t {
+    uint32_t region_nr;
+    uint32_t region_base;
+    uint32_t region_limit;
+    uint32_t region_attridx;
+    enum mpu_armv8m_attr_exec_t      attr_exec;
+    enum mpu_armv8m_attr_access_t    attr_access;
+    enum mpu_armv8m_attr_shared_t    attr_sh;
+#ifdef TFM_PXN_ENABLE
+    enum mpu_armv8m_attr_priv_exec_t attr_pxn;
+#endif
+};
+
+struct mpu_armv8m_region_cfg_raw_t {
+    uint32_t region_nr;
+    uint32_t region_base;
+    uint32_t region_limit;
+};
+
+
+/**
+ * \brief Enable MPU
+ *
+ * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
+ * \param[in] privdef_en     privilege default region 1:enable 0:disable
+ * \param[in] hfnmi_en       mpu for hard fault & nmi  1:enable 0:disable
+ *
+ * \return Error code \ref mpu_armv8m_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+
+enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
+                                          uint32_t privdef_en,
+                                          uint32_t hfnmi_en);
+
+/**
+ * \brief Disable MPU
+ *
+ * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
+ *
+ * \return Error code \ref mpu_armv8m_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpu_armv8m_error_t mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev);
+
+/**
+ * \brief Disable MPU and clean all regions
+ *
+ * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
+ *
+ * \return Error code \ref mpu_armv8m_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev);
+
+/**
+ * \brief Enable MPU Region
+ *
+ * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
+ * \param[in] region_cfg     MPU region config \ref mpu_armv8m_region_cfg_t
+ *
+ * \return Error code \ref mpu_armv8m_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpu_armv8m_error_t mpu_armv8m_region_enable(
+                                struct mpu_armv8m_dev_t *dev,
+                                struct mpu_armv8m_region_cfg_t *region_cfg);
+
+/**
+ * \brief Disable MPU Region
+ *
+ * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
+ * \param[in] region_nr            Region number
+ *
+ * \return Error code \ref mpu_armv8m_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum mpu_armv8m_error_t mpu_armv8m_region_disable(
+                                struct mpu_armv8m_dev_t *dev,
+                                uint32_t region_nr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MPU_ARMV8M_DRV_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/ppc_polaris_drv.c b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/ppc_polaris_drv.c
new file mode 100644
index 0000000..5dd54d3
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/ppc_polaris_drv.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ppc_polaris_drv.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+/* Default peripheral states */
+#define SECURE_AS_DEFAULT_PERIPHERAL_STATE  true
+#define PRIVILEGE_ONLY_AS_DEFAULT_PERIPHERAL_STATE  true
+
+/* Secure Access Configuration Register Block */
+struct polaris_sacfg_block_t {
+    volatile uint32_t reserved0[8];
+    volatile uint32_t secppcintstat;  /* 0x020 (R/ ) Secure PPC IRQ Status */
+    volatile uint32_t secppcintclr;   /* 0x024 (R/W) Secure PPC IRQ Clear */
+    volatile uint32_t secppcinten;    /* 0x028 (R/W) Secure PPC IRQ Enable */
+    volatile uint32_t reserved1[9];
+    volatile uint32_t mainnsppc0;     /* 0x050 (R/W) Non-secure Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on the Main
+                                       *             Interconnect */
+    volatile uint32_t reserved2[3];
+    volatile uint32_t mainnsppcexp0;  /* 0x060 (R/W) Expansion 0 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t mainnsppcexp1;  /* 0x064 (R/W) Expansion 1 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t mainnsppcexp2;  /* 0x068 (R/W) Expansion 2 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t mainnsppcexp3;  /* 0x06C (R/W) Expansion 3 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on the
+                                       *             Main Interconnect */
+    volatile uint32_t periphnsppc0;   /* 0x070 (R/W) Non-secure Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on the Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphnsppc1;   /* 0x074 (R/W) Non-secure Access
+                                       *             Peripheral Protection
+                                       *             Control 1 on the Peripheral
+                                       *             Interconnect */
+    volatile uint32_t reserved3[2];
+    volatile uint32_t periphnsppcexp0;/* 0x080 (R/W) Expansion 0 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t periphnsppcexp1;/* 0x084 (R/W) Expansion 1 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t periphnsppcexp2;/* 0x088 (R/W) Expansion 2 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t periphnsppcexp3;/* 0x08C (R/W) Expansion 3 Non-secure
+                                       *             Access Peripheral
+                                       *             Protection Control on
+                                       *             Peripheral Bus */
+    volatile uint32_t mainspppc0;     /* 0x090 (R/W) Secure Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on Main
+                                       *             Interconnect */
+    volatile uint32_t reserved4[3];
+    volatile uint32_t mainspppcexp0;  /* 0x0A0 (R/W) Expansion 0 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t mainspppcexp1;  /* 0x0A4 (R/W) Expansion 1 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t mainspppcexp2;  /* 0x0A8 (R/W) Expansion 2 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t mainspppcexp3;  /* 0x0AC (R/W) Expansion 3 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Main
+                                       *             Interconnect */
+    volatile uint32_t periphspppc0;   /* 0x0B0 (R/W) Secure Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control 0 on
+                                       *             Peripheral Interconnect */
+    volatile uint32_t periphspppc1;   /* 0x0B4 (R/W) Secure Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control 1 on
+                                       *             Peripheral Interconnect */
+    volatile uint32_t reserved5[2];
+    volatile uint32_t periphspppcexp0;/* 0x0C0 (R/W) Expansion 0 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphspppcexp1;/* 0x0C4 (R/W) Expansion 1 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphspppcexp2;/* 0x0C8 (R/W) Expansion 2 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t periphspppcexp3;/* 0x0CC (R/W) Expansion 3 Secure
+                                       *             Unprivileged Access
+                                       *             Peripheral Protection
+                                       *             Control on Peripheral
+                                       *             Interconnect */
+    volatile uint32_t reserved6[960];
+    volatile uint32_t pidr4;          /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved7[3];
+    volatile uint32_t pidr0;          /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;          /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;          /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;          /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;          /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;          /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;          /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;          /* 0xFFC (R/ ) Component ID 3 */
+};
+
+/* PPC interrupt position mask */
+#define PERIPH_PPC0_INT_POS_MASK     (1UL << 0)
+#define PERIPH_PPC1_INT_POS_MASK     (1UL << 1)
+#define PERIPH_PPCEXP0_INT_POS_MASK  (1UL << 4)
+#define PERIPH_PPCEXP1_INT_POS_MASK  (1UL << 5)
+#define PERIPH_PPCEXP2_INT_POS_MASK  (1UL << 6)
+#define PERIPH_PPCEXP3_INT_POS_MASK  (1UL << 7)
+#define MAIN_PPC0_INT_POS_MASK       (1UL << 16)
+#define MAIN_PPCEXP0_INT_POS_MASK    (1UL << 20)
+#define MAIN_PPCEXP1_INT_POS_MASK    (1UL << 21)
+#define MAIN_PPCEXP2_INT_POS_MASK    (1UL << 22)
+#define MAIN_PPCEXP3_INT_POS_MASK    (1UL << 23)
+
+/* Non-secure Access Configuration Register Block */
+struct polaris_nsacfg_block_t {
+    volatile uint32_t reserved0[36];
+    volatile uint32_t mainnspppc0;     /* 0x090 (R/W) Non-secure Unprivileged
+                                        *             Access Peripheral
+                                        *             Protection Control 0 on
+                                        *             Main Interconnect */
+    volatile uint32_t reserved1[3];
+
+    volatile uint32_t mainnspppcexp0;  /* 0x0A0 (R/W) Expansion 0 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t mainnspppcexp1;  /* 0x0A4 (R/W) Expansion 1 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t mainnspppcexp2;  /* 0x0A8 (R/W) Expansion 2 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t mainnspppcexp3;  /* 0x0AC (R/W) Expansion 3 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Main
+                                        *             Interconnect */
+    volatile uint32_t periphnspppc0;   /* 0x0B0 (R/W) Non-secure Unprivileged
+                                        *             Access Peripheral
+                                        *             Protection Control 0 on
+                                        *             Peripheral Interconnect */
+    volatile uint32_t periphnspppc1;   /* 0x0B4 (R/W) Non-secure Unprivileged
+                                        *             Access Peripheral
+                                        *             Protection Control 1 on
+                                        *             Peripheral Interconnect */
+    volatile uint32_t reserved2[2];
+    volatile uint32_t periphnspppcexp0;/* 0x0C0 (R/W) Expansion 0 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t periphnspppcexp1;/* 0x0C4 (R/W) Expansion 1 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t periphnspppcexp2;/* 0x0C8 (R/W) Expansion 2 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t periphnspppcexp3;/* 0x0CC (R/W) Expansion 3 Non-secure
+                                        *             Unprivileged Access
+                                        *             Peripheral Protection
+                                        *             Control on Peripheral
+                                        *             Interconnect */
+    volatile uint32_t reserved3[960];
+    volatile uint32_t pidr4;           /* 0xFD0 (R/ ) Peripheral ID 4 */
+    volatile uint32_t reserved4[3];
+    volatile uint32_t pidr0;           /* 0xFE0 (R/ ) Peripheral ID 0 */
+    volatile uint32_t pidr1;           /* 0xFE4 (R/ ) Peripheral ID 1 */
+    volatile uint32_t pidr2;           /* 0xFE8 (R/ ) Peripheral ID 2 */
+    volatile uint32_t pidr3;           /* 0xFEC (R/ ) Peripheral ID 3 */
+    volatile uint32_t cidr0;           /* 0xFF0 (R/ ) Component ID 0 */
+    volatile uint32_t cidr1;           /* 0xFF4 (R/ ) Component ID 1 */
+    volatile uint32_t cidr2;           /* 0xFF8 (R/ ) Component ID 2 */
+    volatile uint32_t cidr3;           /* 0xFFC (R/ ) Component ID 3 */
+};
+
+enum ppc_polaris_error_t ppc_polaris_init(struct ppc_polaris_dev_t* dev)
+{
+    struct polaris_sacfg_block_t* p_sacfg =
+                         (struct polaris_sacfg_block_t*)dev->cfg->sacfg_base;
+    struct polaris_nsacfg_block_t* p_nsacfg =
+                       (struct polaris_nsacfg_block_t*)dev->cfg->nsacfg_base;
+
+    switch(dev->cfg->ppc_name) {
+        /* Case for MAIN0 */
+        case PPC_POLARIS_MAIN0:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->mainnsppc0;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->mainspppc0;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppc0;
+            dev->data->int_bit_mask    = MAIN_PPC0_INT_POS_MASK;
+            break;
+
+        /* Case for MAIN EXPX */
+        case PPC_POLARIS_MAIN_EXP0:
+            dev->data->sacfg_ns_ppc   = &p_sacfg-> mainnsppcexp0;
+            dev->data->sacfg_sp_ppc   = &p_sacfg-> mainspppcexp0;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp0;
+            dev->data->int_bit_mask    = MAIN_PPCEXP0_INT_POS_MASK;
+            break;
+        case PPC_POLARIS_MAIN_EXP1:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->mainnsppcexp1;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->mainspppcexp1;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp1;
+            dev->data->int_bit_mask    = MAIN_PPCEXP1_INT_POS_MASK;
+            break;
+        case PPC_POLARIS_MAIN_EXP2:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->mainnsppcexp2;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->mainspppcexp2;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp2;
+            dev->data->int_bit_mask    = MAIN_PPCEXP2_INT_POS_MASK;
+            break;
+        case PPC_POLARIS_MAIN_EXP3:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->mainnsppcexp3;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->mainspppcexp3;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp3;
+            dev->data->int_bit_mask    = MAIN_PPCEXP3_INT_POS_MASK;
+            break;
+
+        /* Case for PERIPHX */
+        case PPC_POLARIS_PERIPH0:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->periphnsppc0;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->periphspppc0;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppc0;
+            dev->data->int_bit_mask    = PERIPH_PPC0_INT_POS_MASK;
+            break;
+        case PPC_POLARIS_PERIPH1:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->periphnsppc1;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->periphspppc1;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppc1;
+            dev->data->int_bit_mask    = PERIPH_PPC1_INT_POS_MASK;
+            break;
+
+        /* Case for PERIPH EXPX */
+        case PPC_POLARIS_PERIPH_EXP0:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->periphnsppcexp0;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->periphspppcexp0;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp0;
+            dev->data->int_bit_mask    = PERIPH_PPCEXP0_INT_POS_MASK;
+            break;
+        case PPC_POLARIS_PERIPH_EXP1:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->periphnsppcexp1;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->periphspppcexp1;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp1;
+            dev->data->int_bit_mask    = PERIPH_PPCEXP1_INT_POS_MASK;
+            break;
+        case PPC_POLARIS_PERIPH_EXP2:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->periphnsppcexp2;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->periphspppcexp2;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp2;
+            dev->data->int_bit_mask    = PERIPH_PPCEXP2_INT_POS_MASK;
+            break;
+        case PPC_POLARIS_PERIPH_EXP3:
+            dev->data->sacfg_ns_ppc   = &p_sacfg->periphnsppcexp3;
+            dev->data->sacfg_sp_ppc   = &p_sacfg->periphspppcexp3;
+            dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp3;
+            dev->data->int_bit_mask    = PERIPH_PPCEXP3_INT_POS_MASK;
+            break;
+        default:
+            return PPC_POLARIS_ERR_INVALID_PARAM;
+        }
+
+    dev->data->is_initialized = true;
+
+    return PPC_POLARIS_ERR_NONE;
+}
+
+enum ppc_polaris_error_t
+ppc_polaris_config_privilege(struct ppc_polaris_dev_t* dev, uint32_t mask,
+                            enum ppc_polaris_sec_attr_t sec_attr,
+                            enum ppc_polaris_priv_attr_t priv_attr)
+{
+    if(dev->data->is_initialized != true) {
+        return PPC_POLARIS_ERR_NOT_INIT;
+    }
+
+    if(sec_attr == PPC_POLARIS_SECURE_ACCESS) {
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+        /* Uses secure unprivileged access address (SACFG) to set privilege
+         * attribute
+         */
+        if(priv_attr == PPC_POLARIS_PRIV_ONLY_ACCESS) {
+            *(dev->data->sacfg_sp_ppc) &= ~mask;
+        } else {
+            *(dev->data->sacfg_sp_ppc) |= mask;
+        }
+#else
+        /* Configuring security from Non-Secure application is not permitted. */
+        return PPC_POLARIS_ERR_NOT_PERMITTED;
+#endif
+    } else {
+        /* Uses non-secure unprivileged access address (NSACFG) to set
+         * privilege attribute */
+        if(priv_attr == PPC_POLARIS_PRIV_ONLY_ACCESS) {
+            *(dev->data->nsacfg_nsp_ppc) &= ~mask;
+        } else {
+            *(dev->data->nsacfg_nsp_ppc) |= mask;
+        }
+    }
+
+    return PPC_POLARIS_ERR_NONE;
+}
+
+bool ppc_polaris_is_periph_priv_only(struct ppc_polaris_dev_t* dev,
+                                    uint32_t mask)
+{
+    if(dev->data->is_initialized != true) {
+        /* Return true as the default configuration is privilege only */
+        return true;
+    }
+
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+    /* In secure domain either secure or non-secure privilege access is returned
+     * based on the configuration */
+    if ((*(dev->data->sacfg_ns_ppc) & mask) == 0) {
+        /* Returns secure unprivileged access (SACFG) */
+        return ((*(dev->data->sacfg_sp_ppc) & mask) == 0);
+    } else {
+        /* Returns non-secure unprivileged access (NSACFG) */
+        return ((*(dev->data->nsacfg_nsp_ppc) & mask) == 0);
+    }
+#else
+    /* Returns non-secure unprivileged access (NSACFG) */
+    return ((*(dev->data->nsacfg_nsp_ppc) & mask) == 0);
+#endif
+}
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+enum ppc_polaris_error_t
+ppc_polaris_config_security(struct ppc_polaris_dev_t* dev, uint32_t mask,
+                           enum ppc_polaris_sec_attr_t sec_attr)
+{
+    if(dev->data->is_initialized != true) {
+        return PPC_POLARIS_ERR_NOT_INIT;
+    }
+
+    if(sec_attr == PPC_POLARIS_SECURE_ACCESS) {
+        *(dev->data->sacfg_ns_ppc) &= ~mask;
+    } else {
+        *(dev->data->sacfg_ns_ppc) |= mask;
+    }
+
+    return PPC_POLARIS_ERR_NONE;
+}
+
+bool ppc_polaris_is_periph_secure(struct ppc_polaris_dev_t* dev,
+                                 uint32_t mask)
+{
+    if(dev->data->is_initialized != true) {
+        /* Return true as the default configuration is secure */
+        return true;
+    }
+
+    return ((*(dev->data->sacfg_ns_ppc) & mask) == 0);
+}
+
+enum ppc_polaris_error_t ppc_polaris_irq_enable(struct ppc_polaris_dev_t* dev)
+{
+    struct polaris_sacfg_block_t* p_sacfg =
+                         (struct polaris_sacfg_block_t*)dev->cfg->sacfg_base;
+
+    if(dev->data->is_initialized != true) {
+        return PPC_POLARIS_ERR_NOT_INIT;
+    }
+
+    p_sacfg->secppcinten |= dev->data->int_bit_mask;
+
+    return PPC_POLARIS_ERR_NONE;
+}
+
+void ppc_polaris_irq_disable(struct ppc_polaris_dev_t* dev)
+{
+    struct polaris_sacfg_block_t* p_sacfg =
+                         (struct polaris_sacfg_block_t*)dev->cfg->sacfg_base;
+
+    if(dev->data->is_initialized == true) {
+        p_sacfg->secppcinten &= ~(dev->data->int_bit_mask);
+    }
+}
+
+void ppc_polaris_clear_irq(struct ppc_polaris_dev_t* dev)
+{
+    struct polaris_sacfg_block_t* p_sacfg =
+                         (struct polaris_sacfg_block_t*)dev->cfg->sacfg_base;
+
+    if(dev->data->is_initialized == true) {
+        p_sacfg->secppcintclr = dev->data->int_bit_mask;
+    }
+}
+
+bool ppc_polaris_irq_state(struct ppc_polaris_dev_t* dev)
+{
+    struct polaris_sacfg_block_t* p_sacfg =
+                         (struct polaris_sacfg_block_t*)dev->cfg->sacfg_base;
+
+    if(dev->data->is_initialized != true) {
+        return false;
+    }
+
+    return ((p_sacfg->secppcintstat & dev->data->int_bit_mask) != 0);
+}
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/ppc_polaris_drv.h b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/ppc_polaris_drv.h
new file mode 100644
index 0000000..0229c7b
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/ppc_polaris_drv.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file ppc_polaris_drv.h
+ * \brief Generic driver for Polaris Peripheral Protection Controllers (PPC).
+ */
+
+#ifndef __PPC_POLARIS_DRV_H__
+#define __PPC_POLARIS_DRV_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Polaris PPC names */
+enum ppc_polaris_name_t {
+    PPC_POLARIS_MAIN0 = 0,        /*!< MAIN PPC 0 */
+    PPC_POLARIS_MAIN_EXP0,        /*!< Expansion 0 MAIN PPC */
+    PPC_POLARIS_MAIN_EXP1,        /*!< Expansion 1 MAIN PPC */
+    PPC_POLARIS_MAIN_EXP2,        /*!< Expansion 2 MAIN PPC */
+    PPC_POLARIS_MAIN_EXP3,        /*!< Expansion 3 MAIN PPC */
+    PPC_POLARIS_PERIPH0,          /*!< PERIPH PPC0 */
+    PPC_POLARIS_PERIPH1,          /*!< PERIPH PPC1 */
+    PPC_POLARIS_PERIPH_EXP0,      /*!< Expansion 0 PERIPH PPC */
+    PPC_POLARIS_PERIPH_EXP1,      /*!< Expansion 1 PERIPH PPC */
+    PPC_POLARIS_PERIPH_EXP2,      /*!< Expansion 2 PERIPH PPC */
+    PPC_POLARIS_PERIPH_EXP3,      /*!< Expansion 3 PERIPH PPC */
+    POLARIS_PPC_MAX_NUM
+};
+
+/* Polaris PPC device configuration structure */
+struct ppc_polaris_dev_cfg_t {
+    uint32_t const sacfg_base;  /*!< Secure Privilege Control Block base */
+    uint32_t const nsacfg_base; /*!< Non-Secure Privilege Control Block base */
+    enum ppc_polaris_name_t ppc_name;
+};
+
+/* Polaris PPC device data structure */
+struct ppc_polaris_dev_data_t {
+    volatile uint32_t* sacfg_ns_ppc;   /*!< Pointer to non-secure register */
+    volatile uint32_t* sacfg_sp_ppc;   /*!< Pointer to secure unprivileged
+                                             register */
+    volatile uint32_t* nsacfg_nsp_ppc; /*!< Pointer to non-secure unprivileged
+                                             register */
+    uint32_t int_bit_mask;              /*!< Interrupt bit mask */
+    bool is_initialized;                /*!< Indicates if the PPC driver
+                                             is initialized */
+};
+
+/* Polaris PPC device structure */
+struct ppc_polaris_dev_t {
+    const struct ppc_polaris_dev_cfg_t* const cfg;  /*!< PPC configuration */
+    struct ppc_polaris_dev_data_t* const data;      /*!< PPC data */
+};
+
+/* Security attribute used to configure the peripherals */
+enum ppc_polaris_sec_attr_t {
+    PPC_POLARIS_SECURE_ACCESS = 0,    /*! Secure access */
+    PPC_POLARIS_NONSECURE_ACCESS,     /*! Non-secure access */
+};
+
+/* Privilege attribute used to configure the peripherals */
+enum ppc_polaris_priv_attr_t {
+    PPC_POLARIS_PRIV_AND_NONPRIV_ACCESS = 0, /*! Privilege and NonPrivilege
+                                                access */
+    PPC_POLARIS_PRIV_ONLY_ACCESS,            /*! Privilege only access */
+};
+
+/* ARM PPC error codes */
+enum ppc_polaris_error_t {
+    PPC_POLARIS_ERR_NONE = 0,      /*!< No error */
+    PPC_POLARIS_ERR_INVALID_PARAM, /*!< PPC invalid parameter error */
+    PPC_POLARIS_ERR_NOT_INIT,      /*!< PPC not initialized */
+    PPC_POLARIS_ERR_NOT_PERMITTED  /*!< PPC Operation not permitted */
+};
+
+/**
+ * \brief Initialize the PPC device.
+ *
+ * \param[in] dev       PPC device \ref ppc_polaris_dev_t
+ *
+ * \return Returns error code as specified in \ref ppc_polaris_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum ppc_polaris_error_t ppc_polaris_init(struct ppc_polaris_dev_t* dev);
+
+/**
+ * \brief Configures privilege attribute through the PPC device.
+ *
+ * \param[in] dev        PPC device \ref ppc_polaris_dev_t
+ * \param[in] mask       Peripheral mask for the PPC.
+ * \param[in] sec_attr   Secure attribute value.
+ * \param[in] priv_attr  Privilege attribute value.
+ *
+ * \return Returns error code as specified in \ref ppc_polaris_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum ppc_polaris_error_t
+ppc_polaris_config_privilege(struct ppc_polaris_dev_t* dev, uint32_t mask,
+                            enum ppc_polaris_sec_attr_t sec_attr,
+                            enum ppc_polaris_priv_attr_t priv_attr);
+
+/**
+ * \brief Checks if the peripheral is configured as Privilege only or
+ *        Privilege and non-Privilege access mode.
+ *
+ * \param[in] dev     PPC device \ref ppc_polaris_dev_t
+ * \param[in] mask    Peripheral mask for the PPC.
+ *
+ * \return Returns true for Privilege only configuration and false otherwise
+ *           - with non-secure caller in the non-secure domain
+ *           - with secure caller in the configured security domain
+ *         If the driver is not initalized the return value of this function is
+ *         true (Privilege only) as it is the default system configuration.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool ppc_polaris_is_periph_priv_only(struct ppc_polaris_dev_t* dev,
+                                    uint32_t mask);
+
+/* Secure only functions */
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
+
+/**
+ * \brief Configures security attribute through the PPC device.
+ *
+ * \param[in] dev        PPC device \ref ppc_polaris_dev_t
+ * \param[in] mask       Peripheral mask for the PPC.
+ * \param[in] sec_attr   Secure attribute value.
+ *
+ * \return Returns error code as specified in \ref ppc_polaris_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum ppc_polaris_error_t
+ppc_polaris_config_security(struct ppc_polaris_dev_t* dev, uint32_t mask,
+                           enum ppc_polaris_sec_attr_t sec_attr);
+
+/**
+ * \brief Checks if the peripheral is configured as secure or non-secure.
+ *
+ * \param[in] dev     PPC device \ref ppc_polaris_dev_t
+ * \param[in] mask    Peripheral mask for the PPC.
+ *
+ * \return Returns true for secure and false for non-secure.
+ *         If the driver is not initalized the return value is true (secure) as
+ *         it is the default system configuration.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool ppc_polaris_is_periph_secure(struct ppc_polaris_dev_t* dev,
+                                 uint32_t mask);
+
+/**
+ * \brief Enables PPC interrupt.
+ *
+ * \param[in] dev  PPC device \ref ppc_polaris_dev_t
+ *
+ * \return Returns error code as specified in \ref ppc_polaris_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum ppc_polaris_error_t ppc_polaris_irq_enable(struct ppc_polaris_dev_t* dev);
+
+/**
+ * \brief Disables PPC interrupt.
+ *
+ * \param[in] dev  PPC device \ref ppc_polaris_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void ppc_polaris_irq_disable(struct ppc_polaris_dev_t* dev);
+
+/**
+ * \brief Clears PPC interrupt.
+ *
+ * \param[in] dev  PPC device \ref ppc_polaris_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void ppc_polaris_clear_irq(struct ppc_polaris_dev_t* dev);
+
+/**
+ * \brief Returns the PPC interrupt state.
+ *
+ * \param[in] dev  PPC device \ref ppc_polaris_dev_t
+ *
+ * \return Returns true if the interrupt is active and otherwise false.
+ *         If the driver is not initalized the return value of this function is
+ *         false (not active) as it is the default system configuration.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool ppc_polaris_irq_state(struct ppc_polaris_dev_t* dev);
+
+#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __PPC_POLARIS_DRV_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/syscounter_armv8-m_cntrl_drv.c b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/syscounter_armv8-m_cntrl_drv.c
new file mode 100644
index 0000000..832bb02
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/syscounter_armv8-m_cntrl_drv.c
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2019 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file syscounter_armv8-m_cntrl_drv.c
+ *
+ * \brief Driver for Armv8-M System Counter Control, covering CNTControlBase
+ *        Frame
+ *
+ * This System Counter is a 64-bit up-counter, generating the physical
+ * count for System Timer.
+ *
+ * Main features:
+ *   - Enabled/disable and Set/Get the 64-bit upcounter
+ *   - 2 scaling register for the 2 clock sources
+ *       - These registers are used to pre-program the scaling values so
+ *          that when hardware based clock switching is implemented there is no
+ *          need to program the scaling increment value each time when clock is
+ *          switched.
+ *        - When counter scaling is enabled, ScaleVal is the amount added to the
+ *          Counter Count Value for every period of the counter as determined
+ *          by 1/Frequency from the current operating frequency of the system
+ *          counter (the “counter tick”).
+ *        - ScaleVal is expressed as an unsigned fixed-point number with
+ *          a 8 bit integer value and a 24-bit fractional value
+ *   - Interrupt for error detection
+ *       There are 2 possible reasons for error notification generation from
+ *       the Counter:
+ *         1. Security attribute mismatch between register access and security
+ *            attribute of the CONTROL frame
+ *         2. Address decode error within a given frame
+ *
+ */
+
+#include "syscounter_armv8-m_cntrl_drv.h"
+
+/** Setter bit manipulation macro */
+#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX)))
+/** Clearing bit manipulation macro */
+#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX)))
+/** Getter bit manipulation macro */
+#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX))))
+/** Clear-and-Set bit manipulation macro */
+#define ASSIGN_BIT(WORD, BIT_INDEX, VALUE) \
+            (WORD = ((WORD & ~(1U << (BIT_INDEX))) | (VALUE << (BIT_INDEX))))
+/** Getter bit-field manipulation macro */
+#define GET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET) \
+            ((WORD & BIT_MASK) >> BIT_OFFSET)
+/** Bit mask for given width bit-field manipulation macro */
+#define BITMASK(width) ((1u<<(width))-1)
+
+/**
+ * \brief CNTControlBase Register map structure
+ */
+struct cnt_control_base_reg_map_t {
+    volatile uint32_t cntcr;
+        /*!< Offset: 0x000 (R/W) Counter Control Register */
+    volatile const uint32_t cntsr;
+        /*!< Offset: 0x004 (RO) Counter Status Register */
+    volatile uint32_t cntcv_low;
+        /*!< Offset: 0x008 (R/W) Counter Count Value [31:0] Register */
+    volatile uint32_t cntcv_high;
+        /*!< Offset: 0x00C (R/W) Counter Count Value [63:32] Register */
+    volatile uint32_t cntscr;
+        /*!< Offset: 0x010 (R/W) Counter Scale Register
+         *   Aliased with CNTSCR0, meaning that either addresses of CNTSCR and
+         *   CNTSCR0 will physically access a single register
+         */
+    volatile const uint32_t reserved0[2];
+        /*!< Offset: 0x014-0x018 Reserved (RAZWI) */
+    volatile const uint32_t cntid;
+        /*!< Offset: 0x01C (RO) Counter ID Register */
+    volatile const uint32_t reserved1[40];
+        /*!< Offset: 0x020-0x0BC Reserved (RAZWI) */
+    volatile const uint32_t reserved2[4];
+        /*!< Offset: 0x0C0-0x0CC Reserved (RAZWI) */
+    volatile uint32_t cntscr0;
+        /*!< Offset: 0x0D0 (R/W) Counter Scale Register 0 */
+    volatile uint32_t cntscr1;
+        /*!< Offset: 0x0D4 (R/W) Counter Scale Register 1 */
+    volatile const uint32_t reserved3[958];
+        /*!< Offset: 0x0D8-0xFCC Reserved (RAZWI) */
+    volatile const uint32_t cntpidr4;
+        /*!< Offset: 0xFD0 (RO) Peripheral ID Register */
+    volatile const uint32_t reserved4[3];
+        /*!< Offset: 0xFD4-0xFDC Reserved (RAZWI) */
+    volatile const uint32_t cntpidr0;
+        /*!< Offset: 0xFE0 (RO) Peripheral ID Register */
+    volatile const uint32_t cntpidr1;
+        /*!< Offset: 0xFE4 (RO) Peripheral ID Register */
+    volatile const uint32_t cntpidr2;
+        /*!< Offset: 0xFE8 (RO) Peripheral ID Register */
+    volatile const uint32_t cntpidr3;
+        /*!< Offset: 0xFEC (RO) Peripheral ID Register */
+    volatile const uint32_t cntcidr0;
+        /*!< Offset: 0xFF0 (RO) Component ID Register */
+    volatile const uint32_t cntcidr1;
+        /*!< Offset: 0xFF4 (RO) Component ID Register */
+    volatile const uint32_t cntcidr2;
+        /*!< Offset: 0xFF8 (RO) Component ID Register */
+    volatile const uint32_t cntcidr3;
+        /*!< Offset: 0xFFC (RO) Component ID Register */
+};
+
+/**
+ * \brief Counter Control Register bit fields
+ */
+#define SYSCOUNTER_ARMV8M_CNTCR_EN_OFF             0u
+    /*!< Counter Control Register Enable Counter bit field offset */
+#define SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF           1u
+    /*!< Counter Control Register Halt On Debug bit field offset */
+#define SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF           2u
+    /*!< Counter Control Register Scale enable bit field offset */
+#define SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF       3u
+    /*!< Counter Control Register Interrupt mask bit field offset */
+#define SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF     4u
+    /*!< Counter Control Register PSLVERR disable bit field offset */
+#define SYSCOUNTER_ARMV8M_CNTCR_INTRCLR_OFF        5u
+    /*!< Counter Control Register Interrupt Clear bit field offset */
+
+/**
+ * \brief Counter Status Register bit fields
+ */
+#define SYSCOUNTER_ARMV8M_CNTSR_DBGH_OFF           1u
+    /*!< Counter Status Register Halt-on-Debug bit field offset */
+
+/**
+ * \brief Counter ID Register bit fields
+ */
+#define SYSCOUNTER_ARMV8M_CNTID_CNTSC_OFF                  0u
+    /*!< Counter ID Register Counter Scaling is implemented bit field offset */
+#define SYSCOUNTER_ARMV8M_CNTID_CNTCS_OFF                  16u
+    /*!< Counter ID Register Clock switching is implemented bit field offset */
+
+/*! Counter ID Register Clock source */
+#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF              17u
+#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_WIDTH            2u
+#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_MASK             \
+            (BITMASK(SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_WIDTH) \
+            << SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF)
+
+#define SYSCOUNTER_ARMV8M_CNTID_CNTSCR_OVR_OFF             19u
+    /*!< Counter ID Register Override counter enable condition for
+     *   writing to CNTSCR registers bit offset
+     */
+
+enum syscounter_armv8_m_cntrl_error_t syscounter_armv8_m_cntrl_init(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    enum syscounter_armv8_m_cntrl_error_t result = SYSCOUNTER_ARMV8_M_ERR_NONE;
+
+    if (dev->data->is_initialized == false) {
+        syscounter_armv8_m_cntrl_disable_counter(dev);
+        if (syscounter_armv8_m_cntrl_is_counter_scaling_implemented(dev)) {
+            result = syscounter_armv8_m_cntrl_set_counter_scale_value(
+                     dev, SYSCOUNTER_ARMV8_M_SCALE_NR_0, dev->cfg->scale0);
+            if (result != SYSCOUNTER_ARMV8_M_ERR_NONE) {
+                return result;
+            }
+            result = syscounter_armv8_m_cntrl_set_counter_scale_value(
+                     dev, SYSCOUNTER_ARMV8_M_SCALE_NR_1, dev->cfg->scale1);
+            if (result != SYSCOUNTER_ARMV8_M_ERR_NONE) {
+                return result;
+            }
+        }
+        syscounter_armv8_m_cntrl_set_counter_value(dev,
+            SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL);
+        syscounter_armv8_m_cntrl_disable_interrupt(dev);
+        syscounter_armv8_m_cntrl_disable_scale(dev);
+
+        syscounter_armv8_m_cntrl_enable_counter(dev);
+        dev->data->is_initialized = true;
+    }
+    return SYSCOUNTER_ARMV8_M_ERR_NONE;
+}
+
+void syscounter_armv8_m_cntrl_uninit(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    if (dev->data->is_initialized == true) {
+        syscounter_armv8_m_cntrl_disable_counter(dev);
+        syscounter_armv8_m_cntrl_disable_interrupt(dev);
+        syscounter_armv8_m_cntrl_set_counter_value(dev,
+                SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL);
+        dev->data->is_initialized = false;
+    }
+}
+
+void syscounter_armv8_m_cntrl_enable_counter(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_EN_OFF);
+}
+
+void syscounter_armv8_m_cntrl_disable_counter(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_EN_OFF);
+}
+
+bool syscounter_armv8_m_cntrl_is_counter_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntcr,
+                         SYSCOUNTER_ARMV8M_CNTCR_EN_OFF);
+}
+
+void syscounter_armv8_m_cntrl_enable_halt_on_debug(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF);
+}
+
+void syscounter_armv8_m_cntrl_disable_halt_on_debug(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF);
+}
+
+bool syscounter_armv8_m_cntrl_is_halt_on_debug_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntcr,
+                         SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF);
+}
+
+void syscounter_armv8_m_cntrl_enable_scale(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF);
+}
+
+void syscounter_armv8_m_cntrl_disable_scale(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF);
+}
+
+bool syscounter_armv8_m_cntrl_is_scale_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntcr,
+                         SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF);
+}
+
+void syscounter_armv8_m_cntrl_enable_interrupt(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF);
+}
+
+void syscounter_armv8_m_cntrl_disable_interrupt(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF);
+}
+
+bool syscounter_armv8_m_cntrl_is_interrupt_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntcr,
+                         SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF);
+}
+
+void syscounter_armv8_m_cntrl_enable_pslverr(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF);
+}
+
+void syscounter_armv8_m_cntrl_disable_pslverr(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF);
+}
+
+bool syscounter_armv8_m_cntrl_is_pslverr_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntcr,
+                         SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF);
+}
+
+void syscounter_armv8_m_cntrl_clear_interrupt(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRCLR_OFF);
+}
+
+bool syscounter_armv8_m_cntrl_is_counter_halted_on_debug(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntsr,
+                         SYSCOUNTER_ARMV8M_CNTSR_DBGH_OFF);
+}
+
+uint64_t syscounter_armv8_m_cntrl_get_counter_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    uint32_t high = 0;
+    uint32_t low = 0;
+    uint32_t high_prev = 0;
+    uint64_t value = 0;
+
+    /* Make sure the 64-bit read will be atomic to avoid overflow between
+     * the low and high registers read
+     */
+    high = p_cnt->cntcv_high;
+    do {
+        high_prev = high;
+        low = p_cnt->cntcv_low;
+        high = p_cnt->cntcv_high;
+    }while(high != high_prev);
+
+    value = low |
+            (((uint64_t)high) << SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH);
+    return value;
+}
+
+void syscounter_armv8_m_cntrl_set_counter_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev,
+        uint64_t value)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    p_cnt->cntcv_low = value & UINT32_MAX;
+    p_cnt->cntcv_high = value >> SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH;
+}
+
+bool syscounter_armv8_m_cntrl_is_counter_scaling_implemented(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntid,
+                         SYSCOUNTER_ARMV8M_CNTID_CNTSC_OFF);
+}
+
+bool syscounter_armv8_m_cntrl_is_clock_switching_implemented(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntid,
+                         SYSCOUNTER_ARMV8M_CNTID_CNTCS_OFF);
+}
+
+enum syscounter_armv8_m_cntrl_selclk_t
+syscounter_armv8_m_cntrl_get_clock_source(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return (enum syscounter_armv8_m_cntrl_selclk_t)
+            GET_BIT_FIELD(p_cnt->cntid,
+                         SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_MASK,
+                         SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF);
+}
+
+enum syscounter_armv8_m_cntrl_cntscr_ovr_t
+syscounter_armv8_m_cntrl_get_override_cntscr(
+        struct syscounter_armv8_m_cntrl_dev_t* dev)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    return (enum syscounter_armv8_m_cntrl_cntscr_ovr_t)
+            GET_BIT(p_cnt->cntid,
+                    SYSCOUNTER_ARMV8M_CNTID_CNTSCR_OVR_OFF);
+}
+
+enum syscounter_armv8_m_cntrl_error_t
+syscounter_armv8_m_cntrl_get_counter_scale_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev,
+        enum syscounter_armv8_m_cntrl_scale_nr_t nr,
+        struct syscounter_armv8_m_cntrl_scale_val_t *val)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+
+    switch (nr) {
+    case SYSCOUNTER_ARMV8_M_SCALE_NR_0:
+        val->integer = p_cnt->cntscr0 >> SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF;
+        val->fixed_point_fraction = p_cnt->cntscr0 &
+                                     SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX;
+        break;
+    case SYSCOUNTER_ARMV8_M_SCALE_NR_1:
+        val->integer = p_cnt->cntscr1 >> SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF;
+        val->fixed_point_fraction = p_cnt->cntscr1 &
+                                     SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX;
+        break;
+    default:
+        val->integer = 0;
+        val->fixed_point_fraction = 0;
+        return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG;
+    }
+
+    return SYSCOUNTER_ARMV8_M_ERR_NONE;
+}
+
+enum syscounter_armv8_m_cntrl_error_t
+syscounter_armv8_m_cntrl_set_counter_scale_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev,
+        enum syscounter_armv8_m_cntrl_scale_nr_t nr,
+        struct syscounter_armv8_m_cntrl_scale_val_t val)
+{
+    struct cnt_control_base_reg_map_t* p_cnt =
+            (struct cnt_control_base_reg_map_t*)dev->cfg->base;
+    uint32_t reg_val = 0;
+
+    if ((syscounter_armv8_m_cntrl_get_override_cntscr(dev) ==
+        SYSCOUNTER_ARMV8_M_CNTSCR_IF_DISABLED) &&
+        syscounter_armv8_m_cntrl_is_counter_enabled(dev)) {
+        return SYSCOUNTER_ARMV8_M_ERR_INVALID;
+    }
+    if (val.integer > SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX ||
+        val.fixed_point_fraction > SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX) {
+        return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG;
+    }
+
+    reg_val = val.integer << SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF;
+    reg_val |= (val.fixed_point_fraction &
+                SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX);
+
+    switch (nr) {
+    case SYSCOUNTER_ARMV8_M_SCALE_NR_0:
+        p_cnt->cntscr0 = reg_val;
+        break;
+    case SYSCOUNTER_ARMV8_M_SCALE_NR_1:
+        p_cnt->cntscr1 = reg_val;
+        break;
+    default:
+        return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG;
+    }
+
+    return SYSCOUNTER_ARMV8_M_ERR_NONE;
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/syscounter_armv8-m_cntrl_drv.h b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/syscounter_armv8-m_cntrl_drv.h
new file mode 100644
index 0000000..e84786d
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/syscounter_armv8-m_cntrl_drv.h
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2019 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file syscounter_armv8-m_cntrl_drv.h
+ *
+ * \brief Driver for Armv8-M System Counter Control, covering CNTControlBase
+ *        Frame
+ *
+ * This System Counter is a 64-bit up-counter, generating the physical
+ * count for System Timer.
+ *
+ * Main features:
+ *   - Enable/disable and Set/Get the 64-bit upcounter
+ *   - 2 scaling registers for the 2 clock sources
+ *       - These registers are used to pre-program the scaling values so
+ *          that when hardware based clock switching is implemented there is no
+ *          need to program the scaling increment value each time when clock is
+ *          switched.
+ *        - When counter scaling is enabled, ScaleVal is the value added to the
+ *          Counter Count Value for every period of the counter as determined
+ *          by 1/Frequency from the current operating frequency of the system
+ *          counter (the “counter tick”).
+ *        - ScaleVal is expressed as an unsigned fixed-point number with
+ *          a 8 bit integer value and a 24-bit fractional value
+ *   - Interrupt for error detection
+ *       There are 2 possible reasons for error notification generation from
+ *       the Counter:
+ *         1. Security attribute mismatch between register access and security
+ *            attribute of the CONTROL frame
+ *         2. Address decode error within a given frame
+ *
+ */
+
+#ifndef __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__
+#define __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH     32u
+    /*!< Armv8-M System Counter Control registers bit width */
+
+#define SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL         0u
+    /*!< Armv8-M System Counter Control default counter init value */
+
+/**
+ * \brief Armv8-M System Counter Control scaling value
+ */
+struct syscounter_armv8_m_cntrl_scale_val_t {
+    uint32_t integer;              /* 8 bit */
+    uint32_t fixed_point_fraction; /* 24 bit */
+};
+
+/**
+ * \brief Armv8-M System Counter Control scaling value macros *
+ *        8 bit integer and 24 bit fixed point fractional value
+ */
+#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX      UINT8_MAX
+#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF      24u
+#define SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX    \
+            ((1u << SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF) - 1u)
+
+/**
+ *  \brief Armv8-M System Counter Control device configuration structure
+ */
+struct syscounter_armv8_m_cntrl_dev_cfg_t {
+    const uint32_t base;
+        /*!< Armv8-M System Counter Control device base address */
+    struct syscounter_armv8_m_cntrl_scale_val_t scale0;
+        /*!< Default clock scaling value for Clock source 0 */
+    struct syscounter_armv8_m_cntrl_scale_val_t scale1;
+        /*!< Default clock scaling value for Clock source 1 */
+};
+
+/**
+ * \brief Armv8-M System Counter Control device data structure
+ */
+struct syscounter_armv8_m_cntrl_dev_data_t {
+    bool is_initialized;
+};
+
+/**
+ * \brief Armv8-M System Counter Control device structure
+ */
+struct syscounter_armv8_m_cntrl_dev_t {
+    const struct syscounter_armv8_m_cntrl_dev_cfg_t* const cfg;
+        /*!< Armv8-M System Counter Control configuration structure */
+    struct syscounter_armv8_m_cntrl_dev_data_t* const data;
+        /*!< Armv8-M System Counter Control data structure */
+};
+
+/**
+ * \brief Armv8-M System Counter Control error enumeration types
+ */
+enum syscounter_armv8_m_cntrl_error_t {
+    SYSCOUNTER_ARMV8_M_ERR_NONE         = 0u,
+    SYSCOUNTER_ARMV8_M_ERR_INVALID      = 1u,
+    SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG  = 2u
+};
+
+/**
+ * \brief Armv8-M System Counter Control scaling number for each clock sources
+ */
+enum syscounter_armv8_m_cntrl_scale_nr_t {
+    SYSCOUNTER_ARMV8_M_SCALE_NR_0         = 0u,
+      /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK0 */
+    SYSCOUNTER_ARMV8_M_SCALE_NR_1         = 1u
+      /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK1 */
+};
+
+/**
+ * \brief Clock select values
+ */
+enum syscounter_armv8_m_cntrl_selclk_t {
+    SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID0  = 0u,
+        /*!< Clock select invalid value */
+    SYSCOUNTER_ARMV8_M_SELCLK_CLK0          = 1u,
+        /*!< Clock select clock source 0 */
+    SYSCOUNTER_ARMV8_M_SELCLK_CLK1          = 2u,
+        /*!< Clock select clock source 1 */
+    SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID1  = 3u
+        /*!< Clock select invalid value */
+};
+
+/**
+ * \brief Override counter enable condition for writing to CNTSCR registers
+ *
+ */
+enum syscounter_armv8_m_cntrl_cntscr_ovr_t {
+    SYSCOUNTER_ARMV8_M_CNTSCR_IF_DISABLED   = 0u,
+    /*!< Scaling registers can be written only when counter is disabled */
+    SYSCOUNTER_ARMV8_M_CNTSCR_ALWAYS        = 1u
+    /*!< CNTSCR can be written regardless of counter enabled or disabled */
+};
+
+/**
+ * \brief Initializes counter to a known default state, which is:
+ *          - counter is enabled, so starts counting
+ *          - interrupt is disabled
+ *          - counter reset to default reset value
+ *              \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL
+ *          - scaling is disabled
+ *          - scaling registers are set to the set values:
+ *              \ref struct syscounter_armv8_m_cntrl_dev_cfg_t
+ *        Init should be called prior to any other process and
+ *        it's the caller's responsibility to follow proper call order.
+ *        More than one call results fall through.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_error_t syscounter_armv8_m_cntrl_init(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Uninitializes counter to a known default state, which is:
+ *          - counter is disabled, so stops counting
+ *          - interrupt is disabled
+ *          - counter reset to default reset value
+ *              \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL
+ *          - scaling is disabled
+ *        Init should be called prior to any other process and
+ *        it's the caller's responsibility to follow proper call order.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_uninit(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables the counter, so counter starts counting
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_counter(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables the counter, so counter stops counting
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_counter(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls counter enable status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_counter_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables Halt-On-Debug feature
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_halt_on_debug(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables Halt-On-Debug feature
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_halt_on_debug(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls Halt-On-Debug enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_halt_on_debug_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables scaling
+ *        The used scaling register is depending on the used HW clock source.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_scale(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables scaling
+ *        Counter count will be incremented by default 1 for each ticks.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_scale(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls scaling enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_scale_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables interrupt
+ *
+ *  There are 2 possible reasons for error notification generation from
+ *  the Counter:
+ *   1. Security attribute mismatch between register access and security
+ *       attribute of the CONTROL frame
+ *   2. Address decode error within a given frame
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_interrupt(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables interrupt
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_interrupt(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls interrupt enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_interrupt_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables PSLVERR output
+ *
+ *        PSLVERR output signal on APB bus dynamically generated for the
+ *        following error:
+ *          For security attribute mismatch between register access and security
+ *          attribute of the CONTROL frame
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_pslverr(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables PSLVERR output
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_pslverr(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls PSLVERR output enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_pslverr_enabled(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Clears interrupt pending flag
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_clear_interrupt(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls Halt-On-Debug status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if counter is halted, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_counter_halted_on_debug(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Read counter value
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return 64 bit counter value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t syscounter_armv8_m_cntrl_get_counter_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Writes counter value
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ * \param[in] value 64 bit counter value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_set_counter_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev,
+        uint64_t value);
+
+/**
+ * \brief Polls whether scaling is implemented
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if implemented, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_counter_scaling_implemented(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls whether HW based clock switching is implemented
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if implemented, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_clock_switching_implemented(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Reads which clock source is being used
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return Clock source \ref enum syscounter_armv8_m_cntrl_selclk_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_selclk_t
+        syscounter_armv8_m_cntrl_get_clock_source(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Reads scaling register can be overriden anytime
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_cntscr_ovr_t
+        syscounter_armv8_m_cntrl_get_override_cntscr(
+        struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Reads scaling register
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ * \param[in] nr Index of scaling register to read
+ *              \ref enum syscounter_armv8_m_cntrl_scale_nr_t
+ * \param[out] nr Pointer to structure to read the scale value
+ *                \ref struct syscounter_armv8_m_cntrl_scale_val_t
+ *
+ * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_error_t
+syscounter_armv8_m_cntrl_get_counter_scale_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev,
+        enum syscounter_armv8_m_cntrl_scale_nr_t nr,
+        struct syscounter_armv8_m_cntrl_scale_val_t *val);
+
+/**
+ * \brief Writes scaling register
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ * \param[in] nr Index of scaling register to write
+ *              \ref enum syscounter_armv8_m_cntrl_scale_nr_t
+ * \param[in] Scale value structure
+ *              \ref struct syscounter_armv8_m_cntrl_scale_val_t
+ *
+ * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_error_t
+syscounter_armv8_m_cntrl_set_counter_scale_value(
+        struct syscounter_armv8_m_cntrl_dev_t* dev,
+        enum syscounter_armv8_m_cntrl_scale_nr_t nr,
+        struct syscounter_armv8_m_cntrl_scale_val_t val);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/systimer_armv8-m_drv.c b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/systimer_armv8-m_drv.c
new file mode 100644
index 0000000..c7b4b15
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/systimer_armv8-m_drv.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2019-2020 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file systimer_armv8-m_drv.c
+ *
+ * \brief Driver for Armv8-M System Timer
+ *
+ */
+
+#include "systimer_armv8-m_drv.h"
+
+/** Setter bit manipulation macro */
+#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1u << (BIT_INDEX)))
+/** Clearing bit manipulation macro */
+#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1u << (BIT_INDEX)))
+/** Getter bit manipulation macro */
+#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1u << (BIT_INDEX))))
+/** Getter bit-field manipulation macro */
+#define GET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET) \
+            ((WORD & BIT_MASK) >> BIT_OFFSET)
+/** Bit mask for given width bit-field manipulation macro */
+#define BITMASK(width) ((1u<<(width))-1)
+
+/**
+ * \brief CNTBase Register map structure
+ */
+struct cnt_base_reg_map_t {
+    volatile const uint32_t cntpct_low;
+        /*!< Offset: 0x000 (RO) Current Physical Counter Value [31:0] */
+    volatile const uint32_t cntpct_high;
+        /*!< Offset: 0x004 (RO) Current Physical Counter Value [63:32] */
+    volatile const uint32_t reserved0[2];
+        /*!< Offset: 0x008-0x0C Reserved  */
+    volatile uint32_t cntfrq;
+        /*!< Offset: 0x010 (R/W) Counter Frequency register in Hz */
+    volatile const uint32_t reserved1[3];
+        /*!< Offset: 0x014-0x01C Reserved  */
+    volatile uint32_t cntp_cval_low;
+        /*!< Offset: 0x020 (R/W) Timer Compare Value register [31:0] */
+    volatile uint32_t cntp_cval_high;
+        /*!< Offset: 0x024 (R/W) Timer Compare Value register [63:32] */
+    volatile uint32_t cntp_tval;
+        /*!< Offset: 0x028 (R/W) Timer Value register */
+    volatile uint32_t cntp_ctl;
+        /*!< Offset: 0x02C (R/W) Timer Control register */
+    volatile const uint32_t reserved2[4];
+        /*!< Offset: 0x030-0x03C Reserved  */
+    volatile const uint32_t cntp_aival_low;
+        /*!< Offset: 0x040 (RO) Auto Increment Value register [31:0]*/
+    volatile const  uint32_t cntp_aival_high;
+        /*!< Offset: 0x044 (RO) Auto Increment Value register [63:32]*/
+    volatile uint32_t cntp_aival_reload;
+        /*!< Offset: 0x048 (R/W) Auto Increment Value Reload register [63:32]*/
+    volatile uint32_t cntp_aival_ctl;
+        /*!< Offset: 0x04C (R/W) Auto Increment Control register */
+    volatile const  uint32_t cntp_cfg;
+        /*!< Offset: 0x050 (RO) Timer Configuration register */
+    volatile const uint32_t reserved3[991];
+        /*!< Offset: 0x054-0xFCC Reserved  */
+    volatile const uint32_t cntp_pid4;
+        /*!< Offset: 0xFD0 (RO) Peripheral ID Register */
+    volatile const uint32_t reserved4[3];
+        /*!< Offset: 0xFD4-0xFDC Reserved (RAZWI) */
+    volatile const uint32_t cntp_pid0;
+        /*!< Offset: 0xFE0 (RO) Peripheral ID Register */
+    volatile const uint32_t cntp_pid1;
+        /*!< Offset: 0xFE4 (RO) Peripheral ID Register */
+    volatile const uint32_t cntp_pid2;
+        /*!< Offset: 0xFE8 (RO) Peripheral ID Register */
+    volatile const uint32_t cntp_pid3;
+        /*!< Offset: 0xFEC (RO) Peripheral ID Register */
+    volatile const uint32_t cntp_cid0;
+        /*!< Offset: 0xFF0 (RO) Component ID Register */
+    volatile const uint32_t cntp_cid1;
+        /*!< Offset: 0xFF4 (RO) Component ID Register */
+    volatile const uint32_t cntp_cid2;
+        /*!< Offset: 0xFF8 (RO) Component ID Register */
+    volatile const uint32_t cntp_cid3;
+        /*!< Offset: 0xFFC (RO) Component ID Register */
+};
+
+/**
+ * \brief Timer Control Register bit fields
+ */
+#define SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF           0u
+    /*!< Timer Control Register Enable Counter bit field offset */
+#define SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF        1u
+/*!< Timer Control Register Interrupt Mask bit field offset */
+#define SYSCTIMER_ARMV8M_CNTP_CTL_ISTATUS_OFF      2u
+/*!< Timer Control Register Interrupt Status bit field offset */
+
+/**
+ * \brief Timer AutoInc Control Register bit fields
+ */
+#define SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF           0u
+    /*!< Timer Control Register Enable Counter bit field offset */
+#define SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_IRQ_CLR_OFF      1u
+/*!< Timer Control Register Interrupt clear bit field offset */
+
+/**
+ * \brief Timer AutoInc Config Register bit fields
+ */
+#define SYSCTIMER_ARMV8M_CNTP_CFG_CTL_AUTOINC_OFF        0u
+    /*!< Timer Control Register AutoInc is implemented bit field offset */
+
+
+void systimer_armv8_m_init(struct systimer_armv8_m_dev_t* dev)
+{
+    if (dev->data->is_initialized == false) {
+        systimer_armv8_m_disable_interrupt(dev);
+        systimer_armv8_m_disable_autoinc(dev);
+        systimer_armv8_m_set_counter_freq(dev, dev->cfg->default_freq_hz);
+        systimer_armv8_m_enable_timer(dev);
+        dev->data->is_initialized = true;
+    }
+}
+
+void systimer_armv8_m_uninit(struct systimer_armv8_m_dev_t* dev)
+{
+    if (dev->data->is_initialized == true) {
+        systimer_armv8_m_disable_interrupt(dev);
+        systimer_armv8_m_disable_autoinc(dev);
+        systimer_armv8_m_disable_timer(dev);
+        dev->data->is_initialized = false;
+    }
+}
+
+uint64_t systimer_armv8_m_get_counter_value(
+           struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    uint32_t high = 0;
+    uint32_t low = 0;
+    uint32_t high_prev = 0;
+    uint64_t value = 0;
+
+    /* Make sure the 64-bit read will be atomic to avoid overflow between
+     * the low and high registers read
+     */
+    high = p_cnt->cntpct_high;
+    do {
+        high_prev = high;
+        low = p_cnt->cntpct_low;
+        high = p_cnt->cntpct_high;
+    }while(high != high_prev);
+
+    value = low | (((uint64_t)high) << SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH);
+    return value;
+}
+
+void systimer_armv8_m_set_compare_value(
+        struct systimer_armv8_m_dev_t* dev,
+        uint64_t value)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    p_cnt->cntp_cval_low = value & UINT32_MAX;
+    p_cnt->cntp_cval_high = value >> SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH;
+}
+
+uint64_t systimer_armv8_m_get_compare_value(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    uint64_t value = 0;
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    value = p_cnt->cntp_cval_low |
+            (((uint64_t)p_cnt->cntp_cval_high) <<
+                    SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH);
+    return value;
+}
+
+void systimer_armv8_m_set_counter_freq(struct systimer_armv8_m_dev_t* dev,
+                                       uint32_t value)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    p_cnt->cntfrq = value;
+}
+
+uint32_t systimer_armv8_m_get_counter_freq(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    return p_cnt->cntfrq;
+}
+
+void systimer_armv8_m_set_timer_value(struct systimer_armv8_m_dev_t* dev,
+                                      uint32_t value)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    p_cnt->cntp_tval = value;
+}
+
+uint32_t systimer_armv8_m_get_timer_value(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    return p_cnt->cntp_tval;
+}
+
+void systimer_armv8_m_enable_timer(struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    SET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF);
+}
+
+void systimer_armv8_m_disable_timer(struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF);
+}
+
+bool systimer_armv8_m_is_timer_enabled(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF);
+}
+
+void systimer_armv8_m_enable_interrupt(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    /* The bit is masking interrupt, so it should be inverted. */
+    CLR_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF);
+}
+
+void systimer_armv8_m_disable_interrupt(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    /* The bit is masking interrupt, so it should be inverted. */
+    SET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF);
+}
+
+bool systimer_armv8_m_is_interrupt_enabled(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    /* The bit is masking interrupt, so it should be inverted. */
+    return !GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF);
+}
+
+bool systimer_armv8_m_is_interrupt_asserted(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_ISTATUS_OFF);
+}
+
+uint64_t systimer_armv8_m_get_autoinc_value(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    uint64_t value = 0;
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    value = p_cnt->cntp_aival_low |
+            (((uint64_t)p_cnt->cntp_aival_high) <<
+             SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH);
+    return value;
+}
+
+void systimer_armv8_m_set_autoinc_reload(
+        struct systimer_armv8_m_dev_t* dev,
+        uint32_t value)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    p_cnt->cntp_aival_reload = value;
+}
+
+uint32_t systimer_armv8_m_get_autoinc_reload(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    return p_cnt->cntp_aival_reload;
+}
+
+void systimer_armv8_m_enable_autoinc(struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    SET_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF);
+}
+
+void systimer_armv8_m_disable_autoinc(struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF);
+}
+
+bool systimer_armv8_m_is_autoinc_enabled(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntp_aival_ctl,
+                   SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF);
+}
+
+void systimer_armv8_m_clear_autoinc_interrupt(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    CLR_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_IRQ_CLR_OFF);
+}
+
+bool systimer_armv8_m_is_autoinc_implemented(
+        struct systimer_armv8_m_dev_t* dev)
+{
+    struct cnt_base_reg_map_t* p_cnt =
+            (struct cnt_base_reg_map_t*)dev->cfg->base;
+    return GET_BIT(p_cnt->cntp_cfg,
+                   SYSCTIMER_ARMV8M_CNTP_CFG_CTL_AUTOINC_OFF);
+}
+
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/systimer_armv8-m_drv.h b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/systimer_armv8-m_drv.h
new file mode 100644
index 0000000..d14d2f7
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/systimer_armv8-m_drv.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2019 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file systimer_armv8-m_drv.h
+ *
+ * \brief Driver for Armv8-M System Timer
+ *
+ * This System Timer is based on the 64-bit Armv8-M System Counter,
+ * generating the physical count for System Timer.
+ *
+ * Main features:
+ *   - Disabling the timer doesn't stop counting, but it disables timer output
+ *     signal, what might be a power saving option.
+ *   - 1 interrupt signal, can be triggered by the 2 modes below
+ *      Modes:
+ *          1. Normal mode
+ *          For clearing the interrupt generated by normal mode, the Timer
+ *          should be disabled.
+ *              Views
+ *                  1.1. 64-bit up-counting Compare view
+ *                       As soon as the physical up-counter reaches the set
+ *                       compare value, the interrupt status will be asserted.
+ *                       \ref systimer_armv8_m_set_compare_value
+ *                       \ref systimer_armv8_m_get_compare_value
+
+ *                  1.2. 32-bit down-counting Timer view
+ *                       As soon as the down-counter timer reaches zero,
+ *                       the interrupt status will be asserted.
+ *                       Setting the down-counter timer value, sets the compare
+ *                       register by
+ *                         compare register = current counter + timer value
+ *                       \ref systimer_armv8_m_set_timer_value
+ *                       \ref systimer_armv8_m_get_timer_value
+ *
+ *          2. Auto-Increment mode
+ *              - The auto-increment feature allows generation of Timer
+ *                interrupt at regular intervals without the need for
+ *                reprogramming the Timer after each interrupt and re-enabling
+ *                the timer logic.
+ *              - Auto-increment is working as a 64-bit up-counter, which is set
+ *                by the 32-bit reload register.
+ *              - If auto-increment mode is enabled, none of the normal modes'
+ *                views can assert interrupt. *
+ *              \ref systimer_armv8_m_get_autoinc_value
+ *              \ref systimer_armv8_m_set_autoinc_reload
+ *              \ref systimer_armv8_m_enable_autoinc
+ *              \ref systimer_armv8_m_disable_autoinc
+ *              \ref systimer_armv8_m_is_autoinc_enabled
+ *              \ref systimer_armv8_m_clear_autoinc_interrupt
+ *              \ref systimer_armv8_m_is_autoinc_implemented
+ *
+ */
+
+#ifndef __SYSTIMER_ARMV8_M_DRV_H__
+#define __SYSTIMER_ARMV8_M_DRV_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH          32u
+    /*!< Armv8-M System Timer registers bit width */
+
+/**
+ *  \brief Armv8-M System Timer device configuration structure
+ */
+struct systimer_armv8_m_dev_cfg_t {
+    const uint32_t base;
+        /*!< Armv8-M System Timer device base address */
+    uint32_t default_freq_hz;
+        /*!< Default reported frequency in Hz */
+};
+
+/**
+ * \brief Armv8-M System Timer device data structure
+ */
+struct systimer_armv8_m_dev_data_t {
+    bool is_initialized;
+};
+
+/**
+ * \brief Armv8-M System Timer device structure
+ */
+struct systimer_armv8_m_dev_t {
+    const struct systimer_armv8_m_dev_cfg_t* const cfg;
+        /*!< Armv8-M System Timer configuration structure */
+    struct systimer_armv8_m_dev_data_t* const data;
+        /*!< Armv8-M System Timer data structure */
+};
+
+/**
+ * \brief Initializes timer to a known default state, which is:
+ *          - timer is enabled
+ *          - interrupt is disabled
+ *          - auto-increment is disabled
+ *          - reported timer frequency is set to default
+ *        Init should be called prior to any other process and
+ *        it's the caller's responsibility to follow proper call order.
+ *        More than one call results fall through.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_init(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Uninitializes timer to a known default state, which is:
+ *          - timer is disabled
+ *          - interrupt is disabled
+ *          - auto-increment is disabled
+ *        Init should be called prior to any other process and
+ *        it's the caller's responsibility to follow proper call order.
+ *        More than one call results fall through.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_uninit(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Reads 64-bit physical counter value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 64-bit counter value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t systimer_armv8_m_get_counter_value(
+           struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets 64-bit compare value
+ *        As soon as the physical up-counter reaches this value, the interrupt
+ *        condition will be asserted \ref systimer_armv8_m_is_interrupt_asserted
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value 64-bit compare value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_compare_value(
+        struct systimer_armv8_m_dev_t* dev,
+        uint64_t value);
+
+/**
+ * \brief Reads 64-bit compare value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 64-bit compare value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t systimer_armv8_m_get_compare_value(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets frequency register in Hz
+ *        Hardware does not interpret the value of the register, so it's only
+ *        for software can discover the frequency of the system counter.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value frequency in Hz
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_counter_freq(
+        struct systimer_armv8_m_dev_t* dev,
+        uint32_t value);
+
+/**
+ * \brief Reads frequency register in Hz
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return frequency in Hz
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t systimer_armv8_m_get_counter_freq(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets 32-bit down-counter timer value
+ *        'Down-counter timer set' automatically sets the compare register by
+ *        compare register = current counter + this timer value
+ *
+ *        As soon as the timer value reaches zero, the interrupt condition will
+ *        be asserted \ref systimer_armv8_m_is_interrupt_asserted.
+ *        Reaching zero doesn't stop the timer.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value 32-bit timer value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_timer_value(struct systimer_armv8_m_dev_t* dev,
+                                      uint32_t value);
+
+/**
+ * \brief Reads down-counter timer value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 32-bit timer value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t systimer_armv8_m_get_timer_value(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Enables timer
+ *        Enables timer output signal and interrupt status assertion
+ *        \ref systimer_armv8_m_is_interrupt_asserted
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_enable_timer(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Disables timer
+ *        Disables timer output signal. Interrupt status will be unknown
+ *        \ref systimer_armv8_m_is_interrupt_asserted
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_disable_timer(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls timer enable status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_timer_enabled(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Enables timer interrupt
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_enable_interrupt(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Disables timer interrupt
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_disable_interrupt(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls timer interrupt enable status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_interrupt_enabled(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls timer interrupt status
+ *        It's asserted if
+ *          1. Auto-Inc is disabled and counter reaches compare value
+ *          OR
+ *          2. Auto-Inc is enabled and counter reaches auto-inc value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if asserted, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_interrupt_asserted(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Reads auto-increment value
+ *        This value is automatically calculated by
+ *        auto-inc = current counter + auto-inc reload
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 64-bit auto-increment value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t systimer_armv8_m_get_autoinc_value(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets 32-bit auto-increment reload value
+ *        Auto-Inc value is automatically calculated by adding this reload value
+ *        to the current counter.
+ *        If the counter reaches auto-inc value, interrupt status is asserted
+ *        and auto-inc value is automatically set by current reload.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value 32-bit reload value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_autoinc_reload(
+        struct systimer_armv8_m_dev_t* dev,
+        uint32_t value);
+
+/**
+ * \brief Reads auto-increment reload value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 32-bit auto-increment reload value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t systimer_armv8_m_get_autoinc_reload(
+           struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Enables auto-increment mode
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_enable_autoinc(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Disables auto-increment mode
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_disable_autoinc(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls auto-increment enable status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_autoinc_enabled(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Clears auto-increment mode interrupt flag
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_clear_autoinc_interrupt(
+        struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls auto-increment implementation status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if implemented, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_autoinc_implemented(
+        struct systimer_armv8_m_dev_t* dev);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __SYSTIMER_ARMV8_M_DRV_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/uart_cmsdk_drv.c b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/uart_cmsdk_drv.c
new file mode 100644
index 0000000..c3d1230
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/uart_cmsdk_drv.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2016-2019 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "uart_cmsdk_drv.h"
+
+#include <stddef.h>
+
+/* UART register map structure */
+struct _uart_cmsdk_reg_map_t {
+    volatile uint32_t data;   /* Offset: 0x000 (R/W) data register    */
+    volatile uint32_t state;  /* Offset: 0x004 (R/W) status register  */
+    volatile uint32_t ctrl;   /* Offset: 0x008 (R/W) control register */
+    union {
+        volatile uint32_t intrstatus;  /* Offset: 0x00c (R/ ) interrupt status
+                                        *                     register
+                                        */
+        volatile uint32_t intrclear;   /* Offset: 0x00c ( /W) interrupt clear
+                                        *                     register
+                                        */
+    }intr_reg;
+    volatile uint32_t bauddiv;        /* Offset: 0x010 (R/W) Baudrate divider
+                                       *                     register
+                                       */
+};
+
+/* CTRL Register */
+#define UART_CMSDK_TX_EN       (1ul << 0)
+#define UART_CMSDK_RX_EN       (1ul << 1)
+#define UART_CMSDK_TX_INTR_EN  (1ul << 2)
+#define UART_CMSDK_RX_INTR_EN  (1ul << 3)
+
+/* STATE Register */
+#define UART_CMSDK_TX_BF  (1ul << 0)
+#define UART_CMSDK_RX_BF  (1ul << 1)
+
+/* INTSTATUS Register */
+#define UART_CMSDK_TX_INTR  (1ul << 0)
+#define UART_CMSDK_RX_INTR  (1ul << 1)
+
+/* UART state definitions */
+#define UART_CMSDK_INITIALIZED  (1ul << 0)
+
+enum uart_cmsdk_error_t uart_cmsdk_init(struct uart_cmsdk_dev_t* dev,
+                                    uint32_t system_clk)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+    if(system_clk == 0) {
+        return UART_CMSDK_ERR_INVALID_ARG;
+    }
+
+    /* Sets baudrate and system clock */
+    dev->data->system_clk = system_clk;
+    dev->data->baudrate = dev->cfg->default_baudrate;
+
+    /* Sets baudrate */
+    p_uart->bauddiv = (dev->data->system_clk / dev->cfg->default_baudrate);
+
+    /* Enables receiver and transmitter */
+    p_uart->ctrl = UART_CMSDK_RX_EN | UART_CMSDK_TX_EN;
+
+    dev->data->state = UART_CMSDK_INITIALIZED;
+
+    return UART_CMSDK_ERR_NONE;
+}
+
+enum uart_cmsdk_error_t uart_cmsdk_set_baudrate(struct uart_cmsdk_dev_t* dev,
+                                            uint32_t baudrate)
+{
+    uint32_t bauddiv;
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(baudrate == 0) {
+        return UART_CMSDK_ERR_INVALID_BAUD;
+    }
+
+    if(!(dev->data->state & UART_CMSDK_INITIALIZED)) {
+        return UART_CMSDK_ERR_NOT_INIT;
+    }
+
+    /* Sets baudrate */
+    bauddiv = (dev->data->system_clk / baudrate);
+    dev->data->baudrate = baudrate;
+
+    /* Minimum bauddiv value */
+    if(bauddiv < 16) {
+        return UART_CMSDK_ERR_INVALID_BAUD;
+    }
+
+    p_uart->bauddiv = bauddiv;
+
+    return UART_CMSDK_ERR_NONE;
+}
+
+uint32_t uart_cmsdk_get_baudrate(struct uart_cmsdk_dev_t* dev)
+{
+    return dev->data->baudrate;
+}
+
+enum uart_cmsdk_error_t uart_cmsdk_set_clock(struct uart_cmsdk_dev_t* dev,
+                                         uint32_t system_clk)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(system_clk == 0) {
+        return UART_CMSDK_ERR_INVALID_ARG;
+    }
+
+    if(!(dev->data->state & UART_CMSDK_INITIALIZED)) {
+        return UART_CMSDK_ERR_NOT_INIT;
+    }
+
+    /* Sets system clock */
+    dev->data->system_clk = system_clk;
+
+    /* Updates baudrate divider */
+    p_uart->bauddiv = (dev->data->system_clk / dev->data->baudrate);
+
+    /* Enables receiver and transmitter */
+    return UART_CMSDK_ERR_NONE;
+}
+
+enum uart_cmsdk_error_t uart_cmsdk_read(struct uart_cmsdk_dev_t* dev,
+                                                                 uint8_t* byte)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(!(p_uart->state & UART_CMSDK_RX_BF)) {
+        return UART_CMSDK_ERR_NOT_READY;
+    }
+
+    /* Reads data */
+    *byte = (uint8_t)p_uart->data;
+
+    return UART_CMSDK_ERR_NONE;
+}
+
+enum uart_cmsdk_error_t uart_cmsdk_write(struct uart_cmsdk_dev_t* dev,
+                                                                  uint8_t byte)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(p_uart->state & UART_CMSDK_TX_BF) {
+        return UART_CMSDK_ERR_NOT_READY;
+    }
+
+    /* Sends data */
+    p_uart->data = byte;
+
+    return UART_CMSDK_ERR_NONE;
+}
+
+enum uart_cmsdk_error_t uart_cmsdk_irq_tx_enable(struct uart_cmsdk_dev_t* dev)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(!(dev->data->state & UART_CMSDK_INITIALIZED)) {
+        return UART_CMSDK_ERR_NOT_INIT;
+    }
+
+    p_uart->ctrl |= UART_CMSDK_TX_INTR_EN;
+
+    return UART_CMSDK_ERR_NONE;
+}
+
+void uart_cmsdk_irq_tx_disable(struct uart_cmsdk_dev_t* dev)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->state & UART_CMSDK_INITIALIZED ) {
+        p_uart->ctrl &= ~UART_CMSDK_TX_INTR_EN;
+    }
+}
+
+uint32_t uart_cmsdk_tx_ready(struct uart_cmsdk_dev_t* dev)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(!(dev->data->state & UART_CMSDK_INITIALIZED)) {
+        return 0;
+    }
+
+    return !(p_uart->state & UART_CMSDK_TX_BF);
+}
+
+enum uart_cmsdk_error_t uart_cmsdk_irq_rx_enable(struct uart_cmsdk_dev_t* dev)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(!(dev->data->state & UART_CMSDK_INITIALIZED)) {
+        return UART_CMSDK_ERR_NOT_INIT;
+    }
+
+    p_uart->ctrl |= UART_CMSDK_RX_INTR_EN;
+
+    return UART_CMSDK_ERR_NONE;
+}
+
+void uart_cmsdk_irq_rx_disable(struct uart_cmsdk_dev_t* dev)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->state & UART_CMSDK_INITIALIZED) {
+        p_uart->ctrl &= ~UART_CMSDK_RX_INTR_EN;
+    }
+}
+
+uint32_t uart_cmsdk_rx_ready(struct uart_cmsdk_dev_t* dev)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                  (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(!(dev->data->state & UART_CMSDK_INITIALIZED)) {
+        return 0;
+    }
+
+    return (p_uart->state & UART_CMSDK_RX_BF);
+}
+
+void uart_cmsdk_clear_interrupt(struct uart_cmsdk_dev_t* dev,
+                              enum uart_cmsdk_irq_t irq)
+{
+    struct _uart_cmsdk_reg_map_t* p_uart =
+                                 (struct _uart_cmsdk_reg_map_t*)dev->cfg->base;
+
+    if(dev->data->state & UART_CMSDK_INITIALIZED) {
+        /* Clears pending interrupts */
+        switch(irq) {
+        case UART_CMSDK_IRQ_RX:
+            p_uart->intr_reg.intrclear = UART_CMSDK_RX_INTR;
+            break;
+        case UART_CMSDK_IRQ_TX:
+            p_uart->intr_reg.intrclear = UART_CMSDK_TX_INTR;
+            break;
+        case UART_CMSDK_IRQ_COMBINED:
+            p_uart->intr_reg.intrclear =
+                                      (UART_CMSDK_RX_INTR | UART_CMSDK_TX_INTR);
+            break;
+        /* default: not defined to force all cases to be handled */
+        }
+    }
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/uart_cmsdk_drv.h b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/uart_cmsdk_drv.h
new file mode 100644
index 0000000..2d3278e
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/native_drivers/uart_cmsdk_drv.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2016-2019 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file uart_cmsdk_drv.h
+ * \brief Generic driver for ARM UART.
+ */
+
+#ifndef __UART_CMSDK_DRV_H__
+#define __UART_CMSDK_DRV_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ARM UART device configuration structure */
+struct uart_cmsdk_dev_cfg_t {
+    const uint32_t base;              /*!< UART base address */
+    const uint32_t default_baudrate;  /*!< Default baudrate */
+};
+
+/* ARM UART device data structure */
+struct uart_cmsdk_dev_data_t {
+    uint32_t state;       /*!< Indicates if the uart driver
+                           *   is initialized and enabled
+                           */
+    uint32_t system_clk;  /*!< System clock */
+    uint32_t baudrate;    /*!< Baudrate */
+};
+
+/* ARM UART device structure */
+struct uart_cmsdk_dev_t {
+    const struct uart_cmsdk_dev_cfg_t* const cfg;  /*!< UART configuration */
+    struct uart_cmsdk_dev_data_t* const data;      /*!< UART data */
+};
+
+/* ARM UART enumeration types */
+enum uart_cmsdk_error_t {
+    UART_CMSDK_ERR_NONE = 0,      /*!< No error */
+    UART_CMSDK_ERR_INVALID_ARG,   /*!< Error invalid input argument */
+    UART_CMSDK_ERR_INVALID_BAUD,  /*!< Invalid baudrate */
+    UART_CMSDK_ERR_NOT_INIT,      /*!< Error UART not initialized */
+    UART_CMSDK_ERR_NOT_READY,     /*!< Error UART not ready */
+};
+
+enum uart_cmsdk_irq_t {
+    UART_CMSDK_IRQ_RX,       /*!< RX interrupt source */
+    UART_CMSDK_IRQ_TX,       /*!< TX interrupt source */
+    UART_CMSDK_IRQ_COMBINED  /*!< RX-TX combined interrupt source */
+};
+
+/**
+ * \brief Initializes UART. It uses the default baudrate to configure
+ * the peripheral at this point.
+ *
+ * \param[in] dev         UART device struct \ref uart_cmsdk_dev_t
+ * \param[in] system_clk  System clock used by the device.
+ *
+ * \return Returns error code as specified in \ref uart_cmsdk_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum uart_cmsdk_error_t uart_cmsdk_init(struct uart_cmsdk_dev_t* dev,
+                                    uint32_t system_clk);
+
+/**
+ * \brief Sets the UART baudrate.
+ *
+ * \param[in] dev       UART device struct \ref uart_cmsdk_dev_t
+ * \param[in] baudrate  New baudrate.
+ *
+ * \return Returns error code as specified in \ref uart_cmsdk_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum uart_cmsdk_error_t uart_cmsdk_set_baudrate(struct uart_cmsdk_dev_t* dev,
+                                            uint32_t baudrate);
+
+/**
+ * \brief Gets the UART baudrate.
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ *
+ * \return Returns the UART baudrate.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t uart_cmsdk_get_baudrate(struct uart_cmsdk_dev_t* dev);
+
+/**
+ * \brief Sets system clock.
+ *
+ * \param[in] dev         UART device struct \ref uart_cmsdk_dev_t
+ * \param[in] system_clk  System clock used by the device.
+ *
+ * \return Returns error code as specified in \ref uart_cmsdk_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum uart_cmsdk_error_t uart_cmsdk_set_clock(struct uart_cmsdk_dev_t* dev,
+                                         uint32_t system_clk);
+/**
+ * \brief Reads one byte from UART dev.
+ *
+ * \param[in] dev   UART device struct \ref uart_cmsdk_dev_t
+ * \param[in] byte  Pointer to byte.
+ *
+ * \return Returns error code as specified in \ref uart_cmsdk_error_t
+ *
+ * \note For better performance, this function doesn't check if dev and byte
+ * pointer are NULL, and if the driver is initialized.
+ */
+enum uart_cmsdk_error_t uart_cmsdk_read(struct uart_cmsdk_dev_t* dev,
+                                                                uint8_t* byte);
+
+/**
+ * \brief Writes a byte to UART dev.
+ *
+ * \param[in] dev   UART device struct \ref uart_cmsdk_dev_t
+ * \param[in] byte  Byte to write.
+ *
+ * \return Returns error code as specified in \ref uart_cmsdk_error_t
+ *
+ * \note For better performance, this function doesn't check if dev is NULL and
+ * if the driver is initialized to have better performance.
+ */
+enum uart_cmsdk_error_t uart_cmsdk_write(struct uart_cmsdk_dev_t* dev,
+                                                                 uint8_t byte);
+
+/**
+ * \brief Enables TX interrupt.
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ *
+ * \return Returns error code as specified in \ref uart_cmsdk_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum uart_cmsdk_error_t uart_cmsdk_irq_tx_enable(struct uart_cmsdk_dev_t* dev);
+
+/**
+ * \brief Disables TX interrupt.
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void uart_cmsdk_irq_tx_disable(struct uart_cmsdk_dev_t* dev);
+
+/**
+ * \brief  Verifies if Tx is ready to send more data.
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ *
+ * \return  1 if TX is ready, 0 otherwise.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t uart_cmsdk_tx_ready(struct uart_cmsdk_dev_t* dev);
+
+/**
+ * \brief Enables RX interrupt.
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ *
+ * \return Returns error code as specified in \ref uart_cmsdk_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum uart_cmsdk_error_t uart_cmsdk_irq_rx_enable(struct uart_cmsdk_dev_t* dev);
+
+/**
+ * \brief Disables RX interrupt
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void uart_cmsdk_irq_rx_disable(struct uart_cmsdk_dev_t* dev);
+
+/**
+ * \brief Verifies if Rx has data.
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ *
+ * \return 1 if RX has data, 0 otherwise.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t uart_cmsdk_rx_ready(struct uart_cmsdk_dev_t* dev);
+
+/**
+ * \brief Clears UART interrupt.
+ *
+ * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
+ * \param[in] irq  IRQ source to clean \ref uart_cmsdk_irq_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void uart_cmsdk_clear_interrupt(struct uart_cmsdk_dev_t* dev,
+                              enum uart_cmsdk_irq_t irq);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __UART_CMSDK_DRV_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/partition/flash_layout.h b/platform/ext/target/arm/mps3/corstone_polaris/partition/flash_layout.h
new file mode 100644
index 0000000..d92041a
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/partition/flash_layout.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FLASH_LAYOUT_H__
+#define __FLASH_LAYOUT_H__
+
+#include "platform_base_address.h"
+
+/* Flash layout on Corstone-Polaris with BL2 (multiple image boot):
+ *
+ * 0x0000_0000 Secure image     primary slot (384 KB)
+ * 0x0006_0000 Non-secure image primary slot (384 KB)
+ * 0x000C_0000 Secure image     secondary slot (384 KB)
+ * 0x0012_0000 Non-secure image secondary slot (384 KB)
+ * 0x0018_0000 Scratch area (384 KB)
+ * 0x001E_0000 Protected Storage Area (20 KB)
+ * 0x001E_5000 Internal Trusted Storage Area (16 KB)
+ * 0x001E_9000 OTP / NV counters  area (8 KB)
+ * 0x001E_B000 Unused
+ *
+ * Flash layout on Corstone-Polaris with BL2 (single image boot):
+ *
+ * 0x0000_0000 Primary image area (768 KB):
+ *    0x0000_0000 Secure     image primary (384 KB)
+ *    0x0006_0000 Non-secure image primary (384 KB)
+ * 0x000C_0000 Secondary image area (768 KB):
+ *    0x000C_0000 Secure     image secondary (384 KB)
+ *    0x0012_0000 Non-secure image secondary (384 KB)
+ * 0x0018_0000 Scratch area (384 KB)
+ * 0x001C_0000 Protected Storage Area (20 KB)
+ * 0x001C_5000 Internal Trusted Storage Area (16 KB)
+ * 0x001C_9000 NV counters area (4 KB)
+ * 0x001E_9000 OTP / NV counters  area (8 KB)
+ * 0x001E_B000 Unused
+ */
+
+
+
+/* This header file is included from linker scatter file as well, where only a
+ * limited C constructs are allowed. Therefore it is not possible to include
+ * here the platform_retarget.h to access flash related defines. To resolve this
+ * some of the values are redefined here with different names, these are marked
+ * with comment.
+ */
+
+/* Size of a Secure and of a Non-secure image */
+#define FLASH_S_PARTITION_SIZE          (0x60000) /* S  partition: 384 KB */
+#define FLASH_NS_PARTITION_SIZE         (0x60000) /* NS partition: 384 KB */
+#define FLASH_MAX_PARTITION_SIZE        ((FLASH_S_PARTITION_SIZE >   \
+                                          FLASH_NS_PARTITION_SIZE) ? \
+                                         FLASH_S_PARTITION_SIZE :    \
+                                         FLASH_NS_PARTITION_SIZE)
+
+/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */
+#define FLASH_AREA_IMAGE_SECTOR_SIZE    (0x1000)     /* 4 KB */
+/* Same as FLASH0_SIZE */
+#define FLASH_TOTAL_SIZE                (SRAM_SIZE)  /* 2 MB */
+
+/* Flash layout info for BL2 bootloader */
+/* Same as FLASH0_BASE_S */
+#define FLASH_BASE_ADDRESS              (SRAM_BASE_S)
+
+/* Offset and size definitions of the flash partitions that are handled by the
+ * bootloader. The image swapping is done between IMAGE_PRIMARY and
+ * IMAGE_SECONDARY, SCRATCH is used as a temporary storage during image
+ * swapping.
+ */
+#define FLASH_AREA_BL2_OFFSET      (0x0)
+#define FLASH_AREA_BL2_SIZE        (ITCM_SIZE) /* 256 KB */
+
+#if !defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1)
+/* Secure + Non-secure image primary slot */
+#define FLASH_AREA_0_ID            (1)
+#define FLASH_AREA_0_OFFSET        (0)
+#define FLASH_AREA_0_SIZE          (FLASH_S_PARTITION_SIZE + \
+                                    FLASH_NS_PARTITION_SIZE)
+/* Secure + Non-secure secondary slot */
+#define FLASH_AREA_2_ID            (FLASH_AREA_0_ID + 1)
+#define FLASH_AREA_2_OFFSET        (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
+#define FLASH_AREA_2_SIZE          (FLASH_S_PARTITION_SIZE + \
+                                    FLASH_NS_PARTITION_SIZE)
+/* Scratch area */
+#define FLASH_AREA_SCRATCH_ID      (FLASH_AREA_2_ID + 1)
+#define FLASH_AREA_SCRATCH_OFFSET  (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
+#define FLASH_AREA_SCRATCH_SIZE    (FLASH_MAX_PARTITION_SIZE)
+/* The maximum number of status entries supported by the bootloader. */
+#define MCUBOOT_STATUS_MAX_ENTRIES ((FLASH_S_PARTITION_SIZE + \
+                                     FLASH_NS_PARTITION_SIZE) / \
+                                    FLASH_AREA_SCRATCH_SIZE)
+/* Maximum number of image sectors supported by the bootloader. */
+#define MCUBOOT_MAX_IMG_SECTORS    ((FLASH_S_PARTITION_SIZE + \
+                                     FLASH_NS_PARTITION_SIZE) / \
+                                    FLASH_AREA_IMAGE_SECTOR_SIZE)
+#elif (MCUBOOT_IMAGE_NUMBER == 2)
+/* Secure image primary slot */
+#define FLASH_AREA_0_ID            (1)
+#define FLASH_AREA_0_OFFSET        (0)
+#define FLASH_AREA_0_SIZE          (FLASH_S_PARTITION_SIZE)
+/* Non-secure image primary slot */
+#define FLASH_AREA_1_ID            (FLASH_AREA_0_ID + 1)
+#define FLASH_AREA_1_OFFSET        (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
+#define FLASH_AREA_1_SIZE          (FLASH_NS_PARTITION_SIZE)
+/* Secure image secondary slot */
+#define FLASH_AREA_2_ID            (FLASH_AREA_1_ID + 1)
+#define FLASH_AREA_2_OFFSET        (FLASH_AREA_1_OFFSET + FLASH_AREA_1_SIZE)
+#define FLASH_AREA_2_SIZE          (FLASH_S_PARTITION_SIZE)
+/* Non-secure image secondary slot */
+#define FLASH_AREA_3_ID            (FLASH_AREA_2_ID + 1)
+#define FLASH_AREA_3_OFFSET        (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
+#define FLASH_AREA_3_SIZE          (FLASH_NS_PARTITION_SIZE)
+/* Scratch area */
+#define FLASH_AREA_SCRATCH_ID      (FLASH_AREA_3_ID + 1)
+#define FLASH_AREA_SCRATCH_OFFSET  (FLASH_AREA_3_OFFSET + FLASH_AREA_3_SIZE)
+#define FLASH_AREA_SCRATCH_SIZE    (FLASH_MAX_PARTITION_SIZE)
+/* The maximum number of status entries supported by the bootloader. */
+#define MCUBOOT_STATUS_MAX_ENTRIES (FLASH_MAX_PARTITION_SIZE / \
+                                    FLASH_AREA_SCRATCH_SIZE)
+/* Maximum number of image sectors supported by the bootloader. */
+#define MCUBOOT_MAX_IMG_SECTORS    (FLASH_MAX_PARTITION_SIZE / \
+                                    FLASH_AREA_IMAGE_SECTOR_SIZE)
+#else /* MCUBOOT_IMAGE_NUMBER > 2 */
+#error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!"
+#endif /* MCUBOOT_IMAGE_NUMBER */
+
+/* mpc_init_cfg function in target_cfg.c expects that all the images can fit
+ * in SRAM area. */
+#if ( FLASH_AREA_SCRATCH_OFFSET + FLASH_AREA_SCRATCH_SIZE > SRAM_SIZE)
+#error "Out of SRAM memory!"
+#endif
+
+/* Protected Storage (PS) Service definitions */
+#define FLASH_PS_AREA_OFFSET            (FLASH_AREA_SCRATCH_OFFSET + \
+                                         FLASH_AREA_SCRATCH_SIZE)
+#define FLASH_PS_AREA_SIZE              (0x5000)   /* 20 KB */
+
+/* Internal Trusted Storage (ITS) Service definitions */
+#define FLASH_ITS_AREA_OFFSET           (FLASH_PS_AREA_OFFSET + \
+                                         FLASH_PS_AREA_SIZE)
+#define FLASH_ITS_AREA_SIZE             (0x4000)   /* 16 KB */
+
+/* OTP_definitions */
+#define FLASH_OTP_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + \
+                                           FLASH_ITS_AREA_SIZE)
+#define FLASH_OTP_NV_COUNTERS_AREA_SIZE   (FLASH_AREA_IMAGE_SECTOR_SIZE * 2)
+#define FLASH_OTP_NV_COUNTERS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
+
+/* Offset and size definition in flash area used by assemble.py */
+#define SECURE_IMAGE_OFFSET             (0x0)
+#define SECURE_IMAGE_MAX_SIZE           FLASH_S_PARTITION_SIZE
+
+#define NON_SECURE_IMAGE_OFFSET         (SECURE_IMAGE_OFFSET + \
+                                         SECURE_IMAGE_MAX_SIZE)
+#define NON_SECURE_IMAGE_MAX_SIZE       FLASH_NS_PARTITION_SIZE
+
+/* Flash device name used by BL2
+ * Name is defined in flash driver file: Driver_Flash.c
+ */
+#define FLASH_DEV_NAME Driver_FLASH0
+/* Smallest flash programmable unit in bytes */
+#define TFM_HAL_FLASH_PROGRAM_UNIT       (0x1)
+
+/* Protected Storage (PS) Service definitions
+ * Note: Further documentation of these definitions can be found in the
+ * TF-M PS Integration Guide.
+ */
+#define TFM_HAL_PS_FLASH_DRIVER Driver_FLASH0
+
+/* In this target the CMSIS driver requires only the offset from the base
+ * address instead of the full memory address.
+ */
+/* Base address of dedicated flash area for PS */
+#define TFM_HAL_PS_FLASH_AREA_ADDR    FLASH_PS_AREA_OFFSET
+/* Size of dedicated flash area for PS */
+#define TFM_HAL_PS_FLASH_AREA_SIZE    FLASH_PS_AREA_SIZE
+#define PS_RAM_FS_SIZE                TFM_HAL_PS_FLASH_AREA_SIZE
+/* Number of physical erase sectors per logical FS block */
+#define TFM_HAL_PS_SECTORS_PER_BLOCK  (1)
+/* Smallest flash programmable unit in bytes */
+#define TFM_HAL_PS_PROGRAM_UNIT       (0x1)
+
+/* Internal Trusted Storage (ITS) Service definitions
+ * Note: Further documentation of these definitions can be found in the
+ * TF-M ITS Integration Guide. The ITS should be in the internal flash, but is
+ * allocated in the external flash just for development platforms that don't
+ * have internal flash available.
+ */
+#define TFM_HAL_ITS_FLASH_DRIVER Driver_FLASH0
+
+/* In this target the CMSIS driver requires only the offset from the base
+ * address instead of the full memory address.
+ */
+/* Base address of dedicated flash area for ITS */
+#define TFM_HAL_ITS_FLASH_AREA_ADDR    FLASH_ITS_AREA_OFFSET
+/* Size of dedicated flash area for ITS */
+#define TFM_HAL_ITS_FLASH_AREA_SIZE    FLASH_ITS_AREA_SIZE
+#define ITS_RAM_FS_SIZE                TFM_HAL_ITS_FLASH_AREA_SIZE
+/* Number of physical erase sectors per logical FS block */
+#define TFM_HAL_ITS_SECTORS_PER_BLOCK  (1)
+/* Smallest flash programmable unit in bytes */
+#define TFM_HAL_ITS_PROGRAM_UNIT       (0x1)
+
+/* OTP / NV counter definitions */
+#define TFM_OTP_NV_COUNTERS_AREA_SIZE   (FLASH_OTP_NV_COUNTERS_AREA_SIZE / 2)
+#define TFM_OTP_NV_COUNTERS_AREA_ADDR   FLASH_OTP_NV_COUNTERS_AREA_OFFSET
+#define TFM_OTP_NV_COUNTERS_SECTOR_SIZE FLASH_OTP_NV_COUNTERS_SECTOR_SIZE
+#define TFM_OTP_NV_COUNTERS_BACKUP_AREA_ADDR (TFM_OTP_NV_COUNTERS_AREA_ADDR + \
+                                              TFM_OTP_NV_COUNTERS_AREA_SIZE)
+
+#endif /* __FLASH_LAYOUT_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/partition/platform_base_address.h b/platform/ext/target/arm/mps3/corstone_polaris/partition/platform_base_address.h
new file mode 100644
index 0000000..265a540
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/partition/platform_base_address.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file platform_base_address.h
+ * \brief This file defines all the peripheral base addresses for Corstone-Polaris.
+ */
+
+#ifndef __PLATFORM_BASE_ADDRESS_H__
+#define __PLATFORM_BASE_ADDRESS_H__
+
+/* ======= Defines peripherals memory map addresses ======= */
+/* Non-secure memory map addresses */
+#define ITCM_BASE_NS                     0x00000000 /* Instruction TCM Non-Secure base address */
+#define SRAM_BASE_NS                     0x01000000 /* CODE SRAM Non-Secure base address */
+#define DTCM0_BASE_NS                    0x20000000 /* Data TCM block 0 Non-Secure base address */
+#define DTCM1_BASE_NS                    0x20020000 /* Data TCM block 1 Non-Secure base address */
+#define DTCM2_BASE_NS                    0x20040000 /* Data TCM block 2 Non-Secure base address */
+#define DTCM3_BASE_NS                    0x20060000 /* Data TCM block 3 Non-Secure base address */
+#define ISRAM0_BASE_NS                   0x21000000 /* Internal SRAM Area Non-Secure base address */
+#define ISRAM1_BASE_NS                   0x21080000 /* Internal SRAM Area Non-Secure base address */
+#define QSPI_SRAM_BASE_NS                0x28000000 /* QSPI SRAM Non-Secure base address */
+/* Non-Secure Subsystem peripheral region */
+#define ETHOS_U55_APB_BASE_NS            0x40004000 /* Ethos-U55 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 POLARIS_NSACFG_BASE_NS           0x40080000 /* Polaris Non-Secure Access Configuration Register Block Non-Secure base address */
+/* Non-Secure MSTEXPPILL Peripheral region */
+#define GPIO0_CMSDK_BASE_NS              0x41100000 /* GPIO 0 Non-Secure base address */
+#define GPIO1_CMSDK_BASE_NS              0x41101000 /* GPIO 1 Non-Secure base address */
+#define GPIO2_CMSDK_BASE_NS              0x41102000 /* GPIO 2 Non-Secure base address */
+#define GPIO3_CMSDK_BASE_NS              0x41103000 /* GPIO 3 Non-Secure base address */
+#define AHB_USER_0_BASE_NS               0x41104000 /* AHB USER 0 Non-Secure base address */
+#define AHB_USER_1_BASE_NS               0x41105000 /* AHB USER 1 Non-Secure base address */
+#define AHB_USER_2_BASE_NS               0x41106000 /* AHB USER 2 Non-Secure base address */
+#define AHB_USER_3_BASE_NS               0x41107000 /* AHB USER 3 Non-Secure base address */
+#define DMA_1_BASE_NS                    0x41201000 /* DMA 1 Non-Secure base address */
+#define DMA_2_BASE_NS                    0x41202000 /* DMA 2 Non-Secure base address */
+#define DMA_3_BASE_NS                    0x41203000 /* DMA 3 Non-Secure base address */
+#define ETHERNET_BASE_NS                 0x41400000 /* Ethernet Non-Secure base address */
+#define USB_BASE_NS                      0x41500000 /* USB Non-Secure base address */
+#define USER_APB0_BASE_NS                0x41700000 /* User APB 0 Non-Secure base address */
+#define USER_APB1_BASE_NS                0x41701000 /* User APB 1 Non-Secure base address */
+#define USER_APB2_BASE_NS                0x41702000 /* User APB 2 Non-Secure base address */
+#define USER_APB3_BASE_NS                0x41703000 /* User APB 3 Non-Secure base address */
+#define QSPI_CONFIG_BASE_NS              0x41800000 /* QSPI Config Non-Secure base address */
+#define QSPI_WRITE_BASE_NS               0x41801000 /* QSPI Write Non-Secure base address */
+/* Non-Secure Subsystem peripheral region */
+#define SYSTIMER0_ARMV8_M_BASE_NS        0x48000000 /* System Timer 0 Non-Secure base address */
+#define SYSTIMER1_ARMV8_M_BASE_NS        0x48001000 /* System Timer 1 Non-Secure base address */
+#define SYSTIMER2_ARMV8_M_BASE_NS        0x48002000 /* System Timer 2 Non-Secure base address */
+#define SYSTIMER3_ARMV8_M_BASE_NS        0x48003000 /* System Timer 3 Non-Secure base address */
+#define POLARIS_SYSINFO_BASE_NS          0x48020000 /* Polaris System info Block Non-Secure base address */
+#define SLOWCLK_TIMER_CMSDK_BASE_NS      0x4802F000 /* CMSDK based SLOWCLK Timer Non-Secure base address */
+#define SYSWDOG_ARMV8_M_CNTRL_BASE_NS    0x48040000 /* Non-Secure Watchdog Timer control frame Non-Secure base address */
+#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 */
+#define FPGA_SPI_SHIELD0_BASE_NS         0x49203000 /* FPGA - PL022 (SPI Shield0) Non-Secure base address */
+#define FPGA_SPI_SHIELD1_BASE_NS         0x49204000 /* FPGA - PL022 (SPI Shield1) Non-Secure base address */
+#define SBCon_I2C_SHIELD0_BASE_NS        0x49205000 /* SBCon (I2C - Shield0) Non-Secure base address */
+#define SBCon_I2C_SHIELD1_BASE_NS        0x49206000 /* SBCon (I2C – Shield1) Non-Secure base address */
+#define USER_APB_BASE_NS                 0x49207000 /* USER APB Non-Secure base address */
+#define FPGA_DDR4_EEPROM_BASE_NS         0x49208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Non-Secure base address */
+#define FPGA_SCC_BASE_NS                 0x49300000 /* FPGA - SCC registers Non-Secure base address */
+#define FPGA_I2S_BASE_NS                 0x49301000 /* FPGA - I2S (Audio) Non-Secure base address */
+#define FPGA_IO_BASE_NS                  0x49302000 /* FPGA - IO (System Ctrl + I/O) Non-Secure base address */
+#define UART0_BASE_NS                    0x49303000 /* UART 0 Non-Secure base address */
+#define UART1_BASE_NS                    0x49304000 /* UART 1 Non-Secure base address */
+#define UART2_BASE_NS                    0x49305000 /* UART 2 Non-Secure base address */
+#define UART3_BASE_NS                    0x49306000 /* UART 3 Non-Secure base address */
+#define UART4_BASE_NS                    0x49307000 /* UART 4 Non-Secure base address */
+#define UART5_BASE_NS                    0x49308000 /* UART 5 Non-Secure base address */
+#define CLCD_Config_Reg_BASE_NS          0x4930A000 /* CLCD Config Reg Non-Secure base address */
+#define RTC_BASE_NS                      0x4930B000 /* RTC Non-Secure base address */
+#define DDR4_BLK0_BASE_NS                0x60000000 /* DDR4 block 0 Non-Secure base address */
+#define DDR4_BLK2_BASE_NS                0x80000000 /* DDR4 block 2 Non-Secure base address */
+#define DDR4_BLK4_BASE_NS                0xA0000000 /* DDR4 block 4 Non-Secure base address */
+#define DDR4_BLK6_BASE_NS                0xC0000000 /* DDR4 block 6 Non-Secure base address */
+
+/* Secure memory map addresses */
+#define ITCM_BASE_S                      0x10000000 /* Instruction TCM Secure base address */
+#define SRAM_BASE_S                      0x11000000 /* CODE SRAM Secure base address */
+#define DTCM0_BASE_S                     0x30000000 /* Data TCM block 0 Secure base address */
+#define DTCM1_BASE_S                     0x30020000 /* Data TCM block 1 Secure base address */
+#define DTCM2_BASE_S                     0x30040000 /* Data TCM block 2 Secure base address */
+#define DTCM3_BASE_S                     0x30060000 /* Data TCM block 3 Secure base address */
+#define ISRAM0_BASE_S                    0x31000000 /* Internal SRAM Area Secure base address */
+#define ISRAM1_BASE_S                    0x31080000 /* Internal SRAM Area Secure base address */
+#define QSPI_SRAM_BASE_S                 0x38000000 /* QSPI SRAM Secure base address */
+/* Secure Subsystem peripheral region */
+#define ETHOS_U55_APB_BASE_S             0x50004000 /* Ethos-U55 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 */
+#define POLARIS_SACFG_BASE_S             0x50080000 /* Polaris Secure Access Configuration Register Secure base address */
+#define MPC_ISRAM0_BASE_S                0x50083000 /* Internal SRAM0 Memory Protection Controller Secure base address */
+#define MPC_ISRAM1_BASE_S                0x50084000 /* Internal SRAM1 Memory Protection Controller Secure base address */
+/* Secure MSTEXPPILL Peripheral region */
+#define GPIO0_CMSDK_BASE_S               0x51100000 /* GPIO 0 Secure base address */
+#define GPIO1_CMSDK_BASE_S               0x51101000 /* GPIO 1 Secure base address */
+#define GPIO2_CMSDK_BASE_S               0x51102000 /* GPIO 2 Secure base address */
+#define GPIO3_CMSDK_BASE_S               0x51103000 /* GPIO 3 Secure base address */
+#define AHB_USER_0_BASE_S                0x51104000 /* AHB USER 0 Secure base address */
+#define AHB_USER_1_BASE_S                0x51105000 /* AHB USER 1 Secure base address */
+#define AHB_USER_2_BASE_S                0x51106000 /* AHB USER 2 Secure base address */
+#define AHB_USER_3_BASE_S                0x51107000 /* AHB USER 3 Secure base address */
+#define DMA_1_BASE_S                     0x51201000 /* DMA 1 Secure base address */
+#define DMA_2_BASE_S                     0x51202000 /* DMA 2 Secure base address */
+#define DMA_3_BASE_S                     0x51203000 /* DMA 3 Secure base address */
+#define ETHERNET_BASE_S                  0x51400000 /* Ethernet Secure base address */
+#define USB_BASE_S                       0x51500000 /* USB Secure base address */
+#define USER_APB0_BASE_S                 0x51700000 /* User APB 0 Secure base address */
+#define USER_APB1_BASE_S                 0x51701000 /* User APB 1 Secure base address */
+#define USER_APB2_BASE_S                 0x51702000 /* User APB 2 Secure base address */
+#define USER_APB3_BASE_S                 0x51703000 /* User APB 3 Secure base address */
+#define QSPI_CONFIG_BASE_S               0x51800000 /* QSPI Config Secure base address */
+#define QSPI_WRITE_BASE_S                0x51801000 /* QSPI Write Secure base address */
+#define MPC_SRAM_BASE_S                  0x57000000 /* SRAM Memory Protection Controller Secure base address */
+#define MPC_QSPI_BASE_S                  0x57001000 /* QSPI Memory Protection Controller Secure base address */
+#define MPC_DDR4_BASE_S                  0x57002000 /* DDR4 Memory Protection Controller Secure base address */
+/* Secure Subsystem peripheral region */
+#define SYSTIMER0_ARMV8_M_BASE_S         0x58000000 /* System Timer 0 Secure base address */
+#define SYSTIMER1_ARMV8_M_BASE_S         0x58001000 /* System Timer 1 Secure base address */
+#define SYSTIMER2_ARMV8_M_BASE_S         0x58002000 /* System Timer 0 Secure base address */
+#define SYSTIMER3_ARMV8_M_BASE_S         0x58003000 /* System Timer 1 Secure base address */
+#define POLARIS_SYSINFO_BASE_S           0x58020000 /* Polaris System info Block Secure base address */
+#define POLARIS_SYSCTRL_BASE_S           0x58021000 /* Polaris System control Block Secure base address */
+#define POLARIS_SYSPPU_BASE_S            0x58022000 /* Polaris System Power Policy Unit Secure base address */
+#define POLARIS_CPU0PPU_BASE_S           0x58023000 /* Polaris CPU 0 Power Policy Unit Secure base address */
+#define POLARIS_MGMTPPU_BASE_S           0x58028000 /* Polaris Management Power Policy Unit Secure base address */
+#define POLARIS_DBGPPU_BASE_S            0x58029000 /* Polaris Debug Power Policy Unit Secure base address */
+#define POLARIS_NPU0PPU_BASE_S           0x5802A000 /* Polaris NPU 0 Power Policy Unit Secure base address */
+#define SLOWCLK_WDOG_CMSDK_BASE_S        0x5802E000 /* CMSDK based SLOWCLK Watchdog Secure base address */
+#define SLOWCLK_TIMER_CMSDK_BASE_S       0x5802F000 /* CMSDK based SLOWCLK Timer Secure base address */
+#define SYSWDOG_ARMV8_M_CNTRL_BASE_S     0x58040000 /* Secure Watchdog Timer control frame Secure base address */
+#define SYSWDOG_ARMV8_M_REFRESH_BASE_S   0x58041000 /* Secure Watchdog Timer refresh frame Secure base address */
+#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 */
+#define FPGA_SPI_SHIELD0_BASE_S          0x59203000 /* FPGA - PL022 (SPI Shield0) Secure base address */
+#define FPGA_SPI_SHIELD1_BASE_S          0x59204000 /* FPGA - PL022 (SPI Shield1) Secure base address */
+#define SBCon_I2C_SHIELD0_BASE_S         0x59205000 /* SBCon (I2C - Shield0) Secure base address */
+#define SBCon_I2C_SHIELD1_BASE_S         0x59206000 /* SBCon (I2C – Shield1) Secure base address */
+#define USER_APB_BASE_S                  0x59207000 /* USER APB Secure base address */
+#define FPGA_DDR4_EEPROM_BASE_S          0x59208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Secure base address */
+#define FPGA_SCC_BASE_S                  0x59300000 /* FPGA - SCC registers Secure base address */
+#define FPGA_I2S_BASE_S                  0x59301000 /* FPGA - I2S (Audio) Secure base address */
+#define FPGA_IO_BASE_S                   0x59302000 /* FPGA - IO (System Ctrl + I/O) Secure base address */
+#define UART0_BASE_S                     0x59303000 /* UART 0 Secure base address */
+#define UART1_BASE_S                     0x59304000 /* UART 1 Secure base address */
+#define UART2_BASE_S                     0x59305000 /* UART 2 Secure base address */
+#define UART3_BASE_S                     0x59306000 /* UART 3 Secure base address */
+#define UART4_BASE_S                     0x59307000 /* UART 4 Secure base address */
+#define UART5_BASE_S                     0x59308000 /* UART 5 Secure base address */
+#define CLCD_Config_Reg_BASE_S           0x5930A000 /* CLCD Config Reg Secure base address */
+#define RTC_BASE_S                       0x5930B000 /* RTC Secure base address */
+#define DDR4_BLK1_BASE_S                 0x70000000 /* DDR4 block 1 Secure base address */
+#define DDR4_BLK3_BASE_S                 0x90000000 /* DDR4 block 3 Secure base address */
+#define DDR4_BLK5_BASE_S                 0xB0000000 /* DDR4 block 5 Secure base address */
+#define DDR4_BLK7_BASE_S                 0xD0000000 /* DDR4 block 7 Secure base address */
+
+/* Memory map addresses exempt from memory attribution by both the SAU and IDAU */
+#define POLARIS_EWIC_BASE                0xE0047000 /* External Wakeup Interrupt Controller
+                                                     * Access from Non-secure software is only allowed
+                                                     * if AIRCR.BFHFNMINS is set to 1 */
+
+/* Memory size definitions */
+#define ITCM_SIZE       (0x00080000) /* 512 kB */
+#define DTCM_BLK_SIZE   (0x00020000) /* 128 kB */
+#define DTCM_BLK_NUM    (0x4)        /* Number of DTCM blocks */
+#define SRAM_SIZE       (0x00200000) /* 2 MB */
+#define ISRAM0_SIZE     (0x00080000) /* 512 kB */
+#define ISRAM1_SIZE     (0x00080000) /* 512 kB */
+#define QSPI_SRAM_SIZE  (0x00800000) /* 8 MB */
+#define DDR4_BLK_SIZE   (0x10000000) /* 256 MB */
+#define DDR4_BLK_NUM    (0x8)        /* Number of DDR4 blocks */
+
+/* Defines for Driver MPC's */
+/* SRAM -- 2 MB */
+#define MPC_SRAM_RANGE_BASE_NS   (SRAM_BASE_NS)
+#define MPC_SRAM_RANGE_LIMIT_NS  (SRAM_BASE_NS + SRAM_SIZE-1)
+#define MPC_SRAM_RANGE_OFFSET_NS (0x0)
+#define MPC_SRAM_RANGE_BASE_S    (SRAM_BASE_S)
+#define MPC_SRAM_RANGE_LIMIT_S   (SRAM_BASE_S + SRAM_SIZE-1)
+#define MPC_SRAM_RANGE_OFFSET_S  (0x0)
+
+/* QSPI -- 8 MB */
+#define MPC_QSPI_RANGE_BASE_NS   (QSPI_SRAM_BASE_NS)
+#define MPC_QSPI_RANGE_LIMIT_NS  (QSPI_SRAM_BASE_NS + QSPI_SRAM_SIZE-1)
+#define MPC_QSPI_RANGE_OFFSET_NS (0x0)
+#define MPC_QSPI_RANGE_BASE_S    (QSPI_SRAM_BASE_S)
+#define MPC_QSPI_RANGE_LIMIT_S   (QSPI_SRAM_BASE_S + QSPI_SRAM_SIZE-1)
+#define MPC_QSPI_RANGE_OFFSET_S  (0x0)
+
+/* ISRAM0 -- 512 kB*/
+#define MPC_ISRAM0_RANGE_BASE_NS   (ISRAM0_BASE_NS)
+#define MPC_ISRAM0_RANGE_LIMIT_NS  (ISRAM0_BASE_NS + ISRAM0_SIZE-1)
+#define MPC_ISRAM0_RANGE_OFFSET_NS (0x0)
+#define MPC_ISRAM0_RANGE_BASE_S    (ISRAM0_BASE_S)
+#define MPC_ISRAM0_RANGE_LIMIT_S   (ISRAM0_BASE_S + ISRAM0_SIZE-1)
+#define MPC_ISRAM0_RANGE_OFFSET_S  (0x0)
+
+/* ISRAM1 -- 512 kB */
+#define MPC_ISRAM1_RANGE_BASE_NS   (ISRAM1_BASE_NS)
+#define MPC_ISRAM1_RANGE_LIMIT_NS  (ISRAM1_BASE_NS + ISRAM1_SIZE-1)
+#define MPC_ISRAM1_RANGE_OFFSET_NS (0x0)
+#define MPC_ISRAM1_RANGE_BASE_S    (ISRAM1_BASE_S)
+#define MPC_ISRAM1_RANGE_LIMIT_S   (ISRAM1_BASE_S + ISRAM1_SIZE-1)
+#define MPC_ISRAM1_RANGE_OFFSET_S  (0x0)
+
+/* DDR4 -- 2GB (8 * 256 MB) */
+#define MPC_DDR4_BLK0_RANGE_BASE_NS   (DDR4_BLK0_BASE_NS)
+#define MPC_DDR4_BLK0_RANGE_LIMIT_NS  (DDR4_BLK0_BASE_NS + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK0_RANGE_OFFSET_NS (0x0)
+#define MPC_DDR4_BLK1_RANGE_BASE_S    (DDR4_BLK1_BASE_S)
+#define MPC_DDR4_BLK1_RANGE_LIMIT_S   (DDR4_BLK1_BASE_S + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK1_RANGE_OFFSET_S  (DDR4_BLK1_BASE_S - DDR4_BLK0_BASE_NS)
+#define MPC_DDR4_BLK2_RANGE_BASE_NS   (DDR4_BLK2_BASE_NS)
+#define MPC_DDR4_BLK2_RANGE_LIMIT_NS  (DDR4_BLK2_BASE_NS + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK2_RANGE_OFFSET_NS (DDR4_BLK2_BASE_NS - DDR4_BLK0_BASE_NS)
+#define MPC_DDR4_BLK3_RANGE_BASE_S    (DDR4_BLK3_BASE_S)
+#define MPC_DDR4_BLK3_RANGE_LIMIT_S   (DDR4_BLK3_BASE_S + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK3_RANGE_OFFSET_S  (DDR4_BLK3_BASE_S - DDR4_BLK0_BASE_NS)
+#define MPC_DDR4_BLK4_RANGE_BASE_NS   (DDR4_BLK4_BASE_NS)
+#define MPC_DDR4_BLK4_RANGE_LIMIT_NS  (DDR4_BLK4_BASE_NS + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK4_RANGE_OFFSET_NS (DDR4_BLK4_BASE_NS - DDR4_BLK0_BASE_NS)
+#define MPC_DDR4_BLK5_RANGE_BASE_S    (DDR4_BLK5_BASE_S)
+#define MPC_DDR4_BLK5_RANGE_LIMIT_S   (DDR4_BLK5_BASE_S + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK5_RANGE_OFFSET_S  (DDR4_BLK5_BASE_S - DDR4_BLK0_BASE_NS)
+#define MPC_DDR4_BLK6_RANGE_BASE_NS   (DDR4_BLK6_BASE_NS)
+#define MPC_DDR4_BLK6_RANGE_LIMIT_NS  (DDR4_BLK6_BASE_NS + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK6_RANGE_OFFSET_NS (DDR4_BLK6_BASE_NS - DDR4_BLK0_BASE_NS)
+#define MPC_DDR4_BLK7_RANGE_BASE_S    (DDR4_BLK7_BASE_S)
+#define MPC_DDR4_BLK7_RANGE_LIMIT_S   (DDR4_BLK7_BASE_S + ((DDR4_BLK_SIZE)-1))
+#define MPC_DDR4_BLK7_RANGE_OFFSET_S  (DDR4_BLK7_BASE_S - DDR4_BLK0_BASE_NS)
+
+#endif  /* __PLATFORM_BASE_ADDRESS_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/partition/region_defs.h b/platform/ext/target/arm/mps3/corstone_polaris/partition/region_defs.h
new file mode 100644
index 0000000..90f7534
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/partition/region_defs.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __REGION_DEFS_H__
+#define __REGION_DEFS_H__
+
+#include "flash_layout.h"
+#include "platform_base_address.h"
+
+#define BL2_HEAP_SIZE           (0x0001000)
+#define BL2_MSP_STACK_SIZE      (0x0001800)
+
+#define S_HEAP_SIZE             (0x0001000)
+#define S_MSP_STACK_SIZE_INIT   (0x0000400)
+#define S_MSP_STACK_SIZE        (0x0000800)
+#define S_PSP_STACK_SIZE        (0x0000800)
+
+#define NS_HEAP_SIZE            (0x0001000)
+#define NS_MSP_STACK_SIZE       (0x0000400)
+#define NS_PSP_STACK_SIZE       (0x0000C00)
+
+/* This size of buffer is big enough to store an attestation
+ * token produced by initial attestation service
+ */
+#define PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE   (0x250)
+
+#ifdef BL2
+#ifndef LINK_TO_SECONDARY_PARTITION
+#define S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_0_OFFSET)
+#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET)
+#else
+#define S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_2_OFFSET)
+#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
+#else
+#define S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0)
+#endif /* BL2 */
+
+#ifndef LINK_TO_SECONDARY_PARTITION
+#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET \
+                                           + FLASH_S_PARTITION_SIZE)
+#else
+#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET \
+                                           + FLASH_S_PARTITION_SIZE)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
+
+/* Boot partition structure if MCUBoot is used:
+ * 0x0_0000 Bootloader header
+ * 0x0_0400 Image area
+ * 0x5_0000 Trailer
+ */
+/* IMAGE_CODE_SIZE is the space available for the software binary image.
+ * It is less than the FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE
+ * because we reserve space for the image header and trailer introduced
+ * by the bootloader.
+ */
+#ifdef BL2
+#define BL2_HEADER_SIZE      (0x400)       /* 1 KB */
+#define BL2_TRAILER_SIZE     (0x800)       /* 2 KB */
+#else
+/* No header if no bootloader, but keep IMAGE_CODE_SIZE the same */
+#define BL2_HEADER_SIZE      (0x0)
+#define BL2_TRAILER_SIZE     (0xC00)
+#endif /* BL2 */
+
+#if (!defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1)) && \
+    (NS_IMAGE_PRIMARY_PARTITION_OFFSET > S_IMAGE_PRIMARY_PARTITION_OFFSET)
+/* If secure image and nonsecure image are concatenated, and nonsecure image
+ * locates at the higher memory range, then the secure image does not need
+ * the trailer area.
+ */
+#define IMAGE_S_CODE_SIZE \
+            (FLASH_S_PARTITION_SIZE - BL2_HEADER_SIZE)
+#else
+#define IMAGE_S_CODE_SIZE \
+            (FLASH_S_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
+#endif
+
+#define IMAGE_NS_CODE_SIZE \
+            (FLASH_NS_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
+
+#define CMSE_VENEER_REGION_SIZE     (0x340)
+
+/* Secure regions */
+#define S_IMAGE_PRIMARY_AREA_OFFSET \
+             (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+/* Secure Code stored in Code SRAM */
+#define S_CODE_START    ((SRAM_BASE_S) +  (S_IMAGE_PRIMARY_AREA_OFFSET))
+#define S_CODE_SIZE     (IMAGE_S_CODE_SIZE - CMSE_VENEER_REGION_SIZE)
+#define S_CODE_LIMIT    (S_CODE_START + S_CODE_SIZE - 1)
+
+/* Secure Data stored in DTCM */
+#define S_DATA_START    (DTCM0_BASE_S)
+#define S_DATA_SIZE     (DTCM_BLK_SIZE * DTCM_BLK_NUM)
+#define S_DATA_LIMIT    (S_DATA_START + S_DATA_SIZE - 1)
+
+/* CMSE Veneers region */
+#define CMSE_VENEER_REGION_START  (S_CODE_LIMIT + 1)
+
+/* Non-secure regions */
+#define NS_IMAGE_PRIMARY_AREA_OFFSET \
+                        (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+/* Non-Secure Code stored in Code SRAM memory */
+#define NS_CODE_START   (SRAM_BASE_NS + (NS_IMAGE_PRIMARY_AREA_OFFSET))
+#define NS_CODE_SIZE    (IMAGE_NS_CODE_SIZE)
+#define NS_CODE_LIMIT   (NS_CODE_START + NS_CODE_SIZE - 1)
+
+/* Non-Secure Data stored in ISRAM0 */
+#define NS_DATA_START   (ISRAM0_BASE_NS)
+#define NS_DATA_SIZE    (ISRAM0_SIZE)
+#define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE - 1)
+
+/* NS partition information is used for MPC and SAU configuration */
+#define NS_PARTITION_START \
+            ((SRAM_BASE_NS) + (NS_IMAGE_PRIMARY_PARTITION_OFFSET))
+#define NS_PARTITION_SIZE (FLASH_NS_PARTITION_SIZE)
+
+/* Secondary partition for new images in case of firmware upgrade */
+#define SECONDARY_PARTITION_START \
+            ((SRAM_BASE_NS) + (S_IMAGE_SECONDARY_PARTITION_OFFSET))
+#define SECONDARY_PARTITION_SIZE (FLASH_S_PARTITION_SIZE + \
+                                  FLASH_NS_PARTITION_SIZE)
+
+#ifdef BL2
+/* Bootloader regions */
+/* Use ITCM to store Bootloader */
+#define BL2_CODE_START    (ITCM_BASE_S)
+#define BL2_CODE_SIZE     (ITCM_SIZE)
+#define BL2_CODE_LIMIT    (BL2_CODE_START + BL2_CODE_SIZE - 1)
+
+/* Bootloader uses same memory as for secure image */
+#define BL2_DATA_START    (S_DATA_START)
+#define BL2_DATA_SIZE     (S_DATA_SIZE)
+#define BL2_DATA_LIMIT    (BL2_DATA_START + BL2_DATA_SIZE - 1)
+#endif /* BL2 */
+
+/* Shared data area between bootloader and runtime firmware.
+ * Shared data area is allocated at the beginning of the RAM, it is overlapping
+ * with TF-M Secure code's MSP stack
+ */
+#define BOOT_TFM_SHARED_DATA_BASE S_DATA_START
+#define BOOT_TFM_SHARED_DATA_SIZE (0x400)
+#define BOOT_TFM_SHARED_DATA_LIMIT (BOOT_TFM_SHARED_DATA_BASE + \
+                                    BOOT_TFM_SHARED_DATA_SIZE - 1)
+
+#endif /* __REGION_DEFS_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/plat_test.c b/platform/ext/target/arm/mps3/corstone_polaris/plat_test.c
new file mode 100644
index 0000000..8fe21c2
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/plat_test.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform_description.h"
+#include "systimer_armv8-m_drv.h"
+#include "tfm_plat_test.h"
+#include "device_definition.h"
+
+/* Interrupt interval is set to 1 ms */
+#define TIMER_RELOAD_VALUE          (SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ / 1000)
+
+void tfm_plat_test_secure_timer_start(void)
+{
+    systimer_armv8_m_init(&SYSTIMER0_ARMV8_M_DEV_S);
+    systimer_armv8_m_set_autoinc_reload(&SYSTIMER0_ARMV8_M_DEV_S, TIMER_RELOAD_VALUE);
+    systimer_armv8_m_enable_autoinc(&SYSTIMER0_ARMV8_M_DEV_S);
+    systimer_armv8_m_enable_interrupt(&SYSTIMER0_ARMV8_M_DEV_S);
+}
+
+void tfm_plat_test_secure_timer_clear_intr(void)
+{
+    systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER0_ARMV8_M_DEV_S);
+}
+
+void tfm_plat_test_secure_timer_stop(void)
+{
+    systimer_armv8_m_uninit(&SYSTIMER0_ARMV8_M_DEV_S);
+    systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER0_ARMV8_M_DEV_S);
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/preload.cmake b/platform/ext/target/arm/mps3/corstone_polaris/preload.cmake
new file mode 100644
index 0000000..e83e3db
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/preload.cmake
@@ -0,0 +1,15 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# preload.cmake is used to set things that related to the platform that are both
+# immutable and global, which is to say they should apply to any kind of project
+# that uses this platform. In practise this is normally compiler definitions and
+# variables related to hardware.
+
+# Set architecture
+set(TFM_SYSTEM_ARCHITECTURE armv8.1-m.main)
+set(TFM_SYSTEM_MVE OFF)
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/services/src/tfm_platform_system.c b/platform/ext/target/arm/mps3/corstone_polaris/services/src/tfm_platform_system.c
new file mode 100644
index 0000000..e081343
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/services/src/tfm_platform_system.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_platform_system.h"
+#include "target_cfg.h"
+#include "cmsis.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+    __disable_irq();
+    mpc_revert_non_secure_to_secure_cfg();
+
+    /* Reset the system */
+    NVIC_SystemReset();
+}
+
+enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
+                                               psa_invec  *in_vec,
+                                               psa_outvec *out_vec)
+{
+    (void)request;
+    (void)in_vec;
+    (void)out_vec;
+
+    /* Not needed for this platform */
+    return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+}
+
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/spm_hal.c b/platform/ext/target/arm/mps3/corstone_polaris/spm_hal.c
new file mode 100644
index 0000000..ce08d20
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/spm_hal.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis.h"
+#include "tfm_spm_hal.h"
+#include "tfm_platform_core_api.h"
+#include "target_cfg.h"
+#include "Driver_MPC.h"
+#include "utilities.h"
+
+/* Get address of memory regions to configure MPU */
+extern const struct memory_region_limits memory_regions;
+
+void MPC_Handler(void)
+{
+    /* Clear MPC interrupt flag and pending MPC IRQ */
+    mpc_clear_irq();
+    NVIC_ClearPendingIRQ(MPC_IRQn);
+
+    /* Print fault message and block execution */
+    ERROR_MSG("Oops... MPC fault!!!");
+
+    /* Inform TF-M core that isolation boundary has been violated */
+    tfm_access_violation_handler();
+}
+
+void PPC_Handler(void)
+{
+    /* Clear PPC interrupt flag and pending PPC IRQ */
+    ppc_clear_irq();
+    NVIC_ClearPendingIRQ(PPC_IRQn);
+
+    /* Print fault message*/
+    ERROR_MSG("Oops... PPC fault!!!");
+
+    /* Inform TF-M core that isolation boundary has been violated */
+    tfm_access_violation_handler();
+}
+
+uint32_t tfm_spm_hal_get_ns_VTOR(void)
+{
+    return memory_regions.non_secure_code_start;
+}
+
+uint32_t tfm_spm_hal_get_ns_MSP(void)
+{
+    return *((uint32_t *)memory_regions.non_secure_code_start);
+}
+
+uint32_t tfm_spm_hal_get_ns_entry_point(void)
+{
+    return *((uint32_t *)(memory_regions.non_secure_code_start+ 4));
+}
+
+enum tfm_plat_err_t tfm_spm_hal_set_secure_irq_priority(IRQn_Type irq_line)
+{
+    NVIC_SetPriority(irq_line, DEFAULT_IRQ_PRIORITY);
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+void tfm_spm_hal_clear_pending_irq(IRQn_Type irq_line)
+{
+    NVIC_ClearPendingIRQ(irq_line);
+}
+
+void tfm_spm_hal_enable_irq(IRQn_Type irq_line)
+{
+    NVIC_EnableIRQ(irq_line);
+}
+
+void tfm_spm_hal_disable_irq(IRQn_Type irq_line)
+{
+    NVIC_DisableIRQ(irq_line);
+}
+
+enum irq_target_state_t tfm_spm_hal_set_irq_target_state(
+                                           IRQn_Type irq_line,
+                                           enum irq_target_state_t target_state)
+{
+    uint32_t result;
+
+    if (target_state == TFM_IRQ_TARGET_STATE_SECURE) {
+        result = NVIC_ClearTargetState(irq_line);
+    } else {
+        result = NVIC_SetTargetState(irq_line);
+    }
+
+    if (result) {
+        return TFM_IRQ_TARGET_STATE_NON_SECURE;
+    } else {
+        return TFM_IRQ_TARGET_STATE_SECURE;
+    }
+}
+
+#ifndef TFM_PSA_API
+
+enum tfm_plat_err_t tfm_spm_hal_configure_default_isolation(
+                  bool privileged,
+                  const struct platform_data_t *platform_data)
+{
+    if (!platform_data) {
+        return TFM_PLAT_ERR_INVALID_INPUT;
+    }
+
+    if (platform_data->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) {
+        ppc_configure_to_secure(platform_data->periph_ppc_bank,
+                                platform_data->periph_ppc_mask);
+        if (privileged) {
+            ppc_clr_secure_unpriv(platform_data->periph_ppc_bank,
+                                  platform_data->periph_ppc_mask);
+        } else {
+            ppc_en_secure_unpriv(platform_data->periph_ppc_bank,
+                                 platform_data->periph_ppc_mask);
+        }
+    }
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+#endif /* TFM_PSA_API */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/target_cfg.c b/platform/ext/target/arm/mps3/corstone_polaris/target_cfg.c
new file mode 100644
index 0000000..7221543
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/target_cfg.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cmsis.h"
+#include "utilities.h"
+#include "target_cfg.h"
+#include "Driver_PPC.h"
+#include "Driver_MPC.h"
+#include "region_defs.h"
+#include "tfm_plat_defs.h"
+#include "region.h"
+#include "device_definition.h"
+#include "syscounter_armv8-m_cntrl_drv.h"
+#include "uart_stdout.h"
+
+/* Throw out bus error when an access causes security violation */
+#define CMSDK_SECRESPCFG_BUS_ERR_MASK   (1UL << 0)
+
+/* The section names come from the scatter file */
+REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+
+const struct memory_region_limits memory_regions = {
+    .non_secure_code_start =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        BL2_HEADER_SIZE,
+
+    .non_secure_partition_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
+
+    .non_secure_partition_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        NS_PARTITION_SIZE - 1,
+
+    .veneer_base = (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+    .veneer_limit = (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+};
+
+/* Configures the RAM region to NS callable in sacfg block's nsccfg register */
+#define RAMNSC  0x2
+/* Configures the CODE region to NS callable in sacfg block's nsccfg register */
+#define CODENSC  0x1
+
+/* Import MPC drivers */
+extern ARM_DRIVER_MPC Driver_ISRAM0_MPC;
+extern ARM_DRIVER_MPC Driver_ISRAM1_MPC;
+extern ARM_DRIVER_MPC Driver_SRAM_MPC;
+extern ARM_DRIVER_MPC Driver_QSPI_MPC;
+
+/* Import PPC drivers */
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN0;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP0;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP1;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP2;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_MAIN_EXP3;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH0;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH1;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP0;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP1;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP2;
+extern DRIVER_PPC_POLARIS Driver_PPC_POLARIS_PERIPH_EXP3;
+
+/* Define Peripherals NS address range for the platform */
+#define PERIPHERALS_BASE_NS_START      (0x40000000)
+#define PERIPHERALS_BASE_NS_END        (0x4FFFFFFF)
+
+/* Enable system reset request for CPU 0 */
+#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 8U)
+
+/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
+ * otherwise the processor ignores the write.
+ */
+#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
+
+/* Debug configuration flags */
+#define SPNIDEN_SEL_STATUS (0x01u << 7)
+#define SPNIDEN_STATUS     (0x01u << 6)
+#define SPIDEN_SEL_STATUS  (0x01u << 5)
+#define SPIDEN_STATUS      (0x01u << 4)
+#define NIDEN_SEL_STATUS   (0x01u << 3)
+#define NIDEN_STATUS       (0x01u << 2)
+#define DBGEN_SEL_STATUS   (0x01u << 1)
+#define DBGEN_STATUS       (0x01u << 0)
+
+#define All_SEL_STATUS (SPNIDEN_SEL_STATUS | SPIDEN_SEL_STATUS | \
+                        NIDEN_SEL_STATUS | DBGEN_SEL_STATUS)
+
+struct platform_data_t tfm_peripheral_std_uart = {
+        UART0_BASE_NS,
+        UART0_BASE_NS + 0xFFF,
+        PPC_SP_DO_NOT_CONFIGURE,
+        -1
+};
+
+struct platform_data_t tfm_peripheral_timer0 = {
+        SYSTIMER0_ARMV8_M_BASE_S,
+        SYSTIMER0_ARMV8_M_BASE_S + 0xFFF,
+        PPC_SP_PERIPH0,
+        SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK
+};
+
+static DRIVER_PPC_POLARIS *const ppc_bank_drivers[] = {
+    &Driver_PPC_POLARIS_MAIN0,
+    &Driver_PPC_POLARIS_MAIN_EXP0,
+    &Driver_PPC_POLARIS_MAIN_EXP1,
+    &Driver_PPC_POLARIS_MAIN_EXP2,
+    &Driver_PPC_POLARIS_MAIN_EXP3,
+    &Driver_PPC_POLARIS_PERIPH0,
+    &Driver_PPC_POLARIS_PERIPH1,
+    &Driver_PPC_POLARIS_PERIPH_EXP0,
+    &Driver_PPC_POLARIS_PERIPH_EXP1,
+    &Driver_PPC_POLARIS_PERIPH_EXP2,
+    &Driver_PPC_POLARIS_PERIPH_EXP3,
+};
+
+#define PPC_BANK_COUNT (sizeof(ppc_bank_drivers)/sizeof(ppc_bank_drivers[0]))
+
+enum tfm_plat_err_t enable_fault_handlers(void)
+{
+    /* Explicitly set secure fault priority to the highest */
+    NVIC_SetPriority(SecureFault_IRQn, 0);
+
+    /* Enables BUS, MEM, USG and Secure faults */
+    SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk
+                  | SCB_SHCSR_BUSFAULTENA_Msk
+                  | SCB_SHCSR_MEMFAULTENA_Msk
+                  | SCB_SHCSR_SECUREFAULTENA_Msk;
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t system_reset_cfg(void)
+{
+    struct polaris_sysctrl_t *sysctrl =
+                            (struct polaris_sysctrl_t *)POLARIS_SYSCTRL_BASE_S;
+    uint32_t reg_value = SCB->AIRCR;
+
+    /* Enable system reset request for CPU 0, to be triggered via
+     * NVIC_SystemReset function.
+     */
+    sysctrl->reset_mask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
+
+    /* Clear SCB_AIRCR_VECTKEY value */
+    reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
+
+    /* Enable system reset request only to the secure world */
+    reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
+
+    SCB->AIRCR = reg_value;
+
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*--------------------- NVIC interrupt NS/S configuration --------------------*/
+enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void)
+{
+    uint8_t i;
+
+    /* Target every interrupt to NS; unimplemented interrupts will be WI */
+    for (i = 0; i < (sizeof(NVIC->ITNS) / sizeof(NVIC->ITNS[0])); i++) {
+        NVIC->ITNS[i] = 0xFFFFFFFF;
+    }
+
+    /* Make sure that MPC and PPC are targeted to S state */
+    NVIC_ClearTargetState(MPC_IRQn);
+    NVIC_ClearTargetState(PPC_IRQn);
+
+#ifdef SECURE_UART1
+    /* UART1 is a secure peripheral, so its IRQs have to target S state */
+    NVIC_ClearTargetState(UARTRX1_IRQn);
+    NVIC_ClearTargetState(UARTTX1_IRQn);
+#endif
+
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*----------------- NVIC interrupt enabling for S peripherals ----------------*/
+enum tfm_plat_err_t nvic_interrupt_enable(void)
+{
+    int32_t ret = ARM_DRIVER_OK;
+    int32_t i = 0;
+
+    /* MPC interrupt enabling */
+    mpc_clear_irq();
+    ret = Driver_ISRAM0_MPC.EnableInterrupt();
+    if (ret != ARM_DRIVER_OK) {
+        ERROR_MSG("Failed to Enable MPC interrupt for ISRAM0!");
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    ret = Driver_SRAM_MPC.EnableInterrupt();
+    if (ret != ARM_DRIVER_OK) {
+        ERROR_MSG("Failed to Enable MPC interrupt for SRAM!");
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    NVIC_ClearPendingIRQ(MPC_IRQn);
+    NVIC_EnableIRQ(MPC_IRQn);
+
+    /* PPC interrupt enabling */
+    ppc_clear_irq();
+
+    for (i = 0; i < PPC_BANK_COUNT; i++)  {
+        ret = ppc_bank_drivers[i]->EnableInterrupt();
+        if (ret != ARM_DRIVER_OK) {
+            ERROR_MSG("Failed to Enable interrupt on PPC");
+            return TFM_PLAT_ERR_SYSTEM_ERR;
+        }
+    }
+
+    NVIC_ClearPendingIRQ(PPC_IRQn);
+    NVIC_EnableIRQ(PPC_IRQn);
+
+#ifdef PSA_FF_TEST_SECURE_UART2
+    NVIC_EnableIRQ(FF_TEST_UART_IRQ);
+#endif
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t init_debug(void)
+{
+    struct polaris_sysctrl_t *sysctrl =
+                            (struct polaris_sysctrl_t *)POLARIS_SYSCTRL_BASE_S;
+
+#if defined(DAUTH_NONE)
+    /* Set all the debug enable selector bits to 1 */
+    sysctrl->secdbgset = All_SEL_STATUS;
+    /* Set all the debug enable bits to 0 */
+    sysctrl->secdbgclr =
+                   DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
+#elif defined(DAUTH_NS_ONLY)
+    /* Set all the debug enable selector bits to 1 */
+    sysctrl->secdbgset = All_SEL_STATUS;
+    /* Set the debug enable bits to 1 for NS, and 0 for S mode */
+    sysctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS;
+    sysctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS;
+#elif defined(DAUTH_FULL)
+    /* Set all the debug enable selector bits to 1 */
+    sysctrl->secdbgset = All_SEL_STATUS;
+    /* Set all the debug enable bits to 1 */
+    sysctrl->secdbgset =
+                   DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
+#else
+
+#if !defined(DAUTH_CHIP_DEFAULT)
+#error "No debug authentication setting is provided."
+#endif
+
+    /* Set all the debug enable selector bits to 0 */
+    sysctrl->secdbgclr = All_SEL_STATUS;
+
+    /* No need to set any enable bits because the value depends on
+     * input signals.
+     */
+#endif
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*------------------- SAU/IDAU configuration functions -----------------------*/
+void sau_and_idau_cfg(void)
+{
+    struct polaris_sacfg_t *sacfg = (struct polaris_sacfg_t*)POLARIS_SACFG_BASE_S;
+
+    /* Enables SAU */
+    TZ_SAU_Enable();
+
+    /* Configures SAU regions to be non-secure */
+    SAU->RNR  = 0;
+    SAU->RBAR = (memory_regions.non_secure_partition_base
+                 & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.non_secure_partition_limit
+                  & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
+
+    SAU->RNR  = 1;
+    SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (NS_DATA_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
+
+    /* Configures veneers region to be non-secure callable */
+    SAU->RNR  = 2;
+    SAU->RBAR = (memory_regions.veneer_base & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk)
+                 | SAU_RLAR_ENABLE_Msk | SAU_RLAR_NSC_Msk;
+
+    /* Configure the peripherals space */
+    SAU->RNR  = 3;
+    SAU->RBAR = (PERIPHERALS_BASE_NS_START & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk)
+                  | SAU_RLAR_ENABLE_Msk;
+
+    /* Allows SAU to define the CODE region as a NSC */
+    sacfg->nsccfg |= CODENSC;
+}
+
+/*------------------- Memory configuration functions -------------------------*/
+enum tfm_plat_err_t mpc_init_cfg(void)
+{
+    int32_t ret = ARM_DRIVER_OK;
+
+    /* ISRAM0 is allocated for NS data, so whole range is set to non-secure
+     * accesible. */
+    ret = Driver_ISRAM0_MPC.Initialize();
+    if (ret != ARM_DRIVER_OK) {
+        ERROR_MSG("Failed to Initialize MPC for ISRAM0!");
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+    ret = Driver_ISRAM0_MPC.ConfigRegion(MPC_ISRAM0_RANGE_BASE_NS,
+                                      MPC_ISRAM0_RANGE_LIMIT_NS,
+                                      ARM_MPC_ATTR_NONSECURE);
+    if (ret != ARM_DRIVER_OK) {
+        ERROR_MSG("Failed to Configure MPC for ISRAM0!");
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    /* Configuring primary and secondary non-secure partition.
+     * It is ensured in flash_layout.h that these memory regions are located in
+     * SRAM SRAM device. */
+    ret = Driver_SRAM_MPC.Initialize();
+    if (ret != ARM_DRIVER_OK) {
+        ERROR_MSG("Failed to Initialize MPC for SRAM!");
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+    ret = Driver_SRAM_MPC.ConfigRegion(
+                                      memory_regions.non_secure_partition_base,
+                                      memory_regions.non_secure_partition_limit,
+                                      ARM_MPC_ATTR_NONSECURE);
+    if (ret != ARM_DRIVER_OK) {
+        ERROR_MSG("Failed to Configure MPC for SRAM!");
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    /* Lock down not used MPC's */
+    Driver_QSPI_MPC.LockDown();
+    Driver_ISRAM1_MPC.LockDown();
+
+    /* SRAM and ISRAM0 MPCs left unlocked as they are not reset if NVIC system
+     * reset asserted.
+     */
+
+    /* Add barriers to assure the MPC configuration is done before continue
+     * the execution.
+     */
+    __DSB();
+    __ISB();
+
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+void mpc_revert_non_secure_to_secure_cfg(void)
+{
+    Driver_ISRAM0_MPC.ConfigRegion(MPC_ISRAM0_RANGE_BASE_S,
+                                   MPC_ISRAM0_RANGE_LIMIT_S,
+                                   ARM_MPC_ATTR_SECURE);
+
+    Driver_SRAM_MPC.ConfigRegion(MPC_SRAM_RANGE_BASE_S,
+                                 MPC_SRAM_RANGE_LIMIT_S,
+                                 ARM_MPC_ATTR_SECURE);
+
+    /* Add barriers to assure the MPC configuration is done before continue
+     * the execution.
+     */
+    __DSB();
+    __ISB();
+}
+
+void mpc_clear_irq(void)
+{
+    Driver_ISRAM0_MPC.ClearInterrupt();
+    Driver_SRAM_MPC.ClearInterrupt();
+}
+
+/*------------------- PPC configuration functions -------------------------*/
+enum tfm_plat_err_t ppc_init_cfg(void)
+{
+    struct polaris_sacfg_t *sacfg =
+                                (struct polaris_sacfg_t*)POLARIS_SACFG_BASE_S;
+    int32_t err = ARM_DRIVER_OK;
+
+    /* Grant non-secure access to peripherals on MAIN EXP0 */
+    err |= Driver_PPC_POLARIS_MAIN_EXP0.Initialize();
+    err |= Driver_PPC_POLARIS_MAIN_EXP0.ConfigSecurity(
+                                        GPIO0_MAIN_PPCEXP0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_MAIN_EXP0.ConfigSecurity(
+                                        GPIO1_MAIN_PPCEXP0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_MAIN_EXP0.ConfigSecurity(
+                                        GPIO2_MAIN_PPCEXP0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_MAIN_EXP0.ConfigSecurity(
+                                        GPIO3_MAIN_PPCEXP0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_MAIN_EXP0.ConfigSecurity(
+                                        USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+
+    /* Grant non-secure access to peripherals on MAIN EXP1 */
+    err |= Driver_PPC_POLARIS_MAIN_EXP1.Initialize();
+    err |= Driver_PPC_POLARIS_MAIN_EXP1.ConfigSecurity(
+                                        DMA1_MAIN_PPCEXP1_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_MAIN_EXP1.ConfigSecurity(
+                                        DMA2_MAIN_PPCEXP1_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_MAIN_EXP1.ConfigSecurity(
+                                        DMA3_MAIN_PPCEXP1_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+
+    /* Grant non-secure access to peripherals on PERIPH0 */
+    err |= Driver_PPC_POLARIS_PERIPH0.Initialize();
+    err |= Driver_PPC_POLARIS_PERIPH0.ConfigSecurity(
+                                        SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH0.ConfigSecurity(
+                                        SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH0.ConfigSecurity(
+                                        SYSTEM_TIMER2_PERIPH_PPC0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH0.ConfigSecurity(
+                                        SYSTEM_TIMER3_PERIPH_PPC0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH0.ConfigSecurity(
+                                        WATCHDOG_PERIPH_PPC0_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+
+    /* Grant non-secure access to peripherals on PERIPH1 */
+    err |= Driver_PPC_POLARIS_PERIPH1.Initialize();
+    err |= Driver_PPC_POLARIS_PERIPH1.ConfigSecurity(
+                                        SLOWCLK_TIMER_PERIPH_PPC1_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+
+    /* Grant non-secure access to peripherals on PERIPH EXP2 */
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.Initialize();
+
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        FPGA_I2S_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        FPGA_IO_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        UART0_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        UART1_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        UART2_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        UART3_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        UART4_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        UART5_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigSecurity(
+                                        CLCD_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG);
+
+    /* Grant un-privileged access for UART0 in NS domain */
+    err |= Driver_PPC_POLARIS_PERIPH_EXP2.ConfigPrivilege(
+                                        UART0_PERIPH_PPCEXP2_POS_MASK,
+                                        PPC_POLARIS_NONSECURE_CONFIG,
+                                        PPC_POLARIS_PRIV_AND_NONPRIV_CONFIG);
+
+    /* Initialize not used PPC drivers */
+    err |= Driver_PPC_POLARIS_MAIN0.Initialize();
+    err |= Driver_PPC_POLARIS_MAIN_EXP2.Initialize();
+    err |= Driver_PPC_POLARIS_MAIN_EXP3.Initialize();
+    err |= Driver_PPC_POLARIS_PERIPH_EXP0.Initialize();
+    err |= Driver_PPC_POLARIS_PERIPH_EXP1.Initialize();
+    err |= Driver_PPC_POLARIS_PERIPH_EXP3.Initialize();
+
+    /*
+     * Configure the response to a security violation as a
+     * bus error instead of RAZ/WI
+     */
+    sacfg->secrespcfg |= CMSDK_SECRESPCFG_BUS_ERR_MASK;
+
+    if (err != ARM_DRIVER_OK) {
+        return TFM_PLAT_ERR_SYSTEM_ERR;
+    }
+
+    return TFM_PLAT_ERR_SUCCESS;
+}
+
+void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos)
+{
+    DRIVER_PPC_POLARIS *ppc_driver;
+
+    if (bank >= PPC_BANK_COUNT) {
+        return;
+    }
+
+    ppc_driver = ppc_bank_drivers[bank];
+    if (ppc_driver) {
+        ppc_driver->ConfigSecurity(pos, PPC_POLARIS_SECURE_CONFIG);
+    }
+}
+
+void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos)
+{
+    DRIVER_PPC_POLARIS *ppc_driver;
+
+    if (bank >= PPC_BANK_COUNT) {
+        return;
+    }
+
+    ppc_driver = ppc_bank_drivers[bank];
+    if (ppc_driver) {
+        ppc_driver->ConfigSecurity(pos, PPC_POLARIS_NONSECURE_CONFIG);
+    }
+}
+
+void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint32_t pos)
+{
+    DRIVER_PPC_POLARIS *ppc_driver;
+
+    if (bank >= PPC_BANK_COUNT) {
+        return;
+    }
+
+    ppc_driver = ppc_bank_drivers[bank];
+    if (ppc_driver) {
+        ppc_driver->ConfigPrivilege(pos,
+                                    PPC_POLARIS_SECURE_CONFIG,
+                                    PPC_POLARIS_PRIV_AND_NONPRIV_CONFIG);
+    }
+}
+
+void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint32_t pos)
+{
+    DRIVER_PPC_POLARIS *ppc_driver;
+
+    if (bank >= PPC_BANK_COUNT) {
+        return;
+    }
+
+    ppc_driver = ppc_bank_drivers[bank];
+    if (ppc_driver) {
+        ppc_driver->ConfigPrivilege(pos,
+                                    PPC_POLARIS_SECURE_CONFIG,
+                                    PPC_POLARIS_PRIV_CONFIG);
+    }
+}
+
+void ppc_clear_irq(void)
+{
+    int32_t i = 0;
+
+    for (i = 0; i < PPC_BANK_COUNT; i++) {
+        ppc_bank_drivers[i]->ClearInterrupt();
+    }
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/target_cfg.h b/platform/ext/target/arm/mps3/corstone_polaris/target_cfg.h
new file mode 100644
index 0000000..f924f06
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/target_cfg.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TARGET_CFG_H__
+#define __TARGET_CFG_H__
+
+#include <stdint.h>
+#include "tfm_peripherals_def.h"
+#include "tfm_plat_defs.h"
+
+#define TFM_DRIVER_STDIO    Driver_USART0
+#define NS_DRIVER_STDIO     Driver_USART0
+
+/**
+ * \brief Defines the word offsets of Slave Peripheral Protection Controller
+ *        Registers
+ */
+enum ppc_bank_e
+{
+    PPC_SP_DO_NOT_CONFIGURE = -1,
+    PPC_SP_MAIN0 = 0,
+    PPC_SP_MAIN_EXP0 = 1,
+    PPC_SP_MAIN_EXP1 = 2,
+    PPC_SP_MAIN_EXP2 = 3,
+    PPC_SP_MAIN_EXP3 = 4,
+    PPC_SP_PERIPH0 = 5,
+    PPC_SP_PERIPH1 = 6,
+    PPC_SP_PERIPH_EXP0 = 7,
+    PPC_SP_PERIPH_EXP1 = 8,
+    PPC_SP_PERIPH_EXP2 = 9,
+    PPC_SP_PERIPH_EXP3 = 10,
+};
+
+/**
+ * \brief Store the addresses of memory regions
+ */
+struct memory_region_limits {
+    uint32_t non_secure_code_start;
+    uint32_t non_secure_partition_base;
+    uint32_t non_secure_partition_limit;
+    uint32_t veneer_base;
+    uint32_t veneer_limit;
+};
+
+/**
+ * \brief Holds the data necessary to do isolation for a specific peripheral.
+ */
+struct platform_data_t {
+    uint32_t periph_start;
+    uint32_t periph_limit;
+    enum ppc_bank_e periph_ppc_bank;
+    int16_t periph_ppc_mask;
+};
+
+/**
+ * \brief Enables the fault handlers BusFault, UsageFault,
+ *        MemManageFault and SecureFault.
+ */
+enum tfm_plat_err_t enable_fault_handlers(void);
+
+/**
+ * \brief Configures the system reset request properties
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t system_reset_cfg(void);
+
+/**
+ * \brief Configures all external interrupts to target the
+ *        NS state, apart for the ones associated to secure
+ *        peripherals (plus MPC and PPC)
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void);
+
+/**
+ * \brief This function enable the interrupts associated
+ *        to the secure peripherals (plus MPC and PPC)
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t nvic_interrupt_enable(void);
+
+/**
+ * \brief Configures the system debug properties.
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t init_debug(void);
+
+/**
+ * \brief Configures the Memory Protection Controller.
+ *
+ * \return  Returns error code.
+ */
+enum tfm_plat_err_t mpc_init_cfg(void);
+
+/**
+ * \brief Clear MPC interrupt.
+ */
+void mpc_clear_irq(void);
+
+/**
+ * \brief Configures the Peripheral Protection Controller.
+ */
+enum tfm_plat_err_t ppc_init_cfg(void);
+
+/**
+ * \brief Restict peripheral access to secure access only
+ *
+ * \note The function does not configure privilege
+ */
+void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos);
+
+/**
+ * \brief Allow non-secure access to peripheral
+ *
+ * \note The function does not configure privilege
+ */
+void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos);
+
+/**
+ * \brief Enable secure unprivileged access to peripheral
+ */
+void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint32_t pos);
+
+/**
+ * \brief Clear secure unprivileged access to peripheral
+ */
+void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint32_t pos);
+
+/**
+ * \brief Clears PPC interrupt.
+ */
+void ppc_clear_irq(void);
+
+/**
+ * \brief Configures SAU and IDAU.
+ */
+void sau_and_idau_cfg(void);
+
+/**
+ * \brief Sets to secure the initialized non-secure regions of
+ *        the Memory Protection Controller.
+ */
+void mpc_revert_non_secure_to_secure_cfg(void);
+
+#endif /* __TARGET_CFG_H__ */
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/tfm_hal_isolation.c b/platform/ext/target/arm/mps3/corstone_polaris/tfm_hal_isolation.c
new file mode 100644
index 0000000..576f4e8
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/tfm_hal_isolation.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "array.h"
+#include "cmsis.h"
+#include "Driver_Common.h"
+#include "mmio_defs.h"
+#include "mpu_armv8m_drv.h"
+#include "region.h"
+#include "target_cfg.h"
+#include "tfm_hal_isolation.h"
+
+#include "tfm_peripherals_def.h"
+#include "tfm_core_utils.h"
+#include "load/partition_defs.h"
+#include "load/asset_defs.h"
+#include "load/spm_load_api.h"
+
+/* It can be retrieved from the MPU_TYPE register. */
+#define MPU_REGION_NUM                  8
+
+#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
+static uint32_t n_configured_regions = 0;
+struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
+
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);
+REGION_DECLARE(Image$$, TFM_APP_CODE_START, $$Base);
+REGION_DECLARE(Image$$, TFM_APP_CODE_END, $$Base);
+REGION_DECLARE(Image$$, TFM_APP_RW_STACK_START, $$Base);
+REGION_DECLARE(Image$$, TFM_APP_RW_STACK_END, $$Base);
+REGION_DECLARE(Image$$, ER_INITIAL_PSP, $$ZI$$Base);
+REGION_DECLARE(Image$$, ER_INITIAL_PSP, $$ZI$$Limit);
+#ifdef TFM_SP_META_PTR_ENABLE
+REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$RW$$Base);
+REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$RW$$Limit);
+#endif /* TFM_SP_META_PTR_ENABLE */
+
+const struct mpu_armv8m_region_cfg_t region_cfg[] = {
+    /* Veneer region */
+    {
+        0, /* will be updated before using */
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+        MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+        MPU_ARMV8M_XN_EXEC_OK,
+        MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+        MPU_ARMV8M_SH_NONE,
+#ifdef TFM_PXN_ENABLE
+        MPU_ARMV8M_PRIV_EXEC_OK
+#endif
+    },
+    /* TFM Core unprivileged code region */
+    {
+        0, /* will be updated before using */
+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base),
+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit),
+        MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+        MPU_ARMV8M_XN_EXEC_OK,
+        MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+        MPU_ARMV8M_SH_NONE,
+#ifdef TFM_PXN_ENABLE
+        MPU_ARMV8M_PRIV_EXEC_OK
+#endif
+    },
+    /* NSPM PSP */
+    {
+        0, /* will be updated before using */
+        (uint32_t)&REGION_NAME(Image$$, ER_INITIAL_PSP, $$ZI$$Base),
+        (uint32_t)&REGION_NAME(Image$$, ER_INITIAL_PSP, $$ZI$$Limit),
+        MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
+        MPU_ARMV8M_XN_EXEC_NEVER,
+        MPU_ARMV8M_AP_RW_PRIV_UNPRIV,
+        MPU_ARMV8M_SH_NONE,
+#ifdef TFM_PXN_ENABLE
+        MPU_ARMV8M_PRIV_EXEC_NEVER
+#endif
+    },
+    /* RO region */
+    {
+        0, /* will be updated before using */
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_CODE_START, $$Base),
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_CODE_END, $$Base),
+        MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+        MPU_ARMV8M_XN_EXEC_OK,
+        MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+        MPU_ARMV8M_SH_NONE,
+#ifdef TFM_PXN_ENABLE
+#if TFM_LVL == 1
+        MPU_ARMV8M_PRIV_EXEC_OK
+#else
+        MPU_ARMV8M_PRIV_EXEC_NEVER
+#endif
+#endif
+    },
+    /* RW, ZI and stack as one region */
+    {
+        0, /* will be updated before using */
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base),
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base),
+        MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
+        MPU_ARMV8M_XN_EXEC_NEVER,
+        MPU_ARMV8M_AP_RW_PRIV_UNPRIV,
+        MPU_ARMV8M_SH_NONE,
+#ifdef TFM_PXN_ENABLE
+        MPU_ARMV8M_PRIV_EXEC_NEVER
+#endif
+    },
+#ifdef TFM_SP_META_PTR_ENABLE
+    /* TFM partition metadata pointer region */
+    {
+        0, /* will be updated before using */
+        (uint32_t)&REGION_NAME(Image$$, TFM_SP_META_PTR, $$RW$$Base),
+        (uint32_t)&REGION_NAME(Image$$, TFM_SP_META_PTR, $$RW$$Limit),
+        MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
+        MPU_ARMV8M_XN_EXEC_NEVER,
+        MPU_ARMV8M_AP_RW_PRIV_UNPRIV,
+        MPU_ARMV8M_SH_NONE,
+#ifdef TFM_PXN_ENABLE
+        MPU_ARMV8M_PRIV_EXEC_NEVER
+#endif
+    }
+#endif
+};
+#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
+
+enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
+{
+#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
+    struct mpu_armv8m_region_cfg_t localcfg;
+#endif
+    /* Set up isolation boundaries between SPE and NSPE */
+    sau_and_idau_cfg();
+    if (mpc_init_cfg() != TFM_PLAT_ERR_SUCCESS) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+    ppc_init_cfg();
+
+    /* Set up static isolation boundaries inside SPE */
+#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
+    int32_t i;
+
+    mpu_armv8m_clean(&dev_mpu_s);
+
+    if (ARRAY_SIZE(region_cfg) > MPU_REGION_NUM) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+    for (i = 0; i < ARRAY_SIZE(region_cfg); i++) {
+        spm_memcpy(&localcfg, &region_cfg[i], sizeof(localcfg));
+        localcfg.region_nr = i;
+        if (mpu_armv8m_region_enable(&dev_mpu_s,
+            (struct mpu_armv8m_region_cfg_t *)&localcfg)
+            != MPU_ARMV8M_OK) {
+            return TFM_HAL_ERROR_GENERIC;
+        }
+    }
+    n_configured_regions = i;
+
+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,
+                      HARDFAULT_NMI_ENABLE);
+#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
+
+    return TFM_HAL_SUCCESS;
+}
+
+/*
+ * Implementation of tfm_hal_bind_boundaries() on Corstone-Polaris:
+ *
+ * The API encodes some attributes into a handle and returns it to SPM.
+ * The attributes include isolation boundaries, privilege, and MMIO information.
+ * When scheduler switches running partitions, SPM compares the handle between
+ * partitions to know if boundary update is necessary. If update is required,
+ * SPM passes the handle to platform to do platform settings and update
+ * isolation boundaries.
+ */
+enum tfm_hal_status_t tfm_hal_bind_boundaries(
+                                    const struct partition_load_info_t *p_ldinf,
+                                    void **pp_boundaries)
+{
+    uint32_t i, j;
+    bool privileged;
+    const struct asset_desc_t *p_asset;
+    struct platform_data_t *plat_data_ptr;
+#if TFM_LVL == 2
+    struct mpu_armv8m_region_cfg_t localcfg;
+#endif
+    if (!p_ldinf || !pp_boundaries) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+
+#if TFM_LVL == 1
+    privileged = true;
+#else
+    privileged = !!(p_ldinf->flags & PARTITION_MODEL_PSA_ROT);
+#endif
+
+    p_asset = (const struct asset_desc_t *)LOAD_INFO_ASSET(p_ldinf);
+
+    /*
+     * Validate if the named MMIO of partition is allowed by the platform.
+     * Otherwise, skip validation.
+     *
+     * NOTE: Need to add validation of numbered MMIO if platform requires.
+     */
+    for (i = 0; i < p_ldinf->nassets; i++) {
+        if (!(p_asset[i].attr & ASSET_ATTR_NAMED_MMIO)) {
+            continue;
+        }
+        for (j = 0; j < ARRAY_SIZE(partition_named_mmio_list); j++) {
+            if (p_asset[i].dev.dev_ref == partition_named_mmio_list[j]) {
+                break;
+            }
+        }
+
+        if (j == ARRAY_SIZE(partition_named_mmio_list)) {
+            /* The MMIO asset is not in the allowed list of platform. */
+            return TFM_HAL_ERROR_GENERIC;
+        }
+        /* Assume PPC & MPC settings are required even under level 1 */
+        plat_data_ptr = REFERENCE_TO_PTR(p_asset[i].dev.dev_ref,
+                                         struct platform_data_t *);
+
+        if (plat_data_ptr->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) {
+            ppc_configure_to_secure(plat_data_ptr->periph_ppc_bank,
+                                    plat_data_ptr->periph_ppc_mask);
+            if (privileged) {
+                ppc_clr_secure_unpriv(plat_data_ptr->periph_ppc_bank,
+                                    plat_data_ptr->periph_ppc_mask);
+            } else {
+                ppc_en_secure_unpriv(plat_data_ptr->periph_ppc_bank,
+                                    plat_data_ptr->periph_ppc_mask);
+            }
+        }
+#if TFM_LVL == 2
+        /*
+         * Static boundaries are set. Set up MPU region for MMIO.
+         * Setup regions for unprivileged assets only.
+         */
+        if (!privileged) {
+            localcfg.region_base = plat_data_ptr->periph_start;
+            localcfg.region_limit = plat_data_ptr->periph_limit;
+            localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX;
+            localcfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+            localcfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+            localcfg.attr_sh = MPU_ARMV8M_SH_NONE;
+#ifdef TFM_PXN_ENABLE
+            localcfg.attr_pxn = MPU_ARMV8M_PRIV_EXEC_NEVER;
+#endif
+            localcfg.region_nr = n_configured_regions++;
+
+            if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg)
+                != MPU_ARMV8M_OK) {
+                return TFM_HAL_ERROR_GENERIC;
+            }
+        }
+#endif
+    }
+
+    *pp_boundaries = (void *)(((uint32_t)privileged) & HANDLE_ATTR_PRIV_MASK);
+
+    return TFM_HAL_SUCCESS;
+}
+
+enum tfm_hal_status_t tfm_hal_update_boundaries(
+                             const struct partition_load_info_t *p_ldinf,
+                             void *p_boundaries)
+{
+    CONTROL_Type ctrl;
+    bool privileged = !!((uint32_t)p_boundaries & HANDLE_ATTR_PRIV_MASK);
+
+    /* Privileged level is required to be set always */
+    ctrl.w = __get_CONTROL();
+    ctrl.b.nPRIV = privileged ? 0 : 1;
+    __set_CONTROL(ctrl.w);
+
+    return TFM_HAL_SUCCESS;
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/tfm_hal_platform.c b/platform/ext/target/arm/mps3/corstone_polaris/tfm_hal_platform.c
new file mode 100644
index 0000000..1ae8843
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/tfm_hal_platform.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis.h"
+#include "target_cfg.h"
+#include "tfm_hal_platform.h"
+#include "tfm_peripherals_def.h"
+#include "uart_stdout.h"
+#include "device_definition.h"
+
+enum tfm_hal_status_t tfm_hal_platform_init(void)
+{
+    enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
+    enum syscounter_armv8_m_cntrl_error_t counter_err = SYSCOUNTER_ARMV8_M_ERR_NONE;
+
+    plat_err = enable_fault_handlers();
+    if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+
+    plat_err = system_reset_cfg();
+    if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+
+    plat_err = init_debug();
+    if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+
+    /* Syscounter enabled by default. This way App-RoT partitions can use
+     * systimers without the need to add the syscounter as an mmio devide.
+     */
+    counter_err = syscounter_armv8_m_cntrl_init(&SYSCOUNTER_CNTRL_ARMV8_M_DEV_S);
+    if (counter_err != SYSCOUNTER_ARMV8_M_ERR_NONE) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+    __enable_irq();
+    stdio_init();
+
+    plat_err = nvic_interrupt_target_state_cfg();
+    if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+
+    plat_err = nvic_interrupt_enable();
+    if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+        return TFM_HAL_ERROR_GENERIC;
+    }
+
+    return TFM_HAL_SUCCESS;
+}
+
+void tfm_hal_system_reset(void)
+{
+    __disable_irq();
+    mpc_revert_non_secure_to_secure_cfg();
+
+    NVIC_SystemReset();
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/tfm_interrupts.c b/platform/ext/target/arm/mps3/corstone_polaris/tfm_interrupts.c
new file mode 100644
index 0000000..3ca0aac
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/tfm_interrupts.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include "cmsis.h"
+#include "spm_ipc.h"
+#include "tfm_hal_interrupt.h"
+#include "tfm_peripherals_def.h"
+#include "load/interrupt_defs.h"
+
+static struct irq_t timer0_irq = {0};
+
+void TFM_TIMER0_IRQ_Handler(void)
+{
+    spm_handle_interrupt(timer0_irq.p_pt, timer0_irq.p_ildi);
+}
+
+enum tfm_hal_status_t tfm_timer0_irq_init(void *p_pt,
+                                          struct irq_load_info_t *p_ildi)
+{
+    timer0_irq.p_ildi = p_ildi;
+    timer0_irq.p_pt = p_pt;
+
+    NVIC_SetPriority(TFM_TIMER0_IRQ, DEFAULT_IRQ_PRIORITY);
+    NVIC_ClearTargetState(TFM_TIMER0_IRQ);
+    NVIC_DisableIRQ(TFM_TIMER0_IRQ);
+
+    return TFM_HAL_SUCCESS;
+}
diff --git a/platform/ext/target/arm/mps3/corstone_polaris/tfm_peripherals_def.h b/platform/ext/target/arm/mps3/corstone_polaris/tfm_peripherals_def.h
new file mode 100644
index 0000000..f348869
--- /dev/null
+++ b/platform/ext/target/arm/mps3/corstone_polaris/tfm_peripherals_def.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PERIPHERALS_DEF_H__
+#define __TFM_PERIPHERALS_DEF_H__
+
+#include "platform_irq.h"
+#include "target_cfg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Quantized default IRQ priority, the value is:
+ * (Number of configurable priority) / 4: (1UL << __NVIC_PRIO_BITS) / 4
+ */
+#define DEFAULT_IRQ_PRIORITY    (1UL << (__NVIC_PRIO_BITS - 2))
+
+#define TFM_TIMER0_IRQ           (TIMER0_IRQn)
+
+extern struct platform_data_t tfm_peripheral_std_uart;
+extern struct platform_data_t tfm_peripheral_timer0;
+
+#define TFM_PERIPHERAL_STD_UART  (&tfm_peripheral_std_uart)
+#define TFM_PERIPHERAL_TIMER0    (&tfm_peripheral_timer0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_PERIPHERALS_DEF_H__ */