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