Merge tag 'v3.14.25' into backport/v3.14.24-ltsi-rc1+v3.14.25/snapshot-merge.wip
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / ktap / include / ktap_ffi.h
1 #ifndef __KTAP_FFI_H__
2 #define __KTAP_FFI_H__
3
4 #ifdef CONFIG_KTAP_FFI
5
6 #include "../include/ktap_types.h"
7
8 /*
9  * Types design in FFI module
10  *
11  * ktap_cdata is an instance of csymbol, so it's a combination of csymbol
12  * and it's actual data in memory.
13  *
14  * csymbol structs are globally unique and readonly type that represent C
15  * types.  For non scalar C types like struct and function, helper structs are
16  * used to store detailed information. See csymbol_func and csymbol_struct for
17  * more information.
18  */
19
20 typedef enum {
21         /* 0 - 4 */
22         FFI_VOID,
23         FFI_UINT8,
24         FFI_INT8,
25         FFI_UINT16,
26         FFI_INT16,
27         /* 5 - 9 */
28         FFI_UINT32,
29         FFI_INT32,
30         FFI_UINT64,
31         FFI_INT64,
32         FFI_PTR,
33         /* 10 - 12 */
34         FFI_FUNC,
35         FFI_STRUCT,
36         FFI_UNKNOWN,
37 } ffi_type;
38 #define NUM_FFI_TYPE ((int)FFI_UNKNOWN)
39
40
41 /* following struct and macros are added for C typedef
42  * size and alignment calculation */
43 typedef struct {
44         size_t size;
45         size_t align;
46         const char *name;
47 } ffi_mode;
48 extern const ffi_mode const ffi_type_modes[];
49
50 #define ffi_type_size(t) (ffi_type_modes[t].size)
51 #define ffi_type_align(t) (ffi_type_modes[t].align)
52 #define ffi_type_name(t) (ffi_type_modes[t].name)
53
54
55 /* start of csymbol definition */
56 #define CSYM_NAME_MAX_LEN 64
57
58 typedef struct csymbol_func {
59         void *addr;             /* function address */
60         csymbol_id ret_id;      /* function return type */
61         int arg_nr;             /* number of arguments */
62         csymbol_id *arg_ids;    /* function argument types */
63         unsigned has_var_arg;   /* is this a var arg function? */
64 } csymbol_func;
65
66 typedef struct struct_member {
67         char name[CSYM_NAME_MAX_LEN];   /* name for this struct member */
68         csymbol_id id;                  /* type for this struct member */
69 } struct_member;
70
71 typedef struct csymbol_struct {
72         int memb_nr;                    /* number of members */
73         struct_member *members;         /* array for each member definition */
74         size_t size;                    /* bytes used to store struct */
75         /* alignment of the struct, 0 indicates uninitialization */
76         size_t align;
77 } csymbol_struct;
78
79
80 /* wrapper struct for all C symbols */
81 typedef struct csymbol {
82         char name[CSYM_NAME_MAX_LEN];   /* name for this symbol */
83         ffi_type type;                  /* type for this symbol  */
84         /* following members are used only for non scalar C types */
85         union {
86                 csymbol_id p;           /* pointer type */
87                 csymbol_func f;         /* C function type */
88                 csymbol_struct st;      /* struct type */
89                 csymbol_id td;          /* typedef type */
90         } u;
91 } csymbol;
92
93 /* lookup csymbol address by it's id */
94 inline csymbol *ffi_get_csym_by_id(ktap_state *ks, csymbol_id id);
95 #define id_to_csym(ks, id) (ffi_get_csym_by_id(ks, id))
96
97 /* helper macros for struct csymbol */
98 #define csym_type(cs) ((cs)->type)
99 #define csym_name(cs) ((cs)->name)
100
101 /*
102  * helper macros for pointer symbol
103  */
104 #define csym_ptr_deref_id(cs) ((cs)->u.p)
105 #define csym_set_ptr_deref_id(cs, id) ((cs)->u.p = (id))
106 /* following macro gets csymbol address */
107 #define csym_ptr_deref(ks, cs) (id_to_csym(ks, csym_ptr_deref_id(cs)))
108
109 /*
110  * helper macros for function symbol
111  * csym_* accepts csymbol type
112  * csymf_* accepts csymbol_func type
113  */
114 #define csymf_addr(csf) ((csf)->addr)
115 #define csymf_ret_id(csf) ((csf)->ret_id)
116 #define csymf_arg_nr(csf) ((csf)->arg_nr)
117 #define csymf_arg_ids(csf) ((csf)->arg_ids)
118 /* get csymbol id for the nth argument */
119 #define csymf_arg_id(csf, n) ((csf)->arg_ids[n])
120 #define csym_func(cs) (&((cs)->u.f))
121 #define csym_func_addr(cs) (csymf_addr(csym_func(cs)))
122 #define csym_func_arg_ids(cs) (csymf_arg_ids(csym_func(cs)))
123 /* following macros get csymbol address */
124 #define csymf_ret(ks, csf) (id_to_csym(ks, csymf_ret_id(csf)))
125 /* get csymbol address for the nth argument */
126 #define csymf_arg(ks, csf, n) (id_to_csym(ks, csymf_arg_id(csf, n)))
127 #define csym_func_arg(ks, cs, n) (csymf_arg(ks, csym_func(cs), n))
128
129 /*
130  * helper macors for struct symbol
131  * csym_* accepts csymbol type
132  * csymst_* accepts csymbol_struct type
133  */
134 #define csymst_mb_nr(csst) ((csst)->memb_nr)
135 #define csym_struct(cs) (&(cs)->u.st)
136 #define csym_struct_mb(cs) (csymst_mb(ks, csym_struct(cs), n))
137 /* following macro gets csymbol address for the nth struct member */
138 #define csymst_mb(ks, csst, n) (id_to_csym(ks, (csst)->members[n].id))
139
140
141 /*
142  * helper macros for ktap_cdata type
143  */
144 #define cd_csym_id(cd) ((cd)->id)
145 #define cd_set_csym_id(cd, id) (cd_csym_id(cd) = (id))
146 #define cd_csym(ks, cd) (id_to_csym(ks, cd_csym_id(cd)))
147 #define cd_type(ks, cd) (cd_csym(ks, cd)->type)
148
149 #define cd_int(cd) ((cd)->u.i)
150 #define cd_ptr(cd) ((cd)->u.p)
151 #define cd_struct(cd) ((cd)->u.st)
152
153
154 #ifdef __KERNEL__
155 size_t csym_size(ktap_state *ks, csymbol *sym);
156 size_t csym_align(ktap_state *ks, csymbol *sym);
157 size_t csym_struct_offset(ktap_state *ks, csymbol_struct *csst, int idx);
158 void init_csym_struct(ktap_state *ks, csymbol_struct *csst);
159
160 void kp_ffi_free_symbol(ktap_state *ks);
161 csymbol_id ffi_get_csym_id(ktap_state *ks, char *name);
162
163 ktap_cdata *kp_cdata_new(ktap_state *ks);
164 void kp_cdata_dump(ktap_state *ks, ktap_cdata *cd);
165 ktap_cdata *kp_cdata_new_ptr(ktap_state *ks, void *addr, csymbol_id id);
166 ktap_cdata *kp_cdata_new_struct(ktap_state *ks, void *val, csymbol_id id);
167
168 int kp_ffi_call(ktap_state *ks, csymbol_func *cf);
169 #endif /* for __KERNEL__ */
170
171 #else
172
173 static void __maybe_unused kp_ffi_free_symbol(ktap_state *ks)
174 {
175         return;
176 }
177
178 #endif /* CONFIG_KTAP_FFI */
179
180 #endif /* __KTAP_FFI_H__ */