Back to home page

LXR

 
 

    


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

0001 /*
0002  * SPDX-License-Identifier: BSD-2-Clause
0003  *
0004  * Copyright (C) 2024 Kevin Kirspel
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #include <bsp/fatal.h>
0029 #include <bsp/irq.h>
0030 #include <bsp/irq-generic.h>
0031 #include <bsp/niosv.h>
0032 
0033 #include <rtems/score/percpu.h>
0034 #include <rtems/score/riscv-utility.h>
0035 
0036 #include <string.h>
0037 
0038 void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
0039 {
0040   uint32_t exception_code = (mcause & ~NIOSV_MCAUSE_INTERRUPT_MASK);
0041 
0042   if (exception_code == RISCV_INTERRUPT_TIMER_MACHINE) {
0043     bsp_interrupt_handler_dispatch_unchecked(NIOSV_INTERRUPT_VECTOR_TIMER);
0044   } else if (exception_code >= 16) {
0045     uint32_t interrupt_index, active;
0046 
0047     active = alt_irq_pending();
0048 
0049     while (active != 0) {
0050       interrupt_index = alt_irq_index(active);
0051 
0052       bsp_interrupt_handler_dispatch(
0053         NIOSV_INTERRUPT_VECTOR_EXTERNAL(interrupt_index)
0054       );
0055 
0056       active = alt_irq_pending();
0057     }
0058   } else if (exception_code == RISCV_INTERRUPT_SOFTWARE_MACHINE) {
0059     bsp_interrupt_handler_dispatch_unchecked(NIOSV_INTERRUPT_VECTOR_SOFTWARE);
0060   } else {
0061     bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
0062   }
0063 }
0064 
0065 void bsp_interrupt_facility_initialize(void)
0066 {
0067 }
0068 
0069 bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
0070 {
0071   return vector < (rtems_vector_number) BSP_INTERRUPT_VECTOR_COUNT;
0072 }
0073 
0074 rtems_status_code bsp_interrupt_get_attributes(
0075   rtems_vector_number         vector,
0076   rtems_interrupt_attributes *attributes
0077 )
0078 {
0079   attributes->is_maskable = true;
0080   attributes->can_enable = true;
0081   attributes->maybe_enable = true;
0082   attributes->can_disable = true;
0083   attributes->maybe_disable = true;
0084   attributes->can_raise = (vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
0085   attributes->can_raise_on = attributes->can_raise;
0086   attributes->cleared_by_acknowledge = true;
0087   attributes->can_get_affinity = false;
0088   attributes->can_set_affinity = false;
0089 
0090   if (vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE) {
0091     attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL;
0092   }
0093 
0094   return RTEMS_SUCCESSFUL;
0095 }
0096 
0097 rtems_status_code bsp_interrupt_is_pending(
0098   rtems_vector_number vector,
0099   bool               *pending
0100 )
0101 {
0102   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0103   bsp_interrupt_assert(pending != NULL);
0104 
0105   if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
0106     uint32_t interrupt_index;
0107 
0108     interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
0109     *pending = alt_irq_is_pending(interrupt_index);
0110     return RTEMS_SUCCESSFUL;
0111   }
0112 
0113   if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
0114     *pending = (read_csr(mip) & MIP_MTIP) != 0;
0115     return RTEMS_SUCCESSFUL;
0116   }
0117 
0118   _Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
0119   *pending = (read_csr(mip) & MIP_MSIP) != 0;
0120   return RTEMS_SUCCESSFUL;
0121 }
0122 
0123 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0124 {
0125   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0126 
0127   if (vector != NIOSV_INTERRUPT_VECTOR_SOFTWARE) {
0128     return RTEMS_UNSATISFIED;
0129   }
0130 
0131   return RTEMS_SUCCESSFUL;
0132 }
0133 
0134 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0135 {
0136   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0137   return RTEMS_UNSATISFIED;
0138 }
0139 
0140 rtems_status_code bsp_interrupt_vector_is_enabled(
0141   rtems_vector_number vector,
0142   bool               *enabled
0143 )
0144 {
0145   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0146   bsp_interrupt_assert(enabled != NULL);
0147 
0148   if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
0149     uint32_t interrupt_index;
0150 
0151     interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
0152     *enabled = alt_irq_is_enabled(interrupt_index);
0153 
0154     return RTEMS_SUCCESSFUL;
0155   }
0156 
0157   if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
0158     *enabled = (read_csr(mie) & MIP_MTIP) != 0;
0159     return RTEMS_SUCCESSFUL;
0160   }
0161 
0162   _Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
0163   *enabled = (read_csr(mie) & MIP_MSIP) != 0;
0164   return RTEMS_SUCCESSFUL;
0165 }
0166 
0167 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
0168 {
0169   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0170 
0171   if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
0172     uint32_t interrupt_index;
0173 
0174     interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
0175     alt_irq_enable(interrupt_index);
0176     return RTEMS_SUCCESSFUL;
0177   }
0178 
0179   if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
0180     set_csr(mie, MIP_MTIP);
0181     return RTEMS_SUCCESSFUL;
0182   }
0183 
0184   _Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
0185   set_csr(mie, MIP_MSIP);
0186   return RTEMS_SUCCESSFUL;
0187 }
0188 
0189 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
0190 {
0191   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0192 
0193   if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
0194     uint32_t interrupt_index;
0195 
0196     interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
0197     alt_irq_disable(interrupt_index);
0198     return RTEMS_SUCCESSFUL;
0199   }
0200 
0201   if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
0202     clear_csr(mie, MIP_MTIP);
0203     return RTEMS_SUCCESSFUL;
0204   }
0205 
0206   _Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
0207   clear_csr(mie, MIP_MSIP);
0208   return RTEMS_SUCCESSFUL;
0209 }
0210 
0211 rtems_status_code bsp_interrupt_set_priority(
0212   rtems_vector_number vector,
0213   uint32_t priority
0214 )
0215 {
0216   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0217   return RTEMS_UNSATISFIED;
0218 }
0219 
0220 rtems_status_code bsp_interrupt_get_priority(
0221   rtems_vector_number vector,
0222   uint32_t *priority
0223 )
0224 {
0225   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0226   bsp_interrupt_assert(priority != NULL);
0227   return RTEMS_UNSATISFIED;
0228 }