diff --git a/.gitlab/templates/build-test.yml b/.gitlab/templates/build-test.yml index 3c31ba8f7c58ff4b6a9eaa082691c5adfe1f9725..6b2489bd2b43744c4608747a4ae966f30719411b 100644 --- a/.gitlab/templates/build-test.yml +++ b/.gitlab/templates/build-test.yml @@ -38,7 +38,7 @@ matrix: - BUILD_PRODUCT: [host, juno, morello, n1sdp, rcar, rdv3, rdv1, rdv1mc, rdn1e1, rdn2, - sgi575, sgm775, sgm776, synquacer, rd1ae] + sgi575, sgm775, sgm776, synquacer, rd1ae, fvp-baser-aemv8r] .build-products-all-products-all-log-levels: extends: .build-products @@ -46,7 +46,7 @@ matrix: - BUILD_PRODUCT: [host, juno, morello, n1sdp, rcar, rdv3, rdv1, rdv1mc, rdn1e1, rdn2, - sgi575, sgm775, sgm776, synquacer, rd1ae] + sgi575, sgm775, sgm776, synquacer, rd1ae, fvp-baser-aemv8r] BUILD_PRODUCTS_LOG_LEVEL: [DEBUG, INFO, WARN, ERROR, CRIT, DISABLED] diff --git a/arch/CMakeLists.txt b/arch/CMakeLists.txt index 38ff7fd6f254950143ae5d8cc3f5373bac75c422..91bff36bdfae74093cf6b4637b88b9b953a04276 100644 --- a/arch/CMakeLists.txt +++ b/arch/CMakeLists.txt @@ -1,10 +1,11 @@ # # Arm SCP/MCP Software -# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +list(APPEND SCP_ARCHITECTURE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/arm/aarch64") list(APPEND SCP_ARCHITECTURE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/arm/arm-m") list(APPEND SCP_ARCHITECTURE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/arm/armv8-a") list(APPEND SCP_ARCHITECTURE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/none/host") diff --git a/arch/arm/aarch64/Architecture.cmake b/arch/arm/aarch64/Architecture.cmake new file mode 100644 index 0000000000000000000000000000000000000000..79af687c087d92862a0dafb18bcebd69d6ba94ff --- /dev/null +++ b/arch/arm/aarch64/Architecture.cmake @@ -0,0 +1,9 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_ARCHITECTURE "aarch64") +set(SCP_ARCHITECTURE_TARGET "arch-aarch64") diff --git a/arch/arm/aarch64/CMakeLists.txt b/arch/arm/aarch64/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a9abdbf666732affdbd8c120492ced9d758e7bc2 --- /dev/null +++ b/arch/arm/aarch64/CMakeLists.txt @@ -0,0 +1,37 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +if(CMAKE_C_COMPILER_ID STREQUAL "ARMClang") + message(FATAL_ERROR "Arm Clang is not supported for the aarch64 architecture") +endif() + +add_library(arch-aarch64) + +target_include_directories(arch-aarch64 + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/include") + +target_sources( + arch-aarch64 + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_crt0.S" + "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_exceptions.S" + "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_gic.c" + "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_main.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/src/arch_mm.c" + ) + +if(SCP_HAVE_NEWLIB) + target_compile_definitions(arch-aarch64 PUBLIC -DUSE_NEWLIB) + target_sources(arch-aarch64 + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_libc_hooks.c") + target_link_options(arch-aarch64 PUBLIC + "LINKER:--undefined=_sbrk" + "LINKER:--undefined=_kill") +endif() + +include(SCPTargetLinkerScript) +scp_target_linker_script(arch-aarch64 "${CMAKE_CURRENT_SOURCE_DIR}/../common/src/arch.ld.S") diff --git a/arch/arm/aarch64/include/arch_helpers.h b/arch/arm/aarch64/include/arch_helpers.h new file mode 100644 index 0000000000000000000000000000000000000000..3803ab557b0f1a47d9c0d92b350cfcc2ab97d30c --- /dev/null +++ b/arch/arm/aarch64/include/arch_helpers.h @@ -0,0 +1,47 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ARCH_HELPERS_H +#define ARCH_HELPERS_H + +#include + +/*! + * \brief Enables global CPU interrupts. + * + * \note inline is necessary as this call can be used in performance sensitive + * path + */ +inline static void arch_interrupts_enable(unsigned int not_used) +{ + /* TODO when GIC support is implemented */ +} + +/*! + * \brief Disables global CPU interrupts. + + * \note inline is necessary as this call can be used in performance sensitive + * path + */ +inline static unsigned int arch_interrupts_disable() +{ + /* TODO when GIC support is implemented */ + return FWK_E_SUPPORT; +} + +/*! + * \brief Suspend execution of current CPU. + + * \note CPU will be woken up by receiving interrupts. + * + */ +inline static void arch_suspend(void) +{ + __asm volatile("wfe"); +} + +#endif /* ARCH_HELPERS_H */ diff --git a/arch/arm/aarch64/include/arch_reg.h b/arch/arm/aarch64/include/arch_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..aec8cbcdade6c9d32494d8de00197cd6ea9913d0 --- /dev/null +++ b/arch/arm/aarch64/include/arch_reg.h @@ -0,0 +1,97 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ARCH_REG_H +#define ARCH_REG_H + +#include + +#define READ_SYSREG(reg) \ + ({ \ + uint64_t reg_value; \ + __asm__ volatile("mrs %0, " FWK_STRINGIFY(reg) \ + : "=r"(reg_value)::"memory"); \ + reg_value; \ + }) + +#define WRITE_SYSREG(reg, value) \ + ({ \ + __asm__ volatile("msr " FWK_STRINGIFY(reg) ", %0" ::"r"(value) \ + : "memory"); \ + }) + +#define BARRIER_DSYNC_FENCE_FULL() \ + ({ __asm__ volatile("dsb sy" ::: "memory"); }) + +#define BARRIER_ISYNC_FENCE_FULL() ({ __asm__ volatile("isb" ::: "memory"); }) + +#define mpuir_el2 S3_4_c0_c0_4 +#define prselr_el2 S3_4_c6_c2_1 +#define prbar_el2 S3_4_c6_c8_0 +#define prlar_el2 S3_4_c6_c8_1 + +/* + * PRBAR values + */ +#define PRBAR_BASE(val) ((val)&FWK_GEN_MASK_64(47, 6)) +#define PRBAR_SH(val) ((val) << 4) +#define PRBAR_SH_NON_SHAREABLE 0x0 +#define PRBAR_SH_OUTER_SHAREABLE 0x2 +#define PRBAR_SH_INNER_SHAREABLE 0x3 +#define PRBAR_AP(val) ((val) << 2) +#define PRBAR_AP_RW_EL2 0x0 +#define PRBAR_AP_RO_EL2 0x2 +#define PRBAR_XN(val) (val) +#define PRBAR_XN_PERMITTED 0x0 +#define PRBAR_XN_NOT_PERMITTED 0x2 +#define PRBAR_VALUE(base, sh, ap, xn) \ + (PRBAR_BASE(base) | PRBAR_SH(sh) | PRBAR_AP(ap) | PRBAR_XN(xn)) + +/* + * PRLAR values + */ +#define PRLAR_LIMIT(limit) ((limit)&FWK_GEN_MASK_64(47, 6)) +#define PRLAR_NS(val) ((val) << 4) +#define PRLAR_NS_SECURE 0x0 +#define PRLAR_NS_NON_SECURE 0x1 +#define PRLAR_ATTR_INDEX(val) ((val) << 1) +#define PRLAR_EN(val) (val) +#define PRLAR_EN_DISABLED 0x0 +#define PRLAR_EN_ENABLED 0x1 +#define PRLAR_VALUE(limit, ns, attr_index, en) \ + (PRLAR_LIMIT(limit) | PRLAR_NS(ns) | PRLAR_ATTR_INDEX(attr_index) | \ + PRLAR_EN(en)) + +/* + * MAIR values + */ +#define MAIR_DEVICE_NGNRNE 0x0 +#define MAIR_NORMAL_WB_NT 0xFF + +/* + * SCTLR_EL2 values + */ +#define SCTLR_EL2_RES1 \ + (FWK_BIT(29) | FWK_BIT(28) | FWK_BIT(23) | FWK_BIT(22) | FWK_BIT(18) | \ + FWK_BIT(16) | FWK_BIT(11) | FWK_BIT(5) | FWK_BIT(4)) +#define SCTLR_EL2_RESET SCTLR_EL2_RES1 +#define SCTLR_EL2_C FWK_BIT(2) +#define SCTLR_EL2_M FWK_BIT(0) + +/* + * HCR_EL2 values + */ +#define HCR_EL2_SWIO FWK_BIT(1) +#define HCR_EL2_RESET HCR_EL2_SWIO + +/* + * ID_AA64MMFR0_EL1 values + */ +#define ID_AA64MMFR0_EL1_MSA_MASK FWK_GEN_MASK_64(51, 48) +#define ID_AA64MMFR0_EL1_MSA_FRAC_MASK FWK_GEN_MASK_64(55, 52) + +#endif /* ARCH_REG_H */ diff --git a/arch/arm/aarch64/src/arch_crt0.S b/arch/arm/aarch64/src/arch_crt0.S new file mode 100644 index 0000000000000000000000000000000000000000..a0f68b47adf17aa813e8db25fe02beffeac10a65 --- /dev/null +++ b/arch/arm/aarch64/src/arch_crt0.S @@ -0,0 +1,125 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + + .section .entrypoint + + .extern arm_main + + .global arch_exception_reset; +arch_exception_reset: + /* Ensure primary core */ + mrs x0, mpidr_el1 + and x0, x0, #0xffffff + cbnz x0, wfe_loop + + /* Check current exception level */ + mrs x0, CurrentEL + cmp x0, (2 << 2) + b.gt el3_init + b.eq el2_init + b wfe_loop + +el3_init: + /* TODO */ + b wfe_loop + +el2_init: + /* Configure exception vectors */ + ldr x0, =exception_vectors + msr vbar_el2, x0 + isb + + /* Ensure PMSA is present */ + mrs x0, id_aa64mmfr0_el1 + and x1, x0, #ID_AA64MMFR0_EL1_MSA_MASK + cbz x1, wfe_loop + and x1, x0, #ID_AA64MMFR0_EL1_MSA_FRAC_MASK + cbz x1, wfe_loop + + /* Initialize HCR */ + ldr x0, =HCR_EL2_RESET + msr hcr_el2, x0 + + /* Initialize SCTLR with PMSA disabled */ + ldr x0, =SCTLR_EL2_RESET + msr sctlr_el2, x0 + + dsb sy + isb + + /* Initial MPU region config */ +#if FMW_MEM_MODE == ARCH_MEM_MODE_SINGLE_REGION + /* Region 0 */ + ldr x1, =PRBAR_VALUE(FMW_MEM0_BASE, PRBAR_SH_NON_SHAREABLE, PRBAR_AP_RW_EL2, PRBAR_XN_PERMITTED) + ldr x2, =PRLAR_VALUE(FMW_MEM0_BASE + FMW_MEM0_SIZE - 1, PRLAR_NS_SECURE, 0, PRLAR_EN_ENABLED) + /* Region 1 */ + mov x3, #0 + mov x4, #0 +#else + /* Region 0 */ + ldr x1, =PRBAR_VALUE(FMW_MEM0_BASE, PRBAR_SH_NON_SHAREABLE, PRBAR_AP_RO_EL2, PRBAR_XN_PERMITTED) + ldr x2, =PRLAR_VALUE(FMW_MEM0_BASE + FMW_MEM0_SIZE - 1, PRLAR_NS_SECURE, 0, PRLAR_EN_ENABLED) + /* Region 1 */ + ldr x3, =PRBAR_VALUE(FMW_MEM1_BASE, PRBAR_SH_NON_SHAREABLE, PRBAR_AP_RW_EL2, PRBAR_XN_NOT_PERMITTED) + ldr x4, =PRLAR_VALUE(FMW_MEM1_BASE + FMW_MEM1_SIZE - 1, PRLAR_NS_SECURE, 0, PRLAR_EN_ENABLED) +#endif + + mov x0, MAIR_NORMAL_WB_NT + msr mair_el2, x0 + + msr prselr_el2, xzr + isb + msr prbar_el2, x1 + msr prlar_el2, x2 + dsb sy + mov x0, #1 + msr prselr_el2, x0 + isb + msr prbar_el2, x3 + msr prlar_el2, x4 + dsb sy + isb + + /* Enable PMSA and data cache */ + ldr x0, =SCTLR_EL2_RESET + mov x1, #(SCTLR_EL2_M | SCTLR_EL2_C) + orr x0, x0, x1 + msr sctlr_el2, x0 + dsb sy + isb + + /* Zero BSS */ + ldr x0, =__bss_start__ + ldr x1, =__bss_end__ + cmp x0, x1 + beq skip_bss + +1: str xzr, [x0], #8 + cmp x0, x1 + b.lo 1b + +skip_bss: + /* Setup stack */ + ldr x0, =stack_top + mov sp, x0 + + bl arm_main + +wfe_loop: + wfe + b wfe_loop + + .section .bss + .align 4; + .global stack_bottom; +stack_bottom: + .zero FMW_STACK_SIZE + .global stack_top; +stack_top: diff --git a/arch/arm/aarch64/src/arch_exceptions.S b/arch/arm/aarch64/src/arch_exceptions.S new file mode 100644 index 0000000000000000000000000000000000000000..14796f5bbde80370761f7e099d5c9ee9f6c90942 --- /dev/null +++ b/arch/arm/aarch64/src/arch_exceptions.S @@ -0,0 +1,23 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +.macro ventry label +.align 7 +b \label +.endm + +.global exception_vectors +exception_vectors: + /* current EL, SP_EL0 */ + ventry err_exception /* synchronous */ + ventry err_exception /* IRQ */ + ventry err_exception /* FIQ */ + ventry err_exception /* SError */ + +err_exception: + wfe + b err_exception diff --git a/arch/arm/aarch64/src/arch_gic.c b/arch/arm/aarch64/src/arch_gic.c new file mode 100644 index 0000000000000000000000000000000000000000..3f94ebedf5caf788ac6a34db3ce3c5d4f212ffa0 --- /dev/null +++ b/arch/arm/aarch64/src/arch_gic.c @@ -0,0 +1,109 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static int global_enable(void) +{ + return FWK_E_SUPPORT; +} + +static int global_disable(void) +{ + return FWK_E_SUPPORT; +} + +static int is_enabled(unsigned int interrupt, bool *enabled) +{ + return FWK_E_SUPPORT; +} + +static int enable(unsigned int interrupt) +{ + return FWK_E_SUPPORT; +} + +static int disable(unsigned int interrupt) +{ + return FWK_E_SUPPORT; +} + +static int is_pending(unsigned int interrupt, bool *pending) +{ + return FWK_E_SUPPORT; +} + +static int set_pending(unsigned int interrupt) +{ + return FWK_E_SUPPORT; +} + +static int clear_pending(unsigned int interrupt) +{ + return FWK_E_SUPPORT; +} + +static int set_isr_irq(unsigned int interrupt, void (*isr)(void)) +{ + return FWK_E_SUPPORT; +} + +static int set_isr_irq_param( + unsigned int interrupt, + void (*isr)(uintptr_t param), + uintptr_t parameter) +{ + return FWK_E_SUPPORT; +} + +static int set_isr_dummy(void (*isr)(void)) +{ + return FWK_E_SUPPORT; +} + +static int set_isr_dummy_param( + void (*isr)(uintptr_t param), + uintptr_t parameter) +{ + return FWK_E_SUPPORT; +} + +static int get_current(unsigned int *interrupt) +{ + return FWK_E_SUPPORT; +} + +static bool is_interrupt_context(void) +{ + return false; +} + +const struct fwk_arch_interrupt_driver arm_gic_driver = { + .global_enable = global_enable, + .global_disable = global_disable, + .is_enabled = is_enabled, + .enable = enable, + .disable = disable, + .is_pending = is_pending, + .set_pending = set_pending, + .clear_pending = clear_pending, + .set_isr_irq = set_isr_irq, + .set_isr_irq_param = set_isr_irq_param, + .set_isr_nmi = set_isr_dummy, + .set_isr_nmi_param = set_isr_dummy_param, + .set_isr_fault = set_isr_dummy, + .get_current = get_current, + .is_interrupt_context = is_interrupt_context, +}; + +int arch_gic_init(const struct fwk_arch_interrupt_driver **driver) +{ + *driver = &arm_gic_driver; + + return FWK_SUCCESS; +} diff --git a/arch/arm/aarch64/src/arch_libc_hooks.c b/arch/arm/aarch64/src/arch_libc_hooks.c new file mode 100644 index 0000000000000000000000000000000000000000..7bb23afa54bc22444c96431ae3bab5a6fc4c6313 --- /dev/null +++ b/arch/arm/aarch64/src/arch_libc_hooks.c @@ -0,0 +1,70 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +extern int errno; + +int _kill(int i, int j) +{ + errno = ENOSYS; + return 0; +} + +int _read(int fd, void *buf, int nbytes) +{ + errno = ENOSYS; + return 0; +} + +int _lseek(int file, int ptr, int dir) +{ + errno = ENOSYS; + return 0; +} + +int _close(int fd) +{ + errno = ENOSYS; + return -1; +} + +int _write(int fd, const void *buf, int nbytes) +{ + errno = ENOSYS; + return 0; +} + +int _getpid(void) +{ + errno = ENOSYS; + return 0; +} + +int _isatty(int file) +{ + errno = ENOSYS; + return 0; +} + +int _fstat(int file, struct stat *st) +{ + errno = ENOSYS; + return 0; +} + +void _exit(int rc) +{ + while (true) { + __asm volatile("wfe"); + } +} diff --git a/arch/arm/aarch64/src/arch_main.c b/arch/arm/aarch64/src/arch_main.c new file mode 100644 index 0000000000000000000000000000000000000000..ce0a60e44f01530a7bbaf0915fedc1aeae73510b --- /dev/null +++ b/arch/arm/aarch64/src/arch_main.c @@ -0,0 +1,24 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include + +extern int arch_gic_init(const struct fwk_arch_interrupt_driver **driver); + +static const struct fwk_arch_init_driver arch_init_driver = { + .interrupt = arch_gic_init, +}; + +int arm_main(void) +{ + return fwk_arch_init(&arch_init_driver); +} diff --git a/arch/arm/arm-m/CMakeLists.txt b/arch/arm/arm-m/CMakeLists.txt index 6f8d45d0a5e1c8eaec7ff29f51536bca269636e7..c07f5666a63d583b299a21a0a38ed3cab6c3f6d9 100644 --- a/arch/arm/arm-m/CMakeLists.txt +++ b/arch/arm/arm-m/CMakeLists.txt @@ -22,7 +22,8 @@ else() endif() target_include_directories(arch-arm-m - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/include") # cmake-lint: disable=E1122 @@ -32,7 +33,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_handlers.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_main.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_nvic.c" - PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src/arch_mm.c") + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../common/src/arch_mm.c") target_link_libraries(arch-arm-m PUBLIC cmsis::core-m) @@ -100,7 +101,7 @@ include(SCPTargetLinkerScript) if(CMAKE_C_COMPILER_ID STREQUAL "ARMClang") set(scp_lds "${CMAKE_CURRENT_SOURCE_DIR}/src/arch.scatter.S") else() - set(scp_lds "${CMAKE_CURRENT_SOURCE_DIR}/src/arch.ld.S") + set(scp_lds "${CMAKE_CURRENT_SOURCE_DIR}/../common/src/arch.ld.S") endif() scp_target_linker_script(arch-arm-m "${scp_lds}") diff --git a/arch/arm/arm-m/src/arch.scatter.S b/arch/arm/arm-m/src/arch.scatter.S index c87efe3f85ee774d4d37266fb1661935b1babf7e..633e5d409f591bf9c7cbb65b0b5555efce1badde 100644 --- a/arch/arm/arm-m/src/arch.scatter.S +++ b/arch/arm/arm-m/src/arch.scatter.S @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -8,7 +8,7 @@ * Arm Compiler 6 scatter file. */ -#include +#include #if FMW_MEM_MODE == ARCH_MEM_MODE_SINGLE_REGION /* diff --git a/arch/arm/arm-m/include/arch_scatter.h b/arch/arm/common/include/arch_mem_mode.h similarity index 94% rename from arch/arm/arm-m/include/arch_scatter.h rename to arch/arm/common/include/arch_mem_mode.h index 0844f696897b400943e3dd4c4759d7fb194670fd..59a86797fc2ea3cea96ec07623762dfb6a36b784 100644 --- a/arch/arm/arm-m/include/arch_scatter.h +++ b/arch/arm/common/include/arch_mem_mode.h @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -31,8 +31,8 @@ * bus. */ -#ifndef ARCH_SCATTER_H -#define ARCH_SCATTER_H +#ifndef ARCH_MEM_MODE_H +#define ARCH_MEM_MODE_H #define ARCH_MEM_MODE_SINGLE_REGION 0 #define ARCH_MEM_MODE_DUAL_REGION_RELOCATION 1 @@ -72,4 +72,4 @@ # define ARCH_MEM1_LIMIT (FMW_MEM1_BASE + FMW_MEM1_SIZE) #endif -#endif /* ARCH_SCATTER_H */ +#endif /* ARCH_MEM_MODE_H */ diff --git a/arch/arm/arm-m/src/arch.ld.S b/arch/arm/common/src/arch.ld.S similarity index 96% rename from arch/arm/arm-m/src/arch.ld.S rename to arch/arm/common/src/arch.ld.S index 3b15e36e2488366f8af2d259cbadb13c6faf2527..edfb2d125043689754b166374c50b573e1d0fbf8 100644 --- a/arch/arm/arm-m/src/arch.ld.S +++ b/arch/arm/common/src/arch.ld.S @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -8,7 +8,7 @@ * GNU LD linker script. */ -#include +#include ENTRY(arch_exception_reset) @@ -84,16 +84,17 @@ SECTIONS { } > x .text : { + *(.entrypoint) *(.text .text.*) } > x #ifdef __clang__ .eh_frame : { - (.eh_frame) + *(.eh_frame) } > x .ARM.exidx : { - (.ARM.exidx) + *(.ARM.exidx) } > x #endif diff --git a/arch/arm/src/arch_mm.c b/arch/arm/common/src/arch_mm.c similarity index 93% rename from arch/arm/src/arch_mm.c rename to arch/arm/common/src/arch_mm.c index aec8e47ce38685c2f0a7abda04833a2a7d2396d9..c46564d3af74289c723e48625e1ed008d9a57c59 100644 --- a/arch/arm/src/arch_mm.c +++ b/arch/arm/common/src/arch_mm.c @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -13,9 +13,11 @@ #include #include +/* clang-format off */ #if FWK_HAS_INCLUDE() # include #endif +/* clang-format on */ #ifdef __NEWLIB__ # include diff --git a/cmake/Toolchain/Clang-Baremetal.cmake b/cmake/Toolchain/Clang-Baremetal.cmake index ffadf6508770eb8c176ac181d80b8f28350b8685..67aa8cc56d0e327d719ae5f0ab5091312c8fb501 100644 --- a/cmake/Toolchain/Clang-Baremetal.cmake +++ b/cmake/Toolchain/Clang-Baremetal.cmake @@ -39,6 +39,10 @@ foreach(language IN ITEMS ASM C CXX) "-mstrict-align -fno-builtin -DAARCH64 -D__ASSEMBLY__ ") string(APPEND CMAKE_${language}_FLAGS_INIT "-I\"${LLVM_SYSROOT_PATH}/include\" ") + if(DEFINED SCP_AARCH64_PROCESSOR_TARGET) + string(APPEND CMAKE_${language}_FLAGS_INIT + "-mcpu=${SCP_AARCH64_PROCESSOR_TARGET} ") + endif() endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "cortex-m(3|7|33|55|85)") diff --git a/doc/Doxyfile b/doc/Doxyfile index 9518eccfc2258e9b880cf54dc849c2519a57ef2b..c737ea66dffbd7f4dec53875049ceeaf643b271c 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -803,6 +803,7 @@ INPUT = $(TOP_DIR)/readme.md \ $(DOC_DIR)/glossary.md \ $(DOC_DIR)/deferred_response_architecture.md \ $(DOC_DIR)/architecture_support.md \ + $(DOC_DIR)/aarch64.md \ $(FWK_DIR)/include \ $(FWK_DIR)/test/fwk_test.h \ $(MODULE_INCLUDES) \ diff --git a/doc/aarch64.md b/doc/aarch64.md new file mode 100644 index 0000000000000000000000000000000000000000..8d8f334b578605090d2b2a4d62b978cd2ed64523 --- /dev/null +++ b/doc/aarch64.md @@ -0,0 +1,28 @@ +# AArch64 Architecture Support + +SCP-firmware has limited support for the AArch64 architecture, specifically a +subset required to boot on Armv8-R64 machines, with the potential to extend to +Armv8-A machines in the future. + +The AArch64 architecutre support follows the structure and interfaces defined on +the [Architechture Support](architecture_support.md) page. + +Only the Armv8-R64 PMSA is currently supported. An initial memory map is +installed in arch_crt0.S, based on the firmware layout, which should be +customized using the armv8r_mpu module configuration. + +Note that AArch64 support only uses one exception level, the initial EL at boot. +For Armv8-R64, this means the firmware runs exclusively at secure EL2, and no +attempts are made to initialize the EL1/0 environment. + +Both GCC and Clang are supported, but not Arm Clang. + +## Usage + +To use the AArch64 architecture in a product, including the following in +Firmware.cmake: + + set(SCP_ARCHITECTURE "aarch64") + +The fvp-baser-aemv8r product can be used as a reference for implementing an +AArch64 product. diff --git a/framework/include/fwk_macros.h b/framework/include/fwk_macros.h index 9bb8b44fca85b078136eac6d345cf41701df9198..316f92b1cad4ed8ece6a971a5b8cbe8b8519cae7 100644 --- a/framework/include/fwk_macros.h +++ b/framework/include/fwk_macros.h @@ -49,8 +49,8 @@ * * \return The nearest multiple which is greater than or equal to VALUE. */ -#define FWK_ALIGN_NEXT(VALUE, INTERVAL) ((\ - ((VALUE) + (INTERVAL) - 1) / (INTERVAL)) * (INTERVAL)) +#define FWK_ALIGN_NEXT(VALUE, INTERVAL) \ + ((((VALUE) + (INTERVAL)-1) / (INTERVAL)) * (INTERVAL)) /*! * \brief Aligns a value to the previous multiple. @@ -60,8 +60,8 @@ * * \return The nearest multiple which is smaller than or equal to VALUE. */ -#define FWK_ALIGN_PREVIOUS(VALUE, INTERVAL) ( \ - ((VALUE) / (INTERVAL)) * (INTERVAL)) +#define FWK_ALIGN_PREVIOUS(VALUE, INTERVAL) \ + (((VALUE) / (INTERVAL)) * (INTERVAL)) /*! * \brief Check the alignment of a value. @@ -79,7 +79,7 @@ /*! * \brief Hertz unit. */ -#define FWK_HZ (1UL) +#define FWK_HZ (1UL) /*! * \brief Kilohertz unit. @@ -332,7 +332,7 @@ * \param[in] ... Remaining values. */ -#define __FWK_MAP_1(MACRO, X) MACRO(X) +#define __FWK_MAP_1(MACRO, X) MACRO(X) #define __FWK_MAP_2(MACRO, X, ...) __FWK_MAP_1(MACRO, __VA_ARGS__) MACRO(X) #define __FWK_MAP_3(MACRO, X, ...) __FWK_MAP_2(MACRO, __VA_ARGS__) MACRO(X) #define __FWK_MAP_4(MACRO, X, ...) __FWK_MAP_3(MACRO, __VA_ARGS__) MACRO(X) @@ -394,6 +394,82 @@ # define FWK_HAS_INCLUDE(HEADER) 1 #endif +#ifdef __ASSEMBLER__ + +# define FWK_BIT(N) (1 << (N)) +# define FWK_BIT64(N) (1 << (N)) + +# define FWK_BIT_MASK(N) (FWK_BIT(N) - 1) +# define FWK_BIT_MASK_64(N) (FWK_BIT_64(N) - 1) + +# define FWK_GEN_MASK(H, L) \ + (((~0) - (1 << (L)) + 1) & (~0 >> (32 - 1 - (H)))) + +# define FWK_GEN_MASK_64(H, L) \ + (((~0) - (1 << (L)) + 1) & (~0 >> (64 - 1 - (H)))) + +#else + +/*! + * \brief Define a bitmask with a single set bit + * + * \param[in] N The bit to set + * + * \return A bitmask with the Nth bit set + */ +# define FWK_BIT(N) (1U << (N)) + +/*! + * \brief Define a 64-bit bitmask with a single set bit + * + * \param[in] N The bit to set + * + * \return A 64-bit bitmask with the Nth bit set + */ +# define FWK_BIT_64(N) (1ULL << (N)) + +/*! + * \brief Define a bitmask with the first bits set + * + * \param[in] N The last bit to set + * + * \return A bitmask with the first N bits set + */ +# define FWK_BIT_MASK(N) (FWK_BIT(N) - 1U) + +/*! + * \brief Define a bitmask with the first bits set + * + * \param[in] N The last bit to set + * + * \return A 64-bit bitmask with the first N bits set + */ +# define FWK_BIT_MASK_64(N) (FWK_BIT_64(N) - 1ULL) + +/*! + * \brief Define a bitmask with a range of bits set + * + * \param[in] H The last bit to set + * \param[in] L The first bit to set + * + * \return A bitmask with bits L through H set + */ +# define FWK_GEN_MASK(H, L) \ + (((~0U) - (1U << (L)) + 1) & (~0U >> (32U - 1 - (H)))) + +/*! + * \brief Define a 64-bit bitmask with a range of bits set + * + * \param[in] H The last bit to set + * \param[in] L The first bit to set + * + * \return A 64-bit bitmask with bits L through H set + */ +# define FWK_GEN_MASK_64(H, L) \ + (((~0ULL) - (1ULL << (L)) + 1) & (~0ULL >> (64ULL - 1 - (H)))) + +#endif + /*! * \} */ diff --git a/framework/test/test_fwk_macros.c b/framework/test/test_fwk_macros.c index 7283ad0d4d581f272df949632a0df6c988ffc88f..983ef20e6943e9d1db19d6f1ecd0a5319f3aece7 100644 --- a/framework/test/test_fwk_macros.c +++ b/framework/test/test_fwk_macros.c @@ -14,6 +14,9 @@ static void test_fwk_macros_align_next(void); static void test_fwk_macros_align_previous(void); static void test_fwk_macros_power_of_two_check(void); static void test_fwk_macros_align_check(void); +static void test_fwk_macros_bit(void); +static void test_fwk_macros_bit_mask(void); +static void test_fwk_macros_gen_mask(void); static const struct fwk_test_case_desc test_case_table[] = { FWK_TEST_CASE(test_fwk_macros_array_size), @@ -21,6 +24,9 @@ static const struct fwk_test_case_desc test_case_table[] = { FWK_TEST_CASE(test_fwk_macros_align_previous), FWK_TEST_CASE(test_fwk_macros_power_of_two_check), FWK_TEST_CASE(test_fwk_macros_align_check), + FWK_TEST_CASE(test_fwk_macros_bit), + FWK_TEST_CASE(test_fwk_macros_bit_mask), + FWK_TEST_CASE(test_fwk_macros_gen_mask), }; struct fwk_test_suite_desc test_suite = { @@ -175,3 +181,44 @@ static void test_fwk_macros_align_check(void) assert(result == test_data[i].verdict); } } + +static void test_fwk_macros_bit(void) +{ + assert(FWK_BIT(0) == 0x1); + assert(FWK_BIT(1) == 0x2); + assert(FWK_BIT(30) == 0x40000000); + assert(FWK_BIT(31) == 0x80000000); + + assert(FWK_BIT_64(0) == 0x1); + assert(FWK_BIT_64(1) == 0x2); + assert(FWK_BIT_64(62) == 0x4000000000000000); + assert(FWK_BIT_64(63) == 0x8000000000000000); +} + +static void test_fwk_macros_bit_mask(void) +{ + assert(FWK_BIT_MASK(0) == 0x0); + assert(FWK_BIT_MASK(1) == 0x1); + assert(FWK_BIT_MASK(31) == 0x7FFFFFFF); + + assert(FWK_BIT_MASK_64(0) == 0x0); + assert(FWK_BIT_MASK_64(1) == 0x1); + assert(FWK_BIT_MASK_64(63) == 0x7FFFFFFFFFFFFFFF); +} + +static void test_fwk_macros_gen_mask(void) +{ + assert(FWK_GEN_MASK(0, 0) == 0x1); + assert(FWK_GEN_MASK(1, 0) == 0x3); + assert(FWK_GEN_MASK(2, 1) == 0x6); + assert(FWK_GEN_MASK(30, 1) == 0x7FFFFFFE); + assert(FWK_GEN_MASK(31, 0) == 0xFFFFFFFF); + assert(FWK_GEN_MASK(31, 31) == 0x80000000); + + assert(FWK_GEN_MASK_64(0, 0) == 0x1); + assert(FWK_GEN_MASK_64(1, 0) == 0x3); + assert(FWK_GEN_MASK_64(2, 1) == 0x6); + assert(FWK_GEN_MASK_64(62, 1) == 0x7FFFFFFFFFFFFFFE); + assert(FWK_GEN_MASK_64(63, 0) == 0xFFFFFFFFFFFFFFFF); + assert(FWK_GEN_MASK_64(63, 63) == 0x8000000000000000); +} diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index ffdde5db8ab777fadb28e1a9c2b9bf6ada2fa7f1..a7423dc751e69354b089aedae61ae363d7349efb 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -22,6 +22,7 @@ list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/atu") list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/apcontext") list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/armv7m_mpu") list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/armv8m_mpu") +list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/armv8r_mpu") list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/bootloader") list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/clock") list(APPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/cmn600") diff --git a/module/armv8r_mpu/CMakeLists.txt b/module/armv8r_mpu/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..62f4e853138f2ebd1c1d93b0eaeec07972c6f56c --- /dev/null +++ b/module/armv8r_mpu/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +add_library(${SCP_MODULE_TARGET} SCP_MODULE) + +target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + +target_sources(${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_armv8r_mpu.c" + "${CMAKE_CURRENT_SOURCE_DIR}/src/armv8r_mpu_reg.c") diff --git a/module/armv8r_mpu/Module.cmake b/module/armv8r_mpu/Module.cmake new file mode 100644 index 0000000000000000000000000000000000000000..79f3bf6fa870baa372d3531b6d68ee576ffd4b0c --- /dev/null +++ b/module/armv8r_mpu/Module.cmake @@ -0,0 +1,9 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_MODULE "armv8r-mpu") +set(SCP_MODULE_TARGET "module-armv8r-mpu") diff --git a/module/armv8r_mpu/doc/armv8r_mpu.md b/module/armv8r_mpu/doc/armv8r_mpu.md new file mode 100644 index 0000000000000000000000000000000000000000..d3e944133b1bdc3ee5b6b85f4385489d289f3276 --- /dev/null +++ b/module/armv8r_mpu/doc/armv8r_mpu.md @@ -0,0 +1,15 @@ +\ingroup GroupModules +\addtogroup GroupMPUARMv8R MPU (ARMv8-R64) + +# Armv8-R MPU configuration module + +This module can be used to configure the PMSA (Protected Memory System +Architecture) in SCP-firmware products using the Armv8-R64 architecture support. +It only defines an init function, which configures the PMSA. + +Note that an initial MPU memory map is configured in the early architecture +code, but this module is still required in order to configure additional memory +regions, e.g. for peripherals. + +`armv8r_mpu` should be listed as the first entry in a product's `SCP_MODULES` +definition. diff --git a/module/armv8r_mpu/include/internal/armv8r_mpu_reg.h b/module/armv8r_mpu/include/internal/armv8r_mpu_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..ae5b334efd50313538b761bcabb158b8bdea8991 --- /dev/null +++ b/module/armv8r_mpu/include/internal/armv8r_mpu_reg.h @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef INTERNAL_ARMV8R_MPU_H +#define INTERNAL_ARMV8R_MPU_H + +#include + +uint64_t read_mair_el2(void); +void write_mair_el2(uint64_t); +uint64_t read_mpuir_el2(void); +void write_prbar_el2(uint64_t); +void write_prlar_el2(uint64_t); +void write_prselr_el2(uint64_t); +uint64_t read_sctlr_el2(void); +void write_sctlr_el2(uint64_t); + +void barrier_dsync_fence_full(void); +void barrier_isync_fence_full(void); + +#endif /* INTERNAL_ARMV8R_MPU_H */ diff --git a/module/armv8r_mpu/include/mod_armv8r_mpu.h b/module/armv8r_mpu/include/mod_armv8r_mpu.h new file mode 100644 index 0000000000000000000000000000000000000000..8a82ad30237ccba3c34560458c6a00d9e88cd1eb --- /dev/null +++ b/module/armv8r_mpu/include/mod_armv8r_mpu.h @@ -0,0 +1,79 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_ARMV8R_MPU_H +#define MOD_ARMV8R_MPU_H + +#include +#include + +/*! + * \ingroup GroupModules + * \addtogroup GroupMPUARMv8R MPU (ARMv8-R64) + * \{ + */ + +/*! + * \brief MPU_MAIR registers indices. + */ +enum mod_armv8m_mpu_attr_id { + MPU_ATTR_0, + MPU_ATTR_1, + MPU_ATTR_2, + MPU_ATTR_3, + MPU_ATTR_4, + MPU_ATTR_5, + MPU_ATTR_6, + MPU_ATTR_7, + MPU_MAX_ATTR_COUNT, +}; + +/*! + * \brief Armv8R64 region configuration + */ +struct mod_armv8r_mpu_region { + /*! + * \brief Provides access to the base address of the MPU region + */ + uint64_t prbar; + + /*! + * \brief Provides access to the limit address of the MPU region + */ + uint64_t prlar; +}; + +/*! + * \brief Module configuration. + */ +struct mod_armv8r_mpu_config { + /*! + * \brief Number of MPU attributes. + */ + uint8_t attributes_count; + + /*! + * \brief Pointer to array of MPU attributes. + */ + const uint8_t *attributes; + + /*! + * \brief Number of MPU regions. + */ + uint32_t region_count; + + /*! + * \brief Pointer to array of MPU regions. + */ + const struct mod_armv8r_mpu_region *regions; +}; + +/*! + * \} + */ + +#endif /* MOD_ARMV8R_MPU_H */ diff --git a/module/armv8r_mpu/src/armv8r_mpu_reg.c b/module/armv8r_mpu/src/armv8r_mpu_reg.c new file mode 100644 index 0000000000000000000000000000000000000000..0e45448a1aaa67b932497b78ef03eb85b4927d0a --- /dev/null +++ b/module/armv8r_mpu/src/armv8r_mpu_reg.c @@ -0,0 +1,61 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +uint64_t read_mair_el2(void) +{ + return READ_SYSREG(mair_el2); +} + +void write_mair_el2(uint64_t value) +{ + WRITE_SYSREG(mair_el2, value); +} + +uint64_t read_mpuir_el2(void) +{ + return READ_SYSREG(mpuir_el2); +} + +void write_prbar_el2(uint64_t value) +{ + WRITE_SYSREG(prbar_el2, value); +} + +void write_prlar_el2(uint64_t value) +{ + WRITE_SYSREG(prlar_el2, value); +} + +void write_prselr_el2(uint64_t value) +{ + WRITE_SYSREG(prselr_el2, value); +} + +uint64_t read_sctlr_el2(void) +{ + return READ_SYSREG(sctlr_el2); +} + +void write_sctlr_el2(uint64_t value) +{ + WRITE_SYSREG(sctlr_el2, value); +} + +void barrier_dsync_fence_full(void) +{ + BARRIER_DSYNC_FENCE_FULL(); +} + +void barrier_isync_fence_full(void) +{ + BARRIER_ISYNC_FENCE_FULL(); +} diff --git a/module/armv8r_mpu/src/mod_armv8r_mpu.c b/module/armv8r_mpu/src/mod_armv8r_mpu.c new file mode 100644 index 0000000000000000000000000000000000000000..e14b5fd0d2240cb2267e3a03b3fe7b65b9582e20 --- /dev/null +++ b/module/armv8r_mpu/src/mod_armv8r_mpu.c @@ -0,0 +1,92 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "internal/armv8r_mpu_reg.h" +#include "mod_armv8r_mpu.h" + +#include +#include +#include +#include + +#define SCTLR_EL2_M (1 << 0) +#define MPUIR_EL2_REGION (0xFF) + +static void set_mem_attr(uint8_t attr_index, uint8_t value) +{ + uint64_t reg_value = read_mair_el2(); + reg_value |= (value << (attr_index * 8)); + write_mair_el2(reg_value); + barrier_dsync_fence_full(); +} + +static void set_mem_region(uint8_t region_index, uint64_t prbar, uint64_t prlar) +{ + write_prselr_el2(region_index); + barrier_isync_fence_full(); + write_prbar_el2(prbar); + write_prlar_el2(prlar); + barrier_dsync_fence_full(); +} + +static int armv8r_mpu_init( + fwk_id_t module_id, + unsigned int element_count, + const void *data) +{ + const struct mod_armv8r_mpu_config *config; + uint8_t index; + uint64_t max_regions; + + fwk_assert(element_count == 0); + fwk_assert(data != NULL); + + config = data; + + if (config->attributes_count >= (uint8_t)MPU_MAX_ATTR_COUNT) { + return FWK_E_RANGE; + } + + max_regions = (read_mpuir_el2() & MPUIR_EL2_REGION); + if (config->region_count >= max_regions) { + return FWK_E_RANGE; + } + + /* Disable MPU */ + write_sctlr_el2(read_sctlr_el2() & ~SCTLR_EL2_M); + barrier_dsync_fence_full(); + barrier_isync_fence_full(); + + /* Write memory attributes */ + for (index = 0U; index < config->attributes_count; index++) { + set_mem_attr(index, config->attributes[index]); + } + + /* Write memory regions */ + for (index = 0U; index < config->region_count; index++) { + set_mem_region( + index, config->regions[index].prbar, config->regions[index].prlar); + } + + /* Clear unused memory regions */ + for (index = config->region_count; index < max_regions; index++) { + set_mem_region(index, 0, 0); + } + + /* Enable MPU */ + write_sctlr_el2(read_sctlr_el2() | SCTLR_EL2_M); + barrier_dsync_fence_full(); + barrier_isync_fence_full(); + + return FWK_SUCCESS; +} + +/* Module description */ +const struct fwk_module module_armv8r_mpu = { + .type = FWK_MODULE_TYPE_DRIVER, + .init = armv8r_mpu_init, +}; diff --git a/module/armv8r_mpu/test/CMakeLists.txt b/module/armv8r_mpu/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..fc1f16203b8389294e36d34b2e71c1c2d7fdcb53 --- /dev/null +++ b/module/armv8r_mpu/test/CMakeLists.txt @@ -0,0 +1,27 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(TEST_SRC mod_armv8r_mpu) +set(TEST_FILE mod_armv8r_mpu) + +set(UNIT_TEST_TARGET mod_${TEST_MODULE}_unit_test) + +set(MODULE_SRC ${MODULE_ROOT}/${TEST_MODULE}/src) +set(MODULE_INC ${MODULE_ROOT}/${TEST_MODULE}/include) +set(MODULE_UT_SRC ${CMAKE_CURRENT_LIST_DIR}) +set(MODULE_UT_INC ${CMAKE_CURRENT_LIST_DIR}) +set(MODULE_UT_MOCK_SRC ${CMAKE_CURRENT_LIST_DIR}/mocks) + +list(APPEND MOCK_REPLACEMENTS fwk_module) +list(APPEND MOCK_REPLACEMENTS fwk_notification) +list(APPEND MOCK_REPLACEMENTS fwk_id) + +include(${SCP_ROOT}/unit_test/module_common.cmake) + +target_sources(${UNIT_TEST_TARGET} + PRIVATE + ${MODULE_UT_MOCK_SRC}/Mockarmv8r_mpu_reg.c) diff --git a/module/armv8r_mpu/test/config_armv8r_mpu.h b/module/armv8r_mpu/test/config_armv8r_mpu.h new file mode 100644 index 0000000000000000000000000000000000000000..0e2222cd971e6948467c9b93424956bee84f7cd0 --- /dev/null +++ b/module/armv8r_mpu/test/config_armv8r_mpu.h @@ -0,0 +1,34 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +static uint8_t mem_attributes[] = { + 0xFF, + 0x00, +}; + +static struct mod_armv8r_mpu_region mem_regions[] = { { .prbar = 0, + .prlar = 0x7fffffC1 }, + { + .prbar = 0x80000000, + .prlar = 0xffffffC3, + } }; + +const struct fwk_module_config config_armv8r_mpu_ut = { + .data = &((struct mod_armv8r_mpu_config){ + .attributes_count = FWK_ARRAY_SIZE(mem_attributes), + .attributes = mem_attributes, + .region_count = FWK_ARRAY_SIZE(mem_regions), + .regions = mem_regions, + }), +}; diff --git a/module/armv8r_mpu/test/fwk_module_idx.h b/module/armv8r_mpu/test/fwk_module_idx.h new file mode 100644 index 0000000000000000000000000000000000000000..087e847ec9c3a8fb1511e43f8190aacc2e37dcda --- /dev/null +++ b/module/armv8r_mpu/test/fwk_module_idx.h @@ -0,0 +1,21 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEST_FWK_MODULE_MODULE_IDX_H +#define TEST_FWK_MODULE_MODULE_IDX_H + +#include + +enum fwk_module_idx { + FWK_MODULE_IDX_ARMV8R_MPU, + FWK_MODULE_IDX_COUNT, +}; + +static const fwk_id_t fwk_module_id_armv8r_mpu = + FWK_ID_MODULE_INIT(FWK_MODULE_IDX_ARMV8R_MPU); + +#endif /* TEST_FWK_MODULE_MODULE_IDX_H */ diff --git a/module/armv8r_mpu/test/mocks/.clang-format b/module/armv8r_mpu/test/mocks/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..eeca2395f4c7551e2016f0d10a971844a3684994 --- /dev/null +++ b/module/armv8r_mpu/test/mocks/.clang-format @@ -0,0 +1,4 @@ +{ + "DisableFormat": true, + "SortIncludes": false, +} diff --git a/module/armv8r_mpu/test/mocks/Mockarmv8r_mpu_reg.c b/module/armv8r_mpu/test/mocks/Mockarmv8r_mpu_reg.c new file mode 100644 index 0000000000000000000000000000000000000000..6545ee35ff204404f084bf7867fdd145778a9e9f --- /dev/null +++ b/module/armv8r_mpu/test/mocks/Mockarmv8r_mpu_reg.c @@ -0,0 +1,1187 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#include +#include +#include +#include "cmock.h" +#include "Mockarmv8r_mpu_reg.h" + +static const char* CMockString_barrier_dsync_fence_full = "barrier_dsync_fence_full"; +static const char* CMockString_barrier_isync_fence_full = "barrier_isync_fence_full"; +static const char* CMockString_cmock_arg1 = "cmock_arg1"; +static const char* CMockString_read_mair_el2 = "read_mair_el2"; +static const char* CMockString_read_mpuir_el2 = "read_mpuir_el2"; +static const char* CMockString_read_sctlr_el2 = "read_sctlr_el2"; +static const char* CMockString_write_mair_el2 = "write_mair_el2"; +static const char* CMockString_write_prbar_el2 = "write_prbar_el2"; +static const char* CMockString_write_prlar_el2 = "write_prlar_el2"; +static const char* CMockString_write_prselr_el2 = "write_prselr_el2"; +static const char* CMockString_write_sctlr_el2 = "write_sctlr_el2"; + +typedef struct _CMOCK_read_mair_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t ReturnVal; + +} CMOCK_read_mair_el2_CALL_INSTANCE; + +typedef struct _CMOCK_write_mair_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t Expected_cmock_arg1; + char IgnoreArg_cmock_arg1; + +} CMOCK_write_mair_el2_CALL_INSTANCE; + +typedef struct _CMOCK_read_mpuir_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t ReturnVal; + +} CMOCK_read_mpuir_el2_CALL_INSTANCE; + +typedef struct _CMOCK_write_prbar_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t Expected_cmock_arg1; + char IgnoreArg_cmock_arg1; + +} CMOCK_write_prbar_el2_CALL_INSTANCE; + +typedef struct _CMOCK_write_prlar_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t Expected_cmock_arg1; + char IgnoreArg_cmock_arg1; + +} CMOCK_write_prlar_el2_CALL_INSTANCE; + +typedef struct _CMOCK_write_prselr_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t Expected_cmock_arg1; + char IgnoreArg_cmock_arg1; + +} CMOCK_write_prselr_el2_CALL_INSTANCE; + +typedef struct _CMOCK_read_sctlr_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t ReturnVal; + +} CMOCK_read_sctlr_el2_CALL_INSTANCE; + +typedef struct _CMOCK_write_sctlr_el2_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + uint64_t Expected_cmock_arg1; + char IgnoreArg_cmock_arg1; + +} CMOCK_write_sctlr_el2_CALL_INSTANCE; + +typedef struct _CMOCK_barrier_dsync_fence_full_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + +} CMOCK_barrier_dsync_fence_full_CALL_INSTANCE; + +typedef struct _CMOCK_barrier_isync_fence_full_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + char ExpectAnyArgsBool; + +} CMOCK_barrier_isync_fence_full_CALL_INSTANCE; + +static struct Mockarmv8r_mpu_regInstance +{ + char read_mair_el2_IgnoreBool; + uint64_t read_mair_el2_FinalReturn; + char read_mair_el2_CallbackBool; + CMOCK_read_mair_el2_CALLBACK read_mair_el2_CallbackFunctionPointer; + int read_mair_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE read_mair_el2_CallInstance; + char write_mair_el2_IgnoreBool; + char write_mair_el2_CallbackBool; + CMOCK_write_mair_el2_CALLBACK write_mair_el2_CallbackFunctionPointer; + int write_mair_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE write_mair_el2_CallInstance; + char read_mpuir_el2_IgnoreBool; + uint64_t read_mpuir_el2_FinalReturn; + char read_mpuir_el2_CallbackBool; + CMOCK_read_mpuir_el2_CALLBACK read_mpuir_el2_CallbackFunctionPointer; + int read_mpuir_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE read_mpuir_el2_CallInstance; + char write_prbar_el2_IgnoreBool; + char write_prbar_el2_CallbackBool; + CMOCK_write_prbar_el2_CALLBACK write_prbar_el2_CallbackFunctionPointer; + int write_prbar_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE write_prbar_el2_CallInstance; + char write_prlar_el2_IgnoreBool; + char write_prlar_el2_CallbackBool; + CMOCK_write_prlar_el2_CALLBACK write_prlar_el2_CallbackFunctionPointer; + int write_prlar_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE write_prlar_el2_CallInstance; + char write_prselr_el2_IgnoreBool; + char write_prselr_el2_CallbackBool; + CMOCK_write_prselr_el2_CALLBACK write_prselr_el2_CallbackFunctionPointer; + int write_prselr_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE write_prselr_el2_CallInstance; + char read_sctlr_el2_IgnoreBool; + uint64_t read_sctlr_el2_FinalReturn; + char read_sctlr_el2_CallbackBool; + CMOCK_read_sctlr_el2_CALLBACK read_sctlr_el2_CallbackFunctionPointer; + int read_sctlr_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE read_sctlr_el2_CallInstance; + char write_sctlr_el2_IgnoreBool; + char write_sctlr_el2_CallbackBool; + CMOCK_write_sctlr_el2_CALLBACK write_sctlr_el2_CallbackFunctionPointer; + int write_sctlr_el2_CallbackCalls; + CMOCK_MEM_INDEX_TYPE write_sctlr_el2_CallInstance; + char barrier_dsync_fence_full_IgnoreBool; + char barrier_dsync_fence_full_CallbackBool; + CMOCK_barrier_dsync_fence_full_CALLBACK barrier_dsync_fence_full_CallbackFunctionPointer; + int barrier_dsync_fence_full_CallbackCalls; + CMOCK_MEM_INDEX_TYPE barrier_dsync_fence_full_CallInstance; + char barrier_isync_fence_full_IgnoreBool; + char barrier_isync_fence_full_CallbackBool; + CMOCK_barrier_isync_fence_full_CALLBACK barrier_isync_fence_full_CallbackFunctionPointer; + int barrier_isync_fence_full_CallbackCalls; + CMOCK_MEM_INDEX_TYPE barrier_isync_fence_full_CallInstance; +} Mock; + +extern jmp_buf AbortFrame; + +void Mockarmv8r_mpu_reg_Verify(void) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_MEM_INDEX_TYPE call_instance; + call_instance = Mock.read_mair_el2_CallInstance; + if (Mock.read_mair_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_read_mair_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.read_mair_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.write_mair_el2_CallInstance; + if (Mock.write_mair_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_write_mair_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.write_mair_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.read_mpuir_el2_CallInstance; + if (Mock.read_mpuir_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_read_mpuir_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.read_mpuir_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.write_prbar_el2_CallInstance; + if (Mock.write_prbar_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_write_prbar_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.write_prbar_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.write_prlar_el2_CallInstance; + if (Mock.write_prlar_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_write_prlar_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.write_prlar_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.write_prselr_el2_CallInstance; + if (Mock.write_prselr_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_write_prselr_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.write_prselr_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.read_sctlr_el2_CallInstance; + if (Mock.read_sctlr_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_read_sctlr_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.read_sctlr_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.write_sctlr_el2_CallInstance; + if (Mock.write_sctlr_el2_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_write_sctlr_el2); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.write_sctlr_el2_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.barrier_dsync_fence_full_CallInstance; + if (Mock.barrier_dsync_fence_full_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_barrier_dsync_fence_full); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.barrier_dsync_fence_full_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } + call_instance = Mock.barrier_isync_fence_full_CallInstance; + if (Mock.barrier_isync_fence_full_IgnoreBool) + call_instance = CMOCK_GUTS_NONE; + if (CMOCK_GUTS_NONE != call_instance) + { + UNITY_SET_DETAIL(CMockString_barrier_isync_fence_full); + UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess); + } + if (Mock.barrier_isync_fence_full_CallbackFunctionPointer != NULL) + { + call_instance = CMOCK_GUTS_NONE; + (void)call_instance; + } +} + +void Mockarmv8r_mpu_reg_Init(void) +{ + Mockarmv8r_mpu_reg_Destroy(); +} + +void Mockarmv8r_mpu_reg_Destroy(void) +{ + CMock_Guts_MemFreeAll(); + memset(&Mock, 0, sizeof(Mock)); +} + +uint64_t read_mair_el2(void) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_read_mair_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_read_mair_el2); + cmock_call_instance = (CMOCK_read_mair_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.read_mair_el2_CallInstance); + Mock.read_mair_el2_CallInstance = CMock_Guts_MemNext(Mock.read_mair_el2_CallInstance); + if (Mock.read_mair_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + if (cmock_call_instance == NULL) + return Mock.read_mair_el2_FinalReturn; + memcpy((void*)(&Mock.read_mair_el2_FinalReturn), (void*)(&cmock_call_instance->ReturnVal), + sizeof(uint64_t[sizeof(cmock_call_instance->ReturnVal) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + return cmock_call_instance->ReturnVal; + } + if (!Mock.read_mair_el2_CallbackBool && + Mock.read_mair_el2_CallbackFunctionPointer != NULL) + { + uint64_t cmock_cb_ret = Mock.read_mair_el2_CallbackFunctionPointer(Mock.read_mair_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return cmock_cb_ret; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (Mock.read_mair_el2_CallbackFunctionPointer != NULL) + { + cmock_call_instance->ReturnVal = Mock.read_mair_el2_CallbackFunctionPointer(Mock.read_mair_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); + return cmock_call_instance->ReturnVal; +} + +void read_mair_el2_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_read_mair_el2_CALL_INSTANCE)); + CMOCK_read_mair_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_read_mair_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.read_mair_el2_CallInstance = CMock_Guts_MemChain(Mock.read_mair_el2_CallInstance, cmock_guts_index); + Mock.read_mair_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ReturnVal = cmock_to_return; + Mock.read_mair_el2_IgnoreBool = (char)1; +} + +void read_mair_el2_CMockStopIgnore(void) +{ + if(Mock.read_mair_el2_IgnoreBool) + Mock.read_mair_el2_CallInstance = CMock_Guts_MemNext(Mock.read_mair_el2_CallInstance); + Mock.read_mair_el2_IgnoreBool = (char)0; +} + +void read_mair_el2_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_read_mair_el2_CALL_INSTANCE)); + CMOCK_read_mair_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_read_mair_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.read_mair_el2_CallInstance = CMock_Guts_MemChain(Mock.read_mair_el2_CallInstance, cmock_guts_index); + Mock.read_mair_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + memcpy((void*)(&cmock_call_instance->ReturnVal), (void*)(&cmock_to_return), + sizeof(uint64_t[sizeof(cmock_to_return) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ +} + +void read_mair_el2_AddCallback(CMOCK_read_mair_el2_CALLBACK Callback) +{ + Mock.read_mair_el2_IgnoreBool = (char)0; + Mock.read_mair_el2_CallbackBool = (char)1; + Mock.read_mair_el2_CallbackFunctionPointer = Callback; +} + +void read_mair_el2_Stub(CMOCK_read_mair_el2_CALLBACK Callback) +{ + Mock.read_mair_el2_IgnoreBool = (char)0; + Mock.read_mair_el2_CallbackBool = (char)0; + Mock.read_mair_el2_CallbackFunctionPointer = Callback; +} + +void write_mair_el2(uint64_t cmock_arg1) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_write_mair_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_write_mair_el2); + cmock_call_instance = (CMOCK_write_mair_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.write_mair_el2_CallInstance); + Mock.write_mair_el2_CallInstance = CMock_Guts_MemNext(Mock.write_mair_el2_CallInstance); + if (Mock.write_mair_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + return; + } + if (!Mock.write_mair_el2_CallbackBool && + Mock.write_mair_el2_CallbackFunctionPointer != NULL) + { + Mock.write_mair_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_mair_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (!cmock_call_instance->ExpectAnyArgsBool) + { + if (!cmock_call_instance->IgnoreArg_cmock_arg1) + { + UNITY_SET_DETAILS(CMockString_write_mair_el2,CMockString_cmock_arg1); + UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), sizeof(uint64_t), cmock_line, CMockStringMismatch); + } + } + if (Mock.write_mair_el2_CallbackFunctionPointer != NULL) + { + Mock.write_mair_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_mair_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); +} + +void CMockExpectParameters_write_mair_el2(CMOCK_write_mair_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1); +void CMockExpectParameters_write_mair_el2(CMOCK_write_mair_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1) +{ + memcpy((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), + sizeof(uint64_t[sizeof(cmock_arg1) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + cmock_call_instance->IgnoreArg_cmock_arg1 = 0; +} + +void write_mair_el2_CMockIgnore(void) +{ + Mock.write_mair_el2_IgnoreBool = (char)1; +} + +void write_mair_el2_CMockStopIgnore(void) +{ + Mock.write_mair_el2_IgnoreBool = (char)0; +} + +void write_mair_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_mair_el2_CALL_INSTANCE)); + CMOCK_write_mair_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_mair_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_mair_el2_CallInstance = CMock_Guts_MemChain(Mock.write_mair_el2_CallInstance, cmock_guts_index); + Mock.write_mair_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ExpectAnyArgsBool = (char)1; +} + +void write_mair_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_mair_el2_CALL_INSTANCE)); + CMOCK_write_mair_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_mair_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_mair_el2_CallInstance = CMock_Guts_MemChain(Mock.write_mair_el2_CallInstance, cmock_guts_index); + Mock.write_mair_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + CMockExpectParameters_write_mair_el2(cmock_call_instance, cmock_arg1); +} + +void write_mair_el2_AddCallback(CMOCK_write_mair_el2_CALLBACK Callback) +{ + Mock.write_mair_el2_IgnoreBool = (char)0; + Mock.write_mair_el2_CallbackBool = (char)1; + Mock.write_mair_el2_CallbackFunctionPointer = Callback; +} + +void write_mair_el2_Stub(CMOCK_write_mair_el2_CALLBACK Callback) +{ + Mock.write_mair_el2_IgnoreBool = (char)0; + Mock.write_mair_el2_CallbackBool = (char)0; + Mock.write_mair_el2_CallbackFunctionPointer = Callback; +} + +void write_mair_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_write_mair_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_mair_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.write_mair_el2_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_cmock_arg1 = 1; +} + +uint64_t read_mpuir_el2(void) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_read_mpuir_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_read_mpuir_el2); + cmock_call_instance = (CMOCK_read_mpuir_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.read_mpuir_el2_CallInstance); + Mock.read_mpuir_el2_CallInstance = CMock_Guts_MemNext(Mock.read_mpuir_el2_CallInstance); + if (Mock.read_mpuir_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + if (cmock_call_instance == NULL) + return Mock.read_mpuir_el2_FinalReturn; + memcpy((void*)(&Mock.read_mpuir_el2_FinalReturn), (void*)(&cmock_call_instance->ReturnVal), + sizeof(uint64_t[sizeof(cmock_call_instance->ReturnVal) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + return cmock_call_instance->ReturnVal; + } + if (!Mock.read_mpuir_el2_CallbackBool && + Mock.read_mpuir_el2_CallbackFunctionPointer != NULL) + { + uint64_t cmock_cb_ret = Mock.read_mpuir_el2_CallbackFunctionPointer(Mock.read_mpuir_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return cmock_cb_ret; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (Mock.read_mpuir_el2_CallbackFunctionPointer != NULL) + { + cmock_call_instance->ReturnVal = Mock.read_mpuir_el2_CallbackFunctionPointer(Mock.read_mpuir_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); + return cmock_call_instance->ReturnVal; +} + +void read_mpuir_el2_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_read_mpuir_el2_CALL_INSTANCE)); + CMOCK_read_mpuir_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_read_mpuir_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.read_mpuir_el2_CallInstance = CMock_Guts_MemChain(Mock.read_mpuir_el2_CallInstance, cmock_guts_index); + Mock.read_mpuir_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ReturnVal = cmock_to_return; + Mock.read_mpuir_el2_IgnoreBool = (char)1; +} + +void read_mpuir_el2_CMockStopIgnore(void) +{ + if(Mock.read_mpuir_el2_IgnoreBool) + Mock.read_mpuir_el2_CallInstance = CMock_Guts_MemNext(Mock.read_mpuir_el2_CallInstance); + Mock.read_mpuir_el2_IgnoreBool = (char)0; +} + +void read_mpuir_el2_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_read_mpuir_el2_CALL_INSTANCE)); + CMOCK_read_mpuir_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_read_mpuir_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.read_mpuir_el2_CallInstance = CMock_Guts_MemChain(Mock.read_mpuir_el2_CallInstance, cmock_guts_index); + Mock.read_mpuir_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + memcpy((void*)(&cmock_call_instance->ReturnVal), (void*)(&cmock_to_return), + sizeof(uint64_t[sizeof(cmock_to_return) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ +} + +void read_mpuir_el2_AddCallback(CMOCK_read_mpuir_el2_CALLBACK Callback) +{ + Mock.read_mpuir_el2_IgnoreBool = (char)0; + Mock.read_mpuir_el2_CallbackBool = (char)1; + Mock.read_mpuir_el2_CallbackFunctionPointer = Callback; +} + +void read_mpuir_el2_Stub(CMOCK_read_mpuir_el2_CALLBACK Callback) +{ + Mock.read_mpuir_el2_IgnoreBool = (char)0; + Mock.read_mpuir_el2_CallbackBool = (char)0; + Mock.read_mpuir_el2_CallbackFunctionPointer = Callback; +} + +void write_prbar_el2(uint64_t cmock_arg1) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_write_prbar_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_write_prbar_el2); + cmock_call_instance = (CMOCK_write_prbar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.write_prbar_el2_CallInstance); + Mock.write_prbar_el2_CallInstance = CMock_Guts_MemNext(Mock.write_prbar_el2_CallInstance); + if (Mock.write_prbar_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + return; + } + if (!Mock.write_prbar_el2_CallbackBool && + Mock.write_prbar_el2_CallbackFunctionPointer != NULL) + { + Mock.write_prbar_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_prbar_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (!cmock_call_instance->ExpectAnyArgsBool) + { + if (!cmock_call_instance->IgnoreArg_cmock_arg1) + { + UNITY_SET_DETAILS(CMockString_write_prbar_el2,CMockString_cmock_arg1); + UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), sizeof(uint64_t), cmock_line, CMockStringMismatch); + } + } + if (Mock.write_prbar_el2_CallbackFunctionPointer != NULL) + { + Mock.write_prbar_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_prbar_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); +} + +void CMockExpectParameters_write_prbar_el2(CMOCK_write_prbar_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1); +void CMockExpectParameters_write_prbar_el2(CMOCK_write_prbar_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1) +{ + memcpy((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), + sizeof(uint64_t[sizeof(cmock_arg1) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + cmock_call_instance->IgnoreArg_cmock_arg1 = 0; +} + +void write_prbar_el2_CMockIgnore(void) +{ + Mock.write_prbar_el2_IgnoreBool = (char)1; +} + +void write_prbar_el2_CMockStopIgnore(void) +{ + Mock.write_prbar_el2_IgnoreBool = (char)0; +} + +void write_prbar_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_prbar_el2_CALL_INSTANCE)); + CMOCK_write_prbar_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prbar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_prbar_el2_CallInstance = CMock_Guts_MemChain(Mock.write_prbar_el2_CallInstance, cmock_guts_index); + Mock.write_prbar_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ExpectAnyArgsBool = (char)1; +} + +void write_prbar_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_prbar_el2_CALL_INSTANCE)); + CMOCK_write_prbar_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prbar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_prbar_el2_CallInstance = CMock_Guts_MemChain(Mock.write_prbar_el2_CallInstance, cmock_guts_index); + Mock.write_prbar_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + CMockExpectParameters_write_prbar_el2(cmock_call_instance, cmock_arg1); +} + +void write_prbar_el2_AddCallback(CMOCK_write_prbar_el2_CALLBACK Callback) +{ + Mock.write_prbar_el2_IgnoreBool = (char)0; + Mock.write_prbar_el2_CallbackBool = (char)1; + Mock.write_prbar_el2_CallbackFunctionPointer = Callback; +} + +void write_prbar_el2_Stub(CMOCK_write_prbar_el2_CALLBACK Callback) +{ + Mock.write_prbar_el2_IgnoreBool = (char)0; + Mock.write_prbar_el2_CallbackBool = (char)0; + Mock.write_prbar_el2_CallbackFunctionPointer = Callback; +} + +void write_prbar_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_write_prbar_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prbar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.write_prbar_el2_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_cmock_arg1 = 1; +} + +void write_prlar_el2(uint64_t cmock_arg1) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_write_prlar_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_write_prlar_el2); + cmock_call_instance = (CMOCK_write_prlar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.write_prlar_el2_CallInstance); + Mock.write_prlar_el2_CallInstance = CMock_Guts_MemNext(Mock.write_prlar_el2_CallInstance); + if (Mock.write_prlar_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + return; + } + if (!Mock.write_prlar_el2_CallbackBool && + Mock.write_prlar_el2_CallbackFunctionPointer != NULL) + { + Mock.write_prlar_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_prlar_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (!cmock_call_instance->ExpectAnyArgsBool) + { + if (!cmock_call_instance->IgnoreArg_cmock_arg1) + { + UNITY_SET_DETAILS(CMockString_write_prlar_el2,CMockString_cmock_arg1); + UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), sizeof(uint64_t), cmock_line, CMockStringMismatch); + } + } + if (Mock.write_prlar_el2_CallbackFunctionPointer != NULL) + { + Mock.write_prlar_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_prlar_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); +} + +void CMockExpectParameters_write_prlar_el2(CMOCK_write_prlar_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1); +void CMockExpectParameters_write_prlar_el2(CMOCK_write_prlar_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1) +{ + memcpy((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), + sizeof(uint64_t[sizeof(cmock_arg1) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + cmock_call_instance->IgnoreArg_cmock_arg1 = 0; +} + +void write_prlar_el2_CMockIgnore(void) +{ + Mock.write_prlar_el2_IgnoreBool = (char)1; +} + +void write_prlar_el2_CMockStopIgnore(void) +{ + Mock.write_prlar_el2_IgnoreBool = (char)0; +} + +void write_prlar_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_prlar_el2_CALL_INSTANCE)); + CMOCK_write_prlar_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prlar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_prlar_el2_CallInstance = CMock_Guts_MemChain(Mock.write_prlar_el2_CallInstance, cmock_guts_index); + Mock.write_prlar_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ExpectAnyArgsBool = (char)1; +} + +void write_prlar_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_prlar_el2_CALL_INSTANCE)); + CMOCK_write_prlar_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prlar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_prlar_el2_CallInstance = CMock_Guts_MemChain(Mock.write_prlar_el2_CallInstance, cmock_guts_index); + Mock.write_prlar_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + CMockExpectParameters_write_prlar_el2(cmock_call_instance, cmock_arg1); +} + +void write_prlar_el2_AddCallback(CMOCK_write_prlar_el2_CALLBACK Callback) +{ + Mock.write_prlar_el2_IgnoreBool = (char)0; + Mock.write_prlar_el2_CallbackBool = (char)1; + Mock.write_prlar_el2_CallbackFunctionPointer = Callback; +} + +void write_prlar_el2_Stub(CMOCK_write_prlar_el2_CALLBACK Callback) +{ + Mock.write_prlar_el2_IgnoreBool = (char)0; + Mock.write_prlar_el2_CallbackBool = (char)0; + Mock.write_prlar_el2_CallbackFunctionPointer = Callback; +} + +void write_prlar_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_write_prlar_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prlar_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.write_prlar_el2_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_cmock_arg1 = 1; +} + +void write_prselr_el2(uint64_t cmock_arg1) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_write_prselr_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_write_prselr_el2); + cmock_call_instance = (CMOCK_write_prselr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.write_prselr_el2_CallInstance); + Mock.write_prselr_el2_CallInstance = CMock_Guts_MemNext(Mock.write_prselr_el2_CallInstance); + if (Mock.write_prselr_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + return; + } + if (!Mock.write_prselr_el2_CallbackBool && + Mock.write_prselr_el2_CallbackFunctionPointer != NULL) + { + Mock.write_prselr_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_prselr_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (!cmock_call_instance->ExpectAnyArgsBool) + { + if (!cmock_call_instance->IgnoreArg_cmock_arg1) + { + UNITY_SET_DETAILS(CMockString_write_prselr_el2,CMockString_cmock_arg1); + UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), sizeof(uint64_t), cmock_line, CMockStringMismatch); + } + } + if (Mock.write_prselr_el2_CallbackFunctionPointer != NULL) + { + Mock.write_prselr_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_prselr_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); +} + +void CMockExpectParameters_write_prselr_el2(CMOCK_write_prselr_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1); +void CMockExpectParameters_write_prselr_el2(CMOCK_write_prselr_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1) +{ + memcpy((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), + sizeof(uint64_t[sizeof(cmock_arg1) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + cmock_call_instance->IgnoreArg_cmock_arg1 = 0; +} + +void write_prselr_el2_CMockIgnore(void) +{ + Mock.write_prselr_el2_IgnoreBool = (char)1; +} + +void write_prselr_el2_CMockStopIgnore(void) +{ + Mock.write_prselr_el2_IgnoreBool = (char)0; +} + +void write_prselr_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_prselr_el2_CALL_INSTANCE)); + CMOCK_write_prselr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prselr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_prselr_el2_CallInstance = CMock_Guts_MemChain(Mock.write_prselr_el2_CallInstance, cmock_guts_index); + Mock.write_prselr_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ExpectAnyArgsBool = (char)1; +} + +void write_prselr_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_prselr_el2_CALL_INSTANCE)); + CMOCK_write_prselr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prselr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_prselr_el2_CallInstance = CMock_Guts_MemChain(Mock.write_prselr_el2_CallInstance, cmock_guts_index); + Mock.write_prselr_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + CMockExpectParameters_write_prselr_el2(cmock_call_instance, cmock_arg1); +} + +void write_prselr_el2_AddCallback(CMOCK_write_prselr_el2_CALLBACK Callback) +{ + Mock.write_prselr_el2_IgnoreBool = (char)0; + Mock.write_prselr_el2_CallbackBool = (char)1; + Mock.write_prselr_el2_CallbackFunctionPointer = Callback; +} + +void write_prselr_el2_Stub(CMOCK_write_prselr_el2_CALLBACK Callback) +{ + Mock.write_prselr_el2_IgnoreBool = (char)0; + Mock.write_prselr_el2_CallbackBool = (char)0; + Mock.write_prselr_el2_CallbackFunctionPointer = Callback; +} + +void write_prselr_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_write_prselr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_prselr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.write_prselr_el2_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_cmock_arg1 = 1; +} + +uint64_t read_sctlr_el2(void) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_read_sctlr_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_read_sctlr_el2); + cmock_call_instance = (CMOCK_read_sctlr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.read_sctlr_el2_CallInstance); + Mock.read_sctlr_el2_CallInstance = CMock_Guts_MemNext(Mock.read_sctlr_el2_CallInstance); + if (Mock.read_sctlr_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + if (cmock_call_instance == NULL) + return Mock.read_sctlr_el2_FinalReturn; + memcpy((void*)(&Mock.read_sctlr_el2_FinalReturn), (void*)(&cmock_call_instance->ReturnVal), + sizeof(uint64_t[sizeof(cmock_call_instance->ReturnVal) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + return cmock_call_instance->ReturnVal; + } + if (!Mock.read_sctlr_el2_CallbackBool && + Mock.read_sctlr_el2_CallbackFunctionPointer != NULL) + { + uint64_t cmock_cb_ret = Mock.read_sctlr_el2_CallbackFunctionPointer(Mock.read_sctlr_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return cmock_cb_ret; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (Mock.read_sctlr_el2_CallbackFunctionPointer != NULL) + { + cmock_call_instance->ReturnVal = Mock.read_sctlr_el2_CallbackFunctionPointer(Mock.read_sctlr_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); + return cmock_call_instance->ReturnVal; +} + +void read_sctlr_el2_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_read_sctlr_el2_CALL_INSTANCE)); + CMOCK_read_sctlr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_read_sctlr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.read_sctlr_el2_CallInstance = CMock_Guts_MemChain(Mock.read_sctlr_el2_CallInstance, cmock_guts_index); + Mock.read_sctlr_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ReturnVal = cmock_to_return; + Mock.read_sctlr_el2_IgnoreBool = (char)1; +} + +void read_sctlr_el2_CMockStopIgnore(void) +{ + if(Mock.read_sctlr_el2_IgnoreBool) + Mock.read_sctlr_el2_CallInstance = CMock_Guts_MemNext(Mock.read_sctlr_el2_CallInstance); + Mock.read_sctlr_el2_IgnoreBool = (char)0; +} + +void read_sctlr_el2_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_read_sctlr_el2_CALL_INSTANCE)); + CMOCK_read_sctlr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_read_sctlr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.read_sctlr_el2_CallInstance = CMock_Guts_MemChain(Mock.read_sctlr_el2_CallInstance, cmock_guts_index); + Mock.read_sctlr_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + memcpy((void*)(&cmock_call_instance->ReturnVal), (void*)(&cmock_to_return), + sizeof(uint64_t[sizeof(cmock_to_return) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ +} + +void read_sctlr_el2_AddCallback(CMOCK_read_sctlr_el2_CALLBACK Callback) +{ + Mock.read_sctlr_el2_IgnoreBool = (char)0; + Mock.read_sctlr_el2_CallbackBool = (char)1; + Mock.read_sctlr_el2_CallbackFunctionPointer = Callback; +} + +void read_sctlr_el2_Stub(CMOCK_read_sctlr_el2_CALLBACK Callback) +{ + Mock.read_sctlr_el2_IgnoreBool = (char)0; + Mock.read_sctlr_el2_CallbackBool = (char)0; + Mock.read_sctlr_el2_CallbackFunctionPointer = Callback; +} + +void write_sctlr_el2(uint64_t cmock_arg1) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_write_sctlr_el2_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_write_sctlr_el2); + cmock_call_instance = (CMOCK_write_sctlr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.write_sctlr_el2_CallInstance); + Mock.write_sctlr_el2_CallInstance = CMock_Guts_MemNext(Mock.write_sctlr_el2_CallInstance); + if (Mock.write_sctlr_el2_IgnoreBool) + { + UNITY_CLR_DETAILS(); + return; + } + if (!Mock.write_sctlr_el2_CallbackBool && + Mock.write_sctlr_el2_CallbackFunctionPointer != NULL) + { + Mock.write_sctlr_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_sctlr_el2_CallbackCalls++); + UNITY_CLR_DETAILS(); + return; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (!cmock_call_instance->ExpectAnyArgsBool) + { + if (!cmock_call_instance->IgnoreArg_cmock_arg1) + { + UNITY_SET_DETAILS(CMockString_write_sctlr_el2,CMockString_cmock_arg1); + UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), sizeof(uint64_t), cmock_line, CMockStringMismatch); + } + } + if (Mock.write_sctlr_el2_CallbackFunctionPointer != NULL) + { + Mock.write_sctlr_el2_CallbackFunctionPointer(cmock_arg1, Mock.write_sctlr_el2_CallbackCalls++); + } + UNITY_CLR_DETAILS(); +} + +void CMockExpectParameters_write_sctlr_el2(CMOCK_write_sctlr_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1); +void CMockExpectParameters_write_sctlr_el2(CMOCK_write_sctlr_el2_CALL_INSTANCE* cmock_call_instance, uint64_t cmock_arg1) +{ + memcpy((void*)(&cmock_call_instance->Expected_cmock_arg1), (void*)(&cmock_arg1), + sizeof(uint64_t[sizeof(cmock_arg1) == sizeof(uint64_t) ? 1 : -1])); /* add uint64_t to :treat_as_array if this causes an error */ + cmock_call_instance->IgnoreArg_cmock_arg1 = 0; +} + +void write_sctlr_el2_CMockIgnore(void) +{ + Mock.write_sctlr_el2_IgnoreBool = (char)1; +} + +void write_sctlr_el2_CMockStopIgnore(void) +{ + Mock.write_sctlr_el2_IgnoreBool = (char)0; +} + +void write_sctlr_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_sctlr_el2_CALL_INSTANCE)); + CMOCK_write_sctlr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_sctlr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_sctlr_el2_CallInstance = CMock_Guts_MemChain(Mock.write_sctlr_el2_CallInstance, cmock_guts_index); + Mock.write_sctlr_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + cmock_call_instance->ExpectAnyArgsBool = (char)1; +} + +void write_sctlr_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_write_sctlr_el2_CALL_INSTANCE)); + CMOCK_write_sctlr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_sctlr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.write_sctlr_el2_CallInstance = CMock_Guts_MemChain(Mock.write_sctlr_el2_CallInstance, cmock_guts_index); + Mock.write_sctlr_el2_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; + CMockExpectParameters_write_sctlr_el2(cmock_call_instance, cmock_arg1); +} + +void write_sctlr_el2_AddCallback(CMOCK_write_sctlr_el2_CALLBACK Callback) +{ + Mock.write_sctlr_el2_IgnoreBool = (char)0; + Mock.write_sctlr_el2_CallbackBool = (char)1; + Mock.write_sctlr_el2_CallbackFunctionPointer = Callback; +} + +void write_sctlr_el2_Stub(CMOCK_write_sctlr_el2_CALLBACK Callback) +{ + Mock.write_sctlr_el2_IgnoreBool = (char)0; + Mock.write_sctlr_el2_CallbackBool = (char)0; + Mock.write_sctlr_el2_CallbackFunctionPointer = Callback; +} + +void write_sctlr_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_write_sctlr_el2_CALL_INSTANCE* cmock_call_instance = (CMOCK_write_sctlr_el2_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.write_sctlr_el2_CallInstance)); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp); + cmock_call_instance->IgnoreArg_cmock_arg1 = 1; +} + +void barrier_dsync_fence_full(void) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_barrier_dsync_fence_full_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_barrier_dsync_fence_full); + cmock_call_instance = (CMOCK_barrier_dsync_fence_full_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.barrier_dsync_fence_full_CallInstance); + Mock.barrier_dsync_fence_full_CallInstance = CMock_Guts_MemNext(Mock.barrier_dsync_fence_full_CallInstance); + if (Mock.barrier_dsync_fence_full_IgnoreBool) + { + UNITY_CLR_DETAILS(); + return; + } + if (!Mock.barrier_dsync_fence_full_CallbackBool && + Mock.barrier_dsync_fence_full_CallbackFunctionPointer != NULL) + { + Mock.barrier_dsync_fence_full_CallbackFunctionPointer(Mock.barrier_dsync_fence_full_CallbackCalls++); + UNITY_CLR_DETAILS(); + return; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (Mock.barrier_dsync_fence_full_CallbackFunctionPointer != NULL) + { + Mock.barrier_dsync_fence_full_CallbackFunctionPointer(Mock.barrier_dsync_fence_full_CallbackCalls++); + } + UNITY_CLR_DETAILS(); +} + +void barrier_dsync_fence_full_CMockIgnore(void) +{ + Mock.barrier_dsync_fence_full_IgnoreBool = (char)1; +} + +void barrier_dsync_fence_full_CMockStopIgnore(void) +{ + Mock.barrier_dsync_fence_full_IgnoreBool = (char)0; +} + +void barrier_dsync_fence_full_CMockExpect(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_barrier_dsync_fence_full_CALL_INSTANCE)); + CMOCK_barrier_dsync_fence_full_CALL_INSTANCE* cmock_call_instance = (CMOCK_barrier_dsync_fence_full_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.barrier_dsync_fence_full_CallInstance = CMock_Guts_MemChain(Mock.barrier_dsync_fence_full_CallInstance, cmock_guts_index); + Mock.barrier_dsync_fence_full_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; +} + +void barrier_dsync_fence_full_AddCallback(CMOCK_barrier_dsync_fence_full_CALLBACK Callback) +{ + Mock.barrier_dsync_fence_full_IgnoreBool = (char)0; + Mock.barrier_dsync_fence_full_CallbackBool = (char)1; + Mock.barrier_dsync_fence_full_CallbackFunctionPointer = Callback; +} + +void barrier_dsync_fence_full_Stub(CMOCK_barrier_dsync_fence_full_CALLBACK Callback) +{ + Mock.barrier_dsync_fence_full_IgnoreBool = (char)0; + Mock.barrier_dsync_fence_full_CallbackBool = (char)0; + Mock.barrier_dsync_fence_full_CallbackFunctionPointer = Callback; +} + +void barrier_isync_fence_full(void) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_barrier_isync_fence_full_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_barrier_isync_fence_full); + cmock_call_instance = (CMOCK_barrier_isync_fence_full_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.barrier_isync_fence_full_CallInstance); + Mock.barrier_isync_fence_full_CallInstance = CMock_Guts_MemNext(Mock.barrier_isync_fence_full_CallInstance); + if (Mock.barrier_isync_fence_full_IgnoreBool) + { + UNITY_CLR_DETAILS(); + return; + } + if (!Mock.barrier_isync_fence_full_CallbackBool && + Mock.barrier_isync_fence_full_CallbackFunctionPointer != NULL) + { + Mock.barrier_isync_fence_full_CallbackFunctionPointer(Mock.barrier_isync_fence_full_CallbackCalls++); + UNITY_CLR_DETAILS(); + return; + } + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + if (Mock.barrier_isync_fence_full_CallbackFunctionPointer != NULL) + { + Mock.barrier_isync_fence_full_CallbackFunctionPointer(Mock.barrier_isync_fence_full_CallbackCalls++); + } + UNITY_CLR_DETAILS(); +} + +void barrier_isync_fence_full_CMockIgnore(void) +{ + Mock.barrier_isync_fence_full_IgnoreBool = (char)1; +} + +void barrier_isync_fence_full_CMockStopIgnore(void) +{ + Mock.barrier_isync_fence_full_IgnoreBool = (char)0; +} + +void barrier_isync_fence_full_CMockExpect(UNITY_LINE_TYPE cmock_line) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_barrier_isync_fence_full_CALL_INSTANCE)); + CMOCK_barrier_isync_fence_full_CALL_INSTANCE* cmock_call_instance = (CMOCK_barrier_isync_fence_full_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.barrier_isync_fence_full_CallInstance = CMock_Guts_MemChain(Mock.barrier_isync_fence_full_CallInstance, cmock_guts_index); + Mock.barrier_isync_fence_full_IgnoreBool = (char)0; + cmock_call_instance->LineNumber = cmock_line; + cmock_call_instance->ExpectAnyArgsBool = (char)0; +} + +void barrier_isync_fence_full_AddCallback(CMOCK_barrier_isync_fence_full_CALLBACK Callback) +{ + Mock.barrier_isync_fence_full_IgnoreBool = (char)0; + Mock.barrier_isync_fence_full_CallbackBool = (char)1; + Mock.barrier_isync_fence_full_CallbackFunctionPointer = Callback; +} + +void barrier_isync_fence_full_Stub(CMOCK_barrier_isync_fence_full_CALLBACK Callback) +{ + Mock.barrier_isync_fence_full_IgnoreBool = (char)0; + Mock.barrier_isync_fence_full_CallbackBool = (char)0; + Mock.barrier_isync_fence_full_CallbackFunctionPointer = Callback; +} + diff --git a/module/armv8r_mpu/test/mocks/Mockarmv8r_mpu_reg.h b/module/armv8r_mpu/test/mocks/Mockarmv8r_mpu_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..ace1babb7421e21b9ba06033e3ffaea5591b76fb --- /dev/null +++ b/module/armv8r_mpu/test/mocks/Mockarmv8r_mpu_reg.h @@ -0,0 +1,154 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#ifndef _MOCKARMV8R_MPU_REG_H +#define _MOCKARMV8R_MPU_REG_H + +#include "unity.h" +#include "armv8r_mpu_reg.h" + +/* Ignore the following warnings, since we are copying code */ +#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) +#pragma GCC diagnostic push +#endif +#if !defined(__clang__) +#pragma GCC diagnostic ignored "-Wpragmas" +#endif +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wduplicate-decl-specifier" +#endif + +void Mockarmv8r_mpu_reg_Init(void); +void Mockarmv8r_mpu_reg_Destroy(void); +void Mockarmv8r_mpu_reg_Verify(void); + + + + +#define read_mair_el2_IgnoreAndReturn(cmock_retval) read_mair_el2_CMockIgnoreAndReturn(__LINE__, cmock_retval) +void read_mair_el2_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return); +#define read_mair_el2_StopIgnore() read_mair_el2_CMockStopIgnore() +void read_mair_el2_CMockStopIgnore(void); +#define read_mair_el2_ExpectAndReturn(cmock_retval) read_mair_el2_CMockExpectAndReturn(__LINE__, cmock_retval) +void read_mair_el2_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return); +typedef uint64_t (* CMOCK_read_mair_el2_CALLBACK)(int cmock_num_calls); +void read_mair_el2_AddCallback(CMOCK_read_mair_el2_CALLBACK Callback); +void read_mair_el2_Stub(CMOCK_read_mair_el2_CALLBACK Callback); +#define read_mair_el2_StubWithCallback read_mair_el2_Stub +#define write_mair_el2_Ignore() write_mair_el2_CMockIgnore() +void write_mair_el2_CMockIgnore(void); +#define write_mair_el2_StopIgnore() write_mair_el2_CMockStopIgnore() +void write_mair_el2_CMockStopIgnore(void); +#define write_mair_el2_ExpectAnyArgs() write_mair_el2_CMockExpectAnyArgs(__LINE__) +void write_mair_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line); +#define write_mair_el2_Expect(cmock_arg1) write_mair_el2_CMockExpect(__LINE__, cmock_arg1) +void write_mair_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1); +typedef void (* CMOCK_write_mair_el2_CALLBACK)(uint64_t cmock_arg1, int cmock_num_calls); +void write_mair_el2_AddCallback(CMOCK_write_mair_el2_CALLBACK Callback); +void write_mair_el2_Stub(CMOCK_write_mair_el2_CALLBACK Callback); +#define write_mair_el2_StubWithCallback write_mair_el2_Stub +#define write_mair_el2_IgnoreArg_cmock_arg1() write_mair_el2_CMockIgnoreArg_cmock_arg1(__LINE__) +void write_mair_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line); +#define read_mpuir_el2_IgnoreAndReturn(cmock_retval) read_mpuir_el2_CMockIgnoreAndReturn(__LINE__, cmock_retval) +void read_mpuir_el2_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return); +#define read_mpuir_el2_StopIgnore() read_mpuir_el2_CMockStopIgnore() +void read_mpuir_el2_CMockStopIgnore(void); +#define read_mpuir_el2_ExpectAndReturn(cmock_retval) read_mpuir_el2_CMockExpectAndReturn(__LINE__, cmock_retval) +void read_mpuir_el2_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return); +typedef uint64_t (* CMOCK_read_mpuir_el2_CALLBACK)(int cmock_num_calls); +void read_mpuir_el2_AddCallback(CMOCK_read_mpuir_el2_CALLBACK Callback); +void read_mpuir_el2_Stub(CMOCK_read_mpuir_el2_CALLBACK Callback); +#define read_mpuir_el2_StubWithCallback read_mpuir_el2_Stub +#define write_prbar_el2_Ignore() write_prbar_el2_CMockIgnore() +void write_prbar_el2_CMockIgnore(void); +#define write_prbar_el2_StopIgnore() write_prbar_el2_CMockStopIgnore() +void write_prbar_el2_CMockStopIgnore(void); +#define write_prbar_el2_ExpectAnyArgs() write_prbar_el2_CMockExpectAnyArgs(__LINE__) +void write_prbar_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line); +#define write_prbar_el2_Expect(cmock_arg1) write_prbar_el2_CMockExpect(__LINE__, cmock_arg1) +void write_prbar_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1); +typedef void (* CMOCK_write_prbar_el2_CALLBACK)(uint64_t cmock_arg1, int cmock_num_calls); +void write_prbar_el2_AddCallback(CMOCK_write_prbar_el2_CALLBACK Callback); +void write_prbar_el2_Stub(CMOCK_write_prbar_el2_CALLBACK Callback); +#define write_prbar_el2_StubWithCallback write_prbar_el2_Stub +#define write_prbar_el2_IgnoreArg_cmock_arg1() write_prbar_el2_CMockIgnoreArg_cmock_arg1(__LINE__) +void write_prbar_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line); +#define write_prlar_el2_Ignore() write_prlar_el2_CMockIgnore() +void write_prlar_el2_CMockIgnore(void); +#define write_prlar_el2_StopIgnore() write_prlar_el2_CMockStopIgnore() +void write_prlar_el2_CMockStopIgnore(void); +#define write_prlar_el2_ExpectAnyArgs() write_prlar_el2_CMockExpectAnyArgs(__LINE__) +void write_prlar_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line); +#define write_prlar_el2_Expect(cmock_arg1) write_prlar_el2_CMockExpect(__LINE__, cmock_arg1) +void write_prlar_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1); +typedef void (* CMOCK_write_prlar_el2_CALLBACK)(uint64_t cmock_arg1, int cmock_num_calls); +void write_prlar_el2_AddCallback(CMOCK_write_prlar_el2_CALLBACK Callback); +void write_prlar_el2_Stub(CMOCK_write_prlar_el2_CALLBACK Callback); +#define write_prlar_el2_StubWithCallback write_prlar_el2_Stub +#define write_prlar_el2_IgnoreArg_cmock_arg1() write_prlar_el2_CMockIgnoreArg_cmock_arg1(__LINE__) +void write_prlar_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line); +#define write_prselr_el2_Ignore() write_prselr_el2_CMockIgnore() +void write_prselr_el2_CMockIgnore(void); +#define write_prselr_el2_StopIgnore() write_prselr_el2_CMockStopIgnore() +void write_prselr_el2_CMockStopIgnore(void); +#define write_prselr_el2_ExpectAnyArgs() write_prselr_el2_CMockExpectAnyArgs(__LINE__) +void write_prselr_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line); +#define write_prselr_el2_Expect(cmock_arg1) write_prselr_el2_CMockExpect(__LINE__, cmock_arg1) +void write_prselr_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1); +typedef void (* CMOCK_write_prselr_el2_CALLBACK)(uint64_t cmock_arg1, int cmock_num_calls); +void write_prselr_el2_AddCallback(CMOCK_write_prselr_el2_CALLBACK Callback); +void write_prselr_el2_Stub(CMOCK_write_prselr_el2_CALLBACK Callback); +#define write_prselr_el2_StubWithCallback write_prselr_el2_Stub +#define write_prselr_el2_IgnoreArg_cmock_arg1() write_prselr_el2_CMockIgnoreArg_cmock_arg1(__LINE__) +void write_prselr_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line); +#define read_sctlr_el2_IgnoreAndReturn(cmock_retval) read_sctlr_el2_CMockIgnoreAndReturn(__LINE__, cmock_retval) +void read_sctlr_el2_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return); +#define read_sctlr_el2_StopIgnore() read_sctlr_el2_CMockStopIgnore() +void read_sctlr_el2_CMockStopIgnore(void); +#define read_sctlr_el2_ExpectAndReturn(cmock_retval) read_sctlr_el2_CMockExpectAndReturn(__LINE__, cmock_retval) +void read_sctlr_el2_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint64_t cmock_to_return); +typedef uint64_t (* CMOCK_read_sctlr_el2_CALLBACK)(int cmock_num_calls); +void read_sctlr_el2_AddCallback(CMOCK_read_sctlr_el2_CALLBACK Callback); +void read_sctlr_el2_Stub(CMOCK_read_sctlr_el2_CALLBACK Callback); +#define read_sctlr_el2_StubWithCallback read_sctlr_el2_Stub +#define write_sctlr_el2_Ignore() write_sctlr_el2_CMockIgnore() +void write_sctlr_el2_CMockIgnore(void); +#define write_sctlr_el2_StopIgnore() write_sctlr_el2_CMockStopIgnore() +void write_sctlr_el2_CMockStopIgnore(void); +#define write_sctlr_el2_ExpectAnyArgs() write_sctlr_el2_CMockExpectAnyArgs(__LINE__) +void write_sctlr_el2_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line); +#define write_sctlr_el2_Expect(cmock_arg1) write_sctlr_el2_CMockExpect(__LINE__, cmock_arg1) +void write_sctlr_el2_CMockExpect(UNITY_LINE_TYPE cmock_line, uint64_t cmock_arg1); +typedef void (* CMOCK_write_sctlr_el2_CALLBACK)(uint64_t cmock_arg1, int cmock_num_calls); +void write_sctlr_el2_AddCallback(CMOCK_write_sctlr_el2_CALLBACK Callback); +void write_sctlr_el2_Stub(CMOCK_write_sctlr_el2_CALLBACK Callback); +#define write_sctlr_el2_StubWithCallback write_sctlr_el2_Stub +#define write_sctlr_el2_IgnoreArg_cmock_arg1() write_sctlr_el2_CMockIgnoreArg_cmock_arg1(__LINE__) +void write_sctlr_el2_CMockIgnoreArg_cmock_arg1(UNITY_LINE_TYPE cmock_line); +#define barrier_dsync_fence_full_Ignore() barrier_dsync_fence_full_CMockIgnore() +void barrier_dsync_fence_full_CMockIgnore(void); +#define barrier_dsync_fence_full_StopIgnore() barrier_dsync_fence_full_CMockStopIgnore() +void barrier_dsync_fence_full_CMockStopIgnore(void); +#define barrier_dsync_fence_full_Expect() barrier_dsync_fence_full_CMockExpect(__LINE__) +void barrier_dsync_fence_full_CMockExpect(UNITY_LINE_TYPE cmock_line); +typedef void (* CMOCK_barrier_dsync_fence_full_CALLBACK)(int cmock_num_calls); +void barrier_dsync_fence_full_AddCallback(CMOCK_barrier_dsync_fence_full_CALLBACK Callback); +void barrier_dsync_fence_full_Stub(CMOCK_barrier_dsync_fence_full_CALLBACK Callback); +#define barrier_dsync_fence_full_StubWithCallback barrier_dsync_fence_full_Stub +#define barrier_isync_fence_full_Ignore() barrier_isync_fence_full_CMockIgnore() +void barrier_isync_fence_full_CMockIgnore(void); +#define barrier_isync_fence_full_StopIgnore() barrier_isync_fence_full_CMockStopIgnore() +void barrier_isync_fence_full_CMockStopIgnore(void); +#define barrier_isync_fence_full_Expect() barrier_isync_fence_full_CMockExpect(__LINE__) +void barrier_isync_fence_full_CMockExpect(UNITY_LINE_TYPE cmock_line); +typedef void (* CMOCK_barrier_isync_fence_full_CALLBACK)(int cmock_num_calls); +void barrier_isync_fence_full_AddCallback(CMOCK_barrier_isync_fence_full_CALLBACK Callback); +void barrier_isync_fence_full_Stub(CMOCK_barrier_isync_fence_full_CALLBACK Callback); +#define barrier_isync_fence_full_StubWithCallback barrier_isync_fence_full_Stub + +#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) +#pragma GCC diagnostic pop +#endif +#endif + +#endif diff --git a/module/armv8r_mpu/test/mod_armv8r_mpu_unit_test.c b/module/armv8r_mpu/test/mod_armv8r_mpu_unit_test.c new file mode 100644 index 0000000000000000000000000000000000000000..b1ad687bb0684324348e564df78753ab29545891 --- /dev/null +++ b/module/armv8r_mpu/test/mod_armv8r_mpu_unit_test.c @@ -0,0 +1,122 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_unity.h" +#include "unity.h" + +#include +#include +#include + +#include UNIT_TEST_SRC + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_mod_armv8r_mpu_insufficient_attributes(void) +{ + fwk_id_t id; + int status; + + static uint8_t mem_attributes[] = { + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, + }; + + const struct fwk_module_config config_armv8r_mpu_max_regions = { + .data = &((struct mod_armv8r_mpu_config){ + .attributes_count = FWK_ARRAY_SIZE(mem_attributes), + .attributes = mem_attributes, + .region_count = 0, + .regions = NULL, + }), + }; + + status = armv8r_mpu_init(id, 0, config_armv8r_mpu_max_regions.data); + TEST_ASSERT_EQUAL(status, FWK_E_RANGE); +} + +void test_mod_armv8r_mpu_insufficient_regions(void) +{ + fwk_id_t id; + int status; + + read_mpuir_el2_ExpectAndReturn(1); + + status = armv8r_mpu_init(id, 0, config_armv8r_mpu_ut.data); + TEST_ASSERT_EQUAL(status, FWK_E_RANGE); +} + +void test_mod_armv8r_mpu_init(void) +{ + fwk_id_t id; + int status; + uint8_t index; + + barrier_dsync_fence_full_Ignore(); + barrier_isync_fence_full_Ignore(); + + /* MPU region count check */ + read_mpuir_el2_ExpectAndReturn(32); + + /* Disable MPU */ + read_sctlr_el2_ExpectAndReturn(0x0); + write_sctlr_el2_Expect(0x0); + + /* Set up memory attributes */ + read_mair_el2_ExpectAndReturn(0x0); + write_mair_el2_Expect(0xff); + read_mair_el2_ExpectAndReturn(0xff); + write_mair_el2_Expect(0xff); + + /* Set up region 0 */ + write_prselr_el2_Expect(0x0); + write_prbar_el2_Expect(0x0); + write_prlar_el2_Expect(0x7fffffC1); + + /* Set up region 1 */ + write_prselr_el2_Expect(0x1); + write_prbar_el2_Expect(0x80000000); + write_prlar_el2_Expect(0xffffffC3); + + /* Clear remaining regions */ + for (index = 2; index < 32; index++) { + write_prselr_el2_Expect(index); + write_prbar_el2_Expect(0); + write_prlar_el2_Expect(0); + } + + /* Enable MPU */ + read_sctlr_el2_ExpectAndReturn(0x0); + write_sctlr_el2_Expect(0x1); + + status = armv8r_mpu_init(id, 0, config_armv8r_mpu_ut.data); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + barrier_dsync_fence_full_StopIgnore(); + barrier_isync_fence_full_StopIgnore(); +} + +int template_test_main(void) +{ + UNITY_BEGIN(); + RUN_TEST(test_mod_armv8r_mpu_insufficient_attributes); + RUN_TEST(test_mod_armv8r_mpu_insufficient_regions); + RUN_TEST(test_mod_armv8r_mpu_init); + return UNITY_END(); +} + +#if !defined(TEST_ON_TARGET) +int main(void) +{ + return template_test_main(); +} +#endif diff --git a/product/fvp-baser-aemv8r/fw/CMakeLists.txt b/product/fvp-baser-aemv8r/fw/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c79ff32d408be46dcba9ed4fcc9aab7055dd6202 --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +add_executable(fvp-baser-aemv8r) + +target_include_directories(fvp-baser-aemv8r PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") +target_sources(fvp-baser-aemv8r PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_armv8r_mpu.c" + ) diff --git a/product/fvp-baser-aemv8r/fw/Firmware.cmake b/product/fvp-baser-aemv8r/fw/Firmware.cmake new file mode 100644 index 0000000000000000000000000000000000000000..7fa43d1643d75ce70fc45a29e529615075c7a794 --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/Firmware.cmake @@ -0,0 +1,20 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_FIRMWARE "fvp-baser-aemv8r") +set(SCP_FIRMWARE_TARGET "fvp-baser-aemv8r") + +set(SCP_TOOLCHAIN_INIT "GNU") + +set(SCP_GENERATE_FLAT_BINARY_INIT TRUE) + +set(SCP_ARCHITECTURE "aarch64") + +list(APPEND SCP_MODULES + "armv8r-mpu" + "pl011" +) diff --git a/product/fvp-baser-aemv8r/fw/Toolchain-Clang.cmake b/product/fvp-baser-aemv8r/fw/Toolchain-Clang.cmake new file mode 100644 index 0000000000000000000000000000000000000000..528e7aae200a0ce54b7c56dd71d038f6f78a7c7e --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/Toolchain-Clang.cmake @@ -0,0 +1,20 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include_guard() + +set(CMAKE_SYSTEM_PROCESSOR "aarch64") + +set(SCP_AARCH64_PROCESSOR_TARGET "cortex-r82") +set(CMAKE_TOOLCHAIN_PREFIX "aarch64-none-elf-") + +set(CMAKE_ASM_COMPILER_TARGET "aarch64-none-elf") +set(CMAKE_C_COMPILER_TARGET "aarch64-none-elf") +set(CMAKE_CXX_COMPILER_TARGET "aarch64-none-elf") + +include( + "${CMAKE_CURRENT_LIST_DIR}/../../../cmake/Toolchain/Clang-Baremetal.cmake") diff --git a/product/fvp-baser-aemv8r/fw/Toolchain-GNU.cmake b/product/fvp-baser-aemv8r/fw/Toolchain-GNU.cmake new file mode 100644 index 0000000000000000000000000000000000000000..049616bb32cc2295e94de923e8695b588dacabe2 --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/Toolchain-GNU.cmake @@ -0,0 +1,18 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include_guard() + +set(CMAKE_SYSTEM_PROCESSOR "aarch64") + +# TODO: Change to cortex-r82 once available in the supported toolchain +set(SCP_AARCH64_PROCESSOR_TARGET "generic") + +set(CMAKE_TOOLCHAIN_PREFIX "aarch64-none-elf-") + +include( + "${CMAKE_CURRENT_LIST_DIR}/../../../cmake/Toolchain/GNU-Baremetal.cmake") diff --git a/product/fvp-baser-aemv8r/fw/config_armv8r_mpu.c b/product/fvp-baser-aemv8r/fw/config_armv8r_mpu.c new file mode 100644 index 0000000000000000000000000000000000000000..cfe1e925c05a2791e110e6de8bcc759d3029cb41 --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/config_armv8r_mpu.c @@ -0,0 +1,63 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fvp_baser_aemv8r_mmap.h" +#include "mod_armv8r_mpu.h" + +#include +#include + +#include + +#include + +static uint8_t mem_attributes[] = { + MAIR_NORMAL_WB_NT, + MAIR_DEVICE_NGNRNE, +}; + +static struct mod_armv8r_mpu_region mem_regions[] = { + { .prbar = PRBAR_VALUE( + FMW_MEM0_BASE, + PRBAR_SH_NON_SHAREABLE, + PRBAR_AP_RO_EL2, + PRBAR_XN_PERMITTED), + .prlar = PRLAR_VALUE( + FMW_MEM0_BASE + FMW_MEM0_SIZE - 1, + PRLAR_NS_SECURE, + MPU_ATTR_0, + PRLAR_EN_ENABLED) }, + { .prbar = PRBAR_VALUE( + FMW_MEM1_BASE, + PRBAR_SH_NON_SHAREABLE, + PRBAR_AP_RW_EL2, + PRBAR_XN_NOT_PERMITTED), + .prlar = PRLAR_VALUE( + FMW_MEM1_BASE + FMW_MEM1_SIZE - 1, + PRLAR_NS_SECURE, + MPU_ATTR_0, + PRLAR_EN_ENABLED) }, + { .prbar = PRBAR_VALUE( + FVP_UART_BASE, + PRBAR_SH_NON_SHAREABLE, + PRBAR_AP_RW_EL2, + PRBAR_XN_NOT_PERMITTED), + .prlar = PRLAR_VALUE( + FVP_UART_BASE + FVP_UART_SIZE - 1, + PRLAR_NS_SECURE, + MPU_ATTR_1, + PRLAR_EN_ENABLED) } +}; + +const struct fwk_module_config config_armv8r_mpu = { + .data = &((struct mod_armv8r_mpu_config){ + .attributes_count = FWK_ARRAY_SIZE(mem_attributes), + .attributes = mem_attributes, + .region_count = FWK_ARRAY_SIZE(mem_regions), + .regions = mem_regions, + }), +}; diff --git a/product/fvp-baser-aemv8r/fw/config_pl011.c b/product/fvp-baser-aemv8r/fw/config_pl011.c new file mode 100644 index 0000000000000000000000000000000000000000..f4bf949d092b829b7a1715b724868c1a89718fda --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/config_pl011.c @@ -0,0 +1,32 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fvp_baser_aemv8r_mmap.h" + +#include + +#include +#include +#include +#include + +static const struct fwk_element pl011_table[] = { + { + .name = "scp_uart", + .data = + &(struct mod_pl011_element_cfg){ + .reg_base = FVP_UART_BASE, + .baud_rate_bps = 115200, + .clock_rate_hz = 24 * FWK_MHZ, + }, + }, + { 0 }, +}; + +const struct fwk_module_config config_pl011 = { + .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(pl011_table), +}; diff --git a/product/fvp-baser-aemv8r/fw/fmw_io.h b/product/fvp-baser-aemv8r/fw/fmw_io.h new file mode 100644 index 0000000000000000000000000000000000000000..ec7f589082d83b408592c8dd44c6ef6ab45ba52f --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/fmw_io.h @@ -0,0 +1,17 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FMW_IO_H +#define FMW_IO_H + +#include +#include + +#define FMW_IO_STDIN_ID FWK_ID_ELEMENT(FWK_MODULE_IDX_PL011, 0) +#define FMW_IO_STDOUT_ID FWK_ID_ELEMENT(FWK_MODULE_IDX_PL011, 0) + +#endif /* FMW_IO_H */ diff --git a/product/fvp-baser-aemv8r/fw/fmw_memory.h b/product/fvp-baser-aemv8r/fw/fmw_memory.h new file mode 100644 index 0000000000000000000000000000000000000000..7f140af55b50ae50a0d4523beb568d28917b4471 --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/fmw_memory.h @@ -0,0 +1,34 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FMW_MEMORY_H +#define FMW_MEMORY_H + +#include "fvp_baser_aemv8r_mmap.h" + +#include + +#define FMW_MEM_MODE ARCH_MEM_MODE_DUAL_REGION_NO_RELOCATION + +/* + * Instruction RAM + */ +#define FMW_MEM0_BASE FVP_ITC_RAM_BASE +#define FMW_MEM0_SIZE FVP_ITC_RAM_SIZE + +/* + * Data RAM + */ +#define FMW_MEM1_BASE FVP_DTC_RAM_BASE +#define FMW_MEM1_SIZE FVP_DTC_RAM_SIZE + +/* + * Stack + */ +#define FMW_STACK_SIZE (2 * FWK_KIB) + +#endif /* FMW_MEMORY_H */ diff --git a/product/fvp-baser-aemv8r/fw/fvp_baser_aemv8r_mmap.h b/product/fvp-baser-aemv8r/fw/fvp_baser_aemv8r_mmap.h new file mode 100644 index 0000000000000000000000000000000000000000..ac34c360bd6bbcb4919f664ff583af417f7f5bd6 --- /dev/null +++ b/product/fvp-baser-aemv8r/fw/fvp_baser_aemv8r_mmap.h @@ -0,0 +1,23 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_BASER_AEMV8R_MMAP_H +#define FVP_BASER_AEMV8R_MMAP_H + +#include + +#define FVP_DRAM_BASE 0x00000000 +#define FVP_ITC_RAM_SIZE (256 * 1024) +#define FVP_DTC_RAM_SIZE (256 * 1024) +#define FVP_ITC_RAM_BASE FVP_DRAM_BASE +#define FVP_DTC_RAM_BASE (FVP_DRAM_BASE + FVP_ITC_RAM_SIZE) + +#define FVP_PERIPHERAL_BASE 0x80000000 +#define FVP_UART_BASE (FVP_PERIPHERAL_BASE + 0x1C090000) +#define FVP_UART_SIZE (64 * FWK_KIB) + +#endif /* FVP_BASER_AEMV8R_MMAP_H */ diff --git a/product/fvp-baser-aemv8r/product.mk b/product/fvp-baser-aemv8r/product.mk new file mode 100644 index 0000000000000000000000000000000000000000..4be5e4d276ae7dd0fdd866ce07a47170372e5ec9 --- /dev/null +++ b/product/fvp-baser-aemv8r/product.mk @@ -0,0 +1,10 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# + +BS_PRODUCT_NAME := fvp-baser-aemv8r +BS_FIRMWARE_LIST := fw diff --git a/tools/config/check_build/default_products_build.yml b/tools/config/check_build/default_products_build.yml index be443eb1ac9f658937e959c3fb0096666203d837..8f0a34ddeb097ca7802e9d556e9566f5ace2be8c 100644 --- a/tools/config/check_build/default_products_build.yml +++ b/tools/config/check_build/default_products_build.yml @@ -5,6 +5,12 @@ # SPDX-License-Identifier: BSD-3-Clause # +- product: fvp-baser-aemv8r + toolchains: + - name: GNU + - name: Clang + extra_config_args: ["-DSCP_LLVM_SYSROOT_CC=aarch64-none-elf-gcc"] + - product: host toolchains: - name: GNU diff --git a/tools/config/cppcheck/cppcheck_suppress_list.txt b/tools/config/cppcheck/cppcheck_suppress_list.txt index d0115816bc9aed8ecbe3859b18b5ffc8ab96eaf0..c6104b56437fd3f45a79afdfa115b53d16bb0e3f 100755 --- a/tools/config/cppcheck/cppcheck_suppress_list.txt +++ b/tools/config/cppcheck/cppcheck_suppress_list.txt @@ -32,7 +32,7 @@ syntaxError:*product/morello/module/morello_system/src/mod_morello_system.c:302 preprocessorErrorDirective:*framework/test/fwk_module_idx.h:14 // Cppcheck does not properly parse the `FWK_HAS_INCLUDE` macro -preprocessorErrorDirective:*arch/arm/src/arch_mm.c:16 +preprocessorErrorDirective:*arch/arm/common/src/arch_mm.c:16 preprocessorErrorDirective:*arch/arm/armv8-a/src/arch_mm.c:17 // Cppcheck is not able to parse returned boolean values inside if conditions @@ -51,3 +51,7 @@ unknownEvaluationOrder:*framework/src/fwk_io.c:61 unknownEvaluationOrder:*framework/src/fwk_io.c:63 unknownEvaluationOrder:*framework/src/fwk_log.c:54 unknownEvaluationOrder:*framework/src/fwk_log.c:56 + +// Cppcheck is unable to fully parse newlib on AArch64 (when included explicitly with Clang) +preprocessorErrorDirective:*machine/* +preprocessorErrorDirective:*sys/* diff --git a/unit_test/CMakeLists.txt b/unit_test/CMakeLists.txt index ffcd1df320e8e3c3463d92e37b51adf46d2d6632..dadf1b4f51e7731e79910f3863b4d1a7170d6a27 100644 --- a/unit_test/CMakeLists.txt +++ b/unit_test/CMakeLists.txt @@ -106,6 +106,7 @@ list(APPEND FWK_SRC ${UNITY_SRC_ROOT}/unity.c) list(APPEND SCP_UNITY_SRC ${TEST_ROOT}/unity_mocks/scp_unity.c) #Append common unit tests below here (alphabetical order) +list(APPEND UNIT_MODULE armv8r_mpu) list(APPEND UNIT_MODULE amu_mmap) list(APPEND UNIT_MODULE amu_smcf_drv) list(APPEND UNIT_MODULE atu)