|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2004 David Decotigny 001 /* Copyright (C) 2004 David Decotigny 002 Copyright (C) 1999 Free Software Foundatio << 003 002 004 This program is free software; you can redi 003 This program is free software; you can redistribute it and/or 005 modify it under the terms of the GNU Genera 004 modify it under the terms of the GNU General Public License 006 as published by the Free Software Foundatio 005 as published by the Free Software Foundation; either version 2 007 of the License, or (at your option) any lat 006 of the License, or (at your option) any later version. 008 007 009 This program is distributed in the hope tha 008 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the 009 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR 010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details 011 GNU General Public License for more details. 013 012 014 You should have received a copy of the GNU 013 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to t 014 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place - Suite 3 015 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 017 USA. 016 USA. 018 */ 017 */ 019 #include "idt.h" 018 #include "idt.h" 020 #include "i8259.h" 019 #include "i8259.h" 021 020 022 #include "irq.h" 021 #include "irq.h" 023 022 024 /** array of IRQ wrappers, defined in irq_wrap 023 /** array of IRQ wrappers, defined in irq_wrappers.S */ 025 extern sos_vaddr_t sos_irq_wrapper_array[SOS_I 024 extern sos_vaddr_t sos_irq_wrapper_array[SOS_IRQ_NUM]; 026 025 027 /** arrays of IRQ handlers, shared with irq_wr 026 /** arrays of IRQ handlers, shared with irq_wrappers.S */ 028 sos_irq_handler_t sos_irq_handler_array[SOS_IR 027 sos_irq_handler_t sos_irq_handler_array[SOS_IRQ_NUM] = { NULL, }; 029 028 030 /** Number of interrupt handlers that are curr 029 /** Number of interrupt handlers that are currently executing */ 031 sos_ui32_t sos_irq_nested_level_counter; 030 sos_ui32_t sos_irq_nested_level_counter; 032 031 033 sos_ret_t sos_irq_subsystem_setup(void) 032 sos_ret_t sos_irq_subsystem_setup(void) 034 { 033 { 035 sos_irq_nested_level_counter = 0; 034 sos_irq_nested_level_counter = 0; 036 return sos_i8259_subsystem_setup(); 035 return sos_i8259_subsystem_setup(); 037 } 036 } 038 037 039 038 040 sos_ret_t sos_irq_set_routine(int irq_level, 039 sos_ret_t sos_irq_set_routine(int irq_level, 041 sos_irq_handler_ 040 sos_irq_handler_t routine) 042 { 041 { 043 sos_ret_t retval; 042 sos_ret_t retval; 044 sos_ui32_t flags; 043 sos_ui32_t flags; 045 044 046 if ((irq_level < 0) || (irq_level >= SOS_IRQ 045 if ((irq_level < 0) || (irq_level >= SOS_IRQ_NUM)) 047 return -SOS_EINVAL; 046 return -SOS_EINVAL; 048 047 049 sos_disable_IRQs(flags); 048 sos_disable_IRQs(flags); 050 049 051 retval = SOS_OK; 050 retval = SOS_OK; 052 051 053 /* Set the irq routine to be called by the I 052 /* Set the irq routine to be called by the IRQ wrapper */ 054 sos_irq_handler_array[irq_level] = routine; 053 sos_irq_handler_array[irq_level] = routine; 055 054 056 /* If the irq is to be enabled, update the I 055 /* If the irq is to be enabled, update the IDT with the IRQ 057 wrapper */ 056 wrapper */ 058 if (routine != NULL) 057 if (routine != NULL) 059 { 058 { 060 retval 059 retval 061 = sos_idt_set_handler(SOS_IRQ_BASE + i 060 = sos_idt_set_handler(SOS_IRQ_BASE + irq_level, 062 (sos_vaddr_t) so 061 (sos_vaddr_t) sos_irq_wrapper_array[irq_level], 063 0 /* CPL0 routin 062 0 /* CPL0 routine */); 064 /* A problem occured */ 063 /* A problem occured */ 065 if (retval != SOS_OK) 064 if (retval != SOS_OK) 066 sos_irq_handler_array[irq_level] = NUL 065 sos_irq_handler_array[irq_level] = NULL; 067 } 066 } 068 else /* Disable this idt entry */ 067 else /* Disable this idt entry */ 069 { 068 { 070 retval 069 retval 071 = sos_idt_set_handler(SOS_IRQ_BASE + i 070 = sos_idt_set_handler(SOS_IRQ_BASE + irq_level, 072 (sos_vaddr_t)NUL 071 (sos_vaddr_t)NULL /* Disable IDTE */, 073 0 /* Don't care 072 0 /* Don't care */); 074 } 073 } 075 074 076 /* Update the PIC only if an IRQ handler has 075 /* Update the PIC only if an IRQ handler has been set */ 077 if (sos_irq_handler_array[irq_level] != NULL 076 if (sos_irq_handler_array[irq_level] != NULL) 078 sos_i8259_enable_irq_line(irq_level); 077 sos_i8259_enable_irq_line(irq_level); 079 else 078 else 080 sos_i8259_disable_irq_line(irq_level); 079 sos_i8259_disable_irq_line(irq_level); 081 080 082 sos_restore_IRQs(flags); 081 sos_restore_IRQs(flags); 083 return retval; 082 return retval; 084 } 083 } 085 084 086 085 087 sos_irq_handler_t sos_irq_get_routine(int irq_ 086 sos_irq_handler_t sos_irq_get_routine(int irq_level) 088 { 087 { 089 if ((irq_level < 0) || (irq_level >= SOS_IRQ 088 if ((irq_level < 0) || (irq_level >= SOS_IRQ_NUM)) 090 return NULL; 089 return NULL; 091 090 092 /* Expected to be atomic */ 091 /* Expected to be atomic */ 093 return sos_irq_handler_array[irq_level]; 092 return sos_irq_handler_array[irq_level]; 094 } 093 } 095 094 096 095 097 sos_ui32_t sos_irq_get_nested_level() 096 sos_ui32_t sos_irq_get_nested_level() 098 { 097 { 099 /* No need to disable interrupts here */ 098 /* No need to disable interrupts here */ 100 return sos_irq_nested_level_counter; 099 return sos_irq_nested_level_counter; 101 } 100 }
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |