File indexing completed on 2025-05-11 08:23:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <rtems/score/armv4.h>
0020
0021 #include <bsp.h>
0022 #include <bsp/irq-generic.h>
0023 #include <bsp/raspberrypi.h>
0024 #include <bsp/linker-symbols.h>
0025 #include <bsp/mmu.h>
0026 #include <rtems/bspIo.h>
0027 #include <strings.h>
0028
0029 #include <rtems/inttypes.h>
0030
0031 #ifdef RTEMS_SMP
0032 #include <rtems/score/smp.h>
0033 #include <rtems/score/smpimpl.h>
0034 #endif
0035
0036 typedef struct {
0037 unsigned long enable_reg_addr;
0038 unsigned long disable_reg_addr;
0039 } bcm2835_irq_ctrl_reg_t;
0040
0041 static const bcm2835_irq_ctrl_reg_t bcm2835_irq_ctrl_reg_table[] = {
0042 { BCM2835_IRQ_ENABLE1, BCM2835_IRQ_DISABLE1 },
0043 { BCM2835_IRQ_ENABLE2, BCM2835_IRQ_DISABLE2 },
0044 { BCM2835_IRQ_ENABLE_BASIC, BCM2835_IRQ_DISABLE_BASIC }
0045 };
0046
0047 static inline const bcm2835_irq_ctrl_reg_t *
0048 bsp_vector_to_reg(rtems_vector_number vector)
0049 {
0050 return bcm2835_irq_ctrl_reg_table + (vector >> 5);
0051 }
0052
0053 static inline uint32_t
0054 bsp_vector_to_mask(rtems_vector_number vector)
0055 {
0056 return 1 << (vector & 0x1f);
0057 }
0058
0059 static const int bcm2835_irq_speedup_table[] =
0060 {
0061 BCM2835_IRQ_ID_BASIC_BASE_ID + 0,
0062 BCM2835_IRQ_ID_BASIC_BASE_ID + 1,
0063 BCM2835_IRQ_ID_BASIC_BASE_ID + 2,
0064 BCM2835_IRQ_ID_BASIC_BASE_ID + 3,
0065 BCM2835_IRQ_ID_BASIC_BASE_ID + 4,
0066 BCM2835_IRQ_ID_BASIC_BASE_ID + 5,
0067 BCM2835_IRQ_ID_BASIC_BASE_ID + 6,
0068 BCM2835_IRQ_ID_BASIC_BASE_ID + 7,
0069 -1,
0070 -2,
0071 7,
0072 9,
0073 10,
0074 18,
0075 19,
0076 53,
0077 54,
0078 55,
0079 56,
0080 57,
0081 62,
0082 };
0083
0084
0085
0086
0087
0088
0089 #define BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS 0x1ffcff
0090
0091
0092
0093
0094 void bsp_interrupt_dispatch(void)
0095 {
0096 unsigned int pend;
0097 unsigned int pend_bit;
0098
0099 rtems_vector_number vector = 255;
0100
0101 #ifdef RTEMS_SMP
0102 uint32_t cpu_index_self = _SMP_Get_current_processor();
0103 uint32_t local_source = BCM2835_REG(BCM2836_IRQ_SOURCE_REG(cpu_index_self));
0104
0105 if ( local_source & BCM2836_IRQ_SOURCE_MBOX3 ) {
0106
0107 BCM2835_REG(BCM2836_MAILBOX_3_READ_CLEAR_BASE + 0x10 * cpu_index_self) = 0xffffffff;
0108 _SMP_Inter_processor_interrupt_handler(
0109 _Per_CPU_Get_by_index(cpu_index_self)
0110 );
0111 }
0112 if ( cpu_index_self != 0 )
0113 return;
0114 #endif
0115
0116 pend = BCM2835_REG(BCM2835_IRQ_BASIC);
0117 if ( pend & BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS ) {
0118 pend_bit = ffs(pend) - 1;
0119 vector = bcm2835_irq_speedup_table[pend_bit];
0120 } else {
0121 pend = BCM2835_REG(BCM2835_IRQ_PENDING1);
0122 if ( pend != 0 ) {
0123 pend_bit = ffs(pend) - 1;
0124 vector = pend_bit;
0125 } else {
0126 pend = BCM2835_REG(BCM2835_IRQ_PENDING2);
0127 if ( pend != 0 ) {
0128 pend_bit = ffs(pend) - 1;
0129 vector = pend_bit + 32;
0130 }
0131 }
0132 }
0133
0134 if ( vector < 255 )
0135 {
0136 bsp_interrupt_handler_dispatch(vector);
0137 }
0138 }
0139
0140 rtems_status_code bsp_interrupt_get_attributes(
0141 rtems_vector_number vector,
0142 rtems_interrupt_attributes *attributes
0143 )
0144 {
0145 return RTEMS_SUCCESSFUL;
0146 }
0147
0148 rtems_status_code bsp_interrupt_is_pending(
0149 rtems_vector_number vector,
0150 bool *pending
0151 )
0152 {
0153 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0154 bsp_interrupt_assert(pending != NULL);
0155 *pending = false;
0156 return RTEMS_UNSATISFIED;
0157 }
0158
0159 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0160 {
0161 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0162 return RTEMS_UNSATISFIED;
0163 }
0164
0165 #if defined(RTEMS_SMP)
0166 rtems_status_code bsp_interrupt_raise_on(
0167 rtems_vector_number vector,
0168 uint32_t cpu_index
0169 )
0170 {
0171 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0172 return RTEMS_UNSATISFIED;
0173 }
0174 #endif
0175
0176 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0177 {
0178 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0179 return RTEMS_UNSATISFIED;
0180 }
0181
0182 rtems_status_code bsp_interrupt_vector_is_enabled(
0183 rtems_vector_number vector,
0184 bool *enabled
0185 )
0186 {
0187 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0188 bsp_interrupt_assert(enabled != NULL);
0189 *enabled = false;
0190 return RTEMS_UNSATISFIED;
0191 }
0192
0193 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
0194 {
0195 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0196 BCM2835_REG(bsp_vector_to_reg(vector)->enable_reg_addr) =
0197 bsp_vector_to_mask(vector);
0198 return RTEMS_SUCCESSFUL;
0199 }
0200
0201 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
0202 {
0203 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0204 BCM2835_REG(bsp_vector_to_reg(vector)->disable_reg_addr) =
0205 bsp_vector_to_mask(vector);
0206 return RTEMS_SUCCESSFUL;
0207 }
0208
0209 rtems_status_code bsp_interrupt_set_priority(
0210 rtems_vector_number vector,
0211 uint32_t priority
0212 )
0213 {
0214 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0215 return RTEMS_UNSATISFIED;
0216 }
0217
0218 rtems_status_code bsp_interrupt_get_priority(
0219 rtems_vector_number vector,
0220 uint32_t *priority
0221 )
0222 {
0223 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0224 bsp_interrupt_assert(priority != NULL);
0225 return RTEMS_UNSATISFIED;
0226 }
0227
0228 #if defined(RTEMS_SMP)
0229 rtems_status_code bsp_interrupt_get_affinity(
0230 rtems_vector_number vector,
0231 Processor_mask *affinity
0232 )
0233 {
0234 (void) vector;
0235 _Processor_mask_From_index( affinity, 0 );
0236 return RTEMS_UNSATISFIED;
0237 }
0238
0239 rtems_status_code bsp_interrupt_set_affinity(
0240 rtems_vector_number vector,
0241 const Processor_mask *affinity
0242 )
0243 {
0244 (void) vector;
0245 (void) affinity;
0246 return RTEMS_UNSATISFIED;
0247 }
0248 #endif
0249
0250 void bsp_interrupt_handler_default(rtems_vector_number vector)
0251 {
0252 printk("spurious interrupt: %" PRIdrtems_vector_number "\n", vector);
0253 }
0254
0255 void bsp_interrupt_facility_initialize(void)
0256 {
0257 BCM2835_REG(BCM2835_IRQ_DISABLE1) = 0xffffffff;
0258 BCM2835_REG(BCM2835_IRQ_DISABLE2) = 0xffffffff;
0259 BCM2835_REG(BCM2835_IRQ_DISABLE_BASIC) = 0xffffffff;
0260 BCM2835_REG(BCM2835_IRQ_FIQ_CTRL) = 0;
0261 }