| /* |
| * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) |
| * |
| * SPDX-License-Identifier: BSD-2-Clause |
| */ |
| |
| #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 |
| }; |
| } |
| |