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

nwflash.c (13092B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Flash memory interface rev.5 driver for the Intel
      4 * Flash chips used on the NetWinder.
      5 *
      6 * 20/08/2000	RMK	use __ioremap to map flash into virtual memory
      7 *			make a few more places use "volatile"
      8 * 22/05/2001	RMK	- Lock read against write
      9 *			- merge printk level changes (with mods) from Alan Cox.
     10 *			- use *ppos as the file position, not file->f_pos.
     11 *			- fix check for out of range pos and r/w size
     12 *
     13 * Please note that we are tampering with the only flash chip in the
     14 * machine, which contains the bootup code.  We therefore have the
     15 * power to convert these machines into doorstops...
     16 */
     17
     18#include <linux/module.h>
     19#include <linux/types.h>
     20#include <linux/fs.h>
     21#include <linux/errno.h>
     22#include <linux/mm.h>
     23#include <linux/delay.h>
     24#include <linux/proc_fs.h>
     25#include <linux/miscdevice.h>
     26#include <linux/spinlock.h>
     27#include <linux/rwsem.h>
     28#include <linux/init.h>
     29#include <linux/mutex.h>
     30#include <linux/jiffies.h>
     31
     32#include <asm/hardware/dec21285.h>
     33#include <asm/io.h>
     34#include <asm/mach-types.h>
     35#include <linux/uaccess.h>
     36
     37/*****************************************************************************/
     38#include <asm/nwflash.h>
     39
     40#define	NWFLASH_VERSION "6.4"
     41
     42static DEFINE_MUTEX(flash_mutex);
     43static void kick_open(void);
     44static int get_flash_id(void);
     45static int erase_block(int nBlock);
     46static int write_block(unsigned long p, const char __user *buf, int count);
     47
     48#define KFLASH_SIZE	1024*1024	//1 Meg
     49#define KFLASH_SIZE4	4*1024*1024	//4 Meg
     50#define KFLASH_ID	0x89A6		//Intel flash
     51#define KFLASH_ID4	0xB0D4		//Intel flash 4Meg
     52
     53static bool flashdebug;		//if set - we will display progress msgs
     54
     55static int gbWriteEnable;
     56static int gbWriteBase64Enable;
     57static volatile unsigned char *FLASH_BASE;
     58static int gbFlashSize = KFLASH_SIZE;
     59static DEFINE_MUTEX(nwflash_mutex);
     60
     61static int get_flash_id(void)
     62{
     63	volatile unsigned int c1, c2;
     64
     65	/*
     66	 * try to get flash chip ID
     67	 */
     68	kick_open();
     69	c2 = inb(0x80);
     70	*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x90;
     71	udelay(15);
     72	c1 = *(volatile unsigned char *) FLASH_BASE;
     73	c2 = inb(0x80);
     74
     75	/*
     76	 * on 4 Meg flash the second byte is actually at offset 2...
     77	 */
     78	if (c1 == 0xB0)
     79		c2 = *(volatile unsigned char *) (FLASH_BASE + 2);
     80	else
     81		c2 = *(volatile unsigned char *) (FLASH_BASE + 1);
     82
     83	c2 += (c1 << 8);
     84
     85	/*
     86	 * set it back to read mode
     87	 */
     88	*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
     89
     90	if (c2 == KFLASH_ID4)
     91		gbFlashSize = KFLASH_SIZE4;
     92
     93	return c2;
     94}
     95
     96static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
     97{
     98	mutex_lock(&flash_mutex);
     99	switch (cmd) {
    100	case CMD_WRITE_DISABLE:
    101		gbWriteBase64Enable = 0;
    102		gbWriteEnable = 0;
    103		break;
    104
    105	case CMD_WRITE_ENABLE:
    106		gbWriteEnable = 1;
    107		break;
    108
    109	case CMD_WRITE_BASE64K_ENABLE:
    110		gbWriteBase64Enable = 1;
    111		break;
    112
    113	default:
    114		gbWriteBase64Enable = 0;
    115		gbWriteEnable = 0;
    116		mutex_unlock(&flash_mutex);
    117		return -EINVAL;
    118	}
    119	mutex_unlock(&flash_mutex);
    120	return 0;
    121}
    122
    123static ssize_t flash_read(struct file *file, char __user *buf, size_t size,
    124			  loff_t *ppos)
    125{
    126	ssize_t ret;
    127
    128	if (flashdebug)
    129		printk(KERN_DEBUG "flash_read: flash_read: offset=0x%llx, "
    130		       "buffer=%p, count=0x%zx.\n", *ppos, buf, size);
    131	/*
    132	 * We now lock against reads and writes. --rmk
    133	 */
    134	if (mutex_lock_interruptible(&nwflash_mutex))
    135		return -ERESTARTSYS;
    136
    137	ret = simple_read_from_buffer(buf, size, ppos, (void *)FLASH_BASE, gbFlashSize);
    138	mutex_unlock(&nwflash_mutex);
    139
    140	return ret;
    141}
    142
    143static ssize_t flash_write(struct file *file, const char __user *buf,
    144			   size_t size, loff_t * ppos)
    145{
    146	unsigned long p = *ppos;
    147	unsigned int count = size;
    148	int written;
    149	int nBlock, temp, rc;
    150	int i, j;
    151
    152	if (flashdebug)
    153		printk("flash_write: offset=0x%lX, buffer=0x%p, count=0x%X.\n",
    154		       p, buf, count);
    155
    156	if (!gbWriteEnable)
    157		return -EINVAL;
    158
    159	if (p < 64 * 1024 && (!gbWriteBase64Enable))
    160		return -EINVAL;
    161
    162	/*
    163	 * check for out of range pos or count
    164	 */
    165	if (p >= gbFlashSize)
    166		return count ? -ENXIO : 0;
    167
    168	if (count > gbFlashSize - p)
    169		count = gbFlashSize - p;
    170			
    171	if (!access_ok(buf, count))
    172		return -EFAULT;
    173
    174	/*
    175	 * We now lock against reads and writes. --rmk
    176	 */
    177	if (mutex_lock_interruptible(&nwflash_mutex))
    178		return -ERESTARTSYS;
    179
    180	written = 0;
    181
    182	nBlock = (int) p >> 16;	//block # of 64K bytes
    183
    184	/*
    185	 * # of 64K blocks to erase and write
    186	 */
    187	temp = ((int) (p + count) >> 16) - nBlock + 1;
    188
    189	/*
    190	 * write ends at exactly 64k boundary?
    191	 */
    192	if (((int) (p + count) & 0xFFFF) == 0)
    193		temp -= 1;
    194
    195	if (flashdebug)
    196		printk(KERN_DEBUG "flash_write: writing %d block(s) "
    197			"starting at %d.\n", temp, nBlock);
    198
    199	for (; temp; temp--, nBlock++) {
    200		if (flashdebug)
    201			printk(KERN_DEBUG "flash_write: erasing block %d.\n", nBlock);
    202
    203		/*
    204		 * first we have to erase the block(s), where we will write...
    205		 */
    206		i = 0;
    207		j = 0;
    208	  RetryBlock:
    209		do {
    210			rc = erase_block(nBlock);
    211			i++;
    212		} while (rc && i < 10);
    213
    214		if (rc) {
    215			printk(KERN_ERR "flash_write: erase error %x\n", rc);
    216			break;
    217		}
    218		if (flashdebug)
    219			printk(KERN_DEBUG "flash_write: writing offset %lX, "
    220			       "from buf %p, bytes left %X.\n", p, buf,
    221			       count - written);
    222
    223		/*
    224		 * write_block will limit write to space left in this block
    225		 */
    226		rc = write_block(p, buf, count - written);
    227		j++;
    228
    229		/*
    230		 * if somehow write verify failed? Can't happen??
    231		 */
    232		if (!rc) {
    233			/*
    234			 * retry up to 10 times
    235			 */
    236			if (j < 10)
    237				goto RetryBlock;
    238			else
    239				/*
    240				 * else quit with error...
    241				 */
    242				rc = -1;
    243
    244		}
    245		if (rc < 0) {
    246			printk(KERN_ERR "flash_write: write error %X\n", rc);
    247			break;
    248		}
    249		p += rc;
    250		buf += rc;
    251		written += rc;
    252		*ppos += rc;
    253
    254		if (flashdebug)
    255			printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written);
    256	}
    257
    258	mutex_unlock(&nwflash_mutex);
    259
    260	return written;
    261}
    262
    263
    264/*
    265 * The memory devices use the full 32/64 bits of the offset, and so we cannot
    266 * check against negative addresses: they are ok. The return value is weird,
    267 * though, in that case (0).
    268 *
    269 * also note that seeking relative to the "end of file" isn't supported:
    270 * it has no meaning, so it returns -EINVAL.
    271 */
    272static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
    273{
    274	loff_t ret;
    275
    276	mutex_lock(&flash_mutex);
    277	if (flashdebug)
    278		printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
    279		       (unsigned int) offset, orig);
    280
    281	ret = no_seek_end_llseek_size(file, offset, orig, gbFlashSize);
    282	mutex_unlock(&flash_mutex);
    283	return ret;
    284}
    285
    286
    287/*
    288 * assume that main Write routine did the parameter checking...
    289 * so just go ahead and erase, what requested!
    290 */
    291
    292static int erase_block(int nBlock)
    293{
    294	volatile unsigned int c1;
    295	volatile unsigned char *pWritePtr;
    296	unsigned long timeout;
    297	int temp, temp1;
    298
    299	/*
    300	 * reset footbridge to the correct offset 0 (...0..3)
    301	 */
    302	*CSR_ROMWRITEREG = 0;
    303
    304	/*
    305	 * dummy ROM read
    306	 */
    307	c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
    308
    309	kick_open();
    310	/*
    311	 * reset status if old errors
    312	 */
    313	*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
    314
    315	/*
    316	 * erase a block...
    317	 * aim at the middle of a current block...
    318	 */
    319	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + 0x8000 + (nBlock << 16)));
    320	/*
    321	 * dummy read
    322	 */
    323	c1 = *pWritePtr;
    324
    325	kick_open();
    326	/*
    327	 * erase
    328	 */
    329	*(volatile unsigned char *) pWritePtr = 0x20;
    330
    331	/*
    332	 * confirm
    333	 */
    334	*(volatile unsigned char *) pWritePtr = 0xD0;
    335
    336	/*
    337	 * wait 10 ms
    338	 */
    339	msleep(10);
    340
    341	/*
    342	 * wait while erasing in process (up to 10 sec)
    343	 */
    344	timeout = jiffies + 10 * HZ;
    345	c1 = 0;
    346	while (!(c1 & 0x80) && time_before(jiffies, timeout)) {
    347		msleep(10);
    348		/*
    349		 * read any address
    350		 */
    351		c1 = *(volatile unsigned char *) (pWritePtr);
    352		//              printk("Flash_erase: status=%X.\n",c1);
    353	}
    354
    355	/*
    356	 * set flash for normal read access
    357	 */
    358	kick_open();
    359//      *(volatile unsigned char*)(FLASH_BASE+0x8000) = 0xFF;
    360	*(volatile unsigned char *) pWritePtr = 0xFF;	//back to normal operation
    361
    362	/*
    363	 * check if erase errors were reported
    364	 */
    365	if (c1 & 0x20) {
    366		printk(KERN_ERR "flash_erase: err at %p\n", pWritePtr);
    367
    368		/*
    369		 * reset error
    370		 */
    371		*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
    372		return -2;
    373	}
    374
    375	/*
    376	 * just to make sure - verify if erased OK...
    377	 */
    378	msleep(10);
    379
    380	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + (nBlock << 16)));
    381
    382	for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
    383		if ((temp1 = *(volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
    384			printk(KERN_ERR "flash_erase: verify err at %p = %X\n",
    385			       pWritePtr, temp1);
    386			return -1;
    387		}
    388	}
    389
    390	return 0;
    391
    392}
    393
    394/*
    395 * write_block will limit number of bytes written to the space in this block
    396 */
    397static int write_block(unsigned long p, const char __user *buf, int count)
    398{
    399	volatile unsigned int c1;
    400	volatile unsigned int c2;
    401	unsigned char *pWritePtr;
    402	unsigned int uAddress;
    403	unsigned int offset;
    404	unsigned long timeout;
    405	unsigned long timeout1;
    406
    407	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
    408
    409	/*
    410	 * check if write will end in this block....
    411	 */
    412	offset = p & 0xFFFF;
    413
    414	if (offset + count > 0x10000)
    415		count = 0x10000 - offset;
    416
    417	/*
    418	 * wait up to 30 sec for this block
    419	 */
    420	timeout = jiffies + 30 * HZ;
    421
    422	for (offset = 0; offset < count; offset++, pWritePtr++) {
    423		uAddress = (unsigned int) pWritePtr;
    424		uAddress &= 0xFFFFFFFC;
    425		if (__get_user(c2, buf + offset))
    426			return -EFAULT;
    427
    428	  WriteRetry:
    429	  	/*
    430	  	 * dummy read
    431	  	 */
    432		c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
    433
    434		/*
    435		 * kick open the write gate
    436		 */
    437		kick_open();
    438
    439		/*
    440		 * program footbridge to the correct offset...0..3
    441		 */
    442		*CSR_ROMWRITEREG = (unsigned int) pWritePtr & 3;
    443
    444		/*
    445		 * write cmd
    446		 */
    447		*(volatile unsigned char *) (uAddress) = 0x40;
    448
    449		/*
    450		 * data to write
    451		 */
    452		*(volatile unsigned char *) (uAddress) = c2;
    453
    454		/*
    455		 * get status
    456		 */
    457		*(volatile unsigned char *) (FLASH_BASE + 0x10000) = 0x70;
    458
    459		c1 = 0;
    460
    461		/*
    462		 * wait up to 1 sec for this byte
    463		 */
    464		timeout1 = jiffies + 1 * HZ;
    465
    466		/*
    467		 * while not ready...
    468		 */
    469		while (!(c1 & 0x80) && time_before(jiffies, timeout1))
    470			c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
    471
    472		/*
    473		 * if timeout getting status
    474		 */
    475		if (time_after_eq(jiffies, timeout1)) {
    476			kick_open();
    477			/*
    478			 * reset err
    479			 */
    480			*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
    481
    482			goto WriteRetry;
    483		}
    484		/*
    485		 * switch on read access, as a default flash operation mode
    486		 */
    487		kick_open();
    488		/*
    489		 * read access
    490		 */
    491		*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
    492
    493		/*
    494		 * if hardware reports an error writing, and not timeout - 
    495		 * reset the chip and retry
    496		 */
    497		if (c1 & 0x10) {
    498			kick_open();
    499			/*
    500			 * reset err
    501			 */
    502			*(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
    503
    504			/*
    505			 * before timeout?
    506			 */
    507			if (time_before(jiffies, timeout)) {
    508				if (flashdebug)
    509					printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
    510					       pWritePtr - FLASH_BASE);
    511
    512				/*
    513				 * wait couple ms
    514				 */
    515				msleep(10);
    516
    517				goto WriteRetry;
    518			} else {
    519				printk(KERN_ERR "write_block: timeout at 0x%X\n",
    520				       pWritePtr - FLASH_BASE);
    521				/*
    522				 * return error -2
    523				 */
    524				return -2;
    525
    526			}
    527		}
    528	}
    529
    530	msleep(10);
    531
    532	pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
    533
    534	for (offset = 0; offset < count; offset++) {
    535		char c, c1;
    536		if (__get_user(c, buf))
    537			return -EFAULT;
    538		buf++;
    539		if ((c1 = *pWritePtr++) != c) {
    540			printk(KERN_ERR "write_block: verify error at 0x%X (%02X!=%02X)\n",
    541			       pWritePtr - FLASH_BASE, c1, c);
    542			return 0;
    543		}
    544	}
    545
    546	return count;
    547}
    548
    549
    550static void kick_open(void)
    551{
    552	unsigned long flags;
    553
    554	/*
    555	 * we want to write a bit pattern XXX1 to Xilinx to enable
    556	 * the write gate, which will be open for about the next 2ms.
    557	 */
    558	raw_spin_lock_irqsave(&nw_gpio_lock, flags);
    559	nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE);
    560	raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
    561
    562	/*
    563	 * let the ISA bus to catch on...
    564	 */
    565	udelay(25);
    566}
    567
    568static const struct file_operations flash_fops =
    569{
    570	.owner		= THIS_MODULE,
    571	.llseek		= flash_llseek,
    572	.read		= flash_read,
    573	.write		= flash_write,
    574	.unlocked_ioctl	= flash_ioctl,
    575};
    576
    577static struct miscdevice flash_miscdev =
    578{
    579	NWFLASH_MINOR,
    580	"nwflash",
    581	&flash_fops
    582};
    583
    584static int __init nwflash_init(void)
    585{
    586	int ret = -ENODEV;
    587
    588	if (machine_is_netwinder()) {
    589		int id;
    590
    591		FLASH_BASE = ioremap(DC21285_FLASH, KFLASH_SIZE4);
    592		if (!FLASH_BASE)
    593			goto out;
    594
    595		id = get_flash_id();
    596		if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
    597			ret = -ENXIO;
    598			iounmap((void *)FLASH_BASE);
    599			printk("Flash: incorrect ID 0x%04X.\n", id);
    600			goto out;
    601		}
    602
    603		printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
    604		       NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
    605
    606		ret = misc_register(&flash_miscdev);
    607		if (ret < 0) {
    608			iounmap((void *)FLASH_BASE);
    609		}
    610	}
    611out:
    612	return ret;
    613}
    614
    615static void __exit nwflash_exit(void)
    616{
    617	misc_deregister(&flash_miscdev);
    618	iounmap((void *)FLASH_BASE);
    619}
    620
    621MODULE_LICENSE("GPL");
    622
    623module_param(flashdebug, bool, 0644);
    624
    625module_init(nwflash_init);
    626module_exit(nwflash_exit);