Lines Matching +full:device +full:- +full:width

22  * For now, this code can emulate flashes of 1, 2 or 4 bytes width.
24 * - flash read
25 * - flash write
26 * - flash ID read
27 * - sector erase
28 * - CFI queries
42 #include "hw/qdev-properties.h"
43 #include "hw/qdev-properties-system.h"
44 #include "sysemu/block-backend.h"
46 #include "qemu/error-report.h"
48 #include "qemu/host-utils.h"
69 uint8_t device_width; /* If 0, device width not specified. */
70 uint8_t max_device_width; /* max device width in bytes */
100 return (pfl->blk_offset != -1); in pflash_blk_write_state_needed()
134 * Perform a CFI query based on the bank width of the flash.
145 * Adjust incoming offset to match expected device-width in pflash_cfi_query()
147 * the maximum supported width of the device. This means that x8 in pflash_cfi_query()
149 * devices that are not used at their max width, we will be in pflash_cfi_query()
151 * expected (based on the max width), so we will shift them lower in pflash_cfi_query()
155 boff = offset >> (ctz32(pfl->bank_width) + in pflash_cfi_query()
156 ctz32(pfl->max_device_width) - ctz32(pfl->device_width)); in pflash_cfi_query()
158 if (boff >= sizeof(pfl->cfi_table)) { in pflash_cfi_query()
163 * device, then replicate that for all devices that make up the in pflash_cfi_query()
165 * are different than native byte-wide parts. in pflash_cfi_query()
167 resp = pfl->cfi_table[boff]; in pflash_cfi_query()
168 if (pfl->device_width != pfl->max_device_width) { in pflash_cfi_query()
172 if (pfl->device_width != 1 || pfl->bank_width > 4) { in pflash_cfi_query()
173 trace_pflash_unsupported_device_configuration(pfl->name, in pflash_cfi_query()
174 pfl->device_width, pfl->max_device_width); in pflash_cfi_query()
180 for (i = 1; i < pfl->max_device_width; i++) { in pflash_cfi_query()
181 resp = deposit32(resp, 8 * i, 8, pfl->cfi_table[boff]); in pflash_cfi_query()
184 /* Replicate responses for each device in bank. */ in pflash_cfi_query()
185 if (pfl->device_width < pfl->bank_width) { in pflash_cfi_query()
186 for (i = pfl->device_width; in pflash_cfi_query()
187 i < pfl->bank_width; i += pfl->device_width) { in pflash_cfi_query()
188 resp = deposit32(resp, 8 * i, 8 * pfl->device_width, resp); in pflash_cfi_query()
197 /* Perform a device id query based on the bank width of the flash. */
205 * Adjust incoming offset to match expected device-width in pflash_devid_query()
206 * addressing. Device ID read addresses are always specified in in pflash_devid_query()
207 * terms of the maximum supported width of the device. This means in pflash_devid_query()
209 * differently. For devices that are not used at their max width, in pflash_devid_query()
211 * than expected (based on the max width), so we will shift them in pflash_devid_query()
215 boff = offset >> (ctz32(pfl->bank_width) + in pflash_devid_query()
216 ctz32(pfl->max_device_width) - ctz32(pfl->device_width)); in pflash_devid_query()
225 resp = pfl->ident0; in pflash_devid_query()
226 trace_pflash_manufacturer_id(pfl->name, resp); in pflash_devid_query()
229 resp = pfl->ident1; in pflash_devid_query()
230 trace_pflash_device_id(pfl->name, resp); in pflash_devid_query()
233 trace_pflash_device_info(pfl->name, offset); in pflash_devid_query()
236 /* Replicate responses for each device in bank. */ in pflash_devid_query()
237 if (pfl->device_width < pfl->bank_width) { in pflash_devid_query()
238 for (i = pfl->device_width; in pflash_devid_query()
239 i < pfl->bank_width; i += pfl->device_width) { in pflash_devid_query()
240 resp = deposit32(resp, 8 * i, 8 * pfl->device_width, resp); in pflash_devid_query()
248 int width, int be) in pflash_data_read() argument
253 p = pfl->storage; in pflash_data_read()
255 ret = ldn_be_p(p + offset, width); in pflash_data_read()
257 ret = ldn_le_p(p + offset, width); in pflash_data_read()
259 trace_pflash_data_read(pfl->name, offset, width, ret); in pflash_data_read()
264 int width, int be) in pflash_read() argument
269 ret = -1; in pflash_read()
270 switch (pfl->cmd) { in pflash_read()
273 trace_pflash_read_unknown_state(pfl->name, pfl->cmd); in pflash_read()
274 pfl->wcycle = 0; in pflash_read()
279 pfl->cmd = 0x00; in pflash_read()
283 ret = pflash_data_read(pfl, offset, width, be); in pflash_read()
294 * Status register read. Return status from each device in in pflash_read()
297 ret = pfl->status; in pflash_read()
298 if (pfl->device_width && width > pfl->device_width) { in pflash_read()
299 int shift = pfl->device_width * 8; in pflash_read()
300 while (shift + pfl->device_width * 8 <= width * 8) { in pflash_read()
301 ret |= pfl->status << shift; in pflash_read()
302 shift += pfl->device_width * 8; in pflash_read()
304 } else if (!pfl->device_width && width > 2) { in pflash_read()
306 * Handle 32 bit flash cases where device width is not in pflash_read()
307 * set. (Existing behavior before device width added.) in pflash_read()
309 ret |= pfl->status << 16; in pflash_read()
311 trace_pflash_read_status(pfl->name, ret); in pflash_read()
314 if (!pfl->device_width) { in pflash_read()
315 /* Preserve old behavior if device width not specified */ in pflash_read()
317 if (pfl->bank_width == 2) { in pflash_read()
319 } else if (pfl->bank_width == 4) { in pflash_read()
325 ret = pfl->ident0 << 8 | pfl->ident1; in pflash_read()
326 trace_pflash_manufacturer_id(pfl->name, ret); in pflash_read()
329 ret = pfl->ident2 << 8 | pfl->ident3; in pflash_read()
330 trace_pflash_device_id(pfl->name, ret); in pflash_read()
333 trace_pflash_device_info(pfl->name, boff); in pflash_read()
340 * manufacturer/device ID queries into a single response. in pflash_read()
343 for (i = 0; i < width; i += pfl->bank_width) { in pflash_read()
344 ret = deposit32(ret, i * 8, pfl->bank_width * 8, in pflash_read()
346 offset + i * pfl->bank_width)); in pflash_read()
351 if (!pfl->device_width) { in pflash_read()
352 /* Preserve old behavior if device width not specified */ in pflash_read()
354 if (pfl->bank_width == 2) { in pflash_read()
356 } else if (pfl->bank_width == 4) { in pflash_read()
360 if (boff < sizeof(pfl->cfi_table)) { in pflash_read()
361 ret = pfl->cfi_table[boff]; in pflash_read()
371 for (i = 0; i < width; i += pfl->bank_width) { in pflash_read()
372 ret = deposit32(ret, i * 8, pfl->bank_width * 8, in pflash_read()
374 offset + i * pfl->bank_width)); in pflash_read()
380 trace_pflash_io_read(pfl->name, offset, width, ret, pfl->cmd, pfl->wcycle); in pflash_read()
391 if (pfl->blk) { in pflash_update()
396 ret = blk_pwrite(pfl->blk, offset, offset_end - offset, in pflash_update()
397 pfl->storage + offset, 0); in pflash_update()
400 error_report("Could not update PFLASH: %s", strerror(-ret)); in pflash_update()
408 hwaddr mask = ~(pfl->writeblock_size - 1); in pflash_blk_write_start()
410 trace_pflash_write_block_start(pfl->name, pfl->counter); in pflash_blk_write_start()
411 pfl->blk_offset = offset & mask; in pflash_blk_write_start()
412 memcpy(pfl->blk_bytes, pfl->storage + pfl->blk_offset, in pflash_blk_write_start()
413 pfl->writeblock_size); in pflash_blk_write_start()
419 g_assert(pfl->blk_offset != -1); in pflash_blk_write_flush()
420 trace_pflash_write_block_flush(pfl->name); in pflash_blk_write_flush()
421 memcpy(pfl->storage + pfl->blk_offset, pfl->blk_bytes, in pflash_blk_write_flush()
422 pfl->writeblock_size); in pflash_blk_write_flush()
423 pflash_update(pfl, pfl->blk_offset, pfl->writeblock_size); in pflash_blk_write_flush()
424 pfl->blk_offset = -1; in pflash_blk_write_flush()
430 trace_pflash_write_block_abort(pfl->name); in pflash_blk_write_abort()
431 pfl->blk_offset = -1; in pflash_blk_write_abort()
435 uint32_t value, int width, int be) in pflash_data_write() argument
439 if (pfl->blk_offset != -1) { in pflash_data_write()
441 if ((offset < pfl->blk_offset) || in pflash_data_write()
442 (offset + width > pfl->blk_offset + pfl->writeblock_size)) { in pflash_data_write()
443 pfl->status |= 0x10; /* Programming error */ in pflash_data_write()
446 trace_pflash_data_write_block(pfl->name, offset, width, value, in pflash_data_write()
447 pfl->counter); in pflash_data_write()
448 p = pfl->blk_bytes + (offset - pfl->blk_offset); in pflash_data_write()
451 trace_pflash_data_write(pfl->name, offset, width, value); in pflash_data_write()
452 p = pfl->storage + offset; in pflash_data_write()
456 stn_be_p(p, width, value); in pflash_data_write()
458 stn_le_p(p, width, value); in pflash_data_write()
463 uint32_t value, int width, int be) in pflash_write() argument
470 trace_pflash_io_write(pfl->name, offset, width, value, pfl->wcycle); in pflash_write()
471 if (!pfl->wcycle) { in pflash_write()
472 /* Set the device in I/O access mode */ in pflash_write()
473 memory_region_rom_device_set_romd(&pfl->mem, false); in pflash_write()
476 switch (pfl->wcycle) { in pflash_write()
484 trace_pflash_write(pfl->name, "single byte program (0)"); in pflash_write()
487 p = pfl->storage; in pflash_write()
488 offset &= ~(pfl->sector_len - 1); in pflash_write()
490 trace_pflash_write_block_erase(pfl->name, offset, pfl->sector_len); in pflash_write()
492 if (!pfl->ro) { in pflash_write()
493 memset(p + offset, 0xff, pfl->sector_len); in pflash_write()
494 pflash_update(pfl, offset, pfl->sector_len); in pflash_write()
496 pfl->status |= 0x20; /* Block erase error */ in pflash_write()
498 pfl->status |= 0x80; /* Ready! */ in pflash_write()
501 trace_pflash_write(pfl->name, "clear status bits"); in pflash_write()
502 pfl->status = 0x0; in pflash_write()
505 trace_pflash_write(pfl->name, "block unlock"); in pflash_write()
508 trace_pflash_write(pfl->name, "read status register"); in pflash_write()
509 pfl->cmd = cmd; in pflash_write()
511 case 0x90: /* Read Device ID */ in pflash_write()
512 trace_pflash_write(pfl->name, "read device information"); in pflash_write()
513 pfl->cmd = cmd; in pflash_write()
516 trace_pflash_write(pfl->name, "CFI query"); in pflash_write()
519 trace_pflash_write(pfl->name, "write to buffer"); in pflash_write()
520 pfl->status |= 0x80; /* Ready! */ in pflash_write()
523 trace_pflash_write(pfl->name, "probe for AMD flash"); in pflash_write()
526 trace_pflash_write(pfl->name, "read array mode"); in pflash_write()
531 pfl->wcycle++; in pflash_write()
532 pfl->cmd = cmd; in pflash_write()
535 switch (pfl->cmd) { in pflash_write()
538 trace_pflash_write(pfl->name, "single byte program (1)"); in pflash_write()
539 if (!pfl->ro) { in pflash_write()
540 pflash_data_write(pfl, offset, value, width, be); in pflash_write()
541 pflash_update(pfl, offset, width); in pflash_write()
543 pfl->status |= 0x10; /* Programming error */ in pflash_write()
545 pfl->status |= 0x80; /* Ready! */ in pflash_write()
546 pfl->wcycle = 0; in pflash_write()
551 pfl->wcycle = 0; in pflash_write()
552 pfl->status |= 0x80; in pflash_write()
561 * Mask writeblock size based on device width, or bank width if in pflash_write()
562 * device width not specified. in pflash_write()
564 /* FIXME check @offset, @width */ in pflash_write()
565 if (pfl->device_width) { in pflash_write()
566 value = extract32(value, 0, pfl->device_width * 8); in pflash_write()
568 value = extract32(value, 0, pfl->bank_width * 8); in pflash_write()
570 pfl->counter = value; in pflash_write()
571 pfl->wcycle++; in pflash_write()
575 pfl->wcycle = 0; in pflash_write()
576 pfl->status |= 0x80; in pflash_write()
578 pfl->wcycle = 0; in pflash_write()
579 pfl->status |= 0x80; in pflash_write()
583 trace_pflash_write(pfl->name, "unknown (un)locking command"); in pflash_write()
591 trace_pflash_write(pfl->name, "leaving query mode"); in pflash_write()
599 switch (pfl->cmd) { in pflash_write()
601 /* FIXME check @offset, @width */ in pflash_write()
602 if (pfl->blk_offset == -1 && pfl->counter) { in pflash_write()
605 if (!pfl->ro && (pfl->blk_offset != -1)) { in pflash_write()
606 pflash_data_write(pfl, offset, value, width, be); in pflash_write()
608 pfl->status |= 0x10; /* Programming error */ in pflash_write()
611 pfl->status |= 0x80; in pflash_write()
613 if (!pfl->counter) { in pflash_write()
614 trace_pflash_write(pfl->name, "block write finished"); in pflash_write()
615 pfl->wcycle++; in pflash_write()
619 pfl->counter--; in pflash_write()
626 switch (pfl->cmd) { in pflash_write()
628 if ((cmd == 0xd0) && !(pfl->status & 0x10)) { in pflash_write()
630 pfl->wcycle = 0; in pflash_write()
631 pfl->status |= 0x80; in pflash_write()
644 trace_pflash_write(pfl->name, "invalid write state"); in pflash_write()
652 "\n", __func__, offset, pfl->wcycle, pfl->cmd, value); in pflash_write()
655 trace_pflash_mode_read_array(pfl->name); in pflash_write()
656 memory_region_rom_device_set_romd(&pfl->mem, true); in pflash_write()
657 pfl->wcycle = 0; in pflash_write()
658 pfl->cmd = 0x00; /* This model reset value for READ_ARRAY (not CFI) */ in pflash_write()
666 bool be = !!(pfl->features & (1 << PFLASH_BE)); in pflash_mem_read_with_attrs()
668 if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) { in pflash_mem_read_with_attrs()
680 bool be = !!(pfl->features & (1 << PFLASH_BE)); in pflash_mem_write_with_attrs()
682 if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) { in pflash_mem_write_with_attrs()
702 * These are only used to expose the parameters of each device in pflash_cfi01_fill_cfi_table()
705 num_devices = pfl->device_width ? (pfl->bank_width / pfl->device_width) : 1; in pflash_cfi01_fill_cfi_table()
706 if (pfl->old_multiple_chip_handling) { in pflash_cfi01_fill_cfi_table()
707 blocks_per_device = pfl->nb_blocs / num_devices; in pflash_cfi01_fill_cfi_table()
708 sector_len_per_device = pfl->sector_len; in pflash_cfi01_fill_cfi_table()
710 blocks_per_device = pfl->nb_blocs; in pflash_cfi01_fill_cfi_table()
711 sector_len_per_device = pfl->sector_len / num_devices; in pflash_cfi01_fill_cfi_table()
717 pfl->cfi_table[0x10] = 'Q'; in pflash_cfi01_fill_cfi_table()
718 pfl->cfi_table[0x11] = 'R'; in pflash_cfi01_fill_cfi_table()
719 pfl->cfi_table[0x12] = 'Y'; in pflash_cfi01_fill_cfi_table()
721 pfl->cfi_table[0x13] = 0x01; in pflash_cfi01_fill_cfi_table()
722 pfl->cfi_table[0x14] = 0x00; in pflash_cfi01_fill_cfi_table()
724 pfl->cfi_table[0x15] = 0x31; in pflash_cfi01_fill_cfi_table()
725 pfl->cfi_table[0x16] = 0x00; in pflash_cfi01_fill_cfi_table()
727 pfl->cfi_table[0x17] = 0x00; in pflash_cfi01_fill_cfi_table()
728 pfl->cfi_table[0x18] = 0x00; in pflash_cfi01_fill_cfi_table()
730 pfl->cfi_table[0x19] = 0x00; in pflash_cfi01_fill_cfi_table()
731 pfl->cfi_table[0x1A] = 0x00; in pflash_cfi01_fill_cfi_table()
733 pfl->cfi_table[0x1B] = 0x45; in pflash_cfi01_fill_cfi_table()
735 pfl->cfi_table[0x1C] = 0x55; in pflash_cfi01_fill_cfi_table()
737 pfl->cfi_table[0x1D] = 0x00; in pflash_cfi01_fill_cfi_table()
739 pfl->cfi_table[0x1E] = 0x00; in pflash_cfi01_fill_cfi_table()
741 pfl->cfi_table[0x1F] = 0x07; in pflash_cfi01_fill_cfi_table()
743 pfl->cfi_table[0x20] = 0x07; in pflash_cfi01_fill_cfi_table()
745 pfl->cfi_table[0x21] = 0x0a; in pflash_cfi01_fill_cfi_table()
747 pfl->cfi_table[0x22] = 0x00; in pflash_cfi01_fill_cfi_table()
749 pfl->cfi_table[0x23] = 0x04; in pflash_cfi01_fill_cfi_table()
751 pfl->cfi_table[0x24] = 0x04; in pflash_cfi01_fill_cfi_table()
753 pfl->cfi_table[0x25] = 0x04; in pflash_cfi01_fill_cfi_table()
755 pfl->cfi_table[0x26] = 0x00; in pflash_cfi01_fill_cfi_table()
756 /* Device size */ in pflash_cfi01_fill_cfi_table()
757 pfl->cfi_table[0x27] = ctz32(device_len); /* + 1; */ in pflash_cfi01_fill_cfi_table()
758 /* Flash device interface (8 & 16 bits) */ in pflash_cfi01_fill_cfi_table()
759 pfl->cfi_table[0x28] = 0x02; in pflash_cfi01_fill_cfi_table()
760 pfl->cfi_table[0x29] = 0x00; in pflash_cfi01_fill_cfi_table()
761 /* Max number of bytes in multi-bytes write */ in pflash_cfi01_fill_cfi_table()
762 if (pfl->bank_width == 1) { in pflash_cfi01_fill_cfi_table()
763 pfl->cfi_table[0x2A] = 0x08; in pflash_cfi01_fill_cfi_table()
765 pfl->cfi_table[0x2A] = 0x0B; in pflash_cfi01_fill_cfi_table()
767 pfl->writeblock_size = 1 << pfl->cfi_table[0x2A]; in pflash_cfi01_fill_cfi_table()
768 if (!pfl->old_multiple_chip_handling && num_devices > 1) { in pflash_cfi01_fill_cfi_table()
769 pfl->writeblock_size *= num_devices; in pflash_cfi01_fill_cfi_table()
772 pfl->cfi_table[0x2B] = 0x00; in pflash_cfi01_fill_cfi_table()
774 pfl->cfi_table[0x2C] = 0x01; in pflash_cfi01_fill_cfi_table()
776 pfl->cfi_table[0x2D] = blocks_per_device - 1; in pflash_cfi01_fill_cfi_table()
777 pfl->cfi_table[0x2E] = (blocks_per_device - 1) >> 8; in pflash_cfi01_fill_cfi_table()
778 pfl->cfi_table[0x2F] = sector_len_per_device >> 8; in pflash_cfi01_fill_cfi_table()
779 pfl->cfi_table[0x30] = sector_len_per_device >> 16; in pflash_cfi01_fill_cfi_table()
782 pfl->cfi_table[0x31] = 'P'; in pflash_cfi01_fill_cfi_table()
783 pfl->cfi_table[0x32] = 'R'; in pflash_cfi01_fill_cfi_table()
784 pfl->cfi_table[0x33] = 'I'; in pflash_cfi01_fill_cfi_table()
786 pfl->cfi_table[0x34] = '1'; in pflash_cfi01_fill_cfi_table()
787 pfl->cfi_table[0x35] = '0'; in pflash_cfi01_fill_cfi_table()
789 pfl->cfi_table[0x36] = 0x00; in pflash_cfi01_fill_cfi_table()
790 pfl->cfi_table[0x37] = 0x00; in pflash_cfi01_fill_cfi_table()
791 pfl->cfi_table[0x38] = 0x00; in pflash_cfi01_fill_cfi_table()
792 pfl->cfi_table[0x39] = 0x00; in pflash_cfi01_fill_cfi_table()
794 pfl->cfi_table[0x3a] = 0x00; in pflash_cfi01_fill_cfi_table()
796 pfl->cfi_table[0x3b] = 0x00; in pflash_cfi01_fill_cfi_table()
797 pfl->cfi_table[0x3c] = 0x00; in pflash_cfi01_fill_cfi_table()
799 pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */ in pflash_cfi01_fill_cfi_table()
809 if (pfl->sector_len == 0) { in pflash_cfi01_realize()
810 error_setg(errp, "attribute \"sector-length\" not specified or zero."); in pflash_cfi01_realize()
813 if (pfl->nb_blocs == 0) { in pflash_cfi01_realize()
814 error_setg(errp, "attribute \"num-blocks\" not specified or zero."); in pflash_cfi01_realize()
817 if (pfl->name == NULL) { in pflash_cfi01_realize()
822 total_len = pfl->sector_len * pfl->nb_blocs; in pflash_cfi01_realize()
825 &pfl->mem, OBJECT(dev), in pflash_cfi01_realize()
828 pfl->name, total_len, errp); in pflash_cfi01_realize()
833 pfl->storage = memory_region_get_ram_ptr(&pfl->mem); in pflash_cfi01_realize()
834 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem); in pflash_cfi01_realize()
836 if (pfl->blk) { in pflash_cfi01_realize()
838 pfl->ro = !blk_supports_write_perm(pfl->blk); in pflash_cfi01_realize()
839 perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE); in pflash_cfi01_realize()
840 ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp); in pflash_cfi01_realize()
845 pfl->ro = false; in pflash_cfi01_realize()
848 if (pfl->blk) { in pflash_cfi01_realize()
849 if (!blk_check_size_and_read_all(pfl->blk, dev, pfl->storage, in pflash_cfi01_realize()
851 vmstate_unregister_ram(&pfl->mem, DEVICE(pfl)); in pflash_cfi01_realize()
857 * Default to devices being used at their maximum device width. This was in pflash_cfi01_realize()
860 if (!pfl->max_device_width) { in pflash_cfi01_realize()
861 pfl->max_device_width = pfl->device_width; in pflash_cfi01_realize()
864 pfl->wcycle = 0; in pflash_cfi01_realize()
869 pfl->cmd = 0x00; in pflash_cfi01_realize()
870 pfl->status = 0x80; /* WSM ready */ in pflash_cfi01_realize()
873 pfl->blk_bytes = g_malloc(pfl->writeblock_size); in pflash_cfi01_realize()
874 pfl->blk_offset = -1; in pflash_cfi01_realize()
881 trace_pflash_reset(pfl->name); in pflash_cfi01_system_reset()
886 pfl->cmd = 0x00; in pflash_cfi01_system_reset()
887 pfl->wcycle = 0; in pflash_cfi01_system_reset()
888 memory_region_rom_device_set_romd(&pfl->mem, true); in pflash_cfi01_system_reset()
893 pfl->status = 0x80; in pflash_cfi01_system_reset()
895 pfl->blk_offset = -1; in pflash_cfi01_system_reset()
900 /* num-blocks is the number of blocks actually visible to the guest,
901 * ie the total size of the device divided by the sector length.
903 * number of blocks per individual device will differ.
905 DEFINE_PROP_UINT32("num-blocks", PFlashCFI01, nb_blocs, 0),
906 DEFINE_PROP_UINT64("sector-length", PFlashCFI01, sector_len, 0),
907 /* width here is the overall width of this QEMU device in bytes.
908 * The QEMU device may be emulating a number of flash devices
909 * wired up in parallel; the width of each individual flash
910 * device should be specified via device-width. If the individual
911 * devices have a maximum width which is greater than the width
912 * they are being used for, this maximum width should be set via
913 * max-device-width (which otherwise defaults to device-width).
914 * So for instance a 32-bit wide QEMU flash device made from four
915 * 16-bit flash devices used in 8-bit wide mode would be configured
916 * with width = 4, device-width = 1, max-device-width = 2.
918 * If device-width is not specified we default to backwards
920 * 16 bit devices making up a 32 bit wide QEMU device. This
921 * is deprecated for new uses of this device.
923 DEFINE_PROP_UINT8("width", PFlashCFI01, bank_width, 0),
924 DEFINE_PROP_UINT8("device-width", PFlashCFI01, device_width, 0),
925 DEFINE_PROP_UINT8("max-device-width", PFlashCFI01, max_device_width, 0),
926 DEFINE_PROP_BIT("big-endian", PFlashCFI01, features, PFLASH_BE, 0),
933 DEFINE_PROP_BOOL("old-multiple-chip-handling", PFlashCFI01,
943 dc->realize = pflash_cfi01_realize; in pflash_cfi01_class_init()
945 dc->vmsd = &vmstate_pflash; in pflash_cfi01_class_init()
946 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); in pflash_cfi01_class_init()
976 qdev_prop_set_uint32(dev, "num-blocks", size / sector_len); in DEFINE_TYPES()
977 qdev_prop_set_uint64(dev, "sector-length", sector_len); in DEFINE_TYPES()
978 qdev_prop_set_uint8(dev, "width", bank_width); in DEFINE_TYPES()
979 qdev_prop_set_bit(dev, "big-endian", !!be); in DEFINE_TYPES()
993 return fl->blk; in pflash_cfi01_get_blk()
998 return &fl->mem; in pflash_cfi01_get_memory()
1002 * Handle -drive if=pflash for machines that use properties.
1016 qemu_opts_loc_restore(dinfo->opts); in pflash_cfi01_legacy_drive()
1017 if (fl->blk) { in pflash_cfi01_legacy_drive()
1018 error_report("clashes with -machine"); in pflash_cfi01_legacy_drive()
1021 qdev_prop_set_drive_err(DEVICE(fl), "drive", blk_by_legacy_dinfo(dinfo), in pflash_cfi01_legacy_drive()
1031 qemu_del_vm_change_state_handler(pfl->vmstate); in postload_update_cb()
1032 pfl->vmstate = NULL; in postload_update_cb()
1034 trace_pflash_postload_cb(pfl->name); in postload_update_cb()
1035 pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs); in postload_update_cb()
1042 if (!pfl->ro) { in pflash_post_load()
1043 pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb, in pflash_post_load()