Index: sys/arch/arm/arm/cpufunc.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/arm/cpufunc.c,v retrieving revision 1.163 diff -u -p -r1.163 cpufunc.c --- sys/arch/arm/arm/cpufunc.c 28 Jan 2017 13:21:11 -0000 1.163 +++ sys/arch/arm/arm/cpufunc.c 21 Jul 2017 11:46:39 -0000 @@ -3691,3 +3693,68 @@ sheeva_setup(char *args) #endif } #endif /* CPU_SHEEVA */ + + + + + +void cpu_actlr(void); + + + +void +cpu_actlr(void) +{ + KASSERT(cputype != 0); + + int actlr_set = 0; + int actlr_clr = 0; + + + if (CPU_ID_CORTEX_A5_P(cputype)) { + /* + * Disable exclusive L1/L2 cache control + * Enable SMP mode + * Enable Cache and TLB maintenance broadcast + */ + actlr_clr = CORTEXA5_ACTLR_EXCL; + actlr_set = + CORTEXA5_ACTLR_SMP | + CORTEXA5_ACTLR_FW; + } else if (CPU_ID_CORTEX_A7_P(cputype)) { + actlr_set = + CORTEXA7_ACTLR_SMP; + } else if (CPU_ID_CORTEX_A8_P(cputype)) { + actlr_set = CORTEXA8_ACTLR_L2EN; + actlr_clr = CORTEXA8_ACTLR_L1ALIAS; + } else if (CPU_ID_CORTEX_A9_P(cputype)) { + // CORTEXA9_AUXCTL_EXCL - clears + actlr_set = + CORTEXA9_AUXCTL_SMP | + CORTEXA9_AUXCTL_FW | + CORTEXA9_AUXCTL_L2PE // Not in FreeBSD + ; + } else if (CPU_ID_CORTEX_A15_P(cputype)) { + actlr_set = + CORTEXA15_ACTLR_SMP | + CORTEXA15_ACTLR_SDEH + ; +#if 0 + } else if (CPU_ID_CORTEX_A12_P(cputype) || + CPU_ID_CORTEX_A17_P(cputype)) { + actlr_set = + CORTEXA17_ACTLR_SMP; +#endif + } else if (CPU_ID_CORTEX_A53_P(cputype)) { + } else if (CPU_ID_CORTEX_A57_P(cputype)) { + } else if (CPU_ID_CORTEX_A72_P(cputype)) { + } + + + + uint32_t actlr = armreg_auxctl_read(); + actlr &= actlr_clr; + actlr |= actlr_set; + + armreg_auxctl_write(actlr); +} Index: sys/arch/arm/arm/armv6_start.S =================================================================== RCS file: sys/arch/arm/arm/armv6_start.S diff -N sys/arch/arm/arm/armv6_start.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/arm/armv6_start.S 21 Jul 2017 11:46:40 -0000 @@ -0,0 +1,1317 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2012, 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry and Nick Hudson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opt_arm_debug.h" +#include "opt_cpuoptions.h" +#include "opt_cputypes.h" +#include "opt_multiprocessor.h" + +#include +#include +#if 0 +#include +#endif +#include "assym.h" + +//#define MPDEBUG + +// Marco to call routines in .text +#if defined(KERNEL_BASES_EQUAL) +#define CALLc(c,f) __CONCAT(bl,c) _C_LABEL(f) +#else +#define CALLc(f) \ + movw ip, #:lower16:_C_LABEL(f); \ + movt ip, #:upper16:_C_LABEL(f); \ + sub ip, ip, #KERNEL_BASE_VOFFSET; \ + __CONCAT(blx,c) ip +#endif +#define CALL(f) CALLc(al,f) + +// We'll modify va and pa at run time so we can use relocatable addresses. +#define MMU_INIT(va,pa,n_sec,attr) \ + .word ((va) & L1_S_FRAME)|(n_sec) ; \ + .word ((pa) & L1_S_FRAME)|(attr) ; \ + +#if defined(VERBOSE_INIT_ARM) +#if !defined(PLATFORM_UARTVA) +#error PLATFORM_UARTVA not defined +#endif +#if !defined(PLATFORM_UARTPA) +#error PLATFORMUART_PA not defined +#endif +#if !defined(PLATFORM_PUTCHAR) +#error PLATFORM_PUTCHAR not defined +#endif +#define ARMV6_START_DEBUG +#endif + + +#if defined(ARMV6_START_DEBUG) +#define XPUTC(n) mov r0, n; bl PLATFORM_PUTCHAR +#if KERNEL_BASE_VOFFSET == 0 +#define XPUTC2(n) mov r0, n; bl PLATFORM_PUTCHAR +#else +#define XPUTC2(n) mov r0, n; blx r11 +#endif +#else +#define XPUTC(n) +#define XPUTC2(n) +#endif + +#define INIT_MEMSIZE 128 +#if 0 + +#define MD_CPU_HATCH _C_LABEL(awin_cpu_hatch) +#endif + + + + + +/* + * A generic kernel start routine. + * + * At this point, this code has been loaded into SDRAM and the MMU maybe on or + * maybe off. + * + * Reference linux boot code (MMU off) and rpi boot protocol + * + * Place the initial pagetable table as the first 16KiB + * + */ +#ifdef KERNEL_BASES_EQUAL + .text +#else + .section .start,"ax",%progbits +#endif + + .global _C_LABEL(generic_start) +_C_LABEL(generic_start): + + // ARMv7 only?!? +#ifdef __ARMEB__ + setend be /* force big endian */ +#endif + + /* disable IRQs/FIQs. */ + cpsid if + + // Save arguments + mov r4, r0 + mov r5, r1 + mov r6, r2 + mov r7, r3 + + // Let's work out what sort of CPU we're running on + + mrc p15, 0, r0, c0, c0, 0 /* Get MIDR */ + and r0, #0xf0000 +#if defined(_ARM_ARCH_7) + cmp r0, #0xf0000 + beq generic_startv7 +#endif +#if defined(_ARM_ARCH_6XXX) + cmp r0, #0x60000 + beq generic_startv6 +#endif +1: b 1b + +#if defined(_ARM_ARCH_7) +generic_startv7: + + .arch armv7a + .arch_extension sec + .arch_extension virt + + /* Leave HYP mode and move into supervisor mode with IRQs/FIQs disabled. */ + mrs r0, cpsr + and r0, r0, #(PSR_MODE) /* Mode is in the low 5 bits of CPSR */ + teq r0, #(PSR_HYP32_MODE) /* Hyp Mode? */ + bne 1f + + /* Ensure that IRQ, and FIQ will be disabled after eret */ + mrs r0, cpsr + bic r0, r0, #(PSR_MODE) + orr r0, r0, #(PSR_SVC32_MODE) + orr r0, r0, #(I32_bit | F32_bit) + msr spsr_cxsf, r0 + /* Exit hypervisor mode */ + adr lr, 2f + msr elr_hyp, lr + eret + +1: + cpsid if, #PSR_SVC32_MODE // SVC32 with no interrupts + +2: + mov r0, #0 + msr spsr_sxc, r0 // set SPSR[23:8] to known value + + + + + + + + + // Twiddle cache/mmu state + + mrc p15, 0, r0, c1, c0, 0 + tst r0, #CPU_CONTROL_DC_ENABLE + CALLc(ne,armv7_dcache_wbinv_all) + + +// CPU_CONTROL_AFLT_ENABLE +// CPU_CONTROL_BPRD_ENABLE +// CPU_CONTROL_SW_ENABLE + +#define SCTLR_CLEAR ( \ + CPU_CONTROL_IC_ENABLE | \ + CPU_CONTROL_DC_ENABLE | \ + CPU_CONTROL_MMU_ENABLE | \ + 0) + +// CPU_CONTROL_UNAL_ENABLE +// CPU_CONTROL_VECRELOC + +#define SCTLR_SET ( \ + 0) + + movw r1, #:lower16:SCTLR_CLEAR + movt r1, #:upper16:SCTLR_CLEAR + movw r2, #:lower16:SCTLR_SET + movt r2, #:upper16:SCTLR_SET + + bic r0, r0, r1 // disable icache/dcache/mmu + orr r0, r0, r2 // + + mcr p15, 0, r0, c1, c0, 0 // SCTLR write + dsb + isb + + // + // Step 1b, invalidate the data cache + // + XPUTC(#'B') + CALL(armv7_dcache_inv_all) + XPUTC(#'C') + + /* + * Save any arguments passed to us. + */ + movw r0, #:lower16:uboot_args + movt r0, #:upper16:uboot_args + +#if KERNEL_BASE_VOFFSET != 0 + /* + * We have to adjust the address the linker gave us to get the to + * the physical address. + */ + sub r0, r0, #KERNEL_BASE_VOFFSET +#endif + + stmia r0, {r4-r7} // Save the arguments + + + /* + * Set up a preliminary mapping in the MMU to allow us to run + * at KERNEL_BASE with caches on. + */ + movw r0, #:lower16:TEMP_L1_TABLE + movt r0, #:upper16:TEMP_L1_TABLE + movw r1, #:lower16:.Lmmu_init_table + movt r1, #:upper16:.Lmmu_init_table + bl arm_boot_l1pt_init + XPUTC(#'D') + + + + + /* Add DTB VA:PA (1MB) from r2 (saved in r6) to MMU init table */ + movw r3, #:lower16:(L1_S_SIZE - 1) /* align DTB PA to 1M */ + movt r3, #:upper16:(L1_S_SIZE - 1) + bic r1, r6, r3 + mov r2, r1 + orr r1, r1, #1 /* 1MB mapping */ + + movw r3, #:lower16:(L1_S_PROTO_armv7|L1_S_APv7_KRW|L1_S_CACHEABLE) + orr r2, r2, r3 + + adr r3, .Lmmu_init_table_end /* table entry addr */ + + movw r0, #:lower16:TEMP_L1_TABLE + movt r0, #:upper16:TEMP_L1_TABLE + bl arm_boot_l1pt_entry + XPUTC(#'X') + + + + + + + + + /* + * Turn on the MMU, Caches, etc. Return to new enabled address space. + */ + movw r0, #:lower16:TEMP_L1_TABLE + movt r0, #:upper16:TEMP_L1_TABLE +#if KERNEL_BASE_VOFFSET == 0 + bl arm_cpuinit +#else + /* + * After the MMU is on, we can execute in the normal .text segment + * so setup the lr to be in .text. Cache the address for xputc + * before we go. + */ +#if defined(VERBOSE_INIT_ARM) + adr r11, xputc @ for XPUTC2 +#endif + movw lr, #:lower16:1f + movt lr, #:upper16:1f + b arm_cpuinit + .pushsection .text,"ax",%progbits +1: +#endif + + + + XPUTC2(#'Z') + /* + * Jump to start in locore.S, which in turn will call initarm and main. + */ + b start + + /* NOTREACHED */ + +#endif + +END(_C_LABEL(generic_start)) + +#ifndef KERNEL_BASES_EQUAL + .popsection +#endif + + +.Lmmu_init_table: + /* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */ + MMU_INIT(KERNEL_BASE, KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) + +#if KERNEL_BASE_VOFFSET != 0 + /* Map memory 1:1 VA to PA, write-back cacheable, shareable */ + MMU_INIT(KERNEL_BASE - KERNEL_BASE_VOFFSET, + KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) +#endif + +#if defined(PLATFORM_UARTVA) && defined(PLATFORM_UARTPA) + /* Early uart */ + MMU_INIT(PLATFORM_UARTVA, PLATFORM_UARTPA, 1, /* L1_S_SIZE */ + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) +#endif + +.Lmmu_init_table_end: + /* end of table */ + MMU_INIT(0, 0, 0, 0) + + .section ".init_pagetable", "aw", %nobits + .align 14 /* 16KiB aligned */ + .globl TEMP_L1_TABLE +TEMP_L1_TABLE: + .space L1_TABLE_SIZE + + .text + .align 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Set up a preliminary mapping in the MMU to allow us to run at KERNEL_BASE +// with caches on. If we are MULTIPROCESSOR, save the TTB address. +// +// On Entry +// +// r0 is l1pt +// r1 is the MMU init table +// r2 is .. +// r3 is .. + +arm_boot_l1pt_init: +#if defined(MULTIPROCESSOR) + movw r4, #:lower16:armv7_mmuinfo + movt r4, #:upper16:armv7_mmuinfo +#if !defined(KERNEL_BASES_EQUAL) + sub r4, r4, #KERNEL_BASE_VOFFSET +#endif + str r0, [r4] + + // Make sure the info makes into memory + mcr p15, 0, r4, c7, c10, 1 // writeback the cache line + dsb +#endif + + mov ip, r1 // save mmu table addr + // Build page table from scratch + mov r1, r0 // Start address to clear memory. + // Zero the entire table so all virtual addresses are invalid. + add r8, r1, #L1_TABLE_SIZE // Ending address + mov r4, #0 + mov r5, #0 + mov r6, #0 + mov r7, #0 +1: stmia r1!, {r4-r7} // 16 bytes at a time + cmp r1, r8 + blt 1b + + // Now create our entries per the mmu_init_table. + l1table .req r0 + va .req r1 + pa .req r2 + itable .req r3 + n_sec .req r4 + attr .req r5 + + mov attr, #0 + mrc p15, 0, r3, c0, c0, 5 // MPIDR read + cmp r3, #0 // not zero? + movne attr, #L1_S_V6_S // yes, shareable attribute + mov itable, ip // reclaim table address + b 3f + +2: str pa, [l1table, va, lsl #2] + add va, va, #1 + add pa, pa, #(L1_S_SIZE) + subs n_sec, n_sec, #1 + bhi 2b + +3: ldmia itable!, {va, pa} + + // We can call here with a single entry in r1, r2 as long as + // r0 is the l1pt and r3 points to somewhere that'll terminate the + // loop +arm_boot_l1pt_entry: + // Convert va to l1 offset: va = 4 * (va >> L1_S_SHIFT) + ubfx n_sec, va, #0, #L1_S_SHIFT + lsr va, va, #L1_S_SHIFT + + // Do we need add sharing for this? + tst pa, #(L1_S_C|L1_S_B) // is this entry cacheable? + orrne pa, pa, attr // add sharing + +4: cmp n_sec, #0 + bne 2b + bx lr // return + + .unreq va + .unreq pa + .unreq n_sec + .unreq attr + .unreq itable + .unreq l1table + + + + + + + + + + + + + + + + + + +// +// Coprocessor register initialization values +// +#ifdef __ARMEL__ +#define CPU_CONTROL_EX_BEND_SET 0 +#else +#define CPU_CONTROL_EX_BEND_SET CPU_CONTROL_EX_BEND +#endif +#ifdef ARM32_DISABLE_ALIGNMENT_FAULTS +#define CPU_CONTROL_AFLT_ENABLE_CLR CPU_CONTROL_AFLT_ENABLE +#define CPU_CONTROL_AFLT_ENABLE_SET 0 +#else +#define CPU_CONTROL_AFLT_ENABLE_CLR 0 +#define CPU_CONTROL_AFLT_ENABLE_SET CPU_CONTROL_AFLT_ENABLE +#endif + +#ifdef ARM_MMU_EXTENDED +#define CPU_CONTROL_XP_ENABLE_CLR 0 +#define CPU_CONTROL_XP_ENABLE_SET CPU_CONTROL_XP_ENABLE +#else +#define CPU_CONTROL_XP_ENABLE_CLR CPU_CONTROL_XP_ENABLE +#define CPU_CONTROL_XP_ENABLE_SET 0 +#endif + +#if 0 + CPU_CONTROL_DC_ENABLE | \ + CPU_CONTROL_IC_ENABLE | \ + +#endif + +// bits to set in the Control Register +// +#define CPU_CONTROL_SET ( \ + CPU_CONTROL_MMU_ENABLE | \ + CPU_CONTROL_UNAL_ENABLE | \ + CPU_CONTROL_AFLT_ENABLE_SET | \ + CPU_CONTROL_EX_BEND_SET | \ + CPU_CONTROL_XP_ENABLE_SET | \ + 0) + +// bits to clear in the Control Register +// +#define CPU_CONTROL_CLR ( \ + CPU_CONTROL_AFLT_ENABLE_CLR | \ + CPU_CONTROL_XP_ENABLE_CLR | \ + 0) + + + + + + + + + + + + + + + + + + + + + +arm_cpuinit: + // Because the MMU may already be on do a typical sequence to set + // the Translation Table Base(s). + mov ip, lr + mov r10, r0 // save TTBR + + + + + +// XXXNH +// We did this ready... no need to do it again +// +#if 0 + mov r1, #0 + mcr p15, 0, r1, c7, c5, 0 // invalidate I cache + + mrc p15, 0, r2, c1, c0, 0 // SCTLR read + movw r1, #(CPU_CONTROL_DC_ENABLE|CPU_CONTROL_IC_ENABLE) + bic r2, r2, r1 // clear I+D cache enable + +#ifdef __ARMEB__ + // SCTLR.EE determines the endianness of translation table lookups. + // So we need to make sure it's set before starting to use the new + // translation tables (which are big endian). + // + orr r2, r2, #CPU_CONTROL_EX_BEND + bic r2, r2, #CPU_CONTROL_MMU_ENABLE + pli [pc, #32] // preload the next few cachelines + pli [pc, #64] + pli [pc, #96] + pli [pc, #128] +#endif + + mcr p15, 0, r2, c1, c0, 0 // SCTLR write +#endif + + + + + + + + + // XXXNH Why? + XPUTC(#'F') + dsb // Drain the write buffers. + + + + + + + + + + + + + XPUTC(#'G') + mrc p15, 0, r1, c0, c0, 5 // MPIDR read + cmp r1, #0 + orrlt r10, r10, #TTBR_MPATTR // MP, cachable (Normal WB) + orrge r10, r10, #TTBR_UPATTR // Non-MP, cacheable, normal WB + XPUTC(#'0') + mcr p15, 0, r10, c2, c0, 0 // TTBR0 write + +#if defined(ARM_MMU_EXTENDED) + // When using split TTBRs, we need to set both since the physical + // addresses we were/are using might be in either. + XPUTC(#'1') + mcr p15, 0, r10, c2, c0, 1 // TTBR1 write +#endif + + XPUTC(#'H') +#if defined(ARM_MMU_EXTENDED) + XPUTC(#'1') + mov r1, #TTBCR_S_N_1 // make sure TTBCR_S_N is 1 +#else + XPUTC(#'0') + mov r1, #0 // make sure TTBCR is 0 +#endif + mcr p15, 0, r1, c2, c0, 2 // TTBCR write + + XPUTC(#'J') + mov r1, #0 // get KERNEL_PID + mcr p15, 0, r1, c13, c0, 1 // CONTEXTIDR write + + + + // XXXNH FreeBSD doesn't do this isb + isb + + + + + // Set the Domain Access register. Very important! + XPUTC(#'K') + mov r1, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) + mcr p15, 0, r1, c3, c0, 0 // DACR write + +#if 0 +//XXXNH FreeBSD + +288 /* +289 * Set TEX remap registers +290 * - All is set to uncacheable memory +291 */ +292 ldr r0, =0xAAAAA +293 mcr CP15_PRRR(r0) +294 mov r0, #0 +295 mcr CP15_NMRR(r0) +#endif + + + XPUTC(#'I') + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 // TLBIALL (just this core) + dsb + isb + + + + + + + + + + // + // Enable the MMU, etc. + // + XPUTC(#'L') + mrc p15, 0, r1, c1, c0, 0 // SCTLR read + + movw r3, #:lower16:CPU_CONTROL_SET +#if (CPU_CONTROL_SET & 0xffff0000) + movt r3, #:upper16:CPU_CONTROL_SET +#endif + orr r0, r1, r3 +#if defined(CPU_CONTROL_CLR) && (CPU_CONTROL_CLR != 0) + bic r0, r0, #CPU_CONTROL_CLR +#endif + //cmp r0, r1 // any changes to SCTLR? + //bxeq ip // no, then return. + + pli 1f + dsb + + // turn mmu on! + // + mov r0, r0 // fetch instruction cacheline +1: mcr p15, 0, r0, c1, c0, 0 // SCTLR write + + // Ensure that the coprocessor has finished turning on the MMU. + // + mrc p15, 0, r0, c0, c0, 0 // Read an arbitrary value. + mov r0, r0 // Stall until read completes. + XPUTC2(#'M') + + bx ip // return + + .p2align 2 + + + + + + + + + + + + + + + + + + + + + + +// +// Perform the initialization of the Cortex core required by NetBSD. +// +// +armv7_init: + mov r10, lr // save lr + + /* Leave HYP mode and move into supervisor mode with IRQs/FIQs disabled. */ + mrs r0, cpsr + and r0, r0, #(PSR_MODE) /* Mode is in the low 5 bits of CPSR */ + teq r0, #(PSR_HYP32_MODE) /* Hyp Mode? */ + bne 1f + + /* Ensure that IRQ, and FIQ will be disabled after eret */ + mrs r0, cpsr + bic r0, r0, #(PSR_MODE) + orr r0, r0, #(PSR_SVC32_MODE) + orr r0, r0, #(I32_bit | F32_bit) + msr spsr_cxsf, r0 + /* Exit hypervisor mode */ + adr lr, 2f + msr elr_hyp, lr + eret + +1: + cpsid if, #PSR_SVC32_MODE // SVC32 with no interrupts + +2: + mov r0, #0 + msr spsr_sxc, r0 // set SPSR[23:8] to known value + + + XPUTC(#'@') + + + + + +/* +#if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA15) || defined(CPU_CORTEXA17) + // + // If SMP is already enabled, don't do anything (maybe). + // + mrc p15, 0, r0, c1, c0, 1 // ACTLR read + orr r1, r0, #CORTEXA9_AUXCTL_SMP // test SMP +#if defined(CPU_CORTEXA15) + // The A15 requires snoop-delayed exclusive handling to be set + // if there are 3 or more CPUs. + mrc p15, 1, r2, c9, c0, 2 // L2CTRL read + ubfx r2, r2, #25, #1 // bit 25 is set when 3+ CPUs + bfi r1, r2, #31, #1 // copy it to bit 31 in ACTRL +#endif + + cmp r0, r1 // ACTLR have SMP+<31> set? + bxeq r10 // return if set +#endif +*/ + + + + + mrc p15, 0, r4, c1, c0, 0 // SCTLR read + + + + +/* +#if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA15) || defined(CPU_CORTEXA17) + // + // Before turning on SMP, turn off the caches and the MMU. + // + dsb + movw r1,#(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE\ + |CPU_CONTROL_MMU_ENABLE) + bic r0, r4, r1 // disable icache/dcache/mmu + mcr p15, 0, r0, c1, c0, 0 // SCTLR write + dsb + isb +#endif +*/ + + + + + + + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 // toss i-cache + +#if defined(CPU_CORTEXA5) || defined(CPU_CORTEXA9) + // + // Step 1a, invalidate the all cache tags in all ways on the SCU. + // + XPUTC(#'A') +#if defined(ARM_CBAR) + movw r3, #:lower16:ARM_CBAR + movt r3, #:upper16:ARM_CBAR +#else + mrc p15, 4, r3, c15, c0, 0 // read cbar +#endif + + + + + + +#ifdef __ARMEB__ + setend le +#endif + mrc p15, 0, r0, c0, c0, 5 // MPIDR get + and r0, r0, #3 // get our cpu numder + lsl r0, r0, #2 // adjust to cpu num shift + mov r1, #0xf // select all ways + lsl r1, r1, r0 // shift into place + str r1, [r3, #SCU_INV_ALL_REG] // write scu invalidate all +#ifdef __ARMEB__ + setend be +#endif + dsb + isb +#endif + + + + + + + + + + + + + // + // Step 1b, invalidate the data cache + // + XPUTC(#'B') + CALL(armv7_dcache_wbinv_all) + XPUTC(#'C') + + // + // Check to see if we are really MP before enabling SMP mode + // + mrc p15, 0, r1, c0, c0, 5 // MPIDR get + ubfx r1, r1, #30, #2 // get MP bits + cmp r1, #2 // is it MP? + bxne r10 // no, return + + + + + + + +#if !defined(CPU_CORTEXA7) && !defined(CPU_CORTEXA17) + // + // Step 2, disable the data cache + // + mrc p15, 0, r2, c1, c0, 0 // SCTLR read + bic r2, r2, #CPU_CONTROL_DC_ENABLE // clear data cache enable + mcr p15, 0, r2, c1, c0, 0 // SCTLR write + isb + XPUTC(#'1') +#endif + +#if defined(CPU_CORTEXA5) || defined(CPU_CORTEXA9) + // + // Step 3, enable the SCU + // +#if defined(ARM_CBAR) + movw r3, #:lower16:ARM_CBAR + movt r3, #:upper16:ARM_CBAR +#else + mrc p15, 4, r3, c15, c0, 0 // read cbar +#endif +#ifdef __ARMEB__ + setend le +#endif + ldr r1, [r3, #SCU_CTL] // read scu control + orr r1, r1, #SCU_CTL_SCU_ENA // set scu enable flag + str r1, [r3, #SCU_CTL] // write scu control +#ifdef __ARMEB__ + setend be +#endif + dsb + isb + XPUTC(#'2') +#endif /* CORTEXA5 || CORTEXA9 */ + + + + + + + + + + + + +#if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA15) || defined(CPU_CORTEXA17) + // + // The MMU is off. Make sure the TLB is invalidated before + // turning on SMP. + // + mov r0, #0 + mcr p15, 0, r1, c8, c7, 0 // TLBIALL (just this core) +#endif + + + + + + // For the A7, SMP must be on ldrex/strex to work. + // +#if defined(MULTIPROCESSOR) || defined(CPU_CORTEXA5) || defined(CPU_CORTEXA7) || defined(CPU_CORTEXA9) || defined(CPU_CORTEXA15) || defined(CPU_CORTEXA17) +#if defined(CPU_CORTEXA5) || defined(CPU_CORTEXA7) || defined(CPU_CORTEXA9) || defined(CPU_CORTEXA15) || defined(CPU_CORTEXA17) + // + // Step 4a, set ACTLR.SMP=1, if ACTLR.SMP=0 + // i.e. OMAP4430 was enabled yet. + // + mrc p15, 0, r0, c1, c0, 1 // ACTLR read + tst r0, #CORTEXA9_AUXCTL_SMP + orreq r0, r0, #CORTEXA9_AUXCTL_SMP // enable SMP + +#if defined(CPU_CORTEXA15) + // The A15 requires snoop-delayed exclusive handling to be set + // if there are 3 or more CPUs. + mrc p15, 1, r2, c9, c0, 2 // L2CTRL read + ubfx r2, r2, #25, #1 // bit 25 is set when 3+ CPUs + bfi r0, r2, #31, #1 // copy it to bit 31 in ACTRL +#endif + +#if defined(CPU_CORTEXA5) || defined(CPU_CORTEXA9) + // + // Step 4a (continued on A5/A9), ACTLR.FW=1) + // + orreq r0, r0, #CORTEXA9_AUXCTL_FW // enable cache/tlb/coherency +#endif /* A5 || A9 */ +#if defined(CPU_CORTEXA9) + // + // Step 4b (continued on A9), ACTLR.L2PE=1) + // + orreq r0, r0, #CORTEXA9_AUXCTL_L2PE // enable L2 cache prefetch +#endif + + mcreq p15, 0, r0, c1, c0, 1 // ACTLR write + isb + dsb +#endif /* A5 || A7 || A9 || A15 || A17 */ +#endif /* MULTIPROCESSOR */ + + + + + + + + + + + + + + + + + + + // + // Step 4b, restore SCTLR (enable the data cache) + // + orr r4, r4, #CPU_CONTROL_IC_ENABLE // enable icache + orr r4, r4, #CPU_CONTROL_DC_ENABLE // enable dcache + mcr p15, 0, r4, c1, c0, 0 // SCTLR write + isb + XPUTC(#'-') + + bx r10 +ASEND(armv7_init) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#ifdef MULTIPROCESSOR + .pushsection .data + .align 2 + .globl armv7_mmuinfo + .type armv7_mmuinfo,%object +armv7_mmuinfo: + .space 4 +// +// If something goes wrong in the inital mpstartup, catch and record it. +// +#ifdef MPDEBUG + .globl armv7_mpfault + .type armv7_mpfault,%object +armv7_mpfault: + .space 16 // PC, LR, FSR, FAR +#endif + .popsection +#endif // MULTIPROCESSOR + +// Secondary processors come here after exiting the SKU ROM. +// Switches to kernel's endian almost immediately. +// + + .global armv7_mpstart + .type armv7_mpstart,%object + +armv7_mpstart: +#ifndef MULTIPROCESSOR + // + // If not MULTIPROCESSOR, drop CPU into power saving state. + // +3: wfi + b 3b +#else +#ifdef __ARMEB__ + setend be // switch to BE now +#endif + + // We haven't used anything from memory yet so we can invalidate the + // L1 cache without fear of losing valuable data. Afterwards, we can + // flush icache without worrying about anything getting written back + // to memory. + CALL(armv7_dcache_l1inv_all) // toss-dcache + CALL(armv7_icache_inv_all) // toss i-cache after d-cache + +#if 0 + mrc p15, 0, r0, c1, c1, 2 // NSACR read + // Allow non-secure access to ACTLR[SMP] + orr r0, r0, #NSACR_SMP +#ifdef FPU_VFP + // Allow non-secure access to VFP/Neon + orr r0, r0, #NSACR_VFPCP +#endif + mcr p15, 0, r0, c1, c1, 2 // NSACR write + + // Allow non-secure access to CPSR[A,F], go to non-secure mode + mrc p15, 0, r0, c1, c1, 0 // SCR read + orr r0, r0, #0x31 + bic r0, r4, #0x0e // non monitor extabt, irq, fiq + mcr p15, 0, r0, c1, c1, 0 // SCR write + isb +#endif + + bl armv7_init + + // We are in SMP mode now. + // + + // Get our initial temporary TTB so we can switch to it. + movw r7, #:lower16:_C_LABEL(armv7_mmuinfo) + movt r7, #:upper16:_C_LABEL(armv7_mmuinfo) +#if !defined(KERNEL_BASES_EQUAL) + sub r7, r7, #KERNEL_BASE_VOFFSET +#endif + dmb + ldr r0, [r7] // load saved TTB address + + // After we turn on the MMU, we will return to do rest of the + // MP startup code in .text. + // + movw lr, #:lower16:armv7_mpcontinuation + movt lr, #:upper16:armv7_mpcontinuation + b arm_cpuinit +#endif // MULTIPROCESSOR +ASEND(armv7_mpstart) + +#ifdef MULTIPROCESSOR + .pushsection .text +armv7_mpcontinuation: +#ifdef MPDEBUG + // + // Setup VBAR to catch errors + // + adr r2, armv7_mpvector + mcr p15, 0, r2, c12, c0, 0 // VBAR set + isb + + mrc p15, 0, r0, c1, c0, 0 // SCTLR read +#ifdef MULTIPROCESSOR + bic r0, r0, #CPU_CONTROL_VECRELOC // use VBAR +#endif + mcr p15, 0, r0, c1, c0, 0 // SCTLR write + dsb + isb +#endif + +#ifdef MPDEBUG + movw r9, #:lower16:_C_LABEL(arm_cpu_marker) + movt r9, #:upper16:_C_LABEL(arm_cpu_marker) + str pc, [r9] + str r2, [r9, #4] +#endif + + mrc p15, 0, r4, c0, c0, 5 // MPIDR get + and r4, r4, #7 // get our cpu numder + mov r5, #1 // make a bitmask of it + lsl r5, r5, r4 // shift into position +#ifdef MPDEBUG + str pc, [r9] +#endif + + mov r1, r5 + movw r0, #:lower16:_C_LABEL(arm_cpu_hatched) + movt r0, #:upper16:_C_LABEL(arm_cpu_hatched) + bl _C_LABEL(atomic_or_32) // show we've hatched + sev + + // + // Now we wait for cpu_boot_secondary_processors to kick us the + // first time. This means the kernel L1PT is ready for us to use. + // + movw r6, #:lower16:_C_LABEL(arm_cpu_mbox) + movt r6, #:upper16:_C_LABEL(arm_cpu_mbox) +#ifdef MPDEBUG + str pc, [r9] +#endif +3: dmb // make stores visible + ldr r2, [r6] // load mbox + tst r2, r5 // is our bit set? +#ifdef MPDEBUG + str pc, [r9] + str r2, [r9, #4] +#endif + wfeeq // no, back to sleep + beq 3b // no, and try again + +#ifdef MPDEBUG + str pc, [r9] +#endif + + movw r0, #:lower16:_C_LABEL(kernel_l1pt) + movt r0, #:upper16:_C_LABEL(kernel_l1pt) + ldr r0, [r0, #PV_PA] // now get the phys addr +#ifdef MPDEBUG + str pc, [r9] + str r0, [r9, #4] +#endif +#ifdef ARM_MMU_EXTENDED + mov r1, #0 +#endif + bl _C_LABEL(armv7_setttb) // set the TTB + + mov r0, #DOMAIN_DEFAULT + mcr p15, 0, r0, c3, c0, 0 // DACR write + + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 // invalidate the TLB + + mrc p15, 0, r1, c2, c0, 2 // TTBCR get + orr r1, r1, #TTBCR_S_PD0 // prevent lookups via TTBR0 + mcr p15, 0, r1, c2, c0, 2 // TTBCR set + +#ifdef MPDEBUG + str pc, [r9] // we've got this far + str r4, [r9, #4] +#endif + + // + // Tell arm32_kvminit we've load the new TTB + // + mov r0, r6 + mvn r1, r5 // pass inverted mask to clear + bl _C_LABEL(atomic_and_32) + sev // wake the master + +#ifdef MPDEBUG + str pc, [r9] // we've got this far +#endif + + // Wait for cpu_boot_secondary_processors the second time. + // +4: dmb // data memory barrier + ldr r2, [r6] // load mbox + tst r2, r5 // is our bit set? + wfeeq // no, back to waiting + beq 4b // no, and try again + +#ifdef MPDEBUG + str pc, [r9] // we've got this far +#endif + + movw r0, #:lower16:cpu_info + movt r0, #:upper16:cpu_info // get pointer to cpu_infos + ldr r5, [r0, r4, lsl #2] // load our cpu_info + ldr r6, [r5, #CI_IDLELWP] // get the idlelwp + ldr r7, [r6, #L_PCB] // now get its pcb + ldr sp, [r7, #PCB_KSP] // finally, we can load our SP +#ifdef TPIDRPRW_IS_CURCPU + mcr p15, 0, r5, c13, c0, 4 // squirrel away curcpu() +#elif defined(TPIDRPRW_IS_CURLWP) + mcr p15, 0, r6, c13, c0, 4 // squirrel away curlwp() +#else +#error either TPIDRPRW_IS_CURCPU or TPIDRPRW_IS_CURLWP must be defined +#endif + str r6, [r5, #CI_CURLWP] // and note we are running on it + +#ifdef MPDEBUG + str pc, [r9] // r9 still has arm_cpu_marker +#endif + + mov r0, r5 // pass cpu_info + mov r1, r4 // pass cpu_id +// movw r2, #:lower16:MD_CPU_HATCH // pass md_cpu_hatch +// movt r2, #:upper16:MD_CPU_HATCH // pass md_cpu_hatch + bl _C_LABEL(cpu_hatch) + b _C_LABEL(idle_loop) // never to return +ASEND(armv7_mpcontinuation) + +#ifdef MPDEBUG +// Our exception table. We only care about prefetch/data/address aborts. +// + .p2align 5 +armv7_mpvector: + b . @ reset + b . @ undefined + b . @ swi + b xprefetch_abort + b xdata_abort + b xaddress_abort + b . @ irq + b . @ fiq + +xprefetch_abort: + adr r10, xprefetch_abort + mrc p15, 0, r11, c5, c0, 1 // IFSR + mrc p15, 0, r12, c6, c0, 1 // IFAR + b xcommon_abort +xdata_abort: + adr r10, xdata_abort + mrc p15, 0, r11, c5, c0, 0 // DFSR + mrc p15, 0, r12, c6, c0, 0 // DFAR + b xcommon_abort +xaddress_abort: + adr r10, xaddress_abort + mrc p15, 0, r11, c5, c0, 0 // DFSR + mrc p15, 0, r12, c6, c0, 0 // DFAR +xcommon_abort: + movw r8, #:lower16:armv7_mpfault // where we should be + movt r8, #:upper16:armv7_mpfault // where we should be + stmia r8, {r10-r12,lr} // save type, PC, FSR, FAR + b . // loop forever +#endif + .popsection +#endif // MULTIPROCESSOR Index: sys/arch/arm/arm32/arm32_kvminit.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/arm32/arm32_kvminit.c,v retrieving revision 1.40 diff -u -p -r1.40 arm32_kvminit.c --- sys/arch/arm/arm32/arm32_kvminit.c 6 Jul 2017 15:09:17 -0000 1.40 +++ sys/arch/arm/arm32/arm32_kvminit.c 21 Jul 2017 11:46:40 -0000 @@ -208,8 +208,10 @@ arm32_bootmem_init(paddr_t memstart, psi /* * Let's record where the kernel lives. */ + const vaddr_t l1pt_va = (vaddr_t)armreg_ttbr_read() & -L1_TABLE_SIZE; + bmi->bmi_kernelstart = kernelstart; - bmi->bmi_kernelend = KERN_VTOPHYS(bmi, round_page((vaddr_t)_end)); + bmi->bmi_kernelend = KERN_VTOPHYS(bmi, l1pt_va + L1_TABLE_SIZE); #ifdef VERBOSE_INIT_ARM printf("%s: kernelend=%#lx\n", __func__, bmi->bmi_kernelend); @@ -676,7 +678,7 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b printf("Mapping kernel\n"); #endif - extern char etext[], _end[]; + extern char etext[]; size_t totalsize = bmi->bmi_kernelend - bmi->bmi_kernelstart; size_t textsize = KERN_VTOPHYS(bmi, (uintptr_t)etext) - bmi->bmi_kernelstart; @@ -956,8 +958,9 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b /* Switch tables */ #ifdef VERBOSE_INIT_ARM printf("switching to new L1 page table @%#lx...", l1pt_pa); -#endif + printf(" ttb"); +#endif #ifdef ARM_MMU_EXTENDED cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | (DOMAIN_CLIENT << (PMAP_DOMAIN_USER*2))); @@ -965,9 +968,23 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); #endif cpu_idcache_wbinv_all(); -#ifdef VERBOSE_INIT_ARM - printf(" ttb"); -#endif + + + + + +void cpu_actlr(void); + + + + cpu_actlr(); + + + + + + + #ifdef ARM_MMU_EXTENDED /* * TTBCR should have been initialized by the MD start code. Index: sys/arch/arm/conf/files.arm =================================================================== RCS file: /cvsroot/src/sys/arch/arm/conf/files.arm,v retrieving revision 1.133 diff -u -p -r1.133 files.arm --- sys/arch/arm/conf/files.arm 28 Jun 2017 23:48:23 -0000 1.133 +++ sys/arch/arm/conf/files.arm 21 Jul 2017 11:46:40 -0000 @@ -76,8 +76,11 @@ defparam opt_cpuoptions.h ARM_CBAR defparam opt_arm_intr_impl.h ARM_INTR_IMPL # ARM-specific debug options -defflag opt_arm_debug.h ARM_LOCK_CAS_DEBUG -defflag opt_arm_debug.h VERBOSE_INIT_ARM +defflag opt_arm_debug.h ARM_LOCK_CAS_DEBUG +defflag opt_arm_debug.h VERBOSE_INIT_ARM +defparam opt_arm_debug.h PLATFORM_UARTVA +defparam opt_arm_debug.h PLATFORM_UARTPA +defparam opt_arm_debug.h PLATFORM_PUTCHAR # Board-specific bus_space(9)/bus_dma(9) definitions defflag opt_arm_bus_space.h __BUS_SPACE_HAS_STREAM_METHODS Index: sys/arch/arm/include/armreg.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/include/armreg.h,v retrieving revision 1.111 diff -u -p -r1.111 armreg.h --- sys/arch/arm/include/armreg.h 17 May 2016 08:27:24 -0000 1.111 +++ sys/arch/arm/include/armreg.h 21 Jul 2017 11:46:41 -0000 @@ -455,6 +455,20 @@ #define PJ4B_AUXFMC0_DCSLFD __BIT(2) /* Disable DC Speculative linefill */ #define PJ4B_AUXFMC0_FW __BIT(8) /* alias of PJ4B_AUXCTL_FW*/ +/* Cortex-A5 Auxiliary Control Register (CP15 register 1, opcode 1) */ +#define CORTEXA5_ACTLR_FW __BIT(0) +#define CORTEXA5_ACTLR_SMP __BIT(6) /* Inner Cache Shared is cacheable */ +#define CORTEXA5_ACTLR_EXCL __BIT(7) /* Exclusive L1/L2 cache control */ + +/* Cortex-A7 Auxiliary Control Register (CP15 register 1, opcode 1) */ +#define CORTEXA7_ACTLR_L1ALIAS __BIT(0) /* */ +#define CORTEXA7_ACTLR_L2EN __BIT(1) /* */ +#define CORTEXA7_ACTLR_SMP __BIT(6) /* */ + +/* Cortex-A8 Auxiliary Control Register (CP15 register 1, opcode 1) */ +#define CORTEXA8_ACTLR_L1ALIAS __BIT(0) /* Enables L1 cache alias checks */ +#define CORTEXA8_ACTLR_L2EN __BIT(1) /* Enables L2 cache */ + /* Cortex-A9 Auxiliary Control Register (CP15 register 1, opcode 1) */ #define CORTEXA9_AUXCTL_FW 0x00000001 /* Cache and TLB updates broadcast */ #define CORTEXA9_AUXCTL_L2PE 0x00000002 /* Prefetch hint enable */ @@ -469,6 +483,7 @@ #define CORTEXA15_ACTLR_BTB __BIT(0) /* Cache and TLB updates broadcast */ #define CORTEXA15_ACTLR_SMP __BIT(6) /* SMP */ #define CORTEXA15_ACTLR_IOBEU __BIT(15) /* In order issue in Branch Exec Unit */ +#define CORTEXA15_ACTLR_SDEH __BIT(31) /* snoop-delayed exclusive handling */ /* Marvell Feroceon Extra Features Register (CP15 register 1, opcode2 0) */ #define FC_DCACHE_REPL_LOCK 0x80000000 /* Replace DCache Lock */ Index: sys/arch/arm/nvidia/soc_tegra124.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/nvidia/soc_tegra124.c,v retrieving revision 1.17 diff -u -p -r1.17 soc_tegra124.c --- sys/arch/arm/nvidia/soc_tegra124.c 23 Apr 2017 12:31:38 -0000 1.17 +++ sys/arch/arm/nvidia/soc_tegra124.c 21 Jul 2017 11:46:41 -0000 @@ -53,7 +53,7 @@ void tegra124_mpinit(void) { #if defined(MULTIPROCESSOR) - extern void cortex_mpstart(void); + extern void armv7_mpstart(void); bus_space_tag_t bst = &armv7_generic_bs_tag; bus_space_handle_t bsh; @@ -64,7 +64,7 @@ tegra124_mpinit(void) KASSERT(arm_cpu_max == 4); bus_space_write_4(bst, bsh, EVP_RESET_VECTOR_0_REG, - (uint32_t)cortex_mpstart); + (uint32_t)armv7_mpstart); bus_space_barrier(bst, bsh, EVP_RESET_VECTOR_0_REG, 4, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); uint32_t started = 0; Index: sys/arch/arm/nvidia/tegra_platform.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/nvidia/tegra_platform.c,v retrieving revision 1.6 diff -u -p -r1.6 tegra_platform.c --- sys/arch/arm/nvidia/tegra_platform.c 2 Jun 2017 13:53:29 -0000 1.6 +++ sys/arch/arm/nvidia/tegra_platform.c 21 Jul 2017 11:46:41 -0000 @@ -26,9 +26,10 @@ * SUCH DAMAGE. */ -#include "opt_tegra.h" -#include "opt_multiprocessor.h" +#include "opt_arm_debug.h" #include "opt_fdt_arm.h" +#include "opt_multiprocessor.h" +#include "opt_tegra.h" #include "ukbd.h" @@ -60,6 +61,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_platfo #include #include +void tegra_platform_early_putchar(char); + #define PLLP_OUT0_FREQ 408000000 #define DEVMAP_ALIGN(a) ((a) & ~L1_S_OFFSET) @@ -91,7 +94,7 @@ tegra_platform_devmap(void) TEGRA_AHB_A2_BASE, TEGRA_AHB_A2_SIZE), DEVMAP_ENTRY_END - }; + }; return devmap; } @@ -114,12 +117,14 @@ tegra_platform_init_attach_args(struct f faa->faa_dmat = &armv7_generic_dma_tag; } -static void +void tegra_platform_early_putchar(char c) { -#ifdef CONSADDR -#define CONSADDR_VA (CONSADDR - TEGRA_APB_BASE + TEGRA_APB_VBASE) - volatile uint32_t *uartaddr = (volatile uint32_t *)CONSADDR_VA; +#if defined(PLATFORM_UARTPA) && defined(PLATFORM_UARTVA) + volatile uint32_t *uartaddr = + (armreg_sctlr_read() & CPU_CONTROL_MMU_ENABLE) ? + (volatile uint32_t *)PLATFORM_UARTVA : + (volatile uint32_t *)PLATFORM_UARTPA; while ((uartaddr[com_lsr] & LSR_TXRDY) == 0) ; Index: sys/arch/arm/vexpress/vexpress_platform.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/vexpress/vexpress_platform.c,v retrieving revision 1.3 diff -u -p -r1.3 vexpress_platform.c --- sys/arch/arm/vexpress/vexpress_platform.c 6 Jun 2017 09:56:57 -0000 1.3 +++ sys/arch/arm/vexpress/vexpress_platform.c 21 Jul 2017 11:46:41 -0000 @@ -52,6 +52,7 @@ __KERNEL_RCSID(0, "$NetBSD: vexpress_pla #include #include +#include #include @@ -107,7 +108,7 @@ static bus_space_handle_t sysreg_bsh; static void vexpress_a15_smp_init(void) { - extern void cortex_mpstart(void); + extern void armv7_mpstart(void); bus_space_tag_t gicd_bst = &armv7_generic_bs_tag; bus_space_handle_t gicd_bsh; int started = 0; @@ -118,7 +119,7 @@ vexpress_a15_smp_init(void) /* Write init vec to SYS_FLAGS register */ SYSREG_WRITE(SYS_FLAGSCLR, 0xffffffff); - SYSREG_WRITE(SYS_FLAGS, (uint32_t)cortex_mpstart); + SYSREG_WRITE(SYS_FLAGS, (uint32_t)armv7_mpstart); /* Map GIC distributor */ bus_space_map(gicd_bst, VEXPRESS_GIC_PBASE + GICD_BASE, @@ -155,7 +156,7 @@ vexpress_platform_devmap(void) VEXPRESS_GIC_PBASE, VEXPRESS_GIC_SIZE), DEVMAP_ENTRY_END - }; + }; return devmap; } @@ -187,9 +188,27 @@ vexpress_platform_init_attach_args(struc faa->faa_dmat = &armv7_generic_dma_tag; } -static void + + + +void vexpress_platform_early_putchar(char); +void vexpress_platform_early_putchar(char c) { +#if defined(PLATFORM_UARTPA) && defined(PLATFORM_UARTVA) + volatile uint8_t *uart = + (armreg_sctlr_read() & CPU_CONTROL_MMU_ENABLE) ? + (volatile uint8_t *)PLATFORM_UARTVA : + (volatile uint8_t *)PLATFORM_UARTPA; + + while (!ISSET(uart[PL01XCOM_FR], PL01X_FR_TXFE)) + continue; + + uart[PL01XCOM_DR] = c; + + while (!ISSET(uart[PL01XCOM_FR], PL01X_FR_TXFE)) + continue; +#endif } static void Index: sys/arch/evbarm/conf/TEGRA =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/TEGRA,v retrieving revision 1.24 diff -u -p -r1.24 TEGRA --- sys/arch/evbarm/conf/TEGRA 16 Jun 2017 21:37:11 -0000 1.24 +++ sys/arch/evbarm/conf/TEGRA 21 Jul 2017 11:46:41 -0000 @@ -26,9 +26,12 @@ pseudo-device openfirm # /dev/openfirm #options LOCKDEBUG #options PMAP_DEBUG # Enable pmap_debug_level code #options IPKDB # remote kernel debugging -#options VERBOSE_INIT_ARM # verbose bootstrapping messages -# CONSADDR is required for early init messages from VERBOSE_INIT_ARM. -#options CONSADDR=0x70006300 +options VERBOSE_INIT_ARM # verbose bootstrapping messages +# these are required for early init messages from VERBOSE_INIT_ARM. +options PLATFORM_UARTVA=0xfc006300 +options PLATFORM_UARTPA=0x70006300 +options PLATFORM_PUTCHAR=tegra_platform_early_putchar + makeoptions DEBUG="-g" # compile full symbol table makeoptions COPY_SYMTAB=1 Index: sys/arch/evbarm/conf/VEXPRESS_A15 =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/VEXPRESS_A15,v retrieving revision 1.17 diff -u -p -r1.17 VEXPRESS_A15 --- sys/arch/evbarm/conf/VEXPRESS_A15 16 Jun 2017 21:37:11 -0000 1.17 +++ sys/arch/evbarm/conf/VEXPRESS_A15 21 Jul 2017 11:46:41 -0000 @@ -19,11 +19,20 @@ pseudo-device openfirm # /dev/openfirm #options LOCKDEBUG #options PMAP_DEBUG # Enable pmap_debug_level code #options IPKDB # remote kernel debugging -#options VERBOSE_INIT_ARM # verbose bootstrapping messages +options VERBOSE_INIT_ARM # verbose bootstrapping messages makeoptions DEBUG="-g" # compile full symbol table makeoptions COPY_SYMTAB=1 +options PLATFORM_UARTPA=0x1c090000 +options PLATFORM_UARTVA=0xfc090000 +options PLATFORM_PUTCHAR=vexpress_platform_early_putchar + +#armv7_generic_bs_map: bpa 1c090000 va fc090000 + + + + config netbsd root on ? type ? # Device tree support Index: sys/arch/evbarm/conf/mk.tegra =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/mk.tegra,v retrieving revision 1.6 diff -u -p -r1.6 mk.tegra --- sys/arch/evbarm/conf/mk.tegra 16 Jun 2017 21:37:11 -0000 1.6 +++ sys/arch/evbarm/conf/mk.tegra 21 Jul 2017 11:46:41 -0000 @@ -3,8 +3,8 @@ CPPFLAGS+= -mcpu=cortex-a15 -mfpu=neon .include "$S/arch/arm/nvidia/tegra_xusb-fw.mk" -SYSTEM_FIRST_OBJ= tegra_start.o -SYSTEM_FIRST_SFILE= ${THISARM}/tegra/tegra_start.S +SYSTEM_FIRST_OBJ= armv6_start.o +SYSTEM_FIRST_SFILE= ${ARM}/arm/armv6_start.S GENASSYM_EXTRAS+= ${THISARM}/tegra/genassym.cf Index: sys/arch/evbarm/conf/mk.vexpress =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/mk.vexpress,v retrieving revision 1.4 diff -u -p -r1.4 mk.vexpress --- sys/arch/evbarm/conf/mk.vexpress 16 Jun 2017 21:37:11 -0000 1.4 +++ sys/arch/evbarm/conf/mk.vexpress 21 Jul 2017 11:46:42 -0000 @@ -4,8 +4,8 @@ EXTRA_LINKFLAGS+= --be8 .endif -SYSTEM_FIRST_OBJ= vexpress_start.o -SYSTEM_FIRST_SFILE= ${THISARM}/vexpress/vexpress_start.S +SYSTEM_FIRST_OBJ= armv6_start.o +SYSTEM_FIRST_SFILE= ${ARM}/arm/armv6_start.S _OSRELEASE!= ${HOST_SH} $S/conf/osrelease.sh Index: sys/arch/evbarm/fdt/fdt_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/fdt/fdt_machdep.c,v retrieving revision 1.10 diff -u -p -r1.10 fdt_machdep.c --- sys/arch/evbarm/fdt/fdt_machdep.c 10 Jul 2017 09:44:14 -0000 1.10 +++ sys/arch/evbarm/fdt/fdt_machdep.c 21 Jul 2017 11:46:42 -0000 @@ -361,10 +363,19 @@ initarm(void *arg) boot_args = bootargs; DPRINT(" devmap"); - pmap_devmap_register(plat->devmap()); + + /* + * Map integrated peripherals at same address in first level page + * table so that we can continue to use console. + */ + const vaddr_t l1pt_va = (vaddr_t)armreg_ttbr_read() & -L1_TABLE_SIZE; + DPRINTN(l1pt_va, 16); + if (plat->ap_devmap()) + pmap_devmap_bootstrap(l1pt_va, plat->ap_devmap()); + DPRINT(" bootstrap"); - plat->bootstrap(); + plat->ap_bootstrap(); /* Heads up ... Setup the CPU / MMU / TLB functions. */ DPRINT(" cpufunc");