xref: /openbsd-src/sys/arch/amd64/include/segments.h (revision 073d4874bad48a3c63c4dc7856fc2e2a893a7964)
1*073d4874Sguenther /*	$OpenBSD: segments.h,v 1.17 2024/02/25 22:33:09 guenther Exp $	*/
2f5df1827Smickey /*	$NetBSD: segments.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $	*/
3f5df1827Smickey 
4f5df1827Smickey /*-
5f5df1827Smickey  * Copyright (c) 1995, 1997
6f5df1827Smickey  *	Charles M. Hannum.  All rights reserved.
7f5df1827Smickey  * Copyright (c) 1989, 1990 William F. Jolitz
8f5df1827Smickey  * Copyright (c) 1990 The Regents of the University of California.
9f5df1827Smickey  * All rights reserved.
10f5df1827Smickey  *
11f5df1827Smickey  * This code is derived from software contributed to Berkeley by
12f5df1827Smickey  * William Jolitz.
13f5df1827Smickey  *
14f5df1827Smickey  * Redistribution and use in source and binary forms, with or without
15f5df1827Smickey  * modification, are permitted provided that the following conditions
16f5df1827Smickey  * are met:
17f5df1827Smickey  * 1. Redistributions of source code must retain the above copyright
18f5df1827Smickey  *    notice, this list of conditions and the following disclaimer.
19f5df1827Smickey  * 2. Redistributions in binary form must reproduce the above copyright
20f5df1827Smickey  *    notice, this list of conditions and the following disclaimer in the
21f5df1827Smickey  *    documentation and/or other materials provided with the distribution.
22c5217b0aSjsg  * 3. Neither the name of the University nor the names of its contributors
23f5df1827Smickey  *    may be used to endorse or promote products derived from this software
24f5df1827Smickey  *    without specific prior written permission.
25f5df1827Smickey  *
26f5df1827Smickey  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27f5df1827Smickey  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28f5df1827Smickey  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29f5df1827Smickey  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30f5df1827Smickey  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31f5df1827Smickey  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32f5df1827Smickey  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33f5df1827Smickey  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34f5df1827Smickey  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35f5df1827Smickey  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36f5df1827Smickey  * SUCH DAMAGE.
37f5df1827Smickey  *
38f5df1827Smickey  *	@(#)segments.h	7.1 (Berkeley) 5/9/91
39f5df1827Smickey  */
40f5df1827Smickey 
41f5df1827Smickey /*
42f5df1827Smickey  * Adapted for NetBSD/amd64 by fvdl@wasabisystems.com.
43f5df1827Smickey  */
44f5df1827Smickey 
45f5df1827Smickey /*
46f5df1827Smickey  * 386 Segmentation Data Structures and definitions
47f5df1827Smickey  *	William F. Jolitz (william@ernie.berkeley.edu) 6/20/1989
48f5df1827Smickey  */
49f5df1827Smickey 
502fa72412Spirofti #ifndef _MACHINE_SEGMENTS_H_
512fa72412Spirofti #define _MACHINE_SEGMENTS_H_
52f5df1827Smickey 
53f5df1827Smickey /*
54f5df1827Smickey  * Selectors
55f5df1827Smickey  */
56f5df1827Smickey 
57f5df1827Smickey #define	ISPL(s)		((s) & SEL_RPL)	/* what is the priority level of a selector */
58f5df1827Smickey #define	SEL_KPL		0		/* kernel privilege level */
59f5df1827Smickey #define	SEL_UPL		3		/* user privilege level */
60f5df1827Smickey #define	SEL_RPL		3		/* requester's privilege level mask */
61f5df1827Smickey #define	ISLDT(s)	((s) & SEL_LDT)	/* is it local or global */
62f5df1827Smickey #define	SEL_LDT		4		/* local descriptor table */
63f5df1827Smickey 
64f5df1827Smickey #define SYSSEL_START	(NGDT_MEM << 3)
65fd94711fSguenther #define GDT_SIZE	(SYSSEL_START + (NGDT_SYS << 4))
66f5df1827Smickey 
67f5df1827Smickey /*
68f5df1827Smickey  * These define the index not from the start of the GDT, but from
69f5df1827Smickey  * the part of the GDT that they're allocated from.
70f5df1827Smickey  * First NGDT_MEM entries are 8-byte descriptors for CS and DS.
71fd94711fSguenther  * Next NGDT_SYS entries are 16-byte descriptors defining TSSs.
72f5df1827Smickey  */
73f5df1827Smickey 
74f5df1827Smickey #define	IDXSEL(s)	(((s) >> 3) & 0x1fff)
75f5df1827Smickey #define IDXDYNSEL(s)	((((s) & ~SEL_RPL) - DYNSEL_START) >> 4)
76f5df1827Smickey 
77f5df1827Smickey #define	GSEL(s,r)	(((s) << 3) | r)
78f5df1827Smickey #define	GSYSSEL(s,r)	((((s) << 4) + SYSSEL_START) | r)
79f5df1827Smickey #define GDYNSEL(s,r)	((((s) << 4) + DYNSEL_START) | r | SEL_KPL)
80f5df1827Smickey 
81f5df1827Smickey #define LSEL(s,r)	((s) | r | SEL_LDT)
82f5df1827Smickey 
83f5df1827Smickey #define	USERMODE(c, f)		(ISPL(c) == SEL_UPL)
84f5df1827Smickey #define	KERNELMODE(c, f)	(ISPL(c) == SEL_KPL)
85f5df1827Smickey 
86f5df1827Smickey #ifndef _LOCORE
87f5df1827Smickey 
88f5df1827Smickey /*
89f5df1827Smickey  * Memory and System segment descriptors
90f5df1827Smickey  */
91f5df1827Smickey 
92f5df1827Smickey /*
93f5df1827Smickey  * Below is used for TSS and LDT.
94f5df1827Smickey  */
95f5df1827Smickey struct sys_segment_descriptor {
96ffa5c1d9Sguenther 	u_int64_t sd_lolimit:16;	/* segment extent (lsb) */
97ffa5c1d9Sguenther 	u_int64_t sd_lobase:24;		/* segment base address (lsb) */
98ffa5c1d9Sguenther 	u_int64_t sd_type:5;		/* segment type */
99ffa5c1d9Sguenther 	u_int64_t sd_dpl:2;		/* segment descriptor priority level */
100ffa5c1d9Sguenther 	u_int64_t sd_p:1;		/* segment descriptor present */
101ffa5c1d9Sguenther 	u_int64_t sd_hilimit:4;		/* segment extent (msb) */
102ffa5c1d9Sguenther 	u_int64_t sd_xx1:3;		/* avl, long and def32 (not used) */
103ffa5c1d9Sguenther 	u_int64_t sd_gran:1;		/* limit granularity (byte/page) */
104ffa5c1d9Sguenther 	u_int64_t sd_hibase:40;		/* segment base address (msb) */
105ffa5c1d9Sguenther 	u_int64_t sd_xx2:8;		/* reserved */
106ffa5c1d9Sguenther 	u_int64_t sd_zero:5;		/* must be zero */
107ffa5c1d9Sguenther 	u_int64_t sd_xx3:19;		/* reserved */
1087fdc08e5Smiod } __packed;
109f5df1827Smickey 
110f5df1827Smickey /*
111f5df1827Smickey  * Below is used for cs, ds, etc.
112f5df1827Smickey  */
113f5df1827Smickey struct mem_segment_descriptor {
11488d48798Sderaadt 	unsigned int sd_lolimit:16;         /* segment extent (lsb) */
11588d48798Sderaadt 	unsigned int sd_lobase:24;          /* segment base address (lsb) */
11688d48798Sderaadt 	unsigned int sd_type:5;             /* segment type */
11788d48798Sderaadt 	unsigned int sd_dpl:2;              /* segment descriptor priority level */
11888d48798Sderaadt 	unsigned int sd_p:1;                /* segment descriptor present */
11988d48798Sderaadt 	unsigned int sd_hilimit:4;          /* segment extent (msb) */
12088d48798Sderaadt 	unsigned int sd_avl:1;		/* available */
12188d48798Sderaadt 	unsigned int sd_long:1;		/* long mode */
12288d48798Sderaadt 	unsigned int sd_def32:1;            /* default 32 vs 16 bit size */
12388d48798Sderaadt 	unsigned int sd_gran:1;             /* limit granularity (byte/page) */
12488d48798Sderaadt 	unsigned int sd_hibase:8;           /* segment base address (msb) */
1257fdc08e5Smiod } __packed;
126f5df1827Smickey 
127f5df1827Smickey /*
128f5df1827Smickey  * Gate descriptors (e.g. indirect descriptors)
129f5df1827Smickey  */
130f5df1827Smickey struct gate_descriptor {
13178cf07b7Sguenther 	u_int64_t gd_looffset:16;	/* gate offset (lsb) */
13278cf07b7Sguenther 	u_int64_t gd_selector:16;	/* gate segment selector */
13378cf07b7Sguenther 	u_int64_t gd_ist:3;		/* IST select */
13478cf07b7Sguenther 	u_int64_t gd_xx1:5;		/* reserved */
13578cf07b7Sguenther 	u_int64_t gd_type:5;		/* segment type */
13678cf07b7Sguenther 	u_int64_t gd_dpl:2;		/* segment descriptor priority level */
13778cf07b7Sguenther 	u_int64_t gd_p:1;		/* segment descriptor present */
13878cf07b7Sguenther 	u_int64_t gd_hioffset:48;	/* gate offset (msb) */
13978cf07b7Sguenther 	u_int64_t gd_xx2:8;		/* reserved */
14078cf07b7Sguenther 	u_int64_t gd_zero:5;		/* must be zero */
14178cf07b7Sguenther 	u_int64_t gd_xx3:19;		/* reserved */
1427fdc08e5Smiod } __packed;
143f5df1827Smickey 
144f5df1827Smickey /*
145f5df1827Smickey  * region descriptors, used to load gdt/idt tables before segments yet exist.
146f5df1827Smickey  */
147f5df1827Smickey struct region_descriptor {
148f5df1827Smickey 	u_int16_t rd_limit;		/* segment extent */
149f5df1827Smickey 	u_int64_t rd_base;		/* base address  */
1507fdc08e5Smiod } __packed;
151f5df1827Smickey 
152f5df1827Smickey #ifdef _KERNEL
153f5df1827Smickey extern struct gate_descriptor *idt;
154f5df1827Smickey 
155f5df1827Smickey void setgate(struct gate_descriptor *, void *, int, int, int, int);
156f5df1827Smickey void unsetgate(struct gate_descriptor *);
157f5df1827Smickey void setregion(struct region_descriptor *, void *, u_int16_t);
158f5df1827Smickey void set_sys_segment(struct sys_segment_descriptor *, void *, size_t,
159f5df1827Smickey 			  int, int, int);
160f5df1827Smickey void set_mem_segment(struct mem_segment_descriptor *, void *, size_t,
161f5df1827Smickey 			  int, int, int, int, int);
162f5df1827Smickey int idt_vec_alloc(int, int);
163fb432fadSkettenis int idt_vec_alloc_range(int, int, int);
164f5df1827Smickey void idt_vec_set(int, void (*)(void));
165f5df1827Smickey void idt_vec_free(int);
166f5df1827Smickey void cpu_init_idt(void);
167f5df1827Smickey 
168f5df1827Smickey #endif /* _KERNEL */
169f5df1827Smickey 
170f5df1827Smickey #endif /* !_LOCORE */
171f5df1827Smickey 
172f5df1827Smickey /* system segments and gate types */
173f5df1827Smickey #define	SDT_SYSNULL	 0	/* system null */
174f5df1827Smickey #define	SDT_SYS286TSS	 1	/* system 286 TSS available */
175f5df1827Smickey #define	SDT_SYSLDT	 2	/* system local descriptor table */
176f5df1827Smickey #define	SDT_SYS286BSY	 3	/* system 286 TSS busy */
177f5df1827Smickey #define	SDT_SYS286CGT	 4	/* system 286 call gate */
178f5df1827Smickey #define	SDT_SYSTASKGT	 5	/* system task gate */
179f5df1827Smickey #define	SDT_SYS286IGT	 6	/* system 286 interrupt gate */
180f5df1827Smickey #define	SDT_SYS286TGT	 7	/* system 286 trap gate */
181f5df1827Smickey #define	SDT_SYSNULL2	 8	/* system null again */
182f5df1827Smickey #define	SDT_SYS386TSS	 9	/* system 386 TSS available */
183f5df1827Smickey #define	SDT_SYSNULL3	10	/* system null again */
184f5df1827Smickey #define	SDT_SYS386BSY	11	/* system 386 TSS busy */
185f5df1827Smickey #define	SDT_SYS386CGT	12	/* system 386 call gate */
186f5df1827Smickey #define	SDT_SYSNULL4	13	/* system null again */
187f5df1827Smickey #define	SDT_SYS386IGT	14	/* system 386 interrupt gate */
188f5df1827Smickey #define	SDT_SYS386TGT	15	/* system 386 trap gate */
189f5df1827Smickey 
190f5df1827Smickey /* memory segment types */
191f5df1827Smickey #define	SDT_MEMRO	16	/* memory read only */
192f5df1827Smickey #define	SDT_MEMROA	17	/* memory read only accessed */
193f5df1827Smickey #define	SDT_MEMRW	18	/* memory read write */
194f5df1827Smickey #define	SDT_MEMRWA	19	/* memory read write accessed */
195f5df1827Smickey #define	SDT_MEMROD	20	/* memory read only expand dwn limit */
196f5df1827Smickey #define	SDT_MEMRODA	21	/* memory read only expand dwn limit accessed */
197f5df1827Smickey #define	SDT_MEMRWD	22	/* memory read write expand dwn limit */
198f5df1827Smickey #define	SDT_MEMRWDA	23	/* memory read write expand dwn limit acessed */
199f5df1827Smickey #define	SDT_MEME	24	/* memory execute only */
200f5df1827Smickey #define	SDT_MEMEA	25	/* memory execute only accessed */
201f5df1827Smickey #define	SDT_MEMER	26	/* memory execute read */
202f5df1827Smickey #define	SDT_MEMERA	27	/* memory execute read accessed */
203f5df1827Smickey #define	SDT_MEMEC	28	/* memory execute only conforming */
204f5df1827Smickey #define	SDT_MEMEAC	29	/* memory execute only accessed conforming */
205f5df1827Smickey #define	SDT_MEMERC	30	/* memory execute read conforming */
206f5df1827Smickey #define	SDT_MEMERAC	31	/* memory execute read accessed conforming */
207f5df1827Smickey 
208f5df1827Smickey /* is memory segment descriptor pointer ? */
209f5df1827Smickey #define ISMEMSDP(s)	((s->d_type) >= SDT_MEMRO && \
210f5df1827Smickey 			 (s->d_type) <= SDT_MEMERAC)
211f5df1827Smickey 
212f5df1827Smickey /* is 286 gate descriptor pointer ? */
213f5df1827Smickey #define IS286GDP(s)	((s->d_type) >= SDT_SYS286CGT && \
214f5df1827Smickey 			 (s->d_type) < SDT_SYS286TGT)
215f5df1827Smickey 
216f5df1827Smickey /* is 386 gate descriptor pointer ? */
217f5df1827Smickey #define IS386GDP(s)	((s->d_type) >= SDT_SYS386CGT && \
218f5df1827Smickey 			 (s->d_type) < SDT_SYS386TGT)
219f5df1827Smickey 
220f5df1827Smickey /* is gate descriptor pointer ? */
221f5df1827Smickey #define ISGDP(s)	(IS286GDP(s) || IS386GDP(s))
222f5df1827Smickey 
223f5df1827Smickey /* is segment descriptor pointer ? */
224f5df1827Smickey #define ISSDP(s)	(ISMEMSDP(s) || !ISGDP(s))
225f5df1827Smickey 
226f5df1827Smickey /* is system segment descriptor pointer ? */
227f5df1827Smickey #define ISSYSSDP(s)	(!ISMEMSDP(s) && !ISGDP(s))
228f5df1827Smickey 
229f5df1827Smickey /*
230f5df1827Smickey  * Segment Protection Exception code bits
231f5df1827Smickey  */
232f5df1827Smickey #define	SEGEX_EXT	0x01	/* recursive or externally induced */
233f5df1827Smickey #define	SEGEX_IDT	0x02	/* interrupt descriptor table */
234f5df1827Smickey #define	SEGEX_TI	0x04	/* local descriptor table */
235f5df1827Smickey 
236f5df1827Smickey /*
237f5df1827Smickey  * Entries in the Interrupt Descriptor Table (IDT)
238f5df1827Smickey  */
239f5df1827Smickey #define	NIDT	256
240f5df1827Smickey #define	NRSVIDT	32		/* reserved entries for cpu exceptions */
241f5df1827Smickey 
242f5df1827Smickey /*
243f5df1827Smickey  * Entries in the Global Descriptor Table (GDT)
244f5df1827Smickey  * The code and data descriptors must come first. There
245f5df1827Smickey  * are NGDT_MEM of them.
246f5df1827Smickey  *
247fd94711fSguenther  * Then comes the predefined TSS descriptor.
248f5df1827Smickey  * There are NGDT_SYS of them.
2491f7e6433Sguenther  *
250*073d4874Sguenther  * The particular order of the UDATA and UCODE descriptors is
251*073d4874Sguenther  * required by the sysretq instruction.
252f5df1827Smickey  */
253f5df1827Smickey #define	GNULL_SEL	0	/* Null descriptor */
254f5df1827Smickey #define	GCODE_SEL	1	/* Kernel code descriptor */
255f5df1827Smickey #define	GDATA_SEL	2	/* Kernel data descriptor */
256*073d4874Sguenther #define	GUDATA_SEL	3	/* User data descriptor */
257*073d4874Sguenther #define	GUCODE_SEL	4	/* User code descriptor */
258*073d4874Sguenther #define NGDT_MEM 5
259f5df1827Smickey 
260fd94711fSguenther #define	GPROC0_SEL	0	/* common TSS */
261fd94711fSguenther #define NGDT_SYS	1
262f5df1827Smickey 
263f5df1827Smickey #define GDT_SYS_OFFSET	(NGDT_MEM << 3)
264f5df1827Smickey 
265f5df1827Smickey #define GDT_ADDR_MEM(s,i)	\
2668a7a62cbSguenther     ((struct mem_segment_descriptor *)((char *)(s) + ((i) << 3)))
267f5df1827Smickey #define GDT_ADDR_SYS(s,i)	\
2688a7a62cbSguenther     ((struct sys_segment_descriptor *)((char *)(s) + ((i) << 4) + SYSSEL_START))
269f5df1827Smickey 
270f5df1827Smickey /*
271ba9e9fd6Sjasper  * Checks for valid user selectors.
27268bd6dfcSmickey  */
27368bd6dfcSmickey #define VALID_USER_CSEL(s) \
27445cb1369Sguenther     ((s) == GSEL(GUCODE_SEL, SEL_UPL))
27568bd6dfcSmickey #define VALID_USER_DSEL(s) \
27645cb1369Sguenther     ((s) == GSEL(GUDATA_SEL, SEL_UPL))
27768bd6dfcSmickey 
2782fa72412Spirofti #endif /* _MACHINE_SEGMENTS_H_ */
279