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

memory.c (4306B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * memory.c: PROM library functions for acquiring/using memory descriptors
      4 *	     given to us from the ARCS firmware.
      5 *
      6 * Copyright (C) 1996 by David S. Miller
      7 * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
      8 * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
      9 *
     10 * PROM library functions for acquiring/using memory descriptors given to us
     11 * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
     12 * because on some machines like SGI IP27 the ARC memory configuration data
     13 * completely bogus and alternate easier to use mechanisms are available.
     14 */
     15#include <linux/init.h>
     16#include <linux/kernel.h>
     17#include <linux/types.h>
     18#include <linux/sched.h>
     19#include <linux/mm.h>
     20#include <linux/memblock.h>
     21#include <linux/swap.h>
     22
     23#include <asm/sgialib.h>
     24#include <asm/page.h>
     25#include <asm/bootinfo.h>
     26
     27#undef DEBUG
     28
     29#define MAX_PROM_MEM 5
     30static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
     31static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
     32static unsigned int nr_prom_mem __initdata;
     33
     34/*
     35 * For ARC firmware memory functions the unit of measuring memory is always
     36 * a 4k page of memory
     37 */
     38#define ARC_PAGE_SHIFT	12
     39
     40struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
     41{
     42	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
     43}
     44
     45#ifdef DEBUG /* convenient for debugging */
     46static char *arcs_mtypes[8] = {
     47	"Exception Block",
     48	"ARCS Romvec Page",
     49	"Free/Contig RAM",
     50	"Generic Free RAM",
     51	"Bad Memory",
     52	"Standalone Program Pages",
     53	"ARCS Temp Storage Area",
     54	"ARCS Permanent Storage Area"
     55};
     56
     57static char *arc_mtypes[8] = {
     58	"Exception Block",
     59	"SystemParameterBlock",
     60	"FreeMemory",
     61	"Bad Memory",
     62	"LoadedProgram",
     63	"FirmwareTemporary",
     64	"FirmwarePermanent",
     65	"FreeContiguous"
     66};
     67#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
     68						: arc_mtypes[a.arc]
     69#endif
     70
     71enum {
     72	mem_free, mem_prom_used, mem_reserved
     73};
     74
     75static inline int memtype_classify_arcs(union linux_memtypes type)
     76{
     77	switch (type.arcs) {
     78	case arcs_fcontig:
     79	case arcs_free:
     80		return mem_free;
     81	case arcs_atmp:
     82		return mem_prom_used;
     83	case arcs_eblock:
     84	case arcs_rvpage:
     85	case arcs_bmem:
     86	case arcs_prog:
     87	case arcs_aperm:
     88		return mem_reserved;
     89	default:
     90		BUG();
     91	}
     92	while(1);				/* Nuke warning.  */
     93}
     94
     95static inline int memtype_classify_arc(union linux_memtypes type)
     96{
     97	switch (type.arc) {
     98	case arc_free:
     99	case arc_fcontig:
    100		return mem_free;
    101	case arc_atmp:
    102		return mem_prom_used;
    103	case arc_eblock:
    104	case arc_rvpage:
    105	case arc_bmem:
    106	case arc_prog:
    107	case arc_aperm:
    108		return mem_reserved;
    109	default:
    110		BUG();
    111	}
    112	while(1);				/* Nuke warning.  */
    113}
    114
    115static int __init prom_memtype_classify(union linux_memtypes type)
    116{
    117	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ... */
    118		return memtype_classify_arcs(type);
    119
    120	return memtype_classify_arc(type);
    121}
    122
    123void __weak __init prom_meminit(void)
    124{
    125	struct linux_mdesc *p;
    126
    127#ifdef DEBUG
    128	int i = 0;
    129
    130	printk("ARCS MEMORY DESCRIPTOR dump:\n");
    131	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
    132	while(p) {
    133		printk("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
    134		       i, p, p->base, p->pages, mtypes(p->type));
    135		p = ArcGetMemoryDescriptor(p);
    136		i++;
    137	}
    138#endif
    139
    140	nr_prom_mem = 0;
    141	p = PROM_NULL_MDESC;
    142	while ((p = ArcGetMemoryDescriptor(p))) {
    143		unsigned long base, size;
    144		long type;
    145
    146		base = p->base << ARC_PAGE_SHIFT;
    147		size = p->pages << ARC_PAGE_SHIFT;
    148		type = prom_memtype_classify(p->type);
    149
    150		/* ignore mirrored RAM on IP28/IP30 */
    151		if (base < PHYS_OFFSET)
    152			continue;
    153
    154		memblock_add(base, size);
    155
    156		if (type == mem_reserved)
    157			memblock_reserve(base, size);
    158
    159		if (type == mem_prom_used) {
    160			memblock_reserve(base, size);
    161			if (nr_prom_mem >= 5) {
    162				pr_err("Too many ROM DATA regions");
    163				continue;
    164			}
    165			prom_mem_base[nr_prom_mem] = base;
    166			prom_mem_size[nr_prom_mem] = size;
    167			nr_prom_mem++;
    168		}
    169	}
    170}
    171
    172void __weak __init prom_cleanup(void)
    173{
    174}
    175
    176void __init prom_free_prom_memory(void)
    177{
    178	int i;
    179
    180	if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
    181		return;
    182
    183	for (i = 0; i < nr_prom_mem; i++) {
    184		free_init_pages("prom memory",
    185			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
    186	}
    187	/*
    188	 * at this point it isn't safe to call PROM functions
    189	 * give platforms a way to do PROM cleanups
    190	 */
    191	prom_cleanup();
    192}