Home | History | Annotate | Line # | Download | only in sparc
      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
     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
    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
    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