metal-cos/sys/arm64/pmap.c
2024-09-26 04:07:50 +08:00

324 lines
6.3 KiB
C

#include <stdbool.h>
#include <stdint.h>
#include <sys/kconfig.h>
#include <sys/kassert.h>
#include <sys/kdebug.h>
#include <sys/kmem.h>
#include <sys/mp.h>
#include <machine/cpu.h>
#include <machine/cpuop.h>
#include <machine/pmap.h>
AS systemAS;
AS *currentAS[MAX_CPUS];
void
PMap_Init()
{
int i, j;
kprintf("Initializing PMAP ... ");
// Setup global state
for (i = 0; i < MAX_CPUS; i++) {
currentAS[i] = 0;
}
// Allocate system page table
systemAS.root = PAlloc_AllocPage();
systemAS.tables = PAGETABLE_ENTRIES / 2 + 1;
systemAS.mappings = 0;
if (!systemAS.root)
PANIC("Cannot allocate system page table");
// Setup system mappings
PMap_SystemLMap(0x0, MEM_DIRECTMAP_BASE + 0x0,
3*512, 0); // 3GB RWX
PMap_SystemLMap(0xC0000000, MEM_DIRECTMAP_BASE + 0xC0000000,
512, 0); // 1GB RW + PCD
PMap_SystemLMap(0x100000000, MEM_DIRECTMAP_BASE + 0x100000000,
60*512, 0); // 60GB RWX
PMap_LoadAS(&systemAS);
kprintf("Done!\n");
}
void
PMap_InitAP()
{
PMap_LoadAS(&systemAS);
}
/**
* PMap_NewAS --
*
* Create a new address space.
*
* @return Newly created address space.
*/
AS*
PMap_NewAS()
{
int i;
AS *as = PAlloc_AllocPage();
if (!as)
return NULL;
as->root = PAlloc_AllocPage();
as->tables = 1;
as->mappings = 0;
// NOT IMPLEMENTED
return as;
}
/**
* PMap_DestroyAS --
*
* Destroys an address space and releases the physical pages.
*
* @param [in] space Address space to destroy.
*/
void
PMap_DestroyAS(AS *space)
{
}
/**
* PMap_CurrentAS --
*
* Get the current address space on this CPU.
*
* @return Current address space.
*/
AS *
PMap_CurrentAS()
{
return currentAS[CPU()];
}
/**
* PMap_LoadAS --
*
* Load an address space into the CPU. Reloads the CR3 register in x86-64 that
* points the physical page tables and flushes the TLB entries.
*
* @param [in] space Address space to load.
*/
void
PMap_LoadAS(AS *space)
{
// Flush TLB
currentAS[CPU()] = space;
}
/**
* PMapAllocPageTable --
*
* Allocates and initializes a page table.
*
* @return Newly created PageTable.
*/
static PageTable *
PMapAllocPageTable()
{
NOT_IMPLEMENTED();
return NULL;
}
/**
* PMap_Translate --
*
* Translates a virtual address to physical address for a given address space.
*
* @param [in] space Address space we wish to lookup a mapping in.
* @param [in] va Virtual address we wish to translate.
*/
uintptr_t
PMap_Translate(AS *space, uintptr_t va)
{
NOT_IMPLEMENTED();
return 0;
}
/**
* PMapLookupEntry --
*
* Lookup a virtual address in a page table and return a pointer to the page
* entry. This function allocates page tables as necessary to fill in the
* 4-level heirarchy.
*
* @param [in] space Address space to search.
* @param [in] va Virtual address to lookup.
* @param [out] entry Pointer will point to the PageEntry.
* @param [in] size Page size we want to use.
*/
static void
PMapLookupEntry(AS *space, uint64_t va, PageEntry **entry, int size)
{
NOT_IMPLEMENTED();
return;
}
/**
* PMap_Map --
*
* Map a physical to virtual mapping in an address space.
*
* @param [in] as Address space.
* @param [in] phys Physical address.
* @param [in] virt Virtual address.
* @param [in] pages Pages to map in.
* @param [in] flags Flags to apply to the mapping.
*
* @retval true On success
* @retval false On failure
*/
bool
PMap_Map(AS *as, uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags)
{
NOT_IMPLEMENTED();
return true;
}
/**
* PMap_Unmap --
*
* Unmap a range of addresses.
*
* @param [in] as Address space.
* @param [in] va Virtual address.
* @param [in] pages Pages to map in.
*
* @retval true On success
* @retval false On failure
*/
bool
PMap_Unmap(AS *as, uint64_t va, uint64_t pages)
{
NOT_IMPLEMENTED();
return true;
}
/**
* PMap_AllocMap --
*
* Map a virtual mapping in an address space and back it by newly allocated
* memory.
*
* @param [in] as Address space.
* @param [in] virt Virtual address.
* @param [in] pages Pages to map in.
* @param [in] flags Flags to apply to the mapping.
*
* @retval true On success
* @retval false On failure
*/
bool
PMap_AllocMap(AS *as, uint64_t virt, uint64_t len, uint64_t flags)
{
NOT_IMPLEMENTED();
return true;
}
/**
* PMap_SystemLookup --
*
* Lookup a kernel virtual address in a page table and return a pointer to the
* page entry. This function allocates page tables as necessary to fill in the
* 4-level heirarchy.
*
* @param [in] va Virtual address to lookup.
* @param [out] entry Pointer will point to the PageEntry.
* @param [in] size Page size we want to use.
*/
void
PMap_SystemLookup(uint64_t va, PageEntry **entry, int size)
{
PMapLookupEntry(&systemAS, va, entry, size);
}
/**
* PMap_SystemLMap --
*
* Map a range of large (64MB) physical pages to virtual pages in the kernel
* address space that is shared by all processes.
*
* @param [in] phys Physical address.
* @param [in] virt Virtual address.
* @param [in] lpages Large pages to map in.
* @param [in] flags Flags to apply to the mapping.
*
* @retval true On success
* @retval false On failure
*/
bool
PMap_SystemLMap(uint64_t phys, uint64_t virt, uint64_t lpages, uint64_t flags)
{
return true;
}
/**
* PMap_SystemLMap --
*
* Map a range of physical pages to virtual pages in the kernel address space
* that is shared by all processes.
*
* @param [in] phys Physical address.
* @param [in] virt Virtual address.
* @param [in] pages Pages to map in.
* @param [in] flags Flags to apply to the mapping.
*
* @retval true On success
* @retval false On failure
*/
bool
PMap_SystemMap(uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags)
{
NOT_IMPLEMENTED();
return true;
}
/**
* PMap_SystemUnmap --
*
* We do not currently use this!
*/
bool
PMap_SystemUnmap(uint64_t virt, uint64_t pages)
{
NOT_IMPLEMENTED();
return false;
}
// static uint64_t
// AddrFromIJKL(uint64_t i, uint64_t j, uint64_t k, uint64_t l)
// {
// return (i << 39) | (j << HUGE_PGSHIFT) | (k << LARGE_PGSHIFT) | (l << PGSHIFT);
// }
void
PMap_Dump(AS *space)
{
return;
}
static void
Debug_PMapDump(int argc, const char *argv[])
{
PMap_Dump(currentAS[CPU()]);
}
REGISTER_DBGCMD(pmapdump, "Dump memory mappings", Debug_PMapDump);