X-Git-Url: https://git.sur5r.net/?p=freertos;a=blobdiff_plain;f=FreeRTOS%2FDemo%2FRISC-V_RV32_SiFive_HiFive1_FreedomStudio%2Ffreedom-metal%2Fsrc%2Fdrivers%2Friscv_plic0.c;h=3272f1c669e971dcfb9f0f2b0e9105dc1995431d;hp=ed9782450036a69fc6ea21e66a7d8c7202a05a12;hb=3bcd0c8a9d1b399c59475115322cbb93484e66d2;hpb=06d74d96f574509835f17691b1919f2562989484 diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c index ed9782450..3272f1c66 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c @@ -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;