| /* |
| * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) |
| * |
| * SPDX-License-Identifier: BSD-2-Clause |
| */ |
| |
| #pragma once |
| |
| #include <autoconf.h> |
| #include <stdlib.h> |
| #include <sel4/types.h> |
| #include <allocman/cspace/cspace.h> |
| |
| /* This is a very simple cspace allocator that monotinically allocates cptrs |
| in a range, free is not possible. */ |
| struct cspace_simple1level_config { |
| /* A cptr to the cnode that we are managing slots in */ |
| seL4_CPtr cnode; |
| /* Size in bits of the cnode */ |
| size_t cnode_size_bits; |
| /* Guard depth added to this cspace. */ |
| size_t cnode_guard_bits; |
| /* First valid slot (as an index) */ |
| size_t first_slot; |
| /* Last valid slot + 1 (as an index) */ |
| size_t end_slot; |
| }; |
| |
| typedef struct cspace_simple1level { |
| struct cspace_simple1level_config config; |
| size_t current_slot; |
| } cspace_simple1level_t; |
| |
| static inline cspacepath_t _cspace_simple1level_make_path(void *_cspace, seL4_CPtr slot) |
| { |
| cspace_simple1level_t *cspace = (cspace_simple1level_t*)_cspace; |
| return (cspacepath_t) { |
| .root = cspace->config.cnode, |
| .capPtr = slot, |
| .offset = slot, |
| .capDepth = cspace->config.cnode_size_bits + cspace->config.cnode_guard_bits, |
| .dest = 0, |
| .destDepth = 0, |
| .window = 1 |
| }; |
| } |
| |
| /* Construction of this cspace is simplified by the fact it has a completely |
| constant memory pool and is defined here. */ |
| void cspace_simple1level_create(cspace_simple1level_t *cspace, struct cspace_simple1level_config config); |
| |
| /* These functions are defined here largely so the interface definition can be |
| made static, instead of returning it from a function. Also so that we can |
| do away with this struct if using statically chosen allocators. cspaces are |
| declared as void* to make type siginatures match up. I know it's ugly, but |
| not my fault that this is the pattern for doing ADTs in C */ |
| int _cspace_simple1level_alloc(struct allocman *alloc, void *_cspace, cspacepath_t *slot); |
| void _cspace_simple1level_free(struct allocman *alloc, void *_cspace, const cspacepath_t *slot); |
| |
| static inline struct cspace_interface cspace_simple1level_make_interface(cspace_simple1level_t *cspace) { |
| return (struct cspace_interface){ |
| .alloc = _cspace_simple1level_alloc, |
| .free = _cspace_simple1level_free, |
| .make_path = _cspace_simple1level_make_path, |
| /* We could give arbitrary recursion properties here. Since we perform no |
| other allocations we never even have the potential to recurse */ |
| .properties = ALLOCMAN_DEFAULT_PROPERTIES, |
| .cspace = cspace |
| }; |
| } |
| |