/* _NVRM_COPYRIGHT_BEGIN_
 *
 * Copyright 2018-2021 by NVIDIA Corporation.  All rights reserved.  All
 * information contained herein is proprietary and confidential to NVIDIA
 * Corporation.  Any use, reproduction, or disclosure without the written
 * permission of NVIDIA Corporation is prohibited.
 *
 * _NVRM_COPYRIGHT_END_
 */

#ifndef CPU__CACHE_H
#define CPU__CACHE_H
#define FSP__CPU__CACHE_H                       1

/* Compiler headers */
#include <stddef.h>
#include <stdint.h>

/**
 * @file cache.h
 * @brief Interfaces for performing Cache operations.
 */

#define RISCV_CACHE_LINE_SIZE    64UL

/**
 * @brief Type to specify the kind of address to use
 */
typedef enum
{
	RISCV_ADDRESS_TYPE_VA = 0,
	RISCV_ADDRESS_TYPE_PA = 1,
} ADDRESS_TYPE;

/**
 * @brief Disable all caches
 *
 * This function will disable the iCache and dCache.  It will also ensure
 * before this function returns.
 *
 * @return none
 *
 * @note
 * - M-mode only.
 * - Should we have to do an explicit check or assert for M-mode.
 * - Currently not implemented because there was no previous implementation in
 *   libnvriscv.
 */
static inline void cache_disable(void) {}

/**
 * @brief Enable all caches
 *
 * This function will enable the iCache and dCache.  It will ensure that
 * the contents of the caches are invalid (e.g. there is no data or instructions
 * in the cache) before enabling the caches.
 *
 * @return none
 *
 * @note
 * - M-mode only.
 * - Should we have to do an explicit check or assert for M-mode.
 * - Currently not implemented because there was no previous implementation in
 *   libnvriscv.
 */
static inline void cache_enable(void) {}

/**
 * @brief Invalidate the entire iCache
 *
 * This function will cause the entire icache contents to be invalidated.
 *
 * @return none
 */
void icache_invalidate_all(void);

/**
 * @brief Invalidate a region of dCache
 *
 * This function will cause the specified region in the dCache to be
 * invalidated.  That is, that data will no longer reside in the dCache
 * at the completion of this function.
 *
 * If the specified range does not align with integral numbers of
 * cache lines, more data may be invalidated than was actually specified.
 *
 * @param[in] base:   Address of start of range to be invalidated
 * @param[in] length: Number of bytes in the range to be invalidated
 *
 * @return none
 */
void dcache_invalidate(void * const base, const size_t length);

/**
 * @brief Invalidate region of dCache using either PA or VA
 *
 * This function will cause the specified region in the dCache to be
 * invalidated.  That is, that data will no longer reside in the dCache
 * at the completion of this function.
 *
 * The addresses to invalidate may be specified to be either a
 * virtual address or a physical address.
 *
 * If the specified range does not align with integral numbers of
 * cache lines, more data may be invalidated than was actually specified.
 *
 * @param[in] base:   Address of start of range to be invalidated
 * @param[in] length: Number of bytes in the range to be invalidated
 * @param[out] address_type: Type of address being passed as argument
 *
 * @return none
 */
void dcache_invalidate_address_type(void * const base, const size_t length, ADDRESS_TYPE address_type);

/**
 * @brief Invalidate entire dCache
 *
 * This function will cause the entire dCache to be invalidated
 *
 * @return none
 */
void dcache_invalidate_all(void);

/**
 * @brief Invalidate a region of dCache
 *
 * This function will cause the specified region in the dCache to be
 * invalidated.  That is, that data will no longer reside in the dCache
 * at the completion of this function.
 *
 * If the specified range does not align with integral numbers of
 * cache lines, more data may be invalidated than was actually specified.
 *
 * @param[in] base:   Address of start of range to be invalidated
 * @param[in] length: Number of bytes in the range to be invalidated
 *
 * @return none
 *
 * @deprecated dcache_invalidate() should be used instead.
 */
void cache_invalidate(void * const base, const size_t length);

/**
 * @brief Clean a region of dCache
 *
 * This function will cause any "dirty" data in the dCache in the
 * specified range to be written back to memory.  The data may still
 * reside in the dCache (e.g. it was not invalidated).
 *
 * If the specified range does not align with integral numbers of
 * cache lines, more data may be "cleaned" than was actually specified.
 *
 * @param[in] base   Address of start of range to be cleaned
 * @param[in] length Number of bytes in the range to be cleaned
 *
 * @return none
 *
 * @deprecated dcache_clean() should be used instead.
 */
static inline void cache_clean(const void * const base, const size_t length) {}

#endif // FSP__CPU__CACHE_H
