Implemented C x86 paging, removed C++ code
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
#include "memorymanagerx86.hpp"
|
||||
|
||||
unsigned int MemoryManagerx86::getPageSize() const
|
||||
{
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
physaddr_t MemoryManagerx86::createAddressSpace()
|
||||
{
|
||||
if(((size_t) table & 0xFFF) != 0)
|
||||
return -1;
|
||||
PageTableEntry* newDirectory = (PageTableEntry*) table;
|
||||
newDirectory[1022] = m_pageDirectory[1022];
|
||||
newDirectory[1023] = m_pageDirectory[1023];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MemoryManagerx86::loadAddressSpace(physaddr_t table)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int MemoryManagerx86::mapPage(void *page, physaddr_t frame, int flags)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
physaddr_t MemoryManagerx86::unmapPage(void *page)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#ifndef MEMORYMANAGERX86_H
|
||||
#define MEMORYMANAGERX86_H
|
||||
|
||||
#include "../memorymanager.hpp"
|
||||
#include "pagetableentry.hpp"
|
||||
|
||||
class MemoryManagerx86 : public MemoryManager
|
||||
{
|
||||
public:
|
||||
|
||||
virtual unsigned int getPageSize() const;
|
||||
|
||||
virtual physaddr_t createAddressSpace();
|
||||
|
||||
virtual void loadAddressSpace(physaddr_t table);
|
||||
|
||||
virtual int mapPage(void* page, physaddr_t frame, int flags);
|
||||
|
||||
virtual physaddr_t unmapPage(void* page);
|
||||
|
||||
private:
|
||||
|
||||
static const unsigned int pageSize = 4096;
|
||||
|
||||
PageTableEntry *m_pageTables, *m_pageDirectory;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
292
src/x86/mmap.cpp
292
src/x86/mmap.cpp
@@ -1,292 +0,0 @@
|
||||
#include "../mmap.hpp"
|
||||
#include "../kernelstate.hpp"
|
||||
|
||||
class PageTableEntry {
|
||||
public:
|
||||
|
||||
PageTableEntry()
|
||||
{
|
||||
this->present = 0;
|
||||
this->rw = 0;
|
||||
this->usermode = 0;
|
||||
this->writeThrough = 0;
|
||||
this->cacheDisable = 0;
|
||||
this->accessed = 0;
|
||||
this->dirty = 0;
|
||||
this->pat = 0;
|
||||
this->global = 0;
|
||||
this->shared = 0;
|
||||
this->ignored = 0;
|
||||
this->physicalAddress = 0;
|
||||
}
|
||||
|
||||
bool getAccessed() const
|
||||
{
|
||||
return accessed == 1;
|
||||
}
|
||||
|
||||
bool getCacheDisable() const
|
||||
{
|
||||
return cacheDisable == 1;
|
||||
}
|
||||
|
||||
void setCacheDisable(bool cacheDisable)
|
||||
{
|
||||
this->cacheDisable = cacheDisable ? 1 : 0;
|
||||
}
|
||||
|
||||
bool getDirty() const
|
||||
{
|
||||
return dirty == 1;
|
||||
}
|
||||
|
||||
bool getGlobal() const
|
||||
{
|
||||
return global == 1;
|
||||
}
|
||||
|
||||
void setGlobal(bool global)
|
||||
{
|
||||
this->global = global ? 1 : 0;
|
||||
}
|
||||
|
||||
bool getPat() const
|
||||
{
|
||||
return pat == 1;
|
||||
}
|
||||
|
||||
void setPat(bool pat)
|
||||
{
|
||||
this->pat = pat ? 1 : 0;
|
||||
}
|
||||
|
||||
physaddr_t getPhysicalAddress() const
|
||||
{
|
||||
physaddr_t physicalAddress = this->physicalAddress;
|
||||
return physicalAddress << 12;
|
||||
}
|
||||
|
||||
physaddr_t setPhysicalAddress(physaddr_t physicalAddress)
|
||||
{
|
||||
this->physicalAddress = physicalAddress >> 12;
|
||||
return this->physicalAddress << 12;
|
||||
}
|
||||
|
||||
bool getPresent() const
|
||||
{
|
||||
return present == 1;
|
||||
}
|
||||
|
||||
void setPresent(bool present)
|
||||
{
|
||||
this->present = present ? 1 : 0;
|
||||
}
|
||||
|
||||
bool getRw() const
|
||||
{
|
||||
return rw == 1;
|
||||
}
|
||||
|
||||
void setRw(bool rw)
|
||||
{
|
||||
this->rw = rw ? 1 : 0;
|
||||
}
|
||||
|
||||
bool getShared() const
|
||||
{
|
||||
return shared == 1;
|
||||
}
|
||||
|
||||
void setShared(bool shared)
|
||||
{
|
||||
this->shared = shared ? 1 : 0;
|
||||
}
|
||||
|
||||
bool getUsermode() const
|
||||
{
|
||||
return usermode == 1;
|
||||
}
|
||||
|
||||
void setUsermode(bool usermode)
|
||||
{
|
||||
this->usermode = usermode ? 1 : 0;
|
||||
}
|
||||
|
||||
bool getWriteThrough() const
|
||||
{
|
||||
return writeThrough == 1;
|
||||
}
|
||||
|
||||
void setWriteThrough(bool writeThrough)
|
||||
{
|
||||
this->writeThrough = writeThrough ? 1 : 0;
|
||||
}
|
||||
|
||||
physaddr_t operator=(physaddr_t rhs)
|
||||
{
|
||||
return setPhysicalAddress(rhs);
|
||||
}
|
||||
|
||||
PageTableEntry operator=(PageTableEntry rhs)
|
||||
{
|
||||
uint32_t* iThis = (uint32_t*) this;
|
||||
uint32_t* iThat = (uint32_t*) &rhs;
|
||||
*iThis = *iThat;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t present : 1;
|
||||
uint32_t rw : 1;
|
||||
uint32_t usermode : 1;
|
||||
uint32_t writeThrough : 1;
|
||||
uint32_t cacheDisable : 1;
|
||||
uint32_t accessed : 1;
|
||||
uint32_t dirty : 1;
|
||||
uint32_t pat : 1;
|
||||
uint32_t global : 1;
|
||||
uint32_t shared : 1;
|
||||
uint32_t ignored : 2;
|
||||
uint32_t physicalAddress : 20;
|
||||
};
|
||||
|
||||
int kernelns::mmap(void* start, size_t length, int flags)
|
||||
{
|
||||
if((size_t) start % 4096 != 0)
|
||||
return -1;
|
||||
PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000;
|
||||
PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000;
|
||||
size_t tableIndex = (size_t) start / 4096;
|
||||
for(int i = (int) length; i > 0; i -= 4096)
|
||||
{
|
||||
size_t directoryIndex = tableIndex / 1024;
|
||||
if(!pageDirectory[directoryIndex].getPresent())
|
||||
{
|
||||
physaddr_t newPT = State::pageAllocator.allocate(4096);
|
||||
if(newPT == 0)
|
||||
return -1;
|
||||
pageDirectory[directoryIndex] = newPT;
|
||||
pageDirectory[directoryIndex].setPresent(true);
|
||||
pageDirectory[directoryIndex].setUsermode(false);
|
||||
pageDirectory[directoryIndex].setRw(true);
|
||||
}
|
||||
if(!pageTables[tableIndex].getPresent())
|
||||
{
|
||||
physaddr_t page = State::pageAllocator.allocate(4096);
|
||||
pageTables[tableIndex] = page;
|
||||
pageTables[tableIndex].setPresent(true);
|
||||
pageTables[tableIndex].setUsermode(false);
|
||||
if(flags & MMAP_RW)
|
||||
pageTables[tableIndex].setRw(true);
|
||||
}
|
||||
tableIndex++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernelns::mmap(void* start, physaddr_t p_start, size_t length, int flags)
|
||||
{
|
||||
if((size_t) start % 4096 != 0 || p_start % 4096 != 0)
|
||||
return -1;
|
||||
physaddr_t page = p_start;
|
||||
for(int i = (int) length; i > 0; i -= 4096)
|
||||
{
|
||||
if(mapPage(start, page, flags) != 0)
|
||||
return -1;
|
||||
page += 4096;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernelns::mapPage(void* start, physaddr_t p_start, int flags)
|
||||
{
|
||||
if((size_t) start % 4096 != 0 || p_start % 4096 != 0)
|
||||
return -1;
|
||||
PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000;
|
||||
PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000;
|
||||
size_t tableIndex = (size_t) start / 4096;
|
||||
physaddr_t page = p_start;
|
||||
size_t directoryIndex = tableIndex / 1024;
|
||||
if(!pageDirectory[directoryIndex].getPresent())
|
||||
{
|
||||
physaddr_t newPT = State::pageAllocator.allocate(4096);
|
||||
if(newPT == 0)
|
||||
return -1;
|
||||
pageDirectory[directoryIndex] = newPT;
|
||||
pageDirectory[directoryIndex].setPresent(true);
|
||||
pageDirectory[directoryIndex].setUsermode(false);
|
||||
pageDirectory[directoryIndex].setRw(true);
|
||||
}
|
||||
if(!pageTables[tableIndex].getPresent())
|
||||
{
|
||||
pageTables[tableIndex] = page;
|
||||
pageTables[tableIndex].setPresent(true);
|
||||
pageTables[tableIndex].setUsermode(false);
|
||||
if(flags & MMAP_RW)
|
||||
pageTables[tableIndex].setRw(true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernelns::munmap(void* start, size_t length)
|
||||
{
|
||||
if((size_t) start % 4096 != 0)
|
||||
return -1;
|
||||
PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000;
|
||||
PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000;
|
||||
size_t tableIndex = (size_t) start / 4096;
|
||||
for(int i = (int) length; i > 0; i -= 4096)
|
||||
{
|
||||
size_t directoryIndex = tableIndex / 1024;
|
||||
if(pageDirectory[directoryIndex].getPresent())
|
||||
{
|
||||
pageTables[tableIndex] = 0;
|
||||
pageTables[tableIndex].setPresent(false);
|
||||
pageTables[tableIndex].setUsermode(false);
|
||||
pageTables[tableIndex].setRw(false);
|
||||
}
|
||||
tableIndex++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool kernelns::isMapped(void* addr)
|
||||
{
|
||||
PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000;
|
||||
size_t tableIndex = (size_t) addr / 4096;
|
||||
size_t directoryIndex = tableIndex / 1024;
|
||||
if(pageDirectory[directoryIndex].getPresent())
|
||||
{
|
||||
PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000;
|
||||
return pageTables[tableIndex].getPresent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
physaddr_t kernelns::getPhysicalAddress(void* addr)
|
||||
{
|
||||
PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000;
|
||||
size_t tableIndex = (size_t) addr / 4096;
|
||||
return pageTables[tableIndex].getPhysicalAddress() + ((size_t) addr & 0xFFF);
|
||||
}
|
||||
|
||||
int kernelns::createAddressSpace(void* table)
|
||||
{
|
||||
if(((size_t) table & 0xFFF) != 0)
|
||||
return -1;
|
||||
PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000;
|
||||
PageTableEntry* newDirectory = (PageTableEntry*) table;
|
||||
newDirectory[1022] = pageDirectory[1022];
|
||||
newDirectory[1023] = pageDirectory[1023];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernelns::loadAddressSpace(physaddr_t table)
|
||||
{
|
||||
if((table & 0xFFF) != 0)
|
||||
return -1;
|
||||
asm("mov %0, %%cr3"
|
||||
:
|
||||
: "r" (table));
|
||||
return 0;
|
||||
}
|
||||
121
src/x86/mmgr.c
Normal file
121
src/x86/mmgr.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "mmgr.h"
|
||||
#include "pageallocator.h"
|
||||
#include "string.h"
|
||||
#include "types/status.h"
|
||||
#include <stdint.h>
|
||||
|
||||
const size_t page_size = 4096;
|
||||
|
||||
const size_t page_bits = 12;
|
||||
|
||||
struct page_table_entry_t
|
||||
{
|
||||
uint32_t present : 1;
|
||||
|
||||
uint32_t rw : 1;
|
||||
|
||||
uint32_t usermode : 1;
|
||||
|
||||
uint32_t writeThrough : 1;
|
||||
|
||||
uint32_t cacheDisable : 1;
|
||||
|
||||
uint32_t accessed : 1;
|
||||
|
||||
uint32_t dirty : 1;
|
||||
|
||||
uint32_t pat : 1;
|
||||
|
||||
uint32_t global : 1;
|
||||
|
||||
uint32_t shared : 1;
|
||||
|
||||
uint32_t ignored : 2;
|
||||
|
||||
uint32_t physicalAddress : 20;
|
||||
};
|
||||
|
||||
struct page_table_entry_t *page_tables = (struct page_table_entry_t*) 0xFFC00000;
|
||||
|
||||
struct page_table_entry_t *page_directory = (struct page_table_entry_t*) 0xFFFFF000;
|
||||
|
||||
physaddr_t create_address_space(struct page_stack_t *page_stack)
|
||||
{
|
||||
physaddr_t table = reserve_page(page_stack);
|
||||
if(table == S_OUT_OF_MEMORY)
|
||||
{
|
||||
return S_OUT_OF_MEMORY;
|
||||
}
|
||||
struct page_table_entry_t buffer = page_directory[0];
|
||||
page_directory[0] = table;
|
||||
asm volatile("invlpg $0xFFC00000" ::: "memory");
|
||||
memset((void*) page_tables, 0, 1022 * 4);
|
||||
page_tables[1022] = page_directory[1022];
|
||||
page_tables[1023] = page_directory[1023];
|
||||
page_directory[0] = buffer;
|
||||
asm volatile("invlpg $0xFFC00000" ::: "memory");
|
||||
return table;
|
||||
}
|
||||
|
||||
void load_address_space(physaddr_t table)
|
||||
{
|
||||
asm volatile("mov %0, %%cr3"
|
||||
:
|
||||
: "r" (table)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int flags)
|
||||
{
|
||||
if((size_t) page % page_size != 0 || frame % page_size != 0)
|
||||
{
|
||||
return S_OUT_OF_BOUNDS;
|
||||
}
|
||||
size_t table_index = (size_t) page / page_size;
|
||||
size_t directory_index = table_index / (page_size / sizeof(struct page_table_entry_t));
|
||||
if(!page_directory[directory_index].present)
|
||||
{
|
||||
physaddr_t new_table = reserve_page(page_stack);
|
||||
if(new_table == S_OUT_OF_MEMORY)
|
||||
{
|
||||
return S_OUT_OF_MEMORY;
|
||||
}
|
||||
page_directory[directory_index] = new_table >> page_bits;
|
||||
page_directory[directory_index].present = 1;
|
||||
page_directory[directory_index].usermode = 0;
|
||||
page_directory[directory_index].rw = 1;
|
||||
}
|
||||
page_tables[table_index] = frame >> 12;
|
||||
page_tables[table_index].present = 1;
|
||||
page_tables[table_index].usermode = 1;
|
||||
page_tables[table_index].rw = 1;
|
||||
asm volatile("invlpg (%0)"
|
||||
:
|
||||
: "r" (page)
|
||||
: "memory");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
physaddr_t unmap_page(void *page)
|
||||
{
|
||||
if((size_t) page % page_size != 0)
|
||||
{
|
||||
return S_OUT_OF_BOUNDS;
|
||||
}
|
||||
size_t table_index = (size_t) page / page_size;
|
||||
size_t directory_index = table_index / (page_size / sizeof(struct page_table_entry_t));
|
||||
if(!page_directory[directory_index].present || !page_tables[table_index].present)
|
||||
{
|
||||
return S_OUT_OF_BOUNDS;
|
||||
}
|
||||
else
|
||||
{
|
||||
physaddr_t frame = page_tables[table_index].physicalAddress << page_bits;
|
||||
memset(&page_tables[table_index], 0, sizeof(struct page_table_entry_t));
|
||||
asm volatile("invlpg (%0)"
|
||||
:
|
||||
: "r" (page)
|
||||
: "memory");
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
#include "pagetableentry.hpp"
|
||||
|
||||
PageTableEntry::PageTableEntry()
|
||||
{
|
||||
this->present = 0;
|
||||
this->rw = 0;
|
||||
this->usermode = 0;
|
||||
this->writeThrough = 0;
|
||||
this->cacheDisable = 0;
|
||||
this->accessed = 0;
|
||||
this->dirty = 0;
|
||||
this->pat = 0;
|
||||
this->global = 0;
|
||||
this->shared = 0;
|
||||
this->ignored = 0;
|
||||
this->physicalAddress = 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getAccessed() const
|
||||
{
|
||||
return accessed == 1;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getCacheDisable() const
|
||||
{
|
||||
return cacheDisable == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setCacheDisable(bool cacheDisable)
|
||||
{
|
||||
this->cacheDisable = cacheDisable ? 1 : 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getDirty() const
|
||||
{
|
||||
return dirty == 1;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getGlobal() const
|
||||
{
|
||||
return global == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setGlobal(bool global)
|
||||
{
|
||||
this->global = global ? 1 : 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getPat() const
|
||||
{
|
||||
return pat == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setPat(bool pat)
|
||||
{
|
||||
this->pat = pat ? 1 : 0;
|
||||
}
|
||||
|
||||
physaddr_t PageTableEntry::getPhysicalAddress() const
|
||||
{
|
||||
physaddr_t physicalAddress = this->physicalAddress;
|
||||
return physicalAddress << 12;
|
||||
}
|
||||
|
||||
physaddr_t PageTableEntry::setPhysicalAddress(physaddr_t physicalAddress)
|
||||
{
|
||||
this->physicalAddress = physicalAddress >> 12;
|
||||
return this->physicalAddress << 12;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getPresent() const
|
||||
{
|
||||
return present == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setPresent(bool present)
|
||||
{
|
||||
this->present = present ? 1 : 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getRw() const
|
||||
{
|
||||
return rw == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setRw(bool rw)
|
||||
{
|
||||
this->rw = rw ? 1 : 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getShared() const
|
||||
{
|
||||
return shared == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setShared(bool shared)
|
||||
{
|
||||
this->shared = shared ? 1 : 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getUsermode() const
|
||||
{
|
||||
return usermode == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setUsermode(bool usermode)
|
||||
{
|
||||
this->usermode = usermode ? 1 : 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getWriteThrough() const
|
||||
{
|
||||
return writeThrough == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setWriteThrough(bool writeThrough)
|
||||
{
|
||||
this->writeThrough = writeThrough ? 1 : 0;
|
||||
}
|
||||
|
||||
physaddr_t PageTableEntry::operator=(physaddr_t rhs)
|
||||
{
|
||||
return setPhysicalAddress(rhs);
|
||||
}
|
||||
|
||||
PageTableEntry PageTableEntry::operator=(PageTableEntry rhs)
|
||||
{
|
||||
uint32_t *iThis = (uint32_t *)this;
|
||||
uint32_t *iThat = (uint32_t *)&rhs;
|
||||
*iThis = *iThat;
|
||||
return rhs;
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
#ifndef PAGETABLEENTRY_H
|
||||
#define PAGETABLEENTRY_H
|
||||
|
||||
#include "../systypes.hpp"
|
||||
|
||||
class PageTableEntry {
|
||||
public:
|
||||
|
||||
PageTableEntry();
|
||||
|
||||
bool getAccessed() const;
|
||||
|
||||
bool getCacheDisable() const;
|
||||
|
||||
void setCacheDisable(bool cacheDisable);
|
||||
|
||||
bool getDirty() const;
|
||||
|
||||
bool getGlobal() const;
|
||||
|
||||
void setGlobal(bool global);
|
||||
|
||||
bool getPat() const;
|
||||
|
||||
void setPat(bool pat);
|
||||
|
||||
physaddr_t getPhysicalAddress() const;
|
||||
|
||||
physaddr_t setPhysicalAddress(physaddr_t physicalAddress);
|
||||
|
||||
bool getPresent() const;
|
||||
|
||||
void setPresent(bool present);
|
||||
|
||||
bool getRw() const;
|
||||
|
||||
void setRw(bool rw);
|
||||
|
||||
bool getShared() const;
|
||||
|
||||
void setShared(bool shared);
|
||||
|
||||
bool getUsermode() const;
|
||||
|
||||
void setUsermode(bool usermode);
|
||||
|
||||
bool getWriteThrough() const;
|
||||
|
||||
void setWriteThrough(bool writeThrough);
|
||||
|
||||
physaddr_t operator=(physaddr_t rhs);
|
||||
|
||||
PageTableEntry operator=(PageTableEntry rhs);
|
||||
|
||||
private:
|
||||
|
||||
uint32_t present : 1;
|
||||
|
||||
uint32_t rw : 1;
|
||||
|
||||
uint32_t usermode : 1;
|
||||
|
||||
uint32_t writeThrough : 1;
|
||||
|
||||
uint32_t cacheDisable : 1;
|
||||
|
||||
uint32_t accessed : 1;
|
||||
|
||||
uint32_t dirty : 1;
|
||||
|
||||
uint32_t pat : 1;
|
||||
|
||||
uint32_t global : 1;
|
||||
|
||||
uint32_t shared : 1;
|
||||
|
||||
uint32_t ignored : 2;
|
||||
|
||||
uint32_t physicalAddress : 20;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user