[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-commits] [qemu/qemu] a907ec: nvme: generate OpenFirmware device pa

From: GitHub
Subject: [Qemu-commits] [qemu/qemu] a907ec: nvme: generate OpenFirmware device path in the "bo...
Date: Tue, 02 Feb 2016 07:00:04 -0800

  Branch: refs/heads/master
  Home:   https://github.com/qemu/qemu
  Commit: a907ec52cc1aefc820768b6e341b56f8f3caaca7
  Author: Laszlo Ersek <address@hidden>
  Date:   2016-02-02 (Tue, 02 Feb 2016)

  Changed paths:
    M hw/block/nvme.c

  Log Message:
  nvme: generate OpenFirmware device path in the "bootorder" fw_cfg file

Background on QEMU boot indices

Normally, the "bootindex" property is configured for bootable devices

    device_add_bootindex_property(..., "bootindex", ...)
      object_property_add(..., device_get_bootindex,
                    device_set_bootindex, ...)

and when the bootindex is set on the QEMU command line, with

  -device DEVICE,...,bootindex=N

the setter that was configured above is invoked:

    /* parse boot index */

    /* verify unicity */

    /* store parsed boot index */

    /* insert device path to boot order */

In the last step, add_boot_device_path() ensures that an OpenFirmware
device path will show up in the "bootorder" fw_cfg file, at a position
corresponding to the device's boot index. Thus guest firmware (SeaBIOS and
OVMF) can try to boot off the device with the right priority.

NVMe boot index

In QEMU commit 33739c712982,

  nvma: ide: add bootindex to qom property

the following generic setters / getters:
- device_set_bootindex()
- device_get_bootindex()

were open-coded for NVMe, under the names
- nvme_set_bootindex()
- nvme_get_bootindex()

Plus nvme_instance_init() was added to configure the "bootindex" property
manually, designating the open-coded getter & setter, rather than calling

Crucially, nvme_set_bootindex() avoided the final add_boot_device_path()
call. This fact is spelled out in the message of commit 33739c712982, and
it was presumably the entire reason for all of the code duplication.

Now, Vladislav filed an RFE for OVMF
<https://github.com/tianocore/edk2/issues/48>; OVMF should boot off NVMe
devices. It is simple to build edk2's existent NvmExpressDxe driver into
OVMF, but the boot order matching logic in OVMF can only handle NVMe if
the "bootorder" fw_cfg file includes such devices.

Therefore this patch converts the NVMe device model to
device_set_bootindex() all the way.

Device paths

device_set_bootindex() accepts an optional parameter called "suffix". When
present, it is expected to take the form of an OpenFirmware device path
node, and it gets appended as last node to the otherwise auto-generated
OFW path.

For NVMe, the auto-generated part is

       ^     ^            ^  ^
       |     |            PCI slot and (present when nonzero)
       |     |            function of the NVMe controller, both hex
       |     "driver name" component, built from PCI vendor & device IDs
       PCI root at system bus port, PIO

to which here we append the suffix

       ^ ^
       | big endian (MSB at lowest address) numeric interpretation
       | of the 64-bit IEEE Extended Unique Identifier, aka EUI-64,
       | hex
       32-bit NVMe namespace identifier, aka NSID, hex

resulting in the OFW device path


The reason for including the NSID and the EUI-64 is that an NVMe device
can in theory produce several different namespaces (distinguished by
NSID). Additionally, each of those may (optionally) have an EUI-64 value.

For now, QEMU only provides namespace 1.

Furthermore, QEMU doesn't even represent the EUI-64 as a standalone field;
it is embedded (and left unused) inside the "NvmeIdNs.res30" array, at the
last eight bytes. (Which is fine, since EUI-64 can be left zero-filled if
unsupported by the device.)

Based on the above, we set the "unit address" part of the last
("namespace") node to fixed "1,0".

OVMF will then map the above OFW device path to the following UEFI device
path fragment, for boot order processing:

    ^        ^   ^    ^    ^   ^
    |        |   |    |    |   octets of the EUI-64 in address order
    |        |   |    |    NSID
    |        |   |    NVMe namespace messaging device path node
    |        PCI slot and function
    PCI root bridge

Cc: Keith Busch <address@hidden> (supporter:nvme)
Cc: Kevin Wolf <address@hidden> (supporter:Block layer core)
Cc: address@hidden (open list:nvme)
Cc: Gonglei <address@hidden>
Cc: Vladislav Vovchenko <address@hidden>
Cc: Feng Tian <address@hidden>
Cc: Gerd Hoffmann <address@hidden>
Cc: Kevin O'Connor <address@hidden>
Signed-off-by: Laszlo Ersek <address@hidden>
Acked-by: Gonglei <address@hidden>
Acked-by: Keith Busch <address@hidden>
Tested-by: Vladislav Vovchenko <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>

  Commit: dce0238c745b698e8464e59ec73354219f750f34
  Author: Peter Maydell <address@hidden>
  Date:   2016-02-02 (Tue, 02 Feb 2016)

  Changed paths:
    M hw/block/nvme.c

  Log Message:
  Merge remote-tracking branch 'remotes/kraxel/tags/pull-fwcfg-20160202-1' into 

nvme: generate OpenFirmware device path in the "bootorder" fw_cfg file

# gpg: Signature made Tue 02 Feb 2016 12:54:04 GMT using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <address@hidden>"
# gpg:                 aka "Gerd Hoffmann <address@hidden>"
# gpg:                 aka "Gerd Hoffmann (private) <address@hidden>"

* remotes/kraxel/tags/pull-fwcfg-20160202-1:
  nvme: generate OpenFirmware device path in the "bootorder" fw_cfg file

Signed-off-by: Peter Maydell <address@hidden>

Compare: https://github.com/qemu/qemu/compare/074d1ccb4229...dce0238c745b

reply via email to

[Prev in Thread] Current Thread [Next in Thread]