[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: [PATCH 11/16] hpet/rtc: Rework RTC IRQ replacement by H
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] Re: [PATCH 11/16] hpet/rtc: Rework RTC IRQ replacement by HPET |
Date: |
Sun, 06 Jun 2010 11:09:05 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 |
Blue Swirl wrote:
> On Sun, Jun 6, 2010 at 8:11 AM, Jan Kiszka <address@hidden> wrote:
>> From: Jan Kiszka <address@hidden>
>>
>> Allow the intercept the RTC IRQ for the HPET legacy mode. Then push
>> routing to IRQ8 completely into the HPET. This allows to turn
>> hpet_in_legacy_mode() into a private function. Furthermore, this stops
>> the RTC from clearing IRQ8 even if the HPET is in control.
>>
>> This patch comes with a side effect: The RTC timers will no longer be
>> stoppend when there is no IRQ consumer, possibly causing a minor
>> performance degration. But as the guest may want to redirect the RTC to
>> the SCI in that mode, it should normally disable unused IRQ source
>> anyway.
>>
>> Signed-off-by: Jan Kiszka <address@hidden>
>> ---
>> hw/hpet.c | 42 +++++++++++++++++++++++++++++++++++-------
>> hw/hpet_emul.h | 4 ----
>> hw/mc146818rtc.c | 54
>> +++++++++++++++---------------------------------------
>> hw/mc146818rtc.h | 4 +++-
>> hw/mips_jazz.c | 2 +-
>> hw/mips_malta.c | 2 +-
>> hw/mips_r4k.c | 2 +-
>> hw/pc.c | 14 ++++++++------
>> hw/ppc_prep.c | 2 +-
>> 9 files changed, 65 insertions(+), 61 deletions(-)
>>
>> diff --git a/hw/hpet.c b/hw/hpet.c
>> index 041dd84..d26cad5 100644
>> --- a/hw/hpet.c
>> +++ b/hw/hpet.c
>> @@ -30,6 +30,7 @@
>> #include "qemu-timer.h"
>> #include "hpet_emul.h"
>> #include "sysbus.h"
>> +#include "mc146818rtc.h"
>>
>> //#define HPET_DEBUG
>> #ifdef HPET_DEBUG
>> @@ -58,6 +59,7 @@ typedef struct HPETState {
>> SysBusDevice busdev;
>> uint64_t hpet_offset;
>> qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
>> + uint8_t rtc_irq_level;
>> HPETTimer timer[HPET_NUM_TIMERS];
>>
>> /* Memory-mapped, software visible registers */
>> @@ -69,12 +71,9 @@ typedef struct HPETState {
>>
>> static HPETState *hpet_statep;
>>
>> -uint32_t hpet_in_legacy_mode(void)
>> +static uint32_t hpet_in_legacy_mode(HPETState *s)
>> {
>> - if (!hpet_statep) {
>> - return 0;
>> - }
>> - return hpet_statep->config & HPET_CFG_LEGACY;
>> + return s->config & HPET_CFG_LEGACY;
>> }
>>
>> static uint32_t timer_int_route(struct HPETTimer *timer)
>> @@ -166,12 +165,12 @@ static void update_irq(struct HPETTimer *timer)
>> {
>> int route;
>>
>> - if (timer->tn <= 1 && hpet_in_legacy_mode()) {
>> + if (timer->tn <= 1 && hpet_in_legacy_mode(timer->state)) {
>> /* if LegacyReplacementRoute bit is set, HPET specification requires
>> * timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
>> * timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
>> */
>> - route = (timer->tn == 0) ? 0 : 8;
>> + route = (timer->tn == 0) ? 0 : RTC_ISA_IRQ;
>> } else {
>> route = timer_int_route(timer);
>> }
>> @@ -515,8 +514,10 @@ static void hpet_ram_writel(void *opaque,
>> target_phys_addr_t addr,
>> /* i8254 and RTC are disabled when HPET is in legacy mode */
>> if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
>> hpet_pit_disable();
>> + qemu_irq_lower(s->irqs[RTC_ISA_IRQ]);
>> } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
>> hpet_pit_enable();
>> + qemu_set_irq(s->irqs[RTC_ISA_IRQ], s->rtc_irq_level);
>> }
>> break;
>> case HPET_CFG + 4:
>> @@ -607,6 +608,30 @@ static void hpet_reset(DeviceState *d)
>> count = 1;
>> }
>>
>> +static void hpet_rtc_delivery_cb(qemu_irq irq, void *opaque, int n, int
>> level,
>> + int result)
>> +{
>> + qemu_irq orig_irq = opaque;
>> +
>> + qemu_irq_fire_delivery_cb(orig_irq, level, result);
>> +}
>> +
>> +static void hpet_handle_rtc_irq(qemu_irq irq, void *opaque, int n, int
>> level)
>> +{
>> + HPETState *s = FROM_SYSBUS(HPETState, opaque);
>> + IRQMsg msg = {
>> + .delivery_cb = hpet_rtc_delivery_cb,
>> + .delivery_opaque = irq,
>> + };
>> +
>> + s->rtc_irq_level = level;
>> + if (hpet_in_legacy_mode(s)) {
>> + qemu_irq_fire_delivery_cb(irq, level, QEMU_IRQ_MASKED);
>> + } else {
>> + qemu_set_irq_msg(s->irqs[RTC_ISA_IRQ], level, &msg);
>
> This is the problem with passing around stack allocated objects: after
> this function finishes, s->irqs[RTC_ISA_IRQ].msg is a dangling pointer
> to some stack space.
s->irqs[RTC_ISA_IRQ].msg is NULL when qemu_set_irq_msg returned, msg
itself will not "leak" out of the qemu_irq subsystem.
Jan
signature.asc
Description: OpenPGP digital signature
[Qemu-devel] [PATCH 10/16] x86: Refactor RTC IRQ coalescing workaround, Jan Kiszka, 2010/06/06
[Qemu-devel] [PATCH 11/16] hpet/rtc: Rework RTC IRQ replacement by HPET, Jan Kiszka, 2010/06/06
[Qemu-devel] [PATCH 12/16] hpet: Drop static state, Jan Kiszka, 2010/06/06
[Qemu-devel] [PATCH 14/16] vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8, Jan Kiszka, 2010/06/06
[Qemu-devel] [PATCH 15/16] hpet: Make number of timers configurable, Jan Kiszka, 2010/06/06
[Qemu-devel] [PATCH 16/16] hpet: Add MSI support, Jan Kiszka, 2010/06/06
[Qemu-devel] [PATCH 13/16] hpet: Add support for level-triggered interrupts, Jan Kiszka, 2010/06/06
[Qemu-devel] [PATCH 08/16] Pass IRQ object on handler invocation, Jan Kiszka, 2010/06/06
[Qemu-devel] Re: [PATCH 00/16] HPET cleanups, fixes, enhancements, Blue Swirl, 2010/06/06