summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base/bitfield.hh37
-rw-r--r--src/dev/virtio/pci.cc10
2 files changed, 45 insertions, 2 deletions
diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh
index 64f192f6d..885b42288 100644
--- a/src/base/bitfield.hh
+++ b/src/base/bitfield.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -211,4 +223,29 @@ popCount(uint64_t val) {
return (val * sum) >> 56; // horizontal sum
#endif // defined(__GNUC__) || (defined(__clang__) && __has_builtin(__builtin_popcountl))
}
+
+/**
+ * Align to the next highest power of two.
+ *
+ * The number passed in is aligned to the next highest power of two,
+ * if it is not already a power of two. Please note that if 0 is
+ * passed in, 0 is returned.
+ *
+ * This code has been modified from the following:
+ * http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
+ */
+inline uint64_t alignToPowerOfTwo(uint64_t val)
+{
+ val--;
+ val |= val >> 1;
+ val |= val >> 2;
+ val |= val >> 4;
+ val |= val >> 8;
+ val |= val >> 16;
+ val |= val >> 32;
+ val++;
+
+ return val;
+};
+
#endif // __BASE_BITFIELD_HH__
diff --git a/src/dev/virtio/pci.cc b/src/dev/virtio/pci.cc
index d8ec4f5f8..783b43e65 100644
--- a/src/dev/virtio/pci.cc
+++ b/src/dev/virtio/pci.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 ARM Limited
+ * Copyright (c) 2014, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -39,6 +39,7 @@
#include "dev/virtio/pci.hh"
+#include "base/bitfield.hh"
#include "debug/VIOIface.hh"
#include "mem/packet_access.hh"
#include "params/PciVirtIO.hh"
@@ -49,7 +50,12 @@ PciVirtIO::PciVirtIO(const Params *params)
{
// Override the subsystem ID with the device ID from VirtIO
config.subsystemID = htole(vio.deviceId);
- BARSize[0] = BAR0_SIZE_BASE + vio.configSize;
+
+ // The kernel driver expects the BAR size to be an exact power of
+ // two. Nothing else is supported. Therefore, we need to force
+ // that alignment here. We do not touch vio.configSize as this is
+ // used to check accesses later on.
+ BARSize[0] = alignToPowerOfTwo(BAR0_SIZE_BASE + vio.configSize);
vio.registerKickCallback(&callbackKick);
}