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