All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Isaku Yamahata <yamahata@valinux.co.jp>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [PATCH v3 3/3] piix_pci: optimize set irq path
Date: Tue, 22 Mar 2011 18:24:38 +0200	[thread overview]
Message-ID: <20110322162438.GA4940@redhat.com> (raw)
In-Reply-To: <20110322140703.GE5546@valinux.co.jp>

On Tue, Mar 22, 2011 at 11:07:03PM +0900, Isaku Yamahata wrote:
> On Tue, Mar 22, 2011 at 03:40:16PM +0200, Michael S. Tsirkin wrote:
> > On Tue, Mar 22, 2011 at 09:50:37AM +0900, Isaku Yamahata wrote:
> > > On Mon, Mar 21, 2011 at 04:10:22PM +0200, Michael S. Tsirkin wrote:
> > > > > @@ -37,8 +37,27 @@
> > > > >  
> > > > >  typedef PCIHostState I440FXState;
> > > > >  
> > > > > +#define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
> > > > > +#define PIIX_NUM_PIRQS          4ULL    /* PIRQ[A-D] */
> > > > 
> > > > I've changed this to
> > > > ((uint64_t)PCI_NUM_PINS)
> > > > 
> > > > Makes sense?
> > > 
> > > No. The number of pirq is independent of PCI_NUM_PINS.
> > 
> > OK, here's what confuses me:
> > 
> > > diff --git a/hw/piix_pci.c b/hw/piix_pci.c
> > > index e88df43..f07e19d 100644
> > > --- a/hw/piix_pci.c
> > > +++ b/hw/piix_pci.c
> > > @@ -37,8 +37,27 @@
> > >  
> > >  typedef PCIHostState I440FXState;
> > >  
> > > +#define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
> > > +#define PIIX_NUM_PIRQS          4ULL    /* PIRQ[A-D] */
> > > +#define PIIX_PIRQC              0x60
> > > +
> > >  typedef struct PIIX3State {
> > >      PCIDevice dev;
> > > +
> > > +    /*
> > > +     * bitmap to track pic levels.
> > > +     * The pic level is the logical OR of all the PCI irqs mapped to it
> > > +     * So one PIC level is tracked by PIIX_NUM_PIRQS bits.
> > > +     *
> > > +     * PIRQ is mapped to PIC pins, we track it by
> > > +     * PIIX_NUM_PIRQS * PIIX_NUM_PIC_IRQS = 64 bits with
> > > +     * pic_irq * PIIX_NUM_PIRQS + pirq
> > > +     */
> > > +#if PIIX_NUM_PIC_IRQS * PIIX_NUM_PIRQS > 64
> > > +#error "unable to encode pic state in 64bit in pic_levels."
> > > +#endif
> > > +    uint64_t pic_levels;
> > > +
> > >      qemu_irq *pic;
> > >  
> > >      /* This member isn't used. Just for save/load compatibility */
> > > @@ -254,25 +273,63 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
> > >  }
> > >  
> > >  /* PIIX3 PCI to ISA bridge */
> > > +static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
> > > +{
> > > +    qemu_set_irq(piix3->pic[pic_irq],
> > > +                 !!(piix3->pic_levels &
> > > +                    ((PIIX_NUM_PIRQS - 1) << (pic_irq * PIIX_NUM_PIRQS))));
> > > +}
> > > +
> > > +static void piix3_set_irq_level(PIIX3State *piix3, int irq_num, int level,
> > > +                                bool propagate)
> > 
> > This is called from piix3_set_irq_pic and gets INTX# (0 to PCI_NUM_PINS).
> 
> I used irq_num some places because of the existing code and pci.c.
> Here irq_num = PIRQ number. But irq_num = intx in pci_lost_get_pirq()
> Hmm should I avoid irq_num totally, and use intx, pirq, pic_irq?

Right, this might make it clearer.

> I hope the following clarifies the conversion.
> 
> A pci device asserts a interrupt pin of intx
>       |
>       V
> pci_set_irq()
>       |
>       V
> pci_slot_get_pirq() = bus->map_irq() gets (PCIDevice, intx)
>   returns pirq
>   This corresponds to how pci intx lines are connected to piix3 pirq pins
>       |
>       V
> piix3_set_irq() = bus->set_irq() gets pirq
>       |
>       V
> piix3_set_irq_levels() gets pirq
>   converts pirq# into pic irq
>   calls piix3_set_irq_pic() with pic_irq
>       |
>       V
> piix3_set_irq_pic() gets pic_irq
>       |
>       V
>    pic code
> 
> 
> thanks,

I think I get it.

> > > +{
> > > +    int pic_irq;
> > > +    uint64_t mask;
> > > +
> > > +    pic_irq = piix3->dev.config[PIIX_PIRQC + irq_num];
> > > +    if (pic_irq >= PIIX_NUM_PIC_IRQS) {
> > > +        return;
> > > +    }
> > > +
> > > +    mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + irq_num);
> > > +    piix3->pic_levels &= ~mask;
> > > +    piix3->pic_levels |= mask * !!level;
> > > +
> > > +    if (propagate) {
> > > +        piix3_set_irq_pic(piix3, pic_irq);
> > > +    }
> > > +}
> > >  
> > >  static void piix3_set_irq(void *opaque, int irq_num, int level)
> > >  {
> > > -    int i, pic_irq, pic_level;
> > >      PIIX3State *piix3 = opaque;
> > > +    piix3_set_irq_level(piix3, irq_num, level, true);
> > > +}
> > >  
> > > -    /* now we change the pic irq level according to the piix irq mappings */
> > > -    /* XXX: optimize */
> > > -    pic_irq = piix3->dev.config[0x60 + irq_num];
> > > -    if (pic_irq < 16) {
> > > -        /* The pic level is the logical OR of all the PCI irqs mapped
> > > -           to it */
> > > -        pic_level = 0;
> > > -        for (i = 0; i < 4; i++) {
> > > -            if (pic_irq == piix3->dev.config[0x60 + i]) {
> > > -                pic_level |= pci_bus_get_irq_level(piix3->dev.bus, i);
> > > -            }
> > > +/* irq routing is changed. so rebuild bitmap */
> > > +static void piix3_update_irq_levels(PIIX3State *piix3)
> > > +{
> > > +    int pirq;
> > > +
> > > +    piix3->pic_levels = 0;
> > > +    for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
> > > +        piix3_set_irq_level(piix3, pirq,
> > > +                            pci_bus_get_irq_level(piix3->dev.bus, pirq),
> > > +                            false);
> > 
> > Here it is called with PIRQ # 0 to PIIX_NUM_PIRQS.
> > 
> > > +    }
> > > +}
> > > +
> > > +static void piix3_write_config(PCIDevice *dev,
> > > +                               uint32_t address, uint32_t val, int len)
> > > +{
> > > +    pci_default_write_config(dev, address, val, len);
> > > +    if (ranges_overlap(address, len, PIIX_PIRQC, 4)) {
> > > +        PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev);
> > > +        int pic_irq;
> > > +        piix3_update_irq_levels(piix3);
> > > +        for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
> > > +            piix3_set_irq_pic(piix3, pic_irq);
> > >          }
> > > -        qemu_set_irq(piix3->pic[pic_irq], pic_level);
> > >      }
> > >  }
> > >  
> > > @@ -312,6 +369,15 @@ static void piix3_reset(void *opaque)
> > >      pci_conf[0xab] = 0x00;
> > >      pci_conf[0xac] = 0x00;
> > >      pci_conf[0xae] = 0x00;
> > > +
> > > +    d->pic_levels = 0;
> > > +}
> > > +
> > > +static int piix3_post_load(void *opaque, int version_id)
> > > +{
> > > +    PIIX3State *piix3 = opaque;
> > > +    piix3_update_irq_levels(piix3);
> > > +    return 0;
> > >  }
> > >  
> > >  static void piix3_pre_save(void *opaque)
> > > @@ -330,6 +396,7 @@ static const VMStateDescription vmstate_piix3 = {
> > >      .version_id = 3,
> > >      .minimum_version_id = 2,
> > >      .minimum_version_id_old = 2,
> > > +    .post_load = piix3_post_load,
> > >      .pre_save = piix3_pre_save,
> > >      .fields      = (VMStateField []) {
> > >          VMSTATE_PCI_DEVICE(dev, PIIX3State),
> > > @@ -372,6 +439,7 @@ static PCIDeviceInfo i440fx_info[] = {
> > >          .qdev.no_user = 1,
> > >          .no_hotplug   = 1,
> > >          .init         = piix3_initfn,
> > > +        .config_write = piix3_write_config,
> > >      },{
> > >          /* end of list */
> > >      }
> > > 
> > 
> 
> -- 
> yamahata

      reply	other threads:[~2011-03-22 16:24 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-19 13:24 [Qemu-devel] [PATCH v3 0/3] piix_pci: optimize irq data path Isaku Yamahata
2011-03-19 13:24 ` [Qemu-devel] [PATCH v3 1/3] pci: add accessor function to get irq levels Isaku Yamahata
2011-03-19 13:24 ` [Qemu-devel] [PATCH v3 2/3] piix_pci: eliminate PIIX3State::pci_irq_levels Isaku Yamahata
2011-03-19 13:24 ` [Qemu-devel] [PATCH v3 3/3] piix_pci: optimize set irq path Isaku Yamahata
2011-03-21 11:37   ` [Qemu-devel] " Michael S. Tsirkin
2011-03-21 12:10     ` Isaku Yamahata
2011-03-21 12:31       ` Michael S. Tsirkin
2011-03-21 12:56         ` Isaku Yamahata
2011-03-21 13:01           ` Michael S. Tsirkin
2011-03-21 12:26     ` Isaku Yamahata
2011-03-21 14:10   ` Michael S. Tsirkin
2011-03-22  0:50     ` Isaku Yamahata
2011-03-22 13:40       ` Michael S. Tsirkin
2011-03-22 14:07         ` Isaku Yamahata
2011-03-22 16:24           ` Michael S. Tsirkin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110322162438.GA4940@redhat.com \
    --to=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=yamahata@valinux.co.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.