xref: /xv6-public/x86.h (revision 7894fcd2)
1ab4cedb5Srtm // Routines to let C code use special x86 instructions.
231085bb4Srsc 
368ae4cc1Srsc static inline uchar
inb(ushort port)4ef30c2c7Srsc inb(ushort port)
555e95b16Srtm {
629270816Srtm   uchar data;
77bb73cdbSrsc 
868ae4cc1Srsc   asm volatile("in %1,%0" : "=a" (data) : "d" (port));
955e95b16Srtm   return data;
1055e95b16Srtm }
1155e95b16Srtm 
1268ae4cc1Srsc static inline void
insl(int port,void * addr,int cnt)1355e95b16Srtm insl(int port, void *addr, int cnt)
1455e95b16Srtm {
15c396d065Srsc   asm volatile("cld; rep insl" :
1655e95b16Srtm                "=D" (addr), "=c" (cnt) :
1755e95b16Srtm                "d" (port), "0" (addr), "1" (cnt) :
1855e95b16Srtm                "memory", "cc");
1955e95b16Srtm }
2055e95b16Srtm 
2168ae4cc1Srsc static inline void
outb(ushort port,uchar data)22ef30c2c7Srsc outb(ushort port, uchar data)
2355e95b16Srtm {
2468ae4cc1Srsc   asm volatile("out %0,%1" : : "a" (data), "d" (port));
2555e95b16Srtm }
2655e95b16Srtm 
2768ae4cc1Srsc static inline void
outw(ushort port,ushort data)28ef30c2c7Srsc outw(ushort port, ushort data)
2955e95b16Srtm {
3068ae4cc1Srsc   asm volatile("out %0,%1" : : "a" (data), "d" (port));
3155e95b16Srtm }
3255e95b16Srtm 
3368ae4cc1Srsc static inline void
outsl(int port,const void * addr,int cnt)3455e95b16Srtm outsl(int port, const void *addr, int cnt)
3555e95b16Srtm {
36c396d065Srsc   asm volatile("cld; rep outsl" :
3755e95b16Srtm                "=S" (addr), "=c" (cnt) :
3855e95b16Srtm                "d" (port), "0" (addr), "1" (cnt) :
3955e95b16Srtm                "cc");
4055e95b16Srtm }
4155e95b16Srtm 
42c396d065Srsc static inline void
stosb(void * addr,int data,int cnt)43c396d065Srsc stosb(void *addr, int data, int cnt)
44c396d065Srsc {
45c396d065Srsc   asm volatile("cld; rep stosb" :
46c396d065Srsc                "=D" (addr), "=c" (cnt) :
47c396d065Srsc                "0" (addr), "1" (cnt), "a" (data) :
48c396d065Srsc                "memory", "cc");
49c396d065Srsc }
50c396d065Srsc 
51*d0f3efcaSAustin Clements static inline void
stosl(void * addr,int data,int cnt)52*d0f3efcaSAustin Clements stosl(void *addr, int data, int cnt)
53*d0f3efcaSAustin Clements {
54*d0f3efcaSAustin Clements   asm volatile("cld; rep stosl" :
55*d0f3efcaSAustin Clements                "=D" (addr), "=c" (cnt) :
56*d0f3efcaSAustin Clements                "0" (addr), "1" (cnt), "a" (data) :
57*d0f3efcaSAustin Clements                "memory", "cc");
58*d0f3efcaSAustin Clements }
59*d0f3efcaSAustin Clements 
602b19190cSrtm struct segdesc;
6155e95b16Srtm 
6268ae4cc1Srsc static inline void
lgdt(struct segdesc * p,int size)63b5f17007Srsc lgdt(struct segdesc *p, int size)
6455e95b16Srtm {
6529270816Srtm   volatile ushort pd[3];
66564f787eSrsc 
67564f787eSrsc   pd[0] = size-1;
68564f787eSrsc   pd[1] = (uint)p;
69564f787eSrsc   pd[2] = (uint)p >> 16;
70564f787eSrsc 
712aae7205Srsc   asm volatile("lgdt (%0)" : : "r" (pd));
72564f787eSrsc }
73564f787eSrsc 
742b19190cSrtm struct gatedesc;
752b19190cSrtm 
7668ae4cc1Srsc static inline void
lidt(struct gatedesc * p,int size)77b5f17007Srsc lidt(struct gatedesc *p, int size)
78564f787eSrsc {
7929270816Srtm   volatile ushort pd[3];
80564f787eSrsc 
81564f787eSrsc   pd[0] = size-1;
82564f787eSrsc   pd[1] = (uint)p;
83564f787eSrsc   pd[2] = (uint)p >> 16;
84564f787eSrsc 
852aae7205Srsc   asm volatile("lidt (%0)" : : "r" (pd));
8655e95b16Srtm }
8755e95b16Srtm 
8868ae4cc1Srsc static inline void
ltr(ushort sel)8929270816Srtm ltr(ushort sel)
9055e95b16Srtm {
9168ae4cc1Srsc   asm volatile("ltr %0" : : "r" (sel));
9255e95b16Srtm }
9355e95b16Srtm 
9468ae4cc1Srsc static inline uint
readeflags(void)9521575761Srsc readeflags(void)
9655e95b16Srtm {
9729270816Srtm   uint eflags;
9868ae4cc1Srsc   asm volatile("pushfl; popl %0" : "=r" (eflags));
9955e95b16Srtm   return eflags;
10055e95b16Srtm }
10155e95b16Srtm 
10268ae4cc1Srsc static inline void
loadgs(ushort v)103d26025d1SRuss Cox loadgs(ushort v)
10419333efbSrsc {
1057b644318Srsc   asm volatile("movw %0, %%gs" : : "r" (v));
10619333efbSrsc }
10719333efbSrsc 
1089aa0337dSFrans Kaashoek static inline void
cli(void)10965bd8e13Srsc cli(void)
11065bd8e13Srsc {
11168ae4cc1Srsc   asm volatile("cli");
11265bd8e13Srsc }
11365bd8e13Srsc 
11468ae4cc1Srsc static inline void
sti(void)11565bd8e13Srsc sti(void)
11665bd8e13Srsc {
11768ae4cc1Srsc   asm volatile("sti");
11865bd8e13Srsc }
11965bd8e13Srsc 
12037ee75f4SAustin Clements static inline uint
xchg(volatile uint * addr,uint newval)12137ee75f4SAustin Clements xchg(volatile uint *addr, uint newval)
12237ee75f4SAustin Clements {
12337ee75f4SAustin Clements   uint result;
12437ee75f4SAustin Clements 
12537ee75f4SAustin Clements   // The + in "+m" denotes a read-modify-write operand.
12637ee75f4SAustin Clements   asm volatile("lock; xchgl %0, %1" :
12737ee75f4SAustin Clements                "+m" (*addr), "=a" (result) :
12837ee75f4SAustin Clements                "1" (newval) :
12937ee75f4SAustin Clements                "cc");
13037ee75f4SAustin Clements   return result;
13137ee75f4SAustin Clements }
13237ee75f4SAustin Clements 
13392639b6bSAustin Clements static inline uint
rcr2(void)13492639b6bSAustin Clements rcr2(void)
13540889627SFrans Kaashoek {
13640889627SFrans Kaashoek   uint val;
13740889627SFrans Kaashoek   asm volatile("movl %%cr2,%0" : "=r" (val));
13840889627SFrans Kaashoek   return val;
13940889627SFrans Kaashoek }
14040889627SFrans Kaashoek 
14192639b6bSAustin Clements static inline void
lcr3(uint val)14292639b6bSAustin Clements lcr3(uint val)
14340889627SFrans Kaashoek {
14440889627SFrans Kaashoek   asm volatile("movl %0,%%cr3" : : "r" (val));
14540889627SFrans Kaashoek }
14640889627SFrans Kaashoek 
1470aef8914SRuss Cox //PAGEBREAK: 36
148ab4cedb5Srtm // Layout of the trap frame built on the stack by the
149ab4cedb5Srtm // hardware and by trapasm.S, and passed to trap().
150b5f17007Srsc struct trapframe {
151f5527388Srsc   // registers as pushed by pusha
15229270816Srtm   uint edi;
15329270816Srtm   uint esi;
15429270816Srtm   uint ebp;
155f5527388Srsc   uint oesp;      // useless & ignored
15629270816Srtm   uint ebx;
15729270816Srtm   uint edx;
15829270816Srtm   uint ecx;
15929270816Srtm   uint eax;
160f5527388Srsc 
161f5527388Srsc   // rest of trap frame
162c7317d4dSkolya   ushort gs;
16329270816Srtm   ushort padding1;
164c7317d4dSkolya   ushort fs;
16529270816Srtm   ushort padding2;
166c7317d4dSkolya   ushort es;
167c7317d4dSkolya   ushort padding3;
168c7317d4dSkolya   ushort ds;
169c7317d4dSkolya   ushort padding4;
17029270816Srtm   uint trapno;
171f5527388Srsc 
172f5527388Srsc   // below here defined by x86 hardware
17329270816Srtm   uint err;
17429270816Srtm   uint eip;
17529270816Srtm   ushort cs;
176c7317d4dSkolya   ushort padding5;
17729270816Srtm   uint eflags;
178f5527388Srsc 
179f5527388Srsc   // below here only when crossing rings, such as from user to kernel
18029270816Srtm   uint esp;
18129270816Srtm   ushort ss;
182c7317d4dSkolya   ushort padding6;
18355e95b16Srtm };
184