Rev 2462 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2462 | Rev 2701 | ||
|---|---|---|---|
| Line 1... | Line 1... | ||
| 1 | /* |
1 | /* |
| 2 | * Copyright (c) 2001-2005 Jakub Jermar |
2 | * Copyright (c) 2008 Jakub Jermar |
| 3 | * All rights reserved. |
3 | * All rights reserved. |
| 4 | * |
4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
7 | * are met: |
| Line 147... | Line 147... | ||
| 147 | uint8_t *ext = base + ct->base_table_length; |
147 | uint8_t *ext = base + ct->base_table_length; |
| 148 | uint8_t sum; |
148 | uint8_t sum; |
| 149 | int i; |
149 | int i; |
| 150 | 150 | ||
| 151 | /* count the checksum for the base table */ |
151 | /* count the checksum for the base table */ |
| 152 | for (i=0,sum=0; i < ct->base_table_length; i++) |
152 | for (i = 0,sum = 0; i < ct->base_table_length; i++) |
| 153 | sum = (uint8_t) (sum + base[i]); |
153 | sum = (uint8_t) (sum + base[i]); |
| 154 | 154 | ||
| 155 | if (sum) |
155 | if (sum) |
| 156 | return 0; |
156 | return 0; |
| 157 | 157 | ||
| 158 | /* count the checksum for the extended table */ |
158 | /* count the checksum for the extended table */ |
| 159 | for (i=0,sum=0; i < ct->ext_table_length; i++) |
159 | for (i = 0, sum = 0; i < ct->ext_table_length; i++) |
| 160 | sum = (uint8_t) (sum + ext[i]); |
160 | sum = (uint8_t) (sum + ext[i]); |
| 161 | 161 | ||
| 162 | return sum == ct->ext_table_checksum; |
162 | return sum == ct->ext_table_checksum; |
| 163 | } |
163 | } |
| 164 | 164 | ||
| Line 176... | Line 176... | ||
| 176 | */ |
176 | */ |
| 177 | 177 | ||
| 178 | addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); |
178 | addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); |
| 179 | for (i = 0; i < 2; i++) { |
179 | for (i = 0; i < 2; i++) { |
| 180 | for (j = 0; j < length[i]; j += 16) { |
180 | for (j = 0; j < length[i]; j += 16) { |
| - | 181 | if (*((uint32_t *) &addr[i][j]) == |
|
| 181 | if (*((uint32_t *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) { |
182 | FS_SIGNATURE && mps_fs_check(&addr[i][j])) { |
| 182 | fs = (struct mps_fs *) &addr[i][j]; |
183 | fs = (struct mps_fs *) &addr[i][j]; |
| 183 | goto fs_found; |
184 | goto fs_found; |
| 184 | } |
185 | } |
| 185 | } |
186 | } |
| 186 | } |
187 | } |
| Line 225... | Line 226... | ||
| 225 | 226 | ||
| 226 | l_apic = (uint32_t *)(uintptr_t)ct->l_apic; |
227 | l_apic = (uint32_t *)(uintptr_t)ct->l_apic; |
| 227 | 228 | ||
| 228 | cnt = 0; |
229 | cnt = 0; |
| 229 | cur = &ct->base_table[0]; |
230 | cur = &ct->base_table[0]; |
| 230 | for (i=0; i < ct->entry_count; i++) { |
231 | for (i = 0; i < ct->entry_count; i++) { |
| 231 | switch (*cur) { |
232 | switch (*cur) { |
| 232 | /* Processor entry */ |
233 | /* Processor entry */ |
| 233 | case 0: |
234 | case 0: |
| 234 | processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur; |
235 | processor_entries = processor_entries ? |
| - | 236 | processor_entries : |
|
| - | 237 | (struct __processor_entry *) cur; |
|
| 235 | processor_entry_cnt++; |
238 | processor_entry_cnt++; |
| 236 | cnt += ct_processor_entry((struct __processor_entry *) cur); |
239 | cnt += ct_processor_entry((struct __processor_entry *) |
| - | 240 | cur); |
|
| 237 | cur += 20; |
241 | cur += 20; |
| 238 | break; |
242 | break; |
| 239 | 243 | ||
| 240 | /* Bus entry */ |
244 | /* Bus entry */ |
| 241 | case 1: |
245 | case 1: |
| - | 246 | bus_entries = bus_entries ? |
|
| 242 | bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur; |
247 | bus_entries : (struct __bus_entry *) cur; |
| 243 | bus_entry_cnt++; |
248 | bus_entry_cnt++; |
| 244 | ct_bus_entry((struct __bus_entry *) cur); |
249 | ct_bus_entry((struct __bus_entry *) cur); |
| 245 | cur += 8; |
250 | cur += 8; |
| 246 | break; |
251 | break; |
| 247 | 252 | ||
| 248 | /* I/O Apic */ |
253 | /* I/O Apic */ |
| 249 | case 2: |
254 | case 2: |
| - | 255 | io_apic_entries = io_apic_entries ? |
|
| 250 | io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur; |
256 | io_apic_entries : (struct __io_apic_entry *) cur; |
| 251 | io_apic_entry_cnt++; |
257 | io_apic_entry_cnt++; |
| 252 | ct_io_apic_entry((struct __io_apic_entry *) cur); |
258 | ct_io_apic_entry((struct __io_apic_entry *) cur); |
| 253 | cur += 8; |
259 | cur += 8; |
| 254 | break; |
260 | break; |
| 255 | 261 | ||
| 256 | /* I/O Interrupt Assignment */ |
262 | /* I/O Interrupt Assignment */ |
| 257 | case 3: |
263 | case 3: |
| - | 264 | io_intr_entries = io_intr_entries ? |
|
| 258 | io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur; |
265 | io_intr_entries : (struct __io_intr_entry *) cur; |
| 259 | io_intr_entry_cnt++; |
266 | io_intr_entry_cnt++; |
| 260 | ct_io_intr_entry((struct __io_intr_entry *) cur); |
267 | ct_io_intr_entry((struct __io_intr_entry *) cur); |
| 261 | cur += 8; |
268 | cur += 8; |
| 262 | break; |
269 | break; |
| 263 | 270 | ||
| 264 | /* Local Interrupt Assignment */ |
271 | /* Local Interrupt Assignment */ |
| 265 | case 4: |
272 | case 4: |
| - | 273 | l_intr_entries = l_intr_entries ? |
|
| 266 | l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur; |
274 | l_intr_entries : (struct __l_intr_entry *) cur; |
| 267 | l_intr_entry_cnt++; |
275 | l_intr_entry_cnt++; |
| 268 | ct_l_intr_entry((struct __l_intr_entry *) cur); |
276 | ct_l_intr_entry((struct __l_intr_entry *) cur); |
| 269 | cur += 8; |
277 | cur += 8; |
| 270 | break; |
278 | break; |
| 271 | 279 | ||
| 272 | default: |
280 | default: |
| 273 | /* |
281 | /* |
| 274 | * Something is wrong. Fallback to UP mode. |
282 | * Something is wrong. Fallback to UP mode. |
| 275 | */ |
283 | */ |
| 276 | 284 | ||
| 277 | printf("%s: ct badness\n", __func__); |
285 | printf("%s: ct badness\n", __func__); |
| 278 | return 1; |
286 | return 1; |
| 279 | } |
287 | } |
| 280 | } |
288 | } |
| 281 | 289 | ||
| 282 | /* |
290 | /* |
| 283 | * Process extended entries. |
291 | * Process extended entries. |
| Line 299... | Line 307... | ||
| 299 | int ct_processor_entry(struct __processor_entry *pr __attribute__((unused))) |
307 | int ct_processor_entry(struct __processor_entry *pr __attribute__((unused))) |
| 300 | { |
308 | { |
| 301 | /* |
309 | /* |
| 302 | * Ignore processors which are not marked enabled. |
310 | * Ignore processors which are not marked enabled. |
| 303 | */ |
311 | */ |
| 304 | if ((pr->cpu_flags & (1<<0)) == 0) |
312 | if ((pr->cpu_flags & (1 << 0)) == 0) |
| 305 | return 0; |
313 | return 0; |
| 306 | 314 | ||
| 307 | apic_id_mask |= (1<<pr->l_apic_id); |
315 | apic_id_mask |= (1 << pr->l_apic_id); |
| 308 | return 1; |
316 | return 1; |
| 309 | } |
317 | } |
| 310 | 318 | ||
| 311 | void ct_bus_entry(struct __bus_entry *bus __attribute__((unused))) |
319 | void ct_bus_entry(struct __bus_entry *bus __attribute__((unused))) |
| 312 | { |
320 | { |
| Line 339... | Line 347... | ||
| 339 | //#define MPSCT_VERBOSE |
347 | //#define MPSCT_VERBOSE |
| 340 | void ct_io_intr_entry(struct __io_intr_entry *iointr __attribute__((unused))) |
348 | void ct_io_intr_entry(struct __io_intr_entry *iointr __attribute__((unused))) |
| 341 | { |
349 | { |
| 342 | #ifdef MPSCT_VERBOSE |
350 | #ifdef MPSCT_VERBOSE |
| 343 | switch (iointr->intr_type) { |
351 | switch (iointr->intr_type) { |
| - | 352 | case 0: |
|
| 344 | case 0: printf("INT"); break; |
353 | printf("INT"); |
| - | 354 | break; |
|
| - | 355 | case 1: |
|
| 345 | case 1: printf("NMI"); break; |
356 | printf("NMI"); |
| - | 357 | break; |
|
| - | 358 | case 2: |
|
| 346 | case 2: printf("SMI"); break; |
359 | printf("SMI"); |
| - | 360 | break; |
|
| - | 361 | case 3: |
|
| 347 | case 3: printf("ExtINT"); break; |
362 | printf("ExtINT"); |
| - | 363 | break; |
|
| 348 | } |
364 | } |
| 349 | putchar(','); |
365 | putchar(','); |
| 350 | switch (iointr->poel&3) { |
366 | switch (iointr->poel & 3) { |
| - | 367 | case 0: |
|
| 351 | case 0: printf("bus-like"); break; |
368 | printf("bus-like"); |
| - | 369 | break; |
|
| - | 370 | case 1: |
|
| 352 | case 1: printf("active high"); break; |
371 | printf("active high"); |
| - | 372 | break; |
|
| - | 373 | case 2: |
|
| 353 | case 2: printf("reserved"); break; |
374 | printf("reserved"); |
| - | 375 | break; |
|
| - | 376 | case 3: |
|
| 354 | case 3: printf("active low"); break; |
377 | printf("active low"); |
| - | 378 | break; |
|
| 355 | } |
379 | } |
| 356 | putchar(','); |
380 | putchar(','); |
| 357 | switch ((iointr->poel>>2)&3) { |
381 | switch ((iointr->poel >> 2) & 3) { |
| - | 382 | case 0: |
|
| 358 | case 0: printf("bus-like"); break; |
383 | printf("bus-like"); |
| - | 384 | break; |
|
| - | 385 | case 1: |
|
| 359 | case 1: printf("edge-triggered"); break; |
386 | printf("edge-triggered"); |
| - | 387 | break; |
|
| - | 388 | case 2: |
|
| 360 | case 2: printf("reserved"); break; |
389 | printf("reserved"); |
| - | 390 | break; |
|
| - | 391 | case 3: |
|
| 361 | case 3: printf("level-triggered"); break; |
392 | printf("level-triggered"); |
| - | 393 | break; |
|
| 362 | } |
394 | } |
| 363 | putchar(','); |
395 | putchar(','); |
| 364 | printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); |
396 | printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); |
| 365 | putchar(','); |
397 | putchar(','); |
| 366 | printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin); |
398 | printf("io_apic%d,pin%d", iointr->dst_io_apic_id, |
| - | 399 | iointr->dst_io_apic_pin); |
|
| 367 | putchar('\n'); |
400 | putchar('\n'); |
| 368 | #endif |
401 | #endif |
| 369 | } |
402 | } |
| 370 | 403 | ||
| 371 | void ct_l_intr_entry(struct __l_intr_entry *lintr __attribute__((unused))) |
404 | void ct_l_intr_entry(struct __l_intr_entry *lintr __attribute__((unused))) |
| 372 | { |
405 | { |
| 373 | #ifdef MPSCT_VERBOSE |
406 | #ifdef MPSCT_VERBOSE |
| 374 | switch (lintr->intr_type) { |
407 | switch (lintr->intr_type) { |
| - | 408 | case 0: |
|
| 375 | case 0: printf("INT"); break; |
409 | printf("INT"); |
| - | 410 | break; |
|
| - | 411 | case 1: |
|
| 376 | case 1: printf("NMI"); break; |
412 | printf("NMI"); |
| - | 413 | break; |
|
| - | 414 | case 2: |
|
| 377 | case 2: printf("SMI"); break; |
415 | printf("SMI"); |
| - | 416 | break; |
|
| - | 417 | case 3: |
|
| 378 | case 3: printf("ExtINT"); break; |
418 | printf("ExtINT"); |
| - | 419 | break; |
|
| 379 | } |
420 | } |
| 380 | putchar(','); |
421 | putchar(','); |
| 381 | switch (lintr->poel&3) { |
422 | switch (lintr->poel & 3) { |
| - | 423 | case 0: |
|
| 382 | case 0: printf("bus-like"); break; |
424 | printf("bus-like"); |
| - | 425 | break; |
|
| - | 426 | case 1: |
|
| 383 | case 1: printf("active high"); break; |
427 | printf("active high"); |
| - | 428 | break; |
|
| - | 429 | case 2: |
|
| 384 | case 2: printf("reserved"); break; |
430 | printf("reserved"); |
| - | 431 | break; |
|
| - | 432 | case 3: |
|
| 385 | case 3: printf("active low"); break; |
433 | printf("active low"); |
| - | 434 | break; |
|
| 386 | } |
435 | } |
| 387 | putchar(','); |
436 | putchar(','); |
| 388 | switch ((lintr->poel>>2)&3) { |
437 | switch ((lintr->poel >> 2) & 3) { |
| - | 438 | case 0: |
|
| 389 | case 0: printf("bus-like"); break; |
439 | printf("bus-like"); |
| - | 440 | break; |
|
| - | 441 | case 1: |
|
| 390 | case 1: printf("edge-triggered"); break; |
442 | printf("edge-triggered"); |
| - | 443 | break; |
|
| - | 444 | case 2: |
|
| 391 | case 2: printf("reserved"); break; |
445 | printf("reserved"); |
| - | 446 | break; |
|
| - | 447 | case 3: |
|
| 392 | case 3: printf("level-triggered"); break; |
448 | printf("level-triggered"); |
| - | 449 | break; |
|
| 393 | } |
450 | } |
| 394 | putchar(','); |
451 | putchar(','); |
| 395 | printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); |
452 | printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); |
| 396 | putchar(','); |
453 | putchar(','); |
| 397 | printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); |
454 | printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); |
| Line 402... | Line 459... | ||
| 402 | void ct_extended_entries(void) |
459 | void ct_extended_entries(void) |
| 403 | { |
460 | { |
| 404 | uint8_t *ext = (uint8_t *) ct + ct->base_table_length; |
461 | uint8_t *ext = (uint8_t *) ct + ct->base_table_length; |
| 405 | uint8_t *cur; |
462 | uint8_t *cur; |
| 406 | 463 | ||
| 407 | for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) { |
464 | for (cur = ext; cur < ext + ct->ext_table_length; |
| - | 465 | cur += cur[CT_EXT_ENTRY_LEN]) { |
|
| 408 | switch (cur[CT_EXT_ENTRY_TYPE]) { |
466 | switch (cur[CT_EXT_ENTRY_TYPE]) { |
| 409 | default: |
467 | default: |
| 410 | printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); |
468 | printf("%p: skipping MP Configuration Table extended " |
| - | 469 | "entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); |
|
| 411 | break; |
470 | break; |
| 412 | } |
471 | } |
| 413 | } |
472 | } |
| 414 | } |
473 | } |
| 415 | 474 | ||
| 416 | int mps_irq_to_pin(unsigned int irq) |
475 | int mps_irq_to_pin(unsigned int irq) |
| 417 | { |
476 | { |
| 418 | unsigned int i; |
477 | unsigned int i; |
| 419 | 478 | ||
| 420 | for (i = 0; i < io_intr_entry_cnt; i++) { |
479 | for (i = 0; i < io_intr_entry_cnt; i++) { |
| 421 | if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0) |
480 | if (io_intr_entries[i].src_bus_irq == irq && |
| - | 481 | io_intr_entries[i].intr_type == 0) |
|
| 422 | return io_intr_entries[i].dst_io_apic_pin; |
482 | return io_intr_entries[i].dst_io_apic_pin; |
| 423 | } |
483 | } |
| 424 | 484 | ||
| 425 | return -1; |
485 | return -1; |
| 426 | } |
486 | } |