Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci Enforce alignments for buses.



details:   https://anonhg.NetBSD.org/src/rev/9f63442829d7
branches:  trunk
changeset: 782191:9f63442829d7
user:      matt <matt%NetBSD.org@localhost>
date:      Sat Oct 20 06:09:07 2012 +0000

description:
Enforce alignments for buses.

diffstat:

 sys/dev/pci/pciconf.c |  51 +++++++++++++++++++++++++++++++++++----------------
 1 files changed, 35 insertions(+), 16 deletions(-)

diffs (166 lines):

diff -r 2af1b4c5768e -r 9f63442829d7 sys/dev/pci/pciconf.c
--- a/sys/dev/pci/pciconf.c     Sat Oct 20 06:04:01 2012 +0000
+++ b/sys/dev/pci/pciconf.c     Sat Oct 20 06:09:07 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pciconf.c,v 1.35 2012/10/20 05:33:00 matt Exp $        */
+/*     $NetBSD: pciconf.c,v 1.36 2012/10/20 06:09:07 matt Exp $        */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pciconf.c,v 1.35 2012/10/20 05:33:00 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pciconf.c,v 1.36 2012/10/20 06:09:07 matt Exp $");
 
 #include "opt_pci.h"
 
@@ -131,6 +131,9 @@
        int             swiz;
        int             io_32bit;
        int             pmem_64bit;
+       int             io_align;
+       int             mem_align;
+       int             pmem_align;
 
        int             ndevs;
        pciconf_dev_t   device[MAX_CONF_DEV];
@@ -324,6 +327,10 @@
        pb->parent_bus = parent;
        alloc_busno(parent, pb);
 
+       pb->mem_align = 0x100000;       /* 1M alignment */
+       pb->pmem_align = 0x100000;      /* 1M alignment */
+       pb->io_align = 0x1000;          /* 4K alignment */
+
        set_busreg(parent->pc, pd->tag, parent->busno, pb->busno, 0xff);
 
        pb->swiz = parent->swiz + dev;
@@ -371,12 +378,14 @@
                            parent->niowin);
                        goto err;
                }
-               pb->io_total |= 0xfff;  /* Round up */
+               pb->io_total |= pb->io_align - 1; /* Round up */
                pi = get_io_desc(parent, pb->io_total);
                pi->dev = pd;
                pi->reg = 0;
                pi->size = pb->io_total;
-               pi->align = 0x1000;     /* 4K alignment */
+               pi->align = pb->io_align;       /* 4K min alignment */
+               if (parent->io_align < pb->io_align)
+                       parent->io_align = pb->io_align;
                pi->prefetch = 0;
                parent->niowin++;
                parent->io_total += pb->io_total;
@@ -388,12 +397,14 @@
                             parent->nmemwin);
                        goto err;
                }
-               pb->mem_total |= 0xfffff;       /* Round up */
+               pb->mem_total |= pb->mem_align-1; /* Round up */
                pm = get_mem_desc(parent, pb->mem_total);
                pm->dev = pd;
                pm->reg = 0;
                pm->size = pb->mem_total;
-               pm->align = 0x100000;   /* 1M alignment */
+               pm->align = pb->mem_align;      /* 1M min alignment */
+               if (parent->mem_align < pb->mem_align)
+                       parent->mem_align = pb->mem_align;
                pm->prefetch = 0;
                parent->nmemwin++;
                parent->mem_total += pb->mem_total;
@@ -404,12 +415,14 @@
                        printf("pciconf: too many MEM windows\n");
                        goto err;
                }
-               pb->pmem_total |= 0xfffff;      /* Round up */
+               pb->pmem_total |= pb->pmem_align-1; /* Round up */
                pm = get_mem_desc(parent, pb->pmem_total);
                pm->dev = pd;
                pm->reg = 0;
                pm->size = pb->pmem_total;
-               pm->align = 0x100000;           /* 1M alignment */
+               pm->align = pb->pmem_align;     /* 1M alignment */
+               if (parent->pmem_align < pb->pmem_align)
+                       parent->pmem_align = pb->pmem_align;
                pm->prefetch = 1;
                parent->nmemwin++;
                parent->pmem_total += pb->pmem_total;
@@ -550,6 +563,8 @@
                        pi->reg = br;
                        pi->size = (u_int64_t) size;
                        pi->align = 4;
+                       if (pb->io_align < pi->size)
+                               pb->io_align = pi->size;
                        pi->prefetch = 0;
                        if (pci_conf_debug) {
                                print_tag(pb->pc, tag);
@@ -593,7 +608,7 @@
                        } else {
                                if (pci_conf_debug) {
                                        print_tag(pb->pc, tag);
-                                       printf("MEM%d BAR 0x%x has size %lx\n",
+                                       printf("MEM%d BAR 0x%x has size %#lx\n",
                                            PCI_MAPREG_MEM_TYPE(mask) ==
                                                PCI_MAPREG_MEM_TYPE_64BIT ?
                                                64 : 32, br, (unsigned long)size);
@@ -619,8 +634,12 @@
                        pb->nmemwin++;
                        if (pm->prefetch) {
                                pb->pmem_total += size;
+                               if (pb->pmem_align < pm->size)
+                                       pb->pmem_align = pm->size;
                        } else {
                                pb->mem_total += size;
+                               if (pb->mem_align < pm->size)
+                                       pb->mem_align = pm->size;
                        }
                }
        }
@@ -681,12 +700,12 @@
 
        r = extent_alloc(ex, amt, align, 0, EX_NOWAIT, &addr);
        if (r) {
-               addr = (u_long) -1;
-               printf("extent_alloc(%p, %" PRIu64 ", %d) returned %d\n",
+               printf("extent_alloc(%p, %#" PRIx64 ", %#x) returned %d\n",
                    ex, amt, align, r);
                extent_print(ex);
+               return ~0ULL;
        }
-       return (pcireg_t) addr;
+       return addr;
 }
 
 static int
@@ -702,7 +721,7 @@
                pd = pi->dev;
                pi->address = pci_allocate_range(pb->ioext, pi->size,
                    pi->align);
-               if (pi->address == -1) {
+               if (~pi->address == 0) {
                        print_tag(pd->pc, pd->tag);
                        printf("Failed to allocate PCI I/O space (%"
                            PRIu64 " req)\n", pi->size);
@@ -752,7 +771,7 @@
                pd = pm->dev;
                ex = (pm->prefetch) ? pb->pmemext : pb->memext;
                pm->address = pci_allocate_range(ex, pm->size, pm->align);
-               if (pm->address == -1) {
+               if (~pm->address == 0) {
                        print_tag(pd->pc, pd->tag);
                        printf(
                           "Failed to allocate PCI memory space (%" PRIu64
@@ -994,8 +1013,8 @@
         * of free memory ranges from the m.d. system.
         */
        if (setup_iowins(pb) || setup_memwins(pb)) {
-               printf("PCI bus configuration failed: ");
-               printf("unable to assign all I/O and memory ranges.");
+               printf("PCI bus configuration failed: "
+               "unable to assign all I/O and memory ranges.\n");
                return -1;
        }
 



Home | Main Index | Thread Index | Old Index