diff options
| -rw-r--r-- | meta-xilinx-core/classes/fpgamanager_custom.bbclass | 135 |
1 files changed, 105 insertions, 30 deletions
diff --git a/meta-xilinx-core/classes/fpgamanager_custom.bbclass b/meta-xilinx-core/classes/fpgamanager_custom.bbclass index 7bec7972..8e7e86c3 100644 --- a/meta-xilinx-core/classes/fpgamanager_custom.bbclass +++ b/meta-xilinx-core/classes/fpgamanager_custom.bbclass | |||
| @@ -20,65 +20,140 @@ BOOTGEN_FLAGS ?= " -arch ${SOC_FAMILY} ${@bb.utils.contains('SOC_FAMILY','zynqmp | |||
| 20 | S ?= "${WORKDIR}" | 20 | S ?= "${WORKDIR}" |
| 21 | FW_DIR ?= "" | 21 | FW_DIR ?= "" |
| 22 | DTSI_PATH ?= "" | 22 | DTSI_PATH ?= "" |
| 23 | DTBO_PATH ?= "" | ||
| 23 | DT_FILES_PATH = "${S}/${DTSI_PATH}" | 24 | DT_FILES_PATH = "${S}/${DTSI_PATH}" |
| 24 | 25 | ||
| 25 | python (){ | 26 | python() { |
| 26 | 27 | soc_family = d.getVar("SOC_FAMILY") | |
| 27 | if "git://" in d.getVar("SRC_URI") or "https://" in d.getVar("SRC_URI"): | 28 | if "git://" in d.getVar("SRC_URI") or "https://" in d.getVar("SRC_URI"): |
| 28 | d.setVar("S",'${WORKDIR}/git/'+d.getVar("FW_DIR")) | 29 | d.setVar("S",'${WORKDIR}/git/'+d.getVar("FW_DIR")) |
| 29 | else: | 30 | else: |
| 30 | if d.getVar("SRC_URI").count(".dtsi") != 1 or d.getVar("SRC_URI").count(".bit") != 1 \ | 31 | dtsi_found = False |
| 31 | or d.getVar("SRC_URI").count("shell.json") != 1: | 32 | dtbo_found = False |
| 32 | raise bb.parse.SkipRecipe("Need one '.dtsi', one '.bit' and one 'shell.json' file added to SRC_URI") | 33 | bit_found = False |
| 33 | 34 | pdi_found = False | |
| 34 | d.setVar("DTSI_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.dtsi' in a][0].lstrip('file://'))) | 35 | |
| 35 | d.setVar("BIT_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.bit' in a][0].lstrip('file://'))) | 36 | # Required Inputs |
| 36 | d.setVar("JSON_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if 'shell.json' in a][0].lstrip('file://'))) | 37 | if '.dtsi' in d.getVar("SRC_URI"): |
| 38 | dtsi_found = True | ||
| 39 | d.setVar("DTSI_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.dtsi' in a][0].lstrip('file://'))) | ||
| 40 | |||
| 41 | if '.dtbo' in d.getVar("SRC_URI"): | ||
| 42 | dtbo_found = True | ||
| 43 | d.setVar("DTBO_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.dtbo' in a][0].lstrip('file://'))) | ||
| 44 | |||
| 45 | if '.bit' in d.getVar("SRC_URI") and soc_family != "versal": | ||
| 46 | bit_found = True | ||
| 47 | d.setVar("BIT_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.bit' in a][0].lstrip('file://'))) | ||
| 48 | |||
| 49 | if '.pdi' in d.getVar("SRC_URI") and soc_family == "versal": | ||
| 50 | pdi_found = True | ||
| 51 | d.setVar("PDI_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.pdi' in a][0].lstrip('file://'))) | ||
| 52 | |||
| 53 | # Check for valid combination of input files in SRC_URI | ||
| 54 | if dtsi_found or dtbo_found: | ||
| 55 | bb.debug(2, "dtsi or dtbo found in SRC_URI") | ||
| 56 | if bit_found or pdi_found: | ||
| 57 | bb.debug(2, "bitstream or pdi found in SRC_URI") | ||
| 58 | else: | ||
| 59 | raise bb.parse.SkipRecipe("Need one '.bit' or one '.pdi' file added to SRC_URI ") | ||
| 60 | else: | ||
| 61 | raise bb.parse.SkipRecipe("Need one '.dtsi' or one '.dtbo' file added to SRC_URI ") | ||
| 62 | |||
| 63 | # Optional input | ||
| 64 | if 'accel.json' in d.getVar("SRC_URI"): | ||
| 65 | d.setVar("JSON_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if 'accel.json' in a][0].lstrip('file://'))) | ||
| 37 | 66 | ||
| 38 | #optional input | ||
| 39 | if '.xclbin' in d.getVar("SRC_URI"): | 67 | if '.xclbin' in d.getVar("SRC_URI"): |
| 40 | d.setVar("XCL_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.xclbin' in a][0].lstrip('file://'))) | 68 | d.setVar("XCL_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.xclbin' in a][0].lstrip('file://'))) |
| 41 | } | 69 | } |
| 42 | python do_configure() { | 70 | python do_configure() { |
| 43 | import glob, re, shutil | 71 | import glob, re, shutil |
| 72 | soc_family = d.getVar("SOC_FAMILY") | ||
| 44 | 73 | ||
| 45 | if bb.utils.contains('MACHINE_FEATURES', 'fpga-overlay', False, True, d): | 74 | if bb.utils.contains('MACHINE_FEATURES', 'fpga-overlay', False, True, d): |
| 46 | bb.warn("Using fpga-manager.bbclass requires fpga-overlay MACHINE_FEATURE to be enabled") | 75 | bb.warn("Using fpga-manager.bbclass requires fpga-overlay MACHINE_FEATURE to be enabled") |
| 47 | 76 | ||
| 48 | #renaming firmware-name using $PN as bitstream will be renamed using $PN when generating the bin file | 77 | # Renaming firmware-name using $PN as bitstream/PDI will be renamed using |
| 49 | orig_dtsi = glob.glob(d.getVar('S')+ (d.getVar('DTSI_PATH') or '') + '/*.dtsi')[0] | 78 | # $PN when generating the bin/pdi file. |
| 50 | new_dtsi = d.getVar('S') + '/pl.dtsi_firmwarename' | 79 | if '.dtsi' in d.getVar("SRC_URI"): |
| 51 | with open(new_dtsi, 'w') as newdtsi: | 80 | orig_dtsi = glob.glob(d.getVar('S')+ (d.getVar('DTSI_PATH') or '') + '/*.dtsi')[0] |
| 52 | with open(orig_dtsi) as olddtsi: | 81 | new_dtsi = d.getVar('S') + '/pl.dtsi_firmwarename' |
| 53 | for line in olddtsi: | 82 | with open(new_dtsi, 'w') as newdtsi: |
| 54 | newdtsi.write(re.sub('firmware-name.*\".*\"','firmware-name = \"'+d.getVar('PN')+'.bit.bin\"',line)) | 83 | with open(orig_dtsi) as olddtsi: |
| 55 | shutil.move(new_dtsi,orig_dtsi) | 84 | for line in olddtsi: |
| 85 | if soc_family == 'versal': | ||
| 86 | newdtsi.write(re.sub('firmware-name.*\".*\"','firmware-name = \"'+d.getVar('PN')+'.pdi\"',line)) | ||
| 87 | else: | ||
| 88 | newdtsi.write(re.sub('firmware-name.*\".*\"','firmware-name = \"'+d.getVar('PN')+'.bit.bin\"',line)) | ||
| 89 | shutil.move(new_dtsi,orig_dtsi) | ||
| 56 | } | 90 | } |
| 57 | 91 | ||
| 58 | python devicetree_do_compile:append() { | 92 | python devicetree_do_compile:append() { |
| 59 | import glob, subprocess | 93 | import glob, subprocess |
| 60 | pn = d.getVar('PN') | 94 | soc_family = d.getVar("SOC_FAMILY") |
| 61 | biffile = pn + '.bif' | 95 | |
| 96 | # Convert .bit to bit.bin format only if dtsi is input. | ||
| 97 | # In case of dtbo as input, bbclass doesn't know if firmware-name is .bit or | ||
| 98 | # .bit.bin format and corresponding file name. Hence we are not doing | ||
| 99 | # bit.bin conversion. | ||
| 100 | if soc_family != 'versal' and '.dtsi' in d.getVar("SRC_URI"): | ||
| 101 | pn = d.getVar('PN') | ||
| 102 | biffile = pn + '.bif' | ||
| 62 | 103 | ||
| 63 | with open(biffile, 'w') as f: | 104 | with open(biffile, 'w') as f: |
| 64 | f.write('all:\n{\n\t' + glob.glob(d.getVar('S')+(d.getVar('BIT_PATH') or '') + '/*.bit')[0] + '\n}') | 105 | f.write('all:\n{\n\t' + glob.glob(d.getVar('S')+(d.getVar('BIT_PATH') or '') + '/*.bit')[0] + '\n}') |
| 65 | 106 | ||
| 66 | bootgenargs = ["bootgen"] + (d.getVar("BOOTGEN_FLAGS") or "").split() | 107 | bootgenargs = ["bootgen"] + (d.getVar("BOOTGEN_FLAGS") or "").split() |
| 67 | bootgenargs += ["-image", biffile, "-o", pn + ".bit.bin"] | 108 | bootgenargs += ["-image", biffile, "-o", pn + ".bit.bin"] |
| 68 | subprocess.run(bootgenargs, check = True) | 109 | subprocess.run(bootgenargs, check = True) |
| 69 | 110 | ||
| 70 | if not os.path.isfile(pn + ".bit.bin"): | 111 | if not os.path.isfile(pn + ".bit.bin"): |
| 71 | bb.fatal("bootgen failed. Enable -log debug with bootgen and check logs") | 112 | bb.fatal("bootgen failed. Enable -log debug with bootgen and check logs") |
| 72 | } | 113 | } |
| 73 | 114 | ||
| 74 | do_install() { | 115 | do_install() { |
| 75 | install -d ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | 116 | install -d ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ |
| 76 | install -Dm 0644 *.dtbo ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.dtbo | 117 | |
| 77 | install -Dm 0644 ${PN}.bit.bin ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.bit.bin | 118 | # In case of dtbo as input, dtbo will be copied from directly from ${S} |
| 119 | # In case of dtsi as input, dtbo will be copied from directly from ${B} | ||
| 120 | if [ -f ${S}/*.dtbo ]; then | ||
| 121 | install -Dm 0644 ${S}/*.dtbo ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
| 122 | elif [ -f ${B}/*.dtbo ]; then | ||
| 123 | install -Dm 0644 ${B}/*.dtbo ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.dtbo | ||
| 124 | else | ||
| 125 | bbfatal "A dtbo ending '.dtbo' expected but not found" | ||
| 126 | fi | ||
| 127 | |||
| 128 | if [ "${SOC_FAMILY}" == "versal" ]; then | ||
| 129 | # In case of dtbo as input, pdi will be copied from directly from ${S} | ||
| 130 | # without renaming the pdi name to ${PN}.pdi | ||
| 131 | if [ -f ${S}/*.pdi ] && [ -f ${S}/*.dtbo ]; then | ||
| 132 | install -Dm 0644 ${S}/*.pdi ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
| 133 | elif [ -f ${S}/*.pdi ] && [ -f ${B}/*.dtbo ]; then | ||
| 134 | install -Dm 0644 ${S}/*.pdi ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.pdi | ||
| 135 | else | ||
| 136 | bbfatal "A PDI file with '.pdi' expected but not found" | ||
| 137 | fi | ||
| 138 | else | ||
| 139 | # In case of dtbo as input, .bit or .bit.in will be copied from directly | ||
| 140 | # from ${S} without renaming the .bit name to ${PN}.bit.bin | ||
| 141 | if [ -f ${S}/*.bit* ] && [ -f ${S}/*.dtbo ]; then | ||
| 142 | install -Dm 0644 ${S}/*.bit* ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
| 143 | elif [ -f ${B}/${PN}.bit.bin ] && [ -f ${B}/*.dtbo ]; then | ||
| 144 | install -Dm 0644 ${B}/${PN}.bit.bin ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.bit.bin | ||
| 145 | else | ||
| 146 | bbfatal "A bitstream file with '.bit' or '.bit.bin' expected but not found" | ||
| 147 | fi | ||
| 148 | fi | ||
| 149 | |||
| 78 | if ls ${S}/${XCL_PATH}/*.xclbin >/dev/null 2>&1; then | 150 | if ls ${S}/${XCL_PATH}/*.xclbin >/dev/null 2>&1; then |
| 79 | install -Dm 0644 ${S}/${XCL_PATH}/*.xclbin ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.xclbin | 151 | install -Dm 0644 ${S}/${XCL_PATH}/*.xclbin ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.xclbin |
| 80 | fi | 152 | fi |
| 81 | install -Dm 0644 ${S}/${JSON_PATH}/shell.json ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/shell.json | 153 | |
| 154 | if [ -f ${WORKDIR}/${JSON_PATH}/accel.json ]; then | ||
| 155 | install -Dm 0644 ${S}/${JSON_PATH}/accel.json ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/accel.json | ||
| 156 | fi | ||
| 82 | } | 157 | } |
| 83 | 158 | ||
| 84 | do_deploy[noexec] = "1" | 159 | do_deploy[noexec] = "1" |
