source: mainline/genarch/src/acpi/matd.c@ 36a140b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 36a140b was 5f85c91, checked in by Martin Decky <martin@…>, 20 years ago

make configuration variables usage consistent

  • Property mode set to 100644
File size: 6.0 KB
RevLine 
[10a2e22]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
[ed0dd65]29#include <arch/types.h>
[232e3ec7]30#include <typedefs.h>
[e16e036a]31#include <genarch/acpi/acpi.h>
32#include <genarch/acpi/madt.h>
[ed0dd65]33#include <arch/smp/apic.h>
[232e3ec7]34#include <arch/smp/smp.h>
[6b7c36f]35#include <panic.h>
[232e3ec7]36#include <debug.h>
37#include <config.h>
[9c0a9b3]38#include <print.h>
[50a4e25]39#include <mm/heap.h>
40#include <memstr.h>
[8491c48]41#include <sort.h>
[10a2e22]42
43struct acpi_madt *acpi_madt = NULL;
[ed0dd65]44
[5f85c91]45#ifdef CONFIG_SMP
[ed0dd65]46
[50a4e25]47static void madt_l_apic_entry(struct madt_l_apic *la, __u32 index);
48static void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index);
[8491c48]49static int madt_cmp(void * a, void * b);
[6b7c36f]50
51struct madt_l_apic *madt_l_apic_entries = NULL;
52struct madt_io_apic *madt_io_apic_entries = NULL;
53
[74b2f5bf]54index_t madt_l_apic_entry_index = 0;
55index_t madt_io_apic_entry_index = 0;
56count_t madt_l_apic_entry_cnt = 0;
57count_t madt_io_apic_entry_cnt = 0;
58count_t cpu_count = 0;
[6b7c36f]59
[50a4e25]60struct madt_apic_header * * madt_entries_index = NULL;
61int madt_entries_index_cnt = 0;
62
[ed0dd65]63char *entry[] = {
64 "L_APIC",
65 "IO_APIC",
66 "INTR_SRC_OVRD",
67 "NMI_SRC",
68 "L_APIC_NMI",
69 "L_APIC_ADDR_OVRD",
70 "IO_SAPIC",
71 "L_SAPIC",
72 "PLATFORM_INTR_SRC"
73};
74
[232e3ec7]75/*
76 * ACPI MADT Implementation of SMP configuration interface.
77 */
78static count_t madt_cpu_count(void);
79static bool madt_cpu_enabled(index_t i);
80static bool madt_cpu_bootstrap(index_t i);
81static __u8 madt_cpu_apic_id(index_t i);
82
83struct smp_config_operations madt_config_operations = {
84 .cpu_count = madt_cpu_count,
85 .cpu_enabled = madt_cpu_enabled,
86 .cpu_bootstrap = madt_cpu_bootstrap,
87 .cpu_apic_id = madt_cpu_apic_id
88};
89
90static count_t madt_cpu_count(void)
91{
92 return madt_l_apic_entry_cnt;
93}
94
95static bool madt_cpu_enabled(index_t i)
96{
97 ASSERT(i < madt_l_apic_entry_cnt);
[50a4e25]98 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
99
[232e3ec7]100}
101
102static bool madt_cpu_bootstrap(index_t i)
103{
104 ASSERT(i < madt_l_apic_entry_cnt);
[50a4e25]105 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
[232e3ec7]106}
107
108static __u8 madt_cpu_apic_id(index_t i)
109{
110 ASSERT(i < madt_l_apic_entry_cnt);
[50a4e25]111 return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
[232e3ec7]112}
113
[8491c48]114int madt_cmp(void * a, void * b)
115{
[01e48c1]116 return
117 (((struct madt_apic_header *) a)->type > ((struct madt_apic_header *) b)->type) ?
118 1 :
119 ((((struct madt_apic_header *) a)->type < ((struct madt_apic_header *) b)->type) ? -1 : 0);
[8491c48]120}
121
[ed0dd65]122void acpi_madt_parse(void)
123{
124 struct madt_apic_header *end = (struct madt_apic_header *) (((__u8 *) acpi_madt) + acpi_madt->header.length);
[50a4e25]125 struct madt_apic_header *h;
[2cd073bd]126
127 l_apic = (__u32 *) (__native) acpi_madt->l_apic_address;
[50a4e25]128
129 /* calculate madt entries */
130 for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) h) + h->length)) {
131 madt_entries_index_cnt++;
132 }
133
134 /* create madt apic entries index array */
135 madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *));
136
137 __u32 index = 0;
[6b7c36f]138
[50a4e25]139 for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) h) + h->length)) {
140 madt_entries_index[index++] = h;
141 }
[ed0dd65]142
[8491c48]143 /* Quicksort MADT index structure */
144 qsort(madt_entries_index, madt_entries_index_cnt, sizeof(__address), &madt_cmp);
[50a4e25]145
146 /* Parse MADT entries */
147 for (index = 0; index < madt_entries_index_cnt - 1; index++) {
148 h = madt_entries_index[index];
[ed0dd65]149 switch (h->type) {
150 case MADT_L_APIC:
[50a4e25]151 madt_l_apic_entry((struct madt_l_apic *) h, index);
[6b7c36f]152 break;
[ed0dd65]153 case MADT_IO_APIC:
[50a4e25]154 madt_io_apic_entry((struct madt_io_apic *) h, index);
[6b7c36f]155 break;
[ed0dd65]156 case MADT_INTR_SRC_OVRD:
157 case MADT_NMI_SRC:
158 case MADT_L_APIC_NMI:
159 case MADT_L_APIC_ADDR_OVRD:
160 case MADT_IO_SAPIC:
161 case MADT_L_SAPIC:
162 case MADT_PLATFORM_INTR_SRC:
163 printf("MADT: skipping %s entry (type=%d)\n", entry[h->type], h->type);
164 break;
165
166 default:
167 if (h->type >= MADT_RESERVED_SKIP_BEGIN && h->type <= MADT_RESERVED_SKIP_END) {
168 printf("MADT: skipping reserved entry (type=%d)\n", h->type);
169 }
170 if (h->type >= MADT_RESERVED_OEM_BEGIN) {
171 printf("MADT: skipping OEM entry (type=%d)\n", h->type);
172 }
173 break;
174 }
[50a4e25]175
176
[ed0dd65]177 }
[50a4e25]178
[ed0dd65]179
[74b2f5bf]180 if (cpu_count)
181 config.cpu_count = cpu_count;
[ed0dd65]182}
[6b7c36f]183
184
[50a4e25]185void madt_l_apic_entry(struct madt_l_apic *la, __u32 index)
186{
187 if (!madt_l_apic_entry_cnt++) {
188 madt_l_apic_entry_index = index;
189 }
[6b7c36f]190
191 if (!(la->flags & 0x1)) {
192 /* Processor is unusable, skip it. */
193 return;
194 }
[74b2f5bf]195
196 cpu_count++;
[6b7c36f]197 apic_id_mask |= 1<<la->apic_id;
198}
199
[50a4e25]200void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index)
[6b7c36f]201{
202 if (!madt_io_apic_entry_cnt++) {
[50a4e25]203 /* remember index of the first io apic entry */
204 madt_io_apic_entry_index = index;
[ab08b42]205 io_apic = (__u32 *) (__native) ioa->io_apic_address;
[50a4e25]206 } else {
[6b7c36f]207 /* currently not supported */
208 return;
209 }
210}
211
[ed0dd65]212
[5f85c91]213#endif /* CONFIG_SMP */
Note: See TracBrowser for help on using the repository browser.