1/* $OpenBSD: locore.S,v 1.22 2021/02/11 14:44:14 visa Exp $ */ 2 3/* 4 * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28#include <sys/errno.h> 29#include <sys/syscall.h> 30 31#include <machine/param.h> 32#include <machine/asm.h> 33#include <machine/cpu.h> 34#include <mips64/mips_cpu.h> 35#include <machine/regnum.h> 36#include <machine/cpustate.h> 37#include <octeon/dev/cn30xxcorereg.h> 38 39#include "assym.h" 40#include "octboot.h" 41 42#define RNG_CONTROL_ADDR 0x9001180040000000 43#define RNG_CONTROL_ENABLE 0x3 44#define RNG_ENTROPY_ADDR 0x9001400000000000 45 46 .set noreorder # Noreorder is default style! 47 .set mips64r2 48 .globl locore_start 49 .ent locore_start, 0 50locore_start: 51/* initialize ebase */ 52 dla t0, 0xffffffff80000000 53 mtc0 t0, COP_0_EBASE 54 55/* initialize cvmctl */ 56 dli t0, COP_0_CVMCTL_FUSE_START_BIT|COP_0_CVMCTL_NOFDA_CP2|\ 57 COP_0_CVMCTL_IPPCI|COP_0_CVMCTL_IPTI 58 dmtc0 t0, COP_0_CVMCTL 59 60/* initialize cvmmemctl */ 61#if 0 62 dli t0, 0x1846104 # If you want to skip write buffer, use this 63#else 64 dli t0, 0x46104 65#endif 66 dmtc0 t0, COP_0_CVMMEMCTL 67 68 mfc0 v0, COP_0_STATUS_REG 69 li v1, ~(SR_INT_ENAB | SR_ERL | SR_EXL) 70 and v0, v1 71 mtc0 v0, COP_0_STATUS_REG # disable all interrupts 72 73 mtc0 zero, COP_0_CAUSE_REG # Clear soft interrupts 74 75 /* Let the init core continue. The others have to wait. */ 76 bne a2, zero, 2f 77 nop 78#if defined(MULTIPROCESSOR) 79 rdhwr t2, $0 80 LA t1, cpu_spinup_mask 811: ll t0, 0(t1) 82 bne t2, t0, 1b 83 nop 84 move t0, zero 85 sc t0, 0(t1) 86 beqz t0, 1b 87 nop 88 j hw_cpu_spinup_trampoline 89 nop 90#elif NOCTBOOT > 0 91 LA t0, octeon_boot_ready 921: lw t1, (t0) 93 beq t1, zero, 1b 94 nop 95 96 LA t0, octeon_boot_entry 97 ld t0, (t0) # get entry point 98 cache 1, 0(zero) # flush and invalidate dcache 99 jr t0 100 cache 0, 0(zero) # invalidate icache 101#else 102 /* Halt extra cores on single-processor kernel. */ 1031: wait 104 j 1b 105 nop 106#endif 1072: 108 /* 109 * Augment the randomdata section using entropy from the RNG. 110 */ 111 112 /* Enable the RNG. */ 113 dli t0, RNG_CONTROL_ADDR 114 ld t1, (t0) 115 ori t1, RNG_CONTROL_ENABLE 116 sd t1, (t0) 117 118 LA t0, __kernel_randomdata 119 LA t1, __kernel_randomdata_end 120 dli t2, RNG_ENTROPY_ADDR 1211: 122 /* Delay to let entropy accumulate. */ 123 li v0, 0x1000 1242: 125 bne v0, zero, 2b 126 subu v0, v0, 1 127 /* Mix entropy. */ 128 ld v0, (t0) # load from randomdata 129 ld v1, (t2) # load entropy 130 xor v0, v0, v1 # mix entropy 131 daddu t0, t0, 8 # advance ptr 132 blt t0, t1, 1b 133 sd v0, -8(t0) # store to randomdata 134 135 /* 136 * Clear the compiled BSS segment in OpenBSD code. 137 * U-Boot is supposed to have done this, though. 138 */ 139 LA t0, edata 140 LA t1, end 1411: 142 daddu t0, t0, 8 143 blt t0, t1, 1b 144 sd zero, -8(t0) 145 146 /* 147 * Initialize stack and call machine startup. 148 */ 149 LA t0, initstack_end - FRAMESZ(CF_SZ) 150 PTR_S ra, CF_RA_OFFS(t0) # save uboot return address 151 PTR_S sp, 0(t0) # and stack 152 move sp, t0 153 jal mips_init # mips_init(argc, argv, envp, 154 nop # callvec, esym) 155 156 beqz v0, 1f # upon failure, return to uboot 157 nop 158 159 PTR_S zero, CF_RA_OFFS(sp) # Zero out old ra for debugger 160 move sp, v0 # switch to new stack 161 jal main # main(regs) 162 move a0, zero 163 PANIC("Startup failed!") 164 1651: PTR_L ra, CF_RA_OFFS(sp) 166 PTR_L sp, 0(sp) 167 jr ra 168 nop 169 .end locore_start 170 171/* 172 * void octeon_sync_tc(vaddr_t reg, uint64_t mul, uint64_t frac) 173 */ 174LEAF(octeon_sync_tc, 0) 175 /* 176 * The measurement is done several times in a loop. 177 * The initial iterations warm up the icache and train the branch 178 * predictor to reduce jitter. 179 * The final iteration performs the actual synchronization. 180 */ 181 li t0, 5 # set number of iterations 182 di t3 # disable all interrupts 183 MTC0_SR_IE_HAZARD 1841: 185 ld t1, (a0) # load data clock counter 186 dmultu t1, a1 # multiply with mul 187 mflo t1 # fetch result 188 beqz a2, 2f # skip if frac == 2^64 189 subu t0, 1 190 dmultu t1, a2 # multiply with frac 191 mfhi t1 # fetch result divided by 2^64 1922: 193 mtc0 t1, COP_0_COUNT # set core clock counter 194 MTC0_HAZARD 195 bnez t0, 1b 196 nop 197 mtc0 t3, COP_0_STATUS_REG # restore status register 198 MTC0_SR_IE_HAZARD 199 jr ra 200 nop 201END(octeon_sync_tc) 202 203#if defined(MULTIPROCESSOR) 204LEAF(hw_cpu_spinup_trampoline, 0) 205 LA t0, cpu_spinup_a0 206 ld a0, 0(t0) 207 LA t0, cpu_spinup_sp 208 ld sp, 0(t0) 209 jal hw_cpu_hatch 210 nop 211END(hw_cpu_spinup_trampoline) 212#endif /* MULTIPROCESSOR */ 213 214/* 215 * Bootstrap stack for mips_init() 216 */ 217 .bss 218 .align 3 219initstack: 220 .space 4096 221initstack_end: 222