|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1992 NeXT Computer, Inc.
27: *
28: * Intel386 Family: Descriptor manipulation.
29: *
30: * HISTORY
31: *
32: * 1 April 1992 ? at NeXT
33: * Created.
34: */
35:
36: #import <mach/vm_param.h> /* for round_page() */
37:
38: #import <architecture/i386/table.h>
39:
40: /*
41: * Convert a segment size
42: * into a page-granular limit.
43: */
44: #define page_limit(size) \
45: (i386_round_page(size) - I386_PGBYTES)
46:
47: /*
48: * Convert a segment size
49: * into a byte-granular limit.
50: */
51: #define byte_limit(size) \
52: ((size) - 1)
53:
54: /*
55: * These types allow the
56: * breaking up of base and
57: * limit values so that the
58: * descriptors can be filled
59: * in easily.
60: */
61:
62: typedef union {
63: unsigned int word;
64: struct {
65: unsigned int base00 :16,
66: base16 :8,
67: base24 :8;
68: } fields;
69: } conv_base_t;
70:
71: typedef union {
72: unsigned int word;
73: struct {
74: unsigned int limit00 :16,
75: limit16 :4,
76: :12;
77: } fields_byte;
78: struct {
79: unsigned int :12,
80: limit00 :16,
81: limit16 :4;
82: } fields_page;
83: } conv_limit_t;
84:
85: /*
86: * Initialize a descriptor
87: * to map an LDT segment.
88: */
89:
90: static inline
91: void
92: map_ldt(desc, base, size)
93: ldt_desc_t * desc;
94: vm_offset_t base;
95: vm_size_t size;
96: {
97: conv_base_t tbase;
98: conv_limit_t tlimit;
99:
100: tbase.word = base;
101: tlimit.word = byte_limit(size);
102:
103: desc->base00 = tbase.fields.base00;
104: desc->base16 = tbase.fields.base16;
105: desc->base24 = tbase.fields.base24;
106: desc->type = DESC_LDT;
107: desc->present = TRUE;
108: desc->granular = DESC_GRAN_BYTE;
109: desc->limit00 = tlimit.fields_byte.limit00;
110: desc->limit16 = tlimit.fields_byte.limit16;
111: }
112:
113: /*
114: * Initialize a descriptor
115: * to map a TSS.
116: */
117:
118: static inline
119: void
120: map_tss(desc, base, size)
121: tss_desc_t * desc;
122: vm_offset_t base;
123: vm_size_t size;
124: {
125: conv_base_t tbase;
126: conv_limit_t tlimit;
127:
128: tbase.word = base;
129: tlimit.word = byte_limit(size);
130:
131: desc->base00 = tbase.fields.base00;
132: desc->base16 = tbase.fields.base16;
133: desc->base24 = tbase.fields.base24;
134: desc->type = DESC_TSS;
135: desc->dpl = KERN_PRIV;
136: desc->present = TRUE;
137: desc->granular = DESC_GRAN_BYTE;
138: desc->limit00 = tlimit.fields_byte.limit00;
139: desc->limit16 = tlimit.fields_byte.limit16;
140: }
141:
142: /*
143: * Initialize a descriptor
144: * to map a code segment.
145: */
146:
147: static inline
148: void
149: map_code(desc, base, size, priv, exec_only)
150: code_desc_t * desc;
151: vm_offset_t base;
152: vm_size_t size;
153: int priv;
154: boolean_t exec_only;
155: {
156: conv_base_t tbase;
157: conv_limit_t tlimit;
158:
159: tbase.word = base;
160:
161: desc->base00 = tbase.fields.base00;
162: desc->base16 = tbase.fields.base16;
163: desc->base24 = tbase.fields.base24;
164: desc->type = exec_only? DESC_CODE_EXEC: DESC_CODE_READ;
165: desc->dpl = priv;
166: desc->present = TRUE;
167: desc->opsz = DESC_CODE_32B;
168:
169: if (byte_limit(size) < (1 << 20)) { /* 2 ^ 20 or 1MB */
170: tlimit.word = byte_limit(size);
171:
172: desc->granular = DESC_GRAN_BYTE;
173: desc->limit00 = tlimit.fields_byte.limit00;
174: desc->limit16 = tlimit.fields_byte.limit16;
175: }
176: else {
177: tlimit.word = page_limit(size);
178:
179: desc->granular = DESC_GRAN_PAGE;
180: desc->limit00 = tlimit.fields_page.limit00;
181: desc->limit16 = tlimit.fields_page.limit16;
182: }
183: }
184:
185: /*
186: * Initialize a descriptor
187: * to map a 16-bit code segment.
188: */
189:
190: static inline
191: void
192: map_code_16(desc, base, size, priv, exec_only)
193: code_desc_t * desc;
194: vm_offset_t base;
195: vm_size_t size;
196: int priv;
197: boolean_t exec_only;
198: {
199: conv_base_t tbase;
200: conv_limit_t tlimit;
201:
202: tbase.word = base;
203:
204: desc->base00 = tbase.fields.base00;
205: desc->base16 = tbase.fields.base16;
206: desc->base24 = tbase.fields.base24;
207: desc->type = exec_only? DESC_CODE_EXEC: DESC_CODE_READ;
208: desc->dpl = priv;
209: desc->present = TRUE;
210: desc->opsz = DESC_CODE_16B;
211:
212: if (byte_limit(size) < (1 << 20)) { /* 2 ^ 20 or 1MB */
213: tlimit.word = byte_limit(size);
214:
215: desc->granular = DESC_GRAN_BYTE;
216: desc->limit00 = tlimit.fields_byte.limit00;
217: desc->limit16 = tlimit.fields_byte.limit16;
218: }
219: else {
220: tlimit.word = page_limit(size);
221:
222: desc->granular = DESC_GRAN_PAGE;
223: desc->limit00 = tlimit.fields_page.limit00;
224: desc->limit16 = tlimit.fields_page.limit16;
225: }
226: }
227:
228: /*
229: * Initialize a descriptor
230: * to map a data segment.
231: */
232:
233: static inline
234: void
235: map_data(desc, base, size, priv, read_only)
236: data_desc_t * desc;
237: vm_offset_t base;
238: vm_size_t size;
239: int priv;
240: boolean_t read_only;
241: {
242: conv_base_t tbase;
243: conv_limit_t tlimit;
244:
245: tbase.word = base;
246:
247: desc->base00 = tbase.fields.base00;
248: desc->base16 = tbase.fields.base16;
249: desc->base24 = tbase.fields.base24;
250: desc->type = read_only? DESC_DATA_RONLY: DESC_DATA_WRITE;
251: desc->dpl = priv;
252: desc->present = TRUE;
253: desc->stksz = DESC_DATA_32B;
254:
255: if (byte_limit(size) < (1 << 20)) { /* 2 ^ 20 or 1MB */
256: tlimit.word = byte_limit(size);
257:
258: desc->granular = DESC_GRAN_BYTE;
259: desc->limit00 = tlimit.fields_byte.limit00;
260: desc->limit16 = tlimit.fields_byte.limit16;
261: }
262: else {
263: tlimit.word = page_limit(size);
264:
265: desc->granular = DESC_GRAN_PAGE;
266: desc->limit00 = tlimit.fields_page.limit00;
267: desc->limit16 = tlimit.fields_page.limit16;
268: }
269: }
270:
271: /*
272: * Change a descriptor to
273: * map a different LDT. Only
274: * change the segment base.
275: */
276:
277: static inline
278: void
279: remap_ldt(desc, base)
280: ldt_desc_t * desc;
281: vm_offset_t base;
282: {
283: conv_base_t tbase;
284:
285: tbase.word = base;
286:
287: desc->base00 = tbase.fields.base00;
288: desc->base16 = tbase.fields.base16;
289: desc->base24 = tbase.fields.base24;
290: }
291:
292: /*
293: * Change a descriptor to
294: * map a different TSS. Only
295: * change the segment base and
296: * reset the type field (busy bit).
297: */
298:
299: static inline
300: void
301: remap_tss(desc, base)
302: tss_desc_t * desc;
303: vm_offset_t base;
304: {
305: conv_base_t tbase;
306:
307: tbase.word = base;
308:
309: desc->base00 = tbase.fields.base00;
310: desc->base16 = tbase.fields.base16;
311: desc->base24 = tbase.fields.base24;
312: desc->type = DESC_TSS;
313: }
314:
315: /*
316: * This type allows the
317: * breaking up of the offset
318: * value so that the gate
319: * can be filled in easily.
320: */
321:
322: typedef union {
323: unsigned int word;
324: struct {
325: unsigned int offset00:16,
326: offset16:16;
327: } fields;
328: } conv_offset_t;
329:
330: /*
331: * Initialize a call gate.
332: */
333:
334: static inline
335: void
336: make_call_gate(desc, seg, offset, priv, argcnt)
337: call_gate_t * desc;
338: sel_t seg;
339: vm_offset_t offset;
340: int priv, argcnt;
341: {
342: conv_offset_t toffset;
343:
344: toffset.word = offset;
345:
346: desc->offset00 = toffset.fields.offset00;
347: desc->offset16 = toffset.fields.offset16;
348: desc->seg = seg;
349: desc->argcnt = argcnt;
350: desc->type = DESC_CALL_GATE;
351: desc->dpl = priv;
352: desc->present = TRUE;
353: }
354:
355: /*
356: * Initialize a trap gate.
357: */
358:
359: static inline
360: void
361: make_trap_gate(desc, seg, offset, priv)
362: trap_gate_t * desc;
363: sel_t seg;
364: vm_offset_t offset;
365: int priv;
366: {
367: conv_offset_t toffset;
368:
369: toffset.word = offset;
370:
371: desc->offset00 = toffset.fields.offset00;
372: desc->offset16 = toffset.fields.offset16;
373: desc->seg = seg;
374: desc->type = DESC_TRAP_GATE;
375: desc->dpl = priv;
376: desc->present = TRUE;
377: }
378:
379: /*
380: * Initialize an interrupt gate.
381: */
382:
383: static inline
384: void
385: make_intr_gate(desc, seg, offset, priv)
386: intr_gate_t * desc;
387: sel_t seg;
388: vm_offset_t offset;
389: int priv;
390: {
391: conv_offset_t toffset;
392:
393: toffset.word = offset;
394:
395: desc->offset00 = toffset.fields.offset00;
396: desc->offset16 = toffset.fields.offset16;
397: desc->seg = seg;
398: desc->type = DESC_INTR_GATE;
399: desc->dpl = priv;
400: desc->present = TRUE;
401: }
402:
403: /*
404: * Initialize a task gate.
405: */
406:
407: static inline
408: void
409: make_task_gate(desc, tss, priv)
410: task_gate_t * desc;
411: sel_t tss;
412: int priv;
413: {
414: desc->tss = tss;
415: desc->type = DESC_TASK_GATE;
416: desc->dpl = priv;
417: desc->present = TRUE;
418: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.