Changeset fe32163 in mainline for kernel/arch/ia32/src/smp/smp.c
- Timestamp:
- 2010-06-29T00:08:48Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c19aa612
- Parents:
- 9a21f9d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/smp/smp.c
r9a21f9d rfe32163 62 62 void smp_init(void) 63 63 { 64 uintptr_t l_apic_address, io_apic_address; 65 64 uintptr_t l_apic_address; 65 uintptr_t io_apic_address; 66 66 67 if (acpi_madt) { 67 68 acpi_madt_parse(); 68 69 ops = &madt_config_operations; 69 70 } 71 70 72 if (config.cpu_count == 1) { 71 73 mps_init(); 72 74 ops = &mps_config_operations; 73 75 } 74 76 75 77 l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 76 78 FRAME_ATOMIC | FRAME_KA); 77 79 if (!l_apic_address) 78 80 panic("Cannot allocate address for l_apic."); 79 81 80 82 io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, 81 83 FRAME_ATOMIC | FRAME_KA); 82 84 if (!io_apic_address) 83 85 panic("Cannot allocate address for io_apic."); 84 86 85 87 if (config.cpu_count > 1) { 86 88 page_table_lock(AS_KERNEL, true); … … 90 92 (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE); 91 93 page_table_unlock(AS_KERNEL, true); 92 94 93 95 l_apic = (uint32_t *) l_apic_address; 94 96 io_apic = (uint32_t *) io_apic_address; … … 108 110 109 111 ASSERT(ops != NULL); 110 112 111 113 /* 112 114 * We need to access data in frame 0. 113 115 * We boldly make use of kernel address space mapping. 114 116 */ 115 117 116 118 /* 117 119 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot() 118 120 */ 119 121 *((uint16_t *) (PA2KA(0x467 + 0))) = 120 (uint16_t) (((uintptr_t) ap_boot) >> 4); 121 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; 122 (uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */ 123 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */ 122 124 123 125 /* … … 125 127 * BIOS will not do the POST after the INIT signal. 126 128 */ 127 pio_write_8((ioport8_t *) 0x70, 0xf);128 pio_write_8((ioport8_t *) 0x71, 0xa);129 129 pio_write_8((ioport8_t *) 0x70, 0xf); 130 pio_write_8((ioport8_t *) 0x71, 0xa); 131 130 132 pic_disable_irqs(0xffff); 131 133 apic_init(); 132 134 133 135 uint8_t apic = l_apic_id(); 134 135 for (i = 0; i < ops->cpu_count(); i++) { 136 descriptor_t *gdt_new; 137 136 137 for (i = 0; i < config.cpu_count; i++) { 138 138 /* 139 139 * Skip processors marked unusable. … … 141 141 if (!ops->cpu_enabled(i)) 142 142 continue; 143 143 144 144 /* 145 145 * The bootstrap processor is already up. … … 147 147 if (ops->cpu_bootstrap(i)) 148 148 continue; 149 149 150 150 if (ops->cpu_apic_id(i) == apic) { 151 151 printf("%s: bad processor entry #%u, will not send IPI " … … 162 162 * the memory subsystem 163 163 */ 164 gdt_new = (descriptor_t *) malloc(GDT_ITEMS * 165 sizeof(descriptor_t), FRAME_ATOMIC); 164 descriptor_t *gdt_new = 165 (descriptor_t *) malloc(GDT_ITEMS * sizeof(descriptor_t), 166 FRAME_ATOMIC); 166 167 if (!gdt_new) 167 168 panic("Cannot allocate memory for GDT."); 168 169 169 170 memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); 170 171 memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); … … 172 173 protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); 173 174 gdtr.base = (uintptr_t) gdt_new; 174 175 175 176 if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { 176 177 /* … … 181 182 if (waitq_sleep_timeout(&ap_completion_wq, 1000000, 182 183 SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { 183 unsigned int cpu = (config.cpu_active > i) ?184 config.cpu_active : i;185 184 printf("%s: waiting for cpu%u (APIC ID = %d) " 186 "timed out\n", __FUNCTION__, cpu,185 "timed out\n", __FUNCTION__, i, 187 186 ops->cpu_apic_id(i)); 188 187 }
Note:
See TracChangeset
for help on using the changeset viewer.