Subversion Repositories HelenOS

Rev

Rev 3536 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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