[bootproto] Create new bootproto lib
This is a rather large commit that is widely focused on cleaning things out of the 'junk drawer' that is src/include. Most notably, several things that were put in there because they needed somewhere where both the kernel, boot, and init could read them have been moved to a new lib, 'bootproto'. - Moved kernel_args.h and init_args.h to bootproto as kernel.h and init.h, respectively. - Moved counted.h and pointer_manipulation.h into util, renaming the latter to util/pointers.h. - Created a new src/include/arch for very arch-dependent definitions, and moved some kernel_memory.h constants like frame size, page table entry count, etc to arch/amd64/memory.h. Also created arch/memory.h which detects platform and includes the former. - Got rid of kernel_memory.h entirely in favor of a new, cog-based approach. The new definitions/memory_layout.csv lists memory regions in descending order from the top of memory, their sizes, and whether they are shared outside the kernel (ie, boot needs to know them). The new header bootproto/memory.h exposes the addresses of the shared regions, while the kernel's memory.h gains the start and size of all the regions. Also renamed the badly-named page-offset area the linear area. - The python build scripts got a few new features: the ability to parse the csv mentioned above in a new memory.py module; the ability to add dependencies to existing source files (The list of files that I had to pull out of the main list just to add them with the dependency on memory.h was getting too large. So I put them back into the sources list, and added the dependency post-hoc.); and the ability to reference 'source_root', 'build_root', and 'module_root' variables in .module files. - Some utility functions that were in the kernel's memory.h got moved to util/pointers.h and util/misc.h, and misc.h's byteswap was renamed byteswap32 to be more specific.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <util/misc.h>
|
||||
#include <util/misc.h> // for byteswap32
|
||||
#include <enum_bitfields.h>
|
||||
|
||||
struct acpi_table_header
|
||||
@@ -22,7 +22,7 @@ struct acpi_table_header
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define TABLE_HEADER(signature) \
|
||||
static constexpr uint32_t type_id = util::byteswap(signature); \
|
||||
static constexpr uint32_t type_id = util::byteswap32(signature); \
|
||||
acpi_table_header header;
|
||||
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "clock.h"
|
||||
#include "interrupts.h"
|
||||
#include "io.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
|
||||
uint64_t lapic::s_ticks_per_us = 0;
|
||||
|
||||
@@ -51,7 +51,7 @@ ioapic_write(uint32_t volatile *base, uint8_t reg, uint32_t value)
|
||||
}
|
||||
|
||||
apic::apic(uintptr_t base) :
|
||||
m_base(memory::to_virtual<uint32_t>(base))
|
||||
m_base(mem::to_virtual<uint32_t>(base))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "device_manager.h"
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "log.h"
|
||||
#include "msr.h"
|
||||
#include "objects/vm_area.h"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <util/misc.h> // for checksum
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "acpi_tables.h"
|
||||
@@ -8,7 +10,6 @@
|
||||
#include "console.h"
|
||||
#include "device_manager.h"
|
||||
#include "interrupts.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "objects/endpoint.h"
|
||||
@@ -47,7 +48,7 @@ struct acpi2_rsdp
|
||||
bool
|
||||
acpi_table_header::validate(uint32_t expected_type) const
|
||||
{
|
||||
if (::checksum(this, length) != 0) return false;
|
||||
if (util::checksum(this, length) != 0) return false;
|
||||
return !expected_type || (expected_type == type);
|
||||
}
|
||||
|
||||
@@ -75,14 +76,14 @@ device_manager::parse_acpi(const void *root_table)
|
||||
{
|
||||
kassert(root_table != 0, "ACPI root table pointer is null.");
|
||||
|
||||
const acpi1_rsdp *acpi1 = memory::to_virtual(
|
||||
const acpi1_rsdp *acpi1 = mem::to_virtual(
|
||||
reinterpret_cast<const acpi1_rsdp *>(root_table));
|
||||
|
||||
for (int i = 0; i < sizeof(acpi1->signature); ++i)
|
||||
kassert(acpi1->signature[i] == expected_signature[i],
|
||||
"ACPI RSDP table signature mismatch");
|
||||
|
||||
uint8_t sum = checksum(acpi1, sizeof(acpi1_rsdp), 0);
|
||||
uint8_t sum = util::checksum(acpi1, sizeof(acpi1_rsdp), 0);
|
||||
kassert(sum == 0, "ACPI 1.0 RSDP checksum mismatch.");
|
||||
|
||||
kassert(acpi1->revision > 1, "ACPI 1.0 not supported.");
|
||||
@@ -90,10 +91,10 @@ device_manager::parse_acpi(const void *root_table)
|
||||
const acpi2_rsdp *acpi2 =
|
||||
reinterpret_cast<const acpi2_rsdp *>(acpi1);
|
||||
|
||||
sum = checksum(acpi2, sizeof(acpi2_rsdp), sizeof(acpi1_rsdp));
|
||||
sum = util::checksum(acpi2, sizeof(acpi2_rsdp), sizeof(acpi1_rsdp));
|
||||
kassert(sum == 0, "ACPI 2.0 RSDP checksum mismatch.");
|
||||
|
||||
load_xsdt(memory::to_virtual(acpi2->xsdt_address));
|
||||
load_xsdt(mem::to_virtual(acpi2->xsdt_address));
|
||||
}
|
||||
|
||||
const device_manager::apic_nmi *
|
||||
@@ -142,7 +143,7 @@ device_manager::load_xsdt(const acpi_table_header *header)
|
||||
size_t num_tables = acpi_table_entries(xsdt, sizeof(void*));
|
||||
for (size_t i = 0; i < num_tables; ++i) {
|
||||
const acpi_table_header *header =
|
||||
memory::to_virtual(xsdt->headers[i]);
|
||||
mem::to_virtual(xsdt->headers[i]);
|
||||
|
||||
put_sig(sig, header->type);
|
||||
log::debug(logs::device, " Found table %s", sig);
|
||||
@@ -212,8 +213,8 @@ device_manager::load_apic(const acpi_table_header *header)
|
||||
|
||||
switch (type) {
|
||||
case 0: { // Local APIC
|
||||
uint8_t uid = read_from<uint8_t>(p+2);
|
||||
uint8_t id = read_from<uint8_t>(p+3);
|
||||
uint8_t uid = util::read_from<uint8_t>(p+2);
|
||||
uint8_t id = util::read_from<uint8_t>(p+3);
|
||||
m_apic_ids.append(id);
|
||||
|
||||
log::debug(logs::device, " Local APIC uid %x id %x", uid, id);
|
||||
@@ -221,8 +222,8 @@ device_manager::load_apic(const acpi_table_header *header)
|
||||
break;
|
||||
|
||||
case 1: { // I/O APIC
|
||||
uintptr_t base = read_from<uint32_t>(p+4);
|
||||
uint32_t base_gsi = read_from<uint32_t>(p+8);
|
||||
uintptr_t base = util::read_from<uint32_t>(p+4);
|
||||
uint32_t base_gsi = util::read_from<uint32_t>(p+8);
|
||||
m_ioapics.emplace(base, base_gsi);
|
||||
|
||||
log::debug(logs::device, " IO APIC gsi %x base %x", base_gsi, base);
|
||||
@@ -231,9 +232,9 @@ device_manager::load_apic(const acpi_table_header *header)
|
||||
|
||||
case 2: { // Interrupt source override
|
||||
irq_override o;
|
||||
o.source = read_from<uint8_t>(p+3);
|
||||
o.gsi = read_from<uint32_t>(p+4);
|
||||
o.flags = read_from<uint16_t>(p+8);
|
||||
o.source = util::read_from<uint8_t>(p+3);
|
||||
o.gsi = util::read_from<uint32_t>(p+4);
|
||||
o.flags = util::read_from<uint16_t>(p+8);
|
||||
m_overrides.append(o);
|
||||
|
||||
log::debug(logs::device, " Intr source override IRQ %d -> %d Pol %d Tri %d",
|
||||
@@ -243,9 +244,9 @@ device_manager::load_apic(const acpi_table_header *header)
|
||||
|
||||
case 4: {// LAPIC NMI
|
||||
apic_nmi nmi;
|
||||
nmi.cpu = read_from<uint8_t>(p + 2);
|
||||
nmi.lint = read_from<uint8_t>(p + 5);
|
||||
nmi.flags = read_from<uint16_t>(p + 3);
|
||||
nmi.cpu = util::read_from<uint8_t>(p + 2);
|
||||
nmi.lint = util::read_from<uint8_t>(p + 5);
|
||||
nmi.flags = util::read_from<uint16_t>(p + 3);
|
||||
m_nmis.append(nmi);
|
||||
|
||||
log::debug(logs::device, " LAPIC NMI Proc %02x LINT%d Pol %d Tri %d",
|
||||
@@ -279,7 +280,7 @@ device_manager::load_mcfg(const acpi_table_header *header)
|
||||
m_pci[i].group = mcfge.group;
|
||||
m_pci[i].bus_start = mcfge.bus_start;
|
||||
m_pci[i].bus_end = mcfge.bus_end;
|
||||
m_pci[i].base = memory::to_virtual<uint32_t>(mcfge.base);
|
||||
m_pci[i].base = mem::to_virtual<uint32_t>(mcfge.base);
|
||||
|
||||
log::debug(logs::device, " Found MCFG entry: base %lx group %d bus %d-%d",
|
||||
mcfge.base, mcfge.group, mcfge.bus_start, mcfge.bus_end);
|
||||
@@ -308,7 +309,7 @@ device_manager::load_hpet(const acpi_table_header *header)
|
||||
log::debug(logs::device, " pci vendor id: %04x", pci_vendor_id);
|
||||
|
||||
m_hpets.emplace(hpet->index,
|
||||
reinterpret_cast<uint64_t*>(hpet->base_address.address + ::memory::page_offset));
|
||||
reinterpret_cast<uint64_t*>(hpet->base_address.address + mem::linear_offset));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include <bootproto/kernel.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "frame_allocator.h"
|
||||
#include "kernel_args.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
|
||||
using memory::frame_size;
|
||||
using mem::frame_size;
|
||||
|
||||
|
||||
frame_allocator &
|
||||
@@ -14,7 +15,7 @@ frame_allocator::get()
|
||||
return g_frame_allocator;
|
||||
}
|
||||
|
||||
frame_allocator::frame_allocator(kernel::init::frame_block *frames, size_t count) :
|
||||
frame_allocator::frame_allocator(bootproto::frame_block *frames, size_t count) :
|
||||
m_blocks {frames},
|
||||
m_count {count}
|
||||
{
|
||||
|
||||
@@ -5,16 +5,15 @@
|
||||
#include <stdint.h>
|
||||
#include <util/spinlock.h>
|
||||
|
||||
namespace kernel {
|
||||
namespace init {
|
||||
namespace bootproto {
|
||||
struct frame_block;
|
||||
}}
|
||||
}
|
||||
|
||||
/// Allocator for physical memory frames
|
||||
class frame_allocator
|
||||
{
|
||||
public:
|
||||
using frame_block = kernel::init::frame_block;
|
||||
using frame_block = bootproto::frame_block;
|
||||
|
||||
/// Constructor
|
||||
/// \arg blocks The bootloader-supplied frame bitmap block list
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <util/pointers.h>
|
||||
#include <util/util.h>
|
||||
|
||||
#include "assert.h"
|
||||
@@ -44,8 +45,8 @@ struct heap_allocator::mem_header
|
||||
set_next(nullptr);
|
||||
}
|
||||
|
||||
inline mem_header * next() { return mask_pointer(m_next, 0x3f); }
|
||||
inline mem_header * prev() { return mask_pointer(m_prev, 0x3f); }
|
||||
inline mem_header * next() { return util::mask_pointer(m_next, 0x3f); }
|
||||
inline mem_header * prev() { return util::mask_pointer(m_prev, 0x3f); }
|
||||
|
||||
inline mem_header * buddy() const {
|
||||
return reinterpret_cast<mem_header *>(
|
||||
@@ -155,7 +156,7 @@ heap_allocator::ensure_block(unsigned order)
|
||||
} else {
|
||||
mem_header *orig = pop_free(order + 1);
|
||||
if (orig) {
|
||||
mem_header *next = offset_pointer(orig, 1 << order);
|
||||
mem_header *next = util::offset_pointer(orig, 1 << order);
|
||||
new (next) mem_header(orig, nullptr, order);
|
||||
|
||||
orig->set_next(next);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "kernel_memory.h"
|
||||
|
||||
#include "assert.h"
|
||||
#include "device_manager.h"
|
||||
#include "hpet.h"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kernel_memory.h"
|
||||
#include "printf/printf.h"
|
||||
|
||||
#include "assert.h"
|
||||
#include "cpu.h"
|
||||
@@ -9,14 +7,16 @@
|
||||
#include "idt.h"
|
||||
#include "interrupts.h"
|
||||
#include "io.h"
|
||||
#include "memory.h"
|
||||
#include "objects/process.h"
|
||||
#include "printf/printf.h"
|
||||
#include "scheduler.h"
|
||||
#include "vm_space.h"
|
||||
|
||||
static const uint16_t PIC1 = 0x20;
|
||||
static const uint16_t PIC2 = 0xa0;
|
||||
|
||||
constexpr uintptr_t apic_eoi_addr = 0xfee000b0 + ::memory::page_offset;
|
||||
constexpr uintptr_t apic_eoi_addr = 0xfee000b0 + mem::linear_offset;
|
||||
|
||||
extern "C" {
|
||||
void isr_handler(cpu_state*);
|
||||
@@ -119,7 +119,7 @@ isr_handler(cpu_state *regs)
|
||||
uintptr_t cr2 = 0;
|
||||
__asm__ __volatile__ ("mov %%cr2, %0" : "=r"(cr2));
|
||||
|
||||
bool user = cr2 < memory::kernel_offset;
|
||||
bool user = cr2 < mem::kernel_offset;
|
||||
vm_space::fault_type ft =
|
||||
static_cast<vm_space::fault_type>(regs->errorcode);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ kernel = module("kernel",
|
||||
default = True,
|
||||
output = "jsix.elf",
|
||||
targets = [ "kernel" ],
|
||||
deps = [ "util", "cpu" ],
|
||||
deps = [ "util", "cpu", "bootproto" ],
|
||||
includes = [ "." ],
|
||||
sources = [
|
||||
"apic.cpp",
|
||||
@@ -15,6 +15,7 @@ kernel = module("kernel",
|
||||
"clock.cpp",
|
||||
"console.cpp",
|
||||
"cpprt.cpp",
|
||||
"cpu.cpp",
|
||||
"debug.cpp",
|
||||
"debug.s",
|
||||
"device_manager.cpp",
|
||||
@@ -29,6 +30,7 @@ kernel = module("kernel",
|
||||
"io.cpp",
|
||||
"log.cpp",
|
||||
"logger.cpp",
|
||||
"main.cpp",
|
||||
"memory.cpp",
|
||||
"memory_bootstrap.cpp",
|
||||
"msr.cpp",
|
||||
@@ -45,6 +47,7 @@ kernel = module("kernel",
|
||||
"printf/printf.c",
|
||||
"scheduler.cpp",
|
||||
"serial.cpp",
|
||||
"syscall.s",
|
||||
"syscalls/channel.cpp",
|
||||
"syscalls/endpoint.cpp",
|
||||
"syscalls/object.cpp",
|
||||
@@ -58,14 +61,41 @@ kernel = module("kernel",
|
||||
])
|
||||
|
||||
from glob import glob
|
||||
definitions = glob('definitions/**/*.def', recursive=True)
|
||||
sysinc = kernel.add_input("syscalls.inc.cog", deps=definitions)
|
||||
kernel.add_input("syscall.s", deps=[sysinc])
|
||||
from os.path import join
|
||||
|
||||
layout = join(source_root, "definitions/memory_layout.csv")
|
||||
definitions = glob('definitions/**/*.def', recursive=True)
|
||||
|
||||
sysinc = kernel.add_input("syscalls.inc.cog", deps=definitions)
|
||||
|
||||
memh = kernel.add_input("memory.h.cog", deps=[layout])
|
||||
sysh = kernel.add_input("syscall.h.cog", deps=definitions)
|
||||
sysc = kernel.add_input("syscall.cpp.cog", deps=definitions + [sysh])
|
||||
|
||||
kernel.add_input("main.cpp", deps=[sysh])
|
||||
kernel.add_input("cpu.cpp", deps=[sysh])
|
||||
kernel.add_depends(["syscall.s"], [sysinc])
|
||||
kernel.add_depends(["main.cpp", "cpu.cpp"], [sysh])
|
||||
kernel.add_depends(["main.cpp", "cpu.cpp"], [sysh])
|
||||
|
||||
kernel.add_depends([
|
||||
"apic.cpp",
|
||||
"device_manager.cpp",
|
||||
"frame_allocator.cpp",
|
||||
"heap_allocator.cpp",
|
||||
"heap_allocator.h",
|
||||
"interrupts.cpp",
|
||||
"log.cpp",
|
||||
"main.cpp",
|
||||
"memory_bootstrap.cpp",
|
||||
"memory.cpp",
|
||||
"objects/channel.cpp",
|
||||
"objects/thread.cpp",
|
||||
"objects/vm_area.cpp",
|
||||
"page_table.cpp",
|
||||
"page_tree.cpp",
|
||||
"syscalls/system.cpp",
|
||||
"tss.cpp",
|
||||
"vm_space.cpp",
|
||||
],
|
||||
[memh])
|
||||
|
||||
kernel.variables['ldflags'] = ["${ldflags}", "-T", "${source_root}/src/kernel/kernel.ld"]
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <bootproto/kernel.h>
|
||||
#include <j6/signals.h>
|
||||
#include <util/vector.h>
|
||||
#include <kernel_args.h>
|
||||
#include <kernel_memory.h>
|
||||
|
||||
#include "apic.h"
|
||||
#include "assert.h"
|
||||
@@ -19,6 +18,7 @@
|
||||
#include "interrupts.h"
|
||||
#include "io.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "msr.h"
|
||||
#include "objects/channel.h"
|
||||
#include "objects/event.h"
|
||||
@@ -36,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
void kernel_main(kernel::init::args *args);
|
||||
void kernel_main(bootproto::args *args);
|
||||
void (*__ctors)(void);
|
||||
void (*__ctors_end)(void);
|
||||
void long_ap_startup(cpu_data *cpu);
|
||||
@@ -45,15 +45,13 @@ extern "C" {
|
||||
void init_ap_trampoline(void*, cpu_data *, void (*)());
|
||||
}
|
||||
|
||||
using namespace kernel;
|
||||
|
||||
volatile size_t ap_startup_count;
|
||||
static bool scheduler_ready = false;
|
||||
|
||||
/// Bootstrap the memory managers.
|
||||
void memory_initialize_pre_ctors(init::args &kargs);
|
||||
void memory_initialize_post_ctors(init::args &kargs);
|
||||
void load_init_server(init::program &program, uintptr_t modules_address);
|
||||
void memory_initialize_pre_ctors(bootproto::args &kargs);
|
||||
void memory_initialize_post_ctors(bootproto::args &kargs);
|
||||
void load_init_server(bootproto::program &program, uintptr_t modules_address);
|
||||
|
||||
unsigned start_aps(lapic &apic, const util::vector<uint8_t> &ids, void *kpml4);
|
||||
|
||||
@@ -80,11 +78,11 @@ run_constructors()
|
||||
}
|
||||
|
||||
void
|
||||
kernel_main(init::args *args)
|
||||
kernel_main(bootproto::args *args)
|
||||
{
|
||||
if (args->panic) {
|
||||
IDT::set_nmi_handler(args->panic->entrypoint);
|
||||
panic::symbol_table = args->symbol_table | memory::page_offset;
|
||||
panic::symbol_table = args->symbol_table | mem::linear_offset;
|
||||
}
|
||||
|
||||
init_console();
|
||||
@@ -108,7 +106,7 @@ kernel_main(init::args *args)
|
||||
cpu->rsp0 = idle_stack_end;
|
||||
cpu_early_init(cpu);
|
||||
|
||||
kassert(args->magic == init::args_magic,
|
||||
kassert(args->magic == bootproto::args_magic,
|
||||
"Bad kernel args magic number");
|
||||
|
||||
log::debug(logs::boot, "jsix init args are at: %016lx", args);
|
||||
@@ -193,8 +191,8 @@ kernel_main(init::args *args)
|
||||
unsigned
|
||||
start_aps(lapic &apic, const util::vector<uint8_t> &ids, void *kpml4)
|
||||
{
|
||||
using memory::frame_size;
|
||||
using memory::kernel_stack_pages;
|
||||
using mem::frame_size;
|
||||
using mem::kernel_stack_pages;
|
||||
|
||||
extern size_t ap_startup_code_size;
|
||||
extern process &g_kernel_process;
|
||||
|
||||
@@ -26,12 +26,3 @@ memcpy(void *dest, const void *src, size_t n)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint8_t
|
||||
checksum(const void *p, size_t len, size_t off)
|
||||
{
|
||||
uint8_t sum = 0;
|
||||
const uint8_t *c = reinterpret_cast<const uint8_t *>(p);
|
||||
for (int i = off; i < len; ++i) sum += c[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void * operator new (size_t, void *p) noexcept;
|
||||
|
||||
/// Allocate from the default allocator.
|
||||
/// \arg size The size in bytes requested
|
||||
/// \returns A pointer to the newly allocated memory,
|
||||
/// or nullptr on error
|
||||
void * kalloc(size_t size);
|
||||
|
||||
/// Free memory allocated by `kalloc`.
|
||||
/// \arg p Pointer that was returned from a `kalloc` call
|
||||
void kfree(void *p);
|
||||
|
||||
/// Read a value of type T from a location in memory
|
||||
/// \arg p The location in memory to read
|
||||
/// \returns The value at the given location cast to T
|
||||
template <typename T>
|
||||
inline T read_from(const void *p)
|
||||
{
|
||||
return *reinterpret_cast<const T *>(p);
|
||||
}
|
||||
|
||||
/// Get a pointer that's offset from another pointer
|
||||
/// \arg p The base pointer
|
||||
/// \arg n The offset in bytes
|
||||
/// \returns The offset pointer
|
||||
template <typename T>
|
||||
inline T * offset_pointer(T *p, ptrdiff_t n)
|
||||
{
|
||||
return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(p) + n);
|
||||
}
|
||||
|
||||
/// Return a pointer with the given bits masked out
|
||||
/// \arg p The original pointer
|
||||
/// \arg mask A bitmask of bits to clear from p
|
||||
/// \returns The masked pointer
|
||||
template <typename T>
|
||||
inline T* mask_pointer(T *p, uintptr_t mask)
|
||||
{
|
||||
return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(p) & ~mask);
|
||||
}
|
||||
|
||||
/// Do a simple byte-wise checksum of an area of memory.
|
||||
/// \arg p The start of the memory region
|
||||
/// \arg len The number of bytes in the region
|
||||
/// \arg off An optional offset into the region
|
||||
uint8_t checksum(const void *p, size_t len, size_t off = 0);
|
||||
79
src/kernel/memory.h.cog
Normal file
79
src/kernel/memory.h.cog
Normal file
@@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
// vim: ft=cpp
|
||||
|
||||
/// \file bootproto/memory.h
|
||||
/// Import memory layout constants necessary for boot
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch/memory.h>
|
||||
|
||||
void * operator new (size_t, void *p) noexcept;
|
||||
|
||||
/// Allocate from the default allocator.
|
||||
/// \arg size The size in bytes requested
|
||||
/// \returns A pointer to the newly allocated memory,
|
||||
/// or nullptr on error
|
||||
void * kalloc(size_t size);
|
||||
|
||||
/// Free memory allocated by `kalloc`.
|
||||
/// \arg p Pointer that was returned from a `kalloc` call
|
||||
void kfree(void *p);
|
||||
|
||||
/// Kernel space virtual memory layout
|
||||
namespace mem {
|
||||
|
||||
using arch::frame_size;
|
||||
using arch::kernel_offset;
|
||||
|
||||
/// Max number of pages for a kernel stack
|
||||
constexpr unsigned kernel_stack_pages = 2;
|
||||
|
||||
/// Max number of pages for a kernel buffer
|
||||
constexpr unsigned kernel_buffer_pages = 16;
|
||||
|
||||
/*[[[cog code generation
|
||||
from os.path import join
|
||||
from memory import Layout
|
||||
|
||||
layout = Layout(join(definitions_path, "memory_layout.csv"))
|
||||
l = max([len(r.name) for r in layout.regions])
|
||||
|
||||
for region in layout.regions:
|
||||
cog.outl(f"constexpr size_t {region.name:>{l}}_size = {region.size:#14x};")
|
||||
|
||||
cog.outl("")
|
||||
|
||||
for region in layout.regions:
|
||||
cog.outl(f"constexpr uintptr_t {region.name:>{l}}_offset = {region.start:#x};")
|
||||
|
||||
]]]*/
|
||||
///[[[end]]]
|
||||
|
||||
/// Helper to determine if a physical address can be accessed
|
||||
/// through the linear_offset area.
|
||||
constexpr bool linear_mappable(uintptr_t a) { return (a & linear_offset) == 0; }
|
||||
|
||||
/// Convert a physical address to a virtual one (in the linear-mapped area)
|
||||
template <typename T> T * to_virtual(uintptr_t a) {
|
||||
return reinterpret_cast<T*>(a|linear_offset);
|
||||
}
|
||||
|
||||
/// Convert a physical address to a virtual one (in the linear-mapped area)
|
||||
template <typename T> T * to_virtual(T *p) {
|
||||
return to_virtual<T>(reinterpret_cast<uintptr_t>(p));
|
||||
}
|
||||
|
||||
/// Get the number of pages needed for a given number of bytes.
|
||||
/// \arg bytes The number of bytes desired
|
||||
/// \returns The number of pages needed to contain the desired bytes
|
||||
constexpr size_t page_count(size_t bytes) { return ((bytes - 1) >> 12) + 1; }
|
||||
|
||||
/// Get the given address, aligned to the next lowest page
|
||||
constexpr uintptr_t page_align_down(uintptr_t a) { return a & ~(frame_size-1); }
|
||||
|
||||
/// Get the given address, aligned to the next page
|
||||
constexpr uintptr_t page_align_up(uintptr_t a) { return page_align_down(a-1) + frame_size; }
|
||||
|
||||
} // namespace mem
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <utility>
|
||||
|
||||
#include <arch/memory.h>
|
||||
#include <bootproto/kernel.h>
|
||||
#include <j6/init.h>
|
||||
#include <util/no_construct.h>
|
||||
#include <kernel_args.h>
|
||||
#include <enum_bitfields.h>
|
||||
|
||||
#include "assert.h"
|
||||
@@ -12,6 +13,7 @@
|
||||
#include "heap_allocator.h"
|
||||
#include "io.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "msr.h"
|
||||
#include "objects/process.h"
|
||||
#include "objects/thread.h"
|
||||
@@ -19,18 +21,12 @@
|
||||
#include "objects/vm_area.h"
|
||||
#include "vm_space.h"
|
||||
|
||||
using memory::heap_start;
|
||||
using memory::kernel_max_heap;
|
||||
namespace bootproto {
|
||||
is_bitfield(section_flags);
|
||||
}
|
||||
|
||||
namespace kernel {
|
||||
namespace init {
|
||||
is_bitfield(section_flags);
|
||||
}}
|
||||
|
||||
using kernel::init::allocation_register;
|
||||
using kernel::init::section_flags;
|
||||
|
||||
using namespace kernel;
|
||||
using bootproto::allocation_register;
|
||||
using bootproto::section_flags;
|
||||
|
||||
extern "C" void initialize_main_thread();
|
||||
extern "C" uintptr_t initialize_main_user_stack();
|
||||
@@ -51,9 +47,9 @@ static util::no_construct<vm_area_guarded> __g_kernel_stacks_storage;
|
||||
vm_area_guarded &g_kernel_stacks = __g_kernel_stacks_storage.value;
|
||||
|
||||
vm_area_guarded g_kernel_buffers {
|
||||
memory::buffers_start,
|
||||
memory::kernel_buffer_pages,
|
||||
memory::kernel_max_buffers,
|
||||
mem::buffers_offset,
|
||||
mem::kernel_buffer_pages,
|
||||
mem::buffers_size,
|
||||
vm_flags::write};
|
||||
|
||||
void * operator new(size_t size) { return g_kernel_heap.allocate(size); }
|
||||
@@ -67,26 +63,26 @@ void kfree(void *p) { return g_kernel_heap.free(p); }
|
||||
template <typename T>
|
||||
uintptr_t
|
||||
get_physical_page(T *p) {
|
||||
return memory::page_align_down(reinterpret_cast<uintptr_t>(p));
|
||||
return mem::page_align_down(reinterpret_cast<uintptr_t>(p));
|
||||
}
|
||||
|
||||
void
|
||||
memory_initialize_pre_ctors(init::args &kargs)
|
||||
memory_initialize_pre_ctors(bootproto::args &kargs)
|
||||
{
|
||||
using kernel::init::frame_block;
|
||||
using bootproto::frame_block;
|
||||
|
||||
page_table *kpml4 = static_cast<page_table*>(kargs.pml4);
|
||||
|
||||
new (&g_kernel_heap) heap_allocator {heap_start, kernel_max_heap};
|
||||
new (&g_kernel_heap) heap_allocator {mem::heap_offset, mem::heap_size};
|
||||
|
||||
frame_block *blocks = reinterpret_cast<frame_block*>(memory::bitmap_start);
|
||||
frame_block *blocks = reinterpret_cast<frame_block*>(mem::bitmap_offset);
|
||||
new (&g_frame_allocator) frame_allocator {blocks, kargs.frame_blocks.count};
|
||||
|
||||
// Mark all the things the bootloader allocated for us as used
|
||||
allocation_register *reg = kargs.allocations;
|
||||
while (reg) {
|
||||
for (auto &alloc : reg->entries)
|
||||
if (alloc.type != init::allocation_type::none)
|
||||
if (alloc.type != bootproto::allocation_type::none)
|
||||
g_frame_allocator.used(alloc.address, alloc.count);
|
||||
reg = reg->next;
|
||||
}
|
||||
@@ -95,27 +91,27 @@ memory_initialize_pre_ctors(init::args &kargs)
|
||||
vm_space &vm = kp->space();
|
||||
|
||||
vm_area *heap = new (&g_kernel_heap_area)
|
||||
vm_area_untracked(kernel_max_heap, vm_flags::write);
|
||||
vm_area_untracked(mem::heap_size, vm_flags::write);
|
||||
|
||||
vm.add(heap_start, heap);
|
||||
vm.add(mem::heap_offset, heap);
|
||||
|
||||
vm_area *stacks = new (&g_kernel_stacks) vm_area_guarded {
|
||||
memory::stacks_start,
|
||||
memory::kernel_stack_pages,
|
||||
memory::kernel_max_stacks,
|
||||
mem::stacks_offset,
|
||||
mem::kernel_stack_pages,
|
||||
mem::stacks_size,
|
||||
vm_flags::write};
|
||||
vm.add(memory::stacks_start, &g_kernel_stacks);
|
||||
vm.add(mem::stacks_offset, &g_kernel_stacks);
|
||||
|
||||
// Clean out any remaning bootloader page table entries
|
||||
for (unsigned i = 0; i < memory::pml4e_kernel; ++i)
|
||||
for (unsigned i = 0; i < arch::kernel_root_index; ++i)
|
||||
kpml4->entries[i] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
memory_initialize_post_ctors(init::args &kargs)
|
||||
memory_initialize_post_ctors(bootproto::args &kargs)
|
||||
{
|
||||
vm_space &vm = vm_space::kernel_space();
|
||||
vm.add(memory::buffers_start, &g_kernel_buffers);
|
||||
vm.add(mem::buffers_offset, &g_kernel_buffers);
|
||||
|
||||
g_frame_allocator.free(
|
||||
get_physical_page(kargs.page_tables.pointer),
|
||||
@@ -179,7 +175,7 @@ log_mtrrs()
|
||||
|
||||
|
||||
void
|
||||
load_init_server(init::program &program, uintptr_t modules_address)
|
||||
load_init_server(bootproto::program &program, uintptr_t modules_address)
|
||||
{
|
||||
process *p = new process;
|
||||
p->add_handle(&system::get());
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "memory.h"
|
||||
#include "objects/channel.h"
|
||||
#include "objects/vm_area.h"
|
||||
|
||||
extern vm_area_guarded g_kernel_buffers;
|
||||
|
||||
constexpr size_t buffer_bytes = memory::kernel_buffer_pages * memory::frame_size;
|
||||
constexpr size_t buffer_bytes = mem::kernel_buffer_pages * mem::frame_size;
|
||||
|
||||
channel::channel() :
|
||||
m_len(0),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <j6/signals.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "log.h"
|
||||
@@ -42,7 +43,7 @@ thread::from_tcb(TCB *tcb)
|
||||
{
|
||||
static ptrdiff_t offset =
|
||||
-1 * static_cast<ptrdiff_t>(offsetof(thread, m_tcb));
|
||||
return reinterpret_cast<thread*>(offset_pointer(tcb, offset));
|
||||
return reinterpret_cast<thread*>(util::offset_pointer(tcb, offset));
|
||||
}
|
||||
|
||||
thread & thread::current() { return *current_cpu().thread; }
|
||||
@@ -196,8 +197,8 @@ thread::add_thunk_user(uintptr_t rip3, uintptr_t rip0, uint64_t flags)
|
||||
void
|
||||
thread::setup_kernel_stack()
|
||||
{
|
||||
using memory::frame_size;
|
||||
using memory::kernel_stack_pages;
|
||||
using mem::frame_size;
|
||||
using mem::kernel_stack_pages;
|
||||
static constexpr size_t stack_bytes = kernel_stack_pages * frame_size;
|
||||
|
||||
constexpr unsigned null_frame_entries = 2;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include "kernel_memory.h"
|
||||
|
||||
#include "assert.h"
|
||||
#include "frame_allocator.h"
|
||||
#include "memory.h"
|
||||
#include "objects/vm_area.h"
|
||||
#include "page_tree.h"
|
||||
#include "vm_space.h"
|
||||
|
||||
using memory::frame_size;
|
||||
using mem::frame_size;
|
||||
|
||||
vm_area::vm_area(size_t size, vm_flags flags) :
|
||||
m_size {size},
|
||||
@@ -74,7 +74,7 @@ vm_area_fixed::~vm_area_fixed()
|
||||
if (m_flags && vm_flags::mmio)
|
||||
return;
|
||||
|
||||
size_t pages = memory::page_count(m_size);
|
||||
size_t pages = mem::page_count(m_size);
|
||||
frame_allocator::get().free(m_start, pages);
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ vm_area_open::get_page(uintptr_t offset, uintptr_t &phys)
|
||||
vm_area_guarded::vm_area_guarded(uintptr_t start, size_t buf_pages, size_t size, vm_flags flags) :
|
||||
m_start {start},
|
||||
m_pages {buf_pages},
|
||||
m_next {memory::frame_size},
|
||||
m_next {mem::frame_size},
|
||||
vm_area_open {size, flags}
|
||||
{
|
||||
}
|
||||
@@ -160,7 +160,7 @@ vm_area_guarded::get_section()
|
||||
}
|
||||
|
||||
uintptr_t addr = m_next;
|
||||
m_next += (m_pages + 1) * memory::frame_size;
|
||||
m_next += (m_pages + 1) * mem::frame_size;
|
||||
return m_start + addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <util/vector.h>
|
||||
#include <enum_bitfields.h>
|
||||
|
||||
#include "kernel_memory.h"
|
||||
#include "objects/kobject.h"
|
||||
|
||||
class page_tree;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#include <string.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "console.h"
|
||||
#include "frame_allocator.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "memory.h"
|
||||
#include "frame_allocator.h"
|
||||
#include "page_table.h"
|
||||
|
||||
using memory::page_offset;
|
||||
using mem::frame_size;
|
||||
using mem::linear_offset;
|
||||
using level = page_table::level;
|
||||
|
||||
free_page_header * page_table::s_page_cache = nullptr;
|
||||
@@ -123,7 +124,7 @@ page_table::iterator::check_table(level l) const
|
||||
|
||||
uint64_t parent = entry(l - 1);
|
||||
if (parent & 1) {
|
||||
table(l) = reinterpret_cast<page_table*>(page_offset | (parent & ~0xfffull));
|
||||
table(l) = reinterpret_cast<page_table*>(linear_offset | (parent & ~0xfffull));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -138,11 +139,11 @@ page_table::iterator::ensure_table(level l)
|
||||
if (check_table(l)) return;
|
||||
|
||||
page_table *table = page_table::get_table_page();
|
||||
uintptr_t phys = reinterpret_cast<uintptr_t>(table) & ~page_offset;
|
||||
uintptr_t phys = reinterpret_cast<uintptr_t>(table) & ~linear_offset;
|
||||
|
||||
uint64_t &parent = entry(l - 1);
|
||||
flag flags = table_flags;
|
||||
if (m_index[0] < memory::pml4e_kernel)
|
||||
if (m_index[0] < arch::kernel_root_index)
|
||||
flags |= flag::user;
|
||||
|
||||
m_table[unsigned(l)] = table;
|
||||
@@ -161,14 +162,14 @@ page_table::get(int i, uint16_t *flags) const
|
||||
if (flags)
|
||||
*flags = entry & 0xfffull;
|
||||
|
||||
return reinterpret_cast<page_table *>((entry & ~0xfffull) + page_offset);
|
||||
return reinterpret_cast<page_table *>((entry & ~0xfffull) + linear_offset);
|
||||
}
|
||||
|
||||
void
|
||||
page_table::set(int i, page_table *p, uint16_t flags)
|
||||
{
|
||||
entries[i] =
|
||||
(reinterpret_cast<uint64_t>(p) - page_offset) |
|
||||
(reinterpret_cast<uint64_t>(p) - linear_offset) |
|
||||
(flags & 0xfff);
|
||||
}
|
||||
|
||||
@@ -192,7 +193,7 @@ page_table::get_table_page()
|
||||
--s_cache_count;
|
||||
}
|
||||
|
||||
memset(page, 0, memory::frame_size);
|
||||
memset(page, 0, frame_size);
|
||||
return reinterpret_cast<page_table*>(page);
|
||||
}
|
||||
|
||||
@@ -219,14 +220,14 @@ page_table::fill_table_page_cache()
|
||||
kassert(phys, "Got physical page 0 as a page table");
|
||||
|
||||
free_page_header *start =
|
||||
memory::to_virtual<free_page_header>(phys);
|
||||
mem::to_virtual<free_page_header>(phys);
|
||||
|
||||
for (int i = 0; i < n - 1; ++i)
|
||||
offset_pointer(start, i * memory::frame_size)
|
||||
->next = offset_pointer(start, (i+1) * memory::frame_size);
|
||||
util::offset_pointer(start, i * frame_size)
|
||||
->next = util::offset_pointer(start, (i+1) * frame_size);
|
||||
|
||||
free_page_header *end =
|
||||
offset_pointer(start, (n-1) * memory::frame_size);
|
||||
util::offset_pointer(start, (n-1) * frame_size);
|
||||
|
||||
end->next = s_page_cache;
|
||||
s_page_cache = start;
|
||||
@@ -238,14 +239,14 @@ void
|
||||
page_table::free(page_table::level l)
|
||||
{
|
||||
unsigned last = l == level::pml4
|
||||
? memory::pml4e_kernel
|
||||
: memory::table_entries;
|
||||
? arch::kernel_root_index
|
||||
: arch::table_entries;
|
||||
|
||||
frame_allocator &fa = frame_allocator::get();
|
||||
for (unsigned i = 0; i < last; ++i) {
|
||||
if (!is_present(i)) continue;
|
||||
if (is_page(l, i)) {
|
||||
size_t count = memory::page_count(entry_sizes[unsigned(l)]);
|
||||
size_t count = mem::page_count(entry_sizes[unsigned(l)]);
|
||||
fa.free(entries[i] & ~0xfffull, count);
|
||||
} else {
|
||||
get(i)->free(l + 1);
|
||||
@@ -261,7 +262,7 @@ page_table::dump(page_table::level lvl, bool recurse)
|
||||
console *cons = console::get();
|
||||
|
||||
cons->printf("\nLevel %d page table @ %lx:\n", lvl, this);
|
||||
for (int i=0; i<memory::table_entries; ++i) {
|
||||
for (int i=0; i<arch::table_entries; ++i) {
|
||||
uint64_t ent = entries[i];
|
||||
|
||||
if ((ent & 0x1) == 0)
|
||||
@@ -275,11 +276,11 @@ page_table::dump(page_table::level lvl, bool recurse)
|
||||
|
||||
else
|
||||
cons->printf(" %3d: %016lx -> Level %d table at %016lx\n",
|
||||
i, ent, deeper(lvl), (ent & ~0xfffull) + page_offset);
|
||||
i, ent, deeper(lvl), (ent & ~0xfffull) + linear_offset);
|
||||
}
|
||||
|
||||
if (lvl != level::pt && recurse) {
|
||||
for (int i=0; i<=memory::table_entries; ++i) {
|
||||
for (int i=0; i<=arch::table_entries; ++i) {
|
||||
if (is_large_page(lvl, i))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
/// Helper structures for dealing with page tables.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <arch/memory.h>
|
||||
#include <util/spinlock.h>
|
||||
#include <enum_bitfields.h>
|
||||
#include <kernel_memory.h>
|
||||
|
||||
struct free_page_header;
|
||||
|
||||
@@ -173,7 +173,7 @@ struct page_table
|
||||
/// Print this table to the debug console.
|
||||
void dump(level lvl = level::pml4, bool recurse = true);
|
||||
|
||||
uint64_t entries[memory::table_entries];
|
||||
uint64_t entries[arch::table_entries];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <arch/memory.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "frame_allocator.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "page_tree.h"
|
||||
|
||||
// Page tree levels map the following parts of an offset. Note the xxx part of
|
||||
@@ -26,7 +27,7 @@ static_assert(sizeof(page_tree) == 66 * sizeof(uintptr_t));
|
||||
static constexpr unsigned max_level = 5;
|
||||
static constexpr unsigned bits_per_level = 6;
|
||||
|
||||
inline int level_shift(uint8_t level) { return level * bits_per_level + memory::frame_bits; }
|
||||
inline int level_shift(uint8_t level) { return level * bits_per_level + arch::frame_bits; }
|
||||
inline uint64_t level_mask(uint8_t level) { return ~0x3full << level_shift(level); }
|
||||
inline int index_for(uint64_t off, uint8_t level) { return (off >> level_shift(level)) & 0x3full; }
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "pointer_manipulation.h"
|
||||
#include "symbol_table.h"
|
||||
|
||||
namespace panicking {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "counted.h"
|
||||
#include <util/counted.h>
|
||||
|
||||
namespace panicking {
|
||||
|
||||
@@ -26,7 +26,7 @@ private:
|
||||
};
|
||||
|
||||
const void *m_data;
|
||||
counted<entry const> m_entries;
|
||||
util::counted<entry const> m_entries;
|
||||
};
|
||||
|
||||
} // namespace panicking
|
||||
|
||||
@@ -106,7 +106,7 @@ pci_device::pci_device(pci_group &group, uint8_t bus, uint8_t device, uint8_t fu
|
||||
// Walk the extended capabilities list
|
||||
uint8_t next = m_base[13] & 0xff;
|
||||
while (next) {
|
||||
pci_cap *cap = reinterpret_cast<pci_cap *>(offset_pointer(m_base, next));
|
||||
pci_cap *cap = reinterpret_cast<pci_cap *>(util::offset_pointer(m_base, next));
|
||||
next = cap->next;
|
||||
log::debug(logs::device, " - found PCI cap type %02x", cap->id);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// PCI devices and groups
|
||||
|
||||
#include <stdint.h>
|
||||
#include "memory.h"
|
||||
#include <util/pointers.h>
|
||||
|
||||
struct pci_group;
|
||||
enum class isr : uint8_t;
|
||||
@@ -126,7 +126,7 @@ struct pci_group
|
||||
/// \returns A pointer to the memory-mapped configuration registers
|
||||
inline uint32_t * base_for(uint8_t bus, uint8_t device, uint8_t func)
|
||||
{
|
||||
return offset_pointer(base,
|
||||
return util::offset_pointer(base,
|
||||
pci_device::bus_addr(bus, device, func) << 12);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "gdt.h"
|
||||
#include "interrupts.h"
|
||||
#include "io.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "log.h"
|
||||
#include "msr.h"
|
||||
#include "objects/channel.h"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "device_manager.h"
|
||||
#include "frame_allocator.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "objects/endpoint.h"
|
||||
#include "objects/thread.h"
|
||||
#include "objects/system.h"
|
||||
@@ -70,7 +71,7 @@ system_map_phys(j6_handle_t handle, j6_handle_t * area, uintptr_t phys, size_t s
|
||||
// TODO: check to see if frames are already used? How would that collide with
|
||||
// the bootloader's allocated pages already being marked used?
|
||||
if (!(flags & vm_flags::mmio))
|
||||
frame_allocator::get().used(phys, memory::page_count(size));
|
||||
frame_allocator::get().used(phys, mem::page_count(size));
|
||||
|
||||
vm_flags vmf = (static_cast<vm_flags>(flags) & vm_flags::driver_mask);
|
||||
construct_handle<vm_area_fixed>(area, phys, size, vmf);
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include "assert.h"
|
||||
#include "cpu.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "objects/vm_area.h"
|
||||
#include "tss.h"
|
||||
|
||||
@@ -45,8 +45,8 @@ void
|
||||
TSS::create_ist_stacks(uint8_t ist_entries)
|
||||
{
|
||||
extern vm_area_guarded &g_kernel_stacks;
|
||||
using memory::frame_size;
|
||||
using memory::kernel_stack_pages;
|
||||
using mem::frame_size;
|
||||
using mem::kernel_stack_pages;
|
||||
constexpr size_t stack_bytes = kernel_stack_pages * frame_size;
|
||||
|
||||
for (unsigned ist = 1; ist < 8; ++ist) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "kernel_memory.h"
|
||||
#include <arch/memory.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "frame_allocator.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "objects/process.h"
|
||||
#include "objects/thread.h"
|
||||
#include "objects/vm_area.h"
|
||||
@@ -42,8 +43,8 @@ vm_space::vm_space() :
|
||||
m_pml4 = page_table::get_table_page();
|
||||
page_table *kpml4 = kernel_space().m_pml4;
|
||||
|
||||
memset(m_pml4, 0, memory::frame_size/2);
|
||||
for (unsigned i = memory::pml4e_kernel; i < memory::table_entries; ++i)
|
||||
memset(m_pml4, 0, mem::frame_size/2);
|
||||
for (unsigned i = arch::kernel_root_index; i < arch::table_entries; ++i)
|
||||
m_pml4->entries[i] = kpml4->entries[i];
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ void
|
||||
vm_space::remove_area(vm_area *area)
|
||||
{
|
||||
area->remove_from(this);
|
||||
clear(*area, 0, memory::page_count(area->size()));
|
||||
clear(*area, 0, mem::page_count(area->size()));
|
||||
area->handle_release();
|
||||
}
|
||||
|
||||
@@ -153,7 +154,7 @@ vm_space::copy_from(const vm_space &source, const vm_area &vma)
|
||||
if (!find_vma(vma, from) || !source.find_vma(vma, from))
|
||||
return;
|
||||
|
||||
size_t count = memory::page_count(vma.size());
|
||||
size_t count = mem::page_count(vma.size());
|
||||
page_table::iterator dit {to, m_pml4};
|
||||
page_table::iterator sit {from, source.m_pml4};
|
||||
|
||||
@@ -169,7 +170,7 @@ vm_space::copy_from(const vm_space &source, const vm_area &vma)
|
||||
void
|
||||
vm_space::page_in(const vm_area &vma, uintptr_t offset, uintptr_t phys, size_t count)
|
||||
{
|
||||
using memory::frame_size;
|
||||
using mem::frame_size;
|
||||
util::scoped_lock lock {m_lock};
|
||||
|
||||
uintptr_t base = 0;
|
||||
@@ -197,7 +198,7 @@ vm_space::page_in(const vm_area &vma, uintptr_t offset, uintptr_t phys, size_t c
|
||||
void
|
||||
vm_space::clear(const vm_area &vma, uintptr_t offset, size_t count, bool free)
|
||||
{
|
||||
using memory::frame_size;
|
||||
using mem::frame_size;
|
||||
util::scoped_lock lock {m_lock};
|
||||
|
||||
uintptr_t base = 0;
|
||||
@@ -248,13 +249,13 @@ vm_space::active() const
|
||||
{
|
||||
uintptr_t pml4 = 0;
|
||||
__asm__ __volatile__ ( "mov %%cr3, %0" : "=r" (pml4) );
|
||||
return memory::to_virtual<page_table>(pml4 & ~0xfffull) == m_pml4;
|
||||
return mem::to_virtual<page_table>(pml4 & ~0xfffull) == m_pml4;
|
||||
}
|
||||
|
||||
void
|
||||
vm_space::activate() const
|
||||
{
|
||||
constexpr uint64_t phys_mask = ~memory::page_offset & ~0xfffull;
|
||||
constexpr uint64_t phys_mask = ~mem::linear_offset & ~0xfffull;
|
||||
uintptr_t p = reinterpret_cast<uintptr_t>(m_pml4) & phys_mask;
|
||||
__asm__ __volatile__ ( "mov %0, %%cr3" :: "r" (p) );
|
||||
}
|
||||
@@ -264,7 +265,7 @@ vm_space::initialize_tcb(TCB &tcb)
|
||||
{
|
||||
tcb.pml4 =
|
||||
reinterpret_cast<uintptr_t>(m_pml4) &
|
||||
~memory::page_offset;
|
||||
~mem::linear_offset;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -300,8 +301,8 @@ vm_space::copy(vm_space &source, vm_space &dest, const void *from, void *to, siz
|
||||
// TODO: iterate page mappings and continue copying. For now i'm blindly
|
||||
// assuming both buffers are fully contained within single pages
|
||||
memcpy(
|
||||
memory::to_virtual<void>((*dit & ~0xfffull) | (ito & 0xffful)),
|
||||
memory::to_virtual<void>((*sit & ~0xfffull) | (ifrom & 0xffful)),
|
||||
mem::to_virtual<void>((*dit & ~0xfffull) | (ito & 0xffful)),
|
||||
mem::to_virtual<void>((*sit & ~0xfffull) | (ifrom & 0xffful)),
|
||||
length);
|
||||
|
||||
return length;
|
||||
|
||||
Reference in New Issue
Block a user