7aa5574713
Only one code change: for some reason, GCC chokes on the cr3 functions as macros (throwing errors about invalid registers.) The BSDs have them as inline functions instead, so they are converted to that here. Tested and working. There seems to be about a 10% decrease in CPU time on some compilation benchmarks that I briefly tried. Change-Id: I31666297394d7619f83fca6ff5f933ddd6f07420 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4515 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
127 lines
2.7 KiB
C
127 lines
2.7 KiB
C
/*
|
|
* Copyright 2018, Jérôme Duval, jerome.duval@gmail.com.
|
|
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
|
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
* Distributed under the terms of the NewOS License.
|
|
*/
|
|
#ifndef _KERNEL_ARCH_x86_CPUASM_H
|
|
#define _KERNEL_ARCH_x86_CPUASM_H
|
|
|
|
|
|
#define nop() __asm__ ("nop"::)
|
|
|
|
#define x86_read_cr0() ({ \
|
|
size_t _v; \
|
|
__asm__("mov %%cr0,%0" : "=r" (_v)); \
|
|
_v; \
|
|
})
|
|
|
|
#define x86_write_cr0(value) \
|
|
__asm__("mov %0,%%cr0" : : "r" (value))
|
|
|
|
#define x86_read_cr2() ({ \
|
|
size_t _v; \
|
|
__asm__("mov %%cr2,%0" : "=r" (_v)); \
|
|
_v; \
|
|
})
|
|
|
|
#define x86_read_cr3() ({ \
|
|
size_t _v; \
|
|
__asm__("mov %%cr3,%0" : "=r" (_v)); \
|
|
_v; \
|
|
})
|
|
|
|
static inline void
|
|
x86_write_cr3(size_t value)
|
|
{
|
|
__asm__("mov %0,%%cr3" : : "r" (value) : "memory");
|
|
}
|
|
|
|
#define x86_read_cr4() ({ \
|
|
size_t _v; \
|
|
__asm__("mov %%cr4,%0" : "=r" (_v)); \
|
|
_v; \
|
|
})
|
|
|
|
#define x86_write_cr4(value) \
|
|
__asm__("mov %0,%%cr4" : : "r" (value))
|
|
|
|
#define x86_read_dr3() ({ \
|
|
size_t _v; \
|
|
__asm__("mov %%dr3,%0" : "=r" (_v)); \
|
|
_v; \
|
|
})
|
|
|
|
#define x86_write_dr3(value) \
|
|
__asm__("mov %0,%%dr3" : : "r" (value))
|
|
|
|
#define invalidate_TLB(va) \
|
|
__asm__("invlpg (%0)" : : "r" (va))
|
|
|
|
#define wbinvd() \
|
|
__asm__ volatile ("wbinvd" : : : "memory")
|
|
|
|
#define set_ac() \
|
|
__asm__ volatile (ASM_STAC : : : "memory")
|
|
|
|
#define clear_ac() \
|
|
__asm__ volatile (ASM_CLAC : : : "memory")
|
|
|
|
#define xgetbv(reg) ({ \
|
|
uint32 low, high; \
|
|
__asm__ volatile ("xgetbv" : "=a" (low), "=d" (high), "c" (reg)); \
|
|
(low | (uint64)high << 32); \
|
|
})
|
|
|
|
#define xsetbv(reg, value) { \
|
|
uint32 low = value; uint32 high = value >> 32; \
|
|
__asm__ volatile ("xsetbv" : : "a" (low), "d" (high), "c" (reg)); }
|
|
|
|
#define out8(value,port) \
|
|
__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
|
|
|
|
#define out16(value,port) \
|
|
__asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
|
|
|
|
#define out32(value,port) \
|
|
__asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
|
|
|
|
#define in8(port) ({ \
|
|
uint8 _v; \
|
|
__asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
|
|
_v; \
|
|
})
|
|
|
|
#define in16(port) ({ \
|
|
uint16 _v; \
|
|
__asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
|
|
_v; \
|
|
})
|
|
|
|
#define in32(port) ({ \
|
|
uint32 _v; \
|
|
__asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
|
|
_v; \
|
|
})
|
|
|
|
#define out8_p(value,port) \
|
|
__asm__ ("outb %%al,%%dx\n" \
|
|
"\tjmp 1f\n" \
|
|
"1:\tjmp 1f\n" \
|
|
"1:" : : "a" (value), "d" (port))
|
|
|
|
#define in8_p(port) ({ \
|
|
uint8 _v; \
|
|
__asm__ volatile ("inb %%dx,%%al\n" \
|
|
"\tjmp 1f\n" \
|
|
"1:\tjmp 1f\n" \
|
|
"1:" : "=a" (_v) : "d" (port)); \
|
|
_v; \
|
|
})
|
|
|
|
|
|
#endif /* _KERNEL_ARCH_x86_CPUASM_H */
|