Changeset a26ddd1 in mainline for arch/ia32/src/smp/smp.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/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.