Reading the PIT: Differences in subsequent counter reads

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.
Post Reply
ShukantPal
Posts: 23
Joined: Tue Dec 12, 2017 6:51 am
Freenode IRC: XtremeCoder

Reading the PIT: Differences in subsequent counter reads

Post by ShukantPal »

Hi Guys,

Brief Background: My kernel (the Silcos-kernel, on GitHub too) uses the (local) interrupt vectors from 20-191 for device drivers. Each local interrupt has a ISR handler that goes through a dynamic array of device-ISR handlers ready to check whether their device caused that interrupt, and if so - handle it. The PIT is mapped to the 190th entry vector in the IDT (and the 2-Redirection-Entry on the IOAPIC).

Analysis of Data: So, I reset the timer to the INTERRUPT_ON_TERMINAL_COUNT mode with the maximum initial count - 0xFFFF. Then, at the next subsequent interrupts the PIT handler does the following things:

1. Arms the timer again with the same previous initial count - 0xFFFF.

2. Debugs (prints on the console) the total ticks recorded on the given counter (counter 0 is being used all over here).

How it works?

For each counter - I made a Counter struct. That includes the total ticks recorded on this counter & the last read count, (also the initial count last-used to program the counter).

On calling getTotalTicks(0), where 0 indicates the counter, the following code executes:

Code: Select all

	U64 getTotalTicks(unsigned index) {
		U16 updatedCounter = getCounter(index);
		progTimers[index].totalTicks +=
				getLastReadCounter(index) - updatedCounter;
		setLastReadCounter(index, updatedCounter);
		return (progTimers[index].totalTicks);
	}
So, in English, it just updates the last-read-count and then adds the number of ticks passed since the last read. When arm() is called, during the interrupt, however, the current counter gets rolled over - and is not zero, as expected, so the arm method does the following:

Code: Select all

oldTimer->totalTicks += oldTimer->lastReadCount;// assume the current count is zero, nah.
DbgInt(oldTimer->totalTicks);// print the total ticks
Notice that arm() so prints the totalTicks. The following results are outputted: (where first column is the total ticks in arm() and second column is the total ticks() printed in step 2 above).

Code: Select all

Interrupt 1: 65535 and then 65610         Difference = about 80
Interrupt 2: 131070 and then 131096      Difference = about 25
Interrupt 3: 196605 and then 196627      Difference = 22
Interrupt 4: 262140 and then 262147      Difference = 7 (only)
Interrupt 5: 327675 amd tjem 327727    Difference= about 50
and so on!
Notice, the amount of difference in the subsequent total ticks. Okay, I would like to say something here:

Notice column 1 is always a multiple of 65535: That is because we assume the counter to be zero when we receive any interrupt on the PIT. Okay, but that should be correct as the initial count was 65535, so adding up column I is theoretically correct, am I right here?

Notice the differences: My question is are the differences in the total ticks after subsequent reads correct - are they too massive and why are the differences so far apart - meaning one is 80 and one is only 7?
Post Reply