Rev 4017 | Rev 4095 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4017 | Rev 4021 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright (c) 2005 Jakub Jermar |
2 | * Copyright (c) 2005 Jakub Jermar |
3 | * All rights reserved. |
3 | * All rights reserved. |
4 | * |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
7 | * are met: |
8 | * |
8 | * |
9 | * - Redistributions of source code must retain the above copyright |
9 | * - Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * - Redistributions in binary form must reproduce the above copyright |
11 | * - Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
13 | * documentation and/or other materials provided with the distribution. |
14 | * - The name of the author may not be used to endorse or promote products |
14 | * - The name of the author may not be used to endorse or promote products |
15 | * derived from this software without specific prior written permission. |
15 | * derived from this software without specific prior written permission. |
16 | * |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | /** @addtogroup amd64 |
29 | /** @addtogroup amd64 |
30 | * @{ |
30 | * @{ |
31 | */ |
31 | */ |
32 | /** @file |
32 | /** @file |
33 | */ |
33 | */ |
34 | 34 | ||
35 | #ifndef KERN_amd64_ASM_H_ |
35 | #ifndef KERN_amd64_ASM_H_ |
36 | #define KERN_amd64_ASM_H_ |
36 | #define KERN_amd64_ASM_H_ |
37 | 37 | ||
38 | #include <config.h> |
38 | #include <config.h> |
- | 39 | #include <arch/types.h> |
|
- | 40 | #include <typedefs.h> |
|
39 | 41 | ||
40 | extern void asm_delay_loop(uint32_t t); |
42 | extern void asm_delay_loop(uint32_t t); |
41 | extern void asm_fake_loop(uint32_t t); |
43 | extern void asm_fake_loop(uint32_t t); |
42 | 44 | ||
43 | /** Return base address of current stack. |
45 | /** Return base address of current stack. |
44 | * |
46 | * |
45 | * Return the base address of the current stack. |
47 | * Return the base address of the current stack. |
46 | * The stack is assumed to be STACK_SIZE bytes long. |
48 | * The stack is assumed to be STACK_SIZE bytes long. |
47 | * The stack must start on page boundary. |
49 | * The stack must start on page boundary. |
48 | * |
50 | * |
49 | */ |
51 | */ |
50 | static inline uintptr_t get_stack_base(void) |
52 | static inline uintptr_t get_stack_base(void) |
51 | { |
53 | { |
52 | uintptr_t v; |
54 | uintptr_t v; |
53 | 55 | ||
54 | asm volatile ( |
56 | asm volatile ( |
55 | "andq %%rsp, %[v]\n" |
57 | "andq %%rsp, %[v]\n" |
56 | : [v] "=r" (v) |
58 | : [v] "=r" (v) |
57 | : "0" (~((uint64_t) STACK_SIZE-1)) |
59 | : "0" (~((uint64_t) STACK_SIZE-1)) |
58 | ); |
60 | ); |
59 | 61 | ||
60 | return v; |
62 | return v; |
61 | } |
63 | } |
62 | 64 | ||
63 | static inline void cpu_sleep(void) |
65 | static inline void cpu_sleep(void) |
64 | { |
66 | { |
65 | asm volatile ("hlt\n"); |
67 | asm volatile ("hlt\n"); |
66 | } |
68 | } |
67 | 69 | ||
68 | static inline void cpu_halt(void) |
70 | static inline void cpu_halt(void) |
69 | { |
71 | { |
70 | asm volatile ("hlt\n"); |
72 | asm volatile ("hlt\n"); |
71 | } |
73 | } |
72 | 74 | ||
73 | 75 | ||
74 | /** Byte from port |
76 | /** Byte from port |
75 | * |
77 | * |
76 | * Get byte from port |
78 | * Get byte from port |
77 | * |
79 | * |
78 | * @param port Port to read from |
80 | * @param port Port to read from |
79 | * @return Value read |
81 | * @return Value read |
80 | * |
82 | * |
81 | */ |
83 | */ |
82 | static inline uint8_t pio_read_8(ioport8_t *port) |
84 | static inline uint8_t pio_read_8(ioport8_t *port) |
83 | { |
85 | { |
84 | uint8_t val; |
86 | uint8_t val; |
85 | 87 | ||
86 | asm volatile ( |
88 | asm volatile ( |
87 | "inb %w[port], %b[val]\n" |
89 | "inb %w[port], %b[val]\n" |
88 | : [val] "=a" (val) |
90 | : [val] "=a" (val) |
89 | : [port] "d" (port) |
91 | : [port] "d" (port) |
90 | ); |
92 | ); |
91 | 93 | ||
92 | return val; |
94 | return val; |
93 | } |
95 | } |
94 | 96 | ||
95 | /** Word from port |
97 | /** Word from port |
96 | * |
98 | * |
97 | * Get word from port |
99 | * Get word from port |
98 | * |
100 | * |
99 | * @param port Port to read from |
101 | * @param port Port to read from |
100 | * @return Value read |
102 | * @return Value read |
101 | * |
103 | * |
102 | */ |
104 | */ |
103 | static inline uint16_t pio_read_16(ioport16_t *port) |
105 | static inline uint16_t pio_read_16(ioport16_t *port) |
104 | { |
106 | { |
105 | uint16_t val; |
107 | uint16_t val; |
106 | 108 | ||
107 | asm volatile ( |
109 | asm volatile ( |
108 | "inw %w[port], %w[val]\n" |
110 | "inw %w[port], %w[val]\n" |
109 | : [val] "=a" (val) |
111 | : [val] "=a" (val) |
110 | : [port] "d" (port) |
112 | : [port] "d" (port) |
111 | ); |
113 | ); |
112 | 114 | ||
113 | return val; |
115 | return val; |
114 | } |
116 | } |
115 | 117 | ||
116 | /** Double word from port |
118 | /** Double word from port |
117 | * |
119 | * |
118 | * Get double word from port |
120 | * Get double word from port |
119 | * |
121 | * |
120 | * @param port Port to read from |
122 | * @param port Port to read from |
121 | * @return Value read |
123 | * @return Value read |
122 | * |
124 | * |
123 | */ |
125 | */ |
124 | static inline uint32_t pio_read_32(ioport32_t *port) |
126 | static inline uint32_t pio_read_32(ioport32_t *port) |
125 | { |
127 | { |
126 | uint32_t val; |
128 | uint32_t val; |
127 | 129 | ||
128 | asm volatile ( |
130 | asm volatile ( |
129 | "inl %w[port], %[val]\n" |
131 | "inl %w[port], %[val]\n" |
130 | : [val] "=a" (val) |
132 | : [val] "=a" (val) |
131 | : [port] "d" (port) |
133 | : [port] "d" (port) |
132 | ); |
134 | ); |
133 | 135 | ||
134 | return val; |
136 | return val; |
135 | } |
137 | } |
136 | 138 | ||
137 | /** Byte to port |
139 | /** Byte to port |
138 | * |
140 | * |
139 | * Output byte to port |
141 | * Output byte to port |
140 | * |
142 | * |
141 | * @param port Port to write to |
143 | * @param port Port to write to |
142 | * @param val Value to write |
144 | * @param val Value to write |
143 | * |
145 | * |
144 | */ |
146 | */ |
145 | static inline void pio_write_8(ioport8_t *port, uint8_t val) |
147 | static inline void pio_write_8(ioport8_t *port, uint8_t val) |
146 | { |
148 | { |
147 | asm volatile ( |
149 | asm volatile ( |
148 | "outb %b[val], %w[port]\n" |
150 | "outb %b[val], %w[port]\n" |
149 | :: [val] "a" (val), [port] "d" (port) |
151 | :: [val] "a" (val), [port] "d" (port) |
150 | ); |
152 | ); |
151 | } |
153 | } |
152 | 154 | ||
153 | /** Word to port |
155 | /** Word to port |
154 | * |
156 | * |
155 | * Output word to port |
157 | * Output word to port |
156 | * |
158 | * |
157 | * @param port Port to write to |
159 | * @param port Port to write to |
158 | * @param val Value to write |
160 | * @param val Value to write |
159 | * |
161 | * |
160 | */ |
162 | */ |
161 | static inline void pio_write_16(ioport16_t *port, uint16_t val) |
163 | static inline void pio_write_16(ioport16_t *port, uint16_t val) |
162 | { |
164 | { |
163 | asm volatile ( |
165 | asm volatile ( |
164 | "outw %w[val], %w[port]\n" |
166 | "outw %w[val], %w[port]\n" |
165 | :: [val] "a" (val), [port] "d" (port) |
167 | :: [val] "a" (val), [port] "d" (port) |
166 | ); |
168 | ); |
167 | } |
169 | } |
168 | 170 | ||
169 | /** Double word to port |
171 | /** Double word to port |
170 | * |
172 | * |
171 | * Output double word to port |
173 | * Output double word to port |
172 | * |
174 | * |
173 | * @param port Port to write to |
175 | * @param port Port to write to |
174 | * @param val Value to write |
176 | * @param val Value to write |
175 | * |
177 | * |
176 | */ |
178 | */ |
177 | static inline void pio_write_32(ioport32_t *port, uint32_t val) |
179 | static inline void pio_write_32(ioport32_t *port, uint32_t val) |
178 | { |
180 | { |
179 | asm volatile ( |
181 | asm volatile ( |
180 | "outl %[val], %w[port]\n" |
182 | "outl %[val], %w[port]\n" |
181 | :: [val] "a" (val), [port] "d" (port) |
183 | :: [val] "a" (val), [port] "d" (port) |
182 | ); |
184 | ); |
183 | } |
185 | } |
184 | 186 | ||
185 | /** Swap Hidden part of GS register with visible one */ |
187 | /** Swap Hidden part of GS register with visible one */ |
186 | static inline void swapgs(void) |
188 | static inline void swapgs(void) |
187 | { |
189 | { |
188 | asm volatile("swapgs"); |
190 | asm volatile("swapgs"); |
189 | } |
191 | } |
190 | 192 | ||
191 | /** Enable interrupts. |
193 | /** Enable interrupts. |
192 | * |
194 | * |
193 | * Enable interrupts and return previous |
195 | * Enable interrupts and return previous |
194 | * value of EFLAGS. |
196 | * value of EFLAGS. |
195 | * |
197 | * |
196 | * @return Old interrupt priority level. |
198 | * @return Old interrupt priority level. |
197 | * |
199 | * |
198 | */ |
200 | */ |
199 | static inline ipl_t interrupts_enable(void) { |
201 | static inline ipl_t interrupts_enable(void) { |
200 | ipl_t v; |
202 | ipl_t v; |
201 | 203 | ||
202 | asm volatile ( |
204 | asm volatile ( |
203 | "pushfq\n" |
205 | "pushfq\n" |
204 | "popq %[v]\n" |
206 | "popq %[v]\n" |
205 | "sti\n" |
207 | "sti\n" |
206 | : [v] "=r" (v) |
208 | : [v] "=r" (v) |
207 | ); |
209 | ); |
208 | 210 | ||
209 | return v; |
211 | return v; |
210 | } |
212 | } |
211 | 213 | ||
212 | /** Disable interrupts. |
214 | /** Disable interrupts. |
213 | * |
215 | * |
214 | * Disable interrupts and return previous |
216 | * Disable interrupts and return previous |
215 | * value of EFLAGS. |
217 | * value of EFLAGS. |
216 | * |
218 | * |
217 | * @return Old interrupt priority level. |
219 | * @return Old interrupt priority level. |
218 | * |
220 | * |
219 | */ |
221 | */ |
220 | static inline ipl_t interrupts_disable(void) { |
222 | static inline ipl_t interrupts_disable(void) { |
221 | ipl_t v; |
223 | ipl_t v; |
222 | 224 | ||
223 | asm volatile ( |
225 | asm volatile ( |
224 | "pushfq\n" |
226 | "pushfq\n" |
225 | "popq %[v]\n" |
227 | "popq %[v]\n" |
226 | "cli\n" |
228 | "cli\n" |
227 | : [v] "=r" (v) |
229 | : [v] "=r" (v) |
228 | ); |
230 | ); |
229 | 231 | ||
230 | return v; |
232 | return v; |
231 | } |
233 | } |
232 | 234 | ||
233 | /** Restore interrupt priority level. |
235 | /** Restore interrupt priority level. |
234 | * |
236 | * |
235 | * Restore EFLAGS. |
237 | * Restore EFLAGS. |
236 | * |
238 | * |
237 | * @param ipl Saved interrupt priority level. |
239 | * @param ipl Saved interrupt priority level. |
238 | * |
240 | * |
239 | */ |
241 | */ |
240 | static inline void interrupts_restore(ipl_t ipl) { |
242 | static inline void interrupts_restore(ipl_t ipl) { |
241 | asm volatile ( |
243 | asm volatile ( |
242 | "pushq %[ipl]\n" |
244 | "pushq %[ipl]\n" |
243 | "popfq\n" |
245 | "popfq\n" |
244 | :: [ipl] "r" (ipl) |
246 | :: [ipl] "r" (ipl) |
245 | ); |
247 | ); |
246 | } |
248 | } |
247 | 249 | ||
248 | /** Return interrupt priority level. |
250 | /** Return interrupt priority level. |
249 | * |
251 | * |
250 | * Return EFLAFS. |
252 | * Return EFLAFS. |
251 | * |
253 | * |
252 | * @return Current interrupt priority level. |
254 | * @return Current interrupt priority level. |
253 | * |
255 | * |
254 | */ |
256 | */ |
255 | static inline ipl_t interrupts_read(void) { |
257 | static inline ipl_t interrupts_read(void) { |
256 | ipl_t v; |
258 | ipl_t v; |
257 | 259 | ||
258 | asm volatile ( |
260 | asm volatile ( |
259 | "pushfq\n" |
261 | "pushfq\n" |
260 | "popq %[v]\n" |
262 | "popq %[v]\n" |
261 | : [v] "=r" (v) |
263 | : [v] "=r" (v) |
262 | ); |
264 | ); |
263 | 265 | ||
264 | return v; |
266 | return v; |
265 | } |
267 | } |
266 | 268 | ||
267 | /** Write to MSR */ |
269 | /** Write to MSR */ |
268 | static inline void write_msr(uint32_t msr, uint64_t value) |
270 | static inline void write_msr(uint32_t msr, uint64_t value) |
269 | { |
271 | { |
270 | asm volatile ( |
272 | asm volatile ( |
271 | "wrmsr\n" |
273 | "wrmsr\n" |
272 | :: "c" (msr), |
274 | :: "c" (msr), |
273 | "a" ((uint32_t) (value)), |
275 | "a" ((uint32_t) (value)), |
274 | "d" ((uint32_t) (value >> 32)) |
276 | "d" ((uint32_t) (value >> 32)) |
275 | ); |
277 | ); |
276 | } |
278 | } |
277 | 279 | ||
278 | static inline unative_t read_msr(uint32_t msr) |
280 | static inline unative_t read_msr(uint32_t msr) |
279 | { |
281 | { |
280 | uint32_t ax, dx; |
282 | uint32_t ax, dx; |
281 | 283 | ||
282 | asm volatile ( |
284 | asm volatile ( |
283 | "rdmsr\n" |
285 | "rdmsr\n" |
284 | : "=a" (ax), "=d" (dx) |
286 | : "=a" (ax), "=d" (dx) |
285 | : "c" (msr) |
287 | : "c" (msr) |
286 | ); |
288 | ); |
287 | 289 | ||
288 | return ((uint64_t) dx << 32) | ax; |
290 | return ((uint64_t) dx << 32) | ax; |
289 | } |
291 | } |
290 | 292 | ||
291 | 293 | ||
292 | /** Enable local APIC |
294 | /** Enable local APIC |
293 | * |
295 | * |
294 | * Enable local APIC in MSR. |
296 | * Enable local APIC in MSR. |
295 | * |
297 | * |
296 | */ |
298 | */ |
297 | static inline void enable_l_apic_in_msr() |
299 | static inline void enable_l_apic_in_msr() |
298 | { |
300 | { |
299 | asm volatile ( |
301 | asm volatile ( |
300 | "movl $0x1b, %%ecx\n" |
302 | "movl $0x1b, %%ecx\n" |
301 | "rdmsr\n" |
303 | "rdmsr\n" |
302 | "orl $(1 << 11),%%eax\n" |
304 | "orl $(1 << 11),%%eax\n" |
303 | "orl $(0xfee00000),%%eax\n" |
305 | "orl $(0xfee00000),%%eax\n" |
304 | "wrmsr\n" |
306 | "wrmsr\n" |
305 | ::: "%eax","%ecx","%edx" |
307 | ::: "%eax","%ecx","%edx" |
306 | ); |
308 | ); |
307 | } |
309 | } |
308 | 310 | ||
309 | static inline uintptr_t * get_ip() |
311 | static inline uintptr_t * get_ip() |
310 | { |
312 | { |
311 | uintptr_t *ip; |
313 | uintptr_t *ip; |
312 | 314 | ||
313 | asm volatile ( |
315 | asm volatile ( |
314 | "mov %%rip, %[ip]" |
316 | "mov %%rip, %[ip]" |
315 | : [ip] "=r" (ip) |
317 | : [ip] "=r" (ip) |
316 | ); |
318 | ); |
317 | 319 | ||
318 | return ip; |
320 | return ip; |
319 | } |
321 | } |
320 | 322 | ||
321 | /** Invalidate TLB Entry. |
323 | /** Invalidate TLB Entry. |
322 | * |
324 | * |
323 | * @param addr Address on a page whose TLB entry is to be invalidated. |
325 | * @param addr Address on a page whose TLB entry is to be invalidated. |
324 | * |
326 | * |
325 | */ |
327 | */ |
326 | static inline void invlpg(uintptr_t addr) |
328 | static inline void invlpg(uintptr_t addr) |
327 | { |
329 | { |
328 | asm volatile ( |
330 | asm volatile ( |
329 | "invlpg %[addr]\n" |
331 | "invlpg %[addr]\n" |
330 | :: [addr] "m" (*((unative_t *) addr)) |
332 | :: [addr] "m" (*((unative_t *) addr)) |
331 | ); |
333 | ); |
332 | } |
334 | } |
333 | 335 | ||
334 | /** Load GDTR register from memory. |
336 | /** Load GDTR register from memory. |
335 | * |
337 | * |
336 | * @param gdtr_reg Address of memory from where to load GDTR. |
338 | * @param gdtr_reg Address of memory from where to load GDTR. |
337 | * |
339 | * |
338 | */ |
340 | */ |
339 | static inline void gdtr_load(struct ptr_16_64 *gdtr_reg) |
341 | static inline void gdtr_load(struct ptr_16_64 *gdtr_reg) |
340 | { |
342 | { |
341 | asm volatile ( |
343 | asm volatile ( |
342 | "lgdtq %[gdtr_reg]\n" |
344 | "lgdtq %[gdtr_reg]\n" |
343 | :: [gdtr_reg] "m" (*gdtr_reg) |
345 | :: [gdtr_reg] "m" (*gdtr_reg) |
344 | ); |
346 | ); |
345 | } |
347 | } |
346 | 348 | ||
347 | /** Store GDTR register to memory. |
349 | /** Store GDTR register to memory. |
348 | * |
350 | * |
349 | * @param gdtr_reg Address of memory to where to load GDTR. |
351 | * @param gdtr_reg Address of memory to where to load GDTR. |
350 | * |
352 | * |
351 | */ |
353 | */ |
352 | static inline void gdtr_store(struct ptr_16_64 *gdtr_reg) |
354 | static inline void gdtr_store(struct ptr_16_64 *gdtr_reg) |
353 | { |
355 | { |
354 | asm volatile ( |
356 | asm volatile ( |
355 | "sgdtq %[gdtr_reg]\n" |
357 | "sgdtq %[gdtr_reg]\n" |
356 | :: [gdtr_reg] "m" (*gdtr_reg) |
358 | :: [gdtr_reg] "m" (*gdtr_reg) |
357 | ); |
359 | ); |
358 | } |
360 | } |
359 | 361 | ||
360 | /** Load IDTR register from memory. |
362 | /** Load IDTR register from memory. |
361 | * |
363 | * |
362 | * @param idtr_reg Address of memory from where to load IDTR. |
364 | * @param idtr_reg Address of memory from where to load IDTR. |
363 | * |
365 | * |
364 | */ |
366 | */ |
365 | static inline void idtr_load(struct ptr_16_64 *idtr_reg) |
367 | static inline void idtr_load(struct ptr_16_64 *idtr_reg) |
366 | { |
368 | { |
367 | asm volatile ( |
369 | asm volatile ( |
368 | "lidtq %[idtr_reg]\n" |
370 | "lidtq %[idtr_reg]\n" |
369 | :: [idtr_reg] "m" (*idtr_reg)); |
371 | :: [idtr_reg] "m" (*idtr_reg)); |
370 | } |
372 | } |
371 | 373 | ||
372 | /** Load TR from descriptor table. |
374 | /** Load TR from descriptor table. |
373 | * |
375 | * |
374 | * @param sel Selector specifying descriptor of TSS segment. |
376 | * @param sel Selector specifying descriptor of TSS segment. |
375 | * |
377 | * |
376 | */ |
378 | */ |
377 | static inline void tr_load(uint16_t sel) |
379 | static inline void tr_load(uint16_t sel) |
378 | { |
380 | { |
379 | asm volatile ( |
381 | asm volatile ( |
380 | "ltr %[sel]" |
382 | "ltr %[sel]" |
381 | :: [sel] "r" (sel) |
383 | :: [sel] "r" (sel) |
382 | ); |
384 | ); |
383 | } |
385 | } |
384 | 386 | ||
385 | #define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
387 | #define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
386 | { \ |
388 | { \ |
387 | unative_t res; \ |
389 | unative_t res; \ |
388 | asm volatile ( \ |
390 | asm volatile ( \ |
389 | "movq %%" #reg ", %[res]" \ |
391 | "movq %%" #reg ", %[res]" \ |
390 | : [res] "=r" (res) \ |
392 | : [res] "=r" (res) \ |
391 | ); \ |
393 | ); \ |
392 | return res; \ |
394 | return res; \ |
393 | } |
395 | } |
394 | 396 | ||
395 | #define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
397 | #define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
396 | { \ |
398 | { \ |
397 | asm volatile ( \ |
399 | asm volatile ( \ |
398 | "movq %[regn], %%" #reg \ |
400 | "movq %[regn], %%" #reg \ |
399 | :: [regn] "r" (regn) \ |
401 | :: [regn] "r" (regn) \ |
400 | ); \ |
402 | ); \ |
401 | } |
403 | } |
402 | 404 | ||
403 | GEN_READ_REG(cr0) |
405 | GEN_READ_REG(cr0) |
404 | GEN_READ_REG(cr2) |
406 | GEN_READ_REG(cr2) |
405 | GEN_READ_REG(cr3) |
407 | GEN_READ_REG(cr3) |
406 | GEN_WRITE_REG(cr3) |
408 | GEN_WRITE_REG(cr3) |
407 | 409 | ||
408 | GEN_READ_REG(dr0) |
410 | GEN_READ_REG(dr0) |
409 | GEN_READ_REG(dr1) |
411 | GEN_READ_REG(dr1) |
410 | GEN_READ_REG(dr2) |
412 | GEN_READ_REG(dr2) |
411 | GEN_READ_REG(dr3) |
413 | GEN_READ_REG(dr3) |
412 | GEN_READ_REG(dr6) |
414 | GEN_READ_REG(dr6) |
413 | GEN_READ_REG(dr7) |
415 | GEN_READ_REG(dr7) |
414 | 416 | ||
415 | GEN_WRITE_REG(dr0) |
417 | GEN_WRITE_REG(dr0) |
416 | GEN_WRITE_REG(dr1) |
418 | GEN_WRITE_REG(dr1) |
417 | GEN_WRITE_REG(dr2) |
419 | GEN_WRITE_REG(dr2) |
418 | GEN_WRITE_REG(dr3) |
420 | GEN_WRITE_REG(dr3) |
419 | GEN_WRITE_REG(dr6) |
421 | GEN_WRITE_REG(dr6) |
420 | GEN_WRITE_REG(dr7) |
422 | GEN_WRITE_REG(dr7) |
421 | 423 | ||
422 | extern size_t interrupt_handler_size; |
424 | extern size_t interrupt_handler_size; |
423 | extern void interrupt_handlers(void); |
425 | extern void interrupt_handlers(void); |
424 | 426 | ||
425 | #endif |
427 | #endif |
426 | 428 | ||
427 | /** @} |
429 | /** @} |
428 | */ |
430 | */ |
429 | 431 |