qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] Re: [PATCH rfc] pcie: get rid of range checks


From: Isaku Yamahata
Subject: [Qemu-devel] Re: [PATCH rfc] pcie: get rid of range checks
Date: Mon, 25 Oct 2010 15:17:37 +0900
User-agent: Mutt/1.5.19 (2009-01-05)

Some comments below.

On Mon, Oct 25, 2010 at 07:05:51AM +0200, Michael S. Tsirkin wrote:
> config cycle operations should be idempotent, so
> there's no need to complicate code with range checks.
> 
> Signed-off-by: Michael S. Tsirkin <address@hidden>
> ---
> 
> Untested. Pls comment.
> 
>  hw/pcie.c |   96 
> ++++++++++++++++++++++++++++++-------------------------------
>  1 files changed, 47 insertions(+), 49 deletions(-)
> 
> diff --git a/hw/pcie.c b/hw/pcie.c
> index 53d1fce..c972337 100644
> --- a/hw/pcie.c
> +++ b/hw/pcie.c
> @@ -302,59 +302,57 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
>                      addr, val, len, sltctl_prev, sltctl, sltsta);
>  
>      /* SLTCTL */
> -    if (ranges_overlap(addr, len, pos + PCI_EXP_SLTCTL, 2)) {
> -        PCIE_DEV_PRINTF(dev, "sltctl: 0x%02"PRIx16" -> 0x%02"PRIx16"\n",
> -                        sltctl_prev, sltctl);
> -        if (pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTCTL,
> -                                         PCI_EXP_SLTCTL_EIC)) {
> -            sltsta ^= PCI_EXP_SLTSTA_EIS; /* toggle PCI_EXP_SLTSTA_EIS bit */
> -            pci_set_word(exp_cap + PCI_EXP_SLTSTA, sltsta);
> -            PCIE_DEV_PRINTF(dev, "PCI_EXP_SLTCTL_EIC: "
> -                            "sltsta -> 0x%02"PRIx16"\n",
> -                            sltsta);
> -        }
> -
> -        /*
> -         * The events control bits might be enabled or disabled,
> -         * Check if the software notificastion condition is satisfied
> -         * or disatisfied.
> -         *
> -         * 6.7.3.4 Software Notification of Hot-plug events
> -         */
> -        if (pci_msi_enabled(dev)) {
> -            bool msi_trigger =
> -                (sltctl & PCI_EXP_SLTCTL_HPIE) &&
> -                ((sltctl_prev ^ sltctl) & sltctl & /* stlctl: 0 -> 1 */
> -                 sltsta & PCI_EXP_HP_EV_SUPPORTED);
> -            if (msi_trigger) {
> -                pci_msi_notify(dev, pcie_cap_flags_get_vector(dev));
> -            }
> -        } else {
> -            int int_level =
> -                (sltctl & PCI_EXP_SLTCTL_HPIE) &&
> -                (sltctl & sltsta & PCI_EXP_HP_EV_SUPPORTED);
> -            qemu_set_irq(dev->irq[dev->exp.hpev_intx], int_level);
> -        }
> +    PCIE_DEV_PRINTF(dev, "sltctl: 0x%02"PRIx16" -> 0x%02"PRIx16"\n",
> +                    sltctl_prev, sltctl);
> +    if (pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTCTL,
> +                                     PCI_EXP_SLTCTL_EIC)) {
> +        sltsta ^= PCI_EXP_SLTSTA_EIS; /* toggle PCI_EXP_SLTSTA_EIS bit */
> +        pci_set_word(exp_cap + PCI_EXP_SLTSTA, sltsta);
> +        PCIE_DEV_PRINTF(dev, "PCI_EXP_SLTCTL_EIC: "
> +                        "sltsta -> 0x%02"PRIx16"\n",
> +                        sltsta);
> +    }
>  
> -        if (!((sltctl_prev ^ sltctl) & PCI_EXP_SLTCTL_SUPPORTED)) {
> -            PCIE_DEV_PRINTF(dev,
> -                            "sprious command completion slctl "
> -                            "0x%"PRIx16" -> 0x%"PRIx16"\n",
> -                            sltctl_prev, sltctl);
> +    /*
> +     * The events control bits might be enabled or disabled,
> +     * Check if the software notificastion condition is satisfied
> +     * or disatisfied.
> +     *
> +     * 6.7.3.4 Software Notification of Hot-plug events
> +     */
> +    if (pci_msi_enabled(dev)) {
> +        bool msi_trigger =
> +            (sltctl & PCI_EXP_SLTCTL_HPIE) &&
> +            ((sltctl_prev ^ sltctl) & sltctl & /* stlctl: 0 -> 1 */
> +             sltsta & PCI_EXP_HP_EV_SUPPORTED);
> +        if (msi_trigger) {
> +            pci_msi_notify(dev, pcie_cap_flags_get_vector(dev));
>          }
> +    } else {
> +        int int_level =
> +            (sltctl & PCI_EXP_SLTCTL_HPIE) &&
> +            (sltctl & sltsta & PCI_EXP_HP_EV_SUPPORTED);
> +        qemu_set_irq(dev->irq[dev->exp.hpev_intx], int_level);
> +    }
>

The above two changes look okay.



> -        /* command completion.
> -         * Real hardware might take a while to complete
> -         * requested command because physical movement would be involved
> -         * like locking the electromechanical lock.
> -         * However in our case, command is completed instantaneously above,
> -         * so send a command completion event right now.
> -         *
> -         * 6.7.3.2 Command Completed Events
> -         */
> -        /* set command completed bit */
> -        pcie_cap_slot_event(dev, PCI_EXP_HP_EV_CCI);
> +    if (!((sltctl_prev ^ sltctl) & PCI_EXP_SLTCTL_SUPPORTED)) {
> +        PCIE_DEV_PRINTF(dev,
> +                        "sprious command completion slctl "
> +                        "0x%"PRIx16" -> 0x%"PRIx16"\n",
> +                        sltctl_prev, sltctl);
>      }
> +
> +    /* command completion.
> +     * Real hardware might take a while to complete
> +     * requested command because physical movement would be involved
> +     * like locking the electromechanical lock.
> +     * However in our case, command is completed instantaneously above,
> +     * so send a command completion event right now.
> +     *
> +     * 6.7.3.2 Command Completed Events
> +     */
> +    /* set command completed bit */
> +    pcie_cap_slot_event(dev, PCI_EXP_HP_EV_CCI);

But this isn't correct.
A single command to the slot means a single write to the slot control
register. With this patch, the interrupt is raised at every time
the configuration space is written no matter which offset is used.

>From 6.7.3.2
> Software issues a command to a hot-plug capable Downstream Port by
> issuing a write transaction that targets any portion of the
> Port's Slot Control register. A single write to the Slot Control
> register is considered to be a single command
...
> The Port must process the command normally even if the status field is
> already set when the command is issued.

With this clause, I don't see any other better way than range check
unfortunately.
-- 
yamahata



reply via email to

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