fix: made paging finally work on x86_64
This commit is contained in:
parent
e9c35831c0
commit
9299f08981
6 changed files with 691 additions and 25 deletions
|
@ -73,6 +73,7 @@ struct pagetbl {
|
||||||
|
|
||||||
struct paging_context_x86: public paging_context {
|
struct paging_context_x86: public paging_context {
|
||||||
phys_t pagemaptbl_addr;
|
phys_t pagemaptbl_addr;
|
||||||
|
bool _512G_full, _1G_full, _2M_full;
|
||||||
paging_context_x86();
|
paging_context_x86();
|
||||||
virtual ~paging_context_x86();
|
virtual ~paging_context_x86();
|
||||||
virtual void switch_context();
|
virtual void switch_context();
|
||||||
|
|
|
@ -3,26 +3,28 @@
|
||||||
extern int kernel_start;
|
extern int kernel_start;
|
||||||
extern int kernel_end;
|
extern int kernel_end;
|
||||||
|
|
||||||
const pagemap_tbl *curr_pagemaptbl = pagemap_tbl *(0x8000000000);
|
pagemap_tbl *curr_pagemaptbl = (pagemap_tbl *)(0x8000000000);
|
||||||
const pagemap_tbl *ref_pagemaptbl = pagemap_tbl *(0x8000001000);
|
pagemap_tbl *ref_pagemaptbl = (pagemap_tbl *)(0x8000001000);
|
||||||
const pagemap *curr_pagemap = pagemap *(0x8000200000);
|
pagemap *curr_pagemap = (pagemap *)(0x8000200000);
|
||||||
const pagemap *ref_pagemap = pagemap *(0x8000400000);
|
pagemap *ref_pagemap = (pagemap *)(0x8000400000);
|
||||||
const pagedir *curr_pagedir = pagedir *(0x8040000000);
|
pagedir *curr_pagedir = (pagedir *)(0x8040000000);
|
||||||
const pagedir *ref_pagedir = pagedir *(0x8080000000);
|
pagedir *ref_pagedir = (pagedir *)(0x8080000000);
|
||||||
const pagetbl *curr_pagetbl = pagetbl *(0xC000000000);
|
pagetbl *curr_pagetbl = (pagetbl *)(0x10000000000);
|
||||||
const pagetbl *ref_pagetbl = pagetbl *(0x10000000000);
|
pagetbl *ref_pagetbl = (pagetbl *)(0x18000000000);
|
||||||
|
inline uint64_t unwrap(phys_t addr) {
|
||||||
|
return addr & 0xFFFFFFFFFFFF;
|
||||||
|
}
|
||||||
inline uint64_t pagemaptbl_index(phys_t addr) {
|
inline uint64_t pagemaptbl_index(phys_t addr) {
|
||||||
return addr >> 39;
|
return unwrap(addr) >> 39;
|
||||||
}
|
}
|
||||||
inline uint64_t pagemap_index(phys_t addr) {
|
inline uint64_t pagemap_index(phys_t addr) {
|
||||||
return addr >> 30;
|
return unwrap(addr) >> 30;
|
||||||
}
|
}
|
||||||
inline uint64_t pagedir_index(phys_t addr) {
|
inline uint64_t pagedir_index(phys_t addr) {
|
||||||
return addr >> 21;
|
return unwrap(addr) >> 21;
|
||||||
}
|
}
|
||||||
inline uint64_t pagetbl_index(phys_t addr) {
|
inline uint64_t pagetbl_index(phys_t addr) {
|
||||||
return addr >> 12;
|
return unwrap(addr) >> 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline phys_t wrap(uint64_t x) {
|
inline phys_t wrap(uint64_t x) {
|
||||||
|
@ -39,12 +41,16 @@ inline phys_t make_phys(uint64_t i, uint64_t j, uint64_t k, uint64_t l) {
|
||||||
inline void* make_virt(uint64_t i, uint64_t j, uint64_t k, uint64_t l) {
|
inline void* make_virt(uint64_t i, uint64_t j, uint64_t k, uint64_t l) {
|
||||||
return (void*)wrap(make_phys(i,j,k,l));
|
return (void*)wrap(make_phys(i,j,k,l));
|
||||||
}
|
}
|
||||||
|
inline void* make_virt(phys_t addr) {
|
||||||
|
return (void*)wrap(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pagemap_tbl kernel[256];
|
pagemap_tbl kernel[256];
|
||||||
|
|
||||||
paging_context_x86::paging_context_x86(): paging_context() {
|
paging_context_x86::paging_context_x86(): paging_context(), _512G_full(false), _1G_full(false), _2M_full(false) {
|
||||||
phys_t pagedir_addr;
|
*pmm >> pagemaptbl_addr;
|
||||||
*pmm >> pagedir_addr;
|
phys_t pagedir_addr = pagemaptbl_addr;
|
||||||
if(context_enabled) {
|
if(context_enabled) {
|
||||||
current_context->mmap(pagedir_addr, ref_pagemaptbl, protection::RW, false);
|
current_context->mmap(pagedir_addr, ref_pagemaptbl, protection::RW, false);
|
||||||
for(int i = 0;i < 256; i++)
|
for(int i = 0;i < 256; i++)
|
||||||
|
@ -97,7 +103,7 @@ paging_context_x86::paging_context_x86(): paging_context() {
|
||||||
for(uint64_t l = pagetbl_start; l < pagetbl_start+512; l++) {
|
for(uint64_t l = pagetbl_start; l < pagetbl_start+512; l++) {
|
||||||
if(!ref_pagetbl[l].active)
|
if(!ref_pagetbl[l].active)
|
||||||
continue;
|
continue;
|
||||||
mmap(make_phys(ref_pagetbl[l].page<<12, curr_pagetbl+l, protection::RW, false);
|
mmap(ref_pagetbl[l].page<<12, curr_pagetbl+l, protection::RW, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +112,7 @@ paging_context_x86::paging_context_x86(): paging_context() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Map the entire kernel
|
//Map the entire kernel
|
||||||
pagemap_tbl *pagemaptbl = (pagedir *)pagedir_addr;
|
pagemap_tbl *pagemaptbl = (pagemap_tbl *)pagemaptbl_addr;
|
||||||
for(int i=0;i<512;i++)
|
for(int i=0;i<512;i++)
|
||||||
pagemaptbl[i].active=false;
|
pagemaptbl[i].active=false;
|
||||||
phys_t kernelpagemap;
|
phys_t kernelpagemap;
|
||||||
|
@ -139,6 +145,19 @@ paging_context_x86::paging_context_x86(): paging_context() {
|
||||||
pagedir *kpagedir = (pagedir*)kernelpagedir;
|
pagedir *kpagedir = (pagedir*)kernelpagedir;
|
||||||
for(int i=0;i<512;i++)
|
for(int i=0;i<512;i++)
|
||||||
kpagedir[i].active=false;
|
kpagedir[i].active=false;
|
||||||
|
phys_t nullpagetbl;
|
||||||
|
*pmm >> nullpagetbl;
|
||||||
|
kpagedir[0].pagetbl = nullpagetbl >> 12;
|
||||||
|
kpagedir[0].writeable=true;
|
||||||
|
kpagedir[0].unprivileged=false;
|
||||||
|
kpagedir[0].no_write_cache=false;
|
||||||
|
kpagedir[0].no_read_cache=false;
|
||||||
|
kpagedir[0].sbz=0;
|
||||||
|
kpagedir[0]._2M_page=false;
|
||||||
|
kpagedir[0].global=true;
|
||||||
|
kpagedir[0].executable=false;
|
||||||
|
kpagedir[0].active=true;
|
||||||
|
|
||||||
phys_t kernelpagetbl;
|
phys_t kernelpagetbl;
|
||||||
*pmm >> kernelpagetbl;
|
*pmm >> kernelpagetbl;
|
||||||
kpagedir[1].pagetbl = kernelpagetbl >> 12;
|
kpagedir[1].pagetbl = kernelpagetbl >> 12;
|
||||||
|
@ -153,10 +172,12 @@ paging_context_x86::paging_context_x86(): paging_context() {
|
||||||
kpagedir[1].active=true;
|
kpagedir[1].active=true;
|
||||||
|
|
||||||
pagetbl *kpagetbl = (pagetbl*)kernelpagetbl;
|
pagetbl *kpagetbl = (pagetbl*)kernelpagetbl;
|
||||||
for(int i=0;i<512;i++)
|
for(int i=0;i<512;i++) {
|
||||||
kpagetbl[i].active=false;
|
kpagetbl[i].active=false;
|
||||||
for(phys_t i=(((phys_t)&kernel_start)>>12)-512,p=(phys_t)&kernel_start;p<(phys_t)&kernel_end;p+=0x1000;i++) {
|
kpagetbl[i].lazy=false;
|
||||||
kpagetbl[i].page=i;
|
}
|
||||||
|
for(phys_t i=(((phys_t)&kernel_start)>>12)-512,p=(phys_t)&kernel_start;p<(phys_t)&kernel_end;p+=0x1000) {
|
||||||
|
kpagetbl[i].page=i+512;
|
||||||
kpagetbl[i].writeable=true;
|
kpagetbl[i].writeable=true;
|
||||||
kpagetbl[i].unprivileged=false;
|
kpagetbl[i].unprivileged=false;
|
||||||
kpagetbl[i].no_write_cache=false;
|
kpagetbl[i].no_write_cache=false;
|
||||||
|
@ -164,8 +185,637 @@ paging_context_x86::paging_context_x86(): paging_context() {
|
||||||
kpagetbl[i].sbz=false;
|
kpagetbl[i].sbz=false;
|
||||||
kpagetbl[i].pat=false;
|
kpagetbl[i].pat=false;
|
||||||
kpagetbl[i].global=true;
|
kpagetbl[i].global=true;
|
||||||
kpagetbl[i].executable=true;
|
kpagetbl[i].executable=false;
|
||||||
kpagetbl[i].active=true;
|
kpagetbl[i].active=true;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//build the selfmap
|
||||||
|
phys_t pagemap_self_1;
|
||||||
|
*pmm >> pagemap_self_1;
|
||||||
|
pagemaptbl[1].pagemap=pagemap_self_1 >> 12;
|
||||||
|
pagemaptbl[1].writeable=true;
|
||||||
|
pagemaptbl[1].unprivileged=false;
|
||||||
|
pagemaptbl[1].no_write_cache=true;
|
||||||
|
pagemaptbl[1].no_read_cache=true;
|
||||||
|
pagemaptbl[1].sbz=0;
|
||||||
|
pagemaptbl[1].executable=false;
|
||||||
|
pagemaptbl[1].active=true;
|
||||||
|
|
||||||
|
pagemap *selfmap_1 = (pagemap*)pagemap_self_1;
|
||||||
|
for(int i=0;i<512;i++)
|
||||||
|
selfmap_1[i].active=false;
|
||||||
|
|
||||||
|
phys_t pagedir_self_1;
|
||||||
|
*pmm >> pagedir_self_1;
|
||||||
|
|
||||||
|
selfmap_1[0].pagedir=pagedir_self_1 >> 12;
|
||||||
|
selfmap_1[0].writeable=true;
|
||||||
|
selfmap_1[0].unprivileged=false;
|
||||||
|
selfmap_1[0].no_write_cache=true;
|
||||||
|
selfmap_1[0].no_read_cache=true;
|
||||||
|
selfmap_1[0]._1G_page=false;
|
||||||
|
selfmap_1[0].sbz=0;
|
||||||
|
selfmap_1[0].executable=false;
|
||||||
|
selfmap_1[0].active=true;
|
||||||
|
|
||||||
|
pagedir *selfdir_1 = (pagedir*)pagedir_self_1;
|
||||||
|
for(int i=0;i<512;i++)
|
||||||
|
selfdir_1[i].active=false;
|
||||||
|
|
||||||
|
//init l2 selftbl
|
||||||
|
|
||||||
|
phys_t pagetbl_self_1;
|
||||||
|
*pmm >> pagetbl_self_1;
|
||||||
|
selfdir_1[0].pagetbl=pagetbl_self_1 >> 12;
|
||||||
|
selfdir_1[0].writeable=true;
|
||||||
|
selfdir_1[0].unprivileged=false;
|
||||||
|
selfdir_1[0].no_write_cache=true;
|
||||||
|
selfdir_1[0].no_read_cache=true;
|
||||||
|
selfdir_1[0]._2M_page=false;
|
||||||
|
selfdir_1[0].sbz=0;
|
||||||
|
selfdir_1[0].executable=false;
|
||||||
|
selfdir_1[0].active=true;
|
||||||
|
|
||||||
|
//map selfmap of pagemaptbl
|
||||||
|
|
||||||
|
pagetbl *selftbl_1 = (pagetbl*)pagetbl_self_1;
|
||||||
|
for(int i=0;i<512;i++) {
|
||||||
|
selftbl_1[i].active=false;
|
||||||
|
selftbl_1[i].lazy=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
selftbl_1[0].page=pagedir_addr >> 12;
|
||||||
|
selftbl_1[0].writeable=true;
|
||||||
|
selftbl_1[0].unprivileged=false;
|
||||||
|
selftbl_1[0].no_write_cache=true;
|
||||||
|
selftbl_1[0].no_read_cache=true;
|
||||||
|
selftbl_1[0].pat=false;
|
||||||
|
selftbl_1[0].global=false;
|
||||||
|
selftbl_1[0].sbz=0;
|
||||||
|
selftbl_1[0].executable=false;
|
||||||
|
selftbl_1[0].active=true;
|
||||||
|
|
||||||
|
phys_t pagetbl_self_2;
|
||||||
|
*pmm >> pagetbl_self_2;
|
||||||
|
selfdir_1[1].pagetbl=pagetbl_self_2 >> 12;
|
||||||
|
selfdir_1[1].writeable=true;
|
||||||
|
selfdir_1[1].unprivileged=false;
|
||||||
|
selfdir_1[1].no_write_cache=true;
|
||||||
|
selfdir_1[1].no_read_cache=true;
|
||||||
|
selfdir_1[1]._2M_page=false;
|
||||||
|
selfdir_1[1].global=false;
|
||||||
|
selfdir_1[1].sbz=0;
|
||||||
|
selfdir_1[1].executable=false;
|
||||||
|
selfdir_1[1].active=true;
|
||||||
|
|
||||||
|
//map selfmap of pagemap
|
||||||
|
|
||||||
|
pagetbl * selftbl_2 = (pagetbl*)pagetbl_self_2;
|
||||||
|
for(int i=0;i<512;i++) {
|
||||||
|
if(!pagemaptbl[i].active) {
|
||||||
|
selftbl_2[i].active=false;
|
||||||
|
selftbl_2[i].lazy=false;
|
||||||
|
} else {
|
||||||
|
selftbl_2[i].page=pagemaptbl[i].pagemap;
|
||||||
|
selftbl_2[i].writeable=true;
|
||||||
|
selftbl_2[i].unprivileged=false;
|
||||||
|
selftbl_2[i].no_write_cache=true;
|
||||||
|
selftbl_2[i].no_read_cache=true;
|
||||||
|
selftbl_2[i].pat=false;
|
||||||
|
selftbl_2[i].global=false;
|
||||||
|
selftbl_2[i].sbz=0;
|
||||||
|
selftbl_2[i].executable=false;
|
||||||
|
selftbl_2[i].active=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_t pagedir_self_2;
|
||||||
|
*pmm >> pagedir_self_2;
|
||||||
|
selfmap_1[1].pagedir=pagedir_self_2 >> 12;
|
||||||
|
selfmap_1[1].writeable=true;
|
||||||
|
selfmap_1[1].unprivileged=false;
|
||||||
|
selfmap_1[1].no_write_cache=true;
|
||||||
|
selfmap_1[1].no_read_cache=true;
|
||||||
|
selfmap_1[1]._1G_page=false;
|
||||||
|
selfmap_1[1].global=false;
|
||||||
|
selfmap_1[1].sbz=0;
|
||||||
|
selfmap_1[1].executable=false;
|
||||||
|
selfmap_1[1].active=true;
|
||||||
|
|
||||||
|
//map selfmap of pagedir
|
||||||
|
|
||||||
|
pagedir * selfdir_2 = (pagedir*)pagedir_self_2;
|
||||||
|
for(int i=0;i<512;i++) {
|
||||||
|
if(!pagemaptbl[i].active) {
|
||||||
|
selfdir_2[i].active=false;
|
||||||
|
} else {
|
||||||
|
phys_t pagetbl_3;
|
||||||
|
*pmm >> pagetbl_3;
|
||||||
|
selfdir_2[i].pagetbl = pagetbl_3 >> 12;
|
||||||
|
selfdir_2[i].writeable=true;
|
||||||
|
selfdir_2[i].unprivileged=false;
|
||||||
|
selfdir_2[i].no_write_cache=true;
|
||||||
|
selfdir_2[i].no_read_cache=true;
|
||||||
|
selfdir_2[i]._2M_page=false;
|
||||||
|
selfdir_2[i].global=false;
|
||||||
|
selfdir_2[i].sbz=0;
|
||||||
|
selfdir_2[i].executable=false;
|
||||||
|
selfdir_2[i].active=true;
|
||||||
|
|
||||||
|
pagemap * pm = (pagemap*)(pagemaptbl[i].pagemap << 12);
|
||||||
|
pagetbl * pt = (pagetbl*)pagetbl_3;
|
||||||
|
for(int j=0;j<512;j++) {
|
||||||
|
if(!pm[j].active) {
|
||||||
|
pt[j].active=false;
|
||||||
|
pt[j].lazy=false;
|
||||||
|
} else {
|
||||||
|
pt[j].page=pm[j].pagedir;
|
||||||
|
pt[j].writeable=true;
|
||||||
|
pt[j].unprivileged=false;
|
||||||
|
pt[j].no_write_cache=true;
|
||||||
|
pt[j].no_read_cache=true;
|
||||||
|
pt[j].pat=false;
|
||||||
|
pt[j].global=false;
|
||||||
|
pt[j].sbz=0;
|
||||||
|
pt[j].executable=false;
|
||||||
|
pt[j].active=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_t selfmap_self_2;
|
||||||
|
*pmm >> selfmap_self_2;
|
||||||
|
pagemaptbl[2].pagemap = selfmap_self_2 >> 12;
|
||||||
|
pagemaptbl[2].writeable=true;
|
||||||
|
pagemaptbl[2].unprivileged=false;
|
||||||
|
pagemaptbl[2].no_write_cache=false;
|
||||||
|
pagemaptbl[2].no_read_cache=false;
|
||||||
|
pagemaptbl[2].sbz=0;
|
||||||
|
pagemaptbl[2].executable=false;
|
||||||
|
pagemaptbl[2].active=true;
|
||||||
|
pagemap * selfmap_2 = (pagemap*)selfmap_self_2;
|
||||||
|
for(int i=0;i<512;i++) {
|
||||||
|
if(i==2) {
|
||||||
|
selfmap_2[i].active=false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!pagemaptbl[i].active) {
|
||||||
|
selfmap_2[i].active=false;
|
||||||
|
} else {
|
||||||
|
phys_t pagedir_3;
|
||||||
|
*pmm >> pagedir_3;
|
||||||
|
selfmap_2[i].pagedir = pagedir_3 >> 12;
|
||||||
|
selfmap_2[i].unprivileged=false;
|
||||||
|
selfmap_2[i].no_write_cache=true;
|
||||||
|
selfmap_2[i].no_read_cache=true;
|
||||||
|
selfmap_2[i]._1G_page=false;
|
||||||
|
selfmap_2[i].global = false;
|
||||||
|
selfmap_2[i].sbz=false;
|
||||||
|
selfmap_2[i].executable=false;
|
||||||
|
selfmap_2[i].active=true;
|
||||||
|
|
||||||
|
pagemap *spm = (pagemap*)(pagemaptbl[i].pagemap << 12);
|
||||||
|
pagedir *dpd = (pagedir*)pagedir_3;
|
||||||
|
for(int j=0;j<512;j++) {
|
||||||
|
if(!spm[j].active) {
|
||||||
|
dpd[j].active=false;
|
||||||
|
} else {
|
||||||
|
phys_t pagetbl_3;
|
||||||
|
*pmm >> pagetbl_3;
|
||||||
|
dpd[j].pagetbl = pagetbl_3 >> 12;
|
||||||
|
dpd[j].unprivileged = false;
|
||||||
|
dpd[j].no_write_cache=true;
|
||||||
|
dpd[j].no_read_cache=true;
|
||||||
|
dpd[j]._2M_page=false;
|
||||||
|
dpd[j].global = false;
|
||||||
|
dpd[j].sbz=false;
|
||||||
|
dpd[j].executable=false;
|
||||||
|
dpd[j].active=true;
|
||||||
|
|
||||||
|
pagedir *spd = (pagedir*)(spm[j].pagedir << 12);
|
||||||
|
pagetbl *dpt = (pagetbl*)pagetbl_3;
|
||||||
|
for(int k=0;k<512;k++) {
|
||||||
|
if(!spd[k].active) {
|
||||||
|
dpt[k].active=false;
|
||||||
|
dpt[k].lazy=false;
|
||||||
|
} else {
|
||||||
|
dpt[k].page=spd[k].pagetbl;
|
||||||
|
dpt[k].writeable=true;
|
||||||
|
dpt[k].unprivileged=false;
|
||||||
|
dpt[k].no_write_cache=true;
|
||||||
|
dpt[k].no_read_cache=true;
|
||||||
|
dpt[k].pat=false;
|
||||||
|
dpt[k].global=false;
|
||||||
|
dpt[k].sbz=0;
|
||||||
|
dpt[k].executable=false;
|
||||||
|
dpt[k].active=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//needs more nesting
|
||||||
|
|
||||||
|
|
||||||
|
//Fix selfmap
|
||||||
|
bool has_changed=true;
|
||||||
|
while(has_changed) {
|
||||||
|
has_changed = false;
|
||||||
|
for(int i=0;i<512;i++) {
|
||||||
|
if(!pagemaptbl[i].active)
|
||||||
|
continue;
|
||||||
|
if(!selftbl_2[i].active) {
|
||||||
|
//add mapping
|
||||||
|
selftbl_2[i].page = pagemaptbl[i].pagemap;
|
||||||
|
selftbl_2[i].writeable = true;
|
||||||
|
selftbl_2[i].unprivileged=false;
|
||||||
|
selftbl_2[i].no_write_cache=true;
|
||||||
|
selftbl_2[i].no_read_cache=true;
|
||||||
|
selftbl_2[i].pat=false;
|
||||||
|
selftbl_2[i].global=false;
|
||||||
|
selftbl_2[i].sbz=0;
|
||||||
|
selftbl_2[i].executable=false;
|
||||||
|
selftbl_2[i].active=true;
|
||||||
|
has_changed=true;
|
||||||
|
}
|
||||||
|
pagemap *spagemap = (pagemap*)(pagemaptbl[i].pagemap << 12);
|
||||||
|
for(int j=0;j<512;j++) {
|
||||||
|
if(!spagemap[j].active)
|
||||||
|
continue;
|
||||||
|
if(!selfdir_2[i].active) {
|
||||||
|
phys_t ptbl;
|
||||||
|
*pmm >> ptbl;
|
||||||
|
selfdir_2[i].pagetbl = ptbl >> 12;
|
||||||
|
selfdir_2[i].unprivileged=false;
|
||||||
|
selfdir_2[i].no_write_cache=true;
|
||||||
|
selfdir_2[i].no_read_cache=true;
|
||||||
|
selfdir_2[i]._2M_page=false;
|
||||||
|
selfdir_2[i].global=false;
|
||||||
|
selfdir_2[i].sbz=0;
|
||||||
|
selfdir_2[i].executable=false;
|
||||||
|
selfdir_2[i].active=true;
|
||||||
|
pagetbl *selftbl = (pagetbl*)(selfdir_2[i].pagetbl<<12);
|
||||||
|
for(int k=0;k<512;k++)
|
||||||
|
selftbl[k].active = false;
|
||||||
|
has_changed=true;
|
||||||
|
}
|
||||||
|
pagetbl *selftbl = (pagetbl*)(selfdir_2[i].pagetbl<<12);
|
||||||
|
if(!selftbl[j].active) {
|
||||||
|
selftbl[j].page = spagemap[j].pagedir;
|
||||||
|
selftbl[j].unprivileged=false;
|
||||||
|
selftbl[j].no_write_cache=true;
|
||||||
|
selftbl[j].no_read_cache=true;
|
||||||
|
selftbl[j].pat=false;
|
||||||
|
selftbl[j].global=false;
|
||||||
|
selftbl[j].sbz=0;
|
||||||
|
selftbl[j].executable=false;
|
||||||
|
selftbl[j].active=true;
|
||||||
|
has_changed=true;
|
||||||
|
}
|
||||||
|
pagedir *spagedir=(pagedir*)(spagemap[j].pagedir<<12);
|
||||||
|
for(int k=0;k<512;k++) {
|
||||||
|
if(!spagedir[k].active)
|
||||||
|
continue;
|
||||||
|
if(!selfmap_2[i].active) {
|
||||||
|
phys_t pdir;
|
||||||
|
*pmm >> pdir;
|
||||||
|
selfmap_2[i].pagedir = pdir >> 12;
|
||||||
|
selfmap_2[i].unprivileged=false;
|
||||||
|
selfmap_2[i].no_write_cache=true;
|
||||||
|
selfmap_2[i].no_read_cache=true;
|
||||||
|
selfmap_2[i]._1G_page=false;
|
||||||
|
selfmap_2[i].global=false;
|
||||||
|
selfmap_2[i].sbz=0;
|
||||||
|
selfmap_2[i].executable=false;
|
||||||
|
selfmap_2[i].active=true;
|
||||||
|
pagedir *selfdir = (pagedir*)(selfmap_2[i].pagedir<<12);
|
||||||
|
for(int l=0;l<512;l++)
|
||||||
|
selfdir[l].active = false;
|
||||||
|
has_changed=true;
|
||||||
|
}
|
||||||
|
pagedir *selfdir = (pagedir*)(selfmap_2[i].pagedir<<12);
|
||||||
|
if(!selfdir[j].active) {
|
||||||
|
phys_t ptbl;
|
||||||
|
*pmm >> ptbl;
|
||||||
|
selfdir[j].pagetbl = ptbl >> 12;
|
||||||
|
selfdir[j].unprivileged=false;
|
||||||
|
selfdir[j].no_write_cache=true;
|
||||||
|
selfdir[j].no_read_cache=true;
|
||||||
|
selfdir[j]._2M_page=false;
|
||||||
|
selfdir[j].global=false;
|
||||||
|
selfdir[j].sbz=0;
|
||||||
|
selfdir[j].executable=false;
|
||||||
|
selfdir[j].active=true;
|
||||||
|
pagetbl *selftbl = (pagetbl*)(selfdir[j].pagetbl<<12);
|
||||||
|
for(int l=0;l<512;l++)
|
||||||
|
selftbl[l].active = false;
|
||||||
|
has_changed=true;
|
||||||
|
}
|
||||||
|
pagetbl *selftbl = (pagetbl*)(selfdir[j].pagetbl<<12);
|
||||||
|
if(!selftbl[k].active) {
|
||||||
|
selftbl[k].page = spagedir[k].pagetbl;
|
||||||
|
selftbl[k].unprivileged=false;
|
||||||
|
selftbl[k].no_write_cache=true;
|
||||||
|
selftbl[k].no_read_cache=true;
|
||||||
|
selftbl[k].pat=false;
|
||||||
|
selftbl[k].global=false;
|
||||||
|
selftbl[k].sbz=0;
|
||||||
|
selftbl[k].executable=false;
|
||||||
|
selftbl[k].active=true;
|
||||||
|
has_changed=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paging_context_x86::~paging_context_x86() {
|
||||||
|
//deallocate userspace
|
||||||
|
phys_t cur_addr = 0xFFFF000000000000ull;
|
||||||
|
while(cur_addr >= 0xFFFF000000000000ull) {
|
||||||
|
if(!curr_pagemaptbl[pagemaptbl_index(cur_addr)].active) {
|
||||||
|
cur_addr += 0x8000000000ull; //512GB
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!curr_pagemap[pagemap_index(cur_addr)].active) {
|
||||||
|
cur_addr += 0x40000000u; //1GB
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!curr_pagedir[pagedir_index(cur_addr)].active) {
|
||||||
|
cur_addr += 0x200000; //2MB
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!curr_pagetbl[pagetbl_index(cur_addr)].active) {
|
||||||
|
cur_addr += 0x1000; //4KB
|
||||||
|
}
|
||||||
|
munmap(make_virt(cur_addr));
|
||||||
|
cur_addr+=0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
//deallocate selfmap
|
||||||
|
phys_t addr = 0x100000000000;
|
||||||
|
while(addr >= 0xC000000000) {
|
||||||
|
if(!curr_pagemap[pagemap_index(addr)].active) {
|
||||||
|
addr += 0x40000000u; //1GB
|
||||||
|
}
|
||||||
|
if(!curr_pagedir[pagedir_index(addr)].active) {
|
||||||
|
addr += 0x200000; //2MB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void paging_context_x86::switch_context() {
|
||||||
|
pagemap_tbl *p=(pagemap_tbl*)pagemaptbl_addr;
|
||||||
|
if(context_enabled)
|
||||||
|
p=curr_pagemaptbl;
|
||||||
|
for(int i=0;i<256;i++) {
|
||||||
|
kernel[i]=p[i];
|
||||||
|
}
|
||||||
|
asm volatile("mov %0, %%cr3" :: "r"(pagemaptbl_addr) : "memory");
|
||||||
|
if(context_enabled) {
|
||||||
|
for(int i=0;i<256;i++) {
|
||||||
|
if((i>=1) && (i<=3)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
p[i]=kernel[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paging_context::switch_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
void paging_context_x86::map_pagetable(paging_context *pc_t) {
|
||||||
|
paging_context_x86 *pc = (paging_context_x86*)pc_t;
|
||||||
|
mmap(pc->pagemaptbl_addr, ref_pagemaptbl, protection::RW, false);
|
||||||
|
for(uint64_t i=0;i<512;i++) {
|
||||||
|
if(!ref_pagemaptbl[i].active)
|
||||||
|
continue;
|
||||||
|
mmap(ref_pagemaptbl[i].pagemap << 12, ref_pagemap+(i<<9), protection::RW, false);
|
||||||
|
for(uint64_t j=0;j<512;j++) {
|
||||||
|
if(!ref_pagemap[j+(i<<9)].active)
|
||||||
|
continue;
|
||||||
|
mmap(ref_pagemap[j+(i<<9)].pagedir << 12, ref_pagedir+(i<<18)+(j<<9), protection::RW, false);
|
||||||
|
for(uint64_t k=0;k<512;k++) {
|
||||||
|
if(!ref_pagedir[k+(j<<9)+(i<<18)].active)
|
||||||
|
continue;
|
||||||
|
mmap(ref_pagedir[k+(j<<9)+(i<<18)].pagetbl << 12, ref_pagetbl+(i<<27)+(j<<18)+(k<<9), protection::RW, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *paging_context_x86::mmap(phys_t phys, void* addr, protection prot, bool lazy) {
|
||||||
|
auto pagemaptbls = (current_context == this)?curr_pagemaptbl:ref_pagemaptbl;
|
||||||
|
auto pagemaps = (current_context == this)?curr_pagemap:ref_pagemap;
|
||||||
|
auto pagedirs = (current_context == this)?curr_pagedir:ref_pagedir;
|
||||||
|
auto pagetbls = (current_context == this)?curr_pagetbl:ref_pagetbl;
|
||||||
|
if((!phys)&&(!lazy)) {
|
||||||
|
*pmm >> phys;
|
||||||
|
}
|
||||||
|
if(!addr) {
|
||||||
|
phys_t start=lazy?0xFFFF800000000000ull:0x14000000000ull;
|
||||||
|
phys_t end=lazy?~0ull:0x800000000000ull;
|
||||||
|
phys_t caddr = start;
|
||||||
|
bool found=false;
|
||||||
|
if(!_512G_full) {
|
||||||
|
for(auto i=pagemaptbl_index(start);i!=pagemaptbl_index(end);i++) {
|
||||||
|
if(!pagemaptbls[i].active) {
|
||||||
|
addr = make_virt(i,0,0,0);
|
||||||
|
found=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!_1G_full && !found) {
|
||||||
|
_512G_full=true;
|
||||||
|
for(auto i=pagemap_index(start);i!=pagemap_index(end);i++) {
|
||||||
|
if(!pagemaps[i].active) {
|
||||||
|
addr = make_virt(0,i,0,0);
|
||||||
|
found=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!_2M_full && !found) {
|
||||||
|
_1G_full = true;
|
||||||
|
for(auto i=pagedir_index(start);i!=pagedir_index(end);i++) {
|
||||||
|
if(!pagedirs[i].active) {
|
||||||
|
addr = make_virt(0,0,i,0);
|
||||||
|
found=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
_2M_full=true;
|
||||||
|
for(auto i=pagetbl_index(start);i!=pagetbl_index(end);i++) {
|
||||||
|
if(!pagetbls[i].active) {
|
||||||
|
addr = make_virt(0,0,0,i);
|
||||||
|
found=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
panic("Not enough virtual address space available (how did you do that?)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_t v = unwrap((phys_t)addr);
|
||||||
|
phys_t l = v>>12;
|
||||||
|
phys_t k = v>>21;
|
||||||
|
phys_t j = v>>30;
|
||||||
|
phys_t i = v>>39;
|
||||||
|
|
||||||
|
if(!pagemaptbls[i].active) {
|
||||||
|
phys_t pm_addr;
|
||||||
|
*pmm >> pm_addr;
|
||||||
|
mmap(pm_addr, curr_pagemap+(i<<9), protection::RW, false);
|
||||||
|
if(current_context != this)
|
||||||
|
current_context->mmap(pm_addr, pagemaps+(i<<9), protection::RW, false);
|
||||||
|
for(int x=0;x<512;x++)
|
||||||
|
pagemaps[x+(i<<9)].active=false;
|
||||||
|
pagemap_tbl &pm = pagemaptbls[i];
|
||||||
|
pm.pagemap = pm_addr>>12;
|
||||||
|
pm.writeable = true;
|
||||||
|
pm.unprivileged = i>=256;
|
||||||
|
pm.no_write_cache=i<4;
|
||||||
|
pm.no_read_cache=false;
|
||||||
|
pm.sbz=0;
|
||||||
|
pm.executable=false;
|
||||||
|
pm.active=true;
|
||||||
|
}
|
||||||
|
if(!pagemaps[j].active) {
|
||||||
|
phys_t pd_addr;
|
||||||
|
*pmm >> pd_addr;
|
||||||
|
mmap(pd_addr, curr_pagedir+(j<<9), protection::RW, false);
|
||||||
|
if(current_context != this)
|
||||||
|
current_context->mmap(pd_addr, pagedirs+(j<<9), protection::RW, false);
|
||||||
|
for(int x=0;x<512;x++)
|
||||||
|
pagedirs[x+(j<<9)].active=false;
|
||||||
|
pagemap &pd = pagemaps[j];
|
||||||
|
pd.pagedir = pd_addr>>12;
|
||||||
|
pd.writeable=true;
|
||||||
|
pd.unprivileged = i>=256;
|
||||||
|
pd.no_write_cache=i<4;
|
||||||
|
pd.no_read_cache=false;
|
||||||
|
pd.sbz=0;
|
||||||
|
pd.global=false;
|
||||||
|
pd._1G_page=false;
|
||||||
|
pd.executable=false;
|
||||||
|
pd.active=true;
|
||||||
|
}
|
||||||
|
if(!pagedirs[k].active) {
|
||||||
|
phys_t pt_addr;
|
||||||
|
*pmm >> pt_addr;
|
||||||
|
mmap(pt_addr, curr_pagetbl+(k<<9), protection::RW, false);
|
||||||
|
if(current_context != this)
|
||||||
|
current_context->mmap(pt_addr, pagetbls+(k<<9), protection::RW, false);
|
||||||
|
for(int x=0;x<512;x++)
|
||||||
|
pagetbls[x+(k<<9)].active=false;
|
||||||
|
pagedir &pt = pagedirs[k];
|
||||||
|
pt.pagetbl = pt_addr >> 12;
|
||||||
|
pt.writeable=true;
|
||||||
|
pt.unprivileged = i>=256;
|
||||||
|
pt.no_write_cache=i<4;
|
||||||
|
pt.no_read_cache=false;
|
||||||
|
pt.sbz=0;
|
||||||
|
pt.global=false;
|
||||||
|
pt._2M_page=false;
|
||||||
|
pt.executable=false;
|
||||||
|
pt.active=true;
|
||||||
|
}
|
||||||
|
uint8_t p=(uint8_t)prot;
|
||||||
|
pagetbl &page = pagetbls[l];
|
||||||
|
page.page = phys >> 12;
|
||||||
|
page.writeable = p & 2;
|
||||||
|
page.unprivileged = p&4;
|
||||||
|
page.no_write_cache=i<4;
|
||||||
|
page.no_read_cache=false;
|
||||||
|
page.sbz=0;
|
||||||
|
page.pat=false;
|
||||||
|
page.global=false;
|
||||||
|
page.lazy=lazy;
|
||||||
|
page.executable=false; //!(p&1);
|
||||||
|
page.active=!lazy;
|
||||||
|
|
||||||
|
if(current_context == this) {
|
||||||
|
asm volatile("invlpg %0" :: "m"(*(char*)addr) : "memory");
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paging_context_x86::munmap(void *addr) {
|
||||||
|
auto pagetbls = (current_context == this)?curr_pagetbl:ref_pagetbl;
|
||||||
|
if(__builtin_expect(!is_mapped(addr),0))
|
||||||
|
return;
|
||||||
|
phys_t l=unwrap((phys_t)addr)>>12;
|
||||||
|
pagetbls[l].active=false;
|
||||||
|
pagetbls[l].lazy=false;
|
||||||
|
asm volatile("invlpg %0" :: "m"(*(char*)addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool paging_context_x86::is_mapped(void* addr) {
|
||||||
|
phys_t v = unwrap((phys_t)addr);
|
||||||
|
phys_t l = v>>12;
|
||||||
|
phys_t k = v>>21;
|
||||||
|
phys_t j = v>>30;
|
||||||
|
phys_t i = v>>39;
|
||||||
|
auto pagemaptbls = (current_context == this)?curr_pagemaptbl:ref_pagemaptbl;
|
||||||
|
auto pagemaps = (current_context == this)?curr_pagemap:ref_pagemap;
|
||||||
|
auto pagedirs = (current_context == this)?curr_pagedir:ref_pagedir;
|
||||||
|
auto pagetbls = (current_context == this)?curr_pagetbl:ref_pagetbl;
|
||||||
|
|
||||||
|
if(!pagemaptbls[i].active)
|
||||||
|
return false;
|
||||||
|
if(!pagemaps[j].active)
|
||||||
|
return false;
|
||||||
|
if(!pagedirs[k].active)
|
||||||
|
return false;
|
||||||
|
return pagetbls[l].active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paging_context_x86::mprotect(void* addr, protection prot) {
|
||||||
|
auto pagetbls = (current_context == this)?curr_pagetbl:ref_pagetbl;
|
||||||
|
if(__builtin_expect(!is_mapped(addr),0))
|
||||||
|
return;
|
||||||
|
phys_t l=unwrap((phys_t)addr)>>12;
|
||||||
|
uint8_t p=(uint8_t)prot;
|
||||||
|
pagetbl &page=pagetbls[l];
|
||||||
|
page.writeable=p&2;
|
||||||
|
page.unprivileged=p&4;
|
||||||
|
page.executable=false;//!(p&1);
|
||||||
|
asm volatile("invlpg %0" :: "m"(*(char*)addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool paging_context_x86::has_no_exec() {return true;}
|
||||||
|
void *paging_context_x86::get_exception_address(cpu_state *cpu) {
|
||||||
|
uint64_t cr2;
|
||||||
|
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||||
|
return (void*)cr2;
|
||||||
|
}
|
||||||
|
bool paging_context_x86::lazymap(void *addr, cpu_state *cpu) {
|
||||||
|
phys_t v = unwrap((phys_t)addr);
|
||||||
|
phys_t l = v>>12;
|
||||||
|
phys_t k = v>>21;
|
||||||
|
phys_t j = v>>30;
|
||||||
|
phys_t i = v>>39;
|
||||||
|
if(!curr_pagemaptbl[i].active)
|
||||||
|
return false;
|
||||||
|
if(!curr_pagemap[j].active)
|
||||||
|
return false;
|
||||||
|
if(!curr_pagedir[k].active)
|
||||||
|
return false;
|
||||||
|
if(!curr_pagetbl[l].lazy)
|
||||||
|
return false;
|
||||||
|
phys_t phys;
|
||||||
|
*pmm >> phys;
|
||||||
|
curr_pagetbl[l].page = phys>>12;
|
||||||
|
curr_pagetbl[l].active=true;
|
||||||
|
asm volatile("invlpg %0" :: "m"(*(char*)addr) :"memory");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../../../hw/pc/8259/pic.hpp"
|
#include "../../../hw/pc/8259/pic.hpp"
|
||||||
#include "../../../hw/pc/idt/idt.hpp"
|
#include "../../../hw/pc/idt/idt.hpp"
|
||||||
#include "../../../hw/pc/pmm/pmm.hpp"
|
#include "../../../hw/pc/pmm/pmm.hpp"
|
||||||
|
#include <paging.h>
|
||||||
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
static multiboot_info_t *mb_info;
|
static multiboot_info_t *mb_info;
|
||||||
|
@ -18,7 +19,7 @@ VESAfb term(mb_info);
|
||||||
#endif
|
#endif
|
||||||
PMM_MB lpmm(mb_info);
|
PMM_MB lpmm(mb_info);
|
||||||
|
|
||||||
#include<paging.hpp>
|
paging_context_x86 main_context;
|
||||||
void main();
|
void main();
|
||||||
extern "C" void start(int eax, multiboot_info_t *ebx) {
|
extern "C" void start(int eax, multiboot_info_t *ebx) {
|
||||||
mb_info = ebx;
|
mb_info = ebx;
|
||||||
|
@ -30,6 +31,12 @@ void drivers_init() {
|
||||||
setMainTTY(&term);
|
setMainTTY(&term);
|
||||||
--term;
|
--term;
|
||||||
initIDT();
|
initIDT();
|
||||||
|
main_context.switch_context();
|
||||||
|
main_context.mmap((phys_t)mb_info, mb_info, protection::RW, false);
|
||||||
|
phys_t start_fb = (phys_t)(mb_info->framebuffer_addr);
|
||||||
|
phys_t end_fb = start_fb + mb_info->framebuffer_height * mb_info->framebuffer_pitch;
|
||||||
|
for(phys_t i=start_fb;i<end_fb;i+=0x1000)
|
||||||
|
main_context.mmap(i,(void*)i,protection::RW,false);
|
||||||
PIC::initPIC(0x20, 0x28);
|
PIC::initPIC(0x20, 0x28);
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,10 @@ _start3:
|
||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %gs
|
mov %ax, %gs
|
||||||
mov %ax, %ss //Load 64-bit data
|
mov %ax, %ss //Load 64-bit data
|
||||||
|
mov $0xC0000080, %rax
|
||||||
|
rdmsr
|
||||||
|
or $(1<<11), %rcx
|
||||||
|
wrmsr
|
||||||
mov $mb_ptr, %rsi
|
mov $mb_ptr, %rsi
|
||||||
lodsl
|
lodsl
|
||||||
mov %rax, %rdi
|
mov %rax, %rdi
|
||||||
|
|
|
@ -30,5 +30,7 @@ auto PMM_MB::isFree(phys_t addr) -> bool {
|
||||||
return false;
|
return false;
|
||||||
if((addr >= (phys_t)((uintptr_t)mb_info)) && (addr < (phys_t)((uintptr_t)mb_info)+0x1000))
|
if((addr >= (phys_t)((uintptr_t)mb_info)) && (addr < (phys_t)((uintptr_t)mb_info)+0x1000))
|
||||||
return false;
|
return false;
|
||||||
|
if(addr <= 0x100000)
|
||||||
|
return false;
|
||||||
return PMM::isFree(addr);
|
return PMM::isFree(addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,10 @@ extern "C" int kernel_start;
|
||||||
extern "C" int kernel_end;
|
extern "C" int kernel_end;
|
||||||
|
|
||||||
static inline void * map(phys_t addr) {
|
static inline void * map(phys_t addr) {
|
||||||
if(__builtin_expect(context_enabled, true))
|
if(__builtin_expect(context_enabled, true)) {
|
||||||
return current_context->mmap(addr, (void*)1, protection::RW, false);
|
current_context->mmap(addr, (void*)1, protection::RW, false);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
return (void*)addr;
|
return (void*)addr;
|
||||||
}
|
}
|
||||||
static inline void unmap(void* addr) {
|
static inline void unmap(void* addr) {
|
||||||
|
|
Loading…
Reference in a new issue