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