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; \ 571: \ 58 CPU_PAUSE(); \ 59 decl %eax; \ 60 jne 1b 61#define POSTCODE_AX \ 62 outw %ax,$(POSTPORT); \ 63 movl $(SPINCOUNT), %eax; \ 641: \ 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_IDLE_PTS_INIT 0xFB 130#define VSTART_PHYSMAP_INIT 0xFA 131#define VSTART_DESC_ALIAS_INIT 0xF9 132#define VSTART_SET_CR3 0xF8 133#define VSTART_CPU_DESC_INIT 0xF7 134#define VSTART_CPU_MODE_INIT 0xF6 135#define VSTART_EXIT 0xF5 136#define I386_INIT_ENTRY 0xF4 137#define CPU_INIT_D 0xF3 138#define PE_INIT_PLATFORM_D 0xF2 139 140#define SLAVE_STARTPROG_ENTRY 0xEF 141#define SLAVE_PSTART 0xEE 142#define I386_INIT_SLAVE 0xED 143 144#define PANIC_DOUBLE_FAULT 0xDF /* Double Fault exception */ 145#define PANIC_MACHINE_CHECK 0xDE /* Machine-Check */ 146#define MP_KDP_ENTER 0xDB /* Machine in kdp DeBugger */ 147#define PANIC_HLT 0xD1 /* Die an early death */ 148#define NO_64BIT 0x64 /* No 64-bit support yet */ 149 150#define ACPI_WAKE_START_ENTRY 0xCF 151#define ACPI_WAKE_PROT_ENTRY 0xCE 152#define ACPI_WAKE_PAGED_ENTRY 0xCD 153 154#define CPU_IA32_ENABLE_ENTRY 0xBF 155#define CPU_IA32_ENABLE_EXIT 0xBE 156#define ML_LOAD_DESC64_ENTRY 0xBD 157#define ML_LOAD_DESC64_GDT 0xBC 158#define ML_LOAD_DESC64_IDT 0xBB 159#define ML_LOAD_DESC64_LDT 0xBA 160#define ML_LOAD_DESC64_EXIT 0xB9 161#define CPU_IA32_DISABLE_ENTRY 0xB8 162#define CPU_IA32_DISABLE_EXIT 0xB7 163 164#ifndef ASSEMBLER 165inline static void 166_postcode_delay(uint32_t spincount) 167{ 168 asm volatile("1: \n\t" 169 " rep; nop; \n\t" 170 " decl %%eax; \n\t" 171 " jne 1b" 172 : : "a" (spincount)); 173} 174inline static void 175_postcode(uint8_t xx) 176{ 177 asm volatile("outb %0, %1" : : "a" (xx), "N" (POSTPORT)); 178} 179inline static void 180_postcode2(uint16_t xxxx) 181{ 182 asm volatile("outw %0, %1" : : "a" (xxxx), "N" (POSTPORT)); 183} 184#if DEBUG_POSTCODE 185inline static void 186postcode(uint8_t xx) 187{ 188 _postcode(xx); 189#if POSTCODE_DELAY 190 _postcode_delay(SPINCOUNT); 191#endif 192} 193inline static void 194postcode2(uint8_t xxxx) 195{ 196 _postcode2(xxxx); 197#if POSTCODE_DELAY 198 _postcode_delay(SPINCOUNT); 199#endif 200} 201#else 202#define postcode(xx) do {} while(0) 203#define postcode2(xxxx) do {} while(0) 204#endif 205#endif 206 207#endif /* _I386_POSTCODE_H_ */ 208