Pflash and firmware configuration patches for 2019-03-11
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJchtowAAoJEDhwtADrkYZTbmwP/i3N1SjDjg6j5ymzjl4YtaBP k61RoZ4Z/FPRuPGov1/WUrreqS7vqPLyCz4UpwgnAc3gslGGhYMAosU3EDtUYlS4 hzI2lfAGoUQwAYvB6nLYQI81gKDf4HY/hMzzC38OrH89XRr2GgBFDJmz9WURlof/ 4ZHLkEQLasq93bEAItNZ/bAiEEwiidE13JTuFZ6PPzoMQYZlD2irjtPefFITGeV8 rz0qRMuPSoOEm5dx4YoLnhyrGQP9DUKmhWKsiZqEVXnNhUtaki0g4wt9/dLsnvzS XnQINyTsGnqyqLaam8MT6hPMFZZexVd0h6JhIFVOxKbpF82/wLgWiWgPiiyZQVaF O10bcz3M2liCC7ttU+LGaoZLch+ua9k0PqqfeCxC8VbpTOBUJc75QJWOOu1snhnA iZB20oG61pEk9GTV8n44uARRdZ9vYAN2C2kKYuRFxTBjp9epKAa7zJGJQcj88l3y AXm+XhZEddFU4eI5wMlRvjVDSLb6CJ1bukps9gKEDBJoiUbLTLQbEtv82PmwRFLk ZkyHhFrox02tblh4bTjE81gTd8yVG2dzTuvykX14EXbeqWcGeR9EGmqOZ1mJv1jq kfKvydh4VEAakhJAdNhypWt9+sjko6jSpHlejRFzgQWFXPiR4Kh72+QWWTFipUXM x8609BVHji8Sg9dWMT/Y =k9u2 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-pflash-2019-03-11' into staging Pflash and firmware configuration patches for 2019-03-11 # gpg: Signature made Mon 11 Mar 2019 21:59:12 GMT # gpg: using RSA key 3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-pflash-2019-03-11: (27 commits) docs/interop/firmware.json: Prefer -machine to if=pflash pc: Support firmware configuration with -blockdev pc_sysfw: Pass PCMachineState to pc_system_firmware_init() pc_sysfw: Remove unused PcSysFwDevice pflash_cfi01: Add pflash_cfi01_get_blk() helper vl: Create block backends before setting machine properties vl: Factor configure_blockdev() out of main() vl: Improve legibility of BlockdevOptions queue sysbus: Fix latent bug with onboard devices vl: Fix latent bug with -global and onboard devices qom: Move compat_props machinery from qdev to QOM qdev: Fix latent bug with compat_props and onboard devices pflash: Clean up after commit 368a354f02b, part 2 pflash: Clean up after commit 368a354f02b, part 1 mips_malta: Clean up definition of flash memory size somewhat hw/mips/malta: Restrict 'bios_size' variable scope hw/mips/malta: Remove fl_sectors variable mips_malta: Delete disabled, broken DEBUG_BOARD_INIT code r2d: Fix flash memory size, sector size, width, device ID ppc405_boards: Don't size flash memory to match backing image ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						eda1df0345
					
				| @ -66,6 +66,7 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms) | ||||
|         *(acc->allowed) = false; | ||||
|         object_unref(OBJECT(accel)); | ||||
|     } | ||||
|     object_set_accelerator_compat_props(acc->compat_props); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -212,9 +212,13 @@ | ||||
| # | ||||
| # @executable: Identifies the firmware executable. The firmware | ||||
| #              executable may be shared by multiple virtual machine | ||||
| #              definitions. The corresponding QEMU command line option | ||||
| #              is "-drive | ||||
| #              if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format". | ||||
| #              definitions. The preferred corresponding QEMU command | ||||
| #              line options are | ||||
| #                  -drive if=none,id=pflash0,readonly=on,file=@executable.@filename,format=@executable.@format | ||||
| #                  -machine pflash0=pflash0 | ||||
| #              or equivalent -blockdev instead of -drive. | ||||
| #              With QEMU versions older than 4.0, you have to use | ||||
| #                  -drive if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format | ||||
| # | ||||
| # @nvram-template: Identifies the NVRAM template compatible with | ||||
| #                  @executable. Management software instantiates an | ||||
| @ -225,9 +229,13 @@ | ||||
| #                  individual copies of it are. An NVRAM file is | ||||
| #                  typically used for persistently storing the | ||||
| #                  non-volatile UEFI variables of a virtual machine | ||||
| #                  definition. The corresponding QEMU command line | ||||
| #                  option is "-drive | ||||
| #                  if=pflash,unit=1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format". | ||||
| #                  definition. The preferred corresponding QEMU | ||||
| #                  command line options are | ||||
| #                      -drive if=none,id=pflash1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format | ||||
| #                      -machine pflash1=pflash1 | ||||
| #                  or equivalent -blockdev instead of -drive. | ||||
| #                  With QEMU versions older than 4.0, you have to use | ||||
| #                      -drive if=pflash,unit=1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format | ||||
| # | ||||
| # Since: 3.0 | ||||
| ## | ||||
|  | ||||
| @ -9,6 +9,7 @@ | ||||
|  * GNU GPL, version 2 or (at your option) any later version. | ||||
|  */ | ||||
| #include "qemu/osdep.h" | ||||
| #include "qemu/units.h" | ||||
| #include "hw/hw.h" | ||||
| #include "hw/sysbus.h" | ||||
| #include "hw/boards.h" | ||||
| @ -35,14 +36,14 @@ static void collie_init(MachineState *machine) | ||||
|     s = sa1110_init(sysmem, collie_binfo.ram_size, machine->cpu_type); | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000, | ||||
|     pflash_cfi01_register(SA_CS0, "collie.fl1", 0x02000000, | ||||
|                     dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                     (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); | ||||
|                     64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0); | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 1); | ||||
|     pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000, | ||||
|     pflash_cfi01_register(SA_CS1, "collie.fl2", 0x02000000, | ||||
|                     dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                     (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0); | ||||
|                     64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0); | ||||
| 
 | ||||
|     sysbus_create_simple("scoop", 0x40800000, NULL); | ||||
| 
 | ||||
|  | ||||
| @ -129,9 +129,8 @@ static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, hwaddr addr, | ||||
| #define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024) | ||||
| #define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024) | ||||
| 
 | ||||
|     pflash_cfi02_register(addr, NULL, "pflash", FLASH_K8P3215UQB_SIZE, | ||||
|     pflash_cfi02_register(addr, "pflash", FLASH_K8P3215UQB_SIZE, | ||||
|                           NULL, FLASH_K8P3215UQB_SECTOR_SIZE, | ||||
|                           FLASH_K8P3215UQB_SIZE / FLASH_K8P3215UQB_SECTOR_SIZE, | ||||
|                           DIGIC4_ROM_MAX_SIZE / FLASH_K8P3215UQB_SIZE, | ||||
|                           4, | ||||
|                           0x00EC, 0x007E, 0x0003, 0x0001, | ||||
|  | ||||
| @ -72,10 +72,9 @@ static void connex_init(MachineState *machine) | ||||
| #else | ||||
|     be = 0; | ||||
| #endif | ||||
|     if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom, | ||||
|     if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom, | ||||
|                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                                sector_len, connex_rom / sector_len, | ||||
|                                2, 0, 0, 0, 0, be)) { | ||||
|                                sector_len, 2, 0, 0, 0, 0, be)) { | ||||
|         error_report("Error registering flash memory"); | ||||
|         exit(1); | ||||
|     } | ||||
| @ -109,10 +108,9 @@ static void verdex_init(MachineState *machine) | ||||
| #else | ||||
|     be = 0; | ||||
| #endif | ||||
|     if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom, | ||||
|     if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom, | ||||
|                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                                sector_len, verdex_rom / sector_len, | ||||
|                                2, 0, 0, 0, 0, be)) { | ||||
|                                sector_len, 2, 0, 0, 0, 0, be)) { | ||||
|         error_report("Error registering flash memory"); | ||||
|         exit(1); | ||||
|     } | ||||
|  | ||||
| @ -148,12 +148,11 @@ static void mainstone_common_init(MemoryRegion *address_space_mem, | ||||
|             exit(1); | ||||
|         } | ||||
| 
 | ||||
|         if (!pflash_cfi01_register(mainstone_flash_base[i], NULL, | ||||
|         if (!pflash_cfi01_register(mainstone_flash_base[i], | ||||
|                                    i ? "mainstone.flash1" : "mainstone.flash0", | ||||
|                                    MAINSTONE_FLASH, | ||||
|                                    blk_by_legacy_dinfo(dinfo), | ||||
|                                    sector_len, MAINSTONE_FLASH / sector_len, | ||||
|                                    4, 0, 0, 0, 0, be)) { | ||||
|                                    sector_len, 4, 0, 0, 0, 0, be)) { | ||||
|             error_report("Error registering flash memory"); | ||||
|             exit(1); | ||||
|         } | ||||
|  | ||||
| @ -1635,16 +1635,16 @@ static void musicpal_init(MachineState *machine) | ||||
|          * image is smaller than 32 MB. | ||||
|          */ | ||||
| #ifdef TARGET_WORDS_BIGENDIAN | ||||
|         pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL, | ||||
|         pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX, | ||||
|                               "musicpal.flash", flash_size, | ||||
|                               blk, 0x10000, (flash_size + 0xffff) >> 16, | ||||
|                               blk, 0x10000, | ||||
|                               MP_FLASH_SIZE_MAX / flash_size, | ||||
|                               2, 0x00BF, 0x236D, 0x0000, 0x0000, | ||||
|                               0x5555, 0x2AAA, 1); | ||||
| #else | ||||
|         pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL, | ||||
|         pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX, | ||||
|                               "musicpal.flash", flash_size, | ||||
|                               blk, 0x10000, (flash_size + 0xffff) >> 16, | ||||
|                               blk, 0x10000, | ||||
|                               MP_FLASH_SIZE_MAX / flash_size, | ||||
|                               2, 0x00BF, 0x236D, 0x0000, 0x0000, | ||||
|                               0x5555, 0x2AAA, 0); | ||||
|  | ||||
| @ -152,11 +152,10 @@ static void sx1_init(MachineState *machine, const int version) | ||||
| #endif | ||||
| 
 | ||||
|     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) { | ||||
|         if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL, | ||||
|         if (!pflash_cfi01_register(OMAP_CS0_BASE, | ||||
|                                    "omap_sx1.flash0-1", flash_size, | ||||
|                                    blk_by_legacy_dinfo(dinfo), | ||||
|                                    sector_size, flash_size / sector_size, | ||||
|                                    4, 0, 0, 0, 0, be)) { | ||||
|                                    sector_size, 4, 0, 0, 0, 0, be)) { | ||||
|             fprintf(stderr, "qemu: Error registering flash memory %d.\n", | ||||
|                            fl_idx); | ||||
|         } | ||||
| @ -176,11 +175,10 @@ static void sx1_init(MachineState *machine, const int version) | ||||
|         memory_region_add_subregion(address_space, | ||||
|                                 OMAP_CS1_BASE + flash1_size, &cs[1]); | ||||
| 
 | ||||
|         if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL, | ||||
|         if (!pflash_cfi01_register(OMAP_CS1_BASE, | ||||
|                                    "omap_sx1.flash1-1", flash1_size, | ||||
|                                    blk_by_legacy_dinfo(dinfo), | ||||
|                                    sector_size, flash1_size / sector_size, | ||||
|                                    4, 0, 0, 0, 0, be)) { | ||||
|                                    sector_size, 4, 0, 0, 0, 0, be)) { | ||||
|             fprintf(stderr, "qemu: Error registering flash memory %d.\n", | ||||
|                            fl_idx); | ||||
|         } | ||||
|  | ||||
| @ -365,11 +365,10 @@ static void versatile_init(MachineState *machine, int board_id) | ||||
|     /* 0x34000000 NOR Flash */ | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash", | ||||
|     if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash", | ||||
|                           VERSATILE_FLASH_SIZE, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           VERSATILE_FLASH_SECT_SIZE, | ||||
|                           VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE, | ||||
|                           4, 0x0089, 0x0018, 0x0000, 0x0, 0)) { | ||||
|         fprintf(stderr, "qemu: Error registering flash memory.\n"); | ||||
|     } | ||||
|  | ||||
| @ -512,10 +512,10 @@ static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt) | ||||
| /* Open code a private version of pflash registration since we
 | ||||
|  * need to set non-default device width for VExpress platform. | ||||
|  */ | ||||
| static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name, | ||||
|                                           DriveInfo *di) | ||||
| static PFlashCFI01 *ve_pflash_cfi01_register(hwaddr base, const char *name, | ||||
|                                              DriveInfo *di) | ||||
| { | ||||
|     DeviceState *dev = qdev_create(NULL, "cfi.pflash01"); | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01); | ||||
| 
 | ||||
|     if (di) { | ||||
|         qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di), | ||||
| @ -536,7 +536,7 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name, | ||||
|     qdev_init_nofail(dev); | ||||
| 
 | ||||
|     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); | ||||
|     return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01"); | ||||
|     return PFLASH_CFI01(dev); | ||||
| } | ||||
| 
 | ||||
| static void vexpress_common_init(MachineState *machine) | ||||
| @ -548,7 +548,7 @@ static void vexpress_common_init(MachineState *machine) | ||||
|     qemu_irq pic[64]; | ||||
|     uint32_t sys_id; | ||||
|     DriveInfo *dinfo; | ||||
|     pflash_t *pflash0; | ||||
|     PFlashCFI01 *pflash0; | ||||
|     I2CBus *i2c; | ||||
|     ram_addr_t vram_size, sram_size; | ||||
|     MemoryRegion *sysmem = get_system_memory(); | ||||
|  | ||||
| @ -35,6 +35,7 @@ | ||||
| #include "hw/arm/arm.h" | ||||
| #include "hw/arm/primecell.h" | ||||
| #include "hw/arm/virt.h" | ||||
| #include "hw/block/flash.h" | ||||
| #include "hw/vfio/vfio-calxeda-xgmac.h" | ||||
| #include "hw/vfio/vfio-amd-xgbe.h" | ||||
| #include "hw/display/ramfb.h" | ||||
| @ -878,7 +879,7 @@ static void create_one_flash(const char *name, hwaddr flashbase, | ||||
|      * parameters as the flash devices on the Versatile Express board. | ||||
|      */ | ||||
|     DriveInfo *dinfo = drive_get_next(IF_PFLASH); | ||||
|     DeviceState *dev = qdev_create(NULL, "cfi.pflash01"); | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01); | ||||
|     SysBusDevice *sbd = SYS_BUS_DEVICE(dev); | ||||
|     const uint64_t sectorlength = 256 * 1024; | ||||
| 
 | ||||
|  | ||||
| @ -205,12 +205,11 @@ static void zynq_init(MachineState *machine) | ||||
|     DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
| 
 | ||||
|     /* AMD */ | ||||
|     pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE, | ||||
|     pflash_cfi02_register(0xe2000000, "zynq.pflash", FLASH_SIZE, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           FLASH_SECTOR_SIZE, | ||||
|                           FLASH_SIZE/FLASH_SECTOR_SIZE, 1, | ||||
|                           FLASH_SECTOR_SIZE, 1, | ||||
|                           1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa, | ||||
|                               0); | ||||
|                           0); | ||||
| 
 | ||||
|     dev = qdev_create(NULL, "xilinx,zynq_slcr"); | ||||
|     qdev_init_nofail(dev); | ||||
|  | ||||
| @ -323,11 +323,9 @@ static void z2_init(MachineState *machine) | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     if (!pflash_cfi01_register(Z2_FLASH_BASE, | ||||
|                                NULL, "z2.flash0", Z2_FLASH_SIZE, | ||||
|     if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE, | ||||
|                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                                sector_len, Z2_FLASH_SIZE / sector_len, | ||||
|                                4, 0, 0, 0, 0, be)) { | ||||
|                                sector_len, 4, 0, 0, 0, 0, be)) { | ||||
|         error_report("Error registering flash memory"); | ||||
|         exit(1); | ||||
|     } | ||||
|  | ||||
| @ -49,12 +49,6 @@ | ||||
| #include "sysemu/sysemu.h" | ||||
| #include "trace.h" | ||||
| 
 | ||||
| #define PFLASH_BUG(fmt, ...) \ | ||||
| do { \ | ||||
|     fprintf(stderr, "PFLASH: Possible BUG - " fmt, ## __VA_ARGS__); \ | ||||
|     exit(1); \ | ||||
| } while(0) | ||||
| 
 | ||||
| /* #define PFLASH_DEBUG */ | ||||
| #ifdef PFLASH_DEBUG | ||||
| #define DPRINTF(fmt, ...)                                   \ | ||||
| @ -65,12 +59,10 @@ do {                                                        \ | ||||
| #define DPRINTF(fmt, ...) do { } while (0) | ||||
| #endif | ||||
| 
 | ||||
| #define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01) | ||||
| 
 | ||||
| #define PFLASH_BE          0 | ||||
| #define PFLASH_SECURE      1 | ||||
| 
 | ||||
| struct pflash_t { | ||||
| struct PFlashCFI01 { | ||||
|     /*< private >*/ | ||||
|     SysBusDevice parent_obj; | ||||
|     /*< public >*/ | ||||
| @ -109,17 +101,17 @@ static const VMStateDescription vmstate_pflash = { | ||||
|     .minimum_version_id = 1, | ||||
|     .post_load = pflash_post_load, | ||||
|     .fields = (VMStateField[]) { | ||||
|         VMSTATE_UINT8(wcycle, pflash_t), | ||||
|         VMSTATE_UINT8(cmd, pflash_t), | ||||
|         VMSTATE_UINT8(status, pflash_t), | ||||
|         VMSTATE_UINT64(counter, pflash_t), | ||||
|         VMSTATE_UINT8(wcycle, PFlashCFI01), | ||||
|         VMSTATE_UINT8(cmd, PFlashCFI01), | ||||
|         VMSTATE_UINT8(status, PFlashCFI01), | ||||
|         VMSTATE_UINT64(counter, PFlashCFI01), | ||||
|         VMSTATE_END_OF_LIST() | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static void pflash_timer (void *opaque) | ||||
| { | ||||
|     pflash_t *pfl = opaque; | ||||
|     PFlashCFI01 *pfl = opaque; | ||||
| 
 | ||||
|     trace_pflash_timer_expired(pfl->cmd); | ||||
|     /* Reset flash */ | ||||
| @ -133,7 +125,7 @@ static void pflash_timer (void *opaque) | ||||
|  * If this code is called we know we have a device_width set for | ||||
|  * this flash. | ||||
|  */ | ||||
| static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset) | ||||
| static uint32_t pflash_cfi_query(PFlashCFI01 *pfl, hwaddr offset) | ||||
| { | ||||
|     int i; | ||||
|     uint32_t resp = 0; | ||||
| @ -193,7 +185,7 @@ static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset) | ||||
| 
 | ||||
| 
 | ||||
| /* Perform a device id query based on the bank width of the flash. */ | ||||
| static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset) | ||||
| static uint32_t pflash_devid_query(PFlashCFI01 *pfl, hwaddr offset) | ||||
| { | ||||
|     int i; | ||||
|     uint32_t resp; | ||||
| @ -241,7 +233,7 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset) | ||||
|     return resp; | ||||
| } | ||||
| 
 | ||||
| static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset, | ||||
| static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset, | ||||
|                                  int width, int be) | ||||
| { | ||||
|     uint8_t *p; | ||||
| @ -284,8 +276,8 @@ static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset, | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, | ||||
|                              int width, int be) | ||||
| static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset, | ||||
|                             int width, int be) | ||||
| { | ||||
|     hwaddr boff; | ||||
|     uint32_t ret; | ||||
| @ -398,7 +390,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, | ||||
| } | ||||
| 
 | ||||
| /* update flash content on disk */ | ||||
| static void pflash_update(pflash_t *pfl, int offset, | ||||
| static void pflash_update(PFlashCFI01 *pfl, int offset, | ||||
|                           int size) | ||||
| { | ||||
|     int offset_end; | ||||
| @ -412,7 +404,7 @@ static void pflash_update(pflash_t *pfl, int offset, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static inline void pflash_data_write(pflash_t *pfl, hwaddr offset, | ||||
| static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset, | ||||
|                                      uint32_t value, int width, int be) | ||||
| { | ||||
|     uint8_t *p = pfl->storage; | ||||
| @ -448,7 +440,7 @@ static inline void pflash_data_write(pflash_t *pfl, hwaddr offset, | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static void pflash_write(pflash_t *pfl, hwaddr offset, | ||||
| static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, | ||||
|                          uint32_t value, int width, int be) | ||||
| { | ||||
|     uint8_t *p; | ||||
| @ -507,6 +499,10 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, | ||||
|             break; | ||||
|         case 0xe8: /* Write to buffer */ | ||||
|             DPRINTF("%s: Write to buffer\n", __func__); | ||||
|             /* FIXME should save @offset, @width for case 1+ */ | ||||
|             qemu_log_mask(LOG_UNIMP, | ||||
|                           "%s: Write to buffer emulation is flawed\n", | ||||
|                           __func__); | ||||
|             pfl->status |= 0x80; /* Ready! */ | ||||
|             break; | ||||
|         case 0xf0: /* Probe for AMD flash */ | ||||
| @ -550,6 +546,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, | ||||
|             /* Mask writeblock size based on device width, or bank width if
 | ||||
|              * device width not specified. | ||||
|              */ | ||||
|             /* FIXME check @offset, @width */ | ||||
|             if (pfl->device_width) { | ||||
|                 value = extract32(value, 0, pfl->device_width * 8); | ||||
|             } else { | ||||
| @ -587,7 +584,13 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, | ||||
|     case 2: | ||||
|         switch (pfl->cmd) { | ||||
|         case 0xe8: /* Block write */ | ||||
|             /* FIXME check @offset, @width */ | ||||
|             if (!pfl->ro) { | ||||
|                 /*
 | ||||
|                  * FIXME writing straight to memory is *wrong*.  We | ||||
|                  * should write to a buffer, and flush it to memory | ||||
|                  * only on confirm command (see below). | ||||
|                  */ | ||||
|                 pflash_data_write(pfl, offset, value, width, be); | ||||
|             } else { | ||||
|                 pfl->status |= 0x10; /* Programming error */ | ||||
| @ -603,6 +606,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, | ||||
|                 pfl->wcycle++; | ||||
|                 if (!pfl->ro) { | ||||
|                     /* Flush the entire write buffer onto backing storage.  */ | ||||
|                     /* FIXME premature! */ | ||||
|                     pflash_update(pfl, offset & mask, pfl->writeblock_size); | ||||
|                 } else { | ||||
|                     pfl->status |= 0x10; /* Programming error */ | ||||
| @ -619,11 +623,15 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, | ||||
|         switch (pfl->cmd) { | ||||
|         case 0xe8: /* Block write */ | ||||
|             if (cmd == 0xd0) { | ||||
|                 /* FIXME this is where we should write out the buffer */ | ||||
|                 pfl->wcycle = 0; | ||||
|                 pfl->status |= 0x80; | ||||
|             } else { | ||||
|                 DPRINTF("%s: unknown command for \"write block\"\n", __func__); | ||||
|                 PFLASH_BUG("Write block confirm"); | ||||
|                 qemu_log_mask(LOG_UNIMP, | ||||
|                     "%s: Aborting write to buffer not implemented," | ||||
|                     " the data is already written to storage!\n" | ||||
|                     "Flash device reset into READ mode.\n", | ||||
|                     __func__); | ||||
|                 goto reset_flash; | ||||
|             } | ||||
|             break; | ||||
| @ -654,7 +662,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, | ||||
| static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_t *value, | ||||
|                                               unsigned len, MemTxAttrs attrs) | ||||
| { | ||||
|     pflash_t *pfl = opaque; | ||||
|     PFlashCFI01 *pfl = opaque; | ||||
|     bool be = !!(pfl->features & (1 << PFLASH_BE)); | ||||
| 
 | ||||
|     if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) { | ||||
| @ -668,7 +676,7 @@ static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_ | ||||
| static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, uint64_t value, | ||||
|                                                unsigned len, MemTxAttrs attrs) | ||||
| { | ||||
|     pflash_t *pfl = opaque; | ||||
|     PFlashCFI01 *pfl = opaque; | ||||
|     bool be = !!(pfl->features & (1 << PFLASH_BE)); | ||||
| 
 | ||||
|     if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) { | ||||
| @ -687,7 +695,7 @@ static const MemoryRegionOps pflash_cfi01_ops = { | ||||
| 
 | ||||
| static void pflash_cfi01_realize(DeviceState *dev, Error **errp) | ||||
| { | ||||
|     pflash_t *pfl = CFI_PFLASH01(dev); | ||||
|     PFlashCFI01 *pfl = PFLASH_CFI01(dev); | ||||
|     uint64_t total_len; | ||||
|     int ret; | ||||
|     uint64_t blocks_per_device, sector_len_per_device, device_len; | ||||
| @ -864,14 +872,14 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) | ||||
| } | ||||
| 
 | ||||
| static Property pflash_cfi01_properties[] = { | ||||
|     DEFINE_PROP_DRIVE("drive", struct pflash_t, blk), | ||||
|     DEFINE_PROP_DRIVE("drive", PFlashCFI01, blk), | ||||
|     /* num-blocks is the number of blocks actually visible to the guest,
 | ||||
|      * ie the total size of the device divided by the sector length. | ||||
|      * If we're emulating flash devices wired in parallel the actual | ||||
|      * number of blocks per indvidual device will differ. | ||||
|      */ | ||||
|     DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0), | ||||
|     DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0), | ||||
|     DEFINE_PROP_UINT32("num-blocks", PFlashCFI01, nb_blocs, 0), | ||||
|     DEFINE_PROP_UINT64("sector-length", PFlashCFI01, sector_len, 0), | ||||
|     /* width here is the overall width of this QEMU device in bytes.
 | ||||
|      * The QEMU device may be emulating a number of flash devices | ||||
|      * wired up in parallel; the width of each individual flash | ||||
| @ -888,17 +896,17 @@ static Property pflash_cfi01_properties[] = { | ||||
|      * 16 bit devices making up a 32 bit wide QEMU device. This | ||||
|      * is deprecated for new uses of this device. | ||||
|      */ | ||||
|     DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0), | ||||
|     DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0), | ||||
|     DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0), | ||||
|     DEFINE_PROP_BIT("big-endian", struct pflash_t, features, PFLASH_BE, 0), | ||||
|     DEFINE_PROP_BIT("secure", struct pflash_t, features, PFLASH_SECURE, 0), | ||||
|     DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0), | ||||
|     DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0), | ||||
|     DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0), | ||||
|     DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0), | ||||
|     DEFINE_PROP_STRING("name", struct pflash_t, name), | ||||
|     DEFINE_PROP_BOOL("old-multiple-chip-handling", struct pflash_t, | ||||
|     DEFINE_PROP_UINT8("width", PFlashCFI01, bank_width, 0), | ||||
|     DEFINE_PROP_UINT8("device-width", PFlashCFI01, device_width, 0), | ||||
|     DEFINE_PROP_UINT8("max-device-width", PFlashCFI01, max_device_width, 0), | ||||
|     DEFINE_PROP_BIT("big-endian", PFlashCFI01, features, PFLASH_BE, 0), | ||||
|     DEFINE_PROP_BIT("secure", PFlashCFI01, features, PFLASH_SECURE, 0), | ||||
|     DEFINE_PROP_UINT16("id0", PFlashCFI01, ident0, 0), | ||||
|     DEFINE_PROP_UINT16("id1", PFlashCFI01, ident1, 0), | ||||
|     DEFINE_PROP_UINT16("id2", PFlashCFI01, ident2, 0), | ||||
|     DEFINE_PROP_UINT16("id3", PFlashCFI01, ident3, 0), | ||||
|     DEFINE_PROP_STRING("name", PFlashCFI01, name), | ||||
|     DEFINE_PROP_BOOL("old-multiple-chip-handling", PFlashCFI01, | ||||
|                      old_multiple_chip_handling, false), | ||||
|     DEFINE_PROP_END_OF_LIST(), | ||||
| }; | ||||
| @ -915,9 +923,9 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data) | ||||
| 
 | ||||
| 
 | ||||
| static const TypeInfo pflash_cfi01_info = { | ||||
|     .name           = TYPE_CFI_PFLASH01, | ||||
|     .name           = TYPE_PFLASH_CFI01, | ||||
|     .parent         = TYPE_SYS_BUS_DEVICE, | ||||
|     .instance_size  = sizeof(struct pflash_t), | ||||
|     .instance_size  = sizeof(PFlashCFI01), | ||||
|     .class_init     = pflash_cfi01_class_init, | ||||
| }; | ||||
| 
 | ||||
| @ -928,20 +936,23 @@ static void pflash_cfi01_register_types(void) | ||||
| 
 | ||||
| type_init(pflash_cfi01_register_types) | ||||
| 
 | ||||
| pflash_t *pflash_cfi01_register(hwaddr base, | ||||
|                                 DeviceState *qdev, const char *name, | ||||
|                                 hwaddr size, | ||||
|                                 BlockBackend *blk, | ||||
|                                 uint32_t sector_len, int nb_blocs, | ||||
|                                 int bank_width, uint16_t id0, uint16_t id1, | ||||
|                                 uint16_t id2, uint16_t id3, int be) | ||||
| PFlashCFI01 *pflash_cfi01_register(hwaddr base, | ||||
|                                    const char *name, | ||||
|                                    hwaddr size, | ||||
|                                    BlockBackend *blk, | ||||
|                                    uint32_t sector_len, | ||||
|                                    int bank_width, | ||||
|                                    uint16_t id0, uint16_t id1, | ||||
|                                    uint16_t id2, uint16_t id3, | ||||
|                                    int be) | ||||
| { | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH01); | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01); | ||||
| 
 | ||||
|     if (blk) { | ||||
|         qdev_prop_set_drive(dev, "drive", blk, &error_abort); | ||||
|     } | ||||
|     qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); | ||||
|     assert(size % sector_len == 0); | ||||
|     qdev_prop_set_uint32(dev, "num-blocks", size / sector_len); | ||||
|     qdev_prop_set_uint64(dev, "sector-length", sector_len); | ||||
|     qdev_prop_set_uint8(dev, "width", bank_width); | ||||
|     qdev_prop_set_bit(dev, "big-endian", !!be); | ||||
| @ -953,17 +964,22 @@ pflash_t *pflash_cfi01_register(hwaddr base, | ||||
|     qdev_init_nofail(dev); | ||||
| 
 | ||||
|     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); | ||||
|     return CFI_PFLASH01(dev); | ||||
|     return PFLASH_CFI01(dev); | ||||
| } | ||||
| 
 | ||||
| MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl) | ||||
| BlockBackend *pflash_cfi01_get_blk(PFlashCFI01 *fl) | ||||
| { | ||||
|     return fl->blk; | ||||
| } | ||||
| 
 | ||||
| MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl) | ||||
| { | ||||
|     return &fl->mem; | ||||
| } | ||||
| 
 | ||||
| static void postload_update_cb(void *opaque, int running, RunState state) | ||||
| { | ||||
|     pflash_t *pfl = opaque; | ||||
|     PFlashCFI01 *pfl = opaque; | ||||
| 
 | ||||
|     /* This is called after bdrv_invalidate_cache_all.  */ | ||||
|     qemu_del_vm_change_state_handler(pfl->vmstate); | ||||
| @ -975,7 +991,7 @@ static void postload_update_cb(void *opaque, int running, RunState state) | ||||
| 
 | ||||
| static int pflash_post_load(void *opaque, int version_id) | ||||
| { | ||||
|     pflash_t *pfl = opaque; | ||||
|     PFlashCFI01 *pfl = opaque; | ||||
| 
 | ||||
|     if (!pfl->ro) { | ||||
|         pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb, | ||||
|  | ||||
| @ -57,9 +57,7 @@ do {                                                       \ | ||||
| 
 | ||||
| #define PFLASH_LAZY_ROMD_THRESHOLD 42 | ||||
| 
 | ||||
| #define CFI_PFLASH02(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH02) | ||||
| 
 | ||||
| struct pflash_t { | ||||
| struct PFlashCFI02 { | ||||
|     /*< private >*/ | ||||
|     SysBusDevice parent_obj; | ||||
|     /*< public >*/ | ||||
| @ -101,7 +99,7 @@ struct pflash_t { | ||||
| /*
 | ||||
|  * Set up replicated mappings of the same region. | ||||
|  */ | ||||
| static void pflash_setup_mappings(pflash_t *pfl) | ||||
| static void pflash_setup_mappings(PFlashCFI02 *pfl) | ||||
| { | ||||
|     unsigned i; | ||||
|     hwaddr size = memory_region_size(&pfl->orig_mem); | ||||
| @ -115,7 +113,7 @@ static void pflash_setup_mappings(pflash_t *pfl) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void pflash_register_memory(pflash_t *pfl, int rom_mode) | ||||
| static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode) | ||||
| { | ||||
|     memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode); | ||||
|     pfl->rom_mode = rom_mode; | ||||
| @ -123,7 +121,7 @@ static void pflash_register_memory(pflash_t *pfl, int rom_mode) | ||||
| 
 | ||||
| static void pflash_timer (void *opaque) | ||||
| { | ||||
|     pflash_t *pfl = opaque; | ||||
|     PFlashCFI02 *pfl = opaque; | ||||
| 
 | ||||
|     trace_pflash_timer_expired(pfl->cmd); | ||||
|     /* Reset flash */ | ||||
| @ -137,8 +135,8 @@ static void pflash_timer (void *opaque) | ||||
|     pfl->cmd = 0; | ||||
| } | ||||
| 
 | ||||
| static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, | ||||
|                              int width, int be) | ||||
| static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset, | ||||
|                             int width, int be) | ||||
| { | ||||
|     hwaddr boff; | ||||
|     uint32_t ret; | ||||
| @ -246,7 +244,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, | ||||
| } | ||||
| 
 | ||||
| /* update flash content on disk */ | ||||
| static void pflash_update(pflash_t *pfl, int offset, | ||||
| static void pflash_update(PFlashCFI02 *pfl, int offset, | ||||
|                           int size) | ||||
| { | ||||
|     int offset_end; | ||||
| @ -260,8 +258,8 @@ static void pflash_update(pflash_t *pfl, int offset, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void pflash_write (pflash_t *pfl, hwaddr offset, | ||||
|                           uint32_t value, int width, int be) | ||||
| static void pflash_write(PFlashCFI02 *pfl, hwaddr offset, | ||||
|                          uint32_t value, int width, int be) | ||||
| { | ||||
|     hwaddr boff; | ||||
|     uint8_t *p; | ||||
| @ -533,7 +531,7 @@ static const MemoryRegionOps pflash_cfi02_ops_le = { | ||||
| 
 | ||||
| static void pflash_cfi02_realize(DeviceState *dev, Error **errp) | ||||
| { | ||||
|     pflash_t *pfl = CFI_PFLASH02(dev); | ||||
|     PFlashCFI02 *pfl = PFLASH_CFI02(dev); | ||||
|     uint32_t chip_len; | ||||
|     int ret; | ||||
|     Error *local_err = NULL; | ||||
| @ -679,25 +677,25 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) | ||||
| } | ||||
| 
 | ||||
| static Property pflash_cfi02_properties[] = { | ||||
|     DEFINE_PROP_DRIVE("drive", struct pflash_t, blk), | ||||
|     DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0), | ||||
|     DEFINE_PROP_UINT32("sector-length", struct pflash_t, sector_len, 0), | ||||
|     DEFINE_PROP_UINT8("width", struct pflash_t, width, 0), | ||||
|     DEFINE_PROP_UINT8("mappings", struct pflash_t, mappings, 0), | ||||
|     DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0), | ||||
|     DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0), | ||||
|     DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0), | ||||
|     DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0), | ||||
|     DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0), | ||||
|     DEFINE_PROP_UINT16("unlock-addr0", struct pflash_t, unlock_addr0, 0), | ||||
|     DEFINE_PROP_UINT16("unlock-addr1", struct pflash_t, unlock_addr1, 0), | ||||
|     DEFINE_PROP_STRING("name", struct pflash_t, name), | ||||
|     DEFINE_PROP_DRIVE("drive", PFlashCFI02, blk), | ||||
|     DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, nb_blocs, 0), | ||||
|     DEFINE_PROP_UINT32("sector-length", PFlashCFI02, sector_len, 0), | ||||
|     DEFINE_PROP_UINT8("width", PFlashCFI02, width, 0), | ||||
|     DEFINE_PROP_UINT8("mappings", PFlashCFI02, mappings, 0), | ||||
|     DEFINE_PROP_UINT8("big-endian", PFlashCFI02, be, 0), | ||||
|     DEFINE_PROP_UINT16("id0", PFlashCFI02, ident0, 0), | ||||
|     DEFINE_PROP_UINT16("id1", PFlashCFI02, ident1, 0), | ||||
|     DEFINE_PROP_UINT16("id2", PFlashCFI02, ident2, 0), | ||||
|     DEFINE_PROP_UINT16("id3", PFlashCFI02, ident3, 0), | ||||
|     DEFINE_PROP_UINT16("unlock-addr0", PFlashCFI02, unlock_addr0, 0), | ||||
|     DEFINE_PROP_UINT16("unlock-addr1", PFlashCFI02, unlock_addr1, 0), | ||||
|     DEFINE_PROP_STRING("name", PFlashCFI02, name), | ||||
|     DEFINE_PROP_END_OF_LIST(), | ||||
| }; | ||||
| 
 | ||||
| static void pflash_cfi02_unrealize(DeviceState *dev, Error **errp) | ||||
| { | ||||
|     pflash_t *pfl = CFI_PFLASH02(dev); | ||||
|     PFlashCFI02 *pfl = PFLASH_CFI02(dev); | ||||
|     timer_del(&pfl->timer); | ||||
| } | ||||
| 
 | ||||
| @ -712,9 +710,9 @@ static void pflash_cfi02_class_init(ObjectClass *klass, void *data) | ||||
| } | ||||
| 
 | ||||
| static const TypeInfo pflash_cfi02_info = { | ||||
|     .name           = TYPE_CFI_PFLASH02, | ||||
|     .name           = TYPE_PFLASH_CFI02, | ||||
|     .parent         = TYPE_SYS_BUS_DEVICE, | ||||
|     .instance_size  = sizeof(struct pflash_t), | ||||
|     .instance_size  = sizeof(PFlashCFI02), | ||||
|     .class_init     = pflash_cfi02_class_init, | ||||
| }; | ||||
| 
 | ||||
| @ -725,22 +723,25 @@ static void pflash_cfi02_register_types(void) | ||||
| 
 | ||||
| type_init(pflash_cfi02_register_types) | ||||
| 
 | ||||
| pflash_t *pflash_cfi02_register(hwaddr base, | ||||
|                                 DeviceState *qdev, const char *name, | ||||
|                                 hwaddr size, | ||||
|                                 BlockBackend *blk, uint32_t sector_len, | ||||
|                                 int nb_blocs, int nb_mappings, int width, | ||||
|                                 uint16_t id0, uint16_t id1, | ||||
|                                 uint16_t id2, uint16_t id3, | ||||
|                                 uint16_t unlock_addr0, uint16_t unlock_addr1, | ||||
|                                 int be) | ||||
| PFlashCFI02 *pflash_cfi02_register(hwaddr base, | ||||
|                                    const char *name, | ||||
|                                    hwaddr size, | ||||
|                                    BlockBackend *blk, | ||||
|                                    uint32_t sector_len, | ||||
|                                    int nb_mappings, int width, | ||||
|                                    uint16_t id0, uint16_t id1, | ||||
|                                    uint16_t id2, uint16_t id3, | ||||
|                                    uint16_t unlock_addr0, | ||||
|                                    uint16_t unlock_addr1, | ||||
|                                    int be) | ||||
| { | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH02); | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI02); | ||||
| 
 | ||||
|     if (blk) { | ||||
|         qdev_prop_set_drive(dev, "drive", blk, &error_abort); | ||||
|     } | ||||
|     qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); | ||||
|     assert(size % sector_len == 0); | ||||
|     qdev_prop_set_uint32(dev, "num-blocks", size / sector_len); | ||||
|     qdev_prop_set_uint32(dev, "sector-length", sector_len); | ||||
|     qdev_prop_set_uint8(dev, "width", width); | ||||
|     qdev_prop_set_uint8(dev, "mappings", nb_mappings); | ||||
| @ -755,5 +756,5 @@ pflash_t *pflash_cfi02_register(hwaddr base, | ||||
|     qdev_init_nofail(dev); | ||||
| 
 | ||||
|     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); | ||||
|     return CFI_PFLASH02(dev); | ||||
|     return PFLASH_CFI02(dev); | ||||
| } | ||||
|  | ||||
| @ -978,25 +978,12 @@ static void device_initfn(Object *obj) | ||||
|     QLIST_INIT(&dev->gpios); | ||||
| } | ||||
| 
 | ||||
| void object_apply_compat_props(Object *obj) | ||||
| { | ||||
|     if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) { | ||||
|         MachineState *m = MACHINE(qdev_get_machine()); | ||||
|         MachineClass *mc = MACHINE_GET_CLASS(m); | ||||
| 
 | ||||
|         if (m->accelerator) { | ||||
|             AccelClass *ac = ACCEL_GET_CLASS(m->accelerator); | ||||
| 
 | ||||
|             if (ac->compat_props) { | ||||
|                 object_apply_global_props(obj, ac->compat_props, &error_abort); | ||||
|             } | ||||
|         } | ||||
|         object_apply_global_props(obj, mc->compat_props, &error_abort); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void device_post_init(Object *obj) | ||||
| { | ||||
|     /*
 | ||||
|      * Note: ordered so that the user's global properties take | ||||
|      * precedence. | ||||
|      */ | ||||
|     object_apply_compat_props(obj); | ||||
|     qdev_prop_set_globals(DEVICE(obj)); | ||||
| } | ||||
|  | ||||
| @ -357,9 +357,6 @@ static void main_system_bus_create(void) | ||||
|     qbus_create_inplace(main_system_bus, system_bus_info.instance_size, | ||||
|                         TYPE_SYSTEM_BUS, NULL, "main-system-bus"); | ||||
|     OBJECT(main_system_bus)->free = g_free; | ||||
|     object_property_add_child(container_get(qdev_get_machine(), | ||||
|                                             "/unattached"), | ||||
|                               "sysbus", OBJECT(main_system_bus), NULL); | ||||
| } | ||||
| 
 | ||||
| BusState *sysbus_get_default(void) | ||||
|  | ||||
| @ -1809,7 +1809,7 @@ void pc_memory_init(PCMachineState *pcms, | ||||
|     } | ||||
| 
 | ||||
|     /* Initialize PC system firmware */ | ||||
|     pc_system_firmware_init(rom_memory, !pcmc->pci_enabled); | ||||
|     pc_system_firmware_init(pcms, rom_memory); | ||||
| 
 | ||||
|     option_rom_mr = g_malloc(sizeof(*option_rom_mr)); | ||||
|     memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, | ||||
| @ -2649,6 +2649,8 @@ static void pc_machine_initfn(Object *obj) | ||||
|     pcms->smbus_enabled = true; | ||||
|     pcms->sata_enabled = true; | ||||
|     pcms->pit_enabled = true; | ||||
| 
 | ||||
|     pc_system_flash_create(pcms); | ||||
| } | ||||
| 
 | ||||
| static void pc_machine_reset(void) | ||||
|  | ||||
| @ -40,10 +40,16 @@ | ||||
| 
 | ||||
| #define BIOS_FILENAME "bios.bin" | ||||
| 
 | ||||
| typedef struct PcSysFwDevice { | ||||
|     SysBusDevice busdev; | ||||
|     uint8_t isapc_ram_fw; | ||||
| } PcSysFwDevice; | ||||
| /*
 | ||||
|  * We don't have a theoretically justifiable exact lower bound on the base | ||||
|  * address of any flash mapping. In practice, the IO-APIC MMIO range is | ||||
|  * [0xFEE00000..0xFEE01000] -- see IO_APIC_DEFAULT_ADDRESS --, leaving free | ||||
|  * only 18MB-4KB below 4G. For now, restrict the cumulative mapping to 8MB in | ||||
|  * size. | ||||
|  */ | ||||
| #define FLASH_SIZE_LIMIT (8 * MiB) | ||||
| 
 | ||||
| #define FLASH_SECTOR_SIZE 4096 | ||||
| 
 | ||||
| static void pc_isa_bios_init(MemoryRegion *rom_memory, | ||||
|                              MemoryRegion *flash_mem, | ||||
| @ -76,100 +82,118 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory, | ||||
|     memory_region_set_readonly(isa_bios, true); | ||||
| } | ||||
| 
 | ||||
| #define FLASH_MAP_UNIT_MAX 2 | ||||
| static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms, | ||||
|                                      const char *name, | ||||
|                                      const char *alias_prop_name) | ||||
| { | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01); | ||||
| 
 | ||||
| /* We don't have a theoretically justifiable exact lower bound on the base
 | ||||
|  * address of any flash mapping. In practice, the IO-APIC MMIO range is | ||||
|  * [0xFEE00000..0xFEE01000[ -- see IO_APIC_DEFAULT_ADDRESS --, leaving free | ||||
|  * only 18MB-4KB below 4G. For now, restrict the cumulative mapping to 8MB in | ||||
|  * size. | ||||
|  */ | ||||
| #define FLASH_MAP_BASE_MIN ((hwaddr)(4 * GiB - 8 * MiB)) | ||||
|     qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE); | ||||
|     qdev_prop_set_uint8(dev, "width", 1); | ||||
|     qdev_prop_set_string(dev, "name", name); | ||||
|     object_property_add_child(OBJECT(pcms), name, OBJECT(dev), | ||||
|                               &error_abort); | ||||
|     object_property_add_alias(OBJECT(pcms), alias_prop_name, | ||||
|                               OBJECT(dev), "drive", &error_abort); | ||||
|     return PFLASH_CFI01(dev); | ||||
| } | ||||
| 
 | ||||
| /* This function maps flash drives from 4G downward, in order of their unit
 | ||||
|  * numbers. The mapping starts at unit#0, with unit number increments of 1, and | ||||
|  * stops before the first missing flash drive, or before | ||||
|  * unit#FLASH_MAP_UNIT_MAX, whichever is reached first. | ||||
| void pc_system_flash_create(PCMachineState *pcms) | ||||
| { | ||||
|     PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); | ||||
| 
 | ||||
|     if (pcmc->pci_enabled) { | ||||
|         pcms->flash[0] = pc_pflash_create(pcms, "system.flash0", | ||||
|                                           "pflash0"); | ||||
|         pcms->flash[1] = pc_pflash_create(pcms, "system.flash1", | ||||
|                                           "pflash1"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void pc_system_flash_cleanup_unused(PCMachineState *pcms) | ||||
| { | ||||
|     char *prop_name; | ||||
|     int i; | ||||
|     Object *dev_obj; | ||||
| 
 | ||||
|     assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled); | ||||
| 
 | ||||
|     for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) { | ||||
|         dev_obj = OBJECT(pcms->flash[i]); | ||||
|         if (!object_property_get_bool(dev_obj, "realized", &error_abort)) { | ||||
|             prop_name = g_strdup_printf("pflash%d", i); | ||||
|             object_property_del(OBJECT(pcms), prop_name, &error_abort); | ||||
|             g_free(prop_name); | ||||
|             object_unparent(dev_obj); | ||||
|             pcms->flash[i] = NULL; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Map the pcms->flash[] from 4GiB downward, and realize. | ||||
|  * Map them in descending order, i.e. pcms->flash[0] at the top, | ||||
|  * without gaps. | ||||
|  * Stop at the first pcms->flash[0] lacking a block backend. | ||||
|  * Set each flash's size from its block backend.  Fatal error if the | ||||
|  * size isn't a non-zero multiple of 4KiB, or the total size exceeds | ||||
|  * FLASH_SIZE_LIMIT. | ||||
|  * | ||||
|  * Addressing within one flash drive is of course not reversed. | ||||
|  * | ||||
|  * An error message is printed and the process exits if: | ||||
|  * - the size of the backing file for a flash drive is non-positive, or not a | ||||
|  *   multiple of the required sector size, or | ||||
|  * - the current mapping's base address would fall below FLASH_MAP_BASE_MIN. | ||||
|  * | ||||
|  * The drive with unit#0 (if available) is mapped at the highest address, and | ||||
|  * it is passed to pc_isa_bios_init(). Merging several drives for isa-bios is | ||||
|  * If pcms->flash[0] has a block backend, its memory is passed to | ||||
|  * pc_isa_bios_init().  Merging several flash devices for isa-bios is | ||||
|  * not supported. | ||||
|  */ | ||||
| static void pc_system_flash_init(MemoryRegion *rom_memory) | ||||
| static void pc_system_flash_map(PCMachineState *pcms, | ||||
|                                 MemoryRegion *rom_memory) | ||||
| { | ||||
|     int unit; | ||||
|     DriveInfo *pflash_drv; | ||||
|     hwaddr total_size = 0; | ||||
|     int i; | ||||
|     BlockBackend *blk; | ||||
|     int64_t size; | ||||
|     char *fatal_errmsg = NULL; | ||||
|     hwaddr phys_addr = 0x100000000ULL; | ||||
|     int sector_bits, sector_size; | ||||
|     pflash_t *system_flash; | ||||
|     PFlashCFI01 *system_flash; | ||||
|     MemoryRegion *flash_mem; | ||||
|     char name[64]; | ||||
|     void *flash_ptr; | ||||
|     int ret, flash_size; | ||||
| 
 | ||||
|     sector_bits = 12; | ||||
|     sector_size = 1 << sector_bits; | ||||
|     assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled); | ||||
| 
 | ||||
|     for (unit = 0; | ||||
|          (unit < FLASH_MAP_UNIT_MAX && | ||||
|           (pflash_drv = drive_get(IF_PFLASH, 0, unit)) != NULL); | ||||
|          ++unit) { | ||||
|         blk = blk_by_legacy_dinfo(pflash_drv); | ||||
|     for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) { | ||||
|         system_flash = pcms->flash[i]; | ||||
|         blk = pflash_cfi01_get_blk(system_flash); | ||||
|         if (!blk) { | ||||
|             break; | ||||
|         } | ||||
|         size = blk_getlength(blk); | ||||
|         if (size < 0) { | ||||
|             fatal_errmsg = g_strdup_printf("failed to get backing file size"); | ||||
|         } else if (size == 0) { | ||||
|             fatal_errmsg = g_strdup_printf("PC system firmware (pflash) " | ||||
|                                "cannot have zero size"); | ||||
|         } else if ((size % sector_size) != 0) { | ||||
|             fatal_errmsg = g_strdup_printf("PC system firmware (pflash) " | ||||
|                                "must be a multiple of 0x%x", sector_size); | ||||
|         } else if (phys_addr < size || phys_addr - size < FLASH_MAP_BASE_MIN) { | ||||
|             fatal_errmsg = g_strdup_printf("oversized backing file, pflash " | ||||
|                                "segments cannot be mapped under " | ||||
|                                TARGET_FMT_plx, FLASH_MAP_BASE_MIN); | ||||
|             error_report("can't get size of block device %s: %s", | ||||
|                          blk_name(blk), strerror(-size)); | ||||
|             exit(1); | ||||
|         } | ||||
|         if (fatal_errmsg != NULL) { | ||||
|             Location loc; | ||||
| 
 | ||||
|             /* push a new, "none" location on the location stack; overwrite its
 | ||||
|              * contents with the location saved in the option; print the error | ||||
|              * (includes location); pop the top | ||||
|              */ | ||||
|             loc_push_none(&loc); | ||||
|             if (pflash_drv->opts != NULL) { | ||||
|                 qemu_opts_loc_restore(pflash_drv->opts); | ||||
|             } | ||||
|             error_report("%s", fatal_errmsg); | ||||
|             loc_pop(&loc); | ||||
|             g_free(fatal_errmsg); | ||||
|         if (size == 0 || size % FLASH_SECTOR_SIZE != 0) { | ||||
|             error_report("system firmware block device %s has invalid size " | ||||
|                          "%" PRId64, | ||||
|                          blk_name(blk), size); | ||||
|             info_report("its size must be a non-zero multiple of 0x%x", | ||||
|                         FLASH_SECTOR_SIZE); | ||||
|             exit(1); | ||||
|         } | ||||
|         if ((hwaddr)size != size | ||||
|             || total_size > HWADDR_MAX - size | ||||
|             || total_size + size > FLASH_SIZE_LIMIT) { | ||||
|             error_report("combined size of system firmware exceeds " | ||||
|                          "%" PRIu64 " bytes", | ||||
|                          FLASH_SIZE_LIMIT); | ||||
|             exit(1); | ||||
|         } | ||||
| 
 | ||||
|         phys_addr -= size; | ||||
|         total_size += size; | ||||
|         qdev_prop_set_uint32(DEVICE(system_flash), "num-blocks", | ||||
|                              size / FLASH_SECTOR_SIZE); | ||||
|         qdev_init_nofail(DEVICE(system_flash)); | ||||
|         sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0, | ||||
|                         0x100000000ULL - total_size); | ||||
| 
 | ||||
|         /* pflash_cfi01_register() creates a deep copy of the name */ | ||||
|         snprintf(name, sizeof name, "system.flash%d", unit); | ||||
|         system_flash = pflash_cfi01_register(phys_addr, NULL /* qdev */, name, | ||||
|                                              size, blk, sector_size, | ||||
|                                              size >> sector_bits, | ||||
|                                              1      /* width */, | ||||
|                                              0x0000 /* id0 */, | ||||
|                                              0x0000 /* id1 */, | ||||
|                                              0x0000 /* id2 */, | ||||
|                                              0x0000 /* id3 */, | ||||
|                                              0      /* be */); | ||||
|         if (unit == 0) { | ||||
|         if (i == 0) { | ||||
|             flash_mem = pflash_cfi01_get_memory(system_flash); | ||||
|             pc_isa_bios_init(rom_memory, flash_mem, size); | ||||
| 
 | ||||
| @ -240,24 +264,63 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw) | ||||
|                                 bios); | ||||
| } | ||||
| 
 | ||||
| void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw) | ||||
| void pc_system_firmware_init(PCMachineState *pcms, | ||||
|                              MemoryRegion *rom_memory) | ||||
| { | ||||
|     PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); | ||||
|     int i; | ||||
|     DriveInfo *pflash_drv; | ||||
|     BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)]; | ||||
|     Location loc; | ||||
| 
 | ||||
|     pflash_drv = drive_get(IF_PFLASH, 0, 0); | ||||
| 
 | ||||
|     if (isapc_ram_fw || pflash_drv == NULL) { | ||||
|         /* When a pflash drive is not found, use rom-mode */ | ||||
|         old_pc_system_rom_init(rom_memory, isapc_ram_fw); | ||||
|     if (!pcmc->pci_enabled) { | ||||
|         old_pc_system_rom_init(rom_memory, true); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (kvm_enabled() && !kvm_readonly_mem_enabled()) { | ||||
|         /* Older KVM cannot execute from device memory. So, flash memory
 | ||||
|          * cannot be used unless the readonly memory kvm capability is present. */ | ||||
|         fprintf(stderr, "qemu: pflash with kvm requires KVM readonly memory support\n"); | ||||
|         exit(1); | ||||
|     /* Map legacy -drive if=pflash to machine properties */ | ||||
|     for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) { | ||||
|         pflash_blk[i] = pflash_cfi01_get_blk(pcms->flash[i]); | ||||
|         pflash_drv = drive_get(IF_PFLASH, 0, i); | ||||
|         if (!pflash_drv) { | ||||
|             continue; | ||||
|         } | ||||
|         loc_push_none(&loc); | ||||
|         qemu_opts_loc_restore(pflash_drv->opts); | ||||
|         if (pflash_blk[i]) { | ||||
|             error_report("clashes with -machine"); | ||||
|             exit(1); | ||||
|         } | ||||
|         pflash_blk[i] = blk_by_legacy_dinfo(pflash_drv); | ||||
|         qdev_prop_set_drive(DEVICE(pcms->flash[i]), | ||||
|                             "drive", pflash_blk[i], &error_fatal); | ||||
|         loc_pop(&loc); | ||||
|     } | ||||
| 
 | ||||
|     pc_system_flash_init(rom_memory); | ||||
|     /* Reject gaps */ | ||||
|     for (i = 1; i < ARRAY_SIZE(pcms->flash); i++) { | ||||
|         if (pflash_blk[i] && !pflash_blk[i - 1]) { | ||||
|             error_report("pflash%d requires pflash%d", i, i - 1); | ||||
|             exit(1); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (!pflash_blk[0]) { | ||||
|         /* Machine property pflash0 not set, use ROM mode */ | ||||
|         old_pc_system_rom_init(rom_memory, false); | ||||
|     } else { | ||||
|         if (kvm_enabled() && !kvm_readonly_mem_enabled()) { | ||||
|             /*
 | ||||
|              * Older KVM cannot execute from device memory. So, flash | ||||
|              * memory cannot be used unless the readonly memory kvm | ||||
|              * capability is present. | ||||
|              */ | ||||
|             error_report("pflash with kvm requires KVM readonly memory support"); | ||||
|             exit(1); | ||||
|         } | ||||
| 
 | ||||
|         pc_system_flash_map(pcms, rom_memory); | ||||
|     } | ||||
| 
 | ||||
|     pc_system_flash_cleanup_unused(pcms); | ||||
| } | ||||
|  | ||||
| @ -113,9 +113,9 @@ static void lm32_evr_init(MachineState *machine) | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     /* Spansion S29NS128P */ | ||||
|     pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size, | ||||
|     pflash_cfi02_register(flash_base, "lm32_evr.flash", flash_size, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           flash_sector_size, flash_size / flash_sector_size, | ||||
|                           flash_sector_size, | ||||
|                           1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); | ||||
| 
 | ||||
|     /* create irq lines */ | ||||
| @ -206,9 +206,9 @@ static void lm32_uclinux_init(MachineState *machine) | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     /* Spansion S29NS128P */ | ||||
|     pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size, | ||||
|     pflash_cfi02_register(flash_base, "lm32_uclinux.flash", flash_size, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           flash_sector_size, flash_size / flash_sector_size, | ||||
|                           flash_sector_size, | ||||
|                           1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); | ||||
| 
 | ||||
|     /* create irq lines */ | ||||
|  | ||||
| @ -120,10 +120,9 @@ milkymist_init(MachineState *machine) | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     /* Numonyx JS28F256J3F105 */ | ||||
|     pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size, | ||||
|     pflash_cfi01_register(flash_base, "milkymist.flash", flash_size, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           flash_sector_size, flash_size / flash_sector_size, | ||||
|                           2, 0x00, 0x89, 0x00, 0x1d, 1); | ||||
|                           flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1); | ||||
| 
 | ||||
|     /* create irq lines */ | ||||
|     env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0)); | ||||
|  | ||||
| @ -106,11 +106,9 @@ petalogix_ml605_init(MachineState *machine) | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     /* 5th parameter 2 means bank-width
 | ||||
|      * 10th paremeter 0 means little-endian */ | ||||
|     pflash_cfi01_register(FLASH_BASEADDR, | ||||
|                           NULL, "petalogix_ml605.flash", FLASH_SIZE, | ||||
|     pflash_cfi01_register(FLASH_BASEADDR, "petalogix_ml605.flash", FLASH_SIZE, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           64 * KiB, FLASH_SIZE >> 16, | ||||
|                           2, 0x89, 0x18, 0x0000, 0x0, 0); | ||||
|                           64 * KiB, 2, 0x89, 0x18, 0x0000, 0x0, 0); | ||||
| 
 | ||||
| 
 | ||||
|     dev = qdev_create(NULL, "xlnx.xps-intc"); | ||||
|  | ||||
| @ -87,10 +87,9 @@ petalogix_s3adsp1800_init(MachineState *machine) | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     pflash_cfi01_register(FLASH_BASEADDR, | ||||
|                           NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE, | ||||
|                           "petalogix_s3adsp1800.flash", FLASH_SIZE, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           64 * KiB, FLASH_SIZE >> 16, | ||||
|                           1, 0x89, 0x18, 0x0000, 0x0, 1); | ||||
|                           64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1); | ||||
| 
 | ||||
|     dev = qdev_create(NULL, "xlnx.xps-intc"); | ||||
|     qdev_prop_set_uint32(dev, "kind-of-intr", | ||||
|  | ||||
| @ -58,8 +58,6 @@ | ||||
| #include "exec/semihost.h" | ||||
| #include "hw/mips/cps.h" | ||||
| 
 | ||||
| //#define DEBUG_BOARD_INIT
 | ||||
| 
 | ||||
| #define ENVP_ADDR		0x80002000l | ||||
| #define ENVP_NB_ENTRIES	 	16 | ||||
| #define ENVP_ENTRY_SIZE	 	256 | ||||
| @ -1189,13 +1187,12 @@ void mips_malta_init(MachineState *machine) | ||||
|     const char *kernel_cmdline = machine->kernel_cmdline; | ||||
|     const char *initrd_filename = machine->initrd_filename; | ||||
|     char *filename; | ||||
|     pflash_t *fl; | ||||
|     PFlashCFI01 *fl; | ||||
|     MemoryRegion *system_memory = get_system_memory(); | ||||
|     MemoryRegion *ram_high = g_new(MemoryRegion, 1); | ||||
|     MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1); | ||||
|     MemoryRegion *ram_low_postio; | ||||
|     MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1); | ||||
|     target_long bios_size = FLASH_SIZE; | ||||
|     const size_t smbus_eeprom_size = 8 * 256; | ||||
|     uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size); | ||||
|     int64_t kernel_entry, bootloader_run_addr; | ||||
| @ -1208,7 +1205,6 @@ void mips_malta_init(MachineState *machine) | ||||
|     DriveInfo *dinfo; | ||||
|     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | ||||
|     int fl_idx = 0; | ||||
|     int fl_sectors = bios_size >> 16; | ||||
|     int be; | ||||
| 
 | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA); | ||||
| @ -1265,18 +1261,10 @@ void mips_malta_init(MachineState *machine) | ||||
| 
 | ||||
|     /* Load firmware in flash / BIOS. */ | ||||
|     dinfo = drive_get(IF_PFLASH, 0, fl_idx); | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     if (dinfo) { | ||||
|         printf("Register parallel flash %d size " TARGET_FMT_lx " at " | ||||
|                "addr %08llx '%s' %x\n", | ||||
|                fl_idx, bios_size, FLASH_ADDRESS, | ||||
|                blk_name(dinfo->bdrv), fl_sectors); | ||||
|     } | ||||
| #endif | ||||
|     fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios", | ||||
|                                BIOS_SIZE, | ||||
|     fl = pflash_cfi01_register(FLASH_ADDRESS, "mips_malta.bios", | ||||
|                                FLASH_SIZE, | ||||
|                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                                65536, fl_sectors, | ||||
|                                65536, | ||||
|                                4, 0x0000, 0x0000, 0x0000, 0x0000, be); | ||||
|     bios = pflash_cfi01_get_memory(fl); | ||||
|     fl_idx++; | ||||
| @ -1312,6 +1300,7 @@ void mips_malta_init(MachineState *machine) | ||||
|                              bootloader_run_addr, kernel_entry); | ||||
|         } | ||||
|     } else { | ||||
|         target_long bios_size = FLASH_SIZE; | ||||
|         /* The flash region isn't executable from a KVM guest */ | ||||
|         if (kvm_enabled()) { | ||||
|             error_report("KVM enabled but no -kernel argument was specified. " | ||||
|  | ||||
| @ -235,10 +235,9 @@ void mips_r4k_init(MachineState *machine) | ||||
|         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); | ||||
|     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { | ||||
|         uint32_t mips_rom = 0x00400000; | ||||
|         if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom, | ||||
|         if (!pflash_cfi01_register(0x1fc00000, "mips_r4k.bios", mips_rom, | ||||
|                                    blk_by_legacy_dinfo(dinfo), | ||||
|                                    sector_len, mips_rom / sector_len, | ||||
|                                    4, 0, 0, 0, 0, be)) { | ||||
|                                    sector_len, 4, 0, 0, 0, 0, be)) { | ||||
|             fprintf(stderr, "qemu: Error registering flash memory.\n"); | ||||
|         } | ||||
|     } else if (!qtest_enabled()) { | ||||
|  | ||||
| @ -48,8 +48,6 @@ | ||||
| 
 | ||||
| #define USE_FLASH_BIOS | ||||
| 
 | ||||
| //#define DEBUG_BOARD_INIT
 | ||||
| 
 | ||||
| /*****************************************************************************/ | ||||
| /* PPC405EP reference board (IBM) */ | ||||
| /* Standalone board with:
 | ||||
| @ -158,7 +156,7 @@ static void ref405ep_init(MachineState *machine) | ||||
|     target_ulong kernel_base, initrd_base; | ||||
|     long kernel_size, initrd_size; | ||||
|     int linux_boot; | ||||
|     int fl_idx, fl_sectors, len; | ||||
|     int len; | ||||
|     DriveInfo *dinfo; | ||||
|     MemoryRegion *sysmem = get_system_memory(); | ||||
| 
 | ||||
| @ -171,9 +169,6 @@ static void ref405ep_init(MachineState *machine) | ||||
|     ram_bases[1] = 0x00000000; | ||||
|     ram_sizes[1] = 0x00000000; | ||||
|     ram_size = 128 * MiB; | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: register cpu\n", __func__); | ||||
| #endif | ||||
|     env = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes, | ||||
|                         33333333, &pic, kernel_filename == NULL ? 0 : 1); | ||||
|     /* allocate SRAM */ | ||||
| @ -182,35 +177,19 @@ static void ref405ep_init(MachineState *machine) | ||||
|                            &error_fatal); | ||||
|     memory_region_add_subregion(sysmem, 0xFFF00000, sram); | ||||
|     /* allocate and load BIOS */ | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: register BIOS\n", __func__); | ||||
| #endif | ||||
|     fl_idx = 0; | ||||
| #ifdef USE_FLASH_BIOS | ||||
|     dinfo = drive_get(IF_PFLASH, 0, fl_idx); | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     if (dinfo) { | ||||
|         BlockBackend *blk = blk_by_legacy_dinfo(dinfo); | ||||
| 
 | ||||
|         bios_size = blk_getlength(blk); | ||||
|         fl_sectors = (bios_size + 65535) >> 16; | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|         printf("Register parallel flash %d size %lx" | ||||
|                " at addr %lx '%s' %d\n", | ||||
|                fl_idx, bios_size, -bios_size, | ||||
|                blk_name(blk), fl_sectors); | ||||
| #endif | ||||
|         bios_size = 8 * MiB; | ||||
|         pflash_cfi02_register((uint32_t)(-bios_size), | ||||
|                               NULL, "ef405ep.bios", bios_size, | ||||
|                               blk, 65536, fl_sectors, 1, | ||||
|                               "ef405ep.bios", bios_size, | ||||
|                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                               64 * KiB, 1, | ||||
|                               2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, | ||||
|                               1); | ||||
|         fl_idx++; | ||||
|     } else | ||||
| #endif | ||||
|     { | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|         printf("Load BIOS from file\n"); | ||||
| #endif | ||||
|         bios = g_new(MemoryRegion, 1); | ||||
|         memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE, | ||||
|                                &error_fatal); | ||||
| @ -239,21 +218,12 @@ static void ref405ep_init(MachineState *machine) | ||||
|         memory_region_set_readonly(bios, true); | ||||
|     } | ||||
|     /* Register FPGA */ | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: register FPGA\n", __func__); | ||||
| #endif | ||||
|     ref405ep_fpga_init(sysmem, 0xF0300000); | ||||
|     /* Register NVRAM */ | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: register NVRAM\n", __func__); | ||||
| #endif | ||||
|     m48t59_init(NULL, 0xF0000000, 0, 8192, 1968, 8); | ||||
|     /* Load kernel */ | ||||
|     linux_boot = (kernel_filename != NULL); | ||||
|     if (linux_boot) { | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|         printf("%s: load kernel\n", __func__); | ||||
| #endif | ||||
|         memset(&bd, 0, sizeof(bd)); | ||||
|         bd.bi_memstart = 0x00000000; | ||||
|         bd.bi_memsize = ram_size; | ||||
| @ -325,10 +295,6 @@ static void ref405ep_init(MachineState *machine) | ||||
|         initrd_size = 0; | ||||
|         bdloc = 0; | ||||
|     } | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("bdloc " RAM_ADDR_FMT "\n", bdloc); | ||||
|     printf("%s: Done\n", __func__); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void ref405ep_class_init(ObjectClass *oc, void *data) | ||||
| @ -455,7 +421,7 @@ static void taihu_405ep_init(MachineState *machine) | ||||
|     target_ulong kernel_base, initrd_base; | ||||
|     long kernel_size, initrd_size; | ||||
|     int linux_boot; | ||||
|     int fl_idx, fl_sectors; | ||||
|     int fl_idx; | ||||
|     DriveInfo *dinfo; | ||||
| 
 | ||||
|     /* RAM is soldered to the board so the size cannot be changed */ | ||||
| @ -473,43 +439,24 @@ static void taihu_405ep_init(MachineState *machine) | ||||
|     memory_region_init_alias(&ram_memories[1], NULL, | ||||
|                              "taihu_405ep.ram-1", ram, ram_bases[1], | ||||
|                              ram_sizes[1]); | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: register cpu\n", __func__); | ||||
| #endif | ||||
|     ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes, | ||||
|                   33333333, &pic, kernel_filename == NULL ? 0 : 1); | ||||
|     /* allocate and load BIOS */ | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: register BIOS\n", __func__); | ||||
| #endif | ||||
|     fl_idx = 0; | ||||
| #if defined(USE_FLASH_BIOS) | ||||
|     dinfo = drive_get(IF_PFLASH, 0, fl_idx); | ||||
|     if (dinfo) { | ||||
|         BlockBackend *blk = blk_by_legacy_dinfo(dinfo); | ||||
| 
 | ||||
|         bios_size = blk_getlength(blk); | ||||
|         /* XXX: should check that size is 2MB */ | ||||
|         //        bios_size = 2 * 1024 * 1024;
 | ||||
|         fl_sectors = (bios_size + 65535) >> 16; | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|         printf("Register parallel flash %d size %lx" | ||||
|                " at addr %lx '%s' %d\n", | ||||
|                fl_idx, bios_size, -bios_size, | ||||
|                blk_name(blk), fl_sectors); | ||||
| #endif | ||||
|         pflash_cfi02_register((uint32_t)(-bios_size), | ||||
|                               NULL, "taihu_405ep.bios", bios_size, | ||||
|                               blk, 65536, fl_sectors, 1, | ||||
|         bios_size = 2 * MiB; | ||||
|         pflash_cfi02_register(0xFFE00000, | ||||
|                               "taihu_405ep.bios", bios_size, | ||||
|                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                               64 * KiB, 1, | ||||
|                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, | ||||
|                               1); | ||||
|         fl_idx++; | ||||
|     } else | ||||
| #endif | ||||
|     { | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|         printf("Load BIOS from file\n"); | ||||
| #endif | ||||
|         if (bios_name == NULL) | ||||
|             bios_name = BIOS_FILENAME; | ||||
|         bios = g_new(MemoryRegion, 1); | ||||
| @ -536,35 +483,19 @@ static void taihu_405ep_init(MachineState *machine) | ||||
|     /* Register Linux flash */ | ||||
|     dinfo = drive_get(IF_PFLASH, 0, fl_idx); | ||||
|     if (dinfo) { | ||||
|         BlockBackend *blk = blk_by_legacy_dinfo(dinfo); | ||||
| 
 | ||||
|         bios_size = blk_getlength(blk); | ||||
|         /* XXX: should check that size is 32MB */ | ||||
|         bios_size = 32 * MiB; | ||||
|         fl_sectors = (bios_size + 65535) >> 16; | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|         printf("Register parallel flash %d size %lx" | ||||
|                " at addr " TARGET_FMT_lx " '%s'\n", | ||||
|                fl_idx, bios_size, (target_ulong)0xfc000000, | ||||
|                blk_name(blk)); | ||||
| #endif | ||||
|         pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size, | ||||
|                               blk, 65536, fl_sectors, 1, | ||||
|         pflash_cfi02_register(0xfc000000, "taihu_405ep.flash", bios_size, | ||||
|                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                               64 * KiB, 1, | ||||
|                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, | ||||
|                               1); | ||||
|         fl_idx++; | ||||
|     } | ||||
|     /* Register CLPD & LCD display */ | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: register CPLD\n", __func__); | ||||
| #endif | ||||
|     taihu_cpld_init(sysmem, 0x50100000); | ||||
|     /* Load kernel */ | ||||
|     linux_boot = (kernel_filename != NULL); | ||||
|     if (linux_boot) { | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|         printf("%s: load kernel\n", __func__); | ||||
| #endif | ||||
|         kernel_base = KERNEL_LOAD_ADDR; | ||||
|         /* now we can load the kernel */ | ||||
|         kernel_size = load_image_targphys(kernel_filename, kernel_base, | ||||
| @ -593,9 +524,6 @@ static void taihu_405ep_init(MachineState *machine) | ||||
|         initrd_base = 0; | ||||
|         initrd_size = 0; | ||||
|     } | ||||
| #ifdef DEBUG_BOARD_INIT | ||||
|     printf("%s: Done\n", __func__); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void taihu_class_init(ObjectClass *oc, void *data) | ||||
|  | ||||
| @ -91,32 +91,42 @@ struct boot_info { | ||||
| 
 | ||||
| static int sam460ex_load_uboot(void) | ||||
| { | ||||
|     /*
 | ||||
|      * This first creates 1MiB of flash memory mapped at the end of | ||||
|      * the 32-bit address space (0xFFF00000..0xFFFFFFFF). | ||||
|      * | ||||
|      * If_PFLASH unit 0 is defined, the flash memory is initialized | ||||
|      * from that block backend. | ||||
|      * | ||||
|      * Else, it's initialized to zero.  And then 512KiB of ROM get | ||||
|      * mapped on top of its second half (0xFFF80000..0xFFFFFFFF), | ||||
|      * initialized from u-boot-sam460-20100605.bin. | ||||
|      * | ||||
|      * This doesn't smell right. | ||||
|      * | ||||
|      * The physical hardware appears to have 512KiB flash memory. | ||||
|      * | ||||
|      * TODO Figure out what we really need here, and clean this up. | ||||
|      */ | ||||
| 
 | ||||
|     DriveInfo *dinfo; | ||||
|     BlockBackend *blk = NULL; | ||||
|     hwaddr base = FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32); | ||||
|     long bios_size = FLASH_SIZE; | ||||
|     int fl_sectors; | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     if (dinfo) { | ||||
|         blk = blk_by_legacy_dinfo(dinfo); | ||||
|         bios_size = blk_getlength(blk); | ||||
|     } | ||||
|     fl_sectors = (bios_size + 65535) >> 16; | ||||
| 
 | ||||
|     if (!pflash_cfi01_register(base, NULL, "sam460ex.flash", bios_size, | ||||
|                                blk, 64 * KiB, fl_sectors, | ||||
|                                1, 0x89, 0x18, 0x0000, 0x0, 1)) { | ||||
|     if (!pflash_cfi01_register(FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32), | ||||
|                                "sam460ex.flash", FLASH_SIZE, | ||||
|                                dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                                64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1)) { | ||||
|         error_report("Error registering flash memory"); | ||||
|         /* XXX: return an error instead? */ | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     if (!blk) { | ||||
|     if (!dinfo) { | ||||
|         /*error_report("No flash image given with the 'pflash' parameter,"
 | ||||
|                 " using default u-boot image");*/ | ||||
|         base = UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32); | ||||
|         rom_add_file_fixed(UBOOT_FILENAME, base, -1); | ||||
|         rom_add_file_fixed(UBOOT_FILENAME, | ||||
|                            UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32), | ||||
|                            -1); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
|  | ||||
| @ -226,10 +226,9 @@ static void virtex_init(MachineState *machine) | ||||
|     memory_region_add_subregion(address_space_mem, ram_base, phys_ram); | ||||
| 
 | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     pflash_cfi01_register(PFLASH_BASEADDR, NULL, "virtex.flash", FLASH_SIZE, | ||||
|     pflash_cfi01_register(PFLASH_BASEADDR, "virtex.flash", FLASH_SIZE, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           64 * KiB, FLASH_SIZE >> 16, | ||||
|                           1, 0x89, 0x18, 0x0000, 0x0, 1); | ||||
|                           64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1); | ||||
| 
 | ||||
|     cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT]; | ||||
|     dev = qdev_create(NULL, "xlnx.xps-intc"); | ||||
|  | ||||
							
								
								
									
										17
									
								
								hw/sh4/r2d.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								hw/sh4/r2d.c
									
									
									
									
									
								
							| @ -43,7 +43,7 @@ | ||||
| #include "exec/address-spaces.h" | ||||
| 
 | ||||
| #define FLASH_BASE 0x00000000 | ||||
| #define FLASH_SIZE 0x02000000 | ||||
| #define FLASH_SIZE (16 * MiB) | ||||
| 
 | ||||
| #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */ | ||||
| #define SDRAM_SIZE 0x04000000 | ||||
| @ -287,12 +287,19 @@ static void r2d_init(MachineState *machine) | ||||
|     sysbus_mmio_map(busdev, 1, 0x1400080c); | ||||
|     mmio_ide_init_drives(dev, dinfo, NULL); | ||||
| 
 | ||||
|     /* onboard flash memory */ | ||||
|     /*
 | ||||
|      * Onboard flash memory | ||||
|      * According to the old board user document in Japanese (under | ||||
|      * NDA) what is referred to as FROM (Area0) is connected via a | ||||
|      * 32-bit bus and CS0 to CN8. The docs mention a Cypress | ||||
|      * S29PL127J60TFI130 chipsset.  Per the 'S29PL-J 002-00615 | ||||
|      * Rev. *E' datasheet, it is a 128Mbit NOR parallel flash | ||||
|      * addressable in words of 16bit. | ||||
|      */ | ||||
|     dinfo = drive_get(IF_PFLASH, 0, 0); | ||||
|     pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE, | ||||
|     pflash_cfi02_register(0x0, "r2d.flash", FLASH_SIZE, | ||||
|                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, | ||||
|                           16 * KiB, FLASH_SIZE >> 16, | ||||
|                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|                           64 * KiB, 1, 2, 0x0001, 0x227e, 0x2220, 0x2200, | ||||
|                           0x555, 0x2aa, 0); | ||||
| 
 | ||||
|     /* NIC: rtl8139 on-board, and 2 slots. */ | ||||
|  | ||||
| @ -162,12 +162,12 @@ static void xtfpga_net_init(MemoryRegion *address_space, | ||||
|     memory_region_add_subregion(address_space, buffers, ram); | ||||
| } | ||||
| 
 | ||||
| static pflash_t *xtfpga_flash_init(MemoryRegion *address_space, | ||||
|                                    const XtfpgaBoardDesc *board, | ||||
|                                    DriveInfo *dinfo, int be) | ||||
| static PFlashCFI01 *xtfpga_flash_init(MemoryRegion *address_space, | ||||
|                                       const XtfpgaBoardDesc *board, | ||||
|                                       DriveInfo *dinfo, int be) | ||||
| { | ||||
|     SysBusDevice *s; | ||||
|     DeviceState *dev = qdev_create(NULL, "cfi.pflash01"); | ||||
|     DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01); | ||||
| 
 | ||||
|     qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo), | ||||
|                         &error_abort); | ||||
| @ -181,7 +181,7 @@ static pflash_t *xtfpga_flash_init(MemoryRegion *address_space, | ||||
|     s = SYS_BUS_DEVICE(dev); | ||||
|     memory_region_add_subregion(address_space, board->flash->base, | ||||
|                                 sysbus_mmio_get_region(s, 0)); | ||||
|     return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01"); | ||||
|     return PFLASH_CFI01(dev); | ||||
| } | ||||
| 
 | ||||
| static uint64_t translate_phys_addr(void *opaque, uint64_t addr) | ||||
| @ -229,7 +229,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine) | ||||
|     XtensaMxPic *mx_pic = NULL; | ||||
|     qemu_irq *extints; | ||||
|     DriveInfo *dinfo; | ||||
|     pflash_t *flash = NULL; | ||||
|     PFlashCFI01 *flash = NULL; | ||||
|     QemuOpts *machine_opts = qemu_get_machine_opts(); | ||||
|     const char *kernel_filename = qemu_opt_get(machine_opts, "kernel"); | ||||
|     const char *kernel_cmdline = qemu_opt_get(machine_opts, "append"); | ||||
|  | ||||
| @ -5,32 +5,46 @@ | ||||
| 
 | ||||
| #include "exec/memory.h" | ||||
| 
 | ||||
| #define TYPE_CFI_PFLASH01 "cfi.pflash01" | ||||
| #define TYPE_CFI_PFLASH02 "cfi.pflash02" | ||||
| 
 | ||||
| typedef struct pflash_t pflash_t; | ||||
| 
 | ||||
| /* pflash_cfi01.c */ | ||||
| pflash_t *pflash_cfi01_register(hwaddr base, | ||||
|                                 DeviceState *qdev, const char *name, | ||||
|                                 hwaddr size, | ||||
|                                 BlockBackend *blk, | ||||
|                                 uint32_t sector_len, int nb_blocs, int width, | ||||
|                                 uint16_t id0, uint16_t id1, | ||||
|                                 uint16_t id2, uint16_t id3, int be); | ||||
| 
 | ||||
| #define TYPE_PFLASH_CFI01 "cfi.pflash01" | ||||
| #define PFLASH_CFI01(obj) \ | ||||
|     OBJECT_CHECK(PFlashCFI01, (obj), TYPE_PFLASH_CFI01) | ||||
| 
 | ||||
| typedef struct PFlashCFI01 PFlashCFI01; | ||||
| 
 | ||||
| PFlashCFI01 *pflash_cfi01_register(hwaddr base, | ||||
|                                    const char *name, | ||||
|                                    hwaddr size, | ||||
|                                    BlockBackend *blk, | ||||
|                                    uint32_t sector_len, | ||||
|                                    int width, | ||||
|                                    uint16_t id0, uint16_t id1, | ||||
|                                    uint16_t id2, uint16_t id3, | ||||
|                                    int be); | ||||
| BlockBackend *pflash_cfi01_get_blk(PFlashCFI01 *fl); | ||||
| MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl); | ||||
| 
 | ||||
| /* pflash_cfi02.c */ | ||||
| pflash_t *pflash_cfi02_register(hwaddr base, | ||||
|                                 DeviceState *qdev, const char *name, | ||||
|                                 hwaddr size, | ||||
|                                 BlockBackend *blk, uint32_t sector_len, | ||||
|                                 int nb_blocs, int nb_mappings, int width, | ||||
|                                 uint16_t id0, uint16_t id1, | ||||
|                                 uint16_t id2, uint16_t id3, | ||||
|                                 uint16_t unlock_addr0, uint16_t unlock_addr1, | ||||
|                                 int be); | ||||
| 
 | ||||
| MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl); | ||||
| #define TYPE_PFLASH_CFI02 "cfi.pflash02" | ||||
| #define PFLASH_CFI02(obj) \ | ||||
|     OBJECT_CHECK(PFlashCFI02, (obj), TYPE_PFLASH_CFI02) | ||||
| 
 | ||||
| typedef struct PFlashCFI02 PFlashCFI02; | ||||
| 
 | ||||
| PFlashCFI02 *pflash_cfi02_register(hwaddr base, | ||||
|                                    const char *name, | ||||
|                                    hwaddr size, | ||||
|                                    BlockBackend *blk, | ||||
|                                    uint32_t sector_len, | ||||
|                                    int nb_mappings, | ||||
|                                    int width, | ||||
|                                    uint16_t id0, uint16_t id1, | ||||
|                                    uint16_t id2, uint16_t id3, | ||||
|                                    uint16_t unlock_addr0, | ||||
|                                    uint16_t unlock_addr1, | ||||
|                                    int be); | ||||
| 
 | ||||
| /* nand.c */ | ||||
| DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id); | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
| #include "hw/boards.h" | ||||
| #include "hw/isa/isa.h" | ||||
| #include "hw/block/fdc.h" | ||||
| #include "hw/block/flash.h" | ||||
| #include "net/net.h" | ||||
| #include "hw/i386/ioapic.h" | ||||
| 
 | ||||
| @ -39,6 +40,7 @@ struct PCMachineState { | ||||
|     PCIBus *bus; | ||||
|     FWCfgState *fw_cfg; | ||||
|     qemu_irq *gsi; | ||||
|     PFlashCFI01 *flash[2]; | ||||
| 
 | ||||
|     /* Configuration options: */ | ||||
|     uint64_t max_ram_below_4g; | ||||
| @ -277,8 +279,8 @@ extern PCIDevice *piix4_dev; | ||||
| int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn); | ||||
| 
 | ||||
| /* pc_sysfw.c */ | ||||
| void pc_system_firmware_init(MemoryRegion *rom_memory, | ||||
|                              bool isapc_ram_fw); | ||||
| void pc_system_flash_create(PCMachineState *pcms); | ||||
| void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory); | ||||
| 
 | ||||
| /* acpi-build.c */ | ||||
| void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, | ||||
|  | ||||
| @ -431,8 +431,6 @@ const char *qdev_fw_name(DeviceState *dev); | ||||
| 
 | ||||
| Object *qdev_get_machine(void); | ||||
| 
 | ||||
| void object_apply_compat_props(Object *obj); | ||||
| 
 | ||||
| /* FIXME: make this a link<> */ | ||||
| void qdev_set_parent_bus(DeviceState *dev, BusState *bus); | ||||
| 
 | ||||
|  | ||||
| @ -677,6 +677,9 @@ Object *object_new_with_propv(const char *typename, | ||||
| 
 | ||||
| void object_apply_global_props(Object *obj, const GPtrArray *props, | ||||
|                                Error **errp); | ||||
| void object_set_machine_compat_props(GPtrArray *compat_props); | ||||
| void object_set_accelerator_compat_props(GPtrArray *compat_props); | ||||
| void object_apply_compat_props(Object *obj); | ||||
| 
 | ||||
| /**
 | ||||
|  * object_set_props: | ||||
|  | ||||
							
								
								
									
										39
									
								
								qom/object.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								qom/object.c
									
									
									
									
									
								
							| @ -408,6 +408,45 @@ void object_apply_global_props(Object *obj, const GPtrArray *props, Error **errp | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Global property defaults | ||||
|  * Slot 0: accelerator's global property defaults | ||||
|  * Slot 1: machine's global property defaults | ||||
|  * Each is a GPtrArray of of GlobalProperty. | ||||
|  * Applied in order, later entries override earlier ones. | ||||
|  */ | ||||
| static GPtrArray *object_compat_props[2]; | ||||
| 
 | ||||
| /*
 | ||||
|  * Set machine's global property defaults to @compat_props. | ||||
|  * May be called at most once. | ||||
|  */ | ||||
| void object_set_machine_compat_props(GPtrArray *compat_props) | ||||
| { | ||||
|     assert(!object_compat_props[1]); | ||||
|     object_compat_props[1] = compat_props; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Set accelerator's global property defaults to @compat_props. | ||||
|  * May be called at most once. | ||||
|  */ | ||||
| void object_set_accelerator_compat_props(GPtrArray *compat_props) | ||||
| { | ||||
|     assert(!object_compat_props[0]); | ||||
|     object_compat_props[0] = compat_props; | ||||
| } | ||||
| 
 | ||||
| void object_apply_compat_props(Object *obj) | ||||
| { | ||||
|     int i; | ||||
| 
 | ||||
|     for (i = 0; i < ARRAY_SIZE(object_compat_props); i++) { | ||||
|         object_apply_global_props(obj, object_compat_props[i], | ||||
|                                   &error_abort); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void object_initialize_with_type(void *data, size_t size, TypeImpl *type) | ||||
| { | ||||
|     Object *obj = data; | ||||
|  | ||||
							
								
								
									
										125
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								vl.c
									
									
									
									
									
								
							| @ -1191,6 +1191,55 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type, | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| typedef struct BlockdevOptionsQueueEntry { | ||||
|     BlockdevOptions *bdo; | ||||
|     Location loc; | ||||
|     QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry; | ||||
| } BlockdevOptionsQueueEntry; | ||||
| 
 | ||||
| typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue; | ||||
| 
 | ||||
| static void configure_blockdev(BlockdevOptionsQueue *bdo_queue, | ||||
|                                MachineClass *machine_class, int snapshot) | ||||
| { | ||||
|     /*
 | ||||
|      * If the currently selected machine wishes to override the | ||||
|      * units-per-bus property of its default HBA interface type, do so | ||||
|      * now. | ||||
|      */ | ||||
|     if (machine_class->units_per_default_bus) { | ||||
|         override_max_devs(machine_class->block_default_type, | ||||
|                           machine_class->units_per_default_bus); | ||||
|     } | ||||
| 
 | ||||
|     /* open the virtual block devices */ | ||||
|     while (!QSIMPLEQ_EMPTY(bdo_queue)) { | ||||
|         BlockdevOptionsQueueEntry *bdo = QSIMPLEQ_FIRST(bdo_queue); | ||||
| 
 | ||||
|         QSIMPLEQ_REMOVE_HEAD(bdo_queue, entry); | ||||
|         loc_push_restore(&bdo->loc); | ||||
|         qmp_blockdev_add(bdo->bdo, &error_fatal); | ||||
|         loc_pop(&bdo->loc); | ||||
|         qapi_free_BlockdevOptions(bdo->bdo); | ||||
|         g_free(bdo); | ||||
|     } | ||||
|     if (snapshot || replay_mode != REPLAY_MODE_NONE) { | ||||
|         qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, | ||||
|                           NULL, NULL); | ||||
|     } | ||||
|     if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, | ||||
|                           &machine_class->block_default_type, &error_fatal)) { | ||||
|         /* We printed help */ | ||||
|         exit(0); | ||||
|     } | ||||
| 
 | ||||
|     default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2, | ||||
|                   CDROM_OPTS); | ||||
|     default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS); | ||||
|     default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static QemuOptsList qemu_smp_opts = { | ||||
|     .name = "smp-opts", | ||||
|     .implied_opt_name = "cpus", | ||||
| @ -2937,17 +2986,6 @@ static void user_register_global_props(void) | ||||
|                       global_init_func, NULL, NULL); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Note: we should see that these properties are actually having a | ||||
|  * priority: accel < machine < user. This means e.g. when user | ||||
|  * specifies something in "-global", it'll always be used with highest | ||||
|  * priority than either machine/accelerator compat properties. | ||||
|  */ | ||||
| static void register_global_properties(MachineState *ms) | ||||
| { | ||||
|     user_register_global_props(); | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char **argv, char **envp) | ||||
| { | ||||
|     int i; | ||||
| @ -2982,13 +3020,7 @@ int main(int argc, char **argv, char **envp) | ||||
|     Error *err = NULL; | ||||
|     bool list_data_dirs = false; | ||||
|     char *dir, **dirs; | ||||
|     typedef struct BlockdevOptions_queue { | ||||
|         BlockdevOptions *bdo; | ||||
|         Location loc; | ||||
|         QSIMPLEQ_ENTRY(BlockdevOptions_queue) entry; | ||||
|     } BlockdevOptions_queue; | ||||
|     QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue | ||||
|         = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); | ||||
|     BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); | ||||
| 
 | ||||
|     module_call_init(MODULE_INIT_TRACE); | ||||
| 
 | ||||
| @ -3112,12 +3144,12 @@ int main(int argc, char **argv, char **envp) | ||||
|             case QEMU_OPTION_blockdev: | ||||
|                 { | ||||
|                     Visitor *v; | ||||
|                     BlockdevOptions_queue *bdo; | ||||
|                     BlockdevOptionsQueueEntry *bdo; | ||||
| 
 | ||||
|                     v = qobject_input_visitor_new_str(optarg, "driver", | ||||
|                                                       &error_fatal); | ||||
| 
 | ||||
|                     bdo = g_new(BlockdevOptions_queue, 1); | ||||
|                     bdo = g_new(BlockdevOptionsQueueEntry, 1); | ||||
|                     visit_type_BlockdevOptions(v, NULL, &bdo->bdo, | ||||
|                                                &error_fatal); | ||||
|                     visit_free(v); | ||||
| @ -3942,6 +3974,8 @@ int main(int argc, char **argv, char **envp) | ||||
|      */ | ||||
|     loc_set_none(); | ||||
| 
 | ||||
|     user_register_global_props(); | ||||
| 
 | ||||
|     replay_configure(icount_opts); | ||||
| 
 | ||||
|     if (incoming && !preconfig_exit_requested) { | ||||
| @ -3953,6 +3987,7 @@ int main(int argc, char **argv, char **envp) | ||||
|     configure_rtc(qemu_find_opts_singleton("rtc")); | ||||
| 
 | ||||
|     machine_class = select_machine(); | ||||
|     object_set_machine_compat_props(machine_class->compat_props); | ||||
| 
 | ||||
|     set_memory_options(&ram_slots, &maxram_size, machine_class); | ||||
| 
 | ||||
| @ -3997,6 +4032,10 @@ int main(int argc, char **argv, char **envp) | ||||
|     } | ||||
|     object_property_add_child(object_get_root(), "machine", | ||||
|                               OBJECT(current_machine), &error_abort); | ||||
|     object_property_add_child(container_get(OBJECT(current_machine), | ||||
|                                             "/unattached"), | ||||
|                               "sysbus", OBJECT(sysbus_get_default()), | ||||
|                               NULL); | ||||
| 
 | ||||
|     if (machine_class->minimum_page_bits) { | ||||
|         if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) { | ||||
| @ -4235,6 +4274,13 @@ int main(int argc, char **argv, char **envp) | ||||
|         exit(0); | ||||
|     } | ||||
| 
 | ||||
|     /*
 | ||||
|      * Note: we need to create block backends before | ||||
|      * machine_set_property(), so machine properties can refer to | ||||
|      * them. | ||||
|      */ | ||||
|     configure_blockdev(&bdo_queue, machine_class, snapshot); | ||||
| 
 | ||||
|     machine_opts = qemu_get_machine_opts(); | ||||
|     qemu_opt_foreach(machine_opts, machine_set_property, current_machine, | ||||
|                      &error_fatal); | ||||
| @ -4249,12 +4295,6 @@ int main(int argc, char **argv, char **envp) | ||||
|                      machine_class->name, machine_class->deprecation_reason); | ||||
|     } | ||||
| 
 | ||||
|     /*
 | ||||
|      * Register all the global properties, including accel properties, | ||||
|      * machine properties, and user-specified ones. | ||||
|      */ | ||||
|     register_global_properties(current_machine); | ||||
| 
 | ||||
|     /*
 | ||||
|      * Migration object can only be created after global properties | ||||
|      * are applied correctly. | ||||
| @ -4367,39 +4407,6 @@ int main(int argc, char **argv, char **envp) | ||||
|     ram_mig_init(); | ||||
|     dirty_bitmap_mig_init(); | ||||
| 
 | ||||
|     /* If the currently selected machine wishes to override the units-per-bus
 | ||||
|      * property of its default HBA interface type, do so now. */ | ||||
|     if (machine_class->units_per_default_bus) { | ||||
|         override_max_devs(machine_class->block_default_type, | ||||
|                           machine_class->units_per_default_bus); | ||||
|     } | ||||
| 
 | ||||
|     /* open the virtual block devices */ | ||||
|     while (!QSIMPLEQ_EMPTY(&bdo_queue)) { | ||||
|         BlockdevOptions_queue *bdo = QSIMPLEQ_FIRST(&bdo_queue); | ||||
| 
 | ||||
|         QSIMPLEQ_REMOVE_HEAD(&bdo_queue, entry); | ||||
|         loc_push_restore(&bdo->loc); | ||||
|         qmp_blockdev_add(bdo->bdo, &error_fatal); | ||||
|         loc_pop(&bdo->loc); | ||||
|         qapi_free_BlockdevOptions(bdo->bdo); | ||||
|         g_free(bdo); | ||||
|     } | ||||
|     if (snapshot || replay_mode != REPLAY_MODE_NONE) { | ||||
|         qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, | ||||
|                           NULL, NULL); | ||||
|     } | ||||
|     if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, | ||||
|                           &machine_class->block_default_type, &error_fatal)) { | ||||
|         /* We printed help */ | ||||
|         exit(0); | ||||
|     } | ||||
| 
 | ||||
|     default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2, | ||||
|                   CDROM_OPTS); | ||||
|     default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS); | ||||
|     default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS); | ||||
| 
 | ||||
|     qemu_opts_foreach(qemu_find_opts("mon"), | ||||
|                       mon_init_func, NULL, &error_fatal); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Peter Maydell
						Peter Maydell