1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #ifndef __LIB_UEFI_SWITCH_STACK_H
19 #define __LIB_UEFI_SWITCH_STACK_H
20 
21 #include <lk/compiler.h>
22 #include <stddef.h>
23 
24 __BEGIN_CDECLS
25 
26 size_t call_with_stack_asm(void *stack, const void *function, void *param1,
27                            void *param2, void *param3, void *param4,
28                            void *param5);
29 
30 __END_CDECLS
31 
32 #ifdef __cplusplus
33 template <typename Function, typename P1, typename P2, typename P3, typename P4,
34           typename P5>
call_with_stack(void * stack,Function && fp,P1 && param1,P2 && param2,P3 && param3,P4 && param4,P5 && param5)35 size_t call_with_stack(void *stack, Function &&fp, P1 &&param1, P2 &&param2,
36                        P3 &&param3, P4 &&param4, P5 &&param5) {
37   return call_with_stack_asm(
38       stack, reinterpret_cast<const void *>(fp),
39       reinterpret_cast<void *>(param1), reinterpret_cast<void *>(param2),
40       reinterpret_cast<void *>(param3), reinterpret_cast<void *>(param4),
41       reinterpret_cast<void *>(param5));
42 }
43 template <typename Function, typename P1, typename P2, typename P3, typename P4>
call_with_stack(void * stack,Function && fp,P1 && param1,P2 && param2,P3 && param3,P4 && param4)44 size_t call_with_stack(void *stack, Function &&fp, P1 &&param1, P2 &&param2,
45                        P3 &&param3, P4 &&param4) {
46   return call_with_stack_asm(stack, reinterpret_cast<const void *>(fp),
47                              reinterpret_cast<void *>(param1),
48                              reinterpret_cast<void *>(param2),
49                              reinterpret_cast<void *>(param3),
50                              reinterpret_cast<void *>(param4), nullptr);
51 }
52 
53 template <typename Function, typename P1, typename P2, typename P3>
call_with_stack(void * stack,Function && fp,P1 && param1,P2 && param2,P3 && param3)54 size_t call_with_stack(void *stack, Function &&fp, P1 &&param1, P2 &&param2,
55                        P3 &&param3) {
56   return call_with_stack_asm(
57       stack, reinterpret_cast<const void *>(fp),
58       reinterpret_cast<void *>(param1), reinterpret_cast<void *>(param2),
59       reinterpret_cast<void *>(param3), nullptr, nullptr);
60 }
61 
62 template <typename Function, typename P1, typename P2>
call_with_stack(void * stack,Function && fp,P1 && param1,P2 && param2)63 size_t call_with_stack(void *stack, Function &&fp, P1 &&param1, P2 &&param2) {
64   return call_with_stack_asm(stack, reinterpret_cast<const void *>(fp),
65                              reinterpret_cast<void *>(param1),
66                              reinterpret_cast<void *>(param2), nullptr, nullptr,
67                              nullptr);
68 }
69 
70 template <typename Function, typename P1>
call_with_stack(void * stack,Function && fp,P1 && param1)71 size_t call_with_stack(void *stack, Function &&fp, P1 &&param1) {
72   return call_with_stack_asm(stack, reinterpret_cast<const void *>(fp),
73                              reinterpret_cast<void *>(param1), nullptr, nullptr,
74                              nullptr, nullptr);
75 }
76 #endif
77 
78 #endif
79