#include <asm/processor.h>
#include <asm/io.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <environment.h>
#include <mtd/cfi_flash.h>
#include <watchdog.h>
u32 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;
+ tmp = get_unaligned(&(qry->erase_region_info[i]));
+ put_unaligned(get_unaligned(&(qry->erase_region_info[j])),
+ &(qry->erase_region_info[i]));
+ put_unaligned(tmp, &(qry->erase_region_info[j]));
}
}
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 = le16_to_cpu(get_unaligned(&(qry.p_id)));
+ info->ext_addr = le16_to_cpu(get_unaligned(&(qry.p_adr)));
num_erase_regions = qry.num_erase_regions;
if (info->ext_addr) {
break;
}
- tmp = le32_to_cpu(qry.erase_region_info[i]);
+ tmp = le32_to_cpu(get_unaligned(
+ &(qry.erase_region_info[i])));
debug("erase region %u: 0x%08lx\n", i, tmp);
erase_region_count = (tmp & 0xffff) + 1;
} cfiword_t;
/* CFI standard query structure */
+/* The offsets and sizes of this packed structure members correspond
+ * to the actual layout in CFI Flash chips. Some 16- and 32-bit members
+ * are unaligned and must be accessed with explicit unaligned access macros.
+ */
struct cfi_qry {
u8 qry[3];
- u16 p_id;
- u16 p_adr;
- u16 a_id;
- u16 a_adr;
+ u16 p_id; /* unaligned */
+ u16 p_adr; /* unaligned */
+ u16 a_id; /* unaligned */
+ u16 a_adr; /* unaligned */
u8 vcc_min;
u8 vcc_max;
u8 vpp_min;
u8 block_erase_timeout_max;
u8 chip_erase_timeout_max;
u8 dev_size;
- u16 interface_desc;
- u16 max_buf_write_size;
+ u16 interface_desc; /* aligned */
+ u16 max_buf_write_size; /* aligned */
u8 num_erase_regions;
- u32 erase_region_info[NUM_ERASE_REGIONS];
+ u32 erase_region_info[NUM_ERASE_REGIONS]; /* unaligned */
} __attribute__((packed));
struct cfi_pri_hdr {