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

#include <assert.h>

#include <sel4/sel4.h>
#include <vka/object.h>
#include <vka/capops.h>

#include "../helpers.h"

/* Arbitrarily start mapping 256mb into the virtual address range */
#define IOPT_MAP_BASE 0x10000000

/* None of these tests actually check that mappings succeed sensibly. This would
 * require having a device that does DMA and making it perform operations.
 * I consider this too much work, and am largely checking that none of these
 * operations will cause the kernel to explode */

#define MAX_IOPT_DEPTH 8

/* The depth at which we expect the last PT to be at before 4K frame
 * mappings. This is 'expected' depth as the actual depth can change
 * per machine. Ideally this value should be exported from the kernel */
#define EXPECTED_PT_DEPTH 3

typedef struct iopt_cptrs {
    int depth;
    seL4_CPtr pts[MAX_IOPT_DEPTH];
} iopt_cptrs_t;

#define FAKE_PCI_DEVICE 0x216u
#define DOMAIN_ID       0xf

#ifdef CONFIG_IOMMU

static int map_iopt_from_iospace(env_t env, seL4_CPtr iospace, iopt_cptrs_t *pts, seL4_CPtr *frame)
{
    int error = seL4_NoError;

    pts->depth = 0;
    /* Allocate and map page tables until we can map a frame */
    *frame = vka_alloc_frame_leaky(&env->vka, seL4_PageBits);
    test_assert(*frame);

    while (seL4_X86_Page_MapIO(*frame, iospace, seL4_AllRights, IOPT_MAP_BASE) == seL4_FailedLookup) {
        test_assert(pts->depth < MAX_IOPT_DEPTH);
        pts->pts[pts->depth] = vka_alloc_io_page_table_leaky(&env->vka);
        test_assert(pts->pts[pts->depth]);
        error = seL4_X86_IOPageTable_Map(pts->pts[pts->depth], iospace, IOPT_MAP_BASE);
        test_eq(error, seL4_NoError);
        pts->depth++;
    }
    test_eq(error, seL4_NoError);

    return error;
}

static int map_iopt_set(env_t env, seL4_CPtr *iospace, iopt_cptrs_t *pts, seL4_CPtr *frame)
{
    int error;
    cspacepath_t master_path, iospace_path;

    /* Allocate a random device ID that hopefully doesn't exist have any
     * RMRR regions */
    error = vka_cspace_alloc(&env->vka, iospace);
    test_error_eq(error, seL4_NoError);
    vka_cspace_make_path(&env->vka, *iospace, &iospace_path);
    vka_cspace_make_path(&env->vka, env->io_space, &master_path);
    error = vka_cnode_mint(&iospace_path, &master_path, seL4_AllRights, (DOMAIN_ID << 16) | FAKE_PCI_DEVICE);
    test_eq(error, seL4_NoError);

    error = map_iopt_from_iospace(env, *iospace, pts, frame);

    return error;
}

static void delete_iospace(env_t env, seL4_CPtr iospace)
{
    cspacepath_t path;
    vka_cspace_make_path(&env->vka, iospace, &path);
    vka_cnode_delete(&path);
}

static int test_iopt_basic_iopt(env_t env)
{
    int error;
    seL4_CPtr iospace, frame;
    iopt_cptrs_t pts;
    error = map_iopt_set(env, &iospace, &pts, &frame);
    test_eq(error, seL4_NoError);

    delete_iospace(env, iospace);
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0001, "Testing basic IOPT mapping", test_iopt_basic_iopt, true)

static int
test_iopt_basic_map_unmap(env_t env)
{
    int error;
    int i;
    iopt_cptrs_t pts;
    seL4_CPtr iospace, frame;
    error = map_iopt_set(env, &iospace, &pts, &frame);
    test_eq(error, seL4_NoError);

    error = seL4_X86_Page_Unmap(frame);
    test_eq(error, seL4_NoError);
    for (i = pts.depth - 1; i >= 0; i--) {
        error = seL4_X86_IOPageTable_Unmap(pts.pts[i]);
        test_eq(error, seL4_NoError);
    }

    error = map_iopt_from_iospace(env, iospace, &pts, &frame);
    test_eq(error, seL4_NoError);

    for (i = 0; i < pts.depth; i++) {
        error = seL4_X86_IOPageTable_Unmap(pts.pts[i]);
        test_eq(error, seL4_NoError);
    }

    error = seL4_X86_Page_Unmap(frame);
    test_eq(error, seL4_NoError);

    delete_iospace(env, iospace);
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0002, "Test basic IOPT mapping then unmapping", test_iopt_basic_map_unmap, true)

static int
test_iopt_no_overlapping_4k(env_t env)
{
    int error;
    iopt_cptrs_t pts;
    seL4_CPtr iospace, frame;
    error = map_iopt_set(env, &iospace, &pts, &frame);
    test_eq(error, seL4_NoError);

    frame = vka_alloc_frame_leaky(&env->vka, seL4_PageBits);
    test_assert(frame);
    error = seL4_X86_Page_MapIO(frame, iospace, seL4_AllRights, IOPT_MAP_BASE);
    test_assert(error != seL4_NoError);

    delete_iospace(env, iospace);
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0004, "Test IOPT cannot map overlapping 4k pages", test_iopt_no_overlapping_4k, true)

static int
test_iopt_map_remap_top_pt(env_t env)
{
    int error;
    iopt_cptrs_t pts;
    seL4_CPtr iospace, frame, pt;
    error = map_iopt_set(env, &iospace, &pts, &frame);
    test_eq(error, seL4_NoError);

    /* unmap the top PT */
    error = seL4_X86_IOPageTable_Unmap(pts.pts[EXPECTED_PT_DEPTH]);
    test_eq(error, seL4_NoError);

    /* now map it back in */
    error = seL4_X86_IOPageTable_Map(pts.pts[EXPECTED_PT_DEPTH], iospace, IOPT_MAP_BASE);
    test_eq(error, seL4_NoError);

    /* it should retain its old mappings, and mapping in a new PT should fail */
    pt = vka_alloc_io_page_table_leaky(&env->vka);
    test_assert(pt);
    error = seL4_X86_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE);
    test_assert(error != seL4_NoError);

    delete_iospace(env, iospace);
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0008, "Test IOPT map and remap top PT", test_iopt_map_remap_top_pt, true)

static int
test_iopt_no_overlapping_pt(env_t env)
{
    int error;
    iopt_cptrs_t pts;
    seL4_CPtr iospace, frame, pt;
    error = map_iopt_set(env, &iospace, &pts, &frame);
    test_eq(error, seL4_NoError);

    /* Mapping in a new PT should fail */
    pt = vka_alloc_io_page_table_leaky(&env->vka);
    test_assert(pt);
    error = seL4_X86_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE);
    test_assert(error != seL4_NoError);

    delete_iospace(env, iospace);
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0009, "Test iopt no overlapping PT", test_iopt_no_overlapping_pt, true)

static int
test_iopt_map_remap_pt(env_t env)
{
    int error;
    iopt_cptrs_t pts;
    seL4_CPtr iospace, frame;
    error = map_iopt_set(env, &iospace, &pts, &frame);
    test_eq(error, seL4_NoError);

    /* unmap the pt */
    error = seL4_X86_IOPageTable_Unmap(pts.pts[pts.depth - 1]);
    test_eq(error, seL4_NoError);

    /* now map it back in */
    error = seL4_X86_IOPageTable_Map(pts.pts[pts.depth - 1], iospace, IOPT_MAP_BASE);
    test_eq(error, seL4_NoError);

    /* it should retain its old mappings, and mapping in a new frame should fail */
    frame = vka_alloc_frame_leaky(&env->vka, seL4_PageBits);
    test_assert(frame);
    error = seL4_X86_Page_MapIO(frame, iospace, seL4_AllRights, IOPT_MAP_BASE);
    test_assert(error != seL4_NoError);

    delete_iospace(env, iospace);
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0011, "Test IOPT map and remap PT", test_iopt_map_remap_pt, true)

#endif /* CONFIG_IOMMU */

#ifdef CONFIG_TK1_SMMU
/* tests for ARM SystemMMU */

#define IOPT_MAP_BASE   0x10000000

static int
map_iopt_from_iospace(env_t env, seL4_CPtr iospace, seL4_CPtr *iopt, seL4_CPtr *frame)
{
    int error;
    *frame = vka_alloc_frame_leaky(&env->vka, seL4_PageBits);
    test_assert(*frame);
    error = seL4_ARM_Page_MapIO(*frame, iospace, seL4_AllRights, IOPT_MAP_BASE);

    if (error == seL4_FailedLookup) {
        *iopt = vka_alloc_io_page_table_leaky(&env->vka);
        test_assert(*iopt);
        error = seL4_ARM_IOPageTable_Map(*iopt, iospace, IOPT_MAP_BASE);
        test_eq(error, seL4_NoError);
        error = seL4_ARM_Page_MapIO(*frame, iospace, seL4_AllRights, IOPT_MAP_BASE);
        test_eq(error, seL4_NoError);
    }
    test_eq(error, seL4_NoError);

    return error;

}

static int map_iopt_set(env_t env, seL4_CPtr iospace, seL4_CPtr *iopt_cptr, seL4_CPtr *frame)
{
    int error = map_iopt_from_iospace(env, iospace, iopt_cptr, frame);
    return error;

}

static void delete_iospace(env_t env, seL4_CPtr iospace)
{
    cspacepath_t path;
    vka_cspace_make_path(&env->vka, iospace, &path);
    vka_cnode_delete(&path);
}

static int test_iopt_basic_iopt(env_t env)
{
    int error;
    seL4_CPtr pt = 0;
    seL4_CPtr frame = 0;
    seL4_SlotRegion caps = env->io_space_caps;
    int cap_count = caps.end - caps.start + 1;
    seL4_CPtr cap = caps.start;

    for (int i = 0; i < cap_count; i++) {
        error = map_iopt_set(env, cap + i, &pt, &frame);
        test_eq(error, seL4_NoError);
        delete_iospace(env, cap + i);
    }
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0001, "Testing basic ARM IOPT mapping", test_iopt_basic_iopt, true);

static int test_iopt_basic_map_unmap(env_t env)
{
    int error;
    int i;
    seL4_CPtr iospace, pt, frame;
    seL4_SlotRegion caps = env->io_space_caps;
    int cap_count = caps.end - caps.start + 1;

    for (i = 0; i < cap_count; i++) {
        iospace = caps.start + i;
        error = map_iopt_set(env, iospace, &pt, &frame);
        test_eq(error, seL4_NoError);

        error = seL4_ARM_Page_Unmap(frame);
        test_eq(error, seL4_NoError);

        error = seL4_ARM_IOPageTable_Unmap(pt);
        test_eq(error, seL4_NoError);

        error = map_iopt_from_iospace(env, iospace, &pt, &frame);
        test_eq(error, seL4_NoError);

        error = seL4_ARM_IOPageTable_Unmap(pt);
        test_eq(error, seL4_NoError);
        error = seL4_ARM_Page_Unmap(frame);
        test_eq(error, seL4_NoError);
        delete_iospace(env, iospace);
    }
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0002, "Test basic ARM IOPT mapping then unmapping", test_iopt_basic_map_unmap, true)

static int
test_iopt_no_overlapping_4k(env_t env)
{
    int error;
    int i;
    seL4_CPtr iospace, pt, frame;
    seL4_SlotRegion caps = env->io_space_caps;
    int cap_count = caps.end - caps.start + 1;
    for (i = 0; i < cap_count; i++) {
        iospace = caps.start + i;
        error = map_iopt_set(env, iospace, &pt, &frame);
        test_eq(error, seL4_NoError);

        frame = vka_alloc_frame_leaky(&env->vka, seL4_PageBits);
        test_assert(frame);
        /* mapping in a new frame should fail */
        error = seL4_ARM_Page_MapIO(frame, iospace, seL4_AllRights, IOPT_MAP_BASE);
        test_assert(error != seL4_NoError);
        delete_iospace(env, iospace);
    }

    return sel4test_get_result();
}
DEFINE_TEST(IOPT0004, "Test ARM IOPT cannot map overlapping 4k pages", test_iopt_no_overlapping_4k, true)

static int
test_iopt_map_remap_pt(env_t env)
{
    int error;
    int i;
    seL4_CPtr iospace, pt, frame;
    seL4_SlotRegion caps = env->io_space_caps;
    int cap_count = caps.end - caps.start + 1;
    for (i = 0; i < cap_count; i++) {
        iospace = caps.start + i;
        error = map_iopt_set(env, iospace, &pt, &frame);
        test_eq(error, seL4_NoError);

        /* unmap the PT */
        error = seL4_ARM_IOPageTable_Unmap(pt);
        test_eq(error, seL4_NoError);

        /* now map it back in */
        error = seL4_ARM_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE);
        test_eq(error, seL4_NoError);

        /* it should retain its old mappings, and mapping in a new PT should fail */
        pt = vka_alloc_io_page_table_leaky(&env->vka);
        test_assert(pt);
        error = seL4_ARM_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE);
        test_assert(error != seL4_NoError);
        delete_iospace(env, iospace);
    }

    return sel4test_get_result();
}
DEFINE_TEST(IOPT0008, "Test ARM IOPT map and remap PT", test_iopt_map_remap_pt, true)

static int
test_iopt_no_overlapping_pt(env_t env)
{
    int error;
    int i;
    seL4_CPtr iospace, pt, frame;
    seL4_SlotRegion caps = env->io_space_caps;
    int cap_count = caps.end - caps.start + 1;
    for (i = 0; i < cap_count; i++) {
        iospace = caps.start + i;
        error = map_iopt_set(env, iospace, &pt, &frame);
        test_eq(error, seL4_NoError);

        /* Mapping in a new PT should fail */
        pt = vka_alloc_io_page_table_leaky(&env->vka);
        test_assert(pt);
        error = seL4_ARM_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE);
        test_assert(error != seL4_NoError);
        delete_iospace(env, iospace);
    }
    return sel4test_get_result();
}
DEFINE_TEST(IOPT0009, "Test ARM iopt no overlapping PT", test_iopt_no_overlapping_pt, true)

#endif
