Reorganized source tree. Started using autotools.
This commit is contained in:
7
src/mmgr/Makefile.am
Normal file
7
src/mmgr/Makefile.am
Normal file
@@ -0,0 +1,7 @@
|
||||
noinst_LIBRARIES = libmmgr.a
|
||||
libmmgr_a_SOURCES = memorymap.cpp buddyallocator.cpp addressspace.cpp
|
||||
libmmgr_a_CPPFLAGS = -ffreestanding -O0 -Wall -fno-exceptions -fno-rtti -ggdb
|
||||
|
||||
if x86
|
||||
libmmgr_a_SOURCES += x86/pagetableentry.cpp
|
||||
endif
|
||||
51
src/mmgr/addressspace.cpp
Normal file
51
src/mmgr/addressspace.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "addressspace.hpp"
|
||||
|
||||
kernel::AddressSpace::AddressSpace(MemoryAllocator& malloc)
|
||||
: malloc(malloc)
|
||||
{
|
||||
this->pageTables = (PageTableEntry*) 0xFFC00000;
|
||||
this->pageDirectory = (PageTableEntry*) 0xFFFFF000;
|
||||
}
|
||||
|
||||
void* kernel::AddressSpace::mmap(void* start, size_t length)
|
||||
{
|
||||
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 = malloc.allocate(4096);
|
||||
pageDirectory[directoryIndex] = newPT;
|
||||
pageDirectory[directoryIndex].setPresent(true);
|
||||
pageDirectory[directoryIndex].setUsermode(false);
|
||||
pageDirectory[directoryIndex].setRw(true);
|
||||
}
|
||||
if(!pageTables[tableIndex].getPresent())
|
||||
{
|
||||
physaddr_t page = malloc.allocate(4096);
|
||||
pageTables[tableIndex] = page;
|
||||
pageTables[tableIndex].setUsermode(false);
|
||||
pageTables[tableIndex].setRw(true);
|
||||
pageTables[tableIndex].setPresent(true);
|
||||
}
|
||||
tableIndex++;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
void kernel::AddressSpace::munmap(void* start, size_t length)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
physaddr_t kernel::AddressSpace::getPhysicalAddress(void* virtualAddress)
|
||||
const
|
||||
{
|
||||
size_t index = (size_t) virtualAddress / 4096;
|
||||
PageTableEntry pte = pageTables[index];
|
||||
if(pte.getPresent())
|
||||
return pte.getPhysicalAddress();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
42
src/mmgr/addressspace.hpp
Executable file
42
src/mmgr/addressspace.hpp
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef SRC_ADDRESSSPACE_H_
|
||||
#define SRC_ADDRESSSPACE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "memoryallocator.hpp"
|
||||
#include "x86/pagetableentry.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
namespace kernel {
|
||||
|
||||
class AddressSpace {
|
||||
public:
|
||||
|
||||
AddressSpace(MemoryAllocator& malloc);
|
||||
|
||||
void* mmap(void* start, size_t length);
|
||||
|
||||
void munmap(void* start, size_t length);
|
||||
|
||||
physaddr_t getPhysicalAddress(void* virtualAddress) const;
|
||||
|
||||
private:
|
||||
|
||||
MemoryAllocator& malloc;
|
||||
|
||||
/**
|
||||
* Array of 1024 page tables, each containing 1024 entries.
|
||||
* The last table represents the page directory.
|
||||
*/
|
||||
PageTableEntry* pageTables;
|
||||
|
||||
/**
|
||||
* Array of 1024 PDEs, located at the end of the pageTables array
|
||||
*/
|
||||
PageTableEntry* pageDirectory;
|
||||
|
||||
};
|
||||
|
||||
} /* namespace kernel */
|
||||
|
||||
#endif
|
||||
269
src/mmgr/buddyallocator.cpp
Executable file
269
src/mmgr/buddyallocator.cpp
Executable file
@@ -0,0 +1,269 @@
|
||||
#include "buddyallocator.hpp"
|
||||
#include "types.hpp"
|
||||
#include "memorymap.hpp"
|
||||
|
||||
#define roundUp(n, m) ((n % m == 0) ? n : (n + m - (n % m)))
|
||||
|
||||
uint32_t ilog2(uint32_t n, bool roundUp)
|
||||
{
|
||||
uint32_t m = n;
|
||||
uint32_t count = 0;
|
||||
bool isPowerOfTwo = true;
|
||||
while(m)
|
||||
{
|
||||
if((m & 1) == 1 && m > 1)
|
||||
{
|
||||
isPowerOfTwo = false;
|
||||
}
|
||||
count++;
|
||||
m >>= 1;
|
||||
}
|
||||
return count - (isPowerOfTwo ? 1 : (roundUp ? 0 : 1));
|
||||
}
|
||||
|
||||
kernel::BuddyAllocator::BuddyAllocator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
kernel::BuddyAllocator::BuddyAllocator(kernel::MemoryMap& memmap,
|
||||
char* bitmap, size_t blockCount,
|
||||
size_t treeHeight)
|
||||
{
|
||||
this->bitmap = bitmap;
|
||||
this->blockSize = 4096;
|
||||
this->blockCount = blockCount;
|
||||
this->treeHeight = treeHeight;
|
||||
for(size_t i = 0; i <= treeHeight; i++)
|
||||
{
|
||||
for(size_t j = 0; j < (blockCount >> i); j++)
|
||||
{
|
||||
reserveNode(i, j);
|
||||
}
|
||||
}
|
||||
physaddr_t location = 0x100000;
|
||||
for(size_t i = 0; i < memmap.size() && memmap[i].getSize() > 0; i++)
|
||||
{
|
||||
if(memmap[i].getType() != kernel::MemoryMap::AVAILABLE)
|
||||
continue;
|
||||
if(memmap[i].getLocation() > location)
|
||||
location = roundUp(memmap[i].getLocation(), 4096);
|
||||
while(memmap[i].contains(location, 4096))
|
||||
{
|
||||
freeNode(0, location / 4096);
|
||||
if(isFree(0, getBuddy(location / 4096)))
|
||||
merge(0, location / 4096);
|
||||
location += 4096;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kernel::BuddyAllocator::BuddyAllocator(char* bitmap, size_t blockSize,
|
||||
size_t blockCount, size_t treeHeight)
|
||||
{
|
||||
this->bitmap = bitmap;
|
||||
this->blockSize = blockSize;
|
||||
this->blockCount = blockCount;
|
||||
this->treeHeight = treeHeight;
|
||||
for(size_t i = 0; i <= treeHeight; i++)
|
||||
{
|
||||
for(size_t j = 0; j < (blockCount >> i); j++)
|
||||
{
|
||||
if(i < treeHeight)
|
||||
reserveNode(i, j);
|
||||
else
|
||||
freeNode(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
physaddr_t kernel::BuddyAllocator::allocate(size_t size)
|
||||
{
|
||||
size_t height = ilog2(roundUp(size, blockSize) / blockSize, true);
|
||||
if(height > treeHeight) // Requested block size is greater than maximum
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t index = findFreeBlock(height);
|
||||
if(index == INVALID) // Failed to find a big enough free block; out of memory
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
reserveNode(height, index);
|
||||
return nodeToAddress(height, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void kernel::BuddyAllocator::free(physaddr_t location, size_t size)
|
||||
{
|
||||
size_t height = ilog2(roundUp(size, blockSize) / blockSize, true);
|
||||
if(height <= treeHeight)
|
||||
{
|
||||
size_t index = addressToNode(height, location);
|
||||
freeNode(height, index);
|
||||
if(isFree(height, getBuddy(index)))
|
||||
{
|
||||
merge(height, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::freeBlocks() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for(size_t j = 0; j < blockCount; j++)
|
||||
{
|
||||
if(isFree(0, j))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::maxAllocationSize() const
|
||||
{
|
||||
for(size_t i = treeHeight; i >= 0; i--)
|
||||
{
|
||||
for(size_t j = 0; j < (blockCount >> i); j++)
|
||||
{
|
||||
if(isFree(i, j))
|
||||
{
|
||||
return 1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::getBlockSize() const
|
||||
{
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::getMemorySize() const
|
||||
{
|
||||
return blockCount;
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::findFreeBlock(size_t height)
|
||||
{
|
||||
for(size_t i = 0; i < (blockCount >> height); i++)
|
||||
{
|
||||
if(isFree(height, i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if(height < treeHeight)
|
||||
{
|
||||
size_t parentIndex = findFreeBlock(height + 1);
|
||||
if(parentIndex != INVALID)
|
||||
{
|
||||
return split(height + 1, parentIndex);
|
||||
}
|
||||
}
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::split(size_t height, size_t index)
|
||||
{
|
||||
if(height > 0 && isFree(height, index))
|
||||
{
|
||||
reserveNode(height, index);
|
||||
freeNode(height - 1, getChild(index));
|
||||
freeNode(height - 1, getBuddy(getChild(index)));
|
||||
return getChild(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::merge(size_t height, size_t index)
|
||||
{
|
||||
if(isFree(height, index) && isFree(height, getBuddy(index)) && height < treeHeight)
|
||||
{
|
||||
reserveNode(height, index);
|
||||
reserveNode(height, getBuddy(index));
|
||||
freeNode(height + 1, getParent(index));
|
||||
if((height + 1) < treeHeight)
|
||||
{
|
||||
if(isFree(height + 1, getBuddy(getParent(index))))
|
||||
{
|
||||
return merge(height + 1, getParent(index));
|
||||
|
||||
}
|
||||
}
|
||||
return getParent(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::getBuddy(size_t index)
|
||||
{
|
||||
return index ^ 1;
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::getParent(size_t index)
|
||||
{
|
||||
return index / 2;
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::getChild(size_t index)
|
||||
{
|
||||
return index * 2;
|
||||
}
|
||||
|
||||
physaddr_t kernel::BuddyAllocator::nodeToAddress(size_t height, size_t index)
|
||||
const
|
||||
{
|
||||
return index * (blockSize << height);
|
||||
}
|
||||
|
||||
size_t kernel::BuddyAllocator::addressToNode(size_t height,
|
||||
physaddr_t location) const
|
||||
{
|
||||
return location / (blockSize << height);
|
||||
}
|
||||
|
||||
void kernel::BuddyAllocator::reserveNode(size_t height, size_t index)
|
||||
{
|
||||
size_t bit = (height == 0) ? 0
|
||||
: ((blockCount * 2) - (blockCount >> (height - 1)));
|
||||
bit += index;
|
||||
bitmap[bit / 8] |= 1 << (bit % 8);
|
||||
}
|
||||
|
||||
void kernel::BuddyAllocator::freeNode(size_t height, size_t index)
|
||||
{
|
||||
size_t bit = (height == 0) ? 0
|
||||
: ((blockCount * 2) - (blockCount >> (height - 1)));
|
||||
bit += index;
|
||||
bitmap[bit / 8] &= ~(1 << (bit % 8));
|
||||
}
|
||||
|
||||
bool kernel::BuddyAllocator::isFree(size_t height, size_t index) const
|
||||
{
|
||||
size_t bit = (height == 0) ? 0
|
||||
: ((blockCount * 2) - (blockCount >> (height - 1)));
|
||||
bit += index;
|
||||
char data = bitmap[bit / 8] & (1 << (bit % 8));
|
||||
if(data == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
94
src/mmgr/buddyallocator.hpp
Executable file
94
src/mmgr/buddyallocator.hpp
Executable file
@@ -0,0 +1,94 @@
|
||||
#ifndef BUDDYALLOCATOR_H_
|
||||
#define BUDDYALLOCATOR_H_
|
||||
|
||||
#include "memoryallocator.hpp"
|
||||
#include "memorymap.hpp"
|
||||
|
||||
namespace kernel
|
||||
{
|
||||
|
||||
class BuddyAllocator : public MemoryAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
BuddyAllocator();
|
||||
|
||||
BuddyAllocator(MemoryMap& memmap, char* bitmap, size_t blockCount,
|
||||
size_t treeHeight);
|
||||
|
||||
BuddyAllocator(char* bitmap, size_t blockSize, size_t blockCount,
|
||||
size_t treeHeight);
|
||||
|
||||
/**
|
||||
* Allocate a block of memory containing at least 'size' bytes.
|
||||
* Rounds up to the nearest power of 2 times the size of a block.
|
||||
*/
|
||||
virtual physaddr_t allocate(size_t size);
|
||||
|
||||
/**
|
||||
* Free the region of memory starting at 'location' and containing
|
||||
* 'size' bytes.
|
||||
*/
|
||||
virtual void free(physaddr_t location, size_t size);
|
||||
|
||||
/**
|
||||
* @returns the total number of free blocks of memory.
|
||||
*/
|
||||
virtual size_t freeBlocks() const;
|
||||
|
||||
/**
|
||||
* @returns the size in blocks of the largest possible allocation that
|
||||
* will not fail due to lack of memory.
|
||||
*/
|
||||
virtual size_t maxAllocationSize() const;
|
||||
|
||||
/**
|
||||
* @returns the size in bytes of a single block.
|
||||
*/
|
||||
virtual size_t getBlockSize() const;
|
||||
|
||||
/**
|
||||
* @returns the total number of blocks managed by this memory
|
||||
* allocator.
|
||||
*/
|
||||
virtual size_t getMemorySize() const;
|
||||
|
||||
private:
|
||||
|
||||
static const size_t INVALID = (size_t) -1;
|
||||
|
||||
char* bitmap;
|
||||
|
||||
size_t blockSize;
|
||||
|
||||
size_t blockCount;
|
||||
|
||||
size_t treeHeight;
|
||||
|
||||
size_t findFreeBlock(size_t height);
|
||||
|
||||
size_t split(size_t height, size_t index);
|
||||
|
||||
size_t merge(size_t height, size_t index);
|
||||
|
||||
size_t getBuddy(size_t index);
|
||||
|
||||
size_t getParent(size_t index);
|
||||
|
||||
size_t getChild(size_t index);
|
||||
|
||||
physaddr_t nodeToAddress(size_t height, size_t index) const;
|
||||
|
||||
size_t addressToNode(size_t height, physaddr_t location) const;
|
||||
|
||||
void reserveNode(size_t height, size_t index);
|
||||
|
||||
void freeNode(size_t height, size_t index);
|
||||
|
||||
bool isFree(size_t height, size_t index) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
55
src/mmgr/memoryallocator.hpp
Executable file
55
src/mmgr/memoryallocator.hpp
Executable file
@@ -0,0 +1,55 @@
|
||||
#ifndef __MEMORYALLOCATOR_H_
|
||||
#define __MEMORYALLOCATOR_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include "types.hpp"
|
||||
|
||||
namespace kernel
|
||||
{
|
||||
|
||||
/**
|
||||
* Interface for a dymanic memory allocator.
|
||||
*/
|
||||
class MemoryAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Allocate a block of memory containing 'size' bytes. May round up
|
||||
* depending on the implementation.
|
||||
*/
|
||||
virtual physaddr_t allocate(size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Free the region of memory starting at 'location' and containing
|
||||
* 'size' bytes.
|
||||
*/
|
||||
virtual void free(physaddr_t location, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* @returns the total number of free blocks of memory.
|
||||
*/
|
||||
virtual size_t freeBlocks() const = 0;
|
||||
|
||||
/**
|
||||
* @returns the size in blocks of the largest possible allocation that
|
||||
* will not fail due to lack of memory.
|
||||
*/
|
||||
virtual size_t maxAllocationSize() const = 0;
|
||||
|
||||
/**
|
||||
* @returns the size in bytes of a single block.
|
||||
*/
|
||||
virtual size_t getBlockSize() const = 0;
|
||||
|
||||
/**
|
||||
* @returns the total number of blocks managed by this memory
|
||||
* allocator.
|
||||
*/
|
||||
virtual size_t getMemorySize() const = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
38
src/mmgr/memorymap.cpp
Normal file
38
src/mmgr/memorymap.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "memorymap.hpp"
|
||||
|
||||
kernel::MemoryMap::MemoryMap(kernel::MemoryMap::Region* map, size_t entries)
|
||||
{
|
||||
this->map = map;
|
||||
this->entries = entries;
|
||||
}
|
||||
|
||||
kernel::MemoryMap::Region& kernel::MemoryMap::operator[](size_t index)
|
||||
{
|
||||
return map[index];
|
||||
}
|
||||
|
||||
size_t kernel::MemoryMap::size()
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
|
||||
physaddr_t kernel::MemoryMap::Region::getLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
size_t kernel::MemoryMap::Region::getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
kernel::MemoryMap::Type kernel::MemoryMap::Region::getType()
|
||||
{
|
||||
return (Type) type;
|
||||
}
|
||||
|
||||
bool kernel::MemoryMap::Region::contains(physaddr_t location, size_t size)
|
||||
{
|
||||
return (location >= this->location) &&
|
||||
(location + size <= this->location + this->size);
|
||||
}
|
||||
61
src/mmgr/memorymap.hpp
Normal file
61
src/mmgr/memorymap.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef MEMORYMAP_H
|
||||
#define MEMORYMAP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace kernel
|
||||
{
|
||||
|
||||
class MemoryMap
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type
|
||||
{
|
||||
AVAILABLE = 1,
|
||||
ACPI = 3,
|
||||
DEFECTIVE = 5
|
||||
};
|
||||
|
||||
class Region
|
||||
{
|
||||
public:
|
||||
|
||||
physaddr_t getLocation();
|
||||
|
||||
size_t getSize();
|
||||
|
||||
Type getType();
|
||||
|
||||
bool contains(physaddr_t location, size_t size);
|
||||
|
||||
private:
|
||||
|
||||
physaddr_t location;
|
||||
|
||||
size_t size;
|
||||
|
||||
uint32_t type;
|
||||
|
||||
};
|
||||
|
||||
MemoryMap(Region* map, size_t entries);
|
||||
|
||||
Region& operator[](size_t index);
|
||||
|
||||
size_t size();
|
||||
|
||||
private:
|
||||
|
||||
Region* map;
|
||||
|
||||
size_t entries;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
15
src/mmgr/types.hpp
Normal file
15
src/mmgr/types.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef MEM_TYPES_H
|
||||
#define MEM_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined __i386__
|
||||
typedef uint32_t physaddr_t;
|
||||
#elif defined __amd64__
|
||||
typedef uint64_t physaddr_t;
|
||||
#else
|
||||
typedef uint64_t physaddr_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
133
src/mmgr/x86/pagetableentry.cpp
Executable file
133
src/mmgr/x86/pagetableentry.cpp
Executable file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* PageTableEntry.cpp
|
||||
*
|
||||
* Created on: May 22, 2019
|
||||
* Author: nathan
|
||||
*/
|
||||
|
||||
#include "pagetableentry.hpp"
|
||||
|
||||
namespace kernel {
|
||||
|
||||
static_assert(sizeof(PageTableEntry) == 4, "PTE structure is the wrong size!");
|
||||
|
||||
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::getUsermode() const
|
||||
{
|
||||
return usermode == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setUsermode(bool usermode)
|
||||
{
|
||||
this->usermode = usermode ? 1 : 0;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getWriteThrough() const {
|
||||
return writeThrough == 1;
|
||||
}
|
||||
|
||||
bool PageTableEntry::getShared() const
|
||||
{
|
||||
return shared == 1;
|
||||
}
|
||||
|
||||
void PageTableEntry::setShared(bool shared)
|
||||
{
|
||||
this->shared = shared ? 1 : 0;
|
||||
}
|
||||
|
||||
void PageTableEntry::setWriteThrough(bool writeThrough)
|
||||
{
|
||||
this->writeThrough = writeThrough ? 1 : 0;
|
||||
}
|
||||
|
||||
physaddr_t PageTableEntry::operator=(physaddr_t rhs)
|
||||
{
|
||||
return setPhysicalAddress(rhs);
|
||||
}
|
||||
|
||||
} /* namespace qkernel */
|
||||
58
src/mmgr/x86/pagetableentry.hpp
Executable file
58
src/mmgr/x86/pagetableentry.hpp
Executable file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* PageTableEntry.h
|
||||
*
|
||||
* Created on: May 22, 2019
|
||||
* Author: nathan
|
||||
*/
|
||||
|
||||
#ifndef SRC_PAGETABLEENTRY_H_
|
||||
#define SRC_PAGETABLEENTRY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../types.hpp"
|
||||
|
||||
namespace kernel {
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} /* namespace qkernel */
|
||||
|
||||
#endif /* SRC_PAGETABLEENTRY_H_ */
|
||||
Reference in New Issue
Block a user