qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [Bug 1777777] Re: arm9 clock pending (SP804)


From: RTOS Pharos
Subject: [Qemu-devel] [Bug 1777777] Re: arm9 clock pending (SP804)
Date: Mon, 30 Jul 2018 18:12:41 -0000

Hello,

Let me explain a bit how to reproduce the problem. I'm developing a RTOS
with qemu (and boards,etc) -
https://sourceforge.net/projects/rtospharos/. The first version used
ARM926 with the versatilepb board and I used the qemu 2.5 version.

In my test (to check that the RTOS is working correctly) I produced a
loop that is always reading the current time ("pharosClockGet") and
checking that it is always increasing. This works perfectly on qemu 2.5.
When qemu 2.12 was released I updated to the new version to add support
for the raspberry pi 3.

Here is a piece of the test:


void aperiodicThread0_0()
{
    uint64_t microseconds;
    uint64_t previousMicroseconds = 0;
    uint32_t i;

    for(i = 0; i < NUMBER_REPETITIONS; i++)
    {
        microseconds = pharosClockGetSinceBoot();
        if(previousMicroseconds > microseconds) 
        {
            print("ERROR! Clock got lower\r\n");
            break;
        }
    }
}


I'll show you the "internals" of Pharos next (this is file clock.c):


uint64_t pharosIClockGetSinceBoot(void)
{
    /* microseconds since last clock tick*/
    uint32_t microseconds;

    /* number of clock ticks since boot */
    ClockTick clockTicks;

    /* >> interrupts are disabled when we get here << */

    /* read the number of microseconds on the counter */
    clockTicks = pharosVClockTicks;

    /* read the timer value */
    microseconds = pharosCpuClockReadCounter();

    /* if the clock interrupt is pending we might have read the microseconds 
before or after the clock tick occurred (but not processed since interrupts are 
disabled) */
    if(pharosCpuClockIsrIsPending() == TRUE)
    {
        /* interrupt is pending, so read again the microseconds and subtract 2 
clock ticks */
        microseconds = (2U * pharosIMicrosecondsPerClockTick()) - 
pharosCpuClockReadCounter();
    }
    else
    {
        /* the timer counts backwards so we must subtract to get the number of 
microseconds since last tick */
        microseconds = pharosIMicrosecondsPerClockTick() - microseconds;
    }

    /* calculate the result using the last us read */
    return (uint64_t) ((pharosIMicrosecondsPerClockTick() * clockTicks) + 
microseconds);
}


And the part that is hw dependent (for ARM926) - this is in file ClockSp804.h: 

INLINE bool armSp804TimerInterruptIsPending(const ptrArmSp804Timer c)
{
        /* get the first bit of the interrupt status (ignore other bits) to 
check if the interrupt is pending */
        return (c->timerInterruptMaskStatus & 0x1U) == 1U ? TRUE : FALSE;
}


I hope the code is easy enough to read.
Thank you

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1777777

Title:
  arm9 clock pending (SP804)

Status in QEMU:
  New

Bug description:
  Hello all,

  I'm using the versatilepb board and the timer Interrupt Mask Status
  register (offset 0x14 of the SP804) does not seem to be working
  properly on the latest qemu-2.12. I tried on the 2.5 (i believe this
  is the mainstream version that comes with Linux) and it works
  perfectly.

  What happens is that the pending bit does not seem to be set in some
  scenarios. In my case, I see the timer value decreasing to 0 and then
  being reset to the reload value and neither does the interrupt is
  triggered nor the pending bit is set.

  I believe this is a matter of timing since in the "long" run the
  system eventually catches up (after a few microseconds).

  Thank you

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1777777/+subscriptions



reply via email to

[Prev in Thread] Current Thread [Next in Thread]