forked from mit-pdos/xv6-public
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathx86.h
183 lines (155 loc) · 3.16 KB
/
x86.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Routines to let C code use special x86 instructions.
static inline uchar
inb(ushort port)
{
uchar data;
asm volatile("in %1,%0" : "=a" (data) : "d" (port));
return data;
}
static inline void
insl(int port, void *addr, int cnt)
{
asm volatile("cld; rep insl" :
"=D" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"memory", "cc");
}
static inline void
outb(ushort port, uchar data)
{
asm volatile("out %0,%1" : : "a" (data), "d" (port));
}
static inline void
outw(ushort port, ushort data)
{
asm volatile("out %0,%1" : : "a" (data), "d" (port));
}
static inline void
outsl(int port, const void *addr, int cnt)
{
asm volatile("cld; rep outsl" :
"=S" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"cc");
}
static inline void
stosb(void *addr, int data, int cnt)
{
asm volatile("cld; rep stosb" :
"=D" (addr), "=c" (cnt) :
"0" (addr), "1" (cnt), "a" (data) :
"memory", "cc");
}
static inline void
stosl(void *addr, int data, int cnt)
{
asm volatile("cld; rep stosl" :
"=D" (addr), "=c" (cnt) :
"0" (addr), "1" (cnt), "a" (data) :
"memory", "cc");
}
#ifndef __i386__ // suppress warning for bootmain
struct segdesc;
static inline void
lgdt(struct segdesc *p, int size)
{
volatile ushort pd[5];
addr_t addr = (addr_t)p;
pd[0] = size-1;
pd[1] = addr;
pd[2] = addr >> 16;
pd[3] = addr >> 32;
pd[4] = addr >> 48;
asm volatile("lgdt (%0)" : : "r" (pd));
}
struct gatedesc;
static inline void
lidt(struct gatedesc *p, int size)
{
volatile ushort pd[5];
addr_t addr = (addr_t)p;
pd[0] = size-1;
pd[1] = addr;
pd[2] = addr >> 16;
pd[3] = addr >> 32;
pd[4] = addr >> 48;
asm volatile("lidt (%0)" : : "r" (pd));
}
#endif // ndef __i386__
static inline void
ltr(ushort sel)
{
asm volatile("ltr %0" : : "r" (sel));
}
static inline addr_t
readeflags(void)
{
addr_t eflags;
asm volatile("pushf; pop %0" : "=r" (eflags));
return eflags;
}
static inline void
cli(void)
{
asm volatile("cli");
}
static inline void
sti(void)
{
asm volatile("sti");
}
static inline void
hlt(void)
{
asm volatile("hlt");
}
static inline uint
xchg(volatile uint *addr, addr_t newval)
{
uint result;
// The + in "+m" denotes a read-modify-write operand.
asm volatile("lock; xchgl %0, %1" :
"+m" (*addr), "=a" (result) :
"1" (newval) :
"cc");
return result;
}
static inline addr_t
rcr2(void)
{
addr_t val;
asm volatile("mov %%cr2,%0" : "=r" (val));
return val;
}
static inline void
lcr3(addr_t val)
{
asm volatile("mov %0,%%cr3" : : "r" (val));
}
//PAGEBREAK: 36
// Layout of the trap frame built on the stack by the
// hardware and by trapasm.S, and passed to trap().
struct trapframe {
uint64 rax;
uint64 rbx;
uint64 rcx;
uint64 rdx;
uint64 rbp;
uint64 rsi;
uint64 rdi;
uint64 r8;
uint64 r9;
uint64 r10;
uint64 r11;
uint64 r12;
uint64 r13;
uint64 r14;
uint64 r15;
uint64 trapno;
uint64 err;
uint64 rip;
uint64 cs;
uint64 rflags;
uint64 rsp;
uint64 ss;
};