1. 02 2月, 2016 2 次提交
    • L
      nvme: generate OpenFirmware device path in the "bootorder" fw_cfg file · a907ec52
      Laszlo Ersek 提交于
      Background on QEMU boot indices
      -------------------------------
      
      Normally, the "bootindex" property is configured for bootable devices
      with:
      
        DEVICE_instance_init()
          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:
      
        device_set_bootindex()
          /* parse boot index */
          visit_type_int32()
      
          /* verify unicity */
          check_boot_index()
      
          /* store parsed boot index */
          ...
      
          /* insert device path to boot order */
          add_boot_device_path()
      
      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 33739c71,
      
        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
      device_add_bootindex_property().
      
      Crucially, nvme_set_bootindex() avoided the final add_boot_device_path()
      call. This fact is spelled out in the message of commit 33739c71, 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@i0cf8/pci8086,5845@6[,1]
             ^     ^            ^  ^
             |     |            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
      
        /namespace@1,0
                   ^ ^
                   | 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
      
        /pci@i0cf8/pci8086,5845@6[,1]/namespace@1,0
      
      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:
      
        PciRoot(0x0)/Pci(0x6,0x1)/NVMe(0x1,00-00-00-00-00-00-00-00)
                ^        ^   ^    ^    ^   ^
                |        |   |    |    |   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 <keith.busch@intel.com> (supporter:nvme)
      Cc: Kevin Wolf <kwolf@redhat.com> (supporter:Block layer core)
      Cc: qemu-block@nongnu.org (open list:nvme)
      Cc: Gonglei <arei.gonglei@huawei.com>
      Cc: Vladislav Vovchenko <vladislav.vovchenko@sk.com>
      Cc: Feng Tian <feng.tian@intel.com>
      Cc: Gerd Hoffmann <kraxel@redhat.com>
      Cc: Kevin O'Connor <kevin@koconnor.net>
      Signed-off-by: NLaszlo Ersek <lersek@redhat.com>
      Acked-by: NGonglei <arei.gonglei@huawei.com>
      Acked-by: NKeith Busch <keith.busch@intel.com>
      Tested-by: NVladislav Vovchenko <vladislav.vovchenko@sk.com>
      Message-id: 1453850483-27511-1-git-send-email-lersek@redhat.com
      Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
      a907ec52
    • P
      Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.6-20160201' into staging · 10ae9d76
      Peter Maydell 提交于
      ppc patch queue for 2016-02-01
      
      Currently accumulated patches for target-ppc, pseries machine type and
      related devices.
        * Cleanup of error handling code in spapr
        * A number of fixes for Macintosh devices for the benefit of MacOS 9 and X
        * Remove some abuses of the RTAS memory access functions in spapr
        * Fixes for the gdbstub (and monitor debug) for VMX and VSX extensions.
        * Fix pseries machine hotplug memory under TCG
        * Clean up and extend handling of multiple page sizes with 64-bit hash MMUs
        * Fix to the TCG implementation of mcrfs
      
      # gpg: Signature made Mon 01 Feb 2016 02:28:34 GMT using RSA key ID 20D9B392
      # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
      # gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
      # gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
      # gpg: WARNING: This key is not certified with sufficiently trusted signatures!
      # gpg:          It is not certain that the signature belongs to the owner.
      # Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392
      
      * remotes/dgibson/tags/ppc-for-2.6-20160201: (40 commits)
        target-ppc: mcrfs should always update FEX/VX and only clear exception bits
        target-ppc: Make every FPSCR_ macro have a corresponding FP_ macro
        target-ppc: Allow more page sizes for POWER7 & POWER8 in TCG
        target-ppc: Helper to determine page size information from hpte alone
        target-ppc: Add new TLB invalidate by HPTE call for hash64 MMUs
        target-ppc: Split 44x tlbiva from ppc_tlb_invalidate_one()
        target-ppc: Remove unused mmu models from ppc_tlb_invalidate_one
        target-ppc: Use actual page size encodings from HPTE
        target-ppc: Rework SLB page size lookup
        target-ppc: Rework ppc_store_slb
        target-ppc: Convert mmu-hash{32,64}.[ch] from CPUPPCState to PowerPCCPU
        target-ppc: Remove unused kvmppc_read_segment_page_sizes() stub
        uninorth.c: add support for UniNorth kMacRISCPCIAddressSelect (0x48) register
        cuda.c: return error for unknown commands
        pseries: Allow TCG h_enter to work with hotplugged memory
        target-ppc: gdbstub: Add VSX support
        target-ppc: gdbstub: fix spe registers for little-endian guests
        target-ppc: gdbstub: fix altivec registers for little-endian guests
        target-ppc: gdbstub: introduce avr_need_swap()
        target-ppc: gdbstub: fix float registers for little-endian guests
        ...
      Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
      10ae9d76
  2. 01 2月, 2016 1 次提交
    • J
      target-ppc: mcrfs should always update FEX/VX and only clear exception bits · d1277156
      James Clarke 提交于
      Here is the description of the mcrfs instruction from the PowerPC Architecture
      Book, Version 2.02, Book I: PowerPC User Instruction Set Architecture
      (http://www.ibm.com/developerworks/systems/library/es-archguide-v2.html), found
      on page 120:
      
          The contents of FPSCR field BFA are copied to Condition Register field BF.
          All exception bits copied are set to 0 in the FPSCR. If the FX bit is
          copied, it is set to 0 in the FPSCR.
      
          Special Registers Altered:
              CR field BF
              FX OX                        (if BFA=0)
              UX ZX XX VXSNAN              (if BFA=1)
              VXISI VXIDI VXZDZ VXIMZ      (if BFA=2)
              VXVC                         (if BFA=3)
              VXSOFT VXSQRT VXCVI          (if BFA=5)
      
      However, currently every bit in FPSCR field BFA is set to 0, including ones not
      on that list.
      
      This can be seen in the following simple C program:
      
          #include <fenv.h>
          #include <stdio.h>
      
          int main(int argc, char **argv) {
              int ret;
              ret = fegetround();
              printf("Current rounding: %d\n", ret);
              ret = fesetround(FE_UPWARD);
              printf("Setting to FE_UPWARD (%d): %d\n", FE_UPWARD, ret);
              ret = fegetround();
              printf("Current rounding: %d\n", ret);
              ret = fegetround();
              printf("Current rounding: %d\n", ret);
              return 0;
          }
      
      which gave the output (before this commit):
      
          Current rounding: 0
          Setting to FE_UPWARD (2): 0
          Current rounding: 2
          Current rounding: 0
      
      instead of (after this commit):
      
          Current rounding: 0
          Setting to FE_UPWARD (2): 0
          Current rounding: 2
          Current rounding: 2
      
      The relevant disassembly is in fegetround(), which, on my system, is:
      
          __GI___fegetround:
          <+0>:   mcrfs  cr7, cr7
          <+4>:   mfcr   r3
          <+8>:   clrldi r3, r3, 62
          <+12>:  blr
      
      What happens is that, the first time fegetround() is called, FPSCR field 7 is
      retrieved. However, because of the bug in mcrfs, the entirety of field 7 is set
      to 0, which includes the rounding mode.
      
      There are other issues this will fix, such as condition flags not persisting
      when they should if read, and if you were to read a specific field with some
      exception bits set, but no others were set in the entire register, then the
      bits would be cleared correctly, but FEX/VX would not be updated to 0 as they
      should be.
      Signed-off-by: NJames Clarke <jrtc27@jrtc27.com>
      Signed-off-by: NDavid Gibson <david@gibson.dropbear.id.au>
      d1277156
  3. 30 1月, 2016 37 次提交