^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright 2003-2013 Broadcom Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This software is available to you under a choice of one of two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * licenses. You may choose to be licensed under the terms of the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * General Public License (GPL) Version 2, available from the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * COPYING in the main directory of this source tree, or the Broadcom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * license below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * notice, this list of conditions and the following disclaimer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/cacheops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/regdef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/stackframe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <asm/addrspace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <asm/netlogic/common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <asm/netlogic/xlp-hal/iomap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <asm/netlogic/xlp-hal/xlp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <asm/netlogic/xlp-hal/sys.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <asm/netlogic/xlp-hal/cpucontrol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SYS_CPU_COHERENT_BASE CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) XLP_IO_SYS_OFFSET(0) + XLP_IO_PCI_HDRSZ + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) SYS_CPU_NONCOHERENT_MODE * 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Enable XLP features and workarounds in the LSU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .macro xlp_config_lsu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) li t0, LSU_DEFEATURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mfcr t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) or t1, t1, t2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) mtcr t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) li t0, ICU_DEFEATURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mfcr t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ori t1, 0x1000 /* Enable Icache partitioning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) mtcr t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) li t0, SCHED_DEFEATURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) lui t1, 0x0100 /* Disable BRU accepting ALU ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) mtcr t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Allow access to physical mem >64G by enabling ELPA in PAGEGRAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * register. This is needed before going to C code since the SP can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * in this region. Called from all HW threads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .macro xlp_early_mmu_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mfc0 t0, CP0_PAGEMASK, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) li t1, (1 << 29) /* ELPA bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) or t0, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) mtc0 t0, CP0_PAGEMASK, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * L1D cache has to be flushed before enabling threads in XLP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * On XLP8xx/XLP3xx, we do a low level flush using processor control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * registers. On XLPII CPUs, usual cache instructions work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .macro xlp_flush_l1_dcache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) mfc0 t0, CP0_PRID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) andi t0, t0, PRID_IMP_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) slt t1, t0, 0x1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) beqz t1, 15f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* XLP8xx low level cache flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) li t0, LSU_DEBUG_DATA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) li t1, LSU_DEBUG_ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) li t2, 0 /* index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) li t3, 0x1000 /* loop count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) sll v0, t2, 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) mtcr zero, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ori v1, v0, 0x3 /* way0 | write_enable | write_active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mtcr v1, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mfcr v1, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) andi v1, 0x1 /* wait for write_active == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bnez v1, 12b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mtcr zero, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ori v1, v0, 0x7 /* way1 | write_enable | write_active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mtcr v1, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mfcr v1, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) andi v1, 0x1 /* wait for write_active == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bnez v1, 13b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) addi t2, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) bne t3, t2, 11b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) b 17f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* XLPII CPUs, Invalidate all 64k of L1 D-cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) li t0, 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) li t1, 0x80010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 16: cache Index_Writeback_Inv_D, 0(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) addiu t0, t0, 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bne t0, t1, 16b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * nlm_reset_entry will be copied to the reset entry point for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * XLR and XLP. The XLP cores start here when they are woken up. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * is also the NMI entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * We use scratch reg 6/7 to save k0/k1 and check for NMI first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * location, this will have the thread mask (used when core is woken up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * and the current NMI handler in case we reached here for an NMI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * When a core or thread is newly woken up, it marks itself ready and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * loops in a 'wait'. When the CPU really needs waking up, we send an NMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * IPI to it, with the NMI handler set to prom_boot_secondary_cpus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .set noreorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) FEXPORT(nlm_reset_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dmtc0 k0, $22, 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) dmtc0 k1, $22, 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mfc0 k0, CP0_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) li k1, 0x80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) and k1, k0, k1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) beqz k1, 1f /* go to real reset entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ld k0, BOOT_NMI_HANDLER(k1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) jr k0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 1: /* Entry point on core wakeup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mfc0 t0, CP0_PRID /* processor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) andi t0, PRID_IMP_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) li t1, 0x1500 /* XLP 9xx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) beq t0, t1, 2f /* does not need to set coherent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) li t1, 0x1300 /* XLP 5xx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) beq t0, t1, 2f /* does not need to set coherent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* set bit in SYS coherent register for the core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mfc0 t0, CP0_EBASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mfc0 t1, CP0_EBASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) srl t1, 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) andi t1, 0x3 /* t1 <- node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) li t2, 0x40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mul t3, t2, t1 /* t3 = node * 0x40000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) srl t0, t0, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) and t0, t0, 0x7 /* t0 <- core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) li t1, 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) sll t0, t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) nor t0, t0, zero /* t0 <- ~(1 << core) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) li t2, SYS_CPU_COHERENT_BASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) add t2, t2, t3 /* t2 <- SYS offset for node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) lw t1, 0(t2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) and t1, t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) sw t1, 0(t2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* read back to ensure complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) lw t1, 0(t2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Configure LSU on Non-0 Cores. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) xlp_config_lsu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* FALL THROUGH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * Wake up sibling threads from the initial thread in a core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) EXPORT(nlm_boot_siblings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* core L1D flush before enable threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) xlp_flush_l1_dcache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* save ra and sp, will be used later (only for boot cpu) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dmtc0 ra, $22, 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dmtc0 sp, $22, 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Enable hw threads by writing to MAP_THREADMODE of the core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) li t0, CKSEG1ADDR(RESET_DATA_PHYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mfcr t2, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) or t2, t2, t1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) mtcr t2, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * The new hardware thread starts at the next instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * For all the cases other than core 0 thread 0, we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * jump to the secondary wait function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * NOTE: All GPR contents are lost after the mtcr above!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mfc0 v0, CP0_EBASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) andi v0, 0x3ff /* v0 <- node/core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Errata: to avoid potential live lock, setup IFU_BRUB_RESERVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * when running 4 threads per core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) andi v1, v0, 0x3 /* v1 <- thread id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) bnez v1, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* thread 0 of each core. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) li t0, CKSEG1ADDR(RESET_DATA_PHYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) subu t1, 0x3 /* 4-thread per core mode? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) bnez t1, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) li t0, IFU_BRUB_RESERVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) li t1, 0x55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) mtcr t1, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) _ehb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) beqz v0, 4f /* boot cpu (cpuid == 0)? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* setup status reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) move t1, zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ori t1, ST0_KX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mtc0 t1, CP0_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) xlp_early_mmu_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* mark CPU ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) li t3, CKSEG1ADDR(RESET_DATA_PHYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ADDIU t1, t3, BOOT_CPU_READY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) sll v1, v0, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) PTR_ADDU t1, v1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) li t2, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) sw t2, 0(t1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Wait until NMI hits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 3: wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) b 3b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * For the boot CPU, we have to restore ra and sp and return, rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * of the registers will be restored by the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dmfc0 ra, $22, 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dmfc0 sp, $22, 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) jr ra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) EXPORT(nlm_reset_entry_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) LEAF(nlm_init_boot_cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #ifdef CONFIG_CPU_XLP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) xlp_config_lsu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) xlp_early_mmu_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) jr ra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) END(nlm_init_boot_cpu)