1/* 2 * Copyright 2016, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(D61_BSD) 11 */ 12 13#include <autoconf.h> 14#ifdef CONFIG_REFOS_RUN_TESTS 15 16#include <stdlib.h> 17#include <string.h> 18#include <autoconf.h> 19#include <refos/test.h> 20#include "test.h" 21#include "test_addrspace.h" 22#include "../state.h" 23#include "../system/addrspace/vspace.h" 24#include <refos/test.h> 25 26/* ------------------------------- Page Dir module test ------------------------------- */ 27 28int 29test_pd(void) 30{ 31 test_start("page directory"); 32 seL4_CPtr p[PD_MAX]; 33 for (int i = 0; i < PD_MAX; i++) { 34 p[i] = pd_assign(&procServ.PDList).kpdObject; 35 test_assert(p[i] != 0); 36 } 37 for (int i = 0; i < PD_MAX; i++) { 38 pd_free(&procServ.PDList, p[i]); 39 } 40 for (int i = 0; i < 2; i++) { 41 p[i] = pd_assign(&procServ.PDList).kpdObject; 42 test_assert(p[i] != 0); 43 } 44 for (int i = 0; i < 2; i++) { 45 pd_free(&procServ.PDList, p[i]); 46 } 47 return test_success(); 48} 49 50/* ------------------------------- VSpace module test ------------------------------- */ 51 52int 53test_vspace(int run) 54{ 55 test_start(run == 0 ? "vspace (run 1)" : "vspace (run 2)"); 56 const int numTestVS = MIN(8, MIN((PID_MAX - 1), PD_MAX)); 57 int error = -1; 58 59 struct vs_vspace vs[numTestVS]; 60 61 /* Allocate ALL the vspaces. */ 62 for (int i = 0; i < numTestVS; i++) { 63 uint32_t bogusPID = (i * 31337 % 1234); 64 error = vs_initialise(&vs[i], bogusPID); 65 66 test_assert(error == ESUCCESS); 67 test_assert(vs[i].magic == REFOS_VSPACE_MAGIC); 68 test_assert(vs[i].ref == 1); 69 test_assert(vs[i].pid == bogusPID); 70 test_assert(vs[i].kpd != 0); 71 test_assert(vs[i].cspace.capPtr != 0); 72 test_assert(vs[i].cspaceSize == REFOS_CSPACE_RADIX); 73 } 74 75 /* Ref every second one thrice. */ 76 for (int i = 0; i < numTestVS; i+=2) { 77 vs_ref(&vs[i]); 78 vs_ref(&vs[i]); 79 vs_ref(&vs[i]); 80 } 81 82 /* Deref every VS. */ 83 for (int i = 0; i < numTestVS; i++) { 84 vs_unref(&vs[i]); 85 } 86 87 /* Check that every second one is still alive. */ 88 for (int i = 0; i < numTestVS; i++) { 89 if (i % 2 == 0) { 90 test_assert(vs[i].ref == 3); 91 test_assert(vs[i].magic == REFOS_VSPACE_MAGIC); 92 vs_unref(&vs[i]); 93 test_assert(vs[i].ref == 2); 94 test_assert(vs[i].magic == REFOS_VSPACE_MAGIC); 95 vs_unref(&vs[i]); 96 test_assert(vs[i].ref == 1); 97 test_assert(vs[i].magic == REFOS_VSPACE_MAGIC); 98 vs_unref(&vs[i]); 99 test_assert(vs[i].ref == 0); 100 test_assert(vs[i].magic != REFOS_VSPACE_MAGIC); 101 } else { 102 test_assert(vs[i].ref == 0); 103 test_assert(vs[i].magic != REFOS_VSPACE_MAGIC); 104 } 105 } 106 107 return test_success(); 108} 109 110int 111test_vspace_mapping(void) 112{ 113 test_start("vspace mapping"); 114 115 /* Create a vspace for testing mapping. */ 116 struct vs_vspace vs; 117 int error = vs_initialise(&vs, 31337); 118 test_assert(error == ESUCCESS); 119 test_assert(vs.magic == REFOS_VSPACE_MAGIC); 120 121 /* Create a memory segment window. */ 122 const vaddr_t window = 0x10000; 123 const vaddr_t windowSize = 0x8000; 124 int windowID; 125 error = vs_create_window(&vs, window, windowSize, W_PERMISSION_WRITE | W_PERMISSION_READ, 126 true, &windowID); 127 test_assert(error == ESUCCESS); 128 test_assert(windowID != W_INVALID_WINID); 129 130 /* Allocate a frame to map. */ 131 vka_object_t frame; 132 error = vka_alloc_frame(&procServ.vka, seL4_PageBits, &frame); 133 test_assert(error == ESUCCESS); 134 test_assert(frame.cptr != 0); 135 136 /* Try to map in some invalid spots. */ 137 tvprintf("trying mapping into invalid spots...\n"); 138 error = vs_map(&vs, 0x9A0, &frame.cptr, 1); 139 test_assert(error == EINVALIDWINDOW); 140 error = vs_map(&vs, window - 0x9A0, &frame.cptr, 1); 141 test_assert(error == EINVALIDWINDOW); 142 error = vs_map(&vs, window + windowSize + 0x1, &frame.cptr, 1); 143 test_assert(error == EINVALIDWINDOW); 144 error = vs_map(&vs, window + windowSize + 0x5123, &frame.cptr, 1); 145 test_assert(error == EINVALIDWINDOW); 146 147 /* Try to unmap from some invalid spots. */ 148 tvprintf("trying unmapping from invalid spots...\n"); 149 error = vs_unmap(&vs, window - 0x9A0, 1); 150 test_assert(error == EINVALIDWINDOW); 151 error = vs_unmap(&vs, window + windowSize + 0x423, 5); 152 test_assert(error == EINVALIDWINDOW); 153 error = vs_unmap(&vs, window, windowSize + 1); 154 test_assert(error == EINVALIDWINDOW); 155 156 /* Map the frame many times in all the valid spots. */ 157 for (vaddr_t waddr = window; waddr < window + windowSize; waddr += (1 << seL4_PageBits)) { 158 tvprintf("trying mapping into valid spot 0x%x...\n", (uint32_t) waddr); 159 /* Map the frame. */ 160 error = vs_map(&vs, waddr, &frame.cptr, 1); 161 test_assert(error == ESUCCESS); 162 /* Try to map frame here again. Should complain. */ 163 error = vs_map(&vs, waddr, &frame.cptr, 1); 164 test_assert(error == EUNMAPFIRST); 165 } 166 167 /* Unmap and remap the frame many times in all the valid spots. */ 168 for (vaddr_t waddr = window; waddr < window + windowSize; waddr += (1 << seL4_PageBits)) { 169 tvprintf("trying remapping into valid spot 0x%x...\n", (uint32_t) waddr); 170 /* Unmap the frame. */ 171 error = vs_unmap(&vs, waddr, 1); 172 test_assert(error == ESUCCESS); 173 /* Remap the frame. */ 174 error = vs_map(&vs, waddr, &frame.cptr, 1); 175 test_assert(error == ESUCCESS); 176 } 177 178 /* Clean up. Note that deleting the vspace should delete the created window. */ 179 tvprintf("cleaning up everything in vspace...\n"); 180 vs_unref(&vs); 181 test_assert(vs.magic != REFOS_VSPACE_MAGIC); 182 vka_free_object(&procServ.vka, &frame); 183 184 return test_success(); 185} 186 187#endif /* CONFIG_REFOS_RUN_TESTS */