summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/aubdump.c96
1 files changed, 95 insertions, 1 deletions
diff --git a/tools/aubdump.c b/tools/aubdump.c
index ed181a50..fbd8bf8f 100644
--- a/tools/aubdump.c
+++ b/tools/aubdump.c
@@ -383,7 +383,7 @@ register_write_out(uint32_t addr, uint32_t value)
}
static void
-gen8_map_ggtt_range(uint64_t start, uint64_t end)
+gen8_emit_ggtt_pte_for_range(uint64_t start, uint64_t end)
{
uint64_t entry_addr;
uint64_t page_num;
@@ -410,6 +410,100 @@ gen8_map_ggtt_range(uint64_t start, uint64_t end)
} while (entry_addr < end);
}
+/**
+ * Sets bits `start` through `end` - 1 in the bitmap array.
+ */
+static void
+set_bitmap_range(uint32_t *bitmap, uint32_t start, uint32_t end)
+{
+ uint32_t pos = start;
+ while (pos < end) {
+ const uint32_t bit = 1 << (pos & 0x1f);
+ if (bit == 1 && (end - pos) > 32) {
+ bitmap[pos >> 5] = 0xffffffff;
+ pos += 32;
+ } else {
+ bitmap[pos >> 5] |= bit;
+ pos++;
+ }
+ }
+}
+
+/**
+ * Finds the next `set` (or clear) bit in the bitmap array.
+ *
+ * The search starts at `*start` and only checks until `end` - 1.
+ *
+ * If found, returns true, and the found bit index in `*start`.
+ */
+static bool
+find_bitmap_bit(uint32_t *bitmap, bool set, uint32_t *start, uint32_t end)
+{
+ uint32_t pos = *start;
+ const uint32_t neg_dw = set ? 0 : -1;
+ while (pos < end) {
+ const uint32_t dw = bitmap[pos >> 5];
+ const uint32_t bit = 1 << (pos & 0x1f);
+ if (!!(dw & bit) == set) {
+ *start = pos;
+ return true;
+ } else if (bit == 1 && dw == neg_dw)
+ pos += 32;
+ else
+ pos++;
+ }
+ return false;
+}
+
+/**
+ * Finds a range of clear bits within the bitmap array.
+ *
+ * The search starts at `*start` and only checks until `*end` - 1.
+ *
+ * If found, returns true, and `*start` and `*end` are set for the
+ * range of clear bits.
+ */
+static bool
+find_bitmap_clear_bit_range(uint32_t *bitmap, uint32_t *start, uint32_t *end)
+{
+ if (find_bitmap_bit(bitmap, false, start, *end)) {
+ uint32_t found_end = *start;
+ if (find_bitmap_bit(bitmap, true, &found_end, *end))
+ *end = found_end;
+ return true;
+ }
+ return false;
+}
+
+static void
+gen8_map_ggtt_range(uint64_t start, uint64_t end)
+{
+ uint32_t pos1, pos2, end_pos;
+ static uint32_t *bitmap = NULL;
+ if (bitmap == NULL) {
+ /* 4GiB (32-bits) of 4KiB pages (12-bits) in dwords (5-bits) */
+ bitmap = calloc(1 << (32 - 12 - 5), sizeof(*bitmap));
+ if (bitmap == NULL)
+ return;
+ }
+
+ pos1 = start >> 12;
+ end_pos = (end + 4096 - 1) >> 12;
+ while (pos1 < end_pos) {
+ pos2 = end_pos;
+ if (!find_bitmap_clear_bit_range(bitmap, &pos1, &pos2))
+ break;
+
+ if (verbose)
+ printf("MAPPING 0x%08lx-0x%08lx\n",
+ (uint64_t)pos1 << 12, (uint64_t)pos2 << 12);
+ gen8_emit_ggtt_pte_for_range((uint64_t)pos1 << 12,
+ (uint64_t)pos2 << 12);
+ set_bitmap_range(bitmap, (uint64_t)pos1, (uint64_t)pos2);
+ pos1 = pos2;
+ }
+}
+
static void
gen10_write_header(void)
{