All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gabbasov, Andrew <Andrew_Gabbasov@mentor.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] ARM: cfi_flash: Fix unaligned accesses to cfi_qry structure
Date: Mon, 29 Apr 2013 09:45:50 +0000	[thread overview]
Message-ID: <6C5EA58090A5ED459815C4D04C2B466FD932D695@EU-MBX-01.mgc.mentorg.com> (raw)
In-Reply-To: <1367228070-6351-1-git-send-email-andrew_gabbasov@mentor.com>

> From: Gabbasov, Andrew
> Sent: Monday, April 29, 2013 13:34
> To: u-boot at lists.denx.de
> Subject: [U-Boot][PATCH] ARM: cfi_flash: Fix unaligned accesses to cfi_qry structure
> 
> Packed structure cfi_qry contains unaligned 16- and 32-bits members,
> accessing which causes problems when cfi_flash driver is compiled with
> -munaligned-access option: flash initialization hangs, probably
> due to data error.
> 
> This fix converts 16- and 32-bit members to byte arrays and uses special
> macros to access such fields. It removes possible unaligned accesses
> in cfi_flash driver.
> 
> Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
> ---
>  drivers/mtd/cfi_flash.c |   23 +++++++++++++----------
>  include/mtd/cfi_flash.h |   18 +++++++++++-------
>  2 files changed, 24 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
> index 60dbb78..2112ffc 100644
> --- a/drivers/mtd/cfi_flash.c
> +++ b/drivers/mtd/cfi_flash.c
> @@ -1636,13 +1636,16 @@ void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
>   */
>  static void cfi_reverse_geometry(struct cfi_qry *qry)
>  {
> -       unsigned int i, j;
> -       u32 tmp;
> +       unsigned int i, j, k;
> +       u8 tmp;
> 
>         for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
> -               tmp = qry->erase_region_info[i];
> -               qry->erase_region_info[i] = qry->erase_region_info[j];
> -               qry->erase_region_info[j] = tmp;
> +               for (k = 0; k < 4; k++) {
> +                       tmp = qry->erase_region_info[k][i];
> +                       qry->erase_region_info[k][i] =
> +                               qry->erase_region_info[k][j];
> +                       qry->erase_region_info[k][j] = tmp;
> +               }
>         }
>  }
> 
> @@ -1891,7 +1894,7 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
>                     && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
>                         flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
>                                         sizeof(struct cfi_qry));
> -                       info->interface = le16_to_cpu(qry->interface_desc);
> +                       info->interface = cfiqry_get16(qry->interface_desc);
> 
>                         info->cfi_offset = flash_offset_cfi[cfi_offset];
>                         debug ("device interface is %d\n",
> @@ -2053,8 +2056,8 @@ ulong flash_get_size (phys_addr_t base, int banknum)
>         info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
> 
>         if (flash_detect_cfi (info, &qry)) {
> -               info->vendor = le16_to_cpu(qry.p_id);
> -               info->ext_addr = le16_to_cpu(qry.p_adr);
> +               info->vendor = cfiqry_get16(qry.p_id);
> +               info->ext_addr = cfiqry_get16(qry.p_adr);
>                 num_erase_regions = qry.num_erase_regions;
> 
>                 if (info->ext_addr) {
> @@ -2140,7 +2143,7 @@ ulong flash_get_size (phys_addr_t base, int banknum)
>                                 break;
>                         }
> 
> -                       tmp = le32_to_cpu(qry.erase_region_info[i]);
> +                       tmp = cfiqry_get32(qry.erase_region_info[i]);
>                         debug("erase region %u: 0x%08lx\n", i, tmp);
> 
>                         erase_region_count = (tmp & 0xffff) + 1;
> @@ -2213,7 +2216,7 @@ ulong flash_get_size (phys_addr_t base, int banknum)
>                 }
> 
>                 info->sector_count = sect_cnt;
> -               info->buffer_size = 1 << le16_to_cpu(qry.max_buf_write_size);
> +               info->buffer_size = 1 << cfiqry_get16(qry.max_buf_write_size);
>                 tmp = 1 << qry.block_erase_timeout_typ;
>                 info->erase_blk_tout = tmp *
>                         (1 << qry.block_erase_timeout_max);
> diff --git a/include/mtd/cfi_flash.h b/include/mtd/cfi_flash.h
> index 966b5e0..30d6896 100644
> --- a/include/mtd/cfi_flash.h
> +++ b/include/mtd/cfi_flash.h
> @@ -131,10 +131,10 @@ typedef union {
>  /* CFI standard query structure */
>  struct cfi_qry {
>         u8      qry[3];
> -       u16     p_id;
> -       u16     p_adr;
> -       u16     a_id;
> -       u16     a_adr;
> +       u8      p_id[2];
> +       u8      p_adr[2];
> +       u8      a_id[2];
> +       u8      a_adr[2];
>         u8      vcc_min;
>         u8      vcc_max;
>         u8      vpp_min;
> @@ -148,10 +148,10 @@ struct cfi_qry {
>         u8      block_erase_timeout_max;
>         u8      chip_erase_timeout_max;
>         u8      dev_size;
> -       u16     interface_desc;
> -       u16     max_buf_write_size;
> +       u8      interface_desc[2];
> +       u8      max_buf_write_size[2];
>         u8      num_erase_regions;
> -       u32     erase_region_info[NUM_ERASE_REGIONS];
> +       u8      erase_region_info[4][NUM_ERASE_REGIONS];
>  } __attribute__((packed));
> 
>  struct cfi_pri_hdr {
> @@ -160,6 +160,10 @@ struct cfi_pri_hdr {
>         u8      minor_version;
>  } __attribute__((packed));
> 
> +#define cfiqry_get16(mp) ((u16)((mp)[0]) | ((u16)((mp)[1]) << 8))
> +#define cfiqry_get32(mp) ((u32)((mp)[0]) | ((u32)((mp)[1]) << 8) | \
> +                         ((u32)((mp)[2]) << 16) | ((u32)((mp)[3]) << 24))
> +
>  #ifndef CONFIG_SYS_FLASH_BANKS_LIST
>  #define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
>  #endif
> --
> 1.7.10.4

Unfortunately, I can't verify this fix for the boards with flash configuration,
requiring reversing geometry. So, if anybody could test it on such board,
I would greatly appreciate it.

Thanks.

Best regards,
Andrew

  reply	other threads:[~2013-04-29  9:45 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-29  9:34 [U-Boot] [PATCH] ARM: cfi_flash: Fix unaligned accesses to cfi_qry structure Andrew Gabbasov
2013-04-29  9:45 ` Gabbasov, Andrew [this message]
2013-05-08 17:26 ` Marek Vasut
2013-05-08 17:38   ` Gabbasov, Andrew
2013-05-10 10:13 ` [U-Boot] " Masahiro Yamada
2013-05-10 12:36   ` Marek Vasut
2013-05-13  2:25     ` Masahiro Yamada
2013-05-13  3:37       ` Marek Vasut
2013-05-13  6:48     ` Albert ARIBAUD
2013-05-14 17:27       ` Gabbasov, Andrew
2013-05-22 15:12         ` Gabbasov, Andrew

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=6C5EA58090A5ED459815C4D04C2B466FD932D695@EU-MBX-01.mgc.mentorg.com \
    --to=andrew_gabbasov@mentor.com \
    --cc=u-boot@lists.denx.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.