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 */
66struct 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
90enum {
91	GATE_INTERRUPT = 0xE,
92	GATE_TRAP = 0xF,
93	GATE_CALL = 0xC,
94	GATE_TASK = 0x5,
95};
96
97enum {
98	DESC_TSS = 0x9,
99	DESC_LDT = 0x2,
100	DESCTYPE_S = 0x10,	/* !system */
101};
102
103/* LDT or TSS descriptor in the GDT. */
104struct 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
116typedef struct ldttss_desc ldt_desc;
117typedef struct ldttss_desc tss_desc;
118
119struct idt_bits {
120	u16		ist	: 3,
121			zero	: 5,
122			type	: 5,
123			dpl	: 2,
124			p	: 1;
125} __attribute__((packed));
126
127struct idt_data {
128	unsigned int	vector;
129	unsigned int	segment;
130	struct idt_bits	bits;
131	const void	*addr;
132};
133
134struct 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
145typedef struct gate_struct gate_desc;
146
147#ifndef _SETUP
148static 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
158static inline unsigned long gate_segment(const gate_desc *g)
159{
160	return g->segment;
161}
162#endif
163
164struct 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