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

macronix.c (11019B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2018 Macronix
      4 *
      5 * Author: Boris Brezillon <boris.brezillon@bootlin.com>
      6 */
      7
      8#include <linux/device.h>
      9#include <linux/kernel.h>
     10#include <linux/mtd/spinand.h>
     11
     12#define SPINAND_MFR_MACRONIX		0xC2
     13#define MACRONIX_ECCSR_MASK		0x0F
     14
     15static SPINAND_OP_VARIANTS(read_cache_variants,
     16		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
     17		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
     18		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
     19		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
     20
     21static SPINAND_OP_VARIANTS(write_cache_variants,
     22		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
     23		SPINAND_PROG_LOAD(false, 0, NULL, 0));
     24
     25static SPINAND_OP_VARIANTS(update_cache_variants,
     26		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
     27		SPINAND_PROG_LOAD(false, 0, NULL, 0));
     28
     29static int mx35lfxge4ab_ooblayout_ecc(struct mtd_info *mtd, int section,
     30				      struct mtd_oob_region *region)
     31{
     32	return -ERANGE;
     33}
     34
     35static int mx35lfxge4ab_ooblayout_free(struct mtd_info *mtd, int section,
     36				       struct mtd_oob_region *region)
     37{
     38	if (section)
     39		return -ERANGE;
     40
     41	region->offset = 2;
     42	region->length = mtd->oobsize - 2;
     43
     44	return 0;
     45}
     46
     47static const struct mtd_ooblayout_ops mx35lfxge4ab_ooblayout = {
     48	.ecc = mx35lfxge4ab_ooblayout_ecc,
     49	.free = mx35lfxge4ab_ooblayout_free,
     50};
     51
     52static int mx35lf1ge4ab_get_eccsr(struct spinand_device *spinand, u8 *eccsr)
     53{
     54	struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x7c, 1),
     55					  SPI_MEM_OP_NO_ADDR,
     56					  SPI_MEM_OP_DUMMY(1, 1),
     57					  SPI_MEM_OP_DATA_IN(1, eccsr, 1));
     58
     59	int ret = spi_mem_exec_op(spinand->spimem, &op);
     60	if (ret)
     61		return ret;
     62
     63	*eccsr &= MACRONIX_ECCSR_MASK;
     64	return 0;
     65}
     66
     67static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
     68				       u8 status)
     69{
     70	struct nand_device *nand = spinand_to_nand(spinand);
     71	u8 eccsr;
     72
     73	switch (status & STATUS_ECC_MASK) {
     74	case STATUS_ECC_NO_BITFLIPS:
     75		return 0;
     76
     77	case STATUS_ECC_UNCOR_ERROR:
     78		return -EBADMSG;
     79
     80	case STATUS_ECC_HAS_BITFLIPS:
     81		/*
     82		 * Let's try to retrieve the real maximum number of bitflips
     83		 * in order to avoid forcing the wear-leveling layer to move
     84		 * data around if it's not necessary.
     85		 */
     86		if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
     87			return nanddev_get_ecc_conf(nand)->strength;
     88
     89		if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength ||
     90			    !eccsr))
     91			return nanddev_get_ecc_conf(nand)->strength;
     92
     93		return eccsr;
     94
     95	default:
     96		break;
     97	}
     98
     99	return -EINVAL;
    100}
    101
    102static const struct spinand_info macronix_spinand_table[] = {
    103	SPINAND_INFO("MX35LF1GE4AB",
    104		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
    105		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
    106		     NAND_ECCREQ(4, 512),
    107		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    108					      &write_cache_variants,
    109					      &update_cache_variants),
    110		     SPINAND_HAS_QE_BIT,
    111		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    112				     mx35lf1ge4ab_ecc_get_status)),
    113	SPINAND_INFO("MX35LF2GE4AB",
    114		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
    115		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
    116		     NAND_ECCREQ(4, 512),
    117		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    118					      &write_cache_variants,
    119					      &update_cache_variants),
    120		     SPINAND_HAS_QE_BIT,
    121		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
    122	SPINAND_INFO("MX35LF2GE4AD",
    123		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26),
    124		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
    125		     NAND_ECCREQ(8, 512),
    126		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    127					      &write_cache_variants,
    128					      &update_cache_variants),
    129		     SPINAND_HAS_QE_BIT,
    130		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    131				     mx35lf1ge4ab_ecc_get_status)),
    132	SPINAND_INFO("MX35LF4GE4AD",
    133		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
    134		     NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1),
    135		     NAND_ECCREQ(8, 512),
    136		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    137					      &write_cache_variants,
    138					      &update_cache_variants),
    139		     SPINAND_HAS_QE_BIT,
    140		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    141				     mx35lf1ge4ab_ecc_get_status)),
    142	SPINAND_INFO("MX35LF1G24AD",
    143		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
    144		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    145		     NAND_ECCREQ(8, 512),
    146		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    147					      &write_cache_variants,
    148					      &update_cache_variants),
    149		     SPINAND_HAS_QE_BIT,
    150		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
    151	SPINAND_INFO("MX35LF2G24AD",
    152		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
    153		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
    154		     NAND_ECCREQ(8, 512),
    155		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    156					      &write_cache_variants,
    157					      &update_cache_variants),
    158		     SPINAND_HAS_QE_BIT,
    159		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
    160	SPINAND_INFO("MX35LF4G24AD",
    161		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
    162		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
    163		     NAND_ECCREQ(8, 512),
    164		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    165					      &write_cache_variants,
    166					      &update_cache_variants),
    167		     SPINAND_HAS_QE_BIT,
    168		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
    169	SPINAND_INFO("MX31LF1GE4BC",
    170		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
    171		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
    172		     NAND_ECCREQ(8, 512),
    173		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    174					      &write_cache_variants,
    175					      &update_cache_variants),
    176		     SPINAND_HAS_QE_BIT,
    177		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    178				     mx35lf1ge4ab_ecc_get_status)),
    179	SPINAND_INFO("MX31UF1GE4BC",
    180		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
    181		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
    182		     NAND_ECCREQ(8, 512),
    183		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    184					      &write_cache_variants,
    185					      &update_cache_variants),
    186		     SPINAND_HAS_QE_BIT,
    187		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    188				     mx35lf1ge4ab_ecc_get_status)),
    189
    190	SPINAND_INFO("MX35LF2G14AC",
    191		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20),
    192		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
    193		     NAND_ECCREQ(4, 512),
    194		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    195					      &write_cache_variants,
    196					      &update_cache_variants),
    197		     SPINAND_HAS_QE_BIT,
    198		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    199				     mx35lf1ge4ab_ecc_get_status)),
    200	SPINAND_INFO("MX35UF4G24AD",
    201		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5),
    202		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
    203		     NAND_ECCREQ(8, 512),
    204		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    205					      &write_cache_variants,
    206					      &update_cache_variants),
    207		     SPINAND_HAS_QE_BIT,
    208		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    209				     mx35lf1ge4ab_ecc_get_status)),
    210	SPINAND_INFO("MX35UF4GE4AD",
    211		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7),
    212		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
    213		     NAND_ECCREQ(8, 512),
    214		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    215					      &write_cache_variants,
    216					      &update_cache_variants),
    217		     SPINAND_HAS_QE_BIT,
    218		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    219				     mx35lf1ge4ab_ecc_get_status)),
    220	SPINAND_INFO("MX35UF2G14AC",
    221		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
    222		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
    223		     NAND_ECCREQ(4, 512),
    224		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    225					      &write_cache_variants,
    226					      &update_cache_variants),
    227		     SPINAND_HAS_QE_BIT,
    228		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    229				     mx35lf1ge4ab_ecc_get_status)),
    230	SPINAND_INFO("MX35UF2G24AD",
    231		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4),
    232		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
    233		     NAND_ECCREQ(8, 512),
    234		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    235					      &write_cache_variants,
    236					      &update_cache_variants),
    237		     SPINAND_HAS_QE_BIT,
    238		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    239				     mx35lf1ge4ab_ecc_get_status)),
    240	SPINAND_INFO("MX35UF2GE4AD",
    241		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6),
    242		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
    243		     NAND_ECCREQ(8, 512),
    244		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    245					      &write_cache_variants,
    246					      &update_cache_variants),
    247		     SPINAND_HAS_QE_BIT,
    248		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    249				     mx35lf1ge4ab_ecc_get_status)),
    250	SPINAND_INFO("MX35UF2GE4AC",
    251		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2),
    252		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
    253		     NAND_ECCREQ(4, 512),
    254		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    255					      &write_cache_variants,
    256					      &update_cache_variants),
    257		     SPINAND_HAS_QE_BIT,
    258		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    259				     mx35lf1ge4ab_ecc_get_status)),
    260	SPINAND_INFO("MX35UF1G14AC",
    261		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90),
    262		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
    263		     NAND_ECCREQ(4, 512),
    264		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    265					      &write_cache_variants,
    266					      &update_cache_variants),
    267		     SPINAND_HAS_QE_BIT,
    268		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    269				     mx35lf1ge4ab_ecc_get_status)),
    270	SPINAND_INFO("MX35UF1G24AD",
    271		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94),
    272		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    273		     NAND_ECCREQ(8, 512),
    274		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    275					      &write_cache_variants,
    276					      &update_cache_variants),
    277		     SPINAND_HAS_QE_BIT,
    278		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    279				     mx35lf1ge4ab_ecc_get_status)),
    280	SPINAND_INFO("MX35UF1GE4AD",
    281		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96),
    282		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    283		     NAND_ECCREQ(8, 512),
    284		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    285					      &write_cache_variants,
    286					      &update_cache_variants),
    287		     SPINAND_HAS_QE_BIT,
    288		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    289				     mx35lf1ge4ab_ecc_get_status)),
    290	SPINAND_INFO("MX35UF1GE4AC",
    291		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
    292		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
    293		     NAND_ECCREQ(4, 512),
    294		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    295					      &write_cache_variants,
    296					      &update_cache_variants),
    297		     SPINAND_HAS_QE_BIT,
    298		     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
    299				     mx35lf1ge4ab_ecc_get_status)),
    300
    301};
    302
    303static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
    304};
    305
    306const struct spinand_manufacturer macronix_spinand_manufacturer = {
    307	.id = SPINAND_MFR_MACRONIX,
    308	.name = "Macronix",
    309	.chips = macronix_spinand_table,
    310	.nchips = ARRAY_SIZE(macronix_spinand_table),
    311	.ops = &macronix_spinand_manuf_ops,
    312};