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

tlb-sh4.c (2598B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * arch/sh/mm/tlb-sh4.c
      4 *
      5 * SH-4 specific TLB operations
      6 *
      7 * Copyright (C) 1999  Niibe Yutaka
      8 * Copyright (C) 2002 - 2007 Paul Mundt
      9 */
     10#include <linux/kernel.h>
     11#include <linux/mm.h>
     12#include <linux/io.h>
     13#include <asm/mmu_context.h>
     14#include <asm/cacheflush.h>
     15
     16void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
     17{
     18	unsigned long flags, pteval, vpn;
     19
     20	/*
     21	 * Handle debugger faulting in for debugee.
     22	 */
     23	if (vma && current->active_mm != vma->vm_mm)
     24		return;
     25
     26	local_irq_save(flags);
     27
     28	/* Set PTEH register */
     29	vpn = (address & MMU_VPN_MASK) | get_asid();
     30	__raw_writel(vpn, MMU_PTEH);
     31
     32	pteval = pte.pte_low;
     33
     34	/* Set PTEA register */
     35#ifdef CONFIG_X2TLB
     36	/*
     37	 * For the extended mode TLB this is trivial, only the ESZ and
     38	 * EPR bits need to be written out to PTEA, with the remainder of
     39	 * the protection bits (with the exception of the compat-mode SZ
     40	 * and PR bits, which are cleared) being written out in PTEL.
     41	 */
     42	__raw_writel(pte.pte_high, MMU_PTEA);
     43#else
     44	if (cpu_data->flags & CPU_HAS_PTEA) {
     45		/* The last 3 bits and the first one of pteval contains
     46		 * the PTEA timing control and space attribute bits
     47		 */
     48		__raw_writel(copy_ptea_attributes(pteval), MMU_PTEA);
     49	}
     50#endif
     51
     52	/* Set PTEL register */
     53	pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
     54#ifdef CONFIG_CACHE_WRITETHROUGH
     55	pteval |= _PAGE_WT;
     56#endif
     57	/* conveniently, we want all the software flags to be 0 anyway */
     58	__raw_writel(pteval, MMU_PTEL);
     59
     60	/* Load the TLB */
     61	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
     62	local_irq_restore(flags);
     63}
     64
     65void local_flush_tlb_one(unsigned long asid, unsigned long page)
     66{
     67	unsigned long addr, data;
     68
     69	/*
     70	 * NOTE: PTEH.ASID should be set to this MM
     71	 *       _AND_ we need to write ASID to the array.
     72	 *
     73	 * It would be simple if we didn't need to set PTEH.ASID...
     74	 */
     75	addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT;
     76	data = page | asid; /* VALID bit is off */
     77	jump_to_uncached();
     78	__raw_writel(data, addr);
     79	back_to_cached();
     80}
     81
     82void local_flush_tlb_all(void)
     83{
     84	unsigned long flags, status;
     85	int i;
     86
     87	/*
     88	 * Flush all the TLB.
     89	 */
     90	local_irq_save(flags);
     91	jump_to_uncached();
     92
     93	status = __raw_readl(MMUCR);
     94	status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT);
     95
     96	if (status == 0)
     97		status = MMUCR_URB_NENTRIES;
     98
     99	for (i = 0; i < status; i++)
    100		__raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8));
    101
    102	for (i = 0; i < 4; i++)
    103		__raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8));
    104
    105	back_to_cached();
    106	ctrl_barrier();
    107	local_irq_restore(flags);
    108}