Subversion Repositories HelenOS

Rev

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

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