Changeset a26ddd1 in mainline for arch/ia32/src/smp/mps.c
- Timestamp:
- 2005-07-18T12:37:11Z (20 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 232e3ec7
- Parents:
- 6b7c36f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/ia32/src/smp/mps.c
r6b7c36f ra26ddd1 29 29 #ifdef __SMP__ 30 30 31 #include <arch/pm.h>32 31 #include <config.h> 33 32 #include <print.h> 34 #include < panic.h>33 #include <debug.h> 35 34 #include <arch/smp/mps.h> 36 #include <arch/smp/ap.h>37 35 #include <arch/smp/apic.h> 36 #include <arch/smp/smp.h> 38 37 #include <func.h> 39 38 #include <arch/types.h> 40 39 #include <typedefs.h> 41 #include <synch/waitq.h>42 #include <time/delay.h>43 #include <mm/heap.h>44 40 #include <mm/page.h> 45 #include <mm/frame.h>46 41 #include <cpu.h> 47 #include <arch/i8259.h>48 42 #include <arch/asm.h> 49 43 #include <arch/bios/bios.h> 50 #include <arch/acpi/madt.h>51 44 52 45 /* … … 88 81 waitq_t ap_completion_wq; 89 82 waitq_t kmp_completion_wq; 83 84 85 /* 86 * Implementation of IA-32 SMP configuration interface. 87 */ 88 static count_t get_cpu_count(void); 89 static bool is_cpu_enabled(index_t i); 90 static bool is_bsp(index_t i); 91 static __u8 get_cpu_apic_id(index_t i); 92 93 struct smp_config_operations mps_config_operations = { 94 .cpu_count = get_cpu_count, 95 .cpu_enabled = is_cpu_enabled, 96 .cpu_bootstrap = is_bsp, 97 .cpu_apic_id = get_cpu_apic_id 98 }; 99 100 count_t get_cpu_count(void) 101 { 102 return processor_entry_cnt; 103 } 104 105 bool is_cpu_enabled(index_t i) 106 { 107 ASSERT(i < processor_entry_cnt); 108 return processor_entries[i].cpu_flags & 0x1; 109 } 110 111 bool is_bsp(index_t i) 112 { 113 ASSERT(i < processor_entry_cnt); 114 return processor_entries[i].cpu_flags & 0x2; 115 } 116 117 __u8 get_cpu_apic_id(index_t i) 118 { 119 ASSERT(i < processor_entry_cnt); 120 return processor_entries[i].l_apic_id; 121 } 122 90 123 91 124 /* … … 393 426 } 394 427 395 396 /*397 * Kernel thread for bringing up application processors. It becomes clear398 * that we need an arrangement like this (AP's being initialized by a kernel399 * thread), for a thread has its dedicated stack. (The stack used during the400 * BSP initialization (prior the very first call to scheduler()) will be used401 * as an initialization stack for each AP.)402 */403 void kmp(void *arg)404 {405 struct __processor_entry *pr;406 __address src, dst;407 int i;408 409 waitq_initialize(&ap_completion_wq);410 411 /*412 * Processor entries immediately follow the configuration table header.413 */414 pr = processor_entries;415 416 /*417 * We need to access data in frame 0.418 * We boldly make use of kernel address space mapping.419 */420 421 /*422 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()423 */424 *((__u16 *) (PA2KA(0x467+0))) = ((__address) ap_boot) >> 4; /* segment */425 *((__u16 *) (PA2KA(0x467+2))) = 0; /* offset */426 427 /*428 * Save 0xa to address 0xf of the CMOS RAM.429 * BIOS will not do the POST after the INIT signal.430 */431 outb(0x70,0xf);432 outb(0x71,0xa);433 434 cpu_priority_high();435 436 pic_disable_irqs(0xffff);437 apic_init();438 439 for (i = 0; i < processor_entry_cnt; i++) {440 struct descriptor *gdt_new;441 442 /*443 * Skip processors marked unusable.444 */445 if (pr[i].cpu_flags & (1<<0) == 0)446 continue;447 448 /*449 * The bootstrap processor is already up.450 */451 if (pr[i].cpu_flags & (1<<1))452 continue;453 454 if (pr[i].l_apic_id == l_apic_id()) {455 printf("%L: bad processor entry #%d, will not send IPI to myself\n", &pr[i], i);456 continue;457 }458 459 /*460 * Prepare new GDT for CPU in question.461 */462 if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor))))463 panic("couldn't allocate memory for GDT\n");464 465 memcopy(gdt, gdt_new, GDT_ITEMS*sizeof(struct descriptor));466 memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0);467 gdtr.base = KA2PA((__address) gdt_new);468 469 if (l_apic_send_init_ipi(pr[i].l_apic_id)) {470 /*471 * There may be just one AP being initialized at472 * the time. After it comes completely up, it is473 * supposed to wake us up.474 */475 waitq_sleep(&ap_completion_wq);476 cpu_priority_high();477 }478 else {479 printf("INIT IPI for l_apic%d failed\n", pr[i].l_apic_id);480 }481 }482 483 /*484 * Wakeup the kinit thread so that485 * system initialization can go on.486 */487 waitq_wakeup(&kmp_completion_wq, WAKEUP_FIRST);488 }489 490 428 int mps_irq_to_pin(int irq) 491 429 {
Note:
See TracChangeset
for help on using the changeset viewer.