1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
72,19 → 72,21 |
ops = &mps_config_operations; |
} |
|
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("cannot allocate address for l_apic\n"); |
|
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("cannot allocate address for io_apic\n"); |
|
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic, |
PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic, |
PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, l_apic_address, |
(uintptr_t) l_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, io_apic_address, |
(uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
|
l_apic = (uint32_t *) l_apic_address; |
io_apic = (uint32_t *) io_apic_address; |
112,7 → 114,8 |
/* |
* Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot() |
*/ |
*((uint16_t *) (PA2KA(0x467 + 0))) = (uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */ |
*((uint16_t *) (PA2KA(0x467 + 0))) = |
(uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */ |
*((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */ |
|
/* |
143,7 → 146,8 |
continue; |
|
if (ops->cpu_apic_id(i) == apic) { |
printf("%s: bad processor entry #%u, will not send IPI to myself\n", __FUNCTION__, i); |
printf("%s: bad processor entry #%u, will not send IPI " |
"to myself\n", __FUNCTION__, i); |
continue; |
} |
|
150,11 → 154,14 |
/* |
* Prepare new GDT for CPU in question. |
*/ |
if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS * sizeof(struct descriptor), FRAME_ATOMIC))) |
gdt_new = (struct descriptor *) malloc(GDT_ITEMS * |
sizeof(struct descriptor), FRAME_ATOMIC); |
if (!gdt_new) |
panic("couldn't allocate memory for GDT\n"); |
|
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0); |
memsetb((uintptr_t)(&gdt_new[TSS_DES]), |
sizeof(struct descriptor), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor); |
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); |
gdtr.base = (uintptr_t) gdt_new; |
165,12 → 172,17 |
* the time. After it comes completely up, it is |
* supposed to wake us up. |
*/ |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { |
unsigned int cpu = (config.cpu_active > i) ? config.cpu_active : i; |
printf("%s: waiting for cpu%u (APIC ID = %d) timed out\n", __FUNCTION__, cpu, ops->cpu_apic_id(i)); |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, |
SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { |
unsigned int cpu = (config.cpu_active > i) ? |
config.cpu_active : i; |
printf("%s: waiting for cpu%u (APIC ID = %d) " |
"timed out\n", __FUNCTION__, cpu, |
ops->cpu_apic_id(i)); |
} |
} else |
printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i)); |
printf("INIT IPI for l_apic%d failed\n", |
ops->cpu_apic_id(i)); |
} |
} |
|