#include <lunaix/types.h>
#include <lunaix/hart_state.h>
+#include <lunaix/device.h>
+
+#include <hal/devtree.h>
typedef void (*isr_cb)(const struct hart_state*);
+typedef struct {
+ ptr_t msi_addr;
+ reg_t msi_data;
+ int mapped_iv;
+} msi_vector_t;
+#define msi_addr(msiv) ((msiv).msi_addr)
+#define msi_data(msiv) ((msiv).msi_data)
+#define msi_vect(msiv) ((msiv).mapped_iv)
+#define check_msiv_invalid(msiv) (msi_vect(msiv) == -1)
+#define invalid_msi_vector ((msi_vector_t) { (ptr_t)-1, (reg_t)-1, -1 });
+
+typedef void* msienv_t;
+
void
isrm_init();
isrm_ivfree(int iv);
/**
- * @brief Allocate an iv resource for os services
+ * @brief Begin MSI allocation for given device
*
* @param iv
*/
-int
-isrm_ivosalloc(isr_cb handler);
+msienv_t
+isrm_msi_start(struct device* dev);
/**
- * @brief Allocate an iv resource for external events
- *
- * @param iv
+ * @brief Query number of msi avaliable for the device
*/
int
-isrm_ivexalloc(isr_cb handler);
+isrm_msi_avaliable(msienv_t msienv);
/**
- * @brief Bind a given irq and associated handler to an iv
- *
- * @param iv iv allocated by system
+ * @brief Allocate a msi resource within defined msi resource list
+ * for the device, indexed by `index`
*/
-int
-isrm_bindirq(int irq, isr_cb irq_handler);
+msi_vector_t
+isrm_msi_alloc(msienv_t msienv, cpu_t cpu, int index, isr_cb handler);
/**
- * @brief Bind given iv with it's associated handler
- *
- * @param iv
- * @param handler
+ * @brief Set the sideband information will be used for upcoming
+ * allocations
+ */
+void
+isrm_msi_set_sideband(msienv_t msienv, ptr_t sideband);
+
+/**
+ * @brief Done MSI allocation
*/
void
-isrm_bindiv(int iv, isr_cb handler);
+isrm_msi_done(msienv_t msienv);
+
+static inline must_inline msi_vector_t
+isrm_msi_alloc_simple(struct device* dev, cpu_t cpu, isr_cb handler)
+{
+ msi_vector_t v;
+ msienv_t env;
+
+ env = isrm_msi_start(dev);
+ v = isrm_msi_alloc(env, cpu, 0, handler);
+ isrm_msi_done(env);
+
+ return v;
+}
+
+/**
+ * @brief Bind the iv according to given device tree node
+ *
+ * @param node
+ */
+int
+isrm_bind_dtn(struct dt_intr_node* node);
/**
* @brief Get the handler associated with the given iv
void
isrm_set_payload(int iv, ptr_t);
-void
-isrm_irq_attach(int irq, int iv, cpu_t dest, u32_t flags);
-
/**
* @brief Notify end of interrupt event
*