delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2002/11/18/18:45:14

From: erfarmer201 AT comcast DOT net (Eric Farmer)
Newsgroups: comp.os.msdos.djgpp
Subject: Question re IRET wrapper and rdtsc
Date: 18 Nov 2002 15:35:46 -0800
Organization: http://groups.google.com/
Lines: 68
Message-ID: <a1babb92.0211181535.480d34e2@posting.google.com>
NNTP-Posting-Host: 128.244.67.244
X-Trace: posting.google.com 1037662546 24891 127.0.0.1 (18 Nov 2002 23:35:46 GMT)
X-Complaints-To: groups-abuse AT google DOT com
NNTP-Posting-Date: 18 Nov 2002 23:35:46 GMT
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Hello all,

I am experimenting with DJGPP, and I have a couple of questions about
a (serial port) interrupt handler I am working on.  (For a bit of
context, I am working on a random number generator based on timing
radioactive decay events, each of which will generate a serial port
interrupt.)

1.  I am using _go32_dpmi_allocate_iret_wrapper and family to install
the handler (see code below).  Does my handler need the commonly-used
cli/pusha preamble (and accompanying popa/sti), or does the wrapper
code do this for me?  I have been unable to decipher the djgpp source,
and there seems to be conflicting advice out there.

2.  Is the rdtsc inline assembly correct?  Note that Intel suggests
also calling cpuid to "serialize," which fills eax, ebx, ecx, and edx.
 My main question here is whether I have correctly accounted for
"clobbered" registers.

Any comments are appreciated.

Thanks,
Eric Farmer

#include <crt0.h>
#include <dpmi.h>
#include <go32.h>

int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY;

int irq = 1;

void isr() {

    // cli?
    // pusha?

    unsigned long long tsc;
    asm volatile ("cpuid\n\t"
                  "rdtsc"
                  : "=A" (tsc)
                  :
                  : "bx", "cx");

    // sti?

    ...

    outportb(0x20, 0x20);

    // popa?
}

int main() {
    _go32_dpmi_seginfo old_isr, new_isr;
    _go32_dpmi_get_protected_mode_interrupt_vector(irq + 8, &old_isr);
    new_isr.pm_offset = (int)isr;
    new_isr.pm_selector = _go32_my_cs();
    _go32_dpmi_allocate_iret_wrapper(&new_isr);
    _go32_dpmi_set_protected_mode_interrupt_vector(irq + 8, &new_isr);

    ...

    _go32_dpmi_set_protected_mode_interrupt_vector(irq + 8, &old_isr);
    _go32_dpmi_free_iret_wrapper(&new_isr);

    return 0;
}

- Raw text -


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