/*
 * Copyright (c) 2021 Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/****************************************************************************
 * Includes
 ****************************************************************************/

// Ethos-U
#include "ethosu_driver.h"

// Trustzone defines and MPC driver
#include "trustzone.h"
#include "mpc_sie_drv.h"
#include "../common/secure_entries.hpp"

#include "inference_process.hpp"

// System includes
#include <arm_cmse.h>
#include <inttypes.h>
#include <stdio.h>

using namespace std;

funcptr_ns nonsecure_result_checker = 0;

/****************************************************************************
 * InferenceJob
 ****************************************************************************/

#define TENSOR_ARENA_SIZE 0xa0000
__attribute__((section(".bss.tensor_arena"), aligned(16))) uint8_t TFLuTensorArena[TENSOR_ARENA_SIZE];

InferenceProcess::InferenceProcess inferenceProcess(TFLuTensorArena, TENSOR_ARENA_SIZE);

/****************************************************************************
 * Functions
 ****************************************************************************/

namespace {

#include "model.h"
#include "input.h"
#include "output.h"

} // namespace

#define N_MEM_RANGES (2)
static int setup_sram0_mpc(const uint32_t baseaddr_s,  /* Secure base address */
                           const uint32_t len_s,       /* Length (in bytes) of secure region */
                           const uint32_t baseaddr_ns, /* Non-secure base address */
                           const uint32_t len_ns)      /* Length (in bytes) of non-secure region */
{
    const char *mem_name = "SRAM0";

    /* Secure range */
    const struct mpc_sie_memory_range_t mpc_range_s = {.base         = SRAM0_BASE_S,
                                                       .limit        = SRAM0_BASE_S + SRAM0_SIZE - 1,
                                                       .range_offset = 0,
                                                       .attr         = MPC_SIE_SEC_ATTR_SECURE};

    /* Non secure range */
    const struct mpc_sie_memory_range_t mpc_range_ns = {.base         = SRAM0_BASE_NS,
                                                        .limit        = SRAM0_BASE_NS + SRAM0_SIZE - 1,
                                                        .range_offset = 0,
                                                        .attr         = MPC_SIE_SEC_ATTR_NONSECURE};

    /* Consolidated ranges */
    const struct mpc_sie_memory_range_t *mpc_range_list[N_MEM_RANGES] = {&mpc_range_s, &mpc_range_ns};

    /* MPC device configuration controller */
    const struct mpc_sie_dev_cfg_t mpc_dev_cfg = {.base = SRAM0_MPC};

    /* MPC device data */
    struct mpc_sie_dev_data_t mpc_dev_data = {0};

    /* MPC device itself */
    struct mpc_sie_dev_t mpc_dev = {&mpc_dev_cfg, &mpc_dev_data};

    enum mpc_sie_error_t ret = MPC_SIE_ERR_NONE;

    printf("Configuring MPC for %s\n", mem_name);

    /* Initialise this MPC device */
    ret = mpc_sie_init(&mpc_dev, mpc_range_list, N_MEM_RANGES);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error initialising MPC for %s\n", mem_name);
        return 1;
    }

    /* Configure the non secure region */
    ret = mpc_sie_config_region(&mpc_dev, baseaddr_ns, baseaddr_ns + len_ns - 1, MPC_SIE_SEC_ATTR_NONSECURE);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error configuring non-secure region for %s (%d)\n", mem_name, ret);
        return 1;
    }

    /* Configure the secure region */
    ret = mpc_sie_config_region(&mpc_dev, baseaddr_s, baseaddr_s + len_s - 1, MPC_SIE_SEC_ATTR_SECURE);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error configuring secure region for %s\n", mem_name);
        return 1;
    }

    /* Lock down the configuration */
    ret = mpc_sie_lock_down(&mpc_dev);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error locking down MPC for %s\n", mem_name);
        return 1;
    }

    return 0;
}

#define N_MEM_RANGES (2)
static int setup_bram_mpc(const uint32_t baseaddr_s,  /* Secure base address */
                          const uint32_t len_s,       /* Length (in bytes) of secure region */
                          const uint32_t baseaddr_ns, /* Non-secure base address */
                          const uint32_t len_ns)      /* Length (in bytes) of non-secure region */
{
    const char *mem_name = "BRAM";

    /* Secure range */
    const struct mpc_sie_memory_range_t mpc_range_s = {
        .base         = BRAM_BASE_S,
        .limit        = BRAM_BASE_S + BRAM_TOTAL_SIZE - 1,
        .range_offset = 0,
        .attr         = MPC_SIE_SEC_ATTR_SECURE
    };

    /* Non secure range */
    const struct mpc_sie_memory_range_t mpc_range_ns = {
        .base         = BRAM_BASE_NS,
        .limit        = BRAM_BASE_NS + BRAM_TOTAL_SIZE - 1,
        .range_offset = 0,
        .attr         = MPC_SIE_SEC_ATTR_NONSECURE
    };

    /* Consolidated ranges */
    const struct mpc_sie_memory_range_t *mpc_range_list[N_MEM_RANGES] = {&mpc_range_s, &mpc_range_ns};

    /* MPC device configuration controller */
    const struct mpc_sie_dev_cfg_t mpc_dev_cfg = {.base = BRAM_MPC};

    /* MPC device data */
    struct mpc_sie_dev_data_t mpc_dev_data = {0};

    /* MPC device itself */
    struct mpc_sie_dev_t mpc_dev = {&mpc_dev_cfg, &mpc_dev_data};

    enum mpc_sie_error_t ret = MPC_SIE_ERR_NONE;

    printf("Configuring MPC for %s\n", mem_name);

    /* Initialise this MPC device */
    ret = mpc_sie_init(&mpc_dev, mpc_range_list, N_MEM_RANGES);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error initialising MPC for %s\n", mem_name);
        return 1;
    }

    /* Configure the non secure region */
    ret = mpc_sie_config_region(&mpc_dev, baseaddr_ns, baseaddr_ns + len_ns - 1, MPC_SIE_SEC_ATTR_NONSECURE);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error configuring non-secure region for %s (%d)\n", mem_name, ret);
        return 1;
    }

    /* Configure the secure region */
    ret = mpc_sie_config_region(&mpc_dev, baseaddr_s, baseaddr_s + len_s - 1, MPC_SIE_SEC_ATTR_SECURE);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error configuring secure region for %s (%d)\n", mem_name, ret);
        return 1;
    }

    /* Lock down the configuration */
    ret = mpc_sie_lock_down(&mpc_dev);
    if (MPC_SIE_ERR_NONE != ret) {
        printf("Error locking down MPC for %s (%d)\n", mem_name, ret);
        return 1;
    }

    return 0;
}

/* Depending on the Cortex-M configuration the LUT for the xTGU has
 * different size, set a maximum value to target all cases
 */
#define MAX_BLK_NBR (32)
void setup_xtgu_ns(uint32_t xtgu_base, uint32_t xtcm_start, uint32_t xtcm_size) {
    struct xtgu {
        uint32_t ctrl;
        uint32_t cfg;
        uint32_t reserved[2];
        uint32_t lut[];
    } *xtgu                            = (struct xtgu *)xtgu_base;
    uint32_t lut_bit_mask[MAX_BLK_NBR] = {0};

    /* Mask of the base offset of the I-/DTCM memory */
    xtcm_start &= 0x00ffffff;

    /* Read out xTGU configuration */
    uint32_t BLKSZ       = 1 << (((xtgu->cfg) & 0xf) + 5);

    if (xtcm_start % BLKSZ != 0)
        printf("XTCM: start address %08x not on block size boundary\n", xtcm_start);

    if ((xtcm_start + xtcm_size) % BLKSZ != 0)
        printf("XTCM: limit address %08x not on block size boundary\n", xtcm_start + xtcm_size);

    printf("setting up xTGU LUT for mem@%08x(%08x)\n", xtcm_start, xtcm_size);

    uint32_t xtcm_end        = xtcm_start + xtcm_size - 1;
    uint32_t xtcm_address    = xtcm_start;
    uint32_t block_idx_start = (xtcm_address / BLKSZ) / 32;
    uint32_t block_idx_end;

    while (xtcm_address < xtcm_end) {
        uint32_t block_nbr = xtcm_address / BLKSZ;
        uint32_t block_idx = block_nbr / 32;
        uint32_t block_bit = 1 << (block_nbr % 32);

        if (block_idx >= MAX_BLK_NBR) {
            printf("lut bit mask too small, aborting!\n");
            exit(1);
        }
        lut_bit_mask[block_idx] |= block_bit;

        xtcm_address += BLKSZ;
        if (block_idx != block_idx_end)
            block_idx_end = block_idx;
    }

    /* Commit the LUT to the xTGU */
    for (uint32_t i = block_idx_start; i <= block_idx_end; i++) {
        xtgu->lut[i] = lut_bit_mask[i];
    }
}

int setup_secure_attributes(void) {
    int res;
    /* Setup ITGU and DTGU to give non-secure state access to ITCM and DTCM memory. */
    /* NS Code */
    setup_xtgu_ns(ITCM_ITGU, TZ_NS_ITCM_START, TZ_NS_ITCM_SIZE);

    /* NS stack location in DTCM */
    setup_xtgu_ns(DTCM_DTGU, TZ_NS_DTCM_START, TZ_NS_DTCM_SIZE);

    res = setup_bram_mpc(TZ_S_BRAM_START, TZ_S_BRAM_SIZE, TZ_NS_BRAM_START, TZ_NS_BRAM_SIZE);
    printf("BRAM MPC %s\n", res ? "Failed" : "OK");

    /* The SRAM has an MPC for each SRAM bank. Configure the first one for non-secure accesses here. */
    res = setup_sram0_mpc(TZ_S_SRAM_START, TZ_S_SRAM_SIZE, TZ_NS_SRAM_START, TZ_NS_SRAM_SIZE);
    printf("SRAM MPC %s\n", res ? "Failed" : "OK");

    /*
     * The IDAU is default not non-secure callable. In order for the code ram and data ram to be
     * non-secure callable the NSCCFG (at 0x50080014) has to be configured.
     * The register description can be found here:
     *    https://developer.arm.com/documentation/101773/0000
     * bit 0 : Sets NSC for 0x10000000-0x1fffffff
     * bit 1 : Sets NSC for 0x30000000-0x3fffffff
     */
    uint32_t *NSCCFG = (uint32_t *)(0x50080014);
    *NSCCFG          = 0x1;
    printf("NSCCFG set NSC for CODE SRAM 0x10000000-0x1fffffff\n");

    return 0;
}

void boot_non_secure() {
    /* Boot the non-secure world */
    typedef void (*ns_func)(void) __attribute__((cmse_nonsecure_call));
    ns_func NS_ResetHandler;

    printf("Setting NS MSP : 0x%x\n", *(uint32_t *)TZ_NS_START_VECTOR);
    /* Setup non-secure stack */
    __TZ_set_MSP_NS(*(uint32_t *)TZ_NS_START_VECTOR);

    /* Setup non-secure reset vector */
    printf("Setting NS VTOR : 0x%x\n", TZ_NS_START_VECTOR);
    SCB_NS->VTOR = TZ_NS_START_VECTOR;

    /* Enable features */
#if (defined(__FPU_USED) && (__FPU_USED == 1U)) || (defined(__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0U))
    SCB_NS->CPACR |= ((3U << 10U * 2U) | /* enable CP10 Full Access */
                      (3U << 11U * 2U)); /* enable CP11 Full Access */
#endif

#ifdef UNALIGNED_SUPPORT_DISABLE
    SCB_NS->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
#endif

    // Enable Loop and branch info cache
    SCB_NS->CCR |= SCB_CCR_LOB_Msk;
    __ISB();

    /* Call cmse_ function to mark function as transition to non-secure state. */
    NS_ResetHandler = (ns_func)cmse_nsfptr_create(*(ns_func *)(TZ_NS_START_VECTOR + 4U));
    printf("Setting NS_ResetHandler to: %p\n", NS_ResetHandler);

    /* Now we've read the NS memory, setup our secure world compartment. */
    setup_secure_attributes();

    /* Enable SAU, we are ready to jump to non-secure. */
    SAU->CTRL = 1;

    printf("Leaving secure world.\n");
    /* Leave secure state. */
    NS_ResetHandler();
}

int main() {
    int ret = -1;
    printf("Secure main starting up.\n");
    SCB->CCR |= SCB_CCR_BFHFNMIGN_Msk;

    SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk |
                  SCB_SHCSR_SECUREFAULTENA_Msk; // enable Usage-/Bus-/MPU-/Secure Fault

    boot_non_secure();

    printf("We're back in secure world!\n");

    if (nonsecure_result_checker != 0) {
        ret = nonsecure_result_checker();
    }

    return ret;
}

/****************************************************************************
 * Secure gateway functions to be callable from non-secure world
 ****************************************************************************/

uint8_t outputData[1001] __attribute__((aligned(4), section("output_data_sec")));

int run_inference(void) {
    vector<InferenceProcess::DataPtr> input;
    input.push_back(InferenceProcess::DataPtr(inputData, sizeof(inputData)));

    vector<InferenceProcess::DataPtr> output;
    output.push_back(InferenceProcess::DataPtr(outputData, sizeof(outputData)));

    vector<InferenceProcess::DataPtr> expected;
    expected.push_back(InferenceProcess::DataPtr(expectedData, sizeof(expectedData)));

    InferenceProcess::InferenceJob job(
        "secure", InferenceProcess::DataPtr(networkModelData, sizeof(networkModelData)), input, output, expected, 512, std::vector<uint8_t>(4), false);

    bool failed = inferenceProcess.runJob(job);
    printf("Status of executing the job: ");
    printf(failed ? "failed\n" : "success\n");

    return failed;
}

extern "C" int __attribute__((cmse_nonsecure_entry)) run_secure_inference(void) {
    return run_inference();
}

extern "C" void __attribute__((cmse_nonsecure_entry)) nonsecure_print(const char *p) {
    // Printing from non-secure, create RED ouput
    printf("\033[31;1m");
    printf("NS: %s\n", p);
    printf("\033[0m");
}

extern "C" void __attribute__((cmse_nonsecure_entry)) set_result_function(funcptr_ns callback_fn) {
    nonsecure_result_checker = callback_fn;
}
