Compare commits
No commits in common. "43c87e5904d0b4d62593ff29ef4f2e75246dc187" and "024407225c9feaec60849cda3180434938d75c2c" have entirely different histories.
43c87e5904
...
024407225c
9 changed files with 32 additions and 190 deletions
|
|
@ -1,19 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "acpi/madt.h"
|
|
||||||
#include "util/optional.h"
|
|
||||||
|
|
||||||
namespace apic {
|
|
||||||
|
|
||||||
struct lapic_timer_calibration_t {
|
|
||||||
uint64_t tsc_frequency_hz;
|
|
||||||
};
|
|
||||||
|
|
||||||
optional<lapic_timer_calibration_t> calibrateTimer(const acpi::Madt& madt);
|
|
||||||
|
|
||||||
// TODO: when dynamic allocation and lists are available
|
|
||||||
// struct Timer {};
|
|
||||||
//
|
|
||||||
// Timer getCoreTimerInstance();
|
|
||||||
|
|
||||||
} // namespace apic
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "acpi/acpi.h"
|
#include "init/acpi.h"
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
#include "util/number.h"
|
#include "util/number.h"
|
||||||
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cpuid.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "util/optional.h"
|
|
||||||
|
|
||||||
struct cpuid_result_t {
|
|
||||||
uint32_t eax;
|
|
||||||
uint32_t ebx;
|
|
||||||
uint32_t ecx;
|
|
||||||
uint32_t edx;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline optional<cpuid_result_t> cpuid(uint32_t leaf, uint32_t subleaf = 0) {
|
|
||||||
cpuid_result_t result{};
|
|
||||||
if (__get_cpuid_count(leaf, subleaf, &result.eax, &result.ebx, &result.ecx, &result.edx) == 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/utility.h"
|
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
struct overloaded : Ts... {
|
struct overloaded : Ts... {
|
||||||
using Ts::operator()...;
|
using Ts::operator()...;
|
||||||
|
|
@ -9,17 +7,3 @@ struct overloaded : Ts... {
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
overloaded(Ts...) -> overloaded<Ts...>;
|
overloaded(Ts...) -> overloaded<Ts...>;
|
||||||
|
|
||||||
template<typename Func, typename... BoundArgs>
|
|
||||||
auto partial(Func func, BoundArgs... bound_args) {
|
|
||||||
return [func, bound_args...](auto&&... call_args) {
|
|
||||||
return func(bound_args..., forward<decltype(call_args)>(call_args)...);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Type>
|
|
||||||
auto construct() {
|
|
||||||
return [](auto&&... args) {
|
|
||||||
return Type{forward<decltype(args)>(args)...};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@
|
||||||
// instead of <utility>. The CrackOS3 value_or_panic() helper is omitted because
|
// instead of <utility>. The CrackOS3 value_or_panic() helper is omitted because
|
||||||
// there is no global panic() in this tree yet.
|
// there is no global panic() in this tree yet.
|
||||||
|
|
||||||
struct nullopt_t {};
|
|
||||||
inline constexpr nullopt_t nullopt{};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct optional {
|
struct optional {
|
||||||
private:
|
private:
|
||||||
|
|
@ -29,7 +26,6 @@ public:
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
constexpr optional() : initialized(false) {}
|
constexpr optional() : initialized(false) {}
|
||||||
constexpr optional(nullopt_t) : initialized(false) {}
|
|
||||||
optional(const T& value) : initialized(true) {
|
optional(const T& value) : initialized(true) {
|
||||||
new (buffer) T(value);
|
new (buffer) T(value);
|
||||||
}
|
}
|
||||||
|
|
@ -139,45 +135,10 @@ public:
|
||||||
return !initialized;
|
return !initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Func>
|
template<typename R, typename Func, typename... ArgT>
|
||||||
auto map(Func&& func) -> optional<decltype(func(value()))> {
|
optional<R> map(Func func, ArgT... args) {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return func(value());
|
return func(value(), forward<ArgT>(args)...);
|
||||||
} else {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Func>
|
|
||||||
auto map(Func&& func) const -> optional<decltype(func(value()))> {
|
|
||||||
if (initialized) {
|
|
||||||
return func(value());
|
|
||||||
} else {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Func>
|
|
||||||
optional or_else(Func&& func) const {
|
|
||||||
if (initialized) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
return func();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Func>
|
|
||||||
auto bind(Func&& func) -> decltype(func(value())) {
|
|
||||||
if (initialized) {
|
|
||||||
return func(value());
|
|
||||||
} else {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Func>
|
|
||||||
auto bind(Func&& func) const -> decltype(func(value())) {
|
|
||||||
if (initialized) {
|
|
||||||
return func(value());
|
|
||||||
} else {
|
} else {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,6 @@ struct remove_reference<T&&> {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using remove_reference_t = typename remove_reference<T>::type;
|
using remove_reference_t = typename remove_reference<T>::type;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline constexpr bool is_void_v = false;
|
|
||||||
template<>
|
|
||||||
inline constexpr bool is_void_v<void> = true;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr remove_reference_t<T>&& move(T&& value) {
|
constexpr remove_reference_t<T>&& move(T&& value) {
|
||||||
return static_cast<remove_reference_t<T>&&>(value);
|
return static_cast<remove_reference_t<T>&&>(value);
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
#include "apic/timer.h"
|
|
||||||
|
|
||||||
#include "util/cpuid.h"
|
|
||||||
#include "util/function.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr uint32_t feature_info_leaf = 0x1;
|
|
||||||
constexpr uint32_t tsc_crystal_ratio_leaf = 0x15;
|
|
||||||
constexpr uint32_t processor_frequency_leaf = 0x16;
|
|
||||||
|
|
||||||
constexpr uint32_t feature_edx_tsc = 1u << 4;
|
|
||||||
|
|
||||||
bool isTscSupported() {
|
|
||||||
return cpuid(feature_info_leaf)
|
|
||||||
.map([](const cpuid_result_t& features) {
|
|
||||||
return (features.edx & feature_edx_tsc) != 0;
|
|
||||||
})
|
|
||||||
.value_or(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<uint64_t> tscFrequencyFromCrystalRatio() {
|
|
||||||
return cpuid(tsc_crystal_ratio_leaf).bind([](const cpuid_result_t& ratio) -> optional<uint64_t> {
|
|
||||||
uint64_t denominator = ratio.eax;
|
|
||||||
uint64_t numerator = ratio.ebx;
|
|
||||||
uint64_t crystal_frequency_hz = ratio.ecx;
|
|
||||||
if (denominator == 0 || numerator == 0 || crystal_frequency_hz == 0) {
|
|
||||||
return nullopt;
|
|
||||||
}
|
|
||||||
return crystal_frequency_hz * numerator / denominator;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<uint64_t> tscFrequencyFromProcessorBase() {
|
|
||||||
return cpuid(processor_frequency_leaf).bind([](const cpuid_result_t& frequency_info) -> optional<uint64_t> {
|
|
||||||
uint64_t base_frequency_mhz = frequency_info.eax & 0xFFFF;
|
|
||||||
if (base_frequency_mhz == 0) {
|
|
||||||
return nullopt;
|
|
||||||
}
|
|
||||||
return base_frequency_mhz * 1'000'000;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<uint64_t> tscFrequency() {
|
|
||||||
return tscFrequencyFromCrystalRatio().or_else(tscFrequencyFromProcessorBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
optional<apic::lapic_timer_calibration_t> apic::calibrateTimer(const acpi::Madt&) {
|
|
||||||
if (!isTscSupported()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return tscFrequency().map(construct<lapic_timer_calibration_t>());
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#include "init/init.h"
|
#include "init/init.h"
|
||||||
#include "acpi/acpi.h"
|
#include "init/acpi.h"
|
||||||
#include "acpi/madt.h"
|
#include "init/apic.h"
|
||||||
#include "init/multiboot2.h"
|
#include "init/multiboot2.h"
|
||||||
#include "init/print.h"
|
#include "init/print.h"
|
||||||
#include "memory/allocator.h"
|
#include "memory/allocator.h"
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
#include "memory/sections.h"
|
#include "memory/sections.h"
|
||||||
#include "util/utility.h"
|
|
||||||
|
|
||||||
[[maybe_unused]] [[noreturn]] __attribute__((used)) static void halt() {
|
[[maybe_unused]] [[noreturn]] __attribute__((used)) static void halt() {
|
||||||
while (true)
|
while (true)
|
||||||
|
|
@ -19,30 +18,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
static int step_depth = 0;
|
static int step_depth = 0;
|
||||||
|
template<typename T>
|
||||||
static void print_step_boundary(const char* prefix, const char* name) {
|
static void step(const char* name, T&& fn) {
|
||||||
for (int i = 0; i < step_depth; ++i) {
|
for (int i = 0; i < step_depth; ++i) {
|
||||||
print(" ");
|
print(" ");
|
||||||
}
|
}
|
||||||
print(prefix);
|
print("Starting ");
|
||||||
print(name);
|
print(name);
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Fn>
|
|
||||||
static auto step(const char* name, Fn&& fn) {
|
|
||||||
print_step_boundary("Starting ", name);
|
|
||||||
++step_depth;
|
++step_depth;
|
||||||
if constexpr (is_void_v<decltype(fn())>) {
|
fn();
|
||||||
fn();
|
--step_depth;
|
||||||
--step_depth;
|
for (int i = 0; i < step_depth; ++i) {
|
||||||
print_step_boundary("Finished ", name);
|
print(" ");
|
||||||
} else {
|
|
||||||
auto result = fn();
|
|
||||||
--step_depth;
|
|
||||||
print_step_boundary("Finished ", name);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
print("Finished ");
|
||||||
|
print(name);
|
||||||
|
print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fn>
|
template<typename Fn>
|
||||||
|
|
@ -153,9 +145,14 @@ void PhysicalAllocator::init(const multiboot::tag_mmap* multiboot_info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupMemory() {
|
static void setupMemory() {
|
||||||
multiboot::visit_all(overloaded{[](const multiboot::tag_mmap* mem) {
|
multiboot::visit_all(
|
||||||
PhysicalAllocator::init(mem);
|
overloaded{
|
||||||
}});
|
[](const multiboot::tag_mmap* mem) {
|
||||||
|
PhysicalAllocator::init(mem);
|
||||||
|
},
|
||||||
|
[](const auto* tag) {}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static paddr_t rsdp_physical_of(const uint8_t* rsdp_payload) {
|
static paddr_t rsdp_physical_of(const uint8_t* rsdp_payload) {
|
||||||
|
|
@ -176,7 +173,8 @@ static acpi::Rsdp findRsdp() {
|
||||||
if (!rsdp.has_value()) {
|
if (!rsdp.has_value()) {
|
||||||
rsdp = rsdp_physical_of(tag->rsdp);
|
rsdp = rsdp_physical_of(tag->rsdp);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
[&](const auto* tag) {}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -191,19 +189,18 @@ struct AcpiDiscoveryResult {
|
||||||
optional<acpi::Madt> madt;
|
optional<acpi::Madt> madt;
|
||||||
};
|
};
|
||||||
|
|
||||||
static AcpiDiscoveryResult setupAcpi() {
|
static void setupAcpi() {
|
||||||
AcpiDiscoveryResult res{};
|
auto rsdp = findRsdp();
|
||||||
res.rsdp = findRsdp();
|
rsdp.for_each_table(overloaded{[&](const acpi::sdt_header_t* header) {
|
||||||
res.rsdp->for_each_table(overloaded{[&](const acpi::madt_t* header) {
|
print(acpi::unfold_signature(header->signature).text);
|
||||||
res.madt = acpi::Madt{header};
|
print("\n");
|
||||||
}});
|
}});
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] [[noreturn]] __attribute__((used)) void init() {
|
[[maybe_unused]] [[noreturn]] __attribute__((used)) void init() {
|
||||||
initFromLow();
|
initFromLow();
|
||||||
print("Reached init\n");
|
print("Reached init\n");
|
||||||
step("memory", setupMemory);
|
step("memory", setupMemory);
|
||||||
auto acpi = step("acpi", setupAcpi);
|
step("acpi", setupAcpi);
|
||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue