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/* Define this to delay about 1 sec after posting each code */ 33//#define POSTCODE_DELAY 1 34 35/* The POSTCODE is port 0x80 */ 36#define POSTPORT 0x80 37 38#define SPINCOUNT 300000000 39#define CPU_PAUSE() rep; nop 40 41#if DEBUG 42/* 43 * Macro to output byte value to postcode, destoying register al. 44 * Additionally, if POSTCODE_DELAY, spin for about a second. 45 */ 46#if POSTCODE_DELAY 47#define POSTCODE_AL \ 48 outb %al,$(POSTPORT); \ 49 movl $(SPINCOUNT), %eax; \ 501: \ 51 CPU_PAUSE(); \ 52 decl %eax; \ 53 jne 1b 54#define POSTCODE_AX \ 55 outw %ax,$(POSTPORT); \ 56 movl $(SPINCOUNT), %eax; \ 571: \ 58 CPU_PAUSE(); \ 59 decl %eax; \ 60 jne 1b 61#else 62#define POSTCODE_AL \ 63 outb %al,$(POSTPORT) 64#define POSTCODE_AX \ 65 outw %ax,$(POSTPORT) 66#endif /* POSTCODE_DELAY */ 67 68#define POSTCODE(XX) \ 69 mov $(XX), %al; \ 70 POSTCODE_AL 71 72#define POSTCODE2(XXXX) \ 73 mov $(XXXX), %ax; \ 74 POSTCODE_AX 75 76/* Output byte value to postcode, without destoying register eax */ 77#define POSTCODE_SAVE_EAX(XX) \ 78 push %eax; \ 79 POSTCODE(XX); \ 80 pop %eax 81 82/* 83 * Display a 32-bit value to the post card - low byte to high byte 84 * Entry: value in %ebx 85 * Exit: %ebx preserved; %eax destroyed 86 */ 87#define POSTCODE32_EBX \ 88 roll $8, %ebx; \ 89 movl %ebx, %eax; \ 90 POSTCODE_AL; \ 91 \ 92 roll $8, %ebx; \ 93 movl %ebx, %eax; \ 94 POSTCODE_AL; \ 95 \ 96 roll $8, %ebx; \ 97 movl %ebx, %eax; \ 98 POSTCODE_AL; \ 99 \ 100 roll $8, %ebx; \ 101 movl %ebx, %eax; \ 102 POSTCODE_AL 103 104#else /* DEBUG */ 105#define POSTCODE_AL 106#define POSTCODE_AX 107#define POSTCODE(X) 108#define POSTCODE2(X) 109#define POSTCODE_SAVE_EAX(X) 110#define POSTCODE32_EBX 111#endif /* DEBUG */ 112 113/* 114 * The following postcodes are defined for stages of early startup: 115 */ 116 117#define PSTART_ENTRY 0xFF 118#define PSTART_REBASE 0xFE 119#define PSTART_BEFORE_PAGING 0xFE 120#define PSTART_VSTART 0xFD 121#define VSTART_ENTRY 0xFC 122#define VSTART_IDLE_PTS_INIT 0xFB 123#define VSTART_PHYSMAP_INIT 0xFA 124#define VSTART_DESC_ALIAS_INIT 0xF9 125#define VSTART_SET_CR3 0xF8 126#define VSTART_CPU_DESC_INIT 0xF7 127#define VSTART_CPU_MODE_INIT 0xF6 128#define VSTART_EXIT 0xF5 129#define I386_INIT_ENTRY 0xF4 130#define CPU_INIT_D 0xF3 131#define PE_INIT_PLATFORM_D 0xF2 132 133#define SLAVE_STARTPROG_ENTRY 0xEF 134#define SLAVE_PSTART 0xEE 135#define I386_INIT_SLAVE 0xED 136 137#define PANIC_DOUBLE_FAULT 0xDF /* Double Fault exception */ 138#define PANIC_MACHINE_CHECK 0xDE /* Machine-Check */ 139#define MP_KDP_ENTER 0xDB /* Machine in kdp DeBugger */ 140#define PANIC_HLT 0xD1 /* Die an early death */ 141#define NO_64BIT 0x64 /* No 64-bit support yet */ 142 143#define ACPI_WAKE_START_ENTRY 0xCF 144#define ACPI_WAKE_PROT_ENTRY 0xCE 145#define ACPI_WAKE_PAGED_ENTRY 0xCD 146 147#define CPU_IA32_ENABLE_ENTRY 0xBF 148#define CPU_IA32_ENABLE_EXIT 0xBE 149#define ML_LOAD_DESC64_ENTRY 0xBD 150#define ML_LOAD_DESC64_GDT 0xBC 151#define ML_LOAD_DESC64_IDT 0xBB 152#define ML_LOAD_DESC64_LDT 0xBA 153#define ML_LOAD_DESC64_EXIT 0xB9 154#define CPU_IA32_DISABLE_ENTRY 0xB8 155#define CPU_IA32_DISABLE_EXIT 0xB7 156 157#ifndef ASSEMBLER 158inline static void 159_postcode_delay(uint32_t spincount) 160{ 161 asm volatile("1: \n\t" 162 " rep; nop; \n\t" 163 " decl %%eax; \n\t" 164 " jne 1b" 165 : : "a" (spincount)); 166} 167inline static void 168_postcode(uint8_t xx) 169{ 170 asm volatile("outb %0, %1" : : "a" (xx), "N" (POSTPORT)); 171} 172inline static void 173_postcode2(uint16_t xxxx) 174{ 175 asm volatile("outw %0, %1" : : "a" (xxxx), "N" (POSTPORT)); 176} 177#if DEBUG 178inline static void 179postcode(uint8_t xx) 180{ 181 _postcode(xx); 182#if POSTCODE_DELAY 183 _postcode_delay(SPINCOUNT); 184#endif 185} 186inline static void 187postcode2(uint8_t xxxx) 188{ 189 _postcode2(xxxx); 190#if POSTCODE_DELAY 191 _postcode_delay(SPINCOUNT); 192#endif 193} 194#else 195#define postcode(xx) do {} while(0) 196#define postcode2(xxxx) do {} while(0) 197#endif 198#endif 199 200#endif /* _I386_POSTCODE_H_ */ 201