delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/08/31/11:30:14

Message-ID: <68C4CF842BD2D411AC1600902740B6DA02CDC54E@mcoexc02.mlm.maxtor.com>
From: "Dykstra, Sean" <Sean_Dykstra AT maxtor DOT com>
To: "'djgpp AT delorie DOT com'" <djgpp AT delorie DOT com>
Subject: RE: Help! - INT x22 problem.
Date: Fri, 31 Aug 2001 09:06:50 -0600
MIME-Version: 1.0
X-Mailer: Internet Mail Service (5.5.2653.19)
Reply-To: djgpp AT delorie DOT com

Hello!

At the moment I am only hooking 1 interrupt.  However, the code is written
to support multiple cards all sharing the same interrupt, so I am using the
chain function.  Initially, I was hooking the timer interrupt but I removed
that to eliminate that as a possibility.  Note, there is a hook to attach
callback functions which happens as well.

I am only hooking the protected mode interrupt.  There is some old lock code
below, but I planning on removing it as I now lock the entire app into
memory  (I have already removed the lock code for locking the vars...But I
wanted to send you the file unedited from what I am running now).  I have
found it to lock up on several machines so far, I will attempt to
characterize them for BIOS, manufacturer, etc..  The interrupt frequency is
about 1 interrupt every 40us - 70us.  One of the machines that passed was an
233Mhz Intel PIIX4 motherboard (Packard Bell), one of the machines that
failed is a clone 1Ghz ASUS motherboard with a VIA chipser).  Another note,
at this point I am not doing any UDMA, the interrupts are generated based on
PIO transfers.  I am attaching the code below.  One of the other reasons for
using C code is that I call back into the app (another reason I suspect the
stack might be corrupted).  Can I still do this if I write the handler
assembly?  You will also notice that I have a handler for each possible IRQ.
This is for performance reasons, but I am only hooking one at the moment.  

//==========================================================================
=============================
// intr.c - Interrupt definition
//
//==========================================================================
=============================
//==========================================================================
=============================
// REVISION HISTORY
//==========================================================================
=============================
// $Logfile:   M:/TOOLSGRP/RELEASE/universal/Portable/intr.c_v  $
// $Date:   22 Aug 2001 09:35:58  $
// $Revision:   1.7  $
// Revision history is at end of this file
//==========================================================================
=============================
//==========================================================================
=============================

#include "..\..\common\common.h"
#include "pci.h"
#include "intr.h"
#include <stdio.h>
#include <go32.h>
#include <dpmi.h>

static _go32_dpmi_seginfo pm_old_handler[NUMIRQ];
static _go32_dpmi_seginfo pm_new_handler[NUMIRQ];
static int alreadylocked=FALSE;


void (lptr * CallBack[NUMIRQ][MAXCONTROLLERS])();

#define PIC1ADDR 0x020
#define PIC2ADDR 0x0A0
#define SPECIFICEOI 0x060
#define GENERALEOI 0x020
#define CHAINEOI 0x062

void
pm_new01h (void)
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[1][Count]!=NULL)
     {
        (CallBack[1][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC1ADDR,SPECIFICEOI+1);
  
  enable ();
}

void
pm_new02h (void)
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[2][Count]!=NULL)
     {
        (CallBack[2][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC1ADDR,SPECIFICEOI+2);
  
  enable ();
}

void
pm_new03h (void)
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[3][Count]!=NULL)
     {
        (CallBack[3][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC1ADDR,SPECIFICEOI+3);
  
  enable ();
}

void
pm_new04h (void)
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[4][Count]!=NULL)
     {
        (CallBack[4][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC1ADDR,SPECIFICEOI+4);
  
  enable ();
}

void
pm_new05h (void)
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[5][Count]!=NULL)
     {
        (CallBack[5][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC1ADDR,SPECIFICEOI+5);
  
  enable ();
}

void
pm_new06h (void)
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[6][Count]!=NULL)
     {
        (CallBack[6][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC1ADDR,SPECIFICEOI+6);
  
  enable ();
}

void
pm_new07h (void)
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[7][Count]!=NULL)
     {
        (CallBack[7][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC1ADDR,SPECIFICEOI+7);
  
  enable ();
}

void
pm_new70h (void) //IRQ 8
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[8][Count]!=NULL)
     {
        (CallBack[8][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+0);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
pm_new71h (void) //IRQ 9
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[9][Count]!=NULL)
     {
        (CallBack[9][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+1);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
pm_new72h (void) //IRQ 10
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[10][Count]!=NULL)
     {
        (CallBack[10][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+2);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
pm_new73h (void) //IRQ 11
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[11][Count]!=NULL)
     {
        (CallBack[11][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+3);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
pm_new74h (void) //IRQ 12
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[12][Count]!=NULL)
     {
        (CallBack[12][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+4);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
pm_new75h (void) //IRQ 13
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[13][Count]!=NULL)
     {
        (CallBack[13][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+5);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
pm_new76h (void) //IRQ 14
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[14][Count]!=NULL)
     {
        (CallBack[14][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+6);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
pm_new77h (void) //IRQ 15
{
  int Count=0;
  disable ();

  //Call each controller specific handler that is attached to the given IRQ
  while (Count!=MAXCONTROLLERS)
  {
     if (CallBack[15][Count]!=NULL)
     {
        (CallBack[15][Count])();
     }
     Count++;
  }

  //Clear the PIC
  outportb (PIC2ADDR,SPECIFICEOI+7);
  outportb (PIC1ADDR,CHAINEOI);
  
  enable ();
}

void
lock_pm_all (void)
{
  _go32_dpmi_lock_code (pm_new01h, (unsigned long) (lock_pm_all -
pm_new01h));
}

void
IRQ_init ()
{

   unsigned int pit0_set, pit0_value;
   int IRQ=0;
   int Count;
   int InnerCount;
   if (FALSE == alreadylocked )
   {
      //temporarily disable all interrupts
      disable ();

      //Make sure that the Callbacks are all pointing to NULLS
      for (Count=0;Count < NUMIRQ;Count++)
      {
         for (InnerCount=0;InnerCount< MAXCONTROLLERS;InnerCount++)
         {
            CallBack[Count][InnerCount]=NULL;
         }
      }

      //lock all possible memory locations associated with an IRQ
      lock_pm_all ();

      //Save away all the old vectors for restoration later
      for (Count=0;Count<16;Count++)
      {
         IRQ=Count;
         if (IRQ>7)
         {
            IRQ+=(0x070-0x08);
         }
         else
         {
            IRQ+=8;
         }
         _go32_dpmi_get_protected_mode_interrupt_vector (IRQ,
&pm_old_handler[Count]);
      }

      alreadylocked=TRUE;
      enable ();
   }

}


void
IRQ_exit (void)
{
   int IRQ=0;
   int Count;

   if (TRUE == alreadylocked)
   {

      disable ();

      //Save away all the old vectors for restoration later
      for (Count=0;Count<16;Count++)
      {
         IRQ=Count;
         if (IRQ>7)
         {
            IRQ+=(0x070-0x08);
         }
         else
         {
            IRQ+=8;
         }
         _go32_dpmi_set_protected_mode_interrupt_vector (IRQ,
&pm_old_handler[Count]);
      }

      enable ();

      alreadylocked=FALSE;

    }
}

int AttachIRQ (IN int16 IRQNum,IN void (lptr *NewCallBack)() )
{
    int Count;
    int IRQ=IRQNum;
    int ret;
    int Mask;  //IRQ Mask

    for (Count=0;Count<MAXCONTROLLERS;Count++)
    {
       //If we have arrived at a NULL pointer in our list, attach
       //to the CallBack
       if (CallBack[IRQNum][Count]==NULL)
       {
          //Unmask the interupt
          if (IRQ<8)
          {
             Mask=inportb (0x021);
             Mask&=~(1<<IRQ);
             outportb (0x21,Mask);
          }
          else {
             //For the upper interrupts we need to make sure the lower chain
             //is unmasked (IRQ 2)
             Mask=inportb (0x021);
             Mask&=~(2<<IRQ);
             outportb (0x21,Mask);
             
             Mask=inportb (0x0A1);
             Mask&=~(1<<(IRQ-8));
             outportb (0xA1,Mask);
          }
          switch (IRQNum)
          {
             case 1:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new01h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 2:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new02h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 3:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new03h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 4:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new04h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 5:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new05h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 6:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new06h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 7:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new07h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 8:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new70h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 9:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new71h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 10:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new72h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 11:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new73h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 12:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new74h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 13:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new75h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 14:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new76h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
             case 15:
                pm_new_handler[IRQNum].pm_offset = (int) pm_new77h;
                pm_new_handler[IRQNum].pm_selector = _go32_my_cs ();
                break;
          }
          if (IRQ>7)
          {
            IRQ+=(0x070-0x08);
          }
          else
          {
            IRQ+=8;
          }
                
          _go32_dpmi_chain_protected_mode_interrupt_vector (IRQ,
&pm_new_handler[IRQNum]);


          CallBack[IRQNum][Count]=NewCallBack;
          return (0);
       }
       //If the NewCallBack pointer matches an existing Callback
       //dont bother attaching again.
       if (CallBack[IRQNum][Count]==NewCallBack)
       {
          return (0);
       }
    }
    return (1);
}





/*==================================================================

   $Log:   M:/TOOLSGRP/RELEASE/universal/Portable/intr.c_v  $
 * 
 *    Rev 1.7   22 Aug 2001 09:35:58   mcosedykst
 * Fixed interrupts on the CMD card.
 * 
 *    Rev 1.6   15 Aug 2001 18:06:22   mcosedykst
 * Fixed the lower 8 interrupts.
 * 
 *    Rev 1.5   25 Jun 2001 08:46:34   mcosedykst
 * Added additional support for interrupt code.
 * 
 *    Rev 1.4   21 Jun 2001 08:32:56   mcosedykst
 * Added some interrupt code.
 * 
 *    Rev 1.3   20 Jun 2001 15:51:38   mcosedykst
 * More interrupt support.
 * 
 *    Rev 1.2   14 May 2001 10:38:28   mcosedykst
 * Rearranged function calls for the new layout.
 * 
 *    Rev 1.1   02 May 2001 11:17:20   mcosedykst
 * Added log information.

==================================================================*/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019