netwinder_machdep.c revision 1.61
1/* $NetBSD: netwinder_machdep.c,v 1.61 2006/04/05 00:37:11 uwe Exp $ */ 2 3/* 4 * Copyright (c) 1997,1998 Mark Brinicombe. 5 * Copyright (c) 1997,1998 Causality Limited. 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. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Mark Brinicombe 19 * for the NetBSD Project. 20 * 4. The name of the company nor the name of the author may be used to 21 * endorse or promote products derived from this software without specific 22 * prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * Machine dependant functions for kernel setup for EBSA285 core architecture 37 * using Netwinder firmware 38 * 39 * Created : 24/11/97 40 */ 41 42#include <sys/cdefs.h> 43__KERNEL_RCSID(0, "$NetBSD: netwinder_machdep.c,v 1.61 2006/04/05 00:37:11 uwe Exp $"); 44 45#include "opt_ddb.h" 46#include "opt_ipkdb.h" 47#include "opt_pmap_debug.h" 48 49#include <sys/param.h> 50#include <sys/device.h> 51#include <sys/systm.h> 52#include <sys/kernel.h> 53#include <sys/exec.h> 54#include <sys/proc.h> 55#include <sys/msgbuf.h> 56#include <sys/reboot.h> 57#include <sys/termios.h> 58#include <sys/ksyms.h> 59 60#include <uvm/uvm_extern.h> 61 62#include <dev/cons.h> 63 64#include <machine/db_machdep.h> 65#include <ddb/db_sym.h> 66#include <ddb/db_extern.h> 67 68#include <arm/arm32/machdep.h> 69 70#include <machine/bootconfig.h> 71#define _ARM32_BUS_DMA_PRIVATE 72#include <machine/bus.h> 73#include <machine/cpu.h> 74#include <machine/frame.h> 75#include <machine/intr.h> 76#include <arm/undefined.h> 77 78#include <machine/netwinder_boot.h> 79#include <arm/footbridge/dc21285mem.h> 80#include <arm/footbridge/dc21285reg.h> 81 82#include "isa.h" 83#include "isadma.h" 84#if NISA > 0 85#include <dev/isa/isareg.h> 86#include <dev/isa/isavar.h> 87#endif 88 89#include "igsfb.h" 90#if NIGSFB > 0 91#include <dev/pci/pcivar.h> 92#include <dev/pci/igsfb_pcivar.h> 93#endif 94 95#include "pckbc.h" 96#if NPCKBC > 0 97#include <dev/ic/i8042reg.h> 98#include <dev/ic/pckbcvar.h> 99#endif 100 101#include "com.h" 102#include <dev/ic/comreg.h> 103#include <dev/ic/comvar.h> 104 105#include "ksyms.h" 106 107static bus_space_handle_t isa_base = (bus_space_handle_t) DC21285_PCI_IO_VBASE; 108 109bs_protos(generic); 110 111#define ISA_GETBYTE(r) generic_bs_r_1(0, isa_base, (r)) 112#define ISA_PUTBYTE(r,v) generic_bs_w_1(0, isa_base, (r), (v)) 113 114/* 115 * Address to call from cpu_reset() to reset the machine. 116 * This is machine architecture dependant as it varies depending 117 * on where the ROM appears when you turn the MMU off. 118 */ 119static void netwinder_reset(void); 120u_int cpu_reset_address; 121 122u_int dc21285_fclk = 63750000; 123 124/* Define various stack sizes in pages */ 125#define IRQ_STACK_SIZE 1 126#define ABT_STACK_SIZE 1 127#ifdef IPKDB 128#define UND_STACK_SIZE 2 129#else 130#define UND_STACK_SIZE 1 131#endif 132 133struct nwbootinfo nwbootinfo; 134BootConfig bootconfig; /* Boot config storage */ 135static char bootargs[MAX_BOOT_STRING + 1]; 136char *boot_args = NULL; 137char *boot_file = NULL; 138 139vm_offset_t physical_start; 140vm_offset_t physical_freestart; 141vm_offset_t physical_freeend; 142vm_offset_t physical_end; 143u_int free_pages; 144vm_offset_t pagetables_start; 145int physmem = 0; 146 147/*int debug_flags;*/ 148#ifndef PMAP_STATIC_L1S 149int max_processes = 64; /* Default number */ 150#endif /* !PMAP_STATIC_L1S */ 151 152/* Physical and virtual addresses for some global pages */ 153pv_addr_t systempage; 154pv_addr_t irqstack; 155pv_addr_t undstack; 156pv_addr_t abtstack; 157extern pv_addr_t kernelstack; /* in arm32_machdep.c */ 158 159vm_offset_t msgbufphys; 160 161extern u_int data_abort_handler_address; 162extern u_int prefetch_abort_handler_address; 163extern u_int undefined_handler_address; 164 165#ifdef PMAP_DEBUG 166extern int pmap_debug_level; 167#endif 168 169#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */ 170#define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */ 171#define KERNEL_PT_VMDATA 2 /* Page tables for mapping kernel VM */ 172#define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */ 173#define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) 174 175pv_addr_t kernel_pt_table[NUM_KERNEL_PTS]; 176 177#define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000) 178/* 179 * The range 0xf1000000 - 0xfcffffff is available for kernel VM space 180 * Footbridge registers and I/O mappings occupy 0xfd000000 - 0xffffffff 181 */ 182#if NIGSFB > 0 183/* XXX: uwe: map 16 megs at 0xfc000000 for igsfb(4) */ 184#define KERNEL_VM_SIZE 0x0B000000 185#else 186#define KERNEL_VM_SIZE 0x0C000000 187#endif 188 189extern struct user *proc0paddr; /* in arm32_machdep.c */ 190 191/* Prototypes */ 192 193void consinit(void); 194void process_kernel_args(char *); 195void data_abort_handler(trapframe_t *); 196void prefetch_abort_handler(trapframe_t *); 197void undefinedinstruction_bounce(trapframe_t *); 198 199 200/* A load of console goo. */ 201#ifndef CONSDEVNAME 202# if (NIGSFB > 0) && (NPCKBC > 0) 203# define CONSDEVNAME "igsfb" 204# elif NCOM > 0 205# define CONSDEVNAME "com" 206# else 207# error CONSDEVNAME not defined and no known console device configured 208# endif 209#endif /* !CONSDEVNAME */ 210 211#ifndef CONCOMADDR 212#define CONCOMADDR 0x3f8 213#endif 214 215#ifndef CONSPEED 216#define CONSPEED B115200 /* match NeTTrom */ 217#endif 218 219#ifndef CONMODE 220#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 221#endif 222 223int comcnspeed = CONSPEED; 224int comcnmode = CONMODE; 225 226extern struct consdev kcomcons; 227static void kcomcnputc(dev_t, int); 228 229#if NIGSFB > 0 230/* XXX: uwe */ 231#define IGS_PCI_MEM_VBASE 0xfc000000 232#define IGS_PCI_MEM_VSIZE 0x01000000 233#define IGS_PCI_MEM_BASE 0x08000000 234 235extern struct arm32_pci_chipset footbridge_pci_chipset; 236extern struct bus_space footbridge_pci_io_bs_tag; 237extern struct bus_space footbridge_pci_mem_bs_tag; 238extern void footbridge_pci_bs_tag_init(void); 239 240/* standard methods */ 241extern bs_map_proto(footbridge_mem); 242extern bs_unmap_proto(footbridge_mem); 243 244/* our hooks */ 245static bs_map_proto(nw_footbridge_mem); 246static bs_unmap_proto(nw_footbridge_mem); 247#endif 248 249 250/* 251 * void cpu_reboot(int howto, char *bootstr) 252 * 253 * Reboots the system 254 * 255 * Deal with any syncing, unmounting, dumping and shutdown hooks, 256 * then reset the CPU. 257 */ 258 259void 260cpu_reboot(int howto, char *bootstr) 261{ 262#ifdef DIAGNOSTIC 263 /* info */ 264 printf("boot: howto=%08x curlwp=%p\n", howto, curlwp); 265#endif 266 267 /* 268 * If we are still cold then hit the air brakes 269 * and crash to earth fast 270 */ 271 if (cold) { 272 doshutdownhooks(); 273 printf("The operating system has halted.\n"); 274 printf("Please press any key to reboot.\n\n"); 275 cngetc(); 276 printf("rebooting...\n"); 277 cpu_reset(); 278 /*NOTREACHED*/ 279 } 280 281 /* Disable console buffering */ 282/* cnpollc(1);*/ 283 284 /* 285 * If RB_NOSYNC was not specified sync the discs. 286 * Note: Unless cold is set to 1 here, syslogd will die during 287 * the unmount. It looks like syslogd is getting woken up 288 * only to find that it cannot page part of the binary in as 289 * the filesystem has been unmounted. 290 */ 291 if (!(howto & RB_NOSYNC)) 292 bootsync(); 293 294 /* Say NO to interrupts */ 295 splhigh(); 296 297 /* Do a dump if requested. */ 298 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 299 dumpsys(); 300 301 /* Run any shutdown hooks */ 302 doshutdownhooks(); 303 304 /* Make sure IRQ's are disabled */ 305 IRQdisable; 306 307 if (howto & RB_HALT) { 308 printf("The operating system has halted.\n"); 309 printf("Please press any key to reboot.\n\n"); 310 cngetc(); 311 } 312 313 printf("rebooting...\n"); 314 cpu_reset(); 315 /*NOTREACHED*/ 316} 317 318/* 319 * NB: this function runs with MMU disabled! 320 */ 321static void 322netwinder_reset(void) 323{ 324 register u_int base = DC21285_PCI_IO_BASE; 325 326#define PUTBYTE(reg, val) \ 327 *((volatile u_int8_t *)(base + (reg))) = (val) 328 329 PUTBYTE(0x338, 0x84); /* Red led(GP17), fan on(GP12) */ 330 PUTBYTE(0x370, 0x87); /* Enter the extended function mode */ 331 PUTBYTE(0x370, 0x87); /* (need to write the magic twice) */ 332 PUTBYTE(0x370, 0x07); /* Select Logical Device Number reg */ 333 PUTBYTE(0x371, 0x07); /* Select Logical Device 7 (GPIO) */ 334 PUTBYTE(0x370, 0xe6); /* Select GP16 Control Reg */ 335 PUTBYTE(0x371, 0x00); /* Make GP16 an output */ 336 PUTBYTE(0x338, 0xc4); /* RESET(GP16), red led, fan on */ 337} 338 339/* 340 * Mapping table for core kernel memory. This memory is mapped at init 341 * time with section mappings. 342 */ 343struct l1_sec_map { 344 vm_offset_t va; 345 vm_offset_t pa; 346 vm_size_t size; 347 vm_prot_t prot; 348 int cache; 349} l1_sec_table[] = { 350 /* Map 1MB for CSR space */ 351 { DC21285_ARMCSR_VBASE, DC21285_ARMCSR_BASE, 352 DC21285_ARMCSR_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 353 PTE_NOCACHE }, 354 355 /* Map 1MB for fast cache cleaning space */ 356 { DC21285_CACHE_FLUSH_VBASE, DC21285_SA_CACHE_FLUSH_BASE, 357 DC21285_CACHE_FLUSH_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 358 PTE_CACHE }, 359 360 /* Map 1MB for PCI IO space */ 361 { DC21285_PCI_IO_VBASE, DC21285_PCI_IO_BASE, 362 DC21285_PCI_IO_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 363 PTE_NOCACHE }, 364 365 /* Map 1MB for PCI IACK space */ 366 { DC21285_PCI_IACK_VBASE, DC21285_PCI_IACK_SPECIAL, 367 DC21285_PCI_IACK_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 368 PTE_NOCACHE }, 369 370 /* Map 16MB of type 1 PCI config access */ 371 { DC21285_PCI_TYPE_1_CONFIG_VBASE, DC21285_PCI_TYPE_1_CONFIG, 372 DC21285_PCI_TYPE_1_CONFIG_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 373 PTE_NOCACHE }, 374 375 /* Map 16MB of type 0 PCI config access */ 376 { DC21285_PCI_TYPE_0_CONFIG_VBASE, DC21285_PCI_TYPE_0_CONFIG, 377 DC21285_PCI_TYPE_0_CONFIG_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 378 PTE_NOCACHE }, 379 380 /* Map 1MB of 32 bit PCI address space for ISA MEM accesses via PCI */ 381 { DC21285_PCI_ISA_MEM_VBASE, DC21285_PCI_MEM_BASE, 382 DC21285_PCI_ISA_MEM_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 383 PTE_NOCACHE }, 384 385#if NIGSFB > 0 386 /* XXX: uwe: Map 16MB of PCI address space for CyberPro as console */ 387 { IGS_PCI_MEM_VBASE, DC21285_PCI_MEM_BASE + IGS_PCI_MEM_BASE, 388 IGS_PCI_MEM_VSIZE, VM_PROT_READ|VM_PROT_WRITE, 389 PTE_NOCACHE }, 390#endif 391 392 { 0, 0, 0, 0, 0 } 393}; 394 395/* 396 * u_int initarm(...); 397 * 398 * Initial entry point on startup. This gets called before main() is 399 * entered. 400 * It should be responsible for setting up everything that must be 401 * in place when main is called. 402 * This includes 403 * Taking a copy of the boot configuration structure. 404 * Initialising the physical console so characters can be printed. 405 * Setting up page tables for the kernel 406 * Relocating the kernel to the bottom of physical memory 407 */ 408 409u_int 410initarm(void *arg) 411{ 412 int loop; 413 int loop1; 414 u_int l1pagetable; 415 extern char _end[]; 416 pv_addr_t kernel_l1pt; 417 418 /* 419 * Turn the led off, then turn it yellow. 420 * 0x80 - red; 0x04 - fan; 0x02 - green. 421 */ 422 ISA_PUTBYTE(0x338, 0x04); 423 ISA_PUTBYTE(0x338, 0x86); 424 425 /* 426 * Set up a diagnostic console so we can see what's going 427 * on. 428 */ 429 cn_tab = &kcomcons; 430 431 /* Talk to the user */ 432 printf("\nNetBSD/netwinder booting ...\n"); 433 434 /* 435 * Heads up ... Setup the CPU / MMU / TLB functions 436 */ 437 if (set_cpufuncs()) 438 panic("CPU not recognized!"); 439 440 /* 441 * We are currently running with the MMU enabled and the 442 * entire address space mapped VA==PA, except for the 443 * first 64MB of RAM is also double-mapped at 0xf0000000. 444 * There is an L1 page table at 0x00008000. 445 * 446 * We also have the 21285's PCI I/O space mapped where 447 * we expect it. 448 */ 449 450 printf("initarm: Configuring system ...\n"); 451 452 /* 453 * Copy out the boot info passed by the firmware. Note that 454 * early versions of NeTTrom fill this in with bogus values, 455 * so we need to sanity check it. 456 */ 457 memcpy(&nwbootinfo, (caddr_t)(KERNEL_BASE + 0x100), 458 sizeof(nwbootinfo)); 459#ifdef VERBOSE_INIT_ARM 460 printf("NeTTrom boot info:\n"); 461 printf("\tpage size = 0x%08lx\n", nwbootinfo.bi_pagesize); 462 printf("\tnpages = %ld (0x%08lx)\n", nwbootinfo.bi_nrpages, 463 nwbootinfo.bi_nrpages); 464 printf("\trootdev = 0x%08lx\n", nwbootinfo.bi_rootdev); 465 printf("\tcmdline = %s\n", nwbootinfo.bi_cmdline); 466#endif 467 if (nwbootinfo.bi_nrpages != 0x02000 && 468 nwbootinfo.bi_nrpages != 0x04000 && 469 nwbootinfo.bi_nrpages != 0x08000 && 470 nwbootinfo.bi_nrpages != 0x10000) { 471 nwbootinfo.bi_pagesize = 0xdeadbeef; 472 nwbootinfo.bi_nrpages = 0x01000; /* 16MB */ 473 nwbootinfo.bi_rootdev = 0; 474 } 475 476 /* Fake bootconfig structure for the benefit of pmap.c */ 477 /* XXX must make the memory description h/w independant */ 478 bootconfig.dramblocks = 1; 479 bootconfig.dram[0].address = 0; 480 bootconfig.dram[0].pages = nwbootinfo.bi_nrpages; 481 482 /* 483 * Set up the variables that define the availablilty of 484 * physical memory. 485 * 486 * Since the NetWinder NeTTrom doesn't load ELF symbols 487 * for us, we can safely assume that everything after end[] 488 * is free. We start there and allocate upwards. 489 */ 490 physical_start = bootconfig.dram[0].address; 491 physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE); 492 493 physical_freestart = ((((vaddr_t) _end) + PGOFSET) & ~PGOFSET) - 494 KERNEL_BASE; 495 physical_freeend = physical_end; 496 free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE; 497 498#ifdef VERBOSE_INIT_ARM 499 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n", 500 physical_freestart, free_pages, free_pages); 501#endif 502 503 physmem = (physical_end - physical_start) / PAGE_SIZE; 504 505 /* Tell the user about the memory */ 506 printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem, 507 physical_start, physical_end - 1); 508 509 /* 510 * Okay, we need to allocate some fixed page tables to get the 511 * kernel going. We allocate one page directory and a number 512 * of page tables and store the physical addresses in the 513 * kernel_pt_table array. 514 * 515 * The kernel page directory must be on a 16K boundary. The page 516 * tables must be on 4K boundaries. What we do is allocate the 517 * page directory on the first 16K boundary that we encounter, 518 * and the page tables on 4K boundaries otherwise. Since we 519 * allocate at least 3 L2 page tables, we are guaranteed to 520 * encounter at least one 16K aligned region. 521 */ 522 523#ifdef VERBOSE_INIT_ARM 524 printf("Allocating page tables\n"); 525#endif 526 527 /* Define a macro to simplify memory allocation */ 528#define valloc_pages(var, np) \ 529 alloc_pages((var).pv_pa, (np)); \ 530 (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start; 531 532#define alloc_pages(var, np) \ 533 (var) = physical_freestart; \ 534 physical_freestart += ((np) * PAGE_SIZE);\ 535 free_pages -= (np); \ 536 memset((char *)(var), 0, ((np) * PAGE_SIZE)); 537 538 loop1 = 0; 539 kernel_l1pt.pv_pa = 0; 540 for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { 541 /* Are we 16KB aligned for an L1 ? */ 542 if ((physical_freestart & (L1_TABLE_SIZE - 1)) == 0 543 && kernel_l1pt.pv_pa == 0) { 544 valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); 545 } else { 546 valloc_pages(kernel_pt_table[loop1], 547 L2_TABLE_SIZE / PAGE_SIZE); 548 ++loop1; 549 } 550 } 551 552 /* This should never be able to happen but better confirm that. */ 553 if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0) 554 panic("initarm: Failed to align the kernel page directory"); 555 556 /* 557 * Allocate a page for the system page mapped to V0x00000000 558 * This page will just contain the system vectors and can be 559 * shared by all processes. 560 */ 561 alloc_pages(systempage.pv_pa, 1); 562 563 /* Allocate stacks for all modes */ 564 valloc_pages(irqstack, IRQ_STACK_SIZE); 565 valloc_pages(abtstack, ABT_STACK_SIZE); 566 valloc_pages(undstack, UND_STACK_SIZE); 567 valloc_pages(kernelstack, UPAGES); 568 569#ifdef VERBOSE_INIT_ARM 570 printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, 571 irqstack.pv_va); 572 printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, 573 abtstack.pv_va); 574 printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, 575 undstack.pv_va); 576 printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, 577 kernelstack.pv_va); 578#endif 579 580 alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE); 581 582 /* 583 * Ok we have allocated physical pages for the primary kernel 584 * page tables 585 */ 586 587#ifdef VERBOSE_INIT_ARM 588 printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa); 589#endif 590 591 /* 592 * Now we start consturction of the L1 page table 593 * We start by mapping the L2 page tables into the L1. 594 * This means that we can replace L1 mappings later on if necessary 595 */ 596 l1pagetable = kernel_l1pt.pv_pa; 597 598 /* Map the L2 pages tables in the L1 page table */ 599 pmap_link_l2pt(l1pagetable, 0x00000000, 600 &kernel_pt_table[KERNEL_PT_SYS]); 601 pmap_link_l2pt(l1pagetable, KERNEL_BASE, 602 &kernel_pt_table[KERNEL_PT_KERNEL]); 603 for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) 604 pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, 605 &kernel_pt_table[KERNEL_PT_VMDATA + loop]); 606 607 /* update the top of the kernel VM */ 608 pmap_curmaxkvaddr = 609 KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000); 610 611#ifdef VERBOSE_INIT_ARM 612 printf("Mapping kernel\n"); 613#endif 614 615 /* Now we fill in the L2 pagetable for the kernel static code/data */ 616 { 617 /* 618 * The kernel starts in the first 1MB of RAM, and we'd 619 * like to use a section mapping for text, so we'll just 620 * map from KERNEL_BASE to etext[] to _end[]. 621 */ 622 623 extern char etext[]; 624 size_t textsize = (uintptr_t) etext - KERNEL_BASE; 625 size_t totalsize = (uintptr_t) _end - KERNEL_BASE; 626 u_int logical; 627 628 textsize = (textsize + PGOFSET) & ~PGOFSET; 629 totalsize = (totalsize + PGOFSET) & ~PGOFSET; 630 631 textsize = textsize & ~PGOFSET; 632 totalsize = (totalsize + PGOFSET) & ~PGOFSET; 633 634 logical = 0; /* offset into RAM */ 635 636 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 637 physical_start + logical, textsize, 638 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 639 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 640 physical_start + logical, totalsize - textsize, 641 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 642 } 643 644#ifdef VERBOSE_INIT_ARM 645 printf("Constructing L2 page tables\n"); 646#endif 647 648 /* Map the stack pages */ 649 pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, 650 IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 651 pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa, 652 ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 653 pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa, 654 UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 655 pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa, 656 UPAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 657 658 pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, 659 L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); 660 661 for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { 662 pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va, 663 kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE, 664 VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); 665 } 666 667 /* Map the vector page. */ 668 pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, 669 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 670 671 /* 672 * Map devices we can map w/ section mappings. 673 */ 674 loop = 0; 675 while (l1_sec_table[loop].size) { 676 vm_size_t sz; 677 678#ifdef VERBOSE_INIT_ARM 679 printf("%08lx -> %08lx @ %08lx\n", l1_sec_table[loop].pa, 680 l1_sec_table[loop].pa + l1_sec_table[loop].size - 1, 681 l1_sec_table[loop].va); 682#endif 683 for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE) 684 pmap_map_section(l1pagetable, 685 l1_sec_table[loop].va + sz, 686 l1_sec_table[loop].pa + sz, 687 l1_sec_table[loop].prot, 688 l1_sec_table[loop].cache); 689 ++loop; 690 } 691 692 /* 693 * Now we have the real page tables in place so we can switch to them. 694 * Once this is done we will be running with the REAL kernel page 695 * tables. 696 */ 697 698 /* Switch tables */ 699#ifdef VERBOSE_INIT_ARM 700 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n", 701 physical_freestart, free_pages, free_pages); 702 printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa); 703#endif 704 705 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 706 setttb(kernel_l1pt.pv_pa); 707 cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); 708 709 /* 710 * Moved from cpu_startup() as data_abort_handler() references 711 * this during uvm init 712 */ 713 proc0paddr = (struct user *)kernelstack.pv_va; 714 lwp0.l_addr = proc0paddr; 715 716#ifdef VERBOSE_INIT_ARM 717 printf("done!\n"); 718#endif 719 720 /* 721 * XXX this should only be done in main() but it useful to 722 * have output earlier ... 723 */ 724 consinit(); 725 726#ifdef VERBOSE_INIT_ARM 727 printf("bootstrap done.\n"); 728#endif 729 730 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); 731 732 /* 733 * Pages were allocated during the secondary bootstrap for the 734 * stacks for different CPU modes. 735 * We must now set the r13 registers in the different CPU modes to 736 * point to these stacks. 737 * Since the ARM stacks use STMFD etc. we must set r13 to the top end 738 * of the stack memory. 739 */ 740 printf("init subsystems: stacks "); 741 742 set_stackptr(PSR_IRQ32_MODE, 743 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); 744 set_stackptr(PSR_ABT32_MODE, 745 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); 746 set_stackptr(PSR_UND32_MODE, 747 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); 748 749 /* 750 * Well we should set a data abort handler. 751 * Once things get going this will change as we will need a proper 752 * handler. 753 * Until then we will use a handler that just panics but tells us 754 * why. 755 * Initialisation of the vectors will just panic on a data abort. 756 * This just fills in a slightly better one. 757 */ 758 printf("vectors "); 759 data_abort_handler_address = (u_int)data_abort_handler; 760 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 761 undefined_handler_address = (u_int)undefinedinstruction_bounce; 762 763 /* Initialise the undefined instruction handlers */ 764 printf("undefined "); 765 undefined_init(); 766 767 /* Load memory into UVM. */ 768 printf("page "); 769 uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ 770 771 /* XXX Always one RAM block -- nuke the loop. */ 772 for (loop = 0; loop < bootconfig.dramblocks; loop++) { 773 paddr_t start = (paddr_t)bootconfig.dram[loop].address; 774 paddr_t end = start + (bootconfig.dram[loop].pages * PAGE_SIZE); 775#if NISADMA > 0 776 paddr_t istart, isize; 777 extern struct arm32_dma_range *footbridge_isa_dma_ranges; 778 extern int footbridge_isa_dma_nranges; 779#endif 780 781 if (start < physical_freestart) 782 start = physical_freestart; 783 if (end > physical_freeend) 784 end = physical_freeend; 785 786#if 0 787 printf("%d: %lx -> %lx\n", loop, start, end - 1); 788#endif 789 790#if NISADMA > 0 791 if (arm32_dma_range_intersect(footbridge_isa_dma_ranges, 792 footbridge_isa_dma_nranges, 793 start, end - start, 794 &istart, &isize)) { 795 /* 796 * Place the pages that intersect with the 797 * ISA DMA range onto the ISA DMA free list. 798 */ 799#if 0 800 printf(" ISADMA 0x%lx -> 0x%lx\n", istart, 801 istart + isize - 1); 802#endif 803 uvm_page_physload(atop(istart), 804 atop(istart + isize), atop(istart), 805 atop(istart + isize), VM_FREELIST_ISADMA); 806 807 /* 808 * Load the pieces that come before the 809 * intersection onto the default free list. 810 */ 811 if (start < istart) { 812#if 0 813 printf(" BEFORE 0x%lx -> 0x%lx\n", 814 start, istart - 1); 815#endif 816 uvm_page_physload(atop(start), 817 atop(istart), atop(start), 818 atop(istart), VM_FREELIST_DEFAULT); 819 } 820 821 /* 822 * Load the pieces that come after the 823 * intersection onto the default free list. 824 */ 825 if ((istart + isize) < end) { 826#if 0 827 printf(" AFTER 0x%lx -> 0x%lx\n", 828 (istart + isize), end - 1); 829#endif 830 uvm_page_physload(atop(istart + isize), 831 atop(end), atop(istart + isize), 832 atop(end), VM_FREELIST_DEFAULT); 833 } 834 } else { 835 uvm_page_physload(atop(start), atop(end), 836 atop(start), atop(end), VM_FREELIST_DEFAULT); 837 } 838#else /* NISADMA > 0 */ 839 uvm_page_physload(atop(start), atop(end), 840 atop(start), atop(end), VM_FREELIST_DEFAULT); 841#endif /* NISADMA > 0 */ 842 } 843 844 /* Boot strap pmap telling it where the kernel page table is */ 845 printf("pmap "); 846 pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, KERNEL_VM_BASE, 847 KERNEL_VM_BASE + KERNEL_VM_SIZE); 848 849 /* Now that pmap is inited, we can set cpu_reset_address */ 850 cpu_reset_address = (u_int)vtophys((vaddr_t)netwinder_reset); 851 852 /* Setup the IRQ system */ 853 printf("irq "); 854 footbridge_intr_init(); 855 printf("done.\n"); 856 857 /* 858 * Warn the user if the bootinfo was bogus. We already 859 * faked up some safe values. 860 */ 861 if (nwbootinfo.bi_pagesize == 0xdeadbeef) 862 printf("WARNING: NeTTrom boot info corrupt\n"); 863 864#ifdef IPKDB 865 /* Initialise ipkdb */ 866 ipkdb_init(); 867 if (boothowto & RB_KDB) 868 ipkdb_connect(0); 869#endif 870 871 872#if NKSYMS || defined(DDB) || defined(LKM) 873 /* Firmware doesn't load symbols. */ 874 ksyms_init(0, NULL, NULL); 875#endif 876 877#ifdef DDB 878 db_machine_init(); 879 if (boothowto & RB_KDB) 880 Debugger(); 881#endif 882 883 /* Turn the led green */ 884 ISA_PUTBYTE(0x338, 0x06); 885 886 /* We return the new stack pointer address */ 887 return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); 888} 889 890void 891process_kernel_args(char *args) 892{ 893 894 boothowto = 0; 895 896 /* Make a local copy of the bootargs */ 897 strncpy(bootargs, args, MAX_BOOT_STRING); 898 899 args = bootargs; 900 boot_file = bootargs; 901 902 /* Skip the kernel image filename */ 903 while (*args != ' ' && *args != 0) 904 ++args; 905 906 if (*args != 0) 907 *args++ = 0; 908 909 while (*args == ' ') 910 ++args; 911 912 boot_args = args; 913 914 printf("bootfile: %s\n", boot_file); 915 printf("bootargs: %s\n", boot_args); 916 917 parse_mi_bootargs(boot_args); 918} 919 920void 921consinit(void) 922{ 923 static int consinit_called = 0; 924 const char *console = CONSDEVNAME; 925 926 if (consinit_called != 0) 927 return; 928 929 consinit_called = 1; 930 931#ifdef DIAGNOSTIC 932 printf("consinit(\"%s\")\n", console); 933#endif 934 935#if NISA > 0 936 /* Initialise the ISA subsystem early ... */ 937 isa_footbridge_init(DC21285_PCI_IO_VBASE, DC21285_PCI_ISA_MEM_VBASE); 938#endif 939 940 if (strncmp(console, "igsfb", 5) == 0) { 941#if NIGSFB > 0 942 int res; 943 944 footbridge_pci_bs_tag_init(); 945 946 /* 947 * XXX: uwe: special case mapping for the igsfb memory space. 948 * 949 * The problem with this is that when footbridge is 950 * attached during normal autoconfiguration the bus 951 * space tags will be reinited and these hooks lost. 952 * However, since igsfb(4) don't unmap memory during 953 * normal operation, this is ok. But if the igsfb is 954 * configured but is not a console, we waste 16M of 955 * kernel VA space. 956 */ 957 footbridge_pci_mem_bs_tag.bs_map = nw_footbridge_mem_bs_map; 958 footbridge_pci_mem_bs_tag.bs_unmap = nw_footbridge_mem_bs_unmap; 959 960 igsfb_pci_cnattach(&footbridge_pci_io_bs_tag, 961 &footbridge_pci_mem_bs_tag, 962 &footbridge_pci_chipset, 963 0, 8, 0); 964#if NPCKBC > 0 965 res = pckbc_cnattach(&isa_io_bs_tag, 966 IO_KBD, KBCMDP, PCKBC_KBD_SLOT); 967 if (res) 968 printf("pckbc_cnattach: %d!\n", res); 969#endif 970#else 971 panic("igsfb console not configured"); 972#endif /* NIGSFB */ 973 } else { 974#ifdef DIAGNOSTIC 975 if (strncmp(console, "com", 3) != 0) { 976 printf("consinit: unknown CONSDEVNAME=\"%s\"," 977 " falling back to \"com\"\n", console); 978 } 979#endif 980#if NCOM > 0 981 if (comcnattach(&isa_io_bs_tag, CONCOMADDR, comcnspeed, 982 COM_FREQ, COM_TYPE_NORMAL, comcnmode)) 983 panic("can't init serial console @%x", CONCOMADDR); 984#else 985 panic("serial console @%x not configured", CONCOMADDR); 986#endif 987 } 988} 989 990 991#if NIGSFB > 0 992static int 993nw_footbridge_mem_bs_map(t, bpa, size, cacheable, bshp) 994 void *t; 995 bus_addr_t bpa; 996 bus_size_t size; 997 int cacheable; 998 bus_space_handle_t *bshp; 999{ 1000 bus_addr_t startpa, endpa; 1001 1002 /* Round the allocation to page boundries */ 1003 startpa = trunc_page(bpa); 1004 endpa = round_page(bpa + size); 1005 1006 /* 1007 * Check for mappings of the igsfb(4) memory space as we have 1008 * this space already mapped. 1009 */ 1010 if (startpa >= IGS_PCI_MEM_BASE 1011 && endpa < (IGS_PCI_MEM_BASE + IGS_PCI_MEM_VSIZE)) { 1012 /* Store the bus space handle */ 1013 *bshp = IGS_PCI_MEM_VBASE 1014 + (bpa - IGS_PCI_MEM_BASE); 1015#ifdef DEBUG 1016 printf("nw/mem_bs_map: %08x+%08x: %08x..%08x -> %08x\n", 1017 (u_int32_t)bpa, (u_int32_t)size, 1018 (u_int32_t)startpa, (u_int32_t)endpa, 1019 (u_int32_t)*bshp); 1020#endif 1021 return 0; 1022 } 1023 1024 return (footbridge_mem_bs_map(t, bpa, size, cacheable, bshp)); 1025} 1026 1027 1028static void 1029nw_footbridge_mem_bs_unmap(t, bsh, size) 1030 void *t; 1031 bus_space_handle_t bsh; 1032 bus_size_t size; 1033{ 1034 1035 /* 1036 * Check for mappings of the igsfb(4) memory space as we have 1037 * this space already mapped. 1038 */ 1039 if (bsh >= IGS_PCI_MEM_VBASE 1040 && bsh < (IGS_PCI_MEM_VBASE + IGS_PCI_MEM_VSIZE)) { 1041#ifdef DEBUG 1042 printf("nw/bs_unmap: 0x%08x\n", (u_int32_t)bsh); 1043#endif 1044 return; 1045 } 1046 1047 footbridge_mem_bs_unmap(t, bsh, size); 1048} 1049#endif /* NIGSFB */ 1050 1051 1052static bus_space_handle_t kcom_base = (bus_space_handle_t) (DC21285_PCI_IO_VBASE + CONCOMADDR); 1053 1054#define KCOM_GETBYTE(r) generic_bs_r_1(0, kcom_base, (r)) 1055#define KCOM_PUTBYTE(r,v) generic_bs_w_1(0, kcom_base, (r), (v)) 1056 1057static int 1058kcomcngetc(dev_t dev) 1059{ 1060 int stat, c; 1061 1062 /* block until a character becomes available */ 1063 while (!ISSET(stat = KCOM_GETBYTE(com_lsr), LSR_RXRDY)) 1064 ; 1065 1066 c = KCOM_GETBYTE(com_data); 1067 stat = KCOM_GETBYTE(com_iir); 1068 return c; 1069} 1070 1071/* 1072 * Console kernel output character routine. 1073 */ 1074static void 1075kcomcnputc(dev_t dev, int c) 1076{ 1077 int timo; 1078 1079 /* wait for any pending transmission to finish */ 1080 timo = 150000; 1081 while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo) 1082 continue; 1083 1084 KCOM_PUTBYTE(com_data, c); 1085 1086 /* wait for this transmission to complete */ 1087 timo = 1500000; 1088 while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo) 1089 continue; 1090} 1091 1092static void 1093kcomcnpollc(dev_t dev, int on) 1094{ 1095} 1096 1097struct consdev kcomcons = { 1098 NULL, NULL, kcomcngetc, kcomcnputc, kcomcnpollc, NULL, 1099 NULL, NULL, NODEV, CN_NORMAL 1100}; 1101