madt.c revision 85399
1/*- 2 * Copyright (c) 2001 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/ia64/acpica/madt.c 85399 2001-10-24 04:48:05Z marcel $ 27 */ 28 29#include "acpi.h" 30 31#pragma pack(1) 32 33#define APIC_INTERRUPT_SOURCE_OVERRIDE 2 34#define APIC_NMI 3 35#define APIC_LOCAL_APIC_NMI 4 36#define APIC_LOCAL_APIC_OVERRIDE 5 37#define APIC_IO_SAPIC 6 38#define APIC_LOCAL_SAPIC 7 39#define APIC_PLATFORM_INTERRUPT 8 40 41 42typedef struct /* Interrupt Source Override */ 43{ 44 APIC_HEADER header; 45 UINT8 Bus; 46 UINT8 Source; 47 UINT32 GlobalSystemInterrupt; 48 UINT16 Flags; 49} INTERRUPT_SOURCE_OVERRIDE; 50 51typedef struct /* IO SAPIC */ 52{ 53 APIC_HEADER header; 54 UINT8 IoSapicId; /* I/O SAPIC ID */ 55 UINT8 Reserved; /* reserved - must be zero */ 56 UINT32 Vector; /* interrupt vector index where INTI 57 * lines start */ 58 UINT64 IoSapicAddress; /* SAPIC's physical address */ 59 60} IO_SAPIC; 61 62 63typedef struct /* LOCAL SAPIC */ 64{ 65 APIC_HEADER header; 66 UINT16 ProcessorId; /* ACPI processor id */ 67 UINT16 ProcessorEnabled: 1; /* Processor is usable if set */ 68 UINT16 Reserved1 : 15; 69 UINT8 LocalSapicId; /* processor's local SAPIC id */ 70 UINT8 LocalSapicEid; /* processor's local SAPIC eid */ 71 72} LOCAL_SAPIC; 73 74 75typedef struct /* PLATFORM INTERRUPT SOURCE */ 76{ 77 APIC_HEADER header; 78 UINT16 Polarity : 2; /* Polarity of input signal */ 79 UINT16 TriggerMode: 2; /* Trigger mode of input signal */ 80 UINT16 Reserved1 : 12; 81 UINT8 InterruptType; /* 1-PMI, 2-INIT, 3-Error */ 82 UINT8 ProcessorId; /* Processor ID of destination */ 83 UINT8 ProcessorEid; /* Processor EID of destination */ 84 UINT8 IoSapicVector; /* Value for redirection table */ 85 UINT32 GlobalSystemInterrupt; /* Global System Interrupt */ 86 UINT32 Reserved2; 87 88} PLATFORM_INTERRUPT_SOURCE; 89 90 91#pragma pack() 92 93static void 94parse_local_apic(PROCESSOR_APIC *apic) 95{ 96 if (bootverbose) { 97 printf("\t\tProcessorId=0x%x, APIC Id=0x%x", 98 apic->ProcessorApicId, apic->LocalApicId); 99 if (!apic->ProcessorEnabled) 100 printf(" (disabled)"); 101 printf("\n"); 102 } 103} 104 105static void 106parse_io_apic(IO_APIC *apic) 107{ 108 if (bootverbose) 109 printf("\t\tId=0x%x, Vector=0x%x, Address=0x%lx\n", 110 apic->IoApicId, apic->Vector, apic->IoApicAddress); 111} 112 113static void 114parse_interrupt_override(INTERRUPT_SOURCE_OVERRIDE *override) 115{ 116 if (bootverbose) 117 printf("\t\tBus=%d, Source=%d, Irq=0x%x\n", 118 override->Bus, 119 override->Source, 120 override->GlobalSystemInterrupt); 121} 122 123static void 124parse_io_sapic(IO_SAPIC *sapic) 125{ 126 if (bootverbose) 127 printf("\t\tId=0x%x, Vector=0x%x, Address=0x%lx\n", 128 sapic->IoSapicId, 129 sapic->Vector, 130 sapic->IoSapicAddress); 131 sapic_create(sapic->IoSapicId, sapic->Vector, sapic->IoSapicAddress); 132} 133 134static void 135parse_local_sapic(LOCAL_SAPIC *sapic) 136{ 137 if (bootverbose) { 138 printf("\t\tProcessorId=0x%x, Id=0x%x, Eid=0x%x", 139 sapic->ProcessorId, sapic->LocalSapicId, 140 sapic->LocalSapicEid); 141 if (!sapic->ProcessorEnabled) 142 printf(" (disabled)"); 143 printf("\n"); 144 } 145} 146 147static void 148parse_platform_interrupt(PLATFORM_INTERRUPT_SOURCE *source) 149{ 150 if (bootverbose) 151 printf("\t\tPolarity=%d, TriggerMode=%d, Id=0x%x, " 152 "Eid=0x%x, Vector=0x%x, Irq=%d\n", 153 source->Polarity, 154 source->TriggerMode, 155 source->ProcessorId, 156 source->ProcessorEid, 157 source->IoSapicVector, 158 source->GlobalSystemInterrupt); 159} 160 161static void 162parse_madt(APIC_TABLE *madt) 163{ 164 char *p, *end; 165 166 /* 167 * MADT header is followed by a number of variable length 168 * structures. 169 */ 170 end = (char *) madt + madt->header.Length; 171 for (p = (char *) (madt + 1); p < end; ) { 172 APIC_HEADER *head = (APIC_HEADER *) p; 173 174 if (bootverbose) 175 printf("\t"); 176 switch (head->Type) { 177 case APIC_PROC: 178 if (bootverbose) 179 printf("Local APIC entry\n"); 180 parse_local_apic((PROCESSOR_APIC *) head); 181 break; 182 183 case APIC_IO: 184 if (bootverbose) 185 printf("I/O APIC entry\n"); 186 parse_io_apic((IO_APIC *) head); 187 break; 188 189 case APIC_INTERRUPT_SOURCE_OVERRIDE: 190 if (bootverbose) 191 printf("Interrupt source override entry\n"); 192 parse_interrupt_override 193 ((INTERRUPT_SOURCE_OVERRIDE *) head); 194 break; 195 196 case APIC_NMI: 197 if (bootverbose) 198 printf("NMI entry\n"); 199 break; 200 201 case APIC_LOCAL_APIC_NMI: 202 if (bootverbose) 203 printf("Local APIC NMI entry\n"); 204 break; 205 206 case APIC_LOCAL_APIC_OVERRIDE: 207 if (bootverbose) 208 printf("Local APIC override entry\n"); 209 break; 210 211 case APIC_IO_SAPIC: 212 if (bootverbose) 213 printf("I/O SAPIC entry\n"); 214 parse_io_sapic((IO_SAPIC *) head); 215 break; 216 217 case APIC_LOCAL_SAPIC: 218 if (bootverbose) 219 printf("Local SAPIC entry\n"); 220 parse_local_sapic((LOCAL_SAPIC *) head); 221 break; 222 223 case APIC_PLATFORM_INTERRUPT: 224 if (bootverbose) 225 printf("Platform interrupt entry\n"); 226 parse_platform_interrupt 227 ((PLATFORM_INTERRUPT_SOURCE *) head); 228 break; 229 230 default: 231 if (bootverbose) 232 printf("Unknown type %d entry\n", head->Type); 233 break; 234 } 235 236 p = p + head->Length; 237 } 238} 239 240void 241ia64_parse_xsdt(XSDT_DESCRIPTOR *xsdt) 242{ 243 int i, count; 244 ACPI_TABLE_HEADER *table; 245 246 /* 247 * First find the MADT. 248 */ 249 count = (UINT64 *) ((char *) xsdt + xsdt->Header.Length) 250 - &xsdt->TableOffsetEntry[0]; 251 for (i = 0; i < count; i++) { 252 table = (ACPI_TABLE_HEADER *) 253 IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[i]); 254 if (bootverbose) 255 printf("Table '%c%c%c%c' at %p\n", 256 table->Signature[0], 257 table->Signature[1], 258 table->Signature[2], 259 table->Signature[3], 260 table); 261 if (!strncmp(table->Signature, APIC_SIG, 4)) { 262 parse_madt((APIC_TABLE *) table); 263 } 264 } 265} 266