intel/genxml: Add support for dword/bits in fields to rest of the code
Change code to temporarily support both the start/end old format and the dword/bits new format. Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Acked-by: José Roberto de Souza <jose.souza@intel.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36138>
This commit is contained in:
@@ -147,6 +147,11 @@ static void
|
||||
get_array_offset_count(const char **atts, uint32_t *offset, uint32_t *count,
|
||||
uint32_t *size, bool *variable)
|
||||
{
|
||||
bool is_old_format = false;
|
||||
bool is_new_format = false;
|
||||
|
||||
*offset = 0;
|
||||
|
||||
for (int i = 0; atts[i]; i += 2) {
|
||||
char *p;
|
||||
|
||||
@@ -155,12 +160,21 @@ get_array_offset_count(const char **atts, uint32_t *offset, uint32_t *count,
|
||||
if (*count == 0)
|
||||
*variable = true;
|
||||
} else if (strcmp(atts[i], "start") == 0) {
|
||||
assert(!is_new_format);
|
||||
is_old_format = true;
|
||||
*offset = strtoul(atts[i + 1], &p, 0);
|
||||
} else if (strcmp(atts[i], "dword") == 0) {
|
||||
assert(!is_old_format);
|
||||
is_new_format = true;
|
||||
*offset += 32 * strtoul(atts[i + 1], &p, 0);
|
||||
} else if (strcmp(atts[i], "offset_bits") == 0) {
|
||||
assert(!is_old_format);
|
||||
is_new_format = true;
|
||||
*offset += strtoul(atts[i + 1], &p, 0);
|
||||
} else if (strcmp(atts[i], "size") == 0) {
|
||||
*size = strtoul(atts[i + 1], &p, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static struct intel_group *
|
||||
@@ -336,6 +350,16 @@ create_field(struct parser_context *ctx, const char **atts)
|
||||
field = rzalloc(ctx->group, struct intel_field);
|
||||
field->parent = ctx->group;
|
||||
|
||||
bool is_old_format = false;
|
||||
bool is_new_format = false;
|
||||
|
||||
uint32_t dword = 0;
|
||||
uint32_t bits_start = 0;
|
||||
uint32_t bits_end = 0;
|
||||
|
||||
bool has_default = false;
|
||||
uint32_t default_value = 0;
|
||||
|
||||
for (int i = 0; atts[i]; i += 2) {
|
||||
char *p;
|
||||
|
||||
@@ -345,18 +369,41 @@ create_field(struct parser_context *ctx, const char **atts)
|
||||
field->parent->dword_length_field = field;
|
||||
}
|
||||
} else if (strcmp(atts[i], "start") == 0) {
|
||||
field->start = strtoul(atts[i + 1], &p, 0);
|
||||
assert(!is_new_format);
|
||||
is_old_format = true;
|
||||
bits_start = strtoul(atts[i + 1], &p, 0);
|
||||
} else if (strcmp(atts[i], "end") == 0) {
|
||||
field->end = strtoul(atts[i + 1], &p, 0);
|
||||
assert(!is_new_format);
|
||||
is_old_format = true;
|
||||
bits_end = strtoul(atts[i + 1], &p, 0);
|
||||
} else if (strcmp(atts[i], "dword") == 0) {
|
||||
assert(!is_old_format);
|
||||
is_new_format = true;
|
||||
dword = strtoul(atts[i + 1], &p, 10);
|
||||
} else if (strcmp(atts[i], "bits") == 0) {
|
||||
assert(!is_old_format);
|
||||
is_new_format = true;
|
||||
const char *bits_str = atts[i + 1];
|
||||
const char *colon = strchr(bits_str, ':');
|
||||
assert(colon);
|
||||
bits_end = strtoul(bits_str, NULL, 10);
|
||||
bits_start = strtoul(colon+1, NULL, 10);
|
||||
} else if (strcmp(atts[i], "type") == 0) {
|
||||
field->type = string_to_type(ctx, atts[i + 1]);
|
||||
} else if (strcmp(atts[i], "default") == 0 &&
|
||||
field->start >= 16 && field->end <= 31) {
|
||||
field->has_default = true;
|
||||
field->default_value = strtoul(atts[i + 1], &p, 0);
|
||||
} else if (strcmp(atts[i], "default") == 0) {
|
||||
has_default = true;
|
||||
default_value = strtoul(atts[i + 1], &p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
field->start = dword * 32 + bits_start;
|
||||
field->end = dword * 32 + bits_end;
|
||||
|
||||
if (has_default && field->start >= 16 && field->end <= 31) {
|
||||
field->has_default = true;
|
||||
field->default_value = default_value;
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,18 @@
|
||||
</group>
|
||||
</group>
|
||||
</struct>
|
||||
<struct name="TEST_DWORD_FIELDS" length="4">
|
||||
<field name="value_dw0" start="0" end="15" type="uint" />
|
||||
<field name="value_dw1" start="32" end="63" type="uint" />
|
||||
<field name="value_dw2" start="72" end="87" type="uint" />
|
||||
<field name="single_bit" start="101" end="101" type="bool" />
|
||||
</struct>
|
||||
<struct name="TEST_OFFSET_BITS" length="6">
|
||||
<field name="header" start="0" end="31" type="uint" />
|
||||
<group count="3" start="48" size="16">
|
||||
<field name="data" start="0" end="15" type="uint" />
|
||||
</group>
|
||||
</struct>
|
||||
<struct name="TEST_STRUCT" length="2">
|
||||
<field name="number1" start="0" end="15" type="uint" />
|
||||
<field name="number2" start="16" end="31" type="uint" />
|
||||
|
||||
@@ -127,6 +127,86 @@ test_two_levels(struct intel_spec *spec) {
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_dword_fields(struct intel_spec *spec) {
|
||||
struct GFX9_TEST_DWORD_FIELDS test = {
|
||||
.value_dw0 = 0x1234,
|
||||
.value_dw1 = 0xABCDEF00,
|
||||
.value_dw2 = 0x5678,
|
||||
.single_bit = true,
|
||||
};
|
||||
|
||||
uint32_t dw[GFX9_TEST_DWORD_FIELDS_length];
|
||||
GFX9_TEST_DWORD_FIELDS_pack(NULL, dw, &test);
|
||||
|
||||
struct intel_group *group;
|
||||
group = intel_spec_find_struct(spec, "TEST_DWORD_FIELDS");
|
||||
|
||||
assert(group != NULL);
|
||||
|
||||
if (!quiet) {
|
||||
printf("\nTEST_DWORD_FIELDS:\n");
|
||||
intel_print_group(stdout, group, 0, dw, 0, false);
|
||||
}
|
||||
|
||||
struct intel_field_iterator iter;
|
||||
intel_field_iterator_init(&iter, group, dw, 0, false);
|
||||
|
||||
while (intel_field_iterator_next(&iter)) {
|
||||
if (strcmp(iter.name, "value_dw0") == 0) {
|
||||
uint16_t value = iter.raw_value;
|
||||
assert(value == test.value_dw0);
|
||||
} else if (strcmp(iter.name, "value_dw1") == 0) {
|
||||
uint32_t value = iter.raw_value;
|
||||
assert(value == test.value_dw1);
|
||||
} else if (strcmp(iter.name, "value_dw2") == 0) {
|
||||
uint16_t value = iter.raw_value;
|
||||
assert(value == test.value_dw2);
|
||||
} else if (strcmp(iter.name, "single_bit") == 0) {
|
||||
bool value = iter.raw_value;
|
||||
assert(value == test.single_bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_offset_bits(struct intel_spec *spec) {
|
||||
struct GFX9_TEST_OFFSET_BITS test = {
|
||||
.header = 0x12345678,
|
||||
};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
test.data[i] = 0x1000 + i;
|
||||
}
|
||||
|
||||
uint32_t dw[GFX9_TEST_OFFSET_BITS_length];
|
||||
GFX9_TEST_OFFSET_BITS_pack(NULL, dw, &test);
|
||||
|
||||
struct intel_group *group;
|
||||
group = intel_spec_find_struct(spec, "TEST_OFFSET_BITS");
|
||||
|
||||
assert(group != NULL);
|
||||
|
||||
if (!quiet) {
|
||||
printf("\nTEST_OFFSET_BITS:\n");
|
||||
intel_print_group(stdout, group, 0, dw, 0, false);
|
||||
}
|
||||
|
||||
struct intel_field_iterator iter;
|
||||
intel_field_iterator_init(&iter, group, dw, 0, false);
|
||||
|
||||
while (intel_field_iterator_next(&iter)) {
|
||||
int idx;
|
||||
if (strcmp(iter.name, "header") == 0) {
|
||||
uint32_t value = iter.raw_value;
|
||||
assert(value == test.header);
|
||||
} else if (sscanf(iter.name, "data[%d]", &idx) == 1) {
|
||||
uint16_t value = iter.raw_value;
|
||||
assert(value == test.data[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct intel_spec *spec = intel_spec_load_filename(GENXML_DIR, GENXML_FILE);
|
||||
@@ -136,6 +216,8 @@ int main(int argc, char **argv)
|
||||
|
||||
test_struct(spec);
|
||||
test_two_levels(spec);
|
||||
test_dword_fields(spec);
|
||||
test_offset_bits(spec);
|
||||
|
||||
intel_spec_destroy(spec);
|
||||
|
||||
|
||||
@@ -213,9 +213,16 @@ class Field(object):
|
||||
|
||||
def add_gen(self, gen, xml_attrs):
|
||||
assert isinstance(gen, Gen)
|
||||
start = int(xml_attrs['start'])
|
||||
end = int(xml_attrs['end'])
|
||||
self.start_by_gen[gen] = start
|
||||
|
||||
if 'start' in xml_attrs:
|
||||
dword = 0
|
||||
start = int(xml_attrs['start'])
|
||||
end = int(xml_attrs['end'])
|
||||
else:
|
||||
dword = int(xml_attrs['dword'])
|
||||
end, start = map(int, xml_attrs['bits'].split(':'))
|
||||
|
||||
self.start_by_gen[gen] = dword * 32 + start
|
||||
self.bits_by_gen[gen] = 1 + end - start
|
||||
|
||||
def has_prop(self, prop):
|
||||
|
||||
@@ -72,8 +72,17 @@ class Field(object):
|
||||
self.parser = parser
|
||||
if "name" in attrs:
|
||||
self.name = safe_name(attrs["name"])
|
||||
self.start = int(attrs["start"])
|
||||
self.end = int(attrs["end"])
|
||||
|
||||
if "start" in attrs:
|
||||
self.start = int(attrs["start"])
|
||||
self.end = int(attrs["end"])
|
||||
else:
|
||||
dword = int(attrs["dword"])
|
||||
end_bit, start_bit = map(int, attrs["bits"].split(":"))
|
||||
|
||||
self.start = dword * 32 + start_bit
|
||||
self.end = dword * 32 + end_bit
|
||||
|
||||
self.type = attrs["type"]
|
||||
self.nonzero = bool_from_str(attrs.get("nonzero", "false"))
|
||||
self.prefix = attrs["prefix"] if "prefix" in attrs else None
|
||||
@@ -458,8 +467,15 @@ class Parser(object):
|
||||
self.group = Group(self, None, 0, 1, size)
|
||||
|
||||
elif name == "group":
|
||||
if "start" in attrs:
|
||||
start = int(attrs["start"])
|
||||
else:
|
||||
dword = int(attrs["dword"])
|
||||
offset_bits = int(attrs.get("offset_bits", 0))
|
||||
start = dword * 32 + offset_bits
|
||||
|
||||
group = Group(self, self.group,
|
||||
int(attrs["start"]), int(attrs["count"]), int(attrs["size"]))
|
||||
start, int(attrs["count"]), int(attrs["size"]))
|
||||
self.group.fields.append(group)
|
||||
self.group = group
|
||||
elif name == "field":
|
||||
|
||||
Reference in New Issue
Block a user