From f8af5c58c3aa83939b1e0f03d550ba63a9ea729e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 27 Jun 2018 11:10:07 -0700 Subject: [PATCH] v3d: Create XML fields for min_ver and max_ver of a packet/struct/enum. This will be used to merge together the V3D 3.3-4.1 XML with the variants disabled based on the version. --- src/broadcom/cle/gen_pack_header.py | 41 +++++++++++++++++++++++++-- src/broadcom/cle/v3d_decoder.c | 43 +++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/broadcom/cle/gen_pack_header.py b/src/broadcom/cle/gen_pack_header.py index df547fb5ab1..c6e1c564e6d 100644 --- a/src/broadcom/cle/gen_pack_header.py +++ b/src/broadcom/cle/gen_pack_header.py @@ -192,6 +192,8 @@ class Group(object): self.count = count self.size = 0 self.fields = [] + self.min_ver = 0 + self.max_ver = 0 def emit_template_struct(self, dim): if self.count == 0: @@ -414,6 +416,24 @@ class Parser(object): def gen_guard(self): return self.gen_prefix("PACK_H") + def attrs_version_valid(self, attrs): + if "min_ver" in attrs and self.ver < attrs["min_ver"]: + return False + + if "max_ver" in attrs and self.ver > attrs["max_ver"]: + return False + + return True + + def group_enabled(self): + if self.group.min_ver != 0 and self.ver < self.group.min_ver: + return False + + if self.group.max_ver != 0 and self.ver > self.group.max_ver: + return False + + return True + def start_element(self, name, attrs): if name == "vcxml": self.platform = "V3D {}.{}".format(self.ver[0], self.ver[1]) @@ -449,6 +469,11 @@ class Parser(object): field.values = [] self.group.fields.append(field) + if "min_ver" in attrs: + self.group.min_ver = attrs["min_ver"] + if "max_ver" in attrs: + self.group.max_ver = attrs["max_ver"] + elif name == "field": self.group.fields.append(Field(self, attrs)) self.values = [] @@ -456,12 +481,14 @@ class Parser(object): self.values = [] self.enum = safe_name(attrs["name"]) self.enums.add(attrs["name"]) + self.enum_enabled = self.attrs_version_valid(attrs) if "prefix" in attrs: self.prefix = attrs["prefix"] else: self.prefix= None elif name == "value": - self.values.append(Value(attrs)) + if self.attrs_version_valid(attrs): + self.values.append(Value(attrs)) def end_element(self, name): if name == "packet": @@ -480,7 +507,8 @@ class Parser(object): elif name == "field": self.group.fields[-1].values = self.values elif name == "enum": - self.emit_enum() + if self.enum_enabled: + self.emit_enum() self.enum = None elif name == "vcxml": print('#endif /* %s */' % self.gen_guard()) @@ -525,6 +553,9 @@ class Parser(object): print('') def emit_packet(self): + if not self.group_enabled(): + return + name = self.packet assert(self.group.fields[0].name == "opcode") @@ -539,6 +570,9 @@ class Parser(object): print('') def emit_register(self): + if not self.group_enabled(): + return + name = self.register if not self.reg_num == None: print('#define %-33s 0x%04x' % @@ -549,6 +583,9 @@ class Parser(object): self.emit_unpack_function(self.register, self.group) def emit_struct(self): + if not self.group_enabled(): + return + name = self.struct self.emit_header(name) diff --git a/src/broadcom/cle/v3d_decoder.c b/src/broadcom/cle/v3d_decoder.c index ed9cb7dd438..d76c004730b 100644 --- a/src/broadcom/cle/v3d_decoder.c +++ b/src/broadcom/cle/v3d_decoder.c @@ -58,6 +58,7 @@ struct location { struct parser_context { XML_Parser parser; + const struct v3d_device_info *devinfo; int foo; struct location loc; @@ -68,6 +69,9 @@ struct parser_context { struct v3d_value *values[256]; struct v3d_spec *spec; + + int parse_depth; + int parse_skip_depth; }; const char * @@ -414,6 +418,25 @@ set_group_opcode(struct v3d_group *group, const char **atts) return; } +static bool +ver_in_range(int ver, int min_ver, int max_ver) +{ + return ((min_ver == 0 || ver >= min_ver) && + (max_ver == 0 || ver <= max_ver)); +} + +static bool +skip_if_ver_mismatch(struct parser_context *ctx, int min_ver, int max_ver) +{ + if (!ctx->parse_skip_depth && !ver_in_range(ctx->devinfo->ver, + min_ver, max_ver)) { + assert(ctx->parse_depth != 0); + ctx->parse_skip_depth = ctx->parse_depth; + } + + return ctx->parse_skip_depth; +} + static void start_element(void *data, const char *element_name, const char **atts) { @@ -421,6 +444,8 @@ start_element(void *data, const char *element_name, const char **atts) int i; const char *name = NULL; const char *ver = NULL; + int min_ver = 0; + int max_ver = 0; ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser); @@ -429,8 +454,15 @@ start_element(void *data, const char *element_name, const char **atts) name = atts[i + 1]; else if (strcmp(atts[i], "gen") == 0) ver = atts[i + 1]; + else if (strcmp(atts[i], "min_ver") == 0) + min_ver = strtoul(atts[i + 1], NULL, 0); + else if (strcmp(atts[i], "max_ver") == 0) + max_ver = strtoul(atts[i + 1], NULL, 0); } + if (skip_if_ver_mismatch(ctx, min_ver, max_ver)) + goto skip; + if (strcmp(element_name, "vcxml") == 0) { if (ver == NULL) fail(&ctx->loc, "no ver given"); @@ -470,6 +502,8 @@ start_element(void *data, const char *element_name, const char **atts) assert(ctx->nvalues < ARRAY_SIZE(ctx->values)); } +skip: + ctx->parse_depth++; } static void @@ -478,6 +512,14 @@ end_element(void *data, const char *name) struct parser_context *ctx = data; struct v3d_spec *spec = ctx->spec; + ctx->parse_depth--; + + if (ctx->parse_skip_depth) { + if (ctx->parse_skip_depth == ctx->parse_depth) + ctx->parse_skip_depth = 0; + return; + } + if (strcmp(name, "packet") == 0 || strcmp(name, "struct") == 0 || strcmp(name, "register") == 0) { @@ -603,6 +645,7 @@ v3d_spec_load(const struct v3d_device_info *devinfo) memset(&ctx, 0, sizeof ctx); ctx.parser = XML_ParserCreate(NULL); + ctx.devinfo = devinfo; XML_SetUserData(ctx.parser, &ctx); if (ctx.parser == NULL) { fprintf(stderr, "failed to create parser\n"); -- 2.30.2