source: mainline/genarch/src/acpi/matd.c@ 9149135

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9149135 was 9149135, checked in by Jakub Jermar <jakub@…>, 20 years ago

SMP cleanup continued.
Add nice type for IO APIC ID register.
Replace some magic numbers with more descriptive macros.

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 * Copyright (C) 2005 Jakub Jermar
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 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <arch/types.h>
30#include <typedefs.h>
31#include <genarch/acpi/acpi.h>
32#include <genarch/acpi/madt.h>
33#include <arch/smp/apic.h>
34#include <arch/smp/smp.h>
35#include <panic.h>
36#include <debug.h>
37#include <config.h>
38#include <print.h>
39#include <mm/heap.h>
40#include <memstr.h>
41#include <sort.h>
42
43struct acpi_madt *acpi_madt = NULL;
44
45#ifdef CONFIG_SMP
46
47/** Standard ISA IRQ map; can be overriden by Interrupt Source Override entries of MADT. */
48int isa_irq_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
49
50static void madt_l_apic_entry(struct madt_l_apic *la, __u32 index);
51static void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index);
52static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, __u32 index);
53static int madt_cmp(void * a, void * b);
54
55struct madt_l_apic *madt_l_apic_entries = NULL;
56struct madt_io_apic *madt_io_apic_entries = NULL;
57
58index_t madt_l_apic_entry_index = 0;
59index_t madt_io_apic_entry_index = 0;
60count_t madt_l_apic_entry_cnt = 0;
61count_t madt_io_apic_entry_cnt = 0;
62count_t cpu_count = 0;
63
64struct madt_apic_header * * madt_entries_index = NULL;
65int madt_entries_index_cnt = 0;
66
67char *entry[] = {
68 "L_APIC",
69 "IO_APIC",
70 "INTR_SRC_OVRD",
71 "NMI_SRC",
72 "L_APIC_NMI",
73 "L_APIC_ADDR_OVRD",
74 "IO_SAPIC",
75 "L_SAPIC",
76 "PLATFORM_INTR_SRC"
77};
78
79/*
80 * ACPI MADT Implementation of SMP configuration interface.
81 */
82static count_t madt_cpu_count(void);
83static bool madt_cpu_enabled(index_t i);
84static bool madt_cpu_bootstrap(index_t i);
85static __u8 madt_cpu_apic_id(index_t i);
86static int madt_irq_to_pin(int irq);
87
88struct smp_config_operations madt_config_operations = {
89 .cpu_count = madt_cpu_count,
90 .cpu_enabled = madt_cpu_enabled,
91 .cpu_bootstrap = madt_cpu_bootstrap,
92 .cpu_apic_id = madt_cpu_apic_id,
93 .irq_to_pin = madt_irq_to_pin
94};
95
96count_t madt_cpu_count(void)
97{
98 return madt_l_apic_entry_cnt;
99}
100
101bool madt_cpu_enabled(index_t i)
102{
103 ASSERT(i < madt_l_apic_entry_cnt);
104 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
105
106}
107
108bool madt_cpu_bootstrap(index_t i)
109{
110 ASSERT(i < madt_l_apic_entry_cnt);
111 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
112}
113
114__u8 madt_cpu_apic_id(index_t i)
115{
116 ASSERT(i < madt_l_apic_entry_cnt);
117 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
118}
119
120int madt_irq_to_pin(int irq)
121{
122 ASSERT(irq < sizeof(isa_irq_map)/sizeof(int));
123 return isa_irq_map[irq];
124}
125
126int madt_cmp(void * a, void * b)
127{
128 return
129 (((struct madt_apic_header *) a)->type > ((struct madt_apic_header *) b)->type) ?
130 1 :
131 ((((struct madt_apic_header *) a)->type < ((struct madt_apic_header *) b)->type) ? -1 : 0);
132}
133
134void acpi_madt_parse(void)
135{
136 struct madt_apic_header *end = (struct madt_apic_header *) (((__u8 *) acpi_madt) + acpi_madt->header.length);
137 struct madt_apic_header *h;
138
139 l_apic = (__u32 *) (__native) acpi_madt->l_apic_address;
140
141 /* calculate madt entries */
142 for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) h) + h->length)) {
143 madt_entries_index_cnt++;
144 }
145
146 /* create madt apic entries index array */
147 madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *));
148
149 __u32 index = 0;
150
151 for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) h) + h->length)) {
152 madt_entries_index[index++] = h;
153 }
154
155 /* Quicksort MADT index structure */
156 qsort(madt_entries_index, madt_entries_index_cnt, sizeof(__address), &madt_cmp);
157
158 /* Parse MADT entries */
159 for (index = 0; index < madt_entries_index_cnt - 1; index++) {
160 h = madt_entries_index[index];
161 switch (h->type) {
162 case MADT_L_APIC:
163 madt_l_apic_entry((struct madt_l_apic *) h, index);
164 break;
165 case MADT_IO_APIC:
166 madt_io_apic_entry((struct madt_io_apic *) h, index);
167 break;
168 case MADT_INTR_SRC_OVRD:
169 madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) h, index);
170 break;
171 case MADT_NMI_SRC:
172 case MADT_L_APIC_NMI:
173 case MADT_L_APIC_ADDR_OVRD:
174 case MADT_IO_SAPIC:
175 case MADT_L_SAPIC:
176 case MADT_PLATFORM_INTR_SRC:
177 printf("MADT: skipping %s entry (type=%d)\n", entry[h->type], h->type);
178 break;
179
180 default:
181 if (h->type >= MADT_RESERVED_SKIP_BEGIN && h->type <= MADT_RESERVED_SKIP_END) {
182 printf("MADT: skipping reserved entry (type=%d)\n", h->type);
183 }
184 if (h->type >= MADT_RESERVED_OEM_BEGIN) {
185 printf("MADT: skipping OEM entry (type=%d)\n", h->type);
186 }
187 break;
188 }
189
190
191 }
192
193
194 if (cpu_count)
195 config.cpu_count = cpu_count;
196}
197
198
199void madt_l_apic_entry(struct madt_l_apic *la, __u32 index)
200{
201 if (!madt_l_apic_entry_cnt++) {
202 madt_l_apic_entry_index = index;
203 }
204
205 if (!(la->flags & 0x1)) {
206 /* Processor is unusable, skip it. */
207 return;
208 }
209
210 cpu_count++;
211 apic_id_mask |= 1<<la->apic_id;
212}
213
214void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index)
215{
216 if (!madt_io_apic_entry_cnt++) {
217 /* remember index of the first io apic entry */
218 madt_io_apic_entry_index = index;
219 io_apic = (__u32 *) (__native) ioa->io_apic_address;
220 } else {
221 /* currently not supported */
222 return;
223 }
224}
225
226void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, __u32 index)
227{
228 ASSERT(override->source < sizeof(isa_irq_map)/sizeof(int));
229 printf("MADT: ignoring %s entry: bus=%d, source=%d, global_int=%d, flags=%W\n",
230 entry[override->header.type], override->bus, override->source,
231 override->global_int, override->flags);
232}
233
234#endif /* CONFIG_SMP */
Note: See TracBrowser for help on using the repository browser.