summaryrefslogtreecommitdiff
path: root/tools/null_state_gen/intel_batchbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/null_state_gen/intel_batchbuffer.c')
-rw-r--r--tools/null_state_gen/intel_batchbuffer.c251
1 files changed, 177 insertions, 74 deletions
diff --git a/tools/null_state_gen/intel_batchbuffer.c b/tools/null_state_gen/intel_batchbuffer.c
index 62e052a3..2a0b3407 100644
--- a/tools/null_state_gen/intel_batchbuffer.c
+++ b/tools/null_state_gen/intel_batchbuffer.c
@@ -29,145 +29,248 @@
**************************************************************************/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
#include "intel_batchbuffer.h"
-int intel_batch_reset(struct intel_batchbuffer *batch,
- void *p,
- uint32_t size,
- uint32_t off)
+void bb_area_emit(struct bb_area *a, uint32_t dword, item_type type, const char *str)
{
- batch->err = -EINVAL;
- batch->base = batch->base_ptr = p;
- batch->state_base = batch->state_ptr = p;
+ struct bb_item *item;
+ assert(a != NULL);
+ assert(a->num_items < MAX_ITEMS);
+ item = &a->item[a->num_items];
- if (off >= size || ALIGN(off, 4) != off)
- return -EINVAL;
+ item->data = dword;
+ item->type = type;
+ strncpy(item->str, str, MAX_STRLEN);
+ item->str[MAX_STRLEN - 1] = 0;
- batch->size = size;
+ a->num_items++;
+}
- batch->state_base = batch->state_ptr = &batch->base[off];
+void bb_area_emit_offset(struct bb_area *a, unsigned offset, uint32_t dword, item_type type, const char *str)
+{
+ const unsigned i = offset / 4;
+ struct bb_item *item;
+ assert(a != NULL);
+ assert(a->num_items < MAX_ITEMS);
+ assert(i < a->num_items);
+ item = &a->item[i];
+
+ item->data = dword;
+ item->type = type;
+ strncpy(item->str, str, MAX_STRLEN);
+ item->str[MAX_STRLEN - 1] = 0;
+}
- batch->num_relocs = 0;
- batch->err = 0;
+static struct bb_item *bb_area_get(struct bb_area *a, unsigned i)
+{
+ assert (i < a->num_items);
+ return &a->item[i];
+}
- return batch->err;
+static unsigned bb_area_items(struct bb_area *a)
+{
+ return a->num_items;
}
-uint32_t intel_batch_state_used(struct intel_batchbuffer *batch)
+static unsigned long bb_area_used(struct bb_area *a)
{
- return batch->state_ptr - batch->state_base;
+ assert(a != NULL);
+ assert(a->num_items <= MAX_ITEMS);
+
+ return a->num_items * 4;
}
-uint32_t intel_batch_state_offset(struct intel_batchbuffer *batch)
+static unsigned long bb_area_room(struct bb_area *a)
{
- return batch->state_ptr - batch->base;
+ assert (a != NULL);
+ assert (a->num_items <= MAX_ITEMS);
+
+ return (MAX_ITEMS - a->num_items) * 4;
}
-void *intel_batch_state_alloc(struct intel_batchbuffer *batch,
- uint32_t size,
- uint32_t align)
+struct intel_batchbuffer *intel_batchbuffer_create(void)
{
- uint32_t cur;
- uint32_t offset;
+ struct intel_batchbuffer *batch;
- if (batch->err)
+ batch = calloc(1, sizeof(*batch));
+ if (batch == NULL)
return NULL;
- cur = intel_batch_state_offset(batch);
- offset = ALIGN(cur, align);
+ batch->cmds = calloc(1, sizeof(struct bb_area));
+ if (batch->cmds == NULL) {
+ free(batch);
+ return NULL;
+ }
- if (offset + size > batch->size) {
- batch->err = -ENOSPC;
+ batch->state = calloc(1, sizeof(struct bb_area));
+ if (batch->state == NULL) {
+ free(batch->cmds);
+ free(batch);
return NULL;
}
- batch->state_ptr = batch->base + offset + size;
+ batch->state_start_offset = -1;
+ batch->cmds_end_offset = -1;
- memset(batch->base + cur, 0, size);
+ return batch;
+}
- return batch->base + offset;
+static void bb_area_align(struct bb_area *a, unsigned align)
+{
+ if (align == 0)
+ return;
+
+ assert((align % 4) == 0);
+
+ while ((a->num_items * 4) % align != 0)
+ bb_area_emit(a, 0, PAD, "align pad");
}
-int intel_batch_offset(struct intel_batchbuffer *batch, const void *ptr)
+static int reloc_exists(struct intel_batchbuffer *batch, uint32_t offset)
{
- return (uint8_t *)ptr - batch->base;
+ int i;
+
+ for (i = 0; i < batch->cmds->num_items; i++)
+ if ((batch->cmds->item[i].type == RELOC ||
+ batch->cmds->item[i].type == RELOC_STATE) &&
+ i * 4 == offset)
+ return 1;
+
+ return 0;
}
-int intel_batch_state_copy(struct intel_batchbuffer *batch,
- const void *ptr,
- const uint32_t size,
- const uint32_t align)
+int intel_batch_is_reloc(struct intel_batchbuffer *batch, unsigned i)
{
- void * const p = intel_batch_state_alloc(batch, size, align);
+ return reloc_exists(batch, i * 4);
+}
- if (p == NULL)
- return -1;
+static void intel_batch_cmd_align(struct intel_batchbuffer *batch, unsigned align)
+{
+ bb_area_align(batch->cmds, align);
+}
- return intel_batch_offset(batch, memcpy(p, ptr, size));
+static void intel_batch_state_align(struct intel_batchbuffer *batch, unsigned align)
+{
+ bb_area_align(batch->state, align);
}
-uint32_t intel_batch_cmds_used(struct intel_batchbuffer *batch)
+unsigned intel_batch_num_cmds(struct intel_batchbuffer *batch)
{
- return batch->base_ptr - batch->base;
+ return bb_area_items(batch->cmds);
}
-uint32_t intel_batch_total_used(struct intel_batchbuffer *batch)
+static unsigned intel_batch_num_state(struct intel_batchbuffer *batch)
{
- return batch->state_ptr - batch->base;
+ return bb_area_items(batch->state);
}
-static uint32_t intel_batch_space(struct intel_batchbuffer *batch)
+struct bb_item *intel_batch_cmd_get(struct intel_batchbuffer *batch, unsigned i)
{
- return batch->state_base - batch->base_ptr;
+ return bb_area_get(batch->cmds, i);
}
-int intel_batch_emit_dword(struct intel_batchbuffer *batch, uint32_t dword)
+struct bb_item *intel_batch_state_get(struct intel_batchbuffer *batch, unsigned i)
{
- uint32_t offset;
+ return bb_area_get(batch->state, i);
+}
- if (batch->err)
- return -1;
+uint32_t intel_batch_state_offset(struct intel_batchbuffer *batch, unsigned align)
+{
+ intel_batch_state_align(batch, align);
+ return bb_area_used(batch->state);
+}
- if (intel_batch_space(batch) < 4) {
- batch->err = -ENOSPC;
- return -1;
- }
+uint32_t intel_batch_state_alloc(struct intel_batchbuffer *batch, unsigned bytes, unsigned align,
+ const char *str)
+{
+ unsigned offset;
+ unsigned dwords = bytes/4;
+ assert ((bytes % 4) == 0);
+ assert (bb_area_room(batch->state) >= bytes);
- offset = intel_batch_offset(batch, batch->base_ptr);
+ offset = intel_batch_state_offset(batch, align);
- *(uint32_t *) (batch->base_ptr) = dword;
- batch->base_ptr += 4;
+ while (dwords--)
+ bb_area_emit(batch->state, 0, UNINITIALIZED, str);
return offset;
}
-int intel_batch_emit_reloc(struct intel_batchbuffer *batch,
- const uint32_t delta)
+uint32_t intel_batch_state_copy(struct intel_batchbuffer *batch,
+ void *d, unsigned bytes,
+ unsigned align,
+ const char *str)
{
- uint32_t offset;
+ unsigned offset;
+ unsigned i;
+ unsigned dwords = bytes/4;
+ assert (d);
+ assert ((bytes % 4) == 0);
+ assert (bb_area_room(batch->state) >= bytes);
+
+ offset = intel_batch_state_offset(batch, align);
- if (batch->err)
- return -1;
+ for (i = 0; i < dwords; i++) {
+ char offsetinside[80];
+ sprintf(offsetinside, "%s: 0x%x", str, i * 4);
- if (delta >= batch->size) {
- batch->err = -EINVAL;
- return -1;
+ uint32_t *s = (uint32_t *)(uint8_t *)d + i;
+ bb_area_emit(batch->state, *s, STATE, offsetinside);
}
- offset = intel_batch_emit_dword(batch, delta);
+ return offset;
+}
+
+void intel_batch_relocate_state(struct intel_batchbuffer *batch)
+{
+ unsigned int i;
+
+ assert (batch->state_start_offset == -1);
- if (batch->err)
- return -1;
+ batch->cmds_end_offset = bb_area_used(batch->cmds) - 4;
- if (batch->num_relocs >= MAX_RELOCS) {
- batch->err = -ENOSPC;
- return -1;
+ /* Hardcoded, could track max align done also */
+ intel_batch_cmd_align(batch, 64);
+
+ batch->state_start_offset = bb_area_used(batch->cmds);
+
+ for (i = 0; i < bb_area_items(batch->state); i++) {
+ const struct bb_item *s = bb_area_get(batch->state, i);
+
+ bb_area_emit(batch->cmds, s->data, s->type, s->str);
}
- batch->relocs[batch->num_relocs++] = offset;
+ for (i = 0; i < bb_area_items(batch->cmds); i++) {
+ struct bb_item *s = bb_area_get(batch->cmds, i);
- return offset;
+ if (s->type == STATE_OFFSET || s->type == RELOC_STATE)
+ s->data += batch->state_start_offset;
+ }
+}
+
+const char *intel_batch_type_as_str(const struct bb_item *item)
+{
+ switch (item->type) {
+ case UNINITIALIZED:
+ return "UNINITIALIZED";
+ case CMD:
+ return "CMD";
+ case STATE:
+ return "STATE";
+ case PAD:
+ return "PAD";
+ case RELOC:
+ return "RELOC";
+ case RELOC_STATE:
+ return "RELOC_STATE";
+ case STATE_OFFSET:
+ return "STATE_OFFSET";
+ }
+
+ return "UNKNOWN";
}