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

sram.c (4442B)


      1/*
      2 * Simple memory allocator for on-board SRAM
      3 *
      4 *
      5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
      6 *
      7 * Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
      8 *
      9 * This file is licensed under the terms of the GNU General Public License
     10 * version 2. This program is licensed "as is" without any warranty of any
     11 * kind, whether express or implied.
     12 */
     13
     14#include <linux/err.h>
     15#include <linux/kernel.h>
     16#include <linux/export.h>
     17#include <linux/slab.h>
     18#include <linux/spinlock.h>
     19#include <linux/string.h>
     20#include <linux/ioport.h>
     21#include <linux/of.h>
     22#include <linux/of_address.h>
     23
     24#include <asm/io.h>
     25#include <asm/mmu.h>
     26
     27#include <linux/fsl/bestcomm/sram.h>
     28
     29
     30/* Struct keeping our 'state' */
     31struct bcom_sram *bcom_sram = NULL;
     32EXPORT_SYMBOL_GPL(bcom_sram);	/* needed for inline functions */
     33
     34
     35/* ======================================================================== */
     36/* Public API                                                               */
     37/* ======================================================================== */
     38/* DO NOT USE in interrupts, if needed in irq handler, we should use the
     39   _irqsave version of the spin_locks */
     40
     41int bcom_sram_init(struct device_node *sram_node, char *owner)
     42{
     43	int rv;
     44	const u32 *regaddr_p;
     45	u64 regaddr64, size64;
     46	unsigned int psize;
     47
     48	/* Create our state struct */
     49	if (bcom_sram) {
     50		printk(KERN_ERR "%s: bcom_sram_init: "
     51			"Already initialized !\n", owner);
     52		return -EBUSY;
     53	}
     54
     55	bcom_sram = kmalloc(sizeof(struct bcom_sram), GFP_KERNEL);
     56	if (!bcom_sram) {
     57		printk(KERN_ERR "%s: bcom_sram_init: "
     58			"Couldn't allocate internal state !\n", owner);
     59		return -ENOMEM;
     60	}
     61
     62	/* Get address and size of the sram */
     63	regaddr_p = of_get_address(sram_node, 0, &size64, NULL);
     64	if (!regaddr_p) {
     65		printk(KERN_ERR "%s: bcom_sram_init: "
     66			"Invalid device node !\n", owner);
     67		rv = -EINVAL;
     68		goto error_free;
     69	}
     70
     71	regaddr64 = of_translate_address(sram_node, regaddr_p);
     72
     73	bcom_sram->base_phys = (phys_addr_t) regaddr64;
     74	bcom_sram->size = (unsigned int) size64;
     75
     76	/* Request region */
     77	if (!request_mem_region(bcom_sram->base_phys, bcom_sram->size, owner)) {
     78		printk(KERN_ERR "%s: bcom_sram_init: "
     79			"Couldn't request region !\n", owner);
     80		rv = -EBUSY;
     81		goto error_free;
     82	}
     83
     84	/* Map SRAM */
     85		/* sram is not really __iomem */
     86	bcom_sram->base_virt = (void*) ioremap(bcom_sram->base_phys, bcom_sram->size);
     87
     88	if (!bcom_sram->base_virt) {
     89		printk(KERN_ERR "%s: bcom_sram_init: "
     90			"Map error SRAM zone 0x%08lx (0x%0x)!\n",
     91			owner, (long)bcom_sram->base_phys, bcom_sram->size );
     92		rv = -ENOMEM;
     93		goto error_release;
     94	}
     95
     96	/* Create an rheap (defaults to 32 bits word alignment) */
     97	bcom_sram->rh = rh_create(4);
     98
     99	/* Attach the free zones */
    100#if 0
    101	/* Currently disabled ... for future use only */
    102	reg_addr_p = of_get_property(sram_node, "available", &psize);
    103#else
    104	regaddr_p = NULL;
    105	psize = 0;
    106#endif
    107
    108	if (!regaddr_p || !psize) {
    109		/* Attach the whole zone */
    110		rh_attach_region(bcom_sram->rh, 0, bcom_sram->size);
    111	} else {
    112		/* Attach each zone independently */
    113		while (psize >= 2 * sizeof(u32)) {
    114			phys_addr_t zbase = of_translate_address(sram_node, regaddr_p);
    115			rh_attach_region(bcom_sram->rh, zbase - bcom_sram->base_phys, regaddr_p[1]);
    116			regaddr_p += 2;
    117			psize -= 2 * sizeof(u32);
    118		}
    119	}
    120
    121	/* Init our spinlock */
    122	spin_lock_init(&bcom_sram->lock);
    123
    124	return 0;
    125
    126error_release:
    127	release_mem_region(bcom_sram->base_phys, bcom_sram->size);
    128error_free:
    129	kfree(bcom_sram);
    130	bcom_sram = NULL;
    131
    132	return rv;
    133}
    134EXPORT_SYMBOL_GPL(bcom_sram_init);
    135
    136void bcom_sram_cleanup(void)
    137{
    138	/* Free resources */
    139	if (bcom_sram) {
    140		rh_destroy(bcom_sram->rh);
    141		iounmap((void __iomem *)bcom_sram->base_virt);
    142		release_mem_region(bcom_sram->base_phys, bcom_sram->size);
    143		kfree(bcom_sram);
    144		bcom_sram = NULL;
    145	}
    146}
    147EXPORT_SYMBOL_GPL(bcom_sram_cleanup);
    148
    149void* bcom_sram_alloc(int size, int align, phys_addr_t *phys)
    150{
    151	unsigned long offset;
    152
    153	spin_lock(&bcom_sram->lock);
    154	offset = rh_alloc_align(bcom_sram->rh, size, align, NULL);
    155	spin_unlock(&bcom_sram->lock);
    156
    157	if (IS_ERR_VALUE(offset))
    158		return NULL;
    159
    160	*phys = bcom_sram->base_phys + offset;
    161	return bcom_sram->base_virt + offset;
    162}
    163EXPORT_SYMBOL_GPL(bcom_sram_alloc);
    164
    165void bcom_sram_free(void *ptr)
    166{
    167	unsigned long offset;
    168
    169	if (!ptr)
    170		return;
    171
    172	offset = ptr - bcom_sram->base_virt;
    173
    174	spin_lock(&bcom_sram->lock);
    175	rh_free(bcom_sram->rh, offset);
    176	spin_unlock(&bcom_sram->lock);
    177}
    178EXPORT_SYMBOL_GPL(bcom_sram_free);
    179