1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Written 2000 by Andi Kleen */
3 #ifndef _ASM_X86_DESC_DEFS_H
4 #define _ASM_X86_DESC_DEFS_H
5 
6 /*
7  * Segment descriptor structure definitions, usable from both x86_64 and i386
8  * archs.
9  */
10 
11 /*
12  * Low-level interface mapping flags/field names to bits
13  */
14 
15 /* Flags for _DESC_S (non-system) descriptors */
16 #define _DESC_ACCESSED		0x0001
17 #define _DESC_DATA_WRITABLE	0x0002
18 #define _DESC_CODE_READABLE	0x0002
19 #define _DESC_DATA_EXPAND_DOWN	0x0004
20 #define _DESC_CODE_CONFORMING	0x0004
21 #define _DESC_CODE_EXECUTABLE	0x0008
22 
23 /* Common flags */
24 #define _DESC_S			0x0010
25 #define _DESC_DPL(dpl)		((dpl) << 5)
26 #define _DESC_PRESENT		0x0080
27 
28 #define _DESC_LONG_CODE		0x2000
29 #define _DESC_DB		0x4000
30 #define _DESC_GRANULARITY_4K	0x8000
31 
32 /* System descriptors have a numeric "type" field instead of flags */
33 #define _DESC_SYSTEM(code)	(code)
34 
35 /*
36  * High-level interface mapping intended usage to low-level combinations
37  * of flags
38  */
39 
40 #define _DESC_DATA		(_DESC_S | _DESC_PRESENT | _DESC_ACCESSED | \
41 				 _DESC_DATA_WRITABLE)
42 #define _DESC_CODE		(_DESC_S | _DESC_PRESENT | _DESC_ACCESSED | \
43 				 _DESC_CODE_READABLE | _DESC_CODE_EXECUTABLE)
44 
45 #define DESC_DATA16		(_DESC_DATA)
46 #define DESC_CODE16		(_DESC_CODE)
47 
48 #define DESC_DATA32		(_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB)
49 #define DESC_DATA32_BIOS	(_DESC_DATA | _DESC_DB)
50 
51 #define DESC_CODE32		(_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_DB)
52 #define DESC_CODE32_BIOS	(_DESC_CODE | _DESC_DB)
53 
54 #define DESC_TSS32		(_DESC_SYSTEM(9) | _DESC_PRESENT)
55 
56 #define DESC_DATA64		(_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB)
57 #define DESC_CODE64		(_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_LONG_CODE)
58 
59 #define DESC_USER		(_DESC_DPL(3))
60 
61 #ifndef __ASSEMBLY__
62 
63 #include <linux/types.h>
64 
65 /* 8 byte segment descriptor */
66 struct desc_struct {
67 	u16	limit0;
68 	u16	base0;
69 	u16	base1: 8, type: 4, s: 1, dpl: 2, p: 1;
70 	u16	limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
71 } __attribute__((packed));
72 
73 #define GDT_ENTRY_INIT(flags, base, limit)			\
74 	{							\
75 		.limit0		= ((limit) >>  0) & 0xFFFF,	\
76 		.limit1		= ((limit) >> 16) & 0x000F,	\
77 		.base0		= ((base)  >>  0) & 0xFFFF,	\
78 		.base1		= ((base)  >> 16) & 0x00FF,	\
79 		.base2		= ((base)  >> 24) & 0x00FF,	\
80 		.type		= ((flags) >>  0) & 0x000F,	\
81 		.s		= ((flags) >>  4) & 0x0001,	\
82 		.dpl		= ((flags) >>  5) & 0x0003,	\
83 		.p		= ((flags) >>  7) & 0x0001,	\
84 		.avl		= ((flags) >> 12) & 0x0001,	\
85 		.l		= ((flags) >> 13) & 0x0001,	\
86 		.d		= ((flags) >> 14) & 0x0001,	\
87 		.g		= ((flags) >> 15) & 0x0001,	\
88 	}
89 
90 enum {
91 	GATE_INTERRUPT = 0xE,
92 	GATE_TRAP = 0xF,
93 	GATE_CALL = 0xC,
94 	GATE_TASK = 0x5,
95 };
96 
97 enum {
98 	DESC_TSS = 0x9,
99 	DESC_LDT = 0x2,
100 	DESCTYPE_S = 0x10,	/* !system */
101 };
102 
103 /* LDT or TSS descriptor in the GDT. */
104 struct ldttss_desc {
105 	u16	limit0;
106 	u16	base0;
107 
108 	u16	base1 : 8, type : 5, dpl : 2, p : 1;
109 	u16	limit1 : 4, zero0 : 3, g : 1, base2 : 8;
110 #ifdef CONFIG_X86_64
111 	u32	base3;
112 	u32	zero1;
113 #endif
114 } __attribute__((packed));
115 
116 typedef struct ldttss_desc ldt_desc;
117 typedef struct ldttss_desc tss_desc;
118 
119 struct idt_bits {
120 	u16		ist	: 3,
121 			zero	: 5,
122 			type	: 5,
123 			dpl	: 2,
124 			p	: 1;
125 } __attribute__((packed));
126 
127 struct idt_data {
128 	unsigned int	vector;
129 	unsigned int	segment;
130 	struct idt_bits	bits;
131 	const void	*addr;
132 };
133 
134 struct gate_struct {
135 	u16		offset_low;
136 	u16		segment;
137 	struct idt_bits	bits;
138 	u16		offset_middle;
139 #ifdef CONFIG_X86_64
140 	u32		offset_high;
141 	u32		reserved;
142 #endif
143 } __attribute__((packed));
144 
145 typedef struct gate_struct gate_desc;
146 
147 #ifndef _SETUP
gate_offset(const gate_desc * g)148 static inline unsigned long gate_offset(const gate_desc *g)
149 {
150 #ifdef CONFIG_X86_64
151 	return g->offset_low | ((unsigned long)g->offset_middle << 16) |
152 		((unsigned long) g->offset_high << 32);
153 #else
154 	return g->offset_low | ((unsigned long)g->offset_middle << 16);
155 #endif
156 }
157 
gate_segment(const gate_desc * g)158 static inline unsigned long gate_segment(const gate_desc *g)
159 {
160 	return g->segment;
161 }
162 #endif
163 
164 struct desc_ptr {
165 	unsigned short size;
166 	unsigned long address;
167 } __attribute__((packed)) ;
168 
169 #endif /* !__ASSEMBLY__ */
170 
171 /* Boot IDT definitions */
172 #define	BOOT_IDT_ENTRIES	32
173 
174 /* Access rights as returned by LAR */
175 #define AR_TYPE_RODATA		(0 * (1 << 9))
176 #define AR_TYPE_RWDATA		(1 * (1 << 9))
177 #define AR_TYPE_RODATA_EXPDOWN	(2 * (1 << 9))
178 #define AR_TYPE_RWDATA_EXPDOWN	(3 * (1 << 9))
179 #define AR_TYPE_XOCODE		(4 * (1 << 9))
180 #define AR_TYPE_XRCODE		(5 * (1 << 9))
181 #define AR_TYPE_XOCODE_CONF	(6 * (1 << 9))
182 #define AR_TYPE_XRCODE_CONF	(7 * (1 << 9))
183 #define AR_TYPE_MASK		(7 * (1 << 9))
184 
185 #define AR_DPL0			(0 * (1 << 13))
186 #define AR_DPL3			(3 * (1 << 13))
187 #define AR_DPL_MASK		(3 * (1 << 13))
188 
189 #define AR_A			(1 << 8)   /* "Accessed" */
190 #define AR_S			(1 << 12)  /* If clear, "System" segment */
191 #define AR_P			(1 << 15)  /* "Present" */
192 #define AR_AVL			(1 << 20)  /* "AVaiLable" (no HW effect) */
193 #define AR_L			(1 << 21)  /* "Long mode" for code segments */
194 #define AR_DB			(1 << 22)  /* D/B, effect depends on type */
195 #define AR_G			(1 << 23)  /* "Granularity" (limit in pages) */
196 
197 #endif /* _ASM_X86_DESC_DEFS_H */
198