Phoenix
Object-oriented orthogonally persistent operating system
md_efi.h
Go to the documentation of this file.
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_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines