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

#include <autoconf.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sel4/sel4.h>
#include <sel4utils/arch/util.h>

#include <vka/object.h>

#include "../test.h"
#include "../helpers.h"

#ifdef CONFIG_ARCH_X86

#define START_PORT 0
#define END_PORT BIT(16)
#define PORT_STRIDE 256
#define EXPECTED_FAULTS ((END_PORT - START_PORT) / PORT_STRIDE)

static volatile int total_faults = 0;

static void increment_pc(seL4_CPtr tcb, seL4_Word inc)
{
    seL4_UserContext ctx;
    seL4_Error error = seL4_TCB_ReadRegisters(tcb,
                                              false,
                                              0,
                                              sizeof(ctx) / sizeof(seL4_Word),
                                              &ctx);
    test_eq(error, seL4_NoError);
#ifdef CONFIG_ARCH_X86_64
    ctx.rax = 1;
    ctx.rip += inc;
#else
    ctx.eax = 1;
    ctx.eip += inc;
#endif
    error = seL4_TCB_WriteRegisters(tcb,
                                    true,
                                    0,
                                    sizeof(ctx) / sizeof(seL4_Word),
                                    &ctx);
    test_eq(error, seL4_NoError);
}

static int handle_fault(seL4_CPtr fault_ep, seL4_CPtr tcb, seL4_Word expected_fault, seL4_CPtr reply)
{
    seL4_MessageInfo_t tag;
    seL4_Word sender_badge = 0;

    while (1) {
        tag = api_recv(fault_ep, &sender_badge, reply);

        test_check(seL4_MessageInfo_get_label(tag) == seL4_Fault_UserException);

        total_faults++;
        increment_pc(tcb, 1);
    }

    return 0;
}

static int do_ioports(int arg1, int arg2, int arg3, int arg4)
{
    unsigned int i;
    for (i = START_PORT; i < END_PORT; i += PORT_STRIDE) {
        volatile unsigned char dummy = 0;
        asm volatile("inb %1,%0"
                     : "=a"(dummy)
                     : "dN"((uint16_t)i)
                    );
        test_check(dummy == 1);
    }
    return 0;
}

static int test_native_ioports(env_t env)
{
    helper_thread_t handler_thread;
    helper_thread_t faulter_thread;
    int error;
    seL4_Word handler_arg0, handler_arg1;
    /* The endpoint on which faults are received. */
    seL4_CPtr fault_ep = vka_alloc_endpoint_leaky(&env->vka);
    seL4_CPtr faulter_vspace, faulter_cspace;

    create_helper_thread(env, &faulter_thread);
    create_helper_thread(env, &handler_thread);
    faulter_cspace = env->cspace_root;
    faulter_vspace = env->page_directory;
    handler_arg0 = fault_ep;
    handler_arg1 = get_helper_tcb(&faulter_thread);
    set_helper_priority(env, &handler_thread, 100);

    error = api_tcb_set_space(get_helper_tcb(&faulter_thread),
                              fault_ep,
                              faulter_cspace,
                              api_make_guard_skip_word(seL4_WordBits - env->cspace_size_bits),
                              faulter_vspace, seL4_NilData);
    set_helper_priority(env, &faulter_thread, 100);

    test_error_eq(error, seL4_NoError);

    /* clear the faults */
    total_faults = 0;

    start_helper(env, &handler_thread, (helper_fn_t) handle_fault,
                 handler_arg0, handler_arg1, 0, get_helper_reply(&handler_thread));
    start_helper(env, &faulter_thread, (helper_fn_t) do_ioports,
                 0, 0, 0, 0);

    wait_for_helper(&faulter_thread);

    test_check(total_faults == EXPECTED_FAULTS);

    cleanup_helper(env, &handler_thread);
    cleanup_helper(env, &faulter_thread);

    return (total_faults == EXPECTED_FAULTS) ? SUCCESS : FAILURE;
}
DEFINE_TEST(IOPORTS1000, "Test fault if directly using I/O ports", test_native_ioports, true)

#endif
