source: mainline/arch/ia32/src/acpi/madt.c@ d6dcdd2e

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

Cleanup.
Cancel fake in pm.c and replace it with LONG(0xdeadbeaf) in linker script. Still need some to find out why it must be there.
Remove comment saying, that mips is little-endian.

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