xref: /illumos-gate/usr/src/uts/i86pc/sys/rm_platter.h (revision 7417cfde)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 /*
25  * Copyright (c) 2010, Intel Corporation.
26  * All rights reserved.
27  */
28 
29 #ifndef	_SYS_RM_PLATTER_H
30 #define	_SYS_RM_PLATTER_H
31 
32 #include <sys/types.h>
33 #include <sys/tss.h>
34 #include <sys/segments.h>
35 
36 #ifdef	__cplusplus
37 extern "C" {
38 #endif
39 
40 #define	RM_PLATTER_CODE_SIZE		0x400
41 #define	RM_PLATTER_CPU_HALT_CODE_SIZE	0x100
42 
43 typedef	struct rm_platter {
44 	char		rm_code[RM_PLATTER_CODE_SIZE];
45 	char		rm_cpu_halt_code[RM_PLATTER_CPU_HALT_CODE_SIZE];
46 #if defined(__amd64)
47 	/*
48 	 * The compiler will want to 64-bit align the 64-bit rm_gdt_base
49 	 * pointer, so we need to add an extra four bytes of padding here to
50 	 * make sure rm_gdt_lim and rm_gdt_base will align to create a proper
51 	 * ten byte GDT pseudo-descriptor.
52 	 */
53 	uint32_t	rm_gdt_pad;
54 #endif	/* __amd64 */
55 	ushort_t	rm_debug;
56 	ushort_t	rm_gdt_lim;	/* stuff for lgdt */
57 	user_desc_t	*rm_gdt_base;
58 #if defined(__amd64)
59 	/*
60 	 * The compiler will want to 64-bit align the 64-bit rm_idt_base
61 	 * pointer, so we need to add an extra four bytes of padding here to
62 	 * make sure rm_idt_lim and rm_idt_base will align to create a proper
63 	 * ten byte IDT pseudo-descriptor.
64 	 */
65 	uint32_t	rm_idt_pad;
66 #endif	/* __amd64 */
67 	ushort_t	rm_cpu_halted;	/* non-zero if CPU has been halted */
68 	ushort_t	rm_idt_lim;	/* stuff for lidt */
69 	gate_desc_t	*rm_idt_base;
70 	uint_t		rm_pdbr;	/* cr3 value */
71 	uint_t		rm_cpu;		/* easy way to know which CPU we are */
72 	uint_t		rm_filler3;
73 	uint_t		rm_cr4;		/* cr4 value on cpu0 */
74 #if defined(__amd64)
75 	/*
76 	 * Temporary GDT for the brief transition from real mode to protected
77 	 * mode before a CPU continues on into long mode.
78 	 *
79 	 * Putting it here assures it will be located in identity mapped memory
80 	 * (va == pa, 1:1).
81 	 *
82 	 * rm_temp_gdt is sized to hold only a null descriptor in slot zero
83 	 * and a 64-bit code descriptor in slot one.
84 	 *
85 	 * rm_temp_[gi]dt_lim and rm_temp_[gi]dt_base are the pseudo-descriptors
86 	 * for the temporary GDT and IDT, respectively.
87 	 */
88 	uint64_t	rm_temp_gdt[2];
89 	ushort_t	rm_temp_gdtdesc_pad;	/* filler to align GDT desc */
90 	ushort_t	rm_temp_gdt_lim;
91 	uint32_t	rm_temp_gdt_base;
92 	ushort_t	rm_temp_idtdesc_pad;	/* filler to align IDT desc */
93 	ushort_t	rm_temp_idt_lim;
94 	uint32_t	rm_temp_idt_base;
95 
96 	/*
97 	 * The code executing in the rm_platter needs the offset into the
98 	 * platter at which the 64-bit code starts, so have mp_startup
99 	 * calculate it and store it here.
100 	 */
101 	uint32_t	rm_longmode64_addr;
102 #endif	/* __amd64 */
103 } rm_platter_t;
104 
105 /*
106  * cpu tables put within a single structure two of the tables which need to be
107  * allocated when a CPU starts up.
108  *
109  * Note: the tss should be 16 byte aligned for best performance on amd64
110  * Since DEFAULTSTKSIZE is a multiple of PAGESIZE tss will be aligned.
111  */
112 struct cpu_tables {
113 	char		ct_stack[DEFAULTSTKSZ];
114 	struct tss	ct_tss;
115 };
116 
117 /*
118  * gdt entries are 8 bytes long, ensure that we have an even no. of them.
119  */
120 #if ((NGDT / 2) * 2 != NGDT)
121 #error "rm_platter.h: tss not properly aligned"
122 #endif
123 
124 #ifdef	__cplusplus
125 }
126 #endif
127 
128 #endif	/* _SYS_RM_PLATTER_H */
129