162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * viking.S: High speed Viking cache/mmu operations 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) 662306a36Sopenharmony_ci * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) 762306a36Sopenharmony_ci * Copyright (C) 1999 Pavel Semerad (semerad@ss1000.ms.mff.cuni.cz) 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <asm/ptrace.h> 1162306a36Sopenharmony_ci#include <asm/psr.h> 1262306a36Sopenharmony_ci#include <asm/asm-offsets.h> 1362306a36Sopenharmony_ci#include <asm/asi.h> 1462306a36Sopenharmony_ci#include <asm/mxcc.h> 1562306a36Sopenharmony_ci#include <asm/page.h> 1662306a36Sopenharmony_ci#include <asm/pgtable.h> 1762306a36Sopenharmony_ci#include <asm/pgtsrmmu.h> 1862306a36Sopenharmony_ci#include <asm/viking.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#ifdef CONFIG_SMP 2162306a36Sopenharmony_ci .data 2262306a36Sopenharmony_ci .align 4 2362306a36Sopenharmony_cisun4dsmp_flush_tlb_spin: 2462306a36Sopenharmony_ci .word 0 2562306a36Sopenharmony_ci#endif 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci .text 2862306a36Sopenharmony_ci .align 4 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci .globl viking_flush_cache_all, viking_flush_cache_mm 3162306a36Sopenharmony_ci .globl viking_flush_cache_range, viking_flush_cache_page 3262306a36Sopenharmony_ci .globl viking_flush_page, viking_mxcc_flush_page 3362306a36Sopenharmony_ci .globl viking_flush_page_for_dma, viking_flush_page_to_ram 3462306a36Sopenharmony_ci .globl viking_flush_sig_insns 3562306a36Sopenharmony_ci .globl viking_flush_tlb_all, viking_flush_tlb_mm 3662306a36Sopenharmony_ci .globl viking_flush_tlb_range, viking_flush_tlb_page 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_civiking_flush_page: 3962306a36Sopenharmony_ci sethi %hi(PAGE_OFFSET), %g2 4062306a36Sopenharmony_ci sub %o0, %g2, %g3 4162306a36Sopenharmony_ci srl %g3, 12, %g1 ! ppage >> 12 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci clr %o1 ! set counter, 0 - 127 4462306a36Sopenharmony_ci sethi %hi(PAGE_OFFSET + PAGE_SIZE - 0x80000000), %o3 4562306a36Sopenharmony_ci sethi %hi(0x80000000), %o4 4662306a36Sopenharmony_ci sethi %hi(VIKING_PTAG_VALID), %o5 4762306a36Sopenharmony_ci sethi %hi(2*PAGE_SIZE), %o0 4862306a36Sopenharmony_ci sethi %hi(PAGE_SIZE), %g7 4962306a36Sopenharmony_ci clr %o2 ! block counter, 0 - 3 5062306a36Sopenharmony_ci5: 5162306a36Sopenharmony_ci sll %o1, 5, %g4 5262306a36Sopenharmony_ci or %g4, %o4, %g4 ! 0x80000000 | (set << 5) 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci sll %o2, 26, %g5 ! block << 26 5562306a36Sopenharmony_ci6: 5662306a36Sopenharmony_ci or %g5, %g4, %g5 5762306a36Sopenharmony_ci ldda [%g5] ASI_M_DATAC_TAG, %g2 5862306a36Sopenharmony_ci cmp %g3, %g1 ! ptag == ppage? 5962306a36Sopenharmony_ci bne 7f 6062306a36Sopenharmony_ci inc %o2 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci andcc %g2, %o5, %g0 ! ptag VALID? 6362306a36Sopenharmony_ci be 7f 6462306a36Sopenharmony_ci add %g4, %o3, %g2 ! (PAGE_OFFSET + PAGE_SIZE) | (set << 5) 6562306a36Sopenharmony_ci ld [%g2], %g3 6662306a36Sopenharmony_ci ld [%g2 + %g7], %g3 6762306a36Sopenharmony_ci add %g2, %o0, %g2 6862306a36Sopenharmony_ci ld [%g2], %g3 6962306a36Sopenharmony_ci ld [%g2 + %g7], %g3 7062306a36Sopenharmony_ci add %g2, %o0, %g2 7162306a36Sopenharmony_ci ld [%g2], %g3 7262306a36Sopenharmony_ci ld [%g2 + %g7], %g3 7362306a36Sopenharmony_ci add %g2, %o0, %g2 7462306a36Sopenharmony_ci ld [%g2], %g3 7562306a36Sopenharmony_ci b 8f 7662306a36Sopenharmony_ci ld [%g2 + %g7], %g3 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci7: 7962306a36Sopenharmony_ci cmp %o2, 3 8062306a36Sopenharmony_ci ble 6b 8162306a36Sopenharmony_ci sll %o2, 26, %g5 ! block << 26 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci8: inc %o1 8462306a36Sopenharmony_ci cmp %o1, 0x7f 8562306a36Sopenharmony_ci ble 5b 8662306a36Sopenharmony_ci clr %o2 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci9: retl 8962306a36Sopenharmony_ci nop 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_civiking_mxcc_flush_page: 9262306a36Sopenharmony_ci sethi %hi(PAGE_OFFSET), %g2 9362306a36Sopenharmony_ci sub %o0, %g2, %g3 9462306a36Sopenharmony_ci sub %g3, -PAGE_SIZE, %g3 ! ppage + PAGE_SIZE 9562306a36Sopenharmony_ci sethi %hi(MXCC_SRCSTREAM), %o3 ! assume %hi(MXCC_SRCSTREAM) == %hi(MXCC_DESTSTREAM) 9662306a36Sopenharmony_ci mov 0x10, %g2 ! set cacheable bit 9762306a36Sopenharmony_ci or %o3, %lo(MXCC_SRCSTREAM), %o2 9862306a36Sopenharmony_ci or %o3, %lo(MXCC_DESSTREAM), %o3 9962306a36Sopenharmony_ci sub %g3, MXCC_STREAM_SIZE, %g3 10062306a36Sopenharmony_ci6: 10162306a36Sopenharmony_ci stda %g2, [%o2] ASI_M_MXCC 10262306a36Sopenharmony_ci stda %g2, [%o3] ASI_M_MXCC 10362306a36Sopenharmony_ci andncc %g3, PAGE_MASK, %g0 10462306a36Sopenharmony_ci bne 6b 10562306a36Sopenharmony_ci sub %g3, MXCC_STREAM_SIZE, %g3 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci9: retl 10862306a36Sopenharmony_ci nop 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_civiking_flush_cache_page: 11162306a36Sopenharmony_civiking_flush_cache_range: 11262306a36Sopenharmony_ci#ifndef CONFIG_SMP 11362306a36Sopenharmony_ci ld [%o0 + VMA_VM_MM], %o0 11462306a36Sopenharmony_ci#endif 11562306a36Sopenharmony_civiking_flush_cache_mm: 11662306a36Sopenharmony_ci#ifndef CONFIG_SMP 11762306a36Sopenharmony_ci ld [%o0 + AOFF_mm_context], %g1 11862306a36Sopenharmony_ci cmp %g1, -1 11962306a36Sopenharmony_ci bne viking_flush_cache_all 12062306a36Sopenharmony_ci nop 12162306a36Sopenharmony_ci b,a viking_flush_cache_out 12262306a36Sopenharmony_ci#endif 12362306a36Sopenharmony_civiking_flush_cache_all: 12462306a36Sopenharmony_ci WINDOW_FLUSH(%g4, %g5) 12562306a36Sopenharmony_civiking_flush_cache_out: 12662306a36Sopenharmony_ci retl 12762306a36Sopenharmony_ci nop 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_civiking_flush_tlb_all: 13062306a36Sopenharmony_ci mov 0x400, %g1 13162306a36Sopenharmony_ci retl 13262306a36Sopenharmony_ci sta %g0, [%g1] ASI_M_FLUSH_PROBE 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_civiking_flush_tlb_mm: 13562306a36Sopenharmony_ci mov SRMMU_CTX_REG, %g1 13662306a36Sopenharmony_ci ld [%o0 + AOFF_mm_context], %o1 13762306a36Sopenharmony_ci lda [%g1] ASI_M_MMUREGS, %g5 13862306a36Sopenharmony_ci#ifndef CONFIG_SMP 13962306a36Sopenharmony_ci cmp %o1, -1 14062306a36Sopenharmony_ci be 1f 14162306a36Sopenharmony_ci#endif 14262306a36Sopenharmony_ci mov 0x300, %g2 14362306a36Sopenharmony_ci sta %o1, [%g1] ASI_M_MMUREGS 14462306a36Sopenharmony_ci sta %g0, [%g2] ASI_M_FLUSH_PROBE 14562306a36Sopenharmony_ci retl 14662306a36Sopenharmony_ci sta %g5, [%g1] ASI_M_MMUREGS 14762306a36Sopenharmony_ci#ifndef CONFIG_SMP 14862306a36Sopenharmony_ci1: retl 14962306a36Sopenharmony_ci nop 15062306a36Sopenharmony_ci#endif 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_civiking_flush_tlb_range: 15362306a36Sopenharmony_ci ld [%o0 + VMA_VM_MM], %o0 15462306a36Sopenharmony_ci mov SRMMU_CTX_REG, %g1 15562306a36Sopenharmony_ci ld [%o0 + AOFF_mm_context], %o3 15662306a36Sopenharmony_ci lda [%g1] ASI_M_MMUREGS, %g5 15762306a36Sopenharmony_ci#ifndef CONFIG_SMP 15862306a36Sopenharmony_ci cmp %o3, -1 15962306a36Sopenharmony_ci be 2f 16062306a36Sopenharmony_ci#endif 16162306a36Sopenharmony_ci sethi %hi(~((1 << PGDIR_SHIFT) - 1)), %o4 16262306a36Sopenharmony_ci sta %o3, [%g1] ASI_M_MMUREGS 16362306a36Sopenharmony_ci and %o1, %o4, %o1 16462306a36Sopenharmony_ci add %o1, 0x200, %o1 16562306a36Sopenharmony_ci sta %g0, [%o1] ASI_M_FLUSH_PROBE 16662306a36Sopenharmony_ci1: sub %o1, %o4, %o1 16762306a36Sopenharmony_ci cmp %o1, %o2 16862306a36Sopenharmony_ci blu,a 1b 16962306a36Sopenharmony_ci sta %g0, [%o1] ASI_M_FLUSH_PROBE 17062306a36Sopenharmony_ci retl 17162306a36Sopenharmony_ci sta %g5, [%g1] ASI_M_MMUREGS 17262306a36Sopenharmony_ci#ifndef CONFIG_SMP 17362306a36Sopenharmony_ci2: retl 17462306a36Sopenharmony_ci nop 17562306a36Sopenharmony_ci#endif 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_civiking_flush_tlb_page: 17862306a36Sopenharmony_ci ld [%o0 + VMA_VM_MM], %o0 17962306a36Sopenharmony_ci mov SRMMU_CTX_REG, %g1 18062306a36Sopenharmony_ci ld [%o0 + AOFF_mm_context], %o3 18162306a36Sopenharmony_ci lda [%g1] ASI_M_MMUREGS, %g5 18262306a36Sopenharmony_ci#ifndef CONFIG_SMP 18362306a36Sopenharmony_ci cmp %o3, -1 18462306a36Sopenharmony_ci be 1f 18562306a36Sopenharmony_ci#endif 18662306a36Sopenharmony_ci and %o1, PAGE_MASK, %o1 18762306a36Sopenharmony_ci sta %o3, [%g1] ASI_M_MMUREGS 18862306a36Sopenharmony_ci sta %g0, [%o1] ASI_M_FLUSH_PROBE 18962306a36Sopenharmony_ci retl 19062306a36Sopenharmony_ci sta %g5, [%g1] ASI_M_MMUREGS 19162306a36Sopenharmony_ci#ifndef CONFIG_SMP 19262306a36Sopenharmony_ci1: retl 19362306a36Sopenharmony_ci nop 19462306a36Sopenharmony_ci#endif 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_civiking_flush_page_to_ram: 19762306a36Sopenharmony_civiking_flush_page_for_dma: 19862306a36Sopenharmony_civiking_flush_sig_insns: 19962306a36Sopenharmony_ci retl 20062306a36Sopenharmony_ci nop 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci#ifdef CONFIG_SMP 20362306a36Sopenharmony_ci .globl sun4dsmp_flush_tlb_all, sun4dsmp_flush_tlb_mm 20462306a36Sopenharmony_ci .globl sun4dsmp_flush_tlb_range, sun4dsmp_flush_tlb_page 20562306a36Sopenharmony_cisun4dsmp_flush_tlb_all: 20662306a36Sopenharmony_ci sethi %hi(sun4dsmp_flush_tlb_spin), %g3 20762306a36Sopenharmony_ci1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 20862306a36Sopenharmony_ci tst %g5 20962306a36Sopenharmony_ci bne 2f 21062306a36Sopenharmony_ci mov 0x400, %g1 21162306a36Sopenharmony_ci sta %g0, [%g1] ASI_M_FLUSH_PROBE 21262306a36Sopenharmony_ci retl 21362306a36Sopenharmony_ci stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)] 21462306a36Sopenharmony_ci2: tst %g5 21562306a36Sopenharmony_ci bne,a 2b 21662306a36Sopenharmony_ci ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 21762306a36Sopenharmony_ci b,a 1b 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cisun4dsmp_flush_tlb_mm: 22062306a36Sopenharmony_ci sethi %hi(sun4dsmp_flush_tlb_spin), %g3 22162306a36Sopenharmony_ci1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 22262306a36Sopenharmony_ci tst %g5 22362306a36Sopenharmony_ci bne 2f 22462306a36Sopenharmony_ci mov SRMMU_CTX_REG, %g1 22562306a36Sopenharmony_ci ld [%o0 + AOFF_mm_context], %o1 22662306a36Sopenharmony_ci lda [%g1] ASI_M_MMUREGS, %g5 22762306a36Sopenharmony_ci mov 0x300, %g2 22862306a36Sopenharmony_ci sta %o1, [%g1] ASI_M_MMUREGS 22962306a36Sopenharmony_ci sta %g0, [%g2] ASI_M_FLUSH_PROBE 23062306a36Sopenharmony_ci sta %g5, [%g1] ASI_M_MMUREGS 23162306a36Sopenharmony_ci retl 23262306a36Sopenharmony_ci stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)] 23362306a36Sopenharmony_ci2: tst %g5 23462306a36Sopenharmony_ci bne,a 2b 23562306a36Sopenharmony_ci ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 23662306a36Sopenharmony_ci b,a 1b 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_cisun4dsmp_flush_tlb_range: 23962306a36Sopenharmony_ci sethi %hi(sun4dsmp_flush_tlb_spin), %g3 24062306a36Sopenharmony_ci1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 24162306a36Sopenharmony_ci tst %g5 24262306a36Sopenharmony_ci bne 3f 24362306a36Sopenharmony_ci mov SRMMU_CTX_REG, %g1 24462306a36Sopenharmony_ci ld [%o0 + VMA_VM_MM], %o0 24562306a36Sopenharmony_ci ld [%o0 + AOFF_mm_context], %o3 24662306a36Sopenharmony_ci lda [%g1] ASI_M_MMUREGS, %g5 24762306a36Sopenharmony_ci sethi %hi(~((1 << PGDIR_SHIFT) - 1)), %o4 24862306a36Sopenharmony_ci sta %o3, [%g1] ASI_M_MMUREGS 24962306a36Sopenharmony_ci and %o1, %o4, %o1 25062306a36Sopenharmony_ci add %o1, 0x200, %o1 25162306a36Sopenharmony_ci sta %g0, [%o1] ASI_M_FLUSH_PROBE 25262306a36Sopenharmony_ci2: sub %o1, %o4, %o1 25362306a36Sopenharmony_ci cmp %o1, %o2 25462306a36Sopenharmony_ci blu,a 2b 25562306a36Sopenharmony_ci sta %g0, [%o1] ASI_M_FLUSH_PROBE 25662306a36Sopenharmony_ci sta %g5, [%g1] ASI_M_MMUREGS 25762306a36Sopenharmony_ci retl 25862306a36Sopenharmony_ci stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)] 25962306a36Sopenharmony_ci3: tst %g5 26062306a36Sopenharmony_ci bne,a 3b 26162306a36Sopenharmony_ci ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 26262306a36Sopenharmony_ci b,a 1b 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cisun4dsmp_flush_tlb_page: 26562306a36Sopenharmony_ci sethi %hi(sun4dsmp_flush_tlb_spin), %g3 26662306a36Sopenharmony_ci1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 26762306a36Sopenharmony_ci tst %g5 26862306a36Sopenharmony_ci bne 2f 26962306a36Sopenharmony_ci mov SRMMU_CTX_REG, %g1 27062306a36Sopenharmony_ci ld [%o0 + VMA_VM_MM], %o0 27162306a36Sopenharmony_ci ld [%o0 + AOFF_mm_context], %o3 27262306a36Sopenharmony_ci lda [%g1] ASI_M_MMUREGS, %g5 27362306a36Sopenharmony_ci and %o1, PAGE_MASK, %o1 27462306a36Sopenharmony_ci sta %o3, [%g1] ASI_M_MMUREGS 27562306a36Sopenharmony_ci sta %g0, [%o1] ASI_M_FLUSH_PROBE 27662306a36Sopenharmony_ci sta %g5, [%g1] ASI_M_MMUREGS 27762306a36Sopenharmony_ci retl 27862306a36Sopenharmony_ci stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)] 27962306a36Sopenharmony_ci2: tst %g5 28062306a36Sopenharmony_ci bne,a 2b 28162306a36Sopenharmony_ci ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5 28262306a36Sopenharmony_ci b,a 1b 28362306a36Sopenharmony_ci nop 28462306a36Sopenharmony_ci#endif 285