|  | /* | 
|  | * Copyright 2014, NICTA | 
|  | * | 
|  | * This software may be distributed and modified according to the terms of | 
|  | * the BSD 2-Clause license. Note that NO WARRANTY is provided. | 
|  | * See "LICENSE_BSD2.txt" for details. | 
|  | * | 
|  | * @TAG(NICTA_BSD) | 
|  | */ | 
|  |  | 
|  | #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, 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, 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, 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, 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); | 
|  | } |