1 /* 2 * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. 3 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. 4 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. 5 * Distributed under the terms of the MIT License. 6 * 7 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 8 * Distributed under the terms of the NewOS License. 9 */ 10 #ifndef _KERNEL_ARCH_x86_CPUASM_H 11 #define _KERNEL_ARCH_x86_CPUASM_H 12 13 14 #define nop() __asm__ ("nop"::) 15 16 #define x86_read_cr0() ({ \ 17 size_t _v; \ 18 __asm__("mov %%cr0,%0" : "=r" (_v)); \ 19 _v; \ 20 }) 21 22 #define x86_write_cr0(value) \ 23 __asm__("mov %0,%%cr0" : : "r" (value)) 24 25 #define x86_read_cr2() ({ \ 26 size_t _v; \ 27 __asm__("mov %%cr2,%0" : "=r" (_v)); \ 28 _v; \ 29 }) 30 31 #define x86_read_cr3() ({ \ 32 size_t _v; \ 33 __asm__("mov %%cr3,%0" : "=r" (_v)); \ 34 _v; \ 35 }) 36 37 static inline void 38 x86_write_cr3(size_t value) 39 { 40 __asm__("mov %0,%%cr3" : : "r" (value) : "memory"); 41 } 42 43 #define x86_read_cr4() ({ \ 44 size_t _v; \ 45 __asm__("mov %%cr4,%0" : "=r" (_v)); \ 46 _v; \ 47 }) 48 49 #define x86_write_cr4(value) \ 50 __asm__("mov %0,%%cr4" : : "r" (value)) 51 52 #define x86_read_dr3() ({ \ 53 size_t _v; \ 54 __asm__("mov %%dr3,%0" : "=r" (_v)); \ 55 _v; \ 56 }) 57 58 #define x86_write_dr3(value) \ 59 __asm__("mov %0,%%dr3" : : "r" (value)) 60 61 #define invalidate_TLB(va) \ 62 __asm__("invlpg (%0)" : : "r" (va)) 63 64 #define wbinvd() \ 65 __asm__ volatile ("wbinvd" : : : "memory") 66 67 #define arch_cpu_enable_user_access() \ 68 __asm__ volatile (ASM_STAC : : : "memory") 69 70 #define arch_cpu_disable_user_access() \ 71 __asm__ volatile (ASM_CLAC : : : "memory") 72 73 #define xgetbv(reg) ({ \ 74 uint32 low, high; \ 75 __asm__ volatile ("xgetbv" : "=a" (low), "=d" (high), "c" (reg)); \ 76 (low | (uint64)high << 32); \ 77 }) 78 79 #define xsetbv(reg, value) { \ 80 uint32 low = value; uint32 high = value >> 32; \ 81 __asm__ volatile ("xsetbv" : : "a" (low), "d" (high), "c" (reg)); } 82 83 #define out8(value,port) \ 84 __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port)) 85 86 #define out16(value,port) \ 87 __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port)) 88 89 #define out32(value,port) \ 90 __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port)) 91 92 #define in8(port) ({ \ 93 uint8 _v; \ 94 __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \ 95 _v; \ 96 }) 97 98 #define in16(port) ({ \ 99 uint16 _v; \ 100 __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \ 101 _v; \ 102 }) 103 104 #define in32(port) ({ \ 105 uint32 _v; \ 106 __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \ 107 _v; \ 108 }) 109 110 #define out8_p(value,port) \ 111 __asm__ ("outb %%al,%%dx\n" \ 112 "\tjmp 1f\n" \ 113 "1:\tjmp 1f\n" \ 114 "1:" : : "a" (value), "d" (port)) 115 116 #define in8_p(port) ({ \ 117 uint8 _v; \ 118 __asm__ volatile ("inb %%dx,%%al\n" \ 119 "\tjmp 1f\n" \ 120 "1:\tjmp 1f\n" \ 121 "1:" : "=a" (_v) : "d" (port)); \ 122 _v; \ 123 }) 124 125 126 #endif /* _KERNEL_ARCH_x86_CPUASM_H */ 127