summaryrefslogtreecommitdiff
path: root/src/base/addr_range.hh
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2019-10-07 16:11:48 +0100
committerAndreas Sandberg <andreas.sandberg@arm.com>2019-10-16 16:11:08 +0000
commite04e976e22be76e13eacd45b33f71eb85cefd81e (patch)
tree2b111fef8e80dc3249ccf73cd68e0f966cd8d2c3 /src/base/addr_range.hh
parent2111c9960078e0d61bc1b6a1788b0d9acc13e97b (diff)
downloadgem5-e04e976e22be76e13eacd45b33f71eb85cefd81e.tar.xz
base: Add addIntlvBits to AddrRange
This method performs the opposite operation of removeIntlvBits and can be used to transform a channel-local address to a global PA. Change-Id: I2fab587d7c094597e52422305775ac7f31efba34 Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21599 Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/base/addr_range.hh')
-rw-r--r--src/base/addr_range.hh38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/base/addr_range.hh b/src/base/addr_range.hh
index cda6ccfb2..84a3d4de5 100644
--- a/src/base/addr_range.hh
+++ b/src/base/addr_range.hh
@@ -471,6 +471,44 @@ class AddrRange
}
/**
+ * This method adds the interleaving bits removed by
+ * removeIntlvBits.
+ */
+ inline Addr addIntlvBits(Addr a) const
+ {
+ // Get the LSB set from each mask
+ int masks_lsb[masks.size()];
+ for (int i = 0; i < masks.size(); i++) {
+ masks_lsb[i] = ctz64(masks[i]);
+ }
+
+ // Add bits one-by-one from the LSB side.
+ std::sort(masks_lsb, masks_lsb + masks.size());
+ for (int i = 0; i < masks.size(); i++) {
+ const int intlv_bit = masks_lsb[i];
+ if (intlv_bit > 0) {
+ // on every iteration we add one bit from the input
+ // address, and therefore the lowest invtl_bit has
+ // also shifted to the left by i positions.
+ a = insertBits(a << 1, intlv_bit + i - 1, 0, a);
+ } else {
+ a <<= 1;
+ }
+ }
+
+ for (int i = 0; i < masks.size(); i++) {
+ const int lsb = ctz64(masks[i]);
+ const Addr intlv_bit = bits(intlvMatch, i);
+ // Calculate the mask ignoring the LSB
+ const Addr masked = a & masks[i] & ~(1 << lsb);
+ // Set the LSB of the mask to whatever satisfies the selector bit
+ a = insertBits(a, lsb, intlv_bit ^ popCount(masked));
+ }
+
+ return a;
+ }
+
+ /**
* Determine the offset of an address within the range.
*
* This function returns the offset of the given address from the