started a bit of paging for x64
This commit is contained in:
parent
3f83577f8f
commit
c061f9e30c
10 changed files with 456 additions and 131 deletions
|
@ -2,6 +2,7 @@
|
|||
#include <base.hpp>
|
||||
extern int kernel_start;
|
||||
extern int kernel_end;
|
||||
pagedir global_kernel[256];
|
||||
paging_context_x86::paging_context_x86(): paging_context() {
|
||||
*pmm >> pagedir_addr;
|
||||
if(context_enabled) {
|
||||
|
@ -175,12 +176,24 @@ paging_context_x86::~paging_context_x86() {
|
|||
}
|
||||
|
||||
void paging_context_x86::switch_context() {
|
||||
pagedir* p = (pagedir*)pagedir_addr;
|
||||
if(context_enabled)
|
||||
p=(pagedir*)0x400000;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
global_kernel[i]=p[i];
|
||||
}
|
||||
asm volatile("mov %0, %%cr3" :: "r"(pagedir_addr) : "memory");
|
||||
if(!context_enabled) {
|
||||
uint32_t cr0;
|
||||
asm volatile("mov %%cr0, %0" : "=r"(cr0));
|
||||
cr0 |= (1<<31);
|
||||
asm volatile("mov %0, %%cr0" :: "r"(cr0) : "memory");
|
||||
} else {
|
||||
for(int i=0;i<256;i++)
|
||||
if((i>=1)&&(i<=3))
|
||||
continue;
|
||||
else
|
||||
p[i]=global_kernel[i];
|
||||
}
|
||||
paging_context::switch_context();
|
||||
}
|
||||
|
|
91
kernel/arch/x86_64/include/paging.h
Normal file
91
kernel/arch/x86_64/include/paging.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <pmm.hpp>
|
||||
#include <regs.h>
|
||||
#include <paging.hpp>
|
||||
typedef phys_t virt_t;
|
||||
struct pagemap_tbl {
|
||||
bool active:1;
|
||||
bool writable:1;
|
||||
bool unprivileged:1;
|
||||
bool no_write_cache:1;
|
||||
bool no_read_cache:1;
|
||||
bool accessed:1;
|
||||
uint8_t sbz:3;
|
||||
uint8_t ignored:3;
|
||||
phys_t pagemap:40;
|
||||
uint16_t ignored2:11;
|
||||
bool executable:1;
|
||||
|
||||
}__attribute__((packed));
|
||||
static_assert(sizeof(pagemap_tbl)==8);
|
||||
|
||||
struct pagemap {
|
||||
bool active:1;
|
||||
bool writable:1;
|
||||
bool unprivileged:1;
|
||||
bool no_write_cache:1;
|
||||
bool no_read_cache:1;
|
||||
bool accessed:1;
|
||||
bool sbz:1;
|
||||
bool _1G_page:1;
|
||||
bool global:1;
|
||||
uint8_t ignored:3;
|
||||
phys_t pagedir:40;
|
||||
uint16_t ignored2:11;
|
||||
bool executable:1;
|
||||
}__attribute__((packed));
|
||||
static_assert(sizeof(pagemap)==8);
|
||||
|
||||
struct pagedir {
|
||||
bool active:1;
|
||||
bool writeable:1;
|
||||
bool privileged:1;
|
||||
bool no_write_cache:1;
|
||||
bool no_read_cache:1;
|
||||
bool accessed:1;
|
||||
bool sbz:1;
|
||||
bool _2M_page:1;
|
||||
bool global:1;
|
||||
uint8_t ignored:3;
|
||||
phys_t pagetbl:40;
|
||||
uint16_t ignored2:11;
|
||||
bool executable:1;
|
||||
}__attribute__((packed));
|
||||
static_assert(sizeof(pagedir)==8);
|
||||
|
||||
struct pagetbl {
|
||||
bool active:1;
|
||||
bool writeable:1;
|
||||
bool privileged:1;
|
||||
bool no_write_cache:1;
|
||||
bool no_read_cache:1;
|
||||
bool accessed:1;
|
||||
bool sbz:1;
|
||||
bool pat:1;
|
||||
bool global:1;
|
||||
uint8_t ignored:2;
|
||||
bool lazy:1;
|
||||
phys_t page:40;
|
||||
uint16_t ignored2:11;
|
||||
bool executable:1;
|
||||
}
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
struct paging_context_x86: public paging_context {
|
||||
phys_t pagemaptbl_addr;
|
||||
paging_context_x86();
|
||||
virtual ~paging_context_x86();
|
||||
virtual void switch_context();
|
||||
virtual void map_pagetable(struct paging_context *);
|
||||
virtual void *mmap(phys_t addr, void *dest, protection prot=protection::RW, bool lazy=true);
|
||||
virtual void munmap(void *addr);
|
||||
virtual bool is_mapped(void *addr);
|
||||
virtual void mprotect(void *addr, protection prot);
|
||||
virtual bool has_no_exec();
|
||||
virtual void *get_exception_address(cpu_state *cpu);
|
||||
virtual bool lazymap(void *addr, cpu_state *cpu);
|
||||
pagedir * operator*();
|
||||
pagetbl * operator[](phys_t);
|
||||
};
|
30
kernel/arch/x86_64/paging.cpp
Normal file
30
kernel/arch/x86_64/paging.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <paging.h>
|
||||
#include <base.hpp>
|
||||
extern int kernel_start;
|
||||
extern int kernel_end;
|
||||
|
||||
|
||||
|
||||
paging_context_x86::paging_context_x86(): paging_context() {
|
||||
*pmm >> pagedir_addr;
|
||||
if(context_enabled) {
|
||||
current_context->mmap(pagedir_addr, (void*)0x800000, protection::RW, false);
|
||||
pagemap *src=(pagemap *)0x400000;
|
||||
pagemap *dest=(pagedir*)0x600000;
|
||||
for(int i=0;i<256;i++)
|
||||
dest[i]=src[i];
|
||||
for(int i=256;i<512;i++)
|
||||
dest[i].active=false;
|
||||
dest[0].active=false;
|
||||
phys_t first_pagedir;
|
||||
*pmm >> first_pagedir;
|
||||
dest[0].pagetable = first_pagedir >> 12;
|
||||
dest[0].writeable=true;
|
||||
dest[0].unprivileged=false;
|
||||
dest[0].no_write_cache=true;
|
||||
dest[0].no_read_cache=false;
|
||||
dest[0].sbz=0;
|
||||
dest[0].active=true;
|
||||
|
||||
}
|
||||
}
|
|
@ -17,9 +17,12 @@ CGATerm term;
|
|||
VESAfb term(mb_info);
|
||||
#endif
|
||||
PMM_MB lpmm(mb_info);
|
||||
|
||||
#include<paging.hpp>
|
||||
void main();
|
||||
extern "C" void start(int eax, multiboot_info_t *ebx) {
|
||||
mb_info = ebx;
|
||||
context_enabled=false;
|
||||
main();
|
||||
}
|
||||
void drivers_init() {
|
||||
|
|
|
@ -58,7 +58,7 @@ union MMAPTag {
|
|||
uint8_t id;
|
||||
uint8_t size;
|
||||
uint8_t value;
|
||||
}__attribute__((packed)) BITS;
|
||||
}__attribute__((packed)) BITSi;
|
||||
struct {
|
||||
uint8_t id;
|
||||
uint8_t size;
|
||||
|
@ -108,7 +108,7 @@ PMM_MMAP::PMM_MMAP(): PMM(0x1000) {
|
|||
;
|
||||
break;
|
||||
case 4:
|
||||
bits = tag.BITS.value;
|
||||
bits = tag.BITSi.value;
|
||||
break;
|
||||
case 5:
|
||||
if(tag.REGION.permission != PERM::RWX)
|
||||
|
|
|
@ -21,3 +21,9 @@ extern "C" void panic(const char* s);
|
|||
#define __BIG_ENDIAN__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define BITS 64
|
||||
#else
|
||||
#define BITS 32
|
||||
#endif
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
class PMM;
|
||||
#include <base.hpp>
|
||||
typedef uintptr_t phys_t; ///< Type used for physical addresses
|
||||
/**
|
||||
* A single entry in the PMM list
|
||||
*/
|
||||
|
||||
#if BITS == 32
|
||||
/**
|
||||
* Physical memory manager. It stores the free memory in a linked list
|
||||
*/
|
||||
|
@ -26,6 +30,34 @@ class PMM {
|
|||
virtual auto operator&&(phys_t page) -> bool; //Returns true if this page is free. O(1).
|
||||
virtual auto setUsed(phys_t page) -> void; //Marks a page as used. O(1).
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct pmm_entry {
|
||||
phys_t next;
|
||||
phys_t last;
|
||||
};
|
||||
|
||||
class PMM {
|
||||
protected:
|
||||
phys_t head;
|
||||
virtual auto isFree(phys_t address) -> bool;
|
||||
auto fill() -> void;
|
||||
phys_t page_size, lowest_page, highest_page;
|
||||
void push(phys_t);
|
||||
phys_t pop();
|
||||
public:
|
||||
PMM(phys_t page_size);
|
||||
virtual ~PMM();
|
||||
virtual auto operator<<(phys_t page) -> PMM &;
|
||||
virtual auto operator>>(phys_t &page) -> PMM &;
|
||||
virtual auto operator,(size_t no_pages) -> phys_t;
|
||||
virtual auto operator()(phys_t pages, size_t no_pages) -> void;
|
||||
virtual auto operator&&(phys_t page) -> bool;
|
||||
virtual auto setUsed(phys_t page) -> void;
|
||||
};
|
||||
|
||||
#endif
|
||||
/**
|
||||
* This definition is for having a python-like syntax - like `page in pmm`
|
||||
*/
|
||||
|
|
|
@ -1,131 +1,7 @@
|
|||
#include <base.hpp>
|
||||
#include <pmm.hpp>
|
||||
extern "C" int kernel_start;
|
||||
extern "C" int kernel_end;
|
||||
|
||||
|
||||
uint32_t pmm_bitmap[32768];
|
||||
|
||||
|
||||
auto PMM::isFree(phys_t addr) -> bool {
|
||||
if(addr == 0)
|
||||
return false;
|
||||
phys_t start = (phys_t)(&kernel_start);
|
||||
phys_t end = (phys_t)(&kernel_end);
|
||||
if((addr >= start) && (addr < end))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
PMM::PMM(phys_t page_size): page_size(page_size), first_free(0), lowest_page(~0), highest_page(0) {
|
||||
for(int i=0;i<32768;i++) {
|
||||
pmm_bitmap[i]=0;
|
||||
}
|
||||
pmm = this;
|
||||
}
|
||||
void PMM::fill() {
|
||||
for(phys_t i=highest_page; i>=lowest_page && i; i-=page_size) {
|
||||
if(isFree(i))
|
||||
*this << i;
|
||||
}
|
||||
}
|
||||
PMM::~PMM() {}
|
||||
|
||||
auto PMM::operator<<(phys_t page) -> PMM & {
|
||||
(*this)(page,1);
|
||||
return *this;
|
||||
}
|
||||
auto PMM::operator>>(phys_t &page) -> PMM & {
|
||||
page = (*this, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto PMM::operator,(size_t no_pages) -> phys_t {
|
||||
if(first_free > highest_page)
|
||||
panic("No free physical memory is available.");
|
||||
if(no_pages == 1) {
|
||||
while(!(first_free in *this)) {
|
||||
first_free += page_size;
|
||||
if(first_free > highest_page)
|
||||
panic("No free physical memory is available.");
|
||||
}
|
||||
phys_t pageno = first_free / page_size;
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] &= ~(1<<bit);
|
||||
auto x = first_free;
|
||||
first_free += page_size;
|
||||
return x;
|
||||
}
|
||||
//Now we need to find a free page with n-1 free pages after it
|
||||
phys_t linear_start = first_free;
|
||||
phys_t length = (no_pages-1) * page_size;
|
||||
while(true) {
|
||||
bool found=true;
|
||||
while(!(linear_start in *this)) {
|
||||
linear_start += page_size;
|
||||
if((linear_start > highest_page)||(linear_start+length > highest_page))
|
||||
panic("No free physical memory is available.");
|
||||
}
|
||||
if(!((linear_start + length) in *this)) {
|
||||
linear_start += no_pages * page_size;
|
||||
}
|
||||
//We're on to something
|
||||
phys_t i;
|
||||
for(i=linear_start; i < linear_start + length; i+=page_size) {
|
||||
if(!(i in *this)) {
|
||||
found=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
linear_start=i+page_size;
|
||||
continue;
|
||||
}
|
||||
//Set the first_free variable correctly when the first page was a hit
|
||||
if(linear_start == first_free)
|
||||
first_free += length + page_size;
|
||||
|
||||
phys_t pageno = linear_start / page_size;
|
||||
|
||||
for(i=linear_start; i <= linear_start + length; i+= page_size) {
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] &= ~(1<<bit);
|
||||
pageno++;
|
||||
}
|
||||
return linear_start;
|
||||
}
|
||||
|
||||
}
|
||||
auto PMM::operator()(phys_t pages, size_t no_pages) -> void {
|
||||
phys_t pageno = pages / page_size;
|
||||
if(pages < first_free)
|
||||
first_free = pages;
|
||||
for(size_t i=0; i<no_pages; i++, pages+=page_size) {
|
||||
if(!isFree(pages))
|
||||
continue;
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] |= 1<<bit;
|
||||
pageno++;
|
||||
}
|
||||
}
|
||||
auto PMM::operator&&(phys_t page) -> bool {
|
||||
phys_t pageno = page / page_size;
|
||||
phys_t index = pageno >> 5;
|
||||
if(!pmm_bitmap[index])
|
||||
return false;
|
||||
phys_t bit = pageno & 31;
|
||||
if(!(pmm_bitmap[index] & (1<<bit)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
auto PMM::setUsed(phys_t page) -> void {
|
||||
phys_t pageno = page / page_size;
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] &= ~(1<<bit);
|
||||
}
|
||||
auto operator&&(phys_t a, PMM mm) -> bool {
|
||||
return mm && a;
|
||||
}
|
||||
#ifdef BITS == 64
|
||||
#include "pmm64.hpp"
|
||||
#else
|
||||
#include "pmm32.hpp"
|
||||
#endif
|
||||
|
|
131
kernel/src/pmm32.hpp
Normal file
131
kernel/src/pmm32.hpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include <base.hpp>
|
||||
#include <pmm.hpp>
|
||||
extern "C" int kernel_start;
|
||||
extern "C" int kernel_end;
|
||||
|
||||
|
||||
uint32_t pmm_bitmap[32768];
|
||||
|
||||
|
||||
auto PMM::isFree(phys_t addr) -> bool {
|
||||
if(addr == 0)
|
||||
return false;
|
||||
phys_t start = (phys_t)(&kernel_start);
|
||||
phys_t end = (phys_t)(&kernel_end);
|
||||
if((addr >= start) && (addr < end))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
PMM::PMM(phys_t page_size): page_size(page_size), first_free(0), lowest_page(~0), highest_page(0) {
|
||||
for(int i=0;i<32768;i++) {
|
||||
pmm_bitmap[i]=0;
|
||||
}
|
||||
pmm = this;
|
||||
}
|
||||
void PMM::fill() {
|
||||
for(phys_t i=highest_page; i>=lowest_page && i; i-=page_size) {
|
||||
if(isFree(i))
|
||||
*this << i;
|
||||
}
|
||||
}
|
||||
PMM::~PMM() {}
|
||||
|
||||
auto PMM::operator<<(phys_t page) -> PMM & {
|
||||
(*this)(page,1);
|
||||
return *this;
|
||||
}
|
||||
auto PMM::operator>>(phys_t &page) -> PMM & {
|
||||
page = (*this, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto PMM::operator,(size_t no_pages) -> phys_t {
|
||||
if(first_free > highest_page)
|
||||
panic("No free physical memory is available.");
|
||||
if(no_pages == 1) {
|
||||
while(!(first_free in *this)) {
|
||||
first_free += page_size;
|
||||
if(first_free > highest_page)
|
||||
panic("No free physical memory is available.");
|
||||
}
|
||||
phys_t pageno = first_free / page_size;
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] &= ~(1<<bit);
|
||||
auto x = first_free;
|
||||
first_free += page_size;
|
||||
return x;
|
||||
}
|
||||
//Now we need to find a free page with n-1 free pages after it
|
||||
phys_t linear_start = first_free;
|
||||
phys_t length = (no_pages-1) * page_size;
|
||||
while(true) {
|
||||
bool found=true;
|
||||
while(!(linear_start in *this)) {
|
||||
linear_start += page_size;
|
||||
if((linear_start > highest_page)||(linear_start+length > highest_page))
|
||||
panic("No free physical memory is available.");
|
||||
}
|
||||
if(!((linear_start + length) in *this)) {
|
||||
linear_start += no_pages * page_size;
|
||||
}
|
||||
//We're on to something
|
||||
phys_t i;
|
||||
for(i=linear_start; i < linear_start + length; i+=page_size) {
|
||||
if(!(i in *this)) {
|
||||
found=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
linear_start=i+page_size;
|
||||
continue;
|
||||
}
|
||||
//Set the first_free variable correctly when the first page was a hit
|
||||
if(linear_start == first_free)
|
||||
first_free += length + page_size;
|
||||
|
||||
phys_t pageno = linear_start / page_size;
|
||||
|
||||
for(i=linear_start; i <= linear_start + length; i+= page_size) {
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] &= ~(1<<bit);
|
||||
pageno++;
|
||||
}
|
||||
return linear_start;
|
||||
}
|
||||
|
||||
}
|
||||
auto PMM::operator()(phys_t pages, size_t no_pages) -> void {
|
||||
phys_t pageno = pages / page_size;
|
||||
if(pages < first_free)
|
||||
first_free = pages;
|
||||
for(size_t i=0; i<no_pages; i++, pages+=page_size) {
|
||||
if(!isFree(pages))
|
||||
continue;
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] |= 1<<bit;
|
||||
pageno++;
|
||||
}
|
||||
}
|
||||
auto PMM::operator&&(phys_t page) -> bool {
|
||||
phys_t pageno = page / page_size;
|
||||
phys_t index = pageno >> 5;
|
||||
if(!pmm_bitmap[index])
|
||||
return false;
|
||||
phys_t bit = pageno & 31;
|
||||
if(!(pmm_bitmap[index] & (1<<bit)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
auto PMM::setUsed(phys_t page) -> void {
|
||||
phys_t pageno = page / page_size;
|
||||
phys_t index = pageno >> 5;
|
||||
phys_t bit = pageno & 31;
|
||||
pmm_bitmap[index] &= ~(1<<bit);
|
||||
}
|
||||
auto operator&&(phys_t a, PMM mm) -> bool {
|
||||
return mm && a;
|
||||
}
|
143
kernel/src/pmm64.hpp
Normal file
143
kernel/src/pmm64.hpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
#include <pmm.hpp>
|
||||
#include <paging.hpp>
|
||||
extern "C" int kernel_start;
|
||||
extern "C" int kernel_end;
|
||||
|
||||
static inline void * map(phys_t addr) {
|
||||
if(__builtin_expect(context_enabled, true))
|
||||
return current_context->mmap(addr, (void*)1, protection::RW, false);
|
||||
return (void*)addr;
|
||||
}
|
||||
static inline void unmap(void* addr) {
|
||||
/* if(__builtin_expect(context_enabled, true))
|
||||
current_context->munmap(addr);*/
|
||||
}
|
||||
|
||||
auto PMM::isFree(phys_t addr) -> bool {
|
||||
if(!addr)
|
||||
return false;
|
||||
auto start = (phys_t)(&kernel_start);
|
||||
auto end = (phys_t)(&kernel_end);
|
||||
if((addr >= start) && (addr < end))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PMM::push(phys_t p) {
|
||||
phys_t h=head;
|
||||
auto ent=(pmm_entry*)map(p);
|
||||
ent->next=head;
|
||||
ent->last=0;
|
||||
head=p;
|
||||
unmap(ent);
|
||||
ent=(pmm_entry*)map(h);
|
||||
ent->last=p;
|
||||
unmap(ent);
|
||||
}
|
||||
phys_t PMM::pop() {
|
||||
phys_t p = head;
|
||||
if(!p)
|
||||
panic("oom");
|
||||
auto ent=(pmm_entry*)map(p);
|
||||
head=ent->next;
|
||||
unmap(ent);
|
||||
ent=(pmm_entry*)map(head);
|
||||
ent->last=0;
|
||||
unmap(ent);
|
||||
return p;
|
||||
}
|
||||
|
||||
PMM::PMM(phys_t page_size): page_size(page_size), head(0), lowest_page(~0), highest_page(0) {
|
||||
pmm=this;
|
||||
}
|
||||
void PMM::fill() {
|
||||
for(phys_t i=highest_page; i>=lowest_page && i; i-=page_size) {
|
||||
if(isFree(i))
|
||||
*this << i;
|
||||
}
|
||||
}
|
||||
|
||||
PMM::~PMM() {}
|
||||
|
||||
auto PMM::operator<<(phys_t page) -> PMM & {
|
||||
push(page);
|
||||
return *this;
|
||||
}
|
||||
auto PMM::operator>>(phys_t &page) -> PMM& {
|
||||
page=pop();
|
||||
return *this;
|
||||
}
|
||||
#define self (*this)
|
||||
auto PMM::operator,(size_t no_pages) -> phys_t {
|
||||
if(no_pages == 1)
|
||||
return pop();
|
||||
for(phys_t i = lowest_page; i < highest_page; i+=page_size) {
|
||||
if(not (i in self))
|
||||
continue;
|
||||
if(not ((i+no_pages*page_size) in self)) {
|
||||
i+=(no_pages-1)*page_size;
|
||||
continue;
|
||||
}
|
||||
//we found something
|
||||
for(phys_t j = i+page_size; j<i+no_pages*page_size; j+=page_size) {
|
||||
if(not (j in self)) {
|
||||
i+=(no_pages-1)*page_size;
|
||||
goto outlbl;
|
||||
}
|
||||
}
|
||||
//if we are here, we found it
|
||||
for(phys_t j = i; j<=i+no_pages*page_size; j+=page_size) {
|
||||
setUsed(j);
|
||||
}
|
||||
return i;
|
||||
outlbl:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto PMM::operator()(phys_t pages, size_t no_pages) -> void {
|
||||
for(phys_t i=pages; i<=pages+no_pages*page_size; i+=page_size) {
|
||||
if(!isFree(i))
|
||||
continue;
|
||||
push(i);
|
||||
}
|
||||
}
|
||||
|
||||
auto PMM::operator&&(phys_t page) -> bool {
|
||||
phys_t curr = head;
|
||||
while(curr) {
|
||||
if(curr == page)
|
||||
return true;
|
||||
auto ent = (pmm_entry *)map(curr);
|
||||
curr = ent->next;
|
||||
unmap(ent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto PMM::setUsed(phys_t page) -> void {
|
||||
if(head == page) {
|
||||
pop();
|
||||
return;
|
||||
}
|
||||
if(not (page in self))
|
||||
return;
|
||||
phys_t next, last;
|
||||
auto ent = (pmm_entry*)map(page);
|
||||
next=ent->next;
|
||||
last=ent->last;
|
||||
unmap(ent);
|
||||
if(next) {
|
||||
ent=(pmm_entry*)map(next);
|
||||
ent->last=last;
|
||||
unmap(ent);
|
||||
}
|
||||
if(last) {
|
||||
ent=(pmm_entry*)map(last);
|
||||
ent->next=next;
|
||||
}
|
||||
}
|
||||
|
||||
auto operator&&(phys_t a, PMM mm) -> bool{
|
||||
return mm in a;
|
||||
}
|
Loading…
Reference in a new issue