]> git.saurik.com Git - apple/xnu.git/blob - osfmk/x86_64/pal_routines_asm.s
xnu-1699.22.73.tar.gz
[apple/xnu.git] / osfmk / x86_64 / pal_routines_asm.s
1 /*
2 * Copyright (c) 2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <i386/asm.h>
30 #include <i386/asm64.h>
31
32 #include <assym.s>
33
34 /*
35 * Copy "count" bytes from "src" to %rsp, using
36 * "tmpindex" for a scratch counter and %rax
37 */
38 #define COPY_STACK(src, count, tmpindex) \
39 mov $0, tmpindex /* initial scratch counter */ ; \
40 1: \
41 mov 0(src,tmpindex,1), %rax /* copy one 64-bit word from source... */ ; \
42 mov %rax, 0(%rsp,tmpindex,1) /* ... to stack */ ; \
43 add $8, tmpindex /* increment counter */ ; \
44 cmp count, tmpindex /* exit it stack has been copied */ ; \
45 jne 1b
46
47 /*
48 void
49 pal_efi_call_in_64bit_mode_asm(uint64_t func,
50 struct pal_efi_registers *efi_reg,
51 void *stack_contents,
52 size_t stack_contents_size)
53
54 * Switch from compatibility mode to long mode, and
55 * then execute the function pointer with the specified
56 * register and stack contents (based at %rsp). Afterwards,
57 * collect the return value, restore the original state,
58 * and return.
59 */
60 ENTRY(_pal_efi_call_in_64bit_mode_asm)
61 FRAME
62
63 /* save non-volatile registers */
64 push %rbx
65 push %r12
66 push %r13
67 push %r14
68 push %r15
69
70 /* save parameters that we will need later */
71 push %rsi
72 push %rcx
73
74 sub $8, %rsp /* align to 16-byte boundary */
75 /* efi_reg in %rsi */
76 /* stack_contents into %rdx */
77 /* s_c_s into %rcx */
78 sub %rcx, %rsp /* make room for stack contents */
79
80 COPY_STACK(%rdx, %rcx, %r8)
81
82 /* load efi_reg into real registers */
83 mov 0(%rsi), %rcx
84 mov 8(%rsi), %rdx
85 mov 16(%rsi), %r8
86 mov 24(%rsi), %r9
87 mov 32(%rsi), %rax
88
89 /* func pointer in %rdi */
90 call *%rdi /* call EFI runtime */
91
92 mov -48(%rbp), %rsi /* load efi_reg into %esi */
93 mov %rax, 32(%rsi) /* save RAX back */
94
95 mov -56(%rbp), %rcx /* load s_c_s into %rcx */
96 add %rcx, %rsp /* discard stack contents */
97 add $8, %rsp /* restore stack pointer */
98
99 pop %rcx
100 pop %rsi
101 pop %r15
102 pop %r14
103 pop %r13
104 pop %r12
105 pop %rbx
106
107 EMARF
108 ret
109
110 /*
111 void
112 pal_efi_call_in_32bit_mode_asm(uint32_t func,
113 struct pal_efi_registers *efi_reg,
114 void *stack_contents,
115 size_t stack_contents_size)
116
117 */
118 ENTRY(_pal_efi_call_in_32bit_mode_asm)
119 FRAME
120
121 /* save non-volatile registers */
122 push %rbx
123 push %r12
124 push %r13
125 push %r14
126 push %r15
127
128 /* save parameters that we will need later */
129 push %rsi
130 push %rcx
131
132 push %rbp /* save %rbp and align to 16-byte boundary */
133 /* efi_reg in %rsi */
134 /* stack_contents into %rdx */
135 /* s_c_s into %rcx */
136 sub %rcx, %rsp /* make room for stack contents */
137
138 COPY_STACK(%rdx, %rcx, %r8)
139
140 /*
141 * Here in long-mode, with high kernel addresses,
142 * but with the kernel double-mapped in the bottom 4GB.
143 * We now switch to compat mode and call into EFI.
144 */
145 ENTER_COMPAT_MODE()
146
147 call *%edi /* call EFI runtime */
148
149 ENTER_64BIT_MODE()
150
151 mov -48(%rbp), %rsi /* load efi_reg into %esi */
152 mov %rax, 32(%rsi) /* save RAX back */
153
154 mov -56(%rbp), %rcx /* load s_c_s into %rcx */
155 add %rcx, %rsp /* discard stack contents */
156 pop %rbp /* restore full 64-bit frame pointer */
157 /* which the 32-bit EFI will have truncated */
158 /* our full %rsp will be restored by EMARF */
159 pop %rcx
160 pop %rsi
161 pop %r15
162 pop %r14
163 pop %r13
164 pop %r12
165 pop %rbx
166
167 EMARF
168 ret
169
170
171
172 /*
173 * void _pal_rtc_nanotime_store(
174 * uint64_t tsc, // %rdi
175 * uint64_t nsec, // %rsi
176 * uint32_t scale, // %rdx
177 * uint32_t shift, // %rcx
178 * rtc_nanotime_t *dst); // %r8
179 */
180 ENTRY(_pal_rtc_nanotime_store)
181 movl RNT_GENERATION(%r8),%eax /* get current generation */
182 movl $0,RNT_GENERATION(%r8) /* flag data as being updated */
183 movq %rdi,RNT_TSC_BASE(%r8)
184 movq %rsi,RNT_NS_BASE(%r8)
185 movl %edx,RNT_SCALE(%r8)
186 movl %ecx,RNT_SHIFT(%r8)
187
188 incl %eax /* next generation */
189 jnz 1f
190 incl %eax /* skip 0, which is a flag */
191 1: movl %eax,RNT_GENERATION(%r8) /* update generation */
192
193 ret
194