diff options
Diffstat (limited to 'meta-xilinx-core/classes-recipe/dfx_user_dts.bbclass')
| -rw-r--r-- | meta-xilinx-core/classes-recipe/dfx_user_dts.bbclass | 107 |
1 files changed, 57 insertions, 50 deletions
diff --git a/meta-xilinx-core/classes-recipe/dfx_user_dts.bbclass b/meta-xilinx-core/classes-recipe/dfx_user_dts.bbclass index 9f63fccc..2b699d9d 100644 --- a/meta-xilinx-core/classes-recipe/dfx_user_dts.bbclass +++ b/meta-xilinx-core/classes-recipe/dfx_user_dts.bbclass | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | # | 1 | # |
| 2 | # Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. | 2 | # Copyright (C) 2023-2024, Advanced Micro Devices, Inc. All rights reserved. |
| 3 | # | 3 | # |
| 4 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
| 5 | # | 5 | # |
| @@ -30,12 +30,23 @@ S ?= "${WORKDIR}" | |||
| 30 | FW_DIR ?= "" | 30 | FW_DIR ?= "" |
| 31 | DTSI_PATH ?= "" | 31 | DTSI_PATH ?= "" |
| 32 | DTBO_PATH ?= "" | 32 | DTBO_PATH ?= "" |
| 33 | BIT_PATH ?= "" | ||
| 34 | BIN_PATH ?= "" | ||
| 35 | PDI_PATH ?= "" | ||
| 36 | JSON_PATH ?= "" | ||
| 37 | XCl_PATH ?= "" | ||
| 33 | DT_FILES_PATH = "${S}/${DTSI_PATH}" | 38 | DT_FILES_PATH = "${S}/${DTSI_PATH}" |
| 34 | FIRMWARE_NAME_DT_FILE ?= "" | 39 | FIRMWARE_NAME_DT_FILE ?= "" |
| 35 | USER_DTS_FILE ?= "" | 40 | USER_DTS_FILE ?= "" |
| 36 | 41 | ||
| 37 | FIRMWARE_NAME_DT_FILE[doc] = "DT file which has firmware-name device-tree property" | 42 | FIRMWARE_NAME_DT_FILE[doc] = "DT file which has firmware-name device-tree property" |
| 38 | USER_DTS_FILE[doc] = "Final DTSI or DTS file which is used for packaging final DT overlay" | 43 | USER_DTS_FILE[doc] = "Final DTSI or DTS file which is used for packaging final DT overlay" |
| 44 | DTSI_PATH[doc] = "Absolute '.dtsi' or ''.dts' file path as input to SRC_URI" | ||
| 45 | DTBO_PATH[doc] = "Absolute '.dtbo' file path as input to SRC_URI" | ||
| 46 | BIT_PATH[doc] = "Absolute '.bit' file path as input to SRC_URI" | ||
| 47 | BIN_PATH[doc] = "Absolute '.bin' file path as input to SRC_URI" | ||
| 48 | JSON_PATH[doc] = "Absolute '.json' file path as input to SRC_URI" | ||
| 49 | XCL_PATH[doc] = "Absolute '.xclbin' file path as input to SRC_URI" | ||
| 39 | 50 | ||
| 40 | python() { | 51 | python() { |
| 41 | import re | 52 | import re |
| @@ -50,26 +61,39 @@ python() { | |||
| 50 | pdi_found = False | 61 | pdi_found = False |
| 51 | 62 | ||
| 52 | # Required Inputs | 63 | # Required Inputs |
| 53 | if '.dtsi ' in d.getVar("SRC_URI") or '.dts ' in d.getVar("SRC_URI"): | 64 | for s in d.getVar("SRC_URI").split(): |
| 54 | dtsi_found = True | 65 | if s.endswith(('.dtsi', '.dts')): |
| 55 | d.setVar("DTSI_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.dtsi' in a or '.dts' in a][0].lstrip('file://'))) | 66 | dtsi_found = True |
| 56 | 67 | d.setVar("DTSI_PATH",os.path.dirname(s.lstrip('file://'))) | |
| 57 | if '.dtbo ' in d.getVar("SRC_URI"): | 68 | if s.endswith('.dtbo'): |
| 58 | dtbo_found = True | 69 | if dtbo_found: |
| 59 | d.setVar("DTBO_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.dtbo' in a][0].lstrip('file://'))) | 70 | bb.warn("More then one '.dtbo' file specified in SRC_URI.") |
| 60 | 71 | dtbo_found = True | |
| 61 | if soc_family == "zynq" or soc_family == "zynqmp": | 72 | d.setVar("DTBO_PATH",os.path.dirname(s.lstrip('file://'))) |
| 62 | if '.bit ' in d.getVar("SRC_URI"): | 73 | if soc_family == "zynq" or soc_family == "zynqmp": |
| 63 | bit_found = True | 74 | if s.endswith('.bit'): |
| 64 | d.setVar("BIT_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.bit' in a][0].lstrip('file://'))) | 75 | if bit_found: |
| 65 | 76 | bb.warn("More then one '.bit' file specified in SRC_URI.") | |
| 66 | if '.bin ' in d.getVar("SRC_URI"): | 77 | bit_found = True |
| 67 | bin_found = True | 78 | d.setVar("BIT_PATH",os.path.dirname(s.lstrip('file://'))) |
| 68 | d.setVar("BIN_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.bin' in a][0].lstrip('file://'))) | 79 | if s.endswith('.bin'): |
| 69 | else: | 80 | if bin_found: |
| 70 | if '.pdi ' in d.getVar("SRC_URI"): | 81 | bb.warn("More then one '.bin' file specified in SRC_URI.") |
| 71 | pdi_found = True | 82 | bin_found = True |
| 72 | d.setVar("PDI_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.pdi' in a][0].lstrip('file://'))) | 83 | d.setVar("BIN_PATH",os.path.dirname(s.lstrip('file://'))) |
| 84 | else: | ||
| 85 | if s.endswith('.pdi'): | ||
| 86 | if pdi_found: | ||
| 87 | bb.warn("More then one '.pdi' file specified in SRC_URI.") | ||
| 88 | pdi_found = True | ||
| 89 | d.setVar("PDI_PATH",os.path.dirname(s.lstrip('file://'))) | ||
| 90 | |||
| 91 | # Optional input | ||
| 92 | if s.endswith('.json'): | ||
| 93 | d.setVar("JSON_PATH",os.path.dirname(s.lstrip('file://'))) | ||
| 94 | |||
| 95 | if s.endswith('.xclbin'): | ||
| 96 | d.setVar("XCL_PATH",os.path.dirname(s.lstrip('file://'))) | ||
| 73 | 97 | ||
| 74 | # Check for valid combination of input files in SRC_URI | 98 | # Check for valid combination of input files in SRC_URI |
| 75 | # Skip recipe if any of the below conditions are not satisfied. | 99 | # Skip recipe if any of the below conditions are not satisfied. |
| @@ -104,27 +128,14 @@ python() { | |||
| 104 | raise bb.parse.SkipRecipe("Recipe has more than one '.dtsi' and zero '.dts' found, this is an unsupported use case") | 128 | raise bb.parse.SkipRecipe("Recipe has more than one '.dtsi' and zero '.dts' found, this is an unsupported use case") |
| 105 | elif dts_count > 1: | 129 | elif dts_count > 1: |
| 106 | raise bb.parse.SkipRecipe("Recipe has more than one '.dts' and zero or more than one '.dtsi' found, this is an unsupported use case") | 130 | raise bb.parse.SkipRecipe("Recipe has more than one '.dts' and zero or more than one '.dtsi' found, this is an unsupported use case") |
| 107 | |||
| 108 | # Optional input | ||
| 109 | if '.json ' in d.getVar("SRC_URI"): | ||
| 110 | d.setVar("JSON_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.json' in a][0].lstrip('file://'))) | ||
| 111 | |||
| 112 | if '.xclbin ' in d.getVar("SRC_URI"): | ||
| 113 | d.setVar("XCL_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.xclbin' in a][0].lstrip('file://'))) | ||
| 114 | } | 131 | } |
| 115 | 132 | ||
| 116 | # Function to get dts or dtsi file count. | ||
| 117 | def get_dt_count(d, dt_ext): | ||
| 118 | import glob | ||
| 119 | dt_count = sum(1 for f in glob.iglob((d.getVar('S') + (d.getVar('DTSI_PATH')) + '/*.' + dt_ext),recursive=True) if os.path.isfile(f)) | ||
| 120 | return dt_count | ||
| 121 | |||
| 122 | # Function to search for dt firmware-name property in dts or dtsi file. | 133 | # Function to search for dt firmware-name property in dts or dtsi file. |
| 123 | python find_firmware_file() { | 134 | python find_firmware_file() { |
| 124 | import glob | 135 | import glob |
| 125 | pattern_fw = 'firmware-name' | 136 | pattern_fw = 'firmware-name' |
| 126 | search_count = 0 | 137 | search_count = 0 |
| 127 | for dt_files in glob.iglob((d.getVar('S') + (d.getVar('DTSI_PATH')) + '/*.dts*'),recursive=True): | 138 | for dt_files in glob.iglob((d.getVar('S') + '/' + (d.getVar('DTSI_PATH')) + '/*.dts*'),recursive=True): |
| 128 | with open(dt_files, "r") as f: | 139 | with open(dt_files, "r") as f: |
| 129 | current_fd = f.read() | 140 | current_fd = f.read() |
| 130 | if pattern_fw in current_fd: | 141 | if pattern_fw in current_fd: |
| @@ -147,9 +158,9 @@ python do_configure() { | |||
| 147 | 158 | ||
| 148 | # Renaming firmware-name using $PN as bitstream/PDI will be renamed using | 159 | # Renaming firmware-name using $PN as bitstream/PDI will be renamed using |
| 149 | # $PN when generating the bin/pdi file. | 160 | # $PN when generating the bin/pdi file. |
| 150 | if os.path.isfile(d.getVar('S') + (d.getVar('DTSI_PATH') or '') + '/' + d.getVar('FIRMWARE_NAME_DT_FILE')): | 161 | if os.path.isfile(d.getVar('S') + '/' + (d.getVar('DTSI_PATH') or '') + '/' + d.getVar('FIRMWARE_NAME_DT_FILE')): |
| 151 | orig_dtsi = glob.glob(d.getVar('S')+ (d.getVar('DTSI_PATH') or '') + '/' + d.getVar('FIRMWARE_NAME_DT_FILE'))[0] | 162 | orig_dtsi = glob.glob(d.getVar('S') + '/' + (d.getVar('DTSI_PATH') or '') + '/' + d.getVar('FIRMWARE_NAME_DT_FILE'))[0] |
| 152 | new_dtsi = d.getVar('S') + '/pl.dtsi_firmwarename' | 163 | new_dtsi = d.getVar('S') + '/' + (d.getVar('DTSI_PATH') or '') + '/pl.dtsi_firmwarename' |
| 153 | with open(new_dtsi, 'w') as newdtsi: | 164 | with open(new_dtsi, 'w') as newdtsi: |
| 154 | with open(orig_dtsi) as olddtsi: | 165 | with open(orig_dtsi) as olddtsi: |
| 155 | for line in olddtsi: | 166 | for line in olddtsi: |
| @@ -168,19 +179,17 @@ python devicetree_do_compile:append() { | |||
| 168 | 179 | ||
| 169 | dtbo_count = sum(1 for f in glob.iglob((d.getVar('S') + '/*.dtbo'),recursive=True) if os.path.isfile(f)) | 180 | dtbo_count = sum(1 for f in glob.iglob((d.getVar('S') + '/*.dtbo'),recursive=True) if os.path.isfile(f)) |
| 170 | bin_count = sum(1 for f in glob.iglob((d.getVar('S') + '/*.bin'),recursive=True) if os.path.isfile(f)) | 181 | bin_count = sum(1 for f in glob.iglob((d.getVar('S') + '/*.bin'),recursive=True) if os.path.isfile(f)) |
| 171 | |||
| 172 | # Skip devicetree do_compile task if input file is dtbo or bin in SRC_URI | 182 | # Skip devicetree do_compile task if input file is dtbo or bin in SRC_URI |
| 173 | if not dtbo_count and not bin_count: | 183 | if not dtbo_count and not bin_count: |
| 174 | # Convert .bit to .bin format only if dtsi is input. | 184 | # Convert .bit to .bin format only if dtsi is input. |
| 175 | # In case of dtbo as input, bbclass doesn't know if firmware-name is .bit | 185 | # In case of dtbo as input, bbclass doesn't know if firmware-name is .bit |
| 176 | # or .bin format and corresponding file name. Hence we are not doing .bin | 186 | # or .bin format and corresponding file name. Hence we are not doing .bin |
| 177 | # conversion. | 187 | # conversion. |
| 178 | if soc_family == 'zynq' or soc_family == 'zynqmp' and glob.glob(d.getVar('S') + '/' + d.getVar('FIRMWARE_NAME_DT_FILE')): | 188 | if soc_family == 'zynq' or soc_family == 'zynqmp' and glob.glob(d.getVar('S') + '/' +(d.getVar('DTSI_PATH') or '') + '/' + d.getVar('FIRMWARE_NAME_DT_FILE')): |
| 179 | pn = d.getVar('PN') | 189 | pn = d.getVar('PN') |
| 180 | biffile = pn + '.bif' | 190 | biffile = pn + '.bif' |
| 181 | |||
| 182 | with open(biffile, 'w') as f: | 191 | with open(biffile, 'w') as f: |
| 183 | f.write('all:\n{\n\t' + glob.glob(d.getVar('S')+(d.getVar('BIT_PATH') or '') + '/*.bit')[0] + '\n}') | 192 | f.write('all:\n{\n\t' + glob.glob(d.getVar('S') + '/' + (d.getVar('BIT_PATH') or '') + '/*.bit')[0] + '\n}') |
| 184 | 193 | ||
| 185 | bootgenargs = ["bootgen"] + (d.getVar("BOOTGEN_FLAGS") or "").split() | 194 | bootgenargs = ["bootgen"] + (d.getVar("BOOTGEN_FLAGS") or "").split() |
| 186 | bootgenargs += ["-image", biffile, "-o", pn + ".bin"] | 195 | bootgenargs += ["-image", biffile, "-o", pn + ".bin"] |
| @@ -193,7 +202,7 @@ python devicetree_do_compile:append() { | |||
| 193 | # ${PN}.bin which matches the firmware name in dtbo and move | 202 | # ${PN}.bin which matches the firmware name in dtbo and move |
| 194 | # ${PN}.bin to ${B} directory. | 203 | # ${PN}.bin to ${B} directory. |
| 195 | if soc_family == 'zynq': | 204 | if soc_family == 'zynq': |
| 196 | src_bitbin_file = glob.glob(d.getVar('S') + (d.getVar('BIT_PATH') or '') + '/*.bin')[0] | 205 | src_bitbin_file = glob.glob(d.getVar('S') + '/' + (d.getVar('BIT_PATH') or '') + '/*.bin')[0] |
| 197 | dst_bitbin_file = d.getVar('B') + '/' + pn + '.bin' | 206 | dst_bitbin_file = d.getVar('B') + '/' + pn + '.bin' |
| 198 | shutil.move(src_bitbin_file, dst_bitbin_file) | 207 | shutil.move(src_bitbin_file, dst_bitbin_file) |
| 199 | 208 | ||
| @@ -207,17 +216,15 @@ python devicetree_do_compile:append() { | |||
| 207 | # overlay file. | 216 | # overlay file. |
| 208 | python find_user_dts_overlay_file() { | 217 | python find_user_dts_overlay_file() { |
| 209 | import glob | 218 | import glob |
| 210 | dtbo_count = sum(1 for f in glob.iglob((d.getVar('S') + '/*.dtbo'),recursive=True) if os.path.isfile(f)) | 219 | dtbo_count = sum(1 for f in glob.iglob((d.getVar('S') + '/' + d.getVar('DTBO_PATH') + '/*.dtbo'),recursive=True) if os.path.isfile(f)) |
| 211 | dts_count = sum(1 for f in glob.iglob((d.getVar('S') + '/*.dts'),recursive=True) if os.path.isfile(f)) | 220 | dts_count = sum(1 for f in glob.iglob((d.getVar('S') + '/' + d.getVar('DTSI_PATH') + '/*.dts'),recursive=True) if os.path.isfile(f)) |
| 212 | dtsi_count = sum(1 for f in glob.iglob((d.getVar('S') + '/*.dtsi'),recursive=True) if os.path.isfile(f)) | 221 | dtsi_count = sum(1 for f in glob.iglob((d.getVar('S') + '/' + d.getVar('DTSI_PATH') + '/*.dtsi'),recursive=True) if os.path.isfile(f)) |
| 213 | # Set USER_DTS_FILE if input file is dts/dtsi in SRC_URI else skip operation. | 222 | # Set USER_DTS_FILE if input file is dts/dtsi in SRC_URI else skip operation. |
| 214 | if not dtbo_count and dts_count or dtsi_count: | 223 | if not dtbo_count and dts_count or dtsi_count: |
| 215 | dts_count = get_dt_count(d, 'dts') | ||
| 216 | dtsi_count = get_dt_count(d, 'dtsi') | ||
| 217 | if dtsi_count == 1 and dts_count == 0: | 224 | if dtsi_count == 1 and dts_count == 0: |
| 218 | dts_file = glob.glob(d.getVar('S')+ (d.getVar('DTSI_PATH') or '') + '/*.dtsi')[0] | 225 | dts_file = glob.glob(d.getVar('S') + '/' + (d.getVar('DTSI_PATH') or '') + '/*.dtsi')[0] |
| 219 | elif dtsi_count >=0 and dts_count == 1: | 226 | elif dtsi_count >=0 and dts_count == 1: |
| 220 | dts_file = glob.glob(d.getVar('S')+ (d.getVar('DTSI_PATH') or '') + '/*.dts')[0] | 227 | dts_file = glob.glob(d.getVar('S') + '/' + (d.getVar('DTSI_PATH') or '') + '/*.dts')[0] |
| 221 | else: | 228 | else: |
| 222 | dts_file = '' | 229 | dts_file = '' |
| 223 | 230 | ||
