BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / master / memory / page.c

// Related

Nucleus

Barry Object manager and heap in kernel library 08afe80 (3 years, 2 months ago)
/*
 * This file implements the Page object.  A Page refers to a page of data in a
 * file or region of memory.  The offset tracks how far into the file the page
 * is, and the frame tracks where in physical memory the data is located.
 */

#include <nucleus/memory.h>
#include <nucleus/object.h>
#include "namespace.h"

extern page_t zeroFrame;

static void page_delete(Object *);

/* Page object type */
ObjectType pageType = {
	.name = "PAGE",
	.size = sizeof(Page),
	.delete = page_delete,
};

/* Destroy a Page object */
static void
page_delete(Object *obj)
{
	Page *page = (void *) obj;
	if (page->frame != zeroFrame)
		free_frame(PAGE_ADDR(page->frame));
}

/* Create a new Page entry */
Page *
create_page(ObjectList *cache, page_t frame, off_t offset)
{
	Page *page = new(&pageType);
	page->frame = frame;
	page->offset = offset;
	add(cache, page);
	put(page);
	return page;
}

/* Find a Page by offset in a cache */
Page *
find_page(ObjectList *cache, off_t offset)
{
	Page *page;
	foreach (cache, page) {
		if (page->offset == offset)
			break;
	}
	return page;
}

/* Install a page into a virtual address space */
void
install_page(uintptr_t addr, Page *page, int prot)
{
	int access = PTE_PRESENT | PTE_USER;
	if (prot & PROT_WRITE)
		access |= PTE_WRITE;
	set_page(PAGE_ADDR(addr), page->frame | access);
	flush_tlb(PAGE_ADDR(addr));
}

/* Get the virtual address for the mapping of a page */
void *
map_page(Page *page)
{
	/*
	 * Since this x86 kernel doesn't keep all physical memory mapped into
	 * the virtual address space, the page needs to be mapped into memory.
	 * If more virtual memory was available (e.g. x86_64) all of physical
	 * memory could be mapped to an offset, and this function would just
	 * return (page->frame + offset);
	 */
	set_page(0x7FF000, page->frame | PTE_PRESENT | PTE_WRITE);
	flush_tlb(0x7FF000);
	return (void *) 0x7FF000;
}