From 948131b41a6a625209bfb05d927278a2aeeb6770 Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Fri, 13 Dec 2024 10:49:07 +0100 Subject: [PATCH] Snitch Cluster Offloading (#13) Added - Driver Functionality: - Introduced a cluster driver as part of the `runtime_host` that currently includes support for the snitch cluster. - Device Functionality: Introduced the `devices` folder to add device specific code and add external runtimes. - CONVOLVE Cluster Target: - Added a new cluster target named `CONVOLVE`. - VSCode Configuration: - Add VSCode configuration to enable automatic configuration of the C/C++ extension and support for the integrated CMake build flow on the IIS workstations. Changed - Refactored Test Infrastructure: - Split into generic and target-specific tests. - Organized subtests by execution environment (`host`, `snitchCluster`). - Clear distinction made between host code and cluster code. This allows to specify the ISA and ABI for the cluster and host code separately - Refactored CMake Flow**: - Refactored CMake build flow to collect all source into static `runtime_host` and `runtime_cluster_` library and keep ISA flags private. - Improve README**: - Added explanation to use the C/C++ extension for VSCode on the IIS workstations. - Simplified formatting commands Fixed - ISA Compatibility and Naked Functions: - Addressed invalid instructions by ensuring that the trampoline function and interrupt handlers are correctly compiled with the appropriate ISA and ABI configurations. - Fixed issues with improperly generated stack frames for functions executed before cluster initialization by enforcing the use of naked functions. - Compiler Warnings - Avoid `warning: trap_vector changed binding to STB_WEAK` --- .gitignore | 2 + .vscode/c_cpp_properties.json | 10 + CMakeLists.txt | 34 +- README.md | 42 +- cmake/Utils.cmake | 69 ++ devices/CMakeLists.txt | 15 + devices/snitch_cluster/CMakeLists.txt | 15 + .../snitch_cluster/trampoline_snitchCluster.c | 58 ++ drivers/CMakeLists.txt | 19 + drivers/cluster/CMakeLists.txt | 15 + drivers/cluster/offload_snitchCluster.c | 196 ++++ drivers/cluster/offload_snitchCluster.h | 24 + drivers/driver.h | 13 + hal/CMakeLists.txt | 4 +- targets/CMakeLists.txt | 7 + targets/chimera-convolve/CMakeLists.txt | 88 ++ targets/chimera-convolve/common.ldh | 57 ++ .../include/addr_maps/cluster_4_addr_map.h | 41 + .../include/addr_maps/soc_addr_map.h | 39 + targets/chimera-convolve/include/cluster_4.h | 13 + .../include/regs/cluster_4_reg.h | 894 ++++++++++++++++++ .../chimera-convolve/include/regs/soc_ctrl.h | 104 ++ targets/chimera-convolve/include/soc.h | 13 + targets/chimera-convolve/link.ld | 46 + targets/chimera-convolve/src/crt0.S | 132 +++ targets/chimera-host/CMakeLists.txt | 42 +- .../include/addr_maps/soc_addr_map.h | 25 + targets/chimera-host/include/regs/soc_ctrl.h | 23 + targets/chimera-host/include/soc.h | 13 + targets/chimera-host/src/crt0.S | 1 - targets/chimera-open/CMakeLists.txt | 69 +- .../include/{ => addr_maps}/soc_addr_map.h | 4 + targets/chimera-open/include/soc.h | 13 + targets/chimera-open/include/soc_ctrl.h | 17 - targets/chimera-open/src/crt0.S | 1 - targets/chimera-open/src/soc_ctrl.c | 91 -- tests/CMakeLists.txt | 12 +- tests/chimera-convolve/.gitkeep | 0 tests/chimera-host/.gitkeep | 0 tests/chimera-host/CMakeLists.txt | 8 + .../host}/CMakeLists.txt | 3 +- .../host/returnZero/CMakeLists.txt | 33 + .../host/returnZero/src_host/test_host.c} | 0 tests/chimera-open/CMakeLists.txt | 7 +- tests/chimera-open/host/.gitkeep | 0 .../chimera-open/snitchCluster/CMakeLists.txt | 8 + .../simpleOffload/CMakeLists.txt | 48 + .../simpleOffload/include/test_cluster.h | 16 + .../simpleOffload/include/test_host.h | 16 + .../simpleOffload/src_cluster/test_cluster.c | 61 ++ .../simpleOffload/src_host/test_host.c | 23 + .../testClusterOffload/CMakeLists.txt | 18 - .../src/testClusterOffload.c | 34 - tests/generic/testReturnZero/CMakeLists.txt | 18 - 54 files changed, 2333 insertions(+), 221 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 devices/CMakeLists.txt create mode 100644 devices/snitch_cluster/CMakeLists.txt create mode 100644 devices/snitch_cluster/trampoline_snitchCluster.c create mode 100644 drivers/CMakeLists.txt create mode 100644 drivers/cluster/CMakeLists.txt create mode 100644 drivers/cluster/offload_snitchCluster.c create mode 100644 drivers/cluster/offload_snitchCluster.h create mode 100644 drivers/driver.h create mode 100644 targets/chimera-convolve/CMakeLists.txt create mode 100644 targets/chimera-convolve/common.ldh create mode 100644 targets/chimera-convolve/include/addr_maps/cluster_4_addr_map.h create mode 100644 targets/chimera-convolve/include/addr_maps/soc_addr_map.h create mode 100644 targets/chimera-convolve/include/cluster_4.h create mode 100644 targets/chimera-convolve/include/regs/cluster_4_reg.h create mode 100644 targets/chimera-convolve/include/regs/soc_ctrl.h create mode 100644 targets/chimera-convolve/include/soc.h create mode 100644 targets/chimera-convolve/link.ld create mode 100644 targets/chimera-convolve/src/crt0.S create mode 100644 targets/chimera-host/include/addr_maps/soc_addr_map.h create mode 100644 targets/chimera-host/include/regs/soc_ctrl.h create mode 100644 targets/chimera-host/include/soc.h rename targets/chimera-open/include/{ => addr_maps}/soc_addr_map.h (87%) create mode 100644 targets/chimera-open/include/soc.h delete mode 100644 targets/chimera-open/include/soc_ctrl.h delete mode 100644 targets/chimera-open/src/soc_ctrl.c create mode 100644 tests/chimera-convolve/.gitkeep create mode 100644 tests/chimera-host/.gitkeep create mode 100644 tests/chimera-host/CMakeLists.txt rename tests/{generic => chimera-host/host}/CMakeLists.txt (75%) create mode 100644 tests/chimera-host/host/returnZero/CMakeLists.txt rename tests/{generic/testReturnZero/src/testReturn0.c => chimera-host/host/returnZero/src_host/test_host.c} (100%) create mode 100644 tests/chimera-open/host/.gitkeep create mode 100644 tests/chimera-open/snitchCluster/CMakeLists.txt create mode 100644 tests/chimera-open/snitchCluster/simpleOffload/CMakeLists.txt create mode 100644 tests/chimera-open/snitchCluster/simpleOffload/include/test_cluster.h create mode 100644 tests/chimera-open/snitchCluster/simpleOffload/include/test_host.h create mode 100644 tests/chimera-open/snitchCluster/simpleOffload/src_cluster/test_cluster.c create mode 100644 tests/chimera-open/snitchCluster/simpleOffload/src_host/test_host.c delete mode 100644 tests/chimera-open/testClusterOffload/CMakeLists.txt delete mode 100644 tests/chimera-open/testClusterOffload/src/testClusterOffload.c delete mode 100644 tests/generic/testReturnZero/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 4ac4e47..9632188 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *~ .ninja* **/build/* + +.vscode/settings.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..10c7365 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,10 @@ +{ + "configurations": [ + { + "name": "cMake", + "configurationProvider": "ms-vscode.cmake-tools", + "compileCommands": "${config:cmake.buildDirectory}/compile_commands.json" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 73acb1e..1c8404e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ # # Moritz Scherer # Viviane Potocnik +# Philip Wiese cmake_minimum_required(VERSION 3.13) @@ -27,16 +28,39 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) project(chimera-sdk LANGUAGES C ASM) +# WIESEP: It is important to set the ISA and ABI for the host and the cluster snitch +set(ABI ilp32) +set(ISA_CLUSTER_SNITCH rv32im) +set(ISA_HOST rv32imc) + +message(STATUS "[CHIMERA-SDK] ABI : ${ABI}") +message(STATUS "[CHIMERA-SDK] ISA_HOST : ${ISA_HOST}") +message(STATUS "[CHIMERA-SDK] ISA_CLUSTER_SNITCH : ${ISA_CLUSTER_SNITCH}") +if (${DISASSEMBLE_LIBRARIES}) + message(STATUS "[CHIMERA-SDK] DISASSEMBLE_LIBRARIES : ON") +else() + message(STATUS "[CHIMERA-SDK] DISASSEMBLE_LIBRARIES : OFF") +endif() + include(${CMAKE_CURRENT_LIST_DIR}/cmake/Utils.cmake) +################################################################################ +# Add subdirectories # +################################################################################ +# WIESEP: Targets have to be included before the other folders to make them available +# Depending on the target, the following static libraries have to added by the targets: +# - runtime_host +# - runtime_cluster_snitch add_subdirectory(targets) -add_subdirectory(hal) -add_library(chimera-sdk INTERFACE) -target_link_libraries(chimera-sdk INTERFACE hal) -target_link_libraries(chimera-sdk INTERFACE runtime) -target_sources(chimera-sdk INTERFACE $) +# Include other subdirectories +add_subdirectory(hal) +add_subdirectory(devices) +add_subdirectory(drivers) +################################################################################ +# Testing # +################################################################################ enable_testing() add_subdirectory(tests) diff --git a/README.md b/README.md index 6d26e1b..0f7a92b 100644 --- a/README.md +++ b/README.md @@ -53,17 +53,45 @@ The resulting binaries will be stored in `build/bin`, and can be used within the To format all source files, run ``` -python scripts/run_clang_format.py -ir hal/ -python scripts/run_clang_format.py -ir targets/ -python scripts/run_clang_format.py -ir tests/ +python scripts/run_clang_format.py -ir hal/ targets/ tests/ drivers/ ``` Our CI uses llvm-12 for clang-format, so on IIS machines you may run ``` -python scripts/run_clang_format.py -ir hal/ --clang-format-executable=/usr/pack/riscv-1.0-kgf/pulp-llvm-0.12.0/bin/clang-format +python scripts/run_clang_format.py -ir tests/ hal/ targets/ drivers/ --clang-format-executable=/usr/pack/riscv-1.0-kgf/pulp-llvm-0.12.0/bin/clang-format -python scripts/run_clang_format.py -ir targets/ --clang-format-executable=/usr/pack/riscv-1.0-kgf/pulp-llvm-0.12.0/bin/clang-format - -python scripts/run_clang_format.py -ir tests/ --clang-format-executable=/usr/pack/riscv-1.0-kgf/pulp-llvm-0.12.0/bin/clang-format +``` +## Visual Studio Code Integration + +To enable automatic configuration of the C/C++ extension and support for the integrated cMake build flow on the IIS workstations, add the following content to `.vscode/settings.json`: +```json +{ + "cmake.configureSettings": { + "TOOLCHAIN_DIR": "/usr/pack/riscv-1.0-kgf/pulp-llvm-0.12.0/bin", + "TARGET_PLATFORM": "chimera-convolve", + }, + "cmake.environment": { + "PATH": "/usr/pack/riscv-1.0-kgf/default/bin:${env:PATH}", + "LD_LIBRARY_PATH": "/usr/pack/riscv-1.0-kgf/lib64:/usr/pack/riscv-1.0-kgf/lib64", + } +} ``` +If you are not on an IIS system, you need to adjust the paths according to your local installation. + +## Technical Details + +### Mixed ISA Compilation +The current approach compiles all code for both the host and cluster cores into a single library. This requires precise handling to ensure compatibility between the different instruction set architectures (ISAs) and application binary interfaces (ABIs). +This requires careful handling to avoid invalid instructions caused by mismatched ISAs between the host and cluster cores. Hence, we define four CMake variables,`ABI`, `ISA_HOST`, and `ISA_CLUSTER_SNITCH`, to specify the appropriate ISA for each core type. The ABI has to be identical to ensure correct function calls. +Furthermore, the tests are split into `src_host` and `src_cluster` directories to clearly separate code executed on the host and cluster cores. + +### cMake Build Flow +All runtime functions executed by the host core are compiled into a dedicated `runtime_host` static library and the cluster code into `runtime_cluster_` (e.g. `runtime_cluster_snitch`). Additionally, the HAL layer is compiled into the `hal_host` static libary. +The final binary is seperated into two object libaries, one for the host and one for the cluster core. The host object library is linked with the `runtime_host` and `hal_host` libraries, while the cluster object library is linked with the `runtime_cluster_` library. The final binary is then linked from the two object libraries. + +### Warning +Special attention is required for functions that execute before the cluster core is fully initialized, such as the trampoline function and interrupt handlers. At this stage, critical resources like the stack, global pointer, and thread pointer are not yet configured. Consequently, the compiler must not generate code that allocates stack frames. To address this, such functions are implemented as naked functions, which prevent the compiler from adding prologues or epilogues that rely on stack operations. + +**It is recommended to always check the generated assembly code to ensure that the correct instructions are generated for the target core!** + diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake index 27e48a3..c89d077 100644 --- a/cmake/Utils.cmake +++ b/cmake/Utils.cmake @@ -29,3 +29,72 @@ macro(add_target_source name) message(WARNING "Path ${CMAKE_CURRENT_LIST_DIR}/${name} does not exist") endif() endmacro() + + +#[=======================================================================[.rst: +.. command:: add_chimera_subdirectories(target_platform, category, mappings) + + Add subdirectories based on a mapping of target platforms to folders. + The mappings are expected to be in the format ``target_platform:folder1,folder2,...``. + + :param target_platform: The target platform to build for. + :param category: The category of the subdirectories. + :param mappings: A list of mappings from target platforms to folders. + + .. code-block:: cmake + :caption Example Usage + + set(MAPPINGS + chimera-convolve:snitch_cluster + chimera-open:snitch_cluster + chimera-host: + ) + add_chimera_subdirectories(${TARGET_PLATFORM} "Device" ${MAPPINGS}) + +#]=======================================================================] +function(add_chimera_subdirectories target_platform category mappings) + # Initialize included folders + set(included_folders "") + + # Process mappings + foreach(mapping IN LISTS mappings) + string(FIND "${mapping}" ":" delim_pos) + if(delim_pos EQUAL -1) + message(WARNING "[CHIMERA-SDK] Invalid mapping entry: '${mapping}'. Skipping.") + continue() + endif() + + # Extract key and value + string(SUBSTRING "${mapping}" 0 ${delim_pos} key) + math(EXPR value_start "${delim_pos} + 1") + string(SUBSTRING "${mapping}" ${value_start} -1 value) + + if(key STREQUAL "${target_platform}") + list(APPEND included_folders ${value}) + break() + endif() + endforeach() + + string(REPLACE "," ";" included_folders "${included_folders}") + + # Align output with padding + string(LENGTH "[CHIMERA-SDK] Enabled ${category}s" category_prefix_length) + math(EXPR padding_length "36 - ${category_prefix_length}") + if(padding_length GREATER 0) + string(REPEAT " " ${padding_length} padding) + else() + set(padding "") + endif() + + # Debug: Print the folders being included + message(STATUS "[CHIMERA-SDK] Enabled ${category}s${padding}: ${included_folders}") + + # Add subdirectories, checking for a valid CMakeLists.txt + foreach(folder IN LISTS included_folders) + if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/${folder}/CMakeLists.txt) + add_subdirectory(${folder}) + else() + message(WARNING "[CHIMERA-SDK] ${category} folder '${folder}' does not contain a valid CMakeLists.txt. Skipping.") + endif() + endforeach() +endfunction() diff --git a/devices/CMakeLists.txt b/devices/CMakeLists.txt new file mode 100644 index 0000000..60dd76f --- /dev/null +++ b/devices/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Philip Wiese + +# Define mappings for devices +set(DEVICE_MAPPINGS + chimera-convolve:snitch_cluster + chimera-open:snitch_cluster + chimera-host: +) + +# Call the macro +add_chimera_subdirectories(${TARGET_PLATFORM} "Device" ${DEVICE_MAPPINGS}) diff --git a/devices/snitch_cluster/CMakeLists.txt b/devices/snitch_cluster/CMakeLists.txt new file mode 100644 index 0000000..79aae8f --- /dev/null +++ b/devices/snitch_cluster/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Philip Wiese + + +################################################################################ +# Snitch Cluster Runtime Library # +################################################################################ +file(GLOB_RECURSE C_SOURCES_SNITCH + "trampoline_snitchCluster.c" +) + +target_sources(runtime_cluster_snitch PRIVATE ${C_SOURCES_SNITCH}) diff --git a/devices/snitch_cluster/trampoline_snitchCluster.c b/devices/snitch_cluster/trampoline_snitchCluster.c new file mode 100644 index 0000000..4c38ba9 --- /dev/null +++ b/devices/snitch_cluster/trampoline_snitchCluster.c @@ -0,0 +1,58 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#include + +// Persistent trampoline function pointer for each core +extern void (*_trampoline_function)(void *); + +// Peristent argument storage for the trampoline function +extern void *_trampoline_args; + +// Persistant stack pointer storage for each core +extern void *_trampoline_stack; + +/** + * @brief Trampoline function for the cluster core. + * This function will set up the stack pointer and call the function. + * + * @warning Make sure that this function is compiled with ISA for the Snitch cores (RV32IM) + * + */ +// WIESEP: Make sure the compiler does not allocate a stack frame +void __attribute__((naked)) _trampoline() { + asm volatile( + // Get hart ID (hardware thread ID) + "csrr t1, mhartid\n" // Load mhartid into a0 + + // Load global pointer + ".option push\n" + ".option norelax\n" // Disable relaxation to ensure `la` behaves as expected + "la gp, __global_pointer$\n" // Load address of global pointer + ".option pop\n" + + // Set thread pointer (tp) to zero + "mv tp, zero\n" + + // Set up stack pointer + "la a0, _trampoline_stack\n" // Load address of _trampoline_stack + "slli t1, t1, 2\n" // Multiply hart ID by 4 (size of pointer) + "add a0, a0, t1\n" // Compute the address of _trampoline_stack[hartId] + "lw sp, 0(a0)\n" // Load stack pointer from the computed address + + // Load function pointer and arguments + "la a0, _trampoline_function\n" // Load address of _trampoline_function + "add a0, a0, t1\n" // Compute address of _trampoline_function[hartId] + "lw a1, 0(a0)\n" // Load function pointer into a1 + + "la a0, _trampoline_args\n" // Load address of _trampoline_args + "add a0, a0, t1\n" // Compute address of _trampoline_args[hartId] + "lw a0, 0(a0)\n" // Load argument pointer into a0 + + // Call the offloaded function + "jr a1\n" // Jump and link to the function pointer in a1 + ); +} diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt new file mode 100644 index 0000000..1798c9a --- /dev/null +++ b/drivers/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Philip Wiese + +# Define mappings for drivers +set(DRIVER_MAPPINGS + chimera-convolve:cluster + chimera-open:cluster + chimera-host: +) + +# Call the macro +add_chimera_subdirectories(${TARGET_PLATFORM} "Driver" ${DRIVER_MAPPINGS}) + + +# WIESEP: Export this directory as root include directory for the drivers +target_include_directories(runtime_host PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/drivers/cluster/CMakeLists.txt b/drivers/cluster/CMakeLists.txt new file mode 100644 index 0000000..6c70ec9 --- /dev/null +++ b/drivers/cluster/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Philip Wiese + + +################################################################################ +# Host Runtime Library # +################################################################################ +file(GLOB_RECURSE C_SOURCES + "offload_snitchCluster.c" +) + +target_sources(runtime_host PRIVATE ${C_SOURCES}) diff --git a/drivers/cluster/offload_snitchCluster.c b/drivers/cluster/offload_snitchCluster.c new file mode 100644 index 0000000..7275e88 --- /dev/null +++ b/drivers/cluster/offload_snitchCluster.c @@ -0,0 +1,196 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Moritz Scherer +// Philip Wiese + +#include "soc.h" +#include "offload_snitchCluster.h" + +#include +#include + +// Persistent trampoline function pointer for each core +void (*_trampoline_function[NUM_CLUSTER_CORES])(void *) = {NULL}; + +// Peristent argument storage for the trampoline function +void *_trampoline_args[NUM_CLUSTER_CORES] = {NULL}; + +// Persistant stack pointer storage for each core +void *_trampoline_stack[NUM_CLUSTER_CORES] = {NULL}; + +/** + * @brief Trampoline function for the cluster core. + * This function will set up the stack pointer and call the function. + * + * @warning Make sure that this function is compiled with ISA for the Snitch cores (RV32IM) + * + */ +extern void _trampoline(); + +/** + * @brief Generate a trampoline function for the cluster core. + * The trampoline function will set up the stack pointer and call the function. + * + * @param function Function pointer to offload + * @param args Arguments to pass to the function + * @param stack Stack pointer for core + * @return A pointer to the persistent trampoline function + */ +static void *_generate_trampoline(uint32_t core_id, void (*function)(void *), void *args, + void *stack) { + // Assign trampoline with captured arguments to the persistent function pointer + _trampoline_function[core_id] = function; + _trampoline_args[core_id] = args; + _trampoline_stack[core_id] = stack; + + // Store captured arguments in a persistent context if needed + return _trampoline; +} + +/** + * @brief Setup the interrupt handler for the cluster cores. + * All cores in all clusters will jump to the handler when an interrupt is triggered. + * + * @param handler Function pointer to the interrupt handler + */ +void setup_snitchCluster_interruptHandler(void *handler) { + volatile void **snitchTrapHandlerAddr = + (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET); + + *snitchTrapHandlerAddr = handler; +} + +/** + * @brief Offload a void function pointer to a cluster's core. + * The function will be executed on the specified core of the cluster. + * + * @param function Function pointer to offload + * @param args Arguments to pass to the function + * @param stack_ptr Stack pointer for the core + * @param clusterId ID of the cluster to offload to + * @param core_id ID of the core to offload to (cores are 0-indexed for each cluster) + */ +void offload_snitchCluster_core(void *function, void *args, void *stack_ptr, uint8_t clusterId, + uint32_t core_id) { + volatile void **snitchBootAddr = + (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET); + + // Core with hartid 0 is CVA6's, thus we start with 1 + uint32_t hartId = 1 + core_id; + for (uint32_t i = 0; i < clusterId; i++) { + hartId += _chimera_numCores[i]; + } + + *snitchBootAddr = _generate_trampoline(hartId, function, args, stack_ptr); + + // Check if the cluster is busy + wait_snitchCluster_busy(clusterId); + + // Send interrupt to the core + volatile uint32_t *interruptTarget = ((uint32_t *)CLINT_CTRL_BASE) + hartId; + *interruptTarget = 1; +} + +/** + * @brief Offload a void function pointer to a cluster. + * The function will be executed on all cores of the cluster. + * + * @param function Function pointer to offload + * @param clusterId ID of the cluster to offload to + */ +void offload_snitchCluster(void *function, void *args, void *stack_ptr, uint8_t clusterId) { + volatile void **snitchBootAddr = + (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET); + + // Core with hartid 0 is CVA6's, thus we start with 1 + uint32_t hartId = 1; + for (uint32_t i = 0; i < clusterId; i++) { + hartId += _chimera_numCores[i]; + } + + // Check if the cluster is busy + wait_snitchCluster_busy(clusterId); + + for (uint32_t i = 0; i < _chimera_numCores[clusterId]; i++) { + *snitchBootAddr = _generate_trampoline(hartId, function, args, stack_ptr); + // Send interrupt to the core + volatile uint32_t *interruptTarget = ((uint32_t *)CLINT_CTRL_BASE) + hartId + i; + *interruptTarget = 1; + } +} + +/** + * @brief Blocking wait for the cluster to become idle. + * The function busy waits until the cluster is ready. + * + * @warning In the current Snitch bootrom implementation each cores clears the busy flag as soon as + * is returned. Hence the busy flag does not reflect the actual status of the cluster. + * + * @todo Fix the bootrom after adding synchornization primitives for the Snitch cores. + * + * @param clusterId ID of the cluster to wait for. + */ +void wait_snitchCluster_busy(uint8_t clusterId) { + volatile int32_t *busy_ptr; + + if (clusterId == 0) { + busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_0_BUSY_REG_OFFSET); + } else if (clusterId == 1) { + busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_1_BUSY_REG_OFFSET); + } else if (clusterId == 2) { + busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_2_BUSY_REG_OFFSET); + } else if (clusterId == 3) { + busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_3_BUSY_REG_OFFSET); + } else if (clusterId == 4) { + busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_4_BUSY_REG_OFFSET); + } + + while (*busy_ptr == 1) { + } + // TODO: temporary race condition fix + for (int i = 0; i < 100; i++) { + // NOP + asm volatile("addi x0, x0, 0\n" :::); + } + + return; +} + +/** + * @brief Wait for the cluster to return a value. + * The function busy waits until the cluster returns a non-zero value. + * + * @warning The return values must be non-zero, otherwise the function will busy wait forever! + * + * @param clusterId ID of the cluster to wait for. + * @return uint32_t Return value of the cluster. + */ +uint32_t wait_snitchCluster_return(uint8_t clusterId) { + volatile int32_t *snitchReturnAddr; + if (clusterId == 0) { + snitchReturnAddr = + (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET); + } else if (clusterId == 1) { + snitchReturnAddr = + (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET); + } else if (clusterId == 2) { + snitchReturnAddr = + (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET); + } else if (clusterId == 3) { + snitchReturnAddr = + (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET); + } else if (clusterId == 4) { + snitchReturnAddr = + (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET); + } + + while (*snitchReturnAddr == 0) { + } + + uint32_t retVal = *snitchReturnAddr; + *snitchReturnAddr = 0; + + return retVal; +} diff --git a/drivers/cluster/offload_snitchCluster.h b/drivers/cluster/offload_snitchCluster.h new file mode 100644 index 0000000..e01d42f --- /dev/null +++ b/drivers/cluster/offload_snitchCluster.h @@ -0,0 +1,24 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _OFFLOAD_INCLUDE_GUARD_ +#define _OFFLOAD_INCLUDE_GUARD_ + +#include + +// Interrupts +void setup_snitchCluster_interruptHandler(void *handler); + +// Function Offloading +void offload_snitchCluster(void *function, void *args, void *stack_ptr, uint8_t clusterId); +void offload_snitchCluster_core(void *function, void *args, void *stack_ptr, uint8_t clusterId, + uint32_t core_id); + +// Synchronization +void wait_snitchCluster_busy(uint8_t clusterId); +uint32_t wait_snitchCluster_return(uint8_t clusterId); + +#endif //_OFFLOAD_INCLUDE_GUARD_ \ No newline at end of file diff --git a/drivers/driver.h b/drivers/driver.h new file mode 100644 index 0000000..6c67411 --- /dev/null +++ b/drivers/driver.h @@ -0,0 +1,13 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _DRIVER_INCLUDE_GUARD_ +#define _DRIVER_INCLUDE_GUARD_ + +// WIESEP: Common header for all drivers +#include "cluster/offload_snitchCluster.h" + +#endif //_DRIVER_INCLUDE_GUARD_ diff --git a/hal/CMakeLists.txt b/hal/CMakeLists.txt index ed20361..c1c6bf3 100644 --- a/hal/CMakeLists.txt +++ b/hal/CMakeLists.txt @@ -8,9 +8,9 @@ file(GLOB_RECURSE SOURCES "src/*" ) -add_library(hal STATIC ${SOURCES}) +add_library(hal_host STATIC ${SOURCES}) -target_include_directories(hal +target_include_directories(hal_host PUBLIC "inc/" ) diff --git a/targets/CMakeLists.txt b/targets/CMakeLists.txt index f9fbbdd..442c15f 100644 --- a/targets/CMakeLists.txt +++ b/targets/CMakeLists.txt @@ -8,6 +8,7 @@ set(AVAILABLE_TARGETS "chimera-host" "chimera-open" + "chimera-convolve" CACHE STRING "Available Targets" ) @@ -17,6 +18,8 @@ if(NOT TARGET_PLATFORM IN_LIST AVAILABLE_TARGETS) message(FATAL_ERROR "Wrong value for TARGET_PLATFORM: Got ${TARGET_PLATFORM}. Available targets are: ${AVAILABLE_TARGETS}") endif() +message(STATUS "[CHIMERA-SDK] TARGET_PLATFORM : ${TARGET_PLATFORM}") + if (TARGET_PLATFORM STREQUAL "chimera-host") add_subdirectory(chimera-host) endif() @@ -24,3 +27,7 @@ endif() if (TARGET_PLATFORM STREQUAL "chimera-open") add_subdirectory(chimera-open) endif() + +if (TARGET_PLATFORM STREQUAL "chimera-convolve") + add_subdirectory(chimera-convolve) +endif() diff --git a/targets/chimera-convolve/CMakeLists.txt b/targets/chimera-convolve/CMakeLists.txt new file mode 100644 index 0000000..57d4cad --- /dev/null +++ b/targets/chimera-convolve/CMakeLists.txt @@ -0,0 +1,88 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Moritz Scherer +# Viviane Potocnik +# Philip Wiese + +################################################################################ +# Host Runtime Library # +################################################################################ +add_library(runtime_host STATIC) + +file(GLOB_RECURSE ASM_SOURCES + "src/crt0.S" +) + +file(GLOB_RECURSE C_SOURCES + "src/*.c" +) + +set_property(SOURCE ${ASM_SOURCES} PROPERTY LANGUAGE ASM) + +target_sources(runtime_host + PRIVATE + ${ASM_SOURCES} + ${C_SOURCES} +) + +# WIESEP: Export the target specific include directory +target_include_directories(runtime_host + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/include +) + +target_compile_options(runtime_host + PRIVATE + -O2 +) + +target_compile_options(runtime_host + PUBLIC + -march=${ISA_HOST} + -mabi=${ABI} +) + +# WIESEP: Export the target specific linkerscript +target_link_options(runtime_host + PUBLIC + -L${CMAKE_CURRENT_LIST_DIR} + -Tlink.ld + -march=${ISA_HOST} + -mabi=${ABI} + -nostartfiles + -ffreestanding +) + +################################################################################ +# Snitch Cluster Runtime Library # +################################################################################ +add_library(runtime_cluster_snitch STATIC) + +# WIESEP: Export the headers also to the cluster runtime +target_include_directories(runtime_cluster_snitch + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/include +) + +# WIESEP: Do not export optimization flags +target_compile_options(runtime_cluster_snitch + PRIVATE + -O2 +) + +target_compile_options(runtime_cluster_snitch + PUBLIC + -march=${ISA_CLUSTER_SNITCH} + -mabi=${ABI} +) + +# WIESEP: Expose common link option +target_link_options(runtime_cluster_snitch + PUBLIC + -march=${ISA_CLUSTER_SNITCH} + -mabi=${ABI} + -nostartfiles + -ffreestanding +) \ No newline at end of file diff --git a/targets/chimera-convolve/common.ldh b/targets/chimera-convolve/common.ldh new file mode 100644 index 0000000..ba8f3c0 --- /dev/null +++ b/targets/chimera-convolve/common.ldh @@ -0,0 +1,57 @@ +/* Copyright 2022 ETH Zurich and University of Bologna. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* Nicole Narr */ +/* Christopher Reinwardt */ +/* Paul Scheffler */ + +/* This header defines symbols and rules universal to bare-metal execution */ + +ENTRY(_start) + +MEMORY { + bootrom (rx) : ORIGIN = 0x02000000, LENGTH = 16K + /* We assume at least 64 KiB SPM, same minus stack for ROMs. */ + /* If more SPM is available, CRT0 repoints the stack. */ + extrom (rx) : ORIGIN = 0x00000000, LENGTH = 48K + spm (rwx) : ORIGIN = 0x10000000, LENGTH = 64K + memisl (rwx) : ORIGIN = 0x48000000, LENGTH = 64K + /* SPM of Cluster 4 (ETH Cluster) */ + l1_c4(rwx) : ORIGIN = 0x40800000, LENGTH = 128K + /* We assume at least 8 MiB of DRAM (minimum for Linux). */ + dram (rwx) : ORIGIN = 0x80000000, LENGTH = 8M +} + +SECTIONS { + /* Keep binaries lean */ + /DISCARD/ : { *(.riscv.attributes) *(.comment) } + + /* Global and stack pointer */ + /* By default, keep the calling context (boot ROM) stack pointer */ + __global_pointer$ = ADDR(.misc) + SIZEOF(.misc) / 2; + __stack_pointer$ = __stack_start - 8; + + /* Further addresses */ + __base_dma = 0x01000000; + __base_bootrom = 0x02000000; + __base_clint = 0x02040000; + __base_axirt = 0x020C0000; + __base_axirtgrd = 0x020C1ffc; + __base_regs = 0x03000000; + __base_llc = 0x03001000; + __base_uart = 0x03002000; + __base_i2c = 0x03003000; + __base_spih = 0x03004000; + __base_gpio = 0x03005000; + __base_slink = 0x03006000; + __base_vga = 0x03007000; + __base_usb = 0x03008000; + __base_bus_err = 0x03009000; + __base_plic = 0x04000000; + __base_clic = 0x08000000; + __base_spm = ORIGIN(spm); + __base_dram = ORIGIN(dram); + __base_memisl = ORIGIN(memisl); + __stack_start = ORIGIN(memisl) + LENGTH(memisl); +} diff --git a/targets/chimera-convolve/include/addr_maps/cluster_4_addr_map.h b/targets/chimera-convolve/include/addr_maps/cluster_4_addr_map.h new file mode 100644 index 0000000..9fbb2c3 --- /dev/null +++ b/targets/chimera-convolve/include/addr_maps/cluster_4_addr_map.h @@ -0,0 +1,41 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _CLUSTER_4_ADDR_MAP_INCLUDE_GUARD_ +#define _CLUSTER_4_ADDR_MAP_INCLUDE_GUARD_ + +#include "addr_maps/soc_addr_map.h" + +#include + +#define CLUSTER_4_TCDM_BASE_ADDR (CLUSTER_4_BASE) +#define CLUSTER_4_PERIPH_BASE_ADDR (CLUSTER_4_BASE + 0x20000) +#define CLUSTER_4_ZERO_MEM_BASE_ADDR (CLUSTER_4_BASE + 0x30000) +#define CLUSTER_4_HWPE_ITA_BASE_ADDR (CLUSTER_4_BASE + 0x40000) + +// Define start and end of the regions +#define CLUSTER_4_TCDM_START_ADDR CLUSTER_4_TCDM_BASE_ADDR +#define CLUSTER_4_TCDM_END_ADDR CLUSTER_4_PERIPH_BASE_ADDR +#define CLUSTER_4_PERIPH_START_ADDR CLUSTER_4_PERIPH_BASE_ADDR +#define CLUSTER_4_PERIPH_END_ADDR CLUSTER_4_ZERO_MEM_BASE_ADDR +#define CLUSTER_4_ZERO_MEM_START_ADDR CLUSTER_4_ZERO_MEM_BASE_ADDR +#define CLUSTER_4_ZERO_MEM_END_ADDR CLUSTER_4_HWPE_ITA_BASE_ADDR +#define CLUSTER_4_HWPE_ITA_START_ADDR CLUSTER_4_HWPE_ITA_BASE_ADDR +#define CLUSTER_4_HWPE_ITA_END_ADDR (CLUSTER_4_BASE + 0x10000) + +#define CLUSTER_4_HW_BARRIER_ADDR \ + (CLUSTER_4_PERIPH_BASE_ADDR + CLUSTER_4_PERIPHERAL_HW_BARRIER_REG_OFFSET) + +#define CLUSTER_4_PERF_COUNTER_ADDR \ + (CLUSTER_4_PERIPH_BASE_ADDR + CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_REG_OFFSET) + +#define CLUSTER_4_HWPE_EVT_ADDR \ + (CLUSTER_4_PERIPH_BASE_ADDR + CLUSTER_4_PERIPHERAL_HWPE_EVT_REG_OFFSET) + +#define CLUSTER_4_HWPE_BUSY_ADDR \ + (CLUSTER_4_PERIPH_BASE_ADDR + CLUSTER_4_PERIPHERAL_HWPE_BUSY_REG_OFFSET) + +#endif //_CLUSTER_4_ADDR_MAP_INCLUDE_GUARD_ \ No newline at end of file diff --git a/targets/chimera-convolve/include/addr_maps/soc_addr_map.h b/targets/chimera-convolve/include/addr_maps/soc_addr_map.h new file mode 100644 index 0000000..7520427 --- /dev/null +++ b/targets/chimera-convolve/include/addr_maps/soc_addr_map.h @@ -0,0 +1,39 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Moritz Scherer + +#ifndef _SOC_ADDR_MAP_INCLUDE_GUARD_ +#define _SOC_ADDR_MAP_INCLUDE_GUARD_ + +#include + +#define CLINT_CTRL_BASE 0x02040000 + +#define SOC_CTRL_BASE 0x30001000 + +#define CLUSTER_0_BASE 0x40000000 +#define CLUSTER_1_BASE 0x40200000 +#define CLUSTER_2_BASE 0x40400000 +#define CLUSTER_3_BASE 0x40600000 +#define CLUSTER_4_BASE 0x40800000 + +#define CLUSTER_0_NUMCORES 2 +#define CLUSTER_1_NUMCORES 2 +#define CLUSTER_2_NUMCORES 2 +#define CLUSTER_3_NUMCORES 3 +#define CLUSTER_4_NUMCORES 9 + +#define NUM_CLUSTER_CORES \ + (CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES + CLUSTER_3_NUMCORES + \ + CLUSTER_4_NUMCORES) + +static uint8_t _chimera_numCores[] = {CLUSTER_0_NUMCORES, CLUSTER_1_NUMCORES, CLUSTER_2_NUMCORES, + CLUSTER_3_NUMCORES, CLUSTER_4_NUMCORES}; +#define _chimera_numClusters 5 + +#define CHIMERA_PADFRAME_BASE_ADDRESS 0x30002000 +#define FLL_BASE_ADDR 0x30003000 + +#endif diff --git a/targets/chimera-convolve/include/cluster_4.h b/targets/chimera-convolve/include/cluster_4.h new file mode 100644 index 0000000..3a75496 --- /dev/null +++ b/targets/chimera-convolve/include/cluster_4.h @@ -0,0 +1,13 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _CLUSTER_4_INCLUDE_GUARD_ +#define _CLUSTER_4_INCLUDE_GUARD_ + +#include "regs/cluster_4_reg.h" +#include "addr_maps/cluster_4_addr_map.h" + +#endif // _CLUSTER_4_INCLUDE_GUARD_ diff --git a/targets/chimera-convolve/include/regs/cluster_4_reg.h b/targets/chimera-convolve/include/regs/cluster_4_reg.h new file mode 100644 index 0000000..f7e0a09 --- /dev/null +++ b/targets/chimera-convolve/include/regs/cluster_4_reg.h @@ -0,0 +1,894 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _CLUSTER_4_REG_DEFS_ +#define _CLUSTER_4_REG_DEFS_ + +#ifdef __cplusplus +extern "C" { +#endif +// Number of performance counters +#define CLUSTER_4_PERIPHERAL_PARAM_NUM_PERF_COUNTERS 16 + +// Register width +#define CLUSTER_4_PERIPHERAL_PARAM_REG_WIDTH 64 + +// Enable particular performance counter and start tracking. (common +// parameters) +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_REG_OFFSET 0x0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_CYCLE_0_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_TCDM_ACCESSED_0_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_TCDM_CONGESTED_0_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ISSUE_FPU_0_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ISSUE_FPU_SEQ_0_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ISSUE_CORE_TO_FPU_0_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_INSTR_0_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_LOAD_0_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_I_0_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_RETIRED_ACC_0_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AW_STALL_0_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AR_STALL_0_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_R_STALL_0_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_W_STALL_0_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_BUF_W_STALL_0_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_BUF_R_STALL_0_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AW_DONE_0_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AW_BW_0_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AR_DONE_0_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_AR_BW_0_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_R_DONE_0_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_R_BW_0_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_W_DONE_0_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_W_BW_0_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_B_DONE_0_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_DMA_BUSY_0_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_MISS_0_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_HIT_0_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_PREFETCH_0_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_DOUBLE_HIT_0_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_0_ICACHE_STALL_0_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_REG_OFFSET 0x8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_CYCLE_1_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_TCDM_ACCESSED_1_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_TCDM_CONGESTED_1_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ISSUE_FPU_1_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ISSUE_FPU_SEQ_1_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ISSUE_CORE_TO_FPU_1_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_INSTR_1_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_LOAD_1_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_I_1_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_RETIRED_ACC_1_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AW_STALL_1_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AR_STALL_1_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_R_STALL_1_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_W_STALL_1_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_BUF_W_STALL_1_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_BUF_R_STALL_1_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AW_DONE_1_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AW_BW_1_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AR_DONE_1_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_AR_BW_1_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_R_DONE_1_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_R_BW_1_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_W_DONE_1_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_W_BW_1_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_B_DONE_1_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_DMA_BUSY_1_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_MISS_1_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_HIT_1_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_PREFETCH_1_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_DOUBLE_HIT_1_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_1_ICACHE_STALL_1_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_REG_OFFSET 0x10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_CYCLE_2_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_TCDM_ACCESSED_2_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_TCDM_CONGESTED_2_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ISSUE_FPU_2_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ISSUE_FPU_SEQ_2_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ISSUE_CORE_TO_FPU_2_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_RETIRED_INSTR_2_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_RETIRED_LOAD_2_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_RETIRED_I_2_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_RETIRED_ACC_2_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_AW_STALL_2_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_AR_STALL_2_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_R_STALL_2_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_W_STALL_2_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_BUF_W_STALL_2_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_BUF_R_STALL_2_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_AW_DONE_2_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_AW_BW_2_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_AR_DONE_2_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_AR_BW_2_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_R_DONE_2_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_R_BW_2_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_W_DONE_2_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_W_BW_2_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_B_DONE_2_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_DMA_BUSY_2_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ICACHE_MISS_2_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ICACHE_HIT_2_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ICACHE_PREFETCH_2_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ICACHE_DOUBLE_HIT_2_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_2_ICACHE_STALL_2_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_REG_OFFSET 0x18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_CYCLE_3_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_TCDM_ACCESSED_3_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_TCDM_CONGESTED_3_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ISSUE_FPU_3_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ISSUE_FPU_SEQ_3_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ISSUE_CORE_TO_FPU_3_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_RETIRED_INSTR_3_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_RETIRED_LOAD_3_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_RETIRED_I_3_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_RETIRED_ACC_3_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_AW_STALL_3_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_AR_STALL_3_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_R_STALL_3_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_W_STALL_3_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_BUF_W_STALL_3_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_BUF_R_STALL_3_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_AW_DONE_3_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_AW_BW_3_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_AR_DONE_3_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_AR_BW_3_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_R_DONE_3_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_R_BW_3_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_W_DONE_3_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_W_BW_3_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_B_DONE_3_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_DMA_BUSY_3_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ICACHE_MISS_3_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ICACHE_HIT_3_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ICACHE_PREFETCH_3_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ICACHE_DOUBLE_HIT_3_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_3_ICACHE_STALL_3_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_REG_OFFSET 0x20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_CYCLE_4_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_TCDM_ACCESSED_4_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_TCDM_CONGESTED_4_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ISSUE_FPU_4_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ISSUE_FPU_SEQ_4_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ISSUE_CORE_TO_FPU_4_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_RETIRED_INSTR_4_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_RETIRED_LOAD_4_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_RETIRED_I_4_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_RETIRED_ACC_4_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_AW_STALL_4_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_AR_STALL_4_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_R_STALL_4_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_W_STALL_4_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_BUF_W_STALL_4_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_BUF_R_STALL_4_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_AW_DONE_4_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_AW_BW_4_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_AR_DONE_4_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_AR_BW_4_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_R_DONE_4_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_R_BW_4_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_W_DONE_4_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_W_BW_4_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_B_DONE_4_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_DMA_BUSY_4_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ICACHE_MISS_4_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ICACHE_HIT_4_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ICACHE_PREFETCH_4_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ICACHE_DOUBLE_HIT_4_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_4_ICACHE_STALL_4_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_REG_OFFSET 0x28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_CYCLE_5_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_TCDM_ACCESSED_5_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_TCDM_CONGESTED_5_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ISSUE_FPU_5_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ISSUE_FPU_SEQ_5_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ISSUE_CORE_TO_FPU_5_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_RETIRED_INSTR_5_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_RETIRED_LOAD_5_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_RETIRED_I_5_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_RETIRED_ACC_5_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_AW_STALL_5_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_AR_STALL_5_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_R_STALL_5_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_W_STALL_5_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_BUF_W_STALL_5_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_BUF_R_STALL_5_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_AW_DONE_5_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_AW_BW_5_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_AR_DONE_5_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_AR_BW_5_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_R_DONE_5_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_R_BW_5_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_W_DONE_5_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_W_BW_5_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_B_DONE_5_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_DMA_BUSY_5_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ICACHE_MISS_5_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ICACHE_HIT_5_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ICACHE_PREFETCH_5_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ICACHE_DOUBLE_HIT_5_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_5_ICACHE_STALL_5_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_REG_OFFSET 0x30 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_CYCLE_6_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_TCDM_ACCESSED_6_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_TCDM_CONGESTED_6_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ISSUE_FPU_6_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ISSUE_FPU_SEQ_6_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ISSUE_CORE_TO_FPU_6_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_RETIRED_INSTR_6_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_RETIRED_LOAD_6_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_RETIRED_I_6_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_RETIRED_ACC_6_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_AW_STALL_6_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_AR_STALL_6_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_R_STALL_6_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_W_STALL_6_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_BUF_W_STALL_6_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_BUF_R_STALL_6_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_AW_DONE_6_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_AW_BW_6_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_AR_DONE_6_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_AR_BW_6_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_R_DONE_6_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_R_BW_6_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_W_DONE_6_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_W_BW_6_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_B_DONE_6_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_DMA_BUSY_6_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ICACHE_MISS_6_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ICACHE_HIT_6_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ICACHE_PREFETCH_6_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ICACHE_DOUBLE_HIT_6_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_6_ICACHE_STALL_6_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_REG_OFFSET 0x38 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_CYCLE_7_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_TCDM_ACCESSED_7_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_TCDM_CONGESTED_7_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ISSUE_FPU_7_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ISSUE_FPU_SEQ_7_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ISSUE_CORE_TO_FPU_7_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_RETIRED_INSTR_7_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_RETIRED_LOAD_7_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_RETIRED_I_7_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_RETIRED_ACC_7_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_AW_STALL_7_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_AR_STALL_7_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_R_STALL_7_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_W_STALL_7_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_BUF_W_STALL_7_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_BUF_R_STALL_7_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_AW_DONE_7_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_AW_BW_7_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_AR_DONE_7_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_AR_BW_7_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_R_DONE_7_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_R_BW_7_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_W_DONE_7_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_W_BW_7_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_B_DONE_7_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_DMA_BUSY_7_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ICACHE_MISS_7_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ICACHE_HIT_7_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ICACHE_PREFETCH_7_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ICACHE_DOUBLE_HIT_7_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_7_ICACHE_STALL_7_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_REG_OFFSET 0x40 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_CYCLE_8_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_TCDM_ACCESSED_8_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_TCDM_CONGESTED_8_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ISSUE_FPU_8_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ISSUE_FPU_SEQ_8_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ISSUE_CORE_TO_FPU_8_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_RETIRED_INSTR_8_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_RETIRED_LOAD_8_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_RETIRED_I_8_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_RETIRED_ACC_8_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_AW_STALL_8_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_AR_STALL_8_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_R_STALL_8_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_W_STALL_8_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_BUF_W_STALL_8_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_BUF_R_STALL_8_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_AW_DONE_8_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_AW_BW_8_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_AR_DONE_8_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_AR_BW_8_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_R_DONE_8_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_R_BW_8_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_W_DONE_8_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_W_BW_8_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_B_DONE_8_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_DMA_BUSY_8_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ICACHE_MISS_8_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ICACHE_HIT_8_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ICACHE_PREFETCH_8_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ICACHE_DOUBLE_HIT_8_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_8_ICACHE_STALL_8_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_REG_OFFSET 0x48 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_CYCLE_9_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_TCDM_ACCESSED_9_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_TCDM_CONGESTED_9_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ISSUE_FPU_9_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ISSUE_FPU_SEQ_9_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ISSUE_CORE_TO_FPU_9_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_RETIRED_INSTR_9_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_RETIRED_LOAD_9_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_RETIRED_I_9_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_RETIRED_ACC_9_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_AW_STALL_9_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_AR_STALL_9_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_R_STALL_9_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_W_STALL_9_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_BUF_W_STALL_9_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_BUF_R_STALL_9_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_AW_DONE_9_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_AW_BW_9_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_AR_DONE_9_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_AR_BW_9_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_R_DONE_9_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_R_BW_9_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_W_DONE_9_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_W_BW_9_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_B_DONE_9_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_DMA_BUSY_9_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ICACHE_MISS_9_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ICACHE_HIT_9_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ICACHE_PREFETCH_9_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ICACHE_DOUBLE_HIT_9_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_9_ICACHE_STALL_9_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_REG_OFFSET 0x50 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_CYCLE_10_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_TCDM_ACCESSED_10_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_TCDM_CONGESTED_10_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ISSUE_FPU_10_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ISSUE_FPU_SEQ_10_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ISSUE_CORE_TO_FPU_10_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_RETIRED_INSTR_10_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_RETIRED_LOAD_10_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_RETIRED_I_10_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_RETIRED_ACC_10_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_AW_STALL_10_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_AR_STALL_10_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_R_STALL_10_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_W_STALL_10_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_BUF_W_STALL_10_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_BUF_R_STALL_10_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_AW_DONE_10_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_AW_BW_10_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_AR_DONE_10_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_AR_BW_10_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_R_DONE_10_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_R_BW_10_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_W_DONE_10_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_W_BW_10_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_B_DONE_10_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_DMA_BUSY_10_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ICACHE_MISS_10_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ICACHE_HIT_10_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ICACHE_PREFETCH_10_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ICACHE_DOUBLE_HIT_10_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_10_ICACHE_STALL_10_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_REG_OFFSET 0x58 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_CYCLE_11_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_TCDM_ACCESSED_11_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_TCDM_CONGESTED_11_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ISSUE_FPU_11_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ISSUE_FPU_SEQ_11_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ISSUE_CORE_TO_FPU_11_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_RETIRED_INSTR_11_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_RETIRED_LOAD_11_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_RETIRED_I_11_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_RETIRED_ACC_11_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_AW_STALL_11_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_AR_STALL_11_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_R_STALL_11_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_W_STALL_11_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_BUF_W_STALL_11_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_BUF_R_STALL_11_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_AW_DONE_11_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_AW_BW_11_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_AR_DONE_11_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_AR_BW_11_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_R_DONE_11_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_R_BW_11_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_W_DONE_11_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_W_BW_11_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_B_DONE_11_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_DMA_BUSY_11_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ICACHE_MISS_11_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ICACHE_HIT_11_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ICACHE_PREFETCH_11_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ICACHE_DOUBLE_HIT_11_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_11_ICACHE_STALL_11_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_REG_OFFSET 0x60 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_CYCLE_12_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_TCDM_ACCESSED_12_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_TCDM_CONGESTED_12_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ISSUE_FPU_12_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ISSUE_FPU_SEQ_12_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ISSUE_CORE_TO_FPU_12_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_RETIRED_INSTR_12_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_RETIRED_LOAD_12_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_RETIRED_I_12_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_RETIRED_ACC_12_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_AW_STALL_12_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_AR_STALL_12_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_R_STALL_12_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_W_STALL_12_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_BUF_W_STALL_12_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_BUF_R_STALL_12_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_AW_DONE_12_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_AW_BW_12_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_AR_DONE_12_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_AR_BW_12_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_R_DONE_12_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_R_BW_12_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_W_DONE_12_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_W_BW_12_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_B_DONE_12_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_DMA_BUSY_12_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ICACHE_MISS_12_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ICACHE_HIT_12_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ICACHE_PREFETCH_12_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ICACHE_DOUBLE_HIT_12_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_12_ICACHE_STALL_12_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_REG_OFFSET 0x68 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_CYCLE_13_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_TCDM_ACCESSED_13_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_TCDM_CONGESTED_13_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ISSUE_FPU_13_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ISSUE_FPU_SEQ_13_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ISSUE_CORE_TO_FPU_13_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_RETIRED_INSTR_13_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_RETIRED_LOAD_13_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_RETIRED_I_13_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_RETIRED_ACC_13_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_AW_STALL_13_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_AR_STALL_13_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_R_STALL_13_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_W_STALL_13_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_BUF_W_STALL_13_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_BUF_R_STALL_13_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_AW_DONE_13_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_AW_BW_13_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_AR_DONE_13_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_AR_BW_13_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_R_DONE_13_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_R_BW_13_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_W_DONE_13_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_W_BW_13_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_B_DONE_13_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_DMA_BUSY_13_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ICACHE_MISS_13_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ICACHE_HIT_13_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ICACHE_PREFETCH_13_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ICACHE_DOUBLE_HIT_13_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_13_ICACHE_STALL_13_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_REG_OFFSET 0x70 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_CYCLE_14_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_TCDM_ACCESSED_14_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_TCDM_CONGESTED_14_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ISSUE_FPU_14_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ISSUE_FPU_SEQ_14_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ISSUE_CORE_TO_FPU_14_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_RETIRED_INSTR_14_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_RETIRED_LOAD_14_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_RETIRED_I_14_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_RETIRED_ACC_14_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_AW_STALL_14_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_AR_STALL_14_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_R_STALL_14_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_W_STALL_14_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_BUF_W_STALL_14_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_BUF_R_STALL_14_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_AW_DONE_14_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_AW_BW_14_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_AR_DONE_14_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_AR_BW_14_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_R_DONE_14_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_R_BW_14_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_W_DONE_14_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_W_BW_14_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_B_DONE_14_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_DMA_BUSY_14_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ICACHE_MISS_14_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ICACHE_HIT_14_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ICACHE_PREFETCH_14_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ICACHE_DOUBLE_HIT_14_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_14_ICACHE_STALL_14_BIT 30 + +// Enable particular performance counter and start tracking. +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_REG_OFFSET 0x78 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_CYCLE_15_BIT 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_TCDM_ACCESSED_15_BIT 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_TCDM_CONGESTED_15_BIT 2 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ISSUE_FPU_15_BIT 3 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ISSUE_FPU_SEQ_15_BIT 4 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ISSUE_CORE_TO_FPU_15_BIT 5 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_RETIRED_INSTR_15_BIT 6 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_RETIRED_LOAD_15_BIT 7 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_RETIRED_I_15_BIT 8 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_RETIRED_ACC_15_BIT 9 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_AW_STALL_15_BIT 10 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_AR_STALL_15_BIT 11 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_R_STALL_15_BIT 12 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_W_STALL_15_BIT 13 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_BUF_W_STALL_15_BIT 14 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_BUF_R_STALL_15_BIT 15 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_AW_DONE_15_BIT 16 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_AW_BW_15_BIT 17 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_AR_DONE_15_BIT 18 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_AR_BW_15_BIT 19 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_R_DONE_15_BIT 20 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_R_BW_15_BIT 21 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_W_DONE_15_BIT 22 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_W_BW_15_BIT 23 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_B_DONE_15_BIT 24 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_DMA_BUSY_15_BIT 25 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ICACHE_MISS_15_BIT 26 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ICACHE_HIT_15_BIT 27 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ICACHE_PREFETCH_15_BIT 28 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ICACHE_DOUBLE_HIT_15_BIT 29 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_ENABLE_15_ICACHE_STALL_15_BIT 30 + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_HART_SELECT_FIELD_WIDTH 10 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_HART_SELECT_FIELDS_PER_REG 6 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_MULTIREG_COUNT 16 + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_0_REG_OFFSET 0x80 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_0_HART_SELECT_0_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_1_REG_OFFSET 0x88 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_1_HART_SELECT_1_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_2_REG_OFFSET 0x90 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_2_HART_SELECT_2_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_2_HART_SELECT_2_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_2_HART_SELECT_2_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_2_HART_SELECT_2_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_2_HART_SELECT_2_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_3_REG_OFFSET 0x98 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_3_HART_SELECT_3_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_3_HART_SELECT_3_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_3_HART_SELECT_3_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_3_HART_SELECT_3_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_3_HART_SELECT_3_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_4_REG_OFFSET 0xa0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_4_HART_SELECT_4_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_4_HART_SELECT_4_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_4_HART_SELECT_4_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_4_HART_SELECT_4_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_4_HART_SELECT_4_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_5_REG_OFFSET 0xa8 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_5_HART_SELECT_5_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_5_HART_SELECT_5_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_5_HART_SELECT_5_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_5_HART_SELECT_5_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_5_HART_SELECT_5_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_6_REG_OFFSET 0xb0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_6_HART_SELECT_6_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_6_HART_SELECT_6_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_6_HART_SELECT_6_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_6_HART_SELECT_6_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_6_HART_SELECT_6_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_7_REG_OFFSET 0xb8 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_7_HART_SELECT_7_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_7_HART_SELECT_7_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_7_HART_SELECT_7_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_7_HART_SELECT_7_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_7_HART_SELECT_7_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_8_REG_OFFSET 0xc0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_8_HART_SELECT_8_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_8_HART_SELECT_8_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_8_HART_SELECT_8_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_8_HART_SELECT_8_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_8_HART_SELECT_8_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_9_REG_OFFSET 0xc8 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_9_HART_SELECT_9_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_9_HART_SELECT_9_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_9_HART_SELECT_9_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_9_HART_SELECT_9_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_9_HART_SELECT_9_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_10_REG_OFFSET 0xd0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_10_HART_SELECT_10_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_10_HART_SELECT_10_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_10_HART_SELECT_10_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_10_HART_SELECT_10_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_10_HART_SELECT_10_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_11_REG_OFFSET 0xd8 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_11_HART_SELECT_11_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_11_HART_SELECT_11_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_11_HART_SELECT_11_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_11_HART_SELECT_11_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_11_HART_SELECT_11_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_12_REG_OFFSET 0xe0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_12_HART_SELECT_12_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_12_HART_SELECT_12_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_12_HART_SELECT_12_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_12_HART_SELECT_12_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_12_HART_SELECT_12_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_13_REG_OFFSET 0xe8 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_13_HART_SELECT_13_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_13_HART_SELECT_13_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_13_HART_SELECT_13_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_13_HART_SELECT_13_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_13_HART_SELECT_13_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_14_REG_OFFSET 0xf0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_14_HART_SELECT_14_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_14_HART_SELECT_14_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_14_HART_SELECT_14_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_14_HART_SELECT_14_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_14_HART_SELECT_14_OFFSET}) + +// Select from which hart in the cluster, starting from `0`, +#define CLUSTER_4_PERIPHERAL_HART_SELECT_15_REG_OFFSET 0xf8 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_15_HART_SELECT_15_MASK 0x3ff +#define CLUSTER_4_PERIPHERAL_HART_SELECT_15_HART_SELECT_15_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HART_SELECT_15_HART_SELECT_15_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HART_SELECT_15_HART_SELECT_15_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HART_SELECT_15_HART_SELECT_15_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_PERF_COUNTER_FIELD_WIDTH 48 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_PERF_COUNTER_FIELDS_PER_REG 1 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_MULTIREG_COUNT 16 + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_0_REG_OFFSET 0x100 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_0_PERF_COUNTER_0_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_1_REG_OFFSET 0x108 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_1_PERF_COUNTER_1_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_2_REG_OFFSET 0x110 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_2_PERF_COUNTER_2_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_2_PERF_COUNTER_2_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_2_PERF_COUNTER_2_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_2_PERF_COUNTER_2_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_2_PERF_COUNTER_2_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_3_REG_OFFSET 0x118 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_3_PERF_COUNTER_3_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_3_PERF_COUNTER_3_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_3_PERF_COUNTER_3_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_3_PERF_COUNTER_3_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_3_PERF_COUNTER_3_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_4_REG_OFFSET 0x120 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_4_PERF_COUNTER_4_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_4_PERF_COUNTER_4_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_4_PERF_COUNTER_4_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_4_PERF_COUNTER_4_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_4_PERF_COUNTER_4_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_5_REG_OFFSET 0x128 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_5_PERF_COUNTER_5_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_5_PERF_COUNTER_5_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_5_PERF_COUNTER_5_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_5_PERF_COUNTER_5_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_5_PERF_COUNTER_5_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_6_REG_OFFSET 0x130 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_6_PERF_COUNTER_6_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_6_PERF_COUNTER_6_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_6_PERF_COUNTER_6_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_6_PERF_COUNTER_6_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_6_PERF_COUNTER_6_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_7_REG_OFFSET 0x138 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_7_PERF_COUNTER_7_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_7_PERF_COUNTER_7_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_7_PERF_COUNTER_7_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_7_PERF_COUNTER_7_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_7_PERF_COUNTER_7_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_8_REG_OFFSET 0x140 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_8_PERF_COUNTER_8_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_8_PERF_COUNTER_8_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_8_PERF_COUNTER_8_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_8_PERF_COUNTER_8_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_8_PERF_COUNTER_8_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_9_REG_OFFSET 0x148 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_9_PERF_COUNTER_9_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_9_PERF_COUNTER_9_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_9_PERF_COUNTER_9_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_9_PERF_COUNTER_9_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_9_PERF_COUNTER_9_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_10_REG_OFFSET 0x150 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_10_PERF_COUNTER_10_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_10_PERF_COUNTER_10_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_10_PERF_COUNTER_10_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_10_PERF_COUNTER_10_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_10_PERF_COUNTER_10_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_11_REG_OFFSET 0x158 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_11_PERF_COUNTER_11_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_11_PERF_COUNTER_11_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_11_PERF_COUNTER_11_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_11_PERF_COUNTER_11_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_11_PERF_COUNTER_11_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_12_REG_OFFSET 0x160 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_12_PERF_COUNTER_12_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_12_PERF_COUNTER_12_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_12_PERF_COUNTER_12_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_12_PERF_COUNTER_12_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_12_PERF_COUNTER_12_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_13_REG_OFFSET 0x168 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_13_PERF_COUNTER_13_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_13_PERF_COUNTER_13_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_13_PERF_COUNTER_13_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_13_PERF_COUNTER_13_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_13_PERF_COUNTER_13_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_14_REG_OFFSET 0x170 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_14_PERF_COUNTER_14_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_14_PERF_COUNTER_14_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_14_PERF_COUNTER_14_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_14_PERF_COUNTER_14_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_14_PERF_COUNTER_14_OFFSET}) + +// Performance counter. Set corresponding PERF_COUNTER_ENABLE bits depending +// on what +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_15_REG_OFFSET 0x178 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_15_PERF_COUNTER_15_MASK 0xffffffffffff +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_15_PERF_COUNTER_15_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_PERF_COUNTER_15_PERF_COUNTER_15_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_PERF_COUNTER_15_PERF_COUNTER_15_MASK, \ + .index = CLUSTER_4_PERIPHERAL_PERF_COUNTER_15_PERF_COUNTER_15_OFFSET}) + +// Set bits in the cluster-local CLINT. Writing a 1 at location i sets the +// cluster-local interrupt +#define CLUSTER_4_PERIPHERAL_CL_CLINT_SET_REG_OFFSET 0x180 +#define CLUSTER_4_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_MASK 0xffffffff +#define CLUSTER_4_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_MASK, \ + .index = CLUSTER_4_PERIPHERAL_CL_CLINT_SET_CL_CLINT_SET_OFFSET}) + +// Clear bits in the cluster-local CLINT. Writing a 1 at location i clears +// the cluster-local interrupt +#define CLUSTER_4_PERIPHERAL_CL_CLINT_CLEAR_REG_OFFSET 0x188 +#define CLUSTER_4_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_MASK 0xffffffff +#define CLUSTER_4_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_MASK, \ + .index = CLUSTER_4_PERIPHERAL_CL_CLINT_CLEAR_CL_CLINT_CLEAR_OFFSET}) + +// Hardware barrier register. Loads to this register will block until all +// cores have +#define CLUSTER_4_PERIPHERAL_HW_BARRIER_REG_OFFSET 0x190 +#define CLUSTER_4_PERIPHERAL_HW_BARRIER_HW_BARRIER_MASK 0xffffffff +#define CLUSTER_4_PERIPHERAL_HW_BARRIER_HW_BARRIER_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HW_BARRIER_HW_BARRIER_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HW_BARRIER_HW_BARRIER_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HW_BARRIER_HW_BARRIER_OFFSET}) + +// Controls prefetching of the instruction cache. +#define CLUSTER_4_PERIPHERAL_ICACHE_PREFETCH_ENABLE_REG_OFFSET 0x198 +#define CLUSTER_4_PERIPHERAL_ICACHE_PREFETCH_ENABLE_ICACHE_PREFETCH_ENABLE_BIT 0 + +// HWPE. This register is used to keep track of the REDMULE event signal. +#define CLUSTER_4_PERIPHERAL_HWPE_EVT_REG_OFFSET 0x1a0 +#define CLUSTER_4_PERIPHERAL_HWPE_EVT_HWPE_EVT_MASK 0x3ffff +#define CLUSTER_4_PERIPHERAL_HWPE_EVT_HWPE_EVT_OFFSET 0 +#define CLUSTER_4_PERIPHERAL_HWPE_EVT_HWPE_EVT_FIELD \ + ((bitfield_field32_t){.mask = CLUSTER_4_PERIPHERAL_HWPE_EVT_HWPE_EVT_MASK, \ + .index = CLUSTER_4_PERIPHERAL_HWPE_EVT_HWPE_EVT_OFFSET}) + +// HWPE. This register is used to keep track of the REDMULE busy signal. +#define CLUSTER_4_PERIPHERAL_HWPE_BUSY_REG_OFFSET 0x1a8 +#define CLUSTER_4_PERIPHERAL_HWPE_BUSY_HWPE_BUSY_BIT 0 + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // _CLUSTER_4_REG_DEFS_ \ No newline at end of file diff --git a/targets/chimera-convolve/include/regs/soc_ctrl.h b/targets/chimera-convolve/include/regs/soc_ctrl.h new file mode 100644 index 0000000..c1c3fce --- /dev/null +++ b/targets/chimera-convolve/include/regs/soc_ctrl.h @@ -0,0 +1,104 @@ +// Generated register defines for chimera + +// Copyright information found in source file: +// Copyright 2024 ETH Zurich and University of Bologna. + +// Licensing information found in source file: +// +// SPDX-License-Identifier: SHL-0.51 + +#ifndef _CHIMERA_REG_DEFS_ +#define _CHIMERA_REG_DEFS_ + +#ifdef __cplusplus +extern "C" { +#endif +// Register width +#define CHIMERA_PARAM_REG_WIDTH 32 + +// Set boot address for all snitch cores +#define CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET 0x0 + +// Set interrupt handler address for all snitch cores +#define CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET 0x4 + +// Register to store return value of Snitch cluster 0 +#define CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET 0x8 + +// Register to store return value of Snitch cluster 1 +#define CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET 0xc + +// Register to store return value of Snitch cluster 2 +#define CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET 0x10 + +// Register to store return value of Snitch cluster 3 +#define CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET 0x14 + +// Register to store return value of Snitch cluster 4 +#define CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET 0x18 + +// Enable clock gate for cluster 0 +#define CHIMERA_CLUSTER_0_CLK_GATE_EN_REG_OFFSET 0x1c +#define CHIMERA_CLUSTER_0_CLK_GATE_EN_CLUSTER_0_CLK_GATE_EN_BIT 0 + +// Enable clock gate for cluster 1 +#define CHIMERA_CLUSTER_1_CLK_GATE_EN_REG_OFFSET 0x20 +#define CHIMERA_CLUSTER_1_CLK_GATE_EN_CLUSTER_1_CLK_GATE_EN_BIT 0 + +// Enable clock gate for cluster 2 +#define CHIMERA_CLUSTER_2_CLK_GATE_EN_REG_OFFSET 0x24 +#define CHIMERA_CLUSTER_2_CLK_GATE_EN_CLUSTER_2_CLK_GATE_EN_BIT 0 + +// Enable clock gate for cluster 3 +#define CHIMERA_CLUSTER_3_CLK_GATE_EN_REG_OFFSET 0x28 +#define CHIMERA_CLUSTER_3_CLK_GATE_EN_CLUSTER_3_CLK_GATE_EN_BIT 0 + +// Enable clock gate for cluster 4 +#define CHIMERA_CLUSTER_4_CLK_GATE_EN_REG_OFFSET 0x2c +#define CHIMERA_CLUSTER_4_CLK_GATE_EN_CLUSTER_4_CLK_GATE_EN_BIT 0 + +// Bypass cluster to mem wide connection for cluster 0 +#define CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_REG_OFFSET 0x30 +#define CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_WIDE_MEM_CLUSTER_0_BYPASS_BIT 0 + +// Bypass cluster to mem wide connection for cluster 1 +#define CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_REG_OFFSET 0x34 +#define CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_WIDE_MEM_CLUSTER_1_BYPASS_BIT 0 + +// Bypass cluster to mem wide connection for cluster 2 +#define CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_REG_OFFSET 0x38 +#define CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_WIDE_MEM_CLUSTER_2_BYPASS_BIT 0 + +// Bypass cluster to mem wide connection for cluster 3 +#define CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_REG_OFFSET 0x3c +#define CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_WIDE_MEM_CLUSTER_3_BYPASS_BIT 0 + +// Bypass cluster to mem wide connection for cluster 4 +#define CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_REG_OFFSET 0x40 +#define CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_WIDE_MEM_CLUSTER_4_BYPASS_BIT 0 + +// Register to identify when cluster 0 is busy +#define CHIMERA_CLUSTER_0_BUSY_REG_OFFSET 0x44 +#define CHIMERA_CLUSTER_0_BUSY_CLUSTER_0_BUSY_BIT 0 + +// Register to identify when cluster 1 is busy +#define CHIMERA_CLUSTER_1_BUSY_REG_OFFSET 0x48 +#define CHIMERA_CLUSTER_1_BUSY_CLUSTER_1_BUSY_BIT 0 + +// Register to identify when cluster 2 is busy +#define CHIMERA_CLUSTER_2_BUSY_REG_OFFSET 0x4c +#define CHIMERA_CLUSTER_2_BUSY_CLUSTER_2_BUSY_BIT 0 + +// Register to identify when cluster 3 is busy +#define CHIMERA_CLUSTER_3_BUSY_REG_OFFSET 0x50 +#define CHIMERA_CLUSTER_3_BUSY_CLUSTER_3_BUSY_BIT 0 + +// Register to identify when cluster 4 is busy +#define CHIMERA_CLUSTER_4_BUSY_REG_OFFSET 0x54 +#define CHIMERA_CLUSTER_4_BUSY_CLUSTER_4_BUSY_BIT 0 + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // _CHIMERA_REG_DEFS_ +// End generated register defines for chimera diff --git a/targets/chimera-convolve/include/soc.h b/targets/chimera-convolve/include/soc.h new file mode 100644 index 0000000..4362aa7 --- /dev/null +++ b/targets/chimera-convolve/include/soc.h @@ -0,0 +1,13 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _SOC_INCLUDE_GUARD_ +#define _SOC_INCLUDE_GUARD_ + +#include "regs/soc_ctrl.h" +#include "addr_maps/soc_addr_map.h" + +#endif //_SOC_INCLUDE_GUARD_ diff --git a/targets/chimera-convolve/link.ld b/targets/chimera-convolve/link.ld new file mode 100644 index 0000000..6dcf16c --- /dev/null +++ b/targets/chimera-convolve/link.ld @@ -0,0 +1,46 @@ +/* Copyright 2022 ETH Zurich and University of Bologna. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* Nicole Narr */ +/* Christopher Reinwardt */ +/* Paul Scheffler */ +/* Lorenzo Leone */ + + +INCLUDE common.ldh + +SECTIONS { + .text : { + *(.text._start) + *(.text) + *(.text.*) + } > memisl + + .misc : ALIGN(16) { + *(.rodata) + *(.rodata.*) + *(.data) + *(.data.*) + *(.srodata) + *(.srodata.*) + *(.sdata) + *(.sdata.*) + } > memisl + + . = ALIGN(32); + __bss_start = .; + .bss : { + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + } > memisl + . = ALIGN(32); + __bss_end = .; + + .bulk : ALIGN(16) { + *(.bulk) + *(.bulk.*) + } > memisl +} diff --git a/targets/chimera-convolve/src/crt0.S b/targets/chimera-convolve/src/crt0.S new file mode 100644 index 0000000..059937c --- /dev/null +++ b/targets/chimera-convolve/src/crt0.S @@ -0,0 +1,132 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Viviane Potocnik + +.section .text._start +// Minimal CRT0 +.global _start +_start: + // Globally disable Machine and Supervisor interrupts + csrrc x0, mstatus, 10 + + // Park SMP harts + csrr t0, mhartid + beqz t0, 2f +1: + wfi + j 1b +2: + // Init stack and global pointer iff linked as nonzero + mv t1, sp + la t0, __stack_pointer$ + beqz t0, 1f + mv sp, t0 +1: .option push + .option norelax + la t0, __global_pointer$ + beqz t0, 1f + mv gp, t0 +1: .option pop + + // Store existing stack, global, return pointers on new stack + addi sp, sp, -12 + sw t1, 0(sp) + sw gp, 4(sp) + sw ra, 8(sp) + + // Set trap vector + la t0, _trap_handler_wrap + csrrw x0, mtvec, t0 + + // Zero the .bss section + la t0, __bss_start // t0 = bss start address + la t1, __bss_end // t1 = bss end address + sub t2, t1, t0 // t2 = #bytes to zero + li a0, 0 + +_zero_bss_loop: + addi t4, t2, -16 + blez t2, _fp_init // t2 <= 0? => No bss to zero + blt t4, x0, _zero_bss_rem // t4 < 0? => Less than 4 words left + sw a0, 0(t0) + sw a0, 4(t0) + sw a0, 8(t0) + sw a0, 12(t0) + addi t2, t2, -16 + addi t0, t0, 16 + bgt t2, x0, _zero_bss_loop // Still more to go + j _fp_init + +_zero_bss_rem: + sb a0, 0(t0) + addi t2, t2, -1 + addi t0, t0, 1 + bgt t2, x0, _zero_bss_rem + +_fp_init: + // Full fence, then jump to main + call main + +// If main returns, we end up here +.global _exit +_exit: + // Restore the original context registers (sp last) + lw ra, 8(sp) + lw gp, 4(sp) + lw sp, 0(sp) + // Save the return value to scratch register 2 and wait forever. + slli t0, a0, 1 + ori t0, t0, 1 + la t1, __base_regs + sw t0, 8(t1) // regs.SCRATCH[2] + // Hand over to whatever called us, passing return + ret + +// This wraps the C trap handler to save the (integer-only) caller-save +// registers and perform a proper machine-mode exception return. +.align 4 +_trap_handler_wrap: + addi sp, sp, -64 + sw ra, 60(sp) + sw t0, 56(sp) + sw t1, 52(sp) + sw t2, 48(sp) + sw a0, 44(sp) + sw a1, 40(sp) + sw a2, 36(sp) + sw a3, 32(sp) + sw a4, 28(sp) + sw a5, 24(sp) + sw a6, 20(sp) + sw a7, 16(sp) + sw t3, 12(sp) + sw t4, 8(sp) + sw t5, 4(sp) + sw t6, 0(sp) + + jal trap_vector + + lw ra, 60(sp) + lw t0, 56(sp) + lw t1, 52(sp) + lw t2, 48(sp) + lw a0, 44(sp) + lw a1, 40(sp) + lw a2, 36(sp) + lw a3, 32(sp) + lw a4, 28(sp) + lw a5, 24(sp) + lw a6, 20(sp) + lw a7, 16(sp) + lw t3, 12(sp) + lw t4, 8(sp) + lw t5, 4(sp) + lw t6, 0(sp) + addi sp, sp, 128 + mret + +.weak trap_vector +trap_vector: + j trap_vector diff --git a/targets/chimera-host/CMakeLists.txt b/targets/chimera-host/CMakeLists.txt index ea4c692..1a7cb65 100644 --- a/targets/chimera-host/CMakeLists.txt +++ b/targets/chimera-host/CMakeLists.txt @@ -4,6 +4,12 @@ # # Moritz Scherer # Viviane Potocnik +# Philip Wiese + +################################################################################ +# Host Runtime Library # +################################################################################ +add_library(runtime_host STATIC) file(GLOB_RECURSE ASM_SOURCES "src/crt0.S" @@ -14,28 +20,42 @@ file(GLOB_RECURSE C_SOURCES ) set_property(SOURCE ${ASM_SOURCES} PROPERTY LANGUAGE ASM) -add_library(runtime OBJECT ${ASM_SOURCES} ${C_SOURCES}) -target_include_directories(runtime +target_sources(runtime_host + PRIVATE + ${ASM_SOURCES} + ${C_SOURCES} +) + +# WIESEP: Export the target specific include directory +target_include_directories(runtime_host PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include ) -set(ISA rv32imc) -set(ABI ilp32) +target_compile_options(runtime_host + PRIVATE + -O2 +) -target_compile_options(runtime +target_compile_options(runtime_host PUBLIC - -march=${ISA} + -march=${ISA_HOST} -mabi=${ABI} ) -target_link_options(runtime +# WIESEP: Export the target specific linkerscript +target_link_options(runtime_host PUBLIC - -march=${ISA} - -mabi=${ABI} - -nostartfiles - -nostdlib -L${CMAKE_CURRENT_LIST_DIR} -Tlink.ld + -march=${ISA_HOST} + -mabi=${ABI} + -nostartfiles + -ffreestanding ) + +################################################################################ +# Snitch Cluster Runtime Library # +################################################################################ +# WIESEP: There is no Snitch cluster present in this target \ No newline at end of file diff --git a/targets/chimera-host/include/addr_maps/soc_addr_map.h b/targets/chimera-host/include/addr_maps/soc_addr_map.h new file mode 100644 index 0000000..dbd9cea --- /dev/null +++ b/targets/chimera-host/include/addr_maps/soc_addr_map.h @@ -0,0 +1,25 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Moritz Scherer + +#ifndef _SOC_ADDR_MAP_INCLUDE_GUARD_ +#define _SOC_ADDR_MAP_INCLUDE_GUARD_ + +#include + +#define CLINT_CTRL_BASE 0x02040000 + +#define SOC_CTRL_BASE 0x30001000 + +#define NUM_CLUSTER_CORES 0 + +static uint8_t _chimera_numCores[] = {0}; + +#define _chimera_numClusters 0 + +#define CHIMERA_PADFRAME_BASE_ADDRESS 0x30002000 +#define FLL_BASE_ADDR 0x30003000 + +#endif diff --git a/targets/chimera-host/include/regs/soc_ctrl.h b/targets/chimera-host/include/regs/soc_ctrl.h new file mode 100644 index 0000000..3ae00e7 --- /dev/null +++ b/targets/chimera-host/include/regs/soc_ctrl.h @@ -0,0 +1,23 @@ +// Generated register defines for chimera + +// Copyright information found in source file: +// Copyright 2024 ETH Zurich and University of Bologna. + +// Licensing information found in source file: +// +// SPDX-License-Identifier: SHL-0.51 + +#ifndef _CHIMERA_REG_DEFS_ +#define _CHIMERA_REG_DEFS_ + +#ifdef __cplusplus +extern "C" { +#endif +// Register width +#define CHIMERA_PARAM_REG_WIDTH 32 + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // _CHIMERA_REG_DEFS_ +// End generated register defines for chimera diff --git a/targets/chimera-host/include/soc.h b/targets/chimera-host/include/soc.h new file mode 100644 index 0000000..4362aa7 --- /dev/null +++ b/targets/chimera-host/include/soc.h @@ -0,0 +1,13 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _SOC_INCLUDE_GUARD_ +#define _SOC_INCLUDE_GUARD_ + +#include "regs/soc_ctrl.h" +#include "addr_maps/soc_addr_map.h" + +#endif //_SOC_INCLUDE_GUARD_ diff --git a/targets/chimera-host/src/crt0.S b/targets/chimera-host/src/crt0.S index 5e44ab5..059937c 100644 --- a/targets/chimera-host/src/crt0.S +++ b/targets/chimera-host/src/crt0.S @@ -127,7 +127,6 @@ _trap_handler_wrap: addi sp, sp, 128 mret -.global trap_vector .weak trap_vector trap_vector: j trap_vector diff --git a/targets/chimera-open/CMakeLists.txt b/targets/chimera-open/CMakeLists.txt index ea4c692..57d4cad 100644 --- a/targets/chimera-open/CMakeLists.txt +++ b/targets/chimera-open/CMakeLists.txt @@ -4,6 +4,12 @@ # # Moritz Scherer # Viviane Potocnik +# Philip Wiese + +################################################################################ +# Host Runtime Library # +################################################################################ +add_library(runtime_host STATIC) file(GLOB_RECURSE ASM_SOURCES "src/crt0.S" @@ -14,28 +20,69 @@ file(GLOB_RECURSE C_SOURCES ) set_property(SOURCE ${ASM_SOURCES} PROPERTY LANGUAGE ASM) -add_library(runtime OBJECT ${ASM_SOURCES} ${C_SOURCES}) -target_include_directories(runtime +target_sources(runtime_host + PRIVATE + ${ASM_SOURCES} + ${C_SOURCES} +) + +# WIESEP: Export the target specific include directory +target_include_directories(runtime_host PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include ) -set(ISA rv32imc) -set(ABI ilp32) +target_compile_options(runtime_host + PRIVATE + -O2 +) -target_compile_options(runtime +target_compile_options(runtime_host PUBLIC - -march=${ISA} + -march=${ISA_HOST} -mabi=${ABI} ) -target_link_options(runtime +# WIESEP: Export the target specific linkerscript +target_link_options(runtime_host PUBLIC - -march=${ISA} - -mabi=${ABI} - -nostartfiles - -nostdlib -L${CMAKE_CURRENT_LIST_DIR} -Tlink.ld + -march=${ISA_HOST} + -mabi=${ABI} + -nostartfiles + -ffreestanding ) + +################################################################################ +# Snitch Cluster Runtime Library # +################################################################################ +add_library(runtime_cluster_snitch STATIC) + +# WIESEP: Export the headers also to the cluster runtime +target_include_directories(runtime_cluster_snitch + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/include +) + +# WIESEP: Do not export optimization flags +target_compile_options(runtime_cluster_snitch + PRIVATE + -O2 +) + +target_compile_options(runtime_cluster_snitch + PUBLIC + -march=${ISA_CLUSTER_SNITCH} + -mabi=${ABI} +) + +# WIESEP: Expose common link option +target_link_options(runtime_cluster_snitch + PUBLIC + -march=${ISA_CLUSTER_SNITCH} + -mabi=${ABI} + -nostartfiles + -ffreestanding +) \ No newline at end of file diff --git a/targets/chimera-open/include/soc_addr_map.h b/targets/chimera-open/include/addr_maps/soc_addr_map.h similarity index 87% rename from targets/chimera-open/include/soc_addr_map.h rename to targets/chimera-open/include/addr_maps/soc_addr_map.h index 8141c6f..244c6ed 100644 --- a/targets/chimera-open/include/soc_addr_map.h +++ b/targets/chimera-open/include/addr_maps/soc_addr_map.h @@ -25,6 +25,10 @@ #define CLUSTER_3_NUMCORES 9 #define CLUSTER_4_NUMCORES 9 +#define NUM_CLUSTER_CORES \ + (CLUSTER_0_NUMCORES + CLUSTER_1_NUMCORES + CLUSTER_2_NUMCORES + CLUSTER_3_NUMCORES + \ + CLUSTER_4_NUMCORES) + static uint8_t _chimera_numCores[] = {CLUSTER_0_NUMCORES, CLUSTER_1_NUMCORES, CLUSTER_2_NUMCORES, CLUSTER_3_NUMCORES, CLUSTER_4_NUMCORES}; #define _chimera_numClusters 5 diff --git a/targets/chimera-open/include/soc.h b/targets/chimera-open/include/soc.h new file mode 100644 index 0000000..4362aa7 --- /dev/null +++ b/targets/chimera-open/include/soc.h @@ -0,0 +1,13 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _SOC_INCLUDE_GUARD_ +#define _SOC_INCLUDE_GUARD_ + +#include "regs/soc_ctrl.h" +#include "addr_maps/soc_addr_map.h" + +#endif //_SOC_INCLUDE_GUARD_ diff --git a/targets/chimera-open/include/soc_ctrl.h b/targets/chimera-open/include/soc_ctrl.h deleted file mode 100644 index 1493fc1..0000000 --- a/targets/chimera-open/include/soc_ctrl.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer - -#ifndef _OFFLOAD_INCLUDE_GUARD_ -#define _OFFLOAD_INCLUDE_GUARD_ - -#include - -void setupInterruptHandler(void *handler); -void offloadToCluster(void *function, uint8_t clusterId); -void waitClusterBusy(uint8_t clusterId); -uint32_t waitForCluster(uint8_t clusterId); - -#endif diff --git a/targets/chimera-open/src/crt0.S b/targets/chimera-open/src/crt0.S index 5e44ab5..059937c 100644 --- a/targets/chimera-open/src/crt0.S +++ b/targets/chimera-open/src/crt0.S @@ -127,7 +127,6 @@ _trap_handler_wrap: addi sp, sp, 128 mret -.global trap_vector .weak trap_vector trap_vector: j trap_vector diff --git a/targets/chimera-open/src/soc_ctrl.c b/targets/chimera-open/src/soc_ctrl.c deleted file mode 100644 index 9190d1b..0000000 --- a/targets/chimera-open/src/soc_ctrl.c +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer - -#include "regs/soc_ctrl.h" -#include "soc_addr_map.h" -#include "soc_ctrl.h" -#include - -void setupInterruptHandler(void *handler) { - volatile void **snitchTrapHandlerAddr = - (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET); - - *snitchTrapHandlerAddr = handler; -} - -void waitClusterBusy(uint8_t clusterId) { - volatile int32_t *busy_ptr; - - if (clusterId == 0) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_0_BUSY_REG_OFFSET); - } else if (clusterId == 1) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_1_BUSY_REG_OFFSET); - } else if (clusterId == 2) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_2_BUSY_REG_OFFSET); - } else if (clusterId == 3) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_3_BUSY_REG_OFFSET); - } else if (clusterId == 4) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_4_BUSY_REG_OFFSET); - } - - while (*busy_ptr == 1) { - } - // TODO: temporary race condition fix - for (int i = 0; i < 1000; i++) { - // NOP - asm volatile("addi x0, x0, 0\n" :::); - } - - return; -} - -/* Offloads a void function pointer to the specified cluster's core 0 */ -void offloadToCluster(void *function, uint8_t clusterId) { - - volatile void **snitchBootAddr = - (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET); - - *snitchBootAddr = function; - - uint32_t hartId = 1; - for (uint32_t i = 0; i < clusterId; i++) { - hartId += _chimera_numCores[i]; - } - - volatile uint32_t *interruptTarget = ((uint32_t *)CLINT_CTRL_BASE) + hartId; - waitClusterBusy(clusterId); - *interruptTarget = 1; -} - -/* Busy waits for the return of a cluster, clears the return register, and - * returns the return value */ -uint32_t waitForCluster(uint8_t clusterId) { - volatile int32_t *snitchReturnAddr; - if (clusterId == 0) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET); - } else if (clusterId == 1) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET); - } else if (clusterId == 2) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET); - } else if (clusterId == 3) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET); - } else if (clusterId == 4) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET); - } - - while (*snitchReturnAddr == 0) { - } - - uint32_t retVal = *snitchReturnAddr; - *snitchReturnAddr = 0; - - return retVal; -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 024c31d..f63e554 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,8 +3,14 @@ # SPDX-License-Identifier: Apache-2.0 # # Moritz Scherer +# Philip Wiese -add_subdirectory(generic) -add_target_source(${TARGET_PLATFORM}) +# Define mappings for tests +set(TEST_MAPPINGS + chimera-convolve:chimera-convolve,chimera-open,chimera-host + chimera-open:chimera-open,chimera-host + chimera-host:chimera-host +) -# TODO: Add target-specific test directories +# Call the macro +add_chimera_subdirectories(${TARGET_PLATFORM} "Test" ${TEST_MAPPINGS}) diff --git a/tests/chimera-convolve/.gitkeep b/tests/chimera-convolve/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/chimera-host/.gitkeep b/tests/chimera-host/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/chimera-host/CMakeLists.txt b/tests/chimera-host/CMakeLists.txt new file mode 100644 index 0000000..9239ce6 --- /dev/null +++ b/tests/chimera-host/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Philip Wiese + +# Add test for host core +add_subdirectory(host) diff --git a/tests/generic/CMakeLists.txt b/tests/chimera-host/host/CMakeLists.txt similarity index 75% rename from tests/generic/CMakeLists.txt rename to tests/chimera-host/host/CMakeLists.txt index bcc761a..483cc57 100644 --- a/tests/generic/CMakeLists.txt +++ b/tests/chimera-host/host/CMakeLists.txt @@ -3,5 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 # # Moritz Scherer +# Philip Wiese -add_subdirectory(testReturnZero) +add_subdirectory(returnZero) diff --git a/tests/chimera-host/host/returnZero/CMakeLists.txt b/tests/chimera-host/host/returnZero/CMakeLists.txt new file mode 100644 index 0000000..e3f58aa --- /dev/null +++ b/tests/chimera-host/host/returnZero/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Moritz Scherer +# Philip Wiese + +set(TEST_NAME test_host_returnZero) + +######## HOST Code ############################################################# +file(GLOB_RECURSE TEST_HOST_SRCS + "src_host/*.c" +) + +add_library(${TEST_NAME}_host OBJECT ${TEST_HOST_SRCS}) +# target_include_directories(${TEST_NAME}_host PUBLIC include) + +# WIESEP: Set the correct ISA and ABI for the host +target_compile_options(${TEST_NAME}_host + PRIVATE + -O2 +) +target_link_libraries(${TEST_NAME}_host PUBLIC runtime_host hal_host) + +######## TEST Executable ####################################################### +add_chimera_test( + ${TEST_NAME} +) + +# WIESEP: Link the host to the test executable +target_link_libraries(${TEST_NAME} PUBLIC ${TEST_NAME}_host) + + diff --git a/tests/generic/testReturnZero/src/testReturn0.c b/tests/chimera-host/host/returnZero/src_host/test_host.c similarity index 100% rename from tests/generic/testReturnZero/src/testReturn0.c rename to tests/chimera-host/host/returnZero/src_host/test_host.c diff --git a/tests/chimera-open/CMakeLists.txt b/tests/chimera-open/CMakeLists.txt index 1d90c6f..e276a85 100644 --- a/tests/chimera-open/CMakeLists.txt +++ b/tests/chimera-open/CMakeLists.txt @@ -3,5 +3,10 @@ # SPDX-License-Identifier: Apache-2.0 # # Moritz Scherer +# Philip Wiese -add_subdirectory(testClusterOffload) +# Add test for host core +# add_subdirectory(host) + +# Add test for snitchCluster +add_subdirectory(snitchCluster) diff --git a/tests/chimera-open/host/.gitkeep b/tests/chimera-open/host/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/chimera-open/snitchCluster/CMakeLists.txt b/tests/chimera-open/snitchCluster/CMakeLists.txt new file mode 100644 index 0000000..4efb99a --- /dev/null +++ b/tests/chimera-open/snitchCluster/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Moritz Scherer +# Philip Wiese + +add_subdirectory(simpleOffload) diff --git a/tests/chimera-open/snitchCluster/simpleOffload/CMakeLists.txt b/tests/chimera-open/snitchCluster/simpleOffload/CMakeLists.txt new file mode 100644 index 0000000..2c1f0bc --- /dev/null +++ b/tests/chimera-open/snitchCluster/simpleOffload/CMakeLists.txt @@ -0,0 +1,48 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Moritz Scherer +# Philip Wiese + +set(TEST_NAME test_snitchCluster_simpleOffload) + +######## HOST Code ############################################################# +file(GLOB_RECURSE TEST_HOST_SRCS + "src_host/*.c" +) + +add_library(${TEST_NAME}_host OBJECT ${TEST_HOST_SRCS}) +target_include_directories(${TEST_NAME}_host PUBLIC include) + +# WIESEP: Set the correct ISA and ABI for the host +target_compile_options(${TEST_NAME}_host + PRIVATE + -O2 +) +target_link_libraries(${TEST_NAME}_host PUBLIC runtime_host hal_host) + +######## CLUSTER Code ########################################################## +file(GLOB_RECURSE TEST_SNITCH_SRCS + "src_cluster/*.c" +) + +add_library(${TEST_NAME}_cluster OBJECT ${TEST_SNITCH_SRCS}) +target_include_directories(${TEST_NAME}_cluster PUBLIC include) + +# WIESEP: Set the correct ISA and ABI for the cluster +target_compile_options(${TEST_NAME}_cluster + PRIVATE + -O2 +) +target_link_libraries(${TEST_NAME}_cluster PUBLIC runtime_cluster_snitch) + +######## TEST Executable ####################################################### +add_chimera_test( + ${TEST_NAME} +) + +# WIESEP: Link the host and cluster code to the test executable +target_link_libraries(${TEST_NAME} PUBLIC ${TEST_NAME}_host) +target_link_libraries(${TEST_NAME} PUBLIC ${TEST_NAME}_cluster) + diff --git a/tests/chimera-open/snitchCluster/simpleOffload/include/test_cluster.h b/tests/chimera-open/snitchCluster/simpleOffload/include/test_cluster.h new file mode 100644 index 0000000..c92c3cf --- /dev/null +++ b/tests/chimera-open/snitchCluster/simpleOffload/include/test_cluster.h @@ -0,0 +1,16 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _TEST_CLUSTER_INCLUDE_GUARD_ +#define _TEST_CLUSTER_INCLUDE_GUARD_ + +#include + +void clusterInterruptHandler(); + +int32_t testReturn(void *args); + +#endif //_TEST_CLUSTER_INCLUDE_GUARD_ diff --git a/tests/chimera-open/snitchCluster/simpleOffload/include/test_host.h b/tests/chimera-open/snitchCluster/simpleOffload/include/test_host.h new file mode 100644 index 0000000..ac214ef --- /dev/null +++ b/tests/chimera-open/snitchCluster/simpleOffload/include/test_host.h @@ -0,0 +1,16 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Philip Wiese + +#ifndef _TEST_HOST_INCLUDE_GUARD_ +#define _TEST_HOST_INCLUDE_GUARD_ + +#define TESTVAL 0x050CCE55 + +typedef struct { + int value; +} offloadArgs_t; + +#endif //_TEST_HOST_INCLUDE_GUARD_ diff --git a/tests/chimera-open/snitchCluster/simpleOffload/src_cluster/test_cluster.c b/tests/chimera-open/snitchCluster/simpleOffload/src_cluster/test_cluster.c new file mode 100644 index 0000000..ffaff19 --- /dev/null +++ b/tests/chimera-open/snitchCluster/simpleOffload/src_cluster/test_cluster.c @@ -0,0 +1,61 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Moritz Scherer + +#include "test_cluster.h" +#include "test_host.h" + +#include "soc.h" + +static uint32_t *clintPointer = (uint32_t *)CLINT_CTRL_BASE; + +/** + * @brief Interrupt handler for the cluster, which clears the interrupt flag for the current hart. + * + * @warning Stack, thread and global pointer might not yet be set up! + */ +__attribute__((naked)) void clusterInterruptHandler() { + asm volatile( + // Load global pointer + ".option push\n" + ".option norelax\n" // Disable relaxation to ensure `la` behaves as expected + "la gp, __global_pointer$\n" // Load address of global pointer + ".option pop\n" + + // Set thread pointer (tp) to zero + "mv tp, zero\n" + + // Load mhartid CSR into t0 + "csrr t0, mhartid\n" + // Load the base address of clintPointer into t1 + "lw t1, %0\n" + // Calculate the interrupt target address: t1 = t1 + (t0 * 4) + "slli t0, t0, 2\n" + "add t1, t1, t0\n" + // Store 0 to the interrupt target address + "sw zero, 0(t1)\n" + "ret" + : + : "m"(clintPointer) // Pass clintPointer as input + : "t0", "t1" // Declare clobbered registers + ); +} + +/** + * @brief Main function of the cluster test. + * + * @return int Return 0 if the test was successful, -1 otherwise. + */ +int32_t testReturn(void *args) { + // Cast to the correct struct + offloadArgs_t *argsStruct = (offloadArgs_t *)args; + + // Check if the value is correct + if (argsStruct->value != 0xdeadbeef) { + return -1; + } + + return TESTVAL; +} \ No newline at end of file diff --git a/tests/chimera-open/snitchCluster/simpleOffload/src_host/test_host.c b/tests/chimera-open/snitchCluster/simpleOffload/src_host/test_host.c new file mode 100644 index 0000000..f0d38de --- /dev/null +++ b/tests/chimera-open/snitchCluster/simpleOffload/src_host/test_host.c @@ -0,0 +1,23 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Moritz Scherer + +#include "test_cluster.h" +#include "test_host.h" + +#include "soc.h" +#include "driver.h" + +#define STACK_ADDRESS (CLUSTER_4_BASE + 0x20000 - 8) + +static offloadArgs_t offloadArgs = {.value = 0xdeadbeef}; + +int main() { + setup_snitchCluster_interruptHandler(clusterInterruptHandler); + offload_snitchCluster_core(testReturn, &offloadArgs, (void *)(STACK_ADDRESS), 4, 0); + uint32_t retVal = wait_snitchCluster_return(4); + + return (retVal != (TESTVAL | 0x000000001)); +} \ No newline at end of file diff --git a/tests/chimera-open/testClusterOffload/CMakeLists.txt b/tests/chimera-open/testClusterOffload/CMakeLists.txt deleted file mode 100644 index 4ad9706..0000000 --- a/tests/chimera-open/testClusterOffload/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2024 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# Moritz Scherer - -project(chimera-sdk-testClusterOffload LANGUAGES C ASM) - -file(GLOB_RECURSE TEST_SRCS - "src/testClusterOffload.c" -) - -add_chimera_test( - testClusterOffload - ${TEST_SRCS} -) - -target_link_libraries(testClusterOffload PUBLIC chimera-sdk) diff --git a/tests/chimera-open/testClusterOffload/src/testClusterOffload.c b/tests/chimera-open/testClusterOffload/src/testClusterOffload.c deleted file mode 100644 index 7731265..0000000 --- a/tests/chimera-open/testClusterOffload/src/testClusterOffload.c +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Moritz Scherer - -#include "soc_ctrl.h" -#include "soc_addr_map.h" -#include - -#define TESTVAL 0x050CCE55 - -static uint32_t *clintPointer = (uint32_t *)CLINT_CTRL_BASE; - -void clusterInterruptHandler() { - uint8_t hartId; - asm("csrr %0, mhartid" : "=r"(hartId)::); - - volatile uint32_t *interruptTarget = clintPointer + hartId; - *interruptTarget = 0; - return; -} - -int32_t testReturn() { - return TESTVAL; -} - -int main() { - setupInterruptHandler(clusterInterruptHandler); - offloadToCluster(testReturn, 0); - uint32_t retVal = waitForCluster(0); - - return (retVal != (TESTVAL | 0x000000001)); -} diff --git a/tests/generic/testReturnZero/CMakeLists.txt b/tests/generic/testReturnZero/CMakeLists.txt deleted file mode 100644 index b958c4c..0000000 --- a/tests/generic/testReturnZero/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2024 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# Moritz Scherer - -project(chimera-sdk-testReturnZero LANGUAGES C ASM) - -file(GLOB_RECURSE TEST_SRCS - "src/testReturn0.c" -) - -add_chimera_test( - testReturnZero - ${TEST_SRCS} -) - -target_link_libraries(testReturnZero PUBLIC chimera-sdk)