/*
 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <autoconf.h>
#include <capdl_loader_app/gen_config.h>

#include <assert.h>
#include <inttypes.h>
#include <limits.h>

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sel4platsupport/platsupport.h>
#include <cpio/cpio.h>
#include <simple-default/simple-default.h>

#include <vka/kobject_t.h>
#include <utils/util.h>
#include <sel4/sel4.h>
#include <sel4utils/sel4_zf_logif.h>
#include "capdl.h"

#ifdef CONFIG_DEBUG_BUILD
#include <utils/attribute.h>
#include <muslcsys/vsyscall.h>
#endif

#include "capdl_spec.h"

#ifdef CONFIG_ARCH_ARM
#include <capdl_loader_app/platform_info.h>
#endif

#ifdef CONFIG_ARCH_RISCV
#define seL4_PageDirIndexBits seL4_PageTableIndexBits
#define PT_LEVEL_SLOT(vaddr, level) (((vaddr) >> ((seL4_PageTableIndexBits * (level-1)) + seL4_PageBits)) & MASK(seL4_PageTableIndexBits))
#endif

#define PML4_SLOT(vaddr) ((vaddr >> (seL4_PDPTIndexBits + seL4_PageDirIndexBits + seL4_PageTableIndexBits + seL4_PageBits)) & MASK(seL4_PML4IndexBits))
#define PDPT_SLOT(vaddr) ((vaddr >> (seL4_PageDirIndexBits + seL4_PageTableIndexBits + seL4_PageBits)) & MASK(seL4_PDPTIndexBits))
#define PD_SLOT(vaddr)   ((vaddr >> (seL4_PageTableIndexBits + seL4_PageBits)) & MASK(seL4_PageDirIndexBits))
#define PT_SLOT(vaddr)   ((vaddr >> seL4_PageBits) & MASK(seL4_PageTableIndexBits))
#define PGD_SLOT(vaddr) ((vaddr >> (seL4_PUDIndexBits + seL4_PageDirIndexBits + seL4_PageTableIndexBits + seL4_PageBits)) & MASK(seL4_PGDIndexBits))
#define PUD_SLOT(vaddr) ((vaddr >> (seL4_PageDirIndexBits + seL4_PageTableIndexBits + seL4_PageBits)) & MASK(seL4_PUDIndexBits))

#define CAPDL_SHARED_FRAMES

#define STACK_ALIGNMENT_BYTES 16

#define MAX_STREAM_IDS 60

static seL4_CPtr capdl_to_sel4_orig[CONFIG_CAPDL_LOADER_MAX_OBJECTS];
static seL4_CPtr capdl_to_sel4_copy[CONFIG_CAPDL_LOADER_MAX_OBJECTS];
static seL4_CPtr capdl_to_sel4_irq[CONFIG_CAPDL_LOADER_MAX_OBJECTS];
static seL4_CPtr capdl_to_sched_ctrl[CONFIG_MAX_NUM_NODES];
/* For static allocation, this maps from untyped derivation index to cslot.
 * Otherwise, this stores the result of sort_untypeds. */
static seL4_CPtr untyped_cptrs[CONFIG_MAX_NUM_BOOTINFO_UNTYPED_CAPS];

static seL4_CPtr free_slot_start, free_slot_end;

static seL4_CPtr first_arm_iospace;

// Hack for seL4_TCB_WriteRegisters because we can't take the address of local variables.
static seL4_UserContext global_user_context;

extern char _capdl_archive[];
extern char _capdl_archive_end[];

/* This symbol is provided by the GNU linker and points at the start/end of our
 * ELF image.
 */
extern char __executable_start[];
extern char _end[];

/* A region at which to map destination frames during loading
 * This is expected to be initialised by 'init_copy_addr' on system init */
uintptr_t copy_addr;

uint32_t sid_number = 0;
/* In the case where we just want a 4K page and we cannot allocate
 * a page table ourselves, we use this pre allocated region that
 * is guaranteed to have a pagetable */
/* Make this slot large enough for 64KiB frames which is the largest
 * last-level page size across all architectures that we support. */
static char copy_addr_with_pt[PAGE_SIZE_4K * 16] __attribute__((aligned(PAGE_SIZE_4K * 16)));

static seL4_BootInfoHeader *extended_bootinfo_table[SEL4_BOOTINFO_HEADER_NUM] = {0};

/* helper functions ---------------------------------------------------------------------------- */

static seL4_CPtr get_free_slot(void)
{
    return free_slot_start;
}

static void next_free_slot(void)
{
    free_slot_start++;
    ZF_LOGF_IF(free_slot_start >= free_slot_end, "Ran out of free slots!");
}

typedef enum {MOVE, COPY} init_cnode_mode;
typedef enum {ORIG, DUP, IRQ, SCHED_CTRL} seL4_cap_type;

static seL4_CPtr orig_caps(CDL_ObjID object_id)
{
    assert(object_id < CONFIG_CAPDL_LOADER_MAX_OBJECTS);
    return capdl_to_sel4_orig[object_id];
}

static seL4_CPtr dup_caps(CDL_ObjID object_id)
{
    assert(object_id < CONFIG_CAPDL_LOADER_MAX_OBJECTS);
    return capdl_to_sel4_copy[object_id];
}

static seL4_CPtr irq_caps(CDL_IRQ irq)
{
    assert(irq < CONFIG_CAPDL_LOADER_MAX_OBJECTS);
    return capdl_to_sel4_irq[irq];
}

static seL4_CPtr sched_ctrl_caps(CDL_Core id)
{
    assert(id < CONFIG_MAX_NUM_NODES);
    return capdl_to_sched_ctrl[id];
}

static void add_sel4_cap(CDL_ObjID object_id, seL4_cap_type type, seL4_CPtr slot)
{
    if (type == ORIG) {
        capdl_to_sel4_orig[object_id] = slot;
    } else if (type == DUP) {
        capdl_to_sel4_copy[object_id] = slot;
    } else if (type == IRQ) {
        capdl_to_sel4_irq[object_id] = slot;
    } else if (type == SCHED_CTRL) {
        capdl_to_sched_ctrl[object_id] = slot;
    }
}

static CDL_Object
*get_spec_object(CDL_Model *spec, CDL_ObjID object_id)
{
    return &spec->objects[object_id];
}

static seL4_Word get_capData(CDL_CapData d)
{
    switch (d.tag) {
    case CDL_CapData_Badge:
        return d.badge;
    case CDL_CapData_Guard:
        return seL4_CNode_CapData_new(d.guard_bits, d.guard_size).words[0];
    case CDL_CapData_Raw:
        return d.data;
    default:
        ZF_LOGF("invalid cap data");
        return seL4_NilData;
    }
}

static CDL_Cap *get_cap_at(CDL_Object *obj, unsigned int slot)
{
    for (unsigned int i = 0; i < CDL_Obj_NumSlots(obj); i++) {
        CDL_CapSlot *s = CDL_Obj_GetSlot(obj, i);
        if (CDL_CapSlot_Slot(s) == slot) {
            return CDL_CapSlot_Cap(s);
        }
    }

    /* Not found. */
    return NULL;
}

#ifdef CONFIG_ARCH_X86_64
static CDL_Cap *get_cdl_frame_pdpt(CDL_ObjID root, uintptr_t vaddr, CDL_Model *spec)
{
    CDL_Object *cdl_pml4 = get_spec_object(spec, root);
    CDL_Cap *pdpt_cap = get_cap_at(cdl_pml4, PML4_SLOT(vaddr));
    if (pdpt_cap == NULL) {
        ZF_LOGF("Could not find PD cap %s[%d]", CDL_Obj_Name(cdl_pml4), (int)PML4_SLOT(vaddr));
    }
    return pdpt_cap;
}

static CDL_Cap *get_cdl_frame_pd(CDL_ObjID root, uintptr_t vaddr, CDL_Model *spec)
{
    CDL_Cap *pdpt_cap = get_cdl_frame_pdpt(root, vaddr, spec);
    CDL_Object *cdl_pdpt = get_spec_object(spec, CDL_Cap_ObjID(pdpt_cap));
    CDL_Cap *pd_cap = get_cap_at(cdl_pdpt, PDPT_SLOT(vaddr));
    if (pd_cap == NULL) {
        ZF_LOGF("Could not find PD cap %s[%d]", CDL_Obj_Name(cdl_pdpt), (int)PDPT_SLOT(vaddr));
    }
    return pd_cap;
}
#endif

#ifdef CONFIG_ARCH_AARCH64
static CDL_Cap *get_cdl_frame_pud(CDL_ObjID root, uintptr_t vaddr, CDL_Model *spec)
{
    CDL_Object *cdl_pgd = get_spec_object(spec, root);
    CDL_Cap *pud_cap = get_cap_at(cdl_pgd, PGD_SLOT(vaddr));
    if (pud_cap == NULL) {
        ZF_LOGF("Could not find PUD cap %s[%d]", CDL_Obj_Name(cdl_pgd), (int)PGD_SLOT(vaddr));
    }
    return pud_cap;
}

static CDL_Cap *get_cdl_frame_pd(CDL_ObjID root, uintptr_t vaddr, CDL_Model *spec)
{
#if CDL_PT_NUM_LEVELS == 3
    CDL_Object *cdl_pud = get_spec_object(spec, root);
#else
    CDL_Cap *pud_cap = get_cdl_frame_pud(root, vaddr, spec);
    CDL_Object *cdl_pud = get_spec_object(spec, CDL_Cap_ObjID(pud_cap));
#endif
    CDL_Cap *pd_cap = get_cap_at(cdl_pud, PUD_SLOT(vaddr));
    if (pd_cap == NULL) {
        ZF_LOGF("Could not find PD cap %s[%d]", CDL_Obj_Name(cdl_pud), (int)PUD_SLOT(vaddr));
    }
    return pd_cap;
}
#endif

#ifndef CONFIG_ARCH_RISCV
static CDL_Cap *get_cdl_frame_pt(CDL_ObjID pd, uintptr_t vaddr, CDL_Model *spec)
{
#if defined(CONFIG_ARCH_X86_64) || defined(CONFIG_ARCH_AARCH64)
    CDL_Cap *pd_cap = get_cdl_frame_pd(pd, vaddr, spec);
    CDL_Object *cdl_pd = get_spec_object(spec, CDL_Cap_ObjID(pd_cap));
#else
    CDL_Object *cdl_pd = get_spec_object(spec, pd);
#endif
    CDL_Cap *pt_cap = get_cap_at(cdl_pd, PD_SLOT(vaddr));
    if (pt_cap == NULL) {
        ZF_LOGF("Could not find PT cap %s[%d]", CDL_Obj_Name(cdl_pd), (int)PD_SLOT(vaddr));
    }
    return pt_cap;
}

#else /* CONFIG_ARCH_RISCV */

/**
 * Do a recursive traversal from the top to bottom of a page table structure to
 * get the cap for a particular page table object for a certain vaddr at a certain
 * level. The level variable treats level==CONFIG_PT_LEVELS as the root page table
 * object, and level 0 as the bottom level 4k frames.
 */
static CDL_Cap *get_cdl_frame_pt_recurse(CDL_ObjID root, uintptr_t vaddr, CDL_Model *spec, int level)
{
    CDL_Object *cdl_pt = NULL;
    if (level < CONFIG_PT_LEVELS) {
        CDL_Cap *pt_cap = get_cdl_frame_pt_recurse(root, vaddr, spec, level + 1);
        cdl_pt = get_spec_object(spec, CDL_Cap_ObjID(pt_cap));
    } else {
        cdl_pt = get_spec_object(spec, root);
    }
    CDL_Cap *pt_cap_ret = get_cap_at(cdl_pt, PT_LEVEL_SLOT(vaddr, level));
    if (pt_cap_ret == NULL) {
        ZF_LOGF("Could not find PD cap %s[%d]", CDL_Obj_Name(cdl_pt), (int)PT_LEVEL_SLOT(vaddr, level));
    }
    return pt_cap_ret;
}

static CDL_Cap *get_cdl_frame_pt(CDL_ObjID pd, uintptr_t vaddr, CDL_Model *spec)
{
    return get_cdl_frame_pt_recurse(pd, vaddr, spec, 2);
}

#endif

static CDL_Cap *get_cdl_frame_cap(CDL_ObjID pd, uintptr_t vaddr, CDL_Model *spec)
{
    CDL_Cap *pt_cap = get_cdl_frame_pt(pd, vaddr, spec);

    /* Check if the PT cap is actually a large frame cap. */
    if (pt_cap->type == CDL_FrameCap) {
        return pt_cap;
    }

    CDL_Object *cdl_pt = get_spec_object(spec, CDL_Cap_ObjID(pt_cap));
    CDL_Cap *frame_cap = get_cap_at(cdl_pt, PT_SLOT(vaddr));
    if (frame_cap == NULL) {
        ZF_LOGF("Could not find frame cap %s[%d]", CDL_Obj_Name(cdl_pt), (int)PT_SLOT(vaddr));
    }

    return frame_cap;
}

/* elf file loading hack - prefill objects with the data defined in the elf file */
static seL4_CPtr get_frame_cap(CDL_ObjID pd, uintptr_t vaddr, CDL_Model *spec)
{
    return orig_caps(CDL_Cap_ObjID(get_cdl_frame_cap(pd, vaddr, spec)));
}

void init_copy_frame(seL4_BootInfo *bootinfo)
{
    /* An original frame will be mapped, backing copy_addr_with_pt. For
     * correctness we should unmap this before mapping into this
     * address. We locate the frame cap by looking in boot info
     * and knowing that the userImageFrames are ordered by virtual
     * address in our address space. The flush is probably not
     * required, but doesn't hurt to be cautious.
     */

    /* Find the number of frames in the user image according to
     * bootinfo, and compare that to the number of frames backing
     * the image computed by comparing start and end symbols. If
     * these numbers are different, assume the image was padded
     * to the left. */
    unsigned int num_user_image_frames_reported =
        bootinfo->userImageFrames.end - bootinfo->userImageFrames.start;
    unsigned int num_user_image_frames_measured =
        (ROUND_UP((uintptr_t)&_end, PAGE_SIZE_4K) -
         (uintptr_t)&__executable_start) / PAGE_SIZE_4K;

    if (num_user_image_frames_reported < num_user_image_frames_measured) {
        ZF_LOGE("Too few frames caps in bootinfo to back user image");
        return;
    }

    size_t additional_user_image_bytes =
        (num_user_image_frames_reported - num_user_image_frames_measured) * PAGE_SIZE_4K;

    if (additional_user_image_bytes > (uintptr_t)&__executable_start) {
        ZF_LOGE("User image padding too high to fit before start symbol");
        return;
    }

    uintptr_t lowest_mapped_vaddr =
        (uintptr_t)&__executable_start - additional_user_image_bytes;

    seL4_CPtr copy_addr_frame = bootinfo->userImageFrames.start +
                                ((uintptr_t)copy_addr_with_pt) / PAGE_SIZE_4K -
                                lowest_mapped_vaddr / PAGE_SIZE_4K;
    /* We currently will assume that we are on a 32-bit platform
     * that has a single PD, followed by all the PTs. So to find
     * our PT in the paging objects list we just need to add 1
     * to skip the PD */
    seL4_CPtr copy_addr_pt = bootinfo->userImagePaging.start + 1 +
                             PD_SLOT(((uintptr_t)copy_addr)) - PD_SLOT(((uintptr_t)&__executable_start));
#if defined(CONFIG_ARCH_X86_64) || defined(CONFIG_ARCH_AARCH64)
    /* guess that there is one PDPT and PML4 on x86_64 or one PGD and PUD on aarch64 */
    copy_addr_pt += 2;
#endif
#ifdef CONFIG_ARCH_RISCV
    /* The base case assumes that there is 2 levels paging structure and already skips
     * the top level and level after that.  We then also need to skip the remaining levels */
    copy_addr_pt += CONFIG_PT_LEVELS - 2;
#endif
    int error;

    for (int i = 0; i < sizeof(copy_addr_with_pt) / PAGE_SIZE_4K; i++) {
        error = seL4_ARCH_Page_Unmap(copy_addr_frame + i);
        ZF_LOGF_IFERR(error, "");
    }
}

#if !CONFIG_CAPDL_LOADER_STATIC_ALLOC
/* Sort the untyped objects from largest to smallest.
 * This ensures that fragmentation is eliminated if the objects
 * themselves are also sorted, largest to smallest.
 *
 * Sorting done using counting sort.
 */
static unsigned int sort_untypeds(seL4_BootInfo *bootinfo)
{
    seL4_CPtr untyped_start = bootinfo->untyped.start;
    seL4_CPtr untyped_end = bootinfo->untyped.end;

    ZF_LOGD("Sorting untypeds...");

    seL4_Word count[CONFIG_WORD_SIZE] = {0};

    // Count how many untypeds there are of each size.
    for (seL4_Word untyped_index = 0; untyped_index != untyped_end - untyped_start; untyped_index++) {
        if (!bootinfo->untypedList[untyped_index].isDevice) {
            count[bootinfo->untypedList[untyped_index].sizeBits] += 1;
        }
    }

    // Calculate the starting index for each untyped.
    seL4_Word total = 0;
    for (seL4_Word size = CONFIG_WORD_SIZE - 1; size != 0; size--) {
        seL4_Word oldCount = count[size];
        count[size] = total;
        total += oldCount;
    }

    unsigned int num_normal_untypes = 0;

    // Store untypeds in untyped_cptrs array.
    for (seL4_Word untyped_index = 0; untyped_index != untyped_end - untyped_start; untyped_index++) {
        if (bootinfo->untypedList[untyped_index].isDevice) {
            ZF_LOGD("Untyped %3d (cptr=%p) (addr=%p) is of size %2d. Skipping as it is device",
                    untyped_index, (void *)(untyped_start + untyped_index),
                    (void *)bootinfo->untypedList[untyped_index].paddr,
                    bootinfo->untypedList[untyped_index].sizeBits);
        } else {
            ZF_LOGD("Untyped %3d (cptr=%p) (addr=%p) is of size %2d. Placing in slot %d...",
                    untyped_index, (void *)(untyped_start + untyped_index),
                    (void *)bootinfo->untypedList[untyped_index].paddr,
                    bootinfo->untypedList[untyped_index].sizeBits,
                    count[bootinfo->untypedList[untyped_index].sizeBits]);

            untyped_cptrs[count[bootinfo->untypedList[untyped_index].sizeBits]] = untyped_start +  untyped_index;
            count[bootinfo->untypedList[untyped_index].sizeBits] += 1;
            num_normal_untypes++;
        }
    }

    return num_normal_untypes;
}
#endif /* !CONFIG_CAPDL_LOADER_STATIC_ALLOC */

static void parse_bootinfo(seL4_BootInfo *bootinfo, CDL_Model *spec)
{
    ZF_LOGD("Parsing bootinfo...");

    free_slot_start = bootinfo->empty.start;
    free_slot_end = bootinfo->empty.end;

    /* When using libsel4platsupport for printing support, we end up using some
     * of our free slots during serial port initialisation. Skip over these to
     * avoid failing our own allocations. Note, this value is just hardcoded
     * for the amount of slots this initialisation currently uses up.
     * JIRA: CAMKES-204.
     */
    free_slot_start += 16;

    ZF_LOGD("  %ld free cap slots, from %ld to %ld",
            (long)(free_slot_end - free_slot_start),
            (long)free_slot_start,
            (long)free_slot_end);

    /* We need to be able to actual store caps to the maximum number of objects
     * we may be dealing with.
     * This check can still pass and initialisation fail as we need extra slots
     * for duplicates for CNodes and TCBs.
     */
    assert(free_slot_end - free_slot_start >= CONFIG_CAPDL_LOADER_MAX_OBJECTS);


#if CONFIG_CAPDL_LOADER_STATIC_ALLOC
    /*
     * Make sure the untypeds in the model correspond to what we got
     * from bootinfo.
     */
    int bi_start = 0;
    for (int u = 0; u < spec->num_untyped; u++) {
        bool found = false;
        int num_untyped = bootinfo->untyped.end - bootinfo->untyped.start;
        CDL_Object *ut = &spec->objects[spec->untyped[u].untyped];
        assert(CDL_Obj_Type(ut) == CDL_Untyped);

        for (int i = bi_start; i < num_untyped; i++) {
            seL4_Word ut_paddr = bootinfo->untypedList[i].paddr;
            if (bootinfo->untypedList[i].paddr == ut->paddr) {
                seL4_Uint8 ut_size = bootinfo->untypedList[i].sizeBits;
                ZF_LOGF_IF(ut_size != ut->size_bits,
                           "Ut at %p in incorrect size, expected %u got %u",
                           ut->paddr, ut->size_bits, ut_size);
                untyped_cptrs[u] = bootinfo->untyped.start + i;
                found = true;
                if (i == bi_start) {
                    bi_start++;
                }
            }
        }
        ZF_LOGF_IF(!found, "Failed to find ut for %p", ut->paddr);
    }
#else
    /* Probably an inconsistency in the build configuration, so fail now. */
    ZF_LOGF_IF(spec->num_untyped, "spec has static alloc, but loader is compiled for dynamic");
#endif

#if CONFIG_CAPDL_LOADER_PRINT_UNTYPEDS
    int num_untyped = bootinfo->untyped.end - bootinfo->untyped.start;
    ZF_LOGD("  Untyped memory (%d)", num_untyped);
    for (int i = 0; i < num_untyped; i++) {
        uintptr_t ut_paddr = bootinfo->untypedList[i].paddr;
        uintptr_t ut_size = bootinfo->untypedList[i].sizeBits;
        bool ut_isDevice = bootinfo->untypedList[i].isDevice;
        ZF_LOGD("    0x%016" PRIxPTR " - 0x%016" PRIxPTR " (%s)", ut_paddr,
                ut_paddr + BIT(ut_size), ut_isDevice ? "device" : "memory");
    }
#endif

    ZF_LOGD("Loader is running in domain %d", bootinfo->initThreadDomain);

    first_arm_iospace = bootinfo->ioSpaceCaps.start;
}

#if !CONFIG_CAPDL_LOADER_STATIC_ALLOC
static int find_device_object(seL4_Word paddr, seL4_Word type, int size_bits, seL4_CPtr free_slot,
                              CDL_ObjID obj_id, seL4_BootInfo *bootinfo, CDL_Model *spec)
{
    int error;
    seL4_CPtr hold_slot = 0;
    /* See if an overlapping object was already created, can only do this for frames.
     * Any overlapping object will be the previous one, since objects are created in
     * order of physical address */
    if (type != seL4_UntypedObject && obj_id > 0) {
        CDL_ObjID prev = obj_id - 1;
        CDL_Object *obj = &spec->objects[prev];
        if (CDL_Obj_Type(obj) == CDL_Frame &&
            obj->frame_extra.paddr == paddr &&
            CDL_Obj_SizeBits(obj) == size_bits) {
            /* Attempt to copy the cap */
            error = seL4_CNode_Copy(seL4_CapInitThreadCNode, free_slot, CONFIG_WORD_SIZE,
                                    seL4_CapInitThreadCNode, orig_caps(prev), CONFIG_WORD_SIZE, seL4_AllRights);
            ZF_LOGF_IFERR(error, "");
            return 0;
        }
    }
    /* Assume we are allocating from a device untyped. Do a linear search for it */
    for (unsigned int i = 0; i < bootinfo->untyped.end - bootinfo->untyped.start; i++) {
        if (bootinfo->untypedList[i].paddr <= (uintptr_t)paddr &&
            bootinfo->untypedList[i].paddr + BIT(bootinfo->untypedList[i].sizeBits) - 1 >= (uintptr_t)paddr + BIT(size_bits) - 1) {
            /* just allocate objects until we get the one we want. To do this
             * correctly we cannot just destroy the cap we allocate, since
             * if it's the only frame from the untyped this will reset the
             * freeIndex in the kernel, resulting in the next allocation
             * giving the same object. To prevent this we need to hold
             * a single allocation to (lock) the untyped, allowing us to
             * allocate and delete over the rest of the untyped. In order
             * to get a free slot we assume that the slot immediately after
             * us is not yet allocated. We'll give it back though :) */
            while (1) {
                error = seL4_Untyped_Retype(bootinfo->untyped.start + i, type, size_bits,
                                            seL4_CapInitThreadCNode, 0, 0, free_slot, 1);
                ZF_LOGF_IFERR(error, "");
                seL4_ARCH_Page_GetAddress_t addr;
                if (type == seL4_UntypedObject) {
                    /* if it's an untyped, create a temporary frame in it
                     * to get the address from */
                    error = seL4_Untyped_Retype(free_slot, arch_kobject_get_type(KOBJECT_FRAME, seL4_PageBits), seL4_PageBits,
                                                seL4_CapInitThreadCNode, 0, 0, free_slot + 2, 1);
                    ZF_LOGF_IFERR(error, "");
                    addr = seL4_ARCH_Page_GetAddress(free_slot + 2);
                    error = seL4_CNode_Delete(seL4_CapInitThreadCNode, free_slot + 2, CONFIG_WORD_SIZE);
                    ZF_LOGF_IFERR(error, "");
                } else {
                    addr = seL4_ARCH_Page_GetAddress(free_slot);
                }
                ZF_LOGF_IFERR(addr.error, "Could not get address for untyped cap.");
                if (addr.paddr == (uintptr_t)paddr) {
                    /* nailed it */
                    /* delete any holding cap */
                    if (hold_slot) {
                        error = seL4_CNode_Delete(seL4_CapInitThreadCNode, hold_slot, CONFIG_WORD_SIZE);
                        ZF_LOGF_IFERR(error, "");
                    }
                    return 0;
                }
                ZF_LOGF_IF(addr.paddr > (uintptr_t)paddr, "device frames probably not ordered by physical address");

                /* if we are currently using a hold slot we can just delete the cap, otherwise start the hold */
                if (hold_slot) {
                    error = seL4_CNode_Delete(seL4_CapInitThreadCNode, free_slot, CONFIG_WORD_SIZE);
                    ZF_LOGF_IFERR(error, "");
                } else {
                    hold_slot = free_slot + 1;
                    error = seL4_CNode_Move(seL4_CapInitThreadCNode, hold_slot, CONFIG_WORD_SIZE, seL4_CapInitThreadCNode, free_slot,
                                            CONFIG_WORD_SIZE);
                    ZF_LOGF_IFERR(error, "");
                }
            }
        }
    }
    return -1;
}

bool isDeviceObject(CDL_Object *obj)
{
    return CDL_Obj_Paddr(obj) != 0;
}
#endif /* !CONFIG_CAPDL_LOADER_STATIC_ALLOC */

/* Create objects */
static int retype_untyped(seL4_CPtr free_slot, seL4_CPtr free_untyped,
                          seL4_ArchObjectType object_type, int object_size)
{
    seL4_CPtr root = seL4_CapInitThreadCNode;
    int node_index = 0;
    int node_depth = 0;
    int node_offset = free_slot;

    int no_objects = 1;

    ZF_LOGF_IF(object_type >= seL4_ObjectTypeCount,
               "Invalid object type %zu size %zu",
               (size_t) object_type, (size_t) object_size);

    return seL4_Untyped_Retype(free_untyped, object_type, object_size,
                               root, node_index, node_depth, node_offset, no_objects);

}

unsigned int create_object(CDL_Model *spec, CDL_Object *obj, CDL_ObjID id, seL4_BootInfo *info, seL4_CPtr untyped_slot,
                           unsigned int free_slot)
{
    int obj_size = CDL_Obj_SizeBits(obj);
    seL4_ArchObjectType obj_type;

    switch (CDL_Obj_Type(obj)) {
    case CDL_Frame:
        obj_type = kobject_get_type(KOBJECT_FRAME, obj_size);
        break;
    case CDL_ASIDPool:
        obj_type = CDL_Untyped;
        obj_size = seL4_ASIDPoolBits;
        break;
#ifdef CONFIG_KERNEL_MCS
    case CDL_SchedContext:
        obj_size = kobject_get_size(KOBJECT_SCHED_CONTEXT, obj_size);
        obj_type = (seL4_ArchObjectType) CDL_Obj_Type(obj);
        break;
#endif
    default:
        obj_type = (seL4_ArchObjectType) CDL_Obj_Type(obj);
    }

    ZF_LOGD_IF(CDL_Obj_Type(obj) == CDL_CNode, " (CNode of size %d bits)", obj_size);

    seL4_Error err = seL4_NoError;

#ifdef CONFIG_ARCH_X86
    if (CDL_Obj_Type(obj) == CDL_IOPorts) {
        err = seL4_X86_IOPortControl_Issue(seL4_CapIOPortControl, obj->start, obj->end, seL4_CapInitThreadCNode, free_slot,
                                           CONFIG_WORD_SIZE);
        ZF_LOGF_IF(err != seL4_NoError, "Failed to allocate IOPort for range [%d,%d]", (int)obj->start, (int)obj->end);
        return seL4_NoError;
    }
#endif

    /* There can be multiple sids per context bank, currently only 1 sid per cb is implemented for the vms.
     * When this gets extended we need to decide to add sid number -> cb number map into the haskell / python tool
     * or generate the capdl spec so that the order remains correct here e.g a list a stream ids followed by the cb they
     * are mapped to, the cb condition here (1***) will the reset the stream id number back to 0 for the next context bank.
     */
#ifdef CONFIG_ARM_SMMU
    if (CDL_Obj_Type(obj) == CDL_SID) {
        err = seL4_ARM_SIDControl_GetSID(seL4_CapSMMUSIDControl, sid_number, seL4_CapInitThreadCNode, free_slot,
                                         CONFIG_WORD_SIZE);
        ZF_LOGF_IF(err != seL4_NoError, "Failed to allocate SID cap");
        sid_number++;
        ZF_LOGF_IF(sid_number > MAX_STREAM_IDS, "Stream ID numbers exhausted");
        return seL4_NoError;
    } else if (CDL_Obj_Type(obj) == CDL_CB) {
        err = seL4_ARM_CBControl_GetCB(seL4_CapSMMUCBControl, CDL_CB_Bank(obj), seL4_CapInitThreadCNode, free_slot,
                                       CONFIG_WORD_SIZE);
        ZF_LOGF_IF(err != seL4_NoError, "Failed to allocate CB cap");
        sid_number = 0; //(1***)
        return seL4_NoError;
    }
#endif

#if !CONFIG_CAPDL_LOADER_STATIC_ALLOC
    if (isDeviceObject(obj)) {
        seL4_Word paddr = CDL_Obj_Paddr(obj);
        ZF_LOGD(" device frame/untyped, paddr = %p, size = %d bits", (void *) paddr, obj_size);

        /* This is a device object. Look for it in bootinfo. */
        err = find_device_object(paddr, obj_type, obj_size, free_slot, id, info, spec);
        ZF_LOGF_IF(err != seL4_NoError, "Failed to find device frame/untyped at paddr = %p", (void *) paddr);
        return seL4_NoError;
    }
#endif

    /* It's not a device object, or it's a statically allocated device
     * object, so we don't need to search for it. */
    return retype_untyped(free_slot, untyped_slot, obj_type, obj_size);
}

static int requires_creation(CDL_ObjectType type)
{
    switch (type) {
    case CDL_Interrupt:
#ifdef CONFIG_ARCH_X86
    case CDL_IODevice:
    case CDL_IOAPICInterrupt:
    case CDL_MSIInterrupt:
#endif /* CONFIG_ARCH_X86 */
#ifdef CONFIG_ARCH_ARM
    case CDL_ARMIODevice:
    case CDL_ARMInterrupt:
#endif /* CONFIG_ARCH_ARM */
        return false;
    default:
        return true;
    }
}

#if CONFIG_CAPDL_LOADER_STATIC_ALLOC

/*
 * Spec was statically allocated; just run its untyped derivation steps.
 */
static void create_objects(CDL_Model *spec, seL4_BootInfo *bootinfo)
{
    ZF_LOGD("Creating objects...");

    unsigned int free_slot_index = 0;

    /* First, allocate most objects and update the spec database with
       the cslot locations. The exception is ASIDPools, where
       create_object only allocates the backing untypeds. */
    for (int ut_index = 0; ut_index < spec->num_untyped; ut_index++) {
        CDL_UntypedDerivation *ud = &spec->untyped[ut_index];
        seL4_CPtr untyped_cptr = untyped_cptrs[ut_index];
        for (int child = 0; child < ud->num; child++) {
            CDL_ObjID obj_id = ud->children[child];
            seL4_CPtr free_slot = free_slot_start + free_slot_index;
            CDL_Object *obj = &spec->objects[obj_id];
            CDL_ObjectType capdl_obj_type = CDL_Obj_Type(obj);

            ZF_LOGV("Creating object %s in slot %ld, from untyped %lx...",
                    CDL_Obj_Name(obj), (long)free_slot, (long)untyped_cptr);

            ZF_LOGF_IF(!requires_creation(capdl_obj_type),
                       "object %s is in static allocation, but requires_creation is false",
                       CDL_Obj_Name(obj));
            seL4_Error err = create_object(spec, obj, obj_id, bootinfo, untyped_cptr, free_slot);
            if (err == seL4_NoError) {
                add_sel4_cap(obj_id, ORIG, free_slot);
                free_slot_index++;
            } else {
                /* Exit with failure. */
                ZF_LOGF_IFERR(err, "Untyped retype failed with unexpected error");
            }
        }
    }

    /* Now, we turn the backing untypeds into ASID pools, in the order
       given by the ASID slot allocation policy. This fixes the layout
       inside the kernel's ASID table, which ensures consistency with
       verification models. */
    if (spec->num_asid_slots > 1) {
        ZF_LOGD("Creating ASID pools...");
    }
    for (seL4_Word asid_high = 1; asid_high < spec->num_asid_slots; asid_high++) {
        CDL_ObjID obj_id = spec->asid_slots[asid_high];
        seL4_CPtr asidpool_ut = orig_caps(obj_id);
        seL4_CPtr asidpool_slot = free_slot_start + free_slot_index;

        seL4_Error err = seL4_ARCH_ASIDControl_MakePool(seL4_CapASIDControl, asidpool_ut,
                                                        seL4_CapInitThreadCNode, asidpool_slot,
                                                        CONFIG_WORD_SIZE);
        ZF_LOGF_IFERR(err, "Failed to create ASID pool #%d from ut slot %ld into slot %ld",
                      (int)asid_high, (long)asidpool_ut, (long)asidpool_slot);

        // update to point to our new ASID pool
        add_sel4_cap(obj_id, ORIG, asidpool_slot);
        free_slot_index++;
    }

    // Update the free slot to go past all the objects we just made.
    free_slot_start += free_slot_index;
}

#else /* !CONFIG_CAPDL_LOADER_STATIC_ALLOC */

/*
 * Spec was not statically allocated; run a simple allocator.
 *
 * For best results, this relies on capDL-tool grouping device objects
 * by address and sorting other objects from largest to smallest, to
 * minimise memory fragmentation. See CapDL/PrintC.hs.
 */
static void create_objects(CDL_Model *spec, seL4_BootInfo *bootinfo)
{
    /* Sort untypeds from largest to smallest. */
    unsigned int num_normal_untypes = sort_untypeds(bootinfo);

    ZF_LOGD("Creating objects...");

    /* First, allocate most objects and update the spec database with
       the cslot locations. The exception is ASIDPools, where
       create_object only allocates the backing untypeds. */
    unsigned int obj_id_index = 0;
    unsigned int free_slot_index = 0;
    unsigned int ut_index = 0;

    // Each time through the loop either:
    //  - we successfully create an object, and move to the next object to create
    //    OR
    //  - we fail to create an object, and move to the next untyped object

    while (obj_id_index < spec->num && ut_index < num_normal_untypes) {
        CDL_ObjID obj_id = obj_id_index;
        seL4_CPtr free_slot = free_slot_start + free_slot_index;
        seL4_CPtr untyped_cptr = untyped_cptrs[ut_index];
        CDL_Object *obj = &spec->objects[obj_id_index];
        CDL_ObjectType capdl_obj_type = CDL_Obj_Type(obj);

        ZF_LOGV("Creating object %s in slot %ld, from untyped %lx...", CDL_Obj_Name(obj), (long)free_slot,
                (long)untyped_cptr);

        if (requires_creation(capdl_obj_type)) {
            /* at this point we are definitely creating an object - figure out what it is */
            seL4_Error err = create_object(spec, obj, obj_id, bootinfo, untyped_cptr, free_slot);
            if (err == seL4_NoError) {
                add_sel4_cap(obj_id, ORIG, free_slot);
                free_slot_index++;
            } else if (err == seL4_NotEnoughMemory) {
                /* go to the next untyped to allocate objects - this one is empty */
                ut_index++;
                /* we failed to process the current object, go back 1 */
                obj_id_index--;
            } else {
                /* Exit with failure. */
                ZF_LOGF_IFERR(err, "Untyped retype failed with unexpected error");
            }
        }
        obj_id_index++;
    }

    if (obj_id_index != spec->num) {
        /* We didn't iterate through all the objects. */
        ZF_LOGF("Ran out of untyped memory while creating objects.");
    }

    /* Now, we turn the backing untypeds into ASID pools, in the order
       given by the ASID slot allocation policy. This fixes the layout
       inside the kernel's ASID table, which ensures consistency with
       verification models. */
    if (spec->num_asid_slots > 1) {
        ZF_LOGD("Creating ASID pools...");
    }
    for (seL4_Word asid_high = 1; asid_high < spec->num_asid_slots; asid_high++) {
        CDL_ObjID obj_id = spec->asid_slots[asid_high];
        seL4_CPtr asid_ut = orig_caps(obj_id);
        seL4_CPtr asid_slot = free_slot_start + free_slot_index;

        seL4_Error err = seL4_ARCH_ASIDControl_MakePool(seL4_CapASIDControl, asid_ut,
                                                        seL4_CapInitThreadCNode, asid_slot,
                                                        CONFIG_WORD_SIZE);
        ZF_LOGF_IFERR(err, "Failed to create asid pool");

        // update to point to our new ASID pool
        add_sel4_cap(obj_id, ORIG, asid_slot);
        free_slot_index++;
    }

    // Update the free slot to go past all the objects we just made.
    free_slot_start += free_slot_index;
}

#endif /* !CONFIG_CAPDL_LOADER_STATIC_ALLOC */

static void create_irq_cap(CDL_IRQ irq, CDL_Object *obj, seL4_CPtr free_slot)
{
    seL4_CPtr root = seL4_CapInitThreadCNode;
    int index = free_slot;
    int depth = CONFIG_WORD_SIZE;
    int error;

    switch (CDL_Obj_Type(obj)) {
#if defined(CONFIG_ARCH_X86)
    case CDL_IOAPICInterrupt:
        error = seL4_IRQControl_GetIOAPIC(seL4_CapIRQControl, root, index, depth,
                                          obj->ioapicirq_extra.ioapic, obj->ioapicirq_extra.ioapic_pin,
                                          obj->ioapicirq_extra.level, obj->ioapicirq_extra.polarity,
                                          irq);
        break;
    case CDL_MSIInterrupt:
        error = seL4_IRQControl_GetMSI(seL4_CapIRQControl, root, index, depth,
                                       obj->msiirq_extra.pci_bus, obj->msiirq_extra.pci_dev,
                                       obj->msiirq_extra.pci_fun, obj->msiirq_extra.handle, irq);
        break;
#elif defined(CONFIG_ARCH_ARM)
    case CDL_ARMInterrupt:
#if CONFIG_MAX_NUM_NODES > 1
        error = seL4_IRQControl_GetTriggerCore(seL4_CapIRQControl, irq, obj->armirq_extra.trigger,
                                               root, index, depth, obj->armirq_extra.target);
#else
        error = seL4_IRQControl_GetTrigger(seL4_CapIRQControl, irq, obj->armirq_extra.trigger,
                                           root, index, depth);
#endif
        break;
#endif
    default:
        error = seL4_IRQControl_Get(seL4_CapIRQControl, irq, root, index, depth);
    }
    ZF_LOGF_IFERR(error, "Failed to create irq cap");
    add_sel4_cap(irq, IRQ, index);
}

static void create_irq_caps(CDL_Model *spec)
{
    ZF_LOGD("Creating irq handler caps...");

    for (CDL_IRQ irq = 0; irq < spec->num_irqs; irq++) {
        if (spec->irqs[irq] != INVALID_OBJ_ID) {
            seL4_CPtr free_slot = get_free_slot();

            ZF_LOGD(" Creating irq handler cap for IRQ %d...", irq);
            create_irq_cap(irq, &spec->objects[spec->irqs[irq]], free_slot);
            next_free_slot();
        }
    }
}

/* Mint a cap that will not be given to the user */
/* Used for badging interrupt notifications and, in the RT kernel, fault eps */
static void mint_cap(CDL_ObjID object_id, int free_slot, seL4_Word badge)
{
    seL4_CapRights_t rights = seL4_AllRights;

    seL4_CPtr dest_root = seL4_CapInitThreadCNode;
    int dest_index = free_slot;
    int dest_depth = CONFIG_WORD_SIZE;

    seL4_CPtr src_root = seL4_CapInitThreadCNode;
    int src_index = orig_caps(object_id);
    int src_depth = CONFIG_WORD_SIZE;

    int error = seL4_CNode_Mint(dest_root, dest_index, dest_depth,
                                src_root, src_index, src_depth, rights,
                                badge);
    ZF_LOGF_IF(error, "Failed to mint cap");
}

/* Duplicate capabilities */
static void duplicate_cap(CDL_ObjID object_id, int free_slot)
{
    seL4_CapRights_t rights = seL4_AllRights;

    seL4_CPtr dest_root = seL4_CapInitThreadCNode;
    int dest_index = free_slot;
    int dest_depth = CONFIG_WORD_SIZE;

    seL4_CPtr src_root = seL4_CapInitThreadCNode;
    int src_index = orig_caps(object_id);
    int src_depth = CONFIG_WORD_SIZE;

    int error = seL4_CNode_Copy(dest_root, dest_index, dest_depth,
                                src_root, src_index, src_depth, rights);
    ZF_LOGF_IFERR(error, "");

    add_sel4_cap(object_id, DUP, dest_index);
}

static void duplicate_caps(CDL_Model *spec)
{
    ZF_LOGD("Duplicating CNodes...");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_CNode || spec->objects[obj_id].type == CDL_TCB) {
            ZF_LOGD(" Duplicating %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            int free_slot = get_free_slot();
            duplicate_cap(obj_id, free_slot);
            next_free_slot();
        }
    }
}

static void create_sched_ctrl_caps(seL4_BootInfo *bi)
{
#ifdef CONFIG_KERNEL_MCS
    for (seL4_Word i = 0; i <= bi->schedcontrol.end - bi->schedcontrol.start; i++) {
        add_sel4_cap(i, SCHED_CTRL, i + bi->schedcontrol.start);
    }
#endif
}

/* Initialise SCs */
static void init_sc(CDL_Model *spec, CDL_ObjID sc, CDL_Core affinity)
{
    CDL_Object *cdl_sc = get_spec_object(spec, sc);

    uint64_t UNUSED budget = CDL_SC_Budget(cdl_sc);
    uint64_t UNUSED period = CDL_SC_Period(cdl_sc);
    seL4_Word UNUSED data = CDL_SC_Data(cdl_sc);

    ZF_LOGD("budget: %llu, period: %llu, data: %u", budget, period, data);

    seL4_CPtr UNUSED seL4_sc = orig_caps(sc);
    seL4_CPtr UNUSED sched_control = sched_ctrl_caps(affinity);
#ifdef CONFIG_KERNEL_MCS
    /* Assign the sched context to run on the CPU that the root task runs on. */
    int error = seL4_SchedControl_Configure(sched_control,
                                            seL4_sc, budget, period, 0, data);
    ZF_LOGF_IFERR(error, "");
#endif
}

/* Initialise TCBs */
static void init_tcb(CDL_Model *spec, CDL_ObjID tcb)
{
    CDL_Object *cdl_tcb = get_spec_object(spec, tcb);

    CDL_Cap *cdl_cspace_root = get_cap_at(cdl_tcb, CDL_TCB_CTable_Slot);
    if (cdl_cspace_root == NULL) {
        ZF_LOGD("Could not find CSpace cap for %s", CDL_Obj_Name(cdl_tcb));
    }
    CDL_Cap *cdl_vspace_root = get_cap_at(cdl_tcb, CDL_TCB_VTable_Slot);
    if (cdl_vspace_root == NULL) {
        ZF_LOGD("Could not find VSpace cap for %s", CDL_Obj_Name(cdl_tcb));
    }
    CDL_Cap *cdl_ipcbuffer   = get_cap_at(cdl_tcb, CDL_TCB_IPCBuffer_Slot);
    if (cdl_ipcbuffer == NULL) {
        ZF_LOGD("  Warning: TCB has no IPC buffer");
    }
#if defined(CONFIG_ARM_HYPERVISOR_SUPPORT) || defined(CONFIG_VTX)
    CDL_Cap *cdl_vcpu = get_cap_at(cdl_tcb, CDL_TCB_VCPU_SLOT);
#endif

    CDL_Cap *cdl_sc   = get_cap_at(cdl_tcb, CDL_TCB_SC_Slot);

    seL4_Word ipcbuffer_addr = CDL_TCB_IPCBuffer_Addr(cdl_tcb);
    uint8_t priority = CDL_TCB_Priority(cdl_tcb);
    CDL_Core UNUSED affinity = CDL_TCB_Affinity(cdl_tcb);
    uint8_t UNUSED max_priority = CDL_TCB_MaxPriority(cdl_tcb);

    seL4_CPtr sel4_tcb = orig_caps(tcb);

    seL4_CPtr sel4_cspace_root = cdl_cspace_root == NULL ? 0 : orig_caps(CDL_Cap_ObjID(cdl_cspace_root));
    seL4_CPtr sel4_vspace_root = cdl_vspace_root ? orig_caps(CDL_Cap_ObjID(cdl_vspace_root)) : 0;
    seL4_CPtr sel4_ipcbuffer   = cdl_ipcbuffer ? orig_caps(CDL_Cap_ObjID(cdl_ipcbuffer)) : 0;
    seL4_CPtr UNUSED sel4_sc   = cdl_sc ? orig_caps(CDL_Cap_ObjID(cdl_sc)) : 0;
#if defined(CONFIG_ARM_HYPERVISOR_SUPPORT) || defined(CONFIG_VTX)
    seL4_CPtr sel4_vcpu        = cdl_vcpu ? orig_caps(CDL_Cap_ObjID(cdl_vcpu)) : 0;
#endif

    seL4_CPtr sel4_fault_ep;
    seL4_CPtr UNUSED sel4_tempfault_ep;
    seL4_CPtr badged_sel4_fault_ep;

    if (config_set(CONFIG_KERNEL_MCS)) {
        /* Fault ep cptrs are in the caller's cspace */

        CDL_Cap *cdl_fault_ep   = get_cap_at(cdl_tcb, CDL_TCB_FaultEP_Slot);
        if (cdl_fault_ep == NULL) {
            ZF_LOGW("  Warning: TCB has no fault endpoint");
        }

        CDL_Cap *cdl_tempfault_ep   = get_cap_at(cdl_tcb, CDL_TCB_TemporalFaultEP_Slot);
        if (cdl_tempfault_ep == NULL) {
            ZF_LOGW("  Warning: TCB has no temporal fault endpoint");
        }

        sel4_fault_ep = cdl_fault_ep ? orig_caps(CDL_Cap_ObjID(cdl_fault_ep)) : 0;
        sel4_tempfault_ep = cdl_tempfault_ep ? orig_caps(CDL_Cap_ObjID(cdl_tempfault_ep)) : 0;

        if (sel4_fault_ep != 0) {
            seL4_Word fault_ep_badge = get_capData(CDL_Cap_Data(cdl_fault_ep));
            if (fault_ep_badge != 0) {
                badged_sel4_fault_ep = (seL4_CPtr) get_free_slot();
                mint_cap(CDL_Cap_ObjID(cdl_fault_ep), badged_sel4_fault_ep,
                         fault_ep_badge);
                next_free_slot();
                sel4_fault_ep = badged_sel4_fault_ep;

            }
        }
    } else {
        /* Fault ep cptrs are in the configured thread's cspace */
        sel4_fault_ep = cdl_tcb->tcb_extra.fault_ep;
    }

    seL4_Word sel4_cspace_root_data = seL4_NilData;
    seL4_Word sel4_vspace_root_data = seL4_NilData;
    if (cdl_cspace_root != NULL) {
        sel4_cspace_root_data = get_capData(CDL_Cap_Data(cdl_cspace_root));
    }
    if (cdl_vspace_root != NULL) {
        sel4_vspace_root_data = get_capData(CDL_Cap_Data(cdl_vspace_root));
    }

    /*
     * seL4_TCB_Configure requires a valid CSpace, VSpace and IPC buffer cap to
     * succeed at assigning any of them. We first try and perform seL4_TCB_Configure
     * but if any of these objects are missing we fall back to only trying to assign
     * an IPC buffer if we have one using seL4_TCB_SetIPCBuffer.  We print an error
     * if a CSpace is available but a VSpace is not or if there is a VSpace but no CSpace.
     */
    int error;
#ifdef CONFIG_KERNEL_MCS
    if (sel4_sc) {
        init_sc(spec, CDL_Cap_ObjID(cdl_sc), affinity);
    }

    if (cdl_cspace_root && cdl_vspace_root && sel4_ipcbuffer) {
        error = seL4_TCB_Configure(sel4_tcb,
                                   sel4_cspace_root, sel4_cspace_root_data,
                                   sel4_vspace_root, sel4_vspace_root_data,
                                   ipcbuffer_addr, sel4_ipcbuffer);
        ZF_LOGF_IFERR(error, "");
    } else {
        ZF_LOGE_IFERR(cdl_cspace_root || cdl_vspace_root || sel4_ipcbuffer,
                      "Could not call seL4_TCB_Configure as not all required objects provided: "
                      "VSpace: %"PRIxPTR", CSpace: %"PRIxPTR", IPC Buffer: %"PRIxPTR, cdl_vspace_root, cdl_cspace_root, sel4_ipcbuffer);

        if (sel4_ipcbuffer) {
            error = seL4_TCB_SetIPCBuffer(sel4_tcb, ipcbuffer_addr, sel4_ipcbuffer);
            ZF_LOGF_IFERR(error, "");
        }
    }

    error = seL4_TCB_SetSchedParams(sel4_tcb, seL4_CapInitThreadTCB, max_priority, priority,
                                    sel4_sc, sel4_fault_ep);
    ZF_LOGF_IFERR(error, "");

    error = seL4_TCB_SetTimeoutEndpoint(sel4_tcb, sel4_tempfault_ep);
#else
    if (cdl_cspace_root && cdl_vspace_root && sel4_ipcbuffer) {
        error = seL4_TCB_Configure(sel4_tcb, sel4_fault_ep,
                                   sel4_cspace_root, sel4_cspace_root_data,
                                   sel4_vspace_root, sel4_vspace_root_data,
                                   ipcbuffer_addr, sel4_ipcbuffer);
        ZF_LOGF_IFERR(error, "");
    } else {
        ZF_LOGE_IFERR(cdl_cspace_root || cdl_vspace_root || sel4_ipcbuffer,
                      "Could not call seL4_TCB_Configure as not all required objects provided: "
                      "VSpace: %"PRIxPTR", CSpace: %"PRIxPTR", IPC Buffer: %"PRIxPTR, cdl_vspace_root, cdl_cspace_root, sel4_ipcbuffer);

        if (sel4_ipcbuffer) {
            error = seL4_TCB_SetIPCBuffer(sel4_tcb, ipcbuffer_addr, sel4_ipcbuffer);
            ZF_LOGF_IFERR(error, "");
        }
    }

    error = seL4_TCB_SetSchedParams(sel4_tcb, seL4_CapInitThreadTCB, max_priority, priority);
#endif

    ZF_LOGF_IFERR(error, "");

#if CONFIG_MAX_NUM_NODES > 1
    error = seL4_TCB_SetAffinity(sel4_tcb, affinity);
#endif

    ZF_LOGF_IFERR(error, "");

#if defined(CONFIG_ARM_HYPERVISOR_SUPPORT) || defined(CONFIG_VTX)
    if (sel4_vcpu) {
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
        int error = seL4_ARM_VCPU_SetTCB(sel4_vcpu, sel4_tcb);
#else //CONFIG_VTX
        int error = seL4_X86_VCPU_SetTCB(sel4_vcpu, sel4_tcb);
#endif
        ZF_LOGF_IFERR(error, "Failed to bind TCB %s to VCPU %s",
                      CDL_Obj_Name(cdl_tcb), CDL_Obj_Name(get_spec_object(spec, CDL_Cap_ObjID(cdl_vcpu))));
    }
#endif

#ifdef CONFIG_DEBUG_BUILD
    /* Name the thread after its TCB name if possible. We need to do some
     * juggling first to ensure the name will not overflow the IPC buffer.
     */
    char safe_name[seL4_MsgMaxLength * sizeof(seL4_Word)];
    const char *name = CDL_Obj_Name(cdl_tcb);
    if (name != NULL) {
        strncpy(safe_name, name, sizeof(safe_name) - 1);
        safe_name[sizeof(safe_name) - 1] = '\0';
        (void)seL4_DebugNameThread(sel4_tcb, safe_name);
    }
#endif
}

static void configure_tcb(CDL_Model *spec, CDL_ObjID tcb)
{
    seL4_CPtr sel4_tcb = dup_caps(tcb);

    CDL_Object *cdl_tcb = get_spec_object(spec, tcb);
    const seL4_Word *argv = cdl_tcb->tcb_extra.init;
    int argc = cdl_tcb->tcb_extra.init_sz;

    uintptr_t pc = CDL_TCB_PC(cdl_tcb);
    uintptr_t sp = CDL_TCB_SP(cdl_tcb);

    if (sp % (sizeof(uintptr_t) * 2) != 0) {
        ZF_LOGF("TCB %s's stack pointer is not dword-aligned", CDL_Obj_Name(&spec->objects[tcb]));
    }
    int reg_args = 0;
#if defined(CONFIG_ARCH_ARM)
    /* On ARM, the first four arguments go in registers. */
    reg_args = 4;
#endif
#if defined(CONFIG_ARCH_IA32) && defined(CONFIG_CAPDL_LOADER_CC_REGISTERS)
    reg_args = 4;
#endif
#if defined(CONFIG_ARCH_X86_64)
    reg_args = 4;
#endif
#if defined(CONFIG_ARCH_RISCV)
    reg_args = 4;
#endif

    if (argc > reg_args) {
#ifdef CONFIG_CAPDL_LOADER_CC_REGISTERS
        ZF_LOGF("TCB %s has more than four arguments, which is not supported using"
                " the register calling convention", CDL_Obj_Name(&spec->objects[tcb]));
#else //!CONFIG_CAPDL_LOADER_CC_REGISTERS
        /* We need to map the TCB's stack into our address space because there
         * are arguments to write.
         */

        /* Find the TCB's PD. */
        CDL_Cap *cdl_vspace_root = get_cap_at(cdl_tcb, CDL_TCB_VTable_Slot);
        CDL_ObjID pd = CDL_Cap_ObjID(cdl_vspace_root);

        if (STACK_ALIGNMENT_BYTES % sizeof(*argv)) {
            ZF_LOGF("Stack alignment requirement not evenly divisible by argument size");
        }

        /* The stack pointer of new threads will initially be aligned to
         * STACK_ALIGNMENT_BYTES bytes. Any padding required to enforce
         * this alignment will come before any stack arguments.
         */

        unsigned int num_stack_args = argc - reg_args; // positive because argc > reg_args
        unsigned int args_per_alignment = (STACK_ALIGNMENT_BYTES / sizeof(*argv));
        unsigned int num_unaligned_args = num_stack_args % args_per_alignment;

        if (num_unaligned_args != 0) {
            unsigned int num_padding_args = args_per_alignment - num_unaligned_args;
            unsigned int num_padding_bytes = num_padding_args * sizeof(*argv);
            sp -= num_padding_bytes;
        }

        /* Find and map the frame representing the TCB's stack. Note that we do
         * `sp - sizeof(uintptr_t)` because the stack pointer may be on a page
         * boundary.
         */
        seL4_CPtr frame = get_frame_cap(pd, sp - sizeof(uintptr_t), spec);
        /* FIXME: The above could actually fail messily if the user has given a
         * spec with stack pointers that point outside the ELF image.
         */
        seL4_ARCH_VMAttributes attribs = seL4_ARCH_Default_VMAttributes;
#ifdef CONFIG_ARCH_ARM
        attribs |= seL4_ARM_ExecuteNever;
#endif
        int error = seL4_ARCH_Page_Map(frame, seL4_CapInitThreadPD, (seL4_Word)copy_addr_with_pt,
                                       seL4_ReadWrite, attribs);
        ZF_LOGF_IFERR(error, "");

        /* Write all necessary arguments to the TCB's stack. */
        for (int i = argc - 1; i >= 0 && i >= reg_args; i--) {
            if (i != argc - 1 && sp % PAGE_SIZE_4K == 0) {
                /* We could support this case with more complicated logic, but
                 * choose not to.
                 */
                ZF_LOGF("TCB %s's initial arguments cause its stack to cross a page boundary",
                        CDL_Obj_Name(&spec->objects[tcb]));
            }
            sp -= sizeof(seL4_Word);
            *(seL4_Word *)(copy_addr_with_pt + sp % PAGE_SIZE_4K) = argv[i];
        }

#ifdef CONFIG_ARCH_ARM
        error = seL4_ARM_Page_Unify_Instruction(frame, 0, PAGE_SIZE_4K);
        ZF_LOGF_IFERR(error, "");
#endif //CONFIG_ARCH_ARM
        error = seL4_ARCH_Page_Unmap(frame);
        ZF_LOGF_IFERR(error, "");
#endif //CONFIG_CAPDL_LOADER_CC_REGISTERS
    }

    seL4_UserContext regs = {
#if defined(CONFIG_ARCH_ARM)
        .pc = pc,
        .sp = sp,
#ifdef CONFIG_ARCH_AARCH32
        .r0 = argc > 0 ? argv[0] : 0,
        .r1 = argc > 1 ? argv[1] : 0,
        .r2 = argc > 2 ? argv[2] : 0,
        .r3 = argc > 3 ? argv[3] : 0,
#else // CONFIG_ARCH_AARCH64
        .x0 = argc > 0 ? argv[0] : 0,
        .x1 = argc > 1 ? argv[1] : 0,
        .x2 = argc > 2 ? argv[2] : 0,
        .x3 = argc > 3 ? argv[3] : 0,
#endif // CONFIG_ARCH_AARCH32
#elif defined(CONFIG_ARCH_IA32)
        .eip = pc,
        .esp = sp,
#ifdef CONFIG_CAPDL_LOADER_CC_REGISTERS
        .eax = argc > 2 ? argv[2] : 0,
        .ebx = argc > 3 ? argv[3] : 0,
        .ecx = argc > 0 ? argv[0] : 0,
        .edx = argc > 1 ? argv[1] : 0,
#endif
#elif defined(CONFIG_ARCH_X86_64)
        .rip = pc,
        .rsp = sp,
        .rdi = argc > 0 ? argv[0] : 0,
        .rsi = argc > 1 ? argv[1] : 0,
        .rdx = argc > 2 ? argv[2] : 0,
        .rcx = argc > 3 ? argv[3] : 0,
#elif defined(CONFIG_ARCH_RISCV)
        .pc = pc,
        .sp = sp,
        .a0 = argc > 0 ? argv[0] : 0,
        .a1 = argc > 1 ? argv[1] : 0,
        .a2 = argc > 2 ? argv[2] : 0,
        .a3 = argc > 3 ? argv[3] : 0,
#endif
    };
    ZF_LOGD("  Setting up _start()");
    ZF_LOGD("   pc   = %p", (void *)pc);
    ZF_LOGD("   sp   = %p", (void *)sp);
    for (int i = 0; i < argc; i++) {
        ZF_LOGD("   arg%d = %p", i, (void *)argv[i]);
    }

    global_user_context = regs;

    int error = seL4_TCB_WriteRegisters(sel4_tcb, false, 0,
                                        sizeof(seL4_UserContext) / sizeof(seL4_Word),
                                        &global_user_context);
    ZF_LOGF_IFERR(error, "");

    uint32_t UNUSED domain = CDL_TCB_Domain(cdl_tcb);
    ZF_LOGD("  Assigning thread to domain %u...", domain);
    error = seL4_DomainSet_Set(seL4_CapDomain, domain, sel4_tcb);
    ZF_LOGF_IFERR(error, "");
}

static void init_tcbs(CDL_Model *spec)
{
    ZF_LOGD("Initialising TCBs...");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_TCB) {
            ZF_LOGD(" Initialising %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            init_tcb(spec, obj_id);

            ZF_LOGD(" Configuring %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            configure_tcb(spec, obj_id);
        }
    }
}


static void init_irq(CDL_Model *spec, CDL_IRQ irq_no)
{
    seL4_CPtr irq_handler_cap = irq_caps(irq_no);

    CDL_Object *cdl_irq = get_spec_object(spec, spec->irqs[irq_no]);
    assert(cdl_irq != NULL);

#ifdef CONFIG_ARCH_X86
    assert(cdl_irq->type == CDL_Interrupt || cdl_irq->type == CDL_IOAPICInterrupt || cdl_irq->type == CDL_MSIInterrupt);
#elif CONFIG_ARCH_ARM
    assert(cdl_irq->type == CDL_Interrupt || cdl_irq->type == CDL_ARMInterrupt);
#else
    assert(cdl_irq->type == CDL_Interrupt);
#endif

    if (cdl_irq->size_bits != 0) {
        ZF_LOGF("Misconfigured IRQ; an IRQ must have a size of 0.");
    }
    if (cdl_irq->slots.num > 1) {
        ZF_LOGF("Misconfigured IRQ; an IRQ cannot have more than one assigned endpoint.");
    }

    if (cdl_irq->slots.num == 1) {
        /* This IRQ is bound. */
        CDL_Cap *endpoint_cap = &cdl_irq->slots.slot[0].cap;
        seL4_CPtr endpoint_cptr;

        seL4_Word badge = get_capData(CDL_Cap_Data(endpoint_cap));
        if (badge) {
            endpoint_cptr = (seL4_CPtr)get_free_slot();
            mint_cap(CDL_Cap_ObjID(endpoint_cap), endpoint_cptr, badge);
            next_free_slot();
        } else {
            endpoint_cptr = orig_caps(CDL_Cap_ObjID(endpoint_cap));
        }

        int error = seL4_IRQHandler_SetNotification(irq_handler_cap, endpoint_cptr);
        ZF_LOGF_IFERR(error, "");
    }
}

static void init_irqs(CDL_Model *spec)
{
    ZF_LOGD("Initialising IRQ handler caps...");

    for (CDL_IRQ irq = 0; irq < spec->num_irqs; irq++) {
        if (spec->irqs[irq] != INVALID_OBJ_ID) {
            ZF_LOGD(" Initialising handler for IRQ %d...", irq);
            init_irq(spec, irq);
        }
    }
}

/* Initialise virtual address spaces */
static void set_asid(CDL_Model *spec UNUSED, CDL_ObjID page)
{
    seL4_CPtr sel4_page = orig_caps(page);
    int error = seL4_ARCH_ASIDPool_Assign(seL4_CapInitThreadASIDPool, sel4_page);
    ZF_LOGF_IFERR(error, "");
}

static void init_pd_asids(CDL_Model *spec)
{
    ZF_LOGD("Initialising Page Directory ASIDs...");

    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        CDL_ObjectType type = CDL_TOP_LEVEL_PD;
        if (spec->objects[obj_id].type == type) {
            ZF_LOGD(" Initialising pd/pml4 ASID %s...",
                    CDL_Obj_Name(&spec->objects[obj_id]));
            set_asid(spec, obj_id);
        }
    }
}

static void map_page(CDL_Model *spec UNUSED, CDL_Cap *page_cap, CDL_ObjID pd_id,
                     seL4_CapRights_t rights, seL4_Word vaddr)
{
    CDL_ObjID page = CDL_Cap_ObjID(page_cap);

    // TODO: We should not be using the original cap here
    seL4_CPtr sel4_page = orig_caps(page);
    seL4_CPtr sel4_pd = orig_caps(pd_id);
#ifdef CONFIG_CAPDL_LOADER_WRITEABLE_PAGES
    /* Make instruction pages writeable to support software breakpoints */
    if (seL4_CapRights_get_capAllowGrant(rights)) {
        rights = seL4_CapRights_set_capAllowWrite(rights, true);
    }
#endif
    seL4_ARCH_VMAttributes vm_attribs = CDL_Cap_VMAttributes(page_cap);
    ZF_LOGD("   Mapping %s into %s with rights={G: %d, R: %d, W: %d}, vaddr=0x%x, vm_attribs=0x%x",
            CDL_Obj_Name(&spec->objects[page]),
            CDL_Obj_Name(&spec->objects[pd_id]),
            seL4_CapRights_get_capAllowGrant(rights),
            seL4_CapRights_get_capAllowRead(rights),
            seL4_CapRights_get_capAllowWrite(rights),
            vaddr, vm_attribs);

    if (CDL_Cap_Type(page_cap) == CDL_PTCap) {
        int error = seL4_ARCH_PageTable_Map(sel4_page, sel4_pd, vaddr, vm_attribs);
        ZF_LOGF_IFERR(error, "");

    } else if (CDL_Cap_Type(page_cap) == CDL_FrameCap) {
#ifdef CAPDL_SHARED_FRAMES
        /* hack to support shared frames: create a new cap for each mapping */
        int dest_index = get_free_slot();

        int error_0 = seL4_CNode_Copy(seL4_CapInitThreadCNode, dest_index, CONFIG_WORD_SIZE,
                                      seL4_CapInitThreadCNode, sel4_page, CONFIG_WORD_SIZE, seL4_AllRights);
        ZF_LOGF_IFERR(error_0, "");

        next_free_slot();
        sel4_page = dest_index;
#endif

        /* XXX: Write-only mappings are silently downgraded by the kernel to
         * kernel-only. This is clearly not what the user intended if they
         * passed us a write-only mapping. Help them out by upgrading it here.
         */
        if (seL4_CapRights_get_capAllowWrite(rights)) {
            rights = seL4_CapRights_set_capAllowRead(rights, true);
        }

#ifdef CONFIG_ARCH_ARM
        if (!seL4_CapRights_get_capAllowGrant(rights)) {
            vm_attribs |= seL4_ARM_ExecuteNever;
        }
#endif

        /* Store the cap used for mapping the page in the CDL_Cap in the
         * corresponding page table/directory slot for later use. */
        page_cap->mapped_frame_cap = sel4_page;

        // FIXME: Add support for super-pages.
        int error = seL4_ARCH_Page_Map(sel4_page, sel4_pd, vaddr, rights, vm_attribs);
        if (error) {
            /* Try and retrieve some useful information to help the user
             * diagnose the error.
             */
            ZF_LOGE("Failed to map frame ");
            seL4_ARCH_Page_GetAddress_t addr UNUSED = seL4_ARCH_Page_GetAddress(sel4_page);
            if (addr.error) {
                ZF_LOGE("<unknown physical address (error = %d)>", addr.error);
            } else {
                ZF_LOGE("%p", (void *)addr.paddr);
            }
            ZF_LOGE(" -> %p (error = %d)", (void *)vaddr, error);
            ZF_LOGF_IFERR(error, "");
        }
#ifdef CONFIG_ARCH_ARM
        /* When seL4 creates a new frame object it zeroes the associated memory
         * through a cached kernel mapping. If we are configuring a cached
         * mapping for the target, standard coherence protocols ensure
         * everything works as expected. However, if we are configuring an
         * uncached mapping for the target, the dirty zero data cached from the
         * kernel's mapping is likely flushed to memory at some time in the
         * future causing an unpleasant surprise for the target whose own
         * uncached writes are mysteriously overwritten. To prevent this, we
         * unify the mapping here, flushing the cached data from the kernel's
         * mapping.
         */
        seL4_Word size_bits = spec->objects[page].size_bits;
        assert(size_bits <= sizeof(uintptr_t) * CHAR_BIT - 1 && "illegal object size");

        seL4_ARCH_Page_GetAddress_t addr = seL4_ARCH_Page_GetAddress(sel4_page);
        if (addr.paddr >= memory_region[0].start && addr.paddr <= memory_region[0].end) {
            if (!(vm_attribs & seL4_ARM_PageCacheable) && CDL_Obj_Paddr(&spec->objects[page]) == 0) {
                error = seL4_ARM_Page_CleanInvalidate_Data(sel4_page, 0, BIT(size_bits));
                ZF_LOGF_IFERR(error, "");
            }

            if (seL4_CapRights_get_capAllowGrant(rights)) {
                error = seL4_ARM_Page_Unify_Instruction(sel4_page, 0, BIT(size_bits));
                ZF_LOGF_IFERR(error, "");
            }
        }
#endif
    } else {
        ZF_LOGF("attempt to map something that is not a frame or PT");
    }
}

#if defined(CONFIG_ARCH_X86_64) || defined(CONFIG_ARCH_AARCH64) || defined(CONFIG_ARCH_RISCV)

static void init_level_3(CDL_Model *spec, CDL_ObjID level_0_obj, uintptr_t level_3_base, CDL_ObjID level_3_obj)
{
    CDL_Object *obj = get_spec_object(spec, level_3_obj);
    for (unsigned long slot_index = 0; slot_index < CDL_Obj_NumSlots(obj); slot_index++) {
        CDL_CapSlot *slot = CDL_Obj_GetSlot(obj, slot_index);
        unsigned long obj_slot = CDL_CapSlot_Slot(slot);
        uintptr_t base = level_3_base + (obj_slot << (seL4_PageBits));
        CDL_Cap *frame_cap = CDL_CapSlot_Cap(slot);
        seL4_CapRights_t frame_rights = CDL_seL4_Cap_Rights(frame_cap);
        map_page(spec, frame_cap, level_0_obj, frame_rights, base);
    }
}

static void init_level_2(CDL_Model *spec, CDL_ObjID level_0_obj, uintptr_t level_2_base, CDL_ObjID level_2_obj)
{
    CDL_Object *obj = get_spec_object(spec, level_2_obj);
    for (unsigned long slot_index = 0; slot_index < CDL_Obj_NumSlots(obj); slot_index++) {
        CDL_CapSlot *slot = CDL_Obj_GetSlot(obj, slot_index);
        unsigned long obj_slot = CDL_CapSlot_Slot(slot);
        uintptr_t base = level_2_base + (obj_slot << (CDL_PT_LEVEL_3_IndexBits + seL4_PageBits));
        CDL_Cap *level_3_cap = CDL_CapSlot_Cap(slot);
        CDL_ObjID level_3_obj = CDL_Cap_ObjID(level_3_cap);
        if (CDL_Cap_Type(level_3_cap) == CDL_FrameCap) {
            seL4_CapRights_t frame_rights = CDL_seL4_Cap_Rights(level_3_cap);
            map_page(spec, level_3_cap, level_0_obj, frame_rights, base);
        } else {
            seL4_ARCH_VMAttributes vm_attribs = CDL_Cap_VMAttributes(level_3_cap);
            CDL_PT_LEVEL_3_MAP(orig_caps(level_3_obj), orig_caps(level_0_obj), base, vm_attribs);
            init_level_3(spec, level_0_obj, base, level_3_obj);
        }
    }
}

static void init_level_1(CDL_Model *spec, CDL_ObjID level_0_obj, uintptr_t level_1_base, CDL_ObjID level_1_obj)
{
    CDL_Object *obj = get_spec_object(spec, level_1_obj);
    for (unsigned int slot_index = 0; slot_index < CDL_Obj_NumSlots(obj); slot_index++) {
        CDL_CapSlot *slot = CDL_Obj_GetSlot(obj, slot_index);
        unsigned long obj_slot = CDL_CapSlot_Slot(slot);
        uintptr_t base = level_1_base + (obj_slot << (CDL_PT_LEVEL_2_IndexBits + CDL_PT_LEVEL_3_IndexBits + seL4_PageBits));
        CDL_Cap *level_2_cap = CDL_CapSlot_Cap(slot);
        CDL_ObjID level_2_obj = CDL_Cap_ObjID(level_2_cap);
        if (CDL_Cap_Type(level_2_cap) == CDL_FrameCap) {
            seL4_CapRights_t frame_rights = CDL_seL4_Cap_Rights(level_2_cap);
            map_page(spec, level_2_cap, level_0_obj, frame_rights, base);
        } else {
            seL4_ARCH_VMAttributes vm_attribs = CDL_Cap_VMAttributes(level_2_cap);
            CDL_PT_LEVEL_2_MAP(orig_caps(level_2_obj), orig_caps(level_0_obj), base, vm_attribs);
            init_level_2(spec, level_0_obj, base, level_2_obj);
        }
    }
}

static void init_level_0(CDL_Model *spec, CDL_ObjID level_0_obj, uintptr_t level_0_base, CDL_ObjID level_0_obj_unused)
{
    CDL_Object *obj = get_spec_object(spec, level_0_obj);
    for (unsigned long slot_index = 0; slot_index < CDL_Obj_NumSlots(obj); slot_index++) {
        CDL_CapSlot *slot = CDL_Obj_GetSlot(obj, slot_index);
        unsigned long obj_slot = CDL_CapSlot_Slot(slot);
        uintptr_t base = (level_0_base + obj_slot) << (CDL_PT_LEVEL_1_IndexBits + CDL_PT_LEVEL_2_IndexBits +
                                                       CDL_PT_LEVEL_3_IndexBits + seL4_PageBits);
        CDL_Cap *level_1_cap = CDL_CapSlot_Cap(slot);
        CDL_ObjID level_1_obj = CDL_Cap_ObjID(level_1_cap);
        seL4_ARCH_VMAttributes vm_attribs = CDL_Cap_VMAttributes(level_1_cap);
#ifdef CDL_PT_LEVEL_1_MAP
        CDL_PT_LEVEL_1_MAP(orig_caps(level_1_obj), orig_caps(level_0_obj), base, vm_attribs);
        init_level_1(spec, level_0_obj, base, level_1_obj);
#else
        ZF_LOGF("CDL_PT_LEVEL_1_MAP is not defined");
#endif
    }
}

#else

static void map_page_directory_slot(CDL_Model *spec UNUSED, CDL_ObjID pd_id, CDL_CapSlot *pd_slot)
{
    ZF_LOGD("  Mapping slot %d in %s", pd_slot->slot, CDL_Obj_Name(&spec->objects[pd_id]));
    CDL_Cap *page_cap = CDL_CapSlot_Cap(pd_slot);

    seL4_Word page_vaddr = CDL_CapSlot_Slot(pd_slot) << (seL4_PageTableIndexBits + seL4_PageBits);
    seL4_CapRights_t page_rights = CDL_seL4_Cap_Rights(page_cap);

    map_page(spec, page_cap, pd_id, page_rights, page_vaddr);
}

static void map_page_directory(CDL_Model *spec, CDL_ObjID pd_id)
{
    CDL_Object *cdl_pd = get_spec_object(spec, pd_id);

    for (unsigned int slot_index = 0; slot_index < CDL_Obj_NumSlots(cdl_pd); slot_index++) {
        map_page_directory_slot(spec, pd_id, CDL_Obj_GetSlot(cdl_pd, slot_index));
    }
}

static void map_page_table_slot(CDL_Model *spec UNUSED, CDL_ObjID pd, CDL_ObjID pt UNUSED,
                                seL4_Word pt_vaddr, CDL_CapSlot *pt_slot)
{
    CDL_Cap *page_cap = CDL_CapSlot_Cap(pt_slot);

    seL4_Word page_vaddr = pt_vaddr + (CDL_CapSlot_Slot(pt_slot) << seL4_PageBits);
    seL4_CapRights_t page_rights = CDL_seL4_Cap_Rights(page_cap);

    ZF_LOGD("  Mapping %s into %s[%d] with rights={G: %d, R: %d, W: %d}, vaddr=0x%" PRIxPTR "",
            CDL_Obj_Name(&spec->objects[pt]), CDL_Obj_Name(&spec->objects[pd]), pt_slot->slot,
            seL4_CapRights_get_capAllowGrant(page_rights),
            seL4_CapRights_get_capAllowRead(page_rights),
            seL4_CapRights_get_capAllowWrite(page_rights),
            (uintptr_t)pt_vaddr);

    map_page(spec, page_cap, pd, page_rights, page_vaddr);
}

static void map_page_table_slots(CDL_Model *spec, CDL_ObjID pd, CDL_CapSlot *pd_slot)
{
    CDL_Cap *page_cap = CDL_CapSlot_Cap(pd_slot);
    CDL_ObjID page = CDL_Cap_ObjID(page_cap);

    seL4_Word page_vaddr = CDL_CapSlot_Slot(pd_slot) << (seL4_PageTableIndexBits + seL4_PageBits);

    if (CDL_Cap_Type(page_cap) == CDL_PTCap) {
        CDL_Object *obj = get_spec_object(spec, page);
        for (unsigned int slot_index = 0; slot_index < CDL_Obj_NumSlots(obj); slot_index++) {
            map_page_table_slot(spec, pd, page, page_vaddr, CDL_Obj_GetSlot(obj, slot_index));
        }
    }
}

static void map_page_directory_page_tables(CDL_Model *spec, CDL_ObjID pd)
{
    CDL_Object *cdl_pd = get_spec_object(spec, pd);
    for (unsigned int slot_index = 0; slot_index < CDL_Obj_NumSlots(cdl_pd); slot_index++) {
        map_page_table_slots(spec, pd, CDL_Obj_GetSlot(cdl_pd, slot_index));
    }
}
#endif

static void init_vspace(CDL_Model *spec)
{
    ZF_LOGD("Initialising VSpaces...");

#if defined(CONFIG_ARCH_X86_64) || defined(CONFIG_ARCH_AARCH64) || defined(CONFIG_ARCH_RISCV)
    /* Have no understanding of the logic of model of whatever the hell the
       other code in this function is doing as it is pure gibberish. For
       x86_64 and aarch64 we will just do the obvious recursive initialization */
    ZF_LOGD("================================");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_TOP_LEVEL_PD) {
            ZF_LOGD(" Initialising top level %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            if (CDL_PT_NUM_LEVELS == 4) {
                init_level_0(spec, obj_id, 0, obj_id);
            } else if (CDL_PT_NUM_LEVELS == 3) {
                init_level_1(spec, obj_id, 0, obj_id);
            } else if (CDL_PT_NUM_LEVELS == 2) {
                init_level_2(spec, obj_id, 0, obj_id);
            } else {
                ZF_LOGF("Unsupported CDL_PT_NUM_LEVELS value: \"%d\"", CDL_PT_NUM_LEVELS);
            }
        }
    }
#else
    ZF_LOGD("================================");
    ZF_LOGD("Initialising page directories...");

    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_PD) {
            ZF_LOGD(" Initialising page directory %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            map_page_directory(spec, obj_id);
        }
    }

    ZF_LOGD("===========================");
    ZF_LOGD("Initialising page tables...");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_PD) {
            ZF_LOGD(" Initialising page tables in %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            map_page_directory_page_tables(spec, obj_id);
        }
    }
#endif
}

static bool ep_related_cap(CDL_CapType cap)
{
    switch (cap) {
    case CDL_EPCap:
    case CDL_NotificationCap:
    case CDL_ReplyCap:
        return true;
    default:
        return false;
    }
}

/* Initialise capability spaces */
static void init_cnode_slot(CDL_Model *spec, init_cnode_mode mode, CDL_ObjID cnode_id, CDL_CapSlot *cnode_slot)
{
    CDL_Cap *target_cap = CDL_CapSlot_Cap(cnode_slot);
    CDL_ObjID target_cap_obj = CDL_Cap_ObjID(target_cap);
    CDL_IRQ target_cap_irq = CDL_Cap_IRQ(target_cap);

    CDL_CapType target_cap_type = CDL_Cap_Type(target_cap);
    seL4_CapRights_t target_cap_rights = CDL_seL4_Cap_Rights(target_cap);

    // For endpoint this is the badge, for cnodes, this is the (encoded) guard.
    seL4_Word target_cap_data = get_capData(CDL_Cap_Data(target_cap));

    /* To support moving original caps, we need a spec with a CDT (most don't).
     * This shoud probably become a separate configuration option for when to
     * use the CDT, and when to just copy. For now, let's just copy.
     */
    bool move_cap = false; //FIXME
    bool is_ep_cap = ep_related_cap(target_cap_type);
    bool is_irq_handler_cap = (target_cap_type == CDL_IRQHandlerCap);
    bool is_frame_cap = (target_cap_type == CDL_FrameCap);

    CDL_Object *dest_obj = get_spec_object(spec, cnode_id);
    uint8_t dest_size = CDL_Obj_SizeBits(dest_obj);

    // Use a copy of the cap to reference the destination, in case the original has already been moved.
    seL4_CPtr dest_root = dup_caps(cnode_id);
    int dest_index = CDL_CapSlot_Slot(cnode_slot);
    uint8_t dest_depth = dest_size;

    // Use an original cap to reference the object to copy.
    seL4_CPtr src_root = seL4_CapInitThreadCNode;
    int src_index;
    switch (target_cap_type) {
#ifdef CONFIG_ARCH_X86
    case CDL_IOSpaceCap:
        src_index = seL4_CapIOSpace;
        break;
#endif
#if defined(CONFIG_ARCH_ARM)
    case CDL_ARMIOSpaceCap:
        src_index = first_arm_iospace + target_cap_data;
        target_cap_data = seL4_NilData;
        break;
#endif
    case CDL_IRQHandlerCap:
        src_index = irq_caps(target_cap_irq);
        break;
    case CDL_IRQControlCap:
        /* there's only one */
        src_index = seL4_CapIRQControl;
        move_cap = true;
        is_irq_handler_cap = true;
        break;
    case CDL_SchedControlCap:
        src_index = sched_ctrl_caps(CDL_Cap_ObjID(target_cap));
        break;
    case CDL_DomainCap:
        /* there's only one */
        src_index = seL4_CapDomain;
        move_cap = false;
        break;
    case CDL_ASIDControlCap:
        /* there's only one */
        src_index = seL4_CapASIDControl;
        move_cap = false;
        break;
    default:
        src_index = orig_caps(target_cap_obj);
        break;
    }

    uint8_t src_depth = CONFIG_WORD_SIZE;

    if (mode == MOVE && move_cap) {
        if (is_ep_cap || is_irq_handler_cap) {
            ZF_LOGD("moving...");
            int error = seL4_CNode_Move(dest_root, dest_index, dest_depth,
                                        src_root, src_index, src_depth);
            ZF_LOGF_IFERR(error, "");
        } else {
            ZF_LOGD("mutating (with badge/guard %p)...", (void *)target_cap_data);
            int error = seL4_CNode_Mutate(dest_root, dest_index, dest_depth,
                                          src_root, src_index, src_depth, target_cap_data);
            ZF_LOGF_IFERR(error, "");
        }
    } else if (mode == COPY && !move_cap) {
        if (is_frame_cap && target_cap->mapping_container_id != INVALID_OBJ_ID) {
            ZF_LOGD("moving mapped...");
            /* The spec requires the frame cap in the current slot be the same one
             * used to perform the mapping of the frame in some container (either
             * a page table or page directory). */
            CDL_ObjID container_id = target_cap->mapping_container_id;
            seL4_Word slot_index = target_cap->mapping_slot;

            /* Look up the container object which contains the mapping. */
            CDL_Object *container = get_spec_object(spec, container_id);
            assert(container);
            /* When the frame was mapped in, a copy of the cap was first created,
             * and the copy used for the mapping. This copy is the cap that must
             * be moved into the current slot. */
            CDL_Cap *frame_cap = get_cap_at(container, slot_index);
            assert(frame_cap);
            assert(frame_cap->type == CDL_FrameCap);
            seL4_CPtr mapped_frame_cap = frame_cap->mapped_frame_cap;

            /* Move the cap to the frame used for the mapping into the destination slot. */
            int error = seL4_CNode_Move(dest_root, dest_index, dest_depth,
                                        src_root, mapped_frame_cap, src_depth);
            ZF_LOGF_IFERR(error, "");
        } else {
            ZF_LOGD("minting (with badge/guard %p)...", (void *)target_cap_data);
            int error = seL4_CNode_Mint(dest_root, dest_index, dest_depth,
                                        src_root, src_index, src_depth, target_cap_rights, target_cap_data);
            ZF_LOGF_IFERR(error, "");
        }
    } else {
        ZF_LOGV("skipping");
    }
}

static void init_cnode(CDL_Model *spec, init_cnode_mode mode, CDL_ObjID cnode)
{
    CDL_Object *cdl_cnode = get_spec_object(spec, cnode);
    for (unsigned int slot_index = 0; slot_index < CDL_Obj_NumSlots(cdl_cnode); slot_index++) {
        if (CDL_Obj_GetSlot(cdl_cnode, slot_index)->cap.type == CDL_IRQHandlerCap) {
            CDL_IRQ UNUSED irq = CDL_Obj_GetSlot(cdl_cnode, slot_index)->cap.irq;
            ZF_LOGD("  Populating slot %d with cap to IRQ %d, name %s...",
                    CDL_Obj_GetSlot(cdl_cnode, slot_index)->slot, irq,
                    CDL_Obj_Name(&spec->objects[spec->irqs[irq]]));
        } else {
            ZF_LOGD("  Populating slot %d with cap to %s...",
                    CDL_Obj_GetSlot(cdl_cnode, slot_index)->slot,
                    CDL_Obj_Name(&spec->objects[CDL_Obj_GetSlot(cdl_cnode, slot_index)->cap.obj_id]));
        }
        init_cnode_slot(spec, mode, cnode, CDL_Obj_GetSlot(cdl_cnode, slot_index));
    }
}

static void init_cspace(CDL_Model *spec)
{
    ZF_LOGD("Copying Caps...");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_CNode) {
            ZF_LOGD(" Copying into %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            init_cnode(spec, COPY, obj_id);
        }
    }

    ZF_LOGD("Moving Caps...");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_CNode) {
            ZF_LOGD(" Moving into %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            init_cnode(spec, MOVE, obj_id);
        }
    }
}

static void start_threads(CDL_Model *spec)
{
    ZF_LOGD("Starting threads...");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_TCB && spec->objects[obj_id].tcb_extra.resume) {
            ZF_LOGD(" Starting %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            seL4_CPtr tcb = orig_caps(obj_id);
            int error = seL4_TCB_Resume(tcb);
            ZF_LOGF_IFERR(error, "");
        }
    }
}


static void init_copy_addr(seL4_BootInfo *bi)
{
    /* We need a page sized and aligned region at which to map the
     * destination frame during loading. We know we have free memory
     * after the end of our binary image + any additional frames
     * the kernel has mapped. The kernel maps 1 frame for IPC buffer
     * 1 frame for bootinfo and on some platforms additional extended
     * bootinfo frames. So we skip these frames and then round up to
     * the next 16mb alignment where we can map in a pagetable.
     */
    uintptr_t bi_start = (uintptr_t)bi;
    copy_addr = ROUND_UP(bi_start + PAGE_SIZE_4K + bi->extraLen, 0x1000000);
}

static void cache_extended_bootinfo_headers(seL4_BootInfo *bi)
{
    uintptr_t cur = (uintptr_t)bi + PAGE_SIZE_4K;
    uintptr_t end = cur + bi->extraLen;

    while (cur < end) {
        seL4_BootInfoHeader *header = (seL4_BootInfoHeader *)cur;
        extended_bootinfo_table[header->id] = header;
        cur += header->len;
    }
}

static void fill_frame_with_bootinfo(uintptr_t base, CDL_FrameFill_Element_t frame_fill)
{
    CDL_FrameFill_BootInfoEnum_t bi_type = frame_fill.bi_type.type;
    switch (bi_type) {
    case CDL_FrameFill_BootInfo_X86_VBE:
    case CDL_FrameFill_BootInfo_X86_TSC_Freq:
    case CDL_FrameFill_BootInfo_FDT:
        break;
    default:
        ZF_LOGF("Unable to parse extra information for \"bootinfo\", given \"%d\"",
                bi_type);
    }

    uintptr_t dest = base + frame_fill.dest_offset;
    size_t max_len = frame_fill.dest_len;
    size_t block_offset = frame_fill.bi_type.src_offset;
    seL4_BootInfoHeader *header = extended_bootinfo_table[bi_type];

    /* Check if the bootinfo has been found */
    if (header) {
        /* Don't copy past the bootinfo */
        size_t copy_len = header->len < block_offset ? 0 : header->len - block_offset;
        /* Don't copy more than what the frame can hold */
        copy_len = MIN(copy_len, max_len);
        void *copy_start = (void *) header + block_offset;
        memcpy((void *) dest, copy_start, copy_len);
    } else {
        /* Bootinfo hasn't been found.
         * If we're at the start of a block, copy an empty header across, otherwise skip the copy */
        if (block_offset == 0) {
            seL4_BootInfoHeader empty = (seL4_BootInfoHeader) {
                .id = -1, .len = -1
            };
            size_t copy_len = MIN(sizeof(empty), max_len);
            memcpy((void *)base, &empty, copy_len);
        }
    }
}

static void fill_frame_with_filedata(uintptr_t base, CDL_FrameFill_Element_t frame_fill)
{
    unsigned long file_size;
    unsigned long cpio_size = _capdl_archive_end - _capdl_archive;
    const void *file = cpio_get_file(_capdl_archive, cpio_size, frame_fill.file_data_type.filename, &file_size);
    memcpy((void *)base + frame_fill.dest_offset, file + frame_fill.file_data_type.file_offset, frame_fill.dest_len);
}

static void init_frame(CDL_Model *spec, CDL_ObjID obj_id, CDL_FrameFill_Element_t frame_fill)
{
    seL4_CPtr cap = orig_caps(obj_id);

    /* get the cap to the original object */
    /* try a large mapping */
    uintptr_t base = (uintptr_t)copy_addr;
    int error = seL4_ARCH_Page_Map(cap, seL4_CapInitThreadPD, (seL4_Word)copy_addr,
                                   seL4_ReadWrite, seL4_ARCH_Default_VMAttributes);
    if (error == seL4_FailedLookup) {
        /* try a small mapping */
        base = (uintptr_t)copy_addr_with_pt;
        error = seL4_ARCH_Page_Map(cap, seL4_CapInitThreadPD, (seL4_Word)copy_addr_with_pt,
                                   seL4_ReadWrite, seL4_ARCH_Default_VMAttributes);
    }
    ZF_LOGF_IFERR(error, "");

    ssize_t max = BIT(spec->objects[obj_id].size_bits) - frame_fill.dest_offset;
    ZF_LOGF_IF(frame_fill.dest_len > max, "Bad spec, fill frame with len larger than frame size");

    /* Check for which type */
    switch (frame_fill.type) {
    case CDL_FrameFill_BootInfo:
        fill_frame_with_bootinfo(base, frame_fill);
        break;
    case CDL_FrameFill_FileData:
        fill_frame_with_filedata(base, frame_fill);
        break;
    default:
        ZF_LOGF("Unsupported frame fill type %u", frame_fill.type);
    }

    /* Unmap the frame */
    error = seL4_ARCH_Page_Unmap(cap);
    ZF_LOGF_IFERR(error, "");
}

static void init_frames(CDL_Model *spec)
{
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_Frame) {
            for (int i = 0; i < CONFIG_CAPDL_LOADER_FILLS_PER_FRAME
                 && spec->objects[obj_id].frame_extra.fill[i].type != CDL_FrameFill_None; i++) {
                CDL_FrameFill_Element_t frame_fill = spec->objects[obj_id].frame_extra.fill[i];
                init_frame(spec, obj_id, frame_fill);
            }
        }
    }
}

static void init_scs(CDL_Model *spec)
{
    ZF_LOGD(" Initialising SCs");
    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        if (spec->objects[obj_id].type == CDL_SchedContext) {
            ZF_LOGD(" Initialising %s...", CDL_Obj_Name(&spec->objects[obj_id]));
            /* all scs get configured on core 0, any scs that should be bound to a tcb will
               be reconfigured for the correct core in init_tcbs */
            init_sc(spec, obj_id, 0);
        }
    }
}

#ifdef CONFIG_ARCH_RISCV
/**
 * RISC-V uses a PageTable object as all table objects in the address structure.
 * in several places this loader assumes that the root VSpace object is a unique
 * object type and can be iterated over in the spec for performing operations on
 * a vspace_root. This function updates the CDL object type of all PageTables that
 * exist in a TCB VSpace slot to CDL_PT_ROOT_ALIAS which allows the rest of the
 * loader to treat the roots as unique objects.
 */
static void mark_vspace_roots(CDL_Model *spec)
{
    ZF_LOGD("Marking top level PageTables as CDL_PT_ROOT_ALIAS...");

    for (CDL_ObjID obj_id = 0; obj_id < spec->num; obj_id++) {
        CDL_ObjectType type = CDL_TCB;
        if (spec->objects[obj_id].type == type) {
            CDL_ObjID root = CDL_Cap_ObjID(get_cap_at(get_spec_object(spec, obj_id), CDL_TCB_VTable_Slot));
            ZF_LOGD(" Updating vspace_root: %d", root);
            spec->objects[root].type = CDL_PT_ROOT_ALIAS;
        }
    }
}
#endif


static void init_system(CDL_Model *spec)
{
    seL4_BootInfo *bootinfo = platsupport_get_bootinfo();
    simple_t simple;

    cache_extended_bootinfo_headers(bootinfo);
    init_copy_addr(bootinfo);

    simple_default_init_bootinfo(&simple, bootinfo);

    init_copy_frame(bootinfo);

    parse_bootinfo(bootinfo, spec);

    create_objects(spec, bootinfo);
#ifdef CONFIG_ARCH_RISCV
    /*
     * This needs to be called after create_objects as it modifies parts of the
     * spec that create_objects uses, but are _hopefully_ safe to change after.
     */
    mark_vspace_roots(spec);
#endif
    create_irq_caps(spec);
    if (config_set(CONFIG_KERNEL_MCS)) {
        create_sched_ctrl_caps(bootinfo);
    }
    duplicate_caps(spec);

    init_irqs(spec);
    init_pd_asids(spec);
    init_frames(spec);
    init_vspace(spec);
    init_scs(spec);
    init_tcbs(spec);
    init_cspace(spec);
    start_threads(spec);

    ZF_LOGD("%d of %d CSlots used (%.2LF%%)", get_free_slot(),
            BIT(CONFIG_ROOT_CNODE_SIZE_BITS),
            ((long double)get_free_slot() / BIT(CONFIG_ROOT_CNODE_SIZE_BITS))
            * 100);

}

#ifdef CONFIG_DEBUG_BUILD
/* We need to give malloc enough memory for musllibc to allocate memory
 * for stdin, stdout, and stderr. */
extern char *morecore_area;
extern size_t morecore_size;
#define DEBUG_LIBC_MORECORE_SIZE 4096
static char debug_libc_morecore_area[DEBUG_LIBC_MORECORE_SIZE];

static void CONSTRUCTOR(MUSLCSYS_WITH_VSYSCALL_PRIORITY) init_bootinfo(void)
{
    /* Init memory area for musl. */
    morecore_area = debug_libc_morecore_area;
    morecore_size = DEBUG_LIBC_MORECORE_SIZE;

    /* Allow us to print via seL4_Debug_PutChar. */
    platsupport_serial_setup_bootinfo_failsafe();
}
#endif

int main(void)
{
    ZF_LOGI("Starting CapDL Loader...");
    init_system(&capdl_spec);
    ZF_LOGI(A_RESET A_FG_G "CapDL Loader done, suspending..." A_RESET "");
    seL4_TCB_Suspend(seL4_CapInitThreadTCB);
}
