OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [score603e/] [startup/] [genpvec.c] - Rev 562

Go to most recent revision | Compare with Previous | Blame | View Log

/*  genpvec.c
 *
 *  These routines handle the external exception.  Multiple ISRs occur off
 *  of this one interrupt.
 *
 *  COPYRIGHT (c) 1989-1997.
 *  On-Line Applications Research Corporation (OAR).
 *  Copyright assigned to U.S. Government, 1994.
 *
 *  The license and distribution terms for this file may in
 *  the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id: 
 */
 
#include <bsp.h>
#include "chain.h"
#include <assert.h>
 
#include <stdio.h> /* for sprintf */
 
 
/* 
 * Proto types for this file                                          
 */
 
rtems_isr external_exception_ISR (
  rtems_vector_number   vector                                  /* IN  */
);
 
#define   NUM_LIRQ_HANDLERS   20
#define   NUM_LIRQ            ( MAX_BOARD_IRQS - PPC_IRQ_LAST )
 
/* 
 * Structure to for one of possible multiple interrupt handlers for 
 * a given interrupt.
 */
typedef struct
{
  Chain_Node          Node;
  rtems_isr_entry     handler;                  /* isr routine        */
  rtems_vector_number vector;                   /* vector number      */
} EE_ISR_Type;
 
 
/* Note:  The following will not work if we add a method to remove
 *        handlers at a later time.
 */
  EE_ISR_Type       ISR_Nodes [NUM_LIRQ_HANDLERS];
  rtems_unsigned16  Nodes_Used; 
  Chain_Control     ISR_Array  [NUM_LIRQ];
 
/* XXX */
void init_irq_data_register();
 
void initialize_external_exception_vector ()
{
  int i;
  rtems_isr_entry previous_isr;
  rtems_status_code status;
 
  Nodes_Used = 0;
 
  /*
   * Mask out all interupts until they have a handler installed.
   */
 
  for (i=0; i <NUM_LIRQ; i++)
    Chain_Initialize_empty( &ISR_Array[i] );
 
  init_irq_data_register();
 
  /*  
   * Install external_exception_ISR () as the handler for 
   *  the General Purpose Interrupt.
   */
  status = rtems_interrupt_catch( external_exception_ISR, 
           PPC_IRQ_EXTERNAL, (rtems_isr_entry *) &previous_isr );
}
 
void Init_EE_mask_init() {
;
}
 
/*
 *  This routine installs one of multiple ISRs for the general purpose 
 *  inerrupt.
 */
rtems_isr_entry  set_EE_vector(
  rtems_isr_entry     handler,      /* isr routine        */
  rtems_vector_number vector        /* vector number      */
)
{
  rtems_unsigned16 vec_idx  = vector - Score_IRQ_First;
  rtems_unsigned32 index;
 
  assert  (Nodes_Used < NUM_LIRQ_HANDLERS);
 
  /*
   *  If we have already installed this handler for this vector, then
   *  just reset it.
   */
 
  for ( index=0 ; index <= Nodes_Used ; index++ ) {
    if ( ISR_Nodes[index].vector == vector &&
         ISR_Nodes[index].handler == handler )
      return NULL;
  }
 
  /*
   *  Doing things in this order makes them more atomic
   */
 
  Nodes_Used++; 
 
  index = Nodes_Used - 1;
 
  ISR_Nodes[index].handler = handler;
  ISR_Nodes[index].vector  = vector;
 
  /* printf( "Vector Index: %04x, Vector: %d (%x)\n", 
          vec_idx, vector, vector); */
 
  Chain_Append( &ISR_Array[vec_idx], &ISR_Nodes[index].Node );
 
  /*
   * Unmask the interrupt.
   */
  unmask_irq( vec_idx );
 
  return NULL;
}
 
/* 
 * This interrupt service routine is called for an External Exception.
 */
rtems_isr external_exception_ISR (
  rtems_vector_number   vector             /* IN  */
)
{ 
 rtems_unsigned16    index;
 EE_ISR_Type         *node;
 rtems_unsigned16    value;
 char                err_msg[100];
#if (HAS_PMC_PSC8)
 rtems_unsigned16    PMC_irq;
 rtems_unsigned16    check_irq;
 rtems_unsigned16    status_word;
#endif
 
 index = read_and_clear_irq();
 if ( index >= NUM_LIRQ ) {
   sprintf( err_msg, "ERROR:: Invalid interrupt number (%02x)\n", index );
   DEBUG_puts( err_msg );
   return;
 }
 
#if (HAS_PMC_PSC8)
  PMC_irq = SCORE603E_PCI_IRQ_0 - SCORE603E_IRQ00;
 
  if (index ==  PMC_irq) {
    status_word = read_and_clear_PMC_irq( index );
 
    for (check_irq=SCORE603E_IRQ16; check_irq<=SCORE603E_IRQ19; check_irq++) {
      if ( Is_PMC_IRQ( check_irq, status_word )) {
        index = check_irq - SCORE603E_IRQ00;
        node = (EE_ISR_Type *)(ISR_Array[ index ].first);
 
        if ( _Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
          sprintf(err_msg,"ERROR:: check %d interrupt %02d has no isr\n", 
                  check_irq, index);
          DEBUG_puts( err_msg);
          value = get_irq_mask();
          sprintf(err_msg,"        Mask = %02x\n", value);
          DEBUG_puts( err_msg);
	}
        while ( !_Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
          (*node->handler)( node->vector );
          node = (EE_ISR_Type *) node->Node.next;
        }
      }
    }
  }
  else
#endif
  { 
    node = (EE_ISR_Type *)(ISR_Array[ index ].first);
    if ( _Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
      sprintf(err_msg,"ERROR:: interrupt %02x has no isr\n", index);
      DEBUG_puts( err_msg);
      value = get_irq_mask();
      sprintf(err_msg,"        Mask = %02x\n", value);
      DEBUG_puts( err_msg);
      return;
    }
    while ( !_Chain_Is_tail( &ISR_Array[ index ], (void *)node ) ) {
     (*node->handler)( node->vector );
     node = (EE_ISR_Type *) node->Node.next;
    }
  }
 
}
 
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.