1 /* $NetBSD: gumstix_machdep.c,v 1.46 2012/12/24 06:53:26 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 166 #include <machine/autoconf.h> 167 #include <machine/bootconfig.h> 168 #include <sys/bus.h> 169 #include <machine/cpu.h> 170 #include <machine/db_machdep.h> 171 #include <machine/frame.h> 172 173 #include <arm/arm32/machdep.h> 174 #ifdef OVERO 175 #include <arm/omap/omap2_gpmcreg.h> 176 #include <arm/omap/omap2_prcm.h> 177 #include <arm/omap/omap2_reg.h> 178 #include <arm/omap/omap_var.h> 179 #include <arm/omap/omap_com.h> 180 #endif 181 #include <arm/undefined.h> 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 #endif 252 static void process_kernel_args(int, char *[]); 253 static void process_kernel_args_liner(char *); 254 #ifdef KGDB 255 static void kgdb_port_init(void); 256 #endif 257 static void gumstix_device_register(device_t, void *); 258 259 bs_protos(bs_notimpl); 260 261 #include "com.h" 262 #if NCOM > 0 263 #include <dev/ic/comreg.h> 264 #include <dev/ic/comvar.h> 265 #endif 266 267 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 268 #include "lcd.h" 269 #endif 270 271 #ifndef CONSPEED 272 #define CONSPEED B115200 /* It's a setting of the default of u-boot */ 273 #endif 274 #ifndef CONMODE 275 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 276 #endif 277 278 int comcnspeed = CONSPEED; 279 int comcnmode = CONMODE; 280 281 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 282 static char console[16]; 283 #endif 284 285 extern void gxio_config_pin(void); 286 extern void gxio_config_expansion(char *); 287 288 /* 289 * void cpu_reboot(int howto, char *bootstr) 290 * 291 * Deal with any syncing, unmounting, dumping and shutdown hooks, 292 * then reset the CPU. 293 */ 294 void 295 cpu_reboot(int howto, char *bootstr) 296 { 297 298 #ifdef DIAGNOSTIC 299 /* info */ 300 printf("boot: howto=%08x curproc=%p\n", howto, curproc); 301 #endif 302 303 /* 304 * If we are still cold then hit the air brakes 305 * and crash to earth fast 306 */ 307 if (cold) { 308 doshutdownhooks(); 309 pmf_system_shutdown(boothowto); 310 printf("The operating system has halted.\n"); 311 printf("Please press any key to reboot.\n\n"); 312 cngetc(); 313 printf("rebooting...\n"); 314 #if defined(OMAP_3530) && NPRCM > 0 315 prcm_cold_reset(); 316 #endif 317 cpu_reset(); 318 /*NOTREACHED*/ 319 } 320 321 /* 322 * If RB_NOSYNC was not specified sync the discs. 323 * Note: Unless cold is set to 1 here, syslogd will die during the 324 * unmount. It looks like syslogd is getting woken up only to find 325 * that it cannot page part of the binary in as the filesystem has 326 * been unmounted. 327 */ 328 if (!(howto & RB_NOSYNC)) 329 bootsync(); 330 331 /* Say NO to interrupts */ 332 splhigh(); 333 334 /* Do a dump if requested. */ 335 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 336 dumpsys(); 337 338 /* Run any shutdown hooks */ 339 doshutdownhooks(); 340 341 pmf_system_shutdown(boothowto); 342 343 /* Make sure IRQ's are disabled */ 344 IRQdisable; 345 346 if (howto & RB_HALT) { 347 printf("The operating system has halted.\n"); 348 printf("Please press any key to reboot.\n\n"); 349 cngetc(); 350 } 351 352 printf("rebooting...\n"); 353 #if defined(OMAP_3530) && NPRCM > 0 354 prcm_cold_reset(); 355 #endif 356 cpu_reset(); 357 /*NOTREACHED*/ 358 } 359 360 static inline pd_entry_t * 361 read_ttb(void) 362 { 363 long ttb; 364 365 __asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb)); 366 367 return (pd_entry_t *)(ttb & ~((1<<14)-1)); 368 } 369 370 /* 371 * Static device mappings. These peripheral registers are mapped at 372 * fixed virtual addresses very early in initarm() so that we can use 373 * them while booting the kernel, and stay at the same address 374 * throughout whole kernel's life time. 375 * 376 * We use this table twice; once with bootstrap page table, and once 377 * with kernel's page table which we build up in initarm(). 378 * 379 * Since we map these registers into the bootstrap page table using 380 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map 381 * registers segment-aligned and segment-rounded in order to avoid 382 * using the 2nd page tables. 383 */ 384 385 #define _A(a) ((a) & ~L1_S_OFFSET) 386 #define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1)) 387 388 static const struct pmap_devmap gumstix_devmap[] = { 389 #if defined(GUMSTIX) 390 { 391 GUMSTIX_GPIO_VBASE, 392 _A(PXA2X0_GPIO_BASE), 393 _S(PXA250_GPIO_SIZE), 394 VM_PROT_READ | VM_PROT_WRITE, 395 PTE_NOCACHE, 396 }, 397 { 398 GUMSTIX_CLKMAN_VBASE, 399 _A(PXA2X0_CLKMAN_BASE), 400 _S(PXA2X0_CLKMAN_SIZE), 401 VM_PROT_READ | VM_PROT_WRITE, 402 PTE_NOCACHE, 403 }, 404 { 405 GUMSTIX_INTCTL_VBASE, 406 _A(PXA2X0_INTCTL_BASE), 407 _S(PXA2X0_INTCTL_SIZE), 408 VM_PROT_READ | VM_PROT_WRITE, 409 PTE_NOCACHE, 410 }, 411 { 412 GUMSTIX_FFUART_VBASE, 413 _A(PXA2X0_FFUART_BASE), 414 _S(4 * COM_NPORTS), 415 VM_PROT_READ | VM_PROT_WRITE, 416 PTE_NOCACHE, 417 }, 418 { 419 GUMSTIX_STUART_VBASE, 420 _A(PXA2X0_STUART_BASE), 421 _S(4 * COM_NPORTS), 422 VM_PROT_READ | VM_PROT_WRITE, 423 PTE_NOCACHE, 424 }, 425 { 426 GUMSTIX_BTUART_VBASE, 427 _A(PXA2X0_BTUART_BASE), 428 _S(4 * COM_NPORTS), 429 VM_PROT_READ | VM_PROT_WRITE, 430 PTE_NOCACHE, 431 }, 432 { 433 GUMSTIX_HWUART_VBASE, 434 _A(PXA2X0_HWUART_BASE), 435 _S(4 * COM_NPORTS), 436 VM_PROT_READ | VM_PROT_WRITE, 437 PTE_NOCACHE, 438 }, 439 { 440 GUMSTIX_LCDC_VBASE, 441 _A(PXA2X0_LCDC_BASE), 442 _S(4 * COM_NPORTS), 443 VM_PROT_READ | VM_PROT_WRITE, 444 PTE_NOCACHE, 445 }, 446 #elif defined(OVERO) 447 { 448 OVERO_L4_PERIPHERAL_VBASE, 449 _A(OMAP3530_L4_PERIPHERAL_BASE), 450 _S(OMAP3530_L4_PERIPHERAL_SIZE), 451 VM_PROT_READ | VM_PROT_WRITE, 452 PTE_NOCACHE 453 }, 454 { 455 OVERO_GPMC_VBASE, 456 _A(GPMC_BASE), 457 _S(GPMC_SIZE), 458 VM_PROT_READ | VM_PROT_WRITE, 459 PTE_NOCACHE 460 }, 461 #endif 462 { 0, 0, 0, 0, 0 } 463 }; 464 465 #undef _A 466 #undef _S 467 468 469 /* 470 * u_int initarm(...) 471 * 472 * Initial entry point on startup. This gets called before main() is 473 * entered. 474 * It should be responsible for setting up everything that must be 475 * in place when main is called. 476 * This includes 477 * Taking a copy of the boot configuration structure. 478 * Initialising the physical console so characters can be printed. 479 * Setting up page tables for the kernel 480 * Relocating the kernel to the bottom of physical memory 481 */ 482 u_int 483 initarm(void *arg) 484 { 485 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 486 #ifdef DIAGNOSTIC 487 extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */ 488 #endif 489 extern vaddr_t xscale_cache_clean_addr; 490 #endif 491 extern uint32_t *u_boot_args[]; 492 extern uint32_t ram_size; 493 enum { r0 = 0, r1 = 1, r2 = 2, r3 = 3 }; /* args from u-boot */ 494 int loop; 495 int loop1; 496 u_int l1pagetable; 497 paddr_t memstart; 498 psize_t memsize; 499 500 /* 501 * U-Boot doesn't use the virtual memory. 502 * 503 * Gumstix (basix, connex, verdex, verdex-pro): 504 * Physical Address Range Description 505 * ----------------------- ---------------------------------- 506 * 0x00000000 - 0x00ffffff flash Memory (16MB or 4MB) 507 * 0x40000000 - 0x480fffff Processor Registers 508 * 0xa0000000 - 0xa3ffffff SDRAM Bank 0 (64MB or 128MB) 509 * 510 * Overo: 511 * Physical Address Range Description 512 * ----------------------- ---------------------------------- 513 */ 514 515 /* 516 * Heads up ... Setup the CPU / MMU / TLB functions 517 */ 518 if (set_cpufuncs()) 519 panic("cpu not recognized!"); 520 521 /* map some peripheral registers at static I/O area */ 522 pmap_devmap_bootstrap((vaddr_t)read_ttb(), gumstix_devmap); 523 524 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 525 /* start 32.768kHz OSC */ 526 ioreg_write(GUMSTIX_CLKMAN_VBASE + CLKMAN_OSCC, OSCC_OON); 527 528 /* Get ready for splfoo() */ 529 pxa2x0_intr_bootstrap(GUMSTIX_INTCTL_VBASE); 530 531 /* setup GPIO for {FF,ST,HW}UART. */ 532 pxa2x0_gpio_bootstrap(GUMSTIX_GPIO_VBASE); 533 534 pxa2x0_clkman_bootstrap(GUMSTIX_CLKMAN_VBASE); 535 #elif defined(CPU_CORTEX) 536 cortex_pmc_ccnt_init(); 537 #endif 538 539 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 540 541 /* configure GPIOs. */ 542 gxio_config_pin(); 543 544 545 #ifndef GUMSTIX_NETBSD_ARGS_CONSOLE 546 consinit(); 547 #endif 548 #ifdef KGDB 549 kgdb_port_init(); 550 #endif 551 552 /* 553 * Examine the boot args string for options we need to know about 554 * now. 555 */ 556 #if defined(GUMSTIX) 557 #define SDRAM_START 0xa0000000UL 558 #elif defined(OVERO) 559 #define SDRAM_START 0x80000000UL 560 #endif 561 if (((uint32_t)u_boot_args[r0] & 0xf0000000) != SDRAM_START) 562 /* Maybe r0 is 'argc'. We are booted by command 'go'. */ 563 process_kernel_args((int)u_boot_args[r0], 564 (char **)u_boot_args[r1]); 565 else 566 /* 567 * Maybe r3 is 'boot args string' of 'bootm'. This string is 568 * linely. 569 */ 570 process_kernel_args_liner((char *)u_boot_args[r3]); 571 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 572 consinit(); 573 #endif 574 575 /* Talk to the user */ 576 #define BDSTR(s) _BDSTR(s) 577 #define _BDSTR(s) #s 578 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); 579 580 /* Read system serial */ 581 #if defined(GUMSTIX) 582 read_system_serial(); 583 #endif 584 585 memstart = SDRAM_START; 586 memsize = ram_size; 587 588 #ifdef VERBOSE_INIT_ARM 589 printf("initarm: Configuring system ...\n"); 590 #endif 591 592 /* Fake bootconfig structure for the benefit of pmap.c */ 593 /* XXX must make the memory description h/w independent */ 594 bootconfig.dramblocks = 1; 595 bootconfig.dram[0].address = memstart; 596 bootconfig.dram[0].pages = memsize / PAGE_SIZE; 597 598 /* 599 * Set up the variables that define the availablilty of 600 * physical memory. For now, we're going to set 601 * physical_freestart to 0xa0200000 (where the kernel 602 * was loaded), and allocate the memory we need downwards. 603 * If we get too close to the L1 table that we set up, we 604 * will panic. We will update physical_freestart and 605 * physical_freeend later to reflect what pmap_bootstrap() 606 * wants to see. 607 * 608 * XXX pmap_bootstrap() needs an enema. 609 */ 610 physical_start = bootconfig.dram[0].address; 611 physical_end = physical_start + memsize; 612 613 #if defined(GUMSTIX) 614 physical_freestart = 0xa0009000UL; 615 physical_freeend = 0xa0200000UL; 616 #elif defined(OVERO) 617 physical_freestart = 0x80009000UL; 618 physical_freeend = 0x80200000UL; 619 #endif 620 621 physmem = (physical_end - physical_start) / PAGE_SIZE; 622 623 #ifdef VERBOSE_INIT_ARM 624 /* Tell the user about the memory */ 625 printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem, 626 physical_start, physical_end - 1); 627 #endif 628 629 /* 630 * Okay, the kernel starts 2MB in from the bottom of physical 631 * memory. We are going to allocate our bootstrap pages downwards 632 * from there. 633 * 634 * We need to allocate some fixed page tables to get the kernel 635 * going. We allocate one page directory and a number of page 636 * tables and store the physical addresses in the kernel_pt_table 637 * array. 638 * 639 * The kernel page directory must be on a 16K boundary. The page 640 * tables must be on 4K bounaries. What we do is allocate the 641 * page directory on the first 16K boundary that we encounter, and 642 * the page tables on 4K boundaries otherwise. Since we allocate 643 * at least 3 L2 page tables, we are guaranteed to encounter at 644 * least one 16K aligned region. 645 */ 646 647 #ifdef VERBOSE_INIT_ARM 648 printf("Allocating page tables\n"); 649 #endif 650 651 free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE; 652 653 #ifdef VERBOSE_INIT_ARM 654 printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n", 655 physical_freestart, free_pages, free_pages); 656 #endif 657 658 /* Define a macro to simplify memory allocation */ 659 #define valloc_pages(var, np) \ 660 alloc_pages((var).pv_pa, (np)); \ 661 (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start; 662 663 #define alloc_pages(var, np) \ 664 physical_freeend -= ((np) * PAGE_SIZE); \ 665 if (physical_freeend < physical_freestart) \ 666 panic("initarm: out of memory"); \ 667 (var) = physical_freeend; \ 668 free_pages -= (np); \ 669 memset((char *)(var), 0, ((np) * PAGE_SIZE)); 670 671 loop1 = 0; 672 for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { 673 /* Are we 16KB aligned for an L1 ? */ 674 if ((physical_freeend & (L1_TABLE_SIZE - 1)) == 0 && 675 kernel_l1pt.pv_pa == 0) { 676 valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); 677 } else { 678 valloc_pages(kernel_pt_table[loop1], 679 L2_TABLE_SIZE / PAGE_SIZE); 680 ++loop1; 681 } 682 } 683 684 /* This should never be able to happen but better confirm that. */ 685 if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0) 686 panic("initarm: Failed to align the kernel page directory"); 687 688 /* 689 * Allocate a page for the system page mapped to V0x00000000 690 * This page will just contain the system vectors and can be 691 * shared by all processes. 692 */ 693 alloc_pages(systempage.pv_pa, 1); 694 #if defined(CPU_CORTEXA8) 695 systempage.pv_va = ARM_VECTORS_HIGH; 696 #endif 697 698 /* Allocate stacks for all modes */ 699 valloc_pages(irqstack, IRQ_STACK_SIZE); 700 valloc_pages(abtstack, ABT_STACK_SIZE); 701 valloc_pages(undstack, UND_STACK_SIZE); 702 valloc_pages(kernelstack, UPAGES); 703 704 /* Allocate enough pages for cleaning the Mini-Data cache. */ 705 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 706 KASSERT(xscale_minidata_clean_size <= PAGE_SIZE); 707 #endif 708 valloc_pages(minidataclean, 1); 709 710 #ifdef VERBOSE_INIT_ARM 711 printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, 712 irqstack.pv_va); 713 printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, 714 abtstack.pv_va); 715 printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, 716 undstack.pv_va); 717 printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, 718 kernelstack.pv_va); 719 #endif 720 721 /* 722 * XXX Defer this to later so that we can reclaim the memory 723 * XXX used by the RedBoot page tables. 724 */ 725 alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE); 726 727 /* 728 * Ok we have allocated physical pages for the primary kernel 729 * page tables 730 */ 731 732 #ifdef VERBOSE_INIT_ARM 733 printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa); 734 #endif 735 736 /* 737 * Now we start construction of the L1 page table 738 * We start by mapping the L2 page tables into the L1. 739 * This means that we can replace L1 mappings later on if necessary 740 */ 741 l1pagetable = kernel_l1pt.pv_va; 742 743 /* Map the L2 pages tables in the L1 page table */ 744 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 745 pmap_link_l2pt(l1pagetable, 0x00000000, 746 &kernel_pt_table[KERNEL_PT_SYS]); 747 #elif defined(CPU_CORTEXA8) 748 pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00400000 - 1), 749 &kernel_pt_table[KERNEL_PT_SYS]); 750 #endif 751 for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) 752 pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000, 753 &kernel_pt_table[KERNEL_PT_KERNEL + loop]); 754 for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++) 755 pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, 756 &kernel_pt_table[KERNEL_PT_VMDATA + loop]); 757 758 /* update the top of the kernel VM */ 759 pmap_curmaxkvaddr = 760 KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000); 761 762 #ifdef VERBOSE_INIT_ARM 763 printf("Mapping kernel\n"); 764 #endif 765 766 /* Now we fill in the L2 pagetable for the kernel static code/data */ 767 { 768 extern char etext[], _end[]; 769 size_t textsize = (uintptr_t) etext - KERNEL_TEXT_BASE; 770 size_t totalsize = (uintptr_t) _end - KERNEL_TEXT_BASE; 771 u_int logical; 772 773 textsize = (textsize + PGOFSET) & ~PGOFSET; 774 totalsize = (totalsize + PGOFSET) & ~PGOFSET; 775 776 logical = 0x00200000; /* offset of kernel in RAM */ 777 778 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 779 physical_start + logical, textsize, 780 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 781 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 782 physical_start + logical, totalsize - textsize, 783 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 784 } 785 786 #ifdef VERBOSE_INIT_ARM 787 printf("Constructing L2 page tables\n"); 788 #endif 789 790 /* Map the stack pages */ 791 pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, 792 IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 793 pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa, 794 ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 795 pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa, 796 UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 797 pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa, 798 UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE); 799 800 pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, 801 L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE); 802 803 for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { 804 pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va, 805 kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE, 806 VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); 807 } 808 809 /* Map the Mini-Data cache clean area. */ 810 #if defined(GUMSTIX) 811 xscale_setup_minidata(l1pagetable, minidataclean.pv_va, 812 minidataclean.pv_pa); 813 #endif 814 815 /* Map the vector page. */ 816 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 817 #if 1 818 /* MULTI-ICE requires that page 0 is NC/NB so that it can download the 819 * cache-clean code there. */ 820 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, 821 VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); 822 #else 823 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, 824 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 825 #endif 826 #elif defined(CPU_CORTEXA8) 827 pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, 828 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 829 #endif 830 831 /* 832 * map integrated peripherals at same address in l1pagetable 833 * so that we can continue to use console. 834 */ 835 pmap_devmap_bootstrap(l1pagetable, gumstix_devmap); 836 837 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 838 /* 839 * Give the XScale global cache clean code an appropriately 840 * sized chunk of unmapped VA space starting at 0xff000000 841 * (our device mappings end before this address). 842 */ 843 xscale_cache_clean_addr = 0xff000000U; 844 #endif 845 846 /* 847 * Now we have the real page tables in place so we can switch to them. 848 * Once this is done we will be running with the REAL kernel page 849 * tables. 850 */ 851 852 /* 853 * Update the physical_freestart/physical_freeend/free_pages 854 * variables. 855 */ 856 { 857 extern char _end[]; 858 859 physical_freestart = physical_start + 860 (((((uintptr_t) _end) + PGOFSET) & ~PGOFSET) - 861 KERNEL_BASE); 862 physical_freeend = physical_end; 863 free_pages = 864 (physical_freeend - physical_freestart) / PAGE_SIZE; 865 } 866 867 /* Switch tables */ 868 #ifdef VERBOSE_INIT_ARM 869 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n", 870 physical_freestart, free_pages, free_pages); 871 printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa); 872 #endif 873 874 cpu_setttb(kernel_l1pt.pv_pa, true); 875 cpu_tlb_flushID(); 876 cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); 877 878 /* 879 * Moved from cpu_startup() as data_abort_handler() references 880 * this during uvm init 881 */ 882 uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); 883 884 #ifdef VERBOSE_INIT_ARM 885 printf("bootstrap done.\n"); 886 #endif 887 888 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 889 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); 890 #elif defined(CPU_CORTEXA8) 891 arm32_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL); 892 #endif 893 894 /* 895 * Pages were allocated during the secondary bootstrap for the 896 * stacks for different CPU modes. 897 * We must now set the r13 registers in the different CPU modes to 898 * point to these stacks. 899 * Since the ARM stacks use STMFD etc. we must set r13 to the top end 900 * of the stack memory. 901 */ 902 #ifdef VERBOSE_INIT_ARM 903 printf("init subsystems: stacks "); 904 #endif 905 906 set_stackptr(PSR_IRQ32_MODE, 907 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); 908 set_stackptr(PSR_ABT32_MODE, 909 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); 910 set_stackptr(PSR_UND32_MODE, 911 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); 912 913 /* 914 * Well we should set a data abort handler. 915 * Once things get going this will change as we will need a proper 916 * handler. 917 * Until then we will use a handler that just panics but tells us 918 * why. 919 * Initialisation of the vectors will just panic on a data abort. 920 * This just fills in a slighly better one. 921 */ 922 #ifdef VERBOSE_INIT_ARM 923 printf("vectors "); 924 #endif 925 data_abort_handler_address = (u_int)data_abort_handler; 926 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 927 undefined_handler_address = (u_int)undefinedinstruction_bounce; 928 929 /* Initialise the undefined instruction handlers */ 930 #ifdef VERBOSE_INIT_ARM 931 printf("undefined "); 932 #endif 933 undefined_init(); 934 935 /* Load memory into UVM. */ 936 #ifdef VERBOSE_INIT_ARM 937 printf("page "); 938 #endif 939 uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ 940 uvm_page_physload(atop(physical_freestart), atop(physical_freeend), 941 atop(physical_freestart), atop(physical_freeend), 942 VM_FREELIST_DEFAULT); 943 944 /* Boot strap pmap telling it where the kernel page table is */ 945 #ifdef VERBOSE_INIT_ARM 946 printf("pmap "); 947 #endif 948 pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); 949 950 #ifdef __HAVE_MEMORY_DISK__ 951 md_root_setconf(memory_disk, sizeof memory_disk); 952 #endif 953 954 #ifdef BOOTHOWTO 955 boothowto |= BOOTHOWTO; 956 #endif 957 958 #ifdef KGDB 959 if (boothowto & RB_KDB) { 960 kgdb_debug_init = 1; 961 kgdb_connect(1); 962 } 963 #endif 964 965 #if NKSYMS || defined(DDB) || defined(MODULAR) 966 /* Firmware doesn't load symbols. */ 967 ddb_init(0, NULL, NULL); 968 #endif 969 970 #ifdef DDB 971 db_machine_init(); 972 if (boothowto & RB_KDB) 973 Debugger(); 974 #endif 975 976 /* We have our own device_register() */ 977 evbarm_device_register = gumstix_device_register; 978 979 /* We return the new stack pointer address */ 980 return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); 981 } 982 983 #if defined(GUMSTIX) 984 static void 985 read_system_serial(void) 986 { 987 #define GUMSTIX_SYSTEM_SERIAL_ADDR 0 988 #define GUMSTIX_SYSTEM_SERIAL_SIZE 8 989 #define FLASH_OFFSET_INTEL_PROTECTION 0x81 990 #define FLASH_OFFSET_USER_PROTECTION 0x85 991 #define FLASH_CMD_READ_ID 0x90 992 #define FLASH_CMD_RESET 0xff 993 int i; 994 char system_serial[GUMSTIX_SYSTEM_SERIAL_SIZE], *src; 995 char x; 996 997 src = (char *)(FLASH_OFFSET_USER_PROTECTION * 2 /*word*/); 998 *(volatile uint16_t *)0 = FLASH_CMD_READ_ID; 999 memcpy(system_serial, 1000 src + GUMSTIX_SYSTEM_SERIAL_ADDR, sizeof (system_serial)); 1001 *(volatile uint16_t *)0 = FLASH_CMD_RESET; 1002 1003 for (i = 1, x = system_serial[0]; i < sizeof (system_serial); i++) 1004 x &= system_serial[i]; 1005 if (x == 0xff) { 1006 src = (char *)(FLASH_OFFSET_INTEL_PROTECTION * 2 /*word*/); 1007 *(volatile uint16_t *)0 = FLASH_CMD_READ_ID; 1008 memcpy(system_serial, 1009 src + GUMSTIX_SYSTEM_SERIAL_ADDR, sizeof (system_serial)); 1010 *(volatile uint16_t *)0 = FLASH_CMD_RESET; 1011 1012 /* 1013 * XXXX: Don't need ??? 1014 * gumstix_serial_hash(system_serial); 1015 */ 1016 } 1017 system_serial_high = system_serial[0] << 24 | system_serial[1] << 16 | 1018 system_serial[2] << 8 | system_serial[3]; 1019 system_serial_low = system_serial[4] << 24 | system_serial[5] << 16 | 1020 system_serial[6] << 8 | system_serial[7]; 1021 1022 printf("system serial: 0x"); 1023 for (i = 0; i < sizeof (system_serial); i++) 1024 printf("%02x", system_serial[i]); 1025 printf("\n"); 1026 } 1027 #endif 1028 1029 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 1030 static const char busheader_name[] = "busheader="; 1031 #endif 1032 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 1033 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 1034 static const char expansion_name[] = "expansion="; 1035 #endif 1036 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1037 static const char console_name[] = "console="; 1038 #endif 1039 static void 1040 process_kernel_args(int argc, char *argv[]) 1041 { 1042 int gxio_configured = 0, i, j; 1043 1044 boothowto = 0; 1045 1046 for (i = 1, j = 0; i < argc; i++) { 1047 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 1048 if (!strncmp(argv[i], busheader_name, strlen(busheader_name))) { 1049 /* Configure for GPIOs of busheader side */ 1050 gxio_config_expansion(argv[i] + strlen(busheader_name)); 1051 gxio_configured = 1; 1052 continue; 1053 } 1054 #endif 1055 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 1056 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 1057 if (!strncmp(argv[i], expansion_name, strlen(expansion_name))) { 1058 /* Configure expansion */ 1059 gxio_config_expansion(argv[i] + strlen(expansion_name)); 1060 gxio_configured = 1; 1061 continue; 1062 } 1063 #endif 1064 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1065 if (!strncmp(argv[i], console_name, strlen(console_name))) { 1066 strncpy(console, argv[i] + strlen(console_name), 1067 sizeof(console)); 1068 consinit(); 1069 } 1070 #endif 1071 if (j == bootargs_len) { 1072 *(bootargs + j) = '\0'; 1073 continue; 1074 } 1075 if (j != 0) 1076 *(bootargs + j++) = ' '; 1077 strncpy(bootargs + j, argv[i], bootargs_len - j); 1078 bootargs[bootargs_len] = '\0'; 1079 j += strlen(argv[i]); 1080 } 1081 boot_args = bootargs; 1082 1083 parse_mi_bootargs(boot_args); 1084 1085 if (!gxio_configured) 1086 gxio_config_expansion(NULL); 1087 } 1088 1089 static void 1090 process_kernel_args_liner(char *args) 1091 { 1092 int i = 0; 1093 char *p = NULL; 1094 1095 boothowto = 0; 1096 1097 strncpy(bootargs, args, sizeof(bootargs)); 1098 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 1099 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 1100 { 1101 char *q; 1102 1103 if ((p = strstr(bootargs, expansion_name))) 1104 q = p + strlen(expansion_name); 1105 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 1106 else if ((p = strstr(bootargs, busheader_name))) 1107 q = p + strlen(busheader_name); 1108 #endif 1109 if (p) { 1110 char expansion[256], c; 1111 1112 i = 0; 1113 do { 1114 c = *(q + i); 1115 if (c == ' ') 1116 c = '\0'; 1117 expansion[i++] = c; 1118 } while (c != '\0' && i < sizeof(expansion)); 1119 gxio_config_expansion(expansion); 1120 strcpy(p, q + i); 1121 } 1122 } 1123 #endif 1124 if (p == NULL) 1125 gxio_config_expansion(NULL); 1126 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1127 p = strstr(bootargs, console_name); 1128 if (p != NULL) { 1129 char c; 1130 1131 i = 0; 1132 do { 1133 c = *(p + strlen(console_name) + i); 1134 if (c == ' ') 1135 c = '\0'; 1136 console[i++] = c; 1137 } while (c != '\0' && i < sizeof(console)); 1138 consinit(); 1139 strcpy(p, p + strlen(console_name) + i); 1140 } 1141 #endif 1142 boot_args = bootargs; 1143 1144 parse_mi_bootargs(boot_args); 1145 } 1146 1147 #ifdef KGDB 1148 #ifndef KGDB_DEVNAME 1149 #define KGDB_DEVNAME "ffuart" 1150 #endif 1151 const char kgdb_devname[] = KGDB_DEVNAME; 1152 1153 #ifndef KGDB_DEVRATE 1154 #define KGDB_DEVRATE CONSPEED 1155 #endif 1156 int kgdb_devrate = KGDB_DEVRATE; 1157 1158 #if (NCOM > 0) 1159 #ifndef KGDB_DEVMODE 1160 #define KGDB_DEVMODE CONMODE 1161 #endif 1162 int comkgdbmode = KGDB_DEVMODE; 1163 #endif /* NCOM */ 1164 1165 #endif /* KGDB */ 1166 1167 1168 void 1169 consinit(void) 1170 { 1171 static int consinit_called = 0; 1172 1173 if (consinit_called != 0) 1174 return; 1175 1176 consinit_called = 1; 1177 1178 #if NCOM > 0 1179 1180 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 1181 /* Maybe passed Linux's bootargs 'console=ttyS?,<speed>...' */ 1182 if (strncmp(console, "ttyS", 4) == 0 && console[5] == ',') { 1183 int i; 1184 1185 comcnspeed = 0; 1186 for (i = 6; i < strlen(console) && isdigit(console[i]); i++) 1187 comcnspeed = comcnspeed * 10 + (console[i] - '0'); 1188 } 1189 #endif 1190 1191 #if defined(GUMSTIX) 1192 1193 #ifdef FFUARTCONSOLE 1194 #ifdef KGDB 1195 if (strcmp(kgdb_devname, "ffuart") == 0){ 1196 /* port is reserved for kgdb */ 1197 } else 1198 #endif 1199 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1200 if (console[0] == '\0' || strcasecmp(console, "ffuart") == 0 || 1201 strncmp(console, "ttyS0,", 6) == 0) 1202 #endif 1203 { 1204 int rv; 1205 1206 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_FFUART_BASE, 1207 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1208 if (rv == 0) { 1209 pxa2x0_clkman_config(CKEN_FFUART, 1); 1210 return; 1211 } 1212 } 1213 #endif /* FFUARTCONSOLE */ 1214 1215 #ifdef STUARTCONSOLE 1216 #ifdef KGDB 1217 if (strcmp(kgdb_devname, "stuart") == 0) { 1218 /* port is reserved for kgdb */ 1219 } else 1220 #endif 1221 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1222 if (console[0] == '\0' || strcasecmp(console, "stuart") == 0) 1223 #endif 1224 { 1225 int rv; 1226 1227 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_STUART_BASE, 1228 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1229 if (rv == 0) { 1230 pxa2x0_clkman_config(CKEN_STUART, 1); 1231 return; 1232 } 1233 } 1234 #endif /* STUARTCONSOLE */ 1235 1236 #ifdef BTUARTCONSOLE 1237 #ifdef KGDB 1238 if (strcmp(kgdb_devname, "btuart") == 0) { 1239 /* port is reserved for kgdb */ 1240 } else 1241 #endif 1242 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1243 if (console[0] == '\0' || strcasecmp(console, "btuart") == 0) 1244 #endif 1245 { 1246 int rv; 1247 1248 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_BTUART_BASE, 1249 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1250 if (rv == 0) { 1251 pxa2x0_clkman_config(CKEN_BTUART, 1); 1252 return; 1253 } 1254 } 1255 #endif /* BTUARTCONSOLE */ 1256 1257 #ifdef HWUARTCONSOLE 1258 #ifdef KGDB 1259 if (strcmp(kgdb_devname, "hwuart") == 0) { 1260 /* port is reserved for kgdb */ 1261 } else 1262 #endif 1263 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1264 if (console[0] == '\0' || strcasecmp(console, "hwuart") == 0) 1265 #endif 1266 { 1267 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_HWUART_BASE, 1268 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 1269 if (rv == 0) { 1270 pxa2x0_clkman_config(CKEN_HWUART, 1); 1271 return; 1272 } 1273 } 1274 #endif /* HWUARTCONSOLE */ 1275 1276 #elif defined(OVERO) 1277 1278 if (comcnattach(&omap_a4x_bs_tag, 0x49020000, comcnspeed, 1279 OMAP_COM_FREQ, COM_TYPE_NORMAL, comcnmode) == 0) 1280 return; 1281 1282 #endif /* GUMSTIX or OVERO */ 1283 1284 #endif /* NCOM */ 1285 1286 #if NLCD > 0 1287 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 1288 if (console[0] == '\0' || strcasecmp(console, "lcd") == 0) 1289 #endif 1290 { 1291 gxlcd_cnattach(); 1292 } 1293 #endif 1294 } 1295 1296 #ifdef KGDB 1297 static void 1298 kgdb_port_init(void) 1299 { 1300 #if (NCOM > 0) && defined(COM_PXA2X0) 1301 paddr_t paddr = 0; 1302 int cken = 0; 1303 1304 if (0 == strcmp(kgdb_devname, "ffuart")) { 1305 paddr = PXA2X0_FFUART_BASE; 1306 cken = CKEN_FFUART; 1307 } else if (0 == strcmp(kgdb_devname, "stuart")) { 1308 paddr = PXA2X0_STUART_BASE; 1309 cken = CKEN_STUART; 1310 } else if (0 == strcmp(kgdb_devname, "btuart")) { 1311 paddr = PXA2X0_BTUART_BASE; 1312 cken = CKEN_BTUART; 1313 } else if (0 == strcmp(kgdb_devname, "hwuart")) { 1314 paddr = PXA2X0_HWUART_BASE; 1315 cken = CKEN_HWUART; 1316 } 1317 1318 if (paddr && 1319 0 == com_kgdb_attach(&pxa2x0_a4x_bs_tag, paddr, 1320 kgdb_devrate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode)) { 1321 1322 pxa2x0_clkman_config(cken, 1); 1323 } 1324 1325 #endif 1326 } 1327 #endif 1328 1329 static void 1330 gumstix_device_register(device_t dev, void *aux) 1331 { 1332 prop_dictionary_t dict = device_properties(dev); 1333 1334 if (device_is_a(dev, "ehci")) { 1335 prop_dictionary_set_cstring(dict, "port0-mode", "none"); 1336 prop_dictionary_set_cstring(dict, "port1-mode", "phy"); 1337 prop_dictionary_set_cstring(dict, "port2-mode", "none"); 1338 prop_dictionary_set_bool(dict, "phy-reset", true); 1339 prop_dictionary_set_int16(dict, "port0-gpio", -1); 1340 prop_dictionary_set_int16(dict, "port1-gpio", 183); 1341 prop_dictionary_set_int16(dict, "port2-gpio", -1); 1342 prop_dictionary_set_uint16(dict, "dpll5-m", 120); 1343 prop_dictionary_set_uint16(dict, "dpll5-n", 12); 1344 prop_dictionary_set_uint16(dict, "dpll5-m2", 1); 1345 } 1346 if (device_is_a(dev, "ohci")) { 1347 if (prop_dictionary_set_bool(dict, 1348 "Ganged-power-mask-on-port1", 1) == false) { 1349 printf("WARNING: unable to set power-mask for port1" 1350 " property for %s\n", device_xname(dev)); 1351 } 1352 if (prop_dictionary_set_bool(dict, 1353 "Ganged-power-mask-on-port2", 1) == false) { 1354 printf("WARNING: unable to set power-mask for port2" 1355 " property for %s\n", device_xname(dev)); 1356 } 1357 if (prop_dictionary_set_bool(dict, 1358 "Ganged-power-mask-on-port3", 1) == false) { 1359 printf("WARNING: unable to set power-mask for port3" 1360 " property for %s\n", device_xname(dev)); 1361 } 1362 } 1363 } 1364