| /* |
| * 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 <stdio.h> |
| #include <stdlib.h> |
| #include <assert.h> |
| |
| #include <sel4/sel4.h> |
| #include <sel4debug/debug.h> |
| #include <simple-default/simple-default.h> |
| |
| #include <vspace/page.h> |
| |
| void *simple_default_get_frame_info(void *data, void *paddr, int size_bits, seL4_CPtr *frame_cap, seL4_Word *offset) { |
| assert(data && paddr && frame_cap); |
| |
| seL4_BootInfo *bi = (seL4_BootInfo *) data; |
| |
| int i; |
| seL4_DeviceRegion* region; |
| |
| *offset = 0; |
| *frame_cap = seL4_CapNull; |
| region = bi->deviceRegions; |
| for(i = 0; i < bi->numDeviceRegions; i++, region++){ |
| seL4_Word region_start = region->basePaddr; |
| seL4_Word n_caps = region->frames.end - region->frames.start; |
| seL4_Word region_end = region_start + (n_caps << region->frameSizeBits); |
| if(region_start <= (seL4_Word) paddr && |
| (seL4_Word) paddr < region_end && |
| region->frameSizeBits == size_bits) { |
| |
| *frame_cap = region->frames.start + (((seL4_Word) paddr - region->basePaddr) >> region->frameSizeBits); |
| i = bi->numDeviceRegions; |
| } |
| } |
| |
| return NULL; |
| } |
| seL4_Error simple_default_get_frame_cap(void *data, void *paddr, int size_bits, cspacepath_t *path) { |
| assert(data && paddr); |
| |
| seL4_CPtr frame_cap; |
| seL4_Word offset; |
| simple_default_get_frame_info(data,paddr, size_bits, &frame_cap, &offset); |
| if (frame_cap == seL4_CapNull) { |
| return seL4_FailedLookup; |
| } |
| return seL4_CNode_Copy(path->root, path->capPtr, path->capDepth, seL4_CapInitThreadCNode, frame_cap, 32, seL4_AllRights); |
| } |
| |
| seL4_CPtr simple_default_get_ut_cap(void *data, void *paddr, int size_bits) { |
| assert(data && paddr); |
| |
| seL4_CPtr frame_cap; |
| seL4_Word offset; |
| |
| simple_default_get_frame_info(data, paddr, size_bits, &frame_cap, &offset); |
| |
| return frame_cap; |
| } |
| |
| void *simple_default_get_frame_mapping(void *data, void *paddr, int size_bits) { |
| return NULL; |
| } |
| |
| seL4_Error simple_default_set_ASID(void *data, seL4_CPtr vspace) { |
| return seL4_ARCH_ASIDPool_Assign(seL4_CapInitThreadASIDPool, vspace); |
| } |
| |
| int simple_default_cap_count(void *data) { |
| assert(data); |
| |
| seL4_BootInfo * bi = (seL4_BootInfo *) data; |
| |
| int device_caps = 0; |
| int i; |
| for(i = 0; i < bi->numDeviceRegions; i++) { |
| device_caps += bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start; |
| } |
| |
| return (device_caps) |
| + (bi->sharedFrames.end - bi->sharedFrames.start) |
| + (bi->userImageFrames.end - bi->userImageFrames.start) |
| + (bi->userImagePaging.end - bi->userImagePaging.start) |
| + (bi->untyped.end - bi->untyped.start) |
| + seL4_NumInitialCaps; //Include all the init caps |
| } |
| |
| seL4_CPtr simple_default_nth_cap(void *data, int n) { |
| assert(data); |
| |
| seL4_BootInfo * bi = (seL4_BootInfo *) data; |
| size_t shared_frame_range = bi->sharedFrames.end - bi->sharedFrames.start + seL4_NumInitialCaps; |
| size_t user_img_frame_range = bi->userImageFrames.end - bi->userImageFrames.start + shared_frame_range; |
| size_t user_img_paging_range = bi->userImagePaging.end - bi->userImagePaging.start + user_img_frame_range; |
| size_t untyped_range = bi->untyped.end - bi->untyped.start + user_img_paging_range; |
| |
| int i; |
| int device_caps = 0; |
| seL4_CPtr true_return = seL4_CapNull; |
| |
| for(i = 0; i < bi->numDeviceRegions; i++) { |
| device_caps += bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start; |
| } |
| |
| size_t device_range = device_caps + untyped_range; |
| |
| if (n < seL4_CapInitThreadASIDPool) { |
| true_return = (seL4_CPtr) n+1; |
| } else if (n < seL4_NumInitialCaps) { |
| true_return = (seL4_CPtr) n+1; |
| #if defined(CONFIG_ARCH_ARM) |
| true_return++; |
| #endif |
| #ifndef CONFIG_IOMMU |
| if(true_return >= seL4_CapIOSpace) { |
| true_return++; |
| } |
| #endif |
| } else if (n < shared_frame_range) { |
| return bi->sharedFrames.start + (n - seL4_NumInitialCaps); |
| } else if (n < user_img_frame_range) { |
| return bi->userImageFrames.start + (n - shared_frame_range); |
| } else if (n < user_img_paging_range) { |
| return bi->userImagePaging.start + (n - user_img_frame_range); |
| } else if (n < untyped_range) { |
| return bi->untyped.start + (n - user_img_paging_range); |
| } else if (n < device_range) { |
| i = 0; |
| int current_count = 0; |
| while((bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start) + |
| current_count < (n - untyped_range)) { |
| current_count += bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start; |
| i++; |
| } |
| return bi->deviceRegions[i].frames.start + (n - untyped_range - current_count); |
| } |
| |
| return true_return; |
| } |
| |
| seL4_CPtr simple_default_init_cap(void *data, seL4_CPtr cap_pos) { |
| return (seL4_CPtr) cap_pos; |
| } |
| |
| uint8_t simple_default_cnode_size(void *data) { |
| assert(data); |
| |
| return ((seL4_BootInfo *)data)->initThreadCNodeSizeBits; |
| } |
| |
| int simple_default_untyped_count(void *data) { |
| assert(data); |
| |
| return ((seL4_BootInfo *)data)->untyped.end - ((seL4_BootInfo *)data)->untyped.start; |
| } |
| |
| seL4_CPtr simple_default_nth_untyped(void *data, int n, uint32_t *size_bits, uint32_t *paddr) { |
| assert(data && size_bits && paddr); |
| |
| seL4_BootInfo *bi = (seL4_BootInfo *)data; |
| |
| if(n < (bi->untyped.end - bi->untyped.start)) { |
| if(paddr != NULL) { |
| *paddr = bi->untypedPaddrList[n]; |
| } |
| if(size_bits != NULL) { |
| *size_bits = bi->untypedSizeBitsList[n]; |
| } |
| return bi->untyped.start + (n); |
| } |
| |
| return seL4_CapNull; |
| } |
| |
| int simple_default_userimage_count(void *data) { |
| assert(data); |
| |
| return ((seL4_BootInfo *)data)->userImageFrames.end - ((seL4_BootInfo *)data)->userImageFrames.start; |
| } |
| |
| seL4_CPtr simple_default_nth_userimage(void *data, int n) { |
| assert(data); |
| |
| seL4_BootInfo *bi = (seL4_BootInfo *)data; |
| |
| if(n < (bi->userImageFrames.end - bi->userImageFrames.start)) { |
| return bi->userImageFrames.start + (n); |
| } |
| |
| return seL4_CapNull; |
| } |
| |
| void simple_default_print(void *data) { |
| if (data == NULL) { |
| ZF_LOGE("Data is null!"); |
| } |
| |
| debug_print_bootinfo((seL4_BootInfo *) data); |
| } |
| |
| void simple_default_init_bootinfo(simple_t *simple, seL4_BootInfo *bi) { |
| assert(simple); |
| assert(bi); |
| |
| simple->data = bi; |
| simple->frame_info = &simple_default_get_frame_info; |
| simple->frame_cap = &simple_default_get_frame_cap; |
| simple->frame_mapping = &simple_default_get_frame_mapping; |
| simple->ASID_assign = &simple_default_set_ASID; |
| simple->cap_count = &simple_default_cap_count; |
| simple->nth_cap = &simple_default_nth_cap; |
| simple->init_cap = &simple_default_init_cap; |
| simple->cnode_size = &simple_default_cnode_size; |
| simple->untyped_count = &simple_default_untyped_count; |
| simple->nth_untyped = &simple_default_nth_untyped; |
| simple->userimage_count = &simple_default_userimage_count; |
| simple->nth_userimage = &simple_default_nth_userimage; |
| simple->print = &simple_default_print; |
| simple_default_init_arch_simple(&simple->arch_simple, NULL); |
| } |
| |