1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #ifndef APP_H
7 #define APP_H
8 
9 #include <app_fw_structures.h>
10 
11 #define APP_VA_START	(UL(0xffffffffffffffff) - XLAT_HIGH_VA_SIZE + 1U)
12 
13 #ifndef __ASSEMBLER__
14 #include <stddef.h>
15 #include <stdint.h>
16 #include <string.h>
17 
18 /* exit_flag bits */
19 /* An SVC call issued with APP_EXIT_CALL as ISS */
20 #define APP_EXIT_SVC_EXIT_FLAG		(UL(1) << 0)
21 /* An SVC call issued with APP_YIELD_CALL as ISS */
22 #define APP_EXIT_SVC_YIELD_FLAG		(UL(1) << 1)
23 /* An SVC call issued with APP_SERVICE_CALL as ISS */
24 #define APP_EXIT_SVC_SERVICE_FLAG	(UL(1) << 2)
25 
26 /* TODO: This should come from a header that is generated by the bin generating python script
27  * or by cmake? A template could be used... See
28  * https://cmake.org/cmake/help/latest/command/configure_file.html
29  */
30 #define RMM_RANDOM_APP_ID			(103U)
31 #define ATTESTATION_APP_ID			(211U)
32 #define RMM_DEV_ASSIGN_APP_ID			(110U)
33 
34 #define GRANULE_COUNT(size)	(round_up(size, GRANULE_SIZE) / GRANULE_SIZE)
35 
36 #ifdef APP_FW_LOGGING
37 #define LOG_APP_FW INFO
38 #else
39 #define LOG_APP_FW VERBOSE
40 #endif
41 
42 /*
43  * Function to set up the App framework. Called once, during cold boot.
44  */
45 void app_framework_setup(void);
46 
47 /*
48  * Function to calculate the number of per instance granules that are used by
49  * this app.
50  *
51  * Arguments:
52  *	- app_id: The ID of the application.
53  *
54  * Return:
55  *	- The number of granules required by the app.
56  */
57 size_t app_get_required_granule_count(unsigned long app_id);
58 
59 /*
60  * Initialise the config data for an App instance.
61  *
62  * Arguments:
63  *	- app_data: Pointer to the config to be initialised
64  *	- app_id: The id of the app to be initialised
65  *	- granule_pas: An array of Granule PAS that can be used for per instance
66  *        data in the app
67  *	- granule_count: The number of elements in the granule_pas array.
68  *	- granule_va_start: The start address of the granules as they are mapped
69  *        in RMM core
70  *
71  * Return:
72  *	- 0 on success or a negative POSIX error otherwise.
73  *
74  * Important: some RMM apps might use the optimisation so that the RMM app stub
75  * (running in EL2) access the RMM app heap directly (i.e. the pages are mapped
76  * in the RMM core VA space). If the app uses this optimisation then the pages
77  * passed in granule_pas must be mapped continuously either in the REC AUX pages
78  * or in the RMM core's RW memory area.
79  * TODO: The current API assumes that the condition above is true, and
80  * granule_va_start contains the start address of the area where the PAs in the
81  * array are mapped.
82  */
83 int app_init_data(struct app_data_cfg *app_data,
84 		      unsigned long app_id,
85 		      uintptr_t granule_pas[],
86 		      size_t granule_count,
87 		      void *granule_va_start);
88 
89 void *app_get_heap_ptr(struct app_data_cfg *app_data);
90 
91 /*
92  * Run the app instance execution specified by the app data config. This
93  * function can only be called if the app is not pre-empted/yieded. This
94  * function loads the app register context, populated the arguments,
95  * runs the app, and returns to the caller if the app finished running
96  * by calling an SVC or caused an exception.
97  *
98  * Arguments:
99  *	- app_data: An initialised app config (selects the app instance to run)
100  *	- app_func_id: The id of the function in the app to be run
101  *	- arg0 - arg3: Arguments to the app function
102  *
103  * Return:
104  *	- App specific return value and is only valid if `app_data->exit_flag`
105  *	  != APP_EXIT_SVC_YIELD_FLAG.
106  */
107 unsigned long app_run(struct app_data_cfg *app_data,
108 			  unsigned long app_func_id,
109 			  unsigned long arg0,
110 			  unsigned long arg1,
111 			  unsigned long arg2,
112 			  unsigned long arg3);
113 
114 /*
115  * Resume the app instance specified by the app data config previously
116  * yielded/premepted. This function loads the saved app register context,
117  * runs the app, and returns to the caller if the app finished running
118  * by calling an SVC or caused an exception.
119  *
120  * Arguments:
121  *	- app_data: An initialised app config (selects the app instance to run)
122  * Return:
123  *	- App specific return value and is only valid if `app_data->exit_flag`
124  *	  != APP_EXIT_SVC_YIELD_FLAG.
125  */
126 unsigned long app_resume(struct app_data_cfg *app_data);
127 
128 /*
129  * Abort an application instance by resetting its register context its init
130  * value. This resets the stack pointer and the PC. General purpose register
131  * values, stack, heap, and data/bss memory content is not affected.
132  *
133  * Arguments:
134  *	- app_data: An initialised app config (selects the app instance to abort)
135  */
136 void app_abort(struct app_data_cfg *app_data);
137 
138 /*
139  * Map the app shared page in the EL2 VA space
140  *
141  * Arguments:
142  *	- app_data: An initialised app config
143  */
144 void app_map_shared_page(struct app_data_cfg *app_data);
145 
146 /*
147  * Unmap the app shared page from the EL2 VA space
148  *
149  * Arguments:
150  *	- app_data: An initialised app config
151  */
152 void app_unmap_shared_page(struct app_data_cfg *app_data);
153 
154 #endif /* __ASSEMBLER__ */
155 #endif /* APP_H */
156