/*
 * 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
 ****************************************************************************/

#include "command_stream.hpp"

#include <inttypes.h>
#include <stdio.h>

using namespace std;

namespace EthosU {
namespace CommandStream {

/****************************************************************************
 * DataPointer
 ****************************************************************************/

DataPointer::DataPointer() : data(nullptr), size(0) {}

DataPointer::DataPointer(const char *_data, size_t _size) : data(_data), size(_size) {}

bool DataPointer::operator!=(const DataPointer &other) {
    if (size != other.size) {
        return true;
    }

    for (size_t i = 0; i < size; i++) {
        if (data[i] != other.data[i]) {
            return true;
        }
    }

    return false;
}

/****************************************************************************
 * PmuConfig
 ****************************************************************************/

Pmu::Pmu(ethosu_driver *_drv, const PmuEvents &_config) : drv(_drv), config(_config) {
    // Enable PMU block
    ETHOSU_PMU_Enable_v2(drv);

    // Enable cycle counter
    ETHOSU_PMU_CNTR_Enable_v2(drv, ETHOSU_PMU_CCNT_Msk);

    // Configure event types
    for (size_t i = 0; i < config.size(); i++) {
        ETHOSU_PMU_Set_EVTYPER_v2(drv, i, config[i]);
        ETHOSU_PMU_CNTR_Enable_v2(drv, 1 << i);
    }
}

void Pmu::clear() {
    ETHOSU_PMU_CYCCNT_Reset_v2(drv);
    ETHOSU_PMU_EVCNTR_ALL_Reset_v2(drv);
}

void Pmu::print() {
    printf("PMU={cycleCount=%llu, events=[%" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 "]}\n",
           ETHOSU_PMU_Get_CCNTR_v2(drv),
           ETHOSU_PMU_Get_EVCNTR_v2(drv, 0),
           ETHOSU_PMU_Get_EVCNTR_v2(drv, 1),
           ETHOSU_PMU_Get_EVCNTR_v2(drv, 2),
           ETHOSU_PMU_Get_EVCNTR_v2(drv, 3));
}

uint64_t Pmu::getCycleCount() const {
    return ETHOSU_PMU_Get_CCNTR_v2(drv);
}

uint32_t Pmu::getEventCount(size_t index) const {
    return ETHOSU_PMU_Get_EVCNTR_v2(drv, index);
}

/****************************************************************************
 * CommandStream
 ****************************************************************************/

CommandStream::CommandStream(const DataPointer &_commandStream,
                             const BasePointers &_basePointers,
                             const PmuEvents &_pmuEvents) :
    drv(ethosu_reserve_driver()),
    commandStream(_commandStream), basePointers(_basePointers), pmu(drv, _pmuEvents) {
    // Disable clock gating, else the NPU PMU will be clock gated and report too few cycles
    ethosu_set_clock_and_power(&drv->dev, ETHOSU_CLOCK_Q_DISABLE, ETHOSU_POWER_Q_DISABLE);

    // Use simplified driver setup
    ethosu_set_power_mode_v2(drv, true);
}

CommandStream::~CommandStream() {
    ethosu_set_power_mode_v2(drv, false);
    ethosu_release_driver(drv);
}

int CommandStream::run(size_t repeat) {
    // Base pointer array
    uint64_t baseAddress[ETHOSU_DRIVER_BASEP_INDEXES];
    size_t baseAddressSize[ETHOSU_DRIVER_BASEP_INDEXES];
    for (size_t i = 0; i < ETHOSU_DRIVER_BASEP_INDEXES; i++) {
        baseAddress[i]     = reinterpret_cast<uint64_t>(basePointers[i].data);
        baseAddressSize[i] = reinterpret_cast<size_t>(basePointers[i].size);
    }

    while (repeat-- > 0) {
        int error = ethosu_invoke_v3(
            drv, commandStream.data, commandStream.size, baseAddress, baseAddressSize, ETHOSU_DRIVER_BASEP_INDEXES);

        if (error != 0) {
            printf("Inference failed. error=%d\n", error);
            return 1;
        }

        // Wait for interrupt
        while (true) {
            uint16_t status;
            ethosu_get_status_mask(&drv->dev, &status);

            // Return if NPU raise error status
            if (status & 0xcc) {
                printf("Job failed with error. status=0x%08x\n", status);
                return 1;
            }

            // Break loop if job is no longer running
            if ((status & 1) == 0) {
                break;
            }

            // Sleep waiting on interrupt
            __WFI();
        }
    }

    return 0;
}

DataPointer &CommandStream::getCommandStream() {
    return commandStream;
}

BasePointers &CommandStream::getBasePointers() {
    return basePointers;
}

Pmu &CommandStream::getPmu() {
    return pmu;
}

}; // namespace CommandStream
}; // namespace EthosU
