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