qemu/hw/arm
Markus Armbruster e0561e60f1 hw/arm/virt: Support firmware configuration with -blockdev
The ARM virt machines put firmware in flash memory.  To configure it,
you use -drive if=pflash,unit=0,... and optionally -drive
if=pflash,unit=1,...

Why two -drive?  This permits setting up one part of the flash memory
read-only, and the other part read/write.  It also makes upgrading
firmware on the host easier.  Below the hood, we get two separate
flash devices, because we were too lazy to improve our flash device
models to support sector protection.

The problem at hand is to do the same with -blockdev somehow, as one
more step towards deprecating -drive.

We recently solved this problem for x86 PC machines, in commit
ebc29e1bea.  See the commit message for design rationale.

This commit solves it for ARM virt basically the same way: new machine
properties pflash0, pflash1 forward to the onboard flash devices'
properties.  Requires creating the onboard devices in the
.instance_init() method virt_instance_init().  The existing code to
pick up drives defined with -drive if=pflash is replaced by code to
desugar into the machine properties.

There are a few behavioral differences, though:

* The flash devices are always present (x86: only present if
  configured)

* Flash base addresses and sizes are fixed (x86: sizes depend on
  images, mapped back to back below a fixed address)

* -bios configures contents of first pflash (x86: -bios configures ROM
   contents)

* -bios is rejected when first pflash is also configured with -machine
   pflash0=... (x86: bios is silently ignored then)

* -machine pflash1=... does not require -machine pflash0=... (x86: it
   does).

The actual code is a bit simpler than for x86 mostly due to the first
two differences.

Before the patch, all the action is in create_flash(), called from the
machine's .init() method machvirt_init():

    main()
        machine_run_board_init()
            machvirt_init()
                create_flash()
                    create_one_flash() for flash[0]
                        create
                        configure
                            includes obeying -drive if=pflash,unit=0
                        realize
                        map
                        fall back to -bios
                    create_one_flash() for flash[1]
                        create
                        configure
                            includes obeying -drive if=pflash,unit=1
                        realize
                        map
                    update FDT

To make the machine properties work, we need to move device creation
to its .instance_init() method virt_instance_init().

Another complication is machvirt_init()'s computation of
@firmware_loaded: it predicts what create_flash() will do.  Instead of
predicting what create_flash()'s replacement virt_firmware_init() will
do, I decided to have virt_firmware_init() return what it did.
Requires calling it a bit earlier.

Resulting call tree:

    main()
        current_machine = object_new()
            ...
                virt_instance_init()
                    virt_flash_create()
                        virt_flash_create1() for flash[0]
                            create
                            configure: set defaults
                            become child of machine [NEW]
                            add machine prop pflash0 as alias for drive [NEW]
                        virt_flash_create1() for flash[1]
                            create
                            configure: set defaults
                            become child of machine [NEW]
                            add machine prop pflash1 as alias for drive [NEW]
        for all machine props from the command line: machine_set_property()
            ...
                property_set_alias() for machine props pflash0, pflash1
                    ...
                        set_drive() for cfi.pflash01 prop drive
                            this is how -machine pflash0=... etc set
        machine_run_board_init(current_machine);
            virt_firmware_init()
                pflash_cfi01_legacy_drive()
                    legacy -drive if=pflash,unit=0 and =1 [NEW]
                virt_flash_map()
                    virt_flash_map1() for flash[0]
                        configure: num-blocks
                        realize
                        map
                    virt_flash_map1() for flash[1]
                        configure: num-blocks
                        realize
                        map
                fall back to -bios
            virt_flash_fdt()
                update FDT

You have László to thank for making me explain this in detail.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 20190416091348.26075-4-armbru@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-07 12:55:02 +01:00
..
allwinner-a10.c hw: Remove unused 'hw/devices.h' include 2019-03-07 22:16:11 +01:00
armsse.c hw/arm/armsse: Unify init-svtor and cpuwait handling 2019-02-28 11:03:04 +00:00
armv7m.c elf: Add optional function ptr to load_elf() to parse ELF notes 2019-02-05 16:50:16 +01:00
aspeed.c hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string 2019-04-29 17:57:21 +01:00
aspeed_soc.c aspeed: add a max_ram_size property to the memory controller 2018-08-16 14:29:58 +01:00
bcm2835_peripherals.c Change references to serial_hds[] to serial_hd() 2018-04-26 13:57:00 +01:00
bcm2836.c hw/arm/bcm2836: Fix crash with device_add bcm2837 on unsupported machines 2018-07-17 13:12:49 +01:00
boot.c hw/arm/boot: introduce fdt_add_memory_node helper 2019-03-05 15:55:08 +00:00
collie.c pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00
cubieboard.c hw: Remove unused 'hw/devices.h' include 2019-03-07 22:16:11 +01:00
digic.c Change references to serial_hds[] to serial_hd() 2018-04-26 13:57:00 +01:00
digic_boards.c pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00
exynos4_boards.c hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string 2019-04-29 17:57:21 +01:00
exynos4210.c hw/arm/exynos4210: Zero memory allocated for Exynos4210State 2018-11-06 11:32:14 +00:00
fsl-imx6.c hw/arm/fsl-imx6: Fix introspection problems with the "fsl, imx6" device 2018-07-17 13:12:49 +01:00
fsl-imx6ul.c hw/arm/fsl-imx6ul: Connect VIRQ and VFIQ 2018-08-24 13:17:33 +01:00
fsl-imx7.c hw/arm/fsl-imx6ul: Connect VIRQ and VFIQ 2018-08-24 13:17:34 +01:00
fsl-imx25.c hw/arm/fsl-imx25: Fix introspection problem with the "fsl, imx25" device 2018-07-17 13:12:49 +01:00
fsl-imx31.c hw/arm/fsl-imx31: Fix introspection problem with the "fsl, imx31" device 2018-07-17 13:12:49 +01:00
gumstix.c hw/devices: Move SMSC 91C111 declaration into a new header 2019-04-29 17:57:21 +01:00
highbank.c hw: Remove unused 'hw/devices.h' include 2019-03-07 22:16:11 +01:00
imx25_pdk.c hw/arm: Set ignore_memory_transaction_failures for most ARM boards 2017-09-07 13:54:54 +01:00
integratorcp.c hw/devices: Move SMSC 91C111 declaration into a new header 2019-04-29 17:57:21 +01:00
Kconfig ptimer: express dependencies with Kconfig 2019-03-07 21:45:53 +01:00
kzm.c hw/devices: Move LAN9118 declarations into a new header 2019-04-29 17:57:21 +01:00
mainstone.c hw/devices: Move SMSC 91C111 declaration into a new header 2019-04-29 17:57:21 +01:00
Makefile.objs hw/arm/musca.c: Implement models of the Musca-A and -B1 boards 2019-02-21 18:17:47 +00:00
mcimx6ul-evk.c i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board 2018-08-16 14:05:28 +01:00
mcimx7d-sabre.c i.mx7d: Remove unused header files 2018-06-29 15:11:16 +01:00
microbit.c arm: Stub out NRF51 TWI magnetometer/accelerometer detection 2019-01-29 11:46:03 +00:00
mps2-tz.c hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string 2019-04-29 17:57:21 +01:00
mps2.c hw/devices: Move LAN9118 declarations into a new header 2019-04-29 17:57:21 +01:00
msf2-soc.c hw/arm: make bitbanded IO optional on ARMv7-M 2018-08-16 14:05:28 +01:00
msf2-som.c hw: Directly use "qemu/units.h" instead of "qemu/cutils.h" 2018-07-02 15:41:12 +02:00
musca.c hw/arm/musca: Wire up PL011 UARTs 2019-02-21 18:17:47 +00:00
musicpal.c pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00
netduino2.c arm: drop intermediate cpu_model -> cpu type parsing and use cpu type directly 2017-09-19 09:09:32 -03:00
nrf51_soc.c hw: Remove unused 'hw/devices.h' include 2019-03-07 22:16:11 +01:00
nseries.c hw/devices: Move TI touchscreen declarations into a new header 2019-04-29 17:57:21 +01:00
omap1.c hw/arm/omap1: Use qemu_log_mask(GUEST_ERROR) instead of fprintf 2018-06-26 17:50:40 +01:00
omap2.c audio: use qapi AudioFormat instead of audfmt_e 2019-03-11 10:29:26 +01:00
omap_sx1.c pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00
palm.c hw/devices: Move TI touchscreen declarations into a new header 2019-04-29 17:57:21 +01:00
pxa2xx.c i2c: have I2C receive operation return uint8_t 2019-02-27 21:06:08 -06:00
pxa2xx_gpio.c Replace all occurances of __FUNCTION__ with __func__ 2018-01-22 09:46:18 +01:00
pxa2xx_pic.c Replace all occurances of __FUNCTION__ with __func__ 2018-01-22 09:46:18 +01:00
raspi.c hw/arm/raspi: Don't bother setting default_cpu_type 2018-04-26 11:04:39 +01:00
realview.c hw/devices: Move SMSC 91C111 declaration into a new header 2019-04-29 17:57:21 +01:00
sabrelite.c hw/arm: Set ignore_memory_transaction_failures for most ARM boards 2017-09-07 13:54:54 +01:00
smmu-common.c hw/arm/smmuv3: Remove SMMUNotifierNode 2019-04-29 17:35:57 +01:00
smmu-internal.h hw/arm/smmu-common: VMSAv8-64 page table walk 2018-05-04 18:05:51 +01:00
smmuv3-internal.h hw/arm/smmuv3: fix eventq recording and IRQ triggerring 2018-09-25 15:13:24 +01:00
smmuv3.c hw/arm/smmuv3: Remove SMMUNotifierNode 2019-04-29 17:35:57 +01:00
spitz.c hw: Remove unused 'hw/devices.h' include 2019-03-07 22:16:11 +01:00
stellaris.c hw/devices: Move Gamepad declarations into a new header 2019-04-29 17:57:21 +01:00
stm32f205_soc.c hw/arm: make bitbanded IO optional on ARMv7-M 2018-08-16 14:05:28 +01:00
strongarm.c strongarm: mask off high[31:28] bits from dir and state registers 2018-11-02 14:03:33 +00:00
strongarm.h Move target-* CPU file into a target/ folder 2016-12-20 21:52:12 +01:00
sysbus-fdt.c hw/arm/sysbus-fdt: Only call match_fn callback if the type matches 2018-11-13 10:47:58 +00:00
tosa.c hw/devices: Move TC6393XB declarations into a new header 2019-04-29 17:57:21 +01:00
trace-events trace-events: Fix attribution of trace points to source 2019-03-22 16:18:07 +00:00
versatilepb.c hw/devices: Move SMSC 91C111 declaration into a new header 2019-04-29 17:57:21 +01:00
vexpress.c hw/devices: Move LAN9118 declarations into a new header 2019-04-29 17:57:21 +01:00
virt-acpi-build.c hw/arm/virt-acpi-build: use PCIE_MMCFG_BUS to retrieve end_bus_number 2019-03-15 11:12:29 +00:00
virt.c hw/arm/virt: Support firmware configuration with -blockdev 2019-05-07 12:55:02 +01:00
xilinx_zynq.c pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00
xlnx-versal-virt.c hw/arm: versal: Plug memory leaks 2019-01-07 15:23:46 +00:00
xlnx-versal.c hw/arm: versal: Add a model of Xilinx Versal SoC 2018-11-02 14:10:53 +00:00
xlnx-zcu102.c xlnx-zynqmp: Swap Cortex-R5 for Cortex-R5F 2018-06-22 13:28:38 +01:00
xlnx-zynqmp.c hw/arm/xlnx-zynqmp: Realize cluster after putting RPUs in it 2019-01-29 11:46:05 +00:00
z2.c pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00