Mail Archives: djgpp/2001/08/31/11:30:14
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 -