00001
00044 #ifndef AVR32_IRQ_HANDLER_H_INCLUDED
00045 #define AVR32_IRQ_HANDLER_H_INCLUDED
00046
00047 #include <io.h>
00048 #include <util.h>
00049 #include <chip/memory-map.h>
00050 #include <cpu/irq_handler.h>
00051
00052 #define irq_entry_symbol(name) name##_irq_entry
00053 #define irq_entry_symbol_str(name) xstr(name##_irq_entry)
00054 #define irq_data_symbol(name) name##_irq_data
00055 #define irq_data_symbol_str(name) xstr(name##_irq_data)
00056
00057 #define __irq_entry_section(name) \
00058 ".libavr32.text.irq." #name ", \"ax\", @progbits"
00059 #define __irq_data_section(name) \
00060 ".libavr32.bss.irq." #name ", \"aw\", @nobits"
00061 #define __irq_entry_size(name) \
00062 irq_entry_symbol_str(name) ", . - " irq_entry_symbol_str(name)
00063 #define __irq_data_size(name) \
00064 irq_data_symbol_str(name) ", . - " irq_data_symbol_str(name)
00065
00083 #define DEFINE_IRQ_HANDLER(name, handler, level) \
00084 extern void irq_entry_symbol(name)(void); \
00085 extern void *irq_data_symbol(name); \
00086 static void __used __dummy_irq_ref_##name(void) \
00087 { \
00088 handler(&handler); \
00089 } \
00090 asm(".section " __irq_entry_section(name) "\n" \
00091 " .global " irq_entry_symbol_str(name) "\n" \
00092 " .type " irq_entry_symbol_str(name) ", @function\n" \
00093 irq_entry_symbol_str(name) ":\n" \
00094 CPU_SAVE_IRQ_REGS(level) \
00095 " lda.w r8, " irq_data_symbol_str(name) "\n" \
00096 " ld.w r12, r8[0]\n" \
00097 " rcall " #handler "\n" \
00098 " rjmp irq_level" #level "_return\n" \
00099 " .size " __irq_entry_size(name) "\n" \
00100 " .previous\n" \
00101 " .section " __irq_data_section(name) "\n" \
00102 " .global " irq_data_symbol_str(name) "\n" \
00103 " .type " irq_data_symbol_str(name) ", @object\n" \
00104 irq_data_symbol_str(name) ":\n" \
00105 " .long 0\n" \
00106 " .size " __irq_data_size(name) "\n" \
00107 " .previous")
00108
00115 #define set_irq_data(name, data) \
00116 do { \
00117 irq_data_symbol(name) = (data); \
00118 } while (0)
00119
00120 extern void __setup_irq_handler(int irq, void (*entry)(void),
00121 void **pdata, unsigned int level, void *data);
00122
00146 #define setup_irq_handler(irq, name, level, data) \
00147 do { \
00148 extern void irq_entry_symbol(name)(void); \
00149 extern void *irq_data_symbol(name); \
00150 __setup_irq_handler(irq, &irq_entry_symbol(name), \
00151 &irq_data_symbol(name), level, data); \
00152 } while (0)
00153
00166 #define remove_irq_handler(name) \
00167 do { \
00168 extern void *irq_data_symbol(name); \
00169 irq_data_symbol(name) = 0; \
00170 } while (0)
00171
00175 static inline unsigned long get_irq_group_requests(unsigned int group)
00176 {
00177 return mmio_read32((void *)(INTC_BASE + 256 + 4 * group));
00178 }
00179
00180 #endif