Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2024 Kevin Kirspel
0005  *
0006  * Copyright (c) 2015 University of York.
0007  * Hesham Almatary <hesham@alumni.york.ac.uk>
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0022  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0024  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0025  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0026  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0027  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0028  * SUCH DAMAGE.
0029  */
0030 
0031 #ifndef LIBBSP_NIOSV_IRQ_H
0032 #define LIBBSP_NIOSV_IRQ_H
0033 
0034 #ifndef ASM
0035 
0036 #include <bsp.h>
0037 #include <rtems/irq.h>
0038 #include <rtems/irq-extension.h>
0039 #include <rtems/score/processormask.h>
0040 #include <rtems/score/riscv-utility.h>
0041 
0042 #define NIOSV_INTERRUPT_VECTOR_SOFTWARE 0
0043 
0044 #define NIOSV_INTERRUPT_VECTOR_TIMER 1
0045 
0046 #define NIOSV_INTERRUPT_VECTOR_EXTERNAL(x) ((x) + 2)
0047 
0048 #define NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(x) ((x) >= 2)
0049 
0050 #define NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(x) ((x) - 2)
0051 
0052 #define BSP_INTERRUPT_VECTOR_COUNT \
0053   NIOSV_INTERRUPT_VECTOR_EXTERNAL(NIOSV_MAXIMUM_EXTERNAL_INTERRUPTS)
0054 
0055 #define BSP_INTERRUPT_CUSTOM_VALID_VECTOR
0056 
0057 /*
0058  * The following enumeration describes the value in the mcause CSR.
0059  */
0060 enum alt_exception_cause_e {
0061   NIOSV_UNDEFINED_CAUSE                = -1,
0062   NIOSV_INSTRUCTION_ADDRESS_MISALIGNED = 0,
0063   NIOSV_INSTRUCTION_ACCESS_FAULT       = 1,
0064   NIOSV_ILLEGAL_INSTRUCTION            = 2,
0065   NIOSV_BREAKPOINT                     = 3,
0066   NIOSV_LOAD_ADDRESS_MISALIGNED        = 4,
0067   NIOSV_LOAD_ACCESS_FAULT              = 5,
0068   NIOSV_STORE_AMO_ADDRESS_MISALIGNED   = 6,
0069   NIOSV_STORE_AMO_ACCESS_FAULT         = 7,
0070   NIOSV_ENVIRONMENT_CALL_FROM_U_MODE   = 8,
0071   NIOSV_ENVIRONMENT_CALL_FROM_S_MODE   = 9,
0072   NIOSV_RESERVED_BIT_10                = 10,
0073   NIOSV_ENVIRONMENT_CALL_FROM_M_MODE   = 11,
0074   NIOSV_INSTRUCTION_PAGE_FAULT         = 12,
0075   NIOSV_LOAD_PAGE_FAULT                = 13,
0076   NIOSV_RESERVED_BIT_14                = 14,
0077   NIOSV_STORE_AMO_PAGE_FAULT           = 15
0078 };
0079 typedef enum alt_exception_cause_e alt_exception_cause;
0080 
0081 #ifdef __cplusplus
0082 extern "C"
0083 {
0084 #endif /* __cplusplus */
0085 
0086 static inline uint32_t alt_irq_pending(void)
0087 {
0088   uint32_t active, enabled;
0089 
0090   active = read_csr(mip);
0091   enabled = read_csr(mie);
0092 
0093   /*
0094    * we want to only process the upper 16-bits, the interrupt lines connected
0095    * via Platform Designer.
0096    */
0097   return (active & enabled) >> 16;
0098 }
0099 
0100 static inline uint32_t alt_irq_index(uint32_t active)
0101 {
0102   uint32_t mask, i;
0103 
0104   i = 0;
0105   mask = 1;
0106   /*
0107    * Test each bit in turn looking for an active interrupt. Once one is
0108    * found, the interrupt handler asigned by a call to alt_irq_register() is
0109    * called to clear the interrupt condition.
0110    */
0111   do {
0112     if (active & mask) {
0113       return i;
0114     }
0115     mask <<= 1;
0116     i++;
0117   } while (1);
0118   /* should not happen */
0119   return 0;
0120 }
0121 
0122 static inline bool alt_irq_is_pending(uint32_t index)
0123 {
0124   uint32_t mask, active;
0125 
0126   active = alt_irq_pending();
0127 
0128   if(active != 0) {
0129     mask = 1 << index;
0130     if (active & mask) {
0131       return true;
0132     }
0133   }
0134   return false;
0135 }
0136 
0137 static inline bool alt_irq_is_enabled(uint32_t index)
0138 {
0139   uint32_t mask, enabled;
0140 
0141   enabled = read_csr(mie) >> 16;
0142 
0143   if(enabled != 0) {
0144     mask = 1 << index;
0145     if (enabled & mask) {
0146       return true;
0147     }
0148   }
0149   return false;
0150 }
0151 
0152 static inline void alt_irq_enable(uint32_t index)
0153 {
0154   uint32_t mask;
0155 
0156   mask = 1 << (index + 16);
0157   set_csr(mie, mask);
0158 }
0159 
0160 static inline void alt_irq_disable(uint32_t index)
0161 {
0162   uint32_t mask;
0163 
0164   mask = 1 << (index + 16);
0165   clear_csr(mie, mask);
0166 }
0167 
0168 #ifdef __cplusplus
0169 }
0170 #endif /* __cplusplus */
0171 
0172 #endif /* ASM */
0173 
0174 #endif /* LIBBSP_NIOSV_IRQ_H */