Annotation of sys/arch/jornada/jornada/jornada_machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: armish_machdep.c,v 1.10 2007/05/19 15:49:05 miod Exp $ */
! 2: /* $NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * Written by Jason R. Thorpe for Wasabi Systems, Inc.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. All advertising materials mentioning features or use of this software
! 19: * must display the following acknowledgement:
! 20: * This product includes software developed for the NetBSD Project by
! 21: * Wasabi Systems, Inc.
! 22: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
! 23: * or promote products derived from this software without specific prior
! 24: * written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
! 30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 36: * POSSIBILITY OF SUCH DAMAGE.
! 37: */
! 38:
! 39: /*
! 40: * Copyright (c) 1997,1998 Mark Brinicombe.
! 41: * Copyright (c) 1997,1998 Causality Limited.
! 42: * All rights reserved.
! 43: *
! 44: * Redistribution and use in source and binary forms, with or without
! 45: * modification, are permitted provided that the following conditions
! 46: * are met:
! 47: * 1. Redistributions of source code must retain the above copyright
! 48: * notice, this list of conditions and the following disclaimer.
! 49: * 2. Redistributions in binary form must reproduce the above copyright
! 50: * notice, this list of conditions and the following disclaimer in the
! 51: * documentation and/or other materials provided with the distribution.
! 52: * 3. All advertising materials mentioning features or use of this software
! 53: * must display the following acknowledgement:
! 54: * This product includes software developed by Mark Brinicombe
! 55: * for the NetBSD Project.
! 56: * 4. The name of the company nor the name of the author may be used to
! 57: * endorse or promote products derived from this software without specific
! 58: * prior written permission.
! 59: *
! 60: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
! 61: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
! 62: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 63: * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
! 64: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 65: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 66: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 67: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 68: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 69: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 70: * SUCH DAMAGE.
! 71: *
! 72: * Machine dependant functions for kernel setup for Intel IQ80321 evaluation
! 73: * boards using RedBoot firmware.
! 74: */
! 75:
! 76: /*
! 77: * DIP switches:
! 78: *
! 79: * S19: no-dot: set RB_KDB. enter kgdb session.
! 80: * S20: no-dot: set RB_SINGLE. don't go multi user mode.
! 81: */
! 82:
! 83: #include <sys/param.h>
! 84: #include <sys/device.h>
! 85: #include <sys/systm.h>
! 86: #include <sys/kernel.h>
! 87: #include <sys/exec.h>
! 88: #include <sys/proc.h>
! 89: #include <sys/msgbuf.h>
! 90: #include <sys/reboot.h>
! 91: #include <sys/termios.h>
! 92: #include <sys/kcore.h>
! 93:
! 94: #include <uvm/uvm_extern.h>
! 95:
! 96: #include <sys/conf.h>
! 97: #include <sys/queue.h>
! 98: #include <sys/device.h>
! 99: #include <dev/cons.h>
! 100:
! 101: #include <machine/db_machdep.h>
! 102: #include <ddb/db_sym.h>
! 103: #include <ddb/db_extern.h>
! 104:
! 105: #include <machine/bootconfig.h>
! 106: #include <machine/bus.h>
! 107: #include <machine/cpu.h>
! 108: #include <machine/frame.h>
! 109: #include <arm/kcore.h>
! 110: #include <arm/undefined.h>
! 111: #include <arm/machdep.h>
! 112:
! 113: #include <arm/sa11x0/sa11x0_reg.h>
! 114: #include <arm/sa11x0/sa11x0_var.h>
! 115: #include <machine/jornada_reg.h>
! 116:
! 117: /* Kernel text starts 2MB in from the bottom of the kernel address space. */
! 118: #define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00200000)
! 119: #define KERNEL_VM_BASE (KERNEL_BASE + 0x10000000)
! 120:
! 121: /*
! 122: * The range 0xc1000000 - 0xcfffffff is available for kernel VM space
! 123: * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff
! 124: */
! 125: #define KERNEL_VM_SIZE 0x20000000
! 126:
! 127:
! 128: /*
! 129: * Address to call from cpu_reset() to reset the machine.
! 130: * This is machine architecture dependant as it varies depending
! 131: * on where the ROM appears when you turn the MMU off.
! 132: */
! 133:
! 134: u_int cpu_reset_address = 0;
! 135:
! 136: /* Define various stack sizes in pages */
! 137: #define IRQ_STACK_SIZE 1
! 138: #define ABT_STACK_SIZE 1
! 139: #ifdef IPKDB
! 140: #define UND_STACK_SIZE 2
! 141: #else
! 142: #define UND_STACK_SIZE 1
! 143: #endif
! 144:
! 145: BootConfig bootconfig; /* Boot config storage */
! 146: char *boot_args = NULL;
! 147: char *boot_file = NULL;
! 148:
! 149: paddr_t physical_start;
! 150: paddr_t physical_freestart;
! 151: paddr_t physical_freeend;
! 152: paddr_t physical_end;
! 153: u_int free_pages;
! 154: paddr_t pagetables_start;
! 155: int physmem = 0;
! 156:
! 157: /*int debug_flags;*/
! 158: #ifndef PMAP_STATIC_L1S
! 159: int max_processes = 64; /* Default number */
! 160: #endif /* !PMAP_STATIC_L1S */
! 161:
! 162: /* Physical and virtual addresses for some global pages */
! 163: pv_addr_t systempage;
! 164: pv_addr_t irqstack;
! 165: pv_addr_t undstack;
! 166: pv_addr_t abtstack;
! 167: extern pv_addr_t kernelstack;
! 168: pv_addr_t minidataclean;
! 169:
! 170: #define CPU_SA110_CACHE_CLEAN_SIZE (0x4000 * 2)
! 171: extern unsigned int sa1_cache_clean_addr;
! 172: extern unsigned int sa1_cache_clean_size;
! 173: static vaddr_t sa1_cc_base;
! 174:
! 175: paddr_t msgbufphys;
! 176:
! 177: extern u_int data_abort_handler_address;
! 178: extern u_int prefetch_abort_handler_address;
! 179: extern u_int undefined_handler_address;
! 180:
! 181: #ifdef PMAP_DEBUG
! 182: extern int pmap_debug_level;
! 183: #endif
! 184:
! 185: #define KERNEL_PT_SYS 0 /* L2 table for mapping zero page */
! 186: #define KERNEL_PT_KERNEL 1 /* L2 table for mapping kernel */
! 187: #define KERNEL_PT_KERNEL_NUM 8
! 188: /* L2 table for mapping peripherals */
! 189: #define KERNEL_PT_IO (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM)
! 190: /* L2 tables for mapping kernel VM */
! 191: #define KERNEL_PT_VMDATA (KERNEL_PT_IO + 1)
! 192: #define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */
! 193: #define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
! 194:
! 195: pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
! 196:
! 197: extern struct user *proc0paddr;
! 198:
! 199: /* Prototypes */
! 200:
! 201: #define BOOT_STRING_MAGIC 0x4f425344
! 202:
! 203: char bootargs[MAX_BOOT_STRING];
! 204: void process_kernel_args(char *);
! 205:
! 206: void consinit(void);
! 207: void fakecninit(bus_addr_t paddr);
! 208:
! 209: #ifdef BOOTCONSOLE_COM
! 210: int sacomcnattach(bus_space_tag_t bust, bus_addr_t busa, int speed);
! 211: void sacomfakecnattach(bus_addr_t addr);
! 212: #else /* !BOOTCONSOLE_COM */
! 213: #include <arch/jornada/dev/jfbreg.h>
! 214: void jfbfakecnattach(bus_addr_t addr);
! 215: int jfbcnattach(bus_space_tag_t bust, bus_addr_t busa);
! 216: #endif /* BOOTCONSOLE_COM */
! 217:
! 218: #ifndef CONSPEED
! 219: #define CONSPEED 115200
! 220: #endif
! 221:
! 222: int comcnspeed = CONSPEED;
! 223:
! 224:
! 225: /*
! 226: * void boot(int howto, char *bootstr)
! 227: *
! 228: * Reboots the system
! 229: *
! 230: * Deal with any syncing, unmounting, dumping and shutdown hooks,
! 231: * then reset the CPU.
! 232: */
! 233: void board_reset(void);
! 234: void board_powerdown(void);
! 235: void
! 236: boot(int howto)
! 237: {
! 238: /*
! 239: * If we are still cold then hit the air brakes
! 240: * and crash to earth fast
! 241: */
! 242: if (cold) {
! 243: doshutdownhooks();
! 244: if ((howto & (RB_HALT | RB_USERREQ)) != RB_USERREQ) {
! 245: printf("The operating system has halted.\n");
! 246: printf("Please press any key to reboot.\n\n");
! 247: cngetc();
! 248: }
! 249: #ifndef DO_NOT_RESET_SA1
! 250: printf("rebooting...\n");
! 251: delay(60000);
! 252: cpu_reset();
! 253: printf("reboot failed; spinning\n");
! 254: #else /* DO_NOT_RESET_SA1 */
! 255: printf("will not reset CPU; spinning\n");
! 256: #endif /* !DO_NOT_RESET_SA1 */
! 257: while(1);
! 258: /*NOTREACHED*/
! 259: }
! 260:
! 261: /* Disable console buffering */
! 262: /* cnpollc(1);*/
! 263:
! 264: /*
! 265: * If RB_NOSYNC was not specified sync the discs.
! 266: * Note: Unless cold is set to 1 here, syslogd will die during the
! 267: * unmount. It looks like syslogd is getting woken up only to find
! 268: * that it cannot page part of the binary in as the filesystem has
! 269: * been unmounted.
! 270: */
! 271: if (!(howto & RB_NOSYNC))
! 272: bootsync(howto);
! 273:
! 274: /* Say NO to interrupts */
! 275: splhigh();
! 276:
! 277: /* Do a dump if requested. */
! 278: if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
! 279: dumpsys();
! 280:
! 281: /* Run any shutdown hooks */
! 282: doshutdownhooks();
! 283:
! 284: /* Make sure IRQ's are disabled */
! 285: IRQdisable;
! 286:
! 287: if (howto & RB_HALT) {
! 288: if (howto & RB_POWERDOWN) {
! 289: /* TODO */
! 290: //board_powerdown();
! 291: printf("WARNING: powerdown failed!\n");
! 292: }
! 293:
! 294: printf("The operating system has halted.\n");
! 295: printf("Please press any key to reboot.\n\n");
! 296: cngetc();
! 297: }
! 298:
! 299: #ifndef DO_NOT_RESET_SA1
! 300: printf("rebooting...\n");
! 301:
! 302: /* TODO board_reset */
! 303: cpu_reset();
! 304: printf("reboot failed; spinning\n");
! 305: #else /* DO_NOT_RESET_SA1 */
! 306: printf("will not reset CPU; spinning\n");
! 307: #endif /* !DO_NOT_RESET_SA1 */
! 308: while(1)
! 309: ;
! 310: /*NOTREACHED*/
! 311: }
! 312:
! 313: /*
! 314: * Mapping table for core kernel memory. These areas are mapped in
! 315: * init time at fixed virtual address with section mappings.
! 316: */
! 317: const struct pmap_devmap jornada_devmap[] = {
! 318: /*
! 319: * Map the on-board devices VA == PA so that we can access them
! 320: * with the MMU on or off.
! 321: */
! 322: {
! 323: SACOM3_BASE,
! 324: SACOM3_HW_BASE,
! 325: 0x24 /* SACOM3_SIZE, */,
! 326: VM_PROT_READ|VM_PROT_WRITE,
! 327: PTE_NOCACHE,
! 328: },
! 329: {
! 330: SAIPIC_VBASE,
! 331: SAIPIC_BASE,
! 332: 0x24 /* SAIPIC_SIZE, */,
! 333: VM_PROT_READ|VM_PROT_WRITE,
! 334: PTE_NOCACHE,
! 335: },
! 336: #ifndef BOOTCONSOLE_COM
! 337: {
! 338: JFB_VBASE,
! 339: JFB_BASE,
! 340: JFB_SIZE,
! 341: VM_PROT_READ|VM_PROT_WRITE,
! 342: PTE_NOCACHE,
! 343: },
! 344: #endif /* !BOOTCONSOLE_COM */
! 345: {0, 0, 0, 0, 0}
! 346: };
! 347:
! 348:
! 349: /*
! 350: * u_int initarm(...)
! 351: *
! 352: * Initial entry point on startup. This gets called before main() is
! 353: * entered.
! 354: * It should be responsible for setting up everything that must be
! 355: * in place when main is called.
! 356: * This includes
! 357: * Taking a copy of the boot configuration structure.
! 358: * Initialising the physical console so characters can be printed.
! 359: * Setting up page tables for the kernel
! 360: * Relocating the kernel to the bottom of physical memory
! 361: */
! 362: u_int
! 363: initarm(void *arg)
! 364: {
! 365: extern cpu_kcore_hdr_t cpu_kcore_hdr;
! 366: int loop;
! 367: int loop1;
! 368: u_int l1pagetable;
! 369: pv_addr_t kernel_l1pt;
! 370: paddr_t memstart;
! 371: psize_t memsize;
! 372: extern u_int32_t esym; /* &_end if no symbols are loaded */
! 373:
! 374: /* get ready for splfoo() */
! 375: sa11x0_intr_bootstrap(SAIPIC_BASE);
! 376:
! 377: pmap_devmap_register(jornada_devmap);
! 378:
! 379: /* setup a serial console for very early boot */
! 380: #ifdef BOOTCONSOLE_COM
! 381: fakecninit(SACOM3_HW_BASE);
! 382: #else
! 383: fakecninit(JFB_BASE);
! 384: #endif
! 385:
! 386: /*
! 387: * Heads up ... Setup the CPU / MMU / TLB functions
! 388: */
! 389: if (set_cpufuncs())
! 390: panic("cpu not recognized!");
! 391:
! 392: /*
! 393: * Examine the boot args string for options we need to know about
! 394: * now.
! 395: */
! 396: /* XXX should really be done after setting up the console, but we
! 397: * XXX need to parse the console selection flags right now. */
! 398: process_kernel_args((char *)0xc0200000 - MAX_BOOT_STRING - 1);
! 399: #ifdef RAMDISK_HOOKS
! 400: boothowto |= RB_DFLTROOT;
! 401: #endif /* RAMDISK_HOOKS */
! 402:
! 403: /* Talk to the user */
! 404: printf("\nOpenBSD/jornada booting ...\n");
! 405:
! 406: #define VERBOSE_INIT_ARM
! 407:
! 408: /* Ugly hardcode DRAM bounds */
! 409: /* TODO */
! 410: memstart = (paddr_t)0xc0000000;
! 411: memsize = (psize_t)32 * 1024 * 1024;
! 412:
! 413: //#define DEBUG
! 414: #ifdef DEBUG
! 415: printf("initarm: Configuring system ...\n");
! 416: #endif
! 417:
! 418: /* Fake bootconfig structure for the benefit of pmap.c */
! 419: /* XXX must make the memory description h/w independant */
! 420: bootconfig.dramblocks = 1;
! 421: bootconfig.dram[0].address = memstart;
! 422: bootconfig.dram[0].pages = memsize / PAGE_SIZE;
! 423:
! 424: /*
! 425: * Set up the variables that define the availablilty of
! 426: * physical memory. For now, we're going to set
! 427: * physical_freestart to 0xc0200000 (where the kernel
! 428: * was loaded), and allocate the memory we need downwards.
! 429: * We will update physical_freestart and physical_freeend
! 430: * later to reflect what pmap_bootstrap() wants to see.
! 431: *
! 432: * XXX pmap_bootstrap() needs an enema.
! 433: */
! 434: physical_start = bootconfig.dram[0].address;
! 435: physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
! 436:
! 437: physical_freestart = 0xc0200000UL;
! 438: physical_freeend = physical_end;
! 439:
! 440: physmem = (physical_end - physical_start) / PAGE_SIZE;
! 441:
! 442: #if defined(DEBUG) || defined(VERBOSE_INIT_ARM)
! 443: /* Tell the user about the memory */
! 444: printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
! 445: physical_start, physical_end - 1);
! 446: #endif
! 447:
! 448: /*
! 449: * Okay, the kernel starts 2MB in from the bottom of physical
! 450: * memory. We are going to allocate our bootstrap pages downwards
! 451: * from there.
! 452: *
! 453: * We need to allocate some fixed page tables to get the kernel
! 454: * going. We allocate one page directory and a number of page
! 455: * tables and store the physical addresses in the kernel_pt_table
! 456: * array.
! 457: *
! 458: * The kernel page directory must be on a 16K boundary. The page
! 459: * tables must be on 4K boundaries. What we do is allocate the
! 460: * page directory on the first 16K boundary that we encounter, and
! 461: * the page tables on 4K boundaries otherwise. Since we allocate
! 462: * at least 3 L2 page tables, we are guaranteed to encounter at
! 463: * least one 16K aligned region.
! 464: */
! 465:
! 466: #ifdef VERBOSE_INIT_ARM
! 467: printf("Allocating page tables\n");
! 468: #endif
! 469:
! 470: free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;
! 471:
! 472: #ifdef VERBOSE_INIT_ARM
! 473: printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
! 474: physical_freestart, free_pages, free_pages);
! 475: #endif
! 476:
! 477: /* Define a macro to simplify memory allocation */
! 478: #define valloc_pages(var, np) \
! 479: alloc_pages((var).pv_pa, (np)); \
! 480: (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
! 481:
! 482: #define alloc_pages(var, np) \
! 483: physical_freeend -= ((np) * PAGE_SIZE); \
! 484: if (physical_freeend < physical_freestart) \
! 485: panic("initarm: out of memory"); \
! 486: (var) = physical_freeend; \
! 487: free_pages -= (np); \
! 488: memset((char *)(var), 0, ((np) * PAGE_SIZE));
! 489:
! 490: loop1 = 0;
! 491: kernel_l1pt.pv_pa = 0;
! 492: for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
! 493: /* Are we 16KB aligned for an L1 ? */
! 494: if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0
! 495: && kernel_l1pt.pv_pa == 0) {
! 496: valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
! 497: } else {
! 498: valloc_pages(kernel_pt_table[loop1],
! 499: L2_TABLE_SIZE / PAGE_SIZE);
! 500: ++loop1;
! 501: }
! 502: }
! 503:
! 504: /* This should never be able to happen but better confirm that. */
! 505: if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
! 506: panic("initarm: Failed to align the kernel page directory");
! 507:
! 508: /*
! 509: * Allocate a page for the system page mapped to V0x00000000
! 510: * This page will just contain the system vectors and can be
! 511: * shared by all processes.
! 512: */
! 513: alloc_pages(systempage.pv_pa, 1);
! 514:
! 515: /* Allocate stacks for all modes */
! 516: valloc_pages(irqstack, IRQ_STACK_SIZE);
! 517: valloc_pages(abtstack, ABT_STACK_SIZE);
! 518: valloc_pages(undstack, UND_STACK_SIZE);
! 519: valloc_pages(kernelstack, UPAGES);
! 520:
! 521: #ifdef VERBOSE_INIT_ARM
! 522: printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
! 523: irqstack.pv_va);
! 524: printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
! 525: abtstack.pv_va);
! 526: printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
! 527: undstack.pv_va);
! 528: printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
! 529: kernelstack.pv_va);
! 530: #endif
! 531:
! 532: /*
! 533: * XXX Defer this to later so that we can reclaim the memory
! 534: * XXX used by the RedBoot page tables.
! 535: */
! 536: alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);
! 537:
! 538: /*
! 539: * XXX Actually, we only need virtual space and don't need
! 540: * XXX physical memory for sa110_cc_base and sa11x0_idle_mem.
! 541: */
! 542: /*
! 543: * XXX totally stuffed hack to work round problems introduced
! 544: * in recent versions of the pmap code. Due to the calls used there
! 545: * we cannot allocate virtual memory during bootstrap.
! 546: */
! 547: for (;;) {
! 548: alloc_pages(sa1_cc_base, 1);
! 549: if (!(sa1_cc_base & (CPU_SA110_CACHE_CLEAN_SIZE - 1)))
! 550: break;
! 551: }
! 552: {
! 553: vaddr_t dummy;
! 554: alloc_pages(dummy, CPU_SA110_CACHE_CLEAN_SIZE / PAGE_SIZE - 1);
! 555: }
! 556: sa1_cache_clean_addr = sa1_cc_base;
! 557: sa1_cache_clean_size = CPU_SA110_CACHE_CLEAN_SIZE / 2;
! 558:
! 559:
! 560: /*
! 561: * Ok we have allocated physical pages for the primary kernel
! 562: * page tables
! 563: */
! 564:
! 565: #ifdef VERBOSE_INIT_ARM
! 566: printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
! 567: #endif
! 568:
! 569: /*
! 570: * Now we start construction of the L1 page table
! 571: * We start by mapping the L2 page tables into the L1.
! 572: * This means that we can replace L1 mappings later on if necessary
! 573: */
! 574: l1pagetable = kernel_l1pt.pv_pa;
! 575:
! 576: #ifdef HIGH_VECT
! 577: /* Map the L2 pages tables in the L1 page table */
! 578: pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00400000 - 1),
! 579: &kernel_pt_table[KERNEL_PT_SYS]);
! 580: #else
! 581: /* Map the L2 pages tables in the L1 page table */
! 582: pmap_link_l2pt(l1pagetable, 0x00000000,
! 583: &kernel_pt_table[KERNEL_PT_SYS]);
! 584: #endif
! 585: for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
! 586: pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
! 587: &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
! 588:
! 589: for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
! 590: pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
! 591: &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
! 592:
! 593: /* link devices */
! 594: pmap_link_l2pt(l1pagetable, 0xfd000000/* XXX XXX */,
! 595: &kernel_pt_table[KERNEL_PT_IO]);
! 596:
! 597: /* update the top of the kernel VM */
! 598: pmap_curmaxkvaddr =
! 599: KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
! 600:
! 601: #ifdef VERBOSE_INIT_ARM
! 602: printf("Mapping kernel\n");
! 603: #endif
! 604:
! 605: /* Now we fill in the L2 pagetable for the kernel static code/data
! 606: * and the symbol table. */
! 607: {
! 608: extern char etext[];
! 609: #ifdef VERBOSE_INIT_ARM
! 610: extern char _end[];
! 611: #endif
! 612: size_t textsize = (u_int32_t) etext - KERNEL_TEXT_BASE;
! 613: size_t totalsize = esym - KERNEL_TEXT_BASE;
! 614: u_int logical;
! 615:
! 616: #ifdef VERBOSE_INIT_ARM
! 617: printf("kernelsize text %x total %x end %x esym %x\n",
! 618: textsize, totalsize, _end, esym);
! 619: #endif
! 620:
! 621: textsize = round_page(textsize);
! 622: totalsize = round_page(totalsize);
! 623:
! 624: logical = 0x00200000; /* offset of kernel in RAM */
! 625:
! 626: /* Update dump information */
! 627: cpu_kcore_hdr.kernelbase = KERNEL_BASE;
! 628: cpu_kcore_hdr.kerneloffs = logical;
! 629: cpu_kcore_hdr.staticsize = totalsize;
! 630:
! 631: logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
! 632: physical_start + logical, textsize,
! 633: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 634: pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
! 635: physical_start + logical, totalsize - textsize,
! 636: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 637: }
! 638:
! 639: #ifdef VERBOSE_INIT_ARM
! 640: printf("Constructing L2 page tables\n");
! 641: #endif
! 642:
! 643: /* Map the stack pages */
! 644: pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
! 645: IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 646: pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
! 647: ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 648: pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
! 649: UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 650: pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
! 651: UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
! 652:
! 653: pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
! 654: L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE);
! 655:
! 656: for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
! 657: pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
! 658: kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
! 659: VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
! 660: }
! 661:
! 662: pmap_map_chunk(l1pagetable, sa1_cache_clean_addr, 0xe0000000,
! 663: CPU_SA110_CACHE_CLEAN_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 664:
! 665: /* Map the vector page. */
! 666: #ifdef HIGH_VECT
! 667: pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
! 668: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 669: #else
! 670: pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
! 671: VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
! 672: #endif
! 673:
! 674: /* XXX XXX */
! 675: pmap_devmap_bootstrap(l1pagetable, jornada_devmap);
! 676:
! 677: /*
! 678: * Now we have the real page tables in place so we can switch to them.
! 679: * Once this is done we will be running with the REAL kernel page
! 680: * tables.
! 681: */
! 682:
! 683: /*
! 684: * Update the physical_freestart/physical_freeend/free_pages
! 685: * variables.
! 686: */
! 687: {
! 688: physical_freestart = physical_start - KERNEL_BASE +
! 689: round_page(esym);
! 690: physical_freeend = physical_end;
! 691: free_pages =
! 692: (physical_freeend - physical_freestart) / PAGE_SIZE;
! 693: }
! 694: #ifdef VERBOSE_INIT_ARM
! 695: printf("physical_freestart %x end %x\n", physical_freestart,
! 696: physical_freeend);
! 697: #endif
! 698:
! 699: /* be a client to all domains */
! 700: cpu_domains(0x55555555);
! 701: /* Switch tables */
! 702: #ifdef VERBOSE_INIT_ARM
! 703: printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
! 704: physical_freestart, free_pages, free_pages);
! 705: printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa);
! 706: #endif
! 707:
! 708: /* set new intc register address so that splfoo() doesn't
! 709: touch illegal address. */
! 710: sa11x0_intr_bootstrap(SAIPIC_VBASE);
! 711:
! 712: cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
! 713: setttb(kernel_l1pt.pv_pa);
! 714: cpu_tlb_flushID();
! 715: cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
! 716:
! 717: /* update with our virtual address */
! 718: #ifdef BOOTCONSOLE_COM
! 719: fakecninit(SACOM3_BASE);
! 720: #else
! 721: fakecninit(JFB_VBASE);
! 722: #endif /* BOOTCONSOLE_COM */
! 723: /*
! 724: * Moved from cpu_startup() as data_abort_handler() references
! 725: * this during uvm init
! 726: */
! 727: proc0paddr = (struct user *)kernelstack.pv_va;
! 728: proc0.p_addr = proc0paddr;
! 729:
! 730: #ifdef VERBOSE_INIT_ARM
! 731: printf("bootstrap done.\n");
! 732: #endif
! 733:
! 734: #ifdef HIGH_VECT
! 735: arm32_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
! 736: #else
! 737: arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
! 738: #endif
! 739:
! 740: /*
! 741: * Pages were allocated during the secondary bootstrap for the
! 742: * stacks for different CPU modes.
! 743: * We must now set the r13 registers in the different CPU modes to
! 744: * point to these stacks.
! 745: * Since the ARM stacks use STMFD etc. we must set r13 to the top end
! 746: * of the stack memory.
! 747: */
! 748: #ifdef VERBOSE_INIT_ARM
! 749: printf("init subsystems: stacks ");
! 750: #endif
! 751:
! 752: set_stackptr(PSR_IRQ32_MODE,
! 753: irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
! 754: set_stackptr(PSR_ABT32_MODE,
! 755: abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
! 756: set_stackptr(PSR_UND32_MODE,
! 757: undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
! 758:
! 759: /*
! 760: * Well we should set a data abort handler.
! 761: * Once things get going this will change as we will need a proper
! 762: * handler.
! 763: * Until then we will use a handler that just panics but tells us
! 764: * why.
! 765: * Initialisation of the vectors will just panic on a data abort.
! 766: * This just fills in a slightly better one.
! 767: */
! 768: #ifdef VERBOSE_INIT_ARM
! 769: printf("vectors ");
! 770: #endif
! 771: data_abort_handler_address = (u_int)data_abort_handler;
! 772: prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
! 773: undefined_handler_address = (u_int)undefinedinstruction_bounce;
! 774:
! 775: /* Initialise the undefined instruction handlers */
! 776: #ifdef VERBOSE_INIT_ARM
! 777: printf("undefined ");
! 778: #endif
! 779: undefined_init();
! 780:
! 781: /* Load memory into UVM. */
! 782: #ifdef VERBOSE_INIT_ARM
! 783: printf("page ");
! 784: #endif
! 785: uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */
! 786: uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
! 787: atop(physical_freestart), atop(physical_freeend),
! 788: VM_FREELIST_DEFAULT);
! 789:
! 790: /* Boot strap pmap telling it where the kernel page table is */
! 791: #ifdef VERBOSE_INIT_ARM
! 792: printf("pmap ");
! 793: #endif
! 794: pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, KERNEL_VM_BASE,
! 795: KERNEL_VM_BASE + KERNEL_VM_SIZE);
! 796:
! 797: /* Update dump information */
! 798: cpu_kcore_hdr.pmap_kernel_l1 = (u_int32_t)pmap_kernel()->pm_l1;
! 799: cpu_kcore_hdr.pmap_kernel_l2 = (u_int32_t)&(pmap_kernel()->pm_l2);
! 800:
! 801: /* Setup the IRQ system */
! 802: #ifdef VERBOSE_INIT_ARM
! 803: printf("irq ");
! 804: #endif
! 805: sa11x0_init_interrupt_masks();
! 806:
! 807: #ifdef VERBOSE_INIT_ARM
! 808: printf("done.\n");
! 809: #endif
! 810:
! 811: #ifdef DDB
! 812: db_machine_init();
! 813:
! 814: /* Firmware doesn't load symbols. */
! 815: ddb_init();
! 816:
! 817: if (boothowto & RB_KDB)
! 818: Debugger();
! 819: #endif
! 820:
! 821: /* We return the new stack pointer address */
! 822: return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
! 823: }
! 824:
! 825: void
! 826: process_kernel_args(char *args)
! 827: {
! 828: char *cp = args;
! 829:
! 830: if (cp == NULL || *(int *)cp != BOOT_STRING_MAGIC) {
! 831: boothowto = RB_AUTOBOOT;
! 832: return;
! 833: }
! 834:
! 835: /* Eat the cookie */
! 836: *(int *)cp = 0;
! 837: cp += sizeof(int);
! 838:
! 839: boothowto = 0;
! 840:
! 841: /* Make a local copy of the bootargs */
! 842: strncpy(bootargs, cp, MAX_BOOT_STRING - sizeof(int));
! 843:
! 844: cp = bootargs;
! 845: boot_file = bootargs;
! 846:
! 847: /* Skip the kernel image filename */
! 848: while (*cp != ' ' && *cp != 0)
! 849: ++cp;
! 850:
! 851: if (*cp != 0)
! 852: *cp++ = 0;
! 853:
! 854: while (*cp == ' ')
! 855: ++cp;
! 856:
! 857: boot_args = cp;
! 858:
! 859: #if 0
! 860: printf("bootfile: %s\n", boot_file);
! 861: printf("bootargs: %s\n", boot_args);
! 862: #endif
! 863:
! 864: /* Setup pointer to boot flags */
! 865: while (*cp != '-')
! 866: if (*cp++ == '\0')
! 867: return;
! 868:
! 869: for (;*++cp;) {
! 870: int fl;
! 871:
! 872: fl = 0;
! 873: switch(*cp) {
! 874: case 'a':
! 875: fl |= RB_ASKNAME;
! 876: break;
! 877: case 'c':
! 878: fl |= RB_CONFIG;
! 879: break;
! 880: case 'd':
! 881: fl |= RB_KDB;
! 882: break;
! 883: case 's':
! 884: fl |= RB_SINGLE;
! 885: break;
! 886: default:
! 887: printf("unknown option `%c'\n", *cp);
! 888: break;
! 889: }
! 890: boothowto |= fl;
! 891: }
! 892: }
! 893:
! 894:
! 895: void
! 896: consinit(void)
! 897: {
! 898: /* XXX defer console attachment to autoconf */
! 899: return;
! 900: }
! 901:
! 902: void
! 903: fakecninit(bus_addr_t addr)
! 904: {
! 905: /*
! 906: * Early console initialization.
! 907: * XXX cn_getc stuff
! 908: */
! 909: switch(addr) {
! 910: #ifdef BOOTCONSOLE_COM
! 911: case SACOM3_HW_BASE:
! 912: case SACOM3_BASE:
! 913: sacomfakecnattach(addr);
! 914: break;
! 915: #else
! 916: case JFB_BASE:
! 917: case JFB_VBASE:
! 918: jfbfakecnattach(addr);
! 919: break;
! 920: #endif /* BOOTCONSOLE_COM */
! 921: default:
! 922: panic("serial console not configured");
! 923: }
! 924: }
! 925:
! 926: void
! 927: board_startup(void)
! 928: {
! 929: if (boothowto & RB_CONFIG) {
! 930: #ifdef BOOT_CONFIG
! 931: user_config();
! 932: #else
! 933: printf("kernel does not support -c; continuing..\n");
! 934: #endif
! 935: }
! 936: }
CVSweb