1 /* 2 * File : interrupt.c 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2009, RT-Thread Development Team 5 * 6 * The license and distribution terms for this file may be 7 * found in the file LICENSE in this distribution or at 8 * http://www.rt-thread.org/license/LICENSE 9 * 10 * Change Logs: 11 * Date Author Notes 12 * 2009-01-05 Bernard first version 13 */ 14 15 #include <rthw.h> 16 #include <asm/ppc4xx.h> 17 #include <asm/processor.h> 18 19 /* interrupt nest */ 20 extern volatile rt_uint8_t rt_interrupt_nest; 21 22 /* exception and interrupt handler table */ 23 #define MAX_HANDLERS 32 24 struct rt_irq_desc isr_table[MAX_HANDLERS]; 25 26 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; 27 rt_uint32_t rt_thread_switch_interrput_flag; 28 29 rt_isr_handler_t rt_hw_interrupt_handler(rt_uint32_t vector, void* param) 30 { 31 rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); 32 return RT_NULL; 33 } 34 35 void uic_irq_ack(unsigned int vec) 36 { 37 mtdcr(uic0sr, UIC_MASK(vec)); 38 } 39 40 void uic_int_handler (unsigned int vec) 41 { 42 rt_interrupt_enter(); 43 44 /* Allow external interrupts to the CPU. */ 45 if (isr_table [vec].handler != 0) 46 { 47 (*isr_table[vec].handler)(vec, isr_table[vec].param); 48 } 49 uic_irq_ack(vec); 50 51 rt_interrupt_leave(); 52 } 53 54 /* handler for UIC interrupt */ 55 void uic_interrupt(rt_uint32_t uic_base, int vec_base) 56 { 57 int vec; 58 rt_uint32_t uic_msr; 59 rt_uint32_t msr_shift; 60 61 /* 62 * Read masked interrupt status register to determine interrupt source 63 */ 64 uic_msr = get_dcr(uic_base + UIC_MSR); 65 msr_shift = uic_msr; 66 vec = vec_base; 67 68 while (msr_shift != 0) 69 { 70 if (msr_shift & 0x80000000) 71 uic_int_handler(vec); 72 73 /* 74 * Shift msr to next position and increment vector 75 */ 76 msr_shift <<= 1; 77 vec++; 78 } 79 } 80 81 rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, 82 void* param, const char* name) 83 { 84 int intVal; 85 rt_isr_handler_t old_handler; 86 87 if (((int)vector < 0) || ((int) vector >= MAX_HANDLERS)) 88 { 89 return RT_NULL; /* out of range */ 90 } 91 92 /* install the handler in the system interrupt table */ 93 intVal = rt_hw_interrupt_disable (); /* lock interrupts to prevent races */ 94 95 old_handler = isr_table[vector].handler; 96 isr_table[vector].handler = new_handler; 97 isr_table[vector].param = param; 98 99 rt_hw_interrupt_enable (intVal); 100 } 101 102 void rt_hw_interrupt_mask(int vector) 103 { 104 mtdcr(uic0er, mfdcr(uic0er) & ~UIC_MASK(vector)); 105 } 106 107 void rt_hw_interrupt_unmask(int vector) 108 { 109 mtdcr(uic0er, mfdcr(uic0er) | UIC_MASK(vector)); 110 } 111 112 void rt_hw_interrupt_init() 113 { 114 int vector; 115 rt_uint32_t pit_value; 116 117 pit_value = RT_TICK_PER_SECOND * (100000000 / RT_CPU_FREQ); 118 119 /* enable pit */ 120 mtspr(SPRN_PIT, pit_value); 121 mtspr(SPRN_TCR, 0x4400000); 122 123 /* set default interrupt handler */ 124 for (vector = 0; vector < MAX_HANDLERS; vector++) 125 { 126 isr_table [vector].handler = (rt_isr_handler_t)rt_hw_interrupt_handler; 127 isr_table [vector].param = RT_NULL; 128 } 129 130 /* initialize interrupt nest, and context in thread sp */ 131 rt_interrupt_nest = 0; 132 rt_interrupt_from_thread = 0; 133 rt_interrupt_to_thread = 0; 134 rt_thread_switch_interrput_flag = 0; 135 } 136 137 /*@}*/ 138