armadaxp_machdep.c revision 1.3 1 /* $NetBSD: armadaxp_machdep.c,v 1.3 2013/09/30 13:29:07 kiyohara 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.3 2013/09/30 13:29:07 kiyohara 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 #include "opt_ipkdb.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/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
96 #include "mvpex.h"
97 #include "com.h"
98 #if NCOM > 0
99 #include <dev/ic/comreg.h>
100 #include <dev/ic/comvar.h>
101 #endif
102
103 /*
104 * Address to call from cpu_reset() to reset the machine.
105 * This is machine architecture dependent as it varies depending
106 * on where the ROM appears when you turn the MMU off.
107 */
108
109
110 /* Define various stack sizes in pages */
111 #define IRQ_STACK_SIZE 1
112 #define ABT_STACK_SIZE 1
113 #ifdef IPKDB
114 #define UND_STACK_SIZE 2
115 #else
116 #define UND_STACK_SIZE 1
117 #endif
118
119 BootConfig bootconfig; /* Boot config storage */
120 char *boot_args = NULL;
121 char *boot_file = NULL;
122
123 extern int KERNEL_BASE_phys[];
124
125 /*extern char KERNEL_BASE_phys[];*/
126 extern char etext[], __data_start[], _edata[], __bss_start[], __bss_end__[];
127 extern char _end[];
128
129 /*
130 * Put some bogus settings of the MEMSTART and MEMSIZE
131 * if they are not defined in kernel configuration file.
132 */
133 #ifndef MEMSTART
134 #define MEMSTART 0x00000000UL
135 #endif
136 #ifndef MEMSIZE
137 #define MEMSIZE 0x40000000UL
138 #endif
139
140 #ifndef STARTUP_PAGETABLE_ADDR
141 #define STARTUP_PAGETABLE_ADDR 0x00000000UL
142 #endif
143
144 /* Physical offset of the kernel from MEMSTART */
145 #define KERNEL_OFFSET (paddr_t)&KERNEL_BASE_phys
146 /* Kernel base virtual address */
147 #define KERNEL_TEXT_BASE (KERNEL_BASE + KERNEL_OFFSET)
148
149 #define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000)
150 #define KERNEL_VM_SIZE 0x10000000
151
152 /* Prototypes */
153 extern int armadaxp_l2_init(bus_addr_t);
154 extern void armadaxp_io_coherency_init(void);
155
156 void consinit(void);
157 #ifdef KGDB
158 static void kgdb_port_init(void);
159 #endif
160
161 static void axp_device_register(device_t dev, void *aux);
162
163 static void
164 axp_system_reset(void)
165 {
166 cpu_reset_address = 0;
167
168 /* Unmask soft reset */
169 write_miscreg(MVSOC_MLMB_RSTOUTNMASKR,
170 MVSOC_MLMB_RSTOUTNMASKR_SOFTRSTOUTEN);
171 /* Assert soft reset */
172 write_miscreg(MVSOC_MLMB_SSRR, MVSOC_MLMB_SSRR_SYSTEMSOFTRST);
173
174 while (1);
175 }
176
177 /*
178 * Static device mappings. These peripheral registers are mapped at
179 * fixed virtual addresses very early in initarm() so that we can use
180 * them while booting the kernel, and stay at the same address
181 * throughout whole kernel's life time.
182 *
183 * We use this table twice; once with bootstrap page table, and once
184 * with kernel's page table which we build up in initarm().
185 *
186 * Since we map these registers into the bootstrap page table using
187 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
188 * registers segment-aligned and segment-rounded in order to avoid
189 * using the 2nd page tables.
190 */
191
192 #define _A(a) ((a) & ~L1_S_OFFSET)
193 #define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
194
195 static const struct pmap_devmap devmap[] = {
196 {
197 /* Internal registers */
198 .pd_va = _A(MARVELL_INTERREGS_VBASE),
199 .pd_pa = _A(MARVELL_INTERREGS_PBASE),
200 .pd_size = _S(MARVELL_INTERREGS_SIZE),
201 .pd_prot = VM_PROT_READ|VM_PROT_WRITE,
202 .pd_cache = PTE_NOCACHE
203 },
204 {0, 0, 0, 0, 0}
205 };
206
207 #undef _A
208 #undef _S
209
210 static inline
211 pd_entry_t *
212 read_ttb(void)
213 {
214 long ttb;
215
216 __asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb));
217
218 return (pd_entry_t *)(ttb & ~((1<<14)-1));
219 }
220
221 static int
222 axp_pcie_free_win(void)
223 {
224 int i;
225 /* Find first disabled window */
226 for (i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
227 if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
228 MVSOC_MLMB_WCR_WINEN) == 0) {
229 return i;
230 }
231 }
232 /* If there is no free window, return erroneous value */
233 return (-1);
234 }
235
236 static void
237 reset_axp_pcie_win(void)
238 {
239 uint32_t target, attr;
240 int memtag = 0, iotag = 0, window, i;
241 uint32_t membase;
242 uint32_t iobase;
243 uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
244 ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
245 ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
246 ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
247 ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
248 ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO};
249
250 nwindow = ARMADAXP_MLMB_NWINDOW;
251 nremap = ARMADAXP_MLMB_NREMAP;
252 membase = MARVELL_PEXMEM_PBASE;
253 iobase = MARVELL_PEXIO_PBASE;
254 for (i = 0; i < __arraycount(tags) / 2; i++) {
255 memtag = tags[2 * i];
256 iotag = tags[(2 * i) + 1];
257
258 /* Reset PCI-Express space to window register. */
259 window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
260
261 /* Find free window if we've got spurious one */
262 if (window >= nwindow) {
263 window = axp_pcie_free_win();
264 /* Just break if there is no free windows left */
265 if (window < 0) {
266 aprint_error(": no free windows for PEX MEM\n");
267 break;
268 }
269 }
270 write_mlmbreg(MVSOC_MLMB_WCR(window),
271 MVSOC_MLMB_WCR_WINEN |
272 MVSOC_MLMB_WCR_TARGET(target) |
273 MVSOC_MLMB_WCR_ATTR(attr) |
274 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
275 write_mlmbreg(MVSOC_MLMB_WBR(window),
276 membase & MVSOC_MLMB_WBR_BASE_MASK);
277 #ifdef PCI_NETBSD_CONFIGURE
278 if (window < nremap) {
279 write_mlmbreg(MVSOC_MLMB_WRLR(window),
280 membase & MVSOC_MLMB_WRLR_REMAP_MASK);
281 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
282 }
283 #endif
284 window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
285
286 /* Find free window if we've got spurious one */
287 if (window >= nwindow) {
288 window = axp_pcie_free_win();
289 /* Just break if there is no free windows left */
290 if (window < 0) {
291 aprint_error(": no free windows for PEX I/O\n");
292 break;
293 }
294 }
295 write_mlmbreg(MVSOC_MLMB_WCR(window),
296 MVSOC_MLMB_WCR_WINEN |
297 MVSOC_MLMB_WCR_TARGET(target) |
298 MVSOC_MLMB_WCR_ATTR(attr) |
299 MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
300 write_mlmbreg(MVSOC_MLMB_WBR(window),
301 iobase & MVSOC_MLMB_WBR_BASE_MASK);
302 #ifdef PCI_NETBSD_CONFIGURE
303 if (window < nremap) {
304 write_mlmbreg(MVSOC_MLMB_WRLR(window),
305 iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
306 write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
307 }
308 #endif
309 membase += MARVELL_PEXMEM_SIZE;
310 iobase += MARVELL_PEXIO_SIZE;
311 }
312 }
313
314 /*
315 * u_int initarm(...)
316 *
317 * Initial entry point on startup. This gets called before main() is
318 * entered.
319 * It should be responsible for setting up everything that must be
320 * in place when main is called.
321 * This includes
322 * Taking a copy of the boot configuration structure.
323 * Initialising the physical console so characters can be printed.
324 * Setting up page tables for the kernel
325 * Relocating the kernel to the bottom of physical memory
326 */
327 u_int
328 initarm(void *arg)
329 {
330 cpu_reset_address = axp_system_reset;
331
332 mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
333
334 /* Set CPU functions */
335 if (set_cpufuncs())
336 panic("cpu not recognized!");
337
338 /*
339 * Map devices into the initial page table
340 * in order to use early console during initialization process.
341 * consinit is going to use this mapping.
342 */
343 pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
344
345 /* Initialize system console */
346 consinit();
347
348 /* Reset PCI-Express space to window register. */
349 reset_axp_pcie_win();
350
351 /* Get CPU, system and timebase frequencies */
352 armadaxp_getclks();
353
354 /* Preconfigure interrupts */
355 armadaxp_intr_bootstrap(MARVELL_INTERREGS_PBASE);
356
357 #ifdef L2CACHE_ENABLE
358 /* Initialize L2 Cache */
359 (void)armadaxp_l2_init(MARVELL_INTERREGS_PBASE);
360 #endif
361
362 #ifdef AURORA_IO_CACHE_COHERENCY
363 /* Initialize cache coherency */
364 armadaxp_io_coherency_init();
365 #endif
366
367 #ifdef KGDB
368 kgdb_port_init();
369 #endif
370
371 #ifdef VERBOSE_INIT_ARM
372 /* Talk to the user */
373 #define BDSTR(s) _BDSTR(s)
374 #define _BDSTR(s) #s
375 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
376 #endif
377
378
379 #ifdef VERBOSE_INIT_ARM
380 printf("initarm: Configuring system ...\n");
381 #endif
382 /* Fake bootconfig structure for the benefit of pmap.c. */
383 bootconfig.dramblocks = 1;
384 bootconfig.dram[0].address = MEMSTART;
385 bootconfig.dram[0].pages = MEMSIZE / PAGE_SIZE;
386
387 physical_start = bootconfig.dram[0].address;
388 physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
389
390 arm32_bootmem_init(0, physical_end, (uintptr_t) KERNEL_BASE_phys);
391 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0,
392 devmap, false);
393
394 /* we've a specific device_register routine */
395 evbarm_device_register = axp_device_register;
396
397 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
398 }
399
400 #ifndef CONSADDR
401 #error Specify the address of the UART with the CONSADDR option.
402 #endif
403 #ifndef CONSPEED
404 #define CONSPEED B115200
405 #endif
406 #ifndef CONMODE
407 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
408 #endif
409 #ifndef CONSFREQ
410 #define CONSFREQ 250000000
411 #endif
412 static const int comcnspeed = CONSPEED;
413 static const int comcnfreq = CONSFREQ;
414 static const tcflag_t comcnmode = CONMODE;
415 static const bus_addr_t comcnaddr = (bus_addr_t)CONSADDR;
416
417 void
418 consinit(void)
419 {
420 static bool consinit_called = false;
421
422 if (consinit_called)
423 return;
424 consinit_called = true;
425
426 #if NCOM > 0
427 extern int mvuart_cnattach(bus_space_tag_t, bus_addr_t, int,
428 uint32_t, int);
429
430 if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
431 comcnfreq, comcnmode))
432 panic("Serial console can not be initialized.");
433 #endif
434 }
435
436 #ifdef KGDB
437 #ifndef KGDB_DEVADDR
438 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
439 #endif
440 #ifndef KGDB_DEVRATE
441 #define KGDB_DEVRATE B115200
442 #endif
443 #define MVUART_SIZE 0x20
444
445 #ifndef KGDB_DEVMODE
446 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
447 #endif
448 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
449 static const int comkgdbspeed = KGDB_DEVRATE;
450 static const int comkgdbmode = KGDB_DEVMODE;
451
452 void
453 static kgdb_port_init(void)
454 {
455 static int kgdbsinit_called = 0;
456
457 if (kgdbsinit_called != 0)
458 return;
459 kgdbsinit_called = 1;
460
461 if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
462 MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
463 panic("KGDB uart can not be initialized.");
464 }
465 #endif
466
467 #if NMVPEX > 0
468 static void
469 marvell_startend_by_tag(int tag, uint64_t *start, uint64_t *end)
470 {
471
472 uint32_t base, size;
473 int win;
474
475 win = mvsoc_target(tag, NULL, NULL, &base, &size);
476 if (size != 0) {
477 if (win < nremap)
478 *start = read_mlmbreg(MVSOC_MLMB_WRLR(win)) |
479 ((read_mlmbreg(MVSOC_MLMB_WRHR(win)) << 16) << 16);
480 else
481 *start = base;
482 *end = *start + size - 1;
483 } else
484 *start = *end = 0;
485 }
486 #endif
487
488 static void
489 axp_device_register(device_t dev, void *aux)
490 {
491 prop_dictionary_t dict = device_properties(dev);
492
493 #if NCOM > 0
494 if (device_is_a(dev, "com") &&
495 device_is_a(device_parent(dev), "mvsoc"))
496 prop_dictionary_set_uint32(dict, "frequency", mvTclk);
497 #endif
498
499 #if NMVPEX > 0
500 extern struct bus_space
501 armadaxp_pex00_io_bs_tag, armadaxp_pex00_mem_bs_tag,
502 armadaxp_pex01_io_bs_tag, armadaxp_pex01_mem_bs_tag,
503 armadaxp_pex02_io_bs_tag, armadaxp_pex02_mem_bs_tag,
504 armadaxp_pex03_io_bs_tag, armadaxp_pex03_mem_bs_tag,
505 armadaxp_pex2_io_bs_tag, armadaxp_pex2_mem_bs_tag,
506 armadaxp_pex3_io_bs_tag, armadaxp_pex3_mem_bs_tag;
507 extern struct arm32_pci_chipset arm32_mvpex0_chipset,
508 arm32_mvpex1_chipset, arm32_mvpex2_chipset,
509 arm32_mvpex3_chipset, arm32_mvpex4_chipset,
510 arm32_mvpex5_chipset;
511
512 struct marvell_attach_args *mva = aux;
513
514 if (device_is_a(dev, "mvpex")) {
515 struct bus_space *mvpex_io_bs_tag, *mvpex_mem_bs_tag;
516 struct arm32_pci_chipset *arm32_mvpex_chipset;
517 prop_data_t io_bs_tag, mem_bs_tag, pc;
518 uint64_t start, end;
519 int iotag, memtag;
520
521 if (mva->mva_offset == MVSOC_PEX_BASE) {
522 mvpex_io_bs_tag = &armadaxp_pex00_io_bs_tag;
523 mvpex_mem_bs_tag = &armadaxp_pex00_mem_bs_tag;
524 arm32_mvpex_chipset = &arm32_mvpex0_chipset;
525 iotag = ARMADAXP_TAG_PEX00_IO;
526 memtag = ARMADAXP_TAG_PEX00_MEM;
527 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x4000) {
528 mvpex_io_bs_tag = &armadaxp_pex01_io_bs_tag;
529 mvpex_mem_bs_tag = &armadaxp_pex01_mem_bs_tag;
530 arm32_mvpex_chipset = &arm32_mvpex1_chipset;
531 iotag = ARMADAXP_TAG_PEX01_IO;
532 memtag = ARMADAXP_TAG_PEX01_MEM;
533 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x8000) {
534 mvpex_io_bs_tag = &armadaxp_pex02_io_bs_tag;
535 mvpex_mem_bs_tag = &armadaxp_pex02_mem_bs_tag;
536 arm32_mvpex_chipset = &arm32_mvpex2_chipset;
537 iotag = ARMADAXP_TAG_PEX02_IO;
538 memtag = ARMADAXP_TAG_PEX02_MEM;
539 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0xc000) {
540 mvpex_io_bs_tag = &armadaxp_pex03_io_bs_tag;
541 mvpex_mem_bs_tag = &armadaxp_pex03_mem_bs_tag;
542 arm32_mvpex_chipset = &arm32_mvpex3_chipset;
543 iotag = ARMADAXP_TAG_PEX03_IO;
544 memtag = ARMADAXP_TAG_PEX03_MEM;
545 } else if (mva->mva_offset == MVSOC_PEX_BASE + 0x2000) {
546 mvpex_io_bs_tag = &armadaxp_pex2_io_bs_tag;
547 mvpex_mem_bs_tag = &armadaxp_pex2_mem_bs_tag;
548 arm32_mvpex_chipset = &arm32_mvpex4_chipset;
549 iotag = ARMADAXP_TAG_PEX2_IO;
550 memtag = ARMADAXP_TAG_PEX2_MEM;
551 } else {
552 mvpex_io_bs_tag = &armadaxp_pex3_io_bs_tag;
553 mvpex_mem_bs_tag = &armadaxp_pex3_mem_bs_tag;
554 arm32_mvpex_chipset = &arm32_mvpex5_chipset;
555 iotag = ARMADAXP_TAG_PEX3_IO;
556 memtag = ARMADAXP_TAG_PEX3_MEM;
557 }
558
559 arm32_mvpex_chipset->pc_conf_v = device_private(dev);
560 arm32_mvpex_chipset->pc_intr_v = device_private(dev);
561
562 io_bs_tag = prop_data_create_data_nocopy(
563 mvpex_io_bs_tag, sizeof(struct bus_space));
564 KASSERT(io_bs_tag != NULL);
565 prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
566 prop_object_release(io_bs_tag);
567 mem_bs_tag = prop_data_create_data_nocopy(
568 mvpex_mem_bs_tag, sizeof(struct bus_space));
569 KASSERT(mem_bs_tag != NULL);
570 prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
571 prop_object_release(mem_bs_tag);
572
573 pc = prop_data_create_data_nocopy(arm32_mvpex_chipset,
574 sizeof(struct arm32_pci_chipset));
575 KASSERT(pc != NULL);
576 prop_dictionary_set(dict, "pci-chipset", pc);
577 prop_object_release(pc);
578
579 marvell_startend_by_tag(iotag, &start, &end);
580 prop_dictionary_set_uint64(dict, "iostart", start);
581 prop_dictionary_set_uint64(dict, "ioend", end);
582 marvell_startend_by_tag(memtag, &start, &end);
583 prop_dictionary_set_uint64(dict, "memstart", start);
584 prop_dictionary_set_uint64(dict, "memend", end);
585 prop_dictionary_set_uint32(dict,
586 "cache-line-size", arm_dcache_align);
587 }
588 #endif
589 }
590