]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/ia64/acpica/madt.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / ia64 / acpica / madt.c
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$
27  */
28
29 #include <contrib/dev/acpica/acpi.h>
30 #include <contrib/dev/acpica/actables.h>
31
32 #include <machine/md_var.h>
33
34 extern u_int64_t ia64_lapic_address;
35
36 struct sapic *sapic_create(int, int, u_int64_t);
37
38 static void
39 print_entry(ACPI_SUBTABLE_HEADER *entry)
40 {
41
42         switch (entry->Type) {
43         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: {
44                 ACPI_MADT_INTERRUPT_OVERRIDE *iso =
45                     (ACPI_MADT_INTERRUPT_OVERRIDE *)entry;
46                 printf("\tInterrupt source override entry\n");
47                 printf("\t\tBus=%u, Source=%u, Irq=0x%x\n", iso->Bus,
48                     iso->SourceIrq, iso->GlobalIrq);
49                 break;
50         }
51
52         case ACPI_MADT_TYPE_IO_APIC:
53                 printf("\tI/O APIC entry\n");
54                 break;
55
56         case ACPI_MADT_TYPE_IO_SAPIC: {
57                 ACPI_MADT_IO_SAPIC *sapic = (ACPI_MADT_IO_SAPIC *)entry;
58                 printf("\tI/O SAPIC entry\n");
59                 printf("\t\tId=0x%x, InterruptBase=0x%x, Address=0x%lx\n",
60                     sapic->Id, sapic->GlobalIrqBase, sapic->Address);
61                 break;
62         }
63
64         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
65                 printf("\tLocal APIC NMI entry\n");
66                 break;
67
68         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: {
69                 ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic =
70                     (ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry;
71                 printf("\tLocal APIC override entry\n");
72                 printf("\t\tLocal APIC address=0x%jx\n", lapic->Address);
73                 break;
74         }
75
76         case ACPI_MADT_TYPE_LOCAL_SAPIC: {
77                 ACPI_MADT_LOCAL_SAPIC *sapic = (ACPI_MADT_LOCAL_SAPIC *)entry;
78                 printf("\tLocal SAPIC entry\n");
79                 printf("\t\tProcessorId=0x%x, Id=0x%x, Eid=0x%x",
80                     sapic->ProcessorId, sapic->Id, sapic->Eid);
81                 if (!(sapic->LapicFlags & ACPI_MADT_ENABLED))
82                         printf(" (disabled)");
83                 printf("\n");
84                 break;
85         }
86
87         case ACPI_MADT_TYPE_NMI_SOURCE:
88                 printf("\tNMI entry\n");
89                 break;
90
91         case ACPI_MADT_TYPE_INTERRUPT_SOURCE: {
92                 ACPI_MADT_INTERRUPT_SOURCE *pis =
93                     (ACPI_MADT_INTERRUPT_SOURCE *)entry;
94                 printf("\tPlatform interrupt entry\n");
95                 printf("\t\tPolarity=%u, TriggerMode=%u, Id=0x%x, "
96                     "Eid=0x%x, Vector=0x%x, Irq=%d\n",
97                     pis->IntiFlags & ACPI_MADT_POLARITY_MASK,
98                     (pis->IntiFlags & ACPI_MADT_TRIGGER_MASK) >> 2,
99                     pis->Id, pis->Eid, pis->IoSapicVector, pis->GlobalIrq);
100                 break;
101         }
102
103         case ACPI_MADT_TYPE_LOCAL_APIC:
104                 printf("\tLocal APIC entry\n");
105                 break;
106
107         default:
108                 printf("\tUnknown type %d entry\n", entry->Type);
109                 break;
110         }
111 }
112
113 void
114 ia64_probe_sapics(void)
115 {
116         ACPI_PHYSICAL_ADDRESS rsdp_ptr;
117         ACPI_SUBTABLE_HEADER *entry;
118         ACPI_TABLE_MADT *table;
119         ACPI_TABLE_RSDP *rsdp;
120         ACPI_TABLE_XSDT *xsdt;
121         char *end, *p;
122         int t, tables;
123
124         if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
125                 return;
126
127         rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr);
128         xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress);
129
130         tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) -
131             xsdt->TableOffsetEntry;
132
133         for (t = 0; t < tables; t++) {
134                 table = (ACPI_TABLE_MADT *)
135                     IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]);
136
137                 if (bootverbose)
138                         printf("Table '%c%c%c%c' at %p\n",
139                             table->Header.Signature[0],
140                             table->Header.Signature[1],
141                             table->Header.Signature[2],
142                             table->Header.Signature[3], table);
143
144                 if (strncmp(table->Header.Signature, ACPI_SIG_MADT,
145                     ACPI_NAME_SIZE) != 0 ||
146                     ACPI_FAILURE(AcpiTbChecksum((void *)table,
147                     table->Header.Length)))
148                         continue;
149
150                 /* Save the address of the processor interrupt block. */
151                 if (bootverbose)
152                         printf("\tLocal APIC address=0x%x\n", table->Address);
153                 ia64_lapic_address = table->Address;
154
155                 end = (char *)table + table->Header.Length;
156                 p = (char *)(table + 1);
157                 while (p < end) {
158                         entry = (ACPI_SUBTABLE_HEADER *)p;
159
160                         if (bootverbose)
161                                 print_entry(entry);
162
163                         switch (entry->Type) {
164                         case ACPI_MADT_TYPE_IO_SAPIC: {
165                                 ACPI_MADT_IO_SAPIC *sapic =
166                                     (ACPI_MADT_IO_SAPIC *)entry;
167                                 sapic_create(sapic->Id, sapic->GlobalIrqBase,
168                                     sapic->Address);
169                                 break;
170                         }
171
172                         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: {
173                                 ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic =
174                                     (ACPI_MADT_LOCAL_APIC_OVERRIDE *)entry;
175                                 ia64_lapic_address = lapic->Address;
176                                 break;
177                         }
178
179 #ifdef SMP
180                         case ACPI_MADT_TYPE_LOCAL_SAPIC: {
181                                 ACPI_MADT_LOCAL_SAPIC *sapic =
182                                     (ACPI_MADT_LOCAL_SAPIC *)entry;
183                                 if (sapic->LapicFlags & ACPI_MADT_ENABLED)
184                                         cpu_mp_add(sapic->ProcessorId,
185                                             sapic->Id, sapic->Eid);
186                                 break;
187                         }
188 #endif
189
190                         default:
191                                 break;
192                         }
193
194                         p += entry->Length;
195                 }
196         }
197 }
198
199 /*
200  * Count the number of local SAPIC entries in the APIC table. Every enabled
201  * entry corresponds to a processor.
202  */
203 int
204 ia64_count_cpus(void)
205 {
206         ACPI_PHYSICAL_ADDRESS rsdp_ptr;
207         ACPI_MADT_LOCAL_SAPIC *entry;
208         ACPI_TABLE_MADT *table;
209         ACPI_TABLE_RSDP *rsdp;
210         ACPI_TABLE_XSDT *xsdt;
211         char *end, *p;
212         int cpus, t, tables;
213
214         if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
215                 return (0);
216
217         rsdp = (ACPI_TABLE_RSDP *)IA64_PHYS_TO_RR7(rsdp_ptr);
218         xsdt = (ACPI_TABLE_XSDT *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress);
219
220         tables = (UINT64 *)((char *)xsdt + xsdt->Header.Length) -
221             xsdt->TableOffsetEntry;
222
223         cpus = 0;
224
225         for (t = 0; t < tables; t++) {
226                 table = (ACPI_TABLE_MADT *)
227                     IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[t]);
228
229                 if (strncmp(table->Header.Signature, ACPI_SIG_MADT,
230                     ACPI_NAME_SIZE) != 0 ||
231                     ACPI_FAILURE(AcpiTbChecksum((void *)table,
232                         table->Header.Length)))
233                         continue;
234
235                 end = (char *)table + table->Header.Length;
236                 p = (char *)(table + 1);
237                 while (p < end) {
238                         entry = (ACPI_MADT_LOCAL_SAPIC *)p;
239
240                         if (entry->Header.Type == ACPI_MADT_TYPE_LOCAL_SAPIC &&
241                             (entry->LapicFlags & ACPI_MADT_ENABLED))
242                                 cpus++;
243
244                         p += entry->Header.Length;
245                 }
246         }
247
248         return (cpus);
249 }