Home | History | Annotate | Line # | Download | only in x86_64
      1  1.1  jakllsch /*	$NetBSD: efi_stub.S,v 1.1.1.1 2014/04/01 16:16:07 jakllsch Exp $	*/
      2  1.1  jakllsch 
      3  1.1  jakllsch /*
      4  1.1  jakllsch  * Function calling ABI conversion from Linux to EFI for x86_64
      5  1.1  jakllsch  *
      6  1.1  jakllsch  * Copyright (C) 2007 Intel Corp
      7  1.1  jakllsch  *	Bibo Mao <bibo.mao (at) intel.com>
      8  1.1  jakllsch  *	Huang Ying <ying.huang (at) intel.com>
      9  1.1  jakllsch  * Copyright (C) 2012 Felipe Contreras <felipe.contreras (at) gmail.com>
     10  1.1  jakllsch  */
     11  1.1  jakllsch 
     12  1.1  jakllsch #if !defined(HAVE_USE_MS_ABI)
     13  1.1  jakllsch /*
     14  1.1  jakllsch  * EFI calling conventions are documented at:
     15  1.1  jakllsch  *   http://msdn.microsoft.com/en-us/library/ms235286%28v=vs.80%29.aspx
     16  1.1  jakllsch  * ELF calling conventions are documented at:
     17  1.1  jakllsch  *   http://www.x86-64.org/documentation/abi.pdf
     18  1.1  jakllsch  *
     19  1.1  jakllsch  * Basically here are the conversion rules:
     20  1.1  jakllsch  * a) our function pointer is in %rdi
     21  1.1  jakllsch  * b) rsi through r8 (elf) aka rcx through r9 (ms) require stack space
     22  1.1  jakllsch  *    on the MS side even though it's not getting used at all.
     23  1.1  jakllsch  * c) 8(%rsp) is always aligned to 16 in ELF, so %rsp is shifted 8 bytes extra
     24  1.1  jakllsch  * d) arguments are as follows: (elf -> ms)
     25  1.1  jakllsch  *   1) rdi -> rcx (32 saved)
     26  1.1  jakllsch  *   2) rsi -> rdx (32 saved)
     27  1.1  jakllsch  *   3) rdx -> r8 (32 saved)
     28  1.1  jakllsch  *   4) rcx -> r9 (32 saved)
     29  1.1  jakllsch  *   5) r8 -> 32(%rsp) (32 saved)
     30  1.1  jakllsch  *   6) r9 -> 40(%rsp) (48 saved)
     31  1.1  jakllsch  *   7) 8(%rsp) -> 48(%rsp) (48 saved)
     32  1.1  jakllsch  *   8) 16(%rsp) -> 56(%rsp) (64 saved)
     33  1.1  jakllsch  *   9) 24(%rsp) -> 64(%rsp) (64 saved)
     34  1.1  jakllsch  *  10) 32(%rsp) -> 72(%rsp) (80 saved)
     35  1.1  jakllsch  * e) because the first argument we recieve in a thunker is actually the
     36  1.1  jakllsch  *    function to be called, arguments are offset as such:
     37  1.1  jakllsch  *   0) rdi -> caller
     38  1.1  jakllsch  *   1) rsi -> rcx (32 saved)
     39  1.1  jakllsch  *   2) rdx -> rdx (32 saved)
     40  1.1  jakllsch  *   3) rcx -> r8 (32 saved)
     41  1.1  jakllsch  *   4) r8 -> r9 (32 saved)
     42  1.1  jakllsch  *   5) r9 -> 32(%rsp) (32 saved)
     43  1.1  jakllsch  *   6) 8(%rsp) -> 40(%rsp) (48 saved)
     44  1.1  jakllsch  *   7) 16(%rsp) -> 48(%rsp) (48 saved)
     45  1.1  jakllsch  *   8) 24(%rsp) -> 56(%rsp) (64 saved)
     46  1.1  jakllsch  *   9) 32(%rsp) -> 64(%rsp) (64 saved)
     47  1.1  jakllsch  *  10) 40(%rsp) -> 72(%rsp) (80 saved)
     48  1.1  jakllsch  * f) arguments need to be moved in opposite order to avoid clobbering
     49  1.1  jakllsch  */
     50  1.1  jakllsch 
     51  1.1  jakllsch #define ENTRY(name)	\
     52  1.1  jakllsch 	.globl name;	\
     53  1.1  jakllsch 	name:
     54  1.1  jakllsch 
     55  1.1  jakllsch ENTRY(efi_call0)
     56  1.1  jakllsch 	subq $40, %rsp
     57  1.1  jakllsch 	call *%rdi
     58  1.1  jakllsch 	addq $40, %rsp
     59  1.1  jakllsch 	ret
     60  1.1  jakllsch 
     61  1.1  jakllsch ENTRY(efi_call1)
     62  1.1  jakllsch 	subq $40, %rsp
     63  1.1  jakllsch 	mov  %rsi, %rcx
     64  1.1  jakllsch 	call *%rdi
     65  1.1  jakllsch 	addq $40, %rsp
     66  1.1  jakllsch 	ret
     67  1.1  jakllsch 
     68  1.1  jakllsch ENTRY(efi_call2)
     69  1.1  jakllsch 	subq $40, %rsp
     70  1.1  jakllsch 	/* mov %rdx, %rdx */
     71  1.1  jakllsch 	mov  %rsi, %rcx
     72  1.1  jakllsch 	call *%rdi
     73  1.1  jakllsch 	addq $40, %rsp
     74  1.1  jakllsch 	ret
     75  1.1  jakllsch 
     76  1.1  jakllsch ENTRY(efi_call3)
     77  1.1  jakllsch 	subq $40, %rsp
     78  1.1  jakllsch 	mov  %rcx, %r8
     79  1.1  jakllsch 	/* mov %rdx, %rdx */
     80  1.1  jakllsch 	mov  %rsi, %rcx
     81  1.1  jakllsch 	call *%rdi
     82  1.1  jakllsch 	addq $40, %rsp
     83  1.1  jakllsch 	ret
     84  1.1  jakllsch 
     85  1.1  jakllsch ENTRY(efi_call4)
     86  1.1  jakllsch 	subq $40, %rsp
     87  1.1  jakllsch 	mov %r8, %r9
     88  1.1  jakllsch 	mov %rcx, %r8
     89  1.1  jakllsch 	/* mov %rdx, %rdx */
     90  1.1  jakllsch 	mov %rsi, %rcx
     91  1.1  jakllsch 	call *%rdi
     92  1.1  jakllsch 	addq $40, %rsp
     93  1.1  jakllsch 	ret
     94  1.1  jakllsch 
     95  1.1  jakllsch ENTRY(efi_call5)
     96  1.1  jakllsch 	subq $40, %rsp
     97  1.1  jakllsch 	mov %r9, 32(%rsp)
     98  1.1  jakllsch 	mov %r8, %r9
     99  1.1  jakllsch 	mov %rcx, %r8
    100  1.1  jakllsch 	/* mov %rdx, %rdx */
    101  1.1  jakllsch 	mov %rsi, %rcx
    102  1.1  jakllsch 	call *%rdi
    103  1.1  jakllsch 	addq $40, %rsp
    104  1.1  jakllsch 	ret
    105  1.1  jakllsch 
    106  1.1  jakllsch ENTRY(efi_call6)
    107  1.1  jakllsch 	subq $56, %rsp
    108  1.1  jakllsch 	mov 56+8(%rsp), %rax
    109  1.1  jakllsch 	mov %rax, 40(%rsp)
    110  1.1  jakllsch 	mov %r9, 32(%rsp)
    111  1.1  jakllsch 	mov %r8, %r9
    112  1.1  jakllsch 	mov %rcx, %r8
    113  1.1  jakllsch 	/* mov %rdx, %rdx */
    114  1.1  jakllsch 	mov %rsi, %rcx
    115  1.1  jakllsch 	call *%rdi
    116  1.1  jakllsch 	addq $56, %rsp
    117  1.1  jakllsch 	ret
    118  1.1  jakllsch 
    119  1.1  jakllsch ENTRY(efi_call7)
    120  1.1  jakllsch 	subq $56, %rsp
    121  1.1  jakllsch 	mov 56+16(%rsp), %rax
    122  1.1  jakllsch 	mov %rax, 48(%rsp)
    123  1.1  jakllsch 	mov 56+8(%rsp), %rax
    124  1.1  jakllsch 	mov %rax, 40(%rsp)
    125  1.1  jakllsch 	mov %r9, 32(%rsp)
    126  1.1  jakllsch 	mov %r8, %r9
    127  1.1  jakllsch 	mov %rcx, %r8
    128  1.1  jakllsch 	/* mov %rdx, %rdx */
    129  1.1  jakllsch 	mov %rsi, %rcx
    130  1.1  jakllsch 	call *%rdi
    131  1.1  jakllsch 	addq $56, %rsp
    132  1.1  jakllsch 	ret
    133  1.1  jakllsch 
    134  1.1  jakllsch ENTRY(efi_call8)
    135  1.1  jakllsch 	subq $72, %rsp
    136  1.1  jakllsch 	mov 72+24(%rsp), %rax
    137  1.1  jakllsch 	mov %rax, 56(%rsp)
    138  1.1  jakllsch 	mov 72+16(%rsp), %rax
    139  1.1  jakllsch 	mov %rax, 48(%rsp)
    140  1.1  jakllsch 	mov 72+8(%rsp), %rax
    141  1.1  jakllsch 	mov %rax, 40(%rsp)
    142  1.1  jakllsch 	mov %r9, 32(%rsp)
    143  1.1  jakllsch 	mov %r8, %r9
    144  1.1  jakllsch 	mov %rcx, %r8
    145  1.1  jakllsch 	/* mov %rdx, %rdx */
    146  1.1  jakllsch 	mov %rsi, %rcx
    147  1.1  jakllsch 	call *%rdi
    148  1.1  jakllsch 	addq $72, %rsp
    149  1.1  jakllsch 	ret
    150  1.1  jakllsch 
    151  1.1  jakllsch ENTRY(efi_call9)
    152  1.1  jakllsch 	subq $72, %rsp
    153  1.1  jakllsch 	mov 72+32(%rsp), %rax
    154  1.1  jakllsch 	mov %rax, 64(%rsp)
    155  1.1  jakllsch 	mov 72+24(%rsp), %rax
    156  1.1  jakllsch 	mov %rax, 56(%rsp)
    157  1.1  jakllsch 	mov 72+16(%rsp), %rax
    158  1.1  jakllsch 	mov %rax, 48(%rsp)
    159  1.1  jakllsch 	mov 72+8(%rsp), %rax
    160  1.1  jakllsch 	mov %rax, 40(%rsp)
    161  1.1  jakllsch 	mov %r9, 32(%rsp)
    162  1.1  jakllsch 	mov %r8, %r9
    163  1.1  jakllsch 	mov %rcx, %r8
    164  1.1  jakllsch 	/* mov %rdx, %rdx */
    165  1.1  jakllsch 	mov %rsi, %rcx
    166  1.1  jakllsch 	call *%rdi
    167  1.1  jakllsch 	addq $72, %rsp
    168  1.1  jakllsch 	ret
    169  1.1  jakllsch 
    170  1.1  jakllsch ENTRY(efi_call10)
    171  1.1  jakllsch 	subq $88, %rsp
    172  1.1  jakllsch 	mov 88+40(%rsp), %rax
    173  1.1  jakllsch 	mov %rax, 72(%rsp)
    174  1.1  jakllsch 	mov 88+32(%rsp), %rax
    175  1.1  jakllsch 	mov %rax, 64(%rsp)
    176  1.1  jakllsch 	mov 88+24(%rsp), %rax
    177  1.1  jakllsch 	mov %rax, 56(%rsp)
    178  1.1  jakllsch 	mov 88+16(%rsp), %rax
    179  1.1  jakllsch 	mov %rax, 48(%rsp)
    180  1.1  jakllsch 	mov 88+8(%rsp), %rax
    181  1.1  jakllsch 	mov %rax, 40(%rsp)
    182  1.1  jakllsch 	mov %r9, 32(%rsp)
    183  1.1  jakllsch 	mov %r8, %r9
    184  1.1  jakllsch 	mov %rcx, %r8
    185  1.1  jakllsch 	/* mov %rdx, %rdx */
    186  1.1  jakllsch 	mov %rsi, %rcx
    187  1.1  jakllsch 	call *%rdi
    188  1.1  jakllsch 	addq $88, %rsp
    189  1.1  jakllsch 	ret
    190  1.1  jakllsch 
    191  1.1  jakllsch #endif
    192