Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:00

0001 /**
0002  * @file
0003  *
0004  * @ingroup riscv_interrupt
0005  *
0006  * @brief Interrupt support.
0007  */
0008 
0009 /*
0010  * Copyright (c) 2018 embedded brains GmbH & Co. KG
0011  *
0012  * Copyright (c) 2015 University of York.
0013  * Hesham Almatary <hesham@alumni.york.ac.uk>
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0034  * SUCH DAMAGE.
0035  */
0036 
0037 #include <bsp/fatal.h>
0038 #include <bsp/irq-generic.h>
0039 #include <amba.h>
0040 
0041 #include <rtems/score/percpu.h>
0042 #include <rtems/score/riscv-utility.h>
0043 #include <rtems/score/smpimpl.h>
0044 
0045 #if defined(RTEMS_SMP)
0046 /* Interrupt to CPU map. Default to CPU0 since in BSS. */
0047 const unsigned char GRLIB_irq_to_cpu[32] __attribute__((weak));
0048 
0049 /* On SMP use map table above relative to SMP Boot CPU (normally CPU0) */
0050 static inline int bsp_irq_cpu(int irq)
0051 {
0052   /* protect from bad user configuration, default to boot cpu */
0053   if (rtems_configuration_get_maximum_processors() <= GRLIB_irq_to_cpu[irq])
0054     return GRLIB_Cpu_Index;
0055   else
0056     return GRLIB_Cpu_Index + GRLIB_irq_to_cpu[irq];
0057 }
0058 #else
0059 /* when not SMP the local CPU is returned */
0060 static inline int bsp_irq_cpu(int irq)
0061 {
0062   return read_csr(mhartid);
0063 }
0064 #endif
0065 
0066 void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
0067 {
0068   if (mcause & 0x80000000) {
0069 
0070     bsp_interrupt_handler_dispatch(mcause & 0xf);
0071 
0072   } else {
0073     bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
0074   }
0075 }
0076 
0077 void bsp_interrupt_facility_initialize(void)
0078 {
0079 
0080   /*
0081    * External M-mode interrupts on secondary processors are enabled in
0082    * bsp_start_on_secondary_processor().
0083    */
0084   set_csr(mie, MIP_MEIP);
0085 }
0086 
0087 rtems_status_code bsp_interrupt_get_attributes(
0088   rtems_vector_number         vector,
0089   rtems_interrupt_attributes *attributes
0090 )
0091 {
0092   return RTEMS_SUCCESSFUL;
0093 }
0094 
0095 rtems_status_code bsp_interrupt_is_pending(
0096   rtems_vector_number vector,
0097   bool               *pending
0098 )
0099 {
0100   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0101   bsp_interrupt_assert(pending != NULL);
0102   *pending = false;
0103   return RTEMS_UNSATISFIED;
0104 }
0105 
0106 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0107 {
0108   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0109   return RTEMS_UNSATISFIED;
0110 }
0111 
0112 #if defined(RTEMS_SMP)
0113 rtems_status_code bsp_interrupt_raise_on(
0114   rtems_vector_number vector,
0115   uint32_t            cpu_index
0116 )
0117 {
0118   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0119   return RTEMS_UNSATISFIED;
0120 }
0121 #endif
0122 
0123 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0124 {
0125   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0126   return RTEMS_UNSATISFIED;
0127 }
0128 
0129 rtems_status_code bsp_interrupt_vector_is_enabled(
0130   rtems_vector_number vector,
0131   bool               *enabled
0132 )
0133 {
0134   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0135   bsp_interrupt_assert(enabled != NULL);
0136   *enabled = false;
0137   return RTEMS_UNSATISFIED;
0138 }
0139 
0140 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
0141 {
0142   int irq = (int)vector;
0143   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0144   GRLIB_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq));
0145   return RTEMS_SUCCESSFUL;
0146 }
0147 
0148 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
0149 {
0150   int irq = (int)vector;
0151   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0152   GRLIB_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq));
0153   return RTEMS_SUCCESSFUL;
0154 }
0155 
0156 rtems_status_code bsp_interrupt_set_priority(
0157   rtems_vector_number vector,
0158   uint32_t priority
0159 )
0160 {
0161   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0162   return RTEMS_UNSATISFIED;
0163 }
0164 
0165 rtems_status_code bsp_interrupt_get_priority(
0166   rtems_vector_number vector,
0167   uint32_t *priority
0168 )
0169 {
0170   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0171   bsp_interrupt_assert(priority != NULL);
0172   return RTEMS_UNSATISFIED;
0173 }
0174 
0175 rtems_status_code bsp_interrupt_get_affinity(
0176   rtems_vector_number vector,
0177   Processor_mask *affinity
0178 )
0179 {
0180   uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
0181   uint32_t cpu_index;
0182 
0183   _Processor_mask_Zero(affinity);
0184 
0185   for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
0186     if (!BSP_Cpu_Is_interrupt_masked(vector, cpu_index)) {
0187       _Processor_mask_Set(affinity, cpu_index);
0188     }
0189   }
0190 
0191   return RTEMS_SUCCESSFUL;
0192 }
0193 
0194 rtems_status_code bsp_interrupt_set_affinity(
0195   rtems_vector_number vector,
0196   const Processor_mask *affinity
0197 )
0198 {
0199   uint32_t unmasked = 0;
0200   uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
0201   uint32_t cpu_index;
0202 
0203   for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
0204     if (_Processor_mask_Is_set(affinity, cpu_index)) {
0205       GRLIB_Cpu_Unmask_interrupt(vector, cpu_index);
0206       ++unmasked;
0207     }
0208   }
0209 
0210   if (unmasked > 1) {
0211     GRLIB_Enable_interrupt_broadcast(vector);
0212   } else {
0213     GRLIB_Disable_interrupt_broadcast(vector);
0214   }
0215 
0216   return RTEMS_SUCCESSFUL;
0217 }