bsps/riscv: interrupt not occurred

Padmarao.Begari at microchip.com Padmarao.Begari at microchip.com
Thu Feb 9 06:36:53 UTC 2023


Hi,

While testing the Candence GEM driver of RTEMS-FreeBSD with the RTEMS
on the PolarFire SoC Icicle Kit found one issue.

Issue:The Interrupt is disabled before clearing the interrupt complete
in the PLIC because of this the same interrupt is not occurred next
time.

Resolved: Clear the Interrupt complete in the PLIC before disable the
interrupt. 

Updated the bsp_interrupt_vector_disable() function like below then the
cgem driver is working fine with the RTEMS. 

@Sebastian Huber - Can I send the patch for this?

-----------------------------------------------------------------------
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number
vector)
{
  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));

  if (RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
    uint32_t interrupt_index;
    volatile uint32_t *enable;
    uint32_t group;
    uint32_t bit;
    rtems_interrupt_lock_context lock_context;
    volatile RISCV_PLIC_hart_regs *plic_hart_regs;

    interrupt_index = RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
    enable = riscv_plic_irq_to_cpu[interrupt_index - 1];
    group = interrupt_index / 32;
    bit = UINT32_C(1) << (interrupt_index % 32);

    rtems_interrupt_lock_acquire(&riscv_plic_lock, &lock_context);

#ifdef RTEMS_SMP
      uint32_t cpu_max;
      uint32_t cpu_index;

      cpu_max = _SMP_Get_processor_maximum();

      for (cpu_index = 0; cpu_index < cpu_max; ++cpu_index) {
        Per_CPU_Control *cpu;

        cpu = _Per_CPU_Get_by_index(cpu_index);
        enable = cpu->cpu_per_cpu.plic_m_ie;
        plic_hart_regs = cpu->cpu_per_cpu.plic_hart_regs;
       
plic_hart_regs->claim_complete = interrupt_index;

        if (enable != NULL) {
          enable[group] &= ~bit;
        }
      }
#else
      Per_CPU_Control *cpu;

      cpu = _Per_CPU_Get_by_index(0);
      enable = cpu->cpu_per_cpu.plic_m_ie;
      plic_hart_regs = cpu->cpu_per_cpu.plic_hart_regs;
      plic_hart_regs->claim_complete = interrupt_index;
      if (enable != NULL) {
        enable[group] &= ~bit;
      }
#endif

    rtems_interrupt_lock_release(&riscv_plic_lock, &lock_context);
    return RTEMS_SUCCESSFUL;
  }

  if (vector == RISCV_INTERRUPT_VECTOR_TIMER) {
    clear_csr(mie, MIP_MTIP);
    return RTEMS_SUCCESSFUL;
  }

  _Assert(vector == RISCV_INTERRUPT_VECTOR_SOFTWARE);
  clear_csr(mie, MIP_MSIP);
  return RTEMS_SUCCESSFUL;
} 


Regards
Padmarao


More information about the devel mailing list