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 (8367B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *
      4 * OMAP SRAM detection and management
      5 *
      6 * Copyright (C) 2005 Nokia Corporation
      7 * Written by Tony Lindgren <tony@atomide.com>
      8 *
      9 * Copyright (C) 2009-2012 Texas Instruments
     10 * Added OMAP4/5 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
     11 */
     12
     13#include <linux/module.h>
     14#include <linux/kernel.h>
     15#include <linux/init.h>
     16#include <linux/io.h>
     17
     18#include <asm/fncpy.h>
     19#include <asm/tlb.h>
     20#include <asm/cacheflush.h>
     21#include <asm/set_memory.h>
     22
     23#include <asm/mach/map.h>
     24
     25#include "soc.h"
     26#include "iomap.h"
     27#include "prm2xxx_3xxx.h"
     28#include "sdrc.h"
     29#include "sram.h"
     30
     31#define OMAP2_SRAM_PUB_PA	(OMAP2_SRAM_PA + 0xf800)
     32#define OMAP3_SRAM_PUB_PA       (OMAP3_SRAM_PA + 0x8000)
     33
     34#define SRAM_BOOTLOADER_SZ	0x00
     35
     36#define OMAP24XX_VA_REQINFOPERM0	OMAP2_L3_IO_ADDRESS(0x68005048)
     37#define OMAP24XX_VA_READPERM0		OMAP2_L3_IO_ADDRESS(0x68005050)
     38#define OMAP24XX_VA_WRITEPERM0		OMAP2_L3_IO_ADDRESS(0x68005058)
     39
     40#define OMAP34XX_VA_REQINFOPERM0	OMAP2_L3_IO_ADDRESS(0x68012848)
     41#define OMAP34XX_VA_READPERM0		OMAP2_L3_IO_ADDRESS(0x68012850)
     42#define OMAP34XX_VA_WRITEPERM0		OMAP2_L3_IO_ADDRESS(0x68012858)
     43#define OMAP34XX_VA_ADDR_MATCH2		OMAP2_L3_IO_ADDRESS(0x68012880)
     44#define OMAP34XX_VA_SMS_RG_ATT0		OMAP2_L3_IO_ADDRESS(0x6C000048)
     45
     46#define GP_DEVICE		0x300
     47
     48#define ROUND_DOWN(value,boundary)	((value) & (~((boundary)-1)))
     49
     50static unsigned long omap_sram_start;
     51static unsigned long omap_sram_size;
     52static void __iomem *omap_sram_base;
     53static unsigned long omap_sram_skip;
     54static void __iomem *omap_sram_ceil;
     55
     56/*
     57 * Memory allocator for SRAM: calculates the new ceiling address
     58 * for pushing a function using the fncpy API.
     59 *
     60 * Note that fncpy requires the returned address to be aligned
     61 * to an 8-byte boundary.
     62 */
     63static void *omap_sram_push_address(unsigned long size)
     64{
     65	unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
     66
     67	available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);
     68
     69	if (size > available) {
     70		pr_err("Not enough space in SRAM\n");
     71		return NULL;
     72	}
     73
     74	new_ceil -= size;
     75	new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN);
     76	omap_sram_ceil = IOMEM(new_ceil);
     77
     78	return (void __force *)omap_sram_ceil;
     79}
     80
     81void *omap_sram_push(void *funcp, unsigned long size)
     82{
     83	void *sram;
     84	unsigned long base;
     85	int pages;
     86	void *dst = NULL;
     87
     88	sram = omap_sram_push_address(size);
     89	if (!sram)
     90		return NULL;
     91
     92	base = (unsigned long)sram & PAGE_MASK;
     93	pages = PAGE_ALIGN(size) / PAGE_SIZE;
     94
     95	set_memory_rw(base, pages);
     96
     97	dst = fncpy(sram, funcp, size);
     98
     99	set_memory_ro(base, pages);
    100	set_memory_x(base, pages);
    101
    102	return dst;
    103}
    104
    105/*
    106 * The SRAM context is lost during off-idle and stack
    107 * needs to be reset.
    108 */
    109static void omap_sram_reset(void)
    110{
    111	omap_sram_ceil = omap_sram_base + omap_sram_size;
    112}
    113
    114/*
    115 * Depending on the target RAMFS firewall setup, the public usable amount of
    116 * SRAM varies.  The default accessible size for all device types is 2k. A GP
    117 * device allows ARM11 but not other initiators for full size. This
    118 * functionality seems ok until some nice security API happens.
    119 */
    120static int is_sram_locked(void)
    121{
    122	if (OMAP2_DEVICE_TYPE_GP == omap_type()) {
    123		/* RAMFW: R/W access to all initiators for all qualifier sets */
    124		if (cpu_is_omap242x()) {
    125			writel_relaxed(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
    126			writel_relaxed(0xCFDE, OMAP24XX_VA_READPERM0);  /* all i-read */
    127			writel_relaxed(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
    128		}
    129		if (cpu_is_omap34xx()) {
    130			writel_relaxed(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
    131			writel_relaxed(0xFFFF, OMAP34XX_VA_READPERM0);  /* all i-read */
    132			writel_relaxed(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
    133			writel_relaxed(0x0, OMAP34XX_VA_ADDR_MATCH2);
    134			writel_relaxed(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0);
    135		}
    136		return 0;
    137	} else
    138		return 1; /* assume locked with no PPA or security driver */
    139}
    140
    141/*
    142 * The amount of SRAM depends on the core type.
    143 * Note that we cannot try to test for SRAM here because writes
    144 * to secure SRAM will hang the system. Also the SRAM is not
    145 * yet mapped at this point.
    146 */
    147static void __init omap_detect_sram(void)
    148{
    149	omap_sram_skip = SRAM_BOOTLOADER_SZ;
    150	if (is_sram_locked()) {
    151		if (cpu_is_omap34xx()) {
    152			omap_sram_start = OMAP3_SRAM_PUB_PA;
    153			if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||
    154			    (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {
    155				omap_sram_size = 0x7000; /* 28K */
    156				omap_sram_skip += SZ_16K;
    157			} else {
    158				omap_sram_size = 0x8000; /* 32K */
    159			}
    160		} else {
    161			omap_sram_start = OMAP2_SRAM_PUB_PA;
    162			omap_sram_size = 0x800; /* 2K */
    163		}
    164	} else {
    165		if (cpu_is_omap34xx()) {
    166			omap_sram_start = OMAP3_SRAM_PA;
    167			omap_sram_size = 0x10000; /* 64K */
    168		} else {
    169			omap_sram_start = OMAP2_SRAM_PA;
    170			if (cpu_is_omap242x())
    171				omap_sram_size = 0xa0000; /* 640K */
    172			else if (cpu_is_omap243x())
    173				omap_sram_size = 0x10000; /* 64K */
    174		}
    175	}
    176}
    177
    178/*
    179 * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
    180 */
    181static void __init omap2_map_sram(void)
    182{
    183	unsigned long base;
    184	int pages;
    185	int cached = 1;
    186
    187	if (cpu_is_omap34xx()) {
    188		/*
    189		 * SRAM must be marked as non-cached on OMAP3 since the
    190		 * CORE DPLL M2 divider change code (in SRAM) runs with the
    191		 * SDRAM controller disabled, and if it is marked cached,
    192		 * the ARM may attempt to write cache lines back to SDRAM
    193		 * which will cause the system to hang.
    194		 */
    195		cached = 0;
    196	}
    197
    198	if (omap_sram_size == 0)
    199		return;
    200
    201	omap_sram_start = ROUND_DOWN(omap_sram_start, PAGE_SIZE);
    202	omap_sram_base = __arm_ioremap_exec(omap_sram_start, omap_sram_size, cached);
    203	if (!omap_sram_base) {
    204		pr_err("SRAM: Could not map\n");
    205		return;
    206	}
    207
    208	omap_sram_reset();
    209
    210	/*
    211	 * Looks like we need to preserve some bootloader code at the
    212	 * beginning of SRAM for jumping to flash for reboot to work...
    213	 */
    214	memset_io(omap_sram_base + omap_sram_skip, 0,
    215		  omap_sram_size - omap_sram_skip);
    216
    217	base = (unsigned long)omap_sram_base;
    218	pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
    219
    220	set_memory_ro(base, pages);
    221	set_memory_x(base, pages);
    222}
    223
    224static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
    225			      u32 base_cs, u32 force_unlock);
    226
    227void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
    228		   u32 base_cs, u32 force_unlock)
    229{
    230	BUG_ON(!_omap2_sram_ddr_init);
    231	_omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
    232			     base_cs, force_unlock);
    233}
    234
    235static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
    236					  u32 mem_type);
    237
    238void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
    239{
    240	BUG_ON(!_omap2_sram_reprogram_sdrc);
    241	_omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
    242}
    243
    244static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
    245
    246u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
    247{
    248	BUG_ON(!_omap2_set_prcm);
    249	return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
    250}
    251
    252#ifdef CONFIG_SOC_OMAP2420
    253static int __init omap242x_sram_init(void)
    254{
    255	_omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init,
    256					omap242x_sram_ddr_init_sz);
    257
    258	_omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc,
    259					    omap242x_sram_reprogram_sdrc_sz);
    260
    261	_omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm,
    262					 omap242x_sram_set_prcm_sz);
    263
    264	return 0;
    265}
    266#else
    267static inline int omap242x_sram_init(void)
    268{
    269	return 0;
    270}
    271#endif
    272
    273#ifdef CONFIG_SOC_OMAP2430
    274static int __init omap243x_sram_init(void)
    275{
    276	_omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init,
    277					omap243x_sram_ddr_init_sz);
    278
    279	_omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc,
    280					    omap243x_sram_reprogram_sdrc_sz);
    281
    282	_omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm,
    283					 omap243x_sram_set_prcm_sz);
    284
    285	return 0;
    286}
    287#else
    288static inline int omap243x_sram_init(void)
    289{
    290	return 0;
    291}
    292#endif
    293
    294#ifdef CONFIG_ARCH_OMAP3
    295
    296void omap3_sram_restore_context(void)
    297{
    298	omap_sram_reset();
    299
    300	omap_push_sram_idle();
    301}
    302
    303static inline int omap34xx_sram_init(void)
    304{
    305	omap3_sram_restore_context();
    306	return 0;
    307}
    308#else
    309static inline int omap34xx_sram_init(void)
    310{
    311	return 0;
    312}
    313#endif /* CONFIG_ARCH_OMAP3 */
    314
    315int __init omap_sram_init(void)
    316{
    317	omap_detect_sram();
    318	omap2_map_sram();
    319
    320	if (cpu_is_omap242x())
    321		omap242x_sram_init();
    322	else if (cpu_is_omap2430())
    323		omap243x_sram_init();
    324	else if (cpu_is_omap34xx())
    325		omap34xx_sram_init();
    326
    327	return 0;
    328}