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

tcm.c (3855B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3#include <linux/highmem.h>
      4#include <linux/genalloc.h>
      5#include <asm/tlbflush.h>
      6#include <asm/fixmap.h>
      7
      8#if (CONFIG_ITCM_RAM_BASE == 0xffffffff)
      9#error "You should define ITCM_RAM_BASE"
     10#endif
     11
     12#ifdef CONFIG_HAVE_DTCM
     13#if (CONFIG_DTCM_RAM_BASE == 0xffffffff)
     14#error "You should define DTCM_RAM_BASE"
     15#endif
     16
     17#if (CONFIG_DTCM_RAM_BASE == CONFIG_ITCM_RAM_BASE)
     18#error "You should define correct DTCM_RAM_BASE"
     19#endif
     20#endif
     21
     22extern char __tcm_start, __tcm_end, __dtcm_start;
     23
     24static struct gen_pool *tcm_pool;
     25
     26static void __init tcm_mapping_init(void)
     27{
     28	pte_t *tcm_pte;
     29	unsigned long vaddr, paddr;
     30	int i;
     31
     32	paddr = CONFIG_ITCM_RAM_BASE;
     33
     34	if (pfn_valid(PFN_DOWN(CONFIG_ITCM_RAM_BASE)))
     35		goto panic;
     36
     37#ifndef CONFIG_HAVE_DTCM
     38	for (i = 0; i < TCM_NR_PAGES; i++) {
     39#else
     40	for (i = 0; i < CONFIG_ITCM_NR_PAGES; i++) {
     41#endif
     42		vaddr = __fix_to_virt(FIX_TCM - i);
     43
     44		tcm_pte =
     45			pte_offset_kernel((pmd_t *)pgd_offset_k(vaddr), vaddr);
     46
     47		set_pte(tcm_pte, pfn_pte(__phys_to_pfn(paddr), PAGE_KERNEL));
     48
     49		flush_tlb_one(vaddr);
     50
     51		paddr = paddr + PAGE_SIZE;
     52	}
     53
     54#ifdef CONFIG_HAVE_DTCM
     55	if (pfn_valid(PFN_DOWN(CONFIG_DTCM_RAM_BASE)))
     56		goto panic;
     57
     58	paddr = CONFIG_DTCM_RAM_BASE;
     59
     60	for (i = 0; i < CONFIG_DTCM_NR_PAGES; i++) {
     61		vaddr = __fix_to_virt(FIX_TCM - CONFIG_ITCM_NR_PAGES - i);
     62
     63		tcm_pte =
     64			pte_offset_kernel((pmd_t *) pgd_offset_k(vaddr), vaddr);
     65
     66		set_pte(tcm_pte, pfn_pte(__phys_to_pfn(paddr), PAGE_KERNEL));
     67
     68		flush_tlb_one(vaddr);
     69
     70		paddr = paddr + PAGE_SIZE;
     71	}
     72#endif
     73
     74#ifndef CONFIG_HAVE_DTCM
     75	memcpy((void *)__fix_to_virt(FIX_TCM),
     76				&__tcm_start, &__tcm_end - &__tcm_start);
     77
     78	pr_info("%s: mapping tcm va:0x%08lx to pa:0x%08x\n",
     79			__func__, __fix_to_virt(FIX_TCM), CONFIG_ITCM_RAM_BASE);
     80
     81	pr_info("%s: __tcm_start va:0x%08lx size:%d\n",
     82			__func__, (unsigned long)&__tcm_start, &__tcm_end - &__tcm_start);
     83#else
     84	memcpy((void *)__fix_to_virt(FIX_TCM),
     85				&__tcm_start, &__dtcm_start - &__tcm_start);
     86
     87	pr_info("%s: mapping itcm va:0x%08lx to pa:0x%08x\n",
     88			__func__, __fix_to_virt(FIX_TCM), CONFIG_ITCM_RAM_BASE);
     89
     90	pr_info("%s: __itcm_start va:0x%08lx size:%d\n",
     91			__func__, (unsigned long)&__tcm_start, &__dtcm_start - &__tcm_start);
     92
     93	memcpy((void *)__fix_to_virt(FIX_TCM - CONFIG_ITCM_NR_PAGES),
     94				&__dtcm_start, &__tcm_end - &__dtcm_start);
     95
     96	pr_info("%s: mapping dtcm va:0x%08lx to pa:0x%08x\n",
     97			__func__, __fix_to_virt(FIX_TCM - CONFIG_ITCM_NR_PAGES),
     98						CONFIG_DTCM_RAM_BASE);
     99
    100	pr_info("%s: __dtcm_start va:0x%08lx size:%d\n",
    101			__func__, (unsigned long)&__dtcm_start, &__tcm_end - &__dtcm_start);
    102
    103#endif
    104	return;
    105panic:
    106	panic("TCM init error");
    107}
    108
    109void *tcm_alloc(size_t len)
    110{
    111	unsigned long vaddr;
    112
    113	if (!tcm_pool)
    114		return NULL;
    115
    116	vaddr = gen_pool_alloc(tcm_pool, len);
    117	if (!vaddr)
    118		return NULL;
    119
    120	return (void *) vaddr;
    121}
    122EXPORT_SYMBOL(tcm_alloc);
    123
    124void tcm_free(void *addr, size_t len)
    125{
    126	gen_pool_free(tcm_pool, (unsigned long) addr, len);
    127}
    128EXPORT_SYMBOL(tcm_free);
    129
    130static int __init tcm_setup_pool(void)
    131{
    132#ifndef CONFIG_HAVE_DTCM
    133	u32 pool_size = (u32) (TCM_NR_PAGES * PAGE_SIZE)
    134				- (u32) (&__tcm_end - &__tcm_start);
    135
    136	u32 tcm_pool_start = __fix_to_virt(FIX_TCM)
    137				+ (u32) (&__tcm_end - &__tcm_start);
    138#else
    139	u32 pool_size = (u32) (CONFIG_DTCM_NR_PAGES * PAGE_SIZE)
    140				- (u32) (&__tcm_end - &__dtcm_start);
    141
    142	u32 tcm_pool_start = __fix_to_virt(FIX_TCM - CONFIG_ITCM_NR_PAGES)
    143				+ (u32) (&__tcm_end - &__dtcm_start);
    144#endif
    145	int ret;
    146
    147	tcm_pool = gen_pool_create(2, -1);
    148
    149	ret = gen_pool_add(tcm_pool, tcm_pool_start, pool_size, -1);
    150	if (ret) {
    151		pr_err("%s: gen_pool add failed!\n", __func__);
    152		return ret;
    153	}
    154
    155	pr_info("%s: Added %d bytes @ 0x%08x to memory pool\n",
    156		__func__, pool_size, tcm_pool_start);
    157
    158	return 0;
    159}
    160
    161static int __init tcm_init(void)
    162{
    163	tcm_mapping_init();
    164
    165	tcm_setup_pool();
    166
    167	return 0;
    168}
    169arch_initcall(tcm_init);