1// Automatically generated. Do not modify.
2//
3// © 2021 Qualcomm Innovation Center, Inc. All rights reserved.
4//
5// SPDX-License-Identifier: BSD-3-Clause
6#extends hypercall_api
7#implements respond
8#def prefix: $internal_prefix
9
10\#include <assert.h>
11\#include <hyptypes.h>
12
13\#include <hypcall_def.h>
14\#include <compiler.h>
15\#include <thread.h>
16\#include <trace.h>
17
18\#include <events/thread.h>
19
20#def trace_in(hypcall_num, hypcall)
21    #set trace_fmt = $hypcall.name + ":"
22    #for i, input in $hypcall.inputs[:5]
23        #if not $input.ignore
24            #set trace_fmt = trace_fmt + " {:#x}"
25        #end if
26    #end for
27    TRACE(USER, HYPERCALL, "${trace_fmt}"
28    #for i, input in $hypcall.inputs[:5]
29        #if not $input.ignore
30        , (register_t)($register_expr($input))
31        #end if
32    #end for
33    );
34#end def
35
36#def trace_out(hypcall_num, hypcall)
37    #set trace_fmt = $hypcall.name + " ret:"
38    #for i, input in $hypcall.outputs[:5]
39        #if not $input.ignore
40            #set trace_fmt = trace_fmt + " {:#x}"
41        #end if
42    #end for
43    TRACE(USER, HYPERCALL, "${trace_fmt}"
44    #if len($hypcall.outputs) == 1
45        , (register_t)ret_
46    #else
47        #for i, output in $hypcall.outputs[:5]
48        , (register_t)ret_.$register_expr($output)
49        #end for
50    #end if
51    );
52#end def
53
54#set $wrapper_suffix = "__c_wrapper"
55#for hypcall_num in sorted($hypcall_dict.keys())
56    #set $hypcall = $hypcall_dict[$hypcall_num]
57    #if len($hypcall.outputs) > 1
58    static_assert(sizeof(${return_type($hypcall)}) <= 8U * sizeof(register_t),
59        "Return structure must fit in 8 machine registers");
60
61    #end if
62    #set $num_in = len($hypcall.inputs)
63    #set $num_out = len($hypcall.outputs)
64    #set $sensitive = $hypcall.properties.get('sensitive', False)
65
66    #assert $num_in <= 8
67    #assert $num_out <= 8
68
69${type_signature($hypcall, suffix=$wrapper_suffix, ignored_inputs=True)}
70	REQUIRE_PREEMPT_DISABLED;
71
72${type_signature($hypcall, suffix=$wrapper_suffix, ignored_inputs=True)} {
73    #if $hypcall.outputs
74        $return_type($hypcall) ret_;
75    #end if
76
77    trigger_thread_entry_from_user_event(THREAD_ENTRY_REASON_HYPERCALL);
78
79#if $sensitive
80    TRACE(USER, HYPERCALL, "$hypcall.name");
81#else
82    $trace_in($hypcall_num, $hypcall)
83#end if
84
85    ## generate reserved input checks
86    #set has_ignores = False
87    #set error_ret = None
88    #for r, output in $hypcall.outputs
89        #if $output.ctype == 'error_t'
90            #set error_ret = $output
91            #break
92        #end if
93    #end for
94    #if error_ret
95        #for r, input in $hypcall.inputs
96            #if $input.ignore
97                #set has_ignores = True
98    if (compiler_unexpected(${input.name} != (${input.ctype})${input.default}U)) {
99                #if len($hypcall.outputs) == 1
100        ret_ = ERROR_ARGUMENT_INVALID;
101                #else
102        ret_ = ($return_type($hypcall)){ .${error_ret.name} = ERROR_ARGUMENT_INVALID };
103                #end if
104        goto out;
105    }
106            #end if
107        #end for
108    #else
109        // FIXME: unchecked reserved inputs
110        #for r, input in $hypcall.inputs
111            #if $input.ignore
112    (void)$input.name;
113            #end if
114        #end for
115    #end if
116
117    ## call the implementation
118    #if $hypcall.outputs
119    ret_ =
120    #end if
121    $prefix${hypcall.name}(#slurp
122    #set sep=''
123    #for i, input in $hypcall.inputs
124        #if not $input.ignore
125            $sep$input.name
126            #set sep=', '
127        #end if
128    #end for
129    );
130
131    #if has_ignores:
132out:
133    #end if
134
135#if not $sensitive
136    $trace_out($hypcall_num, $hypcall)
137#end if
138
139    trigger_thread_exit_to_user_event(THREAD_ENTRY_REASON_HYPERCALL);
140
141    ## return the result, if any
142    #if $hypcall.outputs
143    return ret_;
144    #else
145        #if has_ignores:
146    return;
147        #end if
148    #end if
149}
150
151#end for
152