Lab3 initial merge
[akaros.git] / inc / x86.h
1 #ifndef JOS_INC_X86_H
2 #define JOS_INC_X86_H
3
4 #include <inc/types.h>
5
6 static __inline void breakpoint(void) __attribute__((always_inline));
7 static __inline uint8_t inb(int port) __attribute__((always_inline));
8 static __inline void insb(int port, void *addr, int cnt) __attribute__((always_inline));
9 static __inline uint16_t inw(int port) __attribute__((always_inline));
10 static __inline void insw(int port, void *addr, int cnt) __attribute__((always_inline));
11 static __inline uint32_t inl(int port) __attribute__((always_inline));
12 static __inline void insl(int port, void *addr, int cnt) __attribute__((always_inline));
13 static __inline void outb(int port, uint8_t data) __attribute__((always_inline));
14 static __inline void outsb(int port, const void *addr, int cnt) __attribute__((always_inline));
15 static __inline void outw(int port, uint16_t data) __attribute__((always_inline));
16 static __inline void outsw(int port, const void *addr, int cnt) __attribute__((always_inline));
17 static __inline void outsl(int port, const void *addr, int cnt) __attribute__((always_inline));
18 static __inline void outl(int port, uint32_t data) __attribute__((always_inline));
19 static __inline void invlpg(void *addr) __attribute__((always_inline));
20 static __inline void lidt(void *p) __attribute__((always_inline));
21 static __inline void lldt(uint16_t sel) __attribute__((always_inline));
22 static __inline void ltr(uint16_t sel) __attribute__((always_inline));
23 static __inline void lcr0(uint32_t val) __attribute__((always_inline));
24 static __inline uint32_t rcr0(void) __attribute__((always_inline));
25 static __inline uint32_t rcr2(void) __attribute__((always_inline));
26 static __inline void lcr3(uint32_t val) __attribute__((always_inline));
27 static __inline uint32_t rcr3(void) __attribute__((always_inline));
28 static __inline void lcr4(uint32_t val) __attribute__((always_inline));
29 static __inline uint32_t rcr4(void) __attribute__((always_inline));
30 static __inline void tlbflush(void) __attribute__((always_inline));
31 static __inline uint32_t read_eflags(void) __attribute__((always_inline));
32 static __inline void write_eflags(uint32_t eflags) __attribute__((always_inline));
33 static __inline uint32_t read_ebp(void) __attribute__((always_inline));
34 static __inline uint32_t read_esp(void) __attribute__((always_inline));
35 static __inline void cpuid(uint32_t info, uint32_t *eaxp, uint32_t *ebxp, uint32_t *ecxp, uint32_t *edxp);
36 static __inline uint64_t read_tsc(void) __attribute__((always_inline));
37
38 static __inline void
39 breakpoint(void)
40 {
41         __asm __volatile("int3");
42 }
43
44 static __inline uint8_t
45 inb(int port)
46 {
47         uint8_t data;
48         __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
49         return data;
50 }
51
52 static __inline void
53 insb(int port, void *addr, int cnt)
54 {
55         __asm __volatile("cld\n\trepne\n\tinsb"                 :
56                          "=D" (addr), "=c" (cnt)                :
57                          "d" (port), "0" (addr), "1" (cnt)      :
58                          "memory", "cc");
59 }
60
61 static __inline uint16_t
62 inw(int port)
63 {
64         uint16_t data;
65         __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
66         return data;
67 }
68
69 static __inline void
70 insw(int port, void *addr, int cnt)
71 {
72         __asm __volatile("cld\n\trepne\n\tinsw"                 :
73                          "=D" (addr), "=c" (cnt)                :
74                          "d" (port), "0" (addr), "1" (cnt)      :
75                          "memory", "cc");
76 }
77
78 static __inline uint32_t
79 inl(int port)
80 {
81         uint32_t data;
82         __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
83         return data;
84 }
85
86 static __inline void
87 insl(int port, void *addr, int cnt)
88 {
89         __asm __volatile("cld\n\trepne\n\tinsl"                 :
90                          "=D" (addr), "=c" (cnt)                :
91                          "d" (port), "0" (addr), "1" (cnt)      :
92                          "memory", "cc");
93 }
94
95 static __inline void
96 outb(int port, uint8_t data)
97 {
98         __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
99 }
100
101 static __inline void
102 outsb(int port, const void *addr, int cnt)
103 {
104         __asm __volatile("cld\n\trepne\n\toutsb"                :
105                          "=S" (addr), "=c" (cnt)                :
106                          "d" (port), "0" (addr), "1" (cnt)      :
107                          "cc");
108 }
109
110 static __inline void
111 outw(int port, uint16_t data)
112 {
113         __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
114 }
115
116 static __inline void
117 outsw(int port, const void *addr, int cnt)
118 {
119         __asm __volatile("cld\n\trepne\n\toutsw"                :
120                          "=S" (addr), "=c" (cnt)                :
121                          "d" (port), "0" (addr), "1" (cnt)      :
122                          "cc");
123 }
124
125 static __inline void
126 outsl(int port, const void *addr, int cnt)
127 {
128         __asm __volatile("cld\n\trepne\n\toutsl"                :
129                          "=S" (addr), "=c" (cnt)                :
130                          "d" (port), "0" (addr), "1" (cnt)      :
131                          "cc");
132 }
133
134 static __inline void
135 outl(int port, uint32_t data)
136 {
137         __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
138 }
139
140 static __inline void 
141 invlpg(void *addr)
142
143         __asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
144 }  
145
146 static __inline void
147 lidt(void *p)
148 {
149         __asm __volatile("lidt (%0)" : : "r" (p));
150 }
151
152 static __inline void
153 lldt(uint16_t sel)
154 {
155         __asm __volatile("lldt %0" : : "r" (sel));
156 }
157
158 static __inline void
159 ltr(uint16_t sel)
160 {
161         __asm __volatile("ltr %0" : : "r" (sel));
162 }
163
164 static __inline void
165 lcr0(uint32_t val)
166 {
167         __asm __volatile("movl %0,%%cr0" : : "r" (val));
168 }
169
170 static __inline uint32_t
171 rcr0(void)
172 {
173         uint32_t val;
174         __asm __volatile("movl %%cr0,%0" : "=r" (val));
175         return val;
176 }
177
178 static __inline uint32_t
179 rcr2(void)
180 {
181         uint32_t val;
182         __asm __volatile("movl %%cr2,%0" : "=r" (val));
183         return val;
184 }
185
186 static __inline void
187 lcr3(uint32_t val)
188 {
189         __asm __volatile("movl %0,%%cr3" : : "r" (val));
190 }
191
192 static __inline uint32_t
193 rcr3(void)
194 {
195         uint32_t val;
196         __asm __volatile("movl %%cr3,%0" : "=r" (val));
197         return val;
198 }
199
200 static __inline void
201 lcr4(uint32_t val)
202 {
203         __asm __volatile("movl %0,%%cr4" : : "r" (val));
204 }
205
206 static __inline uint32_t
207 rcr4(void)
208 {
209         uint32_t cr4;
210         __asm __volatile("movl %%cr4,%0" : "=r" (cr4));
211         return cr4;
212 }
213
214 static __inline void
215 tlbflush(void)
216 {
217         uint32_t cr3;
218         __asm __volatile("movl %%cr3,%0" : "=r" (cr3));
219         __asm __volatile("movl %0,%%cr3" : : "r" (cr3));
220 }
221
222 static __inline uint32_t
223 read_eflags(void)
224 {
225         uint32_t eflags;
226         __asm __volatile("pushfl; popl %0" : "=r" (eflags));
227         return eflags;
228 }
229
230 static __inline void
231 write_eflags(uint32_t eflags)
232 {
233         __asm __volatile("pushl %0; popfl" : : "r" (eflags));
234 }
235
236 static __inline uint32_t
237 read_ebp(void)
238 {
239         uint32_t ebp;
240         __asm __volatile("movl %%ebp,%0" : "=r" (ebp));
241         return ebp;
242 }
243
244 static __inline uint32_t
245 read_esp(void)
246 {
247         uint32_t esp;
248         __asm __volatile("movl %%esp,%0" : "=r" (esp));
249         return esp;
250 }
251
252 static __inline void
253 cpuid(uint32_t info, uint32_t *eaxp, uint32_t *ebxp, uint32_t *ecxp, uint32_t *edxp)
254 {
255         uint32_t eax, ebx, ecx, edx;
256         asm volatile("cpuid" 
257                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
258                 : "a" (info));
259         if (eaxp)
260                 *eaxp = eax;
261         if (ebxp)
262                 *ebxp = ebx;
263         if (ecxp)
264                 *ecxp = ecx;
265         if (edxp)
266                 *edxp = edx;
267 }
268
269 static __inline uint64_t
270 read_tsc(void)
271 {
272         uint64_t tsc;
273         __asm __volatile("rdtsc" : "=A" (tsc));
274         return tsc;
275 }
276
277 #endif /* !JOS_INC_X86_H */