^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Cache flushing routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * David Mosberger-Tang <davidm@hpl.hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * 05/28/05 Zoltan Menyhart Dynamic stride size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * flush_icache_range(start,end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Make i-cache(s) coherent with d-caches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Must deal with range from start to end-1 but nothing else (need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * be careful not to touch addresses that may be unmapped).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Note: "in0" and "in1" are preserved for debugging purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .section .kprobes.text,"ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) GLOBAL_ENTRY(flush_icache_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .prologue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) alloc r2=ar.pfs,2,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) movl r3=ia64_i_cache_stride_shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) mov r21=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ld8 r20=[r3] // r20: stride shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) sub r22=in1,r0,1 // last byte address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) shr.u r23=in0,r20 // start / (stride size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) shr.u r22=r22,r20 // (last byte address) / (stride size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) shl r21=r21,r20 // r21: stride size of the i-cache(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) sub r8=r22,r23 // number of strides - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) shl r24=r23,r20 // r24: addresses for "fc.i" =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) // "start" rounded down to stride boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .save ar.lc,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) mov r3=ar.lc // save ar.lc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .body
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) mov ar.lc=r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * 32 byte aligned loop, even number of (actually 2) bundles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .Loop: fc.i r24 // issuable on M0 only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) add r24=r21,r24 // we flush "stride size" bytes per iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) nop.i 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) br.cloop.sptk.few .Loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) sync.i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) srlz.i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mov ar.lc=r3 // restore ar.lc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) br.ret.sptk.many rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) END(flush_icache_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) EXPORT_SYMBOL_GPL(flush_icache_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * clflush_cache_range(start,size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Flush cache lines from start to start+size-1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Must deal with range from start to start+size-1 but nothing else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * (need to be careful not to touch addresses that may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * unmapped).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Note: "in0" and "in1" are preserved for debugging purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .section .kprobes.text,"ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) GLOBAL_ENTRY(clflush_cache_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .prologue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) alloc r2=ar.pfs,2,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) movl r3=ia64_cache_stride_shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mov r21=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) add r22=in1,in0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ld8 r20=[r3] // r20: stride shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) sub r22=r22,r0,1 // last byte address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) shr.u r23=in0,r20 // start / (stride size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) shr.u r22=r22,r20 // (last byte address) / (stride size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) shl r21=r21,r20 // r21: stride size of the i-cache(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sub r8=r22,r23 // number of strides - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) shl r24=r23,r20 // r24: addresses for "fc" =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) // "start" rounded down to stride
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) // boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .save ar.lc,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) mov r3=ar.lc // save ar.lc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .body
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) mov ar.lc=r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * 32 byte aligned loop, even number of (actually 2) bundles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .Loop_fc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) fc r24 // issuable on M0 only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) add r24=r21,r24 // we flush "stride size" bytes per iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) nop.i 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) br.cloop.sptk.few .Loop_fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) sync.i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) srlz.i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ;;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mov ar.lc=r3 // restore ar.lc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) br.ret.sptk.many rp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) END(clflush_cache_range)