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