/*
 * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * 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
 *
 *     http://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.
 */

#include "ethosu_cpu_cache.h"

#include "RTE_Components.h"         /* For CPU related defintiions */
#include "ethosu_driver.h"          /* Arm Ethos-U driver header */
#include "log_macros.h"             /* Logging macros */

/** Structure to maintain data cache states. */
typedef struct _cpu_cache_state {
    uint32_t dcache_invalidated : 1;
    uint32_t dcache_cleaned : 1;
} cpu_cache_state;

/** Static CPU cache state object.
 * @note This logic around flipping these states is based on the driver
 *       calling the functions in this sequence:
 *
 *       Cache flush (ethosu_flush_dcache)
 *                  ↓
 *       Start inference (ethosu_inference_begin)
 *                  ↓
 *       Inference (ethosu_dev_run_command_stream)
 *                  ↓
 *       End inference (ethosu_inference_end)
 *                  ↓
 *       Cache invalidate (ethosu_dcache_invalidate)
 **/
static cpu_cache_state s_cache_state = {.dcache_cleaned = 0, .dcache_invalidated = 0};

/**
 * @brief   Gets the current CPU cache state.
 * @return  Pointer to the CPU cache state object.
 */
static cpu_cache_state* ethosu_get_cpu_cache_state(void)
{
    return &s_cache_state;
}

void ethosu_clear_cache_states(void)
{
    cpu_cache_state* const state = ethosu_get_cpu_cache_state();
    trace("Clearing cache state members\n");
    state->dcache_invalidated = 0;
    state->dcache_cleaned     = 0;
}

void ethosu_flush_dcache(uint32_t *p, size_t bytes)
{
    UNUSED(p);
    UNUSED(bytes);
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    cpu_cache_state* const state = ethosu_get_cpu_cache_state();
    if (SCB->CCR & SCB_CCR_DC_Msk) {

        /**
         * @note We could choose to call the `SCB_CleanDCache_by_Addr` function
         *       here, but the sizes which this function is called for, can
         *       cause unnecessary delays. It's worth noting that this function
         *       is called from the Arm Ethos-U NPU drive repeatedly for each
         *       region it accesses. This could even be RO memory which does
         *       not need cache maintenance, along with parts of the input and
         *       output tensors which rightly need to be cleaned. Therefore, to
         *       reduce overhead of repeated calls for large memory sizes, we
         *       call the clean and invalidation functions for whole cache.
         *
         *       If the neural network to be executed is completely falling
         *       onto the NPU, consider disabling the data cache altogether
         *       for the duration of the inference to further reduce the cache
         *       maintenance burden in these functions.
         */

        /** Clean the cache if it hasn't been cleaned already  */
        if (!state->dcache_cleaned) {
            trace("Cleaning data cache\n");
            SCB_CleanDCache();

            /** Assert the cache cleaned state and clear the invalidation
             *  state. */
            state->dcache_cleaned     = 1;
            state->dcache_invalidated = 0;
        }
    }
#endif /* defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) */
}

void ethosu_invalidate_dcache(uint32_t *p, size_t bytes)
{
    UNUSED(p);
    UNUSED(bytes);
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    cpu_cache_state* const state = ethosu_get_cpu_cache_state();
    if (SCB->CCR & SCB_CCR_DC_Msk) {
        /**
         * See note in ethosu_flush_dcache function for why we clean the whole
         * cache instead of calling it for specific addresses.
         **/
        if (!state->dcache_invalidated) {
            trace("Invalidating data cache\n");
            SCB_InvalidateDCache();

            /** Assert the cache invalidation state and clear the clean
             *  state. */
            state->dcache_invalidated = 1;
            state->dcache_cleaned     = 0;
        }
    }
#endif /* defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) */
}
