#ifndef _ASM_H
#define _ASM_H
#define nop() asm volatile ("nop")
#define load_cs(sel) \
asm volatile ("ljmpl %0, $1f\n" \
"1:" \
:: "i" (sel))
#define load_ds(sel) \
asm volatile ("movw %w0, %%ds" :: "r" (sel) : "memory")
#define load_es(sel) \
asm volatile ("movw %w0, %%es" :: "r" (sel) : "memory")
#define load_fs(sel) \
asm volatile ("movw %w0, %%fs" :: "r" (sel) : "memory")
#define load_gs(sel) \
asm volatile ("movw %w0, %%gs" :: "r" (sel) : "memory")
#define load_ss(sel) \
asm volatile ("movw %w0, %%ss" :: "r" (sel) : "memory")
#define get_fs(fs) \
asm ("movw %%fs, %0" : "=r" (fs))
#define lldt(sel) asm volatile ("lldt %w0" :: "r" (sel))
#define lgdt(descr) asm volatile ("lgdt %0" :: "m" (descr))
#define ltr(sel) asm volatile ("ltr %w0" :: "r" (sel))
#define cli() asm volatile ("cli")
#define sti() asm volatile ("sti")
#define lidt(descr) asm volatile ("lidt %0" :: "m" (descr))
#define disable_intr(intr) \
asm volatile ("pushfl\n\t" \
"popl %0\n\t" \
"andl $0x200, %0\n\t" \
"cli" \
: "=r" (intr) \
:: "memory")
#define restore_intr(intr) \
asm volatile ("testl %0, %0\n\t" \
"jz 1f\n\t" \
"sti\n" \
"1:" \
:: "r" (intr) \
: "cc")
#define outb(value, port) \
asm volatile ("outb %%al, %%dx" :: "a" (value), "d" (port))
#define outbp(value, port) \
asm volatile ("outb %%al, %%dx\n\t" \
"jmp 1f\n" \
"1:" :: "a" (value), "d" (port))
#define inb(port) ({ \
unsigned char _v; \
asm volatile ("inb %%dx, %%al" : "=a" (_v) : "d" (port)); \
_v; \
})
#define inbp(port) ({ \
unsigned char _v; \
asm volatile ("inb %%dx, %%al\n\t" \
"jmp 1f\n" \
"1:" : "=a" (_v) : "d" (port)); \
_v; \
})
#define hlt() asm volatile ("hlt")
#define save_control_flags(flags) \
asm ("movl %%cr0, %0" : "=r" (flags))
#define restore_control_flags(flags) \
asm volatile ("movl %0, %%cr0" :: "r" (flags))
#define disable_cache() \
asm volatile ("movl %%cr0, %%eax\n\t" \
"orl $0x40000000, %%eax\n\t" \
"movl %%eax, %%cr0\n\t" \
"wbinvd\n\t" \
"orl $0x20000000, %%eax\n\t" \
"movl %%eax, %%cr0" \
::: "%eax")
#define set_pg() \
asm volatile ("movl %%cr0, %%eax\n\t" \
"orl $0x80000000, %%eax\n\t" \
"movl %%eax, %%cr0\n\t" \
"jmp 1f\n" \
"1:" \
::: "%eax", "memory")
#define get_page_fault_laddr(laddr) \
asm ("movl %%cr2, %0" : "=r" (laddr))
#define get_pdbr(pdbr) \
asm ("movl %%cr3, %0" : "=r" (pdbr))
#define set_pdbr(pdbr) \
asm volatile ("movl %0, %%cr3" :: "r" (pdbr) : "memory")
#define task_switch(addr) \
asm volatile ("ljmpl *%0" :: "m" (addr) : "memory")
#define invlpg(laddr) \
asm volatile ("invlpg %0" :: "m" (*(char *)laddr) : "memory");
#endif