1 /* SPDX-License-Identifier: GPL-2.0-or-later * 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 2 /* 3 * Copyright (C) 2013 Imagination Technologies 3 * Copyright (C) 2013 Imagination Technologies 4 * Author: Paul Burton <paul.burton@mips.com> 4 * Author: Paul Burton <paul.burton@mips.com> 5 */ 5 */ 6 6 7 #include <linux/init.h> << 8 #include <asm/addrspace.h> 7 #include <asm/addrspace.h> 9 #include <asm/asm.h> 8 #include <asm/asm.h> 10 #include <asm/asm-offsets.h> 9 #include <asm/asm-offsets.h> 11 #include <asm/asmmacro.h> 10 #include <asm/asmmacro.h> 12 #include <asm/cacheops.h> 11 #include <asm/cacheops.h> 13 #include <asm/eva.h> 12 #include <asm/eva.h> 14 #include <asm/mipsregs.h> 13 #include <asm/mipsregs.h> 15 #include <asm/mipsmtregs.h> 14 #include <asm/mipsmtregs.h> 16 #include <asm/pm.h> 15 #include <asm/pm.h> 17 #include <asm/smp-cps.h> 16 #include <asm/smp-cps.h> 18 17 19 #define GCR_CPC_BASE_OFS 0x0088 18 #define GCR_CPC_BASE_OFS 0x0088 20 #define GCR_CL_COHERENCE_OFS 0x2008 19 #define GCR_CL_COHERENCE_OFS 0x2008 21 #define GCR_CL_ID_OFS 0x2028 20 #define GCR_CL_ID_OFS 0x2028 22 21 23 #define CPC_CL_VC_STOP_OFS 0x2020 22 #define CPC_CL_VC_STOP_OFS 0x2020 24 #define CPC_CL_VC_RUN_OFS 0x2028 23 #define CPC_CL_VC_RUN_OFS 0x2028 25 24 26 .extern mips_cm_base 25 .extern mips_cm_base 27 26 28 .set noreorder 27 .set noreorder 29 28 30 #ifdef CONFIG_64BIT 29 #ifdef CONFIG_64BIT 31 # define STATUS_BITDEPS ST0_KX 30 # define STATUS_BITDEPS ST0_KX 32 #else 31 #else 33 # define STATUS_BITDEPS 0 32 # define STATUS_BITDEPS 0 34 #endif 33 #endif 35 34 36 #ifdef CONFIG_MIPS_CPS_NS16550 35 #ifdef CONFIG_MIPS_CPS_NS16550 37 36 38 #define DUMP_EXCEP(name) \ 37 #define DUMP_EXCEP(name) \ 39 PTR_LA a0, 8f; \ 38 PTR_LA a0, 8f; \ 40 jal mips_cps_bev_dump; \ 39 jal mips_cps_bev_dump; \ 41 nop; \ 40 nop; \ 42 TEXT(name) 41 TEXT(name) 43 42 44 #else /* !CONFIG_MIPS_CPS_NS16550 */ 43 #else /* !CONFIG_MIPS_CPS_NS16550 */ 45 44 46 #define DUMP_EXCEP(name) 45 #define DUMP_EXCEP(name) 47 46 48 #endif /* !CONFIG_MIPS_CPS_NS16550 */ 47 #endif /* !CONFIG_MIPS_CPS_NS16550 */ 49 48 50 /* 49 /* 51 * Set dest to non-zero if the core su 50 * Set dest to non-zero if the core supports the MT ASE, else zero. If 52 * MT is not supported then branch to 51 * MT is not supported then branch to nomt. 53 */ 52 */ 54 .macro has_mt dest, nomt 53 .macro has_mt dest, nomt 55 mfc0 \dest, CP0_CONFIG, 1 54 mfc0 \dest, CP0_CONFIG, 1 56 bgez \dest, \nomt 55 bgez \dest, \nomt 57 mfc0 \dest, CP0_CONFIG, 2 56 mfc0 \dest, CP0_CONFIG, 2 58 bgez \dest, \nomt 57 bgez \dest, \nomt 59 mfc0 \dest, CP0_CONFIG, 3 58 mfc0 \dest, CP0_CONFIG, 3 60 andi \dest, \dest, MIPS_CONF3_MT 59 andi \dest, \dest, MIPS_CONF3_MT 61 beqz \dest, \nomt 60 beqz \dest, \nomt 62 nop 61 nop 63 .endm 62 .endm 64 63 65 /* 64 /* 66 * Set dest to non-zero if the core su 65 * Set dest to non-zero if the core supports MIPSr6 multithreading 67 * (ie. VPs), else zero. If MIPSr6 mul 66 * (ie. VPs), else zero. If MIPSr6 multithreading is not supported then 68 * branch to nomt. 67 * branch to nomt. 69 */ 68 */ 70 .macro has_vp dest, nomt 69 .macro has_vp dest, nomt 71 mfc0 \dest, CP0_CONFIG, 1 70 mfc0 \dest, CP0_CONFIG, 1 72 bgez \dest, \nomt 71 bgez \dest, \nomt 73 mfc0 \dest, CP0_CONFIG, 2 72 mfc0 \dest, CP0_CONFIG, 2 74 bgez \dest, \nomt 73 bgez \dest, \nomt 75 mfc0 \dest, CP0_CONFIG, 3 74 mfc0 \dest, CP0_CONFIG, 3 76 bgez \dest, \nomt 75 bgez \dest, \nomt 77 mfc0 \dest, CP0_CONFIG, 4 76 mfc0 \dest, CP0_CONFIG, 4 78 bgez \dest, \nomt 77 bgez \dest, \nomt 79 mfc0 \dest, CP0_CONFIG, 5 78 mfc0 \dest, CP0_CONFIG, 5 80 andi \dest, \dest, MIPS_CONF5_VP 79 andi \dest, \dest, MIPS_CONF5_VP 81 beqz \dest, \nomt 80 beqz \dest, \nomt 82 nop 81 nop 83 .endm 82 .endm 84 83 85 84 86 LEAF(mips_cps_core_boot) !! 85 .balign 0x1000 87 /* Save CCA and GCR base */ !! 86 88 move s0, a0 !! 87 LEAF(mips_cps_core_entry) 89 move s1, a1 !! 88 /* >> 89 * These first several instructions will be patched by cps_smp_setup to load the >> 90 * CCA to use into register s0 and GCR base address to register s1. >> 91 */ >> 92 .rept CPS_ENTRY_PATCH_INSNS >> 93 nop >> 94 .endr >> 95 >> 96 .global mips_cps_core_entry_patch_end >> 97 mips_cps_core_entry_patch_end: >> 98 >> 99 /* Check whether we're here due to an NMI */ >> 100 mfc0 k0, CP0_STATUS >> 101 and k0, k0, ST0_NMI >> 102 beqz k0, not_nmi >> 103 nop >> 104 >> 105 /* This is an NMI */ >> 106 PTR_LA k0, nmi_handler >> 107 jr k0 >> 108 nop >> 109 >> 110 not_nmi: >> 111 /* Setup Cause */ >> 112 li t0, CAUSEF_IV >> 113 mtc0 t0, CP0_CAUSE >> 114 >> 115 /* Setup Status */ >> 116 li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS >> 117 mtc0 t0, CP0_STATUS 90 118 91 /* We don't know how to do coherence s 119 /* We don't know how to do coherence setup on earlier ISA */ 92 #if MIPS_ISA_REV > 0 120 #if MIPS_ISA_REV > 0 93 /* Skip cache & coherence setup if we' 121 /* Skip cache & coherence setup if we're already coherent */ 94 lw s7, GCR_CL_COHERENCE_OFS(s1) 122 lw s7, GCR_CL_COHERENCE_OFS(s1) 95 bnez s7, 1f 123 bnez s7, 1f 96 nop 124 nop 97 125 98 /* Initialize the L1 caches */ 126 /* Initialize the L1 caches */ 99 jal mips_cps_cache_init 127 jal mips_cps_cache_init 100 nop 128 nop 101 129 102 /* Enter the coherent domain */ 130 /* Enter the coherent domain */ 103 li t0, 0xff 131 li t0, 0xff 104 sw t0, GCR_CL_COHERENCE_OFS(s1) 132 sw t0, GCR_CL_COHERENCE_OFS(s1) 105 ehb 133 ehb 106 #endif /* MIPS_ISA_REV > 0 */ 134 #endif /* MIPS_ISA_REV > 0 */ 107 135 108 /* Set Kseg0 CCA to that in s0 */ 136 /* Set Kseg0 CCA to that in s0 */ 109 1: mfc0 t0, CP0_CONFIG 137 1: mfc0 t0, CP0_CONFIG 110 ori t0, 0x7 138 ori t0, 0x7 111 xori t0, 0x7 139 xori t0, 0x7 112 or t0, t0, s0 140 or t0, t0, s0 113 mtc0 t0, CP0_CONFIG 141 mtc0 t0, CP0_CONFIG 114 ehb 142 ehb 115 143 116 /* Jump to kseg0 */ 144 /* Jump to kseg0 */ 117 PTR_LA t0, 1f 145 PTR_LA t0, 1f 118 jr t0 146 jr t0 119 nop 147 nop 120 148 121 /* 149 /* 122 * We're up, cached & coherent. Perfor 150 * We're up, cached & coherent. Perform any EVA initialization necessary 123 * before we access memory. 151 * before we access memory. 124 */ 152 */ 125 1: eva_init 153 1: eva_init 126 154 127 /* Retrieve boot configuration pointer 155 /* Retrieve boot configuration pointers */ 128 jal mips_cps_get_bootcfg 156 jal mips_cps_get_bootcfg 129 nop 157 nop 130 158 131 /* Skip core-level init if we started 159 /* Skip core-level init if we started up coherent */ 132 bnez s7, 1f 160 bnez s7, 1f 133 nop 161 nop 134 162 135 /* Perform any further required core-l 163 /* Perform any further required core-level initialisation */ 136 jal mips_cps_core_init 164 jal mips_cps_core_init 137 nop 165 nop 138 166 139 /* 167 /* 140 * Boot any other VPEs within this cor 168 * Boot any other VPEs within this core that should be online, and 141 * deactivate this VPE if it should be 169 * deactivate this VPE if it should be offline. 142 */ 170 */ 143 move a1, t9 171 move a1, t9 144 jal mips_cps_boot_vpes 172 jal mips_cps_boot_vpes 145 move a0, v0 173 move a0, v0 146 174 147 /* Off we go! */ 175 /* Off we go! */ 148 1: PTR_L t1, VPEBOOTCFG_PC(v1) 176 1: PTR_L t1, VPEBOOTCFG_PC(v1) 149 PTR_L gp, VPEBOOTCFG_GP(v1) 177 PTR_L gp, VPEBOOTCFG_GP(v1) 150 PTR_L sp, VPEBOOTCFG_SP(v1) 178 PTR_L sp, VPEBOOTCFG_SP(v1) 151 jr t1 179 jr t1 152 nop 180 nop 153 END(mips_cps_core_boot) !! 181 END(mips_cps_core_entry) 154 182 155 __INIT !! 183 .org 0x200 156 LEAF(excep_tlbfill) 184 LEAF(excep_tlbfill) 157 DUMP_EXCEP("TLB Fill") 185 DUMP_EXCEP("TLB Fill") 158 b . 186 b . 159 nop 187 nop 160 END(excep_tlbfill) 188 END(excep_tlbfill) 161 189 >> 190 .org 0x280 162 LEAF(excep_xtlbfill) 191 LEAF(excep_xtlbfill) 163 DUMP_EXCEP("XTLB Fill") 192 DUMP_EXCEP("XTLB Fill") 164 b . 193 b . 165 nop 194 nop 166 END(excep_xtlbfill) 195 END(excep_xtlbfill) 167 196 >> 197 .org 0x300 168 LEAF(excep_cache) 198 LEAF(excep_cache) 169 DUMP_EXCEP("Cache") 199 DUMP_EXCEP("Cache") 170 b . 200 b . 171 nop 201 nop 172 END(excep_cache) 202 END(excep_cache) 173 203 >> 204 .org 0x380 174 LEAF(excep_genex) 205 LEAF(excep_genex) 175 DUMP_EXCEP("General") 206 DUMP_EXCEP("General") 176 b . 207 b . 177 nop 208 nop 178 END(excep_genex) 209 END(excep_genex) 179 210 >> 211 .org 0x400 180 LEAF(excep_intex) 212 LEAF(excep_intex) 181 DUMP_EXCEP("Interrupt") 213 DUMP_EXCEP("Interrupt") 182 b . 214 b . 183 nop 215 nop 184 END(excep_intex) 216 END(excep_intex) 185 217 >> 218 .org 0x480 186 LEAF(excep_ejtag) 219 LEAF(excep_ejtag) 187 PTR_LA k0, ejtag_debug_handler 220 PTR_LA k0, ejtag_debug_handler 188 jr k0 221 jr k0 189 nop 222 nop 190 END(excep_ejtag) 223 END(excep_ejtag) 191 __FINIT << 192 224 193 LEAF(mips_cps_core_init) 225 LEAF(mips_cps_core_init) 194 #ifdef CONFIG_MIPS_MT_SMP 226 #ifdef CONFIG_MIPS_MT_SMP 195 /* Check that the core implements the 227 /* Check that the core implements the MT ASE */ 196 has_mt t0, 3f 228 has_mt t0, 3f 197 229 198 .set push 230 .set push 199 .set MIPS_ISA_LEVEL_RAW 231 .set MIPS_ISA_LEVEL_RAW 200 .set mt 232 .set mt 201 233 202 /* Only allow 1 TC per VPE to execute. 234 /* Only allow 1 TC per VPE to execute... */ 203 dmt 235 dmt 204 236 205 /* ...and for the moment only 1 VPE */ 237 /* ...and for the moment only 1 VPE */ 206 dvpe 238 dvpe 207 PTR_LA t1, 1f 239 PTR_LA t1, 1f 208 jr.hb t1 240 jr.hb t1 209 nop 241 nop 210 242 211 /* Enter VPE configuration state */ 243 /* Enter VPE configuration state */ 212 1: mfc0 t0, CP0_MVPCONTROL 244 1: mfc0 t0, CP0_MVPCONTROL 213 ori t0, t0, MVPCONTROL_VPC 245 ori t0, t0, MVPCONTROL_VPC 214 mtc0 t0, CP0_MVPCONTROL 246 mtc0 t0, CP0_MVPCONTROL 215 247 216 /* Retrieve the number of VPEs within 248 /* Retrieve the number of VPEs within the core */ 217 mfc0 t0, CP0_MVPCONF0 249 mfc0 t0, CP0_MVPCONF0 218 srl t0, t0, MVPCONF0_PVPE_SHIFT 250 srl t0, t0, MVPCONF0_PVPE_SHIFT 219 andi t0, t0, (MVPCONF0_PVPE >> MVPC 251 andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT) 220 addiu ta3, t0, 1 252 addiu ta3, t0, 1 221 253 222 /* If there's only 1, we're done */ 254 /* If there's only 1, we're done */ 223 beqz t0, 2f 255 beqz t0, 2f 224 nop 256 nop 225 257 226 /* Loop through each VPE within this c 258 /* Loop through each VPE within this core */ 227 li ta1, 1 259 li ta1, 1 228 260 229 1: /* Operate on the appropriate TC */ 261 1: /* Operate on the appropriate TC */ 230 mtc0 ta1, CP0_VPECONTROL 262 mtc0 ta1, CP0_VPECONTROL 231 ehb 263 ehb 232 264 233 /* Bind TC to VPE (1:1 TC:VPE mapping) 265 /* Bind TC to VPE (1:1 TC:VPE mapping) */ 234 mttc0 ta1, CP0_TCBIND 266 mttc0 ta1, CP0_TCBIND 235 267 236 /* Set exclusive TC, non-active, maste 268 /* Set exclusive TC, non-active, master */ 237 li t0, VPECONF0_MVP 269 li t0, VPECONF0_MVP 238 sll t1, ta1, VPECONF0_XTC_SHIFT 270 sll t1, ta1, VPECONF0_XTC_SHIFT 239 or t0, t0, t1 271 or t0, t0, t1 240 mttc0 t0, CP0_VPECONF0 272 mttc0 t0, CP0_VPECONF0 241 273 242 /* Set TC non-active, non-allocatable 274 /* Set TC non-active, non-allocatable */ 243 mttc0 zero, CP0_TCSTATUS 275 mttc0 zero, CP0_TCSTATUS 244 276 245 /* Set TC halted */ 277 /* Set TC halted */ 246 li t0, TCHALT_H 278 li t0, TCHALT_H 247 mttc0 t0, CP0_TCHALT 279 mttc0 t0, CP0_TCHALT 248 280 249 /* Next VPE */ 281 /* Next VPE */ 250 addiu ta1, ta1, 1 282 addiu ta1, ta1, 1 251 slt t0, ta1, ta3 283 slt t0, ta1, ta3 252 bnez t0, 1b 284 bnez t0, 1b 253 nop 285 nop 254 286 255 /* Leave VPE configuration state */ 287 /* Leave VPE configuration state */ 256 2: mfc0 t0, CP0_MVPCONTROL 288 2: mfc0 t0, CP0_MVPCONTROL 257 xori t0, t0, MVPCONTROL_VPC 289 xori t0, t0, MVPCONTROL_VPC 258 mtc0 t0, CP0_MVPCONTROL 290 mtc0 t0, CP0_MVPCONTROL 259 291 260 3: .set pop 292 3: .set pop 261 #endif 293 #endif 262 jr ra 294 jr ra 263 nop 295 nop 264 END(mips_cps_core_init) 296 END(mips_cps_core_init) 265 297 266 /** 298 /** 267 * mips_cps_get_bootcfg() - retrieve boot conf 299 * mips_cps_get_bootcfg() - retrieve boot configuration pointers 268 * 300 * 269 * Returns: pointer to struct core_boot_config 301 * Returns: pointer to struct core_boot_config in v0, pointer to 270 * struct vpe_boot_config in v1, VPE 302 * struct vpe_boot_config in v1, VPE ID in t9 271 */ 303 */ 272 LEAF(mips_cps_get_bootcfg) 304 LEAF(mips_cps_get_bootcfg) 273 /* Calculate a pointer to this cores s 305 /* Calculate a pointer to this cores struct core_boot_config */ 274 lw t0, GCR_CL_ID_OFS(s1) 306 lw t0, GCR_CL_ID_OFS(s1) 275 li t1, COREBOOTCFG_SIZE 307 li t1, COREBOOTCFG_SIZE 276 mul t0, t0, t1 308 mul t0, t0, t1 277 PTR_LA t1, mips_cps_core_bootcfg 309 PTR_LA t1, mips_cps_core_bootcfg 278 PTR_L t1, 0(t1) 310 PTR_L t1, 0(t1) 279 PTR_ADDU v0, t0, t1 311 PTR_ADDU v0, t0, t1 280 312 281 /* Calculate this VPEs ID. If the core 313 /* Calculate this VPEs ID. If the core doesn't support MT use 0 */ 282 li t9, 0 314 li t9, 0 283 #if defined(CONFIG_CPU_MIPSR6) 315 #if defined(CONFIG_CPU_MIPSR6) 284 has_vp ta2, 1f 316 has_vp ta2, 1f 285 317 286 /* 318 /* 287 * Assume non-contiguous numbering. Pe 319 * Assume non-contiguous numbering. Perhaps some day we'll need 288 * to handle contiguous VP numbering, 320 * to handle contiguous VP numbering, but no such systems yet 289 * exist. 321 * exist. 290 */ 322 */ 291 mfc0 t9, CP0_GLOBALNUMBER 323 mfc0 t9, CP0_GLOBALNUMBER 292 andi t9, t9, MIPS_GLOBALNUMBER_VP 324 andi t9, t9, MIPS_GLOBALNUMBER_VP 293 #elif defined(CONFIG_MIPS_MT_SMP) 325 #elif defined(CONFIG_MIPS_MT_SMP) 294 has_mt ta2, 1f 326 has_mt ta2, 1f 295 327 296 /* Find the number of VPEs present in 328 /* Find the number of VPEs present in the core */ 297 mfc0 t1, CP0_MVPCONF0 329 mfc0 t1, CP0_MVPCONF0 298 srl t1, t1, MVPCONF0_PVPE_SHIFT 330 srl t1, t1, MVPCONF0_PVPE_SHIFT 299 andi t1, t1, MVPCONF0_PVPE >> MVPCO 331 andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT 300 addiu t1, t1, 1 332 addiu t1, t1, 1 301 333 302 /* Calculate a mask for the VPE ID fro 334 /* Calculate a mask for the VPE ID from EBase.CPUNum */ 303 clz t1, t1 335 clz t1, t1 304 li t2, 31 336 li t2, 31 305 subu t1, t2, t1 337 subu t1, t2, t1 306 li t2, 1 338 li t2, 1 307 sll t1, t2, t1 339 sll t1, t2, t1 308 addiu t1, t1, -1 340 addiu t1, t1, -1 309 341 310 /* Retrieve the VPE ID from EBase.CPUN 342 /* Retrieve the VPE ID from EBase.CPUNum */ 311 mfc0 t9, $15, 1 343 mfc0 t9, $15, 1 312 and t9, t9, t1 344 and t9, t9, t1 313 #endif 345 #endif 314 346 315 1: /* Calculate a pointer to this VPEs st 347 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */ 316 li t1, VPEBOOTCFG_SIZE 348 li t1, VPEBOOTCFG_SIZE 317 mul v1, t9, t1 349 mul v1, t9, t1 318 PTR_L ta3, COREBOOTCFG_VPECONFIG(v0) 350 PTR_L ta3, COREBOOTCFG_VPECONFIG(v0) 319 PTR_ADDU v1, v1, ta3 351 PTR_ADDU v1, v1, ta3 320 352 321 jr ra 353 jr ra 322 nop 354 nop 323 END(mips_cps_get_bootcfg) 355 END(mips_cps_get_bootcfg) 324 356 325 LEAF(mips_cps_boot_vpes) 357 LEAF(mips_cps_boot_vpes) 326 lw ta2, COREBOOTCFG_VPEMASK(a0) 358 lw ta2, COREBOOTCFG_VPEMASK(a0) 327 PTR_L ta3, COREBOOTCFG_VPECONFIG(a0) 359 PTR_L ta3, COREBOOTCFG_VPECONFIG(a0) 328 360 329 #if defined(CONFIG_CPU_MIPSR6) 361 #if defined(CONFIG_CPU_MIPSR6) 330 362 331 has_vp t0, 5f 363 has_vp t0, 5f 332 364 333 /* Find base address of CPC */ 365 /* Find base address of CPC */ 334 PTR_LA t1, mips_gcr_base 366 PTR_LA t1, mips_gcr_base 335 PTR_L t1, 0(t1) 367 PTR_L t1, 0(t1) 336 PTR_L t1, GCR_CPC_BASE_OFS(t1) 368 PTR_L t1, GCR_CPC_BASE_OFS(t1) 337 PTR_LI t2, ~0x7fff 369 PTR_LI t2, ~0x7fff 338 and t1, t1, t2 370 and t1, t1, t2 339 PTR_LI t2, UNCAC_BASE 371 PTR_LI t2, UNCAC_BASE 340 PTR_ADD t1, t1, t2 372 PTR_ADD t1, t1, t2 341 373 342 /* Start any other VPs that ought to b 374 /* Start any other VPs that ought to be running */ 343 PTR_S ta2, CPC_CL_VC_RUN_OFS(t1) 375 PTR_S ta2, CPC_CL_VC_RUN_OFS(t1) 344 376 345 /* Ensure this VP stops running if it 377 /* Ensure this VP stops running if it shouldn't be */ 346 not ta2 378 not ta2 347 PTR_S ta2, CPC_CL_VC_STOP_OFS(t1) 379 PTR_S ta2, CPC_CL_VC_STOP_OFS(t1) 348 ehb 380 ehb 349 381 350 #elif defined(CONFIG_MIPS_MT) 382 #elif defined(CONFIG_MIPS_MT) 351 383 352 /* If the core doesn't support MT then 384 /* If the core doesn't support MT then return */ 353 has_mt t0, 5f 385 has_mt t0, 5f 354 386 355 /* Enter VPE configuration state */ 387 /* Enter VPE configuration state */ 356 .set push 388 .set push 357 .set MIPS_ISA_LEVEL_RAW 389 .set MIPS_ISA_LEVEL_RAW 358 .set mt 390 .set mt 359 dvpe 391 dvpe 360 .set pop 392 .set pop 361 393 362 PTR_LA t1, 1f 394 PTR_LA t1, 1f 363 jr.hb t1 395 jr.hb t1 364 nop 396 nop 365 1: mfc0 t1, CP0_MVPCONTROL 397 1: mfc0 t1, CP0_MVPCONTROL 366 ori t1, t1, MVPCONTROL_VPC 398 ori t1, t1, MVPCONTROL_VPC 367 mtc0 t1, CP0_MVPCONTROL 399 mtc0 t1, CP0_MVPCONTROL 368 ehb 400 ehb 369 401 370 /* Loop through each VPE */ 402 /* Loop through each VPE */ 371 move t8, ta2 403 move t8, ta2 372 li ta1, 0 404 li ta1, 0 373 405 374 /* Check whether the VPE should be run 406 /* Check whether the VPE should be running. If not, skip it */ 375 1: andi t0, ta2, 1 407 1: andi t0, ta2, 1 376 beqz t0, 2f 408 beqz t0, 2f 377 nop 409 nop 378 410 379 /* Operate on the appropriate TC */ 411 /* Operate on the appropriate TC */ 380 mfc0 t0, CP0_VPECONTROL 412 mfc0 t0, CP0_VPECONTROL 381 ori t0, t0, VPECONTROL_TARGTC 413 ori t0, t0, VPECONTROL_TARGTC 382 xori t0, t0, VPECONTROL_TARGTC 414 xori t0, t0, VPECONTROL_TARGTC 383 or t0, t0, ta1 415 or t0, t0, ta1 384 mtc0 t0, CP0_VPECONTROL 416 mtc0 t0, CP0_VPECONTROL 385 ehb 417 ehb 386 418 387 .set push 419 .set push 388 .set MIPS_ISA_LEVEL_RAW 420 .set MIPS_ISA_LEVEL_RAW 389 .set mt 421 .set mt 390 422 391 /* Skip the VPE if its TC is not halte 423 /* Skip the VPE if its TC is not halted */ 392 mftc0 t0, CP0_TCHALT 424 mftc0 t0, CP0_TCHALT 393 beqz t0, 2f 425 beqz t0, 2f 394 nop 426 nop 395 427 396 /* Calculate a pointer to the VPEs str 428 /* Calculate a pointer to the VPEs struct vpe_boot_config */ 397 li t0, VPEBOOTCFG_SIZE 429 li t0, VPEBOOTCFG_SIZE 398 mul t0, t0, ta1 430 mul t0, t0, ta1 399 PTR_ADDU t0, t0, ta3 !! 431 addu t0, t0, ta3 400 432 401 /* Set the TC restart PC */ 433 /* Set the TC restart PC */ 402 lw t1, VPEBOOTCFG_PC(t0) 434 lw t1, VPEBOOTCFG_PC(t0) 403 mttc0 t1, CP0_TCRESTART 435 mttc0 t1, CP0_TCRESTART 404 436 405 /* Set the TC stack pointer */ 437 /* Set the TC stack pointer */ 406 lw t1, VPEBOOTCFG_SP(t0) 438 lw t1, VPEBOOTCFG_SP(t0) 407 mttgpr t1, sp 439 mttgpr t1, sp 408 440 409 /* Set the TC global pointer */ 441 /* Set the TC global pointer */ 410 lw t1, VPEBOOTCFG_GP(t0) 442 lw t1, VPEBOOTCFG_GP(t0) 411 mttgpr t1, gp 443 mttgpr t1, gp 412 444 413 /* Copy config from this VPE */ 445 /* Copy config from this VPE */ 414 mfc0 t0, CP0_CONFIG 446 mfc0 t0, CP0_CONFIG 415 mttc0 t0, CP0_CONFIG 447 mttc0 t0, CP0_CONFIG 416 448 417 /* 449 /* 418 * Copy the EVA config from this VPE i 450 * Copy the EVA config from this VPE if the CPU supports it. 419 * CONFIG3 must exist to be running MT 451 * CONFIG3 must exist to be running MT startup - just read it. 420 */ 452 */ 421 mfc0 t0, CP0_CONFIG, 3 453 mfc0 t0, CP0_CONFIG, 3 422 and t0, t0, MIPS_CONF3_SC 454 and t0, t0, MIPS_CONF3_SC 423 beqz t0, 3f 455 beqz t0, 3f 424 nop 456 nop 425 mfc0 t0, CP0_SEGCTL0 457 mfc0 t0, CP0_SEGCTL0 426 mttc0 t0, CP0_SEGCTL0 458 mttc0 t0, CP0_SEGCTL0 427 mfc0 t0, CP0_SEGCTL1 459 mfc0 t0, CP0_SEGCTL1 428 mttc0 t0, CP0_SEGCTL1 460 mttc0 t0, CP0_SEGCTL1 429 mfc0 t0, CP0_SEGCTL2 461 mfc0 t0, CP0_SEGCTL2 430 mttc0 t0, CP0_SEGCTL2 462 mttc0 t0, CP0_SEGCTL2 431 3: 463 3: 432 /* Ensure no software interrupts are p 464 /* Ensure no software interrupts are pending */ 433 mttc0 zero, CP0_CAUSE 465 mttc0 zero, CP0_CAUSE 434 mttc0 zero, CP0_STATUS 466 mttc0 zero, CP0_STATUS 435 467 436 /* Set TC active, not interrupt exempt 468 /* Set TC active, not interrupt exempt */ 437 mftc0 t0, CP0_TCSTATUS 469 mftc0 t0, CP0_TCSTATUS 438 li t1, ~TCSTATUS_IXMT 470 li t1, ~TCSTATUS_IXMT 439 and t0, t0, t1 471 and t0, t0, t1 440 ori t0, t0, TCSTATUS_A 472 ori t0, t0, TCSTATUS_A 441 mttc0 t0, CP0_TCSTATUS 473 mttc0 t0, CP0_TCSTATUS 442 474 443 /* Clear the TC halt bit */ 475 /* Clear the TC halt bit */ 444 mttc0 zero, CP0_TCHALT 476 mttc0 zero, CP0_TCHALT 445 477 446 /* Set VPE active */ 478 /* Set VPE active */ 447 mftc0 t0, CP0_VPECONF0 479 mftc0 t0, CP0_VPECONF0 448 ori t0, t0, VPECONF0_VPA 480 ori t0, t0, VPECONF0_VPA 449 mttc0 t0, CP0_VPECONF0 481 mttc0 t0, CP0_VPECONF0 450 482 451 /* Next VPE */ 483 /* Next VPE */ 452 2: srl ta2, ta2, 1 484 2: srl ta2, ta2, 1 453 addiu ta1, ta1, 1 485 addiu ta1, ta1, 1 454 bnez ta2, 1b 486 bnez ta2, 1b 455 nop 487 nop 456 488 457 /* Leave VPE configuration state */ 489 /* Leave VPE configuration state */ 458 mfc0 t1, CP0_MVPCONTROL 490 mfc0 t1, CP0_MVPCONTROL 459 xori t1, t1, MVPCONTROL_VPC 491 xori t1, t1, MVPCONTROL_VPC 460 mtc0 t1, CP0_MVPCONTROL 492 mtc0 t1, CP0_MVPCONTROL 461 ehb 493 ehb 462 evpe 494 evpe 463 495 464 .set pop 496 .set pop 465 497 466 /* Check whether this VPE is meant to 498 /* Check whether this VPE is meant to be running */ 467 li t0, 1 499 li t0, 1 468 sll t0, t0, a1 500 sll t0, t0, a1 469 and t0, t0, t8 501 and t0, t0, t8 470 bnez t0, 2f 502 bnez t0, 2f 471 nop 503 nop 472 504 473 /* This VPE should be offline, halt th 505 /* This VPE should be offline, halt the TC */ 474 li t0, TCHALT_H 506 li t0, TCHALT_H 475 mtc0 t0, CP0_TCHALT 507 mtc0 t0, CP0_TCHALT 476 PTR_LA t0, 1f 508 PTR_LA t0, 1f 477 1: jr.hb t0 509 1: jr.hb t0 478 nop 510 nop 479 511 480 2: 512 2: 481 513 482 #endif /* CONFIG_MIPS_MT_SMP */ 514 #endif /* CONFIG_MIPS_MT_SMP */ 483 515 484 /* Return */ 516 /* Return */ 485 5: jr ra 517 5: jr ra 486 nop 518 nop 487 END(mips_cps_boot_vpes) 519 END(mips_cps_boot_vpes) 488 520 489 #if MIPS_ISA_REV > 0 521 #if MIPS_ISA_REV > 0 490 LEAF(mips_cps_cache_init) 522 LEAF(mips_cps_cache_init) 491 /* 523 /* 492 * Clear the bits used to index the ca 524 * Clear the bits used to index the caches. Note that the architecture 493 * dictates that writing to any of Tag 525 * dictates that writing to any of TagLo or TagHi selects 0 or 2 should 494 * be valid for all MIPS32 CPUs, even 526 * be valid for all MIPS32 CPUs, even those for which said writes are 495 * unnecessary. 527 * unnecessary. 496 */ 528 */ 497 mtc0 zero, CP0_TAGLO, 0 529 mtc0 zero, CP0_TAGLO, 0 498 mtc0 zero, CP0_TAGHI, 0 530 mtc0 zero, CP0_TAGHI, 0 499 mtc0 zero, CP0_TAGLO, 2 531 mtc0 zero, CP0_TAGLO, 2 500 mtc0 zero, CP0_TAGHI, 2 532 mtc0 zero, CP0_TAGHI, 2 501 ehb 533 ehb 502 534 503 /* Primary cache configuration is indi 535 /* Primary cache configuration is indicated by Config1 */ 504 mfc0 v0, CP0_CONFIG, 1 536 mfc0 v0, CP0_CONFIG, 1 505 537 506 /* Detect I-cache line size */ 538 /* Detect I-cache line size */ 507 _EXT t0, v0, MIPS_CONF1_IL_SHF, MIP 539 _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ 508 beqz t0, icache_done 540 beqz t0, icache_done 509 li t1, 2 541 li t1, 2 510 sllv t0, t1, t0 542 sllv t0, t1, t0 511 543 512 /* Detect I-cache size */ 544 /* Detect I-cache size */ 513 _EXT t1, v0, MIPS_CONF1_IS_SHF, MIP 545 _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ 514 xori t2, t1, 0x7 546 xori t2, t1, 0x7 515 beqz t2, 1f 547 beqz t2, 1f 516 li t3, 32 548 li t3, 32 517 addiu t1, t1, 1 549 addiu t1, t1, 1 518 sllv t1, t3, t1 550 sllv t1, t3, t1 519 1: /* At this point t1 == I-cache sets pe 551 1: /* At this point t1 == I-cache sets per way */ 520 _EXT t2, v0, MIPS_CONF1_IA_SHF, MIP 552 _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ 521 addiu t2, t2, 1 553 addiu t2, t2, 1 522 mul t1, t1, t0 554 mul t1, t1, t0 523 mul t1, t1, t2 555 mul t1, t1, t2 524 556 525 li a0, CKSEG0 557 li a0, CKSEG0 526 PTR_ADD a1, a0, t1 558 PTR_ADD a1, a0, t1 527 1: cache Index_Store_Tag_I, 0(a0) 559 1: cache Index_Store_Tag_I, 0(a0) 528 PTR_ADD a0, a0, t0 560 PTR_ADD a0, a0, t0 529 bne a0, a1, 1b 561 bne a0, a1, 1b 530 nop 562 nop 531 icache_done: 563 icache_done: 532 564 533 /* Detect D-cache line size */ 565 /* Detect D-cache line size */ 534 _EXT t0, v0, MIPS_CONF1_DL_SHF, MIP 566 _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ 535 beqz t0, dcache_done 567 beqz t0, dcache_done 536 li t1, 2 568 li t1, 2 537 sllv t0, t1, t0 569 sllv t0, t1, t0 538 570 539 /* Detect D-cache size */ 571 /* Detect D-cache size */ 540 _EXT t1, v0, MIPS_CONF1_DS_SHF, MIP 572 _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ 541 xori t2, t1, 0x7 573 xori t2, t1, 0x7 542 beqz t2, 1f 574 beqz t2, 1f 543 li t3, 32 575 li t3, 32 544 addiu t1, t1, 1 576 addiu t1, t1, 1 545 sllv t1, t3, t1 577 sllv t1, t3, t1 546 1: /* At this point t1 == D-cache sets pe 578 1: /* At this point t1 == D-cache sets per way */ 547 _EXT t2, v0, MIPS_CONF1_DA_SHF, MIP 579 _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ 548 addiu t2, t2, 1 580 addiu t2, t2, 1 549 mul t1, t1, t0 581 mul t1, t1, t0 550 mul t1, t1, t2 582 mul t1, t1, t2 551 583 552 li a0, CKSEG0 584 li a0, CKSEG0 553 PTR_ADDU a1, a0, t1 585 PTR_ADDU a1, a0, t1 554 PTR_SUBU a1, a1, t0 586 PTR_SUBU a1, a1, t0 555 1: cache Index_Store_Tag_D, 0(a0) 587 1: cache Index_Store_Tag_D, 0(a0) 556 bne a0, a1, 1b 588 bne a0, a1, 1b 557 PTR_ADD a0, a0, t0 589 PTR_ADD a0, a0, t0 558 dcache_done: 590 dcache_done: 559 591 560 jr ra 592 jr ra 561 nop 593 nop 562 END(mips_cps_cache_init) 594 END(mips_cps_cache_init) 563 #endif /* MIPS_ISA_REV > 0 */ 595 #endif /* MIPS_ISA_REV > 0 */ 564 596 565 #if defined(CONFIG_MIPS_CPS_PM) && defined(CON 597 #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM) 566 598 567 /* Calculate a pointer to this CPUs st 599 /* Calculate a pointer to this CPUs struct mips_static_suspend_state */ 568 .macro psstate dest 600 .macro psstate dest 569 .set push 601 .set push 570 .set noat 602 .set noat 571 lw $1, TI_CPU(gp) 603 lw $1, TI_CPU(gp) 572 sll $1, $1, LONGLOG 604 sll $1, $1, LONGLOG 573 PTR_LA \dest, __per_cpu_offset 605 PTR_LA \dest, __per_cpu_offset 574 PTR_ADDU $1, $1, \dest !! 606 addu $1, $1, \dest 575 lw $1, 0($1) 607 lw $1, 0($1) 576 PTR_LA \dest, cps_cpu_state 608 PTR_LA \dest, cps_cpu_state 577 PTR_ADDU \dest, \dest, $1 !! 609 addu \dest, \dest, $1 578 .set pop 610 .set pop 579 .endm 611 .endm 580 612 581 LEAF(mips_cps_pm_save) 613 LEAF(mips_cps_pm_save) 582 /* Save CPU state */ 614 /* Save CPU state */ 583 SUSPEND_SAVE_REGS 615 SUSPEND_SAVE_REGS 584 psstate t1 616 psstate t1 585 SUSPEND_SAVE_STATIC 617 SUSPEND_SAVE_STATIC 586 jr v0 618 jr v0 587 nop 619 nop 588 END(mips_cps_pm_save) 620 END(mips_cps_pm_save) 589 621 590 LEAF(mips_cps_pm_restore) 622 LEAF(mips_cps_pm_restore) 591 /* Restore CPU state */ 623 /* Restore CPU state */ 592 psstate t1 624 psstate t1 593 RESUME_RESTORE_STATIC 625 RESUME_RESTORE_STATIC 594 RESUME_RESTORE_REGS_RETURN 626 RESUME_RESTORE_REGS_RETURN 595 END(mips_cps_pm_restore) 627 END(mips_cps_pm_restore) 596 628 597 #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM 629 #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.