12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 20ee958e1SPaul Burton/* 30ee958e1SPaul Burton * Copyright (C) 2013 Imagination Technologies 4fb615d61SPaul Burton * Author: Paul Burton <paul.burton@mips.com> 50ee958e1SPaul Burton */ 60ee958e1SPaul Burton 70ee958e1SPaul Burton#include <asm/addrspace.h> 80ee958e1SPaul Burton#include <asm/asm.h> 90ee958e1SPaul Burton#include <asm/asm-offsets.h> 100ee958e1SPaul Burton#include <asm/asmmacro.h> 110ee958e1SPaul Burton#include <asm/cacheops.h> 126521d9a4SMarkos Chandras#include <asm/eva.h> 130ee958e1SPaul Burton#include <asm/mipsregs.h> 14245a7868SPaul Burton#include <asm/mipsmtregs.h> 153179d37eSPaul Burton#include <asm/pm.h> 16fea8826dSJiaxun Yang#include <asm/smp-cps.h> 170ee958e1SPaul Burton 185a3e7c02SPaul Burton#define GCR_CPC_BASE_OFS 0x0088 190ee958e1SPaul Burton#define GCR_CL_COHERENCE_OFS 0x2008 20245a7868SPaul Burton#define GCR_CL_ID_OFS 0x2028 21245a7868SPaul Burton 22fa7a3b4aSPaul Burton#define CPC_CL_VC_STOP_OFS 0x2020 235a3e7c02SPaul Burton#define CPC_CL_VC_RUN_OFS 0x2028 245a3e7c02SPaul Burton 25245a7868SPaul Burton.extern mips_cm_base 26245a7868SPaul Burton 27245a7868SPaul Burton.set noreorder 28245a7868SPaul Burton 298fe2c547SPaul Burton#ifdef CONFIG_64BIT 308fe2c547SPaul Burton# define STATUS_BITDEPS ST0_KX 318fe2c547SPaul Burton#else 328fe2c547SPaul Burton# define STATUS_BITDEPS 0 338fe2c547SPaul Burton#endif 348fe2c547SPaul Burton 35609cf6f2SPaul Burton#ifdef CONFIG_MIPS_CPS_NS16550 36609cf6f2SPaul Burton 37609cf6f2SPaul Burton#define DUMP_EXCEP(name) \ 38609cf6f2SPaul Burton PTR_LA a0, 8f; \ 39609cf6f2SPaul Burton jal mips_cps_bev_dump; \ 40609cf6f2SPaul Burton nop; \ 41609cf6f2SPaul Burton TEXT(name) 42609cf6f2SPaul Burton 43609cf6f2SPaul Burton#else /* !CONFIG_MIPS_CPS_NS16550 */ 44609cf6f2SPaul Burton 45609cf6f2SPaul Burton#define DUMP_EXCEP(name) 46609cf6f2SPaul Burton 47609cf6f2SPaul Burton#endif /* !CONFIG_MIPS_CPS_NS16550 */ 48609cf6f2SPaul Burton 49245a7868SPaul Burton /* 50245a7868SPaul Burton * Set dest to non-zero if the core supports the MT ASE, else zero. If 51245a7868SPaul Burton * MT is not supported then branch to nomt. 52245a7868SPaul Burton */ 53245a7868SPaul Burton .macro has_mt dest, nomt 54245a7868SPaul Burton mfc0 \dest, CP0_CONFIG, 1 55245a7868SPaul Burton bgez \dest, \nomt 56245a7868SPaul Burton mfc0 \dest, CP0_CONFIG, 2 57245a7868SPaul Burton bgez \dest, \nomt 58245a7868SPaul Burton mfc0 \dest, CP0_CONFIG, 3 59245a7868SPaul Burton andi \dest, \dest, MIPS_CONF3_MT 60245a7868SPaul Burton beqz \dest, \nomt 611e5fb282SPaul Burton nop 62245a7868SPaul Burton .endm 630ee958e1SPaul Burton 645a3e7c02SPaul Burton /* 655a3e7c02SPaul Burton * Set dest to non-zero if the core supports MIPSr6 multithreading 665a3e7c02SPaul Burton * (ie. VPs), else zero. If MIPSr6 multithreading is not supported then 675a3e7c02SPaul Burton * branch to nomt. 685a3e7c02SPaul Burton */ 695a3e7c02SPaul Burton .macro has_vp dest, nomt 705a3e7c02SPaul Burton mfc0 \dest, CP0_CONFIG, 1 715a3e7c02SPaul Burton bgez \dest, \nomt 725a3e7c02SPaul Burton mfc0 \dest, CP0_CONFIG, 2 735a3e7c02SPaul Burton bgez \dest, \nomt 745a3e7c02SPaul Burton mfc0 \dest, CP0_CONFIG, 3 755a3e7c02SPaul Burton bgez \dest, \nomt 765a3e7c02SPaul Burton mfc0 \dest, CP0_CONFIG, 4 775a3e7c02SPaul Burton bgez \dest, \nomt 785a3e7c02SPaul Burton mfc0 \dest, CP0_CONFIG, 5 795a3e7c02SPaul Burton andi \dest, \dest, MIPS_CONF5_VP 805a3e7c02SPaul Burton beqz \dest, \nomt 815a3e7c02SPaul Burton nop 825a3e7c02SPaul Burton .endm 835a3e7c02SPaul Burton 84f12401d7SPaul Burton 850ee958e1SPaul Burton.balign 0x1000 860ee958e1SPaul Burton 870ee958e1SPaul BurtonLEAF(mips_cps_core_entry) 880ee958e1SPaul Burton /* 89fea8826dSJiaxun Yang * These first several instructions will be patched by cps_smp_setup to load the 90fea8826dSJiaxun Yang * CCA to use into register s0 and GCR base address to register s1. 910ee958e1SPaul Burton */ 92fea8826dSJiaxun Yang .rept CPS_ENTRY_PATCH_INSNS 93fea8826dSJiaxun Yang nop 94fea8826dSJiaxun Yang .endr 95fea8826dSJiaxun Yang 96fea8826dSJiaxun Yang .global mips_cps_core_entry_patch_end 97fea8826dSJiaxun Yangmips_cps_core_entry_patch_end: 980ee958e1SPaul Burton 990ee958e1SPaul Burton /* Check whether we're here due to an NMI */ 1000ee958e1SPaul Burton mfc0 k0, CP0_STATUS 1010ee958e1SPaul Burton and k0, k0, ST0_NMI 1020ee958e1SPaul Burton beqz k0, not_nmi 1030ee958e1SPaul Burton nop 1040ee958e1SPaul Burton 1050ee958e1SPaul Burton /* This is an NMI */ 10681a02e34SMarkos Chandras PTR_LA k0, nmi_handler 1070ee958e1SPaul Burton jr k0 1080ee958e1SPaul Burton nop 1090ee958e1SPaul Burton 1100ee958e1SPaul Burtonnot_nmi: 1110ee958e1SPaul Burton /* Setup Cause */ 1120ee958e1SPaul Burton li t0, CAUSEF_IV 1130ee958e1SPaul Burton mtc0 t0, CP0_CAUSE 1140ee958e1SPaul Burton 1150ee958e1SPaul Burton /* Setup Status */ 1168fe2c547SPaul Burton li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS 1170ee958e1SPaul Burton mtc0 t0, CP0_STATUS 1180ee958e1SPaul Burton 119*aa45787cSJiaxun Yang /* We don't know how to do coherence setup on earlier ISA */ 120*aa45787cSJiaxun Yang#if MIPS_ISA_REV > 0 12187a70bcdSPaul Burton /* Skip cache & coherence setup if we're already coherent */ 122fea8826dSJiaxun Yang lw s7, GCR_CL_COHERENCE_OFS(s1) 12387a70bcdSPaul Burton bnez s7, 1f 12487a70bcdSPaul Burton nop 12587a70bcdSPaul Burton 1263dbc9971SPaul Burton /* Initialize the L1 caches */ 1273dbc9971SPaul Burton jal mips_cps_cache_init 1280ee958e1SPaul Burton nop 1290ee958e1SPaul Burton 13087a70bcdSPaul Burton /* Enter the coherent domain */ 13187a70bcdSPaul Burton li t0, 0xff 132fea8826dSJiaxun Yang sw t0, GCR_CL_COHERENCE_OFS(s1) 13387a70bcdSPaul Burton ehb 134*aa45787cSJiaxun Yang#endif /* MIPS_ISA_REV > 0 */ 13587a70bcdSPaul Burton 1360155a065SPaul Burton /* Set Kseg0 CCA to that in s0 */ 13787a70bcdSPaul Burton1: mfc0 t0, CP0_CONFIG 1380ee958e1SPaul Burton ori t0, 0x7 1390155a065SPaul Burton xori t0, 0x7 1400155a065SPaul Burton or t0, t0, s0 1410ee958e1SPaul Burton mtc0 t0, CP0_CONFIG 1420ee958e1SPaul Burton ehb 1430ee958e1SPaul Burton 1440ee958e1SPaul Burton /* Jump to kseg0 */ 14581a02e34SMarkos Chandras PTR_LA t0, 1f 1460ee958e1SPaul Burton jr t0 1470ee958e1SPaul Burton nop 1480ee958e1SPaul Burton 149245a7868SPaul Burton /* 15087a70bcdSPaul Burton * We're up, cached & coherent. Perform any EVA initialization necessary 15187a70bcdSPaul Burton * before we access memory. 152245a7868SPaul Burton */ 15387a70bcdSPaul Burton1: eva_init 1546521d9a4SMarkos Chandras 155f12401d7SPaul Burton /* Retrieve boot configuration pointers */ 156f12401d7SPaul Burton jal mips_cps_get_bootcfg 157f12401d7SPaul Burton nop 158f12401d7SPaul Burton 15987a70bcdSPaul Burton /* Skip core-level init if we started up coherent */ 16087a70bcdSPaul Burton bnez s7, 1f 16187a70bcdSPaul Burton nop 16287a70bcdSPaul Burton 16387a70bcdSPaul Burton /* Perform any further required core-level initialisation */ 16487a70bcdSPaul Burton jal mips_cps_core_init 16587a70bcdSPaul Burton nop 16687a70bcdSPaul Burton 1670ee958e1SPaul Burton /* 168245a7868SPaul Burton * Boot any other VPEs within this core that should be online, and 169245a7868SPaul Burton * deactivate this VPE if it should be offline. 1700ee958e1SPaul Burton */ 171f12401d7SPaul Burton move a1, t9 172245a7868SPaul Burton jal mips_cps_boot_vpes 173f12401d7SPaul Burton move a0, v0 1740ee958e1SPaul Burton 1750ee958e1SPaul Burton /* Off we go! */ 17687a70bcdSPaul Burton1: PTR_L t1, VPEBOOTCFG_PC(v1) 177f12401d7SPaul Burton PTR_L gp, VPEBOOTCFG_GP(v1) 178f12401d7SPaul Burton PTR_L sp, VPEBOOTCFG_SP(v1) 1790ee958e1SPaul Burton jr t1 1800ee958e1SPaul Burton nop 1810ee958e1SPaul Burton END(mips_cps_core_entry) 1820ee958e1SPaul Burton 1830ee958e1SPaul Burton.org 0x200 1840ee958e1SPaul BurtonLEAF(excep_tlbfill) 185609cf6f2SPaul Burton DUMP_EXCEP("TLB Fill") 1860ee958e1SPaul Burton b . 1870ee958e1SPaul Burton nop 1880ee958e1SPaul Burton END(excep_tlbfill) 1890ee958e1SPaul Burton 1900ee958e1SPaul Burton.org 0x280 1910ee958e1SPaul BurtonLEAF(excep_xtlbfill) 192609cf6f2SPaul Burton DUMP_EXCEP("XTLB Fill") 1930ee958e1SPaul Burton b . 1940ee958e1SPaul Burton nop 1950ee958e1SPaul Burton END(excep_xtlbfill) 1960ee958e1SPaul Burton 1970ee958e1SPaul Burton.org 0x300 1980ee958e1SPaul BurtonLEAF(excep_cache) 199609cf6f2SPaul Burton DUMP_EXCEP("Cache") 2000ee958e1SPaul Burton b . 2010ee958e1SPaul Burton nop 2020ee958e1SPaul Burton END(excep_cache) 2030ee958e1SPaul Burton 2040ee958e1SPaul Burton.org 0x380 2050ee958e1SPaul BurtonLEAF(excep_genex) 206609cf6f2SPaul Burton DUMP_EXCEP("General") 2070ee958e1SPaul Burton b . 2080ee958e1SPaul Burton nop 2090ee958e1SPaul Burton END(excep_genex) 2100ee958e1SPaul Burton 2110ee958e1SPaul Burton.org 0x400 2120ee958e1SPaul BurtonLEAF(excep_intex) 213609cf6f2SPaul Burton DUMP_EXCEP("Interrupt") 2140ee958e1SPaul Burton b . 2150ee958e1SPaul Burton nop 2160ee958e1SPaul Burton END(excep_intex) 2170ee958e1SPaul Burton 2180ee958e1SPaul Burton.org 0x480 2190ee958e1SPaul BurtonLEAF(excep_ejtag) 22081a02e34SMarkos Chandras PTR_LA k0, ejtag_debug_handler 2210ee958e1SPaul Burton jr k0 2220ee958e1SPaul Burton nop 2230ee958e1SPaul Burton END(excep_ejtag) 224245a7868SPaul Burton 225245a7868SPaul BurtonLEAF(mips_cps_core_init) 2267a63076dSPaul Burton#ifdef CONFIG_MIPS_MT_SMP 227245a7868SPaul Burton /* Check that the core implements the MT ASE */ 228245a7868SPaul Burton has_mt t0, 3f 229245a7868SPaul Burton 230245a7868SPaul Burton .set push 23117278a91SJames Hogan .set MIPS_ISA_LEVEL_RAW 232245a7868SPaul Burton .set mt 233245a7868SPaul Burton 234245a7868SPaul Burton /* Only allow 1 TC per VPE to execute... */ 235245a7868SPaul Burton dmt 236245a7868SPaul Burton 237245a7868SPaul Burton /* ...and for the moment only 1 VPE */ 238245a7868SPaul Burton dvpe 23981a02e34SMarkos Chandras PTR_LA t1, 1f 240245a7868SPaul Burton jr.hb t1 241245a7868SPaul Burton nop 242245a7868SPaul Burton 243245a7868SPaul Burton /* Enter VPE configuration state */ 244245a7868SPaul Burton1: mfc0 t0, CP0_MVPCONTROL 245245a7868SPaul Burton ori t0, t0, MVPCONTROL_VPC 246245a7868SPaul Burton mtc0 t0, CP0_MVPCONTROL 247245a7868SPaul Burton 248245a7868SPaul Burton /* Retrieve the number of VPEs within the core */ 249245a7868SPaul Burton mfc0 t0, CP0_MVPCONF0 250245a7868SPaul Burton srl t0, t0, MVPCONF0_PVPE_SHIFT 251245a7868SPaul Burton andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT) 2520586ac75SMarkos Chandras addiu ta3, t0, 1 253245a7868SPaul Burton 254245a7868SPaul Burton /* If there's only 1, we're done */ 255245a7868SPaul Burton beqz t0, 2f 256245a7868SPaul Burton nop 257245a7868SPaul Burton 258245a7868SPaul Burton /* Loop through each VPE within this core */ 2590586ac75SMarkos Chandras li ta1, 1 260245a7868SPaul Burton 261245a7868SPaul Burton1: /* Operate on the appropriate TC */ 2620586ac75SMarkos Chandras mtc0 ta1, CP0_VPECONTROL 263245a7868SPaul Burton ehb 264245a7868SPaul Burton 265245a7868SPaul Burton /* Bind TC to VPE (1:1 TC:VPE mapping) */ 2660586ac75SMarkos Chandras mttc0 ta1, CP0_TCBIND 267245a7868SPaul Burton 268245a7868SPaul Burton /* Set exclusive TC, non-active, master */ 269245a7868SPaul Burton li t0, VPECONF0_MVP 2700586ac75SMarkos Chandras sll t1, ta1, VPECONF0_XTC_SHIFT 271245a7868SPaul Burton or t0, t0, t1 272245a7868SPaul Burton mttc0 t0, CP0_VPECONF0 273245a7868SPaul Burton 274245a7868SPaul Burton /* Set TC non-active, non-allocatable */ 275245a7868SPaul Burton mttc0 zero, CP0_TCSTATUS 276245a7868SPaul Burton 277245a7868SPaul Burton /* Set TC halted */ 278245a7868SPaul Burton li t0, TCHALT_H 279245a7868SPaul Burton mttc0 t0, CP0_TCHALT 280245a7868SPaul Burton 281245a7868SPaul Burton /* Next VPE */ 2820586ac75SMarkos Chandras addiu ta1, ta1, 1 2830586ac75SMarkos Chandras slt t0, ta1, ta3 284245a7868SPaul Burton bnez t0, 1b 285245a7868SPaul Burton nop 286245a7868SPaul Burton 287245a7868SPaul Burton /* Leave VPE configuration state */ 288245a7868SPaul Burton2: mfc0 t0, CP0_MVPCONTROL 289245a7868SPaul Burton xori t0, t0, MVPCONTROL_VPC 290245a7868SPaul Burton mtc0 t0, CP0_MVPCONTROL 291245a7868SPaul Burton 292245a7868SPaul Burton3: .set pop 293245a7868SPaul Burton#endif 294245a7868SPaul Burton jr ra 295245a7868SPaul Burton nop 296245a7868SPaul Burton END(mips_cps_core_init) 297245a7868SPaul Burton 298f12401d7SPaul Burton/** 299f12401d7SPaul Burton * mips_cps_get_bootcfg() - retrieve boot configuration pointers 300f12401d7SPaul Burton * 301f12401d7SPaul Burton * Returns: pointer to struct core_boot_config in v0, pointer to 302f12401d7SPaul Burton * struct vpe_boot_config in v1, VPE ID in t9 303f12401d7SPaul Burton */ 304f12401d7SPaul BurtonLEAF(mips_cps_get_bootcfg) 305245a7868SPaul Burton /* Calculate a pointer to this cores struct core_boot_config */ 306fea8826dSJiaxun Yang lw t0, GCR_CL_ID_OFS(s1) 307245a7868SPaul Burton li t1, COREBOOTCFG_SIZE 308245a7868SPaul Burton mul t0, t0, t1 30981a02e34SMarkos Chandras PTR_LA t1, mips_cps_core_bootcfg 310b677bc03SMarkos Chandras PTR_L t1, 0(t1) 311f12401d7SPaul Burton PTR_ADDU v0, t0, t1 312245a7868SPaul Burton 313245a7868SPaul Burton /* Calculate this VPEs ID. If the core doesn't support MT use 0 */ 314245a7868SPaul Burton li t9, 0 3155a3e7c02SPaul Burton#if defined(CONFIG_CPU_MIPSR6) 3165a3e7c02SPaul Burton has_vp ta2, 1f 3175a3e7c02SPaul Burton 3185a3e7c02SPaul Burton /* 3195a3e7c02SPaul Burton * Assume non-contiguous numbering. Perhaps some day we'll need 3205a3e7c02SPaul Burton * to handle contiguous VP numbering, but no such systems yet 3215a3e7c02SPaul Burton * exist. 3225a3e7c02SPaul Burton */ 32315e6529fSPaul Burton mfc0 t9, CP0_GLOBALNUMBER 32415e6529fSPaul Burton andi t9, t9, MIPS_GLOBALNUMBER_VP 3255a3e7c02SPaul Burton#elif defined(CONFIG_MIPS_MT_SMP) 3261e5fb282SPaul Burton has_mt ta2, 1f 327245a7868SPaul Burton 328245a7868SPaul Burton /* Find the number of VPEs present in the core */ 329245a7868SPaul Burton mfc0 t1, CP0_MVPCONF0 330245a7868SPaul Burton srl t1, t1, MVPCONF0_PVPE_SHIFT 331245a7868SPaul Burton andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT 332acac4108SMarkos Chandras addiu t1, t1, 1 333245a7868SPaul Burton 334245a7868SPaul Burton /* Calculate a mask for the VPE ID from EBase.CPUNum */ 335245a7868SPaul Burton clz t1, t1 336245a7868SPaul Burton li t2, 31 337245a7868SPaul Burton subu t1, t2, t1 338245a7868SPaul Burton li t2, 1 339245a7868SPaul Burton sll t1, t2, t1 340245a7868SPaul Burton addiu t1, t1, -1 341245a7868SPaul Burton 342245a7868SPaul Burton /* Retrieve the VPE ID from EBase.CPUNum */ 343245a7868SPaul Burton mfc0 t9, $15, 1 344245a7868SPaul Burton and t9, t9, t1 345a5b0f6dbSPaul Burton#endif 346245a7868SPaul Burton 347245a7868SPaul Burton1: /* Calculate a pointer to this VPEs struct vpe_boot_config */ 348245a7868SPaul Burton li t1, VPEBOOTCFG_SIZE 349f12401d7SPaul Burton mul v1, t9, t1 350f12401d7SPaul Burton PTR_L ta3, COREBOOTCFG_VPECONFIG(v0) 351f12401d7SPaul Burton PTR_ADDU v1, v1, ta3 352245a7868SPaul Burton 353245a7868SPaul Burton jr ra 354245a7868SPaul Burton nop 355f12401d7SPaul Burton END(mips_cps_get_bootcfg) 356f12401d7SPaul Burton 357f12401d7SPaul BurtonLEAF(mips_cps_boot_vpes) 358fb2155e3SMatt Redfearn lw ta2, COREBOOTCFG_VPEMASK(a0) 359f12401d7SPaul Burton PTR_L ta3, COREBOOTCFG_VPECONFIG(a0) 360f12401d7SPaul Burton 3615a3e7c02SPaul Burton#if defined(CONFIG_CPU_MIPSR6) 3625a3e7c02SPaul Burton 3635a3e7c02SPaul Burton has_vp t0, 5f 3645a3e7c02SPaul Burton 3655a3e7c02SPaul Burton /* Find base address of CPC */ 366fea8826dSJiaxun Yang PTR_LA t1, mips_gcr_base 367fea8826dSJiaxun Yang PTR_L t1, 0(t1) 368fea8826dSJiaxun Yang PTR_L t1, GCR_CPC_BASE_OFS(t1) 3695a3e7c02SPaul Burton PTR_LI t2, ~0x7fff 3705a3e7c02SPaul Burton and t1, t1, t2 3715a3e7c02SPaul Burton PTR_LI t2, UNCAC_BASE 3725a3e7c02SPaul Burton PTR_ADD t1, t1, t2 3735a3e7c02SPaul Burton 374fa7a3b4aSPaul Burton /* Start any other VPs that ought to be running */ 3755a3e7c02SPaul Burton PTR_S ta2, CPC_CL_VC_RUN_OFS(t1) 376fa7a3b4aSPaul Burton 377fa7a3b4aSPaul Burton /* Ensure this VP stops running if it shouldn't be */ 378fa7a3b4aSPaul Burton not ta2 379fa7a3b4aSPaul Burton PTR_S ta2, CPC_CL_VC_STOP_OFS(t1) 3805a3e7c02SPaul Burton ehb 3815a3e7c02SPaul Burton 3825a3e7c02SPaul Burton#elif defined(CONFIG_MIPS_MT) 383245a7868SPaul Burton 384f12401d7SPaul Burton /* If the core doesn't support MT then return */ 385f12401d7SPaul Burton has_mt t0, 5f 386f12401d7SPaul Burton 387f12401d7SPaul Burton /* Enter VPE configuration state */ 3888dbc1864SJames Hogan .set push 3898dbc1864SJames Hogan .set MIPS_ISA_LEVEL_RAW 3908dbc1864SJames Hogan .set mt 391245a7868SPaul Burton dvpe 3928dbc1864SJames Hogan .set pop 3938dbc1864SJames Hogan 39481a02e34SMarkos Chandras PTR_LA t1, 1f 395245a7868SPaul Burton jr.hb t1 396245a7868SPaul Burton nop 397245a7868SPaul Burton1: mfc0 t1, CP0_MVPCONTROL 398245a7868SPaul Burton ori t1, t1, MVPCONTROL_VPC 399245a7868SPaul Burton mtc0 t1, CP0_MVPCONTROL 400245a7868SPaul Burton ehb 401245a7868SPaul Burton 402245a7868SPaul Burton /* Loop through each VPE */ 4030586ac75SMarkos Chandras move t8, ta2 4040586ac75SMarkos Chandras li ta1, 0 405245a7868SPaul Burton 406245a7868SPaul Burton /* Check whether the VPE should be running. If not, skip it */ 4070586ac75SMarkos Chandras1: andi t0, ta2, 1 408245a7868SPaul Burton beqz t0, 2f 409245a7868SPaul Burton nop 410245a7868SPaul Burton 411245a7868SPaul Burton /* Operate on the appropriate TC */ 412245a7868SPaul Burton mfc0 t0, CP0_VPECONTROL 413245a7868SPaul Burton ori t0, t0, VPECONTROL_TARGTC 414245a7868SPaul Burton xori t0, t0, VPECONTROL_TARGTC 4150586ac75SMarkos Chandras or t0, t0, ta1 416245a7868SPaul Burton mtc0 t0, CP0_VPECONTROL 417245a7868SPaul Burton ehb 418245a7868SPaul Burton 4198dbc1864SJames Hogan .set push 4208dbc1864SJames Hogan .set MIPS_ISA_LEVEL_RAW 4218dbc1864SJames Hogan .set mt 4228dbc1864SJames Hogan 423245a7868SPaul Burton /* Skip the VPE if its TC is not halted */ 424245a7868SPaul Burton mftc0 t0, CP0_TCHALT 425245a7868SPaul Burton beqz t0, 2f 426245a7868SPaul Burton nop 427245a7868SPaul Burton 428245a7868SPaul Burton /* Calculate a pointer to the VPEs struct vpe_boot_config */ 429245a7868SPaul Burton li t0, VPEBOOTCFG_SIZE 4300586ac75SMarkos Chandras mul t0, t0, ta1 4310586ac75SMarkos Chandras addu t0, t0, ta3 432245a7868SPaul Burton 433245a7868SPaul Burton /* Set the TC restart PC */ 434245a7868SPaul Burton lw t1, VPEBOOTCFG_PC(t0) 435245a7868SPaul Burton mttc0 t1, CP0_TCRESTART 436245a7868SPaul Burton 437245a7868SPaul Burton /* Set the TC stack pointer */ 438245a7868SPaul Burton lw t1, VPEBOOTCFG_SP(t0) 439245a7868SPaul Burton mttgpr t1, sp 440245a7868SPaul Burton 441245a7868SPaul Burton /* Set the TC global pointer */ 442245a7868SPaul Burton lw t1, VPEBOOTCFG_GP(t0) 443245a7868SPaul Burton mttgpr t1, gp 444245a7868SPaul Burton 445245a7868SPaul Burton /* Copy config from this VPE */ 446245a7868SPaul Burton mfc0 t0, CP0_CONFIG 447245a7868SPaul Burton mttc0 t0, CP0_CONFIG 448245a7868SPaul Burton 44963a8802fSMatt Redfearn /* 45063a8802fSMatt Redfearn * Copy the EVA config from this VPE if the CPU supports it. 45163a8802fSMatt Redfearn * CONFIG3 must exist to be running MT startup - just read it. 45263a8802fSMatt Redfearn */ 45363a8802fSMatt Redfearn mfc0 t0, CP0_CONFIG, 3 45463a8802fSMatt Redfearn and t0, t0, MIPS_CONF3_SC 45563a8802fSMatt Redfearn beqz t0, 3f 45663a8802fSMatt Redfearn nop 45763a8802fSMatt Redfearn mfc0 t0, CP0_SEGCTL0 45863a8802fSMatt Redfearn mttc0 t0, CP0_SEGCTL0 45963a8802fSMatt Redfearn mfc0 t0, CP0_SEGCTL1 46063a8802fSMatt Redfearn mttc0 t0, CP0_SEGCTL1 46163a8802fSMatt Redfearn mfc0 t0, CP0_SEGCTL2 46263a8802fSMatt Redfearn mttc0 t0, CP0_SEGCTL2 46363a8802fSMatt Redfearn3: 464245a7868SPaul Burton /* Ensure no software interrupts are pending */ 465245a7868SPaul Burton mttc0 zero, CP0_CAUSE 466245a7868SPaul Burton mttc0 zero, CP0_STATUS 467245a7868SPaul Burton 468245a7868SPaul Burton /* Set TC active, not interrupt exempt */ 469245a7868SPaul Burton mftc0 t0, CP0_TCSTATUS 470245a7868SPaul Burton li t1, ~TCSTATUS_IXMT 471245a7868SPaul Burton and t0, t0, t1 472245a7868SPaul Burton ori t0, t0, TCSTATUS_A 473245a7868SPaul Burton mttc0 t0, CP0_TCSTATUS 474245a7868SPaul Burton 475245a7868SPaul Burton /* Clear the TC halt bit */ 476245a7868SPaul Burton mttc0 zero, CP0_TCHALT 477245a7868SPaul Burton 478245a7868SPaul Burton /* Set VPE active */ 479245a7868SPaul Burton mftc0 t0, CP0_VPECONF0 480245a7868SPaul Burton ori t0, t0, VPECONF0_VPA 481245a7868SPaul Burton mttc0 t0, CP0_VPECONF0 482245a7868SPaul Burton 483245a7868SPaul Burton /* Next VPE */ 4840586ac75SMarkos Chandras2: srl ta2, ta2, 1 4850586ac75SMarkos Chandras addiu ta1, ta1, 1 4860586ac75SMarkos Chandras bnez ta2, 1b 487245a7868SPaul Burton nop 488245a7868SPaul Burton 489245a7868SPaul Burton /* Leave VPE configuration state */ 490245a7868SPaul Burton mfc0 t1, CP0_MVPCONTROL 491245a7868SPaul Burton xori t1, t1, MVPCONTROL_VPC 492245a7868SPaul Burton mtc0 t1, CP0_MVPCONTROL 493245a7868SPaul Burton ehb 494245a7868SPaul Burton evpe 495245a7868SPaul Burton 4968dbc1864SJames Hogan .set pop 4978dbc1864SJames Hogan 498245a7868SPaul Burton /* Check whether this VPE is meant to be running */ 499245a7868SPaul Burton li t0, 1 500f12401d7SPaul Burton sll t0, t0, a1 501245a7868SPaul Burton and t0, t0, t8 502245a7868SPaul Burton bnez t0, 2f 503245a7868SPaul Burton nop 504245a7868SPaul Burton 505245a7868SPaul Burton /* This VPE should be offline, halt the TC */ 506245a7868SPaul Burton li t0, TCHALT_H 507245a7868SPaul Burton mtc0 t0, CP0_TCHALT 50881a02e34SMarkos Chandras PTR_LA t0, 1f 509245a7868SPaul Burton1: jr.hb t0 510245a7868SPaul Burton nop 511245a7868SPaul Burton 5128dbc1864SJames Hogan2: 513245a7868SPaul Burton 5147a63076dSPaul Burton#endif /* CONFIG_MIPS_MT_SMP */ 515245a7868SPaul Burton 516245a7868SPaul Burton /* Return */ 517f12401d7SPaul Burton5: jr ra 518245a7868SPaul Burton nop 519245a7868SPaul Burton END(mips_cps_boot_vpes) 5203179d37eSPaul Burton 521*aa45787cSJiaxun Yang#if MIPS_ISA_REV > 0 5223dbc9971SPaul BurtonLEAF(mips_cps_cache_init) 5233dbc9971SPaul Burton /* 5243dbc9971SPaul Burton * Clear the bits used to index the caches. Note that the architecture 5253dbc9971SPaul Burton * dictates that writing to any of TagLo or TagHi selects 0 or 2 should 5263dbc9971SPaul Burton * be valid for all MIPS32 CPUs, even those for which said writes are 5273dbc9971SPaul Burton * unnecessary. 5283dbc9971SPaul Burton */ 5293dbc9971SPaul Burton mtc0 zero, CP0_TAGLO, 0 5303dbc9971SPaul Burton mtc0 zero, CP0_TAGHI, 0 5313dbc9971SPaul Burton mtc0 zero, CP0_TAGLO, 2 5323dbc9971SPaul Burton mtc0 zero, CP0_TAGHI, 2 5333dbc9971SPaul Burton ehb 5343dbc9971SPaul Burton 5353dbc9971SPaul Burton /* Primary cache configuration is indicated by Config1 */ 5363dbc9971SPaul Burton mfc0 v0, CP0_CONFIG, 1 5373dbc9971SPaul Burton 5383dbc9971SPaul Burton /* Detect I-cache line size */ 5393dbc9971SPaul Burton _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ 5403dbc9971SPaul Burton beqz t0, icache_done 5413dbc9971SPaul Burton li t1, 2 5423dbc9971SPaul Burton sllv t0, t1, t0 5433dbc9971SPaul Burton 5443dbc9971SPaul Burton /* Detect I-cache size */ 5453dbc9971SPaul Burton _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ 5463dbc9971SPaul Burton xori t2, t1, 0x7 5473dbc9971SPaul Burton beqz t2, 1f 5483dbc9971SPaul Burton li t3, 32 5493dbc9971SPaul Burton addiu t1, t1, 1 5503dbc9971SPaul Burton sllv t1, t3, t1 5513dbc9971SPaul Burton1: /* At this point t1 == I-cache sets per way */ 5523dbc9971SPaul Burton _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ 5533dbc9971SPaul Burton addiu t2, t2, 1 5543dbc9971SPaul Burton mul t1, t1, t0 5553dbc9971SPaul Burton mul t1, t1, t2 5563dbc9971SPaul Burton 5573dbc9971SPaul Burton li a0, CKSEG0 5583dbc9971SPaul Burton PTR_ADD a1, a0, t1 5593dbc9971SPaul Burton1: cache Index_Store_Tag_I, 0(a0) 5603dbc9971SPaul Burton PTR_ADD a0, a0, t0 5613dbc9971SPaul Burton bne a0, a1, 1b 5623dbc9971SPaul Burton nop 5633dbc9971SPaul Burtonicache_done: 5643dbc9971SPaul Burton 5653dbc9971SPaul Burton /* Detect D-cache line size */ 5663dbc9971SPaul Burton _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ 5673dbc9971SPaul Burton beqz t0, dcache_done 5683dbc9971SPaul Burton li t1, 2 5693dbc9971SPaul Burton sllv t0, t1, t0 5703dbc9971SPaul Burton 5713dbc9971SPaul Burton /* Detect D-cache size */ 5723dbc9971SPaul Burton _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ 5733dbc9971SPaul Burton xori t2, t1, 0x7 5743dbc9971SPaul Burton beqz t2, 1f 5753dbc9971SPaul Burton li t3, 32 5763dbc9971SPaul Burton addiu t1, t1, 1 5773dbc9971SPaul Burton sllv t1, t3, t1 5783dbc9971SPaul Burton1: /* At this point t1 == D-cache sets per way */ 5793dbc9971SPaul Burton _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ 5803dbc9971SPaul Burton addiu t2, t2, 1 5813dbc9971SPaul Burton mul t1, t1, t0 5823dbc9971SPaul Burton mul t1, t1, t2 5833dbc9971SPaul Burton 5843dbc9971SPaul Burton li a0, CKSEG0 5853dbc9971SPaul Burton PTR_ADDU a1, a0, t1 5863dbc9971SPaul Burton PTR_SUBU a1, a1, t0 5873dbc9971SPaul Burton1: cache Index_Store_Tag_D, 0(a0) 5883dbc9971SPaul Burton bne a0, a1, 1b 5893dbc9971SPaul Burton PTR_ADD a0, a0, t0 5903dbc9971SPaul Burtondcache_done: 5913dbc9971SPaul Burton 5923dbc9971SPaul Burton jr ra 5933dbc9971SPaul Burton nop 5943dbc9971SPaul Burton END(mips_cps_cache_init) 595*aa45787cSJiaxun Yang#endif /* MIPS_ISA_REV > 0 */ 5963dbc9971SPaul Burton 5973179d37eSPaul Burton#if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM) 5983179d37eSPaul Burton 5993179d37eSPaul Burton /* Calculate a pointer to this CPUs struct mips_static_suspend_state */ 6003179d37eSPaul Burton .macro psstate dest 6013179d37eSPaul Burton .set push 6023179d37eSPaul Burton .set noat 6033179d37eSPaul Burton lw $1, TI_CPU(gp) 6043179d37eSPaul Burton sll $1, $1, LONGLOG 60581a02e34SMarkos Chandras PTR_LA \dest, __per_cpu_offset 6063179d37eSPaul Burton addu $1, $1, \dest 6073179d37eSPaul Burton lw $1, 0($1) 60881a02e34SMarkos Chandras PTR_LA \dest, cps_cpu_state 6093179d37eSPaul Burton addu \dest, \dest, $1 6103179d37eSPaul Burton .set pop 6113179d37eSPaul Burton .endm 6123179d37eSPaul Burton 6133179d37eSPaul BurtonLEAF(mips_cps_pm_save) 6143179d37eSPaul Burton /* Save CPU state */ 6153179d37eSPaul Burton SUSPEND_SAVE_REGS 6163179d37eSPaul Burton psstate t1 6173179d37eSPaul Burton SUSPEND_SAVE_STATIC 6183179d37eSPaul Burton jr v0 6193179d37eSPaul Burton nop 6203179d37eSPaul Burton END(mips_cps_pm_save) 6213179d37eSPaul Burton 6223179d37eSPaul BurtonLEAF(mips_cps_pm_restore) 6233179d37eSPaul Burton /* Restore CPU state */ 6243179d37eSPaul Burton psstate t1 6253179d37eSPaul Burton RESUME_RESTORE_STATIC 6263179d37eSPaul Burton RESUME_RESTORE_REGS_RETURN 6273179d37eSPaul Burton END(mips_cps_pm_restore) 6283179d37eSPaul Burton 6293179d37eSPaul Burton#endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */ 630