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#pragma once
14
15#include <autoconf.h>
16#include <sel4/types.h>
17#include <allocman/utspace/utspace.h>
18#include <vka/cspacepath_t.h>
19#include <assert.h>
20
21/* This is an untyped manager that works by splitting each untyped in half to
22 * create smaller untypeds. */
23
24struct utspace_split_node {
25    cspacepath_t ut;
26    /* if this is a child node, represents our parent. Our parent must by
27     * definition be considered allocated */
28    struct utspace_split_node *parent;
29    /* if we have a parent, then this is a pointer to our other sibling */
30    struct utspace_split_node *sibling;
31    /* which (if any) free list this is in */
32    struct utspace_split_node **head;
33    /* which free list this should go back into */
34    struct utspace_split_node **origin_head;
35    /* physical address of the node */
36    uintptr_t paddr;
37    /* if this node is not allocated then these are the next/previous pointers in the free list */
38    struct utspace_split_node *next, *prev;
39};
40
41typedef struct utspace_split {
42    /* untypeds from the kernel window. Used for anything */
43    struct utspace_split_node *heads[CONFIG_WORD_SIZE];
44    /* untypeds that are unknown device regions */
45    struct utspace_split_node *dev_heads[CONFIG_WORD_SIZE];
46    /* untypeds that are known to be RAM from the device region */
47    struct utspace_split_node *dev_mem_heads[CONFIG_WORD_SIZE];
48} utspace_split_t;
49
50void utspace_split_create(utspace_split_t *split);
51int _utspace_split_add_uts(struct allocman *alloc, void *_split, size_t num, const cspacepath_t *uts, size_t *size_bits, uintptr_t *paddr, int utType);
52
53seL4_Word _utspace_split_alloc(struct allocman *alloc, void *_split, size_t size_bits, seL4_Word type, const cspacepath_t *slot, uintptr_t paddr, bool canBeDev, int *error);
54void _utspace_split_free(struct allocman *alloc, void *_split, seL4_Word cookie, size_t size_bits);
55
56uintptr_t _utspace_split_paddr(void *_split, seL4_Word cookie, size_t size_bits);
57
58static inline struct utspace_interface utspace_split_make_interface(utspace_split_t *split) {
59    return (struct utspace_interface) {
60        .alloc = _utspace_split_alloc,
61        .free = _utspace_split_free,
62        .add_uts = _utspace_split_add_uts,
63        .paddr = _utspace_split_paddr,
64        .properties = ALLOCMAN_DEFAULT_PROPERTIES,
65        .utspace = split
66    };
67}
68
69