blob: 4cf65d9fb2b81431bd3b3e9b59e12bcf4ea30de6 [file] [log] [blame]
Corey Tabaka84697242009-03-26 02:32:01 -04001/*
2 * Copyright (c) 2009 Corey Tabaka
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#ifndef __ARCH_X86_H
24#define __ARCH_X86_H
25
26#include <compiler.h>
27#include <sys/types.h>
28
29#if defined(__cplusplus)
30extern "C" {
31#endif
32
33void x86_mmu_init(void);
34
35struct x86_iframe {
36 uint32_t pivot; // stack switch pivot
37 uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by common handler using pusha
38 uint32_t ds, es, fs, gs; // pushed by common handler
39 uint32_t vector; // pushed by stub
40 uint32_t err_code; // pushed by interrupt or stub
41 uint32_t eip, cs, eflags; // pushed by interrupt
42 uint32_t user_esp, user_ss; // pushed by interrupt if priv change occurs
43};
44
45/*
46 * x86 TSS structure
47 */
48typedef struct {
49 uint16_t backlink, __blh;
50 uint32_t esp0;
51 uint16_t ss0, __ss0h;
52 uint32_t esp1;
53 uint16_t ss1, __ss1h;
54 uint32_t esp2;
55 uint16_t ss2, __ss2h;
56 uint32_t cr3;
57 uint32_t eip;
58 uint32_t eflags;
59 uint32_t eax, ecx, edx, ebx;
60 uint32_t esp, ebp, esi, edi;
61 uint16_t es, __esh;
62 uint16_t cs, __csh;
63 uint16_t ss, __ssh;
64 uint16_t ds, __dsh;
65 uint16_t fs, __fsh;
66 uint16_t gs, __gsh;
67 uint16_t ldt, __ldth;
68 uint16_t trace, bitmap;
69
70 uint8_t tss_bitmap[8192];
71} __PACKED tss_t;
72
73#define X86_CR0_PE 0x00000001 /* protected mode enable */
74#define X86_CR0_MP 0x00000002 /* monitor coprocessor */
75#define X86_CR0_EM 0x00000004 /* emulation */
76#define X86_CR0_TS 0x00000008 /* task switched */
77#define X86_CR0_WP 0x00010000 /* supervisor write protect */
78#define X86_CR0_NW 0x20000000 /* not write-through */
79#define X86_CR0_CD 0x40000000 /* cache disable */
80#define X86_CR0_PG 0x80000000 /* enable paging */
81
82static inline void set_in_cr0(uint32_t mask) {
83 __asm__ __volatile__ (
84 "movl %%cr0,%%eax \n\t"
85 "orl %0,%%eax \n\t"
86 "movl %%eax,%%cr0 \n\t"
87 : : "irg" (mask)
88 :"ax");
89}
90
91static inline void clear_in_cr0(uint32_t mask) {
92 __asm__ __volatile__ (
93 "movl %%cr0, %%eax \n\t"
94 "andl %0, %%eax \n\t"
95 "movl %%eax, %%cr0 \n\t"
96 : : "irg" (~mask)
97 : "ax");
98}
99
100static inline void x86_clts(void) {__asm__ __volatile__ ("clts"); }
101static inline void x86_hlt(void) {__asm__ __volatile__ ("hlt"); }
102static inline void x86_sti(void) {__asm__ __volatile__ ("sti"); }
103static inline void x86_cli(void) {__asm__ __volatile__ ("cli"); }
104static inline void x86_ltr(uint16_t sel) {
105 __asm__ __volatile__ ("ltr %%ax" :: "a" (sel));
106}
107
108static inline uint32_t x86_get_cr2(void) {
109 uint32_t rv;
110
111 __asm__ __volatile__ (
112 "movl %%cr2, %0"
113 : "=r" (rv)
114 );
115
116 return rv;
117}
118
119#define rdtsc(low,high) \
120 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
121
122#define rdtscl(low) \
123 __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
124
125#define rdtscll(val) \
126 __asm__ __volatile__("rdtsc" : "=A" (val))
127
128static inline uint8_t inp(uint16_t _port) {
129 uint8_t rv;
130 __asm__ __volatile__ ("inb %1, %0"
131 : "=a" (rv)
132 : "d" (_port));
133 return(rv);
134}
135
136static inline uint16_t inpw (uint16_t _port) {
137 uint16_t rv;
138 __asm__ __volatile__ ("inw %1, %0"
139 : "=a" (rv)
140 : "d" (_port));
141 return(rv);
142}
143
144static inline uint32_t inpd(uint16_t _port) {
145 uint32_t rv;
146 __asm__ __volatile__ ("inl %1, %0"
147 : "=a" (rv)
148 : "d" (_port));
149 return(rv);
150}
151
152static inline void outp(uint16_t _port, uint8_t _data) {
153 __asm__ __volatile__ ("outb %1, %0"
154 :
155 : "d" (_port),
156 "a" (_data));
157}
158
159static inline void outpw(uint16_t _port, uint16_t _data) {
160 __asm__ __volatile__ ("outw %1, %0"
161 :
162 : "d" (_port),
163 "a" (_data));
164}
165
166static inline void outpd(uint16_t _port, uint32_t _data) {
167 __asm__ __volatile__ ("outl %1, %0"
168 :
169 : "d" (_port),
170 "a" (_data));
171}
172
173static inline void inprep(uint16_t _port, uint8_t *_buffer, uint32_t _reads) {
174 __asm__ __volatile__ ("pushal \n\t"
175 "pushfl \n\t"
176 "cli \n\t"
177 "cld \n\t"
178 "rep insb \n\t"
179 "popfl \n\t"
180 "popal"
181 :
182 : "d" (_port),
183 "D" (_buffer),
184 "c" (_reads));
185}
186
187static inline void outprep(uint16_t _port, uint8_t *_buffer, uint32_t _writes) {
188 __asm__ __volatile__ ("pushal \n\t"
189 "pushfl \n\t"
190 "cli \n\t"
191 "cld \n\t"
192 "rep outsb \n\t"
193 "popfl \n\t"
194 "popal"
195 :
196 : "d" (_port),
197 "S" (_buffer),
198 "c" (_writes));
199}
200
201static inline void inpwrep(uint16_t _port, uint16_t *_buffer, uint32_t _reads) {
202 __asm__ __volatile__ ("pushal \n\t"
203 "pushfl \n\t"
204 "cli \n\t"
205 "cld \n\t"
206 "rep insw \n\t"
207 "popfl \n\t"
208 "popal"
209 :
210 : "d" (_port),
211 "D" (_buffer),
212 "c" (_reads));
213}
214
215static inline void outpwrep(uint16_t _port, uint16_t *_buffer,
216 uint32_t _writes) {
217 __asm__ __volatile__ ("pushal \n\t"
218 "pushfl \n\t"
219 "cli \n\t"
220 "cld \n\t"
221 "rep outsw \n\t"
222 "popfl \n\t"
223 "popal"
224 :
225 : "d" (_port),
226 "S" (_buffer),
227 "c" (_writes));
228}
229
230static inline void inpdrep(uint16_t _port, uint32_t *_buffer,
231 uint32_t _reads) {
232 __asm__ __volatile__ ("pushal \n\t"
233 "pushfl \n\t"
234 "cli \n\t"
235 "cld \n\t"
236 "rep insl \n\t"
237 "popfl \n\t"
238 "popal"
239 :
240 : "d" (_port),
241 "D" (_buffer),
242 "c" (_reads));
243}
244
245static inline void outpdrep(uint16_t _port, uint32_t *_buffer,
246 uint32_t _writes) {
247 __asm__ __volatile__ ("pushal \n\t"
248 "pushfl \n\t"
249 "cli \n\t"
250 "cld \n\t"
251 "rep outsl \n\t"
252 "popfl \n\t"
253 "popal"
254 :
255 : "d" (_port),
256 "S" (_buffer),
257 "c" (_writes));
258}
259
260#if defined(__cplusplus)
261}
262#endif
263
264#endif