Home | History | Annotate | Line # | Download | only in armadaxp
armadaxp_machdep.c revision 1.1
      1 /*******************************************************************************
      2 Copyright (C) Marvell International Ltd. and its affiliates
      3 
      4 Developed by Semihalf
      5 
      6 ********************************************************************************
      7 Marvell BSD License
      8 
      9 If you received this File from Marvell, you may opt to use, redistribute and/or
     10 modify this File under the following licensing terms.
     11 Redistribution and use in source and binary forms, with or without modification,
     12 are permitted provided that the following conditions are met:
     13 
     14     *   Redistributions of source code must retain the above copyright notice,
     15             this list of conditions and the following disclaimer.
     16 
     17     *   Redistributions in binary form must reproduce the above copyright
     18         notice, this list of conditions and the following disclaimer in the
     19         documentation and/or other materials provided with the distribution.
     20 
     21     *   Neither the name of Marvell nor the names of its contributors may be
     22         used to endorse or promote products derived from this software without
     23         specific prior written permission.
     24 
     25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     26 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     28 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     29 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     30 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     32 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     34 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35 
     36 *******************************************************************************/
     37 
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: armadaxp_machdep.c,v 1.1 2013/05/29 19:55:56 rkujawa Exp $");
     40 
     41 #include "opt_machdep.h"
     42 #include "opt_mvsoc.h"
     43 #include "opt_evbarm_boardtype.h"
     44 #include "opt_com.h"
     45 #include "opt_ddb.h"
     46 #include "opt_kgdb.h"
     47 #include "opt_pci.h"
     48 #include "opt_ipkdb.h"
     49 
     50 #include <sys/bus.h>
     51 #include <sys/param.h>
     52 #include <sys/device.h>
     53 #include <sys/systm.h>
     54 #include <sys/kernel.h>
     55 #include <sys/exec.h>
     56 #include <sys/proc.h>
     57 #include <sys/msgbuf.h>
     58 #include <sys/reboot.h>
     59 #include <sys/termios.h>
     60 #include <sys/ksyms.h>
     61 
     62 #include <uvm/uvm_extern.h>
     63 
     64 #include <sys/conf.h>
     65 #include <dev/cons.h>
     66 #include <dev/md.h>
     67 
     68 #include <dev/pci/pcireg.h>
     69 #include <dev/pci/pcivar.h>
     70 #include <machine/pci_machdep.h>
     71 
     72 #include <machine/db_machdep.h>
     73 #include <ddb/db_sym.h>
     74 #include <ddb/db_extern.h>
     75 #ifdef KGDB
     76 #include <sys/kgdb.h>
     77 #endif
     78 
     79 #include <machine/bootconfig.h>
     80 #include <machine/autoconf.h>
     81 #include <machine/cpu.h>
     82 #include <machine/frame.h>
     83 #include <arm/armreg.h>
     84 #include <arm/undefined.h>
     85 
     86 #include <arm/arm32/machdep.h>
     87 
     88 #include <arm/marvell/mvsocreg.h>
     89 #include <arm/marvell/mvsocvar.h>
     90 #include <evbarm/armadaxp/armadaxpreg.h>
     91 
     92 #include <evbarm/marvell/marvellreg.h>
     93 #include <evbarm/marvell/marvellvar.h>
     94 
     95 #include "mvpex.h"
     96 #include "com.h"
     97 #if NCOM > 0
     98 #include <dev/ic/comreg.h>
     99 #include <dev/ic/comvar.h>
    100 #endif
    101 
    102 /*
    103  * Address to call from cpu_reset() to reset the machine.
    104  * This is machine architecture dependent as it varies depending
    105  * on where the ROM appears when you turn the MMU off.
    106  */
    107 
    108 
    109 /* Define various stack sizes in pages */
    110 #define IRQ_STACK_SIZE	1
    111 #define ABT_STACK_SIZE	1
    112 #ifdef IPKDB
    113 #define UND_STACK_SIZE	2
    114 #else
    115 #define UND_STACK_SIZE	1
    116 #endif
    117 
    118 BootConfig bootconfig;		/* Boot config storage */
    119 char *boot_args = NULL;
    120 char *boot_file = NULL;
    121 
    122 extern int KERNEL_BASE_phys[];
    123 
    124 /*extern char KERNEL_BASE_phys[];*/
    125 extern char etext[], __data_start[], _edata[], __bss_start[], __bss_end__[];
    126 extern char _end[];
    127 
    128 /*
    129  * Put some bogus settings of the MEMSTART and MEMSIZE
    130  * if they are not defined in kernel configuration file.
    131  */
    132 #ifndef MEMSTART
    133 #define MEMSTART 0x00000000UL
    134 #endif
    135 #ifndef MEMSIZE
    136 #define MEMSIZE 0x40000000UL
    137 #endif
    138 
    139 #ifndef STARTUP_PAGETABLE_ADDR
    140 #define	STARTUP_PAGETABLE_ADDR 0x00000000UL
    141 #endif
    142 
    143 /* Physical offset of the kernel from MEMSTART */
    144 #define KERNEL_OFFSET		(paddr_t)&KERNEL_BASE_phys
    145 /* Kernel base virtual address */
    146 #define	KERNEL_TEXT_BASE	(KERNEL_BASE + KERNEL_OFFSET)
    147 
    148 #define	KERNEL_VM_BASE		(KERNEL_BASE + 0x01000000)
    149 #define KERNEL_VM_SIZE		0x10000000
    150 
    151 /* Prototypes */
    152 extern int armadaxp_l2_init(void);
    153 extern void armadaxp_io_coherency_init(void);
    154 
    155 void consinit(void);
    156 #ifdef KGDB
    157 static void kgdb_port_init(void);
    158 #endif
    159 
    160 static void axp_device_register(device_t dev, void *aux);
    161 
    162 static void
    163 axp_system_reset(void)
    164 {
    165 	cpu_reset_address = 0;
    166 
    167 	/* Unmask soft reset */
    168 	write_miscreg(MVSOC_MLMB_RSTOUTNMASKR,
    169 	    MVSOC_MLMB_RSTOUTNMASKR_SOFTRSTOUTEN);
    170 	/* Assert soft reset */
    171 	write_miscreg(MVSOC_MLMB_SSRR, MVSOC_MLMB_SSRR_SYSTEMSOFTRST);
    172 
    173 	while (1);
    174 }
    175 
    176 /*
    177  * Static device mappings. These peripheral registers are mapped at
    178  * fixed virtual addresses very early in initarm() so that we can use
    179  * them while booting the kernel, and stay at the same address
    180  * throughout whole kernel's life time.
    181  *
    182  * We use this table twice; once with bootstrap page table, and once
    183  * with kernel's page table which we build up in initarm().
    184  *
    185  * Since we map these registers into the bootstrap page table using
    186  * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
    187  * registers segment-aligned and segment-rounded in order to avoid
    188  * using the 2nd page tables.
    189  */
    190 
    191 #define	_A(a)	((a) & ~L1_S_OFFSET)
    192 #define	_S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
    193 
    194 static const struct pmap_devmap devmap[] = {
    195 	{
    196 		/* Internal registers */
    197 		.pd_va = _A(MARVELL_INTERREGS_VBASE),
    198 		.pd_pa = _A(MARVELL_INTERREGS_PBASE),
    199 		.pd_size = _S(MARVELL_INTERREGS_SIZE),
    200 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    201 		.pd_cache = PTE_NOCACHE
    202 	},
    203 	{0, 0, 0, 0, 0}
    204 };
    205 
    206 #undef	_A
    207 #undef	_S
    208 
    209 static inline
    210 pd_entry_t *
    211 read_ttb(void)
    212 {
    213 	long ttb;
    214 
    215 	__asm volatile("mrc	p15, 0, %0, c2, c0, 0" : "=r" (ttb));
    216 
    217 	return (pd_entry_t *)(ttb & ~((1<<14)-1));
    218 }
    219 
    220 static int
    221 axp_pcie_free_win(void)
    222 {
    223 	int i;
    224 	/* Find first disabled window */
    225 	for (i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
    226 		if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
    227 		    MVSOC_MLMB_WCR_WINEN) == 0) {
    228 			return i;
    229 		}
    230 	}
    231 	/* If there is no free window, return erroneous value */
    232 	return (-1);
    233 }
    234 
    235 static void
    236 reset_axp_pcie_win(void)
    237 {
    238 	uint32_t target, attr;
    239 	int memtag = 0, iotag = 0, window, i;
    240 	uint32_t membase;
    241 	uint32_t iobase;
    242 	uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
    243 			    ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
    244 			    ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
    245 			    ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
    246 			    ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
    247 			    ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO};
    248 
    249 	nwindow = ARMADAXP_MLMB_NWINDOW;
    250 	nremap = ARMADAXP_MLMB_NREMAP;
    251 	membase = MARVELL_PEXMEM_PBASE;
    252 	iobase = MARVELL_PEXIO_PBASE;
    253 	for (i = 0; i < __arraycount(tags) / 2; i++) {
    254 		memtag = tags[2 * i];
    255 		iotag = tags[(2 * i) + 1];
    256 
    257 		/* Reset PCI-Express space to window register. */
    258 		window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
    259 
    260 		/* Find free window if we've got spurious one */
    261 		if (window >= nwindow) {
    262 			window = axp_pcie_free_win();
    263 			/* Just break if there is no free windows left */
    264 			if (window < 0) {
    265 				aprint_error(": no free windows for PEX MEM\n");
    266 				break;
    267 			}
    268 		}
    269 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    270 		    MVSOC_MLMB_WCR_WINEN |
    271 		    MVSOC_MLMB_WCR_TARGET(target) |
    272 		    MVSOC_MLMB_WCR_ATTR(attr) |
    273 		    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
    274 		write_mlmbreg(MVSOC_MLMB_WBR(window),
    275 		    membase & MVSOC_MLMB_WBR_BASE_MASK);
    276 #ifdef PCI_NETBSD_CONFIGURE
    277 		if (window < nremap) {
    278 			write_mlmbreg(MVSOC_MLMB_WRLR(window),
    279 			    membase & MVSOC_MLMB_WRLR_REMAP_MASK);
    280 			write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    281 		}
    282 #endif
    283 		window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
    284 
    285 		/* Find free window if we've got spurious one */
    286 		if (window >= nwindow) {
    287 			window = axp_pcie_free_win();
    288 			/* Just break if there is no free windows left */
    289 			if (window < 0) {
    290 				aprint_error(": no free windows for PEX I/O\n");
    291 				break;
    292 			}
    293 		}
    294 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    295 		    MVSOC_MLMB_WCR_WINEN |
    296 		    MVSOC_MLMB_WCR_TARGET(target) |
    297 		    MVSOC_MLMB_WCR_ATTR(attr) |
    298 		    MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
    299 		write_mlmbreg(MVSOC_MLMB_WBR(window),
    300 		    iobase & MVSOC_MLMB_WBR_BASE_MASK);
    301 #ifdef PCI_NETBSD_CONFIGURE
    302 		if (window < nremap) {
    303 			write_mlmbreg(MVSOC_MLMB_WRLR(window),
    304 			    iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
    305 			write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    306 		}
    307 #endif
    308 		membase += MARVELL_PEXMEM_SIZE;
    309 		iobase += MARVELL_PEXIO_SIZE;
    310 	}
    311 }
    312 
    313 /*
    314  * u_int initarm(...)
    315  *
    316  * Initial entry point on startup. This gets called before main() is
    317  * entered.
    318  * It should be responsible for setting up everything that must be
    319  * in place when main is called.
    320  * This includes
    321  *   Taking a copy of the boot configuration structure.
    322  *   Initialising the physical console so characters can be printed.
    323  *   Setting up page tables for the kernel
    324  *   Relocating the kernel to the bottom of physical memory
    325  */
    326 u_int
    327 initarm(void *arg)
    328 {
    329 	cpu_reset_address = axp_system_reset;
    330 
    331 	mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
    332 
    333 	/* Set CPU functions */
    334 	if (set_cpufuncs())
    335 		panic("cpu not recognized!");
    336 
    337 	/*
    338 	 * Map devices into the initial page table
    339 	 * in order to use early console during initialization process.
    340 	 * consinit is going to use this mapping.
    341 	 */
    342 	pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
    343 
    344 	/* Initialize system console */
    345 	consinit();
    346 
    347 	/* Reset PCI-Express space to window register. */
    348 	reset_axp_pcie_win();
    349 
    350 	/* Get CPU, system and timebase frequencies */
    351 	armadaxp_getclks();
    352 
    353 	/* Preconfigure interrupts */
    354 	armadaxp_intr_bootstrap();
    355 
    356 #ifdef L2CACHE_ENABLE
    357 	/* Initialize L2 Cache */
    358 	(void)armadaxp_l2_init();
    359 #endif
    360 
    361 #ifdef AURORA_IO_CACHE_COHERENCY
    362 	/* Initialize cache coherency */
    363 	armadaxp_io_coherency_init();
    364 #endif
    365 
    366 #ifdef KGDB
    367 	kgdb_port_init();
    368 #endif
    369 
    370 #ifdef VERBOSE_INIT_ARM
    371 	/* Talk to the user */
    372 #define	BDSTR(s)	_BDSTR(s)
    373 #define	_BDSTR(s)	#s
    374 	printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
    375 #endif
    376 
    377 
    378 #ifdef VERBOSE_INIT_ARM
    379 	printf("initarm: Configuring system ...\n");
    380 #endif
    381 	/* Fake bootconfig structure for the benefit of pmap.c. */
    382 	bootconfig.dramblocks = 1;
    383 	bootconfig.dram[0].address = MEMSTART;
    384 	bootconfig.dram[0].pages = MEMSIZE / PAGE_SIZE;
    385 
    386         physical_start = bootconfig.dram[0].address;
    387         physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
    388 
    389 	arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
    390 	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
    391 	    devmap, false);
    392 
    393 	/* we've a specific device_register routine */
    394 	evbarm_device_register = axp_device_register;
    395 
    396 	return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
    397 }
    398 
    399 #ifndef CONSADDR
    400 #error Specify the address of the UART with the CONSADDR option.
    401 #endif
    402 #ifndef CONSPEED
    403 #define	CONSPEED B115200
    404 #endif
    405 #ifndef CONMODE
    406 #define	CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    407 #endif
    408 #ifndef CONSFREQ
    409 #define	CONSFREQ 250000000
    410 #endif
    411 static const int	comcnspeed = CONSPEED;
    412 static const int	comcnfreq  = CONSFREQ;
    413 static const tcflag_t	comcnmode  = CONMODE;
    414 static const bus_addr_t	comcnaddr  = (bus_addr_t)CONSADDR;
    415 
    416 void
    417 consinit(void)
    418 {
    419 	static bool consinit_called = false;
    420 
    421 	if (consinit_called)
    422 		return;
    423 	consinit_called = true;
    424 
    425 #if NCOM > 0
    426 	extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
    427 	    uint32_t, int);
    428 
    429 	if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
    430 			comcnfreq, comcnmode))
    431 		panic("Serial console can not be initialized.");
    432 #endif
    433 }
    434 
    435 #ifdef KGDB
    436 #ifndef KGDB_DEVADDR
    437 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
    438 #endif
    439 #ifndef KGDB_DEVRATE
    440 #define KGDB_DEVRATE B115200
    441 #endif
    442 #define MVUART_SIZE 0x20
    443 
    444 #ifndef KGDB_DEVMODE
    445 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    446 #endif
    447 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
    448 static const int comkgdbspeed = KGDB_DEVRATE;
    449 static const int comkgdbmode = KGDB_DEVMODE;
    450 
    451 void
    452 static kgdb_port_init(void)
    453 {
    454 	static int kgdbsinit_called = 0;
    455 
    456 	if (kgdbsinit_called != 0)
    457 		return;
    458 	kgdbsinit_called = 1;
    459 
    460 	if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
    461 			MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
    462 		panic("KGDB uart can not be initialized.");
    463 }
    464 #endif
    465 
    466 #if NMVPEX > 0
    467 static void
    468 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
    469 {
    470 
    471 	uint32_t base, size;
    472 	int win;
    473 
    474 	win = mvsoc_target(tag, NULL, NULL, &base, &size);
    475 	if (size != 0) {
    476 		if (win < nremap)
    477 			*start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
    478 			    ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
    479 		else
    480 			*start = base;
    481 		*end = *start + size - 1;
    482 	} else
    483 		*start = *end = 0;
    484 }
    485 #endif
    486 
    487 static void
    488 axp_device_register(device_t dev, void *aux)
    489 {
    490 	prop_dictionary_t dict = device_properties(dev);
    491 
    492 #if NCOM > 0
    493 	if (device_is_a(dev, "com") &&
    494 	    device_is_a(device_parent(dev), "mvsoc"))
    495 		prop_dictionary_set_uint32(dict, "frequency", mvTclk);
    496 #endif
    497 
    498 #if NMVPEX > 0
    499 	extern struct bus_space
    500 	    armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
    501 	    armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
    502 	    armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
    503 	    armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
    504 	    armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
    505 	    armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
    506 	extern struct arm32_pci_chipset arm32_mvpex0_chipset,
    507 	    arm32_mvpex1_chipset, arm32_mvpex2_chipset,
    508 	    arm32_mvpex3_chipset, arm32_mvpex4_chipset,
    509 	    arm32_mvpex5_chipset;
    510 
    511 	struct marvell_attach_args *mva = aux;
    512 
    513 	if (device_is_a(dev, "mvpex")) {
    514 		struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
    515 		struct arm32_pci_chipset *arm32_mvpex_chipset;
    516 		prop_data_t io_bs_tag, mem_bs_tag, pc;
    517 		uint64_t start, end;
    518 		int iotag, memtag;
    519 
    520 		if (mva->mva_offset == MVSOC_PEX_BASE) {
    521 			mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
    522 			mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
    523 			arm32_mvpex_chipset = &arm32_mvpex0_chipset;
    524 			iotag = ARMADAXP_TAG_PEX00_IO;
    525 			memtag = ARMADAXP_TAG_PEX00_MEM;
    526 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x4000) {
    527 			mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
    528 			mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
    529 			arm32_mvpex_chipset = &arm32_mvpex1_chipset;
    530 			iotag = ARMADAXP_TAG_PEX01_IO;
    531 			memtag = ARMADAXP_TAG_PEX01_MEM;
    532 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x8000) {
    533 			mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
    534 			mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
    535 			arm32_mvpex_chipset = &arm32_mvpex2_chipset;
    536 			iotag = ARMADAXP_TAG_PEX02_IO;
    537 			memtag = ARMADAXP_TAG_PEX02_MEM;
    538 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0xc000) {
    539 			mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
    540 			mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
    541 			arm32_mvpex_chipset = &arm32_mvpex3_chipset;
    542 			iotag = ARMADAXP_TAG_PEX03_IO;
    543 			memtag = ARMADAXP_TAG_PEX03_MEM;
    544 		} else if (mva->mva_offset == MVSOC_PEX_BASE + 0x2000) {
    545 			mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
    546 			mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
    547 			arm32_mvpex_chipset = &arm32_mvpex4_chipset;
    548 			iotag = ARMADAXP_TAG_PEX2_IO;
    549 			memtag = ARMADAXP_TAG_PEX2_MEM;
    550 		} else {
    551 			mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
    552 			mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
    553 			arm32_mvpex_chipset = &arm32_mvpex5_chipset;
    554 			iotag = ARMADAXP_TAG_PEX3_IO;
    555 			memtag = ARMADAXP_TAG_PEX3_MEM;
    556 		}
    557 
    558 		arm32_mvpex_chipset->pc_conf_v = device_private(dev);
    559 		arm32_mvpex_chipset->pc_intr_v = device_private(dev);
    560 
    561 		io_bs_tag = prop_data_create_data_nocopy(
    562 		    mvpex_io_bs_tag, sizeof(struct bus_space));
    563 		KASSERT(io_bs_tag != NULL);
    564 		prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
    565 		prop_object_release(io_bs_tag);
    566 		mem_bs_tag = prop_data_create_data_nocopy(
    567 		    mvpex_mem_bs_tag, sizeof(struct bus_space));
    568 		KASSERT(mem_bs_tag != NULL);
    569 		prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
    570 		prop_object_release(mem_bs_tag);
    571 
    572 		pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
    573 		    sizeof(struct arm32_pci_chipset));
    574 		KASSERT(pc != NULL);
    575 		prop_dictionary_set(dict, "pci-chipset", pc);
    576 		prop_object_release(pc);
    577 
    578 		marvell_startend_by_tag(iotag, &start, &end);
    579 		prop_dictionary_set_uint64(dict, "iostart", start);
    580 		prop_dictionary_set_uint64(dict, "ioend", end);
    581 		marvell_startend_by_tag(memtag, &start, &end);
    582 		prop_dictionary_set_uint64(dict, "memstart", start);
    583 		prop_dictionary_set_uint64(dict, "memend", end);
    584 		prop_dictionary_set_uint32(dict,
    585 		    "cache-line-size", arm_dcache_align);
    586 	}
    587 #endif
    588 }
    589