source: mainline/kernel/arch/amd64/include/asm.h@ 563c2dd

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 563c2dd was b3f8fb7, checked in by Martin Decky <martin@…>, 19 years ago

huge type system cleanup
remove cyclical type dependencies across multiple header files
many minor coding style fixes

  • Property mode set to 100644
File size: 6.2 KB
RevLine 
[361635c]1/*
[df4ed85]2 * Copyright (c) 2005 Jakub Jermar
[361635c]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
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
15 * derived from this software without specific prior written permission.
16 *
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
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[06e1e95]29/** @addtogroup amd64
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[06e1e95]35#ifndef KERN_amd64_ASM_H_
36#define KERN_amd64_ASM_H_
[361635c]37
38#include <config.h>
39
[7f1c620]40extern void asm_delay_loop(uint32_t t);
41extern void asm_fake_loop(uint32_t t);
[b9e97fb]42
[82a80d3]43/** Return base address of current stack.
44 *
45 * Return the base address of the current stack.
46 * The stack is assumed to be STACK_SIZE bytes long.
47 * The stack must start on page boundary.
48 */
[7f1c620]49static inline uintptr_t get_stack_base(void)
[361635c]50{
[7f1c620]51 uintptr_t v;
[db3341e]52
[e7b7be3f]53 asm volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1)));
[db3341e]54
55 return v;
[361635c]56}
57
[d6dcdd2e]58static inline void cpu_sleep(void) { __asm__ volatile ("hlt\n"); };
59static inline void cpu_halt(void) { __asm__ volatile ("hlt\n"); };
[fa0dfaf]60
[379d73f3]61
[80d2bdb]62/** Byte from port
63 *
64 * Get byte from port
65 *
66 * @param port Port to read from
67 * @return Value read
68 */
[7f1c620]69static inline uint8_t inb(uint16_t port) { uint8_t val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; }
[379d73f3]70
[80d2bdb]71/** Byte to port
72 *
73 * Output byte to port
74 *
75 * @param port Port to write to
76 * @param val Value to write
77 */
[7f1c620]78static inline void outb(uint16_t port, uint8_t val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); }
[379d73f3]79
[37b451f7]80/** Swap Hidden part of GS register with visible one */
81static inline void swapgs(void) { __asm__ volatile("swapgs"); }
82
[22f7769]83/** Enable interrupts.
[379d73f3]84 *
85 * Enable interrupts and return previous
86 * value of EFLAGS.
[22f7769]87 *
88 * @return Old interrupt priority level.
[379d73f3]89 */
[22f7769]90static inline ipl_t interrupts_enable(void) {
91 ipl_t v;
[379d73f3]92 __asm__ volatile (
93 "pushfq\n"
94 "popq %0\n"
95 "sti\n"
96 : "=r" (v)
97 );
98 return v;
99}
100
[22f7769]101/** Disable interrupts.
[379d73f3]102 *
103 * Disable interrupts and return previous
104 * value of EFLAGS.
[22f7769]105 *
106 * @return Old interrupt priority level.
[379d73f3]107 */
[22f7769]108static inline ipl_t interrupts_disable(void) {
109 ipl_t v;
[379d73f3]110 __asm__ volatile (
111 "pushfq\n"
112 "popq %0\n"
113 "cli\n"
114 : "=r" (v)
115 );
116 return v;
117}
118
[22f7769]119/** Restore interrupt priority level.
[379d73f3]120 *
121 * Restore EFLAGS.
[22f7769]122 *
123 * @param ipl Saved interrupt priority level.
[379d73f3]124 */
[22f7769]125static inline void interrupts_restore(ipl_t ipl) {
[379d73f3]126 __asm__ volatile (
127 "pushq %0\n"
128 "popfq\n"
[22f7769]129 : : "r" (ipl)
[379d73f3]130 );
131}
132
[22f7769]133/** Return interrupt priority level.
[b9e97fb]134 *
135 * Return EFLAFS.
[22f7769]136 *
137 * @return Current interrupt priority level.
[b9e97fb]138 */
[22f7769]139static inline ipl_t interrupts_read(void) {
140 ipl_t v;
[b9e97fb]141 __asm__ volatile (
142 "pushfq\n"
143 "popq %0\n"
144 : "=r" (v)
145 );
146 return v;
147}
148
[dd4d6b0]149/** Write to MSR */
[7f1c620]150static inline void write_msr(uint32_t msr, uint64_t value)
[dd4d6b0]151{
152 __asm__ volatile (
153 "wrmsr;" : : "c" (msr),
[7f1c620]154 "a" ((uint32_t)(value)),
155 "d" ((uint32_t)(value >> 32))
[dd4d6b0]156 );
157}
158
[7f1c620]159static inline unative_t read_msr(uint32_t msr)
[dd4d6b0]160{
[7f1c620]161 uint32_t ax, dx;
[dd4d6b0]162
163 __asm__ volatile (
164 "rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr)
165 );
[7f1c620]166 return ((uint64_t)dx << 32) | ax;
[dd4d6b0]167}
168
[c832cc0a]169
[ab08b42]170/** Enable local APIC
171 *
172 * Enable local APIC in MSR.
173 */
174static inline void enable_l_apic_in_msr()
175{
176 __asm__ volatile (
[d6dcdd2e]177 "movl $0x1b, %%ecx\n"
178 "rdmsr\n"
179 "orl $(1<<11),%%eax\n"
180 "orl $(0xfee00000),%%eax\n"
181 "wrmsr\n"
[ab08b42]182 :
183 :
184 :"%eax","%ecx","%edx"
185 );
186}
187
[7f1c620]188static inline uintptr_t * get_ip()
[a3ac9a7]189{
[7f1c620]190 uintptr_t *ip;
[a3ac9a7]191
192 __asm__ volatile (
193 "mov %%rip, %0"
194 : "=r" (ip)
195 );
196 return ip;
197}
198
[7910cff]199/** Invalidate TLB Entry.
200 *
201 * @param addr Address on a page whose TLB entry is to be invalidated.
202 */
[7f1c620]203static inline void invlpg(uintptr_t addr)
[7910cff]204{
[7f1c620]205 __asm__ volatile ("invlpg %0\n" :: "m" (*((unative_t *)addr)));
[897ad60]206}
207
208/** Load GDTR register from memory.
209 *
210 * @param gdtr_reg Address of memory from where to load GDTR.
211 */
212static inline void gdtr_load(struct ptr_16_64 *gdtr_reg)
213{
[11928d5]214 __asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg));
[897ad60]215}
216
217/** Store GDTR register to memory.
218 *
219 * @param gdtr_reg Address of memory to where to load GDTR.
220 */
221static inline void gdtr_store(struct ptr_16_64 *gdtr_reg)
222{
[11928d5]223 __asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg));
[897ad60]224}
225
226/** Load IDTR register from memory.
227 *
228 * @param idtr_reg Address of memory from where to load IDTR.
229 */
230static inline void idtr_load(struct ptr_16_64 *idtr_reg)
231{
[11928d5]232 __asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg));
[897ad60]233}
234
235/** Load TR from descriptor table.
236 *
237 * @param sel Selector specifying descriptor of TSS segment.
238 */
[7f1c620]239static inline void tr_load(uint16_t sel)
[897ad60]240{
241 __asm__ volatile ("ltr %0" : : "r" (sel));
[7910cff]242}
[a3ac9a7]243
[7f1c620]244#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
[4e49572]245 { \
[7f1c620]246 unative_t res; \
[4e49572]247 __asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \
248 return res; \
249 }
250
[7f1c620]251#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
[4e49572]252 { \
253 __asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \
254 }
255
256GEN_READ_REG(cr0);
257GEN_READ_REG(cr2);
258GEN_READ_REG(cr3);
259GEN_WRITE_REG(cr3);
260
261GEN_READ_REG(dr0);
262GEN_READ_REG(dr1);
263GEN_READ_REG(dr2);
264GEN_READ_REG(dr3);
265GEN_READ_REG(dr6);
266GEN_READ_REG(dr7);
267
268GEN_WRITE_REG(dr0);
269GEN_WRITE_REG(dr1);
270GEN_WRITE_REG(dr2);
271GEN_WRITE_REG(dr3);
272GEN_WRITE_REG(dr6);
273GEN_WRITE_REG(dr7);
274
[b9e97fb]275extern size_t interrupt_handler_size;
276extern void interrupt_handlers(void);
[379d73f3]277
[361635c]278#endif
[b45c443]279
[06e1e95]280/** @}
[b45c443]281 */
Note: See TracBrowser for help on using the repository browser.