usb hubs, hotplug support, unplug support, saving log files to disk, smt
This commit is contained in:
1 parent
b838f8d83d
commit
27b31f62b6
39 files changed
+6294
-735
No files matched your search
@@ -321,6 +321,15 @@ static void KiPrepareCpuRecord(uint32_t cpuIndex, const HAL_CPU_INFO* info) {
|
||||
cpu->Parked = 0;
|
||||
cpu->Online = 0;
|
||||
cpu->IsBsp = info->IsBsp ? 1 : 0;
|
||||
cpu->PackageId = 0;
|
||||
cpu->CoreId = cpuIndex;
|
||||
cpu->ThreadId = 0;
|
||||
cpu->PhysicalCoreIndex = cpuIndex;
|
||||
cpu->CoreSiblingMask = (cpuIndex < 64) ? (1ULL << cpuIndex) : 0ULL;
|
||||
cpu->PackageMask = cpu->CoreSiblingMask;
|
||||
cpu->IsPrimaryThread = 1;
|
||||
cpu->SmtThreadCount = 1;
|
||||
cpu->TopologyFlags = 0;
|
||||
cpu->CurrentIrql = PASSIVE_LEVEL;
|
||||
cpu->InterruptDepth = 0;
|
||||
cpu->ReschedulePending = 0;
|
||||
@@ -328,6 +337,223 @@ static void KiPrepareCpuRecord(uint32_t cpuIndex, const HAL_CPU_INFO* info) {
|
||||
cpu->SchedulerActive = 0;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t KiCeilLog2U32(uint32_t value) {
|
||||
if (value <= 1u)
|
||||
return 0u;
|
||||
uint32_t shift = 0;
|
||||
uint32_t n = value - 1u;
|
||||
while (n) {
|
||||
shift++;
|
||||
n >>= 1;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
static uint32_t KiMaskWidth(uint32_t shift) {
|
||||
if (shift >= 32u)
|
||||
return 0xFFFFFFFFu;
|
||||
if (shift == 0u)
|
||||
return 0u;
|
||||
return (1u << shift) - 1u;
|
||||
}
|
||||
|
||||
typedef struct KI_CPUID_TOPOLOGY_PARAMS {
|
||||
uint32_t SmtShift;
|
||||
uint32_t CoreShift;
|
||||
uint32_t ThreadsPerCore;
|
||||
uint32_t LogicalPerPackage;
|
||||
const char* Source;
|
||||
} KI_CPUID_TOPOLOGY_PARAMS;
|
||||
|
||||
static void KiReadCpuidTopologyLeaf(uint32_t leaf, KI_CPUID_TOPOLOGY_PARAMS* out) {
|
||||
if (!out)
|
||||
return;
|
||||
|
||||
for (uint32_t sub = 0; sub < 32u; sub++) {
|
||||
int r[4] = {0, 0, 0, 0};
|
||||
__cpuidex(r, (int)leaf, (int)sub);
|
||||
|
||||
uint32_t levelShift = (uint32_t)r[0] & 0x1Fu;
|
||||
uint32_t logicals = (uint32_t)r[1] & 0xFFFFu;
|
||||
uint32_t levelType = ((uint32_t)r[2] >> 8) & 0xFFu;
|
||||
|
||||
if (levelType == 0u || logicals == 0u)
|
||||
break;
|
||||
|
||||
if (levelType == 1u) { // SMT level
|
||||
out->SmtShift = levelShift;
|
||||
out->ThreadsPerCore = logicals ? logicals : 1u;
|
||||
} else if (levelType == 2u) { // Core/package level
|
||||
out->CoreShift = levelShift;
|
||||
out->LogicalPerPackage = logicals ? logicals : 1u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static KI_CPUID_TOPOLOGY_PARAMS KiDetectCpuidTopologyParams(void) {
|
||||
KI_CPUID_TOPOLOGY_PARAMS topo;
|
||||
memset(&topo, 0, sizeof(topo));
|
||||
topo.ThreadsPerCore = 1;
|
||||
topo.LogicalPerPackage = 1;
|
||||
topo.Source = "flat";
|
||||
|
||||
int maxRegs[4] = {0, 0, 0, 0};
|
||||
__cpuid(maxRegs, 0);
|
||||
uint32_t maxLeaf = (uint32_t)maxRegs[0];
|
||||
|
||||
if (maxLeaf >= 0x1Fu) {
|
||||
KiReadCpuidTopologyLeaf(0x1Fu, &topo);
|
||||
if (topo.CoreShift >= topo.SmtShift && topo.CoreShift != 0u) {
|
||||
topo.Source = "cpuid.1f";
|
||||
return topo;
|
||||
}
|
||||
memset(&topo, 0, sizeof(topo));
|
||||
topo.ThreadsPerCore = 1;
|
||||
topo.LogicalPerPackage = 1;
|
||||
topo.Source = "flat";
|
||||
}
|
||||
|
||||
if (maxLeaf >= 0x0Bu) {
|
||||
KiReadCpuidTopologyLeaf(0x0Bu, &topo);
|
||||
if (topo.CoreShift >= topo.SmtShift && topo.CoreShift != 0u) {
|
||||
topo.Source = "cpuid.0b";
|
||||
return topo;
|
||||
}
|
||||
memset(&topo, 0, sizeof(topo));
|
||||
topo.ThreadsPerCore = 1;
|
||||
topo.LogicalPerPackage = 1;
|
||||
topo.Source = "flat";
|
||||
}
|
||||
|
||||
int r1[4] = {0, 0, 0, 0};
|
||||
__cpuid(r1, 1);
|
||||
uint32_t logicalPerPackage = ((uint32_t)r1[1] >> 16) & 0xFFu;
|
||||
if (logicalPerPackage == 0u)
|
||||
logicalPerPackage = 1u;
|
||||
|
||||
uint32_t coresPerPackage = 1u;
|
||||
if (maxLeaf >= 4u) {
|
||||
int r4[4] = {0, 0, 0, 0};
|
||||
__cpuidex(r4, 4, 0);
|
||||
coresPerPackage = (((uint32_t)r4[0] >> 26) & 0x3Fu) + 1u;
|
||||
if (coresPerPackage == 0u)
|
||||
coresPerPackage = 1u;
|
||||
}
|
||||
|
||||
uint32_t threadsPerCore = logicalPerPackage / coresPerPackage;
|
||||
if (threadsPerCore == 0u)
|
||||
threadsPerCore = 1u;
|
||||
|
||||
topo.ThreadsPerCore = threadsPerCore;
|
||||
topo.LogicalPerPackage = logicalPerPackage;
|
||||
topo.SmtShift = KiCeilLog2U32(threadsPerCore);
|
||||
topo.CoreShift = KiCeilLog2U32(logicalPerPackage);
|
||||
if (topo.CoreShift < topo.SmtShift)
|
||||
topo.CoreShift = topo.SmtShift;
|
||||
topo.Source = "cpuid.1/4";
|
||||
return topo;
|
||||
}
|
||||
|
||||
void KeBuildProcessorTopology(void) {
|
||||
KI_CPUID_TOPOLOGY_PARAMS topo = KiDetectCpuidTopologyParams();
|
||||
|
||||
uint32_t smtMask = KiMaskWidth(topo.SmtShift);
|
||||
uint32_t coreBits = (topo.CoreShift > topo.SmtShift) ?
|
||||
(topo.CoreShift - topo.SmtShift) : 0u;
|
||||
uint32_t coreMask = KiMaskWidth(coreBits);
|
||||
|
||||
for (uint32_t i = 0; i < gCpuCount && i < KE_MAX_CPUS; i++) {
|
||||
KCPU* cpu = &gCpus[i];
|
||||
if (!cpu->Present)
|
||||
continue;
|
||||
|
||||
uint32_t apic = cpu->LapicId;
|
||||
cpu->ThreadId = smtMask ? (apic & smtMask) : 0u;
|
||||
cpu->CoreId = coreBits ? ((apic >> topo.SmtShift) & coreMask) :
|
||||
(apic >> topo.SmtShift);
|
||||
cpu->PackageId = (topo.CoreShift < 32u) ? (apic >> topo.CoreShift) : 0u;
|
||||
cpu->PhysicalCoreIndex = KE_INVALID_CPU;
|
||||
cpu->CoreSiblingMask = 0;
|
||||
cpu->PackageMask = 0;
|
||||
cpu->IsPrimaryThread = 0;
|
||||
cpu->SmtThreadCount = 1;
|
||||
cpu->TopologyFlags = (topo.ThreadsPerCore > 1u) ? 1u : 0u;
|
||||
}
|
||||
|
||||
uint32_t nextCoreIndex = 0;
|
||||
for (uint32_t i = 0; i < gCpuCount && i < KE_MAX_CPUS; i++) {
|
||||
KCPU* cpu = &gCpus[i];
|
||||
if (!cpu->Present)
|
||||
continue;
|
||||
if (cpu->PhysicalCoreIndex != KE_INVALID_CPU)
|
||||
continue;
|
||||
|
||||
uint32_t coreIndex = nextCoreIndex++;
|
||||
uint64_t coreMaskBits = 0;
|
||||
uint64_t packageMaskBits = 0;
|
||||
uint32_t primaryCpuIndex = i;
|
||||
uint32_t siblingCount = 0;
|
||||
|
||||
for (uint32_t j = 0; j < gCpuCount && j < KE_MAX_CPUS; j++) {
|
||||
KCPU* peer = &gCpus[j];
|
||||
if (!peer->Present)
|
||||
continue;
|
||||
if (peer->PackageId == cpu->PackageId) {
|
||||
if (j < 64)
|
||||
packageMaskBits |= (1ULL << j);
|
||||
}
|
||||
if (peer->PackageId == cpu->PackageId && peer->CoreId == cpu->CoreId) {
|
||||
peer->PhysicalCoreIndex = coreIndex;
|
||||
if (j < 64)
|
||||
coreMaskBits |= (1ULL << j);
|
||||
if (j < primaryCpuIndex)
|
||||
primaryCpuIndex = j;
|
||||
siblingCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (siblingCount == 0)
|
||||
siblingCount = 1;
|
||||
|
||||
for (uint32_t j = 0; j < gCpuCount && j < KE_MAX_CPUS; j++) {
|
||||
KCPU* peer = &gCpus[j];
|
||||
if (!peer->Present)
|
||||
continue;
|
||||
if (peer->PackageId == cpu->PackageId && peer->CoreId == cpu->CoreId) {
|
||||
peer->CoreSiblingMask = coreMaskBits;
|
||||
peer->PackageMask = packageMaskBits;
|
||||
peer->SmtThreadCount = (uint8_t)((siblingCount > 255u) ? 255u : siblingCount);
|
||||
peer->IsPrimaryThread = (j == primaryCpuIndex) ? 1u : 0u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DbgPrint("SMP: SMT topology source=%s smtShift=%u coreShift=%u threads/core=%u logical/package=%u physicalCores=%u\n",
|
||||
topo.Source ? topo.Source : "?",
|
||||
topo.SmtShift,
|
||||
topo.CoreShift,
|
||||
topo.ThreadsPerCore,
|
||||
topo.LogicalPerPackage,
|
||||
nextCoreIndex);
|
||||
|
||||
for (uint32_t i = 0; i < gCpuCount && i < KE_MAX_CPUS; i++) {
|
||||
KCPU* cpu = &gCpus[i];
|
||||
if (!cpu->Present)
|
||||
continue;
|
||||
DbgPrint("SMP: cpu%u lapic=%u pkg=%u core=%u thread=%u primary=%u siblings=0x%llx package=0x%llx\n",
|
||||
i,
|
||||
cpu->LapicId,
|
||||
cpu->PackageId,
|
||||
cpu->CoreId,
|
||||
cpu->ThreadId,
|
||||
cpu->IsPrimaryThread,
|
||||
(unsigned long long)cpu->CoreSiblingMask,
|
||||
(unsigned long long)cpu->PackageMask);
|
||||
}
|
||||
}
|
||||
|
||||
static KSTATUS KiAllocateApStack(KCPU* cpu) {
|
||||
// AP kernel stacks do not need physically contiguous memory. Requiring
|
||||
// MmAllocateContiguous(8) made SMP startup depend on a DMA-style run being
|
||||
@@ -510,6 +736,7 @@ KSTATUS KeStartApplicationProcessors(void) {
|
||||
if (claimed == 0 && gCpuCount > 1)
|
||||
DbgPrint("SMP: no APs reached kernel-owned state; continuing BSP-only\n");
|
||||
|
||||
KeBuildProcessorTopology();
|
||||
DbgPrint("SMP: kernel claimed %u APs\n", claimed);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user