Subversion Repositories HelenOS

Rev

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

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