blob: 8c8ecd545069185d6ca6207255ca4f125519a04c [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <autoconf.h>
#include <sel4/types.h>
#include <sel4/sel4.h>
#include <stdio.h>
#include <allocman/allocman.h>
#include <allocman/cspace/simple1level.h>
#include <allocman/mspace/fixed_pool.h>
#include <allocman/utspace/twinkle.h>
#include <allocman/cspace/two_level.h>
#include <allocman/mspace/virtual_pool.h>
#include <allocman/utspace/trickle.h>
#include <allocman/bootstrap.h>
#include <allocman/cspaceops.h>
#include <string.h>
#include <sel4utils/vspace.h>
#include <allocman/vka.h>
#define VIRTUAL_START 0xA0000000
#define MEM_POOL_SIZE (1*1024*1024)
static char initial_mem_pool[MEM_POOL_SIZE];
allocman_t *test_use_current_cspace_bootinfo() {
int error;
allocman_t *allocman;
vspace_alloc_t vspace;
vka_t *vka;
allocman = bootstrap_use_bootinfo(seL4_GetBootInfo(), sizeof(initial_mem_pool), initial_mem_pool);
assert(allocman);
vka = allocman_mspace_alloc(allocman, sizeof(*vka), &error);
assert(!error);
allocman_make_vka(vka, allocman);
sel4util_get_vspace_alloc_leaky(&vspace, seL4_CapInitThreadPD, vka, seL4_GetBootInfo());
reservation_t *reservation = vspace_reserve_range_at(&vspace, VIRTUAL_START, MEM_POOL_SIZE, seL4_AllRights, 1);
assert(reservation);
bootstrap_configure_virtual_pool(allocman, VIRTUAL_START, MEM_POOL_SIZE, seL4_CapInitThreadPD);
error = allocman_fill_reserves(allocman);
assert(!error);
return allocman;
}
void test_use_current_1level_cspace() {
int error;
seL4_CPtr i;
allocman_t *allocman;
seL4_BootInfo *bi = seL4_GetBootInfo();
allocman = bootstrap_use_current_1level(seL4_CapInitThreadCNode, bi->initThreadCNodeSizeBits, bi->empty.start, bi->empty.end, sizeof(initial_mem_pool), initial_mem_pool);
assert(allocman);
/* have to add all our resources manually */
for (i = bi->untyped.start; i < bi->untyped.end; i++) {
cspacepath_t slot = allocman_cspace_make_path(allocman, i);
uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
error = allocman_utspace_add_uts(allocman, 1, &slot, &size_bits, &paddr);
assert(!error);
}
error = allocman_fill_reserves(allocman);
assert(!error);
}
void test_use_current_cspace() {
int error;
seL4_CPtr i;
allocman_t *allocman;
cspace_single_level_t *cspace;
utspace_trickle_t *utspace;
seL4_BootInfo *bi = seL4_GetBootInfo();
allocman = bootstrap_create_allocman(sizeof(initial_mem_pool), initial_mem_pool);
assert(allocman);
/* construct a description of our current cspace */
cspace = allocman_mspace_alloc(allocman, sizeof(*cspace), &error);
assert(!error);
error = cspace_single_level_create(allocman, cspace, (struct cspace_single_level_config) {
.cnode = seL4_CapInitThreadCNode,
.cnode_size_bits = bi->initThreadCNodeSizeBits,
.cnode_guard_bits = seL4_WordBits - bi->initThreadCNodeSizeBits,
.first_slot = bi->empty.start,
.end_slot = bi->empty.end
});
assert(!error);
error = allocman_attach_cspace(allocman, cspace_single_level_make_interface(cspace));
assert(!error);
utspace = allocman_mspace_alloc(allocman, sizeof(*utspace), &error);
assert(!error);
error = allocman_attach_utspace(allocman, utspace_trickle_make_interface(utspace));
assert(!error);
/* have to add all our resources manually */
for (i = bi->untyped.start; i < bi->untyped.end; i++) {
cspacepath_t slot = allocman_cspace_make_path(allocman, i);
uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
error = allocman_utspace_add_uts(allocman, 1, &slot, &size_bits);
assert(!error);
}
error = allocman_fill_reserves(allocman);
assert(!error);
}
void test_new_1level_cspace_bootinfo() {
int error;
allocman_t *allocman;
cspace_simple1level_t *boot_cspace;
cspacepath_t new_path;
allocman = bootstrap_new_1level_bootinfo(seL4_GetBootInfo(), 14, sizeof(initial_mem_pool), initial_mem_pool, &boot_cspace);
assert(allocman);
error = allocman_fill_reserves(allocman);
assert(!error);
/* test we can easily use our old cspace */
error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(boot_cspace), seL4_CapInitThreadTCB, &new_path);
assert(!error);
/* drop our priority */
error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
assert(error == seL4_NoError);
/* no longer need that boot cspace information */
allocman_mspace_free(allocman, boot_cspace, sizeof(*boot_cspace));
}
void test_new_1level_cspace() {
bootstrap_info_t *bootstrap;
seL4_BootInfo *bi = seL4_GetBootInfo();
cspace_simple1level_t boot_cspace;
allocman_t *allocman;
cspacepath_t oldroot;
cspacepath_t currentroot;
cspacepath_t new_path;
cspacepath_t tcb;
cspacepath_t pd;
seL4_CPtr i;
int error;
bootstrap = bootstrap_create_info(sizeof(initial_mem_pool), initial_mem_pool);
assert(bootstrap);
/* describe the current cspace */
cspace_simple1level_create(&boot_cspace, (struct cspace_simple1level_config){
.cnode = seL4_CapInitThreadCNode,
.cnode_size_bits = bi->initThreadCNodeSizeBits,
.cnode_guard_bits = seL4_WordBits - bi->initThreadCNodeSizeBits,
.first_slot = bi->empty.start,
.end_slot = bi->empty.end - 1
});
/* pass to the boot strapper */
currentroot = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadCNode);
bootstrap_set_boot_cspace(bootstrap, cspace_simple1level_make_interface(&boot_cspace), currentroot);
/* give the untypeds to the bootstrapper */
for (i = bi->untyped.start; i < bi->untyped.end; i++) {
cspacepath_t slot = _cspace_simple1level_make_path(&boot_cspace, i);
uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
error = bootstrap_add_untypeds(bootstrap, 1, &slot, &size_bits, &paddr);
assert(!error);
}
/* bootstrapper has enough information to create */
tcb = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadTCB);
pd = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadPD);
allocman = bootstrap_new_1level(bootstrap, 14, tcb, pd, &oldroot);
assert(allocman);
/* take advantage of knowledge of simple1level cspace and just shift its root :) */
assert(oldroot.capDepth == 32);
boot_cspace.config.cnode = oldroot.capPtr;
/* now test we can use it */
error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(&boot_cspace), seL4_CapInitThreadTCB, &new_path);
assert(!error);
/* drop our priority */
error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
assert(error == seL4_NoError);
}
void test_new_2level_cspace_bootinfo() {
int error;
allocman_t *allocman;
cspace_simple1level_t *boot_cspace;
cspacepath_t new_path;
allocman = bootstrap_new_2level_bootinfo(seL4_GetBootInfo(), 6,10, sizeof(initial_mem_pool), initial_mem_pool, &boot_cspace);
assert(allocman);
error = allocman_fill_reserves(allocman);
assert(!error);
/* test we can easily use our old cspace */
error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(boot_cspace), seL4_CapInitThreadTCB, &new_path);
assert(!error);
/* drop our priority */
error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
assert(error == seL4_NoError);
/* no longer need that boot cspace information */
allocman_mspace_free(allocman, boot_cspace, sizeof(*boot_cspace));
}
void test_new_2level_cspace() {
bootstrap_info_t *bootstrap;
seL4_BootInfo *bi = seL4_GetBootInfo();
cspace_simple1level_t boot_cspace;
allocman_t *allocman;
cspacepath_t oldroot;
cspacepath_t currentroot;
cspacepath_t new_path;
cspacepath_t tcb;
cspacepath_t pd;
seL4_CPtr i;
int error;
bootstrap = bootstrap_create_info(sizeof(initial_mem_pool), initial_mem_pool);
assert(bootstrap);
/* describe the current cspace */
cspace_simple1level_create(&boot_cspace, (struct cspace_simple1level_config){
.cnode = seL4_CapInitThreadCNode,
.cnode_size_bits = bi->initThreadCNodeSizeBits,
.cnode_guard_bits = seL4_WordBits - bi->initThreadCNodeSizeBits,
.first_slot = bi->empty.start,
.end_slot = bi->empty.end - 1
});
/* pass to the boot strapper */
currentroot = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadCNode);
bootstrap_set_boot_cspace(bootstrap, cspace_simple1level_make_interface(&boot_cspace), currentroot);
/* give the untypeds to the bootstrapper */
for (i = bi->untyped.start; i < bi->untyped.end; i++) {
cspacepath_t slot = _cspace_simple1level_make_path(&boot_cspace, i);
uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
error = bootstrap_add_untypeds(bootstrap, 1, &slot, &size_bits, &paddr);
assert(!error);
}
/* bootstrapper has enough information to create */
tcb = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadTCB);
pd = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadPD);
allocman = bootstrap_new_2level(bootstrap, 6, 10, tcb, pd, &oldroot);
assert(allocman);
/* take advantage of knowledge of simple1level cspace and just shift its root :) */
assert(oldroot.capDepth == 32);
boot_cspace.config.cnode = oldroot.capPtr;
/* now test we can use it */
error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(&boot_cspace), seL4_CapInitThreadTCB, &new_path);
assert(!error);
/* drop our priority */
error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
assert(error == seL4_NoError);
}
int main(void) {
allocman_t *alloc;
alloc = test_use_current_cspace_bootinfo();
// test_use_current_1level_cspace();
// test_use_current_cspace();
// test_new_1level_cspace_bootinfo();
// test_new_1level_cspace();
// test_new_2level_cspace_bootinfo();
// test_new_2level_cspace();
printf("All is well in the universe.\n");
while(1);
}