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