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