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 struct segdesc; 52 53 static inline void 54 lgdt(struct segdesc *p, int size) 55 { 56 volatile ushort pd[3]; 57 58 pd[0] = size-1; 59 pd[1] = (uint)p; 60 pd[2] = (uint)p >> 16; 61 62 asm volatile("lgdt (%0)" : : "r" (pd)); 63 } 64 65 struct gatedesc; 66 67 static inline void 68 lidt(struct gatedesc *p, int size) 69 { 70 volatile ushort pd[3]; 71 72 pd[0] = size-1; 73 pd[1] = (uint)p; 74 pd[2] = (uint)p >> 16; 75 76 asm volatile("lidt (%0)" : : "r" (pd)); 77 } 78 79 static inline void 80 ltr(ushort sel) 81 { 82 asm volatile("ltr %0" : : "r" (sel)); 83 } 84 85 static inline uint 86 readeflags(void) 87 { 88 uint eflags; 89 asm volatile("pushfl; popl %0" : "=r" (eflags)); 90 return eflags; 91 } 92 93 static inline void 94 loadgs(ushort v) 95 { 96 asm volatile("movw %0, %%gs" : : "r" (v)); 97 } 98 99 static inline uint 100 rebp(void) 101 { 102 uint val; 103 asm volatile("movl %%ebp,%0" : "=r" (val)); 104 return val; 105 } 106 107 static inline uint 108 resp(void) 109 { 110 uint val; 111 asm volatile("movl %%esp,%0" : "=r" (val)); 112 return val; 113 } 114 115 static inline void 116 cli(void) 117 { 118 asm volatile("cli"); 119 } 120 121 static inline void 122 sti(void) 123 { 124 asm volatile("sti"); 125 } 126 127 static inline uint 128 xchg(volatile uint *addr, uint newval) 129 { 130 uint result; 131 132 // The + in "+m" denotes a read-modify-write operand. 133 asm volatile("lock; xchgl %0, %1" : 134 "+m" (*addr), "=a" (result) : 135 "1" (newval) : 136 "cc"); 137 return result; 138 } 139 140 static inline void 141 nop_pause(void) 142 { 143 asm volatile("pause" : :); 144 } 145 146 //PAGEBREAK! 147 static inline void 148 lcr0(uint val) 149 { 150 asm volatile("movl %0,%%cr0" : : "r" (val)); 151 } 152 153 static inline uint 154 rcr0(void) 155 { 156 uint val; 157 asm volatile("movl %%cr0,%0" : "=r" (val)); 158 return val; 159 } 160 161 static inline uint 162 rcr2(void) 163 { 164 uint val; 165 asm volatile("movl %%cr2,%0" : "=r" (val)); 166 return val; 167 } 168 169 static inline void 170 lcr3(uint val) 171 { 172 asm volatile("movl %0,%%cr3" : : "r" (val)); 173 } 174 175 static inline uint 176 rcr3(void) 177 { 178 uint val; 179 asm volatile("movl %%cr3,%0" : "=r" (val)); 180 return val; 181 } 182 183 //PAGEBREAK: 36 184 // Layout of the trap frame built on the stack by the 185 // hardware and by trapasm.S, and passed to trap(). 186 struct trapframe { 187 // registers as pushed by pusha 188 uint edi; 189 uint esi; 190 uint ebp; 191 uint oesp; // useless & ignored 192 uint ebx; 193 uint edx; 194 uint ecx; 195 uint eax; 196 197 // rest of trap frame 198 ushort gs; 199 ushort padding1; 200 ushort fs; 201 ushort padding2; 202 ushort es; 203 ushort padding3; 204 ushort ds; 205 ushort padding4; 206 uint trapno; 207 208 // below here defined by x86 hardware 209 uint err; 210 uint eip; 211 ushort cs; 212 ushort padding5; 213 uint eflags; 214 215 // below here only when crossing rings, such as from user to kernel 216 uint esp; 217 ushort ss; 218 ushort padding6; 219 }; 220