www.delorie.com/djgpp/bugs/show.cgi   search  
Bug 000061

When Created: 02/19/1996 23:17:10
Against DJGPP version: 2.00
By whom: karn@unix.ka9q.ampr.org
Abstract: No way to unchain interrupt vectors
There appears to be no clean way to unchain a hardware interrupt handler
with the existing library. I.e., there is no counterpart to

_go32_dpmi_chain_protected_mode_interrupt_vector()

nor is it easy to write one given the way this function works. It
creates a wrapper and passes it to __dpmi_set_protected_mode_interrupt_vector(),
but it does so in an automatic variable that is lost when the chain call
returns. So you can't just pass the info arg to _go32_dpmi_free_iret_wrapper(),
as the info arg still points to your protected mode handler, not to the
wrapper. If the address of the wrapper were written into the info
argument as is done in go32_dpmi_allocate_iret_wrapper(), this would be
much easier.

Solution added: 02/20/1996 00:44:16
By whom: karn@unix.ka9q.ampr.org
I've written a _go32_dpmi_unchain_protected_mode_interrupt_vector()
that seems to work. Feel free to add this to src/libc/go32/gopint.c

int
_go32_dpmi_unchain_protected_mode_interrupt_vector(uint irq,_go32_dpmi_seginfo *info)
{

  __dpmi_paddr v;
  char *stack;
  char *wrapper;

  __dpmi_get_protected_mode_interrupt_vector(irq,&v);
  /* Sanity check: does the vector point into our program? A bug in gdb
   * keeps us from hooking the keyboard interrupt when we run under its
   * control. This test catches it.
   */
  if(v.selector != _go32_my_cs())
	return -1;
  wrapper = (char *)v.offset32;
  /* Extract previous vector from the wrapper chainback area */
  v.offset32 = *(long *)(wrapper + 0x5b);
  v.selector = *(short *)(wrapper + 0x5f);
  /* Extract stack base from address of _call_count variable in wrapper */
  stack = (char *)(*(long *)(wrapper+0x0F) - 8);
#define	STACK_WAS_MALLOCED	(1 << 0)

  if (*(long *) stack & STACK_WAS_MALLOCED)
      free(stack);
  free(wrapper);
  __dpmi_set_protected_mode_interrupt_vector(irq,&v);
  return 0;
}

Solution added: 02/20/1996 17:01:00
By whom: sandmann@clio.rice.edu
The original idea behind this was if you needed to unchain, what you
did was get the current interrupt vector before the chain call, then
restore it when you are done.  This is only two lines of code, so
it's not clear that we need anything more complicated than this.

Note added: 02/20/1996 17:03:27
By whom: sandmann@clio.rice.edu
There is one fault with the chain code however - there should be 
some way to (probably with the return value) to chain or IRET.
This would allow easy writing of handlers for increased tick 
frequency (which sometimes need to IRET and other times to chain).

Note added: 10/01/1996 06:19:20
By whom: ilya@spy.isp.nsc.ru
There also no way to chain handlers in the way of calling previous handler
*before* next. It may be needed in several ways when previous handler is
much more important then your own, or when your handler uses the result of
previous handler. However all this discussion becomes useless if there will
be implemented the function to just *call* previous handler from inside of
interrupt handler. It may be function like __dpmi_call_iret(prev_handler);
which pushes flags and far pointer and jmps to the prev_handler. It's simple, 
isn't it ?

Closed on 04/13/1999 09:00:04: This is a feature (until someone volunteers to make it better ;-).
By whom: eliz@is.elta.co.il



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