Imported Upstream version 3.0
[platform/upstream/gnu-efi.git] / lib / x86_64 / callwrap.c
1 /*
2  * Convert SysV calling convention to EFI x86_64 calling convention
3  *
4  *  Copyright (C) 2007-2010 Intel Corp
5  *      Bibo Mao <bibo.mao@intel.com>
6  *      Chandramouli Narayanan<mouli@linux.intel.com>
7  *      Huang Ying <ying.huang@intel.com>
8  *
9  *  All rights reserved.
10  *
11  *  Redistribution and use in source and binary forms, with or without
12  *  modification, are permitted provided that the following conditions
13  *  are met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * - Redistributions in binary form must reproduce the above
18  *   copyright notice, this list of conditions and the following
19  *   disclaimer in the documentation and/or other materials
20  *   provided with the distribution.
21  * - Neither the name of Hewlett-Packard Co. nor the names of its
22  *   contributors may be used to endorse or promote products derived
23  *   from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26  *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
30  *  BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31  *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
36  *  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  *  SUCH DAMAGE.
38  */
39
40 #include "efi.h"
41 #include "efistdarg.h"
42
43 #if !defined(HAVE_USE_MS_ABI)
44 UINT64 efi_call0(void *func);
45 UINT64 efi_call1(void *func, UINT64 arg1);
46 UINT64 efi_call2(void *func, UINT64 arg1, UINT64 arg2);
47 UINT64 efi_call3(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3);
48 UINT64 efi_call4(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
49                  UINT64 arg4);
50 UINT64 efi_call5(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
51                  UINT64 arg4, UINT64 arg5);
52 UINT64 efi_call6(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
53                  UINT64 arg4, UINT64 arg5, UINT64 arg6);
54 UINT64 efi_call7(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
55                  UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7);
56 UINT64 efi_call8(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
57                  UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7,
58                  UINT64 arg8);
59 UINT64 efi_call9(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
60                  UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7,
61                  UINT64 arg8, UINT64 arg9);
62 UINT64 efi_call10(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
63                  UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7,
64                  UINT64 arg8, UINT64 arg9, UINT64 arg10);
65
66 #define EFI_ARG_NUM_MAX 10
67
68 EFI_STATUS uefi_call_wrapper(void *fp, unsigned long va_num, ...)
69 {
70         va_list ap;
71         int i;
72         unsigned long args[EFI_ARG_NUM_MAX];
73
74         if (va_num > EFI_ARG_NUM_MAX || va_num < 0) {
75                 return EFI_LOAD_ERROR;
76         }
77         va_start(ap, va_num);
78         for (i = 0; i < va_num; i++) {
79                 args[i] = va_arg(ap, UINT64);
80         }
81         va_end(ap);
82         /* As the number of args grows extend it appropriately */
83         switch (va_num) {
84         case 0:
85                 return efi_call0(fp);
86         case 1:
87                 return efi_call1(fp, args[0]);
88         case 2:
89                 return efi_call2(fp,
90                                  args[0], args[1]);
91         case 3:
92                 return efi_call3(fp,
93                                  args[0], args[1], args[2]);
94         case 4:
95                 return efi_call4(fp,
96                                  args[0], args[1], args[2], args[3]);
97         case 5:
98                 return efi_call5(fp,
99                                  args[0], args[1], args[2], args[3],
100                                  args[4]);
101         case 6:
102                 return efi_call6(fp,
103                                  args[0], args[1], args[2], args[3],
104                                  args[4], args[5]);
105         case 7:
106                 return efi_call7(fp,
107                                  args[0], args[1], args[2], args[3],
108                                  args[4], args[5], args[6]);
109         case 8:
110                 return efi_call8(fp,
111                                  args[0], args[1], args[2], args[3],
112                                  args[4], args[5], args[6], args[7]);
113         case 9:
114                 return efi_call9(fp,
115                                  args[0], args[1], args[2], args[3],
116                                  args[4], args[5], args[6], args[7],
117                                  args[8]);
118         case 10:
119                 return efi_call10(fp,
120                                   args[0], args[1], args[2], args[3],
121                                   args[4], args[5], args[6], args[7],
122                                   args[8], args[9]);
123         default:
124                 return EFI_LOAD_ERROR;
125         }
126 }
127 #endif