diff --git a/src/include/kernel_memory.h b/src/include/kernel_memory.h index 07709a9..92cb2d9 100644 --- a/src/include/kernel_memory.h +++ b/src/include/kernel_memory.h @@ -53,4 +53,9 @@ namespace memory { /// through the page_offset area. inline bool page_mappable(uintptr_t a) { return (a & page_offset) == 0; } + /// Convert a physical address to a virtual one (in the offset-mapped area) + template T * to_virtual(uintptr_t a) { + return reinterpret_cast(a|page_offset); + } + } // namespace memory diff --git a/src/kernel/apic.cpp b/src/kernel/apic.cpp index e197f11..c63b3c1 100644 --- a/src/kernel/apic.cpp +++ b/src/kernel/apic.cpp @@ -3,6 +3,7 @@ #include "clock.h" #include "interrupts.h" #include "io.h" +#include "kernel_memory.h" #include "log.h" #include "page_manager.h" @@ -42,18 +43,13 @@ ioapic_write(uint32_t volatile *base, uint8_t reg, uint32_t value) *(base + 4) = value; } -apic::apic(uint32_t *base) : - m_base(base) +apic::apic(uintptr_t base) : + m_base(memory::to_virtual(base)) { - // Map 1MiB of space for the APIC registers and - // MSI area - page_manager::get()->map_offset_pointer( - reinterpret_cast(&m_base), - 0x100000); } -lapic::lapic(uint32_t *base, isr spurious) : +lapic::lapic(uintptr_t base, isr spurious) : apic(base), m_divisor(0) { @@ -177,7 +173,7 @@ lapic::disable() } -ioapic::ioapic(uint32_t *base, uint32_t base_gsi) : +ioapic::ioapic(uintptr_t base, uint32_t base_gsi) : apic(base), m_base_gsi(base_gsi) { diff --git a/src/kernel/apic.h b/src/kernel/apic.h index 3650d30..54b86ee 100644 --- a/src/kernel/apic.h +++ b/src/kernel/apic.h @@ -11,8 +11,8 @@ class apic { public: /// Constructor - /// \arg base Base virtual address of the APIC's MMIO registers - apic(uint32_t *base); + /// \arg base Physical base address of the APIC's MMIO registers + apic(uintptr_t base); protected: uint32_t *m_base; @@ -25,9 +25,9 @@ class lapic : { public: /// Constructor - /// \arg base Base virtual address of the APIC's MMIO registers + /// \arg base Physicl base address of the APIC's MMIO registers /// \arg spurious Vector of the spurious interrupt handler - lapic(uint32_t *base, isr spurious); + lapic(uintptr_t base, isr spurious); /// Enable interrupts for the LAPIC timer. /// \arg vector Interrupt vector the timer should use @@ -79,9 +79,9 @@ class ioapic : { public: /// Constructor - /// \arg base Base virtual address of the APIC's MMIO registers + /// \arg base Physical base address of the APIC's MMIO registers /// \arg base_gsi Starting global system interrupt number of this IOAPIC - ioapic(uint32_t *base, uint32_t base_gsi); + ioapic(uintptr_t base, uint32_t base_gsi); uint32_t get_base_gsi() const { return m_base_gsi; } uint32_t get_num_gsi() const { return m_num_gsi; } diff --git a/src/kernel/device_manager.cpp b/src/kernel/device_manager.cpp index 5adf68f..51535cc 100644 --- a/src/kernel/device_manager.cpp +++ b/src/kernel/device_manager.cpp @@ -60,7 +60,7 @@ void irq4_callback(void *) device_manager::device_manager() : - m_lapic(nullptr) + m_lapic(0) { m_irqs.ensure_capacity(32); m_irqs.set_size(16); @@ -148,8 +148,7 @@ device_manager::load_xsdt(const acpi_xsdt *xsdt) void device_manager::load_apic(const acpi_apic *apic) { - uint32_t *local = reinterpret_cast(apic->local_address); - + uintptr_t local = apic->local_address; m_lapic = new lapic(local, isr::isrSpurious); size_t count = acpi_table_entries(apic, 1); @@ -173,7 +172,7 @@ device_manager::load_apic(const acpi_apic *apic) const uint8_t type = p[0]; const uint8_t length = p[1]; if (type == 1) { - uint32_t *base = reinterpret_cast(kutil::read_from(p+4)); + uintptr_t base = kutil::read_from(p+4); uint32_t base_gsr = kutil::read_from(p+8); m_ioapics.emplace(base, base_gsr); } @@ -257,13 +256,7 @@ device_manager::load_mcfg(const acpi_mcfg *mcfg) 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 = reinterpret_cast(mcfge.base); - - int num_busses = m_pci[i].bus_end - m_pci[i].bus_start + 1; - - /// Map the MMIO space into memory - pm->map_offset_pointer(reinterpret_cast(&m_pci[i].base), - (num_busses << 20)); + m_pci[i].base = memory::to_virtual(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); diff --git a/src/kernel/page_manager.cpp b/src/kernel/page_manager.cpp index 4c87654..1d3cfb1 100644 --- a/src/kernel/page_manager.cpp +++ b/src/kernel/page_manager.cpp @@ -63,78 +63,6 @@ page_manager::create_process_map() return table; } -uintptr_t -page_manager::copy_page(uintptr_t orig) -{ - uintptr_t copy = 0; - size_t n = m_frames.allocate(1, ©); - kassert(n, "copy_page could not allocate page"); - - uintptr_t orig_virt = orig + page_offset; - uintptr_t copy_virt = copy + page_offset; - - kutil::memcpy( - reinterpret_cast(copy_virt), - reinterpret_cast(orig_virt), - frame_size); - - return copy; -} - -page_table * -page_manager::copy_table(page_table *from, page_table::level lvl, page_table_indices index) -{ - page_table *to = get_table_page(); - log::debug(logs::paging, "Page manager copying level %d table at %016lx to %016lx.", lvl, from, to); - - if (lvl == page_table::level::pml4) { - for (unsigned i = pml4e_kernel; i < table_entries; ++i) - to->entries[i] = m_kernel_pml4->entries[i]; - } - - const int max = - lvl == page_table::level::pml4 - ? pml4e_kernel - : table_entries; - - unsigned pages_copied = 0; - uintptr_t from_addr = 0; - uintptr_t to_addr = 0; - - for (int i = 0; i < max; ++i) { - if (!from->is_present(i)) { - to->entries[i] = 0; - continue; - } - - index[lvl] = i; - - bool is_page = - lvl == page_table::level::pt || - from->is_large_page(lvl, i); - - if (is_page) { - uint16_t flags = from->entries[i] & 0xfffull; - uintptr_t orig = from->entries[i] & ~0xfffull; - to->entries[i] = copy_page(orig) | flags; - if (!pages_copied++) - from_addr = index.addr(); - to_addr = index.addr(); - } else { - uint16_t flags = 0; - page_table *next_from = from->get(i, &flags); - page_table *next_to = copy_table(next_from, page_table::deeper(lvl), index); - to->set(i, next_to, flags); - } - } - - if (pages_copied) - log::debug(logs::paging, " copied %3u pages %016lx - %016lx", - pages_copied, from_addr, to_addr + frame_size); - - return to; -} - void page_manager::delete_process_map(page_table *pml4) { @@ -148,13 +76,6 @@ page_manager::delete_process_map(page_table *pml4) unmap_table(pml4, page_table::level::pml4, true); } -void -page_manager::map_offset_pointer(void **pointer, size_t length) -{ - log::debug(logs::paging, "Mapping offset pointer region at %016lx size 0x%lx", *pointer, length); - *pointer = kutil::offset_pointer(*pointer, page_offset); -} - void * page_manager::get_offset_from_mapped(void *p, page_table *pml4) { @@ -174,7 +95,7 @@ page_manager::get_offset_from_mapped(void *p, page_table *pml4) if (!(a & 1)) return nullptr; - return offset_virt( + return memory::to_virtual( (a & ~0xfffull) | (v & 0xfffull)); } diff --git a/src/kernel/page_manager.h b/src/kernel/page_manager.h index 73ddb03..6bbc236 100644 --- a/src/kernel/page_manager.h +++ b/src/kernel/page_manager.h @@ -58,14 +58,6 @@ public: /// \arg pml4 The process' PML4 table void delete_process_map(page_table *pml4); - /// Copy a process' memory mappings (and memory pages). - /// \arg from Page table to copy from - /// \arg lvl Level of the given tables (default is PML4) - /// \returns The new page table - page_table * copy_table(page_table *from, - page_table::level lvl = page_table::level::pml4, - page_table_indices index = {}); - /// Allocate and map pages into virtual memory. /// \arg address The virtual address at which to map the pages /// \arg count The number of pages to map @@ -80,27 +72,6 @@ public: /// \arg pml4 The pml4 to unmap from - null for the current one void unmap_pages(void *address, size_t count, page_table *pml4 = nullptr); - /// Offset-map a pointer. No physical pages will be mapped. - /// \arg pointer Pointer to a pointer to the memory area to be mapped - /// \arg length Length of the memory area to be mapped - void map_offset_pointer(void **pointer, size_t length); - - /// Get the physical address of an offset-mapped pointer - /// \arg p Virtual address of memory that has been offset-mapped - /// \returns Physical address of the memory pointed to by p - inline uintptr_t offset_phys(void *p) const - { - return reinterpret_cast(kutil::offset_pointer(p, -memory::page_offset)); - } - - /// Get the virtual address of an offset-mapped physical address - /// \arg a Physical address of memory that has been offset-mapped - /// \returns Virtual address of the memory at address a - inline void * offset_virt(uintptr_t a) const - { - return kutil::offset_pointer(reinterpret_cast(a), memory::page_offset); - } - /// Get the offet-mapped virtual address of a normal virtual address /// \arg p Virtual address /// \returns Virtual address in offset-mapped linear space @@ -119,11 +90,6 @@ public: inline page_table * get_kernel_pml4() { return m_kernel_pml4; } private: - /// Copy a physical page - /// \arg orig Physical address of the page to copy - /// \returns Physical address of the new page - uintptr_t copy_page(uintptr_t orig); - /// Allocate a page for a page table, or pull one from the cache /// \returns An empty page mapped in page space page_table * get_table_page();