Subversion Repositories HelenOS

Rev

Rev 1965 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 jermar 1
/*
2
 * Copyright (C) 2001-2004 Jakub Jermar
393 bondari 3
 * Copyright (C) 2005 Sergey Bondari
1 jermar 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
 
11 jermar 30
#ifndef __ia32_ASM_H__
31
#define __ia32_ASM_H__
1 jermar 32
 
1186 jermar 33
#include <arch/pm.h>
1 jermar 34
#include <arch/types.h>
177 jermar 35
#include <config.h>
1 jermar 36
 
37
extern __u32 interrupt_handler_size;
38
 
39
extern void paging_on(void);
40
 
41
extern void interrupt_handlers(void);
42
 
43
extern void enable_l_apic_in_msr(void);
44
 
195 vana 45
 
597 jermar 46
extern void asm_delay_loop(__u32 t);
47
extern void asm_fake_loop(__u32 t);
195 vana 48
 
49
 
115 jermar 50
/** Halt CPU
51
 *
52
 * Halt the current CPU until interrupt event.
53
 */
348 jermar 54
static inline void cpu_halt(void) { __asm__("hlt\n"); };
55
static inline void cpu_sleep(void) { __asm__("hlt\n"); };
1 jermar 56
 
1074 palkovsky 57
#define GEN_READ_REG(reg) static inline __native read_ ##reg (void) \
58
    { \
59
    __native res; \
60
    __asm__ volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
61
    return res; \
62
    }
27 jermar 63
 
1074 palkovsky 64
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (__native regn) \
65
    { \
66
    __asm__ volatile ("movl %0, %%" #reg : : "r" (regn)); \
67
    }
38 jermar 68
 
1074 palkovsky 69
GEN_READ_REG(cr0);
70
GEN_READ_REG(cr2);
71
GEN_READ_REG(cr3);
72
GEN_WRITE_REG(cr3);
115 jermar 73
 
1074 palkovsky 74
GEN_READ_REG(dr0);
75
GEN_READ_REG(dr1);
76
GEN_READ_REG(dr2);
77
GEN_READ_REG(dr3);
78
GEN_READ_REG(dr6);
79
GEN_READ_REG(dr7);
80
 
81
GEN_WRITE_REG(dr0);
82
GEN_WRITE_REG(dr1);
83
GEN_WRITE_REG(dr2);
84
GEN_WRITE_REG(dr3);
85
GEN_WRITE_REG(dr6);
86
GEN_WRITE_REG(dr7);
87
 
352 bondari 88
/** Byte to port
89
 *
90
 * Output byte to port
91
 *
92
 * @param port Port to write to
93
 * @param val Value to write
94
 */
95
static inline void outb(__u16 port, __u8 val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); }
96
 
353 bondari 97
/** Word to port
98
 *
99
 * Output word to port
100
 *
101
 * @param port Port to write to
102
 * @param val Value to write
103
 */
104
static inline void outw(__u16 port, __u16 val) { __asm__ volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); }
352 bondari 105
 
353 bondari 106
/** Double word to port
107
 *
108
 * Output double word to port
109
 *
110
 * @param port Port to write to
111
 * @param val Value to write
112
 */
113
static inline void outl(__u16 port, __u32 val) { __asm__ volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); }
114
 
356 bondari 115
/** Byte from port
116
 *
117
 * Get byte from port
118
 *
119
 * @param port Port to read from
120
 * @return Value read
121
 */
122
static inline __u8 inb(__u16 port) { __u8 val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; }
123
 
124
/** Word from port
125
 *
126
 * Get word from port
127
 *
128
 * @param port Port to read from
129
 * @return Value read
130
 */
131
static inline __u16 inw(__u16 port) { __u16 val; __asm__ volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; }
132
 
133
/** Double word from port
134
 *
135
 * Get double word from port
136
 *
137
 * @param port Port to read from
138
 * @return Value read
139
 */
140
static inline __u32 inl(__u16 port) { __u32 val; __asm__ volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; }
141
 
413 jermar 142
/** Enable interrupts.
115 jermar 143
 *
144
 * Enable interrupts and return previous
145
 * value of EFLAGS.
413 jermar 146
 *
147
 * @return Old interrupt priority level.
115 jermar 148
 */
432 jermar 149
static inline ipl_t interrupts_enable(void)
150
{
413 jermar 151
    ipl_t v;
115 jermar 152
    __asm__ volatile (
358 bondari 153
        "pushf\n\t"
154
        "popl %0\n\t"
115 jermar 155
        "sti\n"
156
        : "=r" (v)
157
    );
158
    return v;
159
}
160
 
413 jermar 161
/** Disable interrupts.
115 jermar 162
 *
163
 * Disable interrupts and return previous
164
 * value of EFLAGS.
413 jermar 165
 *
166
 * @return Old interrupt priority level.
115 jermar 167
 */
432 jermar 168
static inline ipl_t interrupts_disable(void)
169
{
413 jermar 170
    ipl_t v;
115 jermar 171
    __asm__ volatile (
358 bondari 172
        "pushf\n\t"
173
        "popl %0\n\t"
115 jermar 174
        "cli\n"
175
        : "=r" (v)
176
    );
177
    return v;
178
}
179
 
413 jermar 180
/** Restore interrupt priority level.
115 jermar 181
 *
182
 * Restore EFLAGS.
413 jermar 183
 *
184
 * @param ipl Saved interrupt priority level.
115 jermar 185
 */
432 jermar 186
static inline void interrupts_restore(ipl_t ipl)
187
{
115 jermar 188
    __asm__ volatile (
358 bondari 189
        "pushl %0\n\t"
115 jermar 190
        "popf\n"
413 jermar 191
        : : "r" (ipl)
115 jermar 192
    );
193
}
194
 
413 jermar 195
/** Return interrupt priority level.
115 jermar 196
 *
413 jermar 197
 * @return EFLAFS.
115 jermar 198
 */
432 jermar 199
static inline ipl_t interrupts_read(void)
200
{
413 jermar 201
    ipl_t v;
115 jermar 202
    __asm__ volatile (
358 bondari 203
        "pushf\n\t"
115 jermar 204
        "popl %0\n"
205
        : "=r" (v)
206
    );
207
    return v;
208
}
209
 
173 jermar 210
/** Return base address of current stack
211
 *
212
 * Return the base address of the current stack.
213
 * The stack is assumed to be STACK_SIZE bytes long.
180 jermar 214
 * The stack must start on page boundary.
173 jermar 215
 */
216
static inline __address get_stack_base(void)
217
{
218
    __address v;
219
 
220
    __asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1)));
221
 
222
    return v;
223
}
224
 
348 jermar 225
static inline __u64 rdtsc(void)
226
{
227
    __u64 v;
228
 
229
    __asm__ volatile("rdtsc\n" : "=A" (v));
230
 
231
    return v;
232
}
233
 
581 palkovsky 234
/** Return current IP address */
235
static inline __address * get_ip()
236
{
237
    __address *ip;
238
 
239
    __asm__ volatile (
240
        "mov %%eip, %0"
241
        : "=r" (ip)
242
        );
243
    return ip;
244
}
245
 
597 jermar 246
/** Invalidate TLB Entry.
247
 *
248
 * @param addr Address on a page whose TLB entry is to be invalidated.
249
 */
250
static inline void invlpg(__address addr)
251
{
984 palkovsky 252
    __asm__ volatile ("invlpg %0\n" :: "m" (*(__native *)addr));
597 jermar 253
}
254
 
1186 jermar 255
/** Load GDTR register from memory.
256
 *
257
 * @param gdtr_reg Address of memory from where to load GDTR.
258
 */
1187 jermar 259
static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
1186 jermar 260
{
1251 jermar 261
    __asm__ volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
1186 jermar 262
}
263
 
264
/** Store GDTR register to memory.
265
 *
266
 * @param gdtr_reg Address of memory to where to load GDTR.
267
 */
1187 jermar 268
static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
1186 jermar 269
{
1251 jermar 270
    __asm__ volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
1186 jermar 271
}
272
 
273
/** Load IDTR register from memory.
274
 *
275
 * @param idtr_reg Address of memory from where to load IDTR.
276
 */
1187 jermar 277
static inline void idtr_load(ptr_16_32_t *idtr_reg)
1186 jermar 278
{
1251 jermar 279
    __asm__ volatile ("lidtl %0\n" : : "m" (*idtr_reg));
1186 jermar 280
}
281
 
282
/** Load TR from descriptor table.
283
 *
284
 * @param sel Selector specifying descriptor of TSS segment.
285
 */
286
static inline void tr_load(__u16 sel)
287
{
288
    __asm__ volatile ("ltr %0" : : "r" (sel));
289
}
290
 
1 jermar 291
#endif