ia64/xen-unstable

changeset 16834:824ffb1efa9c

hvmloader: Assign PCI resources in descending order of size for better packing.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jan 22 10:54:00 2008 +0000 (2008-01-22)
parents 491c28320794
children b006c58b055e
files tools/firmware/hvmloader/hvmloader.c
line diff
     1.1 --- a/tools/firmware/hvmloader/hvmloader.c	Tue Jan 22 10:18:58 2008 +0000
     1.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Tue Jan 22 10:54:00 2008 +0000
     1.3 @@ -188,6 +188,12 @@ static void pci_setup(void)
     1.4      uint16_t class, vendor_id, device_id;
     1.5      unsigned int bar, pin, link, isa_irq;
     1.6  
     1.7 +    /* Create a list of device BARs in descending order of size. */
     1.8 +    struct bars {
     1.9 +        uint32_t devfn, bar_reg, bar_sz;
    1.10 +    } *bars = (struct bars *)0xc0000;
    1.11 +    unsigned int i, nr_bars = 0;
    1.12 +
    1.13      /* Program PCI-ISA bridge with appropriate link routes. */
    1.14      isa_irq = 0;
    1.15      for ( link = 0; link < 4; link++ )
    1.16 @@ -242,44 +248,30 @@ static void pci_setup(void)
    1.17                      bar_reg = PCI_ROM_ADDRESS;
    1.18  
    1.19                  bar_data = pci_readl(devfn, bar_reg);
    1.20 -
    1.21                  pci_writel(devfn, bar_reg, ~0);
    1.22                  bar_sz = pci_readl(devfn, bar_reg);
    1.23 +                pci_writel(devfn, bar_reg, bar_data);
    1.24                  if ( bar_sz == 0 )
    1.25                      continue;
    1.26  
    1.27 -                if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
    1.28 -                     PCI_BASE_ADDRESS_SPACE_MEMORY )
    1.29 -                {
    1.30 -                    base = &mem_base;
    1.31 -                    bar_sz &= PCI_BASE_ADDRESS_MEM_MASK;
    1.32 -                    bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;
    1.33 -                }
    1.34 -                else
    1.35 -                {
    1.36 -                    base = &io_base;
    1.37 -                    bar_sz &= PCI_BASE_ADDRESS_IO_MASK & 0xffff;
    1.38 -                    bar_data &= ~PCI_BASE_ADDRESS_IO_MASK;
    1.39 -                }
    1.40 +                bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) ==
    1.41 +                           PCI_BASE_ADDRESS_SPACE_MEMORY) ?
    1.42 +                           PCI_BASE_ADDRESS_MEM_MASK :
    1.43 +                           (PCI_BASE_ADDRESS_IO_MASK & 0xffff));
    1.44                  bar_sz &= ~(bar_sz - 1);
    1.45  
    1.46 -                *base = (*base + bar_sz - 1) & ~(bar_sz - 1);
    1.47 -                bar_data |= *base;
    1.48 -                *base += bar_sz;
    1.49 -
    1.50 -                pci_writel(devfn, bar_reg, bar_data);
    1.51 -                printf("pci dev %02x:%x bar %02x size %08x: %08x\n",
    1.52 -                       devfn>>3, devfn&7, bar_reg, bar_sz, bar_data);
    1.53 +                for ( i = 0; i < nr_bars; i++ )
    1.54 +                    if ( bars[i].bar_sz < bar_sz )
    1.55 +                        break;
    1.56  
    1.57 -                /* Now enable the memory or I/O mapping. */
    1.58 -                cmd = pci_readw(devfn, PCI_COMMAND);
    1.59 -                if ( (bar_reg == PCI_ROM_ADDRESS) ||
    1.60 -                     ((bar_data & PCI_BASE_ADDRESS_SPACE) ==
    1.61 -                      PCI_BASE_ADDRESS_SPACE_MEMORY) )
    1.62 -                    cmd |= PCI_COMMAND_MEMORY;
    1.63 -                else
    1.64 -                    cmd |= PCI_COMMAND_IO;
    1.65 -                pci_writew(devfn, PCI_COMMAND, cmd);
    1.66 +                if ( i != nr_bars )
    1.67 +                    memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars));
    1.68 +
    1.69 +                bars[i].devfn   = devfn;
    1.70 +                bars[i].bar_reg = bar_reg;
    1.71 +                bars[i].bar_sz  = bar_sz;
    1.72 +
    1.73 +                nr_bars++;
    1.74              }
    1.75              break;
    1.76          }
    1.77 @@ -296,6 +288,46 @@ static void pci_setup(void)
    1.78                     devfn>>3, devfn&7, 'A'+pin-1, isa_irq);
    1.79          }
    1.80      }
    1.81 +
    1.82 +    /* Assign iomem and ioport resources in descending order of size. */
    1.83 +    for ( i = 0; i < nr_bars; i++ )
    1.84 +    {
    1.85 +        devfn   = bars[i].devfn;
    1.86 +        bar_reg = bars[i].bar_reg;
    1.87 +        bar_sz  = bars[i].bar_sz;
    1.88 +
    1.89 +        bar_data = pci_readl(devfn, bar_reg);
    1.90 +
    1.91 +        if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
    1.92 +             PCI_BASE_ADDRESS_SPACE_MEMORY )
    1.93 +        {
    1.94 +            base = &mem_base;
    1.95 +            bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;
    1.96 +        }
    1.97 +        else
    1.98 +        {
    1.99 +            base = &io_base;
   1.100 +            bar_data &= ~PCI_BASE_ADDRESS_IO_MASK;
   1.101 +        }
   1.102 +
   1.103 +        *base = (*base + bar_sz - 1) & ~(bar_sz - 1);
   1.104 +        bar_data |= *base;
   1.105 +        *base += bar_sz;
   1.106 +
   1.107 +        pci_writel(devfn, bar_reg, bar_data);
   1.108 +        printf("pci dev %02x:%x bar %02x size %08x: %08x %08x/%08x\n",
   1.109 +               devfn>>3, devfn&7, bar_reg, bar_sz, bar_data, i, nr_bars);
   1.110 +
   1.111 +        /* Now enable the memory or I/O mapping. */
   1.112 +        cmd = pci_readw(devfn, PCI_COMMAND);
   1.113 +        if ( (bar_reg == PCI_ROM_ADDRESS) ||
   1.114 +             ((bar_data & PCI_BASE_ADDRESS_SPACE) ==
   1.115 +              PCI_BASE_ADDRESS_SPACE_MEMORY) )
   1.116 +            cmd |= PCI_COMMAND_MEMORY;
   1.117 +        else
   1.118 +            cmd |= PCI_COMMAND_IO;
   1.119 +        pci_writew(devfn, PCI_COMMAND, cmd);
   1.120 +    }
   1.121  }
   1.122  
   1.123  /*