xref: /xnu-8792.81.2/osfmk/i386/postcode.h (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
1 /*
2  * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifndef _I386_POSTCODE_H_
30 #define _I386_POSTCODE_H_
31 
32 /*
33  * Postcodes are no longer enabled by default in the DEBUG kernel
34  * because platforms may not have builtin port 0x80 support.
35  * To re-enable postcode outpout, uncomment the following define:
36  */
37 //#define DEBUG_POSTCODE 1
38 
39 /* Define this to delay about 1 sec after posting each code */
40 //#define POSTCODE_DELAY 1
41 
42 /* The POSTCODE is port 0x80 */
43 #define POSTPORT 0x80
44 
45 #define SPINCOUNT       300000000
46 #define CPU_PAUSE()     rep; nop
47 
48 #if DEBUG_POSTCODE
49 /*
50  * Macro to output byte value to postcode, destoying register al.
51  * Additionally, if POSTCODE_DELAY, spin for about a second.
52  */
53 #if POSTCODE_DELAY
54 #define POSTCODE_AL                     \
55 	outb    %al,$(POSTPORT);        \
56 	movl	$(SPINCOUNT), %eax;     \
57 1:                                      \
58 	CPU_PAUSE();                    \
59 	decl	%eax;                   \
60 	jne	1b
61 #define POSTCODE_AX                     \
62 	outw    %ax,$(POSTPORT);        \
63 	movl	$(SPINCOUNT), %eax;     \
64 1:                                      \
65 	CPU_PAUSE();                    \
66 	decl	%eax;                   \
67 	jne	1b
68 #else
69 #define POSTCODE_AL                     \
70 	outb    %al,$(POSTPORT)
71 #define POSTCODE_AX                     \
72 	outw    %ax,$(POSTPORT)
73 #endif /* POSTCODE_DELAY */
74 
75 #define POSTCODE(XX)                    \
76 	mov	$(XX), %al;             \
77 	POSTCODE_AL
78 
79 #define POSTCODE2(XXXX)                 \
80 	mov	$(XXXX), %ax;           \
81 	POSTCODE_AX
82 
83 /* Output byte value to postcode, without destoying register eax */
84 #define POSTCODE_SAVE_EAX(XX)           \
85 	push	%eax;                   \
86 	POSTCODE(XX);                   \
87 	pop	%eax
88 
89 /*
90  * Display a 32-bit value to the post card - low byte to high byte
91  * Entry: value in %ebx
92  * Exit: %ebx preserved; %eax destroyed
93  */
94 #define POSTCODE32_EBX                  \
95 	roll	$8, %ebx;               \
96 	movl	%ebx, %eax;             \
97 	POSTCODE_AL;                    \
98                                         \
99 	roll	$8, %ebx;               \
100 	movl	%ebx, %eax;             \
101 	POSTCODE_AL;                    \
102                                         \
103 	roll	$8, %ebx;               \
104 	movl	%ebx, %eax;             \
105 	POSTCODE_AL;                    \
106                                         \
107 	roll	$8, %ebx;               \
108 	movl	%ebx, %eax;             \
109 	POSTCODE_AL
110 
111 #else   /* DEBUG_POSTCODE */
112 #define POSTCODE_AL
113 #define POSTCODE_AX
114 #define POSTCODE(X)
115 #define POSTCODE2(X)
116 #define POSTCODE_SAVE_EAX(X)
117 #define POSTCODE32_EBX
118 #endif  /* DEBUG_POSTCODE */
119 
120 /*
121  * The following postcodes are defined for stages of early startup:
122  */
123 
124 #define PSTART_ENTRY                    0xFF
125 #define PSTART_REBASE                   0xFE
126 #define PSTART_BEFORE_PAGING            0xFE
127 #define PSTART_VSTART                   0xFD
128 #define VSTART_ENTRY                    0xFC
129 #define VSTART_IDT_INIT                 0xFB
130 #define VSTART_IDLE_PTS_INIT            0xFA
131 #define VSTART_PHYSMAP_INIT             0xF9
132 #define VSTART_DESC_ALIAS_INIT          0xF8
133 #define VSTART_SET_CR3                  0xF7
134 #define VSTART_CPU_DESC_INIT            0xF6
135 #define VSTART_CPU_MODE_INIT            0xF5
136 #define VSTART_EXIT                     0xF4
137 #define I386_INIT_ENTRY                 0xF3
138 #define CPU_INIT_D                      0xF2
139 #define PE_INIT_PLATFORM_D              0xF1
140 
141 #define SLAVE_STARTPROG_ENTRY           0xEF
142 #define SLAVE_PSTART                    0xEE
143 #define I386_INIT_SLAVE                 0xED
144 
145 #define PANIC_DOUBLE_FAULT              0xDF    /* Double Fault exception */
146 #define PANIC_MACHINE_CHECK             0xDC    /* Machine-Check */
147 #define MP_KDP_ENTER                    0xDB    /* Debugger Begin */
148 #define MP_KDP_EXIT                     0xDE    /* Debugger End */
149 #define PANIC_HLT                       0xD1    /* Die an early death */
150 #define BOOT_TRAP_HLT                   0xD0    /* D'oh! even earlier */
151 
152 #define ACPI_WAKE_START_ENTRY           0xCF
153 #define ACPI_WAKE_PROT_ENTRY            0xCE
154 #define ACPI_WAKE_PAGED_ENTRY           0xCD
155 
156 #define CPU_DESC_LOAD_ENTRY             0xBF
157 #define CPU_DESC_LOAD_GS_BASE           0xBE
158 #define CPU_DESC_LOAD_KERNEL_GS_BASE    0xBD
159 #define CPU_DESC_LOAD_GDT               0xBC
160 #define CPU_DESC_LOAD_IDT               0xBB
161 #define CPU_DESC_LOAD_LDT               0xBA
162 #define CPU_DESC_LOAD_TSS               0xB9
163 #define CPU_DESC_LOAD_EXIT              0xB7
164 
165 #ifndef ASSEMBLER
166 inline static void
_postcode_delay(uint32_t spincount)167 _postcode_delay(uint32_t        spincount)
168 {
169 	asm volatile ("1:			\n\t"
170                       "  rep; nop;		\n\t"
171                       "  decl %%eax;		\n\t"
172                       "  jne 1b"
173                       : : "a" (spincount));
174 }
175 inline static void
_postcode(uint8_t xx)176 _postcode(uint8_t       xx)
177 {
178 	asm volatile ("outb %0, %1" : : "a" (xx), "N" (POSTPORT));
179 }
180 inline static void
_postcode2(uint16_t xxxx)181 _postcode2(uint16_t     xxxx)
182 {
183 	asm volatile ("outw %0, %1" : : "a" (xxxx), "N" (POSTPORT));
184 }
185 #if     DEBUG_POSTCODE
186 inline static void
postcode(uint8_t xx)187 postcode(uint8_t        xx)
188 {
189 	_postcode(xx);
190 #if     POSTCODE_DELAY
191 	_postcode_delay(SPINCOUNT);
192 #endif
193 }
194 inline static void
postcode2(uint8_t xxxx)195 postcode2(uint8_t       xxxx)
196 {
197 	_postcode2(xxxx);
198 #if     POSTCODE_DELAY
199 	_postcode_delay(SPINCOUNT);
200 #endif
201 }
202 #else
203 #define postcode(xx) do {} while(0)
204 #define postcode2(xxxx) do {} while(0)
205 #endif
206 #endif
207 
208 #endif /* _I386_POSTCODE_H_ */
209