|
| 1 | +; |
| 2 | +; Copyright (c) 2011 Intel Corporation |
| 3 | +; Copyright (c) 2018 Alexandro Sanchez Bach <alexandro@phi.nz> |
| 4 | +; |
| 5 | +; Redistribution and use in source and binary forms, with or without |
| 6 | +; modification, are permitted provided that the following conditions are met: |
| 7 | +; |
| 8 | +; 1. Redistributions of source code must retain the above copyright notice, |
| 9 | +; this list of conditions and the following disclaimer. |
| 10 | +; |
| 11 | +; 2. Redistributions in binary form must reproduce the above copyright |
| 12 | +; notice, this list of conditions and the following disclaimer in the |
| 13 | +; documentation and/or other materials provided with the distribution. |
| 14 | +; |
| 15 | +; 3. Neither the name of the copyright holder nor the names of its |
| 16 | +; contributors may be used to endorse or promote products derived from |
| 17 | +; this software without specific prior written permission. |
| 18 | +; |
| 19 | +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 20 | +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 21 | +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 22 | +; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| 23 | +; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 24 | +; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 25 | +; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 26 | +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 27 | +; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 28 | +; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 29 | +; POSSIBILITY OF SUCH DAMAGE. |
| 30 | + |
| 31 | +; |
| 32 | +; Detect architecture |
| 33 | +; |
| 34 | +%ifidn __OUTPUT_FORMAT__, elf32 |
| 35 | + %define __BITS__ 32 |
| 36 | + %define __CONV__ x32_fastcall |
| 37 | +%elifidn __OUTPUT_FORMAT__, win32 |
| 38 | + %define __BITS__ 32 |
| 39 | + %define __CONV__ x32_fastcall |
| 40 | +%elifidn __OUTPUT_FORMAT__, macho32 |
| 41 | + %define __BITS__ 32 |
| 42 | + %define __CONV__ x32_fastcall |
| 43 | +%elifidn __OUTPUT_FORMAT__, elf64 |
| 44 | + %define __BITS__ 64 |
| 45 | + %define __CONV__ x64_systemv |
| 46 | +%elifidn __OUTPUT_FORMAT__, win64 |
| 47 | + %define __BITS__ 64 |
| 48 | + %define __CONV__ x64_microsoft |
| 49 | +%elifidn __OUTPUT_FORMAT__, macho64 |
| 50 | + %define __BITS__ 64 |
| 51 | + %define __CONV__ x64_systemv |
| 52 | +%endif |
| 53 | + |
| 54 | +; |
| 55 | +; Describe calling convention |
| 56 | +; |
| 57 | +%ifidn __CONV__, x32_fastcall |
| 58 | + %define reg_arg1_16 cx |
| 59 | + %define reg_arg1_32 ecx |
| 60 | + %define reg_arg1 reg_arg1_32 |
| 61 | + %define reg_arg2_16 dx |
| 62 | + %define reg_arg2_32 edx |
| 63 | + %define reg_arg2 reg_arg2_32 |
| 64 | + %define reg_ret_16 ax |
| 65 | + %define reg_ret_32 eax |
| 66 | + %define reg_ret reg_ret_32 |
| 67 | +%elifidn __CONV__, x64_systemv |
| 68 | + %define reg_arg1_16 di |
| 69 | + %define reg_arg1_32 edi |
| 70 | + %define reg_arg1_64 rdi |
| 71 | + %define reg_arg1 reg_arg1_64 |
| 72 | + %define reg_arg2_16 si |
| 73 | + %define reg_arg2_32 esi |
| 74 | + %define reg_arg2_64 rsi |
| 75 | + %define reg_arg2 reg_arg2_64 |
| 76 | + %define reg_ret_16 ax |
| 77 | + %define reg_ret_32 eax |
| 78 | + %define reg_ret_64 rax |
| 79 | + %define reg_ret reg_ret_64 |
| 80 | +%elifidn __CONV__, x64_microsoft |
| 81 | + %define reg_arg1_16 cx |
| 82 | + %define reg_arg1_32 ecx |
| 83 | + %define reg_arg1_64 rcx |
| 84 | + %define reg_arg1 reg_arg1_64 |
| 85 | + %define reg_arg2_16 dx |
| 86 | + %define reg_arg2_32 edx |
| 87 | + %define reg_arg2_64 rdx |
| 88 | + %define reg_arg2 reg_arg2_64 |
| 89 | + %define reg_ret_16 ax |
| 90 | + %define reg_ret_32 eax |
| 91 | + %define reg_ret_64 rax |
| 92 | + %define reg_ret reg_ret_64 |
| 93 | +%endif |
| 94 | + |
| 95 | +; |
| 96 | +; Helpers |
| 97 | +; |
| 98 | +%macro function 1 |
| 99 | + global %1 |
| 100 | + %1: |
| 101 | +%endmacro |
| 102 | + |
| 103 | +%macro function_get_reg 1 |
| 104 | + function get_%+%1 |
| 105 | + mov reg_ret, %1 |
| 106 | + ret |
| 107 | +%endmacro |
| 108 | +%macro function_set_reg 1 |
| 109 | + function set_%+%1 |
| 110 | + mov %1, reg_arg1 |
| 111 | + ret |
| 112 | +%endmacro |
| 113 | +%macro function_get_segment 1 |
| 114 | + function get_kernel_%+%1 |
| 115 | + mov reg_ret_16, %1 |
| 116 | + ret |
| 117 | +%endmacro |
| 118 | +%macro function_set_segment 1 |
| 119 | + function set_kernel_%+%1 |
| 120 | + mov %1, reg_arg1_16 |
| 121 | + ret |
| 122 | +%endmacro |
| 123 | + |
| 124 | +section .text |
| 125 | + |
| 126 | +struc qword_struct |
| 127 | + .lo resd 1 |
| 128 | + .hi resd 1 |
| 129 | +endstruc |
| 130 | + |
| 131 | +struc vcpu_state |
| 132 | + ._rax resq 1 |
| 133 | + ._rcx resq 1 |
| 134 | + ._rdx resq 1 |
| 135 | + ._rbx resq 1 |
| 136 | + ._rsp resq 1 |
| 137 | + ._rbp resq 1 |
| 138 | + ._rsi resq 1 |
| 139 | + ._rdi resq 1 |
| 140 | + ._r8 resq 1 |
| 141 | + ._r9 resq 1 |
| 142 | + ._r10 resq 1 |
| 143 | + ._r11 resq 1 |
| 144 | + ._r12 resq 1 |
| 145 | + ._r13 resq 1 |
| 146 | + ._r14 resq 1 |
| 147 | + ._r15 resq 1 |
| 148 | +endstruc |
| 149 | + |
| 150 | +struc cpuid_args |
| 151 | + ._eax resd 1 |
| 152 | + ._ecx resd 1 |
| 153 | + ._edx resd 1 |
| 154 | + ._ebx resd 1 |
| 155 | +endstruc |
| 156 | + |
| 157 | +function __nmi |
| 158 | + int 2h |
| 159 | + ret |
| 160 | + |
| 161 | +function __fls |
| 162 | + bsr eax, ecx |
| 163 | + ret |
| 164 | + |
| 165 | +function __handle_cpuid |
| 166 | +%ifidn __BITS__, 64 |
| 167 | + push rbx |
| 168 | + mov r8, rcx |
| 169 | + mov rax, [r8 + vcpu_state._rax] |
| 170 | + mov rcx, [r8 + vcpu_state._rcx] |
| 171 | + cpuid |
| 172 | + mov [r8 + vcpu_state._rax], rax |
| 173 | + mov [r8 + vcpu_state._rbx], rbx |
| 174 | + mov [r8 + vcpu_state._rcx], rcx |
| 175 | + mov [r8 + vcpu_state._rdx], rdx |
| 176 | + pop rbx |
| 177 | + ret |
| 178 | +%else |
| 179 | + push ebx |
| 180 | + push esi |
| 181 | + mov esi, reg_arg1 |
| 182 | + mov eax, [esi + vcpu_state._rax] |
| 183 | + mov ecx, [esi + vcpu_state._rcx] |
| 184 | + cpuid |
| 185 | + mov [esi + vcpu_state._rax], eax |
| 186 | + mov [esi + vcpu_state._rbx], ebx |
| 187 | + mov [esi + vcpu_state._rcx], ecx |
| 188 | + mov [esi + vcpu_state._rdx], edx |
| 189 | + pop esi |
| 190 | + pop ebx |
| 191 | + ret |
| 192 | +%endif |
| 193 | + |
| 194 | +function asm_btr |
| 195 | + lock btr [reg_arg1], reg_arg2 |
| 196 | + ret |
| 197 | + |
| 198 | +function asm_bts |
| 199 | + lock bts [reg_arg1], reg_arg2 |
| 200 | + ret |
| 201 | + |
| 202 | +function asm_disable_irq |
| 203 | + cli |
| 204 | + ret |
| 205 | + |
| 206 | +function asm_enable_irq |
| 207 | + sti |
| 208 | + ret |
| 209 | + |
| 210 | +function asm_fxinit |
| 211 | + finit |
| 212 | + ret |
| 213 | + |
| 214 | +function asm_fxrstor |
| 215 | + fxrstor [reg_arg1] |
| 216 | + ret |
| 217 | + |
| 218 | +function asm_fxsave |
| 219 | + fxsave [reg_arg1] |
| 220 | + ret |
| 221 | + |
| 222 | +function asm_rdmsr |
| 223 | +%ifidn __BITS__, 64 |
| 224 | + mov rcx, reg_arg1 |
| 225 | + rdmsr |
| 226 | + shl rdx, 32 |
| 227 | + or rax, rdx |
| 228 | + ret |
| 229 | +%else |
| 230 | + mov ecx, reg_arg1 |
| 231 | + rdmsr |
| 232 | + mov [reg_arg2 + qword_struct.lo], eax |
| 233 | + mov [reg_arg2 + qword_struct.hi], edx |
| 234 | + ret |
| 235 | +%endif |
| 236 | + |
| 237 | +function asm_rdtsc |
| 238 | +%ifidn __BITS__, 64 |
| 239 | + rdtsc |
| 240 | + shl rdx, 32 |
| 241 | + or rax, rdx |
| 242 | + ret |
| 243 | +%else |
| 244 | + rdtsc |
| 245 | + mov [reg_arg2 + qword_struct.lo], eax |
| 246 | + mov [reg_arg2 + qword_struct.hi], edx |
| 247 | + ret |
| 248 | +%endif |
| 249 | + |
| 250 | +function asm_wrmsr |
| 251 | +%ifidn __BITS__, 64 |
| 252 | + push rbx |
| 253 | + mov rbx, reg_arg2 |
| 254 | + mov rcx, reg_arg1 |
| 255 | + mov eax, ebx |
| 256 | + mov rdx, rbx |
| 257 | + shl rdx, 32 |
| 258 | + wrmsr |
| 259 | + push rbx |
| 260 | + ret |
| 261 | +%else |
| 262 | + push edi |
| 263 | + push esi |
| 264 | + mov edi, [reg_arg2 + qword_struct.lo] |
| 265 | + mov esi, [reg_arg2 + qword_struct.hi] |
| 266 | + mov ecx, reg_arg1 |
| 267 | + mov eax, edi |
| 268 | + mov edx, esi |
| 269 | + wrmsr |
| 270 | + push esi |
| 271 | + push edi |
| 272 | + ret |
| 273 | +%endif |
| 274 | + |
| 275 | +function get_kernel_rflags |
| 276 | + pushf |
| 277 | + pop ax |
| 278 | + ret |
| 279 | + |
| 280 | +function_get_reg cr0 |
| 281 | +function_get_reg cr2 |
| 282 | +function_get_reg cr3 |
| 283 | +function_get_reg cr4 |
| 284 | +function_get_reg dr0 |
| 285 | +function_get_reg dr1 |
| 286 | +function_get_reg dr2 |
| 287 | +function_get_reg dr3 |
| 288 | +function_get_reg dr6 |
| 289 | +function_get_reg dr7 |
| 290 | + |
| 291 | +function_set_reg cr0 |
| 292 | +function_set_reg cr2 |
| 293 | +function_set_reg cr3 |
| 294 | +function_set_reg cr4 |
| 295 | +function_set_reg dr0 |
| 296 | +function_set_reg dr1 |
| 297 | +function_set_reg dr2 |
| 298 | +function_set_reg dr3 |
| 299 | +function_set_reg dr6 |
| 300 | +function_set_reg dr7 |
| 301 | + |
| 302 | +function_get_segment cs |
| 303 | +function_get_segment ds |
| 304 | +function_get_segment es |
| 305 | +function_get_segment ss |
| 306 | +function_get_segment gs |
| 307 | +function_get_segment fs |
| 308 | + |
| 309 | +function_set_segment cs |
| 310 | +function_set_segment ds |
| 311 | +function_set_segment es |
| 312 | +function_set_segment ss |
| 313 | +function_set_segment gs |
| 314 | +function_set_segment fs |
0 commit comments