1 /*        $NetBSD: pci_fixup.c,v 1.5 2021/11/01 21:28:02 andvar Exp $ */
2 
3 /*-
4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Julian Coleman.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/param.h>
33 #include <sys/device.h>
34 
35 #include <net/if.h>
36 #include <net/if_ether.h>
37 
38 #define _SPARC_BUS_DMA_PRIVATE
39 #include <sys/bus.h>
40 #include <machine/autoconf.h>
41 #include <machine/promlib.h>
42 
43 #include <dev/pci/pcireg.h>
44 #include <dev/pci/pcivar.h>
45 #include <dev/pci/pcidevs.h>
46 
47 #include <dev/ofw/ofw_pci.h>
48 
49 #include <sparc/sparc/msiiepreg.h>
50 #include <sparc/sparc/msiiepvar.h>
51 #include <sparc/sparc/pci_fixup.h>
52 
53 static void mspcic_pci_fixup(int, pcitag_t, int *, uint32_t *, uint32_t *,
54           uint32_t, uint32_t memtop);
55 
56 
57 /* ======================================================================
58  *
59  *                            General PCI bus fixup
60  */
61 
62 #define MAX_DEVFUN  256       /* 32 device * 8 function */
63 #define DF_NEXTDEV(i)         (i + 7 - (i % 8))
64 #define MAP_TOP(map)          (map.pcibase + map.size)
65 #define RND_IO_START(t, m)    (((t & m) == t) ? t : \
66     ((t + PCI_MAPREG_IO_SIZE(m)) & m))
67 #define RND_MEM_START(t, m)   (((t & m) == t) ? t : \
68     ((t + PCI_MAPREG_MEM_SIZE(m)) & m))
69 
70 void
mspcic_pci_scan(int root)71 mspcic_pci_scan(int root)
72 {
73           int i, j, node, bus, dev, fun, maxbus, len, class;
74           struct ofw_pci_register reg;
75           pcitag_t tag;
76           pcireg_t val, saved;
77           uint32_t io[IOMAP_SIZE], mem[MEMMAP_SIZE];
78 #ifdef SPARC_PCI_FIXUP_DEBUG
79           char name[80];
80 
81           memset(name, 0, sizeof(name));
82 #endif
83           maxbus = 1;
84           for (i = 0; i < IOMAP_SIZE; i++)
85                     io[i] = mspcic_pci_iomap[i].pcibase;
86           for (i = 0; i < MEMMAP_SIZE; i++)
87                     mem[i] = mspcic_pci_memmap[i].pcibase;
88           node = OF_child(root);
89 
90 #ifdef SPARC_PCI_FIXUP_DEBUG
91           printf("mspcic_pci_scan start:\n");
92           printf("  max bus %d\n", maxbus);
93           for (i = 0; i < IOMAP_SIZE; i++)
94                     printf("  PCI I/O %d %08x to %08x\n",
95                         i, io[i], MAP_TOP(mspcic_pci_iomap[i]) - 1);
96           for (i = 0; i < MEMMAP_SIZE; i++)
97                     printf("  PCI Mem %d %08x to %08x\n",
98                         i, mem[i], MAP_TOP(mspcic_pci_memmap[i]) - 1);
99 #endif
100 
101           /*
102            * Scan our known PCI devices and collect:
103            *   maximum bus number
104            *   maximum used address in each I/O and memory range
105            */
106           while(node) {
107                     uint32_t busrange[2];
108 
109 #ifdef SPARC_PCI_FIXUP_DEBUG
110                     OF_getprop(node, "name", &name, sizeof(name));
111                     printf("> checking node %x: %s\n", node, name);
112 #endif
113                     len = OF_getproplen(node, "reg");
114                     if (len < sizeof(reg))
115                               continue;
116                     if (OF_getprop(node, "reg", (void *)&reg, sizeof(reg)) != len)
117                               panic("pci_probe_bus: OF_getprop len botch");
118                     bus = OFW_PCI_PHYS_HI_BUS(reg.phys_hi);
119                     dev = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi);
120                     fun = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi);
121                     tag = PCITAG_CREATE(node, bus, dev, fun);
122 #ifdef SPARC_PCI_FIXUP_DEBUG
123                     printf("> bus %2d, dev %2d, fun %2d\n",
124                         PCITAG_BUS(tag), PCITAG_DEV(tag), PCITAG_FUN(tag));
125 #endif
126                     /* Enable all the different spaces/errors for this device */
127                     pci_conf_write(NULL, tag, PCI_COMMAND_STATUS_REG,
128                         PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
129                         PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_PARITY_ENABLE);
130 
131                     /* Configured PCI-PCI bridges - increment max bus number */
132                     if ((OF_getprop(node, "bus-range", (void *)&busrange,
133                        sizeof(busrange)) == sizeof(busrange)))
134                     {
135                               if (busrange[1] > maxbus)
136                                         maxbus = busrange[1] + 1;
137                               if (maxbus > 255)
138                                         panic("mspcic_pci_scan: maxbus > 255");
139 
140                               /* go down one level */
141                               node = OF_child(node);
142                               continue;
143                     }
144 
145                     /* Next node, or parent's next node (if we descended) */
146                     if (OF_peer(node))
147                               node = OF_peer(node);
148                     else if (OF_parent(node) != root) {
149                               node = OF_parent(node);
150                               node = OF_peer(node);
151                     } else
152                               node = 0;
153 
154                     /* Check the Mem and I/O allocations for this node */
155                     val = pci_conf_read(NULL, tag, PCI_BHLC_REG);
156                     if (PCI_HDRTYPE_TYPE(val))    /* Type 0x00 has BAR's */
157                               continue;           /* Skip to next node */
158 
159                     /*
160                      * Read BAR's:
161                      *   save the current (address) value
162                      *   write 0xffffffff and read back the size mask
163                      *   restore the saved value
164                      */
165                     for (i = 0; i < 6; i++) {
166                               saved = pci_conf_read(NULL, tag, PCI_BAR(i));
167                               pci_conf_write(NULL, tag, PCI_BAR(i), (pcireg_t) ~0x0);
168                               val = pci_conf_read(NULL, tag, PCI_BAR(i));
169                               pci_conf_write(NULL, tag, PCI_BAR(i), saved);
170                               if (!val)
171                                         continue; /* Skip to next BAR */
172                               saved &= 0xfffffffe;          /* Remove I/O bit */
173 #ifdef SPARC_PCI_FIXUP_DEBUG
174                               printf("> BAR %02x: value %08x mask %08x\n",
175                                   PCI_BAR(i), saved, val);
176 #endif
177 
178                               /* Compare the address + size against our mappings */
179                               if (PCI_MAPREG_TYPE(val) == PCI_MAPREG_TYPE_IO) {
180                                         saved = saved + PCI_MAPREG_IO_SIZE(val);
181                                         for (j = 0; j < IOMAP_SIZE; j++)
182                                                   if (saved > io[j] && saved <=
183                                                       MAP_TOP(mspcic_pci_iomap[j]))
184                                                   io[j] = saved;
185                               } else {  /* PCI_MAPREG_TYPE_MEM */
186                                         saved = saved + PCI_MAPREG_MEM_SIZE(val);
187                                         for (j = 0; j < MEMMAP_SIZE; j++)
188                                         if (saved > mem[j] && saved <=
189                                             MAP_TOP(mspcic_pci_memmap[j]))
190                                                   mem[j] = saved;
191                               }
192                     }
193 
194                     /* Read ROM */
195                     saved = pci_conf_read(NULL, tag, PCI_MAPREG_ROM);
196                     pci_conf_write(NULL, tag, PCI_MAPREG_ROM, (pcireg_t) ~0x0);
197                     val = pci_conf_read(NULL, tag, PCI_MAPREG_ROM);
198                     pci_conf_write(NULL, tag, PCI_MAPREG_ROM, saved);
199                     if (val) {
200 #ifdef SPARC_PCI_FIXUP_DEBUG
201                               printf("> ROM: start %08x mask %08x\n", saved, val);
202 #endif
203                               saved = saved + PCI_MAPREG_MEM_SIZE(val);
204                               for (j = 0; j < MEMMAP_SIZE; j++)
205                               if (saved > mem[j] && saved <=
206                                   MAP_TOP(mspcic_pci_memmap[j]))
207                                         mem[j] = saved;
208                     }
209           }
210 
211 #ifdef SPARC_PCI_FIXUP_DEBUG
212           printf("mspcic_pci_scan finish:\n");
213           printf("  max bus %d\n", maxbus);
214           for (i = 0; i < IOMAP_SIZE; i++)
215                     if (io[i] < MAP_TOP(mspcic_pci_iomap[i]) - 1)
216                               printf("  PCI I/O free %d %08x to %08x\n",
217                                   i, io[i], MAP_TOP(mspcic_pci_iomap[i]) - 1);
218                     else
219                               printf("  PCI I/O %d full %08x to %08x\n",
220                                   i, mspcic_pci_iomap[i].sysbase,
221                                   MAP_TOP(mspcic_pci_iomap[i]) - 1);
222           for (i = 0; i < MEMMAP_SIZE; i++)
223                     if (mem[i] < MAP_TOP(mspcic_pci_memmap[i]) - 1)
224                               printf("  PCI Mem free %d %08x to %08x\n",
225                                   i, mem[i], MAP_TOP(mspcic_pci_memmap[i]) - 1);
226                     else
227                               printf("  PCI %d Mem full %08x to %08x\n",
228                                   i, mspcic_pci_memmap[i].sysbase,
229                                   MAP_TOP(mspcic_pci_memmap[i]) - 1);
230 #endif
231 
232           node = OF_child(root);
233           /*
234            * Scan our known PCI devices and fix up any buses that
235            * the firmware didn't configure.
236            */
237           while(node) {
238                     int next, k;
239 
240                     /* Next node, or parent's next node (if we descended) */
241                     if (OF_peer(node))
242                               next = OF_peer(node);
243                     else if (OF_parent(node) != root) {
244                               next = OF_parent(node);
245                               next = OF_peer(node);
246                     } else
247                               next = 0;
248 
249                     len = OF_getproplen(node, "class-code");
250                     if (!len) {
251                               node = next;
252                               continue;
253                     }
254                     OF_getprop(node, "class-code", &class, len);
255                     if (!IS_PCI_BRIDGE(class)) {
256                               node = next;
257                               continue;
258                     }
259                     len = OF_getproplen(node, "reg");
260                     if (len < sizeof(reg))
261                               continue;
262                     if (OF_getprop(node, "reg", (void *)&reg, sizeof(reg)) != len)
263                               panic("pci_probe_bus: OF_getprop len botch");
264                     bus = OFW_PCI_PHYS_HI_BUS(reg.phys_hi);
265                     dev = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi);
266                     fun = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi);
267                     tag = PCITAG_CREATE(node, bus, dev, fun);
268 
269                     /*
270                      * Find ranges with largest free space
271                      * Round up start to 12 bit (io) and 20 bit (mem) multiples
272                      * because bridge base/limit registers have that granularity.
273                      */
274                     i = 0;
275                     j = 0;
276                     for (k = 1; k < IOMAP_SIZE; k++) {
277                               io[k] = RND_IO_START(io[k], 0xf000);
278                               if (MAP_TOP(mspcic_pci_iomap[k]) - io[k] >
279                                   MAP_TOP(mspcic_pci_iomap[i]) - io[i])
280                                         i = k;
281                     }
282                     for (k = 1; k < MEMMAP_SIZE; k++) {
283                               mem[k] = RND_MEM_START(mem[k], 0xfff00000);
284                               if (MAP_TOP(mspcic_pci_memmap[k]) - mem[k] >
285                                   MAP_TOP(mspcic_pci_memmap[j]) - mem[j])
286                                         j = k;
287                     }
288                     mspcic_pci_fixup(1, tag, &maxbus, &io[i], &mem[j],
289                         MAP_TOP(mspcic_pci_iomap[i]),
290                         MAP_TOP(mspcic_pci_memmap[j]));
291                     node = next;
292           }
293 }
294 
295 static void
mspcic_pci_fixup(int depth,pcitag_t starttag,int * maxbus,uint32_t * io,uint32_t * mem,uint32_t iotop,uint32_t memtop)296 mspcic_pci_fixup(int depth, pcitag_t starttag, int *maxbus, uint32_t *io,
297           uint32_t *mem, uint32_t iotop, uint32_t memtop)
298 {
299           int i, j, startbus;
300           uint32_t startio, startmem;
301           pcitag_t tag;
302           pcireg_t val, size, start;
303 
304           startbus = *maxbus;
305           startio = *io;
306           startmem = *mem;
307 
308 #ifdef SPARC_PCI_FIXUP_DEBUG
309           printf("mspcic_pci_fixup start:\n");
310           printf("  bridge at (%d %d %d), depth %d\n", PCITAG_BUS(starttag),
311               PCITAG_DEV(starttag), PCITAG_FUN(starttag), depth);
312           printf("  start bus %d\n", startbus);
313           printf("  io free %08x to %08x\n", startio, iotop - 1);
314           printf("  mem free %08x to %08x\n", startmem, memtop - 1);
315 #endif
316 
317           pci_conf_write(NULL, starttag, PCI_COMMAND_STATUS_REG,
318               PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE
319               | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_PARITY_ENABLE);
320           pci_conf_write(NULL, starttag, PCI_BRIDGE_CONTROL_REG, 0);
321 
322           /* Secondary bus = startbus, subordinate bus = 0xff */
323           pci_conf_write(NULL, starttag, PCI_BRIDGE_BUS_REG,
324               __SHIFTIN(startbus & 0xff,  PCI_BRIDGE_BUS_SECONDARY) |
325               __SHIFTIN(0xff, PCI_BRIDGE_BUS_SUBORDINATE));
326 
327           /*
328            * Fix up bus numbering, bus addresses, device addresses,
329            * interrupts and fast back-to-back capabilities.
330            */
331           for (i = 0; i < MAX_DEVFUN; i++) {
332                     tag = PCITAG_CREATE(0, startbus, i / 8, i % 8);
333                     /* Enable all the different spaces for this device */
334                     pci_conf_write(NULL, tag, PCI_COMMAND_STATUS_REG,
335                         PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE
336                         | PCI_COMMAND_IO_ENABLE | PCI_COMMAND_PARITY_ENABLE);
337                     val = pci_conf_read(NULL, tag, PCI_ID_REG);
338                     if (PCI_VENDOR(val) == PCI_VENDOR_INVALID) {
339                               i = DF_NEXTDEV(i);
340                               continue;
341                     }
342 #ifdef SPARC_PCI_FIXUP_DEBUG
343                     printf("> Found %04x:%04x at (%d %d %d)\n", PCI_VENDOR(val),
344                         PCI_PRODUCT(val), startbus, i / 8, i % 8);
345 #endif
346 
347                     /* Check interrupt pin(s), and write depth to line */
348                     val = pci_conf_read(NULL, tag, PCI_INTERRUPT_REG);
349                     if (PCI_INTERRUPT_PIN(val)) {
350                               val = (val & ~(PCI_INTERRUPT_LINE_MASK <<
351                                   PCI_INTERRUPT_LINE_SHIFT)) | depth;
352                               pci_conf_write(NULL, tag, PCI_INTERRUPT_REG, val);
353                     }
354 
355                     /* Check device type */
356                     val = pci_conf_read(NULL, tag, PCI_CLASS_REG);
357                     if (IS_PCI_BRIDGE(val)) {
358                               (*maxbus)++;
359                               if (*maxbus > 255)
360                                         panic("mspcic_pci_fixup: maxbus > 255");
361                               mspcic_pci_fixup(depth + 1, tag, maxbus, io, mem,
362                                   iotop, memtop);
363                     }
364 
365                     pci_conf_write(NULL, tag, PCI_MAPREG_ROM, (pcireg_t) ~0x0);
366                     val = pci_conf_read(NULL, tag, PCI_MAPREG_ROM);
367                     if (val) {
368                               size = PCI_MAPREG_MEM_SIZE(val);
369                               start = RND_MEM_START(*mem, val);
370                               if (start + size <= memtop) {
371                                         *mem = start + size;
372                                         pci_conf_write(NULL, tag, PCI_MAPREG_ROM,
373                                             start);
374 #ifdef SPARC_PCI_FIXUP_DEBUG
375                                         printf("> ROM: %08x to %08x mask %08x\n",
376                                             start, (*mem) - 1, val);
377 #endif
378                               }
379                     }
380 
381                     val = pci_conf_read(NULL, tag, PCI_BHLC_REG);
382                     /* Check for multifunction devices and for BAR's  */
383                     if (!PCI_HDRTYPE_MULTIFN(val))
384                               i = DF_NEXTDEV(i);
385                     if (PCI_HDRTYPE_TYPE(val))
386                               continue;
387 
388                     /*
389                      * Read BAR's:
390                      *   write 0xffffffff and read back the size mask
391                      *   set the base address
392                      */
393                     for (j = 0; j < 6; j++) {
394                               pci_conf_write(NULL, tag, PCI_BAR(j),
395                                   (pcireg_t) ~0x0);
396                               val = pci_conf_read(NULL, tag, PCI_BAR(j));
397                               if (!val)
398                                         continue;
399                               if (PCI_MAPREG_TYPE(val) ==
400                                   PCI_MAPREG_TYPE_IO) {
401                                         size = PCI_MAPREG_IO_SIZE(val);
402                                         start = RND_IO_START(*io, val);
403                                         if (start + size <= iotop) {
404                                                   *io = start + size;
405                                                   pci_conf_write(NULL, tag, PCI_BAR(j),
406                                                       start);
407 #ifdef SPARC_PCI_FIXUP_DEBUG
408                                                   printf("> BAR %02x set: %08x to %08x "
409                                                       "mask %08x (io)\n", PCI_BAR(j),
410                                                       start, (*io) - 1, val);
411 #endif
412                                         } else {
413                                                   pci_conf_write(NULL, tag,
414                                                       PCI_COMMAND_STATUS_REG, 0);
415                                                   printf("Fixup failed for (%d %d %d)\n",
416                                                       startbus, i / 8, i % 8);
417                                         }
418                               } else {  /* PCI_MAPREG_TYPE_MEM */
419                                         size = PCI_MAPREG_MEM_SIZE(val);
420                                         start = RND_MEM_START(*mem, val);
421                                         if (start + size <= memtop) {
422                                                   *mem = start + size;
423                                                   pci_conf_write(NULL, tag, PCI_BAR(j),
424                                                       start);
425 #ifdef SPARC_PCI_FIXUP_DEBUG
426                                                   printf("> BAR %02x set: %08x to %08x "
427                                                       "mask %08x (mem)\n", PCI_BAR(j),
428                                                       start, (*mem) - 1, val);
429 #endif
430                                         } else {
431                                                   pci_conf_write(NULL, tag,
432                                                       PCI_COMMAND_STATUS_REG, 0);
433                                                   printf("Fixup failed for (%d %d %d)\n",
434                                                       startbus, i / 8, i % 8);
435                                         }
436                               }
437                     }
438           }
439 
440           /* Secondary bus = startbus, subordinate bus = maxbus */
441           pci_conf_write(NULL, starttag, PCI_BRIDGE_BUS_REG,
442               __SHIFTIN(startbus & 0xff,  PCI_BRIDGE_BUS_SECONDARY) |
443               __SHIFTIN(*maxbus & 0xff, PCI_BRIDGE_BUS_SUBORDINATE));
444 
445           /* 16-bit I/O range */
446           val = ((startio & 0xf000) >> 8) | ((*(io) - 1) & 0xf000);
447           pci_conf_write(NULL, starttag, PCI_BRIDGE_STATIO_REG, val);
448 #ifdef SPARC_PCI_FIXUP_DEBUG
449           printf("16-bit I/O range = %04x\n",
450               pci_conf_read(NULL, starttag, PCI_BRIDGE_STATIO_REG) & 0xffff);
451 #endif
452 
453           /* Mem range and (disabled) prefetch mem range */
454           val = ((startmem & 0xfff00000) >> 16) |
455               ((*(mem) - 1) & 0xfff00000);
456           pci_conf_write(NULL, starttag, PCI_BRIDGE_MEMORY_REG, val);
457           pci_conf_write(NULL, starttag, PCI_BRIDGE_PREFETCHMEM_REG, 0x0000ffff);
458 #ifdef SPARC_PCI_FIXUP_DEBUG
459           printf("Mem range = %08x\n",
460               pci_conf_read(NULL, starttag, PCI_BRIDGE_MEMORY_REG));
461           printf("Pref mem range = %08x\n",
462               pci_conf_read(NULL, starttag, PCI_BRIDGE_PREFETCHMEM_REG));
463 #endif
464 
465           /* 32-bit I/O range (if supported) */
466           val = pci_conf_read(NULL, starttag, PCI_BRIDGE_STATIO_REG);
467           if ((val & 0x0101) == 0x0101) {
468                     val = ((startio & 0xffff0000) >> 16) |
469                         ((*(io) - 1) & 0xffff0000);
470                     pci_conf_write(NULL, starttag, PCI_BRIDGE_IOHIGH_REG, val);
471           }
472 #ifdef SPARC_PCI_FIXUP_DEBUG
473           printf("32-bit I/O range = %08x\n",
474               pci_conf_read(NULL, starttag, PCI_BRIDGE_IOHIGH_REG));
475 #endif
476 
477           /* 64-bit prefetchable range (if supported) - set it to 0 */
478           val = pci_conf_read(NULL, starttag, PCI_BRIDGE_PREFETCHMEM_REG);
479           if (val & 0x01) {
480                     pci_conf_write(NULL, starttag,
481                         PCI_BRIDGE_PREFETCHBASEUP32_REG, (pcireg_t) ~0);
482                     pci_conf_write(NULL, starttag,
483                         PCI_BRIDGE_PREFETCHLIMITUP32_REG, (pcireg_t) 0);
484           }
485 
486 #ifdef SPARC_PCI_FIXUP_DEBUG
487           printf("mspcic_pci_fixup finish:\n");
488           printf("  bridge at (%d %d %d), depth %d\n", PCITAG_BUS(starttag),
489               PCITAG_DEV(starttag), PCITAG_FUN(starttag), depth);
490           printf("  bus range %d to %d\n", startbus, *maxbus);
491           printf("  io used %08x to %08x\n", startio, *(io) - 1);
492           printf("  mem used %08x to %08x\n", startmem, *(mem) - 1);
493 #endif
494 }
495 
496 /* ======================================================================
497  *
498  *                            PCI device fixup for autoconf
499  */
500 
501 void
set_pci_props(device_t dev)502 set_pci_props(device_t dev)
503 {
504           struct idprom *idp;
505           uint8_t eaddr[ETHER_ADDR_LEN];
506           prop_dictionary_t dict;
507           prop_data_t blob;
508 
509           /*
510            * We only handle network devices.
511            * XXX: We have to set the ethernet address for HME cards here.  If
512            * we leave this to the driver attachment, we will crash when trying
513            * to map the 16MB Ebus device in if_hme_pci.c.
514            */
515           if (!(device_is_a(dev, "le") || device_is_a(dev, "hme") ||
516              device_is_a(dev, "be") || device_is_a(dev, "ie")))
517                     return;
518 
519           idp = prom_getidprom();
520           memcpy(eaddr, idp->idp_etheraddr, 6);
521           dict = device_properties(dev);
522           blob = prop_data_create_data(eaddr, ETHER_ADDR_LEN);
523           prop_dictionary_set(dict, "mac-address", blob);
524           prop_object_release(blob);
525 }
526