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

xtx.c (3684B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Author:
      4 * Felix Matouschek <felix@matouschek.org>
      5 */
      6
      7#include <linux/device.h>
      8#include <linux/kernel.h>
      9#include <linux/mtd/spinand.h>
     10
     11#define SPINAND_MFR_XTX	0x0B
     12
     13#define XT26G0XA_STATUS_ECC_MASK	GENMASK(5, 2)
     14#define XT26G0XA_STATUS_ECC_NO_DETECTED	(0 << 2)
     15#define XT26G0XA_STATUS_ECC_8_CORRECTED	(3 << 4)
     16#define XT26G0XA_STATUS_ECC_UNCOR_ERROR	(2 << 4)
     17
     18static SPINAND_OP_VARIANTS(read_cache_variants,
     19		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
     20		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
     21		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
     22		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
     23		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
     24		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
     25
     26static SPINAND_OP_VARIANTS(write_cache_variants,
     27		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
     28		SPINAND_PROG_LOAD(true, 0, NULL, 0));
     29
     30static SPINAND_OP_VARIANTS(update_cache_variants,
     31		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
     32		SPINAND_PROG_LOAD(false, 0, NULL, 0));
     33
     34static int xt26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section,
     35				   struct mtd_oob_region *region)
     36{
     37	if (section)
     38		return -ERANGE;
     39
     40	region->offset = 48;
     41	region->length = 16;
     42
     43	return 0;
     44}
     45
     46static int xt26g0xa_ooblayout_free(struct mtd_info *mtd, int section,
     47				   struct mtd_oob_region *region)
     48{
     49	if (section)
     50		return -ERANGE;
     51
     52	region->offset = 1;
     53	region->length = 47;
     54
     55	return 0;
     56}
     57
     58static const struct mtd_ooblayout_ops xt26g0xa_ooblayout = {
     59	.ecc = xt26g0xa_ooblayout_ecc,
     60	.free = xt26g0xa_ooblayout_free,
     61};
     62
     63static int xt26g0xa_ecc_get_status(struct spinand_device *spinand,
     64					 u8 status)
     65{
     66	status = status & XT26G0XA_STATUS_ECC_MASK;
     67
     68	switch (status) {
     69	case XT26G0XA_STATUS_ECC_NO_DETECTED:
     70		return 0;
     71	case XT26G0XA_STATUS_ECC_8_CORRECTED:
     72		return 8;
     73	case XT26G0XA_STATUS_ECC_UNCOR_ERROR:
     74		return -EBADMSG;
     75	default:
     76		break;
     77	}
     78
     79	/* At this point values greater than (2 << 4) are invalid  */
     80	if (status > XT26G0XA_STATUS_ECC_UNCOR_ERROR)
     81		return -EINVAL;
     82
     83	/* (1 << 2) through (7 << 2) are 1-7 corrected errors */
     84	return status >> 2;
     85}
     86
     87static const struct spinand_info xtx_spinand_table[] = {
     88	SPINAND_INFO("XT26G01A",
     89		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1),
     90		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
     91		     NAND_ECCREQ(8, 512),
     92		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
     93					      &write_cache_variants,
     94					      &update_cache_variants),
     95		     SPINAND_HAS_QE_BIT,
     96		     SPINAND_ECCINFO(&xt26g0xa_ooblayout,
     97				     xt26g0xa_ecc_get_status)),
     98	SPINAND_INFO("XT26G02A",
     99		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE2),
    100		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
    101		     NAND_ECCREQ(8, 512),
    102		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    103					      &write_cache_variants,
    104					      &update_cache_variants),
    105		     SPINAND_HAS_QE_BIT,
    106		     SPINAND_ECCINFO(&xt26g0xa_ooblayout,
    107				     xt26g0xa_ecc_get_status)),
    108	SPINAND_INFO("XT26G04A",
    109		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE3),
    110		     NAND_MEMORG(1, 2048, 64, 128, 2048, 40, 1, 1, 1),
    111		     NAND_ECCREQ(8, 512),
    112		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    113					      &write_cache_variants,
    114					      &update_cache_variants),
    115		     SPINAND_HAS_QE_BIT,
    116		     SPINAND_ECCINFO(&xt26g0xa_ooblayout,
    117				     xt26g0xa_ecc_get_status)),
    118};
    119
    120static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
    121};
    122
    123const struct spinand_manufacturer xtx_spinand_manufacturer = {
    124	.id = SPINAND_MFR_XTX,
    125	.name = "XTX",
    126	.chips = xtx_spinand_table,
    127	.nchips = ARRAY_SIZE(xtx_spinand_table),
    128	.ops = &xtx_spinand_manuf_ops,
    129};