2 -- Copyright (C) 2013, 2014 Reto Buerki <reet@codelabs.ch>
3 -- Copyright (C) 2013, 2014 Adrian-Ken Rueegsegger <ken@codelabs.ch>
5 -- This program is free software: you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation, either version 3 of the License, or
8 -- (at your option) any later version.
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
19 with System.Machine_Code;
24 -- RDTSC (Read Time-Stamp Counter). The EDX register is loaded with the
25 -- high-order 32 bits of the TSC MSR and the EAX register is loaded with
26 -- the low-order 32 bits.
31 Global => (Input => X86_64.State),
33 pragma Annotate (GNATprove, Terminating, RDTSC);
35 -------------------------------------------------------------------------
42 System.Machine_Code.Asm
47 -------------------------------------------------------------------------
50 (EAX : in out SK.Word32;
52 ECX : in out SK.Word32;
58 System.Machine_Code.Asm
60 Inputs => (SK.Word32'Asm_Input ("a", EAX),
61 SK.Word32'Asm_Input ("c", ECX)),
62 Outputs => (SK.Word32'Asm_Output ("=a", EAX),
63 SK.Word32'Asm_Output ("=b", EBX),
64 SK.Word32'Asm_Output ("=c", ECX),
65 SK.Word32'Asm_Output ("=d", EDX)));
68 -------------------------------------------------------------------------
70 function Get_CR0 return SK.Word64
76 System.Machine_Code.Asm
77 (Template => "movq %%cr0, %0",
78 Outputs => (SK.Word64'Asm_Output ("=r", Result)),
83 -------------------------------------------------------------------------
85 function Get_CR2 return SK.Word64
91 System.Machine_Code.Asm
92 (Template => "movq %%cr2, %0",
93 Outputs => (SK.Word64'Asm_Output ("=r", Result)),
98 -------------------------------------------------------------------------
100 function Get_CR3 return SK.Word64
106 System.Machine_Code.Asm
107 (Template => "movq %%cr3, %0",
108 Outputs => (SK.Word64'Asm_Output ("=r", Result)),
113 -------------------------------------------------------------------------
115 function Get_CR4 return SK.Word64
121 System.Machine_Code.Asm
122 (Template => "movq %%cr4, %0",
123 Outputs => (SK.Word64'Asm_Output ("=r", Result)),
128 -------------------------------------------------------------------------
131 (Register : SK.Word32;
133 High : out SK.Word32)
138 System.Machine_Code.Asm
139 (Template => "rdmsr",
140 Inputs => (SK.Word32'Asm_Input ("c", Register)),
141 Outputs => (SK.Word32'Asm_Output ("=d", High),
142 SK.Word32'Asm_Output ("=a", Low)),
145 pragma Annotate (GNATprove, Terminating, Get_MSR);
147 -------------------------------------------------------------------------
149 function Get_MSR64 (Register : SK.Word32) return SK.Word64
151 Low_Dword, High_Dword : SK.Word32;
153 Get_MSR (Register => Register,
156 return 2 ** 32 * SK.Word64 (High_Dword) + SK.Word64 (Low_Dword);
159 -------------------------------------------------------------------------
161 function Get_RFLAGS return SK.Word64
167 System.Machine_Code.Asm
168 (Template => "pushf; pop %0",
169 Outputs => (SK.Word64'Asm_Output ("=m", Result)),
171 Clobber => "memory");
175 -------------------------------------------------------------------------
182 System.Machine_Code.Asm
187 -------------------------------------------------------------------------
189 procedure Lgdt (Descriptor : Pseudo_Descriptor_Type)
194 System.Machine_Code.Asm
195 (Template => "lgdt %0",
196 Inputs => (Pseudo_Descriptor_Type'Asm_Input ("m", Descriptor)),
200 -------------------------------------------------------------------------
202 procedure Lidt (Descriptor : Pseudo_Descriptor_Type)
207 System.Machine_Code.Asm
208 (Template => "lidt %0",
209 Inputs => (Pseudo_Descriptor_Type'Asm_Input ("m", Descriptor)),
213 -------------------------------------------------------------------------
215 procedure Ltr (Address : SK.Word16)
220 System.Machine_Code.Asm
221 (Template => "ltr %%ax",
222 Inputs => (SK.Word16'Asm_Input ("a", Address)),
226 -------------------------------------------------------------------------
233 System.Machine_Code.Asm
234 (Template => "pause",
238 -------------------------------------------------------------------------
241 (EAX : out SK.Word32;
247 System.Machine_Code.Asm
248 (Template => "rdtsc",
250 (SK.Word32'Asm_Output ("=a", EAX),
251 SK.Word32'Asm_Output ("=d", EDX)),
255 -------------------------------------------------------------------------
257 function RDTSC return SK.Word64
259 Low_Dword, High_Dword : SK.Word32;
261 RDTSC (EAX => Low_Dword,
263 return 2 ** 32 * SK.Word64 (High_Dword) + SK.Word64 (Low_Dword);
266 -------------------------------------------------------------------------
268 procedure Set_CR2 (Value : SK.Word64)
273 System.Machine_Code.Asm
274 (Template => "movq %0, %%cr2",
275 Inputs => (SK.Word64'Asm_Input ("r", Value)),
279 -------------------------------------------------------------------------
281 procedure Set_CR4 (Value : SK.Word64)
286 System.Machine_Code.Asm
287 (Template => "movq %0, %%cr4",
288 Inputs => (SK.Word64'Asm_Input ("r", Value)),
292 -------------------------------------------------------------------------
299 System.Machine_Code.Asm
304 -------------------------------------------------------------------------
315 -------------------------------------------------------------------------
318 (Register : SK.Word32;
325 System.Machine_Code.Asm
326 (Template => "wrmsr",
327 Inputs => (Word32'Asm_Input ("a", Low),
328 Word32'Asm_Input ("d", High),
329 Word32'Asm_Input ("c", Register)),
333 -------------------------------------------------------------------------
335 procedure Write_MSR64
336 (Register : SK.Word32;
339 Low_Dword, High_Dword : SK.Word32;
341 Low_Dword := SK.Word32'Mod (Value);
342 High_Dword := SK.Word32'Mod (Value / 2 ** 32);
344 Write_MSR (Register => Register,
349 -------------------------------------------------------------------------
352 (Register : SK.Word32;
353 Value : out SK.Word64)
357 Low_Dword, High_Dword : SK.Word32;
359 System.Machine_Code.Asm
360 (Template => "xgetbv",
361 Inputs => Word32'Asm_Input ("c", Register),
362 Outputs => (Word32'Asm_Output ("=a", Low_Dword),
363 Word32'Asm_Output ("=d", High_Dword)));
364 Value := Word64 (High_Dword) * 2 ** 32 + Word64 (Low_Dword);
367 -------------------------------------------------------------------------
370 (Source : XSAVE_Area_Type;
375 Low_Dword : constant Word32 := Word32'Mod (State);
376 High_Dword : constant Word32 := Word32'Mod (State / 2 ** 32);
379 -- Restore mask in EDX:EAX specifies to restore x87, SSE and AVX
380 -- registers, see Intel SDM Vol. 3A, "2.6 Extended Control Registers
381 -- (Including XCR0)".
383 System.Machine_Code.Asm
384 (Template => "xrstor64 %2",
385 Inputs => (Word32'Asm_Input ("a", Low_Dword),
386 Word32'Asm_Input ("d", High_Dword),
387 XSAVE_Area_Type'Asm_Input ("m", Source)),
391 -------------------------------------------------------------------------
394 (Target : out XSAVE_Area_Type;
399 Low_Dword : constant Word32 := Word32'Mod (State);
400 High_Dword : constant Word32 := Word32'Mod (State / 2 ** 32);
403 -- Save mask in EDX:EAX specifies to save x87, SSE and AVX registers,
404 -- see Intel SDM Vol. 3A, "2.6 Extended Control Registers (Including
407 System.Machine_Code.Asm
408 (Template => "xsaveopt64 %0",
409 Inputs => (Word32'Asm_Input ("a", Low_Dword),
410 Word32'Asm_Input ("d", High_Dword)),
411 Outputs => (XSAVE_Area_Type'Asm_Output ("=m", Target)),
415 -------------------------------------------------------------------------
418 (Register : SK.Word32;
423 Low_Dword, High_Dword : SK.Word32;
425 Low_Dword := SK.Word32'Mod (Value);
426 High_Dword := SK.Word32'Mod (Value / 2 ** 32);
428 System.Machine_Code.Asm
429 (Template => "xsetbv",
430 Inputs => (Word32'Asm_Input ("a", Low_Dword),
431 Word32'Asm_Input ("d", High_Dword),
432 Word32'Asm_Input ("c", Register)),