/* Copyright 2018 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */

#ifndef METAL__INTERRUPT_H
#define METAL__INTERRUPT_H

/*! @file interrupt.h
 *  @brief API for registering and manipulating interrupts
 */

#include <stddef.h>

/*!
 * @brief Possible interrupt controllers
 */
typedef enum metal_interrupt_controller_ {
    METAL_CPU_CONTROLLER = 0,
    METAL_CLINT_CONTROLLER = 1,
    METAL_CLIC_CONTROLLER = 2,
    METAL_PLIC_CONTROLLER = 3
} metal_intr_cntrl_type;

/*!
 * @brief Possible mode of interrupts to operate
 */
typedef enum metal_vector_mode_ {
    METAL_DIRECT_MODE = 0,
    METAL_VECTOR_MODE = 1,
    METAL_SELECTIVE_NONVECTOR_MODE = 2,
    METAL_SELECTIVE_VECTOR_MODE = 3,
    METAL_HARDWARE_VECTOR_MODE = 4
} metal_vector_mode;

/*!
 * @brief Possible mode of privilege interrupts to operate
 */
typedef enum metal_intr_priv_mode_ {
    METAL_INTR_PRIV_M_MODE = 0,
    METAL_INTR_PRIV_MU_MODE = 1,
    METAL_INTR_PRIV_MSU_MODE = 2
} metal_intr_priv_mode;

/*!
 * @brief Function signature for interrupt callback handlers
 */
typedef void (*metal_interrupt_handler_t) (int, void *);
typedef void (*metal_interrupt_vector_handler_t) (void);

struct metal_interrupt;

struct metal_interrupt_vtable {
    void (*interrupt_init)(struct metal_interrupt *controller);
    int (*interrupt_set_vector_mode)(struct metal_interrupt *controller, metal_vector_mode mode);
    metal_vector_mode (*interrupt_get_vector_mode)(struct metal_interrupt *controller);
    int (*interrupt_set_privilege)(struct metal_interrupt *controller, metal_intr_priv_mode priv);
    metal_intr_priv_mode (*interrupt_get_privilege)(struct metal_interrupt *controller);
    int (*interrupt_clear)(struct metal_interrupt *controller, int id);
    int (*interrupt_set)(struct metal_interrupt *controller, int id);
    int (*interrupt_register)(struct metal_interrupt *controller, int id,
			      metal_interrupt_handler_t isr, void *priv_data);
    int (*interrupt_vector_register)(struct metal_interrupt *controller, int id,
                              metal_interrupt_vector_handler_t isr, void *priv_data);
    int (*interrupt_enable)(struct metal_interrupt *controller, int id);
    int (*interrupt_disable)(struct metal_interrupt *controller, int id);
    int (*interrupt_vector_enable)(struct metal_interrupt *controller, int id);
    int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id);
    unsigned int (*interrupt_get_threshold)(struct metal_interrupt *controller);
    int (*interrupt_set_threshold)(struct metal_interrupt *controller, unsigned int threshold);
    unsigned int (*interrupt_get_priority)(struct metal_interrupt *controller, int id);
    int (*interrupt_set_priority)(struct metal_interrupt *controller, int id, unsigned int priority);
    int (*command_request)(struct metal_interrupt *controller, int cmd, void *data);
    int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time);
};

/*!
 * @brief A handle for an interrupt
 */
struct metal_interrupt {
    const struct metal_interrupt_vtable *vtable;
};

/*!
 * @brief Initialize a given interrupt controller
 *
 * Initialize a given interrupt controller. This function must be called
 * before any interrupts are registered or enabled with the handler. It
 * is invalid to initialize an interrupt controller more than once.
 *
 * @param controller The handle for the interrupt controller
 */
__inline__ void metal_interrupt_init(struct metal_interrupt *controller)
{
    controller->vtable->interrupt_init(controller);
}

/*!
 * @brief Get the handle for an given interrupt controller type
 * @param cntrl The type ofinterrupt controller
 * @param id The instance of the interrupt controller
 * @return A handle to the interrupt controller (CLINT, CLIC, PLIC), or
 * NULL if none is found for the requested label
 */
struct metal_interrupt* metal_interrupt_get_controller(metal_intr_cntrl_type cntrl,
                                                       int id);

/*!
 * @brief Configure vector mode for an interrupt controller
 *
 * Configure vector mode for an interrupt controller.
 * This function must be called after initialization and before
 * configuring individual interrupts, registering ISR.
 *
 * @param controller The handle for the interrupt controller
 * @param mode The vector mode of the interrupt controller.
 * @return 0 upon success
 */
__inline__ int metal_interrupt_set_vector_mode(struct metal_interrupt *controller,
                                               metal_vector_mode mode)
{
    return controller->vtable->interrupt_set_vector_mode(controller, mode);
}

/*!
 * @brief Get vector mode of a given an interrupt controller
 *
 * Configure vector mode for an interrupt controller.
 * This function must be called after initialization and before
 * configuring individual interrupts, registering ISR.
 *
 * @param controller The handle for the interrupt controller
 * @param mode The vector mode of the interrupt controller.
 * @return The interrupt vector mode
 */
__inline__ metal_vector_mode metal_interrupt_get_vector_mode(struct metal_interrupt *controller)
{
    return controller->vtable->interrupt_get_vector_mode(controller);
}

/*!
 * @brief Configure privilege mode a of given interrupt controller
 *
 * Configure privilege mode for a given interrupt controller.
 * This function must be called after initialization and before
 * configuring individual interrupts, registering ISR.
 *
 * @param controller The handle for the interrupt controller
 * @param privilege The privilege mode of the interrupt controller.
 * @return 0 upon success
 */
__inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller,
                                             metal_intr_priv_mode privilege)
{
    return controller->vtable->interrupt_set_privilege(controller, privilege);
}

/*!
 * @brief Get privilege mode a of given interrupt controller
 *
 * Get privilege mode for a given interrupt controller.
 * This function must be called after initialization and before
 * configuring individual interrupts, registering ISR.
 *
 * @param controller The handle for the interrupt controller
 * @return The interrupt privilege mode
 */
__inline__ metal_intr_priv_mode metal_interrupt_get_privilege(struct metal_interrupt *controller)
{
    return controller->vtable->interrupt_get_privilege(controller);
}

/*!
 * @brief clear an interrupt
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to trigger
 * @return 0 upon success
 */
__inline__ int metal_interrupt_clear(struct metal_interrupt *controller, int id)
{
    return controller->vtable->interrupt_clear(controller, id);
}                                         

/*!
 * @brief Set an interrupt
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to trigger
 * @return 0 upon success
 */
__inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id)
{
    return controller->vtable->interrupt_set(controller, id);
}

/*!
 * @brief Register an interrupt handler
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to register
 * @param handler The interrupt handler callback
 * @param priv_data Private data for the interrupt handler
 * @return 0 upon success
 */
__inline__ int metal_interrupt_register_handler(struct metal_interrupt *controller,
                                          int id,
                                          metal_interrupt_handler_t handler,
                                          void *priv_data)
{
    return controller->vtable->interrupt_register(controller, id, handler, priv_data);
}

/*!
 * @brief Register an interrupt vector handler
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to register
 * @param handler The interrupt vector handler callback
 * @param priv_data Private data for the interrupt handler
 * @return 0 upon success
 */
__inline__ int metal_interrupt_register_vector_handler(struct metal_interrupt *controller,
                                          int id,
                                          metal_interrupt_vector_handler_t handler,
                                          void *priv_data)
{
    return controller->vtable->interrupt_vector_register(controller, id, handler, priv_data);
}

/*!
 * @brief Enable an interrupt
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to enable
 * @return 0 upon success
 */
__inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id)
{
    return controller->vtable->interrupt_enable(controller, id);
}

/*!
 * @brief Disable an interrupt
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to disable
 * @return 0 upon success
 */
__inline__ int metal_interrupt_disable(struct metal_interrupt *controller, int id)
{
    return controller->vtable->interrupt_disable(controller, id);
}

/*!
 * @brief Set interrupt threshold level
 * @param controller The handle for the interrupt controller
 * @param threshold The interrupt threshold level
 * @return 0 upon success
 */
inline int metal_interrupt_set_threshold(struct metal_interrupt *controller, unsigned int level)
{
    return controller->vtable->interrupt_set_threshold(controller, level);
}

/*!
 * @brief Get an interrupt threshold level
 * @param controller The handle for the interrupt controller
 * @return The interrupt threshold level
 */
inline unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller)
{
  return controller->vtable->interrupt_get_threshold(controller);
}

/*!
 * @brief Set an interrupt priority level
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to enable
 * @param priority The interrupt priority level
 * @return 0 upon success
 */
inline int metal_interrupt_set_priority(struct metal_interrupt *controller,
					int id, unsigned int priority)
{
    return controller->vtable->interrupt_set_priority(controller, id, priority);
}

/*!
 * @brief Get an interrupt priority level
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to enable
 * @return The interrupt priority level
 */
inline unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id)
{
  return controller->vtable->interrupt_get_priority(controller, id);
}

/*!
 * @brief Enable an interrupt vector
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to enable
 * @return 0 upon success
 */
__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id)
{
    return controller->vtable->interrupt_vector_enable(controller, id);
}

/*!
 * @brief Disable an interrupt vector
 * @param controller The handle for the interrupt controller
 * @param id The interrupt ID to disable
 * @return 0 upon success
 */
__inline__ int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id)
{
    return controller->vtable->interrupt_vector_disable(controller, id);
}

/*!
 * @brief Default interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void);

/*!
 * @brief Metal Software interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_software_interrupt_vector_handler(void);

/*!
 * @brief Metal Timer interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_timer_interrupt_vector_handler(void);

/*!
 * @brief Metal External interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_external_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 0 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 1 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 2 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 3 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 4 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 5 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 6 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void);
    
/*!
 * @brief Metal Local 7 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 8 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 9 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 10 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 11 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 12 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 13 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 14 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler(void);

/*!
 * @brief Metal Local 15 interrupt vector handler, that can be overriden by user
 * @param None
 * @return None
 */
void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler(void);

/* Utilities function to controll, manages devices via a given interrupt controller */
__inline__ int _metal_interrupt_command_request(struct metal_interrupt *controller,
					 int cmd, void *data)
{
    return controller->vtable->command_request(controller, cmd, data);
}

#endif
