Comment 6 for bug 1777777

Revision history for this message
RTOS Pharos (rtos.pharos) wrote :

Sorry to have taken some time to answer.

Created the binary with the test.

Here is the output when it fails (tested in Qemu 2.12):

Checked 0 times if the time is always increasing
Checked 100000 times if the time is always increasing
Checked 200000 times if the time is always increasing
Checked 300000 times if the time is always increasing
Checked 400000 times if the time is always increasing
Checked 500000 times if the time is always increasing
Checked 600000 times if the time is always increasing
Checked 700000 times if the time is always increasing
Error: the time read is smaller than the previous time read

And here with the latest Qemu (4.1.0):

Checked 0 times if the time is always increasing
Checked 100000 times if the time is always increasing
Error: the time read is smaller than the previous time read

The error can occur basically at any time. But when tested with Qemu 2.5 it goes well:

Checked 0 times if the time is always increasing
Checked 100000 times if the time is always increasing
Checked 200000 times if the time is always increasing
Checked 300000 times if the time is always increasing
Checked 400000 times if the time is always increasing
Checked 500000 times if the time is always increasing
Checked 600000 times if the time is always increasing
Checked 700000 times if the time is always increasing
Checked 800000 times if the time is always increasing
Checked 900000 times if the time is always increasing
Checked 1000000 times if the time is always increasing
Checked 1100000 times if the time is always increasing
Checked 1200000 times if the time is always increasing
Checked 1300000 times if the time is always increasing
Checked 1400000 times if the time is always increasing
Checked 1500000 times if the time is always increasing
Checked 1600000 times if the time is always increasing
Checked 1700000 times if the time is always increasing
Checked 1800000 times if the time is always increasing
Checked 1900000 times if the time is always increasing
Checked 2000000 times if the time is always increasing
Checked 2100000 times if the time is always increasing
Checked 2200000 times if the time is always increasing
Checked 2300000 times if the time is always increasing
Checked 2400000 times if the time is always increasing
Checked 2500000 times if the time is always increasing
Checked 2600000 times if the time is always increasing
Checked 2700000 times if the time is always increasing
Checked 2800000 times if the time is always increasing
Checked 2900000 times if the time is always increasing
.
.
.
Checked 9500000 times if the time is always increasing
Checked 9600000 times if the time is always increasing
Checked 9700000 times if the time is always increasing
Checked 9800000 times if the time is always increasing
Checked 9900000 times if the time is always increasing
Example finished

Just to give some background on the test itself, the main.c file contains this:

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

    for(i = 0; i < NUMBER_REPETITIONS; i++)
    {
        microseconds = pharosClockGetSinceBoot();

        if(microseconds < previousMicroseconds)
        {
            printk("Error: the time read is smaller than the previous time read\r\n");
            pharosThreadSuspendSelf();
        }

        previousMicroseconds = microseconds;

        /* only print 100 times the message */
        if(i % (NUMBER_REPETITIONS / 100) == 0)
        {
            printk("Checked %d times if the time is always increasing\r\n" , i);
        }
    }

    printk("Example finished\r\n");
    pharosThreadSuspendSelf();
}

And where I suspect the code is reading the wrong hardware level is here:

bool pharosCpuClockIsrIsPending(void)
{
    /* apparently QEMU has a bug when it comes to reading the SP804 interrupt status. It seems that we have to read
      it multiple times in order for it to give the correct result since it does not update the interrupt status
      of the SP804 when it should. Qemu 2.5 did not have this problem but at least Qemu 2.12, 3.1 and 4.1.0 have this
      problem. So we just create a work-around for it. */
#if 0

    /* number of times to read it. */
#define N 100

    uint32_t i;

    /* read the interrupts status a lot of times to wait for QEMU to update the status */
    for(i = 0; i < N; i++)
    {
        /* if there is an interrupt */
        if(armSp804TimerInterruptIsPending(TIMER1_BASE_ADDRESS) == TRUE)
        {
            /* return right away */
            return TRUE;
        }
    }

    /* read the status a LOT of times, there is no interrupt pending */
    return FALSE;

    /* On a real hardware this problem should not occur so we only have to read it once */
#else
    /* read the SP804 timer interrupt pending info */
    return armSp804TimerInterruptIsPending(TIMER1_BASE_ADDRESS);
#endif
}

that is, the armSp804TimerInterruptIsPending is not correctly returning if the timer1 has a pending interrupt (even though I check the timer load value and it was reset just before and no interrupt was raised - interrupts disabled)