Phoenix
Object-oriented orthogonally persistent operating system
|
00001 /* 00002 * /phoenix/kernel/sys/arch/x86_64/md_efi.h 00003 * 00004 * This file is a part of Phoenix operating system. 00005 * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com> 00006 * All rights reserved. 00007 * See COPYING file for copyright details. 00008 */ 00009 00014 #ifndef MD_EFI_H_ 00015 #define MD_EFI_H_ 00016 00017 namespace efi { 00018 00020 class EfiArg { 00021 public: 00025 union { 00026 u64 raw; 00027 void *ptr; 00028 } value; 00029 00031 template <typename T> 00032 inline EfiArg(T intValue) { 00033 value.raw = intValue; 00034 } 00035 00037 template <typename T> 00038 inline EfiArg(T *ptrValue) { 00039 value.ptr = ptrValue; 00040 } 00041 }; 00042 00044 class EfiCall { 00045 public: 00047 inline Uintn operator()() { 00048 Uintn rc; 00049 ASM ("subq $40, %%rsp\n" 00050 "call *%[func]\n" 00051 "addq $40, %%rsp\n" 00052 : "=a"(rc) 00053 : [func]"r"(vm::mm->PhysToVirt(_addr)) 00054 : "rcx", "rdx", "r8", "r9", "r10", "r11" 00055 ); 00056 return rc; 00057 }; 00058 00060 inline Uintn operator()(EfiArg arg1) { 00061 Uintn rc; 00062 ASM ("subq $40, %%rsp\n" 00063 "call *%[func]\n" 00064 "addq $40, %%rsp\n" 00065 : "=&a"(rc) 00066 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00067 "c"(arg1) 00068 : "rdx", "r8", "r9", "r10", "r11" 00069 ); 00070 return rc; 00071 }; 00072 00074 inline Uintn operator()(EfiArg arg1, EfiArg arg2) { 00075 Uintn rc; 00076 ASM ("subq $40, %%rsp\n" 00077 "call *%[func]\n" 00078 "addq $40, %%rsp\n" 00079 : "=&a"(rc) 00080 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00081 "c"(arg1), 00082 "d"(arg2) 00083 : "r8", "r9", "r10", "r11" 00084 ); 00085 return rc; 00086 }; 00087 00089 inline Uintn operator()(EfiArg arg1, EfiArg arg2, EfiArg arg3) { 00090 Uintn rc; 00091 ASM ("subq $40, %%rsp\n" 00092 "mov %[arg3], %%r8\n" 00093 "call *%[func]\n" 00094 "addq $40, %%rsp\n" 00095 : "=&a"(rc) 00096 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00097 "c"(arg1), 00098 "d"(arg2), 00099 [arg3]"m"(arg3) 00100 : "r8", "r9", "r10", "r11" 00101 ); 00102 return rc; 00103 }; 00104 00106 inline Uintn operator()(EfiArg arg1, EfiArg arg2, EfiArg arg3, EfiArg arg4) { 00107 Uintn rc; 00108 ASM ("subq $40, %%rsp\n" 00109 "mov %[arg3], %%r8\n" 00110 "mov %[arg4], %%r9\n" 00111 "call *%[func]\n" 00112 "addq $40, %%rsp\n" 00113 : "=&a"(rc) 00114 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00115 "c"(arg1), 00116 "d"(arg2), 00117 [arg3]"m"(arg3), 00118 [arg4]"m"(arg4) 00119 : "r8", "r9", "r10", "r11" 00120 ); 00121 return rc; 00122 }; 00123 00125 inline Uintn operator()(EfiArg arg1, EfiArg arg2, EfiArg arg3, EfiArg arg4, 00126 EfiArg arg5) { 00127 Uintn rc; 00128 ASM ("subq $40, %%rsp\n" 00129 "mov %[arg3], %%r8\n" 00130 "mov %[arg4], %%r9\n" 00131 "mov %[arg5], %%rax\n" 00132 "mov %%rax, 32(%%rsp)\n" 00133 "call *%[func]\n" 00134 "addq $40, %%rsp\n" 00135 : "=&a"(rc) 00136 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00137 "c"(arg1), 00138 "d"(arg2), 00139 [arg3]"m"(arg3), 00140 [arg4]"m"(arg4), 00141 [arg5]"m"(arg5) 00142 : "r8", "r9", "r10", "r11" 00143 ); 00144 return rc; 00145 }; 00146 00148 inline Uintn operator()(EfiArg arg1, EfiArg arg2, EfiArg arg3, EfiArg arg4, 00149 EfiArg arg5, EfiArg arg6) { 00150 Uintn rc; 00151 ASM ("subq $56, %%rsp\n" 00152 "mov %[arg3], %%r8\n" 00153 "mov %[arg4], %%r9\n" 00154 "mov %[arg5], %%rax\n" 00155 "mov %%rax, 32(%%rsp)\n" 00156 "mov %[arg6], %%rax\n" 00157 "mov %%rax, 40(%%rsp)\n" 00158 "call *%[func]\n" 00159 "addq $56, %%rsp\n" 00160 : "=&a"(rc) 00161 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00162 "c"(arg1), 00163 "d"(arg2), 00164 [arg3]"m"(arg3), 00165 [arg4]"m"(arg4), 00166 [arg5]"m"(arg5), 00167 [arg6]"m"(arg6) 00168 : "r8", "r9", "r10", "r11" 00169 ); 00170 return rc; 00171 }; 00172 00174 inline Uintn operator()(EfiArg arg1, EfiArg arg2, EfiArg arg3, EfiArg arg4, 00175 EfiArg arg5, EfiArg arg6, EfiArg arg7) { 00176 Uintn rc; 00177 ASM ("subq $56, %%rsp\n" 00178 "mov %[arg3], %%r8\n" 00179 "mov %[arg4], %%r9\n" 00180 "mov %[arg5], %%rax\n" 00181 "mov %%rax, 32(%%rsp)\n" 00182 "mov %[arg6], %%rax\n" 00183 "mov %%rax, 40(%%rsp)\n" 00184 "mov %[arg7], %%rax\n" 00185 "mov %%rax, 48(%%rsp)\n" 00186 "call *%[func]\n" 00187 "addq $56, %%rsp\n" 00188 : "=&a"(rc) 00189 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00190 "c"(arg1), 00191 "d"(arg2), 00192 [arg3]"m"(arg3), 00193 [arg4]"m"(arg4), 00194 [arg5]"m"(arg5), 00195 [arg6]"m"(arg6), 00196 [arg7]"m"(arg7) 00197 : "r8", "r9", "r10", "r11" 00198 ); 00199 return rc; 00200 }; 00201 00203 inline Uintn operator()(EfiArg arg1, EfiArg arg2, EfiArg arg3, EfiArg arg4, 00204 EfiArg arg5, EfiArg arg6, EfiArg arg7, EfiArg arg8) { 00205 Uintn rc; 00206 ASM ("subq $72, %%rsp\n" 00207 "mov %[arg3], %%r8\n" 00208 "mov %[arg4], %%r9\n" 00209 "mov %[arg5], %%rax\n" 00210 "mov %%rax, 32(%%rsp)\n" 00211 "mov %[arg6], %%rax\n" 00212 "mov %%rax, 40(%%rsp)\n" 00213 "mov %[arg7], %%rax\n" 00214 "mov %%rax, 48(%%rsp)\n" 00215 "mov %[arg8], %%rax\n" 00216 "mov %%rax, 56(%%rsp)\n" 00217 "call *%[func]\n" 00218 "addq $72, %%rsp\n" 00219 : "=&a"(rc) 00220 : [func]"r"(vm::mm->PhysToVirt(_addr)), 00221 "c"(arg1), 00222 "d"(arg2), 00223 [arg3]"m"(arg3), 00224 [arg4]"m"(arg4), 00225 [arg5]"m"(arg5), 00226 [arg6]"m"(arg6), 00227 [arg7]"m"(arg7), 00228 [arg8]"m"(arg8) 00229 : "r8", "r9", "r10", "r11" 00230 ); 00231 return rc; 00232 }; 00233 00234 private: 00235 vm::Paddr _addr; 00236 }; 00237 00238 } /* namespace efi */ 00239 00240 #endif /* MD_EFI_H_ */