PIT not triggering an IRQ on VMWare.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

PIT not triggering an IRQ on VMWare.

Post by mduft »

Hi

i have a problem with the PIT not triggering an IRQ. I have all things set up (i hope correctly), but the interupt is simply not triggered. interupts work well alltogether, triggering the correspoding int manually using inline assembly works perfectly.

Also i have checked my PIT setup, but reading the timer count in a tight loop, giving me different values all the time, so it ticks...

IRQ0 is unmasked on the master PIC, so that shouldn't be a problem either.

is there a simple way to check wether any of the PIC triggered interupts are delivered?

my PIC setup is done like this:

Code: Select all

	master_mask = _inp(SX_PIC_MASTER_DAT);
	slave_mask  = _inp(SX_PIC_SLAVE_DAT);

	/* begin init, include ICW4 */
	_outp(SX_PIC_MASTER_CMD,	SX_PIC_ICW1_INIT | SX_PIC_ICW1_IC4);
	_outp(SX_PIC_SLAVE_CMD,		SX_PIC_ICW1_INIT | SX_PIC_ICW1_IC4);

	/* set the interupt vector offsets */
	_outp(SX_PIC_MASTER_DAT,	SX_IRQ_BEGIN);
	_outp(SX_PIC_SLAVE_DAT,		SX_IRQ_BEGIN + 8);

	/* now send the IRQ lines to connect the two PICs */
	_outp(SX_PIC_MASTER_DAT,	4);
	_outp(SX_PIC_SLAVE_DAT,		2);

	/* now ICW4 */
	_outp(SX_PIC_MASTER_DAT,	SX_PIC_ICW4_8086);
	_outp(SX_PIC_SLAVE_DAT,		SX_PIC_ICW4_8086);

	SxConPrint(" * IRQ's remapped to higher Interupts ...\n");
	SxConPrint(" * Interupt Mask on PICs: Master: %bb Slave: %bb\n", master_mask, slave_mask);

	_outp(SX_PIC_MASTER_DAT,	master_mask);
	_outp(SX_PIC_SLAVE_DAT,		slave_mask);
and the timer setup is done like this:

Code: Select all

void SxTimerInit(sx_uint32 interval) {
	sx_uint32 divisor = SX_PIT_FREQUENCY / interval;
	sx_PitCommand cmd;

	SxIrqHandlerSet(0, SxHandleTimerIRQ);

	cmd.cmd.bcd = 0;
	cmd.cmd.mode = SX_PIT_MODE_RATE;

	_outp(SX_PIT_PORT_CMD, cmd.raw);

	_outp(SX_PIT_PORT_CH0, divisor & 0xFF);
	_outp(SX_PIT_PORT_CH0, (divisor>>8) & 0xFF);

	SxConPrint(" * Timer divisor set to %d\n", divisor);

	SxUnmaskPICInterupt(0);
}
hope thats enough but not too much information ..... :)
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

A few things to check:

1) You are reading in a 'tight loop'. Is the variable declared "volatile"?
2) Double check that you are sending an EOI at the end of the interrupt handler.
3) Double check your defines to ensure you really are setting a rate mode rather than fire once.

If you are using C and all is well in ASM, the most likely candidate is 1.

Cheers,
Adam
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

AJ wrote: 1) You are reading in a 'tight loop'. Is the variable declared "volatile"?
2) Double check that you are sending an EOI at the end of the interrupt handler.
3) Double check your defines to ensure you really are setting a rate mode rather than fire once.
thanks for the quick reply :)

1) hmm... nope, it wasn't volatile, but that one was just used to check wether _something_ happens.... i tried now with volatile, and get about the same results -> a long list of altering numbers :)
2) yes, i'm sending an EOI, but: it never gets there, since not a single interupt is triggered. thats my problem. i tried putting an "int 3" as first line of my interupt handler, to force a double/tripple fault, but nothing happened. the thing is that interupt handling works perfectly if i do "int 3" (or any other number of course), or provocate a div/0 exception... i seem to be completely lost here.
3) hmm... i think it's correct. heres what i have:

Code: Select all

#define SX_PIT_FREQUENCY	1193180
#define SX_PIT_PORT_CMD		0x43
#define SX_PIT_PORT_CH0		0x40
#define SX_PIT_PORT_CH1		0x41
#define SX_PIT_PORT_CH2		0x42

#define SX_PIT_MODE_IOTC	0	/* Interupt on Terminal Count */
#define SX_PIT_MODE_HWRTOS	1	/* Hardware re-triggerable one-shot */
#define SX_PIT_MODE_RATE	2	/* Rate generator */
#define SX_PIT_MODE_SQUARE	3	/* Square wave generator */
#define SX_PIT_MODE_STS		4	/* Software triggered strobe */
#define SX_PIT_MODE_HTS		5	/* Hardware triggered strobe */
and this is the union i use for more readability. i forgot that one above:

Code: Select all

typedef union {
	struct {
		sx_uint8 bcd		: 1;
		sx_uint8 mode		: 3;
		sx_uint8 access		: 2;
		sx_uint8 channel	: 1;
	} cmd;

	sx_uint8 raw;
} sx_PitCommand;
thanks again for taking time for this!

Cheers, Markus
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

Just looked at my code and I use mdoe 3 (Square wave generator) - does that make any difference? If not, I'll bow out and let someone else have a go!

Cheers,
Adam
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

AJ wrote: Just looked at my code and I use mdoe 3 (Square wave generator) - does that make any difference? If not, I'll bow out and let someone else have a go!
Adam
no, it didn't make any difference :( i just don't get an interupt.

Thanks anyway for taking time, maybe somebody else could help please?

Cheers, Markus
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

I'll have one more go :) (sorry this is bitty, but I'm doing this in between a lot of work this morning!). I don't mean to be patronising, but you have done an "sti", haven't you?

Perhaps you could archive and post your code. When I get a chance, I'll have a more thorough look.

Cheers,
Adam
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

AJ wrote:I'll have one more go :) (sorry this is bitty, but I'm doing this in between a lot of work this morning!). I don't mean to be patronising, but you have done an "sti", haven't you?

Perhaps you could archive and post your code. When I get a chance, I'll have a more thorough look.

Cheers,
Adam
hehe, i was wondering when this question comes up ;) yes i have done a sti, and it must have worked, since manually doing "int 32" works (which should be mapped to IRQ0 with the PIC setup i posted above, right?)...

right. i'll post the code. you'll need an installed Visual C++ 2008 (Express (which is free), or whatever up to Team System or so) to compile. I uses a network boot setup with pxegrub in vmware (the pxegrub with the lance driver for VMware is not included for size reasons (argl), but the menu.lst is use is). So if you want to use the same setup, you will want to have some external DHCP/BOOTP/TFTP server running (haneWIN DHCP is quite good for this). otherwise, this is a normal GRUB bootable multilib kernel, requiring nothing else than itself :) no modules or black magic required to boot ;)

Thanks for looking again.
Attachments
simplexity.zip
simplexity kernel source (requires Microsoft Visual C++ 2008 to compile)
(15.92 KiB) Downloaded 63 times
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

err... ok another few words:

*) the code in question is mostly in sxTimer.{c,h} and in sxIntHandlers.{c,h}
*) in sxTimer.c i'm calling int 32 manually to test interupts now (so don't think its working :))
*) in sxMain.c at the end of SxCoreMain i call the SxTimerInit() and SxTimerTest() functions

all together it should be quite readable i think ...

Thanks in advance to anyone looking at my issue!

Cheers, Markus
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

another thing i forgot to mention (man...) is that the functions _inp, _outp, _enable and _disable are compiler intrinsics, but disassembling showed that the compiler DTRT:

Code: Select all

_SxInteruptsEnable:
  00000290: 55                 push        ebp
  00000291: 8B EC              mov         ebp,esp
  00000293: FB                 sti
  00000294: 5D                 pop         ebp
  00000295: C3                 ret
  00000296: CC                 int         3
i anyway believed this goes ok, since - as i said - manually triggered interupts are delivered...

thinking about this for a while now, i believe it's not the PIT but the PIC where things go wrong. i just can't tell why...

Cheers, Markus
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

STOP :)

shame on me.... somehow the SxInteruptsEnable call got lost! still i had a printf "enabling interupts", but the actual call was missing.

now things of course work perfectly! what i wonder about is, how could the "int 32" instruction work with interupts disabled?

sorry for taking up your time :(

now i have another question though.... how would you implement a simple sleep? is programming the PIT and doing "hlt" good? or are there better ways?

Cheers, Markus
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

mduft wrote:shame on me.... somehow the SxInteruptsEnable call got lost!
...
sorry for taking up your time :(
No probs - we've all done it!
how would you implement a simple sleep? is programming the PIT and doing "hlt" good? or are there better ways?
Personally, my scheduler deals with this. The sleep(msec) function ensures that a process is not scheduled until a given number of milliseconds have passed. It really depends what your design needs - if you are creating an RTOS, using this scheduler method would be horribly inaccurate. For my purposes, though, it's fine.

Of course, you need to decide whether you move the task to an 'inactive queue', whether the task gets immediate priority once woken and so on...

If you just program the PIT and HLT, what if someone hits the keyboard? What if another task needs to sleep for a different amount of time? (I'm assuming MT here...).

Cheers,
Adam
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

mhm... all good points to think about :) also i saw that hlt'ing seems really slow :)

i'll have to think about it.

the thing i wanted to achieve is, that the vmware doesn't take up 100% cpu (which it of course does if i just - for now - run in a loop handling interupts as they arrive)

up until now i did { cli; hlt } but now i want things to continue working...
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

how could the "int 32" instruction work with interupts disabled?
Common misconception here. The "int" instruction creates a software interrupt which will fire regardless of the IF. So running a cli instruction and then "int 32" will still fire interrupt 32.
User avatar
mduft
Member
Member
Posts: 46
Joined: Thu Jun 05, 2008 9:23 am
Location: Austria

Post by mduft »

pcmattman wrote:Common misconception here. The "int" instruction creates a software interrupt which will fire regardless of the IF. So running a cli instruction and then "int 32" will still fire interrupt 32.
thanks for clearing this up. i had never read this somewhere else before. maybe this would be a quite usefull information for beginners? if i knew that before, things would have been easier...
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

You should also note that it's not the same for exceptions. At least, not if I remember correctly. They are affected by the IF.

This though is where it gets a bit hazy, and I've got way too much schoolwork tonight to be able to test it right now.
Post Reply