x86.h (3973B)
1 // Routines to let C code use special x86 instructions. 2 3 static inline uchar 4 inb(ushort port) 5 { 6 uchar data; 7 8 asm volatile("in %1,%0" : "=a" (data) : "d" (port)); 9 return data; 10 } 11 12 static inline void 13 insl(int port, void *addr, int cnt) 14 { 15 asm volatile("cld; rep insl" : 16 "=D" (addr), "=c" (cnt) : 17 "d" (port), "0" (addr), "1" (cnt) : 18 "memory", "cc"); 19 } 20 21 static inline void 22 outb(ushort port, uchar data) 23 { 24 asm volatile("out %0,%1" : : "a" (data), "d" (port)); 25 } 26 27 static inline void 28 outw(ushort port, ushort data) 29 { 30 asm volatile("out %0,%1" : : "a" (data), "d" (port)); 31 } 32 33 static inline void 34 outsl(int port, const void *addr, int cnt) 35 { 36 asm volatile("cld; rep outsl" : 37 "=S" (addr), "=c" (cnt) : 38 "d" (port), "0" (addr), "1" (cnt) : 39 "cc"); 40 } 41 42 static inline void 43 stosb(void *addr, int data, int cnt) 44 { 45 asm volatile("cld; rep stosb" : 46 "=D" (addr), "=c" (cnt) : 47 "0" (addr), "1" (cnt), "a" (data) : 48 "memory", "cc"); 49 } 50 51 static inline void 52 stosl(void *addr, int data, int cnt) 53 { 54 asm volatile("cld; rep stosl" : 55 "=D" (addr), "=c" (cnt) : 56 "0" (addr), "1" (cnt), "a" (data) : 57 "memory", "cc"); 58 } 59 60 struct segdesc; 61 62 static inline void 63 lgdt(struct segdesc *p, int size) 64 { 65 volatile ushort pd[5]; 66 67 pd[0] = size-1; 68 pd[1] = (uintp)p; 69 pd[2] = (uintp)p >> 16; 70 #if X64 71 pd[3] = (uintp)p >> 32; 72 pd[4] = (uintp)p >> 48; 73 #endif 74 asm volatile("lgdt (%0)" : : "r" (pd)); 75 } 76 77 struct gatedesc; 78 79 static inline void 80 lidt(struct gatedesc *p, int size) 81 { 82 volatile ushort pd[5]; 83 84 pd[0] = size-1; 85 pd[1] = (uintp)p; 86 pd[2] = (uintp)p >> 16; 87 #if X64 88 pd[3] = (uintp)p >> 32; 89 pd[4] = (uintp)p >> 48; 90 #endif 91 asm volatile("lidt (%0)" : : "r" (pd)); 92 } 93 94 static inline void 95 ltr(ushort sel) 96 { 97 asm volatile("ltr %0" : : "r" (sel)); 98 } 99 100 static inline uintp 101 readeflags(void) 102 { 103 uintp eflags; 104 asm volatile("pushf; pop %0" : "=r" (eflags)); 105 return eflags; 106 } 107 108 static inline void 109 loadgs(ushort v) 110 { 111 asm volatile("movw %0, %%gs" : : "r" (v)); 112 } 113 114 static inline void 115 cli(void) 116 { 117 asm volatile("cli"); 118 } 119 120 static inline void 121 sti(void) 122 { 123 asm volatile("sti"); 124 } 125 126 static inline void 127 hlt(void) 128 { 129 asm volatile("hlt"); 130 } 131 132 static inline uint 133 xchg(volatile uint *addr, uintp newval) 134 { 135 uint result; 136 137 // The + in "+m" denotes a read-modify-write operand. 138 asm volatile("lock; xchgl %0, %1" : 139 "+m" (*addr), "=a" (result) : 140 "1" (newval) : 141 "cc"); 142 return result; 143 } 144 145 static inline uintp 146 rcr2(void) 147 { 148 uintp val; 149 asm volatile("mov %%cr2,%0" : "=r" (val)); 150 return val; 151 } 152 153 static inline void 154 lcr3(uintp val) 155 { 156 asm volatile("mov %0,%%cr3" : : "r" (val)); 157 } 158 159 //PAGEBREAK: 36 160 // Layout of the trap frame built on the stack by the 161 // hardware and by trapasm.S, and passed to trap(). 162 #if X64 163 // lie about some register names in 64bit mode to avoid 164 // clunky ifdefs in proc.c and trap.c. 165 struct trapframe { 166 uint64 eax; // rax 167 uint64 rbx; 168 uint64 rcx; 169 uint64 rdx; 170 uint64 rbp; 171 uint64 rsi; 172 uint64 rdi; 173 uint64 r8; 174 uint64 r9; 175 uint64 r10; 176 uint64 r11; 177 uint64 r12; 178 uint64 r13; 179 uint64 r14; 180 uint64 r15; 181 182 uint64 trapno; 183 uint64 err; 184 185 uint64 eip; // rip 186 uint64 cs; 187 uint64 eflags; // rflags 188 uint64 esp; // rsp 189 uint64 ds; // ss 190 }; 191 #else 192 struct trapframe { 193 // registers as pushed by pusha 194 uint edi; 195 uint esi; 196 uint ebp; 197 uint oesp; // useless & ignored 198 uint ebx; 199 uint edx; 200 uint ecx; 201 uint eax; 202 203 // rest of trap frame 204 ushort gs; 205 ushort padding1; 206 ushort fs; 207 ushort padding2; 208 ushort es; 209 ushort padding3; 210 ushort ds; 211 ushort padding4; 212 uint trapno; 213 214 // below here defined by x86 hardware 215 uint err; 216 uint eip; 217 ushort cs; 218 ushort padding5; 219 uint eflags; 220 221 // below here only when crossing rings, such as from user to kernel 222 uint esp; 223 ushort ss; 224 ushort padding6; 225 }; 226 #endif