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

saa7164-fw.c (15862B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Driver for the NXP SAA7164 PCIe bridge
      4 *
      5 *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
      6 */
      7
      8#include <linux/firmware.h>
      9#include <linux/slab.h>
     10
     11#include "saa7164.h"
     12
     13#define SAA7164_REV2_FIRMWARE		"NXP7164-2010-03-10.1.fw"
     14#define SAA7164_REV2_FIRMWARE_SIZE	4019072
     15
     16#define SAA7164_REV3_FIRMWARE		"NXP7164-2010-03-10.1.fw"
     17#define SAA7164_REV3_FIRMWARE_SIZE	4019072
     18
     19struct fw_header {
     20	u32	firmwaresize;
     21	u32	bslsize;
     22	u32	reserved;
     23	u32	version;
     24};
     25
     26static int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
     27{
     28	u32 timeout = SAA_DEVICE_TIMEOUT;
     29	while ((saa7164_readl(reg) & 0x01) == 0) {
     30		timeout -= 10;
     31		if (timeout == 0) {
     32			printk(KERN_ERR "%s() timeout (no d/l ack)\n",
     33				__func__);
     34			return -EBUSY;
     35		}
     36		msleep(100);
     37	}
     38
     39	return 0;
     40}
     41
     42static int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
     43{
     44	u32 timeout = SAA_DEVICE_TIMEOUT;
     45	while (saa7164_readl(reg) & 0x01) {
     46		timeout -= 10;
     47		if (timeout == 0) {
     48			printk(KERN_ERR "%s() timeout (no d/l clr)\n",
     49				__func__);
     50			return -EBUSY;
     51		}
     52		msleep(100);
     53	}
     54
     55	return 0;
     56}
     57
     58/* TODO: move dlflags into dev-> and change to write/readl/b */
     59/* TODO: Excessive levels of debug */
     60static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
     61				 u32 dlflags, u8 __iomem *dst, u32 dstsize)
     62{
     63	u32 reg, timeout, offset;
     64	u8 *srcbuf = NULL;
     65	int ret;
     66
     67	u32 dlflag = dlflags;
     68	u32 dlflag_ack = dlflag + 4;
     69	u32 drflag = dlflag_ack + 4;
     70	u32 drflag_ack = drflag + 4;
     71	u32 bleflag = drflag_ack + 4;
     72
     73	dprintk(DBGLVL_FW,
     74		"%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
     75		__func__, src, srcsize, dlflags, dst, dstsize);
     76
     77	if ((src == NULL) || (dst == NULL)) {
     78		ret = -EIO;
     79		goto out;
     80	}
     81
     82	srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
     83	if (NULL == srcbuf) {
     84		ret = -ENOMEM;
     85		goto out;
     86	}
     87
     88	if (srcsize > (4*1048576)) {
     89		ret = -ENOMEM;
     90		goto out;
     91	}
     92
     93	memcpy(srcbuf, src, srcsize);
     94
     95	dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
     96	dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
     97	dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
     98	dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
     99	dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);
    100
    101	reg = saa7164_readl(dlflag);
    102	dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
    103	if (reg == 1)
    104		dprintk(DBGLVL_FW,
    105			"%s() Download flag already set, please reboot\n",
    106			__func__);
    107
    108	/* Indicate download start */
    109	saa7164_writel(dlflag, 1);
    110	ret = saa7164_dl_wait_ack(dev, dlflag_ack);
    111	if (ret < 0)
    112		goto out;
    113
    114	/* Ack download start, then wait for wait */
    115	saa7164_writel(dlflag, 0);
    116	ret = saa7164_dl_wait_clr(dev, dlflag_ack);
    117	if (ret < 0)
    118		goto out;
    119
    120	/* Deal with the raw firmware, in the appropriate chunk size */
    121	for (offset = 0; srcsize > dstsize;
    122		srcsize -= dstsize, offset += dstsize) {
    123
    124		dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize);
    125		memcpy_toio(dst, srcbuf + offset, dstsize);
    126
    127		/* Flag the data as ready */
    128		saa7164_writel(drflag, 1);
    129		ret = saa7164_dl_wait_ack(dev, drflag_ack);
    130		if (ret < 0)
    131			goto out;
    132
    133		/* Wait for indication data was received */
    134		saa7164_writel(drflag, 0);
    135		ret = saa7164_dl_wait_clr(dev, drflag_ack);
    136		if (ret < 0)
    137			goto out;
    138
    139	}
    140
    141	dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize);
    142	/* Write last block to the device */
    143	memcpy_toio(dst, srcbuf+offset, srcsize);
    144
    145	/* Flag the data as ready */
    146	saa7164_writel(drflag, 1);
    147	ret = saa7164_dl_wait_ack(dev, drflag_ack);
    148	if (ret < 0)
    149		goto out;
    150
    151	saa7164_writel(drflag, 0);
    152	timeout = 0;
    153	while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) {
    154		if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) {
    155			printk(KERN_ERR "%s() image corrupt\n", __func__);
    156			ret = -EBUSY;
    157			goto out;
    158		}
    159
    160		if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) {
    161			printk(KERN_ERR "%s() device memory corrupt\n",
    162				__func__);
    163			ret = -EBUSY;
    164			goto out;
    165		}
    166
    167		msleep(10); /* Checkpatch throws a < 20ms warning */
    168		if (timeout++ > 60)
    169			break;
    170	}
    171
    172	printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__);
    173
    174	ret = saa7164_dl_wait_clr(dev, drflag_ack);
    175	if (ret < 0)
    176		goto out;
    177
    178	printk(KERN_INFO "%s() Image booted successfully.\n", __func__);
    179	ret = 0;
    180
    181out:
    182	kfree(srcbuf);
    183	return ret;
    184}
    185
    186/* TODO: Excessive debug */
    187/* Load the firmware. Optionally it can be in ROM or newer versions
    188 * can be on disk, saving the expense of the ROM hardware. */
    189int saa7164_downloadfirmware(struct saa7164_dev *dev)
    190{
    191	/* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */
    192	u32 tmp, filesize, version, err_flags, first_timeout, fwlength;
    193	u32 second_timeout, updatebootloader = 1, bootloadersize = 0;
    194	const struct firmware *fw = NULL;
    195	struct fw_header *hdr, *boothdr = NULL, *fwhdr;
    196	u32 bootloaderversion = 0, fwloadersize;
    197	u8 *bootloaderoffset = NULL, *fwloaderoffset;
    198	char *fwname;
    199	int ret;
    200
    201	dprintk(DBGLVL_FW, "%s()\n", __func__);
    202
    203	if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) {
    204		fwname = SAA7164_REV2_FIRMWARE;
    205		fwlength = SAA7164_REV2_FIRMWARE_SIZE;
    206	} else {
    207		fwname = SAA7164_REV3_FIRMWARE;
    208		fwlength = SAA7164_REV3_FIRMWARE_SIZE;
    209	}
    210
    211	version = saa7164_getcurrentfirmwareversion(dev);
    212
    213	if (version == 0x00) {
    214
    215		second_timeout = 100;
    216		first_timeout = 100;
    217		err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
    218		dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
    219			__func__, err_flags);
    220
    221		while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
    222			dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
    223				__func__, err_flags);
    224			msleep(10); /* Checkpatch throws a < 20ms warning */
    225
    226			if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
    227				printk(KERN_ERR "%s() firmware corrupt\n",
    228					__func__);
    229				break;
    230			}
    231			if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
    232				printk(KERN_ERR "%s() device memory corrupt\n",
    233					__func__);
    234				break;
    235			}
    236			if (err_flags & SAA_DEVICE_NO_IMAGE) {
    237				printk(KERN_ERR "%s() no first image\n",
    238				__func__);
    239				break;
    240			}
    241			if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
    242				first_timeout -= 10;
    243				if (first_timeout == 0) {
    244					printk(KERN_ERR
    245						"%s() no first image\n",
    246						__func__);
    247					break;
    248				}
    249			} else if (err_flags & SAA_DEVICE_IMAGE_LOADING) {
    250				second_timeout -= 10;
    251				if (second_timeout == 0) {
    252					printk(KERN_ERR
    253					"%s() FW load time exceeded\n",
    254						__func__);
    255					break;
    256				}
    257			} else {
    258				second_timeout -= 10;
    259				if (second_timeout == 0) {
    260					printk(KERN_ERR
    261					"%s() Unknown bootloader flags 0x%x\n",
    262						__func__, err_flags);
    263					break;
    264				}
    265			}
    266
    267			err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
    268		} /* While != Booting */
    269
    270		if (err_flags == SAA_DEVICE_IMAGE_BOOTING) {
    271			dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n",
    272				__func__);
    273			first_timeout = SAA_DEVICE_TIMEOUT;
    274			second_timeout = 60 * SAA_DEVICE_TIMEOUT;
    275			second_timeout = 100;
    276
    277			err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
    278			dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
    279				__func__, err_flags);
    280			while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
    281				dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
    282					__func__, err_flags);
    283				msleep(10); /* Checkpatch throws a < 20ms warning */
    284
    285				if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
    286					printk(KERN_ERR
    287						"%s() firmware corrupt\n",
    288						__func__);
    289					break;
    290				}
    291				if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
    292					printk(KERN_ERR
    293						"%s() device memory corrupt\n",
    294						__func__);
    295					break;
    296				}
    297				if (err_flags & SAA_DEVICE_NO_IMAGE) {
    298					printk(KERN_ERR "%s() no second image\n",
    299						__func__);
    300					break;
    301				}
    302				if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
    303					first_timeout -= 10;
    304					if (first_timeout == 0) {
    305						printk(KERN_ERR
    306						"%s() no second image\n",
    307							__func__);
    308						break;
    309					}
    310				} else if (err_flags &
    311					SAA_DEVICE_IMAGE_LOADING) {
    312					second_timeout -= 10;
    313					if (second_timeout == 0) {
    314						printk(KERN_ERR
    315						"%s() FW load time exceeded\n",
    316							__func__);
    317						break;
    318					}
    319				} else {
    320					second_timeout -= 10;
    321					if (second_timeout == 0) {
    322						printk(KERN_ERR
    323					"%s() Unknown bootloader flags 0x%x\n",
    324							__func__, err_flags);
    325						break;
    326					}
    327				}
    328
    329				err_flags =
    330				saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
    331			} /* err_flags != SAA_DEVICE_IMAGE_BOOTING */
    332
    333			dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n",
    334				__func__,
    335				saa7164_readl(SAA_BOOTLOADERERROR_FLAGS),
    336				saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS));
    337
    338		} /* err_flags == SAA_DEVICE_IMAGE_BOOTING */
    339
    340		/* It's possible for both firmwares to have booted,
    341		 * but that doesn't mean they've finished booting yet.
    342		 */
    343		if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
    344			SAA_DEVICE_IMAGE_BOOTING) &&
    345			(saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
    346			SAA_DEVICE_IMAGE_BOOTING)) {
    347
    348
    349			dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n",
    350				__func__);
    351
    352			first_timeout = SAA_DEVICE_TIMEOUT;
    353			while (first_timeout) {
    354				msleep(10); /* Checkpatch throws a < 20ms warning */
    355
    356				version =
    357					saa7164_getcurrentfirmwareversion(dev);
    358				if (version) {
    359					dprintk(DBGLVL_FW,
    360					"%s() All f/w loaded successfully\n",
    361						__func__);
    362					break;
    363				} else {
    364					first_timeout -= 10;
    365					if (first_timeout == 0) {
    366						printk(KERN_ERR
    367						"%s() FW did not boot\n",
    368							__func__);
    369						break;
    370					}
    371				}
    372			}
    373		}
    374		version = saa7164_getcurrentfirmwareversion(dev);
    375	} /* version == 0 */
    376
    377	/* Has the firmware really booted? */
    378	if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
    379		SAA_DEVICE_IMAGE_BOOTING) &&
    380		(saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
    381		SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) {
    382
    383		printk(KERN_ERR
    384			"%s() The firmware hung, probably bad firmware\n",
    385			__func__);
    386
    387		/* Tell the second stage loader we have a deadlock */
    388		saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET,
    389			SAA_DEVICE_DEADLOCK_DETECTED);
    390
    391		saa7164_getfirmwarestatus(dev);
    392
    393		return -ENOMEM;
    394	}
    395
    396	dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n",
    397		(version & 0x0000fc00) >> 10,
    398		(version & 0x000003e0) >> 5,
    399		(version & 0x0000001f),
    400		(version & 0xffff0000) >> 16);
    401
    402	/* Load the firmware from the disk if required */
    403	if (version == 0) {
    404
    405		printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n",
    406			__func__, fwname);
    407
    408		ret = request_firmware(&fw, fwname, &dev->pci->dev);
    409		if (ret) {
    410			printk(KERN_ERR "%s() Upload failed. (file not found?)\n",
    411			       __func__);
    412			return -ENOMEM;
    413		}
    414
    415		printk(KERN_INFO "%s() firmware read %zu bytes.\n",
    416			__func__, fw->size);
    417
    418		if (fw->size != fwlength) {
    419			printk(KERN_ERR "saa7164: firmware incorrect size %zu != %u\n",
    420				fw->size, fwlength);
    421			ret = -ENOMEM;
    422			goto out;
    423		}
    424
    425		printk(KERN_INFO "%s() firmware loaded.\n", __func__);
    426
    427		hdr = (struct fw_header *)fw->data;
    428		printk(KERN_INFO "Firmware file header part 1:\n");
    429		printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize);
    430		printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize);
    431		printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved);
    432		printk(KERN_INFO " .Version = 0x%x\n", hdr->version);
    433
    434		/* Retrieve bootloader if reqd */
    435		if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0))
    436			/* Second bootloader in the firmware file */
    437			filesize = hdr->reserved * 16;
    438		else
    439			filesize = (hdr->firmwaresize + hdr->bslsize) *
    440				16 + sizeof(struct fw_header);
    441
    442		printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n",
    443			__func__, filesize);
    444
    445		/* Get bootloader (if reqd) and firmware header */
    446		if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
    447			/* Second boot loader is required */
    448
    449			/* Get the loader header */
    450			boothdr = (struct fw_header *)(fw->data +
    451				sizeof(struct fw_header));
    452
    453			bootloaderversion =
    454				saa7164_readl(SAA_DEVICE_2ND_VERSION);
    455			dprintk(DBGLVL_FW, "Onboard BootLoader:\n");
    456			dprintk(DBGLVL_FW, "->Flag 0x%x\n",
    457				saa7164_readl(SAA_BOOTLOADERERROR_FLAGS));
    458			dprintk(DBGLVL_FW, "->Ack 0x%x\n",
    459				saa7164_readl(SAA_DATAREADY_FLAG_ACK));
    460			dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version);
    461			dprintk(DBGLVL_FW, "->Loader Version 0x%x\n",
    462				bootloaderversion);
    463
    464			if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
    465				0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK)
    466				== 0x00) && (version == 0x00)) {
    467
    468				dprintk(DBGLVL_FW, "BootLoader version in  rom %d.%d.%d.%d\n",
    469					(bootloaderversion & 0x0000fc00) >> 10,
    470					(bootloaderversion & 0x000003e0) >> 5,
    471					(bootloaderversion & 0x0000001f),
    472					(bootloaderversion & 0xffff0000) >> 16
    473					);
    474				dprintk(DBGLVL_FW, "BootLoader version in file %d.%d.%d.%d\n",
    475					(boothdr->version & 0x0000fc00) >> 10,
    476					(boothdr->version & 0x000003e0) >> 5,
    477					(boothdr->version & 0x0000001f),
    478					(boothdr->version & 0xffff0000) >> 16
    479					);
    480
    481				if (bootloaderversion == boothdr->version)
    482					updatebootloader = 0;
    483			}
    484
    485			/* Calculate offset to firmware header */
    486			tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 +
    487				(sizeof(struct fw_header) +
    488				sizeof(struct fw_header));
    489
    490			fwhdr = (struct fw_header *)(fw->data+tmp);
    491		} else {
    492			/* No second boot loader */
    493			fwhdr = hdr;
    494		}
    495
    496		dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n",
    497			(fwhdr->version & 0x0000fc00) >> 10,
    498			(fwhdr->version & 0x000003e0) >> 5,
    499			(fwhdr->version & 0x0000001f),
    500			(fwhdr->version & 0xffff0000) >> 16
    501			);
    502
    503		if (version == fwhdr->version) {
    504			/* No download, firmware already on board */
    505			ret = 0;
    506			goto out;
    507		}
    508
    509		if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
    510			if (updatebootloader) {
    511				/* Get ready to upload the bootloader */
    512				bootloadersize = (boothdr->firmwaresize +
    513					boothdr->bslsize) * 16 +
    514					sizeof(struct fw_header);
    515
    516				bootloaderoffset = (u8 *)(fw->data +
    517					sizeof(struct fw_header));
    518
    519				dprintk(DBGLVL_FW, "bootloader d/l starts.\n");
    520				printk(KERN_INFO "%s() FirmwareSize = 0x%x\n",
    521					__func__, boothdr->firmwaresize);
    522				printk(KERN_INFO "%s() BSLSize = 0x%x\n",
    523					__func__, boothdr->bslsize);
    524				printk(KERN_INFO "%s() Reserved = 0x%x\n",
    525					__func__, boothdr->reserved);
    526				printk(KERN_INFO "%s() Version = 0x%x\n",
    527					__func__, boothdr->version);
    528				ret = saa7164_downloadimage(
    529					dev,
    530					bootloaderoffset,
    531					bootloadersize,
    532					SAA_DOWNLOAD_FLAGS,
    533					dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
    534					SAA_DEVICE_BUFFERBLOCKSIZE);
    535				if (ret < 0) {
    536					printk(KERN_ERR
    537						"bootloader d/l has failed\n");
    538					goto out;
    539				}
    540				dprintk(DBGLVL_FW,
    541					"bootloader download complete.\n");
    542
    543			}
    544
    545			printk(KERN_ERR "starting firmware download(2)\n");
    546			bootloadersize = (boothdr->firmwaresize +
    547				boothdr->bslsize) * 16 +
    548				sizeof(struct fw_header);
    549
    550			bootloaderoffset =
    551				(u8 *)(fw->data + sizeof(struct fw_header));
    552
    553			fwloaderoffset = bootloaderoffset + bootloadersize;
    554
    555			/* TODO: fix this bounds overrun here with old f/ws */
    556			fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) *
    557				16 + sizeof(struct fw_header);
    558
    559			ret = saa7164_downloadimage(
    560				dev,
    561				fwloaderoffset,
    562				fwloadersize,
    563				SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET,
    564				dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET,
    565				SAA_DEVICE_2ND_BUFFERBLOCKSIZE);
    566			if (ret < 0) {
    567				printk(KERN_ERR "firmware download failed\n");
    568				goto out;
    569			}
    570			printk(KERN_ERR "firmware download complete.\n");
    571
    572		} else {
    573
    574			/* No bootloader update reqd, download firmware only */
    575			printk(KERN_ERR "starting firmware download(3)\n");
    576
    577			ret = saa7164_downloadimage(
    578				dev,
    579				(u8 *)fw->data,
    580				fw->size,
    581				SAA_DOWNLOAD_FLAGS,
    582				dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
    583				SAA_DEVICE_BUFFERBLOCKSIZE);
    584			if (ret < 0) {
    585				printk(KERN_ERR "firmware download failed\n");
    586				goto out;
    587			}
    588			printk(KERN_ERR "firmware download complete.\n");
    589		}
    590	}
    591
    592	dev->firmwareloaded = 1;
    593	ret = 0;
    594
    595out:
    596	release_firmware(fw);
    597	return ret;
    598}