1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2013-07-06 Bernard first version 9 * 2015-11-06 zchong support iar compiler 10 */ 11 12 #include <rthw.h> 13 #include <rtthread.h> 14 15 #include "am33xx.h" 16 #include "interrupt.h" 17 18 #define AINTC_BASE AM33XX_AINTC_REGS 19 20 #define MAX_HANDLERS 128 21 22 extern volatile rt_uint8_t rt_interrupt_nest; 23 24 /* exception and interrupt handler table */ 25 struct rt_irq_desc isr_table[MAX_HANDLERS]; 26 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; 27 rt_uint32_t rt_thread_switch_interrupt_flag; 28 29 /** 30 * @addtogroup AM33xx 31 */ 32 /*@{*/ 33 34 void rt_dump_aintc(void) 35 { 36 int k; 37 rt_kprintf("active irq %d", INTC_SIR_IRQ(AINTC_BASE)); 38 rt_kprintf("\n--- hw mask ---\n"); 39 for (k = 0; k < 4; k++) 40 { 41 rt_kprintf("0x%08x, ", INTC_MIR(AINTC_BASE, k)); 42 } 43 rt_kprintf("\n--- hw itr ---\n"); 44 for (k = 0; k < 4; k++) 45 { 46 rt_kprintf("0x%08x, ", INTC_ITR(AINTC_BASE, k)); 47 } 48 rt_kprintf("\n"); 49 } 50 51 const unsigned int AM335X_VECTOR_BASE = 0x4030FC00; 52 extern void rt_cpu_vector_set_base(unsigned int addr); 53 #ifdef __ICCARM__ 54 extern int __vector; 55 #else 56 extern int system_vectors; 57 #endif 58 59 static void rt_hw_vector_init(void) 60 { 61 unsigned int *dest = (unsigned int *)AM335X_VECTOR_BASE; 62 63 #ifdef __ICCARM__ 64 unsigned int *src = (unsigned int *)&__vector; 65 #else 66 unsigned int *src = (unsigned int *)&system_vectors; 67 #endif 68 69 rt_memcpy(dest, src, 16 * 4); 70 rt_cpu_vector_set_base(AM335X_VECTOR_BASE); 71 } 72 73 /** 74 * This function will initialize hardware interrupt 75 */ 76 void rt_hw_interrupt_init(void) 77 { 78 /* initialize vector table */ 79 rt_hw_vector_init(); 80 81 /* init exceptions table */ 82 rt_memset(isr_table, 0x00, sizeof(isr_table)); 83 84 /* init interrupt nest, and context in thread sp */ 85 rt_interrupt_nest = 0; 86 rt_interrupt_from_thread = 0; 87 rt_interrupt_to_thread = 0; 88 rt_thread_switch_interrupt_flag = 0; 89 } 90 91 /** 92 * This function will mask a interrupt. 93 * @param vector the interrupt number 94 */ 95 void rt_hw_interrupt_mask(int vector) 96 { 97 INTC_MIR_SET(AINTC_BASE, vector >> 0x05) = 0x1 << (vector & 0x1f); 98 } 99 100 /** 101 * This function will un-mask a interrupt. 102 * @param vector the interrupt number 103 */ 104 void rt_hw_interrupt_umask(int vector) 105 { 106 INTC_MIR_CLEAR(AINTC_BASE, vector >> 0x05) = 0x1 << (vector & 0x1f); 107 } 108 109 /** 110 * This function will control the interrupt attribute. 111 * @param vector the interrupt number 112 */ 113 void rt_hw_interrupt_control(int vector, int priority, int route) 114 { 115 int fiq; 116 117 if (route == 0) 118 fiq = 0; 119 else 120 fiq = 1; 121 122 INTC_ILR(AINTC_BASE, vector) = ((priority << 0x02) & 0x1FC) | fiq ; 123 } 124 125 int rt_hw_interrupt_get_active(int fiq_irq) 126 { 127 int ir; 128 if (fiq_irq == INT_FIQ) 129 { 130 ir = INTC_SIR_FIQ(AINTC_BASE) & 0x7f; 131 } 132 else 133 { 134 ir = INTC_SIR_IRQ(AINTC_BASE) & 0x7f; 135 } 136 137 return ir; 138 } 139 140 void rt_hw_interrupt_ack(int fiq_irq) 141 { 142 if (fiq_irq == INT_FIQ) 143 { 144 /* new FIQ generation */ 145 INTC_CONTROL(AINTC_BASE) |= 0x02; 146 } 147 else 148 { 149 /* new IRQ generation */ 150 INTC_CONTROL(AINTC_BASE) |= 0x01; 151 } 152 } 153 154 /** 155 * This function will install a interrupt service routine to a interrupt. 156 * @param vector the interrupt number 157 * @param new_handler the interrupt service routine to be installed 158 * @param old_handler the old interrupt service routine 159 */ 160 rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, 161 void *param, const char *name) 162 { 163 rt_isr_handler_t old_handler = RT_NULL; 164 165 if(vector < MAX_HANDLERS) 166 { 167 old_handler = isr_table[vector].handler; 168 169 if (handler != RT_NULL) 170 { 171 #ifdef RT_USING_INTERRUPT_INFO 172 rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); 173 #endif /* RT_USING_INTERRUPT_INFO */ 174 isr_table[vector].handler = handler; 175 isr_table[vector].param = param; 176 } 177 } 178 179 return old_handler; 180 } 181 182 /** 183 * This function will trigger an interrupt. 184 * @param vector the interrupt number 185 */ 186 void rt_hw_interrupt_trigger(int vector) 187 { 188 INTC_ISR_SET(AINTC_BASE, vector>>5) = 1 << (vector & 0x1f); 189 } 190 191 void rt_hw_interrupt_clear(int vector) 192 { 193 INTC_ISR_CLEAR(AINTC_BASE, vector>>5) = 1 << (vector & 0x1f); 194 } 195 196 void rt_dump_isr_table(void) 197 { 198 int idx; 199 for(idx = 0; idx < MAX_HANDLERS; idx++) 200 { 201 #ifdef RT_USING_INTERRUPT_INFO 202 rt_kprintf("nr:%4d, name: %*.s, handler: 0x%p, param: 0x%08x\r\n", 203 idx, RT_NAME_MAX, isr_table[idx].name, 204 isr_table[idx].handler, isr_table[idx].param); 205 #else 206 rt_kprintf("nr:%4d, handler: 0x%p, param: 0x%08x\r\n", 207 idx, isr_table[idx].handler, isr_table[idx].param); 208 #endif 209 } 210 } 211 /*@}*/ 212 213 214