Troubles with _intr_v86

I’m programming a TWT pc/104 watchdog.
In the DOS file system it works fine with this instruction:
inregs.x.ax=0xc301; // enable watchdog
inregs.x.bx=0x000a; // 10 seconds
int86(0x15,&inregs,&outregs);
,
But the corresponding function for int86() in QNX, _intr_v86(), is not
working.
I’ve used:
memset(&reg, 0, sizeof(reg));
reg.eax = 0xc301;
reg.ebx = 0x000a;
_intr_v86(0x15, &reg, NULL, 0);

Someone know what’s wrong ?

Thanks,
Ricardo Azevedo : ricardoaz@terra.com.br

Ricardo Az <ricardoaz@terra.com.br> wrote in article <3D7492F6.5000603@terra.com.br>…

I’m programming a TWT pc/104 watchdog.
In the DOS file system it works fine with this instruction:
inregs.x.ax=0xc301; // enable watchdog
inregs.x.bx=0x000a; // 10 seconds
int86(0x15,&inregs,&outregs);
,
But the corresponding function for int86() in QNX, _intr_v86(), is not
working.

_intr_v86() returns -1, right?

I’ve used:
memset(&reg, 0, sizeof(reg));
reg.eax = 0xc301;
reg.ebx = 0x000a;
_intr_v86(0x15, &reg, NULL, 0);

could you provide more complete code?

Eduard.
ed1k at ukr dot net


Someone know what’s wrong ?

Thanks,
Ricardo Azevedo : > ricardoaz@terra.com.br

Ricardo Az <ricardoaz@terra.com.br> wrote:
: Someone know what’s wrong ?

Are you running your program as root? The docs (somewhat obliquely) state
that your effective userid has to be root, otherwise the function fails
and sets errno to EPERM.


Steve Reid stever@qnx.com
TechPubs (Technical Publications)
QNX Software Systems

Are you running your program as root?
Yes



_intr_v86() returns -1, right?
Yes



could you provide more complete code?

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <x86/v86.h>
struct _v86reg reg;
int main( void )
{
int i;
memset(&reg, 0, sizeof(reg));
reg.eax = 0xc301;
reg.ebx = 0x000a;
i=_intr_v86(0x15, &reg, NULL, 0);
printf("\n _intr_v86 returns %d\n",i);
return EXIT_SUCCESS;
}


I also made some tests with _intr_v86() plotting pixels. However it
works (outside photon)…
Here the source:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <x86/v86.h>

struct _v86reg reg;

void setmode()
{
memset(&reg, 0, sizeof(reg));
reg.eax = 0x0013;
_intr_v86(0x10, &reg, NULL, 0);
}

void restore()
{
memset(&reg, 0, sizeof(reg));
reg.eax = 0x0003;
_intr_v86(0x10, &reg, NULL, 0);
}

void pixel(int x, int y)
{
memset(&reg, 0, sizeof(reg));
reg.eax = 0x0c04;
reg.ecx = x;
reg.edx = y;
_intr_v86(0x10, &reg, NULL, 0);
}

int main( void )
{
int i , tmp;
setmode();

for(i=0;i<100;i++)
pixel( i , 50);

sleep(5);
restore();
return EXIT_SUCCESS;
}

Since I have no TWT hardware I tried another int15 function:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <x86/v86.h>
struct _v86reg reg;
int main( void )
{
int i;
memset(&reg, 0, sizeof(reg));
reg.eax = 0x8600;
reg.ecx = 0x001e; //MSW (uS)
reg.edx = 0x8480; //LSW (uS)
//sleep for 2 seconds
i=_intr_v86(0x15, &reg, NULL, 0);
printf("\n _intr_v86 returns %d\n",i);
return EXIT_SUCCESS;
}

And it also works. It gives delay for some more time than 2 seconds in QNX, but it does work. I’m
afraid I can’t help you, sorry.

Eduard.
ed1k at ukr dot net

Ricardo Az <ricardoaz@terra.com.br> wrote:

Are you running your program as root?
Yes

_intr_v86() returns -1, right?
Yes

What’s errno set to? Chances are it’s EFAULT; your BIOS might be trying
to execute a Ring 0 instruction, which is illegal in v86 mode.

(Instructions that are Ring 0 were not part of the original 8086
instruction set).

If that’s the case, I don’t think there is any solution, other than
to rewrite the code to use Neutrino’s timer API instead.

Dave

David Donohoe <ddonohoe@qnx.com> wrote in article <al82it$cje$1@nntp.qnx.com>…

Ricardo Az <> ricardoaz@terra.com.br> > wrote:
Are you running your program as root?
Yes

_intr_v86() returns -1, right?
Yes

What’s errno set to? Chances are it’s EFAULT; your BIOS might be trying
to execute a Ring 0 instruction, which is illegal in v86 mode.

(Instructions that are Ring 0 were not part of the original 8086
instruction set).

If that’s the case, I don’t think there is any solution, other than
to rewrite the code to use Neutrino’s timer API instead.

It is not the solution to replace hardware watchdog by OS timer. This hardware is exactly designed
to avoid Operation System’s hang. I think, if that’s the case, the better way is to set hardware
watchdog by BIOS somewhere in loader (secondary loader is good and there is enough place to add few
asm instructions) and include watchdog’s periodically reseting program (based on Neutrino’s timer)
into image and launch this “watchdog’s resetter” just after procnto (or if 10 secs is actually
required time - this time is quite enough for booting Neutrino…). Another way could be to get
hardware specifications (or source for the BIOS function) and there is a chance it could be done by
few i/o port access operations…
BTW, errno=EFAULT is not documented for this function. Why?

Eduard.
ed1k at ukr dot net

ed1k <ed1k@spamerstrap.com> wrote:

: BTW, errno=EFAULT is not documented for this function. Why?

I wondered the same thing; I’ll look into it.


Steve Reid stever@qnx.com
TechPubs (Technical Publications)
QNX Software Systems

Does the QNX kernel make some control of int 15 ?