Changeset a26ddd1 in mainline
- 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
- Location:
- arch/ia32
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/ia32/include/smp/mps.h
r6b7c36f ra26ddd1 34 34 #include <synch/waitq.h> 35 35 #include <config.h> 36 #include <arch/smp/smp.h> 36 37 37 38 #define CT_EXT_ENTRY_TYPE 0 … … 118 119 extern waitq_t kmp_completion_wq; 119 120 121 extern struct smp_config_operations mps_config_operations; 122 120 123 extern int mps_irq_to_pin(int irq); 121 124 -
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 { -
arch/ia32/src/smp/smp.c
r6b7c36f ra26ddd1 28 28 29 29 #include <smp/smp.h> 30 #include <arch/smp/smp.h> 31 #include <arch/smp/mps.h> 32 #include <arch/smp/ap.h> 30 33 #include <arch/acpi/acpi.h> 31 34 #include <arch/acpi/madt.h> 32 #include <arch/smp/mps.h>33 35 #include <config.h> 36 #include <synch/waitq.h> 37 #include <arch/pm.h> 38 #include <func.h> 39 #include <panic.h> 40 #include <debug.h> 41 #include <arch/asm.h> 42 #include <mm/frame.h> 43 #include <mm/page.h> 44 #include <mm/heap.h> 34 45 35 46 #ifdef __SMP__ 47 48 static struct smp_config_operations *ops = NULL; 36 49 37 50 void smp_init(void) … … 40 53 acpi_madt_parse(); 41 54 } 42 if (config.cpu_count == 1) 55 if (config.cpu_count == 1) { 43 56 mps_init(); 57 ops = &mps_config_operations; 58 } 44 59 } 45 60 61 /* 62 * Kernel thread for bringing up application processors. It becomes clear 63 * that we need an arrangement like this (AP's being initialized by a kernel 64 * thread), for a thread has its dedicated stack. (The stack used during the 65 * BSP initialization (prior the very first call to scheduler()) will be used 66 * as an initialization stack for each AP.) 67 */ 68 void kmp(void *arg) 69 { 70 __address src, dst; 71 int i; 72 73 ASSERT(ops != NULL); 74 75 waitq_initialize(&ap_completion_wq); 76 77 /* 78 * We need to access data in frame 0. 79 * We boldly make use of kernel address space mapping. 80 */ 81 82 /* 83 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot() 84 */ 85 *((__u16 *) (PA2KA(0x467+0))) = ((__address) ap_boot) >> 4; /* segment */ 86 *((__u16 *) (PA2KA(0x467+2))) = 0; /* offset */ 87 88 /* 89 * Save 0xa to address 0xf of the CMOS RAM. 90 * BIOS will not do the POST after the INIT signal. 91 */ 92 outb(0x70,0xf); 93 outb(0x71,0xa); 94 95 cpu_priority_high(); 96 97 pic_disable_irqs(0xffff); 98 apic_init(); 99 100 for (i = 0; i < ops->cpu_count(); i++) { 101 struct descriptor *gdt_new; 102 103 /* 104 * Skip processors marked unusable. 105 */ 106 if (!ops->cpu_enabled(i)) 107 continue; 108 109 /* 110 * The bootstrap processor is already up. 111 */ 112 if (ops->cpu_bootstrap(i)) 113 continue; 114 115 if (ops->cpu_apic_id(i) == l_apic_id()) { 116 printf("kmp: bad processor entry #%d, will not send IPI to myself\n", i); 117 continue; 118 } 119 120 /* 121 * Prepare new GDT for CPU in question. 122 */ 123 if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor)))) 124 panic("couldn't allocate memory for GDT\n"); 125 126 memcopy(gdt, gdt_new, GDT_ITEMS*sizeof(struct descriptor)); 127 memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); 128 gdtr.base = KA2PA((__address) gdt_new); 129 130 if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { 131 /* 132 * There may be just one AP being initialized at 133 * the time. After it comes completely up, it is 134 * supposed to wake us up. 135 */ 136 waitq_sleep(&ap_completion_wq); 137 cpu_priority_high(); 138 } 139 else { 140 printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i)); 141 } 142 } 143 144 /* 145 * Wakeup the kinit thread so that 146 * system initialization can go on. 147 */ 148 waitq_wakeup(&kmp_completion_wq, WAKEUP_FIRST); 149 } 46 150 47 151 #endif /* __SMP__ */
Note:
See TracChangeset
for help on using the changeset viewer.