ref: update formatting
This commit is contained in:
parent
7d0155d8ce
commit
ee097d6cdf
16 changed files with 419 additions and 420 deletions
8
.clang-format
Normal file
8
.clang-format
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 120
|
||||||
|
PointerAlignment: Left
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
BreakTemplateDeclarations: Yes
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/number.h"
|
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
|
#include "util/number.h"
|
||||||
|
|
||||||
namespace acpi {
|
namespace acpi {
|
||||||
|
|
||||||
constexpr uint32_t fold_signature(const char (&text)[5]) {
|
constexpr uint32_t fold_signature(const char (&text)[5]) {
|
||||||
return static_cast<uint32_t>(static_cast<uint8_t>(text[0]))
|
return static_cast<uint32_t>(static_cast<uint8_t>(text[0])) |
|
||||||
| static_cast<uint32_t>(static_cast<uint8_t>(text[1])) << 8
|
static_cast<uint32_t>(static_cast<uint8_t>(text[1])) << 8 |
|
||||||
| static_cast<uint32_t>(static_cast<uint8_t>(text[2])) << 16
|
static_cast<uint32_t>(static_cast<uint8_t>(text[2])) << 16 |
|
||||||
| static_cast<uint32_t>(static_cast<uint8_t>(text[3])) << 24;
|
static_cast<uint32_t>(static_cast<uint8_t>(text[3])) << 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class signature : uint32_t {
|
enum class signature : uint32_t {
|
||||||
|
|
@ -35,10 +35,10 @@ inline signature_text_t unfold_signature(uint32_t folded) {
|
||||||
struct sdt_header_t {
|
struct sdt_header_t {
|
||||||
uint32_t signature;
|
uint32_t signature;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint8_t revision;
|
uint8_t revision;
|
||||||
uint8_t checksum;
|
uint8_t checksum;
|
||||||
char oem_id[6];
|
char oem_id[6];
|
||||||
char oem_table_id[8];
|
char oem_table_id[8];
|
||||||
uint32_t oem_revision;
|
uint32_t oem_revision;
|
||||||
uint32_t creator_id;
|
uint32_t creator_id;
|
||||||
uint32_t creator_revision;
|
uint32_t creator_revision;
|
||||||
|
|
@ -46,16 +46,16 @@ struct sdt_header_t {
|
||||||
static_assert(sizeof(sdt_header_t) == 36);
|
static_assert(sizeof(sdt_header_t) == 36);
|
||||||
|
|
||||||
struct rsdp_t {
|
struct rsdp_t {
|
||||||
char signature[8];
|
char signature[8];
|
||||||
uint8_t checksum;
|
uint8_t checksum;
|
||||||
char oem_id[6];
|
char oem_id[6];
|
||||||
uint8_t revision;
|
uint8_t revision;
|
||||||
uint32_t rsdt_address;
|
uint32_t rsdt_address;
|
||||||
|
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint64_t xsdt_address;
|
uint64_t xsdt_address;
|
||||||
uint8_t extended_checksum;
|
uint8_t extended_checksum;
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(rsdp_t) == 36);
|
static_assert(sizeof(rsdp_t) == 36);
|
||||||
|
|
||||||
|
|
@ -80,17 +80,18 @@ struct Rsdp {
|
||||||
private:
|
private:
|
||||||
template<typename Fn>
|
template<typename Fn>
|
||||||
static void dispatch(const sdt_header_t* header, Fn&& fn) {
|
static void dispatch(const sdt_header_t* header, Fn&& fn) {
|
||||||
#define ACPI_DISPATCH(signature_enum, TableType) \
|
#define ACPI_DISPATCH(signature_enum, TableType) \
|
||||||
case signature::signature_enum: \
|
case signature::signature_enum: \
|
||||||
if constexpr (requires { fn(static_cast<const TableType*>(nullptr)); }) { \
|
if constexpr (requires { fn(static_cast<const TableType*>(nullptr)); }) { \
|
||||||
fn(reinterpret_cast<const TableType*>(header)); \
|
fn(reinterpret_cast<const TableType*>(header)); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (static_cast<signature>(header->signature)) {
|
switch (static_cast<signature>(header->signature)) {
|
||||||
ACPI_DISPATCH(madt, madt_t)
|
ACPI_DISPATCH(madt, madt_t)
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ACPI_DISPATCH
|
#undef ACPI_DISPATCH
|
||||||
|
|
@ -100,9 +101,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uses_xsdt() {
|
bool uses_xsdt() { return physical.access<rsdp_t>()->revision >= 2; }
|
||||||
return physical.access<rsdp_t>()->revision >= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
paddr_t root_table() {
|
paddr_t root_table() {
|
||||||
auto rsdp = physical.access<rsdp_t>();
|
auto rsdp = physical.access<rsdp_t>();
|
||||||
|
|
|
||||||
|
|
@ -7,187 +7,184 @@
|
||||||
namespace acpi {
|
namespace acpi {
|
||||||
|
|
||||||
enum class madt_entry_type : uint8_t {
|
enum class madt_entry_type : uint8_t {
|
||||||
local_apic = 0,
|
local_apic = 0,
|
||||||
io_apic = 1,
|
io_apic = 1,
|
||||||
interrupt_source_override = 2,
|
interrupt_source_override = 2,
|
||||||
nmi_source = 3,
|
nmi_source = 3,
|
||||||
local_apic_nmi = 4,
|
local_apic_nmi = 4,
|
||||||
local_apic_address_override = 5,
|
local_apic_address_override = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline constexpr const char *get_madt_entry_type_name(madt_entry_type type) {
|
inline constexpr const char* get_madt_entry_type_name(madt_entry_type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case madt_entry_type::local_apic:
|
case madt_entry_type::local_apic:
|
||||||
return "local_apic";
|
return "local_apic";
|
||||||
case madt_entry_type::io_apic:
|
case madt_entry_type::io_apic:
|
||||||
return "io_apic";
|
return "io_apic";
|
||||||
case madt_entry_type::interrupt_source_override:
|
case madt_entry_type::interrupt_source_override:
|
||||||
return "interrupt_source_override";
|
return "interrupt_source_override";
|
||||||
case madt_entry_type::nmi_source:
|
case madt_entry_type::nmi_source:
|
||||||
return "nmi_source";
|
return "nmi_source";
|
||||||
case madt_entry_type::local_apic_nmi:
|
case madt_entry_type::local_apic_nmi:
|
||||||
return "local_apic_nmi";
|
return "local_apic_nmi";
|
||||||
case madt_entry_type::local_apic_address_override:
|
case madt_entry_type::local_apic_address_override:
|
||||||
return "local_apic_address_override";
|
return "local_apic_address_override";
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct madt_flags_t {
|
struct madt_flags_t {
|
||||||
uint32_t dual_8259_present : 1;
|
uint32_t dual_8259_present : 1;
|
||||||
uint32_t reserved : 31;
|
uint32_t reserved : 31;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(madt_flags_t) == 4);
|
static_assert(sizeof(madt_flags_t) == 4);
|
||||||
|
|
||||||
struct local_apic_flags_t {
|
struct local_apic_flags_t {
|
||||||
uint32_t enabled : 1;
|
uint32_t enabled : 1;
|
||||||
uint32_t online_capable : 1;
|
uint32_t online_capable : 1;
|
||||||
uint32_t reserved : 30;
|
uint32_t reserved : 30;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(local_apic_flags_t) == 4);
|
static_assert(sizeof(local_apic_flags_t) == 4);
|
||||||
|
|
||||||
enum class inti_polarity : uint16_t {
|
enum class inti_polarity : uint16_t {
|
||||||
bus_default = 0,
|
bus_default = 0,
|
||||||
active_high = 1,
|
active_high = 1,
|
||||||
active_low = 3,
|
active_low = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class inti_trigger_mode : uint16_t {
|
enum class inti_trigger_mode : uint16_t {
|
||||||
bus_default = 0,
|
bus_default = 0,
|
||||||
edge = 1,
|
edge = 1,
|
||||||
level = 3,
|
level = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct inti_flags_t {
|
struct inti_flags_t {
|
||||||
inti_polarity polarity : 2;
|
inti_polarity polarity : 2;
|
||||||
inti_trigger_mode trigger_mode : 2;
|
inti_trigger_mode trigger_mode : 2;
|
||||||
uint16_t reserved : 12;
|
uint16_t reserved : 12;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(inti_flags_t) == 2);
|
static_assert(sizeof(inti_flags_t) == 2);
|
||||||
|
|
||||||
struct madt_t {
|
struct madt_t {
|
||||||
sdt_header_t header;
|
sdt_header_t header;
|
||||||
uint32_t local_apic_address;
|
uint32_t local_apic_address;
|
||||||
madt_flags_t flags;
|
madt_flags_t flags;
|
||||||
uint8_t entries[0];
|
uint8_t entries[0];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_t) == 44);
|
static_assert(sizeof(madt_t) == 44);
|
||||||
|
|
||||||
struct madt_entry_t {
|
struct madt_entry_t {
|
||||||
madt_entry_type type;
|
madt_entry_type type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_entry_t) == 2);
|
static_assert(sizeof(madt_entry_t) == 2);
|
||||||
|
|
||||||
struct madt_local_apic_t {
|
struct madt_local_apic_t {
|
||||||
madt_entry_type type;
|
madt_entry_type type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
uint8_t acpi_processor_uid;
|
uint8_t acpi_processor_uid;
|
||||||
uint8_t apic_id;
|
uint8_t apic_id;
|
||||||
local_apic_flags_t flags;
|
local_apic_flags_t flags;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_local_apic_t) == 8);
|
static_assert(sizeof(madt_local_apic_t) == 8);
|
||||||
|
|
||||||
struct madt_io_apic_t {
|
struct madt_io_apic_t {
|
||||||
madt_entry_type type;
|
madt_entry_type type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
uint8_t io_apic_id;
|
uint8_t io_apic_id;
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
uint32_t io_apic_address;
|
uint32_t io_apic_address;
|
||||||
uint32_t global_system_interrupt_base;
|
uint32_t global_system_interrupt_base;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_io_apic_t) == 12);
|
static_assert(sizeof(madt_io_apic_t) == 12);
|
||||||
|
|
||||||
struct madt_interrupt_source_override_t {
|
struct madt_interrupt_source_override_t {
|
||||||
madt_entry_type type;
|
madt_entry_type type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
uint8_t bus; // always 0 (ISA)
|
uint8_t bus; // always 0 (ISA)
|
||||||
uint8_t source; // ISA IRQ number
|
uint8_t source; // ISA IRQ number
|
||||||
uint32_t global_system_interrupt;
|
uint32_t global_system_interrupt;
|
||||||
inti_flags_t flags;
|
inti_flags_t flags;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_interrupt_source_override_t) == 10);
|
static_assert(sizeof(madt_interrupt_source_override_t) == 10);
|
||||||
|
|
||||||
struct madt_nmi_source_t {
|
struct madt_nmi_source_t {
|
||||||
madt_entry_type type;
|
madt_entry_type type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
inti_flags_t flags;
|
inti_flags_t flags;
|
||||||
uint32_t global_system_interrupt;
|
uint32_t global_system_interrupt;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_nmi_source_t) == 8);
|
static_assert(sizeof(madt_nmi_source_t) == 8);
|
||||||
|
|
||||||
struct madt_local_apic_nmi_t {
|
struct madt_local_apic_nmi_t {
|
||||||
madt_entry_type type;
|
madt_entry_type type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
uint8_t acpi_processor_uid; // 0xFF: applies to all processors
|
uint8_t acpi_processor_uid; // 0xFF: applies to all processors
|
||||||
inti_flags_t flags;
|
inti_flags_t flags;
|
||||||
uint8_t lint; // local APIC LINT# the NMI is wired to
|
uint8_t lint; // local APIC LINT# the NMI is wired to
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_local_apic_nmi_t) == 6);
|
static_assert(sizeof(madt_local_apic_nmi_t) == 6);
|
||||||
|
|
||||||
struct madt_local_apic_address_override_t {
|
struct madt_local_apic_address_override_t {
|
||||||
madt_entry_type type;
|
madt_entry_type type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
uint16_t reserved;
|
uint16_t reserved;
|
||||||
uint64_t local_apic_address;
|
uint64_t local_apic_address;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static_assert(sizeof(madt_local_apic_address_override_t) == 12);
|
static_assert(sizeof(madt_local_apic_address_override_t) == 12);
|
||||||
|
|
||||||
struct Madt {
|
struct Madt {
|
||||||
explicit Madt(paddr_t madt_physical)
|
explicit Madt(paddr_t madt_physical) : table(madt_physical.access<madt_t>()) {}
|
||||||
: table(madt_physical.access<madt_t>()) {}
|
explicit Madt(const madt_t* madt_table) : table(madt_table) {}
|
||||||
explicit Madt(const madt_t *madt_table) : table(madt_table) {}
|
|
||||||
|
|
||||||
paddr_t local_apic_address() {
|
paddr_t local_apic_address() {
|
||||||
uint64_t address = table->local_apic_address;
|
uint64_t address = table->local_apic_address;
|
||||||
for_each_entry(
|
for_each_entry([&](const madt_local_apic_address_override_t* override_entry) {
|
||||||
[&](const madt_local_apic_address_override_t *override_entry) {
|
address = override_entry->local_apic_address;
|
||||||
address = override_entry->local_apic_address;
|
|
||||||
});
|
});
|
||||||
return paddr_t{address};
|
return paddr_t{address};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_legacy_pic() { return table->flags.dual_8259_present != 0; }
|
bool has_legacy_pic() { return table->flags.dual_8259_present != 0; }
|
||||||
|
|
||||||
template <typename Fn> void for_each_entry(Fn &&callback) {
|
template<typename Fn>
|
||||||
auto ptr = table->entries;
|
void for_each_entry(Fn&& callback) {
|
||||||
const auto end =
|
auto ptr = table->entries;
|
||||||
reinterpret_cast<const uint8_t *>(table) + table->header.length;
|
const auto end = reinterpret_cast<const uint8_t*>(table) + table->header.length;
|
||||||
while (ptr < end) {
|
while (ptr < end) {
|
||||||
auto entry = reinterpret_cast<const madt_entry_t *>(ptr);
|
auto entry = reinterpret_cast<const madt_entry_t*>(ptr);
|
||||||
if (entry->length < sizeof(madt_entry_t)) {
|
if (entry->length < sizeof(madt_entry_t)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dispatch(entry, callback);
|
dispatch(entry, callback);
|
||||||
ptr += entry->length;
|
ptr += entry->length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Fn>
|
template<typename Fn>
|
||||||
static void dispatch(const madt_entry_t *entry, Fn &&fn) {
|
static void dispatch(const madt_entry_t* entry, Fn&& fn) {
|
||||||
#define MADT_DISPATCH(entry_enum, EntryType) \
|
#define MADT_DISPATCH(entry_enum, EntryType) \
|
||||||
case madt_entry_type::entry_enum: \
|
case madt_entry_type::entry_enum: \
|
||||||
if constexpr (requires { fn(static_cast<const EntryType *>(nullptr)); }) \
|
if constexpr (requires { fn(static_cast<const EntryType*>(nullptr)); }) \
|
||||||
fn(reinterpret_cast<const EntryType *>(entry)); \
|
fn(reinterpret_cast<const EntryType*>(entry)); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (entry->type) {
|
switch (entry->type) {
|
||||||
MADT_DISPATCH(local_apic, madt_local_apic_t)
|
MADT_DISPATCH(local_apic, madt_local_apic_t)
|
||||||
MADT_DISPATCH(io_apic, madt_io_apic_t)
|
MADT_DISPATCH(io_apic, madt_io_apic_t)
|
||||||
MADT_DISPATCH(interrupt_source_override, madt_interrupt_source_override_t)
|
MADT_DISPATCH(interrupt_source_override, madt_interrupt_source_override_t)
|
||||||
MADT_DISPATCH(nmi_source, madt_nmi_source_t)
|
MADT_DISPATCH(nmi_source, madt_nmi_source_t)
|
||||||
MADT_DISPATCH(local_apic_nmi, madt_local_apic_nmi_t)
|
MADT_DISPATCH(local_apic_nmi, madt_local_apic_nmi_t)
|
||||||
MADT_DISPATCH(local_apic_address_override,
|
MADT_DISPATCH(local_apic_address_override, madt_local_apic_address_override_t)
|
||||||
madt_local_apic_address_override_t)
|
default:
|
||||||
default:
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#undef MADT_DISPATCH
|
#undef MADT_DISPATCH
|
||||||
}
|
}
|
||||||
|
|
||||||
const madt_t *table;
|
const madt_t* table;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace acpi
|
} // namespace acpi
|
||||||
|
|
|
||||||
|
|
@ -1,89 +1,117 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/number.h"
|
|
||||||
#include "util/function.h"
|
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
|
#include "util/function.h"
|
||||||
|
#include "util/number.h"
|
||||||
|
|
||||||
namespace multiboot {
|
namespace multiboot {
|
||||||
|
|
||||||
inline constexpr uint32_t magic = 0x36d76289;
|
inline constexpr uint32_t magic = 0x36d76289;
|
||||||
inline constexpr uint32_t alignment = 8;
|
inline constexpr uint32_t alignment = 8;
|
||||||
|
|
||||||
enum class tag_type : uint32_t {
|
enum class tag_type : uint32_t {
|
||||||
end = 0,
|
end = 0,
|
||||||
cmdline = 1,
|
cmdline = 1,
|
||||||
boot_loader_name = 2,
|
boot_loader_name = 2,
|
||||||
module = 3,
|
module = 3,
|
||||||
basic_meminfo = 4,
|
basic_meminfo = 4,
|
||||||
bootdev = 5,
|
bootdev = 5,
|
||||||
mmap = 6,
|
mmap = 6,
|
||||||
vbe = 7,
|
vbe = 7,
|
||||||
framebuffer = 8,
|
framebuffer = 8,
|
||||||
elf_sections = 9,
|
elf_sections = 9,
|
||||||
apm = 10,
|
apm = 10,
|
||||||
efi32 = 11,
|
efi32 = 11,
|
||||||
efi64 = 12,
|
efi64 = 12,
|
||||||
smbios = 13,
|
smbios = 13,
|
||||||
acpi_old = 14,
|
acpi_old = 14,
|
||||||
acpi_new = 15,
|
acpi_new = 15,
|
||||||
network = 16,
|
network = 16,
|
||||||
efi_mmap = 17,
|
efi_mmap = 17,
|
||||||
efi_bs = 18,
|
efi_bs = 18,
|
||||||
efi32_ih = 19,
|
efi32_ih = 19,
|
||||||
efi64_ih = 20,
|
efi64_ih = 20,
|
||||||
load_base_addr = 21,
|
load_base_addr = 21,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline constexpr const char* get_tag_name(tag_type type) {
|
inline constexpr const char* get_tag_name(tag_type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case tag_type::end: return "end";
|
case tag_type::end:
|
||||||
case tag_type::cmdline: return "cmdline";
|
return "end";
|
||||||
case tag_type::boot_loader_name: return "boot_loader_name";
|
case tag_type::cmdline:
|
||||||
case tag_type::module: return "module";
|
return "cmdline";
|
||||||
case tag_type::basic_meminfo: return "basic_meminfo";
|
case tag_type::boot_loader_name:
|
||||||
case tag_type::bootdev: return "bootdev";
|
return "boot_loader_name";
|
||||||
case tag_type::mmap: return "mmap";
|
case tag_type::module:
|
||||||
case tag_type::vbe: return "vbe";
|
return "module";
|
||||||
case tag_type::framebuffer: return "framebuffer";
|
case tag_type::basic_meminfo:
|
||||||
case tag_type::elf_sections: return "elf_sections";
|
return "basic_meminfo";
|
||||||
case tag_type::apm: return "apm";
|
case tag_type::bootdev:
|
||||||
case tag_type::efi32: return "efi32";
|
return "bootdev";
|
||||||
case tag_type::efi64: return "efi64";
|
case tag_type::mmap:
|
||||||
case tag_type::smbios: return "smbios";
|
return "mmap";
|
||||||
case tag_type::acpi_old: return "acpi_old";
|
case tag_type::vbe:
|
||||||
case tag_type::acpi_new: return "acpi_new";
|
return "vbe";
|
||||||
case tag_type::network: return "network";
|
case tag_type::framebuffer:
|
||||||
case tag_type::efi_mmap: return "efi_mmap";
|
return "framebuffer";
|
||||||
case tag_type::efi_bs: return "efi_bs";
|
case tag_type::elf_sections:
|
||||||
case tag_type::efi32_ih: return "efi32_ih";
|
return "elf_sections";
|
||||||
case tag_type::efi64_ih: return "efi64_ih";
|
case tag_type::apm:
|
||||||
case tag_type::load_base_addr: return "load_base_addr";
|
return "apm";
|
||||||
|
case tag_type::efi32:
|
||||||
|
return "efi32";
|
||||||
|
case tag_type::efi64:
|
||||||
|
return "efi64";
|
||||||
|
case tag_type::smbios:
|
||||||
|
return "smbios";
|
||||||
|
case tag_type::acpi_old:
|
||||||
|
return "acpi_old";
|
||||||
|
case tag_type::acpi_new:
|
||||||
|
return "acpi_new";
|
||||||
|
case tag_type::network:
|
||||||
|
return "network";
|
||||||
|
case tag_type::efi_mmap:
|
||||||
|
return "efi_mmap";
|
||||||
|
case tag_type::efi_bs:
|
||||||
|
return "efi_bs";
|
||||||
|
case tag_type::efi32_ih:
|
||||||
|
return "efi32_ih";
|
||||||
|
case tag_type::efi64_ih:
|
||||||
|
return "efi64_ih";
|
||||||
|
case tag_type::load_base_addr:
|
||||||
|
return "load_base_addr";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class framebuffer_type : uint8_t {
|
enum class framebuffer_type : uint8_t {
|
||||||
indexed = 0,
|
indexed = 0,
|
||||||
rgb = 1,
|
rgb = 1,
|
||||||
ega_text = 2,
|
ega_text = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class mem_type : uint32_t {
|
enum class mem_type : uint32_t {
|
||||||
available = 1,
|
available = 1,
|
||||||
reserved = 2,
|
reserved = 2,
|
||||||
acpi_reclaimable = 3,
|
acpi_reclaimable = 3,
|
||||||
nvs = 4,
|
nvs = 4,
|
||||||
badram = 5,
|
badram = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline constexpr const char* get_mem_type_name(mem_type type) {
|
inline constexpr const char* get_mem_type_name(mem_type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case mem_type::available: return "available";
|
case mem_type::available:
|
||||||
case mem_type::reserved: return "reserved";
|
return "available";
|
||||||
case mem_type::acpi_reclaimable: return "acpi_reclaimable";
|
case mem_type::reserved:
|
||||||
case mem_type::nvs: return "nvs";
|
return "reserved";
|
||||||
case mem_type::badram: return "badram";
|
case mem_type::acpi_reclaimable:
|
||||||
default: return "unknown";
|
return "acpi_reclaimable";
|
||||||
|
case mem_type::nvs:
|
||||||
|
return "nvs";
|
||||||
|
case mem_type::badram:
|
||||||
|
return "badram";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +136,7 @@ struct tag {
|
||||||
struct tag_string {
|
struct tag_string {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
char string[0];
|
char string[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_module {
|
struct tag_module {
|
||||||
|
|
@ -116,7 +144,7 @@ struct tag_module {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t mod_start;
|
uint32_t mod_start;
|
||||||
uint32_t mod_end;
|
uint32_t mod_end;
|
||||||
char cmdline[0];
|
char cmdline[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_basic_meminfo {
|
struct tag_basic_meminfo {
|
||||||
|
|
@ -135,11 +163,11 @@ struct tag_bootdev {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_mmap {
|
struct tag_mmap {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t entry_size;
|
uint32_t entry_size;
|
||||||
uint32_t entry_version;
|
uint32_t entry_version;
|
||||||
mem_entry entries[0];
|
mem_entry entries[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vbe_info_block {
|
struct vbe_info_block {
|
||||||
|
|
@ -151,32 +179,31 @@ struct vbe_mode_info_block {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_vbe {
|
struct tag_vbe {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint16_t vbe_mode;
|
uint16_t vbe_mode;
|
||||||
uint16_t vbe_interface_seg;
|
uint16_t vbe_interface_seg;
|
||||||
uint16_t vbe_interface_off;
|
uint16_t vbe_interface_off;
|
||||||
uint16_t vbe_interface_len;
|
uint16_t vbe_interface_len;
|
||||||
vbe_info_block vbe_control_info;
|
vbe_info_block vbe_control_info;
|
||||||
vbe_mode_info_block vbe_mode_info;
|
vbe_mode_info_block vbe_mode_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct tag_framebuffer {
|
struct tag_framebuffer {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint64_t framebuffer_addr;
|
uint64_t framebuffer_addr;
|
||||||
uint32_t framebuffer_pitch;
|
uint32_t framebuffer_pitch;
|
||||||
uint32_t framebuffer_width;
|
uint32_t framebuffer_width;
|
||||||
uint32_t framebuffer_height;
|
uint32_t framebuffer_height;
|
||||||
uint8_t framebuffer_bpp;
|
uint8_t framebuffer_bpp;
|
||||||
framebuffer_type framebuffer_type;
|
framebuffer_type framebuffer_type;
|
||||||
uint16_t reserved;
|
uint16_t reserved;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
uint16_t framebuffer_palette_num_colors;
|
uint16_t framebuffer_palette_num_colors;
|
||||||
color framebuffer_palette[0];
|
color framebuffer_palette[0];
|
||||||
};
|
};
|
||||||
struct {
|
struct {
|
||||||
uint8_t framebuffer_red_field_position;
|
uint8_t framebuffer_red_field_position;
|
||||||
|
|
@ -195,7 +222,7 @@ struct tag_elf_sections {
|
||||||
uint32_t num;
|
uint32_t num;
|
||||||
uint32_t entsize;
|
uint32_t entsize;
|
||||||
uint32_t shndx;
|
uint32_t shndx;
|
||||||
char sections[0];
|
char sections[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_apm {
|
struct tag_apm {
|
||||||
|
|
@ -227,28 +254,28 @@ struct tag_efi64 {
|
||||||
struct tag_smbios {
|
struct tag_smbios {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t major;
|
uint8_t major;
|
||||||
uint8_t minor;
|
uint8_t minor;
|
||||||
uint8_t reserved[6];
|
uint8_t reserved[6];
|
||||||
uint8_t tables[0];
|
uint8_t tables[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_old_acpi {
|
struct tag_old_acpi {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t rsdp[0];
|
uint8_t rsdp[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_new_acpi {
|
struct tag_new_acpi {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t rsdp[0];
|
uint8_t rsdp[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_network {
|
struct tag_network {
|
||||||
tag_type type;
|
tag_type type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t dhcpack[0];
|
uint8_t dhcpack[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_efi_mmap {
|
struct tag_efi_mmap {
|
||||||
|
|
@ -256,7 +283,7 @@ struct tag_efi_mmap {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t descr_size;
|
uint32_t descr_size;
|
||||||
uint32_t descr_vers;
|
uint32_t descr_vers;
|
||||||
uint8_t efi_mmap[0];
|
uint8_t efi_mmap[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tag_efi32_ih {
|
struct tag_efi32_ih {
|
||||||
|
|
@ -290,34 +317,35 @@ inline info* get_multiboot_info() {
|
||||||
|
|
||||||
template<typename Fn>
|
template<typename Fn>
|
||||||
void visit(const tag* t, Fn&& fn) {
|
void visit(const tag* t, Fn&& fn) {
|
||||||
#define MB_DISPATCH(tag_enum, TagType) \
|
#define MB_DISPATCH(tag_enum, TagType) \
|
||||||
case tag_type::tag_enum: \
|
case tag_type::tag_enum: \
|
||||||
if constexpr (requires { fn(static_cast<const TagType*>(nullptr)); }) \
|
if constexpr (requires { fn(static_cast<const TagType*>(nullptr)); }) \
|
||||||
fn(reinterpret_cast<const TagType*>(t)); \
|
fn(reinterpret_cast<const TagType*>(t)); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (t->type) {
|
switch (t->type) {
|
||||||
MB_DISPATCH(cmdline, tag_string)
|
MB_DISPATCH(cmdline, tag_string)
|
||||||
MB_DISPATCH(boot_loader_name, tag_string)
|
MB_DISPATCH(boot_loader_name, tag_string)
|
||||||
MB_DISPATCH(module, tag_module)
|
MB_DISPATCH(module, tag_module)
|
||||||
MB_DISPATCH(basic_meminfo, tag_basic_meminfo)
|
MB_DISPATCH(basic_meminfo, tag_basic_meminfo)
|
||||||
MB_DISPATCH(bootdev, tag_bootdev)
|
MB_DISPATCH(bootdev, tag_bootdev)
|
||||||
MB_DISPATCH(mmap, tag_mmap)
|
MB_DISPATCH(mmap, tag_mmap)
|
||||||
MB_DISPATCH(vbe, tag_vbe)
|
MB_DISPATCH(vbe, tag_vbe)
|
||||||
MB_DISPATCH(framebuffer, tag_framebuffer)
|
MB_DISPATCH(framebuffer, tag_framebuffer)
|
||||||
MB_DISPATCH(elf_sections, tag_elf_sections)
|
MB_DISPATCH(elf_sections, tag_elf_sections)
|
||||||
MB_DISPATCH(apm, tag_apm)
|
MB_DISPATCH(apm, tag_apm)
|
||||||
MB_DISPATCH(efi32, tag_efi32)
|
MB_DISPATCH(efi32, tag_efi32)
|
||||||
MB_DISPATCH(efi64, tag_efi64)
|
MB_DISPATCH(efi64, tag_efi64)
|
||||||
MB_DISPATCH(smbios, tag_smbios)
|
MB_DISPATCH(smbios, tag_smbios)
|
||||||
MB_DISPATCH(acpi_old, tag_old_acpi)
|
MB_DISPATCH(acpi_old, tag_old_acpi)
|
||||||
MB_DISPATCH(acpi_new, tag_new_acpi)
|
MB_DISPATCH(acpi_new, tag_new_acpi)
|
||||||
MB_DISPATCH(network, tag_network)
|
MB_DISPATCH(network, tag_network)
|
||||||
MB_DISPATCH(efi_mmap, tag_efi_mmap)
|
MB_DISPATCH(efi_mmap, tag_efi_mmap)
|
||||||
MB_DISPATCH(efi32_ih, tag_efi32_ih)
|
MB_DISPATCH(efi32_ih, tag_efi32_ih)
|
||||||
MB_DISPATCH(efi64_ih, tag_efi64_ih)
|
MB_DISPATCH(efi64_ih, tag_efi64_ih)
|
||||||
MB_DISPATCH(load_base_addr, tag_load_base_addr)
|
MB_DISPATCH(load_base_addr, tag_load_base_addr)
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MB_DISPATCH
|
#undef MB_DISPATCH
|
||||||
|
|
@ -329,7 +357,8 @@ void visit_all(const info* mb, Fn&& fn) {
|
||||||
const auto end = reinterpret_cast<const uint8_t*>(mb) + mb->total_size;
|
const auto end = reinterpret_cast<const uint8_t*>(mb) + mb->total_size;
|
||||||
while (ptr < end) {
|
while (ptr < end) {
|
||||||
auto t = reinterpret_cast<const tag*>(ptr);
|
auto t = reinterpret_cast<const tag*>(ptr);
|
||||||
if (t->type == tag_type::end) break;
|
if (t->type == tag_type::end)
|
||||||
|
break;
|
||||||
visit(t, fn);
|
visit(t, fn);
|
||||||
ptr += (t->size + alignment - 1) & ~(alignment - 1);
|
ptr += (t->size + alignment - 1) & ~(alignment - 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,22 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
enum class Color : uint8_t {
|
enum class Color : uint8_t {
|
||||||
Black = 0,
|
Black = 0,
|
||||||
Blue = 1,
|
Blue = 1,
|
||||||
Green = 2,
|
Green = 2,
|
||||||
Cyan = 3,
|
Cyan = 3,
|
||||||
Red = 4,
|
Red = 4,
|
||||||
Magenta = 5,
|
Magenta = 5,
|
||||||
Brown = 6,
|
Brown = 6,
|
||||||
LightGray = 7,
|
LightGray = 7,
|
||||||
DarkGray = 8,
|
DarkGray = 8,
|
||||||
LightBlue = 9,
|
LightBlue = 9,
|
||||||
LightGreen = 10,
|
LightGreen = 10,
|
||||||
LightCyan = 11,
|
LightCyan = 11,
|
||||||
LightRed = 12,
|
LightRed = 12,
|
||||||
LightMagenta = 13,
|
LightMagenta = 13,
|
||||||
Yellow = 14,
|
Yellow = 14,
|
||||||
White = 15,
|
White = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextAttr {
|
struct TextAttr {
|
||||||
|
|
@ -27,9 +27,7 @@ struct TextAttr {
|
||||||
constexpr TextAttr(Color fg = Color::White, Color bg = Color::Black) : fg(fg), bg(bg) {}
|
constexpr TextAttr(Color fg = Color::White, Color bg = Color::Black) : fg(fg), bg(bg) {}
|
||||||
|
|
||||||
// Returns the attribute in the high byte, ready to OR with a character value.
|
// Returns the attribute in the high byte, ready to OR with a character value.
|
||||||
constexpr uint16_t word() const {
|
constexpr uint16_t word() const { return (uint16_t)(((uint8_t)bg << 4) | (uint8_t)fg) << 8; }
|
||||||
return (uint16_t)(((uint8_t)bg << 4) | (uint8_t)fg) << 8;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void initFromLow();
|
void initFromLow();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "init/multiboot2.h"
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
#include "util/optional.h"
|
#include "util/optional.h"
|
||||||
#include "init/multiboot2.h"
|
|
||||||
|
|
||||||
constexpr const size_t page_size = 4096;
|
constexpr const size_t page_size = 4096;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,19 @@
|
||||||
|
|
||||||
constexpr uint64_t high_base = 0xFFFF800000000000;
|
constexpr uint64_t high_base = 0xFFFF800000000000;
|
||||||
|
|
||||||
#define read_symbol(symbol) [](){uint64_t res; asm volatile("movabsq $" symbol ", %0": "=r"(res)); return res;}()
|
#define read_symbol(symbol) \
|
||||||
|
[]() { \
|
||||||
|
uint64_t res; \
|
||||||
|
asm volatile("movabsq $" symbol ", %0" : "=r"(res)); \
|
||||||
|
return res; \
|
||||||
|
}()
|
||||||
|
|
||||||
struct paddr_t {
|
struct paddr_t {
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* access() {
|
T* access() {
|
||||||
return reinterpret_cast<T*>(address+high_base);
|
return reinterpret_cast<T*>(address + high_base);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -25,14 +30,14 @@ inline void* operator new[](size_t, void* p) {
|
||||||
|
|
||||||
inline void* memcpy(void* dest, const void* src, size_t n) {
|
inline void* memcpy(void* dest, const void* src, size_t n) {
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
((uint8_t*) dest)[i] = ((uint8_t*) src)[i];
|
((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
|
||||||
}
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* memset(void* dest, int c, size_t n) {
|
inline void* memset(void* dest, int c, size_t n) {
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
((uint8_t*) dest)[i] = (uint8_t) c;
|
((uint8_t*)dest)[i] = (uint8_t)c;
|
||||||
}
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ struct KernelSection {
|
||||||
const char* name;
|
const char* name;
|
||||||
|
|
||||||
paddr_t phys_start() const { return paddr_t{vma_start >= high_base ? vma_start - high_base : vma_start}; }
|
paddr_t phys_start() const { return paddr_t{vma_start >= high_base ? vma_start - high_base : vma_start}; }
|
||||||
paddr_t phys_end() const { return paddr_t{vma_end >= high_base ? vma_end - high_base : vma_end}; }
|
paddr_t phys_end() const { return paddr_t{vma_end >= high_base ? vma_end - high_base : vma_end}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern KernelSection __reserved_ranges_start__[], __reserved_ranges_end__[];
|
extern KernelSection __reserved_ranges_start__[], __reserved_ranges_end__[];
|
||||||
|
|
@ -21,8 +21,7 @@ void for_each_reserved_section(Fn&& fn) {
|
||||||
inline bool is_in_reserved_section(paddr_t ptr, size_t size = 1) {
|
inline bool is_in_reserved_section(paddr_t ptr, size_t size = 1) {
|
||||||
bool res = false;
|
bool res = false;
|
||||||
for_each_reserved_section([&](const KernelSection& section) {
|
for_each_reserved_section([&](const KernelSection& section) {
|
||||||
if (ptr.address < section.phys_end().address &&
|
if (ptr.address < section.phys_end().address && section.phys_start().address < ptr.address + size) {
|
||||||
section.phys_start().address < ptr.address + size) {
|
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ private:
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
((T*) buffer)->~T();
|
((T*)buffer)->~T();
|
||||||
initialized = false;
|
initialized = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,12 +26,8 @@ public:
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
constexpr optional() : initialized(false) {}
|
constexpr optional() : initialized(false) {}
|
||||||
optional(const T& value) : initialized(true) {
|
optional(const T& value) : initialized(true) { new (buffer) T(value); }
|
||||||
new (buffer) T(value);
|
optional(T&& value) : initialized(true) { new (buffer) T(move(value)); }
|
||||||
}
|
|
||||||
optional(T&& value) : initialized(true) {
|
|
||||||
new (buffer) T(move(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
optional(const optional& other) : initialized(other.initialized) {
|
optional(const optional& other) : initialized(other.initialized) {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
|
|
@ -46,28 +42,19 @@ public:
|
||||||
other.initialized = false;
|
other.initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~optional() {
|
~optional() { destroy(); }
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator->() {
|
T* operator->() { return (T*)buffer; }
|
||||||
return (T*) buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator*() {
|
T& operator*() { return *((T*)buffer); }
|
||||||
return *((T*) buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
const T* operator->() const {
|
const T* operator->() const { return (const T*)buffer; }
|
||||||
return (const T*) buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T& operator*() const {
|
const T& operator*() const { return *((const T*)buffer); }
|
||||||
return *((const T*) buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
optional& operator=(const optional& other) {
|
optional& operator=(const optional& other) {
|
||||||
if (this == &other) return *this;
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
destroy();
|
destroy();
|
||||||
if (other.initialized) {
|
if (other.initialized) {
|
||||||
new (buffer) T(*other);
|
new (buffer) T(*other);
|
||||||
|
|
@ -77,7 +64,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
optional& operator=(optional&& other) noexcept {
|
optional& operator=(optional&& other) noexcept {
|
||||||
if (this == &other) return *this;
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
destroy();
|
destroy();
|
||||||
if (other.initialized) {
|
if (other.initialized) {
|
||||||
new (buffer) T(move(*other));
|
new (buffer) T(move(*other));
|
||||||
|
|
@ -87,17 +75,11 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool has_value() const {
|
[[nodiscard]] bool has_value() const { return initialized; }
|
||||||
return initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& value() {
|
T& value() { return *((T*)buffer); }
|
||||||
return *((T*) buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
const T& value() const {
|
const T& value() const { return *((const T*)buffer); }
|
||||||
return *((const T*) buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Func, typename... ArgT>
|
template<typename Func, typename... ArgT>
|
||||||
T value_or_create(Func func, ArgT... args) {
|
T value_or_create(Func func, ArgT... args) {
|
||||||
|
|
@ -119,19 +101,15 @@ public:
|
||||||
|
|
||||||
const T& value_or(const T& default_value) const {
|
const T& value_or(const T& default_value) const {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return *((const T*) buffer);
|
return *((const T*)buffer);
|
||||||
} else {
|
} else {
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const {
|
operator bool() const { return initialized; }
|
||||||
return initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!() const {
|
bool operator!() const { return !initialized; }
|
||||||
return !initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename Func, typename... ArgT>
|
template<typename R, typename Func, typename... ArgT>
|
||||||
optional<R> map(Func func, ArgT... args) {
|
optional<R> map(Func func, ArgT... args) {
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,17 @@
|
||||||
// Minimal freestanding replacements for <utility> (no stdlib available).
|
// Minimal freestanding replacements for <utility> (no stdlib available).
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct remove_reference { using type = T; };
|
struct remove_reference {
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct remove_reference<T&> { using type = T; };
|
struct remove_reference<T&> {
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct remove_reference<T&&> { using type = T; };
|
struct remove_reference<T&&> {
|
||||||
|
using type = 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;
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,4 @@ void __cxa_pure_virtual() {
|
||||||
__asm__ volatile("cli; hlt");
|
__asm__ volatile("cli; hlt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
#include "memory/pointer.h"
|
|
||||||
#include "memory/sections.h"
|
|
||||||
#include "init/init.h"
|
#include "init/init.h"
|
||||||
#include "init/multiboot2.h"
|
|
||||||
#include "init/print.h"
|
|
||||||
#include "init/acpi.h"
|
#include "init/acpi.h"
|
||||||
#include "init/apic.h"
|
#include "init/apic.h"
|
||||||
|
#include "init/multiboot2.h"
|
||||||
|
#include "init/print.h"
|
||||||
#include "memory/allocator.h"
|
#include "memory/allocator.h"
|
||||||
|
#include "memory/pointer.h"
|
||||||
|
#include "memory/sections.h"
|
||||||
|
|
||||||
[[maybe_unused]] [[noreturn]] __attribute__((used)) static void halt() {
|
[[maybe_unused]] [[noreturn]] __attribute__((used)) static void halt() {
|
||||||
while (true) __asm__ volatile ("hlt");
|
while (true)
|
||||||
|
__asm__ volatile("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] [[noreturn]] __attribute__((used)) static void panic(const char* msg) {
|
[[maybe_unused]] [[noreturn]] __attribute__((used)) static void panic(const char* msg) {
|
||||||
|
|
@ -19,7 +20,7 @@
|
||||||
static int step_depth = 0;
|
static int step_depth = 0;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void step(const char* name, T&& fn) {
|
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("Starting ");
|
print("Starting ");
|
||||||
|
|
@ -28,7 +29,7 @@ static void step(const char* name, T&& fn) {
|
||||||
++step_depth;
|
++step_depth;
|
||||||
fn();
|
fn();
|
||||||
--step_depth;
|
--step_depth;
|
||||||
for(int i = 0; i < step_depth; ++i) {
|
for (int i = 0; i < step_depth; ++i) {
|
||||||
print(" ");
|
print(" ");
|
||||||
}
|
}
|
||||||
print("Finished ");
|
print("Finished ");
|
||||||
|
|
@ -52,11 +53,10 @@ static void for_each_boot_reserved_range(Fn&& fn) {
|
||||||
static bool is_in_boot_reserved_range(paddr_t ptr, size_t size) {
|
static bool is_in_boot_reserved_range(paddr_t ptr, size_t size) {
|
||||||
bool res = false;
|
bool res = false;
|
||||||
for_each_boot_reserved_range([&](paddr_t start, size_t length) {
|
for_each_boot_reserved_range([&](paddr_t start, size_t length) {
|
||||||
if(length == 0) {
|
if (length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(ptr.address < start.address + length &&
|
if (ptr.address < start.address + length && start.address < ptr.address + size) {
|
||||||
start.address < ptr.address + size) {
|
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -65,21 +65,21 @@ static bool is_in_boot_reserved_range(paddr_t ptr, size_t size) {
|
||||||
|
|
||||||
optional<paddr_t> findInitialMemoryPages(const multiboot::tag_mmap* multiboot_info, size_t count) {
|
optional<paddr_t> findInitialMemoryPages(const multiboot::tag_mmap* multiboot_info, size_t count) {
|
||||||
const auto* base = reinterpret_cast<const uint8_t*>(multiboot_info->entries);
|
const auto* base = reinterpret_cast<const uint8_t*>(multiboot_info->entries);
|
||||||
const auto* end = reinterpret_cast<const uint8_t*>(multiboot_info) + multiboot_info->size;
|
const auto* end = reinterpret_cast<const uint8_t*>(multiboot_info) + multiboot_info->size;
|
||||||
for (const auto* ptr = base; ptr < end; ptr += multiboot_info->entry_size) {
|
for (const auto* ptr = base; ptr < end; ptr += multiboot_info->entry_size) {
|
||||||
const auto* entry = reinterpret_cast<const multiboot::mem_entry*>(ptr);
|
const auto* entry = reinterpret_cast<const multiboot::mem_entry*>(ptr);
|
||||||
if(entry->type != multiboot::mem_type::available) {
|
if (entry->type != multiboot::mem_type::available) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto start_ptr = (entry->addr + page_size - 1) & ~(page_size - 1);
|
auto start_ptr = (entry->addr + page_size - 1) & ~(page_size - 1);
|
||||||
auto end_ptr = (entry->addr + entry->len) & ~(page_size - 1);
|
auto end_ptr = (entry->addr + entry->len) & ~(page_size - 1);
|
||||||
auto size = end_ptr - start_ptr;
|
auto size = end_ptr - start_ptr;
|
||||||
if(size < page_size * count) {
|
if (size < page_size * count) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(auto ptr = start_ptr; ptr < (end_ptr - page_size * (count - 1)); ptr += page_size) {
|
for (auto ptr = start_ptr; ptr < (end_ptr - page_size * (count - 1)); ptr += page_size) {
|
||||||
if(!is_in_reserved_section(paddr_t{ptr}, page_size) &&
|
if (!is_in_reserved_section(paddr_t{ptr}, page_size) &&
|
||||||
!is_in_boot_reserved_range(paddr_t{ptr}, page_size)) {
|
!is_in_boot_reserved_range(paddr_t{ptr}, page_size)) {
|
||||||
return paddr_t{ptr};
|
return paddr_t{ptr};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +91,7 @@ void PhysicalAllocator::init(const multiboot::tag_mmap* multiboot_info) {
|
||||||
PhysicalAllocator alloc;
|
PhysicalAllocator alloc;
|
||||||
|
|
||||||
auto page_opt = findInitialMemoryPages(multiboot_info, 1);
|
auto page_opt = findInitialMemoryPages(multiboot_info, 1);
|
||||||
if(!page_opt.has_value()) {
|
if (!page_opt.has_value()) {
|
||||||
panic("System could not find enough valid ram!");
|
panic("System could not find enough valid ram!");
|
||||||
}
|
}
|
||||||
auto page = page_opt.value();
|
auto page = page_opt.value();
|
||||||
|
|
@ -102,15 +102,15 @@ void PhysicalAllocator::init(const multiboot::tag_mmap* multiboot_info) {
|
||||||
|
|
||||||
step("multiboot", [&]() {
|
step("multiboot", [&]() {
|
||||||
const auto* base = reinterpret_cast<const uint8_t*>(multiboot_info->entries);
|
const auto* base = reinterpret_cast<const uint8_t*>(multiboot_info->entries);
|
||||||
const auto* end = reinterpret_cast<const uint8_t*>(multiboot_info) + multiboot_info->size;
|
const auto* end = reinterpret_cast<const uint8_t*>(multiboot_info) + multiboot_info->size;
|
||||||
for (const auto* ptr = base; ptr < end; ptr += multiboot_info->entry_size) {
|
for (const auto* ptr = base; ptr < end; ptr += multiboot_info->entry_size) {
|
||||||
const auto* entry = reinterpret_cast<const multiboot::mem_entry*>(ptr);
|
const auto* entry = reinterpret_cast<const multiboot::mem_entry*>(ptr);
|
||||||
if(entry->type!=multiboot::mem_type::available) {
|
if (entry->type != multiboot::mem_type::available) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto start_ptr = (entry->addr + page_size - 1) & ~(page_size - 1);
|
auto start_ptr = (entry->addr + page_size - 1) & ~(page_size - 1);
|
||||||
auto end_ptr = (entry->addr + entry->len) & ~(page_size - 1);
|
auto end_ptr = (entry->addr + entry->len) & ~(page_size - 1);
|
||||||
if(end_ptr <= start_ptr) {
|
if (end_ptr <= start_ptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
alloc.force({paddr_t{start_ptr}, (end_ptr - start_ptr) / page_size}, true);
|
alloc.force({paddr_t{start_ptr}, (end_ptr - start_ptr) / page_size}, true);
|
||||||
|
|
@ -118,8 +118,8 @@ void PhysicalAllocator::init(const multiboot::tag_mmap* multiboot_info) {
|
||||||
});
|
});
|
||||||
|
|
||||||
step("reserved_sections", [&]() {
|
step("reserved_sections", [&]() {
|
||||||
for_each_reserved_section([&](const KernelSection& section){
|
for_each_reserved_section([&](const KernelSection& section) {
|
||||||
if(section.vma_start == section.vma_end) {
|
if (section.vma_start == section.vma_end) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto start_ptr = section.phys_start().address & ~(page_size - 1);
|
auto start_ptr = section.phys_start().address & ~(page_size - 1);
|
||||||
|
|
@ -129,8 +129,8 @@ void PhysicalAllocator::init(const multiboot::tag_mmap* multiboot_info) {
|
||||||
});
|
});
|
||||||
|
|
||||||
step("boot_reserved", [&]() {
|
step("boot_reserved", [&]() {
|
||||||
for_each_boot_reserved_range([&](paddr_t start, size_t length){
|
for_each_boot_reserved_range([&](paddr_t start, size_t length) {
|
||||||
if(length == 0) {
|
if (length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto start_ptr = start.address & ~(page_size - 1);
|
auto start_ptr = start.address & ~(page_size - 1);
|
||||||
|
|
@ -145,12 +145,8 @@ void PhysicalAllocator::init(const multiboot::tag_mmap* multiboot_info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupMemory() {
|
static void setupMemory() {
|
||||||
multiboot::visit_all(overloaded{
|
multiboot::visit_all(
|
||||||
[](const multiboot::tag_mmap* mem) {
|
overloaded{[](const multiboot::tag_mmap* mem) { PhysicalAllocator::init(mem); }, [](const auto* tag) {}});
|
||||||
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) {
|
||||||
|
|
@ -162,19 +158,15 @@ static paddr_t rsdp_physical_of(const uint8_t* rsdp_payload) {
|
||||||
|
|
||||||
static acpi::Rsdp findRsdp() {
|
static acpi::Rsdp findRsdp() {
|
||||||
optional<paddr_t> rsdp{};
|
optional<paddr_t> rsdp{};
|
||||||
multiboot::visit_all(overloaded{
|
multiboot::visit_all(overloaded{[&](const multiboot::tag_new_acpi* tag) { rsdp = rsdp_physical_of(tag->rsdp); },
|
||||||
[&](const multiboot::tag_new_acpi* tag) {
|
[&](const multiboot::tag_old_acpi* tag) {
|
||||||
rsdp = rsdp_physical_of(tag->rsdp);
|
if (!rsdp.has_value()) {
|
||||||
},
|
rsdp = rsdp_physical_of(tag->rsdp);
|
||||||
[&](const multiboot::tag_old_acpi* tag) {
|
}
|
||||||
if(!rsdp.has_value()) {
|
},
|
||||||
rsdp = rsdp_physical_of(tag->rsdp);
|
[&](const auto* tag) {}});
|
||||||
}
|
|
||||||
},
|
|
||||||
[&](const auto* tag) {}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(!rsdp.has_value()) {
|
if (!rsdp.has_value()) {
|
||||||
panic("System could not find ACPI RSDP!");
|
panic("System could not find ACPI RSDP!");
|
||||||
}
|
}
|
||||||
return acpi::Rsdp(*rsdp);
|
return acpi::Rsdp(*rsdp);
|
||||||
|
|
@ -187,12 +179,10 @@ struct AcpiDiscoveryResult {
|
||||||
|
|
||||||
static void setupAcpi() {
|
static void setupAcpi() {
|
||||||
auto rsdp = findRsdp();
|
auto rsdp = findRsdp();
|
||||||
rsdp.for_each_table(overloaded{
|
rsdp.for_each_table(overloaded{[&](const acpi::sdt_header_t* header) {
|
||||||
[&](const acpi::sdt_header_t* header) {
|
print(acpi::unfold_signature(header->signature).text);
|
||||||
print(acpi::unfold_signature(header->signature).text);
|
print("\n");
|
||||||
print("\n");
|
}});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] [[noreturn]] __attribute__((used)) void init() {
|
[[maybe_unused]] [[noreturn]] __attribute__((used)) void init() {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
#include "init/print.h"
|
#include "init/print.h"
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
|
|
||||||
static constexpr uint64_t VGA_PHYS_BASE = 0xb8000;
|
static constexpr uint64_t VGA_PHYS_BASE = 0xb8000;
|
||||||
static constexpr int VGA_COLS = 80;
|
static constexpr int VGA_COLS = 80;
|
||||||
static constexpr int VGA_ROWS = 25;
|
static constexpr int VGA_ROWS = 25;
|
||||||
static constexpr int BYTES_PER_CELL = 2;
|
static constexpr int BYTES_PER_CELL = 2;
|
||||||
static constexpr int BYTES_PER_ROW = VGA_COLS * BYTES_PER_CELL;
|
static constexpr int BYTES_PER_ROW = VGA_COLS * BYTES_PER_CELL;
|
||||||
static constexpr int SCREEN_BYTES = BYTES_PER_ROW * VGA_ROWS;
|
static constexpr int SCREEN_BYTES = BYTES_PER_ROW * VGA_ROWS;
|
||||||
static constexpr int HEX_BITS = 4;
|
static constexpr int HEX_BITS = 4;
|
||||||
static constexpr int HEX_TOP_SHIFT = (sizeof(uint64_t) * 8) - HEX_BITS;
|
static constexpr int HEX_TOP_SHIFT = (sizeof(uint64_t) * 8) - HEX_BITS;
|
||||||
|
|
||||||
static const char hex_chars[] = "0123456789ABCDEF";
|
static const char hex_chars[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ static void put_char(char ch, uint16_t attr_word) {
|
||||||
cursor += BYTES_PER_CELL;
|
cursor += BYTES_PER_CELL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initFromLow () {
|
void initFromLow() {
|
||||||
auto __cursor = read_symbol("__cursor");
|
auto __cursor = read_symbol("__cursor");
|
||||||
cursor = *paddr_t{__cursor}.access<volatile uint32_t>();
|
cursor = *paddr_t{__cursor}.access<volatile uint32_t>();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,9 @@
|
||||||
#include "memory/sections.h"
|
#include "memory/sections.h"
|
||||||
|
|
||||||
#define RESERVE_SECTION(n) \
|
#define RESERVE_SECTION(n) \
|
||||||
extern char __##n##_start__[], __##n##_end__[]; \
|
extern char __##n##_start__[], __##n##_end__[]; \
|
||||||
[[maybe_unused]] static const KernelSection _rsv_##n \
|
[[maybe_unused]] static const KernelSection _rsv_##n \
|
||||||
__attribute__((section(".reserved_ranges"), used)) = { \
|
__attribute__((section(".reserved_ranges"), used)) = {(uint64_t)__##n##_start__, (uint64_t)__##n##_end__, #n}
|
||||||
(uint64_t)__##n##_start__, \
|
|
||||||
(uint64_t)__##n##_end__, \
|
|
||||||
#n \
|
|
||||||
}
|
|
||||||
|
|
||||||
RESERVE_SECTION(boot);
|
RESERVE_SECTION(boot);
|
||||||
RESERVE_SECTION(startup_text);
|
RESERVE_SECTION(startup_text);
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,7 @@ struct PhysicalAllocatorImpl {
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t& entry(size_t i) {
|
uint64_t& entry(size_t i) { return cursor_at(i).value(); }
|
||||||
return cursor_at(i).value();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t node_count() {
|
size_t node_count() {
|
||||||
size_t nodes = 0;
|
size_t nodes = 0;
|
||||||
|
|
@ -68,9 +66,7 @@ struct PhysicalAllocatorImpl {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t capacity() {
|
size_t capacity() { return node_count() * entries_per_node; }
|
||||||
return node_count() * entries_per_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t logical_length() {
|
size_t logical_length() {
|
||||||
Cursor cursor = cursor_at(0);
|
Cursor cursor = cursor_at(0);
|
||||||
|
|
@ -87,9 +83,7 @@ struct PhysicalAllocatorImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t free_slots() {
|
size_t free_slots() { return capacity() - (logical_length() + 2); }
|
||||||
return capacity() - (logical_length() + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<paddr_t> find_free_page() {
|
optional<paddr_t> find_free_page() {
|
||||||
Cursor cursor = cursor_at(0);
|
Cursor cursor = cursor_at(0);
|
||||||
|
|
@ -168,8 +162,8 @@ struct PhysicalAllocatorImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_list_t collect_runs(uint64_t start_page, uint64_t count, bool is_free,
|
run_list_t collect_runs(uint64_t start_page, uint64_t count, bool is_free, const run_location_t& start,
|
||||||
const run_location_t& start, const run_location_t& end, size_t total_runs) {
|
const run_location_t& end, size_t total_runs) {
|
||||||
bool has_left_neighbor = start.index > 0;
|
bool has_left_neighbor = start.index > 0;
|
||||||
bool has_right_neighbor = end.index + 1 < total_runs;
|
bool has_right_neighbor = end.index + 1 < total_runs;
|
||||||
uint64_t left_remainder = start_page - start.address;
|
uint64_t left_remainder = start_page - start.address;
|
||||||
|
|
@ -177,13 +171,13 @@ struct PhysicalAllocatorImpl {
|
||||||
|
|
||||||
run_list_t list{};
|
run_list_t list{};
|
||||||
if (has_left_neighbor) {
|
if (has_left_neighbor) {
|
||||||
list.runs[list.count++] = { ((start.index - 1) & 1) != 0, entry(start.index - 1) };
|
list.runs[list.count++] = {((start.index - 1) & 1) != 0, entry(start.index - 1)};
|
||||||
}
|
}
|
||||||
list.runs[list.count++] = { (start.index & 1) != 0, left_remainder };
|
list.runs[list.count++] = {(start.index & 1) != 0, left_remainder};
|
||||||
list.runs[list.count++] = { is_free, count };
|
list.runs[list.count++] = {is_free, count};
|
||||||
list.runs[list.count++] = { (end.index & 1) != 0, right_remainder };
|
list.runs[list.count++] = {(end.index & 1) != 0, right_remainder};
|
||||||
if (has_right_neighbor) {
|
if (has_right_neighbor) {
|
||||||
list.runs[list.count++] = { ((end.index + 1) & 1) != 0, entry(end.index + 1) };
|
list.runs[list.count++] = {((end.index + 1) & 1) != 0, entry(end.index + 1)};
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +204,7 @@ struct PhysicalAllocatorImpl {
|
||||||
for (size_t i = list.count; i > 0; --i) {
|
for (size_t i = list.count; i > 0; --i) {
|
||||||
list.runs[i] = list.runs[i - 1];
|
list.runs[i] = list.runs[i - 1];
|
||||||
}
|
}
|
||||||
list.runs[0] = { first_is_free, 0 };
|
list.runs[0] = {first_is_free, 0};
|
||||||
++list.count;
|
++list.count;
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
@ -222,7 +216,7 @@ struct PhysicalAllocatorImpl {
|
||||||
size_t delta = list.count - old_count;
|
size_t delta = list.count - old_count;
|
||||||
Cursor source = cursor_at(terminator_end - 1);
|
Cursor source = cursor_at(terminator_end - 1);
|
||||||
Cursor dest = cursor_at(terminator_end - 1 + delta);
|
Cursor dest = cursor_at(terminator_end - 1 + delta);
|
||||||
for (size_t i = terminator_end; i-- > last_index + 1; ) {
|
for (size_t i = terminator_end; i-- > last_index + 1;) {
|
||||||
dest.value() = source.value();
|
dest.value() = source.value();
|
||||||
source.retreat();
|
source.retreat();
|
||||||
dest.retreat();
|
dest.retreat();
|
||||||
|
|
@ -307,7 +301,7 @@ struct PhysicalAllocatorImpl {
|
||||||
if (aligned_start + page_count <= run_start + length) {
|
if (aligned_start + page_count <= run_start + length) {
|
||||||
set_range(aligned_start, page_count, false);
|
set_range(aligned_start, page_count, false);
|
||||||
reclaim_nodes();
|
reclaim_nodes();
|
||||||
return allocation_t{ paddr_t{aligned_start * page_size}, page_count };
|
return allocation_t{paddr_t{aligned_start * page_size}, page_count};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_start += length;
|
run_start += length;
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
#include "memory/pointer.h"
|
#include "memory/pointer.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// Linker-defined bounds of the (NOLOAD) .bss section and the .init_array of
|
// Linker-defined bounds of the (NOLOAD) .bss section and the .init_array of
|
||||||
// global constructors. See linker.ld.
|
// global constructors. See linker.ld.
|
||||||
extern char __bss_start__[];
|
extern char __bss_start__[];
|
||||||
extern char __bss_end__[];
|
extern char __bss_end__[];
|
||||||
|
|
||||||
using constructor_t = void (*)();
|
using constructor_t = void (*)();
|
||||||
extern constructor_t __init_array_start__[];
|
extern constructor_t __init_array_start__[];
|
||||||
extern constructor_t __init_array_end__[];
|
extern constructor_t __init_array_end__[];
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" [[maybe_unused]] [[noreturn]] __attribute__((used)) void __entry64() {
|
extern "C" [[maybe_unused]] [[noreturn]] __attribute__((used)) void __entry64() {
|
||||||
|
|
@ -18,7 +18,8 @@ extern "C" [[maybe_unused]] [[noreturn]] __attribute__((used)) void __entry64()
|
||||||
(*ctor)();
|
(*ctor)();
|
||||||
}
|
}
|
||||||
init();
|
init();
|
||||||
while (true) __asm__ volatile ("hlt");
|
while (true)
|
||||||
|
__asm__ volatile("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
asm(R"(
|
asm(R"(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue