1 /* $NetBSD: gumstix_machdep.c,v 1.48 2013/09/26 16:14:34 kiyohara Exp $ */ 2 /* 3 * Copyright (C) 2005, 2006, 2007 WIDE Project and SOUM Corporation. 4 * All rights reserved. 5 * 6 * Written by Takashi Kiyohara and Susumu Miki for WIDE Project and SOUM 7 * Corporation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the name of SOUM Corporation 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT and SOUM CORPORATION ``AS IS'' 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT AND SOUM CORPORATION 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 /* 34 * Copyright (c) 2002, 2003, 2004, 2005 Genetec Corporation. 35 * All rights reserved. 36 * 37 * Written by Hiroyuki Bessho for Genetec Corporation. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. The name of Genetec Corporation may not be used to endorse or 48 * promote products derived from this software without specific prior 49 * written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 * 63 * Machine dependent functions for kernel setup for Genetec G4250EBX 64 * evaluation board. 65 * 66 * Based on iq80310_machhdep.c 67 */ 68 /* 69 * Copyright (c) 2001 Wasabi Systems, Inc. 70 * All rights reserved. 71 * 72 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 73 * 74 * Redistribution and use in source and binary forms, with or without 75 * modification, are permitted provided that the following conditions 76 * are met: 77 * 1. Redistributions of source code must retain the above copyright 78 * notice, this list of conditions and the following disclaimer. 79 * 2. Redistributions in binary form must reproduce the above copyright 80 * notice, this list of conditions and the following disclaimer in the 81 * documentation and/or other materials provided with the distribution. 82 * 3. All advertising materials mentioning features or use of this software 83 * must display the following acknowledgement: 84 * This product includes software developed for the NetBSD Project by 85 * Wasabi Systems, Inc. 86 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 87 * or promote products derived from this software without specific prior 88 * written permission. 89 * 90 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 91 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 92 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 93 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 94 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 95 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 96 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 97 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 98 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 99 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 100 * POSSIBILITY OF SUCH DAMAGE. 101 */ 102 103 /* 104 * Copyright (c) 1997,1998 Mark Brinicombe. 105 * Copyright (c) 1997,1998 Causality Limited. 106 * All rights reserved. 107 * 108 * Redistribution and use in source and binary forms, with or without 109 * modification, are permitted provided that the following conditions 110 * are met: 111 * 1. Redistributions of source code must retain the above copyright 112 * notice, this list of conditions and the following disclaimer. 113 * 2. Redistributions in binary form must reproduce the above copyright 114 * notice, this list of conditions and the following disclaimer in the 115 * documentation and/or other materials provided with the distribution. 116 * 3. All advertising materials mentioning features or use of this software 117 * must display the following acknowledgement: 118 * This product includes software developed by Mark Brinicombe 119 * for the NetBSD Project. 120 * 4. The name of the company nor the name of the author may be used to 121 * endorse or promote products derived from this software without specific 122 * prior written permission. 123 * 124 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 125 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 126 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 127 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 128 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 129 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 130 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 131 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 132 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 133 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 134 * SUCH DAMAGE. 135 * 136 * Machine dependent functions for kernel setup for Intel IQ80310 evaluation 137 * boards using RedBoot firmware. 138 */ 139 140 #include "opt_evbarm_boardtype.h" 141 #include "opt_cputypes.h" 142 #include "opt_gumstix.h" 143 #ifdef OVERO 144 #include "opt_omap.h" 145 #include "prcm.h" 146 #endif 147 #include "opt_ddb.h" 148 #include "opt_kgdb.h" 149 #include "opt_pmap_debug.h" 150 #include "opt_md.h" 151 #include "opt_modular.h" 152 #include "opt_com.h" 153 154 #include <sys/param.h> 155 #include <sys/conf.h> 156 #include <sys/device.h> 157 #include <sys/exec.h> 158 #include <sys/kernel.h> 159 #include <sys/ksyms.h> 160 #include <sys/msgbuf.h> 161 #include <sys/proc.h> 162 #include <sys/reboot.h> 163 #include <sys/systm.h> 164 #include <sys/termios.h> 165 #include <sys/bus.h> 166 #include <sys/cpu.h> 167 168 #include <machine/autoconf.h> 169 #include <machine/bootconfig.h> 170 #include <machine/db_machdep.h> 171 #include <arm/locore.h> 172 #include <arm/undefined.h> 173 174 #include <arm/arm32/machdep.h> 175 #ifdef OVERO 176 #include <arm/omap/omap2_gpmcreg.h> 177 #include <arm/omap/omap2_prcm.h> 178 #include <arm/omap/omap2_reg.h> 179 #include <arm/omap/omap_var.h> 180 #include <arm/omap/omap_com.h> 181 #endif 182 #include <arm/xscale/pxa2x0reg.h> 183 #include <arm/xscale/pxa2x0var.h> 184 #include <arm/xscale/pxa2x0_gpio.h> 185 #include <evbarm/gumstix/gumstixreg.h> 186 #include <evbarm/gumstix/gumstixvar.h> 187 188 #include <uvm/uvm_extern.h> 189 190 #include <dev/cons.h> 191 #include <dev/md.h> 192 193 #include <ddb/db_sym.h> 194 #include <ddb/db_extern.h> 195 #ifdef KGDB 196 #include <sys/kgdb.h> 197 #endif 198 199 /* Kernel text starts 2MB in from the bottom of the kernel address space. */ 200 #define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00200000) 201 #ifndef KERNEL_VM_BASE 202 #define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000) 203 #endif 204 205 /* 206 * The range 0xc1000000 - 0xccffffff is available for kernel VM space 207 * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff 208 */ 209 #define KERNEL_VM_SIZE 0x0C000000 210 211 BootConfig bootconfig; /* Boot config storage */ 212 static char bootargs[MAX_BOOT_STRING]; 213 const size_t bootargs_len = sizeof(bootargs) - 1; /* without nul */ 214 char *boot_args = NULL; 215 216 uint32_t system_serial_high; 217 uint32_t system_serial_low; 218 219 vm_offset_t physical_start; 220 vm_offset_t physical_freestart; 221 vm_offset_t physical_freeend; 222 vm_offset_t physical_end; 223 u_int free_pages; 224 225 /*int debug_flags;*/ 226 #ifndef PMAP_STATIC_L1S 227 int max_processes = 64; /* Default number */ 228 #endif /* !PMAP_STATIC_L1S */ 229 230 pv_addr_t minidataclean; 231 232 vm_offset_t msgbufphys; 233 234 #ifdef PMAP_DEBUG 235 extern int pmap_debug_level; 236 #endif 237 238 #define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */ 239 #define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */ 240 #define KERNEL_PT_KERNEL_NUM ((KERNEL_VM_BASE - KERNEL_BASE) >> 22) 241 #define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL+KERNEL_PT_KERNEL_NUM) 242 /* Page tables for mapping kernel VM */ 243 #define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */ 244 #define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) 245 246 pv_addr_t kernel_pt_table[NUM_KERNEL_PTS]; 247 248 /* Prototypes */ 249 #if defined(GUMSTIX) 250 static void read_system_serial(void); 251 #elif defined(OVERO) 252 static void find_cpu_clock(void); 253 #endif 254 static void process_kernel_args(int, char *[]); 255 static void process_kernel_args_liner(char *); 256 #ifdef KGDB 257 static void kgdb_port_init(void); 258 #endif 259 static void gumstix_device_register(device_t, void *); 260 261 bs_protos(bs_notimpl); 262 263 #include "com.h" 264 #if NCOM > 0 265 #include <dev/ic/comreg.h> 266 #include <dev/ic/comvar.h> 267 #endif 268 269 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 270 #include "lcd.h" 271 #endif 272 273 #ifndef CONSPEED 274 #define CONSPEED B115200 /* It's a setting of the default of u-boot */ 275 #endif 276 #ifndef CONMODE 277 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 278 #endif 279 280 int comcnspeed = CONSPEED; 281 int comcnmode = CONMODE; 282 283 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 284 static char console[16]; 285 #endif 286 287 extern void gxio_config_pin(void); 288 extern void gxio_config_expansion(char *); 289 290 /* 291 * void cpu_reboot(int howto, char *bootstr) 292 * 293 * Deal with any syncing, unmounting, dumping and shutdown hooks, 294 * then reset the CPU. 295 */ 296 void 297 cpu_reboot(int howto, char *bootstr) 298 { 299 300 #ifdef DIAGNOSTIC 301 /* info */ 302 printf("boot: howto=%08x curproc=%p\n", howto, curproc); 303 #endif 304 305 /* 306 * If we are still cold then hit the air brakes 307 * and crash to earth fast 308 */ 309 if (cold) { 310 doshutdownhooks(); 311 pmf_system_shutdown(boothowto); 312 printf("The operating system has halted.\n"); 313 printf("Please press any key to reboot.\n\n"); 314 cngetc(); 315 printf("rebooting...\n"); 316 #if defined(OMAP_3530) && NPRCM > 0 317 prcm_cold_reset(); 318 #endif 319 cpu_reset(); 320 /*NOTREACHED*/ 321 } 322 323 /* 324 * If RB_NOSYNC was not specified sync the discs. 325 * Note: Unless cold is set to 1 here, syslogd will die during the 326 * unmount. It looks like syslogd is getting woken up only to find 327 * that it cannot page part of the binary in as the filesystem has 328 * been unmounted. 329 */ 330 if (!(howto & RB_NOSYNC)) 331 bootsync(); 332 333 /* Say NO to interrupts */ 334 splhigh(); 335 336 /* Do a dump if requested. */ 337 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 338 dumpsys(); 339 340 /* Run any shutdown hooks */ 341 doshutdownhooks(); 342 343 pmf_system_shutdown(boothowto); 344 345 /* Make sure IRQ's are disabled */ 346 IRQdisable; 347 348 if (howto & RB_HALT) { 349 printf("The operating system has halted.\n"); 350 printf("Please press any key to reboot.\n\n"); 351 cngetc(); 352 } 353 354 printf("rebooting...\n"); 355 #if defined(OMAP_3530) && NPRCM > 0 356 prcm_cold_reset(); 357 #endif 358 cpu_reset(); 359 /*NOTREACHED*/ 360 } 361 362 static inline pd_entry_t * 363 read_ttb(void) 364 { 365 long ttb; 366 367 __asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb)); 368 369 return (pd_entry_t *)(ttb & ~((1<<14)-1)); 370 } 371 372 /* 373 * Static device mappings. These peripheral registers are mapped at 374 * fixed virtual addresses very early in initarm() so that we can use 375 * them while booting the kernel, and stay at the same address 376 * throughout whole kernel's life time. 377 * 378 * We use this table twice; once with bootstrap page table, and once 379 * with kernel's page table which we build up in initarm(). 380 * 381 * Since we map these registers into the bootstrap page table using 382 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map 383 * registers segment-aligned and segment-rounded in order to avoid 384 * using the 2nd page tables. 385 */ 386 387 #define _A(a) ((a) & ~L1_S_OFFSET) 388 #define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1)) 389 390 static const struct pmap_devmap gumstix_devmap[] = { 391 #if defined(GUMSTIX) 392 { 393 GUMSTIX_GPIO_VBASE, 394 _A(PXA2X0_GPIO_BASE), 395 _S(PXA250_GPIO_SIZE), 396 VM_PROT_READ | VM_PROT_WRITE, 397 PTE_NOCACHE, 398 }, 399 { 400 GUMSTIX_CLKMAN_VBASE, 401 _A(PXA2X0_CLKMAN_BASE), 402 _S(PXA2X0_CLKMAN_SIZE), 403 VM_PROT_READ | VM_PROT_WRITE, 404 PTE_NOCACHE, 405 }, 406 { 407 GUMSTIX_INTCTL_VBASE, 408 _A(PXA2X0_INTCTL_BASE), 409 _S(PXA2X0_INTCTL_SIZE), 410 VM_PROT_READ | VM_PROT_WRITE, 411 PTE_NOCACHE, 412 }, 413 { 414 GUMSTIX_FFUART_VBASE, 415 _A(PXA2X0_FFUART_BASE), 416 _S(4 * COM_NPORTS), 417 VM_PROT_READ | VM_PROT_WRITE, 418 PTE_NOCACHE, 419 }, 420 { 421 GUMSTIX_STUART_VBASE, 422 _A(PXA2X0_STUART_BASE), 423 _S(4 * COM_NPORTS), 424 VM_PROT_READ | VM_PROT_WRITE, 425 PTE_NOCACHE, 426 }, 427 { 428 GUMSTIX_BTUART_VBASE, 429 _A(PXA2X0_BTUART_BASE), 430 _S(4 * COM_NPORTS), 431 VM_PROT_READ | VM_PROT_WRITE, 432 PTE_NOCACHE, 433 }, 434 { 435 GUMSTIX_HWUART_VBASE, 436 _A(PXA2X0_HWUART_BASE), 437 _S(4 * COM_NPORTS), 438 VM_PROT_READ | VM_PROT_WRITE, 439 PTE_NOCACHE, 440 }, 441 { 442 GUMSTIX_LCDC_VBASE, 443 _A(PXA2X0_LCDC_BASE), 444 _S(4 * COM_NPORTS), 445 VM_PROT_READ | VM_PROT_WRITE, 446 PTE_NOCACHE, 447 }, 448 #elif defined(OVERO) 449 { 450 OVERO_L4_PERIPHERAL_VBASE, 451 _A(OMAP3530_L4_PERIPHERAL_BASE), 452 _S(OMAP3530_L4_PERIPHERAL_SIZE), 453 VM_PROT_READ | VM_PROT_WRITE, 454 PTE_NOCACHE 455 }, 456 { 457 OVERO_GPMC_VBASE, 458 _A(GPMC_BASE), 459 _S(GPMC_SIZE), 460 VM_PROT_READ | VM_PROT_WRITE, 461 PTE_NOCACHE 462 }, 463 #endif 464 { 0, 0, 0, 0, 0 } 465 }; 466 467 #undef _A 468 #undef _S 469 470 471 /* 472 * u_int initarm(...) 473 * 474 * Initial entry point on startup. This gets called before main() is 475 * entered. 476 * It should be responsible for setting up everything that must be 477 * in place when main is called. 478 * This includes 479 * Taking a copy of the boot configuration structure. 480 * Initialising the physical console so characters can be printed. 481 * Setting up page tables for the kernel 482 * Relocating the kernel to the bottom of physical memory 483 */ 484 u_int 485 initarm(void *arg) 486 { 487 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 488 #ifdef DIAGNOSTIC 489 extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */ 490 #endif 491 extern vaddr_t xscale_cache_clean_addr; 492 #endif 493 extern uint32_t *u_boot_args[]; 494 extern uint32_t ram_size; 495 enum { r0 = 0, r1 = 1, r2 = 2, r3 = 3 }; /* args from u-boot */ 496 int loop; 497 int loop1; 498 u_int l1pagetable; 499 paddr_t memstart; 500 psize_t memsize; 501 502 /* 503 * We mapped PA == VA in gumstix_start.S. 504 * Also mapped SDRAM to KERNEL_BASE first 64Mbyte only with cachable. 505 * 506 * Gumstix (basix, connex, verdex, verdex-pro): 507 * Physical Address Range Description 508 * ----------------------- ---------------------------------- 509 * 0x00000000 - 0x00ffffff flash Memory (16MB or 4MB) 510 * 0x40000000 - 0x480fffff Processor Registers 511 * 0xa0000000 - 0xa3ffffff SDRAM Bank 0 (64MB or 128MB) 512 * 0xc0000000 - 0xc3ffffff KERNEL_BASE 513 * 514 * Overo: 515 * Physical Address Range Description 516 * ----------------------- ---------------------------------- 517 * 0x80000000 - 0x8fffffff SDRAM Bank 0 (256MB, 512MB or 1024MB) 518 * 0x80000000 - 0x83ffffff KERNEL_BASE 519 */ 520 521 #if defined(OVERO) 522 find_cpu_clock(); // find our CPU speed. 523 #endif 524 525 /* 526 * Heads up ... Setup the CPU / MMU / TLB functions 527 */ 528 if (set_cpufuncs()) 529 panic("cpu not recognized!"); 530 531 /* map some peripheral registers at static I/O area */ 532 pmap_devmap_bootstrap((vaddr_t)read_ttb(), gumstix_devmap); 533 534 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 535 /* start 32.768kHz OSC */ 536 ioreg_write(GUMSTIX_CLKMAN_VBASE + CLKMAN_OSCC, OSCC_OON); 537 538 /* Get ready for splfoo() */ 539 pxa2x0_intr_bootstrap(GUMSTIX_INTCTL_VBASE); 540 541 /* setup GPIO for {FF,ST,HW}UART. */ 542 pxa2x0_gpio_bootstrap(GUMSTIX_GPIO_VBASE); 543 544 pxa2x0_clkman_bootstrap(GUMSTIX_CLKMAN_VBASE); 545 #elif defined(CPU_CORTEX) 546 cortex_pmc_ccnt_init(); 547 #endif 548 549 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 550 551 /* configure GPIOs. */ 552 gxio_config_pin(); 553 554 555 #ifndef GUMSTIX_NETBSD_ARGS_CONSOLE 556 consinit(); 557 #endif 558 #ifdef KGDB 559 kgdb_port_init(); 560 #endif 561 562 /* 563 * Examine the boot args string for options we need to know about 564 * now. 565 */ 566 #if defined(GUMSTIX) 567 #define SDRAM_START 0xa0000000UL 568 #elif defined(OVERO) 569 #define SDRAM_START 0x80000000UL 570 #endif 571 if (((uint32_t)u_boot_args[r0] & 0xf0000000) != SDRAM_START) 572 /* Maybe r0 is 'argc'. We are booted by command 'go'. */ 573 process_kernel_args((int)u_boot_args[r0], 574 (char **)u_boot_args[r1]); 575 else 576 /* 577 * Maybe r3 is 'boot args string' of 'bootm'. This string is 578 * linely. 579 */ 580 process_kernel_args_liner((char *)u_boot_args[r3]); 581 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 582 consinit(); 583 #endif 584 585 /* Talk to the user */ 586 #define BDSTR(s) _BDSTR(s) 587 #define _BDSTR(s) #s 588 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); 589 590 /* Read system serial */ 591 #if defined(GUMSTIX) 592 read_system_serial(); 593 #endif 594 595 memstart = SDRAM_START; 596 memsize = ram_size; 597 598 #ifdef VERBOSE_INIT_ARM 599 printf("initarm: Configuring system ...\n"); 600 #endif 601 602 /* Fake bootconfig structure for the benefit of pmap.c */ 603 /* XXX must make the memory description h/w independent */ 604 bootconfig.dramblocks = 1; 605 bootconfig.dram[0].address = memstart; 606 bootconfig.dram[0].pages = memsize / PAGE_SIZE; 607 608 /* 609 * Set up the variables that define the availablilty of 610 * physical memory. For now, we're going to set 611 * physical_freestart to 0xa0200000 (where the kernel 612 * was loaded), and allocate the memory we need downwards. 613 * If we get too close to the L1 table that we set up, we 614 * will panic. We will update physical_freestart and 615 * physical_freeend later to reflect what pmap_bootstrap() 616 * wants to see. 617 * 618 * XXX pmap_bootstrap() needs an enema. 619 */ 620 physical_start = bootconfig.dram[0].address; 621 physical_end = physical_start + memsize; 622 623 #if defined(GUMSTIX) 624 physical_freestart = 0xa0009000UL; 625 physical_freeend = 0xa0200000UL; 626 #elif defined(OVERO) 627 physical_freestart = 0x80009000UL; 628 physical_freeend = 0x80200000UL; 629 #endif 630 631 physmem = (physical_end - physical_start) / PAGE_SIZE; 632 633 #ifdef VERBOSE_INIT_ARM 634 /* Tell the user about the memory */ 635 printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem, 636 physical_start, physical_end - 1); 637 #endif 638 639 /* 640 * Okay, the kernel starts 2MB in from the bottom of physical 641 * memory. We are going to allocate our bootstrap pages downwards 642 * from there. 643 * 644 * We need to allocate some fixed page tables to get the kernel 645 * going. We allocate one page directory and a number of page 646 * tables and store the physical addresses in the kernel_pt_table 647 * array. 648 * 649 * The kernel page directory must be on a 16K boundary. The page 650 * tables must be on 4K bounaries. What we do is allocate the 651 * page directory on the first 16K boundary that we encounter, and 652 * the page tables on 4K boundaries otherwise. Since we allocate 653 * at least 3 L2 page tables, we are guaranteed to encounter at 654 * least one 16K aligned region. 655 */ 656 657 #ifdef VERBOSE_INIT_ARM 658 printf("Allocating page tables\n"); 659 #endif 660 661 free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE; 662 663 #ifdef VERBOSE_INIT_ARM 664 printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n", 665 physical_freestart, free_pages, free_pages); 666 #endif 667 668 /* Define a macro to simplify memory allocation */ 669 #define valloc_pages(var, np) \ 670 alloc_pages((var).pv_pa, (np)); \ 671 (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start; 672 673 #define alloc_pages(var, np) \ 674 physical_freeend -= ((np) * PAGE_SIZE); \ 675 if (physical_freeend < physical_freestart) \ 676 panic("initarm: out of memory"); \ 677 (var) = physical_freeend; \ 678 free_pages -= (np); \ 679 memset((char *)(var), 0, ((np) * PAGE_SIZE)); 680 681 loop1 = 0; 682 for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { 683 /* Are we 16KB aligned for an L1 ? */ 684 if ((physical_freeend & (L1_TABLE_SIZE - 1)) == 0 && 685 kernel_l1pt.pv_pa == 0) { 686 valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); 687 } else { 688 valloc_pages(kernel_pt_table[loop1], 689 L2_TABLE_SIZE / PAGE_SIZE); 690 ++loop1; 691 } 692 } 693 694 /* This should never be able to happen but better confirm that. */ 695 if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0) 696 panic("initarm: Failed to align the kernel page directory"); 697 698 /* 699 * Allocate a page for the system page mapped to V0x00000000 700 * This page will just contain the system vectors and can be 701 * shared by all processes. 702 */ 703 alloc_pages(systempage.pv_pa, 1); 704 #if defined(CPU_CORTEXA8) 705 systempage.pv_va = ARM_VECTORS_HIGH; 706 #endif 707 708 /* Allocate stacks for all modes */ 709 valloc_pages(irqstack, IRQ_STACK_SIZE); 710 valloc_pages(abtstack, ABT_STACK_SIZE); 711 valloc_pages(undstack, UND_STACK_SIZE); 712 valloc_pages(kernelstack, UPAGES); 713 714 /* Allocate enough pages for cleaning the Mini-Data cache. */ 715 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 716 KASSERT(xscale_minidata_clean_size <= PAGE_SIZE); 717 #endif 718 valloc_pages(minidataclean, 1); 719 720 #ifdef VERBOSE_INIT_ARM 721 printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, 722 irqstack.pv_va); 723 printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, 724 abtstack.pv_va); 725 printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, 726 undstack.pv_va); 727 printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, 728 kernelstack.pv_va); 729 #endif 730 731 /* 732 * XXX Defer this to later so that we can reclaim the memory 733 * XXX used by the RedBoot page tables. 734 */ 735 alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE); 736 737 /* 738 * Ok we have allocated physical pages for the primary kernel 739 * page tables 740 */ 741 742 #ifdef VERBOSE_INIT_ARM 743 printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa); 744 #endif 745 746 /* 747 * Now we start construction of the L1 page table 748 * We start by mapping the L2 page tables into the L1. 749 * This means that we can replace L1 mappings later on if necessary 750 */ 751 l1pagetable = kernel_l1pt.pv_va; 752 753 /* Map the L2 pages tables in the L1 page table */ 754 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 755 pmap_link_l2pt(l1pagetable, 0x00000000, 756 &kernel_pt_table[KERNEL_PT_SYS]); 757 #elif defined(CPU_CORTEXA8) 758 pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00400000 - 1), 759 &kernel_pt_table[KERNEL_PT_SYS]); 760 #endif 761 for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) 762 pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000, 763 &kernel_pt_table[KERNEL_PT_KERNEL + loop]); 764 for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++) 765 pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, 766 &kernel_pt_table[KERNEL_PT_VMDATA + loop]); 767 768 /* update the top of the kernel VM */ 769 pmap_curmaxkvaddr = 770 KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000); 771 772 #ifdef VERBOSE_INIT_ARM 773 printf("Mapping kernel\n"); 774 #endif 775 776 /* Now we fill in the L2 pagetable for the kernel static code/data */ 777 { 778 extern char etext[], _end[]; 779 size_t textsize = (uintptr_t) etext - KERNEL_TEXT_BASE; 780 size_t totalsize = (uintptr_t) _end - KERNEL_TEXT_BASE; 781 u_int logical; 782 783 textsize = (textsize + PGOFSET) & ~PGOFSET; 784 totalsize = (totalsize + PGOFSET) & ~PGOFSET; 785 786 logical = 0x00200000; /* offset of kernel in RAM */ 787 788 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 789 physical_start + logical, textsize, 790 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 791 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 792 physical_start + logical, totalsize - textsize, 793 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 794 } 795 796 #ifdef VERBOSE_INIT_ARM 797 printf("Constructing L2 page tables\n"); 798 #endif 799 800 /* Map the stack pages */ 801 pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, 802 IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 803 pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa, 804 ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 805 pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa, 806 UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 807 pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa, 808 UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE); 809 810 pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, 811 L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE); 812 813 for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { 814 pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va, 815 kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE, 816 VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); 817 } 818 819 /* Map the Mini-Data cache clean area. */ 820 #if defined(GUMSTIX) 821 xscale_setup_minidata(l1pagetable, minidataclean.pv_va, 822 minidataclean.pv_pa); 823 #endif 824 825 /* Map the vector page. */ 826 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 827 #if 1 828 /* MULTI-ICE requires that page 0 is NC/NB so that it can download the 829 * cache-clean code there. */ 830 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, 831 VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); 832 #else 833 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, 834 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 835 #endif 836 #elif defined(CPU_CORTEXA8) 837 pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, 838 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 839 #endif 840 841 /* 842 * map integrated peripherals at same address in l1pagetable 843 * so that we can continue to use console. 844 */ 845 pmap_devmap_bootstrap(l1pagetable, gumstix_devmap); 846 847 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 848 /* 849 * Give the XScale global cache clean code an appropriately 850 * sized chunk of unmapped VA space starting at 0xff000000 851 * (our device mappings end before this address). 852 */ 853 xscale_cache_clean_addr = 0xff000000U; 854 #endif 855 856 /* 857 * Now we have the real page tables in place so we can switch to them. 858 * Once this is done we will be running with the REAL kernel page 859 * tables. 860 */ 861 862 /* 863 * Update the physical_freestart/physical_freeend/free_pages 864 * variables. 865 */ 866 { 867 extern char _end[]; 868 869 physical_freestart = physical_start + 870 (((((uintptr_t) _end) + PGOFSET) & ~PGOFSET) - 871 KERNEL_BASE); 872 physical_freeend = physical_end; 873 free_pages = 874 (physical_freeend - physical_freestart) / PAGE_SIZE; 875 } 876 877 /* Switch tables */ 878 #ifdef VERBOSE_INIT_ARM 879 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n", 880 physical_freestart, free_pages, free_pages); 881 printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa); 882 #endif 883 884 cpu_setttb(kernel_l1pt.pv_pa, true); 885 cpu_tlb_flushID(); 886 cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); 887 888 /* 889 * Moved from cpu_startup() as data_abort_handler() references 890 * this during uvm init 891 */ 892 uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); 893 894 #ifdef VERBOSE_INIT_ARM 895 printf("bootstrap done.\n"); 896 #endif 897 898 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 899 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); 900 #elif defined(CPU_CORTEXA8) 901 arm32_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL); 902 #endif 903 904 /* 905 * Pages were allocated during the secondary bootstrap for the 906 * stacks for different CPU modes. 907 * We must now set the r13 registers in the different CPU modes to 908 * point to these stacks. 909 * Since the ARM stacks use STMFD etc. we must set r13 to the top end 910 * of the stack memory. 911 */ 912 #ifdef VERBOSE_INIT_ARM 913 printf("init subsystems: stacks "); 914 #endif 915 916 set_stackptr(PSR_IRQ32_MODE, 917 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); 918 set_stackptr(PSR_ABT32_MODE, 919 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); 920 set_stackptr(PSR_UND32_MODE, 921 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); 922 923 /* 924 * Well we should set a data abort handler. 925 * Once things get going this will change as we will need a proper 926 * handler. 927 * Until then we will use a handler that just panics but tells us 928 * why. 929 * Initialisation of the vectors will just panic on a data abort. 930 * This just fills in a slighly better one. 931 */ 932 #ifdef VERBOSE_INIT_ARM 933 printf("vectors "); 934 #endif 935 data_abort_handler_address = (u_int)data_abort_handler; 936 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 937 undefined_handler_address = (u_int)undefinedinstruction_bounce; 938 939 /* Initialise the undefined instruction handlers */ 940 #ifdef VERBOSE_INIT_ARM 941 printf("undefined "); 942 #endif 943 undefined_init(); 944 945 /* Load memory into UVM. */ 946 #ifdef VERBOSE_INIT_ARM 947 printf("page "); 948 #endif 949 uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ 950 uvm_page_physload(atop(physical_freestart), atop(physical_freeend), 951 atop(physical_freestart), atop(physical_freeend), 952 VM_FREELIST_DEFAULT); 953 954 /* Boot strap pmap telling it where the kernel page table is */ 955 #ifdef VERBOSE_INIT_ARM 956 printf("pmap "); 957 #endif 958 pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); 959 960 #ifdef __HAVE_MEMORY_DISK__ 961 md_root_setconf(memory_disk, sizeof memory_disk); 962 #endif 963 964 #ifdef BOOTHOWTO 965 boothowto |= BOOTHOWTO; 966 #endif 967 968 #ifdef KGDB 969 if (boothowto & RB_KDB) { 970 kgdb_debug_init = 1; 971 kgdb_connect(1); 972 } 973 #endif 974 975 #if NKSYMS || defined(DDB) || defined(MODULAR) 976 /* Firmware doesn't load symbols. */ 977 ddb_init(0, NULL, NULL); 978 #endif 979 980 #ifdef DDB 981 db_machine_init(); 982 if (boothowto & RB_KDB) 983 Debugger(); 984 #endif 985 986 /* We have our own device_register() */ 987 evbarm_device_register = gumstix_device_register; 988 989 /* We return the new stack pointer address */ 990 return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); 991 } 992 993 #if defined(GUMSTIX) 994 static void 995 read_system_serial(void) 996 { 997 #define GUMSTIX_SYSTEM_SERIAL_ADDR 0 998 #define GUMSTIX_SYSTEM_SERIAL_SIZE 8 999 #define FLASH_OFFSET_INTEL_PROTECTION 0x81 1000 #define FLASH_OFFSET_USER_PROTECTION 0x85 1001 #define FLASH_CMD_READ_ID 0x90 1002 #define FLASH_CMD_RESET 0xff 1003 int i; 1004 char system_serial[GUMSTIX_SYSTEM_SERIAL_SIZE], *src; 1005 char x; 1006 1007 src = (char *)(FLASH_OFFSET_USER_PROTECTION * 2 /*word*/); 1008 *(volatile uint16_t *)0 = FLASH_CMD_READ_ID; 1009 memcpy(system_serial, 1010 src + GUMSTIX_SYSTEM_SERIAL_ADDR, sizeof (system_serial)); 1011 *(volatile uint16_t *)0 = FLASH_CMD_RESET; 1012 1013 for (i = 1, x = system_serial[0]; i < sizeof (system_serial); i++) 1014 x &= system_serial[i]; 1015 if (x == 0xff) { 1016 src = (char *)(FLASH_OFFSET_INTEL_PROTECTION * 2 /*word*/); 1017 *(volatile uint16_t *)0 = FLASH_CMD_READ_ID; 1018 memcpy(system_serial, 1019 src + GUMSTIX_SYSTEM_SERIAL_ADDR, sizeof (system_serial)); 1020 *(volatile uint16_t *)0 = FLASH_CMD_RESET; 1021 1022 /* 1023 * XXXX: Don't need ??? 1024 * gumstix_serial_hash(system_serial); 1025 */ 1026 } 1027 system_serial_high = system_serial[0] << 24 | system_serial[1] << 16 | 1028 system_serial[2] << 8 | system_serial[3]; 1029 system_serial_low = system_serial[4] << 24 | system_serial[5] << 16 | 1030 system_serial[6] << 8 | system_serial[7]; 1031 1032 printf("system serial: 0x"); 1033 for (i = 0; i < sizeof (system_serial); i++) 1034 printf("%02x", system_serial[i]); 1035 printf("\n"); 1036 } 1037 #elif defined(OVERO) 1038 static void 1039 find_cpu_clock(void) 1040 { 1041 const vaddr_t prm_base = OMAP2_PRM_BASE; 1042 const vaddr_t cm_base = OMAP2_CM_BASE; 1043 const uint32_t prm_clksel = 1044 *(volatile uint32_t *)(prm_base + PLL_MOD + OMAP3_PRM_CLKSEL); 1045 static const uint32_t prm_clksel_freqs[] = OMAP3_PRM_CLKSEL_FREQS; 1046 const uint32_t sys_clk = 1047 prm_clksel_freqs[__SHIFTOUT(prm_clksel, OMAP3_PRM_CLKSEL_CLKIN)]; 1048 const uint32_t dpll1 = 1049 *(volatile uint32_t *)(cm_base + OMAP3_CM_CLKSEL1_PLL_MPU); 1050 const uint32_t dpll2 = 1051 *(volatile uint32_t *)(cm_base + OMAP3_CM_CLKSEL2_PLL_MPU); 1052 const uint32_t m = 1053 __SHIFTOUT(dpll1, OMAP3_CM_CLKSEL1_PLL_MPU_DPLL_MULT); 1054 const uint32_t n = __SHIFTOUT(dpll1, OMAP3_CM_CLKSEL1_PLL_MPU_DPLL_DIV); 1055 const uint32_t m2 = 1056 __SHIFTOUT(dpll2, OMAP3_CM_CLKSEL2_PLL_MPU_DPLL_CLKOUT_DIV); 1057 1058 /* 1059 * MPU_CLK supplies ARM_FCLK which is twice the CPU frequency. 1060 */ 1061 curcpu()->ci_data.cpu_cc_freq = 1062 ((sys_clk * m) / ((n + 1) * m2 * 2)) * OMAP3_PRM_CLKSEL_MULT; 1063 omap_sys_clk = sys_clk * OMAP3_PRM_CLKSEL_MULT; 1064 } 1065 #endif 1066 1067 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 1068 static const char busheader_name[] = "busheader="; 1069 #endif 1070 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 1071 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 1072 static const char expansion_name[] = "expansion="; 1073 #endif 1074 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1075 static const char console_name[] = "console="; 1076 #endif 1077 static void 1078 process_kernel_args(int argc, char *argv[]) 1079 { 1080 int gxio_configured = 0, i, j; 1081 1082 boothowto = 0; 1083 1084 for (i = 1, j = 0; i < argc; i++) { 1085 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 1086 if (!strncmp(argv[i], busheader_name, strlen(busheader_name))) { 1087 /* Configure for GPIOs of busheader side */ 1088 gxio_config_expansion(argv[i] + strlen(busheader_name)); 1089 gxio_configured = 1; 1090 continue; 1091 } 1092 #endif 1093 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 1094 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 1095 if (!strncmp(argv[i], expansion_name, strlen(expansion_name))) { 1096 /* Configure expansion */ 1097 gxio_config_expansion(argv[i] + strlen(expansion_name)); 1098 gxio_configured = 1; 1099 continue; 1100 } 1101 #endif 1102 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1103 if (!strncmp(argv[i], console_name, strlen(console_name))) { 1104 strncpy(console, argv[i] + strlen(console_name), 1105 sizeof(console)); 1106 consinit(); 1107 } 1108 #endif 1109 if (j == bootargs_len) { 1110 *(bootargs + j) = '\0'; 1111 continue; 1112 } 1113 if (j != 0) 1114 *(bootargs + j++) = ' '; 1115 strncpy(bootargs + j, argv[i], bootargs_len - j); 1116 bootargs[bootargs_len] = '\0'; 1117 j += strlen(argv[i]); 1118 } 1119 boot_args = bootargs; 1120 1121 parse_mi_bootargs(boot_args); 1122 1123 if (!gxio_configured) 1124 gxio_config_expansion(NULL); 1125 } 1126 1127 static void 1128 process_kernel_args_liner(char *args) 1129 { 1130 int i = 0; 1131 char *p = NULL; 1132 1133 boothowto = 0; 1134 1135 strncpy(bootargs, args, sizeof(bootargs)); 1136 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 1137 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 1138 { 1139 char *q; 1140 1141 if ((p = strstr(bootargs, expansion_name))) 1142 q = p + strlen(expansion_name); 1143 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 1144 else if ((p = strstr(bootargs, busheader_name))) 1145 q = p + strlen(busheader_name); 1146 #endif 1147 if (p) { 1148 char expansion[256], c; 1149 1150 i = 0; 1151 do { 1152 c = *(q + i); 1153 if (c == ' ') 1154 c = '\0'; 1155 expansion[i++] = c; 1156 } while (c != '\0' && i < sizeof(expansion)); 1157 gxio_config_expansion(expansion); 1158 strcpy(p, q + i); 1159 } 1160 } 1161 #endif 1162 if (p == NULL) 1163 gxio_config_expansion(NULL); 1164 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1165 p = strstr(bootargs, console_name); 1166 if (p != NULL) { 1167 char c; 1168 1169 i = 0; 1170 do { 1171 c = *(p + strlen(console_name) + i); 1172 if (c == ' ') 1173 c = '\0'; 1174 console[i++] = c; 1175 } while (c != '\0' && i < sizeof(console)); 1176 consinit(); 1177 strcpy(p, p + strlen(console_name) + i); 1178 } 1179 #endif 1180 boot_args = bootargs; 1181 1182 parse_mi_bootargs(boot_args); 1183 } 1184 1185 #ifdef KGDB 1186 #ifndef KGDB_DEVNAME 1187 #define KGDB_DEVNAME "ffuart" 1188 #endif 1189 const char kgdb_devname[] = KGDB_DEVNAME; 1190 1191 #ifndef KGDB_DEVRATE 1192 #define KGDB_DEVRATE CONSPEED 1193 #endif 1194 int kgdb_devrate = KGDB_DEVRATE; 1195 1196 #if (NCOM > 0) 1197 #ifndef KGDB_DEVMODE 1198 #define KGDB_DEVMODE CONMODE 1199 #endif 1200 int comkgdbmode = KGDB_DEVMODE; 1201 #endif /* NCOM */ 1202 1203 #endif /* KGDB */ 1204 1205 1206 void 1207 consinit(void) 1208 { 1209 static int consinit_called = 0; 1210 1211 if (consinit_called != 0) 1212 return; 1213 1214 consinit_called = 1; 1215 1216 #if NCOM > 0 1217 1218 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1219 /* Maybe passed Linux's bootargs 'console=ttyS?,<speed>...' */ 1220 if (strncmp(console, "ttyS", 4) == 0 && console[5] == ',') { 1221 int i; 1222 1223 comcnspeed = 0; 1224 for (i = 6; i < strlen(console) && isdigit(console[i]); i++) 1225 comcnspeed = comcnspeed * 10 + (console[i] - '0'); 1226 } 1227 #endif 1228 1229 #if defined(GUMSTIX) 1230 1231 #ifdef FFUARTCONSOLE 1232 #ifdef KGDB 1233 if (strcmp(kgdb_devname, "ffuart") == 0){ 1234 /* port is reserved for kgdb */ 1235 } else 1236 #endif 1237 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1238 if (console[0] == '\0' || strcasecmp(console, "ffuart") == 0 || 1239 strncmp(console, "ttyS0,", 6) == 0) 1240 #endif 1241 { 1242 int rv; 1243 1244 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_FFUART_BASE, 1245 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1246 if (rv == 0) { 1247 pxa2x0_clkman_config(CKEN_FFUART, 1); 1248 return; 1249 } 1250 } 1251 #endif /* FFUARTCONSOLE */ 1252 1253 #ifdef STUARTCONSOLE 1254 #ifdef KGDB 1255 if (strcmp(kgdb_devname, "stuart") == 0) { 1256 /* port is reserved for kgdb */ 1257 } else 1258 #endif 1259 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1260 if (console[0] == '\0' || strcasecmp(console, "stuart") == 0) 1261 #endif 1262 { 1263 int rv; 1264 1265 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_STUART_BASE, 1266 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1267 if (rv == 0) { 1268 pxa2x0_clkman_config(CKEN_STUART, 1); 1269 return; 1270 } 1271 } 1272 #endif /* STUARTCONSOLE */ 1273 1274 #ifdef BTUARTCONSOLE 1275 #ifdef KGDB 1276 if (strcmp(kgdb_devname, "btuart") == 0) { 1277 /* port is reserved for kgdb */ 1278 } else 1279 #endif 1280 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1281 if (console[0] == '\0' || strcasecmp(console, "btuart") == 0) 1282 #endif 1283 { 1284 int rv; 1285 1286 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_BTUART_BASE, 1287 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1288 if (rv == 0) { 1289 pxa2x0_clkman_config(CKEN_BTUART, 1); 1290 return; 1291 } 1292 } 1293 #endif /* BTUARTCONSOLE */ 1294 1295 #ifdef HWUARTCONSOLE 1296 #ifdef KGDB 1297 if (strcmp(kgdb_devname, "hwuart") == 0) { 1298 /* port is reserved for kgdb */ 1299 } else 1300 #endif 1301 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1302 if (console[0] == '\0' || strcasecmp(console, "hwuart") == 0) 1303 #endif 1304 { 1305 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_HWUART_BASE, 1306 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1307 if (rv == 0) { 1308 pxa2x0_clkman_config(CKEN_HWUART, 1); 1309 return; 1310 } 1311 } 1312 #endif /* HWUARTCONSOLE */ 1313 1314 #elif defined(OVERO) 1315 1316 if (comcnattach(&omap_a4x_bs_tag, 0x49020000, comcnspeed, 1317 OMAP_COM_FREQ, COM_TYPE_NORMAL, comcnmode) == 0) 1318 return; 1319 1320 #endif /* GUMSTIX or OVERO */ 1321 1322 #endif /* NCOM */ 1323 1324 #if NLCD > 0 1325 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1326 if (console[0] == '\0' || strcasecmp(console, "lcd") == 0) 1327 #endif 1328 { 1329 gxlcd_cnattach(); 1330 } 1331 #endif 1332 } 1333 1334 #ifdef KGDB 1335 static void 1336 kgdb_port_init(void) 1337 { 1338 #if (NCOM > 0) && defined(COM_PXA2X0) 1339 paddr_t paddr = 0; 1340 int cken = 0; 1341 1342 if (0 == strcmp(kgdb_devname, "ffuart")) { 1343 paddr = PXA2X0_FFUART_BASE; 1344 cken = CKEN_FFUART; 1345 } else if (0 == strcmp(kgdb_devname, "stuart")) { 1346 paddr = PXA2X0_STUART_BASE; 1347 cken = CKEN_STUART; 1348 } else if (0 == strcmp(kgdb_devname, "btuart")) { 1349 paddr = PXA2X0_BTUART_BASE; 1350 cken = CKEN_BTUART; 1351 } else if (0 == strcmp(kgdb_devname, "hwuart")) { 1352 paddr = PXA2X0_HWUART_BASE; 1353 cken = CKEN_HWUART; 1354 } 1355 1356 if (paddr && 1357 0 == com_kgdb_attach(&pxa2x0_a4x_bs_tag, paddr, 1358 kgdb_devrate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode)) { 1359 1360 pxa2x0_clkman_config(cken, 1); 1361 } 1362 1363 #endif 1364 } 1365 #endif 1366 1367 static void 1368 gumstix_device_register(device_t dev, void *aux) 1369 { 1370 prop_dictionary_t dict = device_properties(dev); 1371 1372 if (device_is_a(dev, "ehci")) { 1373 prop_dictionary_set_cstring(dict, "port0-mode", "none"); 1374 prop_dictionary_set_cstring(dict, "port1-mode", "phy"); 1375 prop_dictionary_set_cstring(dict, "port2-mode", "none"); 1376 prop_dictionary_set_bool(dict, "phy-reset", true); 1377 prop_dictionary_set_int16(dict, "port0-gpio", -1); 1378 prop_dictionary_set_int16(dict, "port1-gpio", 183); 1379 prop_dictionary_set_int16(dict, "port2-gpio", -1); 1380 prop_dictionary_set_uint16(dict, "dpll5-m", 443); 1381 prop_dictionary_set_uint16(dict, "dpll5-n", 11); 1382 prop_dictionary_set_uint16(dict, "dpll5-m2", 4); 1383 } 1384 if (device_is_a(dev, "ohci")) { 1385 if (prop_dictionary_set_bool(dict, 1386 "Ganged-power-mask-on-port1", 1) == false) { 1387 printf("WARNING: unable to set power-mask for port1" 1388 " property for %s\n", device_xname(dev)); 1389 } 1390 if (prop_dictionary_set_bool(dict, 1391 "Ganged-power-mask-on-port2", 1) == false) { 1392 printf("WARNING: unable to set power-mask for port2" 1393 " property for %s\n", device_xname(dev)); 1394 } 1395 if (prop_dictionary_set_bool(dict, 1396 "Ganged-power-mask-on-port3", 1) == false) { 1397 printf("WARNING: unable to set power-mask for port3" 1398 " property for %s\n", device_xname(dev)); 1399 } 1400 } 1401 } 1402