delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2002/06/11/04:46:02

From: AYeryomin AT excelsior-usa DOT com (Alex Yeryomin)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Question about djgpp's int-wrapper
Date: 10 Jun 2002 22:44:23 -0700
Organization: http://groups.google.com/
Lines: 108
Message-ID: <96eb2770.0206102144.74a87c25@posting.google.com>
References: <5 DOT 0 DOT 2 DOT 1 DOT 2 DOT 20020608134608 DOT 009e4050 AT pop DOT gmx DOT net>
NNTP-Posting-Host: 212.164.176.30
X-Trace: posting.google.com 1023774263 24685 127.0.0.1 (11 Jun 2002 05:44:23 GMT)
X-Complaints-To: groups-abuse AT google DOT com
NNTP-Posting-Date: 11 Jun 2002 05:44:23 GMT
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Hi all.

So, it means that some of DPMI providers may "block" sti/cli
instruction. But if your program runs under "pure" DOS & CWSDPMI
(usual DJGPP configuration), you can rely upon the fact that it works
fine with privelage instructions like sti/cli, and without any CPU
time overhead.

Since cli and sti are privileged instructions, they will cause a
protection violation and the DPMI provider will simulate the
instruction. Because of the overhead involved in processing the
exception, cli and sti should be used as little as possible. In
general, you should expect either of these instructions to require at
least 300 clocks (see below how you can test it).

As a rule (near 100% of probability) the interrupt controller on your
computer will work in FNI mode (Fully Nested Interrupt mode). It means
that when an intterupt is raised, the interrupt controller (f.e. Intel
8259 chip) is immediatelly blocked - it will not accept any interrupt
request from peripheral devices till the handler processing the
current interrupt tells NON_SPECIFIC_END_OF_INTERRUPT (=0x20) to
interrupt controller's control register (0x20 port for leading, 0xA0
port for driven IC). And the program should enable CPU to process
interrupts to set IF flag.

Of course, when the instuction "iret" is executed, it restores IF flag
of CPU (and all context previously stored to the stack when the
inturrupt was raised). But don't forget that if some of hardware
interrupt handlers, which your program establishes, may work a long
time you must give a change to others interrupts to be proccessed. It
is inadmissibly to lost some important interrupts, f.e, timer, I/O
interruprs and so on.

An interrupt handler may look like this (it is real hardware interrupt
handler for Real Time Clock to count milliseconds):

static void RTC_Interrupt_Handler (void)
{
  INTERRUPT_ENTER ();

  // Read status register 3 of RTC, otherwise
  // the interrupt will not be enabled
  readReg (RTC_STATUS_REG_3);

  // Read status register 2 of RTC
  // timer interrupt?
  if (readReg (RTC_STATUS_REG_2) & 0x40)
    ++TimerCount;

  INTERRUPT_LEAVE_BOTH ();
}
END_OF_STATIC_FUNCTION (RTC_Interrupt_Handler);


where:


#define INTERRUPT_ENTER(); asm ("sti"); /* enable maskable interrupts
*/

#define INTERRUPT_LEAVE(); asm ("cli"); /* disable maskable interrupts
*/ \
                           outportb (0x20, 0x20); /* End of interrupt 
*/

#define INTERRUPT_LEAVE_BOTH();	asm ("cli"); /* disable maskable
interrupts */ \
                                outportb (0x20, 0x20); /* End of
interrupt  */ \
                                outportb (0xA0, 0x20); /* End of
interrupt  */

Here, we must unblock both the leading Interrupt Controller and driven
one because the RTC interrupt is mapped to the second IC.


Again, in general, you should expect that "sti" or "cli" instructions
to require many clocks under some DPMI provider. But used pure DOS it
takes only several CPU ticks. How can you test it?It is easy. Use
"rdtsc" instruction. It allows to take CPU ticks at the moment, and
returns 64-bits tick counter from the computer has rebooted. It shows
that "sti" takes only ~30 CPU ticks to be executed. It proves that a
program under DOS & CWSDMPI has enough privelage to execute "sti" or
"cli" instructions.

Best regards,

Alex



PS Here is "rdtsc" code.

-------------------------------------------
[BITS 32]
[GLOBAL _Read_TSC]
[SECTION .text]
_Read_TSC:
        mov ecx, [esp+4]
        rdtsc
        mov [ecx], eax
        mov [ecx+4], edx
        ret
;_Read_TSC 
-------------------------------------------
typedef unsigned long long int TICK;
extern void Read_TSC (TICK *tick);
-------------------------------------------

- Raw text -


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