23 #include "pedigree/kernel/utilities/utility.h" 25 #if !defined(SMP_NOTICE) 29 #if !defined(SMP_ERROR) 36 void Smp::initialise()
41 ERROR(
"smp: not compliant to the Intel Multiprocessor Specification");
46 "Intel Multiprocessor Specification 1." 47 <<
Dec << m_pFloatingPointer->revision);
49 " floating pointer at " 50 <<
Hex << reinterpret_cast<uintptr_t>(m_pFloatingPointer));
53 if (m_pFloatingPointer->features[0] != 0)
56 "smp: default configurations (#" 57 <<
Dec << m_pFloatingPointer->features[0] <<
") not supported");
62 m_pConfigTable =
reinterpret_cast<ConfigTableHeader *
>(
63 m_pFloatingPointer->physicalAddress);
64 if (m_pConfigTable == 0)
66 ERROR(
"smp: configuration table not present");
69 if (reinterpret_cast<uintptr_t>(m_pConfigTable) >= 0x100000)
71 ERROR(
"smp: configuration table above 1MB");
76 " configuration table at " 77 <<
Hex << reinterpret_cast<uintptr_t>(m_pConfigTable));
79 if (m_pConfigTable->signature != 0x504D4350 ||
80 checksum(m_pConfigTable) !=
true ||
81 m_pConfigTable->revision != m_pFloatingPointer->revision)
83 ERROR(
"smp: configuration table invalid");
90 m_bPICMode = ((m_pFloatingPointer->features[1] & 0x80) == 0x80);
93 m_LocalApicAddress = m_pConfigTable->localApicAddress;
98 uint8_t *pType =
reinterpret_cast<uint8_t *
>(
99 adjust_pointer(m_pConfigTable,
sizeof(ConfigTableHeader)));
100 for (
size_t i = 0; i < m_pConfigTable->entryCount; i++)
110 bool bUsable = ((pProcessor->flags & 0x01) == 0x01);
113 " Processor #" <<
Dec << pProcessor->localApicId
114 << (bUsable ?
" usable" :
" unusable"));
116 #if defined(MULTIPROCESSOR) 123 pProcessor->localApicId, pProcessor->localApicId);
124 m_Processors.pushBack(pProcessorInfo);
131 else if (*pType == 1)
133 Bus *pBus =
reinterpret_cast<Bus *
>(pType);
136 StringCopyN(name, pBus->name, 6);
139 NOTICE(
" Bus #" <<
Dec << pBus->busId <<
" \"" << name <<
"\"");
145 else if (*pType == 2)
147 IoApic *pIoApic =
reinterpret_cast<IoApic *
>(pType);
149 bool bUsable = ((pIoApic->flags & 0x01) == 0x01);
152 " I/O APIC #" <<
Dec << pIoApic->id
153 << (bUsable ?
" usable" :
"") <<
" at " <<
Hex 154 << pIoApic->address);
163 pIoApic->id, pIoApic->address);
164 m_IoApics.pushBack(pIoApicInfo);
169 else if (*pType == 3)
178 else if (*pType == 4)
187 pType = adjust_pointer(pType, sEntry);
196 : m_bValid(false), m_pFloatingPointer(0), m_pConfigTable(0)
199 m_bPICMode(false), m_LocalApicAddress(0), m_IoApics()
200 #if defined(MULTIPROCESSOR)
211 uint16_t *ebdaSegment =
reinterpret_cast<uint16_t *
>(0x40E);
213 find(reinterpret_cast<void *>((*ebdaSegment) * 16), 0x400);
215 if (m_pFloatingPointer == 0)
218 uint16_t *baseSize =
reinterpret_cast<uint16_t *
>(0x413);
220 find(reinterpret_cast<void *>((*baseSize - 1) * 1024), 0x400);
222 if (m_pFloatingPointer == 0)
226 find(reinterpret_cast<void *>(0xF0000), 0x10000);
230 return (m_pFloatingPointer != 0);
233 Smp::FloatingPointer *Smp::find(
void *pMemory,
size_t sMemory)
235 FloatingPointer *pFloatingPointer =
236 reinterpret_cast<FloatingPointer *
>(pMemory);
237 while (reinterpret_cast<uintptr_t>(pFloatingPointer) <
238 (
reinterpret_cast<uintptr_t
>(pMemory) + sMemory))
240 if (pFloatingPointer->signature == 0x5F504D5F &&
241 checksum(pFloatingPointer) ==
true)
242 return pFloatingPointer;
243 pFloatingPointer = adjust_pointer(pFloatingPointer, 16);
248 bool Smp::checksum(
const FloatingPointer *pFloatingPointer)
251 reinterpret_cast<const uint8_t *>(pFloatingPointer),
252 pFloatingPointer->length * 16);
255 bool Smp::checksum(
const ConfigTableHeader *pConfigTable)
259 reinterpret_cast<const uint8_t *>(pConfigTable),
260 pConfigTable->baseTableLength) ==
false)
264 uint8_t sum = pConfigTable->extendedChecksum;
265 for (
size_t i = 0; i < pConfigTable->extendedTableLength; i++)
266 sum += reinterpret_cast<const uint8_t *>(
267 pConfigTable)[pConfigTable->baseTableLength + i];
The exception was caused by a hardware task switch.