1/* $NetBSD: smdk2800_machdep.c,v 1.36 2011/06/30 20:09:28 wiz Exp $ */ 2 3/* 4 * Copyright (c) 2002, 2003, 2005 Fujitsu Component Limited 5 * Copyright (c) 2002, 2003, 2005 Genetec Corporation 6 * All rights reserved. 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. Neither the name of The Fujitsu Component Limited nor the name of 17 * Genetec corporation may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC 21 * CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC 25 * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35/* 36 * Copyright (c) 2001,2002 ARM Ltd 37 * All rights reserved. 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 the company may not be used to endorse or promote 48 * products derived from this software without specific prior written 49 * permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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 */ 64 65/* 66 * Copyright (c) 1997,1998 Mark Brinicombe. 67 * Copyright (c) 1997,1998 Causality Limited. 68 * All rights reserved. 69 * 70 * Redistribution and use in source and binary forms, with or without 71 * modification, are permitted provided that the following conditions 72 * are met: 73 * 1. Redistributions of source code must retain the above copyright 74 * notice, this list of conditions and the following disclaimer. 75 * 2. Redistributions in binary form must reproduce the above copyright 76 * notice, this list of conditions and the following disclaimer in the 77 * documentation and/or other materials provided with the distribution. 78 * 3. All advertising materials mentioning features or use of this software 79 * must display the following acknowledgement: 80 * This product includes software developed by Mark Brinicombe 81 * for the NetBSD Project. 82 * 4. The name of the company nor the name of the author may be used to 83 * endorse or promote products derived from this software without specific 84 * prior written permission. 85 * 86 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 87 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 88 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 89 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 90 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 91 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 92 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 93 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 94 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 95 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 96 * SUCH DAMAGE. 97 * 98 * Machine dependent functions for kernel setup for integrator board 99 * 100 * Created : 24/11/97 101 */ 102 103/* 104 * Machine dependent functions for kernel setup for Samsung SMDK2800 105 * derived from integrator_machdep.c 106 */ 107 108#include <sys/cdefs.h> 109__KERNEL_RCSID(0, "$NetBSD: smdk2800_machdep.c,v 1.36 2011/06/30 20:09:28 wiz Exp $"); 110 111#include "opt_ddb.h" 112#include "opt_kgdb.h" 113#include "opt_pmap_debug.h" 114#include "opt_md.h" 115#include "pci.h" 116 117#include <sys/param.h> 118#include <sys/device.h> 119#include <sys/systm.h> 120#include <sys/kernel.h> 121#include <sys/exec.h> 122#include <sys/proc.h> 123#include <sys/msgbuf.h> 124#include <sys/reboot.h> 125#include <sys/termios.h> 126#include <sys/ksyms.h> 127 128#include <uvm/uvm_extern.h> 129 130#include <dev/cons.h> 131#include <dev/md.h> 132 133#include <machine/db_machdep.h> 134#include <ddb/db_sym.h> 135#include <ddb/db_extern.h> 136#ifdef KGDB 137#include <sys/kgdb.h> 138#endif 139 140#include <machine/bootconfig.h> 141#include <sys/bus.h> 142#include <machine/cpu.h> 143#include <machine/frame.h> 144#include <machine/intr.h> 145#include <arm/undefined.h> 146 147#include <arm/arm32/machdep.h> 148 149#include <arm/s3c2xx0/s3c2800reg.h> 150#include <arm/s3c2xx0/s3c2800var.h> 151#include <evbarm/smdk2xx0/smdk2800var.h> 152 153#include "ksyms.h" 154 155/* Kernel text starts 2MB in from the bottom of the kernel address space. */ 156#define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00200000) 157#define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000) 158 159/* 160 * The range 0xc1000000 - 0xccffffff is available for kernel VM space 161 * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff 162 */ 163#define KERNEL_VM_SIZE 0x0C000000 164 165/* Memory disk support */ 166#if defined(MEMORY_DISK_DYNAMIC) && defined(MEMORY_DISK_ROOT_ADDR) 167#define DO_MEMORY_DISK 168/* We have memory disk image outside of the kernel on ROM. */ 169#ifdef MEMORY_DISK_ROOT_ROM 170/* map the image directory and use read-only */ 171#else 172/* copy the image to RAM */ 173#endif 174#endif 175 176 177/* 178 * Address to call from cpu_reset() to reset the machine. 179 * This is machine architecture dependent as it varies depending 180 * on where the ROM appears when you turn the MMU off. 181 */ 182u_int cpu_reset_address = (u_int)0; 183 184/* Define various stack sizes in pages */ 185#define IRQ_STACK_SIZE 1 186#define ABT_STACK_SIZE 1 187#define UND_STACK_SIZE 1 188 189BootConfig bootconfig; /* Boot config storage */ 190char *boot_args = NULL; 191char *boot_file = NULL; 192 193vm_offset_t physical_start; 194vm_offset_t physical_freestart; 195vm_offset_t physical_freeend; 196vm_offset_t physical_end; 197u_int free_pages; 198 199/*int debug_flags;*/ 200#ifndef PMAP_STATIC_L1S 201int max_processes = 64; /* Default number */ 202#endif /* !PMAP_STATIC_L1S */ 203 204/* Physical and virtual addresses for some global pages */ 205pv_addr_t irqstack; 206pv_addr_t undstack; 207pv_addr_t abtstack; 208pv_addr_t kernelstack; 209 210vm_offset_t msgbufphys; 211 212extern u_int data_abort_handler_address; 213extern u_int prefetch_abort_handler_address; 214extern u_int undefined_handler_address; 215 216#ifdef PMAP_DEBUG 217extern int pmap_debug_level; 218#endif 219 220#define KERNEL_PT_SYS 0 /* L2 table for mapping zero page */ 221#define KERNEL_PT_KERNEL 1 /* L2 table for mapping kernel */ 222#define KERNEL_PT_KERNEL_NUM 2 /* L2 tables for mapping kernel VM */ 223 224#define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM) 225 226#define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */ 227#define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) 228 229pv_addr_t kernel_pt_table[NUM_KERNEL_PTS]; 230 231/* Prototypes */ 232 233void consinit(void); 234void kgdb_port_init(void); 235 236/* A load of console goo. */ 237#include "vga.h" 238#if NVGA > 0 239#include <dev/ic/mc6845reg.h> 240#include <dev/ic/pcdisplayvar.h> 241#include <dev/ic/vgareg.h> 242#include <dev/ic/vgavar.h> 243#endif 244 245#include "com.h" 246#if NCOM > 0 247#include <dev/ic/comreg.h> 248#include <dev/ic/comvar.h> 249#endif 250 251#include "sscom.h" 252#if NSSCOM > 0 253#include "opt_sscom.h" 254#include <arm/s3c2xx0/sscom_var.h> 255#endif 256 257/* 258 * Define the default console speed for the board. This is generally 259 * what the firmware provided with the board defaults to. 260 */ 261#ifndef CONSPEED 262#define CONSPEED B115200 /* TTYDEF_SPEED */ 263#endif 264#ifndef CONMODE 265#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 266#endif 267 268int comcnspeed = CONSPEED; 269int comcnmode = CONMODE; 270 271/* 272 * void cpu_reboot(int howto, char *bootstr) 273 * 274 * Reboots the system 275 * 276 * Deal with any syncing, unmounting, dumping and shutdown hooks, 277 * then reset the CPU. 278 */ 279void 280cpu_reboot(int howto, char *bootstr) 281{ 282 283 cpu_reset_address = vtophys((u_int)s3c2800_softreset); 284 285 /* 286 * If we are still cold then hit the air brakes 287 * and crash to earth fast 288 */ 289 if (cold) { 290 doshutdownhooks(); 291 pmf_system_shutdown(boothowto); 292 printf("The operating system has halted.\n"); 293 printf("Please press any key to reboot.\n\n"); 294 cngetc(); 295 printf("rebooting...\n"); 296 cpu_reset(); 297 /* NOTREACHED */ 298 } 299 /* Disable console buffering */ 300 301 /* 302 * If RB_NOSYNC was not specified sync the discs. 303 * Note: Unless cold is set to 1 here, syslogd will die during the 304 * unmount. It looks like syslogd is getting woken up only to find 305 * that it cannot page part of the binary in as the filesystem has 306 * been unmounted. 307 */ 308 if (!(howto & RB_NOSYNC)) 309 bootsync(); 310 311 /* Say NO to interrupts */ 312 splhigh(); 313 314 /* Do a dump if requested. */ 315 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 316 dumpsys(); 317 318 /* Run any shutdown hooks */ 319 doshutdownhooks(); 320 321 pmf_system_shutdown(boothowto); 322 323 /* Make sure IRQ's are disabled */ 324 IRQdisable; 325 326 if (howto & RB_HALT) { 327 printf("The operating system has halted.\n"); 328 printf("Please press any key to reboot.\n\n"); 329 cngetc(); 330 } 331 printf("rebooting...\n"); 332 cpu_reset(); 333 /* NOTREACHED */ 334} 335 336/* 337 * All built-in peripheral registers are statically mapped in start up 338 * routine. This table tells pmap subsystem about it, and to map them 339 * at the same position. 340 */ 341static const struct pmap_devmap smdk2800_devmap[] = { 342 { 343 SMDK2800_IO_AREA_VBASE, 344 S3C2800_PERIPHERALS, 345 S3C2800_PERIPHERALS_SIZE, 346 VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, 347 }, 348 { 0, 0, 0, 0 } 349}; 350 351#define ioreg_vaddr(pa) ((pa) - S3C2800_PERIPHERALS + SMDK2800_IO_AREA_VBASE) 352#define ioreg32(pa) (*(volatile uint32_t *)ioreg_vaddr(pa)) 353 354/* 355 * u_int initarm(...) 356 * 357 * Initial entry point on startup. This gets called before main() is 358 * entered. 359 * It should be responsible for setting up everything that must be 360 * in place when main is called. 361 * This includes 362 * Taking a copy of the boot configuration structure. 363 * Initialising the physical console so characters can be printed. 364 * Setting up page tables for the kernel 365 * Relocating the kernel to the bottom of physical memory 366 */ 367 368u_int 369initarm(void *arg) 370{ 371 int loop; 372 int loop1; 373 u_int l1pagetable; 374 extern int etext __asm("_etext"); 375 extern int end __asm("_end"); 376 int progress_counter = 0; 377 378#ifdef DO_MEMORY_DISK 379 vm_offset_t md_root_start; 380#define MD_ROOT_SIZE (MEMORY_DISK_ROOT_SIZE * DEV_BSIZE) 381#endif 382 383#define gpio8(reg) (*(volatile uint8_t *)(ioreg_vaddr(S3C2800_GPIO_BASE) + (reg))) 384 385#define LEDSTEP() __LED(progress_counter++) 386 387#define pdatc gpio8(GPIO_PDATC) 388#define __LED(x) (pdatc = (pdatc & ~0x07) | (~(x) & 0x07)) 389 390 LEDSTEP(); 391 /* 392 * Heads up ... Setup the CPU / MMU / TLB functions 393 */ 394 if (set_cpufuncs()) 395 panic("CPU not recognized!"); 396 397 LEDSTEP(); 398 399 400 /* Disable all peripheral interrupts */ 401 ioreg32(S3C2800_INTCTL_BASE + INTCTL_INTMSK) = 0; 402 403 consinit(); 404#ifdef VERBOSE_INIT_ARM 405 printf("consinit done\n"); 406#endif 407 408#ifdef KGDB 409 LEDSTEP(); 410 kgdb_port_init(); 411#endif 412 LEDSTEP(); 413 414#ifdef VERBOSE_INIT_ARM 415 /* Talk to the user */ 416 printf("\nNetBSD/evbarm (SMDK2800) booting ...\n"); 417#endif 418 419 /* 420 * Ok we have the following memory map 421 * 422 * Physical Address Range Description 423 * ----------------------- ---------------------------------- 424 * 0x00000000 - 0x00ffffff Intel flash Memory (16MB) 425 * 0x02000000 - 0x020fffff AMD flash Memory (1MB) 426 * or (depend on DIPSW setting) 427 * 0x00000000 - 0x000fffff AMD flash Memory (1MB) 428 * 0x02000000 - 0x02ffffff Intel flash Memory (16MB) 429 * 430 * 0x08000000 - 0x09ffffff SDRAM (32MB) 431 * 0x20000000 - 0x3fffffff PCI space 432 * 433 * The initarm() has the responsibility for creating the kernel 434 * page tables. 435 * It must also set up various memory pointers that are used 436 * by pmap etc. 437 */ 438 439 /* Fake bootconfig structure for the benefit of pmap.c */ 440 /* XXX must make the memory description h/w independent */ 441 bootconfig.dramblocks = 1; 442 bootconfig.dram[0].address = SDRAM_START; 443 bootconfig.dram[0].pages = SDRAM_SIZE / PAGE_SIZE; 444 445 /* 446 * Set up the variables that define the availablilty of 447 * physical memory. For now, we're going to set 448 * physical_freestart to 0x08200000 (where the kernel 449 * was loaded), and allocate the memory we need downwards. 450 * If we get too close to the bottom of SDRAM, we 451 * will panic. We will update physical_freestart and 452 * physical_freeend later to reflect what pmap_bootstrap() 453 * wants to see. 454 * 455 * XXX pmap_bootstrap() needs an enema. 456 */ 457 physical_start = bootconfig.dram[0].address; 458 physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE); 459 460#if DO_MEMORY_DISK 461#ifdef MEMORY_DISK_ROOT_ROM 462 md_root_start = MEMORY_DISK_ROOT_ADDR; 463 boothowto |= RB_RDONLY; 464#else 465 /* Reserve physmem for ram disk */ 466 md_root_start = ((physical_end - MD_ROOT_SIZE) & ~(L1_S_SIZE-1)); 467 printf("Reserve %ld bytes for memory disk\n", 468 physical_end - md_root_start); 469 /* copy fs contents */ 470 memcpy((void *)md_root_start, (void *)MEMORY_DISK_ROOT_ADDR, 471 MD_ROOT_SIZE); 472 physical_end = md_root_start; 473#endif 474#endif 475 476 physical_freestart = 0x08000000UL; /* XXX */ 477 physical_freeend = 0x08200000UL; 478 479 physmem = (physical_end - physical_start) / PAGE_SIZE; 480 481#ifdef VERBOSE_INIT_ARM 482 /* Tell the user about the memory */ 483 printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem, 484 physical_start, physical_end - 1); 485#endif 486 487 /* 488 * XXX 489 * Okay, the kernel starts 2MB in from the bottom of physical 490 * memory. We are going to allocate our bootstrap pages downwards 491 * from there. 492 * 493 * We need to allocate some fixed page tables to get the kernel 494 * going. We allocate one page directory and a number of page 495 * tables and store the physical addresses in the kernel_pt_table 496 * array. 497 * 498 * The kernel page directory must be on a 16K boundary. The page 499 * tables must be on 4K boundaries. What we do is allocate the 500 * page directory on the first 16K boundary that we encounter, and 501 * the page tables on 4K boundaries otherwise. Since we allocate 502 * at least 3 L2 page tables, we are guaranteed to encounter at 503 * least one 16K aligned region. 504 */ 505 506#ifdef VERBOSE_INIT_ARM 507 printf("Allocating page tables\n"); 508#endif 509 510 free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE; 511 512#ifdef VERBOSE_INIT_ARM 513 printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n", 514 physical_freestart, free_pages, free_pages); 515#endif 516 517 /* Define a macro to simplify memory allocation */ 518#define valloc_pages(var, np) \ 519 alloc_pages((var).pv_pa, (np)); \ 520 (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start; 521 522#define alloc_pages(var, np) \ 523 physical_freeend -= ((np) * PAGE_SIZE); \ 524 if (physical_freeend < physical_freestart) \ 525 panic("initarm: out of memory"); \ 526 (var) = physical_freeend; \ 527 free_pages -= (np); \ 528 memset((char *)(var), 0, ((np) * PAGE_SIZE)); 529 530 loop1 = 0; 531 for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { 532 /* Are we 16KB aligned for an L1 ? */ 533 if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0 534 && kernel_l1pt.pv_pa == 0) { 535 valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); 536 } else { 537 valloc_pages(kernel_pt_table[loop1], 538 L2_TABLE_SIZE / PAGE_SIZE); 539 ++loop1; 540 } 541 } 542 543 /* This should never be able to happen but better confirm that. */ 544 if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0) 545 panic("initarm: Failed to align the kernel page directory\n"); 546 547 /* 548 * Allocate a page for the system page mapped to V0x00000000 549 * This page will just contain the system vectors and can be 550 * shared by all processes. 551 */ 552 alloc_pages(systempage.pv_pa, 1); 553 554 /* Allocate stacks for all modes */ 555 valloc_pages(irqstack, IRQ_STACK_SIZE); 556 valloc_pages(abtstack, ABT_STACK_SIZE); 557 valloc_pages(undstack, UND_STACK_SIZE); 558 valloc_pages(kernelstack, UPAGES); 559 560#ifdef VERBOSE_INIT_ARM 561 printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, 562 irqstack.pv_va); 563 printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, 564 abtstack.pv_va); 565 printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, 566 undstack.pv_va); 567 printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, 568 kernelstack.pv_va); 569#endif 570 571 alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE); 572 573 LEDSTEP(); 574 575 /* 576 * Ok we have allocated physical pages for the primary kernel 577 * page tables 578 */ 579 580#ifdef VERBOSE_INIT_ARM 581 printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa); 582#endif 583 584 /* 585 * Now we start construction of the L1 page table 586 * We start by mapping the L2 page tables into the L1. 587 * This means that we can replace L1 mappings later on if necessary 588 */ 589 l1pagetable = kernel_l1pt.pv_pa; 590 591 /* Map the L2 pages tables in the L1 page table */ 592 pmap_link_l2pt(l1pagetable, 0x00000000, 593 &kernel_pt_table[KERNEL_PT_SYS]); 594 for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) 595 pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000, 596 &kernel_pt_table[KERNEL_PT_KERNEL + loop]); 597 for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++) 598 pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, 599 &kernel_pt_table[KERNEL_PT_VMDATA + loop]); 600 601 /* update the top of the kernel VM */ 602 pmap_curmaxkvaddr = 603 KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000); 604 605#ifdef VERBOSE_INIT_ARM 606 printf("Mapping kernel\n"); 607#endif 608 609 /* Now we fill in the L2 pagetable for the kernel static code/data */ 610 { 611 size_t textsize = (uintptr_t)&etext - KERNEL_TEXT_BASE; 612 size_t totalsize = (uintptr_t)&end - KERNEL_TEXT_BASE; 613 u_int logical; 614 615 textsize = (textsize + PGOFSET) & ~PGOFSET; 616 totalsize = (totalsize + PGOFSET) & ~PGOFSET; 617 618 logical = 0x00200000; /* offset of kernel in RAM */ 619 620 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 621 physical_start + logical, textsize, 622 VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE); 623 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 624 physical_start + logical, totalsize - textsize, 625 VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE); 626 } 627 628#ifdef VERBOSE_INIT_ARM 629 printf("Constructing L2 page tables\n"); 630#endif 631 632 /* Map the stack pages */ 633 pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, 634 IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, 635 PTE_CACHE); 636 pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa, 637 ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, 638 PTE_CACHE); 639 pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa, 640 UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, 641 PTE_CACHE); 642 pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa, 643 UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE); 644 645 pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, 646 L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE); 647 648 for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { 649 pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va, 650 kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE, 651 VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); 652 } 653 654 /* Map the vector page. */ 655#if 1 656 /* MULTI-ICE requires that page 0 is NC/NB so that it can download the 657 * cache-clean code there. */ 658 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, 659 VM_PROT_READ | VM_PROT_WRITE, PTE_NOCACHE); 660#else 661 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, 662 VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE); 663#endif 664 665#ifdef MEMORY_DISK_DYNAMIC 666 /* map MD root image */ 667 pmap_map_chunk(l1pagetable, SMDK2800_MEMORY_DISK_VADDR, md_root_start, 668 MD_ROOT_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE); 669 670 md_root_setconf((void *)md_root_start, MD_ROOT_SIZE); 671#endif /* MEMORY_DISK_DYNAMIC */ 672 /* 673 * map integrated peripherals at same address in l1pagetable 674 * so that we can continue to use console. 675 */ 676 pmap_devmap_bootstrap(l1pagetable, smdk2800_devmap); 677 678 /* 679 * Now we have the real page tables in place so we can switch to them. 680 * Once this is done we will be running with the REAL kernel page 681 * tables. 682 */ 683 684 /* 685 * Update the physical_freestart/physical_freeend/free_pages 686 * variables. 687 */ 688 { 689 physical_freestart = physical_start + 690 (((((uintptr_t)&end) + PGOFSET) & ~PGOFSET) - KERNEL_BASE); 691 physical_freeend = physical_end; 692 free_pages = 693 (physical_freeend - physical_freestart) / PAGE_SIZE; 694 } 695 696 /* Switch tables */ 697#ifdef VERBOSE_INIT_ARM 698 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n", 699 physical_freestart, free_pages, free_pages); 700 printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa); 701#endif 702 LEDSTEP(); 703 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 704 cpu_setttb(kernel_l1pt.pv_pa); 705 cpu_tlb_flushID(); 706 cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); 707 708 /* 709 * Moved from cpu_startup() as data_abort_handler() references 710 * this during uvm init 711 */ 712 uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); 713 714#ifdef VERBOSE_INIT_ARM 715 printf("done!\n"); 716#endif 717 718#if 0 719 /* 720 * The IFPGA registers have just moved. 721 * Detach the diagnostic serial port and reattach at the new address. 722 */ 723 plcomcndetach(); 724 /* 725 * XXX this should only be done in main() but it useful to 726 * have output earlier ... 727 */ 728 consinit(); 729#endif 730 731 LEDSTEP(); 732#ifdef VERBOSE_INIT_ARM 733 printf("bootstrap done.\n"); 734#endif 735 736 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); 737 738 /* 739 * Pages were allocated during the secondary bootstrap for the 740 * stacks for different CPU modes. 741 * We must now set the r13 registers in the different CPU modes to 742 * point to these stacks. 743 * Since the ARM stacks use STMFD etc. we must set r13 to the top end 744 * of the stack memory. 745 */ 746#ifdef VERBOSE_INIT_ARM 747 printf("init subsystems: stacks "); 748#endif 749 750 set_stackptr(PSR_IRQ32_MODE, 751 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); 752 set_stackptr(PSR_ABT32_MODE, 753 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); 754 set_stackptr(PSR_UND32_MODE, 755 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); 756 757 LEDSTEP(); 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 LEDSTEP(); 782 783 /* Load memory into UVM. */ 784#ifdef VERBOSE_INIT_ARM 785 printf("page "); 786#endif 787 uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ 788 uvm_page_physload(atop(physical_freestart), atop(physical_freeend), 789 atop(physical_freestart), atop(physical_freeend), 790 VM_FREELIST_DEFAULT); 791 792 LEDSTEP(); 793 /* Boot strap pmap telling it where the kernel page table is */ 794#ifdef VERBOSE_INIT_ARM 795 printf("pmap "); 796#endif 797 pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); 798 799 LEDSTEP(); 800 801 /* Setup the IRQ system */ 802#ifdef VERBOSE_INIT_ARM 803 printf("irq "); 804#endif 805 /* XXX irq_init(); */ 806 807#ifdef VERBOSE_INIT_ARM 808 printf("done.\n"); 809#endif 810 811#ifdef BOOTHOWTO_INIT 812 boothowto |= BOOTHOWTO_INIT; 813#endif 814 { 815 uint8_t gpio = ~gpio8(GPIO_PDATF); 816 817 if (gpio & (1<<5)) /* SW3 */ 818 boothowto ^= RB_SINGLE; 819 if (gpio & (1<<7)) /* SW7 */ 820 boothowto ^= RB_KDB; 821#ifdef VERBOSE_INIT_ARM 822 printf( "sw: %x boothowto: %x\n", gpio, boothowto ); 823#endif 824 } 825 826#ifdef KGDB 827 if (boothowto & RB_KDB) { 828 kgdb_debug_init = 1; 829 kgdb_connect(1); 830 } 831#endif 832 833#ifdef DDB 834 db_machine_init(); 835 if (boothowto & RB_KDB) 836 Debugger(); 837#endif 838 839 /* We return the new stack pointer address */ 840 return (kernelstack.pv_va + USPACE_SVC_STACK_TOP); 841} 842 843void 844consinit(void) 845{ 846 static int consinit_done = 0; 847 bus_space_tag_t iot = &s3c2xx0_bs_tag; 848 int pclk; 849 850 if (consinit_done != 0) 851 return; 852 853 consinit_done = 1; 854 855 pmap_devmap_register(smdk2800_devmap); 856 857 s3c2800_clock_freq2(ioreg_vaddr(S3C2800_CLKMAN_BASE), NULL, NULL, &pclk); 858 859#if NSSCOM > 0 860#ifdef SSCOM0CONSOLE 861 if (0 == s3c2800_sscom_cnattach(iot, 0, comcnspeed, 862 pclk, comcnmode)) 863 return; 864#endif 865#ifdef SSCOM1CONSOLE 866 if (0 == s3c2800_sscom_cnattach(iot, 1, comcnspeed, 867 pclk, comcnmode)) 868 return; 869#endif 870#endif /* NSSCOM */ 871#if NCOM>0 && defined(CONCOMADDR) 872 if (comcnattach(&isa_io_bs_tag, CONCOMADDR, comcnspeed, 873 COM_FREQ, COM_TYPE_NORMAL, comcnmode)) 874 panic("can't init serial console @%x", CONCOMADDR); 875 return; 876#endif 877 878 consinit_done = 0; 879} 880 881 882#ifdef KGDB 883 884#if (NSSCOM > 0) 885 886#ifdef KGDB_DEVNAME 887const char kgdb_devname[] = KGDB_DEVNAME; 888#else 889const char kgdb_devname[] = ""; 890#endif 891 892#ifndef KGDB_DEVMODE 893#define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE|CSTOPB|PARENB))|CS8) /* 8N1 */ 894#endif 895int kgdb_sscom_mode = KGDB_DEVMODE; 896 897#endif /* NSSCOM */ 898 899void 900kgdb_port_init(void) 901{ 902#if (NSSCOM > 0) 903 int unit = -1; 904 int pclk; 905 906 if (strcmp(kgdb_devname, "sscom0") == 0) 907 unit = 0; 908 else if (strcmp(kgdb_devname, "sscom1") == 0) 909 unit = 1; 910 911 if (unit >= 0) { 912 s3c2800_clock_freq2(ioreg_vaddr(S3C2800_CLKMAN_BASE), 913 NULL, NULL, &pclk); 914 915 s3c2800_sscom_kgdb_attach(&s3c2xx0_bs_tag, 916 unit, kgdb_rate, pclk, kgdb_sscom_mode); 917 } 918#endif 919} 920#endif 921