xv6

port of xv6 to x86-64
git clone http://frotz.net/git/xv6.git
Log | Files | Refs | README | LICENSE

x86.h (3973B)


      1 // Routines to let C code use special x86 instructions.
      2 
      3 static inline uchar
      4 inb(ushort port)
      5 {
      6   uchar data;
      7 
      8   asm volatile("in %1,%0" : "=a" (data) : "d" (port));
      9   return data;
     10 }
     11 
     12 static inline void
     13 insl(int port, void *addr, int cnt)
     14 {
     15   asm volatile("cld; rep insl" :
     16                "=D" (addr), "=c" (cnt) :
     17                "d" (port), "0" (addr), "1" (cnt) :
     18                "memory", "cc");
     19 }
     20 
     21 static inline void
     22 outb(ushort port, uchar data)
     23 {
     24   asm volatile("out %0,%1" : : "a" (data), "d" (port));
     25 }
     26 
     27 static inline void
     28 outw(ushort port, ushort data)
     29 {
     30   asm volatile("out %0,%1" : : "a" (data), "d" (port));
     31 }
     32 
     33 static inline void
     34 outsl(int port, const void *addr, int cnt)
     35 {
     36   asm volatile("cld; rep outsl" :
     37                "=S" (addr), "=c" (cnt) :
     38                "d" (port), "0" (addr), "1" (cnt) :
     39                "cc");
     40 }
     41 
     42 static inline void
     43 stosb(void *addr, int data, int cnt)
     44 {
     45   asm volatile("cld; rep stosb" :
     46                "=D" (addr), "=c" (cnt) :
     47                "0" (addr), "1" (cnt), "a" (data) :
     48                "memory", "cc");
     49 }
     50 
     51 static inline void
     52 stosl(void *addr, int data, int cnt)
     53 {
     54   asm volatile("cld; rep stosl" :
     55                "=D" (addr), "=c" (cnt) :
     56                "0" (addr), "1" (cnt), "a" (data) :
     57                "memory", "cc");
     58 }
     59 
     60 struct segdesc;
     61 
     62 static inline void
     63 lgdt(struct segdesc *p, int size)
     64 {
     65   volatile ushort pd[5];
     66 
     67   pd[0] = size-1;
     68   pd[1] = (uintp)p;
     69   pd[2] = (uintp)p >> 16;
     70 #if X64
     71   pd[3] = (uintp)p >> 32;
     72   pd[4] = (uintp)p >> 48;
     73 #endif
     74   asm volatile("lgdt (%0)" : : "r" (pd));
     75 }
     76 
     77 struct gatedesc;
     78 
     79 static inline void
     80 lidt(struct gatedesc *p, int size)
     81 {
     82   volatile ushort pd[5];
     83 
     84   pd[0] = size-1;
     85   pd[1] = (uintp)p;
     86   pd[2] = (uintp)p >> 16;
     87 #if X64
     88   pd[3] = (uintp)p >> 32;
     89   pd[4] = (uintp)p >> 48;
     90 #endif
     91   asm volatile("lidt (%0)" : : "r" (pd));
     92 }
     93 
     94 static inline void
     95 ltr(ushort sel)
     96 {
     97   asm volatile("ltr %0" : : "r" (sel));
     98 }
     99 
    100 static inline uintp
    101 readeflags(void)
    102 {
    103   uintp eflags;
    104   asm volatile("pushf; pop %0" : "=r" (eflags));
    105   return eflags;
    106 }
    107 
    108 static inline void
    109 loadgs(ushort v)
    110 {
    111   asm volatile("movw %0, %%gs" : : "r" (v));
    112 }
    113 
    114 static inline void
    115 cli(void)
    116 {
    117   asm volatile("cli");
    118 }
    119 
    120 static inline void
    121 sti(void)
    122 {
    123   asm volatile("sti");
    124 }
    125 
    126 static inline void
    127 hlt(void)
    128 {
    129   asm volatile("hlt");
    130 }
    131 
    132 static inline uint
    133 xchg(volatile uint *addr, uintp newval)
    134 {
    135   uint result;
    136   
    137   // The + in "+m" denotes a read-modify-write operand.
    138   asm volatile("lock; xchgl %0, %1" :
    139                "+m" (*addr), "=a" (result) :
    140                "1" (newval) :
    141                "cc");
    142   return result;
    143 }
    144 
    145 static inline uintp
    146 rcr2(void)
    147 {
    148   uintp val;
    149   asm volatile("mov %%cr2,%0" : "=r" (val));
    150   return val;
    151 }
    152 
    153 static inline void
    154 lcr3(uintp val) 
    155 {
    156   asm volatile("mov %0,%%cr3" : : "r" (val));
    157 }
    158 
    159 //PAGEBREAK: 36
    160 // Layout of the trap frame built on the stack by the
    161 // hardware and by trapasm.S, and passed to trap().
    162 #if X64
    163 // lie about some register names in 64bit mode to avoid
    164 // clunky ifdefs in proc.c and trap.c.
    165 struct trapframe {
    166   uint64 eax;      // rax
    167   uint64 rbx;
    168   uint64 rcx;
    169   uint64 rdx;
    170   uint64 rbp;
    171   uint64 rsi;
    172   uint64 rdi;
    173   uint64 r8;
    174   uint64 r9;
    175   uint64 r10;
    176   uint64 r11;
    177   uint64 r12;
    178   uint64 r13;
    179   uint64 r14;
    180   uint64 r15;
    181 
    182   uint64 trapno;
    183   uint64 err;
    184 
    185   uint64 eip;     // rip
    186   uint64 cs;
    187   uint64 eflags;  // rflags
    188   uint64 esp;     // rsp
    189   uint64 ds;      // ss
    190 };
    191 #else
    192 struct trapframe {
    193   // registers as pushed by pusha
    194   uint edi;
    195   uint esi;
    196   uint ebp;
    197   uint oesp;      // useless & ignored
    198   uint ebx;
    199   uint edx;
    200   uint ecx;
    201   uint eax;
    202 
    203   // rest of trap frame
    204   ushort gs;
    205   ushort padding1;
    206   ushort fs;
    207   ushort padding2;
    208   ushort es;
    209   ushort padding3;
    210   ushort ds;
    211   ushort padding4;
    212   uint trapno;
    213 
    214   // below here defined by x86 hardware
    215   uint err;
    216   uint eip;
    217   ushort cs;
    218   ushort padding5;
    219   uint eflags;
    220 
    221   // below here only when crossing rings, such as from user to kernel
    222   uint esp;
    223   ushort ss;
    224   ushort padding6;
    225 };
    226 #endif