/* $NetBSD: locore_octeon.S,v 1.14 2022/07/20 10:07:49 riastradh Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. * All rights reserved. * * 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 REGENTS 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 REGENTS 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 RCSID("$NetBSD: locore_octeon.S,v 1.14 2022/07/20 10:07:49 riastradh Exp $") #include "cpunode.h" /* for NWDOG */ #include "opt_cputype.h" #include "opt_ddb.h" #include "opt_multiprocessor.h" #include #include RCSID("$NetBSD: locore_octeon.S,v 1.14 2022/07/20 10:07:49 riastradh Exp $") #include "assym.h" #define _CP0_READ64(_cp0) \ dmfc0 v0, _cp0; \ j ra; \ nop #define _CP0_WRITE64(_cp0) \ dmtc0 a0, _cp0; \ j ra; \ nop .set noreorder .set noat .set arch=octeon .text LEAF(mips_cp0_cvmctl_read) _CP0_READ64(MIPS_COP_0_CVMCTL) END(mips_cp0_cvmctl_read) #ifdef notyet /* the rest of these aren't used (yet) */ LEAF(mips_cp0_cvmctl_write) _CP0_WRITE64(MIPS_COP_0_CVMCTL) END(mips_cp0_cvmctl_write) LEAF(mips_cp0_cvmmemctl_read) _CP0_READ64(MIPS_COP_0_CVMMEMCTL) END(mips_cp0_cvmmemctl_read) LEAF(mips_cp0_cvmmemctl_write) _CP0_WRITE64(MIPS_COP_0_CVMMEMCTL) END(mips_cp0_cvmmemctl_write) LEAF(mips_cp0_cvmcnt_read) _CP0_READ64(MIPS_COP_0_CVMCNT) END(mips_cp0_cvmcnt_read) LEAF(mips_cp0_cvmcnt_write) _CP0_WRITE64(MIPS_COP_0_CVMCNT) END(mips_cp0_cvmcnt_write) LEAF(mips_cp0_performance_counter_control0_read) _CP0_READ64(MIPS_COP_0_PERFCNT0_CTL) END(mips_cp0_performance_counter_control0_read) LEAF(mips_cp0_performance_counter_control0_write) _CP0_WRITE64(MIPS_COP_0_PERFCNT0_CTL) END(mips_cp0_performance_counter_control0_write) LEAF(mips_cp0_performance_counter_control1_read) _CP0_READ64(MIPS_COP_0_PERFCNT1_CTL) END(mips_cp0_performance_counter_control1_read) LEAF(mips_cp0_performance_counter_control1_write) _CP0_WRITE64(MIPS_COP_0_PERFCNT1_CTL) END(mips_cp0_performance_counter_control1_write) LEAF(mips_cp0_performance_counter_counter0_read) _CP0_READ64(MIPS_COP_0_PERFCNT0_CNT) END(mips_cp0_performance_counter_counter0_read) LEAF(mips_cp0_performance_counter_counter0_write) _CP0_WRITE64(MIPS_COP_0_PERFCNT0_CNT) END(mips_cp0_performance_counter_counter0_write) LEAF(mips_cp0_performance_counter_counter1_read) _CP0_READ64(MIPS_COP_0_PERFCNT1_CNT) END(mips_cp0_performance_counter_counter1_read) LEAF(mips_cp0_performance_counter_counter1_write) _CP0_WRITE64(MIPS_COP_0_PERFCNT1_CNT) END(mips_cp0_performance_counter_counter1_write) #endif /* notyet */ #ifdef MULTIPROCESSOR NESTED_NOPROFILE(octeon_cpu_spinup, 0, ra) // // Since the OCTEON cpus doesn't a COP0 OSCONTEXT register, each core // must has its own exception vector page. The exceptions will be // modified to refer to that CPU's cpu_info structure. // mfc0 s1, MIPS_COP_0_EBASE # get EBASE andi s0, s1, MIPS_EBASE_CPUNUM # fetch cpunum # insert cpunum as exception address base: ins s1, s0, MIPS_EBASE_EXC_BASE_SHIFT, MIPS_EBASE_CPUNUM_WIDTH ehb mtc0 s1, MIPS_COP_0_EBASE # set EBASE COP0_SYNC // Indicate this CPU was started by u-boot PTR_LA a0, _C_LABEL(cpus_booted) li a1, 1 jal _C_LABEL(atomic_or_64) sllv a1, a1, s0 # shift cpu number to bit position // Wait until cpuid_infos[cpunum] is not NULL. PTR_LA a1, _C_LABEL(cpuid_infos) dsll v0, s0, PTR_SCALESHIFT # cpunum -> array index PTR_ADD t0, a1, v0 # add to array start 1: PTR_L a1, (t0) # get cpu_info pointer SYNC_ACQ # PTR_L/SYNC_ACQ matches # atomic_store_release in # cpu_attach_common beqz a1, 1b # loop until non-NULL nop j _C_LABEL(cpu_trampoline) nop END(octeon_cpu_spinup) #endif /* MULTIPROCESSOR */ #if NWDOG > 0 || defined(DDB) #define UINT64_C(x) (x) #include NESTED_NOPROFILE(octeon_reset_vector, 0, ra) mfc0 k0, MIPS_COP_0_STATUS # get cp0 status bbit1 k0, V_MIPS3_SR_SR, 1f # MIPS3_SR_SR ins k0, zero, V_MIPS_SR_BEV, 1 # clear boot exception vectors mtc0 k0, MIPS_COP_0_STATUS # write cp0 status ehb # hazard barrier #ifdef MULTIPROCESSOR mfc0 k0, MIPS_COP_0_EBASE # get EBASE andi k0, k0, MIPS_EBASE_CPUNUM # fetch cpunum dsll k0, k0, PTR_SCALESHIFT # cpunum -> array index PTR_LA k1, _C_LABEL(cpuid_infos) PTR_ADDU k1, k1, k0 # add to array start PTR_L k0, (k1) # get cpu_info #else PTR_LA k0, _C_LABEL(cpu_info_store) # get cpu_info #endif j _C_LABEL(mips64r2_kern_nonmaskable_intr) sd zero, CIU_NMI_OFFSET(k1)# clear NMI 1: li k1, ((MIPS_XKPHYS_START|CIU_BASE) >> 32) # CIU base (MSW) dsll k1, 32 # shift it place ld k0, CIU_FUSE_OFFSET(k1) # get mask of CPUs sd k0, CIU_SOFT_RST_OFFSET(k1) # reset them ld v0, CIU_SOFT_RST_OFFSET(k1) # force a load sd k0, CIU_SOFT_RST_OFFSET(k1) # do it again. 2: wait # wait forever b 2b # and loop until reset nop END(octeon_reset_vector) #endif