1// Routines to let C code use special x86 instructions.
2
3static inline uchar
4inb(ushort port)
5{
6 uchar data;
7
8 asm volatile("in %1,%0" : "=a" (data) : "d" (port));
9 return data;
10}
11
12static inline void
13insl(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
21static inline void
22outb(ushort port, uchar data)
23{
24 asm volatile("out %0,%1" : : "a" (data), "d" (port));
25}
26
27static inline void
28outw(ushort port, ushort data)
29{
30 asm volatile("out %0,%1" : : "a" (data), "d" (port));
31}
32
33static inline void
34outsl(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
42static inline void
43stosb(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
51static inline void
52stosl(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
60struct segdesc;
61
62static inline void
63lgdt(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
74struct gatedesc;
75
76static inline void
77lidt(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
88static inline void
89ltr(ushort sel)
90{
91 asm volatile("ltr %0" : : "r" (sel));
92}
93
94static inline uint
95readeflags(void)
96{
97 uint eflags;
98 asm volatile("pushfl; popl %0" : "=r" (eflags));
99 return eflags;
100}
101
102static inline void
103loadgs(ushort v)
104{
105 asm volatile("movw %0, %%gs" : : "r" (v));
106}
107
108static inline void
109cli(void)
110{
111 asm volatile("cli");
112}
113
114static inline void
115sti(void)
116{
117 asm volatile("sti");
118}
119
120static inline uint
121xchg(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
133static inline uint
134rcr2(void)
135{
136 uint val;
137 asm volatile("movl %%cr2,%0" : "=r" (val));
138 return val;
139}
140
141static inline void
142lcr3(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().
150struct 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