1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors. 4 */ 5 6 #ifndef APP_FW_STRUCTURES_H 7 #define APP_FW_STRUCTURES_H 8 9 #include <utils_def.h> 10 #include <xlat_high_va.h> 11 12 #define APP_SAVED_GEN_REG_COUNT U(31) 13 14 #define APP_XLAT_TABLE_COUNT U(1) 15 16 #define APP_TTBR1_EL2_OFFSET UL(0) 17 #define RMM_TTBR1_EL2_OFFSET UL(8) 18 #define RMM_VBAR_EL2_OFFSET UL(16) 19 #define RMM_TPIDR_EL0_OFFSET UL(24) 20 #define RMM_TPIDRRO_EL0_OFFSET UL(32) 21 #define PC_OFFSET UL(40) 22 #define PSTATE_OFFSET UL(48) 23 #define APP_SAVED_REGS_OFFSET UL(56) 24 #define SP_EL0_OFFSET UL(304) 25 26 #ifndef __ASSEMBLER__ 27 28 /* This structure must always be aligned to page boundary as it is mapped into 29 * the app VA space. 30 */ 31 struct app_reg_ctx { 32 /* 33 * Members are defined with macros to make sure that the member offsets 34 * that are used by the assembly code are aligned with the structure 35 * definition. 36 */ 37 SET_MEMBER(uint64_t app_ttbr1_el2, APP_TTBR1_EL2_OFFSET, RMM_TTBR1_EL2_OFFSET); 38 SET_MEMBER(uint64_t rmm_ttbr1_el2, RMM_TTBR1_EL2_OFFSET, RMM_VBAR_EL2_OFFSET); 39 SET_MEMBER(uint64_t rmm_vbar_el2, RMM_VBAR_EL2_OFFSET, RMM_TPIDR_EL0_OFFSET); 40 SET_MEMBER(uint64_t rmm_tpidr_el0, RMM_TPIDR_EL0_OFFSET, RMM_TPIDRRO_EL0_OFFSET); 41 SET_MEMBER(uint64_t rmm_tpidrro_el0, RMM_TPIDRRO_EL0_OFFSET, PC_OFFSET); 42 SET_MEMBER(uint64_t pc, PC_OFFSET, PSTATE_OFFSET); 43 SET_MEMBER(uint64_t pstate, PSTATE_OFFSET, APP_SAVED_REGS_OFFSET); 44 SET_MEMBER(uint64_t app_regs[APP_SAVED_GEN_REG_COUNT], 45 APP_SAVED_REGS_OFFSET, SP_EL0_OFFSET); 46 SET_MEMBER(uint64_t sp_el0, SP_EL0_OFFSET, GRANULE_SIZE); 47 } __aligned(GRANULE_SIZE); 48 COMPILER_ASSERT(sizeof(struct app_reg_ctx) == GRANULE_SIZE); 49 COMPILER_ASSERT(SIZEOF_MEMBER(struct app_reg_ctx, app_regs) == 50 (sizeof(unsigned long) * APP_SAVED_GEN_REG_COUNT)); 51 /* 52 * NS_TPIDR[RO]_EL0_OFFSET registers are saved/restored with a single stp/ldr 53 * instruction, so they must be close. 54 */ 55 COMPILER_ASSERT((RMM_TPIDR_EL0_OFFSET + sizeof(unsigned long)) == RMM_TPIDRRO_EL0_OFFSET); 56 /* 57 * The code entering and exiting from EL0 app assumes that sp_el0 is 58 * right after the `regs` array. 59 */ 60 COMPILER_ASSERT(U(offsetof(struct app_reg_ctx, sp_el0)) == 61 (U(offsetof(struct app_reg_ctx, app_regs)) + 62 (APP_SAVED_GEN_REG_COUNT * sizeof(unsigned long)))); 63 /* Make sure that the last member in the list is at the desired offset */ 64 COMPILER_ASSERT(U(offsetof(struct app_reg_ctx, sp_el0)) == SP_EL0_OFFSET); 65 66 struct app_data_cfg { 67 /* Structures for setting up and storing app translation related data */ 68 struct xlat_ctx_cfg app_va_xlat_ctx_cfg; 69 struct xlat_ctx app_va_xlat_ctx; 70 struct xlat_ctx_tbls app_va_tbls; 71 struct xlat_mmu_cfg mmu_config; 72 struct xlat_llt_info cached_app_llt_info; 73 uintptr_t app_reg_ctx_pa; 74 75 uintptr_t shared_page_pa; 76 uintptr_t el0_shared_page_va; 77 void *el2_shared_page; /* Is NULL while the shared page is not mapped */ 78 void *el2_heap_start; /* The start VA in the EL2 VA space of the app heap area */ 79 uintptr_t heap_va; /* this VA address is valid in the EL0 VA space */ 80 uintptr_t heap_size; 81 uintptr_t stack_buf_start_va; 82 uintptr_t stack_top; /* Initial value of the stack pointer */ 83 84 /* App entry point VA */ 85 uintptr_t entry_point; 86 87 bool app_entered; 88 uint32_t exit_flag; /* App Exit Flag */ 89 }; 90 COMPILER_ASSERT((XLAT_TABLE_ENTRIES * APP_XLAT_TABLE_COUNT) <= GRANULE_SIZE); 91 92 #endif /* __ASSEMBLER__ */ 93 #endif /* APP_FW_STRUCTURES_H */ 94