You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
3.5 KiB
C
154 lines
3.5 KiB
C
/* See the end of this file for copyright and license terms. */
|
|
|
|
#include <arch/page.h>
|
|
#include <arch/trap.h>
|
|
|
|
#include <gay/cdefs.h>
|
|
#include <gay/config.h>
|
|
#include <gay/errno.h>
|
|
#include <gay/kprintf.h>
|
|
#include <gay/mm.h>
|
|
#include <gay/systm.h>
|
|
#include <gay/types.h>
|
|
|
|
#include <string.h>
|
|
|
|
/* from linker script */
|
|
extern void _image_start_phys;
|
|
extern void _image_end_phys;
|
|
|
|
__asmlink x86_pt_t _pt0;
|
|
__asmlink x86_pd_t _pd0;
|
|
__asmlink x86_pdp_t _pdp0;
|
|
__asmlink x86_pml4_t _pml4;
|
|
|
|
int map_page(uintptr_t phys, void *virt, enum pflags flags)
|
|
{
|
|
flags |= P_PRESENT;
|
|
x86_pml4e_t *pml4e = X86_PML4E(virt);
|
|
if (!pml4e->flags.present) {
|
|
void *page = get_pages(0, M_ATOMIC);
|
|
if (page == nil)
|
|
return -ENOMEM;
|
|
pml4e->val = __p(page) | P_PRESENT | P_RW;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* The only difference between this and map_page() is that we can't allocate
|
|
* new pages using get_pages() but have to use __early_get_page() instead here.
|
|
* So, all we need to do is ensure that map_page() doesn't need to allocate new
|
|
* pages when we call it, which it only does if pflags does not have P_HUGE
|
|
* set and the page table doesn't exist (present bit in the page directory is
|
|
* clear). Therefore, we just need to make sure that, if P_HUGE is *not*
|
|
* set, the page table is already allocated and marked as present in the page
|
|
* directory.
|
|
*/
|
|
void __early_map_page(uintptr_t phys, void *virt, enum pflags pflags)
|
|
{
|
|
}
|
|
|
|
uintptr_t unmap_page(void *virt)
|
|
{
|
|
}
|
|
|
|
enum pflags get_pflags(void *page)
|
|
{
|
|
}
|
|
|
|
int set_pflags(void *page, enum pflags pflags)
|
|
{
|
|
}
|
|
|
|
void x86_isr_page_fault(trap_frame_t *frame, u32 error_code)
|
|
{
|
|
void *address;
|
|
__asm__ volatile(
|
|
" mov %%cr2, %0 \n"
|
|
: "=r"(address)
|
|
:
|
|
);
|
|
|
|
const char *space;
|
|
if (error_code & X86_PF_USER)
|
|
space = "user";
|
|
else
|
|
space = "kernel";
|
|
|
|
const char *rwx;
|
|
if (error_code & X86_PF_WRITE)
|
|
rwx = "write to";
|
|
else if (error_code & X86_PF_INSTR)
|
|
rwx = "exec at";
|
|
else
|
|
rwx = "read from";
|
|
|
|
const char *present;
|
|
if (error_code & X86_PF_PRESENT)
|
|
present = "";
|
|
else
|
|
present = " non-mapped";
|
|
|
|
kprintf("\n########## B O N K ##########\n");
|
|
kprintf("Illegal %s %s%s address %p!\n", space, rwx, present, address);
|
|
print_regs(frame);
|
|
panic("Page fault");
|
|
}
|
|
|
|
uintptr_t vtophys(void *virt)
|
|
{
|
|
x86_pml4e_t *pml4e = X86_PML4E(virt);
|
|
if (!pml4e->flags.present)
|
|
return 0;
|
|
|
|
x86_pdpe_t *pdpe = X86_PDPE(virt);
|
|
if (!pml4e->flags.present)
|
|
return 0;
|
|
if (pml4e->flags.huge) {
|
|
uintptr_t phys_base = pdpe->val & X86_PMAP_MASK;
|
|
return phys_base + ((uintptr_t)virt % (1 << X86_PDP_SHIFT));
|
|
}
|
|
|
|
x86_pde_t *pde = X86_PDE(virt);
|
|
if (!pde->flags.present)
|
|
return 0;
|
|
if (pde->flags.huge) {
|
|
uintptr_t phys_base = pde->val & X86_PMAP_MASK;
|
|
return phys_base + ((uintptr_t)virt % (1 << X86_PD_SHIFT));
|
|
}
|
|
|
|
x86_pte_t *pte = X86_PTE(virt);
|
|
if (!pte->flags.present)
|
|
return 0;
|
|
uintptr_t phys_base = pte->val & X86_PMAP_MASK;
|
|
return phys_base + ((uintptr_t)virt % (1 << X86_PT_SHIFT));
|
|
}
|
|
|
|
void vm_flush(void)
|
|
{
|
|
register_t tmp;
|
|
__asm__ volatile(
|
|
" mov %%cr3, %0 \n"
|
|
" mov %0, %%cr3 \n"
|
|
: "=r"(tmp)
|
|
:
|
|
: "memory"
|
|
);
|
|
}
|
|
|
|
/*
|
|
* This file is part of GayBSD.
|
|
* Copyright (c) 2021 fef <owo@fef.moe>.
|
|
*
|
|
* GayBSD is nonviolent software: you may only use, redistribute, and/or
|
|
* modify it under the terms of the Cooperative Nonviolent Public License
|
|
* (CNPL) as found in the LICENSE file in the source code root directory
|
|
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
|
* of the license, or (at your option) any later version.
|
|
*
|
|
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
|
* permitted by applicable law. See the CNPL for details.
|
|
*/
|