Subversion Repositories HelenOS

Rev

Rev 4017 | Rev 4095 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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