diff options
Diffstat (limited to 'meta-xilinx-core/classes/fpgamanager_custom.bbclass')
-rw-r--r-- | meta-xilinx-core/classes/fpgamanager_custom.bbclass | 197 |
1 files changed, 22 insertions, 175 deletions
diff --git a/meta-xilinx-core/classes/fpgamanager_custom.bbclass b/meta-xilinx-core/classes/fpgamanager_custom.bbclass index e5255783..8c8997a1 100644 --- a/meta-xilinx-core/classes/fpgamanager_custom.bbclass +++ b/meta-xilinx-core/classes/fpgamanager_custom.bbclass | |||
@@ -1,177 +1,24 @@ | |||
1 | # This bbclass is inherited by flat, DFx Static and DFx RP firmware recipes. | 1 | # This class inherits dfx_user_dts.bbclass for below use cases. |
2 | # fpgamanager_custom.bbclass expects user to generate pl dtsi for flat, DFx Static | 2 | # Zynq-7000 and ZynqMP: Full bitstream loading. |
3 | # and DFx RP xsa outside of yocto. | 3 | # ZynqMP: DFx Static and Partial bitstream loading. |
4 | 4 | # Versal: DFx Static and Parial pdi loading. | |
5 | inherit devicetree | 5 | # Versal: Full PDI loading. |
6 | 6 | ||
7 | DEPENDS = "dtc-native bootgen-native" | 7 | inherit dfx_user_dts |
8 | 8 | ||
9 | # recipes that inherit from this class need to use an appropriate machine | 9 | python fpgamanager_warn_msg () { |
10 | # override for COMPATIBLE_MACHINE to build successfully; don't allow building | 10 | if not d.getVar("FPGAMANAGER_NO_WARN"): |
11 | # for microblaze MACHINE | 11 | arch = d.getVar('SOC_FAMILY') |
12 | COMPATIBLE_MACHINE ?= "^$" | 12 | pn = d.getVar('PN') |
13 | COMPATIBLE_MACHINE:microblaze = "^$" | 13 | warn_msg = 'Users should start using dfx_user_dts bbclass for ' |
14 | 14 | if arch == 'zynq': | |
15 | PACKAGE_ARCH = "${MACHINE_ARCH}" | 15 | warn_msg += 'Zynq-7000 Full bitstream loading use case.' |
16 | 16 | elif arch == 'zynqmp': | |
17 | PROVIDES = "" | 17 | warn_msg += 'ZynqMP Full or DFx Static or DFx Partial bitstream loading use case.' |
18 | 18 | elif arch == 'versal': | |
19 | do_fetch[cleandirs] = "${B}" | 19 | warn_msg += 'Versal DFx Static or DFx Partial or Full PDI loading use case.' |
20 | 20 | ||
21 | DT_PADDING_SIZE = "0x1000" | 21 | bb.warn("Recipe %s has inherited fpgamanager_custom bbclass which will be deprecated in 2024.1 release. \n%s" % (pn, warn_msg)) |
22 | BOOTGEN_FLAGS ?= " -arch ${SOC_FAMILY} -w ${@bb.utils.contains('SOC_FAMILY','zynqmp','','-process_bitstream bin',d)}" | ||
23 | |||
24 | S ?= "${WORKDIR}" | ||
25 | FW_DIR ?= "" | ||
26 | DTSI_PATH ?= "" | ||
27 | DTBO_PATH ?= "" | ||
28 | DT_FILES_PATH = "${S}/${DTSI_PATH}" | ||
29 | |||
30 | python() { | ||
31 | soc_family = d.getVar("SOC_FAMILY") | ||
32 | if "git://" in d.getVar("SRC_URI") or "https://" in d.getVar("SRC_URI"): | ||
33 | d.setVar("S",'${WORKDIR}/git/'+d.getVar("FW_DIR")) | ||
34 | else: | ||
35 | dtsi_found = False | ||
36 | dtbo_found = False | ||
37 | bit_found = False | ||
38 | pdi_found = False | ||
39 | |||
40 | # Required Inputs | ||
41 | if '.dtsi' in d.getVar("SRC_URI"): | ||
42 | dtsi_found = True | ||
43 | d.setVar("DTSI_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.dtsi' in a][0].lstrip('file://'))) | ||
44 | |||
45 | if '.dtbo' in d.getVar("SRC_URI"): | ||
46 | dtbo_found = True | ||
47 | d.setVar("DTBO_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.dtbo' in a][0].lstrip('file://'))) | ||
48 | |||
49 | if '.bit' in d.getVar("SRC_URI") and soc_family != "versal": | ||
50 | bit_found = True | ||
51 | d.setVar("BIT_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.bit' in a][0].lstrip('file://'))) | ||
52 | |||
53 | if '.pdi' in d.getVar("SRC_URI") and soc_family == "versal": | ||
54 | pdi_found = True | ||
55 | d.setVar("PDI_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.pdi' in a][0].lstrip('file://'))) | ||
56 | |||
57 | # Check for valid combination of input files in SRC_URI | ||
58 | if dtsi_found or dtbo_found: | ||
59 | bb.debug(2, "dtsi or dtbo found in SRC_URI") | ||
60 | if bit_found or pdi_found: | ||
61 | bb.debug(2, "bitstream or pdi found in SRC_URI") | ||
62 | else: | ||
63 | raise bb.parse.SkipRecipe("Need one '.bit' or one '.pdi' file added to SRC_URI ") | ||
64 | else: | ||
65 | raise bb.parse.SkipRecipe("Need one '.dtsi' or one '.dtbo' file added to SRC_URI ") | ||
66 | |||
67 | # Optional input | ||
68 | if '.json' in d.getVar("SRC_URI"): | ||
69 | d.setVar("JSON_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.json' in a][0].lstrip('file://'))) | ||
70 | |||
71 | if '.xclbin' in d.getVar("SRC_URI"): | ||
72 | d.setVar("XCL_PATH",os.path.dirname([a for a in d.getVar('SRC_URI').split() if '.xclbin' in a][0].lstrip('file://'))) | ||
73 | } | 22 | } |
74 | python do_configure() { | ||
75 | import glob, re, shutil | ||
76 | soc_family = d.getVar("SOC_FAMILY") | ||
77 | |||
78 | if bb.utils.contains('MACHINE_FEATURES', 'fpga-overlay', False, True, d): | ||
79 | bb.warn("Using fpga-manager.bbclass requires fpga-overlay MACHINE_FEATURE to be enabled") | ||
80 | |||
81 | # Renaming firmware-name using $PN as bitstream/PDI will be renamed using | ||
82 | # $PN when generating the bin/pdi file. | ||
83 | if '.dtsi' in d.getVar("SRC_URI"): | ||
84 | orig_dtsi = glob.glob(d.getVar('S')+ (d.getVar('DTSI_PATH') or '') + '/*.dtsi')[0] | ||
85 | new_dtsi = d.getVar('S') + '/pl.dtsi_firmwarename' | ||
86 | with open(new_dtsi, 'w') as newdtsi: | ||
87 | with open(orig_dtsi) as olddtsi: | ||
88 | for line in olddtsi: | ||
89 | if soc_family == 'versal': | ||
90 | newdtsi.write(re.sub('firmware-name.*\".*\"','firmware-name = \"'+d.getVar('PN')+'.pdi\"',line)) | ||
91 | else: | ||
92 | newdtsi.write(re.sub('firmware-name.*\".*\"','firmware-name = \"'+d.getVar('PN')+'.bit.bin\"',line)) | ||
93 | shutil.move(new_dtsi,orig_dtsi) | ||
94 | } | ||
95 | |||
96 | python devicetree_do_compile:append() { | ||
97 | import glob, subprocess, shutil | ||
98 | soc_family = d.getVar("SOC_FAMILY") | ||
99 | |||
100 | # Convert .bit to bit.bin format only if dtsi is input. | ||
101 | # In case of dtbo as input, bbclass doesn't know if firmware-name is .bit or | ||
102 | # .bit.bin format and corresponding file name. Hence we are not doing | ||
103 | # bit.bin conversion. | ||
104 | if soc_family != 'versal' and glob.glob(d.getVar('S') + '/*.dtsi'): | ||
105 | pn = d.getVar('PN') | ||
106 | biffile = pn + '.bif' | ||
107 | |||
108 | with open(biffile, 'w') as f: | ||
109 | f.write('all:\n{\n\t' + glob.glob(d.getVar('S')+(d.getVar('BIT_PATH') or '') + '/*.bit')[0] + '\n}') | ||
110 | |||
111 | bootgenargs = ["bootgen"] + (d.getVar("BOOTGEN_FLAGS") or "").split() | ||
112 | bootgenargs += ["-image", biffile, "-o", pn + ".bit.bin"] | ||
113 | subprocess.run(bootgenargs, check = True) | ||
114 | |||
115 | # In Zynq7k using both "-process_bitstream bin" and "-o" in bootgen flag, | ||
116 | # to convert bit file to bin format, "-o" option will not be effective | ||
117 | # and generated output file name is ${S}+${BIT_PATH}/<bit_file_name>.bit.bin | ||
118 | # file, Hence we need to rename this file from <bit_file_name>.bit.bin to | ||
119 | # ${PN}.bit.bin which matches the firmware name in dtbo and move | ||
120 | # ${PN}.bit.bin to ${B} directory. | ||
121 | if soc_family == 'zynq': | ||
122 | src_bitbin_file = glob.glob(d.getVar('S') + (d.getVar('BIT_PATH') or '') + '/*.bit.bin')[0] | ||
123 | dst_bitbin_file = d.getVar('B') + '/' + pn + '.bit.bin' | ||
124 | shutil.move(src_bitbin_file, dst_bitbin_file) | ||
125 | |||
126 | if not os.path.isfile(pn + ".bit.bin"): | ||
127 | bb.fatal("Couldn't find %s file, Enable '-log trace' in BOOTGEN_FLAGS" \ | ||
128 | "and check bootgen_log.txt" % (d.getVar('B') + '/' + pn + '.bit.bin')) | ||
129 | } | ||
130 | |||
131 | do_install() { | ||
132 | install -d ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
133 | |||
134 | # In case of dtbo as input, dtbo will be copied from directly from ${S} | ||
135 | # In case of dtsi as input, dtbo will be copied from directly from ${B} | ||
136 | if [ -f ${S}/*.dtbo ]; then | ||
137 | install -Dm 0644 ${S}/*.dtbo ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
138 | elif [ -f ${B}/*.dtbo ]; then | ||
139 | install -Dm 0644 ${B}/*.dtbo ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.dtbo | ||
140 | else | ||
141 | bbfatal "A dtbo ending '.dtbo' expected but not found" | ||
142 | fi | ||
143 | |||
144 | if [ "${SOC_FAMILY}" == "versal" ]; then | ||
145 | # In case of dtbo as input, pdi will be copied from directly from ${S} | ||
146 | # without renaming the pdi name to ${PN}.pdi | ||
147 | if [ -f ${S}/*.pdi ] && [ -f ${S}/*.dtbo ]; then | ||
148 | install -Dm 0644 ${S}/*.pdi ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
149 | elif [ -f ${S}/*.pdi ] && [ -f ${B}/*.dtbo ]; then | ||
150 | install -Dm 0644 ${S}/*.pdi ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.pdi | ||
151 | else | ||
152 | bbfatal "A PDI file with '.pdi' expected but not found" | ||
153 | fi | ||
154 | else | ||
155 | # In case of dtbo as input, .bit or .bit.in will be copied from directly | ||
156 | # from ${S} without renaming the .bit name to ${PN}.bit.bin | ||
157 | if [ -f ${S}/*.bit* ] && [ -f ${S}/*.dtbo ]; then | ||
158 | install -Dm 0644 ${S}/*.bit* ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
159 | elif [ -f ${B}/${PN}.bit.bin ] && [ -f ${B}/*.dtbo ]; then | ||
160 | install -Dm 0644 ${B}/${PN}.bit.bin ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.bit.bin | ||
161 | else | ||
162 | bbfatal "A bitstream file with '.bit' or '.bit.bin' expected but not found" | ||
163 | fi | ||
164 | fi | ||
165 | |||
166 | if ls ${S}/${XCL_PATH}/*.xclbin >/dev/null 2>&1; then | ||
167 | install -Dm 0644 ${S}/${XCL_PATH}/*.xclbin ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/${PN}.xclbin | ||
168 | fi | ||
169 | |||
170 | if [ -f ${S}/${JSON_PATH}/shell.json ] || [ -f ${S}/${JSON_PATH}/accel.json ]; then | ||
171 | install -Dm 0644 ${S}/${JSON_PATH}/*.json ${D}/${nonarch_base_libdir}/firmware/xilinx/${PN}/ | ||
172 | fi | ||
173 | } | ||
174 | |||
175 | do_deploy[noexec] = "1" | ||
176 | 23 | ||
177 | FILES:${PN} += "${nonarch_base_libdir}/firmware/xilinx/${PN}" | 24 | do_install[postfuncs] += "fpgamanager_warn_msg" \ No newline at end of file |