bootconfig.dram[0].pages = ram_size / PAGE_SIZE; #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS const bool mapallmem_p = true; #ifndef PMAP_NEED_ALLOC_POOLPAGE if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) { printf("%s: dropping RAM size from %luMB to %uMB\n", __func__, (unsigned long) (ram_size >> 20), (KERNEL_VM_BASE - KERNEL_BASE) >> 20); ram_size = KERNEL_VM_BASE - KERNEL_BASE; } #endif #else const bool mapallmem_p = false; #endif KASSERT((armreg_pfr1_read() & ARM_PFR1_SEC_MASK) != 0); arm32_bootmem_init(bootconfig.dram[0].address, ram_size, KERNEL_BASE_PHYS); arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, devmap, mapallmem_p); if (mapallmem_p) { /* * "bootargs" env variable is passed as 4th argument * to kernel but it's using the physical address and * we to convert that to a virtual address. */ if (uboot_args[3] - AWIN_SDRAM_PBASE < ram_size) { const char * const args = (const char *) (uboot_args[3] + KERNEL_BASE_VOFFSET);
/* * u_int initarm(...) * * Initial entry point on startup. This gets called before main() is * entered. * It should be responsible for setting up everything that must be * in place when main is called. * This includes * Taking a copy of the boot configuration structure. * Initialising the physical console so characters can be printed. * Setting up page tables for the kernel * Relocating the kernel to the bottom of physical memory */ u_int initarm(void *arg) { pmap_devmap_register(devmap); awin_bootstrap(AWIN_CORE_VBASE, CONADDR_VA); /* Heads up ... Setup the CPU / MMU / TLB functions. */ if (set_cpufuncs()) panic("cpu not recognized!"); /* The console is going to try to map things. Give pmap a devmap. */ consinit(); #ifdef VERBOSE_INIT_ARM printf("\nuboot arg = %#x, %#x, %#x, %#x\n", uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]); #endif #ifdef KGDB kgdb_port_init(); #endif cpu_reset_address = awin_wdog_reset; #ifdef VERBOSE_INIT_ARM /* Talk to the user */ printf("\nNetBSD/evbarm (cubie) booting ...\n"); #endif #ifdef BOOT_ARGS char mi_bootargs[] = BOOT_ARGS; parse_mi_bootargs(mi_bootargs); #endif #ifdef VERBOSE_INIT_ARM printf("initarm: Configuring system ...\n"); #if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA9) || defined(CPU_CORTEXA15) printf("initarm: cbar=%#x\n", armreg_cbar_read()); #endif #endif /* * Set up the variables that define the availability of physical * memory. */ psize_t ram_size = awin_memprobe(); /* * If MEMSIZE specified less than what we really have, limit ourselves * to that. */ #ifdef MEMSIZE if (ram_size == 0 || ram_size > (unsigned)MEMSIZE * 1024 * 1024) ram_size = (unsigned)MEMSIZE * 1024 * 1024; #else KASSERTMSG(ram_size > 0, "RAM size unknown and MEMSIZE undefined"); #endif /* Fake bootconfig structure for the benefit of pmap.c. */ bootconfig.dramblocks = 1; bootconfig.dram[0].address = AWIN_SDRAM_PBASE; bootconfig.dram[0].pages = ram_size / PAGE_SIZE; #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS const bool mapallmem_p = true; KASSERT(ram_size <= KERNEL_VM_BASE - KERNEL_BASE); #else const bool mapallmem_p = false; #endif KASSERT((armreg_pfr1_read() & ARM_PFR1_SEC_MASK) != 0); arm32_bootmem_init(bootconfig.dram[0].address, ram_size, KERNEL_BASE_PHYS); arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, devmap, mapallmem_p); if (mapallmem_p) { /* * "bootargs" env variable is passed as 4th argument * to kernel but it's using the physical address and * we to convert that to a virtual address. */ if (uboot_args[3] - AWIN_SDRAM_PBASE < ram_size) { const char * const args = (const char *) (uboot_args[3] + KERNEL_PHYS_VOFFSET); strlcpy(bootargs, args, sizeof(bootargs)); } } boot_args = bootargs; parse_mi_bootargs(boot_args); /* we've a specific device_register routine */ evbarm_device_register = cubie_device_register; #if NAWIN_FB > 0 char *ptr; if (get_bootconf_option(boot_args, "console", BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) { use_fb_console = true; } #endif return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); }
/* * arm32_vector_init: * * Initialize the vector page, and select whether or not to * relocate the vectors. * * NOTE: We expect the vector page to be mapped at its expected * destination. */ void arm32_vector_init(vaddr_t va, int which) { #if defined(CPU_ARMV7) || defined(CPU_ARM11) || defined(ARM_HAS_VBAR) /* * If this processor has the security extension, don't bother * to move/map the vector page. Simply point VBAR to the copy * that exists in the .text segment. */ #ifndef ARM_HAS_VBAR if (va == ARM_VECTORS_LOW && (armreg_pfr1_read() & ARM_PFR1_SEC_MASK) != 0) { #endif extern const uint32_t page0rel[]; vector_page = (vaddr_t)page0rel; KASSERT((vector_page & 0x1f) == 0); armreg_vbar_write(vector_page); #ifdef VERBOSE_INIT_ARM printf(" vbar=%p", page0rel); #endif cpu_control(CPU_CONTROL_VECRELOC, 0); return; #ifndef ARM_HAS_VBAR } #endif #endif #ifndef ARM_HAS_VBAR if (CPU_IS_PRIMARY(curcpu())) { extern unsigned int page0[], page0_data[]; unsigned int *vectors = (int *) va; unsigned int *vectors_data = vectors + (page0_data - page0); int vec; /* * Loop through the vectors we're taking over, and copy the * vector's insn and data word. */ for (vec = 0; vec < ARM_NVEC; vec++) { if ((which & (1 << vec)) == 0) { /* Don't want to take over this vector. */ continue; } vectors[vec] = page0[vec]; vectors_data[vec] = page0_data[vec]; } /* Now sync the vectors. */ cpu_icache_sync_range(va, (ARM_NVEC * 2) * sizeof(u_int)); vector_page = va; } if (va == ARM_VECTORS_HIGH) { /* * Assume the MD caller knows what it's doing here, and * really does want the vector page relocated. * * Note: This has to be done here (and not just in * cpu_setup()) because the vector page needs to be * accessible *before* cpu_startup() is called. * Think ddb(9) ... * * NOTE: If the CPU control register is not readable, * this will totally fail! We'll just assume that * any system that has high vector support has a * readable CPU control register, for now. If we * ever encounter one that does not, we'll have to * rethink this. */ cpu_control(CPU_CONTROL_VECRELOC, CPU_CONTROL_VECRELOC); } #endif }