HelenOS sources
This source file includes following definitions.
- page_arch_init
- set_environment
- vhpt_hash
- vhpt_compare
- vhpt_set_record
#include <arch/mm/page.h>
#include <assert.h>
#include <genarch/mm/page_ht.h>
#include <mm/asid.h>
#include <arch/mm/asid.h>
#include <arch/mm/vhpt.h>
#include <typedefs.h>
#include <mm/page.h>
#include <mm/frame.h>
#include <config.h>
#include <panic.h>
#include <arch/asm.h>
#include <barrier.h>
#include <align.h>
static void set_environment(void);
void page_arch_init(void)
{
page_mapping_operations = &ht_mapping_operations;
pk_disable();
set_environment();
}
void set_environment(void)
{
region_register_t rr;
pta_register_t pta;
int i;
#ifdef CONFIG_VHPT
uintptr_t vhpt_base;
#endif
for (i = 0; i < REGION_REGISTERS; i++) {
rr.word = rr_read(i);
rr.map.ve = 0;
rr.map.rid = ASID2RID(ASID_KERNEL, i);
rr.map.ps = PAGE_WIDTH;
rr_write(i, rr.word);
srlz_i();
srlz_d();
}
#ifdef CONFIG_VHPT
vhpt_base = vhpt_set_up();
#endif
pta.word = pta_read();
#ifndef CONFIG_VHPT
pta.map.ve = 0;
pta.map.base = 0 >> PTA_BASE_SHIFT;
#else
pta.map.ve = 1;
pta.map.base = vhpt_base >> PTA_BASE_SHIFT;
#endif
pta.map.vf = 1;
pta.map.size = VHPT_WIDTH;
pta_write(pta.word);
srlz_i();
srlz_d();
}
vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
{
region_register_t rr_save, rr;
size_t vrn;
rid_t rid;
vhpt_entry_t *v;
vrn = page >> VRN_SHIFT;
rid = ASID2RID(asid, vrn);
rr_save.word = rr_read(vrn);
if (rr_save.map.rid == rid) {
v = (vhpt_entry_t *) thash(page);
return v;
}
rr.word = rr_save.word;
rr.map.rid = rid;
rr_write(vrn, rr.word);
srlz_i();
v = (vhpt_entry_t *) thash(page);
rr_write(vrn, rr_save.word);
srlz_i();
srlz_d();
return v;
}
bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
{
region_register_t rr_save, rr;
size_t vrn;
rid_t rid;
bool match;
assert(v);
vrn = page >> VRN_SHIFT;
rid = ASID2RID(asid, vrn);
rr_save.word = rr_read(vrn);
if (rr_save.map.rid == rid) {
return ttag(page) == v->present.tag.tag_word;
}
rr.word = rr_save.word;
rr.map.rid = rid;
rr_write(vrn, rr.word);
srlz_i();
match = (ttag(page) == v->present.tag.tag_word);
rr_write(vrn, rr_save.word);
srlz_i();
srlz_d();
return match;
}
void
vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame,
int flags)
{
region_register_t rr_save, rr;
size_t vrn;
rid_t rid;
uint64_t tag;
assert(v);
vrn = page >> VRN_SHIFT;
rid = ASID2RID(asid, vrn);
rr_save.word = rr_read(vrn);
rr.word = rr_save.word;
rr.map.rid = rid;
rr_write(vrn, rr.word);
srlz_i();
tag = ttag(page);
rr_write(vrn, rr_save.word);
srlz_i();
srlz_d();
v->word[0] = 0;
v->word[1] = 0;
v->word[2] = 0;
v->word[3] = 0;
v->present.p = true;
v->present.ma = (flags & PAGE_CACHEABLE) ?
MA_WRITEBACK : MA_UNCACHEABLE;
v->present.a = false;
v->present.d = false;
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ;
v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0;
v->present.ppn = frame >> PPN_SHIFT;
v->present.ed = false;
v->present.ps = PAGE_WIDTH;
v->present.key = 0;
v->present.tag.tag_word = tag;
}
HelenOS homepage, sources at GitHub