blob: 2e7c7e4592046ea39ad30b4574b57a8413b7df0c (
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
67
68
69
70
|
#include "kapi/platform.hpp"
#include "kapi/acpi.hpp"
#include "kapi/devices.hpp"
#include "kapi/memory.hpp"
#include "arch/devices/local_apic.hpp"
#include <kstd/memory>
#include <kstd/print>
#include <cstddef>
#include <cstdint>
namespace kapi::platform
{
namespace
{
constexpr auto default_lapic_address = kapi::memory::physical_address{0xFEE0'0000};
}
auto discover_cpu_topology(kapi::devices::bus & bus) -> bool
{
auto madt = kapi::acpi::get_table("APIC");
if (!madt)
{
kstd::println("[x86_64:PLT] Failed to find ACPI APIC table");
return false;
}
auto const * current = reinterpret_cast<std::byte const *>(madt.get()) + sizeof(kapi::acpi::madt_header);
auto const * 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;
if (kapi::platform::cpu_detected(bus, local_apic->processor_id(), is_bsp))
{
++core_count;
}
}
}
current += sub_table->length();
}
kstd::println("[x86_64:PLT] Found {} CPU cores", core_count);
return core_count > 0;
}
auto create_core_interrupt_controller(std::size_t major, std::size_t minor, std::uint64_t hardware_id)
-> kstd::unique_ptr<devices::device>
{
return kstd::make_unique<arch::devices::local_apic>(major, minor, hardware_id, default_lapic_address);
}
} // namespace kapi::platform
|