1 static __inline uchar 2 inb(int port) 3 { 4 uchar data; 5 __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port)); 6 return data; 7 } 8 9 static __inline void 10 insl(int port, void *addr, int cnt) 11 { 12 __asm __volatile("cld\n\trepne\n\tinsl" : 13 "=D" (addr), "=c" (cnt) : 14 "d" (port), "0" (addr), "1" (cnt) : 15 "memory", "cc"); 16 } 17 18 static __inline void 19 outb(int port, uchar data) 20 { 21 __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port)); 22 } 23 24 static __inline void 25 outw(int port, ushort data) 26 { 27 __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port)); 28 } 29 30 static __inline void 31 outsl(int port, const void *addr, int cnt) 32 { 33 __asm __volatile("cld\n\trepne\n\toutsl" : 34 "=S" (addr), "=c" (cnt) : 35 "d" (port), "0" (addr), "1" (cnt) : 36 "cc"); 37 } 38 39 struct segdesc; 40 41 static __inline void 42 lgdt(struct segdesc *p, int size) 43 { 44 volatile ushort pd[3]; 45 46 pd[0] = size-1; 47 pd[1] = (uint)p; 48 pd[2] = (uint)p >> 16; 49 50 asm volatile("lgdt (%0)" : : "g" (pd)); 51 } 52 53 struct gatedesc; 54 55 static __inline void 56 lidt(struct gatedesc *p, int size) 57 { 58 volatile ushort pd[3]; 59 60 pd[0] = size-1; 61 pd[1] = (uint)p; 62 pd[2] = (uint)p >> 16; 63 64 asm volatile("lidt (%0)" : : "g" (pd)); 65 } 66 67 static __inline void 68 ltr(ushort sel) 69 { 70 __asm __volatile("ltr %0" : : "r" (sel)); 71 } 72 73 static __inline uint 74 read_eflags(void) 75 { 76 uint eflags; 77 __asm __volatile("pushfl; popl %0" : "=r" (eflags)); 78 return eflags; 79 } 80 81 static __inline void 82 write_eflags(uint eflags) 83 { 84 __asm __volatile("pushl %0; popfl" : : "r" (eflags)); 85 } 86 87 static __inline void 88 cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp) 89 { 90 uint eax, ebx, ecx, edx; 91 asm volatile("cpuid" : 92 "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : 93 "a" (info)); 94 if(eaxp) 95 *eaxp = eax; 96 if(ebxp) 97 *ebxp = ebx; 98 if(ecxp) 99 *ecxp = ecx; 100 if(edxp) 101 *edxp = edx; 102 } 103 104 static __inline uint 105 cmpxchg(uint oldval, uint newval, volatile uint* lock_addr) 106 { 107 uint result; 108 __asm__ __volatile__("lock; cmpxchgl %2, %0" : 109 "+m" (*lock_addr), "=a" (result) : 110 "r"(newval), "1"(oldval) : 111 "cc"); 112 return result; 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 struct trapframe { 128 /* registers as pushed by pusha */ 129 uint edi; 130 uint esi; 131 uint ebp; 132 uint oesp; /* Useless */ 133 uint ebx; 134 uint edx; 135 uint ecx; 136 uint eax; 137 /* rest of trap frame */ 138 ushort es; 139 ushort padding1; 140 ushort ds; 141 ushort padding2; 142 uint trapno; 143 /* below here defined by x86 hardware */ 144 uint err; 145 uint eip; 146 ushort cs; 147 ushort padding3; 148 uint eflags; 149 /* below here only when crossing rings, such as from user to kernel */ 150 uint esp; 151 ushort ss; 152 ushort padding4; 153 }; 154