master
  1/*	$NetBSD: segments.h,v 1.70 2022/05/18 13:56:32 andvar Exp $	*/
  2
  3/*-
  4 * Copyright (c) 1990 The Regents of the University of California.
  5 * All rights reserved.
  6 *
  7 * This code is derived from software contributed to Berkeley by
  8 * William Jolitz.
  9 *
 10 * Redistribution and use in source and binary forms, with or without
 11 * modification, are permitted provided that the following conditions
 12 * are met:
 13 * 1. Redistributions of source code must retain the above copyright
 14 *    notice, this list of conditions and the following disclaimer.
 15 * 2. Redistributions in binary form must reproduce the above copyright
 16 *    notice, this list of conditions and the following disclaimer in the
 17 *    documentation and/or other materials provided with the distribution.
 18 * 3. Neither the name of the University nor the names of its contributors
 19 *    may be used to endorse or promote products derived from this software
 20 *    without specific prior written permission.
 21 *
 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 32 * SUCH DAMAGE.
 33 *
 34 *	@(#)segments.h	7.1 (Berkeley) 5/9/91
 35 */
 36
 37/*-
 38 * Copyright (c) 1995, 1997
 39 *	Charles M. Hannum.  All rights reserved.
 40 * Copyright (c) 1989, 1990 William F. Jolitz
 41 *
 42 * This code is derived from software contributed to Berkeley by
 43 * William Jolitz.
 44 *
 45 * Redistribution and use in source and binary forms, with or without
 46 * modification, are permitted provided that the following conditions
 47 * are met:
 48 * 1. Redistributions of source code must retain the above copyright
 49 *    notice, this list of conditions and the following disclaimer.
 50 * 2. Redistributions in binary form must reproduce the above copyright
 51 *    notice, this list of conditions and the following disclaimer in the
 52 *    documentation and/or other materials provided with the distribution.
 53 * 3. All advertising materials mentioning features or use of this software
 54 *    must display the following acknowledgement:
 55 *	This product includes software developed by the University of
 56 *	California, Berkeley and its contributors.
 57 * 4. Neither the name of the University nor the names of its contributors
 58 *    may be used to endorse or promote products derived from this software
 59 *    without specific prior written permission.
 60 *
 61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 64 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 71 * SUCH DAMAGE.
 72 *
 73 *	@(#)segments.h	7.1 (Berkeley) 5/9/91
 74 */
 75
 76/*
 77 * 386 Segmentation Data Structures and definitions
 78 *	William F. Jolitz (william@ernie.berkeley.edu) 6/20/1989
 79 */
 80
 81#ifndef _I386_SEGMENTS_H_
 82#define _I386_SEGMENTS_H_
 83#ifdef _KERNEL_OPT
 84#include "opt_xen.h"
 85#endif
 86
 87/*
 88 * Selectors
 89 */
 90
 91#define ISPL(s)		((s) & SEL_RPL)	/* what is the priority level of a selector */
 92#ifndef XENPV
 93#define SEL_KPL		0		/* kernel privilege level */
 94#else
 95#define SEL_XEN		0		/* Xen privilege level */
 96#define SEL_KPL		1		/* kernel privilege level */
 97#endif /* XENPV */
 98#define SEL_UPL		3		/* user privilege level */
 99#define SEL_RPL		3		/* requester's privilege level mask */
100#ifdef XENPV
101#define CHK_UPL		2		/* user privilege level mask */
102#else
103#define CHK_UPL		SEL_RPL
104#endif /* XENPV */
105#define ISLDT(s)	((s) & SEL_LDT)	/* is it local or global */
106#define SEL_LDT		4		/* local descriptor table */
107
108#define IOPL_KPL	SEL_KPL
109
110/* Dynamically allocated TSSs and LDTs start (byte offset) */
111#define DYNSEL_START	(NGDT << 3)
112
113#define IDXSEL(s)	(((s) >> 3) & 0x1fff)		/* index of selector */
114#define IDXSELN(s)	(((s) >> 3))			/* index of selector */
115#define IDXDYNSEL(s)	((((s) & ~SEL_RPL) - DYNSEL_START) >> 3)
116
117#define GSEL(s,r)	(((s) << 3) | r)		/* a global selector */
118#define GSYSSEL(s,r)	GSEL(s,r)			/* compat with amd64 */
119#define GDYNSEL(s,r)	((((s) << 3) + DYNSEL_START) | r | SEL_KPL)
120
121#define LSEL(s,r)	(((s) << 3) | r | SEL_LDT)	/* a local selector */
122
123#define USERMODE(c)		(ISPL(c) == SEL_UPL)
124#define KERNELMODE(c)		(ISPL(c) == SEL_KPL)
125
126#ifndef _LOCORE
127
128#if __GNUC__ == 2 && __GNUC_MINOR__ < 7
129#pragma pack(1)
130#endif
131
132/*
133 * Memory and System segment descriptors (both 8 bytes).
134 */
135struct segment_descriptor {
136	unsigned sd_lolimit:16;		/* segment extent (lsb) */
137	unsigned sd_lobase:24;		/* segment base address (lsb) */
138	unsigned sd_type:5;		/* segment type */
139	unsigned sd_dpl:2;		/* segment descriptor priority level */
140	unsigned sd_p:1;		/* segment descriptor present */
141	unsigned sd_hilimit:4;		/* segment extent (msb) */
142	unsigned sd_xx:2;		/* unused */
143	unsigned sd_def32:1;		/* default 32 vs 16 bit size */
144	unsigned sd_gran:1;		/* limit granularity (byte/page) */
145	unsigned sd_hibase:8;		/* segment base address (msb) */
146} __packed;
147
148/*
149 * Gate descriptors (8 bytes).
150 */
151struct gate_descriptor {
152	unsigned gd_looffset:16;	/* gate offset (lsb) */
153	unsigned gd_selector:16;	/* gate segment selector */
154	unsigned gd_stkcpy:5;		/* number of stack wds to cpy */
155	unsigned gd_xx:3;		/* unused */
156	unsigned gd_type:5;		/* segment type */
157	unsigned gd_dpl:2;		/* segment descriptor priority level */
158	unsigned gd_p:1;		/* segment descriptor present */
159	unsigned gd_hioffset:16;	/* gate offset (msb) */
160} __packed;
161
162/*
163 * Xen-specific?
164 */
165struct ldt_descriptor {
166	__vaddr_t ld_base;
167	uint32_t ld_entries;
168} __packed;
169
170/*
171 * Generic descriptor (8 bytes).
172 */
173union descriptor {
174	struct segment_descriptor sd;
175	struct gate_descriptor gd;
176	struct ldt_descriptor ld;
177	uint32_t raw[2];
178	uint64_t raw64;
179} __packed;
180
181/*
182 * Region descriptors, used to load gdt/idt tables before segments yet exist.
183 */
184struct region_descriptor {
185	unsigned rd_limit:16;		/* segment extent */
186	unsigned rd_base:32;		/* base address  */
187} __packed;
188
189#if __GNUC__ == 2 && __GNUC_MINOR__ < 7
190#pragma pack(4)
191#endif
192
193#ifdef _KERNEL
194#ifdef XENPV
195typedef struct trap_info idt_descriptor_t;
196#else
197typedef struct gate_descriptor idt_descriptor_t; 
198#endif /* XENPV */
199extern union descriptor *gdtstore, *ldtstore;
200
201void setgate(struct gate_descriptor *, void *, int, int, int, int);
202void set_idtgate(idt_descriptor_t *, void *, int, int, int, int);
203void unset_idtgate(idt_descriptor_t *);
204void setregion(struct region_descriptor *, void *, size_t);
205void setsegment(struct segment_descriptor *, const void *, size_t, int, int,
206    int, int);
207void unsetgate(struct gate_descriptor *);
208void update_descriptor(union descriptor *, union descriptor *);
209
210struct idt_vec;
211void idt_vec_reserve(struct idt_vec *, int);
212int idt_vec_alloc(struct idt_vec *, int, int);
213void idt_vec_set(struct idt_vec *, int, void (*)(void));
214void idt_vec_free(struct idt_vec *, int);
215void idt_vec_init_cpu_md(struct idt_vec *, cpuid_t);
216bool idt_vec_is_pcpu(void);
217struct idt_vec* idt_vec_ref(struct idt_vec *);
218
219
220#endif /* _KERNEL */
221
222#endif /* !_LOCORE */
223
224/* system segments and gate types */
225#define SDT_SYSNULL	 0	/* system null */
226#define SDT_SYS286TSS	 1	/* system 286 TSS available */
227#define SDT_SYSLDT	 2	/* system local descriptor table */
228#define SDT_SYS286BSY	 3	/* system 286 TSS busy */
229#define SDT_SYS286CGT	 4	/* system 286 call gate */
230#define SDT_SYSTASKGT	 5	/* system task gate */
231#define SDT_SYS286IGT	 6	/* system 286 interrupt gate */
232#define SDT_SYS286TGT	 7	/* system 286 trap gate */
233#define SDT_SYSNULL2	 8	/* system null again */
234#define SDT_SYS386TSS	 9	/* system 386 TSS available */
235#define SDT_SYSNULL3	10	/* system null again */
236#define SDT_SYS386BSY	11	/* system 386 TSS busy */
237#define SDT_SYS386CGT	12	/* system 386 call gate */
238#define SDT_SYSNULL4	13	/* system null again */
239#define SDT_SYS386IGT	14	/* system 386 interrupt gate */
240#define SDT_SYS386TGT	15	/* system 386 trap gate */
241
242/* memory segment types */
243#define SDT_MEMRO	16	/* memory read only */
244#define SDT_MEMROA	17	/* memory read only accessed */
245#define SDT_MEMRW	18	/* memory read write */
246#define SDT_MEMRWA	19	/* memory read write accessed */
247#define SDT_MEMROD	20	/* memory read only expand dwn limit */
248#define SDT_MEMRODA	21	/* memory read only expand dwn limit accessed */
249#define SDT_MEMRWD	22	/* memory read write expand dwn limit */
250#define SDT_MEMRWDA	23	/* memory read write expand dwn limit accessed */
251#define SDT_MEME	24	/* memory execute only */
252#define SDT_MEMEA	25	/* memory execute only accessed */
253#define SDT_MEMER	26	/* memory execute read */
254#define SDT_MEMERA	27	/* memory execute read accessed */
255#define SDT_MEMEC	28	/* memory execute only conforming */
256#define SDT_MEMEAC	29	/* memory execute only accessed conforming */
257#define SDT_MEMERC	30	/* memory execute read conforming */
258#define SDT_MEMERAC	31	/* memory execute read accessed conforming */
259
260#define SDTYPE(p)	(((const struct segment_descriptor *)(p))->sd_type)
261/* is memory segment descriptor pointer ? */
262#define ISMEMSDP(s)	(SDTYPE(s) >= SDT_MEMRO && \
263			 SDTYPE(s) <= SDT_MEMERAC)
264
265/* is 286 gate descriptor pointer ? */
266#define IS286GDP(s)	(SDTYPE(s) >= SDT_SYS286CGT && \
267			 SDTYPE(s) < SDT_SYS286TGT)
268
269/* is 386 gate descriptor pointer ? */
270#define IS386GDP(s)	(SDTYPE(s) >= SDT_SYS386CGT && \
271			 SDTYPE(s) < SDT_SYS386TGT)
272
273/* is gate descriptor pointer ? */
274#define ISGDP(s)	(IS286GDP(s) || IS386GDP(s))
275
276/* is segment descriptor pointer ? */
277#define ISSDP(s)	(ISMEMSDP(s) || !ISGDP(s))
278
279/* is system segment descriptor pointer ? */
280#define ISSYSSDP(s)	(!ISMEMSDP(s) && !ISGDP(s))
281
282/*
283 * Segment Protection Exception code bits
284 */
285#define SEGEX_EXT	0x01	/* recursive or externally induced */
286#define SEGEX_IDT	0x02	/* interrupt descriptor table */
287#define SEGEX_TI	0x04	/* local descriptor table */
288
289/*
290 * Entries in the Interrupt Descriptor Table (IDT)
291 */
292#define NIDT	256
293#define NRSVIDT	32		/* reserved entries for CPU exceptions */
294
295/*
296 * Entries in the Global Descriptor Table (GDT).
297 *
298 * NB: If you change GBIOSCODE/GBIOSDATA, you *must* rebuild arch/i386/
299 * bioscall/biostramp.inc, as that relies on GBIOSCODE/GBIOSDATA and a
300 * normal kernel build does not rebuild it (it's merely included whole-
301 * sale from i386/bioscall.s)
302 *
303 * Also, note that the GEXTBIOSDATA_SEL selector is special, as it maps
304 * to the value 0x0040 (when created as a KPL global selector).  Some
305 * BIOSes reference the extended BIOS data area at segment 0040 in a non
306 * relocatable fashion (even when in protected mode); mapping the zero page
307 * via the GEXTBIOSDATA_SEL allows these buggy BIOSes to continue to work
308 * under NetBSD.
309 *
310 * The order if the first 5 descriptors is special; the sysenter/sysexit
311 * instructions depend on them.
312 */
313#define GNULL_SEL	0	/* Null descriptor */
314#define GCODE_SEL	1	/* Kernel code descriptor */
315#define GDATA_SEL	2	/* Kernel data descriptor */
316#define GUCODE_SEL	3	/* User code descriptor */
317#define GUDATA_SEL	4	/* User data descriptor */
318#define GLDT_SEL	5	/* Default LDT descriptor */
319#define GCPU_SEL	6	/* per-CPU segment */
320#define GEXTBIOSDATA_SEL 8	/* magic to catch BIOS refs to EBDA */
321#define GAPM32CODE_SEL	9	/* 3 APM segments must be consecutive */
322#define GAPM16CODE_SEL	10	/* and in the specified order: code32 */
323#define GAPMDATA_SEL	11	/* code16 and then data per APM spec */
324#define GBIOSCODE_SEL	12
325#define GBIOSDATA_SEL	13
326#define GPNPBIOSCODE_SEL 14
327#define GPNPBIOSDATA_SEL 15
328#define GPNPBIOSSCRATCH_SEL 16
329#define GPNPBIOSTRAMP_SEL 17
330#define GTRAPTSS_SEL	18
331#define GIPITSS_SEL	19
332#define GUCODEBIG_SEL	20	/* User code with executable stack */
333#define GUFS_SEL	21	/* Per-thread %fs */
334#define GUGS_SEL	22	/* Per-thread %gs */
335#define NGDT		23
336
337/*
338 * Entries in the Local Descriptor Table (LDT).
339 * DO NOT ADD KERNEL DATA/CODE SEGMENTS TO THIS TABLE.
340 */
341#define LSYS5CALLS_SEL	0	/* iBCS system call gate */
342#define LSYS5SIGR_SEL	1	/* iBCS sigreturn gate */
343#define LUCODE_SEL	2	/* User code descriptor */
344#define LUDATA_SEL	3	/* User data descriptor */
345#define LSOL26CALLS_SEL	4	/* Solaris 2.6 system call gate */
346#define LUCODEBIG_SEL	5	/* User code with executable stack */
347#define LBSDICALLS_SEL	16	/* BSDI system call gate */
348#define NLDT		17
349
350#endif /* _I386_SEGMENTS_H_ */