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

chipram.c (2690B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3**  linux/amiga/chipram.c
      4**
      5**      Modified 03-May-94 by Geert Uytterhoeven <geert@linux-m68k.org>
      6**          - 64-bit aligned allocations for full AGA compatibility
      7**
      8**	Rewritten 15/9/2000 by Geert to use resource management
      9*/
     10
     11#include <linux/types.h>
     12#include <linux/kernel.h>
     13#include <linux/mm.h>
     14#include <linux/init.h>
     15#include <linux/ioport.h>
     16#include <linux/slab.h>
     17#include <linux/string.h>
     18#include <linux/module.h>
     19
     20#include <asm/atomic.h>
     21#include <asm/page.h>
     22#include <asm/amigahw.h>
     23
     24unsigned long amiga_chip_size;
     25EXPORT_SYMBOL(amiga_chip_size);
     26
     27static struct resource chipram_res = {
     28	.name = "Chip RAM", .start = CHIP_PHYSADDR
     29};
     30static atomic_t chipavail;
     31
     32
     33void __init amiga_chip_init(void)
     34{
     35	if (!AMIGAHW_PRESENT(CHIP_RAM))
     36		return;
     37
     38	chipram_res.end = CHIP_PHYSADDR + amiga_chip_size - 1;
     39	request_resource(&iomem_resource, &chipram_res);
     40
     41	atomic_set(&chipavail, amiga_chip_size);
     42}
     43
     44
     45void *amiga_chip_alloc(unsigned long size, const char *name)
     46{
     47	struct resource *res;
     48	void *p;
     49
     50	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
     51	if (!res)
     52		return NULL;
     53
     54	res->name = name;
     55	p = amiga_chip_alloc_res(size, res);
     56	if (!p) {
     57		kfree(res);
     58		return NULL;
     59	}
     60
     61	return p;
     62}
     63EXPORT_SYMBOL(amiga_chip_alloc);
     64
     65
     66	/*
     67	 *  Warning:
     68	 *  amiga_chip_alloc_res is meant only for drivers that need to
     69	 *  allocate Chip RAM before kmalloc() is functional. As a consequence,
     70	 *  those drivers must not free that Chip RAM afterwards.
     71	 */
     72
     73void *amiga_chip_alloc_res(unsigned long size, struct resource *res)
     74{
     75	int error;
     76
     77	/* round up */
     78	size = PAGE_ALIGN(size);
     79
     80	pr_debug("amiga_chip_alloc_res: allocate %lu bytes\n", size);
     81	error = allocate_resource(&chipram_res, res, size, 0, UINT_MAX,
     82				  PAGE_SIZE, NULL, NULL);
     83	if (error < 0) {
     84		pr_err("amiga_chip_alloc_res: allocate_resource() failed %d!\n",
     85		       error);
     86		return NULL;
     87	}
     88
     89	atomic_sub(size, &chipavail);
     90	pr_debug("amiga_chip_alloc_res: returning %pR\n", res);
     91	return ZTWO_VADDR(res->start);
     92}
     93
     94void amiga_chip_free(void *ptr)
     95{
     96	unsigned long start = ZTWO_PADDR(ptr);
     97	struct resource *res;
     98	unsigned long size;
     99
    100	res = lookup_resource(&chipram_res, start);
    101	if (!res) {
    102		pr_err("amiga_chip_free: trying to free nonexistent region at "
    103		       "%p\n", ptr);
    104		return;
    105	}
    106
    107	size = resource_size(res);
    108	pr_debug("amiga_chip_free: free %lu bytes at %p\n", size, ptr);
    109	atomic_add(size, &chipavail);
    110	release_resource(res);
    111	kfree(res);
    112}
    113EXPORT_SYMBOL(amiga_chip_free);
    114
    115
    116unsigned long amiga_chip_avail(void)
    117{
    118	unsigned long n = atomic_read(&chipavail);
    119
    120	pr_debug("amiga_chip_avail : %lu bytes\n", n);
    121	return n;
    122}
    123EXPORT_SYMBOL(amiga_chip_avail);
    124