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