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