/*
 * Copyright 2014, NICTA
 *
 * 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(NICTA_BSD)
 */

#include <autoconf.h>

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <sel4/sel4.h>
#include <sel4debug/debug.h>
#include <simple-default/simple-default.h>

#include <vspace/page.h>

void *simple_default_get_frame_info(void *data, void *paddr, int size_bits, seL4_CPtr *frame_cap, seL4_Word *offset) {
    assert(data && paddr && frame_cap);

    seL4_BootInfo *bi = (seL4_BootInfo *) data;

    int i;
    seL4_DeviceRegion* region;

    *offset = 0;
    *frame_cap = seL4_CapNull;
    region = bi->deviceRegions;
    for(i = 0; i < bi->numDeviceRegions; i++, region++){
        seL4_Word region_start = region->basePaddr;
        seL4_Word n_caps = region->frames.end - region->frames.start;
        seL4_Word region_end = region_start + (n_caps << region->frameSizeBits);
        if(region_start <= (seL4_Word) paddr &&
           (seL4_Word) paddr < region_end &&
           region->frameSizeBits == size_bits) {

            *frame_cap =  region->frames.start + (((seL4_Word) paddr - region->basePaddr) >> region->frameSizeBits);
            i = bi->numDeviceRegions;
        }
    }

    return NULL;
}
seL4_Error simple_default_get_frame_cap(void *data, void *paddr, int size_bits, cspacepath_t *path) {
    assert(data && paddr);

    seL4_CPtr frame_cap;
    seL4_Word offset;
    simple_default_get_frame_info(data,paddr, size_bits, &frame_cap, &offset);
    if (frame_cap == seL4_CapNull) {
        return seL4_FailedLookup;
    }
    return seL4_CNode_Copy(path->root, path->capPtr, path->capDepth, seL4_CapInitThreadCNode, frame_cap, 32, seL4_AllRights);
}

seL4_CPtr simple_default_get_ut_cap(void *data, void *paddr, int size_bits) {
    assert(data && paddr);

    seL4_CPtr frame_cap;
    seL4_Word offset;

    simple_default_get_frame_info(data, paddr, size_bits, &frame_cap, &offset);

    return frame_cap;
}

void *simple_default_get_frame_mapping(void *data, void *paddr, int size_bits) {
    return NULL;
}

seL4_Error simple_default_set_ASID(void *data, seL4_CPtr vspace) {
    return seL4_ARCH_ASIDPool_Assign(seL4_CapInitThreadASIDPool, vspace);
}

int simple_default_cap_count(void *data) {
    assert(data);

    seL4_BootInfo * bi = (seL4_BootInfo *) data;

    int device_caps = 0;
    int i;
    for(i = 0; i < bi->numDeviceRegions; i++) {
        device_caps += bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start;
    }

    return (device_caps)
           + (bi->sharedFrames.end - bi->sharedFrames.start)
           + (bi->userImageFrames.end - bi->userImageFrames.start)
           + (bi->userImagePaging.end - bi->userImagePaging.start)
           + (bi->untyped.end - bi->untyped.start)
           + seL4_NumInitialCaps; //Include all the init caps
}

seL4_CPtr simple_default_nth_cap(void *data, int n) {
    assert(data);

    seL4_BootInfo * bi = (seL4_BootInfo *) data;
    size_t shared_frame_range = bi->sharedFrames.end - bi->sharedFrames.start + seL4_NumInitialCaps;
    size_t user_img_frame_range = bi->userImageFrames.end - bi->userImageFrames.start + shared_frame_range;
    size_t user_img_paging_range = bi->userImagePaging.end - bi->userImagePaging.start + user_img_frame_range;
    size_t untyped_range = bi->untyped.end - bi->untyped.start + user_img_paging_range;

    int i;
    int device_caps = 0;
    seL4_CPtr true_return = seL4_CapNull;

    for(i = 0; i < bi->numDeviceRegions; i++) {
        device_caps += bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start;
    }

    size_t device_range = device_caps + untyped_range;

    if (n < seL4_CapInitThreadASIDPool) {
        true_return = (seL4_CPtr) n+1;
    } else if (n < seL4_NumInitialCaps) {
        true_return = (seL4_CPtr) n+1;
#if defined(CONFIG_ARCH_ARM)
        true_return++;
#endif
#ifndef CONFIG_IOMMU
        if(true_return >= seL4_CapIOSpace) {
            true_return++;
        }
#endif
    } else if (n < shared_frame_range) {
        return bi->sharedFrames.start + (n - seL4_NumInitialCaps);
    } else if (n < user_img_frame_range) {
        return bi->userImageFrames.start + (n - shared_frame_range);
    } else if (n < user_img_paging_range) {
        return bi->userImagePaging.start + (n - user_img_frame_range);
    } else if (n < untyped_range) {
        return bi->untyped.start + (n - user_img_paging_range);
    } else if (n < device_range) {
        i = 0;
        int current_count = 0;
        while((bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start) +
               current_count < (n - untyped_range)) {
            current_count += bi->deviceRegions[i].frames.end - bi->deviceRegions[i].frames.start;
            i++;
        }
        return bi->deviceRegions[i].frames.start + (n - untyped_range - current_count);
    }

    return true_return;
}

seL4_CPtr simple_default_init_cap(void *data, seL4_CPtr cap_pos) {
    return (seL4_CPtr) cap_pos;
}

uint8_t simple_default_cnode_size(void *data) {
    assert(data);

    return ((seL4_BootInfo *)data)->initThreadCNodeSizeBits;
}

int simple_default_untyped_count(void *data) {
    assert(data);

    return ((seL4_BootInfo *)data)->untyped.end - ((seL4_BootInfo *)data)->untyped.start;
}

seL4_CPtr simple_default_nth_untyped(void *data, int n, uint32_t *size_bits, uint32_t *paddr) {
    assert(data && size_bits && paddr);

    seL4_BootInfo *bi = (seL4_BootInfo *)data;

    if(n < (bi->untyped.end - bi->untyped.start)) {
        if(paddr != NULL) {
            *paddr = bi->untypedPaddrList[n];
        }
        if(size_bits != NULL) {
            *size_bits = bi->untypedSizeBitsList[n];
        }
        return bi->untyped.start + (n);
    }

    return seL4_CapNull;
}

int simple_default_userimage_count(void *data) {
    assert(data);

    return ((seL4_BootInfo *)data)->userImageFrames.end - ((seL4_BootInfo *)data)->userImageFrames.start;
}

seL4_CPtr simple_default_nth_userimage(void *data, int n) {
    assert(data);

    seL4_BootInfo *bi = (seL4_BootInfo *)data;

    if(n < (bi->userImageFrames.end - bi->userImageFrames.start)) {
        return bi->userImageFrames.start + (n);
    }

    return seL4_CapNull;
}

void simple_default_print(void *data) {
    if (data == NULL) {
        ZF_LOGE("Data is null!");
    }

    debug_print_bootinfo((seL4_BootInfo *) data);
}

void simple_default_init_bootinfo(simple_t *simple, seL4_BootInfo *bi) {
    assert(simple);
    assert(bi);

    simple->data = bi;
    simple->frame_info = &simple_default_get_frame_info;
    simple->frame_cap = &simple_default_get_frame_cap;
    simple->frame_mapping = &simple_default_get_frame_mapping;
    simple->ASID_assign = &simple_default_set_ASID;
    simple->cap_count = &simple_default_cap_count;
    simple->nth_cap = &simple_default_nth_cap;
    simple->init_cap = &simple_default_init_cap;
    simple->cnode_size = &simple_default_cnode_size;
    simple->untyped_count = &simple_default_untyped_count;
    simple->nth_untyped = &simple_default_nth_untyped;
    simple->userimage_count = &simple_default_userimage_count;
    simple->nth_userimage = &simple_default_nth_userimage;
    simple->print = &simple_default_print;
    simple_default_init_arch_simple(&simple->arch_simple, NULL);
}

