1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Copyright (C) 2013 Imagination Technologies
4 * Author: Paul Burton <paul.burton@mips.com>
7 #include <asm/addrspace.h>
9 #include <asm/asm-offsets.h>
10 #include <asm/asmmacro.h>
11 #include <asm/cacheops.h>
13 #include <asm/mipsregs.h>
14 #include <asm/mipsmtregs.h>
17 #define GCR_CPC_BASE_OFS 0x0088
18 #define GCR_CL_COHERENCE_OFS 0x2008
19 #define GCR_CL_ID_OFS 0x2028
21 #define CPC_CL_VC_STOP_OFS 0x2020
22 #define CPC_CL_VC_RUN_OFS 0x2028
29 # define STATUS_BITDEPS ST0_KX
31 # define STATUS_BITDEPS 0
34 #ifdef CONFIG_MIPS_CPS_NS16550
36 #define DUMP_EXCEP(name) \
38 jal mips_cps_bev_dump; \
42 #else /* !CONFIG_MIPS_CPS_NS16550 */
44 #define DUMP_EXCEP(name)
46 #endif /* !CONFIG_MIPS_CPS_NS16550 */
49 * Set dest to non-zero if the core supports the MT ASE, else zero. If
50 * MT is not supported then branch to nomt.
52 .macro has_mt dest, nomt
53 mfc0 \dest, CP0_CONFIG, 1
55 mfc0 \dest, CP0_CONFIG, 2
57 mfc0 \dest, CP0_CONFIG, 3
58 andi \dest, \dest, MIPS_CONF3_MT
64 * Set dest to non-zero if the core supports MIPSr6 multithreading
65 * (ie. VPs), else zero. If MIPSr6 multithreading is not supported then
68 .macro has_vp dest, nomt
69 mfc0 \dest, CP0_CONFIG, 1
71 mfc0 \dest, CP0_CONFIG, 2
73 mfc0 \dest, CP0_CONFIG, 3
75 mfc0 \dest, CP0_CONFIG, 4
77 mfc0 \dest, CP0_CONFIG, 5
78 andi \dest, \dest, MIPS_CONF5_VP
83 /* Calculate an uncached address for the CM GCRs */
87 MFC0 $1, CP0_CMGCRBASE
89 PTR_LI \dest, UNCAC_BASE
90 PTR_ADDU \dest, \dest, $1
96 LEAF(mips_cps_core_entry)
98 * These first 4 bytes will be patched by cps_smp_setup to load the
99 * CCA to use into register s0.
103 /* Check whether we're here due to an NMI */
110 PTR_LA k0, nmi_handler
120 li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS
123 /* Skip cache & coherence setup if we're already coherent */
125 lw s7, GCR_CL_COHERENCE_OFS(v1)
129 /* Initialize the L1 caches */
130 jal mips_cps_cache_init
133 /* Enter the coherent domain */
135 sw t0, GCR_CL_COHERENCE_OFS(v1)
138 /* Set Kseg0 CCA to that in s0 */
139 1: mfc0 t0, CP0_CONFIG
152 * We're up, cached & coherent. Perform any EVA initialization necessary
153 * before we access memory.
157 /* Retrieve boot configuration pointers */
158 jal mips_cps_get_bootcfg
161 /* Skip core-level init if we started up coherent */
165 /* Perform any further required core-level initialisation */
166 jal mips_cps_core_init
170 * Boot any other VPEs within this core that should be online, and
171 * deactivate this VPE if it should be offline.
174 jal mips_cps_boot_vpes
178 1: PTR_L t1, VPEBOOTCFG_PC(v1)
179 PTR_L gp, VPEBOOTCFG_GP(v1)
180 PTR_L sp, VPEBOOTCFG_SP(v1)
183 END(mips_cps_core_entry)
187 DUMP_EXCEP("TLB Fill")
194 DUMP_EXCEP("XTLB Fill")
208 DUMP_EXCEP("General")
215 DUMP_EXCEP("Interrupt")
222 PTR_LA k0, ejtag_debug_handler
227 LEAF(mips_cps_core_init)
228 #ifdef CONFIG_MIPS_MT_SMP
229 /* Check that the core implements the MT ASE */
233 .set MIPS_ISA_LEVEL_RAW
236 /* Only allow 1 TC per VPE to execute... */
239 /* ...and for the moment only 1 VPE */
245 /* Enter VPE configuration state */
246 1: mfc0 t0, CP0_MVPCONTROL
247 ori t0, t0, MVPCONTROL_VPC
248 mtc0 t0, CP0_MVPCONTROL
250 /* Retrieve the number of VPEs within the core */
251 mfc0 t0, CP0_MVPCONF0
252 srl t0, t0, MVPCONF0_PVPE_SHIFT
253 andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT)
256 /* If there's only 1, we're done */
260 /* Loop through each VPE within this core */
263 1: /* Operate on the appropriate TC */
264 mtc0 ta1, CP0_VPECONTROL
267 /* Bind TC to VPE (1:1 TC:VPE mapping) */
268 mttc0 ta1, CP0_TCBIND
270 /* Set exclusive TC, non-active, master */
272 sll t1, ta1, VPECONF0_XTC_SHIFT
274 mttc0 t0, CP0_VPECONF0
276 /* Set TC non-active, non-allocatable */
277 mttc0 zero, CP0_TCSTATUS
289 /* Leave VPE configuration state */
290 2: mfc0 t0, CP0_MVPCONTROL
291 xori t0, t0, MVPCONTROL_VPC
292 mtc0 t0, CP0_MVPCONTROL
298 END(mips_cps_core_init)
301 * mips_cps_get_bootcfg() - retrieve boot configuration pointers
303 * Returns: pointer to struct core_boot_config in v0, pointer to
304 * struct vpe_boot_config in v1, VPE ID in t9
306 LEAF(mips_cps_get_bootcfg)
307 /* Calculate a pointer to this cores struct core_boot_config */
309 lw t0, GCR_CL_ID_OFS(t0)
310 li t1, COREBOOTCFG_SIZE
312 PTR_LA t1, mips_cps_core_bootcfg
316 /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
318 #if defined(CONFIG_CPU_MIPSR6)
322 * Assume non-contiguous numbering. Perhaps some day we'll need
323 * to handle contiguous VP numbering, but no such systems yet
326 mfc0 t9, CP0_GLOBALNUMBER
327 andi t9, t9, MIPS_GLOBALNUMBER_VP
328 #elif defined(CONFIG_MIPS_MT_SMP)
331 /* Find the number of VPEs present in the core */
332 mfc0 t1, CP0_MVPCONF0
333 srl t1, t1, MVPCONF0_PVPE_SHIFT
334 andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT
337 /* Calculate a mask for the VPE ID from EBase.CPUNum */
345 /* Retrieve the VPE ID from EBase.CPUNum */
350 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */
351 li t1, VPEBOOTCFG_SIZE
353 PTR_L ta3, COREBOOTCFG_VPECONFIG(v0)
358 END(mips_cps_get_bootcfg)
360 LEAF(mips_cps_boot_vpes)
361 lw ta2, COREBOOTCFG_VPEMASK(a0)
362 PTR_L ta3, COREBOOTCFG_VPECONFIG(a0)
364 #if defined(CONFIG_CPU_MIPSR6)
368 /* Find base address of CPC */
370 PTR_L t1, GCR_CPC_BASE_OFS(t3)
373 PTR_LI t2, UNCAC_BASE
376 /* Start any other VPs that ought to be running */
377 PTR_S ta2, CPC_CL_VC_RUN_OFS(t1)
379 /* Ensure this VP stops running if it shouldn't be */
381 PTR_S ta2, CPC_CL_VC_STOP_OFS(t1)
384 #elif defined(CONFIG_MIPS_MT)
386 /* If the core doesn't support MT then return */
389 /* Enter VPE configuration state */
391 .set MIPS_ISA_LEVEL_RAW
399 1: mfc0 t1, CP0_MVPCONTROL
400 ori t1, t1, MVPCONTROL_VPC
401 mtc0 t1, CP0_MVPCONTROL
404 /* Loop through each VPE */
408 /* Check whether the VPE should be running. If not, skip it */
413 /* Operate on the appropriate TC */
414 mfc0 t0, CP0_VPECONTROL
415 ori t0, t0, VPECONTROL_TARGTC
416 xori t0, t0, VPECONTROL_TARGTC
418 mtc0 t0, CP0_VPECONTROL
422 .set MIPS_ISA_LEVEL_RAW
425 /* Skip the VPE if its TC is not halted */
430 /* Calculate a pointer to the VPEs struct vpe_boot_config */
431 li t0, VPEBOOTCFG_SIZE
435 /* Set the TC restart PC */
436 lw t1, VPEBOOTCFG_PC(t0)
437 mttc0 t1, CP0_TCRESTART
439 /* Set the TC stack pointer */
440 lw t1, VPEBOOTCFG_SP(t0)
443 /* Set the TC global pointer */
444 lw t1, VPEBOOTCFG_GP(t0)
447 /* Copy config from this VPE */
452 * Copy the EVA config from this VPE if the CPU supports it.
453 * CONFIG3 must exist to be running MT startup - just read it.
455 mfc0 t0, CP0_CONFIG, 3
456 and t0, t0, MIPS_CONF3_SC
460 mttc0 t0, CP0_SEGCTL0
462 mttc0 t0, CP0_SEGCTL1
464 mttc0 t0, CP0_SEGCTL2
466 /* Ensure no software interrupts are pending */
467 mttc0 zero, CP0_CAUSE
468 mttc0 zero, CP0_STATUS
470 /* Set TC active, not interrupt exempt */
471 mftc0 t0, CP0_TCSTATUS
472 li t1, ~TCSTATUS_IXMT
474 ori t0, t0, TCSTATUS_A
475 mttc0 t0, CP0_TCSTATUS
477 /* Clear the TC halt bit */
478 mttc0 zero, CP0_TCHALT
481 mftc0 t0, CP0_VPECONF0
482 ori t0, t0, VPECONF0_VPA
483 mttc0 t0, CP0_VPECONF0
491 /* Leave VPE configuration state */
492 mfc0 t1, CP0_MVPCONTROL
493 xori t1, t1, MVPCONTROL_VPC
494 mtc0 t1, CP0_MVPCONTROL
500 /* Check whether this VPE is meant to be running */
507 /* This VPE should be offline, halt the TC */
516 #endif /* CONFIG_MIPS_MT_SMP */
521 END(mips_cps_boot_vpes)
523 LEAF(mips_cps_cache_init)
525 * Clear the bits used to index the caches. Note that the architecture
526 * dictates that writing to any of TagLo or TagHi selects 0 or 2 should
527 * be valid for all MIPS32 CPUs, even those for which said writes are
530 mtc0 zero, CP0_TAGLO, 0
531 mtc0 zero, CP0_TAGHI, 0
532 mtc0 zero, CP0_TAGLO, 2
533 mtc0 zero, CP0_TAGHI, 2
536 /* Primary cache configuration is indicated by Config1 */
537 mfc0 v0, CP0_CONFIG, 1
539 /* Detect I-cache line size */
540 _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ
545 /* Detect I-cache size */
546 _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ
552 1: /* At this point t1 == I-cache sets per way */
553 _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ
560 1: cache Index_Store_Tag_I, 0(a0)
566 /* Detect D-cache line size */
567 _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ
572 /* Detect D-cache size */
573 _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ
579 1: /* At this point t1 == D-cache sets per way */
580 _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ
588 1: cache Index_Store_Tag_D, 0(a0)
595 END(mips_cps_cache_init)
597 #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
599 /* Calculate a pointer to this CPUs struct mips_static_suspend_state */
605 PTR_LA \dest, __per_cpu_offset
608 PTR_LA \dest, cps_cpu_state
609 addu \dest, \dest, $1
613 LEAF(mips_cps_pm_save)
620 END(mips_cps_pm_save)
622 LEAF(mips_cps_pm_restore)
623 /* Restore CPU state */
625 RESUME_RESTORE_STATIC
626 RESUME_RESTORE_REGS_RETURN
627 END(mips_cps_pm_restore)
629 #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */