]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py
IntelFsp2Pkg: Add Config Editor tool support
[mirror_edk2.git] / IntelFsp2Pkg / Tools / FspDscBsf2Yaml.py
index d2ca7145ae1505bed55050ee208cdcad75b750cd..923fa6eeadaac455db27f3dda67a7c1baf813dc7 100644 (file)
 import os\r
 import re\r
 import sys\r
-from datetime import date\r
+\r
 from collections import OrderedDict\r
-from functools import reduce\r
+from datetime import date\r
 \r
-from GenCfgOpt import CGenCfgOpt\r
+from FspGenCfgData import CFspBsf2Dsc, CGenCfgData\r
 \r
 __copyright_tmp__ = """## @file\r
 #\r
-#  YAML CFGDATA %s File.\r
+#  Slim Bootloader CFGDATA %s File.\r
 #\r
-#  Copyright(c) %4d, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 ##\r
 """\r
 \r
-__copyright_dsc__ = """## @file\r
-#\r
-#  Copyright (c) %04d, Intel Corporation. All rights reserved.<BR>\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-[PcdsDynamicVpd.Upd]\r
-  #\r
-  # Global definitions in BSF\r
-  # !BSF BLOCK:{NAME:"FSP UPD Configuration", VER:"0.1"}\r
-  #\r
-\r
-"""\r
-\r
-\r
-def Bytes2Val(Bytes):\r
-    return reduce(lambda x, y: (x << 8) | y, Bytes[::-1])\r
-\r
-\r
-def Str2Bytes(Value, Blen):\r
-    Result = bytearray(Value[1:-1], 'utf-8')  # Excluding quotes\r
-    if len(Result) < Blen:\r
-        Result.extend(b'\x00' * (Blen - len(Result)))\r
-    return Result\r
-\r
-\r
-class CFspBsf2Dsc:\r
-\r
-    def __init__(self, bsf_file):\r
-        self.cfg_list = CFspBsf2Dsc.parse_bsf(bsf_file)\r
-\r
-    def get_dsc_lines(self):\r
-        return CFspBsf2Dsc.generate_dsc(self.cfg_list)\r
-\r
-    def save_dsc(self, dsc_file):\r
-        return CFspBsf2Dsc.generate_dsc(self.cfg_list, dsc_file)\r
-\r
-    @staticmethod\r
-    def parse_bsf(bsf_file):\r
-\r
-        fd = open(bsf_file, 'r')\r
-        bsf_txt = fd.read()\r
-        fd.close()\r
-\r
-        find_list = []\r
-        regex = re.compile(r'\s+Find\s+"(.*?)"(.*?)^\s+\$(.*?)\s+', re.S | re.MULTILINE)\r
-        for match in regex.finditer(bsf_txt):\r
-            find = match.group(1)\r
-            name = match.group(3)\r
-            if not name.endswith('_Revision'):\r
-                raise Exception("Unexpected CFG item following 'Find' !")\r
-            find_list.append((name, find))\r
-\r
-        idx = 0\r
-        count = 0\r
-        prefix = ''\r
-        chk_dict = {}\r
-        cfg_list = []\r
-        cfg_temp = {'find': '', 'cname': '', 'length': 0, 'value': '0', 'type': 'Reserved',\r
-                    'embed': '', 'page': '', 'option': '', 'instance': 0}\r
-        regex = re.compile(r'^\s+(\$(.*?)|Skip)\s+(\d+)\s+bytes(\s+\$_DEFAULT_\s+=\s+(.+?))?$',\r
-                           re.S | re.MULTILINE)\r
-\r
-        for match in regex.finditer(bsf_txt):\r
-            dlen = int(match.group(3))\r
-            if match.group(1) == 'Skip':\r
-                key = 'gPlatformFspPkgTokenSpaceGuid_BsfSkip%d' % idx\r
-                val = ', '.join(['%02X' % ord(i) for i in '\x00' * dlen])\r
-                idx += 1\r
-                option = '$SKIP'\r
-            else:\r
-                key = match.group(2)\r
-                val = match.group(5)\r
-                option = ''\r
-\r
-            cfg_item = dict(cfg_temp)\r
-            finds = [i for i in find_list if i[0] == key]\r
-            if len(finds) > 0:\r
-                if count >= 1:\r
-                    # Append a dummy one\r
-                    cfg_item['cname'] = 'Dummy'\r
-                    cfg_list.append(dict(cfg_item))\r
-                    cfg_list[-1]['embed'] = '%s:TAG_%03X:END' % (prefix, ord(prefix[-1]))\r
-                prefix = finds[0][1]\r
-                cfg_item['embed'] = '%s:TAG_%03X:START' % (prefix, ord(prefix[-1]))\r
-                cfg_item['find'] = prefix\r
-                cfg_item['cname'] = 'Signature'\r
-                cfg_item['length'] = len(finds[0][1])\r
-                str2byte = Str2Bytes("'" + finds[0][1] + "'", len(finds[0][1]))\r
-                cfg_item['value'] = '0x%X' % Bytes2Val(str2byte)\r
-                cfg_list.append(dict(cfg_item))\r
-                cfg_item = dict(cfg_temp)\r
-                find_list.pop(0)\r
-                count = 0\r
-\r
-            cfg_item['cname'] = key\r
-            cfg_item['length'] = dlen\r
-            cfg_item['value'] = val\r
-            cfg_item['option'] = option\r
-\r
-            if key not in chk_dict.keys():\r
-                chk_dict[key] = 0\r
-            else:\r
-                chk_dict[key] += 1\r
-            cfg_item['instance'] = chk_dict[key]\r
-\r
-            cfg_list.append(cfg_item)\r
-            count += 1\r
-\r
-        if prefix:\r
-            cfg_item = dict(cfg_temp)\r
-            cfg_item['cname'] = 'Dummy'\r
-            cfg_item['embed'] = '%s:%03X:END' % (prefix, ord(prefix[-1]))\r
-            cfg_list.append(cfg_item)\r
-\r
-        option_dict = {}\r
-        selreg = re.compile(r'\s+Selection\s*(.+?)\s*,\s*"(.*?)"$', re.S | re.MULTILINE)\r
-        regex = re.compile(r'^List\s&(.+?)$(.+?)^EndList$', re.S | re.MULTILINE)\r
-        for match in regex.finditer(bsf_txt):\r
-            key = match.group(1)\r
-            option_dict[key] = []\r
-            for select in selreg.finditer(match.group(2)):\r
-                option_dict[key].append((int(select.group(1), 0), select.group(2)))\r
-\r
-        chk_dict = {}\r
-        pagereg = re.compile(r'^Page\s"(.*?)"$(.+?)^EndPage$', re.S | re.MULTILINE)\r
-        for match in pagereg.finditer(bsf_txt):\r
-            page = match.group(1)\r
-            for line in match.group(2).splitlines():\r
-                match = re.match(r'\s+(Combo|EditNum)\s\$(.+?),\s"(.*?)",\s(.+?),$', line)\r
-                if match:\r
-                    cname = match.group(2)\r
-                    if cname not in chk_dict.keys():\r
-                        chk_dict[cname] = 0\r
-                    else:\r
-                        chk_dict[cname] += 1\r
-                    instance = chk_dict[cname]\r
-                    cfg_idxs = [i for i, j in enumerate(cfg_list) if j['cname'] == cname and j['instance'] == instance]\r
-                    if len(cfg_idxs) != 1:\r
-                        raise Exception("Multiple CFG item '%s' found !" % cname)\r
-                    cfg_item = cfg_list[cfg_idxs[0]]\r
-                    cfg_item['page'] = page\r
-                    cfg_item['type'] = match.group(1)\r
-                    cfg_item['prompt'] = match.group(3)\r
-                    cfg_item['range'] = None\r
-                    if cfg_item['type'] == 'Combo':\r
-                        cfg_item['option'] = option_dict[match.group(4)[1:]]\r
-                    elif cfg_item['type'] == 'EditNum':\r
-                        cfg_item['option'] = match.group(4)\r
-                match = re.match(r'\s+ Help\s"(.*?)"$', line)\r
-                if match:\r
-                    cfg_item['help'] = match.group(1)\r
-\r
-                match = re.match(r'\s+"Valid\srange:\s(.*)"$', line)\r
-                if match:\r
-                    parts = match.group(1).split()\r
-                    cfg_item['option'] = (\r
-                        (int(parts[0], 0), int(parts[2], 0), cfg_item['option']))\r
-\r
-        return cfg_list\r
-\r
-    @staticmethod\r
-    def generate_dsc(option_list, dsc_file=None):\r
-        dsc_lines = []\r
-        header = '%s' % (__copyright_dsc__ % date.today().year)\r
-        dsc_lines.extend(header.splitlines())\r
-\r
-        pages = []\r
-        for cfg_item in option_list:\r
-            if cfg_item['page'] and (cfg_item['page'] not in pages):\r
-                pages.append(cfg_item['page'])\r
-\r
-        page_id = 0\r
-        for page in pages:\r
-            dsc_lines.append('  # !BSF PAGES:{PG%02X::"%s"}' % (page_id, page))\r
-            page_id += 1\r
-        dsc_lines.append('')\r
-\r
-        last_page = ''\r
-        for option in option_list:\r
-            dsc_lines.append('')\r
-            default = option['value']\r
-            pos = option['cname'].find('_')\r
-            name = option['cname'][pos + 1:]\r
-\r
-            if option['find']:\r
-                dsc_lines.append('  # !BSF FIND:{%s}' % option['find'])\r
-                dsc_lines.append('')\r
-\r
-            if option['instance'] > 0:\r
-                name = name + '_%s' % option['instance']\r
-\r
-            if option['embed']:\r
-                dsc_lines.append('  # !HDR EMBED:{%s}' % option['embed'])\r
-\r
-            if option['type'] == 'Reserved':\r
-                dsc_lines.append('  # !BSF NAME:{Reserved} TYPE:{Reserved}')\r
-                if option['option'] == '$SKIP':\r
-                    dsc_lines.append('  # !BSF OPTION:{$SKIP}')\r
-            else:\r
-                prompt = option['prompt']\r
-\r
-                if last_page != option['page']:\r
-                    last_page = option['page']\r
-                    dsc_lines.append('  # !BSF PAGE:{PG%02X}' % (pages.index(option['page'])))\r
-\r
-                if option['type'] == 'Combo':\r
-                    dsc_lines.append('  # !BSF NAME:{%s} TYPE:{%s}' %\r
-                                     (prompt, option['type']))\r
-                    ops = []\r
-                    for val, text in option['option']:\r
-                        ops.append('0x%x:%s' % (val, text))\r
-                    dsc_lines.append('  # !BSF OPTION:{%s}' % (', '.join(ops)))\r
-                elif option['type'] == 'EditNum':\r
-                    cfg_len = option['length']\r
-                    if ',' in default and cfg_len > 8:\r
-                        dsc_lines.append('  # !BSF NAME:{%s} TYPE:{Table}' % (prompt))\r
-                        if cfg_len > 16:\r
-                            cfg_len = 16\r
-                        ops = []\r
-                        for i in range(cfg_len):\r
-                            ops.append('%X:1:HEX' % i)\r
-                        dsc_lines.append('  # !BSF OPTION:{%s}' % (', '.join(ops)))\r
-                    else:\r
-                        dsc_lines.append(\r
-                            '  # !BSF NAME:{%s} TYPE:{%s, %s,(0x%X, 0x%X)}' %\r
-                            (prompt, option['type'], option['option'][2],\r
-                             option['option'][0], option['option'][1]))\r
-                dsc_lines.append('  # !BSF HELP:{%s}' % option['help'])\r
-\r
-            if ',' in default:\r
-                default = '{%s}' % default\r
-            dsc_lines.append('  gCfgData.%-30s | * | 0x%04X | %s' %\r
-                             (name, option['length'], default))\r
-\r
-        if dsc_file:\r
-            fd = open(dsc_file, 'w')\r
-            fd.write('\n'.join(dsc_lines))\r
-            fd.close()\r
-\r
-        return dsc_lines\r
-\r
 \r
 class CFspDsc2Yaml():\r
 \r
     def __init__(self):\r
         self._Hdr_key_list = ['EMBED', 'STRUCT']\r
-        self._Bsf_key_list = ['NAME', 'HELP', 'TYPE', 'PAGE', 'PAGES', 'OPTION',\r
-                              'CONDITION', 'ORDER', 'MARKER', 'SUBT', 'FIELD', 'FIND']\r
+        self._Bsf_key_list = ['NAME', 'HELP', 'TYPE', 'PAGE', 'PAGES',\r
+                              'OPTION', 'CONDITION', 'ORDER', 'MARKER',\r
+                              'SUBT', 'FIELD', 'FIND']\r
         self.gen_cfg_data = None\r
-        self.cfg_reg_exp = re.compile(r"^([_a-zA-Z0-9$\(\)]+)\s*\|\s*(0x[0-9A-F]+|\*)\s*\|"\r
-                                      + r"\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)")\r
-        self.bsf_reg_exp = re.compile(r"(%s):{(.+?)}(?:$|\s+)" % '|'.join(self._Bsf_key_list))\r
-        self.hdr_reg_exp = re.compile(r"(%s):{(.+?)}" % '|'.join(self._Hdr_key_list))\r
+        self.cfg_reg_exp = re.compile(\r
+            "^([_a-zA-Z0-9$\\(\\)]+)\\s*\\|\\s*(0x[0-9A-F]+|\\*)"\r
+            "\\s*\\|\\s*(\\d+|0x[0-9a-fA-F]+)\\s*\\|\\s*(.+)")\r
+        self.bsf_reg_exp = re.compile("(%s):{(.+?)}(?:$|\\s+)"\r
+                                      % '|'.join(self._Bsf_key_list))\r
+        self.hdr_reg_exp = re.compile("(%s):{(.+?)}"\r
+                                      % '|'.join(self._Hdr_key_list))\r
         self.prefix = ''\r
         self.unused_idx = 0\r
         self.offset = 0\r
@@ -290,15 +51,15 @@ class CFspDsc2Yaml():
         """\r
         Load and parse a DSC CFGDATA file.\r
         """\r
-        gen_cfg_data = CGenCfgOpt('FSP')\r
+        gen_cfg_data = CGenCfgData('FSP')\r
         if file_name.endswith('.dsc'):\r
-            # if gen_cfg_data.ParseDscFileYaml(file_name, '') != 0:\r
-            if gen_cfg_data.ParseDscFile(file_name, '') != 0:\r
+            if gen_cfg_data.ParseDscFile(file_name) != 0:\r
                 raise Exception('DSC file parsing error !')\r
             if gen_cfg_data.CreateVarDict() != 0:\r
                 raise Exception('DSC variable creation error !')\r
         else:\r
             raise Exception('Unsupported file "%s" !' % file_name)\r
+        gen_cfg_data.UpdateDefaultValue()\r
         self.gen_cfg_data = gen_cfg_data\r
 \r
     def print_dsc_line(self):\r
@@ -312,14 +73,15 @@ class CFspDsc2Yaml():
         """\r
         Format a CFGDATA item into YAML format.\r
         """\r
-        if(not text.startswith('!expand')) and (': ' in text):\r
+        if (not text.startswith('!expand')) and (': ' in text):\r
             tgt = ':' if field == 'option' else '- '\r
             text = text.replace(': ', tgt)\r
         lines = text.splitlines()\r
         if len(lines) == 1 and field != 'help':\r
             return text\r
         else:\r
-            return '>\n   ' + '\n   '.join([indent + i.lstrip() for i in lines])\r
+            return '>\n   ' + '\n   '.join(\r
+                [indent + i.lstrip() for i in lines])\r
 \r
     def reformat_pages(self, val):\r
         # Convert XXX:YYY into XXX::YYY format for page definition\r
@@ -355,14 +117,16 @@ class CFspDsc2Yaml():
             cfg['page'] = self.reformat_pages(cfg['page'])\r
 \r
         if 'struct' in cfg:\r
-            cfg['value'] = self.reformat_struct_value(cfg['struct'], cfg['value'])\r
+            cfg['value'] = self.reformat_struct_value(\r
+                cfg['struct'], cfg['value'])\r
 \r
     def parse_dsc_line(self, dsc_line, config_dict, init_dict, include):\r
         """\r
         Parse a line in DSC and update the config dictionary accordingly.\r
         """\r
         init_dict.clear()\r
-        match = re.match(r'g(CfgData|\w+FspPkgTokenSpaceGuid)\.(.+)', dsc_line)\r
+        match = re.match('g(CfgData|\\w+FspPkgTokenSpaceGuid)\\.(.+)',\r
+                         dsc_line)\r
         if match:\r
             match = self.cfg_reg_exp.match(match.group(2))\r
             if not match:\r
@@ -385,7 +149,7 @@ class CFspDsc2Yaml():
                 self.offset = offset + int(length, 0)\r
             return True\r
 \r
-        match = re.match(r"^\s*#\s+!([<>])\s+include\s+(.+)", dsc_line)\r
+        match = re.match("^\\s*#\\s+!([<>])\\s+include\\s+(.+)", dsc_line)\r
         if match and len(config_dict) == 0:\r
             # !include should not be inside a config field\r
             # if so, do not convert include into YAML\r
@@ -398,7 +162,7 @@ class CFspDsc2Yaml():
                 config_dict['include'] = ''\r
             return True\r
 \r
-        match = re.match(r"^\s*#\s+(!BSF|!HDR)\s+(.+)", dsc_line)\r
+        match = re.match("^\\s*#\\s+(!BSF|!HDR)\\s+(.+)", dsc_line)\r
         if not match:\r
             return False\r
 \r
@@ -434,16 +198,19 @@ class CFspDsc2Yaml():
                     tmp_name = parts[0][:-5]\r
                     if tmp_name == 'CFGHDR':\r
                         cfg_tag = '_$FFF_'\r
-                        sval = '!expand { %s_TMPL : [ ' % tmp_name + '%s, %s, ' % (parts[1], cfg_tag) \\r
-                               + ', '.join(parts[2:]) + ' ] }'\r
+                        sval = '!expand { %s_TMPL : [ ' % \\r
+                            tmp_name + '%s, %s, ' % (parts[1], cfg_tag) + \\r
+                            ', '.join(parts[2:]) + ' ] }'\r
                     else:\r
-                        sval = '!expand { %s_TMPL : [ ' % tmp_name + ', '.join(parts[1:]) + ' ] }'\r
+                        sval = '!expand { %s_TMPL : [ ' % \\r
+                            tmp_name + ', '.join(parts[1:]) + ' ] }'\r
                     config_dict.clear()\r
                     config_dict['cname'] = tmp_name\r
                     config_dict['expand'] = sval\r
                     return True\r
                 else:\r
-                    if key in ['name', 'help', 'option'] and val.startswith('+'):\r
+                    if key in ['name', 'help', 'option'] and \\r
+                            val.startswith('+'):\r
                         val = config_dict[key] + '\n' + val[1:]\r
                     if val.strip() == '':\r
                         val = "''"\r
@@ -493,21 +260,23 @@ class CFspDsc2Yaml():
         include_file = ['.']\r
 \r
         for line in lines:\r
-            match = re.match(r"^\s*#\s+!([<>])\s+include\s+(.+)", line)\r
+            match = re.match("^\\s*#\\s+!([<>])\\s+include\\s+(.+)", line)\r
             if match:\r
                 if match.group(1) == '<':\r
                     include_file.append(match.group(2))\r
                 else:\r
                     include_file.pop()\r
 \r
-            match = re.match(r"^\s*#\s+(!BSF)\s+DEFT:{(.+?):(START|END)}", line)\r
+            match = re.match(\r
+                "^\\s*#\\s+(!BSF)\\s+DEFT:{(.+?):(START|END)}", line)\r
             if match:\r
                 if match.group(3) == 'START' and not template_name:\r
                     template_name = match.group(2).strip()\r
                     temp_file_dict[template_name] = list(include_file)\r
                     bsf_temp_dict[template_name] = []\r
-                if match.group(3) == 'END' and (template_name == match.group(2).strip()) \\r
-                   and template_name:\r
+                if match.group(3) == 'END' and \\r
+                        (template_name == match.group(2).strip()) and \\r
+                        template_name:\r
                     template_name = ''\r
             else:\r
                 if template_name:\r
@@ -531,12 +300,14 @@ class CFspDsc2Yaml():
                     init_dict.clear()\r
                     padding_dict = {}\r
                     cfgs.append(padding_dict)\r
-                    padding_dict['cname'] = 'UnusedUpdSpace%d' % self.unused_idx\r
+                    padding_dict['cname'] = 'UnusedUpdSpace%d' % \\r
+                        self.unused_idx\r
                     padding_dict['length'] = '0x%x' % num\r
                     padding_dict['value'] = '{ 0 }'\r
                     self.unused_idx += 1\r
 \r
-                if cfgs and cfgs[-1]['cname'][0] != '@' and config_dict['cname'][0] == '@':\r
+                if cfgs and cfgs[-1]['cname'][0] != '@' and \\r
+                        config_dict['cname'][0] == '@':\r
                     # it is a bit field, mark the previous one as virtual\r
                     cname = cfgs[-1]['cname']\r
                     new_cfg = dict(cfgs[-1])\r
@@ -545,7 +316,8 @@ class CFspDsc2Yaml():
                     cfgs[-1]['cname'] = cname\r
                     cfgs.append(new_cfg)\r
 \r
-                if cfgs and cfgs[-1]['cname'] == 'CFGHDR' and config_dict['cname'][0] == '<':\r
+                if cfgs and cfgs[-1]['cname'] == 'CFGHDR' and \\r
+                        config_dict['cname'][0] == '<':\r
                     # swap CfgHeader and the CFG_DATA order\r
                     if ':' in config_dict['cname']:\r
                         # replace the real TAG for CFG_DATA\r
@@ -661,7 +433,7 @@ class CFspDsc2Yaml():
         lines = []\r
         for each in self.gen_cfg_data._MacroDict:\r
             key, value = self.variable_fixup(each)\r
-            lines.append('%-30s : %s' % (key, value))\r
+            lines.append('%-30s : %s' % (key,  value))\r
         return lines\r
 \r
     def output_template(self):\r
@@ -671,7 +443,8 @@ class CFspDsc2Yaml():
         self.offset = 0\r
         self.base_offset = 0\r
         start, end = self.get_section_range('PcdsDynamicVpd.Tmp')\r
-        bsf_temp_dict, temp_file_dict = self.process_template_lines(self.gen_cfg_data._DscLines[start:end])\r
+        bsf_temp_dict, temp_file_dict = self.process_template_lines(\r
+            self.gen_cfg_data._DscLines[start:end])\r
         template_dict = dict()\r
         lines = []\r
         file_lines = {}\r
@@ -679,15 +452,18 @@ class CFspDsc2Yaml():
         file_lines[last_file] = []\r
 \r
         for tmp_name in temp_file_dict:\r
-            temp_file_dict[tmp_name][-1] = self.normalize_file_name(temp_file_dict[tmp_name][-1], True)\r
+            temp_file_dict[tmp_name][-1] = self.normalize_file_name(\r
+                temp_file_dict[tmp_name][-1], True)\r
             if len(temp_file_dict[tmp_name]) > 1:\r
-                temp_file_dict[tmp_name][-2] = self.normalize_file_name(temp_file_dict[tmp_name][-2], True)\r
+                temp_file_dict[tmp_name][-2] = self.normalize_file_name(\r
+                    temp_file_dict[tmp_name][-2], True)\r
 \r
         for tmp_name in bsf_temp_dict:\r
             file = temp_file_dict[tmp_name][-1]\r
             if last_file != file and len(temp_file_dict[tmp_name]) > 1:\r
                 inc_file = temp_file_dict[tmp_name][-2]\r
-                file_lines[inc_file].extend(['', '- !include %s' % temp_file_dict[tmp_name][-1], ''])\r
+                file_lines[inc_file].extend(\r
+                    ['', '- !include %s' % temp_file_dict[tmp_name][-1], ''])\r
             last_file = file\r
             if file not in file_lines:\r
                 file_lines[file] = []\r
@@ -708,7 +484,8 @@ class CFspDsc2Yaml():
         self.offset = 0\r
         self.base_offset = 0\r
         start, end = self.get_section_range('PcdsDynamicVpd.Upd')\r
-        cfgs = self.process_option_lines(self.gen_cfg_data._DscLines[start:end])\r
+        cfgs = self.process_option_lines(\r
+            self.gen_cfg_data._DscLines[start:end])\r
         self.config_fixup(cfgs)\r
         file_lines = self.output_dict(cfgs, True)\r
         return file_lines\r
@@ -721,13 +498,17 @@ class CFspDsc2Yaml():
         level = 0\r
         file = '.'\r
         for each in cfgs:\r
-            if 'length' in each and int(each['length'], 0) == 0:\r
-                continue\r
+            if 'length' in each:\r
+                if not each['length'].endswith('b') and int(each['length'],\r
+                                                            0) == 0:\r
+                    continue\r
 \r
             if 'include' in each:\r
                 if each['include']:\r
-                    each['include'] = self.normalize_file_name(each['include'])\r
-                    file_lines[file].extend(['', '- !include %s' % each['include'], ''])\r
+                    each['include'] = self.normalize_file_name(\r
+                        each['include'])\r
+                    file_lines[file].extend(\r
+                        ['', '- !include %s' % each['include'], ''])\r
                     file = each['include']\r
                 else:\r
                     file = '.'\r
@@ -766,7 +547,8 @@ class CFspDsc2Yaml():
             for field in each:\r
                 if field in ['cname', 'expand', 'include']:\r
                     continue\r
-                value_str = self.format_value(field, each[field], padding + ' ' * 16)\r
+                value_str = self.format_value(\r
+                    field, each[field], padding + ' ' * 16)\r
                 full_line = '  %s  %-12s : %s' % (padding, field, value_str)\r
                 lines.extend(full_line.splitlines())\r
 \r
@@ -802,11 +584,13 @@ def dsc_to_yaml(dsc_file, yaml_file):
             if file == '.':\r
                 cfgs[cfg] = lines\r
             else:\r
-                if('/' in file or '\\' in file):\r
+                if ('/' in file or '\\' in file):\r
                     continue\r
                 file = os.path.basename(file)\r
-                fo = open(os.path.join(file), 'w')\r
-                fo.write(__copyright_tmp__ % (cfg, date.today().year) + '\n\n')\r
+                out_dir = os.path.dirname(file)\r
+                fo = open(os.path.join(out_dir, file), 'w')\r
+                fo.write(__copyright_tmp__ % (\r
+                    cfg, date.today().year) + '\n\n')\r
                 for line in lines:\r
                     fo.write(line + '\n')\r
                 fo.close()\r
@@ -821,13 +605,11 @@ def dsc_to_yaml(dsc_file, yaml_file):
 \r
     fo.write('\n\ntemplate:\n')\r
     for line in cfgs['Template']:\r
-        if line != '':\r
-            fo.write('  ' + line + '\n')\r
+        fo.write('  ' + line + '\n')\r
 \r
     fo.write('\n\nconfigs:\n')\r
     for line in cfgs['Option']:\r
-        if line != '':\r
-            fo.write('  ' + line + '\n')\r
+        fo.write('  ' + line + '\n')\r
 \r
     fo.close()\r
 \r
@@ -864,7 +646,8 @@ def main():
     bsf_file = sys.argv[1]\r
     yaml_file = sys.argv[2]\r
     if os.path.isdir(yaml_file):\r
-        yaml_file = os.path.join(yaml_file, get_fsp_name_from_path(bsf_file) + '.yaml')\r
+        yaml_file = os.path.join(\r
+            yaml_file, get_fsp_name_from_path(bsf_file) + '.yaml')\r
 \r
     if bsf_file.endswith('.dsc'):\r
         dsc_file = bsf_file\r