1/* $NetBSD: brh_machdep.c,v 1.56 2024/02/20 23:36:02 andvar Exp $ */ 2 3/* 4 * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38/* 39 * Copyright (c) 1997,1998 Mark Brinicombe. 40 * Copyright (c) 1997,1998 Causality Limited. 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by Mark Brinicombe 54 * for the NetBSD Project. 55 * 4. The name of the company nor the name of the author may be used to 56 * endorse or promote products derived from this software without specific 57 * prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 60 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 61 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 62 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 63 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 64 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 65 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * Machine dependent functions for kernel setup for the ADI Engineering 72 * BRH i80200 evaluation platform. 73 */ 74 75#include <sys/cdefs.h> 76__KERNEL_RCSID(0, "$NetBSD: brh_machdep.c,v 1.56 2024/02/20 23:36:02 andvar Exp $"); 77 78#include "opt_arm_debug.h" 79#include "opt_console.h" 80#include "opt_ddb.h" 81 82#include <sys/param.h> 83#include <sys/device.h> 84#include <sys/systm.h> 85#include <sys/kernel.h> 86#include <sys/exec.h> 87#include <sys/proc.h> 88#include <sys/msgbuf.h> 89#include <sys/reboot.h> 90#include <sys/termios.h> 91#include <sys/ksyms.h> 92#include <sys/bus.h> 93#include <sys/cpu.h> 94 95#include <uvm/uvm_extern.h> 96 97#include <dev/cons.h> 98 99#include <machine/db_machdep.h> 100#include <ddb/db_sym.h> 101#include <ddb/db_extern.h> 102 103#include <machine/bootconfig.h> 104#include <arm/locore.h> 105#include <arm/undefined.h> 106 107#include <arm/arm32/machdep.h> 108 109#include <arm/xscale/i80200reg.h> 110#include <arm/xscale/i80200var.h> 111 112#include <dev/pci/ppbreg.h> 113 114#include <arm/xscale/beccreg.h> 115#include <arm/xscale/beccvar.h> 116 117#include <evbarm/adi_brh/brhreg.h> 118#include <evbarm/adi_brh/brhvar.h> 119#include <evbarm/adi_brh/obiovar.h> 120 121#include "ksyms.h" 122 123/* Kernel text starts 2MB in from the bottom of the kernel address space. */ 124#define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00200000) 125#define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000) 126 127/* 128 * The range 0xc1000000 - 0xccffffff is available for kernel VM space 129 * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff 130 */ 131#define KERNEL_VM_SIZE 0x0C000000 132 133BootConfig bootconfig; /* Boot config storage */ 134char *boot_args = NULL; 135char *boot_file = NULL; 136 137vaddr_t physical_start; 138vaddr_t physical_freestart; 139vaddr_t physical_freeend; 140vaddr_t physical_end; 141u_int free_pages; 142 143/*int debug_flags;*/ 144#ifndef PMAP_STATIC_L1S 145int max_processes = 64; /* Default number */ 146#endif /* !PMAP_STATIC_L1S */ 147 148/* Physical and virtual addresses for some global pages */ 149pv_addr_t minidataclean; 150 151paddr_t msgbufphys; 152 153#define KERNEL_PT_SYS 0 /* L2 table for mapping zero page */ 154 155#define KERNEL_PT_KERNEL 1 /* L2 table for mapping kernel */ 156#define KERNEL_PT_KERNEL_NUM 2 157 158 /* L2 tables for mapping kernel VM */ 159#define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM) 160#define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */ 161#define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) 162 163pv_addr_t kernel_pt_table[NUM_KERNEL_PTS]; 164 165/* Prototypes */ 166 167void consinit(void); 168 169#include "com.h" 170#if NCOM > 0 171#include <dev/ic/comreg.h> 172#include <dev/ic/comvar.h> 173#endif 174 175/* 176 * Define the default console speed for the board. This is generally 177 * what the firmware provided with the board defaults to. 178 */ 179#ifndef CONSPEED 180#define CONSPEED B57600 181#endif /* ! CONSPEED */ 182 183#ifndef CONUNIT 184#define CONUNIT 0 185#endif 186 187#ifndef CONMODE 188#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 189#endif 190 191int comcnspeed = CONSPEED; 192int comcnmode = CONMODE; 193int comcnunit = CONUNIT; 194 195/* 196 * void cpu_reboot(int howto, char *bootstr) 197 * 198 * Reboots the system 199 * 200 * Deal with any syncing, unmounting, dumping and shutdown hooks, 201 * then reset the CPU. 202 */ 203void 204cpu_reboot(int howto, char *bootstr) 205{ 206 207 /* 208 * If we are still cold then hit the air brakes 209 * and crash to earth fast 210 */ 211 if (cold) { 212 doshutdownhooks(); 213 pmf_system_shutdown(boothowto); 214 printf("The operating system has halted.\n"); 215 printf("Please press any key to reboot.\n\n"); 216 cngetc(); 217 printf("rebooting...\n"); 218 goto reset; 219 } 220 221 /* Disable console buffering */ 222 223 /* 224 * If RB_NOSYNC was not specified sync the discs. 225 * Note: Unless cold is set to 1 here, syslogd will die during the 226 * unmount. It looks like syslogd is getting woken up only to find 227 * that it cannot page part of the binary in as the filesystem has 228 * been unmounted. 229 */ 230 if (!(howto & RB_NOSYNC)) 231 bootsync(); 232 233 /* Say NO to interrupts */ 234 splhigh(); 235 236 /* Do a dump if requested. */ 237 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 238 dumpsys(); 239 240 /* Run any shutdown hooks */ 241 doshutdownhooks(); 242 243 pmf_system_shutdown(boothowto); 244 245 /* Make sure IRQ's are disabled */ 246 IRQdisable; 247 248 if (howto & RB_HALT) { 249 brh_7seg('8'); 250 printf("The operating system has halted.\n"); 251 printf("Please press any key to reboot.\n\n"); 252 cngetc(); 253 } 254 255 printf("rebooting...\n\r"); 256 reset: 257 cpu_reset(); 258} 259 260/* Static device mappings. */ 261static const struct pmap_devmap brh_devmap[] = { 262 DEVMAP_ENTRY( 263 BRH_PCI_CONF_VBASE, 264 BECC_PCI_CONF_BASE, 265 BRH_PCI_CONF_VSIZE 266 ), 267 DEVMAP_ENTRY( 268 BRH_PCI_MEM1_VBASE, 269 BECC_PCI_MEM1_BASE, 270 BRH_PCI_MEM1_VSIZE 271 ), 272 DEVMAP_ENTRY( 273 BRH_PCI_MEM2_VBASE, 274 BECC_PCI_MEM2_BASE, 275 BRH_PCI_MEM2_VSIZE 276 ), 277 DEVMAP_ENTRY( 278 BRH_UART1_VBASE, 279 BRH_UART1_BASE, 280 BRH_UART1_VSIZE 281 ), 282 DEVMAP_ENTRY( 283 BRH_UART2_VBASE, 284 BRH_UART2_BASE, 285 BRH_UART2_VSIZE 286 ), 287 DEVMAP_ENTRY( 288 BRH_LED_VBASE, 289 BRH_LED_BASE, 290 BRH_LED_VSIZE 291 ), 292 DEVMAP_ENTRY( 293 BRH_PCI_IO_VBASE, 294 BECC_PCI_IO_BASE, 295 BRH_PCI_IO_VSIZE 296 ), 297 DEVMAP_ENTRY( 298 BRH_BECC_VBASE, 299 BECC_REG_BASE, 300 BRH_BECC_VSIZE 301 ), 302 DEVMAP_ENTRY_END 303}; 304 305static void 306brh_hardclock_hook(void) 307{ 308 static int snakefreq; 309 310 if ((snakefreq++ & 15) == 0) 311 brh_7seg_snake(); 312} 313 314/* 315 * vaddr_t initarm(...) 316 * 317 * Initial entry point on startup. This gets called before main() is 318 * entered. 319 * It should be responsible for setting up everything that must be 320 * in place when main is called. 321 * This includes 322 * Taking a copy of the boot configuration structure. 323 * Initialising the physical console so characters can be printed. 324 * Setting up page tables for the kernel 325 * Relocating the kernel to the bottom of physical memory 326 */ 327vaddr_t 328initarm(void *arg) 329{ 330 int loop; 331 int loop1; 332 u_int l1pagetable; 333 paddr_t memstart; 334 psize_t memsize; 335 336 /* 337 * Clear out the 7-segment display. Whee, the first visual 338 * indication that we're running kernel code. 339 */ 340 brh_7seg(' '); 341 342 /* 343 * Since we have mapped the on-board devices at their permanent 344 * locations already, it is possible for us to initialize 345 * the console now. 346 */ 347 consinit(); 348 349#ifdef VERBOSE_INIT_ARM 350 /* Talk to the user */ 351 printf("\nNetBSD/evbarm (ADI BRH) booting ...\n"); 352#endif 353 354 /* Calibrate the delay loop. */ 355 becc_hardclock_hook = brh_hardclock_hook; 356 357 /* 358 * Heads up ... Setup the CPU / MMU / TLB functions 359 */ 360 if (set_cpufuncs()) 361 panic("CPU not recognized!"); 362 363 /* 364 * We are currently running with the MMU enabled and the 365 * entire address space mapped VA==PA. Memory conveniently 366 * starts at 0xc0000000, which is where we want it. Certain 367 * on-board devices have already been mapped where we want 368 * them to be. There is an L1 page table at 0xc0004000. 369 */ 370 371 becc_icu_init(); 372 373 /* 374 * Memory always starts at 0xc0000000 on a BRH, and the 375 * memory size is always 128M. 376 */ 377 memstart = 0xc0000000UL; 378 memsize = (128UL * 1024 * 1024); 379 380#ifdef VERBOSE_INIT_ARM 381 printf("initarm: Configuring system ...\n"); 382#endif 383 384 /* Fake bootconfig structure for the benefit of pmap.c */ 385 /* XXX must make the memory description h/w independent */ 386 bootconfig.dramblocks = 1; 387 bootconfig.dram[0].address = memstart; 388 bootconfig.dram[0].pages = memsize / PAGE_SIZE; 389 390 /* 391 * Set up the variables that define the availability of 392 * physical memory. For now, we're going to set 393 * physical_freestart to 0xc0200000 (where the kernel 394 * was loaded), and allocate the memory we need downwards. 395 * If we get too close to the L1 table that we set up, we 396 * will panic. We will update physical_freestart and 397 * physical_freeend later to reflect what pmap_bootstrap() 398 * wants to see. 399 * 400 * XXX pmap_bootstrap() needs an enema. 401 */ 402 physical_start = bootconfig.dram[0].address; 403 physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE); 404 405 physical_freestart = 0xc0009000UL; 406 physical_freeend = 0xc0200000UL; 407 408#ifdef VERBOSE_INIT_ARM 409 /* Tell the user about the memory */ 410 printf("physmemory: 0x%"PRIxPSIZE" pages at " 411 "0x%08"PRIxPADDR" -> 0x%08"PRIxPADDR"\n", 412 physmem, physical_start, physical_end - 1); 413#endif 414 415 /* 416 * Okay, the kernel starts 2MB in from the bottom of physical 417 * memory. We are going to allocate our bootstrap pages downwards 418 * from there. 419 * 420 * We need to allocate some fixed page tables to get the kernel 421 * going. We allocate one page directory and a number of page 422 * tables and store the physical addresses in the kernel_pt_table 423 * array. 424 * 425 * The kernel page directory must be on a 16K boundary. The page 426 * tables must be on 4K boundaries. What we do is allocate the 427 * page directory on the first 16K boundary that we encounter, and 428 * the page tables on 4K boundaries otherwise. Since we allocate 429 * at least 3 L2 page tables, we are guaranteed to encounter at 430 * least one 16K aligned region. 431 */ 432 433#ifdef VERBOSE_INIT_ARM 434 printf("Allocating page tables\n"); 435#endif 436 437 free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE; 438 439#ifdef VERBOSE_INIT_ARM 440 printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n", 441 physical_freestart, free_pages, free_pages); 442#endif 443 444 /* Define a macro to simplify memory allocation */ 445#define valloc_pages(var, np) \ 446 alloc_pages((var).pv_pa, (np)); \ 447 (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start; 448 449#define alloc_pages(var, np) \ 450 physical_freeend -= ((np) * PAGE_SIZE); \ 451 if (physical_freeend < physical_freestart) \ 452 panic("initarm: out of memory"); \ 453 (var) = physical_freeend; \ 454 free_pages -= (np); \ 455 memset((char *)(var), 0, ((np) * PAGE_SIZE)); 456 457 loop1 = 0; 458 for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { 459 /* Are we 16KB aligned for an L1 ? */ 460 if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0 461 && kernel_l1pt.pv_pa == 0) { 462 valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); 463 } else { 464 valloc_pages(kernel_pt_table[loop1], 465 L2_TABLE_SIZE / PAGE_SIZE); 466 ++loop1; 467 } 468 } 469 470 /* This should never be able to happen but better confirm that. */ 471 if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0) 472 panic("initarm: Failed to align the kernel page directory\n"); 473 474 /* 475 * Allocate a page for the system page mapped to V0x00000000 476 * This page will just contain the system vectors and can be 477 * shared by all processes. 478 */ 479 alloc_pages(systempage.pv_pa, 1); 480 481 /* Allocate stacks for all modes */ 482 valloc_pages(irqstack, IRQ_STACK_SIZE); 483 valloc_pages(abtstack, ABT_STACK_SIZE); 484 valloc_pages(undstack, UND_STACK_SIZE); 485 valloc_pages(kernelstack, UPAGES); 486 487 /* Allocate enough pages for cleaning the Mini-Data cache. */ 488 KASSERT(xscale_minidata_clean_size <= PAGE_SIZE); 489 valloc_pages(minidataclean, 1); 490 491#ifdef VERBOSE_INIT_ARM 492 printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, 493 irqstack.pv_va); 494 printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, 495 abtstack.pv_va); 496 printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, 497 undstack.pv_va); 498 printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, 499 kernelstack.pv_va); 500#endif 501 502 /* 503 * XXX Defer this to later so that we can reclaim the memory 504 * XXX used by the RedBoot page tables. 505 */ 506 alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE); 507 508 /* 509 * Ok we have allocated physical pages for the primary kernel 510 * page tables 511 */ 512 513#ifdef VERBOSE_INIT_ARM 514 printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa); 515#endif 516 517 /* 518 * Now we start construction of the L1 page table 519 * We start by mapping the L2 page tables into the L1. 520 * This means that we can replace L1 mappings later on if necessary 521 */ 522 l1pagetable = kernel_l1pt.pv_pa; 523 524 /* Map the L2 pages tables in the L1 page table */ 525 pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00400000 - 1), 526 &kernel_pt_table[KERNEL_PT_SYS]); 527 for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) 528 pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000, 529 &kernel_pt_table[KERNEL_PT_KERNEL + loop]); 530 for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++) 531 pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, 532 &kernel_pt_table[KERNEL_PT_VMDATA + loop]); 533 534 /* update the top of the kernel VM */ 535 pmap_curmaxkvaddr = 536 KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000); 537 538#ifdef VERBOSE_INIT_ARM 539 printf("Mapping kernel\n"); 540#endif 541 542 /* Now we fill in the L2 pagetable for the kernel static code/data */ 543 { 544 extern char etext[], _end[]; 545 size_t textsize = (uintptr_t) etext - KERNEL_TEXT_BASE; 546 size_t totalsize = (uintptr_t) _end - KERNEL_TEXT_BASE; 547 u_int logical; 548 549 textsize = (textsize + PGOFSET) & ~PGOFSET; 550 totalsize = (totalsize + PGOFSET) & ~PGOFSET; 551 552 logical = 0x00200000; /* offset of kernel in RAM */ 553 554 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 555 physical_start + logical, textsize, 556 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 557 logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, 558 physical_start + logical, totalsize - textsize, 559 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 560 } 561 562#ifdef VERBOSE_INIT_ARM 563 printf("Constructing L2 page tables\n"); 564#endif 565 566 /* Map the stack pages */ 567 pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, 568 IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 569 pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa, 570 ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 571 pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa, 572 UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 573 pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa, 574 UPAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 575 576 pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, 577 L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); 578 579 for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { 580 pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va, 581 kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE, 582 VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); 583 } 584 585 /* Map the Mini-Data cache clean area. */ 586 xscale_setup_minidata(l1pagetable, minidataclean.pv_va, 587 minidataclean.pv_pa); 588 589 /* Map the vector page. */ 590 pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, 591 VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); 592 593 /* Map the statically mapped devices. */ 594 pmap_devmap_bootstrap(l1pagetable, brh_devmap); 595 596 /* 597 * Give the XScale global cache clean code an appropriately 598 * sized chunk of unmapped VA space starting at 0xff500000 599 * (our device mappings end before this address). 600 */ 601 xscale_cache_clean_addr = 0xff500000U; 602 603 /* 604 * Now we have the real page tables in place so we can switch to them. 605 * Once this is done we will be running with the REAL kernel page 606 * tables. 607 */ 608 609 /* Switch tables */ 610#ifdef VERBOSE_INIT_ARM 611 printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa); 612#endif 613 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 614 cpu_setttb(kernel_l1pt.pv_pa, true); 615 cpu_tlb_flushID(); 616 cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); 617 618 /* 619 * Move from cpu_startup() as data_abort_handler() references 620 * this during uvm init 621 */ 622 uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); 623 624#ifdef VERBOSE_INIT_ARM 625 printf("done!\n"); 626#endif 627 628#ifdef VERBOSE_INIT_ARM 629 printf("bootstrap done.\n"); 630#endif 631 632 /* 633 * Inform the BECC code where the BECC is mapped. 634 */ 635 becc_vaddr = BRH_BECC_VBASE; 636 637 /* 638 * Now that we have becc_vaddr set, calibrate delay. 639 */ 640 becc_calibrate_delay(); 641 642 /* 643 * BECC <= Rev7 can only address 64M through the inbound 644 * PCI windows. Limit memory to 64M on those revs. (This 645 * problem was fixed in Rev8 of the BECC; get an FPGA upgrade.) 646 */ 647 { 648 vaddr_t va = BRH_PCI_CONF_VBASE | (1U << BECC_IDSEL_BIT) | 649 PCI_CLASS_REG; 650 uint32_t reg; 651 652 reg = *(volatile uint32_t *) va; 653 becc_rev = PCI_REVISION(reg); 654 if (becc_rev <= BECC_REV_V7 && 655 memsize > (64UL * 1024 * 1024)) { 656 memsize = (64UL * 1024 * 1024); 657 bootconfig.dram[0].pages = memsize / PAGE_SIZE; 658 physical_end = physical_start + 659 (bootconfig.dram[0].pages * PAGE_SIZE); 660 printf("BECC <= Rev7: memory truncated to 64M\n"); 661 } 662 } 663 664 /* 665 * Update the physical_freestart/physical_freeend/free_pages 666 * variables. 667 */ 668 { 669 extern char _end[]; 670 671 physical_freestart = physical_start + 672 (((((uintptr_t) _end) + PGOFSET) & ~PGOFSET) - 673 KERNEL_BASE); 674 physical_freeend = physical_end; 675 free_pages = 676 (physical_freeend - physical_freestart) / PAGE_SIZE; 677 } 678#ifdef VERBOSE_INIT_ARM 679 printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n", 680 physical_freestart, free_pages, free_pages); 681#endif 682 683 physmem = (physical_end - physical_start) / PAGE_SIZE; 684 685 arm32_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL); 686 687 /* 688 * Pages were allocated during the secondary bootstrap for the 689 * stacks for different CPU modes. 690 * We must now set the r13 registers in the different CPU modes to 691 * point to these stacks. 692 * Since the ARM stacks use STMFD etc. we must set r13 to the top end 693 * of the stack memory. 694 */ 695#ifdef VERBOSE_INIT_ARM 696 printf("init subsystems: stacks "); 697#endif 698 699 set_stackptr(PSR_IRQ32_MODE, 700 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); 701 set_stackptr(PSR_ABT32_MODE, 702 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); 703 set_stackptr(PSR_UND32_MODE, 704 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); 705 706 /* 707 * Well we should set a data abort handler. 708 * Once things get going this will change as we will need a proper 709 * handler. 710 * Until then we will use a handler that just panics but tells us 711 * why. 712 * Initialisation of the vectors will just panic on a data abort. 713 * This just fills in a slightly better one. 714 */ 715#ifdef VERBOSE_INIT_ARM 716 printf("vectors "); 717#endif 718 data_abort_handler_address = (u_int)data_abort_handler; 719 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 720 undefined_handler_address = (u_int)undefinedinstruction_bounce; 721 722 /* Initialise the undefined instruction handlers */ 723#ifdef VERBOSE_INIT_ARM 724 printf("undefined "); 725#endif 726 undefined_init(); 727 728 /* Load memory into UVM. */ 729#ifdef VERBOSE_INIT_ARM 730 printf("page "); 731#endif 732 uvm_md_init(); 733 uvm_page_physload(atop(physical_freestart), atop(physical_freeend), 734 atop(physical_freestart), atop(physical_freeend), 735 VM_FREELIST_DEFAULT); 736 737 /* Boot strap pmap telling it where the managed kernel virtual memory is */ 738#ifdef VERBOSE_INIT_ARM 739 printf("pmap "); 740#endif 741 pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); 742 743 /* Setup the IRQ system */ 744#ifdef VERBOSE_INIT_ARM 745 printf("irq "); 746#endif 747 becc_intr_init(); 748#ifdef VERBOSE_INIT_ARM 749 printf("done.\n"); 750#endif 751 752#ifdef DDB 753 db_machine_init(); 754 if (boothowto & RB_KDB) 755 Debugger(); 756#endif 757 758 /* We return the new stack pointer address */ 759 return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); 760} 761 762void 763consinit(void) 764{ 765 static const bus_addr_t comcnaddrs[] = { 766 BRH_UART1_BASE, /* com0 */ 767 BRH_UART2_BASE, /* com1 */ 768 }; 769 static int consinit_called; 770 771 if (consinit_called != 0) 772 return; 773 774 consinit_called = 1; 775 776 /* 777 * brh_start() has mapped the console devices for us per 778 * the devmap, so register it now so drivers can map the 779 * console device. 780 */ 781 pmap_devmap_register(brh_devmap); 782 783#if NCOM > 0 784 if (comcnattach(&obio_bs_tag, comcnaddrs[comcnunit], comcnspeed, 785 BECC_PERIPH_CLOCK, COM_TYPE_NORMAL, comcnmode)) 786 panic("can't init serial console @%lx", comcnaddrs[comcnunit]); 787#else 788 panic("serial console @%lx not configured", comcnaddrs[comcnunit]); 789#endif 790} 791