cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

flush-sh4.c (2689B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/mm.h>
      3#include <asm/mmu_context.h>
      4#include <asm/cache_insns.h>
      5#include <asm/cacheflush.h>
      6#include <asm/traps.h>
      7
      8/*
      9 * Write back the dirty D-caches, but not invalidate them.
     10 *
     11 * START: Virtual Address (U0, P1, or P3)
     12 * SIZE: Size of the region.
     13 */
     14static void sh4__flush_wback_region(void *start, int size)
     15{
     16	reg_size_t aligned_start, v, cnt, end;
     17
     18	aligned_start = register_align(start);
     19	v = aligned_start & ~(L1_CACHE_BYTES-1);
     20	end = (aligned_start + size + L1_CACHE_BYTES-1)
     21		& ~(L1_CACHE_BYTES-1);
     22	cnt = (end - v) / L1_CACHE_BYTES;
     23
     24	while (cnt >= 8) {
     25		__ocbwb(v); v += L1_CACHE_BYTES;
     26		__ocbwb(v); v += L1_CACHE_BYTES;
     27		__ocbwb(v); v += L1_CACHE_BYTES;
     28		__ocbwb(v); v += L1_CACHE_BYTES;
     29		__ocbwb(v); v += L1_CACHE_BYTES;
     30		__ocbwb(v); v += L1_CACHE_BYTES;
     31		__ocbwb(v); v += L1_CACHE_BYTES;
     32		__ocbwb(v); v += L1_CACHE_BYTES;
     33		cnt -= 8;
     34	}
     35
     36	while (cnt) {
     37		__ocbwb(v); v += L1_CACHE_BYTES;
     38		cnt--;
     39	}
     40}
     41
     42/*
     43 * Write back the dirty D-caches and invalidate them.
     44 *
     45 * START: Virtual Address (U0, P1, or P3)
     46 * SIZE: Size of the region.
     47 */
     48static void sh4__flush_purge_region(void *start, int size)
     49{
     50	reg_size_t aligned_start, v, cnt, end;
     51
     52	aligned_start = register_align(start);
     53	v = aligned_start & ~(L1_CACHE_BYTES-1);
     54	end = (aligned_start + size + L1_CACHE_BYTES-1)
     55		& ~(L1_CACHE_BYTES-1);
     56	cnt = (end - v) / L1_CACHE_BYTES;
     57
     58	while (cnt >= 8) {
     59		__ocbp(v); v += L1_CACHE_BYTES;
     60		__ocbp(v); v += L1_CACHE_BYTES;
     61		__ocbp(v); v += L1_CACHE_BYTES;
     62		__ocbp(v); v += L1_CACHE_BYTES;
     63		__ocbp(v); v += L1_CACHE_BYTES;
     64		__ocbp(v); v += L1_CACHE_BYTES;
     65		__ocbp(v); v += L1_CACHE_BYTES;
     66		__ocbp(v); v += L1_CACHE_BYTES;
     67		cnt -= 8;
     68	}
     69	while (cnt) {
     70		__ocbp(v); v += L1_CACHE_BYTES;
     71		cnt--;
     72	}
     73}
     74
     75/*
     76 * No write back please
     77 */
     78static void sh4__flush_invalidate_region(void *start, int size)
     79{
     80	reg_size_t aligned_start, v, cnt, end;
     81
     82	aligned_start = register_align(start);
     83	v = aligned_start & ~(L1_CACHE_BYTES-1);
     84	end = (aligned_start + size + L1_CACHE_BYTES-1)
     85		& ~(L1_CACHE_BYTES-1);
     86	cnt = (end - v) / L1_CACHE_BYTES;
     87
     88	while (cnt >= 8) {
     89		__ocbi(v); v += L1_CACHE_BYTES;
     90		__ocbi(v); v += L1_CACHE_BYTES;
     91		__ocbi(v); v += L1_CACHE_BYTES;
     92		__ocbi(v); v += L1_CACHE_BYTES;
     93		__ocbi(v); v += L1_CACHE_BYTES;
     94		__ocbi(v); v += L1_CACHE_BYTES;
     95		__ocbi(v); v += L1_CACHE_BYTES;
     96		__ocbi(v); v += L1_CACHE_BYTES;
     97		cnt -= 8;
     98	}
     99
    100	while (cnt) {
    101		__ocbi(v); v += L1_CACHE_BYTES;
    102		cnt--;
    103	}
    104}
    105
    106void __init sh4__flush_region_init(void)
    107{
    108	__flush_wback_region		= sh4__flush_wback_region;
    109	__flush_invalidate_region	= sh4__flush_invalidate_region;
    110	__flush_purge_region		= sh4__flush_purge_region;
    111}