asm.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #ifndef __amd64_ASM_H__
00036 #define __amd64_ASM_H__
00037 
00038 #include <arch/pm.h>
00039 #include <arch/types.h>
00040 #include <config.h>
00041 
00042 extern void asm_delay_loop(__u32 t);
00043 extern void asm_fake_loop(__u32 t);
00044 
00051 static inline __address get_stack_base(void)
00052 {
00053         __address v;
00054         
00055         __asm__ volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((__u64)STACK_SIZE-1)));
00056         
00057         return v;
00058 }
00059 
00060 static inline void cpu_sleep(void) { __asm__ volatile ("hlt\n"); };
00061 static inline void cpu_halt(void) { __asm__ volatile ("hlt\n"); };
00062 
00063 
00071 static inline __u8 inb(__u16 port) { __u8 val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; }
00072 
00080 static inline void outb(__u16 port, __u8 val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); }
00081 
00083 static inline void swapgs(void) { __asm__ volatile("swapgs"); }
00084 
00092 static inline ipl_t interrupts_enable(void) {
00093         ipl_t v;
00094         __asm__ volatile (
00095                 "pushfq\n"
00096                 "popq %0\n"
00097                 "sti\n"
00098                 : "=r" (v)
00099         );
00100         return v;
00101 }
00102 
00110 static inline ipl_t interrupts_disable(void) {
00111         ipl_t v;
00112         __asm__ volatile (
00113                 "pushfq\n"
00114                 "popq %0\n"
00115                 "cli\n"
00116                 : "=r" (v)
00117                 );
00118         return v;
00119 }
00120 
00127 static inline void interrupts_restore(ipl_t ipl) {
00128         __asm__ volatile (
00129                 "pushq %0\n"
00130                 "popfq\n"
00131                 : : "r" (ipl)
00132                 );
00133 }
00134 
00141 static inline ipl_t interrupts_read(void) {
00142         ipl_t v;
00143         __asm__ volatile (
00144                 "pushfq\n"
00145                 "popq %0\n"
00146                 : "=r" (v)
00147         );
00148         return v;
00149 }
00150 
00152 static inline void write_msr(__u32 msr, __u64 value)
00153 {
00154         __asm__ volatile (
00155                 "wrmsr;" : : "c" (msr), 
00156                 "a" ((__u32)(value)),
00157                 "d" ((__u32)(value >> 32))
00158                 );
00159 }
00160 
00161 static inline __native read_msr(__u32 msr)
00162 {
00163         __u32 ax, dx;
00164 
00165         __asm__ volatile (
00166                 "rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr)
00167                 );
00168         return ((__u64)dx << 32) | ax;
00169 }
00170 
00171 
00176 static inline void enable_l_apic_in_msr()
00177 {
00178         __asm__ volatile (
00179                 "movl $0x1b, %%ecx\n"
00180                 "rdmsr\n"
00181                 "orl $(1<<11),%%eax\n"
00182                 "orl $(0xfee00000),%%eax\n"
00183                 "wrmsr\n"
00184                 :
00185                 :
00186                 :"%eax","%ecx","%edx"
00187                 );
00188 }
00189 
00190 static inline __address * get_ip() 
00191 {
00192         __address *ip;
00193 
00194         __asm__ volatile (
00195                 "mov %%rip, %0"
00196                 : "=r" (ip)
00197                 );
00198         return ip;
00199 }
00200 
00205 static inline void invlpg(__address addr)
00206 {
00207         __asm__ volatile ("invlpg %0\n" :: "m" (*((__native *)addr)));
00208 }
00209 
00214 static inline void gdtr_load(struct ptr_16_64 *gdtr_reg)
00215 {
00216         __asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg));
00217 }
00218 
00223 static inline void gdtr_store(struct ptr_16_64 *gdtr_reg)
00224 {
00225         __asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg));
00226 }
00227 
00232 static inline void idtr_load(struct ptr_16_64 *idtr_reg)
00233 {
00234         __asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg));
00235 }
00236 
00241 static inline void tr_load(__u16 sel)
00242 {
00243         __asm__ volatile ("ltr %0" : : "r" (sel));
00244 }
00245 
00246 #define GEN_READ_REG(reg) static inline __native read_ ##reg (void) \
00247     { \
00248         __native res; \
00249         __asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \
00250         return res; \
00251     }
00252 
00253 #define GEN_WRITE_REG(reg) static inline void write_ ##reg (__native regn) \
00254     { \
00255         __asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \
00256     }
00257 
00258 GEN_READ_REG(cr0);
00259 GEN_READ_REG(cr2);
00260 GEN_READ_REG(cr3);
00261 GEN_WRITE_REG(cr3);
00262 
00263 GEN_READ_REG(dr0);
00264 GEN_READ_REG(dr1);
00265 GEN_READ_REG(dr2);
00266 GEN_READ_REG(dr3);
00267 GEN_READ_REG(dr6);
00268 GEN_READ_REG(dr7);
00269 
00270 GEN_WRITE_REG(dr0);
00271 GEN_WRITE_REG(dr1);
00272 GEN_WRITE_REG(dr2);
00273 GEN_WRITE_REG(dr3);
00274 GEN_WRITE_REG(dr6);
00275 GEN_WRITE_REG(dr7);
00276 
00277 
00278 extern size_t interrupt_handler_size;
00279 extern void interrupt_handlers(void);
00280 
00281 #endif
00282 

Generated on Sun Jun 18 16:26:57 2006 for HelenOS Kernel (amd64) by  doxygen 1.4.6