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