1 /*        $NetBSD: pciconf.c,v 1.55 2022/09/25 17:52:25 thorpej Exp $ */
2 
3 /*
4  * Copyright 2001 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Allen Briggs for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed for the NetBSD Project by
20  *      Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 /*
38  * Derived in part from code from PMON/2000 (http://pmon.groupbsd.org/).
39  */
40 
41 /*
42  * To do:
43  *    - Perform all data structure allocation dynamically, don't have
44  *        statically-sized arrays ("oops, you lose because you have too
45  *        many slots filled!")
46  *    - Do this in 2 passes, with an MD hook to control the behavior:
47  *                  (1) Configure the bus (possibly including expansion
48  *                      ROMs.
49  *                  (2) Another pass to disable expansion ROMs if they're
50  *                      mapped (since you're not supposed to leave them
51  *                      mapped when you're not using them).
52  *        This would facilitate MD code executing the expansion ROMs
53  *        if necessary (possibly with an x86 emulator) to configure
54  *        devices (e.g. VGA cards).
55  *    - Deal with "anything can be hot-plugged" -- i.e., carry configuration
56  *        information around & be able to reconfigure on the fly
57  *    - Deal with segments (See IA64 System Abstraction Layer)
58  *    - Deal with subtractive bridges (& non-spec positive/subtractive decode)
59  *    - Deal with ISA/VGA/VGA palette snooping
60  *    - Deal with device capabilities on bridges
61  *    - Worry about changing a bridge to/from transparency
62  * From thorpej (05/25/01)
63  *    - Try to handle devices that are already configured (perhaps using that
64  *      as a hint to where we put other devices)
65  */
66 
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: pciconf.c,v 1.55 2022/09/25 17:52:25 thorpej Exp $");
69 
70 #include "opt_pci.h"
71 
72 #include <sys/param.h>
73 #include <sys/queue.h>
74 #include <sys/systm.h>
75 #include <sys/kmem.h>
76 #include <sys/vmem.h>
77 
78 #include <dev/pci/pcivar.h>
79 #include <dev/pci/pciconf.h>
80 #include <dev/pci/pcidevs.h>
81 #include <dev/pci/pccbbreg.h>
82 
83 int pci_conf_debug = 0;
84 
85 #if !defined(MIN)
86 #define   MIN(a,b) (((a)<(b))?(a):(b))
87 #define   MAX(a,b) (((a)>(b))?(a):(b))
88 #endif
89 
90 /* per-bus constants. */
91 #define MAX_CONF_DEV          32                            /* Arbitrary */
92 #define MAX_CONF_MEM          (3 * MAX_CONF_DEV)  /* Avg. 3 per device -- Arb. */
93 #define MAX_CONF_IO (3 * MAX_CONF_DEV)  /* Avg. 1 per device -- Arb. */
94 
95 struct _s_pciconf_bus_t;                          /* Forward declaration */
96 
97 struct pciconf_resource {
98           vmem_t              *arena;
99           bus_addr_t          min_addr;
100           bus_addr_t          max_addr;
101           bus_size_t          total_size;
102 };
103 
104 #define   PCICONF_RESOURCE_NTYPES       3
105 CTASSERT(PCICONF_RESOURCE_IO < PCICONF_RESOURCE_NTYPES);
106 CTASSERT(PCICONF_RESOURCE_MEM < PCICONF_RESOURCE_NTYPES);
107 CTASSERT(PCICONF_RESOURCE_PREFETCHABLE_MEM < PCICONF_RESOURCE_NTYPES);
108 
109 static const char *pciconf_resource_names[] = {
110           [PCICONF_RESOURCE_IO]                             =         "pci-io",
111           [PCICONF_RESOURCE_MEM]                            =         "pci-mem",
112           [PCICONF_RESOURCE_PREFETCHABLE_MEM]     =         "pci-pmem",
113 };
114 
115 struct pciconf_resources {
116           struct pciconf_resource resources[PCICONF_RESOURCE_NTYPES];
117 };
118 
119 struct pciconf_resource_rsvd {
120           int                 type;
121           uint64_t  start;
122           bus_size_t          size;
123           void                (*callback)(void *, uint64_t);
124           void                *callback_arg;
125           LIST_ENTRY(pciconf_resource_rsvd) next;
126 };
127 
128 static LIST_HEAD(, pciconf_resource_rsvd) pciconf_resource_reservations =
129     LIST_HEAD_INITIALIZER(pciconf_resource_reservations);
130 
131 typedef struct _s_pciconf_dev_t {
132           int                 ipin;
133           int                 iline;
134           int                 min_gnt;
135           int                 max_lat;
136           int                 enable;
137           pcitag_t  tag;
138           pci_chipset_tag_t   pc;
139           struct _s_pciconf_bus_t       *ppb;               /* I am really a bridge */
140           pcireg_t  ea_cap_ptr;
141 } pciconf_dev_t;
142 
143 typedef struct _s_pciconf_win_t {
144           pciconf_dev_t       *dev;
145           int                 reg;                          /* 0 for busses */
146           int                 align;
147           int                 prefetch;
148           uint64_t  size;
149           uint64_t  address;
150 } pciconf_win_t;
151 
152 typedef struct _s_pciconf_bus_t {
153           int                 busno;
154           int                 next_busno;
155           int                 last_busno;
156           int                 max_mingnt;
157           int                 min_maxlat;
158           int                 cacheline_size;
159           int                 prefetch;
160           int                 fast_b2b;
161           int                 freq_66;
162           int                 def_ltim;
163           int                 max_ltim;
164           int                 bandwidth_used;
165           int                 swiz;
166           int                 io_32bit;
167           int                 pmem_64bit;
168           int                 mem_64bit;
169           int                 io_align;
170           int                 mem_align;
171           int                 pmem_align;
172 
173           int                 ndevs;
174           pciconf_dev_t       device[MAX_CONF_DEV];
175 
176           /* These should be sorted in order of decreasing size */
177           int                 nmemwin;
178           pciconf_win_t       pcimemwin[MAX_CONF_MEM];
179           int                 niowin;
180           pciconf_win_t       pciiowin[MAX_CONF_IO];
181 
182           bus_size_t          io_total;
183           bus_size_t          mem_total;
184           bus_size_t          pmem_total;
185 
186           struct pciconf_resource io_res;
187           struct pciconf_resource mem_res;
188           struct pciconf_resource pmem_res;
189 
190           pci_chipset_tag_t   pc;
191           struct _s_pciconf_bus_t *parent_bus;
192 } pciconf_bus_t;
193 
194 static int          probe_bus(pciconf_bus_t *);
195 static void         alloc_busno(pciconf_bus_t *, pciconf_bus_t *);
196 static void         set_busreg(pci_chipset_tag_t, pcitag_t, int, int, int);
197 static int          pci_do_device_query(pciconf_bus_t *, pcitag_t, int, int, int);
198 static int          setup_iowins(pciconf_bus_t *);
199 static int          setup_memwins(pciconf_bus_t *);
200 static int          configure_bridge(pciconf_dev_t *);
201 static int          configure_bus(pciconf_bus_t *);
202 static uint64_t     pci_allocate_range(struct pciconf_resource *, uint64_t, int,
203                         bool);
204 static pciconf_win_t          *get_io_desc(pciconf_bus_t *, bus_size_t);
205 static pciconf_win_t          *get_mem_desc(pciconf_bus_t *, bus_size_t);
206 static pciconf_bus_t          *query_bus(pciconf_bus_t *, pciconf_dev_t *, int);
207 
208 static void         print_tag(pci_chipset_tag_t, pcitag_t);
209 
210 static vmem_t *
create_vmem_arena(const char * name,bus_addr_t start,bus_size_t size,int flags)211 create_vmem_arena(const char *name, bus_addr_t start, bus_size_t size,
212     int flags)
213 {
214           KASSERT(start < VMEM_ADDR_MAX);
215           KASSERT(size == 0 ||
216                     (VMEM_ADDR_MAX - start) >= (size - 1));
217 
218           return vmem_create(name, start, size,
219                                  1,               /*quantum*/
220                                  NULL,  /*importfn*/
221                                  NULL,  /*releasefn*/
222                                  NULL,  /*source*/
223                                  0,               /*qcache_max*/
224                                  flags,
225                                  IPL_NONE);
226 }
227 
228 static int
init_range_resource(struct pciconf_resource * r,const char * name,bus_addr_t start,bus_addr_t size)229 init_range_resource(struct pciconf_resource *r, const char *name,
230     bus_addr_t start, bus_addr_t size)
231 {
232           r->arena = create_vmem_arena(name, start, size, VM_NOSLEEP);
233           if (r->arena == NULL)
234                     return ENOMEM;
235 
236           r->min_addr = start;
237           r->max_addr = start + (size - 1);
238           r->total_size = size;
239 
240           return 0;
241 }
242 
243 static void
fini_range_resource(struct pciconf_resource * r)244 fini_range_resource(struct pciconf_resource *r)
245 {
246           if (r->arena) {
247                     vmem_xfreeall(r->arena);
248                     vmem_destroy(r->arena);
249           }
250           memset(r, 0, sizeof(*r));
251 }
252 
253 static void
print_tag(pci_chipset_tag_t pc,pcitag_t tag)254 print_tag(pci_chipset_tag_t pc, pcitag_t tag)
255 {
256           int       bus, dev, func;
257 
258           pci_decompose_tag(pc, tag, &bus, &dev, &func);
259           printf("PCI: bus %d, device %d, function %d: ", bus, dev, func);
260 }
261 
262 #ifdef _LP64
263 #define   __used_only_lp64    __unused
264 #else
265 #define   __used_only_lp64    /* nothing */
266 #endif /* _LP64 */
267 
268 /************************************************************************/
269 /************************************************************************/
270 /***********************   Bus probing routines   ***********************/
271 /************************************************************************/
272 /************************************************************************/
273 static pciconf_win_t *
get_io_desc(pciconf_bus_t * pb,bus_size_t size)274 get_io_desc(pciconf_bus_t *pb, bus_size_t size)
275 {
276           int       i, n;
277 
278           n = pb->niowin;
279           for (i = n; i > 0 && size > pb->pciiowin[i-1].size; i--)
280                     pb->pciiowin[i] = pb->pciiowin[i-1]; /* struct copy */
281           return &pb->pciiowin[i];
282 }
283 
284 static pciconf_win_t *
get_mem_desc(pciconf_bus_t * pb,bus_size_t size)285 get_mem_desc(pciconf_bus_t *pb, bus_size_t size)
286 {
287           int       i, n;
288 
289           n = pb->nmemwin;
290           for (i = n; i > 0 && size > pb->pcimemwin[i-1].size; i--)
291                     pb->pcimemwin[i] = pb->pcimemwin[i-1]; /* struct copy */
292           return &pb->pcimemwin[i];
293 }
294 
295 /*
296  * Set up bus common stuff, then loop over devices & functions.
297  * If we find something, call pci_do_device_query()).
298  */
299 static int
probe_bus(pciconf_bus_t * pb)300 probe_bus(pciconf_bus_t *pb)
301 {
302           int device;
303           uint8_t devs[32];
304           int i, n;
305 
306           pb->ndevs = 0;
307           pb->niowin = 0;
308           pb->nmemwin = 0;
309           pb->freq_66 = 1;
310 #ifdef PCICONF_NO_FAST_B2B
311           pb->fast_b2b = 0;
312 #else
313           pb->fast_b2b = 1;
314 #endif
315           pb->prefetch = 1;
316           pb->max_mingnt = 0; /* we are looking for the maximum */
317           pb->min_maxlat = 0x100;       /* we are looking for the minimum */
318           pb->bandwidth_used = 0;
319 
320           n = pci_bus_devorder(pb->pc, pb->busno, devs, __arraycount(devs));
321           for (i = 0; i < n; i++) {
322                     pcitag_t tag;
323                     pcireg_t id, bhlcr;
324                     int function, nfunction;
325                     int confmode;
326 
327                     device = devs[i];
328 
329                     tag = pci_make_tag(pb->pc, pb->busno, device, 0);
330                     if (pci_conf_debug) {
331                               print_tag(pb->pc, tag);
332                     }
333                     id = pci_conf_read(pb->pc, tag, PCI_ID_REG);
334 
335                     if (pci_conf_debug) {
336                               printf("id=%x: Vendor=%x, Product=%x\n",
337                                   id, PCI_VENDOR(id), PCI_PRODUCT(id));
338                     }
339                     /* Invalid vendor ID value? */
340                     if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
341                               continue;
342 
343                     bhlcr = pci_conf_read(pb->pc, tag, PCI_BHLC_REG);
344                     nfunction = PCI_HDRTYPE_MULTIFN(bhlcr) ? 8 : 1;
345                     for (function = 0; function < nfunction; function++) {
346                               tag = pci_make_tag(pb->pc, pb->busno, device, function);
347                               id = pci_conf_read(pb->pc, tag, PCI_ID_REG);
348                               if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
349                                         continue;
350                               if (pb->ndevs + 1 < MAX_CONF_DEV) {
351                                         if (pci_conf_debug) {
352                                                   print_tag(pb->pc, tag);
353                                                   printf("Found dev 0x%04x 0x%04x -- "
354                                                       "really probing.\n",
355                                                   PCI_VENDOR(id), PCI_PRODUCT(id));
356                                         }
357 #ifdef __HAVE_PCI_CONF_HOOK
358                                         confmode = pci_conf_hook(pb->pc, pb->busno,
359                                             device, function, id);
360                                         if (confmode == 0)
361                                                   continue;
362 #else
363                                         /*
364                                          * Don't enable expansion ROMS -- some cards
365                                          * share address decoders between the EXPROM
366                                          * and PCI memory space, and enabling the ROM
367                                          * when not needed will cause all sorts of
368                                          * lossage.
369                                          */
370                                         confmode = PCI_CONF_DEFAULT;
371 #endif
372                                         if (pci_do_device_query(pb, tag, device,
373                                             function, confmode))
374                                                   return -1;
375                                         pb->ndevs++;
376                               }
377                     }
378           }
379           return 0;
380 }
381 
382 static void
alloc_busno(pciconf_bus_t * parent,pciconf_bus_t * pb)383 alloc_busno(pciconf_bus_t *parent, pciconf_bus_t *pb)
384 {
385           pb->busno = parent->next_busno;
386           pb->next_busno = pb->busno + 1;
387 }
388 
389 static void
set_busreg(pci_chipset_tag_t pc,pcitag_t tag,int prim,int sec,int sub)390 set_busreg(pci_chipset_tag_t pc, pcitag_t tag, int prim, int sec, int sub)
391 {
392           pcireg_t  busreg;
393 
394           busreg  = __SHIFTIN(prim, PCI_BRIDGE_BUS_PRIMARY);
395           busreg |= __SHIFTIN(sec,  PCI_BRIDGE_BUS_SECONDARY);
396           busreg |= __SHIFTIN(sub,  PCI_BRIDGE_BUS_SUBORDINATE);
397           pci_conf_write(pc, tag, PCI_BRIDGE_BUS_REG, busreg);
398 }
399 
400 static pciconf_bus_t *
query_bus(pciconf_bus_t * parent,pciconf_dev_t * pd,int dev)401 query_bus(pciconf_bus_t *parent, pciconf_dev_t *pd, int dev)
402 {
403           pciconf_bus_t       *pb;
404           pcireg_t  io, pmem;
405           pciconf_win_t       *pi, *pm;
406 
407           pb = kmem_zalloc(sizeof (pciconf_bus_t), KM_SLEEP);
408           pb->cacheline_size = parent->cacheline_size;
409           pb->parent_bus = parent;
410           alloc_busno(parent, pb);
411 
412           pb->mem_align = 0x100000;     /* 1M alignment */
413           pb->pmem_align = 0x100000;    /* 1M alignment */
414           pb->io_align = 0x1000;                  /* 4K alignment */
415 
416           set_busreg(parent->pc, pd->tag, parent->busno, pb->busno, 0xff);
417 
418           pb->swiz = parent->swiz + dev;
419 
420           memset(&pb->io_res, 0, sizeof(pb->io_res));
421           memset(&pb->mem_res, 0, sizeof(pb->mem_res));
422           memset(&pb->pmem_res, 0, sizeof(pb->pmem_res));
423 
424           pb->pc = parent->pc;
425           pb->io_total = pb->mem_total = pb->pmem_total = 0;
426 
427           pb->io_32bit = 0;
428           if (parent->io_32bit) {
429                     io = pci_conf_read(parent->pc, pd->tag, PCI_BRIDGE_STATIO_REG);
430                     if (PCI_BRIDGE_IO_32BITS(io))
431                               pb->io_32bit = 1;
432           }
433 
434           pb->pmem_64bit = 0;
435           if (parent->pmem_64bit) {
436                     pmem = pci_conf_read(parent->pc, pd->tag,
437                         PCI_BRIDGE_PREFETCHMEM_REG);
438                     if (PCI_BRIDGE_PREFETCHMEM_64BITS(pmem))
439                               pb->pmem_64bit = 1;
440           }
441 
442           /* Bridges only forward a 32-bit range of non-prefetcable memory. */
443           pb->mem_64bit = 0;
444 
445           if (probe_bus(pb)) {
446                     printf("Failed to probe bus %d\n", pb->busno);
447                     goto err;
448           }
449 
450           /* We have found all subordinate busses now, reprogram busreg. */
451           pb->last_busno = pb->next_busno - 1;
452           parent->next_busno = pb->next_busno;
453           set_busreg(parent->pc, pd->tag, parent->busno, pb->busno,
454                        pb->last_busno);
455           if (pci_conf_debug)
456                     printf("PCI bus bridge (parent %d) covers busses %d-%d\n",
457                               parent->busno, pb->busno, pb->last_busno);
458 
459           if (pb->io_total > 0) {
460                     if (parent->niowin >= MAX_CONF_IO) {
461                               printf("pciconf: too many (%d) I/O windows\n",
462                                   parent->niowin);
463                               goto err;
464                     }
465                     pb->io_total |= pb->io_align - 1; /* Round up */
466                     pi = get_io_desc(parent, pb->io_total);
467                     pi->dev = pd;
468                     pi->reg = 0;
469                     pi->size = pb->io_total;
470                     pi->align = pb->io_align;     /* 4K min alignment */
471                     if (parent->io_align < pb->io_align)
472                               parent->io_align = pb->io_align;
473                     pi->prefetch = 0;
474                     parent->niowin++;
475                     parent->io_total += pb->io_total;
476           }
477 
478           if (pb->mem_total > 0) {
479                     if (parent->nmemwin >= MAX_CONF_MEM) {
480                               printf("pciconf: too many (%d) MEM windows\n",
481                                    parent->nmemwin);
482                               goto err;
483                     }
484                     pb->mem_total |= pb->mem_align - 1; /* Round up */
485                     pm = get_mem_desc(parent, pb->mem_total);
486                     pm->dev = pd;
487                     pm->reg = 0;
488                     pm->size = pb->mem_total;
489                     pm->align = pb->mem_align;    /* 1M min alignment */
490                     if (parent->mem_align < pb->mem_align)
491                               parent->mem_align = pb->mem_align;
492                     pm->prefetch = 0;
493                     parent->nmemwin++;
494                     parent->mem_total += pb->mem_total;
495           }
496 
497           if (pb->pmem_total > 0) {
498                     if (parent->nmemwin >= MAX_CONF_MEM) {
499                               printf("pciconf: too many MEM windows\n");
500                               goto err;
501                     }
502                     pb->pmem_total |= pb->pmem_align - 1; /* Round up */
503                     pm = get_mem_desc(parent, pb->pmem_total);
504                     pm->dev = pd;
505                     pm->reg = 0;
506                     pm->size = pb->pmem_total;
507                     pm->align = pb->pmem_align;   /* 1M alignment */
508                     if (parent->pmem_align < pb->pmem_align)
509                               parent->pmem_align = pb->pmem_align;
510                     pm->prefetch = 1;
511                     parent->nmemwin++;
512                     parent->pmem_total += pb->pmem_total;
513           }
514 
515           return pb;
516 err:
517           kmem_free(pb, sizeof(*pb));
518           return NULL;
519 }
520 
521 static struct pciconf_resource_rsvd *
pci_resource_is_reserved(int type,uint64_t addr,uint64_t size)522 pci_resource_is_reserved(int type, uint64_t addr, uint64_t size)
523 {
524           struct pciconf_resource_rsvd *rsvd;
525 
526           LIST_FOREACH(rsvd, &pciconf_resource_reservations, next) {
527                     if (rsvd->type != type)
528                               continue;
529                     if (rsvd->start <= addr + size && rsvd->start + rsvd->size >= addr)
530                               return rsvd;
531           }
532 
533           return NULL;
534 }
535 
536 static struct pciconf_resource_rsvd *
pci_bar_is_reserved(pciconf_bus_t * pb,pciconf_dev_t * pd,int br)537 pci_bar_is_reserved(pciconf_bus_t *pb, pciconf_dev_t *pd, int br)
538 {
539           pcireg_t base, base64, mask, mask64;
540           pcitag_t tag;
541           uint64_t addr, size;
542 
543           /*
544            * Resource reservation does not apply to bridges
545            */
546           if (pd->ppb)
547                     return NULL;
548 
549           tag = pd->tag;
550 
551           /*
552            * Look to see if this device is enabled and one of the resources
553            * is already in use (eg. firmware configured console device).
554            */
555           base = pci_conf_read(pb->pc, tag, br);
556           pci_conf_write(pb->pc, tag, br, 0xffffffff);
557           mask = pci_conf_read(pb->pc, tag, br);
558           pci_conf_write(pb->pc, tag, br, base);
559 
560           switch (PCI_MAPREG_TYPE(base)) {
561           case PCI_MAPREG_TYPE_IO:
562                     addr = PCI_MAPREG_IO_ADDR(base);
563                     size = PCI_MAPREG_IO_SIZE(mask);
564                     return pci_resource_is_reserved(PCI_CONF_MAP_IO, addr, size);
565 
566           case PCI_MAPREG_TYPE_MEM:
567                     if (PCI_MAPREG_MEM_TYPE(base) == PCI_MAPREG_MEM_TYPE_64BIT) {
568                               base64 = pci_conf_read(pb->pc, tag, br + 4);
569                               pci_conf_write(pb->pc, tag, br + 4, 0xffffffff);
570                               mask64 = pci_conf_read(pb->pc, tag, br + 4);
571                               pci_conf_write(pb->pc, tag, br + 4, base64);
572                               addr = (uint64_t)PCI_MAPREG_MEM64_ADDR(
573                                     (((uint64_t)base64) << 32) | base);
574                               size = (uint64_t)PCI_MAPREG_MEM64_SIZE(
575                                     (((uint64_t)mask64) << 32) | mask);
576                     } else {
577                               addr = PCI_MAPREG_MEM_ADDR(base);
578                               size = PCI_MAPREG_MEM_SIZE(mask);
579                     }
580                     return pci_resource_is_reserved(PCI_CONF_MAP_MEM, addr, size);
581 
582           default:
583                     return NULL;
584           }
585 }
586 
587 static int
pci_do_device_query(pciconf_bus_t * pb,pcitag_t tag,int dev,int func,int mode)588 pci_do_device_query(pciconf_bus_t *pb, pcitag_t tag, int dev, int func,
589     int mode)
590 {
591           pciconf_dev_t       *pd;
592           pciconf_win_t       *pi, *pm;
593           pcireg_t  classreg, cmd, icr, bhlc, bar, mask, bar64, mask64,
594               busreg;
595           uint64_t  size;
596           int                 br, width, reg_start, reg_end;
597 
598           pd = &pb->device[pb->ndevs];
599           pd->pc = pb->pc;
600           pd->tag = tag;
601           pd->ppb = NULL;
602           pd->enable = mode;
603           pd->ea_cap_ptr = 0;
604 
605           classreg = pci_conf_read(pb->pc, tag, PCI_CLASS_REG);
606 
607           cmd = pci_conf_read(pb->pc, tag, PCI_COMMAND_STATUS_REG);
608           bhlc = pci_conf_read(pb->pc, tag, PCI_BHLC_REG);
609 
610           if (pci_get_capability(pb->pc, tag, PCI_CAP_EA, &pd->ea_cap_ptr,
611               NULL)) {
612                     /* XXX Skip devices with EA for now. */
613                     print_tag(pb->pc, tag);
614                     printf("skipping devices with Enhanced Allocations\n");
615                     return 0;
616           }
617 
618           if (PCI_CLASS(classreg) != PCI_CLASS_BRIDGE
619               && PCI_HDRTYPE_TYPE(bhlc) != PCI_HDRTYPE_PPB) {
620                     cmd &= ~(PCI_COMMAND_MASTER_ENABLE |
621                         PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE);
622                     pci_conf_write(pb->pc, tag, PCI_COMMAND_STATUS_REG, cmd);
623           } else if (pci_conf_debug) {
624                     print_tag(pb->pc, tag);
625                     printf("device is a bridge; not clearing enables\n");
626           }
627 
628           if ((cmd & PCI_STATUS_BACKTOBACK_SUPPORT) == 0)
629                     pb->fast_b2b = 0;
630 
631           if ((cmd & PCI_STATUS_66MHZ_SUPPORT) == 0)
632                     pb->freq_66 = 0;
633 
634           switch (PCI_HDRTYPE_TYPE(bhlc)) {
635           case PCI_HDRTYPE_DEVICE:
636                     reg_start = PCI_MAPREG_START;
637                     reg_end = PCI_MAPREG_END;
638                     break;
639           case PCI_HDRTYPE_PPB:
640                     pd->ppb = query_bus(pb, pd, dev);
641                     if (pd->ppb == NULL)
642                               return -1;
643                     return 0;
644           case PCI_HDRTYPE_PCB:
645                     reg_start = PCI_MAPREG_START;
646                     reg_end = PCI_MAPREG_PCB_END;
647 
648                     busreg = pci_conf_read(pb->pc, tag, PCI_BUSNUM);
649                     busreg = (busreg & 0xff000000) |
650                         __SHIFTIN(pb->busno, PCI_BRIDGE_BUS_PRIMARY) |
651                         __SHIFTIN(pb->next_busno, PCI_BRIDGE_BUS_SECONDARY) |
652                         __SHIFTIN(pb->next_busno, PCI_BRIDGE_BUS_SUBORDINATE);
653                     pci_conf_write(pb->pc, tag, PCI_BUSNUM, busreg);
654 
655                     pb->next_busno++;
656                     break;
657           default:
658                     return -1;
659           }
660 
661           icr = pci_conf_read(pb->pc, tag, PCI_INTERRUPT_REG);
662           pd->ipin = PCI_INTERRUPT_PIN(icr);
663           pd->iline = PCI_INTERRUPT_LINE(icr);
664           pd->min_gnt = PCI_MIN_GNT(icr);
665           pd->max_lat = PCI_MAX_LAT(icr);
666           if (pd->iline || pd->ipin) {
667                     pci_conf_interrupt(pb->pc, pb->busno, dev, pd->ipin, pb->swiz,
668                         &pd->iline);
669                     icr &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT);
670                     icr |= (pd->iline << PCI_INTERRUPT_LINE_SHIFT);
671                     pci_conf_write(pb->pc, tag, PCI_INTERRUPT_REG, icr);
672           }
673 
674           if (pd->min_gnt != 0 || pd->max_lat != 0) {
675                     if (pd->min_gnt != 0 && pd->min_gnt > pb->max_mingnt)
676                               pb->max_mingnt = pd->min_gnt;
677 
678                     if (pd->max_lat != 0 && pd->max_lat < pb->min_maxlat)
679                               pb->min_maxlat = pd->max_lat;
680 
681                     pb->bandwidth_used += pd->min_gnt * 4000000 /
682                                         (pd->min_gnt + pd->max_lat);
683           }
684 
685           width = 4;
686           for (br = reg_start; br < reg_end; br += width) {
687 #if 0
688 /* XXX Should only ignore if IDE not in legacy mode? */
689                     if (PCI_CLASS(classreg) == PCI_CLASS_MASS_STORAGE &&
690                         PCI_SUBCLASS(classreg) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
691                               break;
692                     }
693 #endif
694                     bar = pci_conf_read(pb->pc, tag, br);
695                     pci_conf_write(pb->pc, tag, br, 0xffffffff);
696                     mask = pci_conf_read(pb->pc, tag, br);
697                     pci_conf_write(pb->pc, tag, br, bar);
698                     width = 4;
699 
700                     if (   (mode & PCI_CONF_MAP_IO)
701                         && (PCI_MAPREG_TYPE(mask) == PCI_MAPREG_TYPE_IO)) {
702                               /*
703                                * Upper 16 bits must be one.  Devices may hardwire
704                                * them to zero, though, per PCI 2.2, 6.2.5.1, p 203.
705                                */
706                               mask |= 0xffff0000;
707 
708                               size = PCI_MAPREG_IO_SIZE(mask);
709                               if (size == 0) {
710                                         if (pci_conf_debug) {
711                                                   print_tag(pb->pc, tag);
712                                                   printf("I/O BAR 0x%x is void\n", br);
713                                         }
714                                         continue;
715                               }
716 
717                               if (pb->niowin >= MAX_CONF_IO) {
718                                         printf("pciconf: too many I/O windows\n");
719                                         return -1;
720                               }
721 
722                               pi = get_io_desc(pb, size);
723                               pi->dev = pd;
724                               pi->reg = br;
725                               pi->size = (uint64_t)size;
726                               pi->align = 4;
727                               if (pb->io_align < pi->size)
728                                         pb->io_align = pi->size;
729                               pi->prefetch = 0;
730                               if (pci_conf_debug) {
731                                         print_tag(pb->pc, tag);
732                                         printf("Register 0x%x, I/O size %" PRIu64 "\n",
733                                             br, pi->size);
734                               }
735                               pb->niowin++;
736                               pb->io_total += size;
737                     } else if ((mode & PCI_CONF_MAP_MEM)
738                                  && (PCI_MAPREG_TYPE(mask) == PCI_MAPREG_TYPE_MEM)) {
739                               switch (PCI_MAPREG_MEM_TYPE(mask)) {
740                               case PCI_MAPREG_MEM_TYPE_32BIT:
741                               case PCI_MAPREG_MEM_TYPE_32BIT_1M:
742                                         size = (uint64_t)PCI_MAPREG_MEM_SIZE(mask);
743                                         break;
744                               case PCI_MAPREG_MEM_TYPE_64BIT:
745                                         bar64 = pci_conf_read(pb->pc, tag, br + 4);
746                                         pci_conf_write(pb->pc, tag, br + 4, 0xffffffff);
747                                         mask64 = pci_conf_read(pb->pc, tag, br + 4);
748                                         pci_conf_write(pb->pc, tag, br + 4, bar64);
749                                         size = (uint64_t)PCI_MAPREG_MEM64_SIZE(
750                                               (((uint64_t)mask64) << 32) | mask);
751                                         width = 8;
752                                         break;
753                               default:
754                                         print_tag(pb->pc, tag);
755                                         printf("reserved mapping type 0x%x\n",
756                                                   PCI_MAPREG_MEM_TYPE(mask));
757                                         continue;
758                               }
759 
760                               if (size == 0) {
761                                         if (pci_conf_debug) {
762                                                   print_tag(pb->pc, tag);
763                                                   printf("MEM%d BAR 0x%x is void\n",
764                                                       PCI_MAPREG_MEM_TYPE(mask) ==
765                                                             PCI_MAPREG_MEM_TYPE_64BIT ?
766                                                             64 : 32, br);
767                                         }
768                                         continue;
769                               } else {
770                                         if (pci_conf_debug) {
771                                                   print_tag(pb->pc, tag);
772                                                   printf("MEM%d BAR 0x%x has size %#lx\n",
773                                                       PCI_MAPREG_MEM_TYPE(mask) ==
774                                                             PCI_MAPREG_MEM_TYPE_64BIT ?
775                                                             64 : 32,
776                                                       br, (unsigned long)size);
777                                         }
778                               }
779 
780                               if (pb->nmemwin >= MAX_CONF_MEM) {
781                                         printf("pciconf: too many memory windows\n");
782                                         return -1;
783                               }
784 
785                               pm = get_mem_desc(pb, size);
786                               pm->dev = pd;
787                               pm->reg = br;
788                               pm->size = size;
789                               pm->align = 4;
790                               pm->prefetch = PCI_MAPREG_MEM_PREFETCHABLE(mask);
791                               if (pci_conf_debug) {
792                                         print_tag(pb->pc, tag);
793                                         printf("Register 0x%x, memory size %"
794                                             PRIu64 "\n", br, pm->size);
795                               }
796                               pb->nmemwin++;
797                               if (pm->prefetch) {
798                                         pb->pmem_total += size;
799                                         if (pb->pmem_align < pm->size)
800                                                   pb->pmem_align = pm->size;
801                               } else {
802                                         pb->mem_total += size;
803                                         if (pb->mem_align < pm->size)
804                                                   pb->mem_align = pm->size;
805                               }
806                     }
807           }
808 
809           if (mode & PCI_CONF_MAP_ROM) {
810                     bar = pci_conf_read(pb->pc, tag, PCI_MAPREG_ROM);
811                     pci_conf_write(pb->pc, tag, PCI_MAPREG_ROM, 0xfffffffe);
812                     mask = pci_conf_read(pb->pc, tag, PCI_MAPREG_ROM);
813                     pci_conf_write(pb->pc, tag, PCI_MAPREG_ROM, bar);
814 
815                     if (mask != 0 && mask != 0xffffffff) {
816                               if (pb->nmemwin >= MAX_CONF_MEM) {
817                                         printf("pciconf: too many memory windows\n");
818                                         return -1;
819                               }
820                               size = (uint64_t)PCI_MAPREG_MEM_SIZE(mask);
821 
822                               pm = get_mem_desc(pb, size);
823                               pm->dev = pd;
824                               pm->reg = PCI_MAPREG_ROM;
825                               pm->size = size;
826                               pm->align = 4;
827                               pm->prefetch = 0;
828                               if (pci_conf_debug) {
829                                         print_tag(pb->pc, tag);
830                                         printf("Expansion ROM memory size %"
831                                             PRIu64 "\n", pm->size);
832                               }
833                               pb->nmemwin++;
834                               if (pm->prefetch) {
835                                         pb->pmem_total += size;
836                                         if (pb->pmem_align < pm->size)
837                                                   pb->pmem_align = pm->size;
838                               } else {
839                                         pb->mem_total += size;
840                                         if (pb->mem_align < pm->size)
841                                                   pb->mem_align = pm->size;
842                               }
843                     }
844           } else {
845                     /* Don't enable ROMs if we aren't going to map them. */
846                     mode &= ~PCI_CONF_ENABLE_ROM;
847                     pd->enable &= ~PCI_CONF_ENABLE_ROM;
848           }
849 
850           if (!(mode & PCI_CONF_ENABLE_ROM)) {
851                     /* Ensure ROM is disabled */
852                     bar = pci_conf_read(pb->pc, tag, PCI_MAPREG_ROM);
853                     pci_conf_write(pb->pc, tag, PCI_MAPREG_ROM,
854                         bar & ~PCI_MAPREG_ROM_ENABLE);
855           }
856 
857           return 0;
858 }
859 
860 /************************************************************************/
861 /************************************************************************/
862 /********************   Bus configuration routines   ********************/
863 /************************************************************************/
864 /************************************************************************/
865 static uint64_t
pci_allocate_range(struct pciconf_resource * const r,const uint64_t amt,const int align,const bool ok64 __used_only_lp64)866 pci_allocate_range(struct pciconf_resource * const r, const uint64_t amt,
867                        const int align, const bool ok64 __used_only_lp64)
868 {
869           vmem_size_t const size = (vmem_size_t) amt;
870           vmem_addr_t result;
871           int error;
872 
873 #ifdef _LP64
874           /*
875            * If a 64-bit range IS OK, then we prefer allocating above 4GB.
876            *
877            * XXX We guard this with _LP64 because vmem uses uintptr_t
878            * internally.
879            */
880           if (!ok64) {
881                     error = vmem_xalloc(r->arena, size, align, 0, 0,
882                                             VMEM_ADDR_MIN, 0xffffffffUL,
883                                             VM_BESTFIT | VM_NOSLEEP,
884                                             &result);
885           } else {
886                     error = vmem_xalloc(r->arena, size, align, 0, 0,
887                                             (1UL << 32), VMEM_ADDR_MAX,
888                                             VM_BESTFIT | VM_NOSLEEP,
889                                             &result);
890                     if (error) {
891                               error = vmem_xalloc(r->arena, size, align, 0, 0,
892                                                       VMEM_ADDR_MIN, VMEM_ADDR_MAX,
893                                                       VM_BESTFIT | VM_NOSLEEP,
894                                                       &result);
895                     }
896           }
897 #else
898           error = vmem_xalloc(r->arena, size, align, 0, 0,
899                                   VMEM_ADDR_MIN, 0xffffffffUL,
900                                   VM_BESTFIT | VM_NOSLEEP,
901                                   &result);
902 #endif /* _L64 */
903 
904           if (error)
905                     return ~0ULL;
906 
907           return result;
908 }
909 
910 static int
setup_iowins(pciconf_bus_t * pb)911 setup_iowins(pciconf_bus_t *pb)
912 {
913           pciconf_win_t       *pi;
914           pciconf_dev_t       *pd;
915           struct pciconf_resource_rsvd *rsvd;
916           int                 error;
917 
918           for (pi = pb->pciiowin; pi < &pb->pciiowin[pb->niowin]; pi++) {
919                     if (pi->size == 0)
920                               continue;
921 
922                     pd = pi->dev;
923                     rsvd = pci_bar_is_reserved(pb, pd, pi->reg);
924 
925                     if (pb->io_res.arena == NULL) {
926                               /* Bus has no IO ranges, disable IO BAR */
927                               pi->address = 0;
928                               pd->enable &= ~PCI_CONF_ENABLE_IO;
929                               goto write_ioaddr;
930                     }
931 
932                     pi->address = pci_allocate_range(&pb->io_res, pi->size,
933                         pi->align, false);
934                     if (~pi->address == 0) {
935                               print_tag(pd->pc, pd->tag);
936                               printf("Failed to allocate PCI I/O space (%"
937                                   PRIu64 " req)\n", pi->size);
938                               return -1;
939                     }
940                     if (pd->ppb && pi->reg == 0) {
941                               error = init_range_resource(&pd->ppb->io_res,
942                                   "ppb-io", pi->address, pi->size);
943                               if (error) {
944                                         print_tag(pd->pc, pd->tag);
945                                         printf("Failed to alloc I/O arena for bus %d\n",
946                                             pd->ppb->busno);
947                                         return -1;
948                               }
949                               continue;
950                     }
951                     if (!pb->io_32bit && pi->address > 0xFFFF) {
952                               pi->address = 0;
953                               pd->enable &= ~PCI_CONF_ENABLE_IO;
954                     } else {
955                               pd->enable |= PCI_CONF_ENABLE_IO;
956                     }
957 write_ioaddr:
958                     if (pci_conf_debug) {
959                               print_tag(pd->pc, pd->tag);
960                               printf("Putting %" PRIu64 " I/O bytes @ %#" PRIx64
961                                   " (reg %x)\n", pi->size, pi->address, pi->reg);
962                     }
963                     pci_conf_write(pd->pc, pd->tag, pi->reg,
964                         PCI_MAPREG_IO_ADDR(pi->address) | PCI_MAPREG_TYPE_IO);
965 
966                     if (rsvd != NULL && rsvd->start != pi->address)
967                               rsvd->callback(rsvd->callback_arg, pi->address);
968           }
969           return 0;
970 }
971 
972 static int
setup_memwins(pciconf_bus_t * pb)973 setup_memwins(pciconf_bus_t *pb)
974 {
975           pciconf_win_t       *pm;
976           pciconf_dev_t       *pd;
977           pcireg_t  base;
978           struct pciconf_resource *r;
979           struct pciconf_resource_rsvd *rsvd;
980           bool                ok64;
981           int                 error;
982 
983           for (pm = pb->pcimemwin; pm < &pb->pcimemwin[pb->nmemwin]; pm++) {
984                     if (pm->size == 0)
985                               continue;
986 
987                     ok64 = false;
988                     pd = pm->dev;
989                     rsvd = pci_bar_is_reserved(pb, pd, pm->reg);
990 
991                     if (pm->prefetch) {
992                               r = &pb->pmem_res;
993                               ok64 = pb->pmem_64bit;
994                     } else {
995                               r = &pb->mem_res;
996                               ok64 = pb->mem_64bit && pd->ppb == NULL;
997                     }
998 
999                     /*
1000                      * We need to figure out if the memory BAR is 64-bit
1001                      * capable or not.  If it's not, then we need to constrain
1002                      * the address allocation.
1003                      */
1004                     if (pm->reg == PCI_MAPREG_ROM) {
1005                               ok64 = false;
1006                     } else if (ok64) {
1007                               base = pci_conf_read(pd->pc, pd->tag, pm->reg);
1008                               ok64 = PCI_MAPREG_MEM_TYPE(base) ==
1009                                   PCI_MAPREG_MEM_TYPE_64BIT;
1010                     }
1011 
1012                     pm->address = pci_allocate_range(r, pm->size, pm->align,
1013                                                              ok64);
1014                     if (~pm->address == 0 && r == &pb->pmem_res) {
1015                               r = &pb->mem_res;
1016                               pm->address = pci_allocate_range(r, pm->size,
1017                                                                        pm->align, ok64);
1018                     }
1019                     if (~pm->address == 0) {
1020                               print_tag(pd->pc, pd->tag);
1021                               printf(
1022                                  "Failed to allocate PCI memory space (%" PRIu64
1023                                  " req, prefetch=%d ok64=%d)\n", pm->size,
1024                                  pm->prefetch, (int)ok64);
1025                               return -1;
1026                     }
1027                     if (pd->ppb && pm->reg == 0) {
1028                               const char *name = pm->prefetch ? "ppb-pmem"
1029                                                                       : "ppb-mem";
1030                               r = pm->prefetch ? &pd->ppb->pmem_res
1031                                                    : &pd->ppb->mem_res;
1032                               error = init_range_resource(r, name,
1033                                   pm->address, pm->size);
1034                               if (error) {
1035                                         print_tag(pd->pc, pd->tag);
1036                                         printf("Failed to alloc MEM arena for bus %d\n",
1037                                             pd->ppb->busno);
1038                                         return -1;
1039                               }
1040                               continue;
1041                     }
1042                     if (!ok64 && pm->address > 0xFFFFFFFFULL) {
1043                               pm->address = 0;
1044                               pd->enable &= ~PCI_CONF_ENABLE_MEM;
1045                     } else
1046                               pd->enable |= PCI_CONF_ENABLE_MEM;
1047 
1048                     if (pm->reg != PCI_MAPREG_ROM) {
1049                               if (pci_conf_debug) {
1050                                         print_tag(pd->pc, pd->tag);
1051                                         printf(
1052                                             "Putting %" PRIu64 " MEM bytes @ %#"
1053                                             PRIx64 " (reg %x)\n", pm->size,
1054                                             pm->address, pm->reg);
1055                               }
1056                               base = pci_conf_read(pd->pc, pd->tag, pm->reg);
1057                               base = PCI_MAPREG_MEM_ADDR(pm->address) |
1058                                   PCI_MAPREG_MEM_TYPE(base);
1059                               pci_conf_write(pd->pc, pd->tag, pm->reg, base);
1060                               if (PCI_MAPREG_MEM_TYPE(base) ==
1061                                   PCI_MAPREG_MEM_TYPE_64BIT) {
1062                                         base = (pcireg_t)
1063                                             (PCI_MAPREG_MEM64_ADDR(pm->address) >> 32);
1064                                         pci_conf_write(pd->pc, pd->tag, pm->reg + 4,
1065                                             base);
1066                               }
1067                     }
1068 
1069                     if (rsvd != NULL && rsvd->start != pm->address) {
1070                               /*
1071                                * Resource allocation will never reuse a reserved
1072                                * address. Check to see if the BAR is still reserved
1073                                * to cover the case where the new resource was not
1074                                * applied. In this case, there is no need to notify
1075                                * the device callback of a change.
1076                                */
1077                               if (!pci_bar_is_reserved(pb, pd, pm->reg)) {
1078                                         rsvd->callback(rsvd->callback_arg, pm->address);
1079                               }
1080                     }
1081           }
1082           for (pm = pb->pcimemwin; pm < &pb->pcimemwin[pb->nmemwin]; pm++) {
1083                     if (pm->reg == PCI_MAPREG_ROM && pm->address != -1) {
1084                               pd = pm->dev;
1085                               if (!(pd->enable & PCI_CONF_MAP_ROM))
1086                                         continue;
1087                               if (pci_conf_debug) {
1088                                         print_tag(pd->pc, pd->tag);
1089                                         printf(
1090                                             "Putting %" PRIu64 " ROM bytes @ %#"
1091                                             PRIx64 " (reg %x)\n", pm->size,
1092                                             pm->address, pm->reg);
1093                               }
1094                               base = (pcireg_t) pm->address;
1095                               if (pd->enable & PCI_CONF_ENABLE_ROM)
1096                                         base |= PCI_MAPREG_ROM_ENABLE;
1097 
1098                               pci_conf_write(pd->pc, pd->tag, pm->reg, base);
1099                     }
1100           }
1101           return 0;
1102 }
1103 
1104 static bool
constrain_bridge_mem_range(struct pciconf_resource * const r,u_long * const base,u_long * const limit,const bool ok64 __used_only_lp64)1105 constrain_bridge_mem_range(struct pciconf_resource * const r,
1106                                  u_long * const base,
1107                                  u_long * const limit,
1108                                  const bool ok64 __used_only_lp64)
1109 {
1110 
1111           *base = r->min_addr;
1112           *limit = r->max_addr;
1113 
1114 #ifdef _LP64
1115           if (!ok64) {
1116                     if (r->min_addr >= (1UL << 32)) {
1117                               return true;
1118                     }
1119                     if (r->max_addr > 0xffffffffUL) {
1120                               *limit = 0xffffffffUL;
1121                     }
1122           }
1123 #endif /* _LP64 */
1124 
1125           return false;
1126 }
1127 
1128 /*
1129  * Configure I/O, memory, and prefetcable memory spaces, then make
1130  * a call to configure_bus().
1131  */
1132 static int
configure_bridge(pciconf_dev_t * pd)1133 configure_bridge(pciconf_dev_t *pd)
1134 {
1135           unsigned long       io_base, io_limit, mem_base, mem_limit;
1136           pciconf_bus_t       *pb;
1137           pcireg_t  io, iohigh, mem, cmd;
1138           int                 rv;
1139           bool                isprefetchmem64;
1140           bool                bad_range;
1141 
1142           pb = pd->ppb;
1143           /* Configure I/O base & limit*/
1144           if (pb->io_res.arena) {
1145                     io_base = pb->io_res.min_addr;
1146                     io_limit = pb->io_res.max_addr;
1147           } else {
1148                     io_base  = 0x1000;  /* 4K */
1149                     io_limit = 0x0000;
1150           }
1151           if (pb->io_32bit) {
1152                     iohigh = __SHIFTIN(io_base >> 16, PCI_BRIDGE_IOHIGH_BASE) |
1153                         __SHIFTIN(io_limit >> 16, PCI_BRIDGE_IOHIGH_LIMIT);
1154           } else {
1155                     if (io_limit > 0xFFFF) {
1156                               printf("Bus %d bridge does not support 32-bit I/O.  ",
1157                                   pb->busno);
1158                               printf("Disabling I/O accesses\n");
1159                               io_base  = 0x1000;  /* 4K */
1160                               io_limit = 0x0000;
1161                     }
1162                     iohigh = 0;
1163           }
1164           io = pci_conf_read(pb->pc, pd->tag, PCI_BRIDGE_STATIO_REG) &
1165               PCI_BRIDGE_STATIO_STATUS;
1166           io |= __SHIFTIN((io_base >> 8) & PCI_BRIDGE_STATIO_IOADDR,
1167               PCI_BRIDGE_STATIO_IOBASE);
1168           io |= __SHIFTIN((io_limit >> 8) & PCI_BRIDGE_STATIO_IOADDR,
1169               PCI_BRIDGE_STATIO_IOLIMIT);
1170           pci_conf_write(pb->pc, pd->tag, PCI_BRIDGE_STATIO_REG, io);
1171           pci_conf_write(pb->pc, pd->tag, PCI_BRIDGE_IOHIGH_REG, iohigh);
1172 
1173           /* Configure mem base & limit */
1174           bad_range = false;
1175           if (pb->mem_res.arena) {
1176                     bad_range = constrain_bridge_mem_range(&pb->mem_res,
1177                                                                    &mem_base,
1178                                                                    &mem_limit,
1179                                                                    false);
1180           } else {
1181                     mem_base  = 0x100000;         /* 1M */
1182                     mem_limit = 0x000000;
1183           }
1184           if (bad_range) {
1185                     printf("Bus %d bridge MEM range out of range.  ", pb->busno);
1186                     printf("Disabling MEM accesses\n");
1187                     mem_base  = 0x100000;         /* 1M */
1188                     mem_limit = 0x000000;
1189           }
1190           mem = __SHIFTIN((mem_base >> 16) & PCI_BRIDGE_MEMORY_ADDR,
1191               PCI_BRIDGE_MEMORY_BASE);
1192           mem |= __SHIFTIN((mem_limit >> 16) & PCI_BRIDGE_MEMORY_ADDR,
1193               PCI_BRIDGE_MEMORY_LIMIT);
1194           pci_conf_write(pb->pc, pd->tag, PCI_BRIDGE_MEMORY_REG, mem);
1195 
1196           /* Configure prefetchable mem base & limit */
1197           mem = pci_conf_read(pb->pc, pd->tag, PCI_BRIDGE_PREFETCHMEM_REG);
1198           isprefetchmem64 = PCI_BRIDGE_PREFETCHMEM_64BITS(mem);
1199           bad_range = false;
1200           if (pb->pmem_res.arena) {
1201                     bad_range = constrain_bridge_mem_range(&pb->pmem_res,
1202                                                                    &mem_base,
1203                                                                    &mem_limit,
1204                                                                    isprefetchmem64);
1205           } else {
1206                     mem_base  = 0x100000;         /* 1M */
1207                     mem_limit = 0x000000;
1208           }
1209           if (bad_range) {
1210                     printf("Bus %d bridge does not support 64-bit PMEM.  ",
1211                         pb->busno);
1212                     printf("Disabling prefetchable-MEM accesses\n");
1213                     mem_base  = 0x100000;         /* 1M */
1214                     mem_limit = 0x000000;
1215           }
1216           mem = __SHIFTIN((mem_base >> 16) & PCI_BRIDGE_PREFETCHMEM_ADDR,
1217               PCI_BRIDGE_PREFETCHMEM_BASE);
1218           mem |= __SHIFTIN((mem_limit >> 16) & PCI_BRIDGE_PREFETCHMEM_ADDR,
1219               PCI_BRIDGE_PREFETCHMEM_LIMIT);
1220           pci_conf_write(pb->pc, pd->tag, PCI_BRIDGE_PREFETCHMEM_REG, mem);
1221           /*
1222            * XXX -- 64-bit systems need a lot more than just this...
1223            */
1224           if (isprefetchmem64) {
1225                     mem_base  = (uint64_t)mem_base  >> 32;
1226                     mem_limit = (uint64_t)mem_limit >> 32;
1227                     pci_conf_write(pb->pc, pd->tag,
1228                         PCI_BRIDGE_PREFETCHBASEUP32_REG, mem_base & 0xffffffff);
1229                     pci_conf_write(pb->pc, pd->tag,
1230                         PCI_BRIDGE_PREFETCHLIMITUP32_REG, mem_limit & 0xffffffff);
1231           }
1232 
1233           rv = configure_bus(pb);
1234 
1235           fini_range_resource(&pb->io_res);
1236           fini_range_resource(&pb->mem_res);
1237           fini_range_resource(&pb->pmem_res);
1238 
1239           if (rv == 0) {
1240                     cmd = pci_conf_read(pd->pc, pd->tag, PCI_BRIDGE_CONTROL_REG);
1241                     cmd &= ~PCI_BRIDGE_CONTROL; /* Clear control bit first */
1242                     cmd |= PCI_BRIDGE_CONTROL_PERE | PCI_BRIDGE_CONTROL_SERR;
1243                     if (pb->fast_b2b)
1244                               cmd |= PCI_BRIDGE_CONTROL_SECFASTB2B;
1245 
1246                     pci_conf_write(pd->pc, pd->tag, PCI_BRIDGE_CONTROL_REG, cmd);
1247                     cmd = pci_conf_read(pd->pc, pd->tag, PCI_COMMAND_STATUS_REG);
1248                     cmd |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;
1249                     pci_conf_write(pd->pc, pd->tag, PCI_COMMAND_STATUS_REG, cmd);
1250           }
1251 
1252           return rv;
1253 }
1254 
1255 /*
1256  * Calculate latency values, allocate I/O and MEM segments, then set them
1257  * up.  If a PCI-PCI bridge is found, configure the bridge separately,
1258  * which will cause a recursive call back here.
1259  */
1260 static int
configure_bus(pciconf_bus_t * pb)1261 configure_bus(pciconf_bus_t *pb)
1262 {
1263           pciconf_dev_t       *pd;
1264           int                 def_ltim, max_ltim, band, bus_mhz;
1265 
1266           if (pb->ndevs == 0) {
1267                     if (pci_conf_debug)
1268                               printf("PCI bus %d - no devices\n", pb->busno);
1269                     return 1;
1270           }
1271           bus_mhz = pb->freq_66 ? 66 : 33;
1272           max_ltim = pb->max_mingnt * bus_mhz / 4;          /* cvt to cycle count */
1273           band = 4000000;                                             /* 0.25us cycles/sec */
1274           if (band < pb->bandwidth_used) {
1275                     printf("PCI bus %d: Warning: Total bandwidth exceeded!? (%d)\n",
1276                         pb->busno, pb->bandwidth_used);
1277                     def_ltim = -1;
1278           } else {
1279                     def_ltim = (band - pb->bandwidth_used) / pb->ndevs;
1280                     if (def_ltim > pb->min_maxlat)
1281                               def_ltim = pb->min_maxlat;
1282                     def_ltim = def_ltim * bus_mhz / 4;
1283           }
1284           def_ltim = (def_ltim + 7) & ~7;
1285           max_ltim = (max_ltim + 7) & ~7;
1286 
1287           pb->def_ltim = MIN(def_ltim, 255);
1288           pb->max_ltim = MIN(MAX(max_ltim, def_ltim), 255);
1289 
1290           /*
1291            * Now we have what we need to initialize the devices.
1292            * It would probably be better if we could allocate all of these
1293            * for all busses at once, but "not right now".  First, get a list
1294            * of free memory ranges from the m.d. system.
1295            */
1296           if (setup_iowins(pb) || setup_memwins(pb)) {
1297                     printf("PCI bus configuration failed: "
1298                     "unable to assign all I/O and memory ranges.\n");
1299                     return -1;
1300           }
1301 
1302           /*
1303            * Configure the latency for the devices, and enable them.
1304            */
1305           for (pd = pb->device; pd < &pb->device[pb->ndevs]; pd++) {
1306                     pcireg_t cmd, classreg, misc;
1307                     int       ltim;
1308 
1309                     if (pci_conf_debug) {
1310                               print_tag(pd->pc, pd->tag);
1311                               printf("Configuring device.\n");
1312                     }
1313                     classreg = pci_conf_read(pd->pc, pd->tag, PCI_CLASS_REG);
1314                     misc = pci_conf_read(pd->pc, pd->tag, PCI_BHLC_REG);
1315                     cmd = pci_conf_read(pd->pc, pd->tag, PCI_COMMAND_STATUS_REG);
1316                     if (pd->enable & PCI_CONF_ENABLE_PARITY)
1317                               cmd |= PCI_COMMAND_PARITY_ENABLE;
1318                     if (pd->enable & PCI_CONF_ENABLE_SERR)
1319                               cmd |= PCI_COMMAND_SERR_ENABLE;
1320                     if (pb->fast_b2b)
1321                               cmd |= PCI_COMMAND_BACKTOBACK_ENABLE;
1322                     if (PCI_CLASS(classreg) != PCI_CLASS_BRIDGE ||
1323                         PCI_SUBCLASS(classreg) != PCI_SUBCLASS_BRIDGE_PCI) {
1324                               if (pd->enable & PCI_CONF_ENABLE_IO)
1325                                         cmd |= PCI_COMMAND_IO_ENABLE;
1326                               if (pd->enable & PCI_CONF_ENABLE_MEM)
1327                                         cmd |= PCI_COMMAND_MEM_ENABLE;
1328                               if (pd->enable & PCI_CONF_ENABLE_BM)
1329                                         cmd |= PCI_COMMAND_MASTER_ENABLE;
1330                               ltim = pd->min_gnt * bus_mhz / 4;
1331                               ltim = MIN (MAX (pb->def_ltim, ltim), pb->max_ltim);
1332                     } else {
1333                               cmd |= PCI_COMMAND_MASTER_ENABLE;
1334                               ltim = MIN (pb->def_ltim, pb->max_ltim);
1335                     }
1336                     if ((pd->enable &
1337                         (PCI_CONF_ENABLE_MEM | PCI_CONF_ENABLE_IO)) == 0) {
1338                               print_tag(pd->pc, pd->tag);
1339                               printf("Disabled due to lack of resources.\n");
1340                               cmd &= ~(PCI_COMMAND_MASTER_ENABLE |
1341                                   PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE);
1342                     }
1343                     pci_conf_write(pd->pc, pd->tag, PCI_COMMAND_STATUS_REG, cmd);
1344 
1345                     misc &= ~((PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT) |
1346                         (PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT));
1347                     misc |= (ltim & PCI_LATTIMER_MASK) << PCI_LATTIMER_SHIFT;
1348                     misc |= ((pb->cacheline_size >> 2) & PCI_CACHELINE_MASK) <<
1349                         PCI_CACHELINE_SHIFT;
1350                     pci_conf_write(pd->pc, pd->tag, PCI_BHLC_REG, misc);
1351 
1352                     if (pd->ppb) {
1353                               if (configure_bridge(pd) < 0)
1354                                         return -1;
1355                               continue;
1356                     }
1357           }
1358 
1359           if (pci_conf_debug)
1360                     printf("PCI bus %d configured\n", pb->busno);
1361 
1362           return 0;
1363 }
1364 
1365 static bool
mem_region_ok64(struct pciconf_resource * const r __used_only_lp64)1366 mem_region_ok64(struct pciconf_resource * const r __used_only_lp64)
1367 {
1368           bool rv = false;
1369 
1370 #ifdef _LP64
1371           /*
1372            * XXX We need to guard this with _LP64 because vmem uses
1373            * uintptr_t internally.
1374            */
1375           vmem_size_t result;
1376           if (vmem_xalloc(r->arena, 1/*size*/, 1/*align*/, 0/*phase*/,
1377                               0/*nocross*/, (1UL << 32), VMEM_ADDR_MAX,
1378                               VM_INSTANTFIT | VM_NOSLEEP, &result) == 0) {
1379                     vmem_free(r->arena, result, 1);
1380                     rv = true;
1381           }
1382 #endif /* _LP64 */
1383 
1384           return rv;
1385 }
1386 
1387 /*
1388  * pciconf_resource_init:
1389  *
1390  *        Allocate and initilize a pci configuration resources container.
1391  */
1392 struct pciconf_resources *
pciconf_resource_init(void)1393 pciconf_resource_init(void)
1394 {
1395           struct pciconf_resources *rs;
1396 
1397           rs = kmem_zalloc(sizeof(*rs), KM_SLEEP);
1398 
1399           return (rs);
1400 }
1401 
1402 /*
1403  * pciconf_resource_fini:
1404  *
1405  *        Dispose of a pci configuration resources container.
1406  */
1407 void
pciconf_resource_fini(struct pciconf_resources * rs)1408 pciconf_resource_fini(struct pciconf_resources *rs)
1409 {
1410           int i;
1411 
1412           for (i = 0; i < PCICONF_RESOURCE_NTYPES; i++) {
1413                     fini_range_resource(&rs->resources[i]);
1414           }
1415 
1416           kmem_free(rs, sizeof(*rs));
1417 }
1418 
1419 /*
1420  * pciconf_resource_add:
1421  *
1422  *        Add a pci configuration resource to a container.
1423  */
1424 int
pciconf_resource_add(struct pciconf_resources * rs,int type,bus_addr_t start,bus_size_t size)1425 pciconf_resource_add(struct pciconf_resources *rs, int type,
1426     bus_addr_t start, bus_size_t size)
1427 {
1428           bus_addr_t end = start + (size - 1);
1429           struct pciconf_resource *r;
1430           struct pciconf_resource_rsvd *rsvd;
1431           int error, rsvd_type, align;
1432           vmem_addr_t result;
1433           bool first;
1434 
1435           if (size == 0 || end <= start)
1436                     return EINVAL;
1437 
1438           if (type < 0 || type >= PCICONF_RESOURCE_NTYPES)
1439                     return EINVAL;
1440 
1441           r = &rs->resources[type];
1442 
1443           first = r->arena == NULL;
1444           if (first) {
1445                     r->arena = create_vmem_arena(pciconf_resource_names[type],
1446                         0, 0, VM_SLEEP);
1447                     r->min_addr = VMEM_ADDR_MAX;
1448                     r->max_addr = VMEM_ADDR_MIN;
1449           }
1450 
1451           error = vmem_add(r->arena, start, size, VM_SLEEP);
1452           if (error == 0) {
1453                     if (start < r->min_addr)
1454                               r->min_addr = start;
1455                     if (end > r->max_addr)
1456                               r->max_addr = end;
1457           }
1458 
1459           r->total_size += size;
1460 
1461           switch (type) {
1462           case PCICONF_RESOURCE_IO:
1463                     rsvd_type = PCI_CONF_MAP_IO;
1464                     align = 0x1000;
1465                     break;
1466           case PCICONF_RESOURCE_MEM:
1467           case PCICONF_RESOURCE_PREFETCHABLE_MEM:
1468                     rsvd_type = PCI_CONF_MAP_MEM;
1469                     align = 0x100000;
1470                     break;
1471           default:
1472                     rsvd_type = 0;
1473                     align = 0;
1474                     break;
1475           }
1476 
1477           /*
1478            * Exclude reserved ranges from available resources
1479            */
1480           LIST_FOREACH(rsvd, &pciconf_resource_reservations, next) {
1481                     if (rsvd->type != rsvd_type)
1482                               continue;
1483                     /*
1484                      * The reserved range may not be within our resource window.
1485                      * That's fine, so ignore the error.
1486                      */
1487                     (void)vmem_xalloc(r->arena, rsvd->size, align, 0, 0,
1488                                           rsvd->start, rsvd->start + rsvd->size,
1489                                           VM_BESTFIT | VM_NOSLEEP,
1490                                           &result);
1491           }
1492 
1493           return 0;
1494 }
1495 
1496 /*
1497  * pciconf_resource_reserve:
1498  *
1499  *        Mark a pci configuration resource as in-use. Devices
1500  *        already configured to use these resources are notified
1501  *        during resource assignment if their resources are changed.
1502  */
1503 void
pciconf_resource_reserve(int type,bus_addr_t start,bus_size_t size,void (* callback)(void *,uint64_t),void * callback_arg)1504 pciconf_resource_reserve(int type, bus_addr_t start, bus_size_t size,
1505     void (*callback)(void *, uint64_t), void *callback_arg)
1506 {
1507           struct pciconf_resource_rsvd *rsvd;
1508 
1509           rsvd = kmem_zalloc(sizeof(*rsvd), KM_SLEEP);
1510           rsvd->type = type;
1511           rsvd->start = start;
1512           rsvd->size = size;
1513           rsvd->callback = callback;
1514           rsvd->callback_arg = callback_arg;
1515           LIST_INSERT_HEAD(&pciconf_resource_reservations, rsvd, next);
1516 }
1517 
1518 /*
1519  * Let's configure the PCI bus.
1520  * This consists of basically scanning for all existing devices,
1521  * identifying their needs, and then making another pass over them
1522  * to set:
1523  *        1. I/O addresses
1524  *        2. Memory addresses (Prefetchable and not)
1525  *        3. PCI command register
1526  *        4. The latency part of the PCI BHLC (BIST (Built-In Self Test),
1527  *            Header type, Latency timer, Cache line size) register
1528  *
1529  * The command register is set to enable fast back-to-back transactions
1530  * if the host bridge says it can handle it.  We also configure
1531  * Master Enable, SERR enable, parity enable, and (if this is not a
1532  * PCI-PCI bridge) the I/O and Memory spaces.  Apparently some devices
1533  * will not report some I/O space.
1534  *
1535  * The latency is computed to be a "fair share" of the bus bandwidth.
1536  * The bus bandwidth variable is initialized to the number of PCI cycles
1537  * in one second.  The number of cycles taken for one transaction by each
1538  * device (MAX_LAT + MIN_GNT) is then subtracted from the bandwidth.
1539  * Care is taken to ensure that the latency timer won't be set such that
1540  * it would exceed the critical time for any device.
1541  *
1542  * This is complicated somewhat due to the presence of bridges.  PCI-PCI
1543  * bridges are probed and configured recursively.
1544  */
1545 int
pci_configure_bus(pci_chipset_tag_t pc,struct pciconf_resources * rs,int firstbus,int cacheline_size)1546 pci_configure_bus(pci_chipset_tag_t pc, struct pciconf_resources *rs,
1547     int firstbus, int cacheline_size)
1548 {
1549           pciconf_bus_t       *pb;
1550           int                 rv;
1551 
1552           pb = kmem_zalloc(sizeof (pciconf_bus_t), KM_SLEEP);
1553           pb->busno = firstbus;
1554           pb->next_busno = pb->busno + 1;
1555           pb->last_busno = 255;
1556           pb->cacheline_size = cacheline_size;
1557           pb->parent_bus = NULL;
1558           pb->swiz = 0;
1559           pb->io_32bit = 1;
1560           pb->io_res = rs->resources[PCICONF_RESOURCE_IO];
1561 
1562           pb->mem_res = rs->resources[PCICONF_RESOURCE_MEM];
1563           if (pb->mem_res.arena == NULL)
1564                     pb->mem_res = rs->resources[PCICONF_RESOURCE_PREFETCHABLE_MEM];
1565 
1566           pb->pmem_res = rs->resources[PCICONF_RESOURCE_PREFETCHABLE_MEM];
1567           if (pb->pmem_res.arena == NULL)
1568                     pb->pmem_res = rs->resources[PCICONF_RESOURCE_MEM];
1569 
1570           /*
1571            * Probe the memory region arenas to see if allocation of
1572            * 64-bit addresses is possible.
1573            */
1574           pb->mem_64bit = mem_region_ok64(&pb->mem_res);
1575           pb->pmem_64bit = mem_region_ok64(&pb->pmem_res);
1576 
1577           pb->pc = pc;
1578           pb->io_total = pb->mem_total = pb->pmem_total = 0;
1579 
1580           rv = probe_bus(pb);
1581           pb->last_busno = pb->next_busno - 1;
1582           if (rv == 0)
1583                     rv = configure_bus(pb);
1584 
1585           /*
1586            * All done!
1587            */
1588           kmem_free(pb, sizeof(*pb));
1589           return rv;
1590 }
1591