1/*	$NetBSD: segments.h,v 1.53 2009/05/17 18:24:23 bouyer 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 XEN
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 /* XEN */
98#define	SEL_UPL		3		/* user privilege level */
99#define	SEL_RPL		3		/* requester's privilege level mask */
100#ifdef XEN
101#define	CHK_UPL		2		/* user privilege level mask */
102#else
103#define CHK_UPL		SEL_RPL
104#endif /* XEN */
105#define	ISLDT(s)	((s) & SEL_LDT)	/* is it local or global */
106#define	SEL_LDT		4		/* local descriptor table */
107#define	IDXSEL(s)	(((s) >> 3) & 0x1fff)		/* index of selector */
108#define	IDXSELN(s)	(((s) >> 3))			/* index of selector */
109#define	GSEL(s,r)	(((s) << 3) | r)		/* a global selector */
110#define	LSEL(s,r)	(((s) << 3) | r | SEL_LDT)	/* a local selector */
111#define	GSYSSEL(s,r)	GSEL(s,r)	/* compat with amd64 */
112
113#if defined(_KERNEL_OPT)
114#include "opt_vm86.h"
115#endif
116
117#ifdef VM86
118#define	USERMODE(c, f)		(ISPL(c) == SEL_UPL || ((f) & PSL_VM) != 0)
119#define	KERNELMODE(c, f)	(ISPL(c) == SEL_KPL && ((f) & PSL_VM) == 0)
120#else
121#define	USERMODE(c, f)		(ISPL(c) == SEL_UPL)
122#define	KERNELMODE(c, f)	(ISPL(c) == SEL_KPL)
123#endif
124
125#ifndef _LOCORE
126
127#if __GNUC__ == 2 && __GNUC_MINOR__ < 7
128#pragma pack(1)
129#endif
130
131/*
132 * Memory and System segment descriptors
133 */
134struct segment_descriptor {
135	unsigned sd_lolimit:16;		/* segment extent (lsb) */
136	unsigned sd_lobase:24;		/* segment base address (lsb) */
137	unsigned sd_type:5;		/* segment type */
138	unsigned sd_dpl:2;		/* segment descriptor priority level */
139	unsigned sd_p:1;		/* segment descriptor present */
140	unsigned sd_hilimit:4;		/* segment extent (msb) */
141	unsigned sd_xx:2;		/* unused */
142	unsigned sd_def32:1;		/* default 32 vs 16 bit size */
143	unsigned sd_gran:1;		/* limit granularity (byte/page) */
144	unsigned sd_hibase:8;		/* segment base address (msb) */
145} __packed;
146
147/*
148 * Gate descriptors (e.g. indirect descriptors)
149 */
150struct gate_descriptor {
151	unsigned gd_looffset:16;	/* gate offset (lsb) */
152	unsigned gd_selector:16;	/* gate segment selector */
153	unsigned gd_stkcpy:5;		/* number of stack wds to cpy */
154	unsigned gd_xx:3;		/* unused */
155	unsigned gd_type:5;		/* segment type */
156	unsigned gd_dpl:2;		/* segment descriptor priority level */
157	unsigned gd_p:1;		/* segment descriptor present */
158	unsigned gd_hioffset:16;	/* gate offset (msb) */
159} __packed;
160
161struct ldt_descriptor {
162	vaddr_t ld_base;
163	uint32_t ld_entries;
164} __packed;
165
166/*
167 * Generic descriptor
168 */
169union descriptor {
170	struct segment_descriptor sd;
171	struct gate_descriptor gd;
172	struct ldt_descriptor ld;
173	uint32_t raw[2];
174	uint64_t raw64;
175} __packed;
176
177/*
178 * region descriptors, used to load gdt/idt tables before segments yet exist.
179 */
180struct region_descriptor {
181	unsigned rd_limit:16;		/* segment extent */
182	unsigned rd_base:32;		/* base address  */
183} __packed;
184
185#if __GNUC__ == 2 && __GNUC_MINOR__ < 7
186#pragma pack(4)
187#endif
188
189#ifdef _KERNEL
190extern union descriptor *gdt, *ldt;
191extern struct gate_descriptor *idt;
192
193void setgate(struct gate_descriptor *, void *, int, int, int, int);
194void setregion(struct region_descriptor *, void *, size_t);
195void setsegment(struct segment_descriptor *, const void *, size_t, int, int,
196    int, int);
197void setgdt(int, const void *, size_t, int, int, int, int);
198void unsetgate(struct gate_descriptor *);
199void cpu_init_idt(void);
200void update_descriptor(union descriptor *, union descriptor *);
201
202#if !defined(XEN)
203void idt_init(void);
204void idt_vec_reserve(int);
205int idt_vec_alloc(int, int);
206void idt_vec_set(int, void (*)(void));
207void idt_vec_free(int);
208#endif
209
210#endif /* _KERNEL */
211
212#endif /* !_LOCORE */
213
214/* system segments and gate types */
215#define	SDT_SYSNULL	 0	/* system null */
216#define	SDT_SYS286TSS	 1	/* system 286 TSS available */
217#define	SDT_SYSLDT	 2	/* system local descriptor table */
218#define	SDT_SYS286BSY	 3	/* system 286 TSS busy */
219#define	SDT_SYS286CGT	 4	/* system 286 call gate */
220#define	SDT_SYSTASKGT	 5	/* system task gate */
221#define	SDT_SYS286IGT	 6	/* system 286 interrupt gate */
222#define	SDT_SYS286TGT	 7	/* system 286 trap gate */
223#define	SDT_SYSNULL2	 8	/* system null again */
224#define	SDT_SYS386TSS	 9	/* system 386 TSS available */
225#define	SDT_SYSNULL3	10	/* system null again */
226#define	SDT_SYS386BSY	11	/* system 386 TSS busy */
227#define	SDT_SYS386CGT	12	/* system 386 call gate */
228#define	SDT_SYSNULL4	13	/* system null again */
229#define	SDT_SYS386IGT	14	/* system 386 interrupt gate */
230#define	SDT_SYS386TGT	15	/* system 386 trap gate */
231
232/* memory segment types */
233#define	SDT_MEMRO	16	/* memory read only */
234#define	SDT_MEMROA	17	/* memory read only accessed */
235#define	SDT_MEMRW	18	/* memory read write */
236#define	SDT_MEMRWA	19	/* memory read write accessed */
237#define	SDT_MEMROD	20	/* memory read only expand dwn limit */
238#define	SDT_MEMRODA	21	/* memory read only expand dwn limit accessed */
239#define	SDT_MEMRWD	22	/* memory read write expand dwn limit */
240#define	SDT_MEMRWDA	23	/* memory read write expand dwn limit acessed */
241#define	SDT_MEME	24	/* memory execute only */
242#define	SDT_MEMEA	25	/* memory execute only accessed */
243#define	SDT_MEMER	26	/* memory execute read */
244#define	SDT_MEMERA	27	/* memory execute read accessed */
245#define	SDT_MEMEC	28	/* memory execute only conforming */
246#define	SDT_MEMEAC	29	/* memory execute only accessed conforming */
247#define	SDT_MEMERC	30	/* memory execute read conforming */
248#define	SDT_MEMERAC	31	/* memory execute read accessed conforming */
249
250#define SDTYPE(p)	(((const struct segment_descriptor *)(p))->sd_type)
251/* is memory segment descriptor pointer ? */
252#define ISMEMSDP(s)	(SDTYPE(s) >= SDT_MEMRO && \
253			 SDTYPE(s) <= SDT_MEMERAC)
254
255/* is 286 gate descriptor pointer ? */
256#define IS286GDP(s)	(SDTYPE(s) >= SDT_SYS286CGT && \
257			 SDTYPE(s) < SDT_SYS286TGT)
258
259/* is 386 gate descriptor pointer ? */
260#define IS386GDP(s)	(SDTYPE(s) >= SDT_SYS386CGT && \
261			 SDTYPE(s) < SDT_SYS386TGT)
262
263/* is gate descriptor pointer ? */
264#define ISGDP(s)	(IS286GDP(s) || IS386GDP(s))
265
266/* is segment descriptor pointer ? */
267#define ISSDP(s)	(ISMEMSDP(s) || !ISGDP(s))
268
269/* is system segment descriptor pointer ? */
270#define ISSYSSDP(s)	(!ISMEMSDP(s) && !ISGDP(s))
271
272/*
273 * Segment Protection Exception code bits
274 */
275#define	SEGEX_EXT	0x01	/* recursive or externally induced */
276#define	SEGEX_IDT	0x02	/* interrupt descriptor table */
277#define	SEGEX_TI	0x04	/* local descriptor table */
278
279/*
280 * Entries in the Interrupt Descriptor Table (IDT)
281 */
282#define	NIDT	256
283#define	NRSVIDT	32		/* reserved entries for CPU exceptions */
284
285/*
286 * Entries in the Global Descriptor Table (GDT).
287 *
288 * NB: If you change GBIOSCODE/GBIOSDATA, you *must* rebuild arch/i386/
289 * bioscall/biostramp.inc, as that relies on GBIOSCODE/GBIOSDATA and a
290 * normal kernel build does not rebuild it (it's merely included whole-
291 * sale from i386/bioscall.s)
292 *
293 * Also, note that the GEXTBIOSDATA_SEL selector is special, as it maps
294 * to the value 0x0040 (when created as a KPL global selector).  Some
295 * BIOSes reference the extended BIOS data area at segment 0040 in a non
296 * relocatable fashion (even when in protected mode); mapping the zero page
297 * via the GEXTBIOSDATA_SEL allows these buggy BIOSes to continue to work
298 * under NetBSD.
299 *
300 * The order if the first 5 descriptors is special; the sysenter/sysexit
301 * instructions depend on them.
302 */
303#define	GNULL_SEL	0	/* Null descriptor */
304#define	GCODE_SEL	1	/* Kernel code descriptor */
305#define	GDATA_SEL	2	/* Kernel data descriptor */
306#define	GUCODE_SEL	3	/* User code descriptor */
307#define	GUDATA_SEL	4	/* User data descriptor */
308#define	GLDT_SEL	5	/* Default LDT descriptor */
309#define GCPU_SEL	6	/* per-CPU segment */
310#define	GEXTBIOSDATA_SEL 8	/* magic to catch BIOS refs to EBDA */
311#define	GAPM32CODE_SEL	9	/* 3 APM segments must be consecutive */
312#define	GAPM16CODE_SEL	10	/* and in the specified order: code32 */
313#define	GAPMDATA_SEL	11	/* code16 and then data per APM spec */
314#define	GBIOSCODE_SEL	12
315#define	GBIOSDATA_SEL	13
316#define	GPNPBIOSCODE_SEL 14
317#define	GPNPBIOSDATA_SEL 15
318#define	GPNPBIOSSCRATCH_SEL 16
319#define	GPNPBIOSTRAMP_SEL 17
320#define GTRAPTSS_SEL	18
321#define GIPITSS_SEL	19
322#define GUCODEBIG_SEL	20	/* User code with executable stack */
323#define	GUFS_SEL	21	/* Per-thread %fs */
324#define	GUGS_SEL	22	/* Per-thread %gs */
325#define	NGDT		23
326
327/*
328 * Entries in the Local Descriptor Table (LDT).
329 * DO NOT ADD KERNEL DATA/CODE SEGMENTS TO THIS TABLE.
330 */
331#define	LSYS5CALLS_SEL	0	/* iBCS system call gate */
332#define	LSYS5SIGR_SEL	1	/* iBCS sigreturn gate */
333#define	LUCODE_SEL	2	/* User code descriptor */
334#define	LUDATA_SEL	3	/* User data descriptor */
335#define	LSOL26CALLS_SEL	4	/* Solaris 2.6 system call gate */
336#define	LUCODEBIG_SEL	5	/* User code with executable stack */
337#define	LBSDICALLS_SEL	16	/* BSDI system call gate */
338#define	NLDT		17
339
340#endif /* _I386_SEGMENTS_H_ */
341