xref: /xv6-public/x86.h (revision 7894fcd2)
1 // Routines to let C code use special x86 instructions.
2 
3 static inline uchar
inb(ushort port)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
insl(int port,void * addr,int cnt)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
outb(ushort port,uchar data)22 outb(ushort port, uchar data)
23 {
24   asm volatile("out %0,%1" : : "a" (data), "d" (port));
25 }
26 
27 static inline void
outw(ushort port,ushort data)28 outw(ushort port, ushort data)
29 {
30   asm volatile("out %0,%1" : : "a" (data), "d" (port));
31 }
32 
33 static inline void
outsl(int port,const void * addr,int cnt)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
stosb(void * addr,int data,int cnt)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
stosl(void * addr,int data,int cnt)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
lgdt(struct segdesc * p,int size)63 lgdt(struct segdesc *p, int size)
64 {
65   volatile ushort pd[3];
66 
67   pd[0] = size-1;
68   pd[1] = (uint)p;
69   pd[2] = (uint)p >> 16;
70 
71   asm volatile("lgdt (%0)" : : "r" (pd));
72 }
73 
74 struct gatedesc;
75 
76 static inline void
lidt(struct gatedesc * p,int size)77 lidt(struct gatedesc *p, int size)
78 {
79   volatile ushort pd[3];
80 
81   pd[0] = size-1;
82   pd[1] = (uint)p;
83   pd[2] = (uint)p >> 16;
84 
85   asm volatile("lidt (%0)" : : "r" (pd));
86 }
87 
88 static inline void
ltr(ushort sel)89 ltr(ushort sel)
90 {
91   asm volatile("ltr %0" : : "r" (sel));
92 }
93 
94 static inline uint
readeflags(void)95 readeflags(void)
96 {
97   uint eflags;
98   asm volatile("pushfl; popl %0" : "=r" (eflags));
99   return eflags;
100 }
101 
102 static inline void
loadgs(ushort v)103 loadgs(ushort v)
104 {
105   asm volatile("movw %0, %%gs" : : "r" (v));
106 }
107 
108 static inline void
cli(void)109 cli(void)
110 {
111   asm volatile("cli");
112 }
113 
114 static inline void
sti(void)115 sti(void)
116 {
117   asm volatile("sti");
118 }
119 
120 static inline uint
xchg(volatile uint * addr,uint newval)121 xchg(volatile uint *addr, uint newval)
122 {
123   uint result;
124 
125   // The + in "+m" denotes a read-modify-write operand.
126   asm volatile("lock; xchgl %0, %1" :
127                "+m" (*addr), "=a" (result) :
128                "1" (newval) :
129                "cc");
130   return result;
131 }
132 
133 static inline uint
rcr2(void)134 rcr2(void)
135 {
136   uint val;
137   asm volatile("movl %%cr2,%0" : "=r" (val));
138   return val;
139 }
140 
141 static inline void
lcr3(uint val)142 lcr3(uint val)
143 {
144   asm volatile("movl %0,%%cr3" : : "r" (val));
145 }
146 
147 //PAGEBREAK: 36
148 // Layout of the trap frame built on the stack by the
149 // hardware and by trapasm.S, and passed to trap().
150 struct trapframe {
151   // registers as pushed by pusha
152   uint edi;
153   uint esi;
154   uint ebp;
155   uint oesp;      // useless & ignored
156   uint ebx;
157   uint edx;
158   uint ecx;
159   uint eax;
160 
161   // rest of trap frame
162   ushort gs;
163   ushort padding1;
164   ushort fs;
165   ushort padding2;
166   ushort es;
167   ushort padding3;
168   ushort ds;
169   ushort padding4;
170   uint trapno;
171 
172   // below here defined by x86 hardware
173   uint err;
174   uint eip;
175   ushort cs;
176   ushort padding5;
177   uint eflags;
178 
179   // below here only when crossing rings, such as from user to kernel
180   uint esp;
181   ushort ss;
182   ushort padding6;
183 };
184