/* * hal_cpu.S - Miscellaneous CPU functions * * Copyright (c) 2017 Maxime Villard * * This file is part of ALMOS-MKH. * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-MKH; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define x86_ASM #include #include #include ASM_ENTRY(lgdt) lgdt (%rdi) /* Reload the prefetch queue */ jmp 1f nop 1: /* Reload stale selectors */ movl $GDT_FIXED_SEL(GDT_KDATA_SEL, SEL_KPL),%eax movl %eax,%ds movl %eax,%es movl %eax,%ss ret ASM_ENTRY(lidt) lidt (%rdi) ret ASM_ENTRY(ltr) ltr %di ret ASM_ENTRY(invlpg) invlpg (%rdi) ret ASM_ENTRY(sti) sti ret ASM_ENTRY(cli) cli ret ASM_ENTRY(rdtsc) xorq %rax,%rax rdtsc shlq $32,%rdx orq %rdx,%rax ret ASM_ENTRY(in8) movq %rdi,%rdx xorq %rax,%rax inb %dx,%al ret ASM_ENTRY(in16) movq %rdi,%rdx xorq %rax,%rax inw %dx,%ax ret ASM_ENTRY(out8) movq %rdi,%rdx movq %rsi,%rax outb %al,%dx ret ASM_ENTRY(out16) movq %rdi,%rdx movq %rsi,%rax outw %ax,%dx ret ASM_ENTRY(rdmsr) movq %rdi,%rcx xorq %rax,%rax rdmsr shlq $32,%rdx orq %rdx,%rax ret ASM_ENTRY(wrmsr) movq %rdi,%rcx movq %rsi,%rax movq %rsi,%rdx shrq $32,%rdx wrmsr ret ASM_ENTRY(mfence) mfence ret ASM_ENTRY(rcr0) movq %cr0,%rax ret ASM_ENTRY(rcr2) movq %cr2,%rax ret ASM_ENTRY(rcr3) movq %cr3,%rax ret ASM_ENTRY(rcr4) movq %cr4,%rax ret ASM_ENTRY(lcr4) movq %rdi,%cr4 ret ASM_ENTRY(cpuid) movq %rbx,%r8 movq %rdi,%rax movq %rsi,%rcx movq %rdx,%rsi cpuid movl %eax,0(%rsi) movl %ebx,4(%rsi) movl %ecx,8(%rsi) movl %edx,12(%rsi) movq %r8,%rbx ret /* * To flush all TLB entries, we must re-set the CR4_PGE flag in %cr4. */ ASM_ENTRY(tlbflushg) movq %cr4,%rax movq %rax,%rdx andq $~CR4_PGE,%rdx movq %rdx,%cr4 movq %rax,%cr4 ret ASM_ENTRY(tlbflush) movq %cr3,%rax movq %rax,%cr3 ret ASM_ENTRY(x86_stop) /* debug only */ int $0x0b ret ASM_ENTRY(pause) pause ret ASM_ENTRY(wbinvd) wbinvd ret /* -------------------------------------------------------------------------- */ ASM_ENTRY(atomic_cas_32) movl %esi,%eax lock cmpxchgl %edx,(%rdi) /* %eax now contains the old value */ ret ASM_ENTRY(atomic_add_32) movl %esi,%eax lock xaddl %eax,(%rdi) /* %eax now contains the old value */ ret ASM_ENTRY(atomic_and_32) movl (%rdi),%eax 1: movl %eax,%ecx andl %esi,%ecx lock cmpxchgl %ecx,(%rdi) jnz 1b /* %eax now contains the old value */ ret ASM_ENTRY(atomic_or_32) movl (%rdi),%eax 1: movl %eax,%ecx orl %esi,%ecx lock cmpxchgl %ecx,(%rdi) jnz 1b /* %eax now contains the old value */ ret