mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Jan Remmet <J.Remmet@phytec.de>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH 2/2] imx-bbu-nand-fcb: add support for imx6ul
Date: Thu, 27 Apr 2017 11:40:44 +0200	[thread overview]
Message-ID: <20170427094044.GC2932@lws-weitzel2@phytec.de> (raw)
In-Reply-To: <20170427070132.rc6rwbhyskdvit5y@pengutronix.de>

On Thu, Apr 27, 2017 at 09:01:32AM +0200, Sascha Hauer wrote:
> On Wed, Apr 26, 2017 at 04:43:16PM +0200, Jan Remmet wrote:
> > On Wed, Dec 14, 2016 at 08:59:08AM +0100, Jan Remmet wrote:
> > > imx6ul secure the fcb with bch 40. The imx-kobs tool use a own modified
> > > bch lib. They reverse the bit order of the data and the ecc.
> > > To use the bch lib in barebox the bytes in the data buffers must be
> > > reversed.
> > > The data layout on nand is bit aligned. But with 40 bits this is not an
> > > issue for imx6ul now.
> > I saw that this wasn't applied, is there any rework needed?
> 
> It seems this patch slipped through the cracks. Applied now.

Thanks
Jan
> 
> Sascha
> 
> > 
> > Jan
> > 
> > > 
> > > Signed-off-by: Jan Remmet <j.remmet@phytec.de>
> > > ---
> > >  common/Kconfig            |   1 +
> > >  common/imx-bbu-nand-fcb.c | 145 +++++++++++++++++++++++++++++++++++++++++++++-
> > >  2 files changed, 143 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/common/Kconfig b/common/Kconfig
> > > index ed472a0..a10caf6 100644
> > > --- a/common/Kconfig
> > > +++ b/common/Kconfig
> > > @@ -101,6 +101,7 @@ config BAREBOX_UPDATE_IMX_NAND_FCB
> > >  	depends on BAREBOX_UPDATE
> > >  	depends on MTD_WRITE
> > >  	depends on NAND_MXS
> > > +	select BCH if ARCH_IMX6
> > >  	default y
> > >  
> > >  config UBIFORMAT
> > > diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
> > > index 34a5f83..5d3d3f7 100644
> > > --- a/common/imx-bbu-nand-fcb.c
> > > +++ b/common/imx-bbu-nand-fcb.c
> > > @@ -33,9 +33,12 @@
> > >  #include <linux/mtd/mtd.h>
> > >  #include <linux/mtd/nand.h>
> > >  #include <linux/stat.h>
> > > +#include <linux/bch.h>
> > > +#include <linux/bitops.h>
> > >  #include <io.h>
> > >  #include <crc.h>
> > >  #include <mach/generic.h>
> > > +#include <mach/imx6.h>
> > >  #include <mtd/mtd-peb.h>
> > >  
> > >  struct dbbt_block {
> > > @@ -129,6 +132,132 @@ static uint8_t calculate_parity_13_8(uint8_t d)
> > >  	return p;
> > >  }
> > >  
> > > +static uint8_t reverse_bit(uint8_t b)
> > > +{
> > > +	b = (b & 0xf0) >> 4 | (b & 0x0f) << 4;
> > > +	b = (b & 0xcc) >> 2 | (b & 0x33) << 2;
> > > +	b = (b & 0xaa) >> 1 | (b & 0x55) << 1;
> > > +
> > > +	return b;
> > > +}
> > > +
> > > +static void encode_bch_ecc(void *buf, struct fcb_block *fcb, int eccbits)
> > > +{
> > > +	int i, j, m = 13;
> > > +	int blocksize = 128;
> > > +	int numblocks = 8;
> > > +	int ecc_buf_size = (m * eccbits + 7) / 8;
> > > +	struct bch_control *bch = init_bch(m, eccbits, 0);
> > > +	uint8_t *ecc_buf = xmalloc(ecc_buf_size);
> > > +	uint8_t *tmp_buf = xzalloc(blocksize * numblocks);
> > > +	uint8_t *psrc, *pdst;
> > > +
> > > +	/*
> > > +	 * The blocks here are bit aligned. If eccbits is a multiple of 8,
> > > +	 * we just can copy bytes. Otherwiese we must move the blocks to
> > > +	 * the next free bit position.
> > > +	 */
> > > +	BUG_ON(eccbits % 8);
> > > +
> > > +	memcpy(tmp_buf, fcb, sizeof(*fcb));
> > > +
> > > +	for (i = 0; i < numblocks; i++) {
> > > +		memset(ecc_buf, 0, ecc_buf_size);
> > > +		psrc = tmp_buf + i * blocksize;
> > > +		pdst = buf + i * (blocksize + ecc_buf_size);
> > > +
> > > +		/* copy data byte aligned to destination buf */
> > > +		memcpy(pdst, psrc, blocksize);
> > > +
> > > +		/*
> > > +		 * imx-kobs use a modified encode_bch which reverse the
> > > +		 * bit order of the data before calculating bch.
> > > +		 * Do this in the buffer and use the bch lib here.
> > > +		 */
> > > +		for (j = 0; j < blocksize; j++)
> > > +			psrc[j] = reverse_bit(psrc[j]);
> > > +
> > > +		encode_bch(bch, psrc, blocksize, ecc_buf);
> > > +
> > > +		/* reverse ecc bit */
> > > +		for (j = 0; j < ecc_buf_size; j++)
> > > +			ecc_buf[j] = reverse_bit(ecc_buf[j]);
> > > +
> > > +		/* Here eccbuf is byte aligned and we can just copy it */
> > > +		memcpy(pdst + blocksize, ecc_buf, ecc_buf_size);
> > > +	}
> > > +
> > > +	free(ecc_buf);
> > > +	free(tmp_buf);
> > > +	free_bch(bch);
> > > +}
> > > +
> > > +struct fcb_block *read_fcb_bch(void *rawpage, int eccbits)
> > > +{
> > > +	int i, j, ret, errbit, m = 13;
> > > +	int blocksize = 128;
> > > +	int numblocks = 8;
> > > +	int ecc_buf_size = (m * eccbits + 7) / 8;
> > > +	struct bch_control *bch = init_bch(m, eccbits, 0);
> > > +	uint8_t *fcb = xmalloc(numblocks * blocksize);
> > > +	uint8_t *ecc_buf = xmalloc(ecc_buf_size);
> > > +	uint8_t *data_buf = xmalloc(blocksize);
> > > +	unsigned int *errloc = xmalloc(eccbits * sizeof(*errloc));
> > > +	uint8_t *psrc, *pdst;
> > > +
> > > +	/* see encode_bch_ecc */
> > > +	BUG_ON(eccbits % 8);
> > > +
> > > +	for (i = 0; i < numblocks; i++) {
> > > +		psrc = rawpage + 32 + i * (blocksize + ecc_buf_size);
> > > +		pdst = fcb + i * blocksize;
> > > +
> > > +		/* reverse data bit */
> > > +		for (j = 0; j < blocksize; j++)
> > > +			data_buf[j] = reverse_bit(psrc[j]);
> > > +
> > > +		/* reverse ecc bit */
> > > +		for (j = 0; j < ecc_buf_size; j++)
> > > +			ecc_buf[j] = reverse_bit(psrc[j + blocksize]);
> > > +
> > > +		ret = decode_bch(bch, data_buf, blocksize, ecc_buf,
> > > +				 NULL, NULL, errloc);
> > > +
> > > +		if (ret < 0) {
> > > +			pr_err("Uncorrectable error at block %d\n", i);
> > > +			free(fcb);
> > > +			fcb = ERR_PTR(ret);
> > > +			goto out;
> > > +		}
> > > +		if (ret > 0)
> > > +			pr_info("Found %d correctable errors in block %d\n",
> > > +				ret, i);
> > > +
> > > +		for (j = 0; j < ret; j++) {
> > > +			/*
> > > +			 * calculate the reverse position
> > > +			 * pos - (pos % 8) -> byte offset
> > > +			 * 7 - (pos % 8) -> reverse bit position
> > > +			 */
> > > +			errbit = errloc[j] - 2 * (errloc[j] % 8) + 7;
> > > +			pr_debug("Found error: bit %d in block %d\n",
> > > +				 errbit, i);
> > > +			if (errbit < blocksize * 8)
> > > +				change_bit(errbit, psrc);
> > > +			/* else error in ecc, ignore it */
> > > +		}
> > > +		memcpy(pdst, psrc, blocksize);
> > > +	}
> > > +
> > > +out:
> > > +	free(data_buf);
> > > +	free(ecc_buf);
> > > +	free(errloc);
> > > +	free_bch(bch);
> > > +
> > > +	return (struct fcb_block *)fcb;
> > > +}
> > > +
> > >  static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
> > >  {
> > >  	int i;
> > > @@ -312,7 +441,11 @@ static int read_fcb(struct mtd_info *mtd, int num, struct fcb_block **retfcb)
> > >  		goto err;
> > >  	}
> > >  
> > > -	fcb = read_fcb_hamming_13_8(rawpage);
> > > +	if (cpu_is_mx6ul())
> > > +		fcb = read_fcb_bch(rawpage, 40);
> > > +	else
> > > +		fcb = read_fcb_hamming_13_8(rawpage);
> > > +
> > >  	if (IS_ERR(fcb)) {
> > >  		pr_err("Cannot read fcb\n");
> > >  		ret = PTR_ERR(fcb);
> > > @@ -766,8 +899,14 @@ static int imx_bbu_write_fcbs_dbbts(struct mtd_info *mtd, struct fcb_block *fcb)
> > >  
> > >  	fcb_raw_page = xzalloc(mtd->writesize + mtd->oobsize);
> > >  
> > > -	memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
> > > -	encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512);
> > > +	if (cpu_is_mx6ul()) {
> > > +		/* 40 bit BCH, for i.MX6UL */
> > > +		encode_bch_ecc(fcb_raw_page + 32, fcb, 40);
> > > +	} else {
> > > +		memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
> > > +		encode_hamming_13_8(fcb_raw_page + 12,
> > > +				    fcb_raw_page + 12 + 512, 512);
> > > +	}
> > >  
> > >  	dbbt = dbbt_data_create(mtd);
> > >  
> > > -- 
> > > 2.7.4
> > > 
> > > 
> > > _______________________________________________
> > > barebox mailing list
> > > barebox@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/barebox
> > 
> > _______________________________________________
> > barebox mailing list
> > barebox@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/barebox
> > 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

      reply	other threads:[~2017-04-27  9:41 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-14  7:59 [PATCH 1/2] imx-bbu-nand-fcb: split up read_fcb Jan Remmet
2016-12-14  7:59 ` [PATCH 2/2] imx-bbu-nand-fcb: add support for imx6ul Jan Remmet
2017-04-26 14:43   ` Jan Remmet
2017-04-27  7:01     ` Sascha Hauer
2017-04-27  9:40       ` Jan Remmet [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170427094044.GC2932@lws-weitzel2@phytec.de \
    --to=j.remmet@phytec.de \
    --cc=barebox@lists.infradead.org \
    --cc=s.hauer@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox