203 lines
6.5 KiB
C
203 lines
6.5 KiB
C
#include <test_helper.h>
|
|
#include <test_paging.h>
|
|
#include <aos/paging.h>
|
|
|
|
// ASSESSMENT M1: these lines show mapping to fixed locations and read/write
|
|
|
|
// used to avoid conflicts between tests
|
|
static lvaddr_t vaddr = 0x0000100000000000L;
|
|
|
|
static void test_paging_run(errval_t func(struct paging_state *paging_state), char *name, struct paging_state *paging_state) {
|
|
errval_t err;
|
|
|
|
// debug_printf("TEST_PAGING %19s: start\n", name);
|
|
err = func(paging_state);
|
|
|
|
if (err_is_ok(err)) {
|
|
debug_printf("TEST_PAGING %23s: OK\n", name);
|
|
} else {
|
|
debug_printf("TEST_PAGING %23s: ERR\n", name);
|
|
USER_PANIC_ERR(err, "Test Failed with Error");
|
|
}
|
|
}
|
|
|
|
static errval_t test_paging_full_l3(struct paging_state *paging_state) {
|
|
errval_t err;
|
|
|
|
size_t mapping_size = BASE_PAGE_SIZE;
|
|
|
|
// map all entries of a single l3 table
|
|
for(size_t i = 0; i < VMSAv8_64_PTABLE_NUM_ENTRIES; ++i) {
|
|
struct capref frame;
|
|
err = frame_alloc(&frame, mapping_size, NULL);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
|
}
|
|
err = paging_map_fixed_attr(paging_state, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
|
}
|
|
|
|
// verify mapping using a random value at a random location
|
|
uint8_t val = rand() % 256;
|
|
memset((void *) vaddr, val, mapping_size);
|
|
if(*((uint8_t *) vaddr + (rand() % mapping_size)) != val) {
|
|
return ERR_INVALID_ARGS;
|
|
}
|
|
|
|
vaddr += mapping_size;
|
|
}
|
|
|
|
return SYS_ERR_OK;
|
|
}
|
|
|
|
static errval_t test_paging_full_l2(struct paging_state *paging_state) {
|
|
errval_t err;
|
|
|
|
size_t mapping_size = BASE_PAGE_SIZE;
|
|
|
|
// map a page in all slots of a single l2 node (the 0-th slot was already used in a previous test)
|
|
for(size_t i = 1; i < VMSAv8_64_PTABLE_NUM_ENTRIES; ++i) {
|
|
struct capref frame;
|
|
err = frame_alloc(&frame, mapping_size, NULL);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
|
}
|
|
err = paging_map_fixed_attr(paging_state, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
|
}
|
|
|
|
// verify mapping using a random value at a random location
|
|
uint8_t val = rand() % 256;
|
|
memset((void *) vaddr, val, mapping_size);
|
|
if(*((uint8_t *) vaddr + (rand() % mapping_size)) != val) {
|
|
return ERR_INVALID_ARGS;
|
|
}
|
|
|
|
vaddr += LARGE_PAGE_SIZE;
|
|
}
|
|
|
|
return SYS_ERR_OK;
|
|
}
|
|
|
|
static errval_t test_paging_big_regions(struct paging_state *paging_state) {
|
|
errval_t err;
|
|
|
|
size_t mapping_size;
|
|
|
|
// map larger areas
|
|
for(size_t i = 1; i <= VMSAv8_64_PTABLE_NUM_ENTRIES - 1; ++i) {
|
|
mapping_size = i * BASE_PAGE_SIZE;
|
|
|
|
struct capref frame;
|
|
err = frame_alloc(&frame, mapping_size, NULL);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
|
}
|
|
err = paging_map_fixed_attr(paging_state, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
|
}
|
|
|
|
// verify mapping using a random value at a random location
|
|
uint8_t val = rand() % 256;
|
|
memset((void *) vaddr, val, mapping_size);
|
|
if(*((uint8_t *) vaddr + (rand() % mapping_size)) != val) {
|
|
return ERR_INVALID_ARGS;
|
|
}
|
|
|
|
vaddr += LARGE_PAGE_SIZE;
|
|
}
|
|
|
|
return SYS_ERR_OK;
|
|
}
|
|
|
|
static errval_t test_paging_map_frame(struct paging_state *paging_state) {
|
|
errval_t err;
|
|
|
|
for(size_t mapping_size = BASE_PAGE_SIZE; mapping_size <= VMSAv8_64_PTABLE_NUM_ENTRIES - 1; mapping_size += BASE_PAGE_SIZE) {
|
|
|
|
void *retaddr;
|
|
|
|
struct capref frame;
|
|
err = frame_alloc(&frame, mapping_size, NULL);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
|
}
|
|
err = paging_map_frame_attr(paging_state, &retaddr, mapping_size, frame, VREGION_FLAGS_READ_WRITE);
|
|
if (err_is_fail(err)) {
|
|
return err_push(err, LIB_ERR_PMAP_NOT_MAPPED);
|
|
}
|
|
|
|
// verify mapping using a random value at a random location
|
|
uint8_t val = rand() % 256;
|
|
memset(retaddr, val, mapping_size);
|
|
if(*((uint8_t *)retaddr + (rand() % mapping_size)) != val) {
|
|
return ERR_INVALID_ARGS;
|
|
}
|
|
|
|
vaddr += LARGE_PAGE_SIZE;
|
|
}
|
|
|
|
return SYS_ERR_OK;
|
|
}
|
|
|
|
static errval_t test_paging_foreign(struct paging_state *ignored) {
|
|
errval_t err;
|
|
|
|
// setup all the stuff for the test
|
|
struct capref rootcn_cap;
|
|
struct cnoderef rootcn;
|
|
struct cnoderef pagecn;
|
|
struct paging_state st;
|
|
err = cnode_create_l1(&rootcn_cap, &rootcn);
|
|
assert(err_is_ok(err));
|
|
err = cnode_create_foreign_l2(rootcn_cap, ROOTCN_SLOT_PAGECN, &pagecn);
|
|
assert(err_is_ok(err));
|
|
struct capref l0 = {
|
|
.cnode = pagecn,
|
|
.slot = PAGECN_SLOT_VROOT,
|
|
};
|
|
err = vnode_create(l0, ObjType_VNode_AARCH64_l0);
|
|
assert(err_is_ok(err));
|
|
|
|
// initialize foreign state
|
|
err = paging_init_state_foreign(&st, VADDR_OFFSET, l0, get_default_slot_allocator());
|
|
if (err_is_fail(err)) {
|
|
return err;
|
|
}
|
|
|
|
size_t mapping_size = BASE_PAGE_SIZE;
|
|
// map all entries of a single l3 table in the foreign state
|
|
for(size_t i = 0; i < VMSAv8_64_PTABLE_NUM_ENTRIES; ++i) {
|
|
struct capref frame;
|
|
err = frame_alloc(&frame, mapping_size, NULL);
|
|
if (err_is_fail(err)) {
|
|
return err;
|
|
}
|
|
err = paging_map_fixed_attr(&st, vaddr, frame, mapping_size, VREGION_FLAGS_READ_WRITE);
|
|
if (err_is_fail(err)) {
|
|
return err;
|
|
}
|
|
vaddr += mapping_size;
|
|
}
|
|
|
|
return SYS_ERR_OK;
|
|
}
|
|
|
|
void do_test_paging(void) {
|
|
test_paging_run(test_paging_full_l3, "test_paging_full_l3", get_current_paging_state());
|
|
test_paging_run(test_paging_full_l2, "test_paging_full_l2", get_current_paging_state());
|
|
test_paging_run(test_paging_big_regions, "test_paging_big_regions", get_current_paging_state());
|
|
test_paging_run(test_paging_map_frame, "test_paging_map_frame", get_current_paging_state());
|
|
test_paging_run(test_paging_foreign, "test_paging_foreign", NULL);
|
|
|
|
// Test paging
|
|
for (int i = 0; i < 40; i++) {
|
|
debug_printf("TEST: page %lu\n", i);
|
|
char *data = alloc_frame(5176*4096, 16, NULL, NULL);
|
|
memset(data, 33, 5176*4096);
|
|
}
|
|
}
|