~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/kernel/cps-vec.S

Version: ~ [ linux-5.15-rc6 ] ~ [ linux-5.14.14 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.75 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.155 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.213 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.252 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.287 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.289 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  */
  6 
  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>
 16 
 17 #define GCR_CPC_BASE_OFS        0x0088
 18 #define GCR_CL_COHERENCE_OFS    0x2008
 19 #define GCR_CL_ID_OFS           0x2028
 20 
 21 #define CPC_CL_VC_STOP_OFS      0x2020
 22 #define CPC_CL_VC_RUN_OFS       0x2028
 23 
 24 .extern mips_cm_base
 25 
 26 .set noreorder
 27 
 28 #ifdef CONFIG_64BIT
 29 # define STATUS_BITDEPS         ST0_KX
 30 #else
 31 # define STATUS_BITDEPS         0
 32 #endif
 33 
 34 #ifdef CONFIG_MIPS_CPS_NS16550
 35 
 36 #define DUMP_EXCEP(name)                \
 37         PTR_LA  a0, 8f;                 \
 38         jal     mips_cps_bev_dump;      \
 39          nop;                           \
 40         TEXT(name)
 41 
 42 #else /* !CONFIG_MIPS_CPS_NS16550 */
 43 
 44 #define DUMP_EXCEP(name)
 45 
 46 #endif /* !CONFIG_MIPS_CPS_NS16550 */
 47 
 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
 62 
 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
 82 
 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
 93 
 94 .section .text.cps-vec
 95 .balign 0x1000
 96 
 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
103 
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
109 
110         /* This is an NMI */
111         PTR_LA  k0, nmi_handler
112         jr      k0
113          nop
114 
115 not_nmi:
116         /* Setup Cause */
117         li      t0, CAUSEF_IV
118         mtc0    t0, CP0_CAUSE
119 
120         /* Setup Status */
121         li      t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS
122         mtc0    t0, CP0_STATUS
123 
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
129 
130         /* Initialize the L1 caches */
131         jal     mips_cps_cache_init
132          nop
133 
134         /* Enter the coherent domain */
135         li      t0, 0xff
136         sw      t0, GCR_CL_COHERENCE_OFS(v1)
137         ehb
138 
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
146 
147         /* Jump to kseg0 */
148         PTR_LA  t0, 1f
149         jr      t0
150          nop
151 
152         /*
153          * We're up, cached & coherent. Perform any EVA initialization necessary
154          * before we access memory.
155          */
156 1:      eva_init
157 
158         /* Retrieve boot configuration pointers */
159         jal     mips_cps_get_bootcfg
160          nop
161 
162         /* Skip core-level init if we started up coherent */
163         bnez    s7, 1f
164          nop
165 
166         /* Perform any further required core-level initialisation */
167         jal     mips_cps_core_init
168          nop
169 
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
177 
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)
185 
186 .org 0x200
187 LEAF(excep_tlbfill)
188         DUMP_EXCEP("TLB Fill")
189         b       .
190          nop
191         END(excep_tlbfill)
192 
193 .org 0x280
194 LEAF(excep_xtlbfill)
195         DUMP_EXCEP("XTLB Fill")
196         b       .
197          nop
198         END(excep_xtlbfill)
199 
200 .org 0x300
201 LEAF(excep_cache)
202         DUMP_EXCEP("Cache")
203         b       .
204          nop
205         END(excep_cache)
206 
207 .org 0x380
208 LEAF(excep_genex)
209         DUMP_EXCEP("General")
210         b       .
211          nop
212         END(excep_genex)
213 
214 .org 0x400
215 LEAF(excep_intex)
216         DUMP_EXCEP("Interrupt")
217         b       .
218          nop
219         END(excep_intex)
220 
221 .org 0x480
222 LEAF(excep_ejtag)
223         PTR_LA  k0, ejtag_debug_handler
224         jr      k0
225          nop
226         END(excep_ejtag)
227 
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
232 
233         .set    push
234         .set    MIPS_ISA_LEVEL_RAW
235         .set    mt
236 
237         /* Only allow 1 TC per VPE to execute... */
238         dmt
239 
240         /* ...and for the moment only 1 VPE */
241         dvpe
242         PTR_LA  t1, 1f
243         jr.hb   t1
244          nop
245 
246         /* Enter VPE configuration state */
247 1:      mfc0    t0, CP0_MVPCONTROL
248         ori     t0, t0, MVPCONTROL_VPC
249         mtc0    t0, CP0_MVPCONTROL
250 
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
256 
257         /* If there's only 1, we're done */
258         beqz    t0, 2f
259          nop
260 
261         /* Loop through each VPE within this core */
262         li      ta1, 1
263 
264 1:      /* Operate on the appropriate TC */
265         mtc0    ta1, CP0_VPECONTROL
266         ehb
267 
268         /* Bind TC to VPE (1:1 TC:VPE mapping) */
269         mttc0   ta1, CP0_TCBIND
270 
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
276 
277         /* Set TC non-active, non-allocatable */
278         mttc0   zero, CP0_TCSTATUS
279 
280         /* Set TC halted */
281         li      t0, TCHALT_H
282         mttc0   t0, CP0_TCHALT
283 
284         /* Next VPE */
285         addiu   ta1, ta1, 1
286         slt     t0, ta1, ta3
287         bnez    t0, 1b
288          nop
289 
290         /* Leave VPE configuration state */
291 2:      mfc0    t0, CP0_MVPCONTROL
292         xori    t0, t0, MVPCONTROL_VPC
293         mtc0    t0, CP0_MVPCONTROL
294 
295 3:      .set    pop
296 #endif
297         jr      ra
298          nop
299         END(mips_cps_core_init)
300 
301 /**
302  * mips_cps_get_bootcfg() - retrieve boot configuration pointers
303  *
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
316 
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
321 
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
331 
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
337 
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
345 
346         /* Retrieve the VPE ID from EBase.CPUNum */
347         mfc0    t9, $15, 1
348         and     t9, t9, t1
349 #endif
350 
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
356 
357         jr      ra
358          nop
359         END(mips_cps_get_bootcfg)
360 
361 LEAF(mips_cps_boot_vpes)
362         lw      ta2, COREBOOTCFG_VPEMASK(a0)
363         PTR_L   ta3, COREBOOTCFG_VPECONFIG(a0)
364 
365 #if defined(CONFIG_CPU_MIPSR6)
366 
367         has_vp  t0, 5f
368 
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
376 
377         /* Start any other VPs that ought to be running */
378         PTR_S   ta2, CPC_CL_VC_RUN_OFS(t1)
379 
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
384 
385 #elif defined(CONFIG_MIPS_MT)
386 
387         /* If the core doesn't support MT then return */
388         has_mt  t0, 5f
389 
390         /* Enter VPE configuration state */
391         .set    push
392         .set    MIPS_ISA_LEVEL_RAW
393         .set    mt
394         dvpe
395         .set    pop
396 
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
404 
405         /* Loop through each VPE */
406         move    t8, ta2
407         li      ta1, 0
408 
409         /* Check whether the VPE should be running. If not, skip it */
410 1:      andi    t0, ta2, 1
411         beqz    t0, 2f
412          nop
413 
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
421 
422         .set    push
423         .set    MIPS_ISA_LEVEL_RAW
424         .set    mt
425 
426         /* Skip the VPE if its TC is not halted */
427         mftc0   t0, CP0_TCHALT
428         beqz    t0, 2f
429          nop
430 
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
435 
436         /* Set the TC restart PC */
437         lw      t1, VPEBOOTCFG_PC(t0)
438         mttc0   t1, CP0_TCRESTART
439 
440         /* Set the TC stack pointer */
441         lw      t1, VPEBOOTCFG_SP(t0)
442         mttgpr  t1, sp
443 
444         /* Set the TC global pointer */
445         lw      t1, VPEBOOTCFG_GP(t0)
446         mttgpr  t1, gp
447 
448         /* Copy config from this VPE */
449         mfc0    t0, CP0_CONFIG
450         mttc0   t0, CP0_CONFIG
451 
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
466 3:
467         /* Ensure no software interrupts are pending */
468         mttc0   zero, CP0_CAUSE
469         mttc0   zero, CP0_STATUS
470 
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
477 
478         /* Clear the TC halt bit */
479         mttc0   zero, CP0_TCHALT
480 
481         /* Set VPE active */
482         mftc0   t0, CP0_VPECONF0
483         ori     t0, t0, VPECONF0_VPA
484         mttc0   t0, CP0_VPECONF0
485 
486         /* Next VPE */
487 2:      srl     ta2, ta2, 1
488         addiu   ta1, ta1, 1
489         bnez    ta2, 1b
490          nop
491 
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
498 
499         .set    pop
500 
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
507 
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
514 
515 2:
516 
517 #endif /* CONFIG_MIPS_MT_SMP */
518 
519         /* Return */
520 5:      jr      ra
521          nop
522         END(mips_cps_boot_vpes)
523 
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
536 
537         /* Primary cache configuration is indicated by Config1 */
538         mfc0    v0, CP0_CONFIG, 1
539 
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
545 
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
558 
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:
566 
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
572 
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
585 
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:
593 
594         jr      ra
595          nop
596         END(mips_cps_cache_init)
597 
598 #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
599 
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
613 
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)
622 
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)
629 
630 #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp