1 1.6 mrg /* $NetBSD: madt.c,v 1.6 2023/07/13 18:43:34 mrg Exp $ */ 2 1.1 kiyohara /*- 3 1.1 kiyohara * Copyright (c) 2001 Doug Rabson 4 1.1 kiyohara * All rights reserved. 5 1.1 kiyohara * 6 1.1 kiyohara * Redistribution and use in source and binary forms, with or without 7 1.1 kiyohara * modification, are permitted provided that the following conditions 8 1.1 kiyohara * are met: 9 1.1 kiyohara * 1. Redistributions of source code must retain the above copyright 10 1.1 kiyohara * notice, this list of conditions and the following disclaimer. 11 1.1 kiyohara * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 kiyohara * notice, this list of conditions and the following disclaimer in the 13 1.1 kiyohara * documentation and/or other materials provided with the distribution. 14 1.1 kiyohara * 15 1.1 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 1.1 kiyohara * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 1.1 kiyohara * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 1.1 kiyohara * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 1.1 kiyohara * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 1.1 kiyohara * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 1.1 kiyohara * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 kiyohara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 1.1 kiyohara * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 kiyohara * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 kiyohara * SUCH DAMAGE. 26 1.1 kiyohara * 27 1.1 kiyohara * $FreeBSD: src/sys/ia64/acpica/madt.c,v 1.20 2007/03/22 18:16:42 jkim Exp $ 28 1.1 kiyohara */ 29 1.1 kiyohara 30 1.1 kiyohara #include <sys/param.h> 31 1.1 kiyohara #include <sys/reboot.h> 32 1.6 mrg #include <sys/mutex.h> 33 1.1 kiyohara 34 1.1 kiyohara #include <machine/md_var.h> 35 1.3 kiyohara #include <machine/sapicvar.h> 36 1.1 kiyohara 37 1.1 kiyohara #include <dev/acpi/acpica.h> 38 1.1 kiyohara #include <dev/acpi/acpivar.h> 39 1.2 skrll #include <actables.h> 40 1.1 kiyohara 41 1.1 kiyohara 42 1.1 kiyohara extern uint64_t ia64_lapic_address; 43 1.1 kiyohara 44 1.1 kiyohara static void 45 1.1 kiyohara print_entry(ACPI_SUBTABLE_HEADER *entry) 46 1.1 kiyohara { 47 1.1 kiyohara 48 1.1 kiyohara switch (entry->Type) { 49 1.1 kiyohara case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: { 50 1.1 kiyohara ACPI_MADT_INTERRUPT_OVERRIDE *iso = 51 1.1 kiyohara (ACPI_MADT_INTERRUPT_OVERRIDE *)entry; 52 1.1 kiyohara printf("\tInterrupt source override entry\n"); 53 1.1 kiyohara printf("\t\tBus=%u, Source=%u, Irq=0x%x\n", iso->Bus, 54 1.1 kiyohara iso->SourceIrq, iso->GlobalIrq); 55 1.1 kiyohara break; 56 1.1 kiyohara } 57 1.1 kiyohara 58 1.1 kiyohara case ACPI_MADT_TYPE_IO_APIC: 59 1.1 kiyohara printf("\tI/O APIC entry\n"); 60 1.1 kiyohara break; 61 1.1 kiyohara 62 1.1 kiyohara case ACPI_MADT_TYPE_IO_SAPIC: { 63 1.1 kiyohara ACPI_MADT_IO_SAPIC *sapic = (ACPI_MADT_IO_SAPIC *)entry; 64 1.1 kiyohara printf("\tI/O SAPIC entry\n"); 65 1.1 kiyohara printf("\t\tId=0x%x, InterruptBase=0x%x, Address=0x%lx\n", 66 1.1 kiyohara sapic->Id, sapic->GlobalIrqBase, sapic->Address); 67 1.1 kiyohara break; 68 1.1 kiyohara } 69 1.1 kiyohara 70 1.1 kiyohara case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 71 1.1 kiyohara printf("\tLocal APIC NMI entry\n"); 72 1.1 kiyohara break; 73 1.1 kiyohara 74 1.1 kiyohara case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: { 75 1.1 kiyohara ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic = 76 1.1 kiyohara (ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry; 77 1.1 kiyohara printf("\tLocal APIC override entry\n"); 78 1.1 kiyohara printf("\t\tLocal APIC address=0x%jx\n", lapic->Address); 79 1.1 kiyohara break; 80 1.1 kiyohara } 81 1.1 kiyohara 82 1.1 kiyohara case ACPI_MADT_TYPE_LOCAL_SAPIC: { 83 1.1 kiyohara ACPI_MADT_LOCAL_SAPIC *sapic = (ACPI_MADT_LOCAL_SAPIC *)entry; 84 1.1 kiyohara printf("\tLocal SAPIC entry\n"); 85 1.1 kiyohara printf("\t\tProcessorId=0x%x, Id=0x%x, Eid=0x%x", 86 1.1 kiyohara sapic->ProcessorId, sapic->Id, sapic->Eid); 87 1.1 kiyohara if (!(sapic->LapicFlags & ACPI_MADT_ENABLED)) 88 1.1 kiyohara printf(" (disabled)"); 89 1.1 kiyohara printf("\n"); 90 1.1 kiyohara break; 91 1.1 kiyohara } 92 1.1 kiyohara 93 1.1 kiyohara case ACPI_MADT_TYPE_NMI_SOURCE: 94 1.1 kiyohara printf("\tNMI entry\n"); 95 1.1 kiyohara break; 96 1.1 kiyohara 97 1.1 kiyohara case ACPI_MADT_TYPE_INTERRUPT_SOURCE: { 98 1.1 kiyohara ACPI_MADT_INTERRUPT_SOURCE *pis = 99 1.1 kiyohara (ACPI_MADT_INTERRUPT_SOURCE *)entry; 100 1.1 kiyohara printf("\tPlatform interrupt entry\n"); 101 1.1 kiyohara printf("\t\tPolarity=%u, TriggerMode=%u, Id=0x%x, " 102 1.1 kiyohara "Eid=0x%x, Vector=0x%x, Irq=%d\n", 103 1.1 kiyohara pis->IntiFlags & ACPI_MADT_POLARITY_MASK, 104 1.1 kiyohara (pis->IntiFlags & ACPI_MADT_TRIGGER_MASK) >> 2, 105 1.1 kiyohara pis->Id, pis->Eid, pis->IoSapicVector, pis->GlobalIrq); 106 1.1 kiyohara break; 107 1.1 kiyohara } 108 1.1 kiyohara 109 1.1 kiyohara case ACPI_MADT_TYPE_LOCAL_APIC: 110 1.1 kiyohara printf("\tLocal APIC entry\n"); 111 1.1 kiyohara break; 112 1.1 kiyohara 113 1.1 kiyohara default: 114 1.1 kiyohara printf("\tUnknown type %d entry\n", entry->Type); 115 1.1 kiyohara break; 116 1.1 kiyohara } 117 1.1 kiyohara } 118 1.1 kiyohara 119 1.1 kiyohara void 120 1.1 kiyohara ia64_probe_sapics(void) 121 1.1 kiyohara { 122 1.1 kiyohara ACPI_PHYSICAL_ADDRESS rsdp_ptr; 123 1.1 kiyohara ACPI_SUBTABLE_HEADER *entry; 124 1.1 kiyohara ACPI_TABLE_MADT *table; 125 1.1 kiyohara ACPI_TABLE_RSDP *rsdp; 126 1.1 kiyohara ACPI_TABLE_XSDT *xsdt; 127 1.1 kiyohara char *end, *p; 128 1.1 kiyohara int t, tables; 129 1.1 kiyohara extern int has_i8259; 130 1.1 kiyohara 131 1.1 kiyohara if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) 132 1.1 kiyohara return; 133 1.1 kiyohara 134 1.1 kiyohara rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr); 135 1.1 kiyohara xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress); 136 1.1 kiyohara 137 1.1 kiyohara tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) - 138 1.1 kiyohara xsdt->TableOffsetEntry; 139 1.1 kiyohara 140 1.1 kiyohara for (t = 0; t < tables; t++) { 141 1.1 kiyohara table = (ACPI_TABLE_MADT *) 142 1.1 kiyohara IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]); 143 1.1 kiyohara 144 1.1 kiyohara if (bootverbose) 145 1.1 kiyohara printf("Table '%c%c%c%c' at %p\n", 146 1.1 kiyohara table->Header.Signature[0], 147 1.1 kiyohara table->Header.Signature[1], 148 1.1 kiyohara table->Header.Signature[2], 149 1.1 kiyohara table->Header.Signature[3], table); 150 1.1 kiyohara 151 1.1 kiyohara if (strncmp(table->Header.Signature, ACPI_SIG_MADT, 152 1.4 scole ACPI_NAMESEG_SIZE) != 0 || 153 1.5 gutterid ACPI_FAILURE(AcpiUtChecksum((void *)table, 154 1.1 kiyohara table->Header.Length))) 155 1.1 kiyohara continue; 156 1.1 kiyohara 157 1.1 kiyohara /* Save the address of the processor interrupt block. */ 158 1.1 kiyohara if (bootverbose) 159 1.1 kiyohara printf("\tLocal APIC address=0x%x\n", table->Address); 160 1.1 kiyohara ia64_lapic_address = table->Address; 161 1.1 kiyohara 162 1.1 kiyohara if (table->Flags & ACPI_MADT_PCAT_COMPAT) 163 1.1 kiyohara has_i8259 = 1; 164 1.1 kiyohara 165 1.1 kiyohara end = (char *)table + table->Header.Length; 166 1.1 kiyohara p = (char *)(table + 1); 167 1.1 kiyohara while (p < end) { 168 1.1 kiyohara entry = (ACPI_SUBTABLE_HEADER *)p; 169 1.1 kiyohara 170 1.1 kiyohara if (bootverbose) 171 1.1 kiyohara print_entry(entry); 172 1.1 kiyohara 173 1.1 kiyohara switch (entry->Type) { 174 1.1 kiyohara case ACPI_MADT_TYPE_IO_SAPIC: 175 1.1 kiyohara { 176 1.1 kiyohara ACPI_MADT_IO_SAPIC *sapic = 177 1.1 kiyohara (ACPI_MADT_IO_SAPIC *)entry; 178 1.1 kiyohara 179 1.1 kiyohara sapic_create(sapic->Id, sapic->GlobalIrqBase, 180 1.1 kiyohara sapic->Address); 181 1.1 kiyohara break; 182 1.1 kiyohara } 183 1.1 kiyohara 184 1.1 kiyohara case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 185 1.1 kiyohara { 186 1.1 kiyohara ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic = 187 1.1 kiyohara (ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry; 188 1.1 kiyohara 189 1.1 kiyohara ia64_lapic_address = lapic->Address; 190 1.1 kiyohara break; 191 1.1 kiyohara } 192 1.1 kiyohara 193 1.1 kiyohara #ifdef MULTIPROCESSOR 194 1.1 kiyohara case ACPI_MADT_TYPE_LOCAL_SAPIC: 195 1.1 kiyohara { 196 1.1 kiyohara ACPI_MADT_LOCAL_SAPIC *sapic = 197 1.1 kiyohara (ACPI_MADT_LOCAL_SAPIC *)entry; 198 1.1 kiyohara 199 1.1 kiyohara if (sapic->LapicFlags & ACPI_MADT_ENABLED) 200 1.1 kiyohara cpu_mp_add(sapic->ProcessorId, 201 1.1 kiyohara sapic->Id, sapic->Eid); 202 1.1 kiyohara break; 203 1.1 kiyohara } 204 1.1 kiyohara #endif 205 1.1 kiyohara 206 1.1 kiyohara default: 207 1.1 kiyohara break; 208 1.1 kiyohara } 209 1.1 kiyohara 210 1.1 kiyohara p += entry->Length; 211 1.1 kiyohara } 212 1.1 kiyohara } 213 1.1 kiyohara } 214 1.1 kiyohara 215 1.1 kiyohara /* 216 1.1 kiyohara * Count the number of local SAPIC entries in the APIC table. Every enabled 217 1.1 kiyohara * entry corresponds to a processor. 218 1.1 kiyohara */ 219 1.1 kiyohara int 220 1.1 kiyohara ia64_count_cpus(void) 221 1.1 kiyohara { 222 1.1 kiyohara ACPI_PHYSICAL_ADDRESS rsdp_ptr; 223 1.1 kiyohara ACPI_MADT_LOCAL_SAPIC *entry; 224 1.1 kiyohara ACPI_TABLE_MADT *table; 225 1.1 kiyohara ACPI_TABLE_RSDP *rsdp; 226 1.1 kiyohara ACPI_TABLE_XSDT *xsdt; 227 1.1 kiyohara char *end, *p; 228 1.1 kiyohara int cpus, t, tables; 229 1.1 kiyohara 230 1.1 kiyohara if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) 231 1.1 kiyohara return 0; 232 1.1 kiyohara 233 1.1 kiyohara rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr); 234 1.1 kiyohara xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress); 235 1.1 kiyohara 236 1.1 kiyohara tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) - 237 1.1 kiyohara xsdt->TableOffsetEntry; 238 1.1 kiyohara 239 1.1 kiyohara cpus = 0; 240 1.1 kiyohara 241 1.1 kiyohara for (t = 0; t < tables; t++) { 242 1.1 kiyohara table = (ACPI_TABLE_MADT *) 243 1.1 kiyohara IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]); 244 1.1 kiyohara 245 1.1 kiyohara if (strncmp(table->Header.Signature, ACPI_SIG_MADT, 246 1.4 scole ACPI_NAMESEG_SIZE) != 0 || 247 1.5 gutterid ACPI_FAILURE(AcpiUtChecksum((void *)table, 248 1.1 kiyohara table->Header.Length))) 249 1.1 kiyohara continue; 250 1.1 kiyohara 251 1.1 kiyohara end = (char *)table + table->Header.Length; 252 1.1 kiyohara p = (char *)(table + 1); 253 1.1 kiyohara while (p < end) { 254 1.1 kiyohara entry = (ACPI_MADT_LOCAL_SAPIC *)p; 255 1.1 kiyohara 256 1.1 kiyohara if (entry->Header.Type == ACPI_MADT_TYPE_LOCAL_SAPIC && 257 1.1 kiyohara (entry->LapicFlags & ACPI_MADT_ENABLED)) 258 1.1 kiyohara cpus++; 259 1.1 kiyohara 260 1.1 kiyohara p += entry->Header.Length; 261 1.1 kiyohara } 262 1.1 kiyohara } 263 1.1 kiyohara 264 1.1 kiyohara return cpus; 265 1.1 kiyohara } 266