source: mainline/kernel/genarch/src/acpi/madt.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.8 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/** @addtogroup genarch
30 * @{
31 */
32/**
33 * @file
34 * @brief Multiple APIC Description Table (MADT) parsing.
35 */
36
37#include <assert.h>
38#include <typedefs.h>
39#include <genarch/acpi/acpi.h>
40#include <genarch/acpi/madt.h>
41#include <arch/smp/apic.h>
42#include <arch/smp/smp.h>
43#include <panic.h>
44#include <config.h>
45#include <log.h>
46#include <mm/slab.h>
47#include <gsort.h>
48
49struct acpi_madt *acpi_madt = NULL;
50
51#ifdef CONFIG_SMP
52
53/**
54 * Standard ISA IRQ map; can be overriden by
55 * Interrupt Source Override entries of MADT.
56 */
57static int isa_irq_map[] =
58 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
59
60struct madt_l_apic *madt_l_apic_entries = NULL;
61struct madt_io_apic *madt_io_apic_entries = NULL;
62
63static size_t madt_l_apic_entry_index = 0;
64static size_t madt_io_apic_entry_index = 0;
65static size_t madt_l_apic_entry_cnt = 0;
66static size_t madt_io_apic_entry_cnt = 0;
67
68static struct madt_apic_header **madt_entries_index = NULL;
69
70const char *entry[] = {
71 "L_APIC",
72 "IO_APIC",
73 "INTR_SRC_OVRD",
74 "NMI_SRC",
75 "L_APIC_NMI",
76 "L_APIC_ADDR_OVRD",
77 "IO_SAPIC",
78 "L_SAPIC",
79 "PLATFORM_INTR_SRC"
80};
81
82static uint8_t madt_cpu_apic_id(size_t i)
83{
84 assert(i < madt_l_apic_entry_cnt);
85
86 return ((struct madt_l_apic *)
87 madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
88}
89
90static bool madt_cpu_enabled(size_t i)
91{
92 assert(i < madt_l_apic_entry_cnt);
93
94 /*
95 * FIXME: The current local APIC driver limits usable
96 * CPU IDs to 8.
97 *
98 */
99 if (i > 7)
100 return false;
101
102 return ((struct madt_l_apic *)
103 madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
104}
105
106static bool madt_cpu_bootstrap(size_t i)
107{
108 assert(i < madt_l_apic_entry_cnt);
109
110 return ((struct madt_l_apic *)
111 madt_entries_index[madt_l_apic_entry_index + i])->apic_id ==
112 bsp_l_apic;
113}
114
115static int madt_irq_to_pin(unsigned int irq)
116{
117 if (irq >= sizeof(isa_irq_map) / sizeof(int))
118 return (int) irq;
119
120 return isa_irq_map[irq];
121}
122
123/** ACPI MADT Implementation of SMP configuration interface.
124 *
125 */
126struct smp_config_operations madt_config_operations = {
127 .cpu_enabled = madt_cpu_enabled,
128 .cpu_bootstrap = madt_cpu_bootstrap,
129 .cpu_apic_id = madt_cpu_apic_id,
130 .irq_to_pin = madt_irq_to_pin
131};
132
133static int madt_cmp(void *a, void *b, void *arg)
134{
135 uint8_t typea = (*((struct madt_apic_header **) a))->type;
136 uint8_t typeb = (*((struct madt_apic_header **) b))->type;
137
138 if (typea > typeb)
139 return 1;
140
141 if (typea < typeb)
142 return -1;
143
144 return 0;
145}
146
147static void madt_l_apic_entry(struct madt_l_apic *la, size_t i)
148{
149 if (madt_l_apic_entry_cnt == 0)
150 madt_l_apic_entry_index = i;
151
152 madt_l_apic_entry_cnt++;
153
154 if (!(la->flags & 0x1)) {
155 /* Processor is unusable, skip it. */
156 return;
157 }
158
159 apic_id_mask |= 1 << la->apic_id;
160}
161
162static void madt_io_apic_entry(struct madt_io_apic *ioa, size_t i)
163{
164 if (madt_io_apic_entry_cnt == 0) {
165 /* Remember index of the first io apic entry */
166 madt_io_apic_entry_index = i;
167 io_apic = (uint32_t *) (sysarg_t) ioa->io_apic_address;
168 } else {
169 /* Currently not supported */
170 }
171
172 madt_io_apic_entry_cnt++;
173}
174
175static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override,
176 size_t i)
177{
178 assert(override->source < sizeof(isa_irq_map) / sizeof(int));
179
180 isa_irq_map[override->source] = override->global_int;
181}
182
183void acpi_madt_parse(void)
184{
185 struct madt_apic_header *end = (struct madt_apic_header *)
186 (((uint8_t *) acpi_madt) + acpi_madt->header.length);
187 struct madt_apic_header *hdr;
188
189 l_apic = (uint32_t *) (sysarg_t) acpi_madt->l_apic_address;
190
191 /* Count MADT entries */
192 unsigned int madt_entries_index_cnt = 0;
193 for (hdr = acpi_madt->apic_header; hdr < end;
194 hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length))
195 madt_entries_index_cnt++;
196
197 /* Create MADT APIC entries index array */
198 madt_entries_index = (struct madt_apic_header **)
199 malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header *),
200 FRAME_ATOMIC);
201 if (!madt_entries_index)
202 panic("Memory allocation error.");
203
204 size_t i = 0;
205
206 for (hdr = acpi_madt->apic_header; hdr < end;
207 hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length)) {
208 madt_entries_index[i] = hdr;
209 i++;
210 }
211
212 /* Sort MADT index structure */
213 if (!gsort(madt_entries_index, madt_entries_index_cnt,
214 sizeof(struct madt_apic_header *), madt_cmp, NULL))
215 panic("Sorting error.");
216
217 /* Parse MADT entries */
218 for (i = 0; i < madt_entries_index_cnt; i++) {
219 hdr = madt_entries_index[i];
220
221 switch (hdr->type) {
222 case MADT_L_APIC:
223 madt_l_apic_entry((struct madt_l_apic *) hdr, i);
224 break;
225 case MADT_IO_APIC:
226 madt_io_apic_entry((struct madt_io_apic *) hdr, i);
227 break;
228 case MADT_INTR_SRC_OVRD:
229 madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) hdr, i);
230 break;
231 case MADT_NMI_SRC:
232 case MADT_L_APIC_NMI:
233 case MADT_L_APIC_ADDR_OVRD:
234 case MADT_IO_SAPIC:
235 case MADT_L_SAPIC:
236 case MADT_PLATFORM_INTR_SRC:
237 log(LF_ARCH, LVL_WARN,
238 "MADT: Skipping %s entry (type=%" PRIu8 ")",
239 entry[hdr->type], hdr->type);
240 break;
241 default:
242 if ((hdr->type >= MADT_RESERVED_SKIP_BEGIN)
243 && (hdr->type <= MADT_RESERVED_SKIP_END))
244 log(LF_ARCH, LVL_NOTE,
245 "MADT: Skipping reserved entry (type=%" PRIu8 ")",
246 hdr->type);
247
248 if (hdr->type >= MADT_RESERVED_OEM_BEGIN)
249 log(LF_ARCH, LVL_NOTE,
250 "MADT: Skipping OEM entry (type=%" PRIu8 ")",
251 hdr->type);
252
253 break;
254 }
255 }
256
257 if (madt_l_apic_entry_cnt > 0)
258 config.cpu_count = madt_l_apic_entry_cnt;
259}
260
261#endif /* CONFIG_SMP */
262
263/** @}
264 */
Note: See TracBrowser for help on using the repository browser.