1/* 2 * Copyright 2017, 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(DATA61_BSD) 11 */ 12 13#include <autoconf.h> 14 15#include <stdio.h> 16#include <stdlib.h> 17#include <assert.h> 18#include <inttypes.h> 19#include <string.h> 20 21#include <sel4/sel4.h> 22#include <sel4debug/debug.h> 23#include <simple-default/simple-default.h> 24 25#include <vspace/page.h> 26#include <vka/kobject_t.h> 27 28void *simple_default_get_frame_info(void *data, void *paddr, int size_bits, seL4_CPtr *frame_cap, seL4_Word *offset) 29{ 30 unsigned int i; 31 seL4_BootInfo *bi = (seL4_BootInfo *) data; 32 assert(bi && paddr && offset && frame_cap); 33 34 for (i = 0; i < bi->untyped.end - bi->untyped.start; i++) { 35 if (bi->untypedList[i].paddr <= (seL4_Word)paddr && 36 bi->untypedList[i].paddr + BIT(bi->untypedList[i].sizeBits) >= (seL4_Word)paddr + BIT(size_bits)) { 37 *frame_cap = bi->untyped.start + i; 38 *offset = (seL4_Word)paddr - bi->untypedList[i].paddr; 39 break; 40 } 41 } 42 return NULL; 43} 44seL4_Error simple_default_get_frame_cap(void *data, void *paddr, int size_bits, cspacepath_t *path) 45{ 46 unsigned int i; 47 seL4_BootInfo *bi = (seL4_BootInfo *) data; 48 assert(bi && paddr); 49 50 for (i = 0; i < bi->untyped.end - bi->untyped.start; i++) { 51 if (bi->untypedList[i].paddr == (seL4_Word)paddr && 52 bi->untypedList[i].sizeBits >= size_bits) { 53 return seL4_Untyped_Retype(bi->untyped.start + i, kobject_get_type(KOBJECT_FRAME, size_bits), 54 size_bits, path->root, path->dest, path->destDepth, path->offset, 1); 55 } 56 } 57 return seL4_FailedLookup; 58} 59 60void *simple_default_get_frame_mapping(void *data, void *paddr, int size_bits) 61{ 62 return NULL; 63} 64 65seL4_Error simple_default_set_ASID(void *data, seL4_CPtr vspace) 66{ 67 return seL4_ARCH_ASIDPool_Assign(seL4_CapInitThreadASIDPool, vspace); 68} 69 70int simple_default_cap_count(void *data) 71{ 72 assert(data); 73 74 seL4_BootInfo *bi = data; 75 76 return (bi->sharedFrames.end - bi->sharedFrames.start) 77 + (bi->userImageFrames.end - bi->userImageFrames.start) 78 + (bi->userImagePaging.end - bi->userImagePaging.start) 79 + (bi->untyped.end - bi->untyped.start) 80 + SIMPLE_NUM_INIT_CAPS; //Include all the init caps 81} 82 83seL4_CPtr simple_default_nth_cap(void *data, int n) 84{ 85 assert(data); 86 87 seL4_BootInfo *bi = data; 88 size_t shared_frame_range = bi->sharedFrames.end - bi->sharedFrames.start + SIMPLE_NUM_INIT_CAPS; 89 size_t user_img_frame_range = bi->userImageFrames.end - bi->userImageFrames.start + shared_frame_range; 90 size_t user_img_paging_range = bi->userImagePaging.end - bi->userImagePaging.start + user_img_frame_range; 91 size_t untyped_range = bi->untyped.end - bi->untyped.start + user_img_paging_range; 92 93 seL4_CPtr true_return = seL4_CapNull; 94 95 if (n < SIMPLE_NUM_INIT_CAPS) { 96 /* skip seL4_CapNull */ 97 true_return = (seL4_CPtr) n + 1; 98#if !(defined(CONFIG_ARCH_IA32) || defined(CONFIG_ARCH_X86_64)) 99 /* skip seL4_CapIOPortControl on non-x86 */ 100 if (true_return >= seL4_CapIOPortControl) { 101 true_return++; 102 } 103#endif 104#ifndef CONFIG_IOMMU 105 /* skip seL4_CapIOSpace if IOMMU isn't supported on x86 */ 106 if (true_return >= seL4_CapIOSpace) { 107 true_return++; 108 } 109#endif 110 } else if (n < shared_frame_range) { 111 return bi->sharedFrames.start + (n - SIMPLE_NUM_INIT_CAPS); 112 } else if (n < user_img_frame_range) { 113 return bi->userImageFrames.start + (n - shared_frame_range); 114 } else if (n < user_img_paging_range) { 115 return bi->userImagePaging.start + (n - user_img_frame_range); 116 } else if (n < untyped_range) { 117 return bi->untyped.start + (n - user_img_paging_range); 118 } 119 120 return true_return; 121} 122 123seL4_CPtr simple_default_init_cap(void *data, seL4_CPtr cap_pos) 124{ 125 return cap_pos; 126} 127 128uint8_t simple_default_cnode_size(void *data) 129{ 130 assert(data); 131 132 return ((seL4_BootInfo *)data)->initThreadCNodeSizeBits; 133} 134 135int simple_default_untyped_count(void *data) 136{ 137 assert(data); 138 139 return ((seL4_BootInfo *)data)->untyped.end - ((seL4_BootInfo *)data)->untyped.start; 140} 141 142seL4_CPtr simple_default_nth_untyped(void *data, int n, size_t *size_bits, uintptr_t *paddr, bool *device) 143{ 144 assert(data); 145 146 seL4_BootInfo *bi = data; 147 148 if (n < (bi->untyped.end - bi->untyped.start)) { 149 if (paddr != NULL) { 150 *paddr = bi->untypedList[n].paddr; 151 } 152 if (size_bits != NULL) { 153 *size_bits = bi->untypedList[n].sizeBits; 154 } 155 if (device != NULL) { 156 *device = (bool)bi->untypedList[n].isDevice; 157 } 158 return bi->untyped.start + (n); 159 } 160 161 return seL4_CapNull; 162} 163 164int simple_default_userimage_count(void *data) 165{ 166 assert(data); 167 168 return ((seL4_BootInfo *)data)->userImageFrames.end - ((seL4_BootInfo *)data)->userImageFrames.start; 169} 170 171seL4_CPtr simple_default_nth_userimage(void *data, int n) 172{ 173 assert(data); 174 175 seL4_BootInfo *bi = data; 176 177 if (n < (bi->userImageFrames.end - bi->userImageFrames.start)) { 178 return bi->userImageFrames.start + (n); 179 } 180 181 return seL4_CapNull; 182} 183 184int simple_default_core_count(void *data) 185{ 186 assert(data); 187 188 return ((seL4_BootInfo *)data)->numNodes; 189} 190 191void simple_default_print(void *data) 192{ 193 if (data == NULL) { 194 ZF_LOGE("Data is null!"); 195 } 196 197 debug_print_bootinfo(data); 198} 199 200seL4_CPtr simple_default_sched_control(void *data, int core) 201{ 202 assert(core < simple_default_core_count(data)); 203#if CONFIG_KERNEL_MCS 204 return ((seL4_BootInfo *) data)->schedcontrol.start + core; 205#else 206 ZF_LOGW("not implemented"); 207 return seL4_CapNull; 208#endif 209} 210 211ssize_t simple_default_get_extended_bootinfo_size(void *data, seL4_Word type) 212{ 213 if (data == NULL) { 214 ZF_LOGE("Data is null!"); 215 return -1; 216 } 217 seL4_BootInfo *bi = data; 218 219 /* start of the extended bootinfo is defined to be 4K from the start of regular bootinfo */ 220 uintptr_t cur = (uintptr_t)bi + PAGE_SIZE_4K; 221 uintptr_t end = cur + bi->extraLen; 222 while (cur < end) { 223 seL4_BootInfoHeader *header = (seL4_BootInfoHeader *)cur; 224 if (header->id == type) { 225 return header->len; 226 } 227 cur += header->len; 228 } 229 return -1; 230} 231 232ssize_t simple_default_get_extended_bootinfo(void *data, seL4_Word type, void *dest, ssize_t max_len) 233{ 234 assert(data); 235 seL4_BootInfo *bi = data; 236 237 if (max_len < 0) { 238 ZF_LOGE("Unexpected negative size"); 239 return -1; 240 } 241 /* start of the extended bootinfo is defined to be 4K from the start of regular bootinfo */ 242 uintptr_t cur = (uintptr_t)bi + PAGE_SIZE_4K; 243 uintptr_t end = cur + bi->extraLen; 244 while (cur < end) { 245 seL4_BootInfoHeader *header = (seL4_BootInfoHeader *)cur; 246 if (header->id == type) { 247 ssize_t copy_len = MIN(header->len, max_len); 248 memcpy(dest, (void *)cur, copy_len); 249 return copy_len; 250 } 251 cur += header->len; 252 } 253 return -1; 254} 255 256void simple_default_init_bootinfo(simple_t *simple, seL4_BootInfo *bi) 257{ 258 assert(simple); 259 assert(bi); 260 261 simple->data = bi; 262 simple->frame_info = &simple_default_get_frame_info; 263 simple->frame_cap = &simple_default_get_frame_cap; 264 simple->frame_mapping = &simple_default_get_frame_mapping; 265 simple->ASID_assign = &simple_default_set_ASID; 266 simple->cap_count = &simple_default_cap_count; 267 simple->nth_cap = &simple_default_nth_cap; 268 simple->init_cap = &simple_default_init_cap; 269 simple->cnode_size = &simple_default_cnode_size; 270 simple->untyped_count = &simple_default_untyped_count; 271 simple->nth_untyped = &simple_default_nth_untyped; 272 simple->userimage_count = &simple_default_userimage_count; 273 simple->core_count = &simple_default_core_count; 274 simple->nth_userimage = &simple_default_nth_userimage; 275 simple->print = &simple_default_print; 276 simple->sched_ctrl = &simple_default_sched_control; 277 simple->extended_bootinfo_len = &simple_default_get_extended_bootinfo_size; 278 simple->extended_bootinfo = &simple_default_get_extended_bootinfo; 279 simple_default_init_arch_simple(&simple->arch_simple, NULL); 280} 281