1 static __inline void breakpoint(void) __attribute__((always_inline)); 2 static __inline uchar inb(int port) __attribute__((always_inline)); 3 static __inline void insb(int port, void *addr, int cnt) __attribute__((always_inline)); 4 static __inline ushort inw(int port) __attribute__((always_inline)); 5 static __inline void insw(int port, void *addr, int cnt) __attribute__((always_inline)); 6 static __inline uint inl(int port) __attribute__((always_inline)); 7 static __inline void insl(int port, void *addr, int cnt) __attribute__((always_inline)); 8 static __inline void outb(int port, uchar data) __attribute__((always_inline)); 9 static __inline void outsb(int port, const void *addr, int cnt) __attribute__((always_inline)); 10 static __inline void outw(int port, ushort data) __attribute__((always_inline)); 11 static __inline void outsw(int port, const void *addr, int cnt) __attribute__((always_inline)); 12 static __inline void outsl(int port, const void *addr, int cnt) __attribute__((always_inline)); 13 static __inline void outl(int port, uint data) __attribute__((always_inline)); 14 static __inline void invlpg(void *addr) __attribute__((always_inline)); 15 struct segdesc; 16 static __inline void lgdt(struct segdesc *p, int) __attribute__((always_inline)); 17 struct gatedesc; 18 static __inline void lidt(struct gatedesc *p, int) __attribute__((always_inline)); 19 static __inline void lldt(ushort sel) __attribute__((always_inline)); 20 static __inline void ltr(ushort sel) __attribute__((always_inline)); 21 static __inline void lcr0(uint val) __attribute__((always_inline)); 22 static __inline uint rcr0(void) __attribute__((always_inline)); 23 static __inline uint rcr2(void) __attribute__((always_inline)); 24 static __inline void lcr3(uint val) __attribute__((always_inline)); 25 static __inline uint rcr3(void) __attribute__((always_inline)); 26 static __inline void lcr4(uint val) __attribute__((always_inline)); 27 static __inline uint rcr4(void) __attribute__((always_inline)); 28 static __inline void tlbflush(void) __attribute__((always_inline)); 29 static __inline uint read_eflags(void) __attribute__((always_inline)); 30 static __inline void write_eflags(uint eflags) __attribute__((always_inline)); 31 static __inline uint read_ebp(void) __attribute__((always_inline)); 32 static __inline uint read_esp(void) __attribute__((always_inline)); 33 static __inline void cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp); 34 static __inline void cli(void) __attribute__((always_inline)); 35 static __inline void sti(void) __attribute__((always_inline)); 36 37 static __inline void 38 breakpoint(void) 39 { 40 __asm __volatile("int3"); 41 } 42 43 static __inline uchar 44 inb(int port) 45 { 46 uchar data; 47 __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port)); 48 return data; 49 } 50 51 static __inline void 52 insb(int port, void *addr, int cnt) 53 { 54 __asm __volatile("cld\n\trepne\n\tinsb" : 55 "=D" (addr), "=c" (cnt) : 56 "d" (port), "0" (addr), "1" (cnt) : 57 "memory", "cc"); 58 } 59 60 static __inline ushort 61 inw(int port) 62 { 63 ushort data; 64 __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port)); 65 return data; 66 } 67 68 static __inline void 69 insw(int port, void *addr, int cnt) 70 { 71 __asm __volatile("cld\n\trepne\n\tinsw" : 72 "=D" (addr), "=c" (cnt) : 73 "d" (port), "0" (addr), "1" (cnt) : 74 "memory", "cc"); 75 } 76 77 static __inline uint 78 inl(int port) 79 { 80 uint data; 81 __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port)); 82 return data; 83 } 84 85 static __inline void 86 insl(int port, void *addr, int cnt) 87 { 88 __asm __volatile("cld\n\trepne\n\tinsl" : 89 "=D" (addr), "=c" (cnt) : 90 "d" (port), "0" (addr), "1" (cnt) : 91 "memory", "cc"); 92 } 93 94 static __inline void 95 outb(int port, uchar data) 96 { 97 __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port)); 98 } 99 100 static __inline void 101 outsb(int port, const void *addr, int cnt) 102 { 103 __asm __volatile("cld\n\trepne\n\toutsb" : 104 "=S" (addr), "=c" (cnt) : 105 "d" (port), "0" (addr), "1" (cnt) : 106 "cc"); 107 } 108 109 static __inline void 110 outw(int port, ushort data) 111 { 112 __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port)); 113 } 114 115 static __inline void 116 outsw(int port, const void *addr, int cnt) 117 { 118 __asm __volatile("cld\n\trepne\n\toutsw" : 119 "=S" (addr), "=c" (cnt) : 120 "d" (port), "0" (addr), "1" (cnt) : 121 "cc"); 122 } 123 124 static __inline void 125 outsl(int port, const void *addr, int cnt) 126 { 127 __asm __volatile("cld\n\trepne\n\toutsl" : 128 "=S" (addr), "=c" (cnt) : 129 "d" (port), "0" (addr), "1" (cnt) : 130 "cc"); 131 } 132 133 static __inline void 134 outl(int port, uint data) 135 { 136 __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port)); 137 } 138 139 static __inline void 140 invlpg(void *addr) 141 { 142 __asm __volatile("invlpg (%0)" : : "r" (addr) : "memory"); 143 } 144 145 static __inline void 146 lgdt(struct segdesc *p, int size) 147 { 148 volatile ushort pd[3]; 149 150 pd[0] = size-1; 151 pd[1] = (uint)p; 152 pd[2] = (uint)p >> 16; 153 154 asm volatile("lgdt (%0)" : : "g" (pd)); 155 } 156 157 static __inline void 158 lidt(struct gatedesc *p, int size) 159 { 160 volatile ushort pd[3]; 161 162 pd[0] = size-1; 163 pd[1] = (uint)p; 164 pd[2] = (uint)p >> 16; 165 166 asm volatile("lidt (%0)" : : "g" (pd)); 167 } 168 169 static __inline void 170 lldt(ushort sel) 171 { 172 __asm __volatile("lldt %0" : : "r" (sel)); 173 } 174 175 static __inline void 176 ltr(ushort sel) 177 { 178 __asm __volatile("ltr %0" : : "r" (sel)); 179 } 180 181 static __inline void 182 lcr0(uint val) 183 { 184 __asm __volatile("movl %0,%%cr0" : : "r" (val)); 185 } 186 187 static __inline uint 188 rcr0(void) 189 { 190 uint val; 191 __asm __volatile("movl %%cr0,%0" : "=r" (val)); 192 return val; 193 } 194 195 static __inline uint 196 rcr2(void) 197 { 198 uint val; 199 __asm __volatile("movl %%cr2,%0" : "=r" (val)); 200 return val; 201 } 202 203 static __inline void 204 lcr3(uint val) 205 { 206 __asm __volatile("movl %0,%%cr3" : : "r" (val)); 207 } 208 209 static __inline uint 210 rcr3(void) 211 { 212 uint val; 213 __asm __volatile("movl %%cr3,%0" : "=r" (val)); 214 return val; 215 } 216 217 static __inline void 218 lcr4(uint val) 219 { 220 __asm __volatile("movl %0,%%cr4" : : "r" (val)); 221 } 222 223 static __inline uint 224 rcr4(void) 225 { 226 uint cr4; 227 __asm __volatile("movl %%cr4,%0" : "=r" (cr4)); 228 return cr4; 229 } 230 231 static __inline void 232 tlbflush(void) 233 { 234 uint cr3; 235 __asm __volatile("movl %%cr3,%0" : "=r" (cr3)); 236 __asm __volatile("movl %0,%%cr3" : : "r" (cr3)); 237 } 238 239 static __inline uint 240 read_eflags(void) 241 { 242 uint eflags; 243 __asm __volatile("pushfl; popl %0" : "=r" (eflags)); 244 return eflags; 245 } 246 247 static __inline void 248 write_eflags(uint eflags) 249 { 250 __asm __volatile("pushl %0; popfl" : : "r" (eflags)); 251 } 252 253 static __inline uint 254 read_ebp(void) 255 { 256 uint ebp; 257 __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); 258 return ebp; 259 } 260 261 static __inline uint 262 read_esp(void) 263 { 264 uint esp; 265 __asm __volatile("movl %%esp,%0" : "=r" (esp)); 266 return esp; 267 } 268 269 static __inline uint 270 read_esi(void) 271 { 272 uint esi; 273 __asm __volatile("movl %%esi,%0" : "=r" (esi)); 274 return esi; 275 } 276 277 static __inline uint 278 read_edi(void) 279 { 280 uint edi; 281 __asm __volatile("movl %%edi,%0" : "=r" (edi)); 282 return edi; 283 } 284 285 static __inline uint 286 read_ebx(void) 287 { 288 uint ebx; 289 __asm __volatile("movl %%ebx,%0" : "=r" (ebx)); 290 return ebx; 291 } 292 293 static __inline void 294 cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp) 295 { 296 uint eax, ebx, ecx, edx; 297 asm volatile("cpuid" 298 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) 299 : "a" (info)); 300 if (eaxp) 301 *eaxp = eax; 302 if (ebxp) 303 *ebxp = ebx; 304 if (ecxp) 305 *ecxp = ecx; 306 if (edxp) 307 *edxp = edx; 308 } 309 310 static __inline uint 311 cmpxchg(uint oldval, uint newval, volatile uint* lock_addr) 312 { 313 uint result; 314 __asm__ __volatile__( 315 "lock; cmpxchgl %2, %0" 316 :"+m" (*lock_addr), "=a" (result) : "r"(newval), "1"(oldval) : "cc" 317 ); 318 return result; 319 } 320 321 static __inline void 322 cli(void) 323 { 324 __asm__ volatile("cli"); 325 } 326 327 static __inline void 328 sti(void) 329 { 330 __asm__ volatile("sti"); 331 } 332 333 struct trapframe { 334 /* registers as pushed by pusha */ 335 uint edi; 336 uint esi; 337 uint ebp; 338 uint oesp; /* Useless */ 339 uint ebx; 340 uint edx; 341 uint ecx; 342 uint eax; 343 /* rest of trap frame */ 344 ushort es; 345 ushort padding1; 346 ushort ds; 347 ushort padding2; 348 uint trapno; 349 /* below here defined by x86 hardware */ 350 uint err; 351 uint eip; 352 ushort cs; 353 ushort padding3; 354 uint eflags; 355 /* below here only when crossing rings, such as from user to kernel */ 356 uint esp; 357 ushort ss; 358 ushort padding4; 359 }; 360 361 #define MAX_IRQS 16 // Number of IRQs 362 363 #define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET 364 365 #define IRQ_KBD 1 366 #define IRQ_IDE 14 367 #define IRQ_ERROR 19 368 #define IRQ_SPURIOUS 31 369