| /* | |
| * Copyright 2017, Data61 | |
| * Commonwealth Scientific and Industrial Research Organisation (CSIRO) | |
| * ABN 41 687 119 230. | |
| * | |
| * 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(DATA61_BSD) | |
| */ | |
| #pragma once | |
| #include <autoconf.h> | |
| #include <sel4/types.h> | |
| #include <allocman/utspace/utspace.h> | |
| #include <vka/cspacepath_t.h> | |
| #include <vka/vka.h> | |
| #include <vka/kobject_t.h> | |
| #include <assert.h> | |
| /* This is an untyped manager that just proxies calls to a VKA interface. | |
| * We also need to do some extra book keeping work */ | |
| typedef struct utspace_vka_cookie { | |
| seL4_Word original_cookie; | |
| seL4_Word type; | |
| } utspace_vka_cookie_t; | |
| static inline seL4_Word _utspace_vka_alloc(struct allocman *alloc, void *_vka, size_t size_bits, seL4_Word type, const cspacepath_t *slot, uintptr_t paddr, bool canBeDevice, int *error) | |
| { | |
| vka_t *vka = (vka_t *)_vka; | |
| size_t sel4_size_bits = get_sel4_object_size(type, size_bits); | |
| utspace_vka_cookie_t *cookie = (utspace_vka_cookie_t*)malloc(sizeof(*cookie)); | |
| if (!cookie) { | |
| SET_ERROR(error, 1); | |
| return 0; | |
| } | |
| int _error; | |
| if (paddr == ALLOCMAN_NO_PADDR) { | |
| _error = vka_utspace_alloc(vka, slot, type, sel4_size_bits, &cookie->original_cookie); | |
| } else { | |
| _error = vka_utspace_alloc_at(vka, slot, type, sel4_size_bits, paddr, &cookie->original_cookie); | |
| } | |
| SET_ERROR(error, _error); | |
| if (!_error) { | |
| cookie->type = type; | |
| } else { | |
| free(cookie); | |
| cookie = NULL; | |
| } | |
| return (seL4_Word)cookie; | |
| } | |
| static inline void _utspace_vka_free(struct allocman *alloc, void *_vka, seL4_Word _cookie, size_t size_bits) | |
| { | |
| vka_t *vka = (vka_t *)_vka; | |
| utspace_vka_cookie_t *cookie = (utspace_vka_cookie_t*)_cookie; | |
| vka_utspace_free(vka, cookie->original_cookie, cookie->type, get_sel4_object_size(cookie->type, size_bits)); | |
| } | |
| static inline uintptr_t _utspace_vka_paddr(void *_vka, seL4_Word _cookie, size_t size_bits) | |
| { | |
| vka_t *vka = (vka_t *)_vka; | |
| utspace_vka_cookie_t *cookie = (utspace_vka_cookie_t*)_cookie; | |
| return vka_utspace_paddr(vka, cookie->original_cookie, cookie->type, get_sel4_object_size(cookie->type, size_bits)); | |
| } | |
| static inline int _utspace_vka_add_uts(struct allocman *alloc, void *_trickle, size_t num, const cspacepath_t *uts, size_t *size_bits, uintptr_t *paddr, int utType) | |
| { | |
| assert(!"VKA interface does not support adding untypeds after creation"); | |
| return -1; | |
| } | |
| /** | |
| * Make a utspace interface from a VKA. It is the responsibility of the caller to ensure | |
| * that this pointer remains valid for as long as this cspace is used | |
| * | |
| * @param vka Allocator to proxy cspace calls to | |
| * @return utspace_interface that can be given to allocman | |
| */ | |
| static inline struct utspace_interface utspace_vka_make_interface(vka_t *vka) { | |
| return (struct utspace_interface) { | |
| .alloc = _utspace_vka_alloc, | |
| .free = _utspace_vka_free, | |
| .add_uts = _utspace_vka_add_uts, | |
| .paddr = _utspace_vka_paddr, | |
| .properties = ALLOCMAN_DEFAULT_PROPERTIES, | |
| .utspace = vka | |
| }; | |
| } | |