btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / system / kernel / arch / x86 / 64 / syscalls.cpp
blob174755f5a054b78fe2156e9ca0129d28f4464b61
1 /*
2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "x86_syscalls.h"
9 #include <KernelExport.h>
11 #include <cpu.h>
12 #include <smp.h>
15 // SYSCALL handler (in interrupts.S).
16 extern "C" void x86_64_syscall_entry(void);
19 static void
20 init_syscall_registers(void* dummy, int cpuNum)
22 // Enable SYSCALL (EFER.SCE = 1).
23 x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER)
24 | IA32_MSR_EFER_SYSCALL);
26 // Flags to clear upon entry. Want interrupts disabled and the direction
27 // flag cleared.
28 x86_write_msr(IA32_MSR_FMASK, X86_EFLAGS_INTERRUPT | X86_EFLAGS_DIRECTION);
30 // Entry point address.
31 x86_write_msr(IA32_MSR_LSTAR, (addr_t)x86_64_syscall_entry);
33 // Segments that will be set upon entry and return. This is very strange
34 // and requires a specific ordering of segments in the GDT. Upon entry:
35 // - CS is set to IA32_STAR[47:32]
36 // - SS is set to IA32_STAR[47:32] + 8
37 // Upon return:
38 // - CS is set to IA32_STAR[63:48] + 16
39 // - SS is set to IA32_STAR[63:48] + 8
40 // From this we get:
41 // - Entry CS = KERNEL_CODE_SELECTOR
42 // - Entry SS = KERNEL_CODE_SELECTOR + 8 = KERNEL_DATA_SELECTOR
43 // - Return CS = KERNEL_DATA_SELECTOR + 16 = USER_CODE_SELECTOR
44 // - Return SS = KERNEL_DATA_SELECTOR + 8 = USER_DATA_SLECTORG
45 x86_write_msr(IA32_MSR_STAR, ((uint64)(KERNEL_DATA_SELECTOR | 3) << 48)
46 | ((uint64)KERNEL_CODE_SELECTOR << 32));
50 // #pragma mark -
53 void
54 x86_initialize_syscall(void)
56 // SYSCALL/SYSRET are always available on x86_64 so we just use them, no
57 // need to use the commpage. Tell all CPUs to initialize the SYSCALL MSRs.
58 call_all_cpus_sync(&init_syscall_registers, NULL);