blob: d881f8a4d0e053e47c699fe4a3d2c140e9806362 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
#include "kapi/platform.hpp"
#include "kapi/acpi.hpp"
#include "kapi/devices.hpp"
#include "arch/devices/local_apic.hpp"
#include <kstd/memory>
#include <kstd/print>
#include <cstddef>
#include <utility>
namespace kapi::platform
{
auto discover_cpu_topology(kapi::devices::bus & bus) -> bool
{
auto static const core_major = kapi::devices::allocate_major_number();
auto static const interrupt_controller_major = kapi::devices::allocate_major_number();
auto static core_index = 0uz;
auto madt = kapi::acpi::get_table("APIC");
if (!madt)
{
kstd::println("[x86_64:PLT] Failed to find ACPI APIC table");
return false;
}
auto real_madt = static_cast<acpi::madt_header const *>(madt.get());
auto current = reinterpret_cast<std::byte const *>(madt.get()) + sizeof(kapi::acpi::madt_header);
auto end = reinterpret_cast<std::byte const *>(madt.get()) + madt->length();
auto bsp_found = false;
auto core_count = 0uz;
while (current < end)
{
auto const * sub_table = reinterpret_cast<kapi::acpi::madt_subtable_header const *>(current);
if (sub_table->type() == 0)
{
auto const * local_apic = reinterpret_cast<kapi::acpi::madt_local_apic const *>(sub_table);
if (local_apic->flags() & 0b11)
{
auto is_bsp = !bsp_found;
bsp_found = true;
auto lapic = kstd::make_unique<arch::devices::local_apic>(
interrupt_controller_major, core_index, local_apic->apic_id(),
real_madt->local_interrupt_controller_address(), is_bsp);
if (kapi::platform::cpu_detected(bus, core_major, core_index, local_apic->processor_id(), is_bsp,
std::move(lapic)))
{
++core_count;
}
}
}
current += sub_table->length();
}
kstd::println("[x86_64:PLT] Found {} CPU cores", core_count);
return core_count > 0;
}
} // namespace kapi::platform
|