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