1 /* $NetBSD: armadaxp_machdep.c,v 1.19 2023/04/21 15:04:47 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.19 2023/04/21 15:04:47 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
axp_system_reset(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 static const struct pmap_devmap devmap[] = {
191 DEVMAP_ENTRY(MARVELL_INTERREGS_VBASE,
192 MARVELL_INTERREGS_PBASE,
193 MVSOC_INTERREGS_SIZE),
194 DEVMAP_ENTRY_END
195 };
196
197 static inline pd_entry_t *
read_ttb(void)198 read_ttb(void)
199 {
200 return (pd_entry_t *)(armreg_ttbr_read() & ~((1<<14)-1));
201 }
202
203 static int
axp_pcie_free_win(void)204 axp_pcie_free_win(void)
205 {
206 /* Find first disabled window */
207 for (size_t i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
208 if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
209 MVSOC_MLMB_WCR_WINEN) == 0) {
210 return i;
211 }
212 }
213 /* If there is no free window, return erroneous value */
214 return (-1);
215 }
216
217 static void
reset_axp_pcie_win(void)218 reset_axp_pcie_win(void)
219 {
220 uint32_t target, attr;
221 int memtag = 0, iotag = 0, window, i;
222 uint32_t membase;
223 uint32_t iobase;
224 uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
225 ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
226 ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
227 ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
228 ARMADAXP_TAG_PEX10_MEM, ARMADAXP_TAG_PEX10_IO,
229 ARMADAXP_TAG_PEX11_MEM, ARMADAXP_TAG_PEX11_IO,
230 ARMADAXP_TAG_PEX12_MEM, ARMADAXP_TAG_PEX12_IO,
231 ARMADAXP_TAG_PEX13_MEM, ARMADAXP_TAG_PEX13_IO,
232 ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
233 ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO
234 };
235
236 nwindow = ARMADAXP_MLMB_NWINDOW;
237 nremap = ARMADAXP_MLMB_NREMAP;
238 membase = MARVELL_PEXMEM_PBASE;
239 iobase = MARVELL_PEXIO_PBASE;
240 for (i = 0; i < __arraycount(tags) / 2; i++) {
241 memtag = tags[2 * i];
242 iotag = tags[(2 * i) + 1];
243
244 /* Reset PCI-Express space to window register. */
245 window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
246
247 /* Find free window if we've got spurious one */
248 if (window >= nwindow) {
249 window = axp_pcie_free_win();
250 /* Just break if there is no free windows left */
251 if (window < 0) {
252 aprint_error(": no free windows for PEX MEM\n");
253 break;
254 }
255 }
256 write_mlmbreg(MVSOC_MLMB_WCR(window),
257 MVSOC_MLMB_WCR_WINEN |
258 MVSOC_MLMB_WCR_TARGET(target) |
259 MVSOC_MLMB_WCR_ATTR(attr) |
260 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
261 write_mlmbreg(MVSOC_MLMB_WBR(window),
262 membase & MVSOC_MLMB_WBR_BASE_MASK);
263 #ifdef PCI_NETBSD_CONFIGURE
264 if (window < nremap) {
265 write_mlmbreg(MVSOC_MLMB_WRLR(window),
266 membase & MVSOC_MLMB_WRLR_REMAP_MASK);
267 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
268 }
269 #endif
270 window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
271
272 /* Find free window if we've got spurious one */
273 if (window >= nwindow) {
274 window = axp_pcie_free_win();
275 /* Just break if there is no free windows left */
276 if (window < 0) {
277 aprint_error(": no free windows for PEX I/O\n");
278 break;
279 }
280 }
281 write_mlmbreg(MVSOC_MLMB_WCR(window),
282 MVSOC_MLMB_WCR_WINEN |
283 MVSOC_MLMB_WCR_TARGET(target) |
284 MVSOC_MLMB_WCR_ATTR(attr) |
285 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
286 write_mlmbreg(MVSOC_MLMB_WBR(window),
287 iobase & MVSOC_MLMB_WBR_BASE_MASK);
288 #ifdef PCI_NETBSD_CONFIGURE
289 if (window < nremap) {
290 write_mlmbreg(MVSOC_MLMB_WRLR(window),
291 iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
292 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
293 }
294 #endif
295 membase += MARVELL_PEXMEM_SIZE;
296 iobase += MARVELL_PEXIO_SIZE;
297 }
298 }
299
300 /*
301 * vaddr_t initarm(...)
302 *
303 * Initial entry point on startup. This gets called before main() is
304 * entered.
305 * It should be responsible for setting up everything that must be
306 * in place when main is called.
307 * This includes
308 * Taking a copy of the boot configuration structure.
309 * Initialising the physical console so characters can be printed.
310 * Setting up page tables for the kernel
311 * Relocating the kernel to the bottom of physical memory
312 */
313 vaddr_t
initarm(void * arg)314 initarm(void *arg)
315 {
316 cpu_reset_address = axp_system_reset;
317
318 mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
319
320 /* Set CPU functions */
321 if (set_cpufuncs())
322 panic("cpu not recognized!");
323
324 /*
325 * Map devices into the initial page table
326 * in order to use early console during initialization process.
327 * consinit is going to use this mapping.
328 */
329 pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
330
331 /* Initialize system console */
332 consinit();
333
334 /* Reset PCI-Express space to window register. */
335 reset_axp_pcie_win();
336
337 /* Get CPU, system and timebase frequencies */
338 armadaxp_bootstrap(
339 MARVELL_INTERREGS_VBASE,
340 MARVELL_INTERREGS_PBASE);
341
342 #ifdef KGDB
343 kgdb_port_init();
344 #endif
345
346 #ifdef VERBOSE_INIT_ARM
347 /* Talk to the user */
348 #define BDSTR(s) _BDSTR(s)
349 #define _BDSTR(s) #s
350 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
351 #endif
352
353 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
354 const bool mapallmem_p = true;
355 #else
356 const bool mapallmem_p = false;
357 #endif
358
359 #ifdef VERBOSE_INIT_ARM
360 printf("initarm: Configuring system ...\n");
361 #endif
362 psize_t memsize = MEMSIZE;
363 if (mapallmem_p && memsize > KERNEL_VM_BASE - KERNEL_BASE) {
364 printf("%s: dropping RAM size from %luMB to %uMB\n",
365 __func__, (unsigned long) (memsize >> 20),
366 (KERNEL_VM_BASE - KERNEL_BASE) >> 20);
367 memsize = KERNEL_VM_BASE - KERNEL_BASE;
368 }
369 /* Fake bootconfig structure for the benefit of pmap.c. */
370 bootconfig.dramblocks = 1;
371 bootconfig.dram[0].address = MEMSTART;
372 bootconfig.dram[0].pages = memsize / PAGE_SIZE;
373
374 physical_start = bootconfig.dram[0].address;
375 physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
376
377 arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
378 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
379 devmap, mapallmem_p);
380
381 /* we've a specific device_register routine */
382 evbarm_device_register = axp_device_register;
383
384 /* copy U-Boot args from U-Boot heap to kernel memory */
385 uboot_regs_va = (int *)((unsigned int)uboot_regs_pa + KERNEL_BASE);
386 boot_args = (char *)(uboot_regs_va[3] + KERNEL_BASE);
387 strlcpy(boot_argbuf, (char *)boot_args, sizeof(boot_argbuf));
388 boot_args = boot_argbuf;
389 parse_mi_bootargs(boot_args);
390
391 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
392 }
393
394 #ifndef CONSADDR
395 #error Specify the address of the UART with the CONSADDR option.
396 #endif
397 #ifndef CONSPEED
398 #define CONSPEED B115200
399 #endif
400 #ifndef CONMODE
401 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
402 #endif
403 #ifndef CONSFREQ
404 #define CONSFREQ 0
405 #endif
406 static const int comcnspeed = CONSPEED;
407 static const int comcnfreq = CONSFREQ;
408 static const tcflag_t comcnmode = CONMODE;
409 static const bus_addr_t comcnaddr = (bus_addr_t)CONSADDR;
410
411 void
consinit(void)412 consinit(void)
413 {
414 static bool consinit_called = false;
415
416 if (consinit_called)
417 return;
418 consinit_called = true;
419
420 #if NCOM > 0
421 extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
422 uint32_t, int);
423
424 if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
425 comcnfreq ? comcnfreq : mvTclk , comcnmode))
426 panic("Serial console can not be initialized.");
427 #endif
428 }
429
430 #ifdef KGDB
431 #ifndef KGDB_DEVADDR
432 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
433 #endif
434 #ifndef KGDB_DEVRATE
435 #define KGDB_DEVRATE B115200
436 #endif
437 #define MVUART_SIZE 0x20
438
439 #ifndef KGDB_DEVMODE
440 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
441 #endif
442 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
443 static const int comkgdbspeed = KGDB_DEVRATE;
444 static const int comkgdbmode = KGDB_DEVMODE;
445
446 void
kgdb_port_init(void)447 static kgdb_port_init(void)
448 {
449 static int kgdbsinit_called = 0;
450
451 if (kgdbsinit_called != 0)
452 return;
453 kgdbsinit_called = 1;
454
455 if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
456 MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
457 panic("KGDB uart can not be initialized.");
458 }
459 #endif
460
461 #if NMVPEX > 0
462 static void
marvell_startend_by_tag(int tag,uint64_t * start,uint64_t * end)463 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
464 {
465
466 uint32_t base, size;
467 int win;
468
469 win = mvsoc_target(tag, NULL, NULL, &base, &size);
470 if (size != 0) {
471 if (win < nremap)
472 *start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
473 ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
474 else
475 *start = base;
476 *end = *start + size - 1;
477 } else
478 *start = *end = 0;
479 }
480 #endif
481
482 static void
axp_device_register(device_t dev,void * aux)483 axp_device_register(device_t dev, void *aux)
484 {
485 prop_dictionary_t dict = device_properties(dev);
486
487 #if NCOM > 0
488 if (device_is_a(dev, "com") &&
489 device_is_a(device_parent(dev), "mvsoc"))
490 prop_dictionary_set_uint32(dict, "frequency", mvTclk);
491 #endif
492
493 #if NMVPEX > 0
494 extern struct bus_space
495 armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
496 armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
497 armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
498 armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
499 armadaxp_pex10_io_bs_tag, armadaxp_pex10_mem_bs_tag,
500 armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
501 armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
502 extern struct arm32_pci_chipset arm32_mvpex0_chipset,
503 arm32_mvpex1_chipset, arm32_mvpex2_chipset,
504 arm32_mvpex3_chipset, arm32_mvpex4_chipset,
505 arm32_mvpex5_chipset, arm32_mvpex6_chipset;
506
507 struct marvell_attach_args *mva = aux;
508
509 if (device_is_a(dev, "mvpex")) {
510 struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
511 struct arm32_pci_chipset *arm32_mvpex_chipset;
512 prop_data_t io_bs_tag, mem_bs_tag, pc;
513 uint64_t start, end;
514 int iotag, memtag;
515
516 if (mva->mva_offset == MVSOC_PEX_BASE) {
517 mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
518 mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
519 arm32_mvpex_chipset = &arm32_mvpex0_chipset;
520 iotag = ARMADAXP_TAG_PEX00_IO;
521 memtag = ARMADAXP_TAG_PEX00_MEM;
522 } else if (mva->mva_offset == ARMADAXP_PEX01_BASE) {
523 mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
524 mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
525 arm32_mvpex_chipset = &arm32_mvpex1_chipset;
526 iotag = ARMADAXP_TAG_PEX01_IO;
527 memtag = ARMADAXP_TAG_PEX01_MEM;
528 } else if (mva->mva_offset == ARMADAXP_PEX02_BASE) {
529 mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
530 mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
531 arm32_mvpex_chipset = &arm32_mvpex2_chipset;
532 iotag = ARMADAXP_TAG_PEX02_IO;
533 memtag = ARMADAXP_TAG_PEX02_MEM;
534 } else if (mva->mva_offset == ARMADAXP_PEX03_BASE) {
535 mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
536 mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
537 arm32_mvpex_chipset = &arm32_mvpex3_chipset;
538 iotag = ARMADAXP_TAG_PEX03_IO;
539 memtag = ARMADAXP_TAG_PEX03_MEM;
540 } else if (mva->mva_offset == ARMADAXP_PEX10_BASE) {
541 mvpex_io_bs_tag = &armadaxp_pex10_io_bs_tag;
542 mvpex_mem_bs_tag = &armadaxp_pex10_mem_bs_tag;
543 arm32_mvpex_chipset = &arm32_mvpex4_chipset;
544 iotag = ARMADAXP_TAG_PEX10_IO;
545 memtag = ARMADAXP_TAG_PEX10_MEM;
546 } else if (mva->mva_offset == ARMADAXP_PEX2_BASE) {
547 mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
548 mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
549 arm32_mvpex_chipset = &arm32_mvpex5_chipset;
550 iotag = ARMADAXP_TAG_PEX2_IO;
551 memtag = ARMADAXP_TAG_PEX2_MEM;
552 } else {
553 mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
554 mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
555 arm32_mvpex_chipset = &arm32_mvpex6_chipset;
556 iotag = ARMADAXP_TAG_PEX3_IO;
557 memtag = ARMADAXP_TAG_PEX3_MEM;
558 }
559
560 arm32_mvpex_chipset->pc_conf_v = device_private(dev);
561 arm32_mvpex_chipset->pc_intr_v = device_private(dev);
562
563 io_bs_tag = prop_data_create_data_nocopy(
564 mvpex_io_bs_tag, sizeof(struct bus_space));
565 KASSERT(io_bs_tag != NULL);
566 prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
567 prop_object_release(io_bs_tag);
568 mem_bs_tag = prop_data_create_data_nocopy(
569 mvpex_mem_bs_tag, sizeof(struct bus_space));
570 KASSERT(mem_bs_tag != NULL);
571 prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
572 prop_object_release(mem_bs_tag);
573
574 pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
575 sizeof(struct arm32_pci_chipset));
576 KASSERT(pc != NULL);
577 prop_dictionary_set(dict, "pci-chipset", pc);
578 prop_object_release(pc);
579
580 marvell_startend_by_tag(iotag, &start, &end);
581 prop_dictionary_set_uint64(dict, "iostart", start);
582 prop_dictionary_set_uint64(dict, "ioend", end);
583 marvell_startend_by_tag(memtag, &start, &end);
584 prop_dictionary_set_uint64(dict, "memstart", start);
585 prop_dictionary_set_uint64(dict, "memend", end);
586 prop_dictionary_set_uint32(dict,
587 "cache-line-size", arm_dcache_align);
588 }
589 if (device_is_a(dev, "mvgbec")) {
590 uint8_t enaddr[ETHER_ADDR_LEN];
591 char optname[9];
592 int unit = device_unit(dev);
593
594 if (unit > 9)
595 return;
596 switch (unit) {
597 case 0:
598 strlcpy(optname, "ethaddr", sizeof(optname));
599 break;
600 default:
601 /* eth1addr ... eth9addr */
602 snprintf(optname, sizeof(optname),
603 "eth%daddr", unit);
604 break;
605 }
606 if (get_bootconf_option(boot_args, optname,
607 BOOTOPT_TYPE_MACADDR, enaddr)) {
608 prop_data_t pd =
609 prop_data_create_data(enaddr, sizeof(enaddr));
610
611 prop_dictionary_set(dict, "mac-address", pd);
612 }
613 }
614 if (device_is_a(dev, "mvxpe")) {
615 uint8_t enaddr[ETHER_ADDR_LEN];
616 char optname[9];
617 int unit = device_unit(dev);
618
619 if (unit > 9)
620 return;
621 switch (unit) {
622 case 0:
623 strlcpy(optname, "ethaddr", sizeof(optname));
624 break;
625 default:
626 /* eth1addr ... eth9addr */
627 snprintf(optname, sizeof(optname),
628 "eth%daddr", unit);
629 break;
630 }
631 if (get_bootconf_option(boot_args, optname,
632 BOOTOPT_TYPE_MACADDR, enaddr)) {
633 prop_data_t pd =
634 prop_data_create_data(enaddr, sizeof(enaddr));
635
636 prop_dictionary_set(dict, "mac-address", pd);
637 }
638 }
639 #endif
640 }
641