summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorKshitij Sisodia <kshitij.sisodia@arm.com>2024-04-08 09:58:46 +0100
committerKshitij Sisodia <kshitij.sisodia@arm.com>2024-05-03 14:52:28 +0100
commit4cef9acc2624a31111b47c25b8b1a2f37f7e0cb9 (patch)
tree6a43d17ae1ded33b4115dbe2cd70fcad42a027a3 /source
parent6bc730c0aab22aa0ac147283a1b19eaf11a80d1a (diff)
downloadml-embedded-evaluation-kit-4cef9acc2624a31111b47c25b8b1a2f37f7e0cb9.tar.gz
MLECO-4825: Adding Arm Corstone-315 support
This patch adds initial support for MPS4 based Arm Corstone-315 FVPs. The applications will execute on the FVP but with INITSVTOR set to `0x12000000` explicitly. The default value is the 64kiB code region at `0x11000000`. The linker scripts will be changed for the initial boot logic and vector table to be moved to the code region. This patch adds `source/hal/source/platform/mps4` directory. There is considerable overlap with MPS3 platform and this is expected to be the case until the support for MPS4 matures. Refactoring to pull in common bits from these targets will follow. Same goes for the CMake build support added under `scripts/cmake/platforms/mps4`. Change-Id: I981be9e1ec57cfedcf7d340b4f19e5eb40b5cbd3 Signed-off-by: Kshitij Sisodia <kshitij.sisodia@arm.com> Tested-by: mlecosys <mlecosys@arm.com> Reviewed-by: Conor Kennedy <conor.kennedy@arm.com> Reviewed-by: Alex Tawse <alex.tawse@arm.com> Signed-off-by: Kshitij Sisodia <kshitij.sisodia@arm.com>
Diffstat (limited to 'source')
-rw-r--r--source/application/main/Main.cc5
-rw-r--r--source/hal/source/platform/mps4/CMakeLists.txt150
-rw-r--r--source/hal/source/platform/mps4/include/platform_drivers.h47
-rw-r--r--source/hal/source/platform/mps4/include/sse-315/mem_regions.h124
-rw-r--r--source/hal/source/platform/mps4/include/sse-315/peripheral_irqs.h121
-rw-r--r--source/hal/source/platform/mps4/include/sse-315/peripheral_memmap.h196
-rw-r--r--source/hal/source/platform/mps4/include/timer_mps4.h64
-rw-r--r--source/hal/source/platform/mps4/readme.md3
-rw-r--r--source/hal/source/platform/mps4/source/platform_drivers.c180
-rw-r--r--source/hal/source/platform/mps4/source/smm_mps4.h152
-rw-r--r--source/hal/source/platform/mps4/source/timer_mps4.c230
11 files changed, 1270 insertions, 2 deletions
diff --git a/source/application/main/Main.cc b/source/application/main/Main.cc
index bbe35d9..08ac978 100644
--- a/source/application/main/Main.cc
+++ b/source/application/main/Main.cc
@@ -1,5 +1,6 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2021-2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,7 +37,7 @@ static void print_application_intro()
{
info("%s\n", PRJ_DES_STR);
info("Version %s Build date: " __DATE__ " @ " __TIME__ "\n", PRJ_VER_STR);
- info("Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>\n\n");
+ info("Copyright 2021-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>\n\n");
}
int main ()
diff --git a/source/hal/source/platform/mps4/CMakeLists.txt b/source/hal/source/platform/mps4/CMakeLists.txt
new file mode 100644
index 0000000..679d5b3
--- /dev/null
+++ b/source/hal/source/platform/mps4/CMakeLists.txt
@@ -0,0 +1,150 @@
+#----------------------------------------------------------------------------
+# SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+# affiliates <open-source-office@arm.com>
+# 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.
+#----------------------------------------------------------------------------
+
+#########################################################
+# MPS4 platform support library #
+#########################################################
+
+cmake_minimum_required(VERSION 3.21.0)
+set(PLATFORM_DRIVERS_TARGET platform_drivers)
+project(${PLATFORM_DRIVERS_TARGET}
+ DESCRIPTION "Platform drivers library for MPS4 FPGA/FVP targets"
+ LANGUAGES C CXX ASM)
+
+# 1. We should be cross-compiling (MPS4 target only runs Cortex-M targets)
+if (NOT ${CMAKE_CROSSCOMPILING})
+ message(FATAL_ERROR "No ${PLATFORM_DRIVERS_TARGET} support for this target.")
+endif()
+# Define target specific base addresses here (before adding the components)
+if (TARGET_SUBSYSTEM STREQUAL sse-315)
+ set(UART0_BASE "0x48203000" CACHE STRING "UART base address")
+ set(UART0_BAUDRATE "115200" CACHE STRING "UART baudrate")
+ set(SYSTEM_CORE_CLOCK "25000000" CACHE STRING "System peripheral clock (Hz)")
+
+ set(ETHOS_U_IRQN "16" CACHE STRING "Ethos-U Interrupt")
+ set(ETHOS_U_SEC_ENABLED "1" CACHE STRING "Ethos-U NPU Security enable")
+ set(ETHOS_U_PRIV_ENABLED "1" CACHE STRING "Ethos-U NPU Privilege enable")
+
+ if (ETHOS_U_SEC_ENABLED)
+ set(ETHOS_U_BASE_ADDR "0x50004000" CACHE STRING "Ethos-U NPU base address")
+ else ()
+ set(ETHOS_U_BASE_ADDR "0x40004000" CACHE STRING "Ethos-U NPU base address")
+ endif ()
+
+ if (ETHOS_U_NPU_TIMING_ADAPTER_ENABLED)
+ message(FATAL_ERROR "Timing adapter support should be disabled for ${TARGET_SUBSYSTEM}")
+ endif()
+endif()
+
+set(DYNAMIC_MODEL_BASE "0x90000000" CACHE STRING "Region to be used for dynamic load of model into memory")
+set(DYNAMIC_MODEL_SIZE "0x02000000" CACHE STRING "Size of the space reserved for the model")
+
+math(EXPR IFM_BASE "${DYNAMIC_MODEL_BASE} + ${DYNAMIC_MODEL_SIZE}" OUTPUT_FORMAT HEXADECIMAL)
+set(DYNAMIC_IFM_BASE "${IFM_BASE}" CACHE STRING "Base address for IFMs to be loaded")
+set(DYNAMIC_IFM_SIZE "0x01000000" CACHE STRING "Size of the space reserved for the IFM")
+math(EXPR OFM_BASE "${DYNAMIC_IFM_BASE} + ${DYNAMIC_IFM_SIZE}" OUTPUT_FORMAT HEXADECIMAL)
+set(DYNAMIC_OFM_BASE "${OFM_BASE}" CACHE STRING "Base address for OFMs to be dumped to")
+set(DYNAMIC_OFM_SIZE "0x01000000" CACHE STRING "Size of the space reserved for the OFM")
+
+
+# 2. Create static library
+add_library(${PLATFORM_DRIVERS_TARGET} STATIC)
+
+## Include directories - private
+target_include_directories(${PLATFORM_DRIVERS_TARGET}
+ PRIVATE
+ source)
+
+## Include directories - public
+target_include_directories(${PLATFORM_DRIVERS_TARGET}
+ PUBLIC
+ include
+ include/${TARGET_SUBSYSTEM})
+
+## Platform sources
+target_sources(${PLATFORM_DRIVERS_TARGET}
+ PRIVATE
+ source/timer_mps4.c
+ source/platform_drivers.c)
+
+## Directory for additional components required by MPS4:
+if (NOT DEFINED COMPONENTS_DIR)
+ set(COMPONENTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../components)
+endif()
+
+## Platform component: cmsis_device (provides generic Cortex-M start up library)
+add_subdirectory(${COMPONENTS_DIR}/cmsis_device ${CMAKE_BINARY_DIR}/cmsis_device)
+
+## Platform component: stdout
+set(STDOUT_RETARGET ON CACHE BOOL "Retarget stdout/err to UART")
+add_subdirectory(${COMPONENTS_DIR}/stdout ${CMAKE_BINARY_DIR}/stdout)
+
+## Platform component: lcd
+add_subdirectory(${COMPONENTS_DIR}/lcd ${CMAKE_BINARY_DIR}/lcd)
+
+## Platform component: PMU
+add_subdirectory(${COMPONENTS_DIR}/platform_pmu ${CMAKE_BINARY_DIR}/platform_pmu)
+
+## Logging utilities:
+if (NOT TARGET log)
+ if (NOT DEFINED LOG_PROJECT_DIR)
+ message(FATAL_ERROR "LOG_PROJECT_DIR needs to be defined.")
+ endif()
+ add_subdirectory(${LOG_PROJECT_DIR} ${CMAKE_BINARY_DIR}/log)
+endif()
+
+# Add dependencies:
+target_link_libraries(${PLATFORM_DRIVERS_TARGET} PUBLIC
+ log
+ cmsis_device
+ platform_pmu
+ lcd_stubs
+ $<IF:$<BOOL:STDOUT_RETARGET>,stdout_retarget_cmsdk,stdout>)
+
+# Set the CPU profiling definition
+if (CPU_PROFILE_ENABLED)
+ target_compile_definitions(${PLATFORM_DRIVERS_TARGET} PUBLIC CPU_PROFILE_ENABLED)
+endif()
+
+# If Ethos-U is enabled, we need the driver library too
+if (ETHOS_U_NPU_ENABLED)
+
+ ## Platform component: Ethos-U initialization
+ add_subdirectory(${COMPONENTS_DIR}/npu ${CMAKE_BINARY_DIR}/npu)
+
+ target_link_libraries(${PLATFORM_DRIVERS_TARGET}
+ PUBLIC
+ ethos_u_npu)
+
+ if (ETHOS_U_NPU_TIMING_ADAPTER_ENABLED)
+ ## Platform component: Ethos-U timing adapter initialization
+ add_subdirectory(${COMPONENTS_DIR}/npu_ta ${CMAKE_BINARY_DIR}/npu_ta)
+
+ target_link_libraries(${PLATFORM_DRIVERS_TARGET}
+ PUBLIC
+ ethos_u_ta)
+ endif()
+
+endif()
+
+# 3. Display status:
+message(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR})
+message(STATUS "*******************************************************")
+message(STATUS "Library : " ${PLATFORM_DRIVERS_TARGET})
+message(STATUS "CMAKE_SYSTEM_PROCESSOR : " ${CMAKE_SYSTEM_PROCESSOR})
+message(STATUS "*******************************************************")
diff --git a/source/hal/source/platform/mps4/include/platform_drivers.h b/source/hal/source/platform/mps4/include/platform_drivers.h
new file mode 100644
index 0000000..d3060de
--- /dev/null
+++ b/source/hal/source/platform/mps4/include/platform_drivers.h
@@ -0,0 +1,47 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
+ * 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.
+ */
+
+#ifndef PLATFORM_DRIVERS_H
+#define PLATFORM_DRIVERS_H
+
+#include "log_macros.h" /* Logging related helpers. */
+
+/* Platform components */
+#include "RTE_Components.h" /* For CPU related defintiions */
+#include "timer_mps4.h" /* Timer functions. */
+#include "user_input.h" /* User input function */
+#include "lcd_img.h" /* LCD functions. */
+
+/**
+ * @brief Initialises the platform components.
+ * @return 0 if successful, error code otherwise.
+ */
+int platform_init(void);
+
+/**
+ * @brief Teardown for platform components.
+ */
+void platform_release(void);
+
+/**
+ * @brief Gets the platform name.
+ * @return Pointer to the name
+ */
+const char* platform_name(void);
+
+#endif /* PLATFORM_DRIVERS_H */
diff --git a/source/hal/source/platform/mps4/include/sse-315/mem_regions.h b/source/hal/source/platform/mps4/include/sse-315/mem_regions.h
new file mode 100644
index 0000000..8fc111b
--- /dev/null
+++ b/source/hal/source/platform/mps4/include/sse-315/mem_regions.h
@@ -0,0 +1,124 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
+ * 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.
+ */
+
+#ifndef MEM_REGION_DEFS_H
+#define MEM_REGION_DEFS_H
+
+/** Sizes */
+#define ITCM_SIZE (0x00080000) /* ITCM size */
+#define DTCM_BLK_SIZE (0x00020000) /* DTCM size, 4 banks of this size available */
+#define BRAM_SIZE (0x00200000) /* BRAM size */
+#define ISRAM0_SIZE (0x00200000) /* ISRAM0 size */
+#define ISRAM1_SIZE (0x00200000) /* ISRAM1 size */
+#define QSPI_SRAM_SIZE (0x00800000) /* QSPI Flash size */
+#define DDR4_BLK_SIZE (0x10000000) /* DDR4 block size */
+
+/** Non-secure addresses */
+#define ITCM_BASE_NS (0x00000000) /* Instruction TCM Non-Secure base address */
+#define BRAM_BASE_NS (0x01000000) /* FPGA 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 (0x21200000) /* Internal SRAM Area Non-Secure base address */
+#define QSPI_SRAM_BASE_NS (0x28000000) /* QSPI SRAM Non-Secure base address */
+#define DDR4_BLK0_BASE_NS (0x60000000) /* DDR4 block 0 Non-Secure base address */
+#define DDR4_BLK1_BASE_NS (0x80000000) /* DDR4 block 1 Non-Secure base address */
+#define DDR4_BLK2_BASE_NS (0xA0000000) /* DDR4 block 2 Non-Secure base address */
+#define DDR4_BLK3_BASE_NS (0xC0000000) /* DDR4 block 3 Non-Secure base address */
+
+/** Secure addresses */
+#define ITCM_BASE_S (0x10000000) /* Instruction TCM Secure base address */
+#define BRAM_BASE_S (0x12000000) /* FPGA 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 (0x31200000) /* Internal SRAM Area Secure base address */
+#define DDR4_BLK0_BASE_S (0x70000000) /* DDR4 block 0 Secure base address */
+#define DDR4_BLK1_BASE_S (0x90000000) /* DDR4 block 1 Secure base address */
+#define DDR4_BLK2_BASE_S (0xB0000000) /* DDR4 block 2 Secure base address */
+#define DDR4_BLK3_BASE_S (0xD0000000) /* DDR4 block 3 Secure base address */
+
+/** All VMs use the same MPC block size as defined by VMMPCBLKSIZE. */
+#define SRAM_MPC_BLK_SIZE (0x4000) /* 16 kB */
+#define QSPI_MPC_BLK_SIZE (0x40000) /* 256 kB */
+#define DDR4_MPC_BLK_SIZE (0x100000) /* 1 MB */
+
+/** 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 -- 2 MB*/
+#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 -- 2 MB */
+#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 /* MEM_REGION_DEFS_H */
diff --git a/source/hal/source/platform/mps4/include/sse-315/peripheral_irqs.h b/source/hal/source/platform/mps4/include/sse-315/peripheral_irqs.h
new file mode 100644
index 0000000..e6004b5
--- /dev/null
+++ b/source/hal/source/platform/mps4/include/sse-315/peripheral_irqs.h
@@ -0,0 +1,121 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
+ * 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.
+ */
+
+#ifndef PERIPHERAL_IRQS_H
+#define PERIPHERAL_IRQS_H
+
+/******************************************************************************/
+/* Peripheral interrupt numbers */
+/******************************************************************************/
+
+/* ------------------- Cortex-M Processor Exceptions Numbers -------------- */
+/* -14 to -1 should be defined by the system header */
+/* ---------------------- Core Specific Interrupt Numbers ------------------*/
+#define NONSEC_WATCHDOG_IRQn (1) /* Non-Secure Watchdog Interrupt */
+#define SLOWCLK_TIMER_IRQn (2) /* SLOWCLK Timer Interrupt */
+#define TIMER0_IRQn (3) /* TIMER 0 Interrupt */
+#define TIMER1_IRQn (4) /* TIMER 1 Interrupt */
+#define TIMER2_IRQn (5) /* TIMER 2 Interrupt */
+
+/** 6,7 and 8 are reserved */
+
+#define MPC_IRQn (9) /* MPC Combined (Secure) Interrupt */
+#define PPC_IRQn (10) /* PPC Combined (Secure) Interrupt */
+#define MSC_IRQn (11) /* MSC Combined (Secure) Interrput */
+#define BRIDGE_ERROR_IRQn (12) /* Bridge Error Combined (Secure) Interrupt*/
+
+/** 13 reserved */
+
+#define Combined_PPU_IRQn (14) /* Combined PPU */
+#define SDC_IRQn (15) /* Secure Debug channel Interrupt */
+#define NPU0_IRQn (16) /* NPU0 i.e., EthosU_IRQn */
+
+/** 17, 18 and 19 are reserved */
+
+#define KMU_IRQn (20) /* KMU Interrupt */
+
+/** 21, 22 and 23 are reserved */
+
+#define DMA_SEC_Combined_IRQn (24) /* DMA Secure Combined Interrupt */
+#define DMA_NONSEC_Combined_IRQn (25) /* DMA Non-Secure Combined Interrupt */
+#define DMA_SECURITY_VIOLATION_IRQn (26) /* DMA Security Violation Interrupt */
+#define TIMER3_AON_IRQn (27) /* TIMER 3 AON Interrupt */
+#define CPU0_CTI_0_IRQn (28) /* CPU0 CTI IRQ 0 */
+#define CPU0_CTI_1_IRQn (29) /* CPU0 CTI IRQ 1 */
+#define SAM_CRITICAL_SEVERITY_FAULT_IRQn (30) /* SAM Critical Severity Fault Interrupt */
+#define SAM_SEVERITY_FAULT_HANDLER_IRQn (31) /* SAM Severity Fault Handler Interrupt */
+
+/** 32 reserved */
+
+#define UARTRX0_IRQn (33) /* UART 0 RX Interrupt */
+#define UARTTX0_IRQn (34) /* UART 0 TX Interrupt */
+#define UARTRX1_IRQn (35) /* UART 1 RX Interrupt */
+#define UARTTX1_IRQn (36) /* UART 1 TX Interrupt */
+#define UARTRX2_IRQn (37) /* UART 2 RX Interrupt */
+#define UARTTX2_IRQn (38) /* UART 2 TX Interrupt */
+#define UARTRX3_IRQn (39) /* UART 3 RX Interrupt */
+#define UARTTX3_IRQn (40) /* UART 3 TX Interrupt */
+#define UARTRX4_IRQn (41) /* UART 4 RX Interrupt */
+#define UARTTX4_IRQn (42) /* UART 4 TX Interrupt */
+#define UART0_Combined_IRQn (43) /* UART 0 Combined Interrupt */
+#define UART1_Combined_IRQn (44) /* UART 1 Combined Interrupt */
+#define UART2_Combined_IRQn (45) /* UART 2 Combined Interrupt */
+#define UART3_Combined_IRQn (46) /* UART 3 Combined Interrupt */
+#define UART4_Combined_IRQn (47) /* UART 4 Combined Interrupt */
+#define UARTOVF_IRQn (48) /* UART 0, 1, 2, 3, 4 & 5 Overflow Interrupt */
+#define ETHERNET_IRQn (49) /* Ethernet Interrupt */
+#define I2S_IRQn (50) /* Audio I2S Interrupt */
+
+/** 51-16 are reserved */
+
+#define DMA_CHANNEL_0_IRQn (57) /* DMA Channel 0 Interrupt */
+#define DMA_CHANNEL_1_IRQn (58) /* DMA Channel 1 Interrupt */
+
+/** 59-68 are reseved */
+
+#define GPIO0_Combined_IRQn (69) /* GPIO 0 Combined Interrupt */
+#define GPIO1_Combined_IRQn (70) /* GPIO 1 Combined Interrupt */
+#define GPIO2_Combined_IRQn (71) /* GPIO 2 Combined Interrupt */
+#define GPIO3_Combined_IRQn (72) /* GPIO 3 Combined Interrupt */
+
+/** 73-124 are reserved */
+
+#define UARTRX5_IRQn (125) /* UART 5 RX Interrupt */
+#define UARTTX5_IRQn (126) /* UART 5 TX Interrupt */
+
+/** 127 reserved */
+
+#define RTC_IRQn (128) /* RTC Interrupt */
+
+/** 129-131 are reserved */
+
+#define ISP_IRQn (132) /* ISP C55 Interrupt */
+#define HDLCD_IRQn (133) /* HDLCD Interrupt */
+
+/** 134-223 are reserved */
+
+#define ARM_VSI0_IRQn (224) /* VSI 0 Interrupt */
+#define ARM_VSI1_IRQn (225) /* VSI 1 Interrupt */
+#define ARM_VSI2_IRQn (226) /* VSI 2 Interrupt */
+#define ARM_VSI3_IRQn (227) /* VSI 3 Interrupt */
+#define ARM_VSI4_IRQn (228) /* VSI 4 Interrupt */
+#define ARM_VSI5_IRQn (229) /* VSI 5 Interrupt */
+#define ARM_VSI6_IRQn (230) /* VSI 6 Interrupt */
+#define ARM_VSI7_IRQn (231) /* VSI 7 Interrupt */
+
+#endif /* PERIPHERAL_IRQS_H */
diff --git a/source/hal/source/platform/mps4/include/sse-315/peripheral_memmap.h b/source/hal/source/platform/mps4/include/sse-315/peripheral_memmap.h
new file mode 100644
index 0000000..203fb95
--- /dev/null
+++ b/source/hal/source/platform/mps4/include/sse-315/peripheral_memmap.h
@@ -0,0 +1,196 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates
+ * <open-source-office@arm.com> 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.
+ */
+
+#ifndef PERIPHERAL_MEMMAP_H
+#define PERIPHERAL_MEMMAP_H
+
+#include "mem_regions.h"
+
+#define DESIGN_NAME "Arm Corstone-315"
+
+/** Non-Secure subsystem peripheral region */
+#define DMA_350_BASE_NS 0x40002000 /* DMA350 register block Non-Secure base address */
+#define NPU0_APB_BASE_NS 0x40004000 /* NPU0 APB Non-Secure base address */
+#define CPU0_PWRCTRL_BASE_NS 0x40012000 /* CPU 0 Power Control Block Non-Secure base address */
+#define CPU0_IDENTITY_BASE_NS 0x4001F000 /* CPU 0 Identity Block Non-Secure base address */
+#define CORSTONE315_NSACFG_BASE_NS 0x40080000 /* Corstone-315 Non-Secure Access Configuration Register Block Non-Secure base address */
+
+/** Non-Secure MSTEXPPILL peripheral region */
+#define GPIO0_CMSDK_BASE_NS 0x40100000 /* GPIO 0 Non-Secure base address */
+#define GPIO1_CMSDK_BASE_NS 0x40101000 /* GPIO 1 Non-Secure base address */
+#define GPIO2_CMSDK_BASE_NS 0x40102000 /* GPIO 2 Non-Secure base address */
+#define GPIO3_CMSDK_BASE_NS 0x40103000 /* GPIO 3 Non-Secure base address */
+#define AHB_USER_0_BASE_NS 0x40104000 /* AHB USER 0 Non-Secure base address */
+#define AHB_USER_1_BASE_NS 0x40105000 /* AHB USER 1 Non-Secure base address */
+#define AHB_USER_2_BASE_NS 0x40106000 /* AHB USER 2 Non-Secure base address */
+#define AHB_USER_3_BASE_NS 0x40107000 /* AHB USER 3 Non-Secure base address */
+#define HDLCD_BASE_NS 0x40310000 /* HDLCD Non-Secure base address */
+#define ETHERNET_BASE_NS 0x40400000 /* Ethernet Non-Secure base address */
+#define USB_BASE_NS 0x40500000 /* USB Non-Secure base address */
+#define USER_APB0_BASE_NS 0x40700000 /* User APB 0 Non-Secure base address */
+#define USER_APB1_BASE_NS 0x40701000 /* User APB 1 Non-Secure base address */
+#define USER_APB2_BASE_NS 0x40702000 /* User APB 2 Non-Secure base address */
+#define USER_APB3_BASE_NS 0x40703000 /* User APB 3 Non-Secure base address */
+#define QSPI_CONFIG_BASE_NS 0x40800000 /* QSPI Config Non-Secure base address */
+#define QSPI_WRITE_BASE_NS 0x40801000 /* 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 CORSTONE315_SYSINFO_BASE_NS 0x48020000 /* Corstone-315 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 FPGA_SBCon_I2C_TOUCH_BASE_NS 0x48100000 /* FPGA - SBCon I2C (Touch) Non-Secure base address */
+#define FPGA_SBCon_I2C_AUDIO_BASE_NS 0x48101000 /* FPGA - SBCon I2C (Audio Conf) Non-Secure base address */
+#define FPGA_SPI_ADC_BASE_NS 0x48102000 /* FPGA - PL022 (SPI ADC) Non-Secure base address */
+#define FPGA_SPI_SHIELD0_BASE_NS 0x48103000 /* FPGA - PL022 (SPI Shield0) Non-Secure base address */
+#define FPGA_SPI_SHIELD1_BASE_NS 0x48104000 /* FPGA - PL022 (SPI Shield1) Non-Secure base address */
+#define SBCon_I2C_SHIELD0_BASE_NS 0x48105000 /* SBCon (I2C - Shield0) Non-Secure base address */
+#define SBCon_I2C_SHIELD1_BASE_NS 0x48106000 /* SBCon (I2C – Shield1) Non-Secure base address */
+#define USER_APB_BASE_NS 0x48107000 /* USER APB Non-Secure base address */
+#define FPGA_DDR4_EEPROM_BASE_NS 0x48108000 /* FPGA - SBCon I2C (DDR4 EEPROM) Non-Secure base address */
+#define FPGA_SCC_BASE_NS 0x48200000 /* FPGA - SCC registers Non-Secure base address */
+#define FPGA_I2S_BASE_NS 0x48201000 /* FPGA - I2S (Audio) Non-Secure base address */
+#define FPGA_IO_BASE_NS 0x48202000 /* FPGA - IO (System Ctrl + I/O) Non-Secure base address */
+#define UART0_BASE_NS 0x48203000 /* UART 0 Non-Secure base address */
+#define UART1_BASE_NS 0x48204000 /* UART 1 Non-Secure base address */
+#define UART2_BASE_NS 0x48205000 /* UART 2 Non-Secure base address */
+#define UART3_BASE_NS 0x48206000 /* UART 3 Non-Secure base address */
+#define UART4_BASE_NS 0x48207000 /* UART 4 Non-Secure base address */
+#define UART5_BASE_NS 0x48208000 /* UART 5 Non-Secure base address */
+#define RTC_BASE_NS 0x4820B000 /* RTC Non-Secure base address */
+#define ISP_BASE_NS 0x48300000 /* ISP SOC base address */
+#define ISP_VIRTUAL_CAMERA_BASE_NS 0x48400000 /* ISP Virtual Camera base address */
+
+#define VSOCKET_BASE_NS 0x4FEE0000 /*!< VSOCKET Non-Secure base address */
+#define VIO_BASE_NS 0x4FEF0000 /*!< VIO Non-Secure base address */
+#define VSI0_BASE_NS 0x4FF00000 /*!< VSI 0 Non-Secure base address */
+#define VSI1_BASE_NS 0x4FF10000 /*!< VSI 1 Non-Secure base address */
+#define VSI2_BASE_NS 0x4FF20000 /*!< VSI 2 Non-Secure base address */
+#define VSI3_BASE_NS 0x4FF30000 /*!< VSI 3 Non-Secure base address */
+#define VSI4_BASE_NS 0x4FF40000 /*!< VSI 4 Non-Secure base address */
+#define VSI5_BASE_NS 0x4FF50000 /*!< VSI 5 Non-Secure base address */
+#define VSI6_BASE_NS 0x4FF60000 /*!< VSI 6 Non-Secure base address */
+#define VSI7_BASE_NS 0x4FF70000 /*!< VSI 7 Non-Secure base address */
+
+/** Secure subsystem peripheral region */
+#define DMA_350_BASE_S 0x50002000 /* DMA350 register block Secure base address */
+#define NPU0_APB_BASE_S 0x50004000 /* NPU0 APB Secure base address */
+#define CPU0_SECCTRL_BASE_S 0x50011000 /* CPU 0 Local Security Control Block Secure base address */
+#define CPU0_PWRCTRL_BASE_S 0x50012000 /* CPU 0 Power Control Block Secure base address */
+#define CPU0_IDENTITY_BASE_S 0x5001F000 /* CPU 0 Identity Block Secure base address */
+#define CORSTONE315_SACFG_BASE_S 0x50080000 /* Corstone-315 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 */
+#define CC3XX_BASE_S 0x50094000 /* CryptoCell CC3XX Secure base address */
+#define KMU_BASE_S 0x5009E000 /* KMU Secure base address */
+#define LCM_BASE_S 0x500A0000 /* LCM Secure base address */
+
+/** Secure MSTEXPPILL peripheral region */
+#define GPIO0_CMSDK_BASE_S 0x50100000 /* GPIO 0 Secure base address */
+#define GPIO1_CMSDK_BASE_S 0x50101000 /* GPIO 1 Secure base address */
+#define GPIO2_CMSDK_BASE_S 0x50102000 /* GPIO 2 Secure base address */
+#define GPIO3_CMSDK_BASE_S 0x50103000 /* GPIO 3 Secure base address */
+#define AHB_USER_0_BASE_S 0x50104000 /* AHB USER 0 Secure base address */
+#define AHB_USER_1_BASE_S 0x50105000 /* AHB USER 1 Secure base address */
+#define AHB_USER_2_BASE_S 0x50106000 /* AHB USER 2 Secure base address */
+#define AHB_USER_3_BASE_S 0x50107000 /* AHB USER 3 Secure base address */
+#define HDLCD_BASE_S 0x50310000 /* HDLCD Secure base address */
+#define ETHERNET_BASE_S 0x50400000 /* Ethernet Secure base address */
+#define USB_BASE_S 0x50500000 /* USB Secure base address */
+#define USER_APB0_BASE_S 0x50700000 /* User APB 0 Secure base address */
+#define USER_APB1_BASE_S 0x50701000 /* User APB 1 Secure base address */
+#define USER_APB2_BASE_S 0x50702000 /* User APB 2 Secure base address */
+#define USER_APB3_BASE_S 0x50703000 /* User APB 3 Secure base address */
+#define QSPI_CONFIG_BASE_S 0x50800000 /* QSPI Config Secure base address */
+#define QSPI_WRITE_BASE_S 0x50801000 /* 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 CORSTONE315_SYSINFO_BASE_S 0x58020000 /* Corstone-315 System info Block Secure base address */
+#define CORSTONE315_SYSCTRL_BASE_S 0x58021000 /* Corstone-315 System control Block Secure base address */
+#define CORSTONE315_SYSPPU_BASE_S 0x58022000 /* Corstone-315 System Power Policy Unit Secure base address */
+#define CORSTONE315_CPU0PPU_BASE_S 0x58023000 /* Corstone-315 CPU 0 Power Policy Unit Secure base address */
+#define CORSTONE315_MGMTPPU_BASE_S 0x58028000 /* Corstone-315 Management Power Policy Unit Secure base address */
+#define CORSTONE315_DBGPPU_BASE_S 0x58029000 /* Corstone-315 Debug Power Policy Unit Secure base address */
+#define CORSTONE315_NPU0PPU_BASE_S 0x5802A000 /* Corstone-315 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 SAM_BASE_S 0x58042000 /* SAM 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 FPGA_SBCon_I2C_TOUCH_BASE_S 0x58100000 /* FPGA - SBCon I2C (Touch) Secure base address */
+#define FPGA_SBCon_I2C_AUDIO_BASE_S 0x58101000 /* FPGA - SBCon I2C (Audio Conf) Secure base address */
+#define FPGA_SPI_ADC_BASE_S 0x58102000 /* FPGA - PL022 (SPI ADC) Secure base address */
+#define FPGA_SPI_SHIELD0_BASE_S 0x58103000 /* FPGA - PL022 (SPI Shield0) Secure base address */
+#define FPGA_SPI_SHIELD1_BASE_S 0x58104000 /* FPGA - PL022 (SPI Shield1) Secure base address */
+#define SBCon_I2C_SHIELD0_BASE_S 0x58105000 /* SBCon (I2C - Shield0) Secure base address */
+#define SBCon_I2C_SHIELD1_BASE_S 0x58106000 /* SBCon (I2C – Shield1) Secure base address */
+#define USER_APB_BASE_S 0x58107000 /* USER APB Secure base address */
+#define FPGA_DDR4_EEPROM_BASE_S 0x58108000 /* FPGA - SBCon I2C (DDR4 EEPROM) Secure base address */
+#define FPGA_SCC_BASE_S 0x58200000 /* FPGA - SCC registers Secure base address */
+#define FPGA_I2S_BASE_S 0x58201000 /* FPGA - I2S (Audio) Secure base address */
+#define FPGA_IO_BASE_S 0x58202000 /* FPGA - IO (System Ctrl + I/O) Secure base address */
+#define UART0_BASE_S 0x58203000 /* UART 0 Secure base address */
+#define UART1_BASE_S 0x58204000 /* UART 1 Secure base address */
+#define UART2_BASE_S 0x58205000 /* UART 2 Secure base address */
+#define UART3_BASE_S 0x58206000 /* UART 3 Secure base address */
+#define UART4_BASE_S 0x58207000 /* UART 4 Secure base address */
+#define UART5_BASE_S 0x58208000 /* UART 5 Secure base address */
+#define RTC_BASE_S 0x5820B000 /* RTC Secure base address */
+
+#define VSOCKET_BASE_S 0x5FEE0000 /*!< VSOCKET Secure base address */
+#define VIO_BASE_S 0x5FEF0000 /*!< VIO Secure base address */
+#define VSI0_BASE_S 0x5FF00000 /*!< VSI 0 Secure base address */
+#define VSI1_BASE_S 0x5FF10000 /*!< VSI 1 Secure base address */
+#define VSI2_BASE_S 0x5FF20000 /*!< VSI 2 Secure base address */
+#define VSI3_BASE_S 0x5FF30000 /*!< VSI 3 Secure base address */
+#define VSI4_BASE_S 0x5FF40000 /*!< VSI 4 Secure base address */
+#define VSI5_BASE_S 0x5FF50000 /*!< VSI 5 Secure base address */
+#define VSI6_BASE_S 0x5FF60000 /*!< VSI 6 Secure base address */
+#define VSI7_BASE_S 0x5FF70000 /*!< VSI 7 Secure base address */
+
+/* TCM Security Gate register addresses */
+#define ITGU_CTRL_BASE 0xE001E500 /* TGU control register for ITCM */
+#define ITGU_CFG_BASE 0xE001E504 /* TGU configuration register for ITCM */
+#define ITGU_LUTn_BASE 0xE001E510 /* TGU Look Up Table register for ITCM */
+#define DTGU_CTRL_BASE 0xE001E600 /* TGU control register for DTCM */
+#define DTGU_CFG_BASE 0xE001E604 /* TGU configuration register for DTCM */
+#define DTGU_LUTn_BASE 0xE001E610 /* TGU Look Up Table register for DTCM */
+
+/* Memory map addresses exempt from memory attribution by both the SAU and IDAU */
+#define CORSTONE315_EWIC_BASE 0xE0047000 /* External Wakeup Interrupt Controller
+ * Access from Non-secure software is only allowed
+ * if AIRCR.BFHFNMINS is set to 1 */
+
+#endif /* PERIPHERAL_MEMMAP_H */
diff --git a/source/hal/source/platform/mps4/include/timer_mps4.h b/source/hal/source/platform/mps4/include/timer_mps4.h
new file mode 100644
index 0000000..49dc62d
--- /dev/null
+++ b/source/hal/source/platform/mps4/include/timer_mps4.h
@@ -0,0 +1,64 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
+ * 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.
+ */
+#ifndef TIMER_MPS4_H
+#define TIMER_MPS4_H
+
+#include "platform_pmu.h"
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#if defined (ARM_NPU)
+ #include "ethosu_profiler.h" /* Arm Ethos-U NPU profiling functions. */
+#endif /* defined (ARM_NPU) */
+
+/* Container for timestamp up-counters. */
+typedef struct mps4_pmu_counters_ {
+ uint32_t counter_1Hz;
+ uint32_t counter_100Hz;
+
+ /* Running at FPGA clock rate. See get_mps4_core_clock(). */
+ uint32_t counter_fpga;
+
+ /* Running at processor core's internal clock rate, triggered by SysTick. */
+ uint64_t counter_systick;
+} mps4_pmu_counters;
+
+/**
+ * @brief Resets the counters.
+ */
+void platform_reset_counters(void);
+
+/**
+ * @brief Gets the current counter values.
+ * @param[out] Pointer to a pmu_counters object.
+ **/
+void platform_get_counters(pmu_counters* counters);
+
+/**
+ * @brief Gets the MPS4 core clock
+ * @return Clock rate in Hz expressed as 32 bit unsigned integer.
+ */
+uint32_t get_mps4_core_clock(void);
+
+/**
+ * @brief System tick interrupt handler.
+ **/
+void SysTick_Handler(void);
+
+#endif /* TIMER_MPS4_H */
diff --git a/source/hal/source/platform/mps4/readme.md b/source/hal/source/platform/mps4/readme.md
new file mode 100644
index 0000000..2a17638
--- /dev/null
+++ b/source/hal/source/platform/mps4/readme.md
@@ -0,0 +1,3 @@
+## MPS4 platform drivers
+
+Project to provide HAL platform drivers for the Arm MPS4 FPGA/FVP targets.
diff --git a/source/hal/source/platform/mps4/source/platform_drivers.c b/source/hal/source/platform/mps4/source/platform_drivers.c
new file mode 100644
index 0000000..127d9b3
--- /dev/null
+++ b/source/hal/source/platform/mps4/source/platform_drivers.c
@@ -0,0 +1,180 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
+ * 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 "platform_drivers.h"
+
+#include "log_macros.h" /* Logging functions */
+#include "uart_stdout.h" /* stdout over UART. */
+#include "smm_mps4.h" /* Memory map for MPS4. */
+
+#if defined(ARM_NPU)
+#include "ethosu_npu_init.h"
+
+#if defined(ETHOS_U_NPU_TIMING_ADAPTER_ENABLED)
+#include "ethosu_ta_init.h"
+#endif /* ETHOS_U_NPU_TIMING_ADAPTER_ENABLED */
+
+#endif /* ARM_NPU */
+
+/**
+ * @brief Checks if the platform is valid by checking
+ * the CPU ID for the FPGA implementation against
+ * the register from the CPU core.
+ * @return 0 if successful, 1 otherwise
+ */
+static int verify_platform(void);
+
+/** Platform name */
+static const char* s_platform_name = DESIGN_NAME;
+
+int platform_init(void)
+{
+ int err = 0;
+
+ SystemCoreClockUpdate(); /* From start up code */
+
+ /* UART init - will enable valid use of printf (stdout
+ * re-directed at this UART (UART0) */
+ UartStdOutInit();
+
+ if (0 != (err = verify_platform())) {
+ return err;
+ }
+
+#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
+ info("Enabling I-cache.\n");
+ SCB_EnableICache();
+#endif /* __ICACHE_PRESENT */
+
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
+ info("Enabling D-cache.\n");
+ SCB_EnableDCache();
+#endif /* __DCACHE_PRESENT */
+
+#if defined(ARM_NPU)
+
+#if defined(ETHOS_U_NPU_TIMING_ADAPTER_ENABLED)
+ /* If the platform has timing adapter blocks along with Ethos-U core
+ * block, initialise them here. */
+ if (0 != (err = arm_ethosu_timing_adapter_init())) {
+ return err;
+ }
+#endif /* ETHOS_U_NPU_TIMING_ADAPTER_ENABLED */
+
+ int state;
+
+ /* If Arm Ethos-U NPU is to be used, we initialise it here */
+ if (0 != (state = arm_ethosu_npu_init())) {
+ return state;
+ }
+
+#endif /* ARM_NPU */
+
+ /* Print target design info */
+ info("Target system design: %s\n", s_platform_name);
+ return 0;
+}
+
+void platform_release(void)
+{
+ __disable_irq();
+}
+
+const char* platform_name(void)
+{
+ return s_platform_name;
+}
+
+#define CREATE_MASK(msb, lsb) (int)(((1U << ((msb) - (lsb) + 1)) - 1) << (lsb))
+#define MASK_BITS(arg, msb, lsb) (int)((arg) & CREATE_MASK(msb, lsb))
+#define EXTRACT_BITS(arg, msb, lsb) (int)(MASK_BITS(arg, msb, lsb) >> (lsb))
+
+static int verify_platform(void)
+{
+ uint32_t id = 0;
+ uint32_t fpgaid = 0;
+ uint32_t apnote = 0;
+ uint32_t rev = 0;
+ uint32_t aid = 0;
+ uint32_t fpga_clk = 0;
+ const uint32_t ascii_A = (uint32_t)('A');
+
+ /* Initialise the LEDs as the switches are */
+ MPS4_FPGAIO->LED = MPS4_FPGAIO->SWITCHES & 0xFF;
+
+ info("Processor internal clock: %" PRIu32 "Hz\n", get_mps4_core_clock());
+
+ /* Get revision information from various registers */
+ rev = MPS4_SCC->CFG_REG4;
+ fpgaid = MPS4_SCC->SCC_ID;
+ aid = MPS4_SCC->SCC_AID;
+ apnote = EXTRACT_BITS(fpgaid, 15, 4);
+ fpga_clk = get_mps4_core_clock();
+
+ info("V2M-MPS4 revision %c\n\n", (char)(rev + ascii_A));
+ info("Application Note AN%" PRIx32 ", Revision %c\n", apnote,
+ (char)(EXTRACT_BITS(aid, 23, 20) + ascii_A));
+ info("MPS4 build %d\n", EXTRACT_BITS(aid, 31, 24));
+ info("MPS4 core clock has been set to: %" PRIu32 "Hz\n", fpga_clk);
+
+ /* Display CPU ID */
+ id = SCB->CPUID;
+ info("CPU ID: 0x%08" PRIx32 "\n", id);
+
+ if(EXTRACT_BITS(id, 15, 8) == 0xD2) {
+ if (EXTRACT_BITS(id, 7, 4) == 3) {
+ info ("CPU: Cortex-M85 r%dp%d\n\n",
+ EXTRACT_BITS(id, 23, 20),EXTRACT_BITS(id, 3, 0));
+#if defined (ARMv81MML_DSP_DP_MVE_FP) || defined (CPU_CORTEX_M85)
+ /* CPU ID should be "0x_41_0f_d2_30" for Cortex-M85 */
+ return 0;
+#endif /* (ARMv81MML_DSP_DP_MVE_FP) || (CPU_CORTEX_M85) */
+ } else if (EXTRACT_BITS(id, 7, 4) == 2) {
+ info ("CPU: Cortex-M55 r%dp%d\n\n",
+ EXTRACT_BITS(id, 23, 20),EXTRACT_BITS(id, 3, 0));
+#if defined (CPU_CORTEX_M55)
+ /* CPU ID should be "0x_41_0f_d2_20" for Cortex-M55 */
+ return 0;
+#endif /* CPU_CORTEX_M55 */
+ } else if (EXTRACT_BITS(id, 7, 4) == 1) {
+ info ("CPU: Cortex-M33 r%dp%d\n\n",
+ EXTRACT_BITS(id, 23, 20),EXTRACT_BITS(id, 3, 0));
+#if defined (CPU_CORTEX_M33)
+ return 0;
+#endif /* CPU_CORTEX_M33 */
+ } else if (EXTRACT_BITS(id, 7, 4) == 0) {
+ info ("CPU: Cortex-M23 r%dp%d\n\n",
+ EXTRACT_BITS(id, 23, 20),EXTRACT_BITS(id, 3, 0));
+ } else {
+ info ("CPU: Cortex-M processor family");
+ }
+ } else if (EXTRACT_BITS(id, 15, 8) == 0xC6) {
+ info ("CPU: Cortex-M%d+ r%dp%d\n\n",
+ EXTRACT_BITS(id, 7, 4), EXTRACT_BITS(id, 23, 20),
+ EXTRACT_BITS(id, 3, 0));
+ } else {
+ info ("CPU: Cortex-M%d r%dp%d\n\n",
+ EXTRACT_BITS(id, 7, 4), EXTRACT_BITS(id, 23, 20),
+ EXTRACT_BITS(id, 3, 0));
+ }
+
+ /* If the CPU is anything other than Arm Cortex-M33, Arm Cortex-M55 or
+ * Arm Cortex-M85, we return 1 */
+ printf_err("CPU mismatch!\n");
+ return 1;
+}
diff --git a/source/hal/source/platform/mps4/source/smm_mps4.h b/source/hal/source/platform/mps4/source/smm_mps4.h
new file mode 100644
index 0000000..374ffbb
--- /dev/null
+++ b/source/hal/source/platform/mps4/source/smm_mps4.h
@@ -0,0 +1,152 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
+ * 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.
+ */
+#ifndef SMM_MPS4_H
+#define SMM_MPS4_H
+
+#include "peripheral_memmap.h" /* Peripheral memory map definitions. */
+
+#include "RTE_Components.h"
+
+#if defined ( __CC_ARM )
+#pragma anon_unions
+#endif
+
+/** FPGA System Register declaration */
+typedef struct
+{
+ __IO uint32_t LED; /* Offset: 0x000 (R/W) LED connections
+ * [31:2] : Reserved
+ * [1:0] : LEDs
+ */
+ uint32_t RESERVED1[1];
+ __IO uint32_t BUTTON; /* Offset: 0x008 (R/W) Buttons
+ * [31:2] : Reserved
+ * [1:0] : Buttons
+ */
+ uint32_t RESERVED2[1];
+ __IO uint32_t CLK1HZ; /* Offset: 0x010 (R/W) 1Hz up counter */
+ __IO uint32_t CLK100HZ; /* Offset: 0x014 (R/W) 100Hz up counter */
+ __IO uint32_t COUNTER; /* Offset: 0x018 (R/W) Cycle Up Counter
+ * Increments when 32-bit prescale counter reach zero
+ */
+ __IO uint32_t PRESCALE; /* Offset: 0x01C (R/W) Prescaler
+ * Bit[31:0] : reload value for prescale counter
+ */
+ __IO uint32_t PSCNTR; /* Offset: 0x020 (R/W) 32-bit Prescale counter
+ * current value of the pre-scaler counter
+ * The Cycle Up Counter increment when the prescale down counter reach 0
+ * The pre-scaler counter is reloaded with PRESCALE after reaching 0.
+ */
+ uint32_t RESERVED3[1];
+ __IO uint32_t SWITCHES; /* Offset: 0x028 (R/W) Switches
+ * [31:8] : Reserved
+ * [7:0] : Switches
+ */
+ uint32_t RESERVED4[8];
+ __IO uint32_t MISC; /* Offset: 0x04C (R/W) Misc control
+ * [31:10] : Reserved
+ * [9] :
+ * [8] :
+ * [7] : ADC_SPI_nCS
+ * [6] : CLCD_BL_CTRL
+ * [5] : CLCD_RD
+ * [4] : CLCD_RS
+ * [3] : CLCD_RESET
+ * [2] : SHIELD_1_SPI_nCS
+ * [1] : SHIELD_0_SPI_nCS
+ * [0] : CLCD_CS
+ */
+} MPS4_FPGAIO_TypeDef;
+
+/** SCC Register declaration */
+typedef struct
+{
+ __IO uint32_t CFG_REG0; /* Offset: 0x000 (R/W) Remaps block RAM to ZBT
+ * [31:1] : Reserved
+ * [0] 1 : REMAP BlockRam to ZBT
+ */
+ __IO uint32_t LEDS; /* Offset: 0x004 (R/W) Controls the MCC user LEDs
+ * [31:8] : Reserved
+ * [7:0] : MCC LEDs
+ */
+ uint32_t RESERVED0[1];
+ __I uint32_t SWITCHES; /* Offset: 0x00C (R/ ) Denotes the state of the MCC user switches
+ * [31:8] : Reserved
+ * [7:0] : These bits indicate state of the MCC switches
+ */
+ __I uint32_t CFG_REG4; /* Offset: 0x010 (R/ ) Denotes the board revision
+ * [31:4] : Reserved
+ * [3:0] : Used by the MCC to pass PCB revision. 0 = A 1 = B
+ */
+ __I uint32_t CFG_ACLK; /* Offset: 0x014 (R/ ) System Clock
+ */
+ uint32_t RESERVED1[34];
+ __IO uint32_t SYS_CFGDATA_RTN; /* Offset: 0x0A0 (R/W) User data register
+ * [31:0] : Data
+ */
+ __IO uint32_t SYS_CFGDATA_OUT; /* Offset: 0x0A4 (R/W) User data register
+ * [31:0] : Data
+ */
+ __IO uint32_t SYS_CFGCTRL; /* Offset: 0x0A8 (R/W) Control register
+ * [31] : Start (generates interrupt on write to this bit)
+ * [30] : R/W access
+ * [29:26] : Reserved
+ * [25:20] : Function value
+ * [19:12] : Reserved
+ * [11:0] : Device (value of 0/1/2 for supported clocks)
+ */
+ __IO uint32_t SYS_CFGSTAT; /* Offset: 0x0AC (R/W) Contains status information
+ * [31:2] : Reserved
+ * [1] : Error
+ * [0] : Complete
+ */
+ __IO uint32_t RESERVED2[20];
+ __IO uint32_t SCC_DLL; /* Offset: 0x100 (R/W) DLL Lock Register
+ * [31:24] : DLL LOCK MASK[7:0] - Indicate if the DLL locked is masked
+ * [23:16] : DLL LOCK MASK[7:0] - Indicate if the DLLs are locked or unlocked
+ * [15:1] : Reserved
+ * [0] : This bit indicates if all enabled DLLs are locked
+ */
+ uint32_t RESERVED3[957];
+ __I uint32_t SCC_AID; /* Offset: 0xFF8 (R/ ) SCC AID Register
+ * [31:24] : FPGA build number
+ * [23:20] : V2M-MPS4 target board revision (A = 0, B = 1)
+ * [19:11] : Reserved
+ * [10] : if “1” SCC_SW register has been implemented
+ * [9] : if “1” SCC_LED register has been implemented
+ * [8] : if “1” DLL lock register has been implemented
+ * [7:0] : number of SCC configuration register
+ */
+ __I uint32_t SCC_ID; /* Offset: 0xFFC (R/ ) Contains information about the FPGA image
+ * [31:24] : Implementer ID: 0x41 = ARM
+ * [23:20] : Application note IP variant number
+ * [19:16] : IP Architecture: 0x4 =AHB
+ * [15:4] : Primary part number: 386 = AN386
+ * [3:0] : Application note IP revision number
+ */
+} MPS4_SCC_TypeDef;
+
+/** Non-secure peripheral declarations */
+#define MPS4_FPGAIO ((MPS4_FPGAIO_TypeDef *) FPGA_IO_BASE_NS)
+#define MPS4_SCC ((MPS4_SCC_TypeDef *) FPGA_SCC_BASE_NS)
+
+/** Secure peripheral declarations */
+#define MPS4_FPGAIO_S ((MPS4_FPGAIO_TypeDef *) FPGA_IO_BASE_S)
+#define MPS4_SCC_S ((MPS4_SCC_TypeDef *) FPGA_SCC_BASE_S)
+
+#endif /* SMM_MPS4_H */
diff --git a/source/hal/source/platform/mps4/source/timer_mps4.c b/source/hal/source/platform/mps4/source/timer_mps4.c
new file mode 100644
index 0000000..4fc27c7
--- /dev/null
+++ b/source/hal/source/platform/mps4/source/timer_mps4.c
@@ -0,0 +1,230 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its
+ * affiliates <open-source-office@arm.com>
+ * 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 "timer_mps4.h"
+
+#include "log_macros.h"
+#include "smm_mps4.h" /* Memory map for MPS4. */
+
+static uint64_t cpu_cycle_count = 0; /* 64-bit cpu cycle counter */
+static const char* unit_cycles = "cycles";
+static const char* unit_ms = "milliseconds";
+
+/**
+ * @brief Gets the system tick triggered cycle counter for the CPU.
+ * @return 64-bit counter value.
+ **/
+static uint64_t Get_SysTick_Cycle_Count(void);
+
+/**
+ * SysTick initialisation
+ */
+static int Init_SysTick(void);
+
+/**
+ * @brief Adds one PMU counter to the counters' array
+ * @param value Value of the counter
+ * @param name Name for the given counter
+ * @param unit Unit for the "value"
+ * @param counters Pointer to the counter struct - the one to be populated.
+ * @return true if successfully added, false otherwise
+ */
+static bool add_pmu_counter(
+ uint64_t value,
+ const char* name,
+ const char* unit,
+ pmu_counters* counters);
+
+/**
+ * @brief Gets the evaluated millisecond timestamp from the given MPS4 counter struct.
+ * @param mps4_counters Pointer to the MPS4 counters.
+ * @return microseconds timestamp as 32 bit unsigned integer.
+ */
+static uint32_t get_tstamp_milliseconds(mps4_pmu_counters* mps4_counters);
+
+void platform_reset_counters(void)
+{
+ MPS4_FPGAIO->CLK1HZ = 0;
+ MPS4_FPGAIO->CLK100HZ = 0;
+ MPS4_FPGAIO->COUNTER = 0;
+
+ if (0 != Init_SysTick()) {
+ printf_err("Failed to initialise system tick config\n");
+ }
+ debug("system tick config ready\n");
+
+#if defined (ARM_NPU)
+ ethosu_pmu_init();
+#endif /* defined (ARM_NPU) */
+}
+
+void platform_get_counters(pmu_counters* counters)
+{
+ counters->num_counters = 0;
+ counters->initialised = true;
+ uint32_t i = 0;
+
+#if defined (ARM_NPU)
+ ethosu_pmu_counters npu_counters = ethosu_get_pmu_counters();
+ for (i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
+ add_pmu_counter(
+ npu_counters.npu_evt_counters[i].counter_value,
+ npu_counters.npu_evt_counters[i].name,
+ npu_counters.npu_evt_counters[i].unit,
+ counters);
+ }
+ for (i = 0; i < ETHOSU_DERIVED_NCOUNTERS; ++i) {
+ add_pmu_counter(
+ npu_counters.npu_derived_counters[i].counter_value,
+ npu_counters.npu_derived_counters[i].name,
+ npu_counters.npu_derived_counters[i].unit,
+ counters);
+ }
+ add_pmu_counter(
+ npu_counters.npu_total_ccnt,
+ "NPU TOTAL",
+ unit_cycles,
+ counters);
+#else
+ UNUSED(i);
+#endif /* defined (ARM_NPU) */
+
+#if defined(CPU_PROFILE_ENABLED)
+ mps4_pmu_counters mps4_counters = {
+ .counter_1Hz = MPS4_FPGAIO->CLK1HZ,
+ .counter_100Hz = MPS4_FPGAIO->CLK100HZ,
+ .counter_fpga = MPS4_FPGAIO->COUNTER,
+ .counter_systick = Get_SysTick_Cycle_Count()
+ };
+
+ add_pmu_counter(
+ mps4_counters.counter_systick,
+ "CPU TOTAL",
+ unit_cycles,
+ counters);
+
+ add_pmu_counter(
+ get_tstamp_milliseconds(&mps4_counters),
+ "DURATION",
+ unit_ms,
+ counters);
+#endif /* defined(CPU_PROFILE_ENABLED) */
+
+#if !defined(CPU_PROFILE_ENABLED)
+ UNUSED(get_tstamp_milliseconds);
+ UNUSED(Get_SysTick_Cycle_Count);
+ UNUSED(unit_ms);
+#if !defined(ARM_NPU)
+ UNUSED(unit_cycles);
+ UNUSED(add_pmu_counter);
+#endif /* !defined(ARM_NPU) */
+#endif /* !defined(CPU_PROFILE_ENABLED) */
+}
+
+uint32_t get_mps4_core_clock(void)
+{
+ const uint32_t default_clock = 32000000 /* 32 MHz clock */;
+ static int warned_once = 0;
+ if (0 != MPS4_SCC->CFG_ACLK) {
+ return MPS4_SCC->CFG_ACLK;
+ }
+
+ if (!warned_once) {
+ warn("MPS4_SCC->CFG_ACLK reads 0. Assuming default clock of %" PRIu32 "\n",
+ default_clock);
+ warned_once = 1;
+ }
+ return default_clock;
+}
+
+void SysTick_Handler(void)
+{
+ /* Increment the cycle counter based on load value. */
+ cpu_cycle_count += SysTick->LOAD + 1;
+}
+
+/**
+ * Gets the current SysTick derived counter value
+ */
+static uint64_t Get_SysTick_Cycle_Count(void)
+{
+ uint32_t systick_val;
+
+ NVIC_DisableIRQ(SysTick_IRQn);
+ systick_val = SysTick->VAL & SysTick_VAL_CURRENT_Msk;
+ NVIC_EnableIRQ(SysTick_IRQn);
+
+ return cpu_cycle_count + (SysTick->LOAD - systick_val);
+}
+
+
+/**
+ * SysTick initialisation
+ */
+static int Init_SysTick(void)
+{
+ const uint32_t ticks_10ms = get_mps4_core_clock()/100 + 1;
+ int err = 0;
+
+ /* Reset CPU cycle count value. */
+ cpu_cycle_count = 0;
+
+ /* Changing configuration for sys tick => guard from being
+ * interrupted. */
+ NVIC_DisableIRQ(SysTick_IRQn);
+
+ /* SysTick init - this will enable interrupt too. */
+ err = SysTick_Config(ticks_10ms);
+
+ /* Enable interrupt again. */
+ NVIC_EnableIRQ(SysTick_IRQn);
+
+ /* Wait for SysTick to kick off */
+ while (!err && !SysTick->VAL) {
+ __NOP();
+ }
+
+ return err;
+}
+
+static bool add_pmu_counter(uint64_t value,
+ const char* name,
+ const char* unit,
+ pmu_counters* counters)
+{
+ const uint32_t idx = counters->num_counters;
+ if (idx < NUM_PMU_COUNTERS) {
+ counters->counters[idx].value = value;
+ counters->counters[idx].name = name;
+ counters->counters[idx].unit = unit;
+ ++counters->num_counters;
+
+ debug("%s: %" PRIu64 " %s\n", name, value, unit);
+ return true;
+ }
+ printf_err("Failed to add PMU counter!\n");
+ return false;
+}
+
+static uint32_t get_tstamp_milliseconds(mps4_pmu_counters* mps4_counters)
+{
+ const uint32_t divisor = get_mps4_core_clock() / 1000;
+ if (mps4_counters->counter_100Hz > 100) {
+ return (mps4_counters->counter_100Hz * 10);
+ }
+ return (mps4_counters->counter_systick/divisor);
+}