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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e7f2ad68 was 92d349c8, checked in by Jakub Jermar <jakub@…>, 18 years ago

More suncc fixes.

  • remove more empty declarations
  • add options to turn errors on empty structs into warnings and options to silence these warnings
  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 2005 Jakub Jermar
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
29/** @addtogroup amd64
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_amd64_ASM_H_
36#define KERN_amd64_ASM_H_
37
38#include <config.h>
39
40extern void asm_delay_loop(uint32_t t);
41extern void asm_fake_loop(uint32_t t);
42
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 */
49static inline uintptr_t get_stack_base(void)
50{
51 uintptr_t v;
52
53 asm volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1)));
54
55 return v;
56}
57
58static inline void cpu_sleep(void)
59{
60 asm volatile ("hlt\n");
61}
62
63static inline void cpu_halt(void)
64{
65 asm volatile ("hlt\n");
66}
67
68
69/** Byte from port
70 *
71 * Get byte from port
72 *
73 * @param port Port to read from
74 * @return Value read
75 */
76static inline uint8_t inb(uint16_t port)
77{
78 uint8_t val;
79
80 asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port));
81 return val;
82}
83
84/** Byte to port
85 *
86 * Output byte to port
87 *
88 * @param port Port to write to
89 * @param val Value to write
90 */
91static inline void outb(uint16_t port, uint8_t val)
92{
93 asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port));
94}
95
96/** Swap Hidden part of GS register with visible one */
97static inline void swapgs(void)
98{
99 asm volatile("swapgs");
100}
101
102/** Enable interrupts.
103 *
104 * Enable interrupts and return previous
105 * value of EFLAGS.
106 *
107 * @return Old interrupt priority level.
108 */
109static inline ipl_t interrupts_enable(void) {
110 ipl_t v;
111 __asm__ volatile (
112 "pushfq\n"
113 "popq %0\n"
114 "sti\n"
115 : "=r" (v)
116 );
117 return v;
118}
119
120/** Disable interrupts.
121 *
122 * Disable interrupts and return previous
123 * value of EFLAGS.
124 *
125 * @return Old interrupt priority level.
126 */
127static inline ipl_t interrupts_disable(void) {
128 ipl_t v;
129 __asm__ volatile (
130 "pushfq\n"
131 "popq %0\n"
132 "cli\n"
133 : "=r" (v)
134 );
135 return v;
136}
137
138/** Restore interrupt priority level.
139 *
140 * Restore EFLAGS.
141 *
142 * @param ipl Saved interrupt priority level.
143 */
144static inline void interrupts_restore(ipl_t ipl) {
145 __asm__ volatile (
146 "pushq %0\n"
147 "popfq\n"
148 : : "r" (ipl)
149 );
150}
151
152/** Return interrupt priority level.
153 *
154 * Return EFLAFS.
155 *
156 * @return Current interrupt priority level.
157 */
158static inline ipl_t interrupts_read(void) {
159 ipl_t v;
160 __asm__ volatile (
161 "pushfq\n"
162 "popq %0\n"
163 : "=r" (v)
164 );
165 return v;
166}
167
168/** Write to MSR */
169static inline void write_msr(uint32_t msr, uint64_t value)
170{
171 __asm__ volatile (
172 "wrmsr;" : : "c" (msr),
173 "a" ((uint32_t)(value)),
174 "d" ((uint32_t)(value >> 32))
175 );
176}
177
178static inline unative_t read_msr(uint32_t msr)
179{
180 uint32_t ax, dx;
181
182 __asm__ volatile (
183 "rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr)
184 );
185 return ((uint64_t)dx << 32) | ax;
186}
187
188
189/** Enable local APIC
190 *
191 * Enable local APIC in MSR.
192 */
193static inline void enable_l_apic_in_msr()
194{
195 __asm__ volatile (
196 "movl $0x1b, %%ecx\n"
197 "rdmsr\n"
198 "orl $(1<<11),%%eax\n"
199 "orl $(0xfee00000),%%eax\n"
200 "wrmsr\n"
201 :
202 :
203 :"%eax","%ecx","%edx"
204 );
205}
206
207static inline uintptr_t * get_ip()
208{
209 uintptr_t *ip;
210
211 __asm__ volatile (
212 "mov %%rip, %0"
213 : "=r" (ip)
214 );
215 return ip;
216}
217
218/** Invalidate TLB Entry.
219 *
220 * @param addr Address on a page whose TLB entry is to be invalidated.
221 */
222static inline void invlpg(uintptr_t addr)
223{
224 __asm__ volatile ("invlpg %0\n" :: "m" (*((unative_t *)addr)));
225}
226
227/** Load GDTR register from memory.
228 *
229 * @param gdtr_reg Address of memory from where to load GDTR.
230 */
231static inline void gdtr_load(struct ptr_16_64 *gdtr_reg)
232{
233 __asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg));
234}
235
236/** Store GDTR register to memory.
237 *
238 * @param gdtr_reg Address of memory to where to load GDTR.
239 */
240static inline void gdtr_store(struct ptr_16_64 *gdtr_reg)
241{
242 __asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg));
243}
244
245/** Load IDTR register from memory.
246 *
247 * @param idtr_reg Address of memory from where to load IDTR.
248 */
249static inline void idtr_load(struct ptr_16_64 *idtr_reg)
250{
251 __asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg));
252}
253
254/** Load TR from descriptor table.
255 *
256 * @param sel Selector specifying descriptor of TSS segment.
257 */
258static inline void tr_load(uint16_t sel)
259{
260 __asm__ volatile ("ltr %0" : : "r" (sel));
261}
262
263#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
264 { \
265 unative_t res; \
266 __asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \
267 return res; \
268 }
269
270#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
271 { \
272 __asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \
273 }
274
275GEN_READ_REG(cr0)
276GEN_READ_REG(cr2)
277GEN_READ_REG(cr3)
278GEN_WRITE_REG(cr3)
279
280GEN_READ_REG(dr0)
281GEN_READ_REG(dr1)
282GEN_READ_REG(dr2)
283GEN_READ_REG(dr3)
284GEN_READ_REG(dr6)
285GEN_READ_REG(dr7)
286
287GEN_WRITE_REG(dr0)
288GEN_WRITE_REG(dr1)
289GEN_WRITE_REG(dr2)
290GEN_WRITE_REG(dr3)
291GEN_WRITE_REG(dr6)
292GEN_WRITE_REG(dr7)
293
294extern size_t interrupt_handler_size;
295extern void interrupt_handlers(void);
296
297#endif
298
299/** @}
300 */
Note: See TracBrowser for help on using the repository browser.