-
Notifications
You must be signed in to change notification settings - Fork 8
/
x86.h
148 lines (119 loc) · 3.37 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
// 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");
}
struct segdesc;
static inline void lgdt(struct segdesc *p, int size) {
volatile ushort pd[3];
pd[0] = size - 1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
asm volatile ("lgdt (%0)" : : "r" (pd));
}
struct gatedesc;
static inline void lidt(struct gatedesc *p, int size) {
volatile ushort pd[3];
pd[0] = size - 1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
asm volatile ("lidt (%0)" : : "r" (pd));
}
static inline void ltr(ushort sel) {
asm volatile ("ltr %0" : : "r" (sel));
}
static inline uint readeflags(void) {
uint eflags;
asm volatile ("pushfl; popl %0" : "=r" (eflags));
return eflags;
}
static inline void loadgs(ushort v) {
asm volatile ("movw %0, %%gs" : : "r" (v));
}
static inline void cli(void) {
asm volatile ("cli");
}
static inline void sti(void) {
asm volatile ("sti");
}
static inline uint xchg(volatile uint *addr, uint 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 uint rcr2(void) {
uint val;
asm volatile ("movl %%cr2,%0" : "=r" (val));
return val;
}
static inline void lcr3(uint val) {
asm volatile ("movl %0,%%cr3" : : "r" (val));
}
// Layout of the trap frame built on the stack by the
// hardware and by trapasm.S, and passed to trap().
struct trapframe {
// registers as pushed by pusha
uint edi;
uint esi;
uint ebp;
uint oesp; // useless & ignored
uint ebx;
uint edx;
uint ecx;
uint eax;
// rest of trap frame
ushort gs;
ushort padding1;
ushort fs;
ushort padding2;
ushort es;
ushort padding3;
ushort ds;
ushort padding4;
uint trapno;
// below here defined by x86 hardware
uint err;
uint eip;
ushort cs;
ushort padding5;
uint eflags;
// below here only when crossing rings, such as from user to kernel
uint esp;
ushort ss;
ushort padding6;
};