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
|
/*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* Processor registers for i386 and i486.
*/
#ifndef _I386_PROC_REG_H_
#define _I386_PROC_REG_H_
/*
* CR0
*/
#define CR0_PG 0x80000000 /* enable paging */
#define CR0_CD 0x40000000 /* i486: cache disable */
#define CR0_NW 0x20000000 /* i486: no write-through */
#define CR0_AM 0x00040000 /* i486: alignment check mask */
#define CR0_WP 0x00010000 /* i486: write-protect kernel access */
#define CR0_NE 0x00000020 /* i486: handle numeric exceptions */
#define CR0_ET 0x00000010 /* extension type is 80387 */
/* (not official) */
#define CR0_TS 0x00000008 /* task switch */
#define CR0_EM 0x00000004 /* emulate coprocessor */
#define CR0_MP 0x00000002 /* monitor coprocessor */
#define CR0_PE 0x00000001 /* enable protected mode */
#ifndef __ASSEMBLER__
#ifdef __GNUC__
static inline unsigned
get_eflags()
{
unsigned eflags;
asm volatile("pushfd; popl %0" : "=r" (eflags));
return eflags;
}
static inline void
set_eflags(unsigned eflags)
{
asm volatile("pushl %0; popfd" : : "r" (eflags));
}
#define get_esp() \
({ \
register unsigned int _temp__; \
asm("mov %%esp, %0" : "=r" (_temp__)); \
_temp__; \
})
#define get_eflags() \
({ \
register unsigned int _temp__; \
asm("pushf; popl %0" : "=r" (_temp__)); \
_temp__; \
})
#define get_cr0() \
({ \
register unsigned int _temp__; \
asm("mov %%cr0, %0" : "=r" (_temp__)); \
_temp__; \
})
#define set_cr0(value) \
({ \
register unsigned int _temp__ = (value); \
asm volatile("mov %0, %%cr0" : : "r" (_temp__)); \
})
#define get_cr2() \
({ \
register unsigned int _temp__; \
asm("mov %%cr2, %0" : "=r" (_temp__)); \
_temp__; \
})
#define get_cr3() \
({ \
register unsigned int _temp__; \
asm("mov %%cr3, %0" : "=r" (_temp__)); \
_temp__; \
})
#define set_cr3(value) \
({ \
register unsigned int _temp__ = (value); \
asm volatile("mov %0, %%cr3" : : "r" (_temp__)); \
})
#define flush_tlb() set_cr3(get_cr3())
#define set_ts() \
set_cr0(get_cr0() | CR0_TS)
#define clear_ts() \
asm volatile("clts")
#define get_tr() \
({ \
unsigned short _seg__; \
asm volatile("str %0" : "=rm" (_seg__) ); \
_seg__; \
})
#define set_tr(seg) \
asm volatile("ltr %0" : : "rm" ((unsigned short)(seg)) )
#define get_ldt() \
({ \
unsigned short _seg__; \
asm volatile("sldt %0" : "=rm" (_seg__) ); \
_seg__; \
})
#define set_ldt(seg) \
asm volatile("lldt %0" : : "rm" ((unsigned short)(seg)) )
/* This doesn't set a processor register,
but it's often used immediately after setting one,
to flush the instruction queue. */
#define flush_instr_queue() \
asm("jmp 0f\n" \
"0:\n")
#endif /* __GNUC__ */
#endif /* __ASSEMBLER__ */
#endif /* _I386_PROC_REG_H_ */
|