Annotation of sys/arch/zaurus/zaurus/zaurus_machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: zaurus_machdep.c,v 1.27 2007/05/19 15:49:06 miod Exp $ */
! 2: /* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved.
! 6: * Written by Hiroyuki Bessho for Genetec Corporation.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. The name of Genetec Corporation may not be used to endorse or
! 17: * promote products derived from this software without specific prior
! 18: * written permission.
! 19: *
! 20: * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
! 21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 22: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 23: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
! 24: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 25: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 26: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 27: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 28: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 29: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 30: * POSSIBILITY OF SUCH DAMAGE.
! 31: *
! 32: * Machine dependant functions for kernel setup for
! 33: * Intel DBPXA250 evaluation board (a.k.a. Lubbock).
! 34: * Based on iq80310_machhdep.c
! 35: */
! 36: /*
! 37: * Copyright (c) 2001 Wasabi Systems, Inc.
! 38: * All rights reserved.
! 39: *
! 40: * Written by Jason R. Thorpe for Wasabi Systems, Inc.
! 41: *
! 42: * Redistribution and use in source and binary forms, with or without
! 43: * modification, are permitted provided that the following conditions
! 44: * are met:
! 45: * 1. Redistributions of source code must retain the above copyright
! 46: * notice, this list of conditions and the following disclaimer.
! 47: * 2. Redistributions in binary form must reproduce the above copyright
! 48: * notice, this list of conditions and the following disclaimer in the
! 49: * documentation and/or other materials provided with the distribution.
! 50: * 3. All advertising materials mentioning features or use of this software
! 51: * must display the following acknowledgement:
! 52: * This product includes software developed for the NetBSD Project by
! 53: * Wasabi Systems, Inc.
! 54: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
! 55: * or promote products derived from this software without specific prior
! 56: * written permission.
! 57: *
! 58: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
! 59: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 60: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 61: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
! 62: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 63: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 64: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 65: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 66: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 67: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 68: * POSSIBILITY OF SUCH DAMAGE.
! 69: */
! 70:
! 71: /*
! 72: * Copyright (c) 1997,1998 Mark Brinicombe.
! 73: * Copyright (c) 1997,1998 Causality Limited.
! 74: * All rights reserved.
! 75: *
! 76: * Redistribution and use in source and binary forms, with or without
! 77: * modification, are permitted provided that the following conditions
! 78: * are met:
! 79: * 1. Redistributions of source code must retain the above copyright
! 80: * notice, this list of conditions and the following disclaimer.
! 81: * 2. Redistributions in binary form must reproduce the above copyright
! 82: * notice, this list of conditions and the following disclaimer in the
! 83: * documentation and/or other materials provided with the distribution.
! 84: * 3. All advertising materials mentioning features or use of this software
! 85: * must display the following acknowledgement:
! 86: * This product includes software developed by Mark Brinicombe
! 87: * for the NetBSD Project.
! 88: * 4. The name of the company nor the name of the author may be used to
! 89: * endorse or promote products derived from this software without specific
! 90: * prior written permission.
! 91: *
! 92: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
! 93: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
! 94: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 95: * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
! 96: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 97: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 98: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 99: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 100: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 101: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 102: * SUCH DAMAGE.
! 103: *
! 104: * Machine dependant functions for kernel setup for Intel IQ80310 evaluation
! 105: * boards using RedBoot firmware.
! 106: */
! 107:
! 108: /*
! 109: * DIP switches:
! 110: *
! 111: * S19: no-dot: set RB_KDB. enter kgdb session.
! 112: * S20: no-dot: set RB_SINGLE. don't go multi user mode.
! 113: */
! 114:
! 115: #include <sys/param.h>
! 116: #include <sys/device.h>
! 117: #include <sys/systm.h>
! 118: #include <sys/kernel.h>
! 119: #include <sys/exec.h>
! 120: #include <sys/proc.h>
! 121: #include <sys/msgbuf.h>
! 122: #include <sys/reboot.h>
! 123: #include <sys/termios.h>
! 124: #include <sys/kcore.h>
! 125:
! 126: #include <uvm/uvm_extern.h>
! 127:
! 128: #include <sys/conf.h>
! 129: #include <sys/queue.h>
! 130: #include <sys/device.h>
! 131: #include <dev/cons.h>
! 132: #include <dev/ic/smc91cxxreg.h>
! 133:
! 134: #include <machine/db_machdep.h>
! 135: #include <ddb/db_sym.h>
! 136: #include <ddb/db_extern.h>
! 137: #ifdef KGDB
! 138: #include <sys/kgdb.h>
! 139: #endif
! 140:
! 141: #include <machine/bootconfig.h>
! 142: #include <machine/bus.h>
! 143: #include <machine/cpu.h>
! 144: #include <machine/frame.h>
! 145: #include <arm/kcore.h>
! 146: #include <arm/undefined.h>
! 147: #include <arm/machdep.h>
! 148:
! 149: #include <arm/xscale/pxa2x0reg.h>
! 150: #include <arm/xscale/pxa2x0var.h>
! 151: #include <arm/xscale/pxa2x0_gpio.h>
! 152: #include <arm/sa11x0/sa1111_reg.h>
! 153: #include <machine/zaurus_reg.h>
! 154: #include <machine/zaurus_var.h>
! 155:
! 156: #include <zaurus/dev/zaurus_scoopreg.h>
! 157:
! 158: #include "apm.h"
! 159: #if NAPM > 0
! 160: #include <zaurus/dev/zaurus_apm.h>
! 161: #endif
! 162:
! 163: #include "wsdisplay.h"
! 164:
! 165: /* Kernel text starts 2MB in from the bottom of the kernel address space. */
! 166: #define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00200000)
! 167: #define KERNEL_VM_BASE (KERNEL_BASE + 0x04000000)
! 168:
! 169: /*
! 170: * The range 0xc1000000 - 0xccffffff is available for kernel VM space
! 171: * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff
! 172: */
! 173: /*
! 174: #define KERNEL_VM_SIZE 0x0C000000
! 175: */
! 176: #define KERNEL_VM_SIZE 0x10000000
! 177:
! 178:
! 179: /*
! 180: * Address to call from cpu_reset() to reset the machine.
! 181: * This is machine architecture dependant as it varies depending
! 182: * on where the ROM appears when you turn the MMU off.
! 183: */
! 184:
! 185: u_int cpu_reset_address = 0;
! 186:
! 187: /* Define various stack sizes in pages */
! 188: #define IRQ_STACK_SIZE 1
! 189: #define ABT_STACK_SIZE 1
! 190: #ifdef IPKDB
! 191: #define UND_STACK_SIZE 2
! 192: #else
! 193: #define UND_STACK_SIZE 1
! 194: #endif
! 195:
! 196: int zaurusmod;
! 197:
! 198: BootConfig bootconfig; /* Boot config storage */
! 199: char *boot_args = NULL;
! 200: char *boot_file = NULL;
! 201:
! 202: paddr_t physical_start;
! 203: paddr_t physical_freestart;
! 204: paddr_t physical_freeend;
! 205: paddr_t physical_end;
! 206: u_int free_pages;
! 207: int physmem = 0;
! 208:
! 209: /*int debug_flags;*/
! 210: #ifndef PMAP_STATIC_L1S
! 211: int max_processes = 64; /* Default number */
! 212: #endif /* !PMAP_STATIC_L1S */
! 213:
! 214: /* Physical and virtual addresses for some global pages */
! 215: pv_addr_t systempage;
! 216: pv_addr_t irqstack;
! 217: pv_addr_t undstack;
! 218: pv_addr_t abtstack;
! 219: extern pv_addr_t kernelstack;
! 220: pv_addr_t minidataclean;
! 221:
! 222: paddr_t msgbufphys;
! 223:
! 224: extern u_int data_abort_handler_address;
! 225: extern u_int prefetch_abort_handler_address;
! 226: extern u_int undefined_handler_address;
! 227:
! 228: #ifdef PMAP_DEBUG
! 229: extern int pmap_debug_level;
! 230: #endif
! 231:
! 232: #define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
! 233: #define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */
! 234: #define KERNEL_PT_KERNEL_NUM 32
! 235: #define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL+KERNEL_PT_KERNEL_NUM)
! 236: /* Page tables for mapping kernel VM */
! 237: #define KERNEL_PT_VMDATA_NUM 8 /* start with 32MB of KVM */
! 238: #define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
! 239:
! 240: pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
! 241:
! 242: extern struct user *proc0paddr;
! 243:
! 244: /* Prototypes */
! 245:
! 246: #define BOOT_STRING_MAGIC 0x4f425344
! 247:
! 248: char bootargs[MAX_BOOT_STRING];
! 249: void process_kernel_args(char *);
! 250:
! 251: void consinit(void);
! 252: void early_clkman(u_int, int);
! 253: void kgdb_port_init(void);
! 254: void change_clock(uint32_t v);
! 255:
! 256: bs_protos(bs_notimpl);
! 257:
! 258: #include "com.h"
! 259: #if NCOM > 0
! 260: #include <dev/ic/comvar.h>
! 261: #include <dev/ic/comreg.h>
! 262: #endif
! 263:
! 264: #ifndef CONSPEED
! 265: #define CONSPEED B9600 /* What RedBoot uses */
! 266: #endif
! 267: #ifndef CONMODE
! 268: #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
! 269: #endif
! 270:
! 271: int comcnspeed = CONSPEED;
! 272: int comcnmode = CONMODE;
! 273:
! 274:
! 275: /*
! 276: * void boot(int howto, char *bootstr)
! 277: *
! 278: * Reboots the system
! 279: *
! 280: * Deal with any syncing, unmounting, dumping and shutdown hooks,
! 281: * then reset the CPU.
! 282: */
! 283: void
! 284: boot(int howto)
! 285: {
! 286: /*
! 287: * If we are still cold then hit the air brakes
! 288: * and crash to earth fast
! 289: */
! 290: if (cold) {
! 291: doshutdownhooks();
! 292: if ((howto & (RB_HALT | RB_USERREQ)) != RB_USERREQ) {
! 293: printf("The operating system has halted.\n");
! 294: printf("Please press any key to reboot.\n\n");
! 295: cngetc();
! 296: }
! 297: printf("rebooting...\n");
! 298: delay(6000000);
! 299: #if NAPM > 0
! 300: zapm_restart();
! 301: #endif
! 302: printf("reboot failed; spinning\n");
! 303: while(1);
! 304: /*NOTREACHED*/
! 305: }
! 306:
! 307: /* Disable console buffering */
! 308: /* cnpollc(1);*/
! 309:
! 310: /*
! 311: * If RB_NOSYNC was not specified sync the discs.
! 312: * Note: Unless cold is set to 1 here, syslogd will die during the
! 313: * unmount. It looks like syslogd is getting woken up only to find
! 314: * that it cannot page part of the binary in as the filesystem has
! 315: * been unmounted.
! 316: */
! 317: if (!(howto & RB_NOSYNC))
! 318: bootsync(howto);
! 319:
! 320: /* Say NO to interrupts */
! 321: splhigh();
! 322:
! 323: /* Do a dump if requested. */
! 324: if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
! 325: dumpsys();
! 326:
! 327: /* Run any shutdown hooks */
! 328: doshutdownhooks();
! 329:
! 330: /* Make sure IRQ's are disabled */
! 331: IRQdisable;
! 332:
! 333: if (howto & RB_HALT) {
! 334: #if NAPM > 0
! 335: if (howto & RB_POWERDOWN) {
! 336:
! 337: printf("\nAttempting to power down...\n");
! 338: delay(6000000);
! 339: zapm_poweroff();
! 340: }
! 341: #endif
! 342:
! 343: printf("The operating system has halted.\n");
! 344: printf("Please press any key to reboot.\n\n");
! 345: cngetc();
! 346: }
! 347:
! 348: printf("rebooting...\n");
! 349: delay(6000000);
! 350: #if NAPM > 0
! 351: zapm_restart();
! 352: #endif
! 353: printf("reboot failed; spinning\n");
! 354: while(1);
! 355: /*NOTREACHED*/
! 356: }
! 357:
! 358: static __inline
! 359: pd_entry_t *
! 360: read_ttb(void)
! 361: {
! 362: long ttb;
! 363:
! 364: __asm __volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb));
! 365:
! 366:
! 367: return (pd_entry_t *)(ttb & ~((1<<14)-1));
! 368: }
! 369:
! 370: /*
! 371: * Mapping table for core kernel memory. These areas are mapped in
! 372: * init time at fixed virtual address with section mappings.
! 373: */
! 374: struct l1_sec_map {
! 375: vaddr_t va;
! 376: vaddr_t pa;
! 377: vsize_t size;
! 378: int flags;
! 379: } l1_sec_table[] = {
! 380: {
! 381: ZAURUS_GPIO_VBASE,
! 382: PXA2X0_GPIO_BASE,
! 383: PXA2X0_GPIO_SIZE,
! 384: PTE_NOCACHE,
! 385: },
! 386: {
! 387: ZAURUS_CLKMAN_VBASE,
! 388: PXA2X0_CLKMAN_BASE,
! 389: PXA2X0_CLKMAN_SIZE,
! 390: PTE_NOCACHE,
! 391: },
! 392: {
! 393: ZAURUS_INTCTL_VBASE,
! 394: PXA2X0_INTCTL_BASE,
! 395: PXA2X0_INTCTL_SIZE,
! 396: PTE_NOCACHE,
! 397: },
! 398: {
! 399: ZAURUS_SCOOP0_VBASE,
! 400: C3000_SCOOP0_BASE,
! 401: SCOOP_SIZE,
! 402: PTE_NOCACHE,
! 403: },
! 404: {
! 405: ZAURUS_SCOOP1_VBASE,
! 406: trunc_page(C3000_SCOOP1_BASE),
! 407: round_page(SCOOP_SIZE),
! 408: PTE_NOCACHE,
! 409: },
! 410: {0, 0, 0, 0,}
! 411: };
! 412:
! 413: static void
! 414: map_io_area(paddr_t pagedir)
! 415: {
! 416: int loop;
! 417:
! 418: /*
! 419: * Map devices we can map w/ section mappings.
! 420: */
! 421: loop = 0;
! 422: while (l1_sec_table[loop].size) {
! 423: vsize_t sz;
! 424:
! 425: #define VERBOSE_INIT_ARM
! 426: #ifdef VERBOSE_INIT_ARM
! 427: printf("%08lx -> %08lx @ %08lx\n", l1_sec_table[loop].pa,
! 428: l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,
! 429: l1_sec_table[loop].va);
! 430: #endif
! 431: for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE)
! 432: pmap_map_section(pagedir, l1_sec_table[loop].va + sz,
! 433: l1_sec_table[loop].pa + sz,
! 434: VM_PROT_READ|VM_PROT_WRITE,
! 435: l1_sec_table[loop].flags);
! 436: ++loop;
! 437: }
! 438: }
! 439:
! 440: /*
! 441: * simple memory mapping function used in early bootstrap stage
! 442: * before pmap is initialized.
! 443: * size and cacheability are ignored and map one section with nocache.
! 444: */
! 445: static vaddr_t section_free = ZAURUS_VBASE_FREE;
! 446:
! 447: static int
! 448: bootstrap_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
! 449: int cacheable, bus_space_handle_t *bshp)
! 450: {
! 451: u_long startpa;
! 452: vaddr_t va;
! 453: pd_entry_t *pagedir = read_ttb();
! 454: /* This assumes PA==VA for page directory */
! 455:
! 456: va = section_free;
! 457: section_free += L1_S_SIZE;
! 458:
! 459: startpa = trunc_page(bpa);
! 460: pmap_map_section((vaddr_t)pagedir, va, startpa,
! 461: VM_PROT_READ | VM_PROT_WRITE, PTE_NOCACHE);
! 462: cpu_tlb_flushD();
! 463:
! 464: *bshp = (bus_space_handle_t)(va + (bpa - startpa));
! 465:
! 466: return(0);
! 467: }
! 468:
! 469: static void
! 470: copy_io_area_map(pd_entry_t *new_pd)
! 471: {
! 472: pd_entry_t *cur_pd = read_ttb();
! 473: vaddr_t va;
! 474:
! 475: for (va = ZAURUS_IO_AREA_VBASE;
! 476: (cur_pd[va>>L1_S_SHIFT] & L1_TYPE_MASK) == L1_TYPE_S;
! 477: va += L1_S_SIZE) {
! 478:
! 479: new_pd[va>>L1_S_SHIFT] = cur_pd[va>>L1_S_SHIFT];
! 480: if (va == (0 - L1_S_SIZE))
! 481: break; /* STUPID */
! 482:
! 483: }
! 484: }
! 485:
! 486: /* XXX tidy up! */
! 487: void green_on(int virt);
! 488: void
! 489: green_on(int virt)
! 490: {
! 491: /* clobber green led p */
! 492: volatile u_int16_t *p;
! 493: if (virt)
! 494: p = (u_int16_t *)(ZAURUS_SCOOP0_VBASE+SCOOP_GPWR);
! 495: else
! 496: p = (u_int16_t *)(C3000_SCOOP0_BASE+SCOOP_GPWR);
! 497:
! 498: *p = *p | (1<<SCOOP0_LED_GREEN);
! 499: }
! 500: void irda_on(int virt);
! 501: void
! 502: irda_on(int virt)
! 503: {
! 504: /* clobber IrDA led p */
! 505: volatile u_int16_t *p;
! 506: /* XXX scoop1 registers are not page-aligned! */
! 507: int ofs = C3000_SCOOP1_BASE - trunc_page(C3000_SCOOP1_BASE);
! 508:
! 509: if (virt)
! 510: p = (u_int16_t *)(ZAURUS_SCOOP1_VBASE+ofs+SCOOP_GPWR);
! 511: else
! 512: p = (u_int16_t *)(C3000_SCOOP1_BASE+SCOOP_GPWR);
! 513:
! 514: *p = *p & ~(1<<SCOOP1_IR_ON);
! 515: }
! 516:
! 517: #if 0
! 518: void sysprobe(void);
! 519: void
! 520: sysprobe(void)
! 521: {
! 522: u_int32_t *p;
! 523:
! 524: p = (void *)0x48000014; /* MECR */
! 525: printf("MECR %x\n", *p);
! 526:
! 527: p = (void *)0x48000028; /* MCMEM0 */
! 528: printf("MCMEM0 %x\n", *p);
! 529: p = (void *)0x4800002C; /* MCMEM1 */
! 530: printf("MCMEM1 %x\n", *p);
! 531:
! 532: p = (void *)0x48000030; /* MCATTx */
! 533: printf("MCATT0 %x\n", *p);
! 534: p = (void *)0x48000034; /* MCATTx */
! 535: printf("MCATT1 %x\n", *p);
! 536:
! 537: p = (void *)0x48000038; /* MCIOx */
! 538: printf("MCIO0 %x\n", *p);
! 539: p = (void *)0x4800003C; /* MCIOx */
! 540: printf("MCIO1 %x\n", *p);
! 541: }
! 542: #endif
! 543:
! 544: /*
! 545: * u_int initarm(...)
! 546: *
! 547: * Initial entry point on startup. This gets called before main() is
! 548: * entered.
! 549: * It should be responsible for setting up everything that must be
! 550: * in place when main is called.
! 551: * This includes
! 552: * Taking a copy of the boot configuration structure.
! 553: * Initialising the physical console so characters can be printed.
! 554: * Setting up page tables for the kernel
! 555: * Relocating the kernel to the bottom of physical memory
! 556: */
! 557: u_int
! 558: initarm(void *arg)
! 559: {
! 560: extern vaddr_t xscale_cache_clean_addr;
! 561: extern cpu_kcore_hdr_t cpu_kcore_hdr;
! 562: int loop;
! 563: int loop1;
! 564: u_int l1pagetable;
! 565: pv_addr_t kernel_l1pt;
! 566: paddr_t memstart;
! 567: psize_t memsize;
! 568: extern u_int32_t esym; /* &_end if no symbols are loaded */
! 569:
! 570: #if 0
! 571: int led_data = 0;
! 572: #endif
! 573: #ifdef DIAGNOSTIC
! 574: extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */
! 575: #endif
! 576: /* early bus_space_map support */
! 577: struct bus_space tmp_bs_tag;
! 578: int (*map_func_save)(void *, bus_addr_t, bus_size_t, int,
! 579: bus_space_handle_t *);
! 580:
! 581:
! 582: #if 0
! 583: /* XXX */
! 584: /* start 32.768KHz OSC */
! 585: ioreg_write(PXA2X0_CLKMAN_BASE + 0x08, 2);
! 586: #endif
! 587:
! 588: /*
! 589: * Heads up ... Setup the CPU / MMU / TLB functions
! 590: */
! 591: if (set_cpufuncs())
! 592: panic("cpu not recognized!");
! 593:
! 594: /* Get ready for splfoo() */
! 595: pxa2x0_intr_bootstrap(PXA2X0_INTCTL_BASE);
! 596:
! 597: #if 0
! 598: /* Calibrate the delay loop. */
! 599: #endif
! 600:
! 601: /*
! 602: * Okay, RedBoot has provided us with the following memory map:
! 603: *
! 604: * Physical Address Range Description
! 605: * ----------------------- ----------------------------------
! 606: * 0x00000000 - 0x01ffffff flash Memory (32MB)
! 607: * 0x04000000 - 0x05ffffff Application flash Memory (32MB)
! 608: * 0x08000000 - 0x080000ff I/O baseboard registers
! 609: * 0x0a000000 - 0x0a0fffff SRAM (1MB)
! 610: * 0x0c000000 - 0x0c0fffff Ethernet Controller
! 611: * 0x0e000000 - 0x0e0fffff Ethernet Controller (Attribute)
! 612: * 0x10000000 - 0x103fffff SA-1111 Companion Chip
! 613: * 0x14000000 - 0x17ffffff Expansion Card (64MB)
! 614: * 0x40000000 - 0x480fffff Processor Registers
! 615: * 0xa0000000 - 0xa3ffffff SDRAM Bank 0 (64MB)
! 616: *
! 617: *
! 618: * Virtual Address Range X C B Description
! 619: * ----------------------- - - - ----------------------------------
! 620: * 0x00000000 - 0x00003fff N Y Y SDRAM
! 621: * 0x00004000 - 0x000fffff N Y N Boot ROM
! 622: * 0x00100000 - 0x01ffffff N N N Application Flash
! 623: * 0x04000000 - 0x05ffffff N N N Exp Application Flash
! 624: * 0x08000000 - 0x080fffff N N N I/O baseboard registers
! 625: * 0x0a000000 - 0x0a0fffff N N N SRAM
! 626: * 0x40000000 - 0x480fffff N N N Processor Registers
! 627: * 0xa0000000 - 0xa000ffff N Y N RedBoot SDRAM
! 628: * 0xa0017000 - 0xa3ffffff Y Y Y SDRAM
! 629: * 0xc0000000 - 0xcfffffff Y Y Y Cache Flush Region
! 630: * (done by this routine)
! 631: * 0xfd000000 - 0xfd0000ff N N N I/O baseboard registers
! 632: * 0xfd100000 - 0xfd2fffff N N N Processor Registers.
! 633: * 0xfd200000 - 0xfd2fffff N N N 0x10800000 registers
! 634: *
! 635: * The first level page table is at 0xa0004000. There are also
! 636: * 2 second-level tables at 0xa0008000 and 0xa0008400.
! 637: *
! 638: */
! 639:
! 640: {
! 641: /*
! 642: * Tweak RedBoot's pagetable so that we can access to
! 643: * some registers at same VA before and after installing
! 644: * our page table.
! 645: */
! 646: paddr_t ttb = (paddr_t)read_ttb();
! 647:
! 648: map_io_area(ttb);
! 649: cpu_tlb_flushD();
! 650: }
! 651:
! 652: /*
! 653: * Examine the boot args string for options we need to know about
! 654: * now.
! 655: */
! 656: /* XXX should really be done after setting up the console, but we
! 657: * XXX need to parse the console selection flags right now. */
! 658: process_kernel_args((char *)0xa0200000 - MAX_BOOT_STRING - 1);
! 659: #ifdef RAMDISK_HOOKS
! 660: boothowto |= RB_DFLTROOT;
! 661: #endif /* RAMDISK_HOOKS */
! 662:
! 663: /*
! 664: * This test will work for now but has to be revised when support
! 665: * for other models is added.
! 666: */
! 667: if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X)
! 668: zaurusmod = ZAURUS_C3000;
! 669: else
! 670: zaurusmod = ZAURUS_C860;
! 671:
! 672: /* setup GPIO for BTUART, in case bootloader doesn't take care of it */
! 673: pxa2x0_gpio_bootstrap(ZAURUS_GPIO_VBASE);
! 674: #if 0
! 675: pxa2x0_gpio_set_function(42, GPIO_ALT_FN_1_IN);
! 676: pxa2x0_gpio_set_function(43, GPIO_ALT_FN_2_OUT);
! 677: pxa2x0_gpio_set_function(44, GPIO_ALT_FN_1_IN);
! 678: pxa2x0_gpio_set_function(45, GPIO_ALT_FN_2_OUT);
! 679:
! 680: /* FFUART */
! 681: pxa2x0_gpio_set_function(34, GPIO_ALT_FN_1_IN);
! 682: pxa2x0_gpio_set_function(39, GPIO_ALT_FN_2_OUT);
! 683: pxa2x0_gpio_set_function(35, GPIO_ALT_FN_1_IN);
! 684: pxa2x0_gpio_set_function(40, GPIO_ALT_FN_2_OUT);
! 685: pxa2x0_gpio_set_function(41, GPIO_ALT_FN_2_OUT);
! 686:
! 687: /* STUART */
! 688: pxa2x0_gpio_set_function(46, GPIO_ALT_FN_2_IN);
! 689: pxa2x0_gpio_set_function(47, GPIO_ALT_FN_1_OUT);
! 690: #endif
! 691:
! 692: /* tell com to drive STUART in slow infrared mode */
! 693: comsiraddr = (bus_addr_t)PXA2X0_STUART_BASE;
! 694:
! 695: #if 1
! 696: /* turn on clock to UART block.
! 697: XXX this should not be necessary, consinit() will do it */
! 698: early_clkman(CKEN_FFUART | CKEN_BTUART | CKEN_STUART, 1);
! 699: #endif
! 700:
! 701: green_on(0);
! 702:
! 703: /*
! 704: * Temporarily replace bus_space_map() functions so that
! 705: * console devices can get mapped.
! 706: *
! 707: * Note that this relies upon the fact that both regular
! 708: * and a4x bus_space tags use the same map function.
! 709: */
! 710: tmp_bs_tag = pxa2x0_bs_tag;
! 711: tmp_bs_tag.bs_map = bootstrap_bs_map;
! 712: map_func_save = pxa2x0_bs_tag.bs_map;
! 713: pxa2x0_a4x_bs_tag.bs_map = pxa2x0_bs_tag.bs_map = bootstrap_bs_map;
! 714:
! 715: /* setup a serial console for very early boot */
! 716: consinit();
! 717: #ifdef KGDB
! 718: kgdb_port_init();
! 719: #endif
! 720:
! 721:
! 722: /* Talk to the user */
! 723: printf("\nOpenBSD/zaurus booting ...\n");
! 724:
! 725: {
! 726: /* XXX - all Zaurus have this for now, fix memory sizing */
! 727: memstart = 0xa0000000;
! 728: memsize = 0x04000000; /* 64MB */
! 729: }
! 730:
! 731: #if 0
! 732: {
! 733: volatile int *p;
! 734: char *membase;
! 735: char *memmax;
! 736: int chunksize = 0x02000000;
! 737: printf("probing memory");
! 738:
! 739: membase = (char *)0xa0000000;
! 740: memmax = (char *)0xc0000000;
! 741: for (p = (int *)membase;
! 742: p < (int *)memmax;
! 743: p = (int *) (((char *)p) + chunksize)) {
! 744: printf ("cbase %p\n", p);
! 745: p[0] = 0x12345678;
! 746: p[1] = 0x12345678;
! 747: if ((p[0] != 0x12345678) || (p[1] != 0x12345678))
! 748: break;
! 749: }
! 750: memsize = ((char *)p) - membase;
! 751:
! 752: printf("probing memory done found memsize %d\n", memsize);
! 753: }
! 754: #else
! 755: #endif
! 756:
! 757: #define DEBUG
! 758: #ifdef DEBUG
! 759: printf("initarm: Configuring system ...\n");
! 760: #endif
! 761:
! 762: /* Fake bootconfig structure for the benefit of pmap.c */
! 763: /* XXX must make the memory description h/w independant */
! 764: bootconfig.dramblocks = 1;
! 765: bootconfig.dram[0].address = memstart;
! 766: bootconfig.dram[0].pages = memsize / PAGE_SIZE;
! 767:
! 768: /*
! 769: * Set up the variables that define the availablilty of
! 770: * physical memory. For now, we're going to set
! 771: * physical_freestart to 0xa0200000 (where the kernel
! 772: * was loaded), and allocate the memory we need downwards.
! 773: * If we get too close to the page tables that RedBoot
! 774: * set up, we will panic. We will update physical_freestart
! 775: * and physical_freeend later to reflect what pmap_bootstrap()
! 776: * wants to see.
! 777: *
! 778: * XXX pmap_bootstrap() needs an enema.
! 779: */
! 780: physical_start = bootconfig.dram[0].address;
! 781: physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
! 782:
! 783: physical_freestart = 0xa0009000UL;
! 784: physical_freeend = 0xa0200000UL;
! 785:
! 786: physmem = (physical_end - physical_start) / PAGE_SIZE;
! 787:
! 788: #ifdef DEBUG
! 789: /* Tell the user about the memory */
! 790: printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
! 791: physical_start, physical_end - 1);
! 792: #endif
! 793:
! 794: /*
! 795: * Okay, the kernel starts 2MB in from the bottom of physical
! 796: * memory. We are going to allocate our bootstrap pages downwards
! 797: * from there.
! 798: *
! 799: * We need to allocate some fixed page tables to get the kernel
! 800: * going. We allocate one page directory and a number of page
! 801: * tables and store the physical addresses in the kernel_pt_table
! 802: * array.
! 803: *
! 804: * The kernel page directory must be on a 16K boundary. The page
! 805: * tables must be on 4K bounaries. What we do is allocate the
! 806: * page directory on the first 16K boundary that we encounter, and
! 807: * the page tables on 4K boundaries otherwise. Since we allocate
! 808: * at least 3 L2 page tables, we are guaranteed to encounter at
! 809: * least one 16K aligned region.
! 810: */
! 811:
! 812: #ifdef VERBOSE_INIT_ARM
! 813: printf("Allocating page tables\n");
! 814: #endif
! 815:
! 816: free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;
! 817:
! 818: #ifdef VERBOSE_INIT_ARM
! 819: printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
! 820: physical_freestart, free_pages, free_pages);
! 821: #endif
! 822:
! 823: /* Define a macro to simplify memory allocation */
! 824: #define valloc_pages(var, np) \
! 825: alloc_pages((var).pv_pa, (np)); \
! 826: (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
! 827:
! 828: #define alloc_pages(var, np) \
! 829: physical_freeend -= ((np) * PAGE_SIZE); \
! 830: if (physical_freeend < physical_freestart) \
! 831: panic("initarm: out of memory"); \
! 832: (var) = physical_freeend; \
! 833: free_pages -= (np); \
! 834: memset((char *)(var), 0, ((np) * PAGE_SIZE));
! 835:
! 836: loop1 = 0;
! 837: kernel_l1pt.pv_pa = 0;
! 838: for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
! 839: /* Are we 16KB aligned for an L1 ? */
! 840: if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0
! 841: && kernel_l1pt.pv_pa == 0) {
! 842: valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
! 843: } else {
! 844: valloc_pages(kernel_pt_table[loop1],
! 845: L2_TABLE_SIZE / PAGE_SIZE);
! 846: ++loop1;
! 847: }
! 848: }
! 849:
! 850: /* This should never be able to happen but better confirm that. */
! 851: if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
! 852: panic("initarm: Failed to align the kernel page directory");
! 853:
! 854: /*
! 855: * Allocate a page for the system page mapped to V0x00000000
! 856: * This page will just contain the system vectors and can be
! 857: * shared by all processes.
! 858: */
! 859: alloc_pages(systempage.pv_pa, 1);
! 860:
! 861: /* Allocate stacks for all modes */
! 862: valloc_pages(irqstack, IRQ_STACK_SIZE);
! 863: valloc_pages(abtstack, ABT_STACK_SIZE);
! 864: valloc_pages(undstack, UND_STACK_SIZE);
! 865: valloc_pages(kernelstack, UPAGES);
! 866:
! 867: /* Allocate enough pages for cleaning the Mini-Data cache. */
! 868: KASSERT(xscale_minidata_clean_size <= PAGE_SIZE);
! 869: valloc_pages(minidataclean, 1);
! 870:
! 871: #ifdef VERBOSE_INIT_ARM
! 872: printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
! 873: irqstack.pv_va);
! 874: printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
! 875: abtstack.pv_va);
! 876: printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
! 877: undstack.pv_va);
! 878: printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
! 879: kernelstack.pv_va);
! 880: #endif
! 881:
! 882: /*
! 883: * XXX Defer this to later so that we can reclaim the memory
! 884: * XXX used by the RedBoot page tables.
! 885: */
! 886: alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);
! 887:
! 888: /*
! 889: * Ok we have allocated physical pages for the primary kernel
! 890: * page tables
! 891: */
! 892:
! 893: #ifdef VERBOSE_INIT_ARM
! 894: printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
! 895: #endif
! 896:
! 897: /*
! 898: * Now we start construction of the L1 page table
! 899: * We start by mapping the L2 page tables into the L1.
! 900: * This means that we can replace L1 mappings later on if necessary
! 901: */
! 902: l1pagetable = kernel_l1pt.pv_pa;
! 903:
! 904: /* Map the L2 pages tables in the L1 page table */
! 905: pmap_link_l2pt(l1pagetable, 0x00000000,
! 906: &kernel_pt_table[KERNEL_PT_SYS]);
! 907:
! 908: for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
! 909: pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
! 910: &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
! 911:
! 912: for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
! 913: pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
! 914: &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
! 915:
! 916: /* update the top of the kernel VM */
! 917: pmap_curmaxkvaddr =
! 918: KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
! 919:
! 920: #ifdef VERBOSE_INIT_ARM
! 921: printf("Mapping kernel\n");
! 922: #endif
! 923:
! 924: /* Now we fill in the L2 pagetable for the kernel static code/data
! 925: * and the symbol table. */
! 926: {
! 927: extern char etext[];
! 928: size_t textsize = (u_int32_t) etext - KERNEL_TEXT_BASE;
! 929: size_t totalsize = esym - KERNEL_TEXT_BASE;
! 930: u_int logical;
! 931:
! 932: textsize = (textsize + PGOFSET) & ~PGOFSET;
! 933: totalsize = (totalsize + PGOFSET) & ~PGOFSET;
! 934:
! 935: logical = 0x00200000; /* offset of kernel in RAM */
! 936:
! 937: /* Update dump information */
! 938: cpu_kcore_hdr.kernelbase = KERNEL_BASE;
! 939: cpu_kcore_hdr.kerneloffs = logical;
! 940: cpu_kcore_hdr.staticsize = totalsize;
! 941:
! 942: logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
! 943: physical_start + logical, textsize,
! 944: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 945: pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
! 946: physical_start + logical, totalsize - textsize,
! 947: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 948: }
! 949:
! 950: #ifdef VERBOSE_INIT_ARM
! 951: printf("Constructing L2 page tables\n");
! 952: #endif
! 953:
! 954: /* Map the stack pages */
! 955: pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
! 956: IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 957: pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
! 958: ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 959: pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
! 960: UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 961: pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
! 962: UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
! 963:
! 964: pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
! 965: L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE);
! 966:
! 967: for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
! 968: pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
! 969: kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
! 970: VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
! 971: }
! 972:
! 973: /* Map the Mini-Data cache clean area. */
! 974: xscale_setup_minidata(l1pagetable, minidataclean.pv_va,
! 975: minidataclean.pv_pa);
! 976:
! 977: /* Map the vector page. */
! 978: #if 1
! 979: /* MULTI-ICE requires that page 0 is NC/NB so that it can download the
! 980: * cache-clean code there. */
! 981: pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
! 982: VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
! 983: #else
! 984: pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
! 985: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 986: #endif
! 987:
! 988: /*
! 989: * map integrated peripherals at same address in l1pagetable
! 990: * so that we can continue to use console.
! 991: */
! 992: copy_io_area_map((pd_entry_t *)l1pagetable);
! 993:
! 994: /*
! 995: * Give the XScale global cache clean code an appropriately
! 996: * sized chunk of unmapped VA space starting at 0xff000000
! 997: * (our device mappings end before this address).
! 998: */
! 999: xscale_cache_clean_addr = 0xff000000U;
! 1000:
! 1001: /*
! 1002: * Now we have the real page tables in place so we can switch to them.
! 1003: * Once this is done we will be running with the REAL kernel page
! 1004: * tables.
! 1005: */
! 1006:
! 1007: /*
! 1008: * Update the physical_freestart/physical_freeend/free_pages
! 1009: * variables.
! 1010: */
! 1011: {
! 1012: physical_freestart = physical_start +
! 1013: (((esym + PGOFSET) & ~PGOFSET) - KERNEL_BASE);
! 1014: physical_freeend = physical_end;
! 1015: free_pages =
! 1016: (physical_freeend - physical_freestart) / PAGE_SIZE;
! 1017: }
! 1018:
! 1019: /* be a client to all domains */
! 1020: cpu_domains(0x55555555);
! 1021: /* Switch tables */
! 1022: #ifdef VERBOSE_INIT_ARM
! 1023: printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
! 1024: physical_freestart, free_pages, free_pages);
! 1025: printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa);
! 1026: #endif
! 1027:
! 1028: /* set new intc register address so that splfoo() doesn't
! 1029: touch illegal address. */
! 1030: pxa2x0_intr_bootstrap(ZAURUS_INTCTL_VBASE);
! 1031:
! 1032: cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
! 1033: setttb(kernel_l1pt.pv_pa);
! 1034: cpu_tlb_flushID();
! 1035: cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
! 1036:
! 1037: /*
! 1038: * Moved from cpu_startup() as data_abort_handler() references
! 1039: * this during uvm init
! 1040: */
! 1041: proc0paddr = (struct user *)kernelstack.pv_va;
! 1042: proc0.p_addr = proc0paddr;
! 1043:
! 1044: #ifdef VERBOSE_INIT_ARM
! 1045: printf("bootstrap done.\n");
! 1046: #endif
! 1047:
! 1048: arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
! 1049:
! 1050: /*
! 1051: * Pages were allocated during the secondary bootstrap for the
! 1052: * stacks for different CPU modes.
! 1053: * We must now set the r13 registers in the different CPU modes to
! 1054: * point to these stacks.
! 1055: * Since the ARM stacks use STMFD etc. we must set r13 to the top end
! 1056: * of the stack memory.
! 1057: */
! 1058: #ifdef VERBOSE_INIT_ARM
! 1059: printf("init subsystems: stacks ");
! 1060: #endif
! 1061:
! 1062: set_stackptr(PSR_IRQ32_MODE,
! 1063: irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
! 1064: set_stackptr(PSR_ABT32_MODE,
! 1065: abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
! 1066: set_stackptr(PSR_UND32_MODE,
! 1067: undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
! 1068:
! 1069: /*
! 1070: * Well we should set a data abort handler.
! 1071: * Once things get going this will change as we will need a proper
! 1072: * handler.
! 1073: * Until then we will use a handler that just panics but tells us
! 1074: * why.
! 1075: * Initialisation of the vectors will just panic on a data abort.
! 1076: * This just fills in a slightly better one.
! 1077: */
! 1078: #ifdef VERBOSE_INIT_ARM
! 1079: printf("vectors ");
! 1080: #endif
! 1081: data_abort_handler_address = (u_int)data_abort_handler;
! 1082: prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
! 1083: undefined_handler_address = (u_int)undefinedinstruction_bounce;
! 1084:
! 1085: /* Initialise the undefined instruction handlers */
! 1086: #ifdef VERBOSE_INIT_ARM
! 1087: printf("undefined ");
! 1088: #endif
! 1089: undefined_init();
! 1090:
! 1091: /* Load memory into UVM. */
! 1092: #ifdef VERBOSE_INIT_ARM
! 1093: printf("page ");
! 1094: #endif
! 1095: uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */
! 1096: uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
! 1097: atop(physical_freestart), atop(physical_freeend),
! 1098: VM_FREELIST_DEFAULT);
! 1099:
! 1100: /* Boot strap pmap telling it where the kernel page table is */
! 1101: #ifdef VERBOSE_INIT_ARM
! 1102: printf("pmap ");
! 1103: #endif
! 1104: pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, KERNEL_VM_BASE,
! 1105: KERNEL_VM_BASE + KERNEL_VM_SIZE);
! 1106:
! 1107: /* Update dump information */
! 1108: cpu_kcore_hdr.pmap_kernel_l1 = (u_int32_t)pmap_kernel()->pm_l1;
! 1109: cpu_kcore_hdr.pmap_kernel_l2 = (u_int32_t)&(pmap_kernel()->pm_l2);
! 1110:
! 1111: #ifdef __HAVE_MEMORY_DISK__
! 1112: md_root_setconf(memory_disk, sizeof memory_disk);
! 1113: #endif
! 1114:
! 1115: #ifdef IPKDB
! 1116: /* Initialise ipkdb */
! 1117: ipkdb_init();
! 1118: if (boothowto & RB_KDB)
! 1119: ipkdb_connect(0);
! 1120: #endif
! 1121:
! 1122: #ifdef KGDB
! 1123: if (boothowto & RB_KDB) {
! 1124: kgdb_debug_init = 1;
! 1125: kgdb_connect(1);
! 1126: }
! 1127: #endif
! 1128:
! 1129: /*
! 1130: * Restore proper bus_space operation, now that pmap is initialized.
! 1131: */
! 1132: pxa2x0_a4x_bs_tag.bs_map = pxa2x0_bs_tag.bs_map = map_func_save;
! 1133:
! 1134: #ifdef DDB
! 1135: db_machine_init();
! 1136:
! 1137: /* Firmware doesn't load symbols. */
! 1138: ddb_init();
! 1139:
! 1140: if (boothowto & RB_KDB)
! 1141: Debugger();
! 1142: #endif
! 1143:
! 1144: /* We return the new stack pointer address */
! 1145: return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
! 1146: }
! 1147:
! 1148: const char *console = "glass";
! 1149:
! 1150: void
! 1151: process_kernel_args(char *args)
! 1152: {
! 1153: char *cp = args;
! 1154:
! 1155: if (cp == NULL || *(int *)cp != BOOT_STRING_MAGIC) {
! 1156: boothowto = RB_AUTOBOOT;
! 1157: return;
! 1158: }
! 1159:
! 1160: /* Eat the cookie */
! 1161: *(int *)cp = 0;
! 1162: cp += sizeof(int);
! 1163:
! 1164: boothowto = 0;
! 1165:
! 1166: /* Make a local copy of the bootargs */
! 1167: strncpy(bootargs, cp, MAX_BOOT_STRING - sizeof(int));
! 1168:
! 1169: cp = bootargs;
! 1170: boot_file = bootargs;
! 1171:
! 1172: /* Skip the kernel image filename */
! 1173: while (*cp != ' ' && *cp != 0)
! 1174: ++cp;
! 1175:
! 1176: if (*cp != 0)
! 1177: *cp++ = 0;
! 1178:
! 1179: while (*cp == ' ')
! 1180: ++cp;
! 1181:
! 1182: boot_args = cp;
! 1183:
! 1184: printf("bootfile: %s\n", boot_file);
! 1185: printf("bootargs: %s\n", boot_args);
! 1186:
! 1187: /* Setup pointer to boot flags */
! 1188: while (*cp != '-')
! 1189: if (*cp++ == '\0')
! 1190: return;
! 1191:
! 1192: for (;*++cp;) {
! 1193: int fl;
! 1194:
! 1195: fl = 0;
! 1196: switch(*cp) {
! 1197: case 'a':
! 1198: fl |= RB_ASKNAME;
! 1199: break;
! 1200: case 'c':
! 1201: fl |= RB_CONFIG;
! 1202: break;
! 1203: case 'd':
! 1204: fl |= RB_KDB;
! 1205: break;
! 1206: case 's':
! 1207: fl |= RB_SINGLE;
! 1208: break;
! 1209: /* XXX undocumented console switching flags */
! 1210: case '0':
! 1211: console = "ffuart";
! 1212: break;
! 1213: case '1':
! 1214: console = "btuart";
! 1215: break;
! 1216: case '2':
! 1217: console = "stuart";
! 1218: break;
! 1219: default:
! 1220: printf("unknown option `%c'\n", *cp);
! 1221: break;
! 1222: }
! 1223: boothowto |= fl;
! 1224: }
! 1225: }
! 1226:
! 1227: #ifdef KGDB
! 1228: #ifndef KGDB_DEVNAME
! 1229: #define KGDB_DEVNAME "ffuart"
! 1230: #endif
! 1231: const char kgdb_devname[] = KGDB_DEVNAME;
! 1232:
! 1233: #if (NCOM > 0)
! 1234: #ifndef KGDB_DEVMODE
! 1235: #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
! 1236: #endif
! 1237: int comkgdbmode = KGDB_DEVMODE;
! 1238: #endif /* NCOM */
! 1239:
! 1240: #endif /* KGDB */
! 1241:
! 1242: void
! 1243: consinit(void)
! 1244: {
! 1245: #if NCOM > 0
! 1246: static int consinit_called = 0;
! 1247: paddr_t paddr;
! 1248: u_int cken = 0;
! 1249:
! 1250: if (consinit_called != 0)
! 1251: return;
! 1252:
! 1253: consinit_called = 1;
! 1254:
! 1255: #ifdef KGDB
! 1256: if (strcmp(kgdb_devname, console) == 0) {
! 1257: /* port is reserved for kgdb */
! 1258: } else
! 1259: #endif
! 1260: if (strcmp(console, "ffuart") == 0) {
! 1261: paddr = PXA2X0_FFUART_BASE;
! 1262: cken = CKEN_FFUART;
! 1263: } else if (strcmp(console, "btuart") == 0) {
! 1264: paddr = PXA2X0_BTUART_BASE;
! 1265: cken = CKEN_BTUART;
! 1266: } else if (strcmp(console, "stuart") == 0) {
! 1267: paddr = PXA2X0_STUART_BASE;
! 1268: cken = CKEN_STUART;
! 1269: irda_on(0);
! 1270: }
! 1271: if (cken != 0 && comcnattach(&pxa2x0_a4x_bs_tag, paddr, comcnspeed,
! 1272: PXA2X0_COM_FREQ, comcnmode) == 0) {
! 1273: early_clkman(cken, 1);
! 1274: }
! 1275: #endif /* NCOM */
! 1276: }
! 1277:
! 1278: #ifdef KGDB
! 1279: void
! 1280: kgdb_port_init(void)
! 1281: {
! 1282: #if (NCOM > 0) && defined(COM_PXA2X0)
! 1283: paddr_t paddr;
! 1284: u_int cken;
! 1285:
! 1286: if (strcmp(kgdb_devname, "ffuart") == 0) {
! 1287: paddr = PXA2X0_FFUART_BASE;
! 1288: cken = CKEN_FFUART;
! 1289: } else if (strcmp(kgdb_devname, "btuart") == 0) {
! 1290: paddr = PXA2X0_BTUART_BASE;
! 1291: cken = CKEN_BTUART;
! 1292: } else if (strcmp(kgdb_devname, "stuart") == 0) {
! 1293: paddr = PXA2X0_STUART_BASE;
! 1294: cken = CKEN_STUART;
! 1295: irda_on(0);
! 1296: } else
! 1297: return;
! 1298:
! 1299: if (com_kgdb_attach_pxa2x0(&pxa2x0_a4x_bs_tag, paddr,
! 1300: kgdb_rate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode) == 0) {
! 1301: early_clkman(cken, 1);
! 1302: }
! 1303: #endif
! 1304: }
! 1305: #endif
! 1306:
! 1307: /* same as pxa2x0_clkman, but before autoconf */
! 1308: void
! 1309: early_clkman(u_int clk, int enable)
! 1310: {
! 1311: u_int32_t rv;
! 1312:
! 1313: rv = ioreg_read(ZAURUS_CLKMAN_VBASE + CLKMAN_CKEN);
! 1314: if (enable)
! 1315: rv |= clk;
! 1316: else
! 1317: rv &= ~clk;
! 1318: ioreg_write(ZAURUS_CLKMAN_VBASE + CLKMAN_CKEN, rv);
! 1319: }
! 1320:
! 1321: int glass_console = 0;
! 1322:
! 1323: void
! 1324: board_startup(void)
! 1325: {
! 1326: extern int lcd_cnattach(void (*)(u_int, int));
! 1327: extern bus_addr_t comconsaddr;
! 1328:
! 1329: #if NWSDISPLAY > 0
! 1330: /*
! 1331: * Try to attach the display console now that VM services
! 1332: * are available.
! 1333: */
! 1334:
! 1335: if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) {
! 1336: if (strcmp(console, "glass") == 0) {
! 1337: printf("attempting to switch console to lcd screen\n");
! 1338: glass_console = 1;
! 1339: }
! 1340: if (glass_console == 1 && lcd_cnattach(early_clkman) == 0) {
! 1341: /*
! 1342: * Kill the existing serial console.
! 1343: * XXX need to bus_space_unmap resources and disable
! 1344: * clocks...
! 1345: */
! 1346: comconsaddr = 0;
! 1347:
! 1348: /*
! 1349: * Display the copyright notice again on the new console
! 1350: */
! 1351: extern const char copyright[];
! 1352: printf("%s\n", copyright);
! 1353: }
! 1354: }
! 1355: #endif
! 1356:
! 1357: if (boothowto & RB_CONFIG) {
! 1358: #ifdef BOOT_CONFIG
! 1359: user_config();
! 1360: #else
! 1361: printf("kernel does not support -c; continuing..\n");
! 1362: #endif
! 1363: }
! 1364: }
CVSweb