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