2007-12-02 Till Straumann <strauman@slac.stanford.edu>

* shared/irq/i8259.c, shared/irq/irq.h, shared/irq/irq_supp.h,
	shared/irq/openpic_i8259_irq.c: BSP_disable_irq_at_pic(),
	openpic_disable_irq(), BSP_irq_disable_at_i8259s() now return
	0/1 if irq was disabled/enabled prior to disabling.
	irq_supp.h now exports a inline helper routine for scanning
	a list of shared handlers; to be used by PIC drivers.
This commit is contained in:
Till Straumann
2007-12-02 21:49:07 +00:00
parent daccc4ad33
commit c10dc130f9
5 changed files with 60 additions and 33 deletions

View File

@@ -1,3 +1,12 @@
2007-12-02 Till Straumann <strauman@slac.stanford.edu>
* shared/irq/i8259.c, shared/irq/irq.h, shared/irq/irq_supp.h,
shared/irq/openpic_i8259_irq.c: BSP_disable_irq_at_pic(),
openpic_disable_irq(), BSP_irq_disable_at_i8259s() now return
0/1 if irq was disabled/enabled prior to disabling.
irq_supp.h now exports a inline helper routine for scanning
a list of shared handlers; to be used by PIC drivers.
2007-12-02 Till Straumann <strauman@slac.stanford.edu> 2007-12-02 Till Straumann <strauman@slac.stanford.edu>
* shared/openpic/openpic.c shared/openpic/openpic.h, * shared/openpic/openpic.c shared/openpic/openpic.h,

View File

@@ -29,21 +29,23 @@ volatile rtems_i8259_masks i8259s_cache = 0xfffb;
| Description: Mask IRQ line in appropriate PIC chip. | Description: Mask IRQ line in appropriate PIC chip.
| Global Variables: i8259s_cache | Global Variables: i8259s_cache
| Arguments: vector_offset - number of IRQ line to mask. | Arguments: vector_offset - number of IRQ line to mask.
| Returns: Nothing. | Returns: original state or -1 on error.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine) int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine)
{ {
unsigned short mask; unsigned short mask;
rtems_interrupt_level level; rtems_interrupt_level level;
int rval;
if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) || if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET) ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)
) )
return 1; return -1;
rtems_interrupt_disable(level); rtems_interrupt_disable(level);
mask = 1 << irqLine; mask = 1 << irqLine;
rval = i8259s_cache & mask ? 0 : 1;
i8259s_cache |= mask; i8259s_cache |= mask;
if (irqLine < 8) if (irqLine < 8)
@@ -56,7 +58,7 @@ int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine)
} }
rtems_interrupt_enable(level); rtems_interrupt_enable(level);
return 0; return rval;
} }
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+

View File

@@ -157,6 +157,9 @@ void BSP_i8259s_init(void);
* function to disable a particular irq at 8259 level. After calling * function to disable a particular irq at 8259 level. After calling
* this function, even if the device asserts the interrupt line it will * this function, even if the device asserts the interrupt line it will
* not be propagated further to the processor * not be propagated further to the processor
*
* RETURNS: 1/0 if the interrupt was enabled/disabled originally or
* a value < 0 on error.
*/ */
int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine); int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine);
/* /*

View File

@@ -30,7 +30,11 @@ extern "C" {
* PIC(s). * PIC(s).
*/ */
extern void BSP_enable_irq_at_pic (const rtems_irq_number irqLine); extern void BSP_enable_irq_at_pic (const rtems_irq_number irqLine);
extern void BSP_disable_irq_at_pic (const rtems_irq_number irqLine); /*
* RETURNS: nonzero (> 0 ) if irq was enabled originally, zero if irq
* was off and negative value if there was an error.
*/
extern int BSP_disable_irq_at_pic (const rtems_irq_number irqLine);
/* /*
* Initialize the PIC. * Initialize the PIC.
@@ -48,6 +52,38 @@ struct _BSP_Exception_frame;
*/ */
void C_dispatch_irq_handler (struct _BSP_Exception_frame *frame, unsigned int excNum); void C_dispatch_irq_handler (struct _BSP_Exception_frame *frame, unsigned int excNum);
/*
* Snippet to be used by PIC drivers;
* enables interrupts, traverses list of
* shared handlers for a given interrupt
* and restores original irq level
*/
static inline void
bsp_irq_dispatch_list(rtems_irq_connect_data *tbl, unsigned irq, rtems_irq_hdl sentinel)
{
register uint32_t l_orig;
l_orig = _ISR_Get_level();
/* Enable all interrupts */
_ISR_Set_level(0);
/* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */
{
rtems_irq_connect_data* vchain;
for( vchain = &tbl[irq];
((int)vchain != -1 && vchain->hdl != sentinel);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->hdl(vchain->handle);
}
}
/* Restore original level */
_ISR_Set_level(l_orig);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -118,7 +118,7 @@ BSP_enable_irq_at_pic(const rtems_irq_number name)
} }
} }
void int
BSP_disable_irq_at_pic(const rtems_irq_number name) BSP_disable_irq_at_pic(const rtems_irq_number name)
{ {
#ifdef BSP_PCI_ISA_BRIDGE_IRQ #ifdef BSP_PCI_ISA_BRIDGE_IRQ
@@ -126,15 +126,16 @@ BSP_disable_irq_at_pic(const rtems_irq_number name)
/* /*
* disable interrupt at PIC level * disable interrupt at PIC level
*/ */
BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET); return BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
} }
#endif #endif
if (is_pci_irq(name)) { if (is_pci_irq(name)) {
/* /*
* disable interrupt at OPENPIC level * disable interrupt at OPENPIC level
*/ */
openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET); return openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
} }
return -1;
} }
/* /*
@@ -209,30 +210,6 @@ int _BSP_vme_bridge_irq = -1;
unsigned BSP_spuriousIntr = 0; unsigned BSP_spuriousIntr = 0;
static inline void
dispatch_list(unsigned int irq)
{
register uint32_t l_orig;
l_orig = _ISR_Get_level();
/* Enable all interrupts */
_ISR_Set_level(0);
/* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[irq];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->hdl(vchain->handle);
}
}
/* Restore original level */
_ISR_Set_level(l_orig);
}
/* /*
* High level IRQ handler called from shared_raw_irq_code_entry * High level IRQ handler called from shared_raw_irq_code_entry
*/ */
@@ -247,7 +224,7 @@ void C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
if (excNum == ASM_DEC_VECTOR) { if (excNum == ASM_DEC_VECTOR) {
dispatch_list(BSP_DECREMENTER); bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);
return; return;
@@ -282,7 +259,7 @@ void C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
#endif #endif
/* dispatch handlers */ /* dispatch handlers */
dispatch_list(irq); bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
#ifdef BSP_PCI_ISA_BRIDGE_IRQ #ifdef BSP_PCI_ISA_BRIDGE_IRQ
if (isaIntr) { if (isaIntr) {