source: mainline/kernel/arch/ia32/include/asm.h@ ff685c9

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ff685c9 was c22e964, checked in by Jakub Jermar <jakub@…>, 16 years ago

There is no need to define ioport{8,16,32}_t types for each architecture separately.

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