On Fri, Mar 20, 2020 at 06:48:53AM +0100, Gerd Hoffmann wrote:
> > > +static void *pci_mmconfig_addr(u16 bdf, u32 addr)
> > > +{
> > > +    if (!mmconfig)
> > > +        return NULL;
> > > +    return (void*)(mmconfig + ((u32)bdf << 12) + addr);
> > > +}
> > > +
> > >  void pci_config_writel(u16 bdf, u32 addr, u32 val)
> > >  {
> > > -    outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
> > > -    outl(val, PORT_PCI_DATA);
> > > +    void *mmcfg = pci_mmconfig_addr(bdf, addr);
> > > +    if (mmcfg) {
> > > +        writel(mmcfg, val);
> > > +    } else {
> > > +        outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
> > > +        outl(val, PORT_PCI_DATA);
> > > +    }
> > >  }
> > 
> > The pci_config_writeX() functions are called from 16-bit mode and
> > 32-big segment mode, so this doesn't look correct to me.
> 
> Oh.  Wasn't aware of that.
> 
> > What device would call the pci_config_writeX() functions frequently
> > enough that performance would matter?
> 
> I expect most vmexists come from PCI bar configuration in POST which
> runs in 32bit mode.  I think we can restrict this to 32bit mode without
> loosing much.

What is the time improvement for using mmconfig?

> --- a/src/hw/pci.c
> +++ b/src/hw/pci.c
> @@ -18,6 +18,8 @@ static u32 mmconfig;
>  
>  static void *pci_mmconfig_addr(u16 bdf, u32 addr)
>  {
> +    if (MODESEGMENT)
> +        return NULL;
>      if (!mmconfig)
>          return NULL;
>      return (void*)(mmconfig + ((u32)bdf << 12) + addr);

FWIW, given the low-level nature of these functions, it may be worth
using wrappers like the following:

void pci_config_writel(u16 bdf, u32 addr, u32 val)
{
    if (!MODESEGMENT && mmconfig)
        pci_mmconfig_writel(bdf, addr, val);
    else
        pci_ioconfig_writel(bdf, addr, val);
}

-Kevin
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-le...@seabios.org

Reply via email to