Subversion Repositories HelenOS

Rev

Rev 4344 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4344 Rev 4345
Line 25... Line 25...
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
28
 */
29
 
29
 
30
/** @addtogroup ia32   
30
/** @addtogroup ia32
31
 * @{
31
 * @{
32
 */
32
 */
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
36
#ifndef KERN_ia32_ASM_H_
36
#ifndef KERN_ia32_ASM_H_
37
#define KERN_ia32_ASM_H_
37
#define KERN_ia32_ASM_H_
38
 
38
 
39
#include <arch/pm.h>
39
#include <arch/pm.h>
40
#include <arch/types.h>
40
#include <arch/types.h>
-
 
41
#include <typedefs.h>
41
#include <config.h>
42
#include <config.h>
42
 
43
 
43
extern uint32_t interrupt_handler_size;
44
extern uint32_t interrupt_handler_size;
44
 
45
 
45
extern void paging_on(void);
46
extern void paging_on(void);
Line 54... Line 55...
54
 
55
 
55
 
56
 
56
/** Halt CPU
57
/** Halt CPU
57
 *
58
 *
58
 * Halt the current CPU until interrupt event.
59
 * Halt the current CPU until interrupt event.
-
 
60
 *
59
 */
61
 */
60
static inline void cpu_halt(void)
62
static inline void cpu_halt(void)
61
{
63
{
62
    asm volatile ("hlt\n");
64
    asm volatile ("hlt\n");
63
}
65
}
Line 66... Line 68...
66
{
68
{
67
    asm volatile ("hlt\n");
69
    asm volatile ("hlt\n");
68
}
70
}
69
 
71
 
70
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
72
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
71
    { \
73
    { \
72
    unative_t res; \
74
        unative_t res; \
-
 
75
        asm volatile ( \
73
    asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
76
            "movl %%" #reg ", %[res]" \
-
 
77
            : [res] "=r" (res) \
-
 
78
        ); \
74
    return res; \
79
        return res; \
75
    }
80
    }
76
 
81
 
77
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
82
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
78
    { \
83
    { \
-
 
84
        asm volatile ( \
79
    asm volatile ("movl %0, %%" #reg : : "r" (regn)); \
85
            "movl %[regn], %%" #reg \
-
 
86
            :: [regn] "r" (regn) \
80
    }
87
        ); \
-
 
88
    }
81
 
89
 
82
GEN_READ_REG(cr0)
90
GEN_READ_REG(cr0)
83
GEN_READ_REG(cr2)
91
GEN_READ_REG(cr2)
84
GEN_READ_REG(cr3)
92
GEN_READ_REG(cr3)
85
GEN_WRITE_REG(cr3)
93
GEN_WRITE_REG(cr3)
Line 102... Line 110...
102
 *
110
 *
103
 * Output byte to port
111
 * Output byte to port
104
 *
112
 *
105
 * @param port Port to write to
113
 * @param port Port to write to
106
 * @param val Value to write
114
 * @param val Value to write
-
 
115
 *
107
 */
116
 */
108
static inline void pio_write_8(ioport8_t *port, uint8_t val)
117
static inline void pio_write_8(ioport8_t *port, uint8_t val)
109
{
118
{
-
 
119
    asm volatile (
-
 
120
        "outb %b[val], %w[port]\n"
110
    asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port));
121
        :: [val] "a" (val), [port] "d" (port)
-
 
122
    );
111
}
123
}
112
 
124
 
113
/** Word to port
125
/** Word to port
114
 *
126
 *
115
 * Output word to port
127
 * Output word to port
116
 *
128
 *
117
 * @param port Port to write to
129
 * @param port Port to write to
118
 * @param val Value to write
130
 * @param val Value to write
-
 
131
 *
119
 */
132
 */
120
static inline void pio_write_16(ioport16_t *port, uint16_t val)
133
static inline void pio_write_16(ioport16_t *port, uint16_t val)
121
{
134
{
-
 
135
    asm volatile (
-
 
136
        "outw %w[val], %w[port]\n"
122
    asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port));
137
        :: [val] "a" (val), [port] "d" (port)
-
 
138
    );
123
}
139
}
124
 
140
 
125
/** Double word to port
141
/** Double word to port
126
 *
142
 *
127
 * Output double word to port
143
 * Output double word to port
128
 *
144
 *
129
 * @param port Port to write to
145
 * @param port Port to write to
130
 * @param val Value to write
146
 * @param val Value to write
-
 
147
 *
131
 */
148
 */
132
static inline void pio_write_32(ioport32_t *port, uint32_t val)
149
static inline void pio_write_32(ioport32_t *port, uint32_t val)
133
{
150
{
-
 
151
    asm volatile (
-
 
152
        "outl %[val], %w[port]\n"
134
    asm volatile ("outl %0, %w1\n" : : "a" (val), "d" (port));
153
        :: [val] "a" (val), [port] "d" (port)
-
 
154
    );
135
}
155
}
136
 
156
 
137
/** Byte from port
157
/** Byte from port
138
 *
158
 *
139
 * Get byte from port
159
 * Get byte from port
140
 *
160
 *
141
 * @param port Port to read from
161
 * @param port Port to read from
142
 * @return Value read
162
 * @return Value read
-
 
163
 *
143
 */
164
 */
144
static inline uint8_t pio_read_8(ioport8_t *port)
165
static inline uint8_t pio_read_8(ioport8_t *port)
145
{
166
{
146
    uint8_t val;
167
    uint8_t val;
147
   
168
   
-
 
169
    asm volatile (
148
    asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port));
170
        "inb %w[port], %b[val]\n"
-
 
171
        : [val] "=a" (val)
-
 
172
        : [port] "d" (port)
-
 
173
    );
-
 
174
   
149
    return val;
175
    return val;
150
}
176
}
151
 
177
 
152
/** Word from port
178
/** Word from port
153
 *
179
 *
154
 * Get word from port
180
 * Get word from port
155
 *
181
 *
156
 * @param port Port to read from
182
 * @param port Port to read from
157
 * @return Value read
183
 * @return Value read
-
 
184
 *
158
 */
185
 */
159
static inline uint16_t pio_read_16(ioport16_t *port)
186
static inline uint16_t pio_read_16(ioport16_t *port)
160
{
187
{
161
    uint16_t val;
188
    uint16_t val;
162
   
189
   
-
 
190
    asm volatile (
163
    asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port));
191
        "inw %w[port], %w[val]\n"
-
 
192
        : [val] "=a" (val)
-
 
193
        : [port] "d" (port)
-
 
194
    );
-
 
195
   
164
    return val;
196
    return val;
165
}
197
}
166
 
198
 
167
/** Double word from port
199
/** Double word from port
168
 *
200
 *
169
 * Get double word from port
201
 * Get double word from port
170
 *
202
 *
171
 * @param port Port to read from
203
 * @param port Port to read from
172
 * @return Value read
204
 * @return Value read
-
 
205
 *
173
 */
206
 */
174
static inline uint32_t pio_read_32(ioport32_t *port)
207
static inline uint32_t pio_read_32(ioport32_t *port)
175
{
208
{
176
    uint32_t val;
209
    uint32_t val;
177
   
210
   
-
 
211
    asm volatile (
178
    asm volatile ("inl %w1, %0 \n" : "=a" (val) : "d" (port));
212
        "inl %w[port], %[val]\n"
-
 
213
        : [val] "=a" (val)
-
 
214
        : [port] "d" (port)
-
 
215
    );
-
 
216
   
179
    return val;
217
    return val;
180
}
218
}
181
 
219
 
182
/** Enable interrupts.
220
/** Enable interrupts.
183
 *
221
 *
184
 * Enable interrupts and return previous
222
 * Enable interrupts and return previous
185
 * value of EFLAGS.
223
 * value of EFLAGS.
186
 *
224
 *
187
 * @return Old interrupt priority level.
225
 * @return Old interrupt priority level.
-
 
226
 *
188
 */
227
 */
189
static inline ipl_t interrupts_enable(void)
228
static inline ipl_t interrupts_enable(void)
190
{
229
{
191
    ipl_t v;
230
    ipl_t v;
-
 
231
   
192
    asm volatile (
232
    asm volatile (
193
        "pushf\n\t"
233
        "pushf\n"
194
        "popl %0\n\t"
234
        "popl %[v]\n"
195
        "sti\n"
235
        "sti\n"
196
        : "=r" (v)
236
        : [v] "=r" (v)
197
    );
237
    );
-
 
238
   
198
    return v;
239
    return v;
199
}
240
}
200
 
241
 
201
/** Disable interrupts.
242
/** Disable interrupts.
202
 *
243
 *
203
 * Disable interrupts and return previous
244
 * Disable interrupts and return previous
204
 * value of EFLAGS.
245
 * value of EFLAGS.
205
 *
246
 *
206
 * @return Old interrupt priority level.
247
 * @return Old interrupt priority level.
-
 
248
 *
207
 */
249
 */
208
static inline ipl_t interrupts_disable(void)
250
static inline ipl_t interrupts_disable(void)
209
{
251
{
210
    ipl_t v;
252
    ipl_t v;
-
 
253
   
211
    asm volatile (
254
    asm volatile (
212
        "pushf\n\t"
255
        "pushf\n"
213
        "popl %0\n\t"
256
        "popl %[v]\n"
214
        "cli\n"
257
        "cli\n"
215
        : "=r" (v)
258
        : [v] "=r" (v)
216
    );
259
    );
-
 
260
   
217
    return v;
261
    return v;
218
}
262
}
219
 
263
 
220
/** Restore interrupt priority level.
264
/** Restore interrupt priority level.
221
 *
265
 *
222
 * Restore EFLAGS.
266
 * Restore EFLAGS.
223
 *
267
 *
224
 * @param ipl Saved interrupt priority level.
268
 * @param ipl Saved interrupt priority level.
-
 
269
 *
225
 */
270
 */
226
static inline void interrupts_restore(ipl_t ipl)
271
static inline void interrupts_restore(ipl_t ipl)
227
{
272
{
228
    asm volatile (
273
    asm volatile (
229
        "pushl %0\n\t"
274
        "pushl %[ipl]\n"
230
        "popf\n"
275
        "popf\n"
231
        : : "r" (ipl)
276
        :: [ipl] "r" (ipl)
232
    );
277
    );
233
}
278
}
234
 
279
 
235
/** Return interrupt priority level.
280
/** Return interrupt priority level.
236
 *
281
 *
237
 * @return EFLAFS.
282
 * @return EFLAFS.
-
 
283
 *
238
 */
284
 */
239
static inline ipl_t interrupts_read(void)
285
static inline ipl_t interrupts_read(void)
240
{
286
{
241
    ipl_t v;
287
    ipl_t v;
-
 
288
   
242
    asm volatile (
289
    asm volatile (
243
        "pushf\n\t"
290
        "pushf\n"
244
        "popl %0\n"
291
        "popl %[v]\n"
245
        : "=r" (v)
292
        : [v] "=r" (v)
246
    );
293
    );
-
 
294
   
247
    return v;
295
    return v;
248
}
296
}
249
 
297
 
250
/** Write to MSR */
298
/** Write to MSR */
251
static inline void write_msr(uint32_t msr, uint64_t value)
299
static inline void write_msr(uint32_t msr, uint64_t value)
252
{
300
{
-
 
301
    asm volatile (
-
 
302
        "wrmsr"
253
    asm volatile ("wrmsr" : : "c" (msr), "a" ((uint32_t)(value)),
303
        :: "c" (msr), "a" ((uint32_t) (value)),
254
        "d" ((uint32_t)(value >> 32)));
304
           "d" ((uint32_t) (value >> 32))
-
 
305
    );
255
}
306
}
256
 
307
 
257
static inline uint64_t read_msr(uint32_t msr)
308
static inline uint64_t read_msr(uint32_t msr)
258
{
309
{
259
    uint32_t ax, dx;
310
    uint32_t ax, dx;
260
 
311
   
-
 
312
    asm volatile (
-
 
313
        "rdmsr"
261
    asm volatile ("rdmsr" : "=a"(ax), "=d"(dx) : "c" (msr));
314
        : "=a" (ax), "=d" (dx)
-
 
315
        : "c" (msr)
-
 
316
    );
-
 
317
   
262
    return ((uint64_t)dx << 32) | ax;
318
    return ((uint64_t) dx << 32) | ax;
263
}
319
}
264
 
320
 
265
 
321
 
266
/** Return base address of current stack
322
/** Return base address of current stack
267
 *
323
 *
268
 * Return the base address of the current stack.
324
 * Return the base address of the current stack.
269
 * The stack is assumed to be STACK_SIZE bytes long.
325
 * The stack is assumed to be STACK_SIZE bytes long.
270
 * The stack must start on page boundary.
326
 * The stack must start on page boundary.
-
 
327
 *
271
 */
328
 */
272
static inline uintptr_t get_stack_base(void)
329
static inline uintptr_t get_stack_base(void)
273
{
330
{
274
    uintptr_t v;
331
    uintptr_t v;
275
   
332
   
276
    asm volatile (
333
    asm volatile (
277
        "andl %%esp, %0\n"
334
        "andl %%esp, %[v]\n"
278
        : "=r" (v)
335
        : [v] "=r" (v)
279
        : "0" (~(STACK_SIZE - 1))
336
        : "0" (~(STACK_SIZE - 1))
280
    );
337
    );
281
   
338
   
282
    return v;
339
    return v;
283
}
340
}
284
 
341
 
285
/** Return current IP address */
342
/** Return current IP address */
286
static inline uintptr_t * get_ip()
343
static inline uintptr_t * get_ip()
287
{
344
{
288
    uintptr_t *ip;
345
    uintptr_t *ip;
289
 
346
   
290
    asm volatile (
347
    asm volatile (
291
        "mov %%eip, %0"
348
        "mov %%eip, %[ip]"
292
        : "=r" (ip)
349
        : [ip] "=r" (ip)
293
        );
350
    );
-
 
351
   
294
    return ip;
352
    return ip;
295
}
353
}
296
 
354
 
297
/** Invalidate TLB Entry.
355
/** Invalidate TLB Entry.
298
 *
356
 *
299
 * @param addr Address on a page whose TLB entry is to be invalidated.
357
 * @param addr Address on a page whose TLB entry is to be invalidated.
-
 
358
 *
300
 */
359
 */
301
static inline void invlpg(uintptr_t addr)
360
static inline void invlpg(uintptr_t addr)
302
{
361
{
-
 
362
    asm volatile (
-
 
363
        "invlpg %[addr]\n"
303
    asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
364
        :: [addr] "m" (*(unative_t *) addr)
-
 
365
    );
304
}
366
}
305
 
367
 
306
/** Load GDTR register from memory.
368
/** Load GDTR register from memory.
307
 *
369
 *
308
 * @param gdtr_reg Address of memory from where to load GDTR.
370
 * @param gdtr_reg Address of memory from where to load GDTR.
-
 
371
 *
309
 */
372
 */
310
static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
373
static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
311
{
374
{
-
 
375
    asm volatile (
-
 
376
        "lgdtl %[gdtr_reg]\n"
312
    asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
377
        :: [gdtr_reg] "m" (*gdtr_reg)
-
 
378
    );
313
}
379
}
314
 
380
 
315
/** Store GDTR register to memory.
381
/** Store GDTR register to memory.
316
 *
382
 *
317
 * @param gdtr_reg Address of memory to where to load GDTR.
383
 * @param gdtr_reg Address of memory to where to load GDTR.
-
 
384
 *
318
 */
385
 */
319
static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
386
static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
320
{
387
{
-
 
388
    asm volatile (
-
 
389
        "sgdtl %[gdtr_reg]\n"
321
    asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
390
        :: [gdtr_reg] "m" (*gdtr_reg)
-
 
391
    );
322
}
392
}
323
 
393
 
324
/** Load IDTR register from memory.
394
/** Load IDTR register from memory.
325
 *
395
 *
326
 * @param idtr_reg Address of memory from where to load IDTR.
396
 * @param idtr_reg Address of memory from where to load IDTR.
-
 
397
 *
327
 */
398
 */
328
static inline void idtr_load(ptr_16_32_t *idtr_reg)
399
static inline void idtr_load(ptr_16_32_t *idtr_reg)
329
{
400
{
-
 
401
    asm volatile (
-
 
402
        "lidtl %[idtr_reg]\n"
330
    asm volatile ("lidtl %0\n" : : "m" (*idtr_reg));
403
        :: [idtr_reg] "m" (*idtr_reg)
-
 
404
    );
331
}
405
}
332
 
406
 
333
/** Load TR from descriptor table.
407
/** Load TR from descriptor table.
334
 *
408
 *
335
 * @param sel Selector specifying descriptor of TSS segment.
409
 * @param sel Selector specifying descriptor of TSS segment.
-
 
410
 *
336
 */
411
 */
337
static inline void tr_load(uint16_t sel)
412
static inline void tr_load(uint16_t sel)
338
{
413
{
-
 
414
    asm volatile (
-
 
415
        "ltr %[sel]"
339
    asm volatile ("ltr %0" : : "r" (sel));
416
        :: [sel] "r" (sel)
-
 
417
    );
340
}
418
}
341
 
419
 
342
#endif
420
#endif
343
 
421
 
344
/** @}
422
/** @}