22 #include "Multiprocessor.h" 23 #include "pedigree/kernel/Log.h" 24 #include "pedigree/kernel/Spinlock.h" 25 #include "pedigree/kernel/processor/Processor.h" 26 #include "pedigree/kernel/processor/ProcessorInformation.h" 27 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 28 #include "pedigree/kernel/processor/types.h" 29 #include "pedigree/kernel/utilities/Vector.h" 30 #include "pedigree/kernel/utilities/utility.h" 33 #include "../x86/VirtualAddressSpace.h" 35 #include "../x64/VirtualAddressSpace.h" 38 #include <machine/mach_pc/Acpi.h> 39 #include <machine/mach_pc/LocalApic.h> 40 #include <machine/mach_pc/Pc.h> 41 #include <machine/mach_pc/Smp.h> 44 #error APIC not defined 46 #if !defined(ACPI) && !defined(SMP) 47 #error Neither ACPI nor SMP defined 52 Spinlock Multiprocessor::m_ProcessorLock1(
false,
true);
53 Spinlock Multiprocessor::m_ProcessorLock2(
true,
true);
55 extern "C" void mp_trampoline16(
void);
56 extern "C" void mp_trampoline32(
void);
57 extern "C" void *trampolinegdt;
58 extern "C" void *trampolinegdtr;
59 extern "C" void *trampolinegdt64;
60 extern "C" void *trampolinegdtr64;
65 bool bMPInfoFound =
false;
71 Acpi &acpi = Acpi::instance();
72 if ((bMPInfoFound = acpi.validProcessorInfo()) ==
true)
73 Processors = &acpi.getProcessorList();
78 Smp &smp = Smp::instance();
79 if (bMPInfoFound ==
false && (bMPInfoFound = smp.valid()) ==
true)
80 Processors = &smp.getProcessorList();
84 if (bMPInfoFound ==
false || !Processors)
86 NOTICE(
"Multiprocessor: couldn't find any information about multiple " 92 "Multiprocessor: Found " <<
Dec << Processors->
count() <<
Hex 101 reinterpret_cast<void *>(0x7000),
102 reinterpret_cast<void *>(&mp_trampoline16), 0x100);
104 reinterpret_cast<void *>(0x7100),
105 reinterpret_cast<void *>(&mp_trampoline32), 0x100);
106 MemoryCopy(reinterpret_cast<void *>(0x7200), &trampolinegdtr64, 0x10);
107 MemoryCopy(reinterpret_cast<void *>(0x7210), &trampolinegdt64, 0xF0);
111 volatile uint32_t *trampolineStack =
112 reinterpret_cast<volatile uint32_t *
>(0x7FF8);
113 volatile uint32_t *trampolineKernelEntry =
114 reinterpret_cast<volatile uint32_t *
>(0x7FF4);
117 *
reinterpret_cast<volatile uint32_t *
>(0x7FFC) =
118 static_cast<X86VirtualAddressSpace &>(
120 .m_PhysicalPageDirectory;
122 volatile uint64_t *trampolineStack =
123 reinterpret_cast<volatile uint64_t *
>(0x7FF0);
124 volatile uint64_t *trampolineKernelEntry =
125 reinterpret_cast<volatile uint64_t *
>(0x7FE8);
128 *
reinterpret_cast<volatile uint64_t *
>(0x7FF8) =
129 static_cast<X64VirtualAddressSpace &>(
135 *trampolineKernelEntry =
136 reinterpret_cast<uintptr_t
>(&applicationProcessorStartup);
138 LocalApic &localApic = Pc::instance().getLocalApic();
143 for (
size_t i = 0; i < Processors->
count(); i++)
146 ::ProcessorInformation *pProcessorInfo = 0;
149 if (localApic.getId() != (*Processors)[i]->apicId)
152 pProcessorInfo = new ::ProcessorInformation(
153 (*Processors)[i]->processorId, (*Processors)[i]->apicId);
160 *trampolineStack =
reinterpret_cast<uintptr_t
>(pStack->getTop());
163 " Booting processor #" 164 <<
Dec << (*Processors)[i]->processorId <<
", stack at 0x" 165 <<
Hex << reinterpret_cast<uintptr_t>(pStack->getTop()));
172 m_ProcessorLock1.acquire(
false);
174 localApic.interProcessorInterrupt(
175 (*Processors)[i]->apicId, 0x07, LocalApic::deliveryModeInit,
177 for (
int z = 0; z < 0x10000; z++)
181 localApic.interProcessorInterrupt(
182 (*Processors)[i]->apicId, 0x07, LocalApic::deliveryModeStartup,
186 m_ProcessorLock1.acquire(
false,
false);
187 m_ProcessorLock1.release();
192 "Currently running on CPU #" 193 <<
Dec << localApic.getId() <<
Hex 194 <<
", skipping boot (not necessary)");
197 &Processor::m_SafeBspProcessorInformation);
198 Processor::m_SafeBspProcessorInformation.setIds(
199 (*Processors)[i]->processorId, (*Processors)[i]->apicId);
203 return Processors->
count();
208 m_ProcessorLock2.release();
A vector / dynamic array.
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
virtual Stack * allocateStack()=0
static size_t initialise1() INITIALISATION_ONLY
static void initialise2() INITIALISATION_ONLY
static ProcessorInformation m_ProcessorInformation