]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c
Update RISCC-V-RV32-SiFive_HiFive1_FreedomStudio project to latest tools and metal...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_FreedomStudio / freedom-metal / src / drivers / riscv_plic0.c
index ed9782450036a69fc6ea21e66a7d8c7202a05a12..3272f1c669e971dcfb9f0f2b0e9105dc1995431d 100644 (file)
@@ -25,30 +25,47 @@ void __metal_plic0_complete_interrupt(struct __metal_driver_riscv_plic0 *plic,
                                       METAL_RISCV_PLIC0_CLAIM)) = id;
 }
 
-void __metal_plic0_set_threshold(struct __metal_driver_riscv_plic0 *plic,
-                              unsigned int threshold)
+int __metal_plic0_set_threshold(struct metal_interrupt *controller, unsigned int threshold)
 {
-    unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
+    unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller);
     __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
                                       METAL_RISCV_PLIC0_THRESHOLD)) = threshold;
+    return 0;
 }
 
-void __metal_plic0_set_priority(struct __metal_driver_riscv_plic0 *plic,
-                             int id, unsigned int priority)
+unsigned int __metal_plic0_get_threshold(struct metal_interrupt *controller)
 {
-    unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
-    int max_priority = __metal_driver_sifive_plic0_max_priority((struct metal_interrupt *)plic);
+    unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller);
+
+    return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
+                                      METAL_RISCV_PLIC0_THRESHOLD));
+}
+
+int __metal_plic0_set_priority(struct metal_interrupt *controller, int id, unsigned int priority)
+{
+    unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)controller);
+    unsigned int max_priority = __metal_driver_sifive_plic0_max_priority((struct metal_interrupt *)controller);
     if ( (max_priority) && (priority < max_priority) ) {
         __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
                                           METAL_RISCV_PLIC0_PRIORITY_BASE +
                                           (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))) = priority;
+        return 0;
     }
+    return -1;
+}
+
+unsigned int __metal_plic0_get_priority(struct metal_interrupt *controller, int id)
+{
+    unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller);
+
+    return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
+                                          METAL_RISCV_PLIC0_PRIORITY_BASE +
+                                          (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT)));
 }
 
 void __metal_plic0_enable(struct __metal_driver_riscv_plic0 *plic, int id, int enable)
 {
     unsigned int current;
-    unsigned long hartid = __metal_myhart_id();
     unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
 
     current = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
@@ -69,7 +86,7 @@ void __metal_plic0_handler (int id, void *priv)
 {
     struct __metal_driver_riscv_plic0 *plic = priv;
     unsigned int idx = __metal_plic0_claim_interrupt(plic);
-    int num_interrupts = __metal_driver_sifive_plic0_num_interrupts((struct metal_interrupt *)plic);
+    unsigned int num_interrupts = __metal_driver_sifive_plic0_num_interrupts((struct metal_interrupt *)plic);
 
     if ( (idx < num_interrupts) && (plic->metal_exint_table[idx]) ) {
        plic->metal_exint_table[idx](idx,
@@ -97,13 +114,13 @@ void __metal_driver_riscv_plic0_init (struct metal_interrupt *controller)
 
            for (int i = 0; i < num_interrupts; i++) {
                __metal_plic0_enable(plic, i, METAL_DISABLE);
-               __metal_plic0_set_priority(plic, i, 0);
+               __metal_plic0_set_priority(controller, i, 0);
                plic->metal_exint_table[i] = NULL;
                plic->metal_exdata_table[i].sub_int = NULL;
                plic->metal_exdata_table[i].exint_data = NULL;
            }
 
-           __metal_plic0_set_threshold(plic, 0);
+           __metal_plic0_set_threshold(controller, 0);
 
            /* Register plic (ext) interrupt with with parent controller */
            intc->vtable->interrupt_register(intc, line, NULL, plic);
@@ -127,11 +144,11 @@ int __metal_driver_riscv_plic0_register (struct metal_interrupt *controller,
     }
  
     if (isr) {
-        __metal_plic0_set_priority(plic ,id, 2);
+        __metal_plic0_set_priority(controller, id, 2);
        plic->metal_exint_table[id] = isr;
        plic->metal_exdata_table[id].exint_data = priv;
     } else {
-        __metal_plic0_set_priority(plic, id, 1);
+        __metal_plic0_set_priority(controller, id, 1);
        plic->metal_exint_table[id] = __metal_plic0_default_handler;
        plic->metal_exdata_table[id].sub_int = priv;
     }
@@ -167,6 +184,12 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_plic0) = {
     .plic_vtable.interrupt_register = __metal_driver_riscv_plic0_register,
     .plic_vtable.interrupt_enable   = __metal_driver_riscv_plic0_enable,
     .plic_vtable.interrupt_disable  = __metal_driver_riscv_plic0_disable,
+    .plic_vtable.interrupt_get_threshold  = __metal_plic0_get_threshold,
+    .plic_vtable.interrupt_set_threshold  = __metal_plic0_set_threshold,
+    .plic_vtable.interrupt_get_priority  = __metal_plic0_get_priority,
+    .plic_vtable.interrupt_set_priority  = __metal_plic0_set_priority,
 };
 
 #endif /* METAL_RISCV_PLIC0 */
+
+typedef int no_empty_translation_units;