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 | |