qemu/hw
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
..
9pfs trace-events: Fix attribution of trace points to source 2019-03-22 16:18:07 +00:00
acpi acpi: verify file entries in bios_linker_loader_add_pointer() 2019-04-02 11:49:14 -04:00
adc kconfig: introduce kconfig files 2019-03-07 21:45:53 +01:00
alpha * Kconfig improvements (msi_nonbroken, imply for default PCI devices) 2019-03-28 09:18:53 +00:00
arm hw/arm/virt: Support firmware configuration with -blockdev 2019-05-07 12:55:02 +01:00
audio Revert "audio: fix pc speaker init" 2019-04-01 08:53:40 +02:00
block pflash_cfi01: New pflash_cfi01_legacy_drive() 2019-05-07 12:55:02 +01:00
bt kconfig: introduce kconfig files 2019-03-07 21:45:53 +01:00
char * Kconfig improvements (msi_nonbroken, imply for default PCI devices) 2019-03-28 09:18:53 +00:00
core hw: add compat machines for 4.1 2019-04-25 14:16:41 -03:00
cpu kconfig: introduce kconfig files 2019-03-07 21:45:53 +01:00
cris cris-softmmu.mak: express dependencies with Kconfig 2019-03-07 21:46:19 +01:00
display hw/devices: Move Blizzard declarations into a new header 2019-04-29 17:57:21 +01:00
dma hw/dma: Compile the bcm2835_dma device as common object 2019-04-29 17:36:03 +01:00
gpio Pull request 2019-03-25 17:01:10 +00:00
hppa * Kconfig improvements (msi_nonbroken, imply for default PCI devices) 2019-03-28 09:18:53 +00:00
hyperv hyperv: express dependencies with kconfig 2019-03-07 21:45:53 +01:00
i2c trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
i386 pflash_cfi01: New pflash_cfi01_legacy_drive() 2019-05-07 12:55:02 +01:00
ide trace-events: Fix attribution of trace points to source 2019-03-22 16:18:07 +00:00
input hw/devices: Move TI touchscreen declarations into a new header 2019-04-29 17:57:21 +01:00
intc target/arm: New function armv7m_nvic_set_pending_lazyfp() 2019-04-29 17:36:02 +01:00
ipack build: convert pci.mak to Kconfig 2019-03-07 21:45:53 +01:00
ipmi ipmi: express dependencies with kconfig 2019-03-07 21:45:53 +01:00
isa * Kconfig improvements (msi_nonbroken, imply for default PCI devices) 2019-03-28 09:18:53 +00:00
lm32 pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00
m68k m68k-softmmu.mak: express dependencies with Kconfig 2019-03-07 21:46:19 +01:00
mem trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
microblaze pflash: Clean up after commit 368a354f02, part 2 2019-03-11 22:53:44 +01:00
mips mips/boston: Report errors with error_report(), not error_printf() 2019-04-17 21:21:49 +02:00
misc hw/devices: Move CBus declarations into a new header 2019-04-29 17:57:21 +01:00
moxie moxie-softmmu.mak: express dependencies with Kconfig 2019-03-07 21:46:19 +01:00
net hw/devices: Move SMSC 91C111 declaration into a new header 2019-04-29 17:57:21 +01:00
nios2 Add generic Nios II board. 2019-04-29 16:09:51 +01:00
nvram trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
openrisc or1k-softmmu.mak: express dependencies with Kconfig 2019-03-07 21:46:19 +01:00
pci spapr: Drop duplicate PCI swizzle code 2019-04-26 11:37:57 +10:00
pci-bridge kconfig: add dependencies on CONFIG_MSI_NONBROKEN 2019-03-18 09:39:57 +01:00
pci-host hw/pci-host: Use object_initialize_child for correct reference counting 2019-05-02 16:56:33 +02:00
pcmcia kconfig: introduce kconfig files 2019-03-07 21:45:53 +01:00
ppc ppc patch queue 2019-04-26 2019-04-27 21:34:46 +01:00
rdma * Kconfig improvements (msi_nonbroken, imply for default PCI devices) 2019-03-28 09:18:53 +00:00
riscv riscv: plic: Log guest errors 2019-04-04 16:36:21 -07:00
s390x Machine queue, 2019-04-25 2019-04-26 14:30:18 +01:00
scsi trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
sd trace-events: Delete unused trace points 2019-03-22 16:18:07 +00:00
sh4 hw/usb/hcd-ohci: Move PCI-related code into a separate file 2019-05-02 08:42:17 +02:00
smbios kconfig: introduce kconfig files 2019-03-07 21:45:53 +01:00
sparc trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
sparc64 * Kconfig improvements (msi_nonbroken, imply for default PCI devices) 2019-03-28 09:18:53 +00:00
ssi hw/ssi/xilinx_spips: Avoid variable length array 2019-04-29 17:35:57 +01:00
timer hpet: Report warnings with warn_report(), not error_printf() 2019-04-17 21:21:49 +02:00
tpm trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
tricore - qtest fixes 2019-03-08 16:31:34 +00:00
unicore32 unicore32-softmmu.mak: express dependencies with Kconfig 2019-03-07 21:46:19 +01:00
usb hw/usb: avoid format truncation warning when formatting port name 2019-05-03 08:56:58 +02:00
vfio ppc patch queue 2019-04-26 2019-04-27 21:34:46 +01:00
virtio trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
watchdog trace-events: Fix attribution of trace points to source 2019-03-22 16:18:07 +00:00
xen trace-events: Shorten file names in comments 2019-03-22 16:18:07 +00:00
xenpv xen: Replace few mentions of xend by libxl 2019-01-14 13:45:40 +00:00
xtensa hw: Use PFLASH_CFI0{1,2} and TYPE_PFLASH_CFI0{1,2} 2019-03-11 22:53:44 +01:00
Kconfig kconfig: add dependencies on CONFIG_MSI_NONBROKEN 2019-03-18 09:39:57 +01:00
Makefile.objs i2c: express dependencies with Kconfig 2019-03-07 21:45:53 +01:00