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

nvram.c (15414B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
      4 *
      5 *  Todo: - add support for the OF persistent properties
      6 */
      7#include <linux/export.h>
      8#include <linux/kernel.h>
      9#include <linux/stddef.h>
     10#include <linux/string.h>
     11#include <linux/nvram.h>
     12#include <linux/init.h>
     13#include <linux/delay.h>
     14#include <linux/errno.h>
     15#include <linux/adb.h>
     16#include <linux/pmu.h>
     17#include <linux/memblock.h>
     18#include <linux/completion.h>
     19#include <linux/spinlock.h>
     20#include <linux/of_address.h>
     21#include <asm/sections.h>
     22#include <asm/io.h>
     23#include <asm/machdep.h>
     24#include <asm/nvram.h>
     25
     26#include "pmac.h"
     27
     28#define DEBUG
     29
     30#ifdef DEBUG
     31#define DBG(x...) printk(x)
     32#else
     33#define DBG(x...)
     34#endif
     35
     36#define NVRAM_SIZE		0x2000	/* 8kB of non-volatile RAM */
     37
     38#define CORE99_SIGNATURE	0x5a
     39#define CORE99_ADLER_START	0x14
     40
     41/* On Core99, nvram is either a sharp, a micron or an AMD flash */
     42#define SM_FLASH_STATUS_DONE	0x80
     43#define SM_FLASH_STATUS_ERR	0x38
     44
     45#define SM_FLASH_CMD_ERASE_CONFIRM	0xd0
     46#define SM_FLASH_CMD_ERASE_SETUP	0x20
     47#define SM_FLASH_CMD_RESET		0xff
     48#define SM_FLASH_CMD_WRITE_SETUP	0x40
     49#define SM_FLASH_CMD_CLEAR_STATUS	0x50
     50#define SM_FLASH_CMD_READ_STATUS	0x70
     51
     52/* CHRP NVRAM header */
     53struct chrp_header {
     54  u8		signature;
     55  u8		cksum;
     56  u16		len;
     57  char          name[12];
     58  u8		data[];
     59};
     60
     61struct core99_header {
     62  struct chrp_header	hdr;
     63  u32			adler;
     64  u32			generation;
     65  u32			reserved[2];
     66};
     67
     68/*
     69 * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
     70 */
     71static int nvram_naddrs;
     72static volatile unsigned char __iomem *nvram_data;
     73static int is_core_99;
     74static int core99_bank;
     75static int nvram_partitions[3];
     76// XXX Turn that into a sem
     77static DEFINE_RAW_SPINLOCK(nv_lock);
     78
     79static int (*core99_write_bank)(int bank, u8* datas);
     80static int (*core99_erase_bank)(int bank);
     81
     82static char *nvram_image;
     83
     84
     85static unsigned char core99_nvram_read_byte(int addr)
     86{
     87	if (nvram_image == NULL)
     88		return 0xff;
     89	return nvram_image[addr];
     90}
     91
     92static void core99_nvram_write_byte(int addr, unsigned char val)
     93{
     94	if (nvram_image == NULL)
     95		return;
     96	nvram_image[addr] = val;
     97}
     98
     99static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
    100{
    101	int i;
    102
    103	if (nvram_image == NULL)
    104		return -ENODEV;
    105	if (*index > NVRAM_SIZE)
    106		return 0;
    107
    108	i = *index;
    109	if (i + count > NVRAM_SIZE)
    110		count = NVRAM_SIZE - i;
    111
    112	memcpy(buf, &nvram_image[i], count);
    113	*index = i + count;
    114	return count;
    115}
    116
    117static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
    118{
    119	int i;
    120
    121	if (nvram_image == NULL)
    122		return -ENODEV;
    123	if (*index > NVRAM_SIZE)
    124		return 0;
    125
    126	i = *index;
    127	if (i + count > NVRAM_SIZE)
    128		count = NVRAM_SIZE - i;
    129
    130	memcpy(&nvram_image[i], buf, count);
    131	*index = i + count;
    132	return count;
    133}
    134
    135static ssize_t core99_nvram_size(void)
    136{
    137	if (nvram_image == NULL)
    138		return -ENODEV;
    139	return NVRAM_SIZE;
    140}
    141
    142#ifdef CONFIG_PPC32
    143static volatile unsigned char __iomem *nvram_addr;
    144static int nvram_mult;
    145
    146static ssize_t ppc32_nvram_size(void)
    147{
    148	return NVRAM_SIZE;
    149}
    150
    151static unsigned char direct_nvram_read_byte(int addr)
    152{
    153	return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
    154}
    155
    156static void direct_nvram_write_byte(int addr, unsigned char val)
    157{
    158	out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
    159}
    160
    161
    162static unsigned char indirect_nvram_read_byte(int addr)
    163{
    164	unsigned char val;
    165	unsigned long flags;
    166
    167	raw_spin_lock_irqsave(&nv_lock, flags);
    168	out_8(nvram_addr, addr >> 5);
    169	val = in_8(&nvram_data[(addr & 0x1f) << 4]);
    170	raw_spin_unlock_irqrestore(&nv_lock, flags);
    171
    172	return val;
    173}
    174
    175static void indirect_nvram_write_byte(int addr, unsigned char val)
    176{
    177	unsigned long flags;
    178
    179	raw_spin_lock_irqsave(&nv_lock, flags);
    180	out_8(nvram_addr, addr >> 5);
    181	out_8(&nvram_data[(addr & 0x1f) << 4], val);
    182	raw_spin_unlock_irqrestore(&nv_lock, flags);
    183}
    184
    185
    186#ifdef CONFIG_ADB_PMU
    187
    188static void pmu_nvram_complete(struct adb_request *req)
    189{
    190	if (req->arg)
    191		complete((struct completion *)req->arg);
    192}
    193
    194static unsigned char pmu_nvram_read_byte(int addr)
    195{
    196	struct adb_request req;
    197	DECLARE_COMPLETION_ONSTACK(req_complete);
    198	
    199	req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
    200	if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
    201			(addr >> 8) & 0xff, addr & 0xff))
    202		return 0xff;
    203	if (system_state == SYSTEM_RUNNING)
    204		wait_for_completion(&req_complete);
    205	while (!req.complete)
    206		pmu_poll();
    207	return req.reply[0];
    208}
    209
    210static void pmu_nvram_write_byte(int addr, unsigned char val)
    211{
    212	struct adb_request req;
    213	DECLARE_COMPLETION_ONSTACK(req_complete);
    214	
    215	req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
    216	if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
    217			(addr >> 8) & 0xff, addr & 0xff, val))
    218		return;
    219	if (system_state == SYSTEM_RUNNING)
    220		wait_for_completion(&req_complete);
    221	while (!req.complete)
    222		pmu_poll();
    223}
    224
    225#endif /* CONFIG_ADB_PMU */
    226#endif /* CONFIG_PPC32 */
    227
    228static u8 chrp_checksum(struct chrp_header* hdr)
    229{
    230	u8 *ptr;
    231	u16 sum = hdr->signature;
    232	for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
    233		sum += *ptr;
    234	while (sum > 0xFF)
    235		sum = (sum & 0xFF) + (sum>>8);
    236	return sum;
    237}
    238
    239static u32 core99_calc_adler(u8 *buffer)
    240{
    241	int cnt;
    242	u32 low, high;
    243
    244   	buffer += CORE99_ADLER_START;
    245	low = 1;
    246	high = 0;
    247	for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
    248		if ((cnt % 5000) == 0) {
    249			high  %= 65521UL;
    250			high %= 65521UL;
    251		}
    252		low += buffer[cnt];
    253		high += low;
    254	}
    255	low  %= 65521UL;
    256	high %= 65521UL;
    257
    258	return (high << 16) | low;
    259}
    260
    261static u32 __init core99_check(u8 *datas)
    262{
    263	struct core99_header* hdr99 = (struct core99_header*)datas;
    264
    265	if (hdr99->hdr.signature != CORE99_SIGNATURE) {
    266		DBG("Invalid signature\n");
    267		return 0;
    268	}
    269	if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
    270		DBG("Invalid checksum\n");
    271		return 0;
    272	}
    273	if (hdr99->adler != core99_calc_adler(datas)) {
    274		DBG("Invalid adler\n");
    275		return 0;
    276	}
    277	return hdr99->generation;
    278}
    279
    280static int sm_erase_bank(int bank)
    281{
    282	int stat;
    283	unsigned long timeout;
    284
    285	u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
    286
    287       	DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
    288
    289	out_8(base, SM_FLASH_CMD_ERASE_SETUP);
    290	out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
    291	timeout = 0;
    292	do {
    293		if (++timeout > 1000000) {
    294			printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
    295			break;
    296		}
    297		out_8(base, SM_FLASH_CMD_READ_STATUS);
    298		stat = in_8(base);
    299	} while (!(stat & SM_FLASH_STATUS_DONE));
    300
    301	out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
    302	out_8(base, SM_FLASH_CMD_RESET);
    303
    304	if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
    305		printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
    306		return -ENXIO;
    307	}
    308	return 0;
    309}
    310
    311static int sm_write_bank(int bank, u8* datas)
    312{
    313	int i, stat = 0;
    314	unsigned long timeout;
    315
    316	u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
    317
    318       	DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
    319
    320	for (i=0; i<NVRAM_SIZE; i++) {
    321		out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
    322		udelay(1);
    323		out_8(base+i, datas[i]);
    324		timeout = 0;
    325		do {
    326			if (++timeout > 1000000) {
    327				printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
    328				break;
    329			}
    330			out_8(base, SM_FLASH_CMD_READ_STATUS);
    331			stat = in_8(base);
    332		} while (!(stat & SM_FLASH_STATUS_DONE));
    333		if (!(stat & SM_FLASH_STATUS_DONE))
    334			break;
    335	}
    336	out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
    337	out_8(base, SM_FLASH_CMD_RESET);
    338	if (memcmp(base, datas, NVRAM_SIZE)) {
    339		printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
    340		return -ENXIO;
    341	}
    342	return 0;
    343}
    344
    345static int amd_erase_bank(int bank)
    346{
    347	int stat = 0;
    348	unsigned long timeout;
    349
    350	u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
    351
    352       	DBG("nvram: AMD Erasing bank %d...\n", bank);
    353
    354	/* Unlock 1 */
    355	out_8(base+0x555, 0xaa);
    356	udelay(1);
    357	/* Unlock 2 */
    358	out_8(base+0x2aa, 0x55);
    359	udelay(1);
    360
    361	/* Sector-Erase */
    362	out_8(base+0x555, 0x80);
    363	udelay(1);
    364	out_8(base+0x555, 0xaa);
    365	udelay(1);
    366	out_8(base+0x2aa, 0x55);
    367	udelay(1);
    368	out_8(base, 0x30);
    369	udelay(1);
    370
    371	timeout = 0;
    372	do {
    373		if (++timeout > 1000000) {
    374			printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
    375			break;
    376		}
    377		stat = in_8(base) ^ in_8(base);
    378	} while (stat != 0);
    379	
    380	/* Reset */
    381	out_8(base, 0xf0);
    382	udelay(1);
    383
    384	if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
    385		printk(KERN_ERR "nvram: AMD flash erase failed !\n");
    386		return -ENXIO;
    387	}
    388	return 0;
    389}
    390
    391static int amd_write_bank(int bank, u8* datas)
    392{
    393	int i, stat = 0;
    394	unsigned long timeout;
    395
    396	u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
    397
    398       	DBG("nvram: AMD Writing bank %d...\n", bank);
    399
    400	for (i=0; i<NVRAM_SIZE; i++) {
    401		/* Unlock 1 */
    402		out_8(base+0x555, 0xaa);
    403		udelay(1);
    404		/* Unlock 2 */
    405		out_8(base+0x2aa, 0x55);
    406		udelay(1);
    407
    408		/* Write single word */
    409		out_8(base+0x555, 0xa0);
    410		udelay(1);
    411		out_8(base+i, datas[i]);
    412		
    413		timeout = 0;
    414		do {
    415			if (++timeout > 1000000) {
    416				printk(KERN_ERR "nvram: AMD flash write timeout !\n");
    417				break;
    418			}
    419			stat = in_8(base) ^ in_8(base);
    420		} while (stat != 0);
    421		if (stat != 0)
    422			break;
    423	}
    424
    425	/* Reset */
    426	out_8(base, 0xf0);
    427	udelay(1);
    428
    429	if (memcmp(base, datas, NVRAM_SIZE)) {
    430		printk(KERN_ERR "nvram: AMD flash write failed !\n");
    431		return -ENXIO;
    432	}
    433	return 0;
    434}
    435
    436static void __init lookup_partitions(void)
    437{
    438	u8 buffer[17];
    439	int i, offset;
    440	struct chrp_header* hdr;
    441
    442	if (pmac_newworld) {
    443		nvram_partitions[pmac_nvram_OF] = -1;
    444		nvram_partitions[pmac_nvram_XPRAM] = -1;
    445		nvram_partitions[pmac_nvram_NR] = -1;
    446		hdr = (struct chrp_header *)buffer;
    447
    448		offset = 0;
    449		buffer[16] = 0;
    450		do {
    451			for (i=0;i<16;i++)
    452				buffer[i] = ppc_md.nvram_read_val(offset+i);
    453			if (!strcmp(hdr->name, "common"))
    454				nvram_partitions[pmac_nvram_OF] = offset + 0x10;
    455			if (!strcmp(hdr->name, "APL,MacOS75")) {
    456				nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
    457				nvram_partitions[pmac_nvram_NR] = offset + 0x110;
    458			}
    459			offset += (hdr->len * 0x10);
    460		} while(offset < NVRAM_SIZE);
    461	} else {
    462		nvram_partitions[pmac_nvram_OF] = 0x1800;
    463		nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
    464		nvram_partitions[pmac_nvram_NR] = 0x1400;
    465	}
    466	DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
    467	DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
    468	DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
    469}
    470
    471static void core99_nvram_sync(void)
    472{
    473	struct core99_header* hdr99;
    474	unsigned long flags;
    475
    476	if (!is_core_99 || !nvram_data || !nvram_image)
    477		return;
    478
    479	raw_spin_lock_irqsave(&nv_lock, flags);
    480	if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
    481		NVRAM_SIZE))
    482		goto bail;
    483
    484	DBG("Updating nvram...\n");
    485
    486	hdr99 = (struct core99_header*)nvram_image;
    487	hdr99->generation++;
    488	hdr99->hdr.signature = CORE99_SIGNATURE;
    489	hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
    490	hdr99->adler = core99_calc_adler(nvram_image);
    491	core99_bank = core99_bank ? 0 : 1;
    492	if (core99_erase_bank)
    493		if (core99_erase_bank(core99_bank)) {
    494			printk("nvram: Error erasing bank %d\n", core99_bank);
    495			goto bail;
    496		}
    497	if (core99_write_bank)
    498		if (core99_write_bank(core99_bank, nvram_image))
    499			printk("nvram: Error writing bank %d\n", core99_bank);
    500 bail:
    501	raw_spin_unlock_irqrestore(&nv_lock, flags);
    502
    503#ifdef DEBUG
    504       	mdelay(2000);
    505#endif
    506}
    507
    508static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
    509{
    510	int i;
    511	u32 gen_bank0, gen_bank1;
    512
    513	if (nvram_naddrs < 1) {
    514		printk(KERN_ERR "nvram: no address\n");
    515		return -EINVAL;
    516	}
    517	nvram_image = memblock_alloc(NVRAM_SIZE, SMP_CACHE_BYTES);
    518	if (!nvram_image)
    519		panic("%s: Failed to allocate %u bytes\n", __func__,
    520		      NVRAM_SIZE);
    521	nvram_data = ioremap(addr, NVRAM_SIZE*2);
    522	nvram_naddrs = 1; /* Make sure we get the correct case */
    523
    524	DBG("nvram: Checking bank 0...\n");
    525
    526	gen_bank0 = core99_check((u8 *)nvram_data);
    527	gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
    528	core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
    529
    530	DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
    531	DBG("nvram: Active bank is: %d\n", core99_bank);
    532
    533	for (i=0; i<NVRAM_SIZE; i++)
    534		nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
    535
    536	ppc_md.nvram_read_val	= core99_nvram_read_byte;
    537	ppc_md.nvram_write_val	= core99_nvram_write_byte;
    538	ppc_md.nvram_read	= core99_nvram_read;
    539	ppc_md.nvram_write	= core99_nvram_write;
    540	ppc_md.nvram_size	= core99_nvram_size;
    541	ppc_md.nvram_sync	= core99_nvram_sync;
    542	ppc_md.machine_shutdown	= core99_nvram_sync;
    543	/* 
    544	 * Maybe we could be smarter here though making an exclusive list
    545	 * of known flash chips is a bit nasty as older OF didn't provide us
    546	 * with a useful "compatible" entry. A solution would be to really
    547	 * identify the chip using flash id commands and base ourselves on
    548	 * a list of known chips IDs
    549	 */
    550	if (of_device_is_compatible(dp, "amd-0137")) {
    551		core99_erase_bank = amd_erase_bank;
    552		core99_write_bank = amd_write_bank;
    553	} else {
    554		core99_erase_bank = sm_erase_bank;
    555		core99_write_bank = sm_write_bank;
    556	}
    557	return 0;
    558}
    559
    560int __init pmac_nvram_init(void)
    561{
    562	struct device_node *dp;
    563	struct resource r1, r2;
    564	unsigned int s1 = 0, s2 = 0;
    565	int err = 0;
    566
    567	nvram_naddrs = 0;
    568
    569	dp = of_find_node_by_name(NULL, "nvram");
    570	if (dp == NULL) {
    571		printk(KERN_ERR "Can't find NVRAM device\n");
    572		return -ENODEV;
    573	}
    574
    575	/* Try to obtain an address */
    576	if (of_address_to_resource(dp, 0, &r1) == 0) {
    577		nvram_naddrs = 1;
    578		s1 = resource_size(&r1);
    579		if (of_address_to_resource(dp, 1, &r2) == 0) {
    580			nvram_naddrs = 2;
    581			s2 = resource_size(&r2);
    582		}
    583	}
    584
    585	is_core_99 = of_device_is_compatible(dp, "nvram,flash");
    586	if (is_core_99) {
    587		err = core99_nvram_setup(dp, r1.start);
    588		goto bail;
    589	}
    590
    591#ifdef CONFIG_PPC32
    592	if (machine_is(chrp) && nvram_naddrs == 1) {
    593		nvram_data = ioremap(r1.start, s1);
    594		nvram_mult = 1;
    595		ppc_md.nvram_read_val	= direct_nvram_read_byte;
    596		ppc_md.nvram_write_val	= direct_nvram_write_byte;
    597		ppc_md.nvram_size	= ppc32_nvram_size;
    598	} else if (nvram_naddrs == 1) {
    599		nvram_data = ioremap(r1.start, s1);
    600		nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
    601		ppc_md.nvram_read_val	= direct_nvram_read_byte;
    602		ppc_md.nvram_write_val	= direct_nvram_write_byte;
    603		ppc_md.nvram_size	= ppc32_nvram_size;
    604	} else if (nvram_naddrs == 2) {
    605		nvram_addr = ioremap(r1.start, s1);
    606		nvram_data = ioremap(r2.start, s2);
    607		ppc_md.nvram_read_val	= indirect_nvram_read_byte;
    608		ppc_md.nvram_write_val	= indirect_nvram_write_byte;
    609		ppc_md.nvram_size	= ppc32_nvram_size;
    610	} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
    611#ifdef CONFIG_ADB_PMU
    612		nvram_naddrs = -1;
    613		ppc_md.nvram_read_val	= pmu_nvram_read_byte;
    614		ppc_md.nvram_write_val	= pmu_nvram_write_byte;
    615		ppc_md.nvram_size	= ppc32_nvram_size;
    616#endif /* CONFIG_ADB_PMU */
    617	} else {
    618		printk(KERN_ERR "Incompatible type of NVRAM\n");
    619		err = -ENXIO;
    620	}
    621#endif /* CONFIG_PPC32 */
    622bail:
    623	of_node_put(dp);
    624	if (err == 0)
    625		lookup_partitions();
    626	return err;
    627}
    628
    629int pmac_get_partition(int partition)
    630{
    631	return nvram_partitions[partition];
    632}
    633
    634u8 pmac_xpram_read(int xpaddr)
    635{
    636	int offset = pmac_get_partition(pmac_nvram_XPRAM);
    637
    638	if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
    639		return 0xff;
    640
    641	return ppc_md.nvram_read_val(xpaddr + offset);
    642}
    643
    644void pmac_xpram_write(int xpaddr, u8 data)
    645{
    646	int offset = pmac_get_partition(pmac_nvram_XPRAM);
    647
    648	if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
    649		return;
    650
    651	ppc_md.nvram_write_val(xpaddr + offset, data);
    652}
    653
    654EXPORT_SYMBOL(pmac_get_partition);
    655EXPORT_SYMBOL(pmac_xpram_read);
    656EXPORT_SYMBOL(pmac_xpram_write);