qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] icount mode


From: Wu, Wentong
Subject: Re: [Qemu-devel] icount mode
Date: Mon, 24 Jun 2019 20:43:31 +0000

Hi Alex,

Thanks for your reply.

For the different frequencies, please see below code in armv7m_systick.c and 
mps2.c first, the s->reload will be set by the guest os code according to the 
CPU's frequency which will be SYSCLK_FRQ, and s->tick will be set as "s->tick 
+= (s->reload + 1) * systick_scale(s);", it means the frequency of this timer 
which I called qemu timer will be NANOSECONDS_PER_SECOND.
static void systick_reload(SysTickState *s, int reset)
{
    /* The Cortex-M3 Devices Generic User Guide says that "When the
     * ENABLE bit is set to 1, the counter loads the RELOAD value from the
     * SYST RVR register and then counts down". So, we need to check the
     * ENABLE bit before reloading the value.
     */
    trace_systick_reload();

    if ((s->control & SYSTICK_ENABLE) == 0) {
        return;
    }

    if (reset) {
        s->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    }
    s->tick += (s->reload + 1) * systick_scale(s);
    timer_mod(s->timer, s->tick);
}

static void mps2_common_init(MachineState *machine)
{
      ...
      system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
      ...
}

But for below code, it will use qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) to get 
the current time which will be calculated by 2^N ns * instruction counter, but 
this frequency will be NANOSECONDS_PER_SECOND /  2^N. Below code is an example 
two different frequencies are used, actually in cpus.c, 
qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL) will use the qemu timer(freq is 
NANOSECONDS_PER_SECOND), and cpu_icount_to_ns will calcaute time with frequency 
NANOSECONDS_PER_SECOND /  2^N.

static void systick_write(void *opaque, hwaddr addr,
                          uint64_t value, unsigned size)
{
    SysTickState *s = opaque;

    trace_systick_write(addr, value, size);

    switch (addr) {
    case 0x0: /* SysTick Control and Status.  */
    {
        uint32_t oldval = s->control;

        s->control &= 0xfffffff8;
        s->control |= value & 7;
        if ((oldval ^ value) & SYSTICK_ENABLE) {
            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
            if (value & SYSTICK_ENABLE) {
                if (s->tick) {
                    s->tick += now;
                    timer_mod(s->timer, s->tick);
                } else {
                    systick_reload(s, 1);
                }
            } else {
                timer_del(s->timer);
                s->tick -= now;
                if (s->tick < 0) {
                    s->tick = 0;
                }
            }
        } else if ((oldval ^ value) & SYSTICK_CLKSOURCE) {
            /* This is a hack. Force the timer to be reloaded
               when the reference clock is changed.  */
            systick_reload(s, 1);
        }
        break;
    }
    case 0x4: /* SysTick Reload Value.  */
        s->reload = value;
        break;
    ......

Yes, I'm for the for determinism, in my guest image there are some testing 
cases for timer system which locate in a small rtos.
And for shift value, I mean it seems shift value impact system greatly, for the 
same one guest image and different shift value in count mode(-icount 
shift=4,align=off,sleep=off -rtc clock=vm) give very different accuracy for 
guest timer. So my question is how to calculate the shift value for the end 
user.

Thanks again for your help.

Thanks  

-----Original Message-----
From: Qemu-devel [mailto:qemu-devel-bounces+wentong.wu=address@hidden] On 
Behalf Of Alex Bennée
Sent: Monday, June 24, 2019 11:48 PM
To: address@hidden
Subject: Re: [Qemu-devel] icount mode


Wu, Wentong <address@hidden> writes:

> Hi all,
>
> Recently I'm using Qemu TCG icount mode, from the code I found Qemu 
> timers run at 1GHz, and for ArmV7M example, there will be conversion

Are you talking about:

  #define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */

because as far as I can tell that only affects the scaling factors applied to 
PMU counters. The internal counters (CNTFRQ_EL0 and friends) are hardwired to:

   /* Scale factor for generic timers, ie number of ns per tick.
    * This gives a 62.5MHz timer.
    */
   #define GTIMER_SCALE 16

but this only affects the nominal rate the counters expire at. Software could 
attempt to reprogram it and the emulation will read-as-written but it won't 
actually change anything. However this only affects the clocks
- it implies nothing about how fast the core may be executing. In fact unless 
you are using icount we will just run as fast a possible.

> factor from qemu timer to SysTick frequency which will be calculated 
> by NANOSECONDS_PER_SECOND / SYSCLK_FRQ.

You need to be a little more precise here. ARM systems vary in the number of 
timer sources they have. The qemu timers are an internal implementation detail 
for providing a way to track time. The value of SYSCLK_FRQ varies depending on 
what board you have launched and mostly seems to be used to calculate the 
additional timer values for various peripherals.

> But the shift value also define the target cpu frequency(2^N ns /one 
> instruction), and both frequencies will be used together to calculate 
> the guest timer, so I think there is buggy because of the different 
> frequency, can anyone give some explanation for this? Thanks a lot!

All icount does is peg the elapsed virtual time to the number of instructions 
executed (the instruction count). This means whenever the code requests:

  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)

Instead of returning the number of ns the guest has been running based on 
elapsed host time it will return the number of instructions run shifted by 
icount_shift. So with higher shift values each instruction sees an increased 
amount of virtual time pass - the practical effect will be you see less 
instructions executed between timer interrupts.

>
> Also can anyone give some hints about how to give the shift value when 
> use icount TCG mode?

  $QEMU $QEMU_ARGS -icount N

or

  $QEMU $QEMU_ARGS -icount shift=N

What is your interest in icount? Is it purely for determinism?

--
Alex Bennée


reply via email to

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