All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] hpet emulation problems
@ 2009-07-21 12:29 Andriy Gapon
  2009-07-21 12:53 ` [Qemu-devel] " Andriy Gapon
  0 siblings, 1 reply; 5+ messages in thread
From: Andriy Gapon @ 2009-07-21 12:29 UTC (permalink / raw)
  To: qemu-devel


I observe the following problems with qemu-emulated HPET:

1. setting lower 32bits of a 64-bit register clears the higher 32 bits;
At least this happens with TIMn_CONF register - I set some bits at offset 0x100
and all bits at 0x104 become cleared. The problem is aggravated by the fact that
those bits are supposed to be RO - they specify interrupt routing capabilities.

2. Setting interrupt type to level-triggered has no effect in the sense that
interrupt status bits are not set in GINTR_STA when interrupts are generated.

-- 
Andriy Gapon

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Qemu-devel] Re: hpet emulation problems
  2009-07-21 12:29 [Qemu-devel] hpet emulation problems Andriy Gapon
@ 2009-07-21 12:53 ` Andriy Gapon
  2009-07-21 18:16   ` Beth Kon
  0 siblings, 1 reply; 5+ messages in thread
From: Andriy Gapon @ 2009-07-21 12:53 UTC (permalink / raw)
  To: qemu-devel


I obtained qemu code and looked through hw/hpet.c, below are some observations.


on 21/07/2009 15:29 Andriy Gapon said the following:
> I observe the following problems with qemu-emulated HPET:
> 
> 1. setting lower 32bits of a 64-bit register clears the higher 32 bits;
> At least this happens with TIMn_CONF register - I set some bits at offset 0x100
> and all bits at 0x104 become cleared. The problem is aggravated by the fact that
> those bits are supposed to be RO - they specify interrupt routing capabilities.

This probably happens because of the following.
New value is set using a filter function, e.g.:
timer->config = hpet_fixup_reg(new_val, old_val,
                               HPET_TN_CFG_WRITE_MASK);
But old_val was set to:
old_val = hpet_ram_readl(opaque, addr);

Apparently hpet_ram_readl returns value in the lower 32 bits and thus higher 32
bits are lost.
timer->config is a 64-bit variable that is supposed to hold all bits of TIMn_CONF
(judging from hpet_ram_readl).

> 2. Setting interrupt type to level-triggered has no effect in the sense that
> interrupt status bits are not set in GINTR_STA when interrupts are generated.

>From the code I see that level-triggered interrupts are not supposed to be
supported at all:
if (new_val & HPET_TIMER_TYPE_LEVEL) {
    printf("qemu: level-triggered hpet not supported\n");
    exit (-1);
}

The code is quite harsh in calling exit(), but it is incorrect too.
This how HPET_TIMER_TYPE_LEVEL is defined:
#define HPET_TIMER_TYPE_LEVEL 1
#define HPET_TIMER_TYPE_EDGE 0

But Interrupt Type is bit #1 in TIMn_CONF, bit #0 is reserved and is typically
zero. The check should be:
if (new_val & (HPET_TIMER_TYPE_LEVEL << 1))
or something like that.

But maybe level-triggered HPET interrupts could be supported after all.

-- 
Andriy Gapon

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] Re: hpet emulation problems
  2009-07-21 12:53 ` [Qemu-devel] " Andriy Gapon
@ 2009-07-21 18:16   ` Beth Kon
  2009-07-21 18:26     ` Andriy Gapon
  0 siblings, 1 reply; 5+ messages in thread
From: Beth Kon @ 2009-07-21 18:16 UTC (permalink / raw)
  To: Andriy Gapon; +Cc: qemu-devel

Andriy Gapon wrote:
> I obtained qemu code and looked through hw/hpet.c, below are some observations.
>
>
> on 21/07/2009 15:29 Andriy Gapon said the following:
>   
>> I observe the following problems with qemu-emulated HPET:
>>
>> 1. setting lower 32bits of a 64-bit register clears the higher 32 bits;
>> At least this happens with TIMn_CONF register - I set some bits at offset 0x100
>> and all bits at 0x104 become cleared. The problem is aggravated by the fact that
>> those bits are supposed to be RO - they specify interrupt routing capabilities.
>>     
>
> This probably happens because of the following.
> New value is set using a filter function, e.g.:
> timer->config = hpet_fixup_reg(new_val, old_val,
>                                HPET_TN_CFG_WRITE_MASK);
> But old_val was set to:
> old_val = hpet_ram_readl(opaque, addr);
>
> Apparently hpet_ram_readl returns value in the lower 32 bits and thus higher 32
> bits are lost.
> timer->config is a 64-bit variable that is supposed to hold all bits of TIMn_CONF
> (judging from hpet_ram_readl).
>
>   
>> 2. Setting interrupt type to level-triggered has no effect in the sense that
>> interrupt status bits are not set in GINTR_STA when interrupts are generated.
>>     
>
> From the code I see that level-triggered interrupts are not supposed to be
> supported at all:
> if (new_val & HPET_TIMER_TYPE_LEVEL) {
>     printf("qemu: level-triggered hpet not supported\n");
>     exit (-1);
> }
>
> The code is quite harsh in calling exit(), but it is incorrect too.
> This how HPET_TIMER_TYPE_LEVEL is defined:
> #define HPET_TIMER_TYPE_LEVEL 1
> #define HPET_TIMER_TYPE_EDGE 0
>
> But Interrupt Type is bit #1 in TIMn_CONF, bit #0 is reserved and is typically
> zero. The check should be:
> if (new_val & (HPET_TIMER_TYPE_LEVEL << 1))
> or something like that.
>
> But maybe level-triggered HPET interrupts could be supported after all.
>   
Thanks for catching these bugs! I'll submit corrections shortly.

As far as supporting level-triggered interrupts, all the guests I tested 
used edge-triggered interrupts, so this is what I implemented as a first 
pass. I don't think there is any reason not to implement 
level-triggered, though I am not planning to work on that at this point.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] Re: hpet emulation problems
  2009-07-21 18:16   ` Beth Kon
@ 2009-07-21 18:26     ` Andriy Gapon
  2009-07-23 10:10       ` Andriy Gapon
  0 siblings, 1 reply; 5+ messages in thread
From: Andriy Gapon @ 2009-07-21 18:26 UTC (permalink / raw)
  To: Beth Kon; +Cc: qemu-devel

on 21/07/2009 21:16 Beth Kon said the following:
> Thanks for catching these bugs! I'll submit corrections shortly.
> 
> As far as supporting level-triggered interrupts, all the guests I tested
> used edge-triggered interrupts, so this is what I implemented as a first
> pass. I don't think there is any reason not to implement
> level-triggered, though I am not planning to work on that at this point.

Beth,

thank you very much!

I think that level-triggered interrupt support could be useful (in the future),
for supporting HPET drivers that use non-legacy-replacement mode or extra
timers, when the respective interrupts have to be shared with PCI interrupts for
one reason or another.

-- 
Andriy Gapon

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] Re: hpet emulation problems
  2009-07-21 18:26     ` Andriy Gapon
@ 2009-07-23 10:10       ` Andriy Gapon
  0 siblings, 0 replies; 5+ messages in thread
From: Andriy Gapon @ 2009-07-23 10:10 UTC (permalink / raw)
  To: Beth Kon; +Cc: qemu-devel


BTW, looking here:
http://lxr.linux.no/linux+v2.6.30/drivers/char/hpet.c
I see that the code sets level-triggered mode.
I think that this is a driver for exposing HPET to userland (as opposed to using
it as a clock source).

-- 
Andriy Gapon

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-07-23 10:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-21 12:29 [Qemu-devel] hpet emulation problems Andriy Gapon
2009-07-21 12:53 ` [Qemu-devel] " Andriy Gapon
2009-07-21 18:16   ` Beth Kon
2009-07-21 18:26     ` Andriy Gapon
2009-07-23 10:10       ` Andriy Gapon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.