diff options
| author | Varalaxmi Bingi <varalaxmi.bingi@xilinx.com> | 2022-04-27 16:50:18 +0530 |
|---|---|---|
| committer | Mark Hatle <mhatle@xilinx.com> | 2022-04-28 06:56:59 -0700 |
| commit | e75c70e4db78afa8f5c5ec1790359ede5e8bf00e (patch) | |
| tree | 3931638ed2a626865d3e353291425f42e81a7246 | |
| parent | 9097f6a96da97bad6a688d0bee40f03423b21d7b (diff) | |
| download | meta-xilinx-e75c70e4db78afa8f5c5ec1790359ede5e8bf00e.tar.gz | |
fpga-manager-script: adding this recipe to meta-xilinx
This fpgautil recipe was part of meta-xilinx-tools.
This is required in decoupling flow as well
till dfx mgr gets stabled and meta-xilinx-tools layer will
no be there in decoupling flow.
So moving this recipe to meta-xilinx.
Signed-off-by: Varalaxmi Bingi <varalaxmi.bingi@xilinx.com>
Signed-off-by: Mark Hatle <mhatle@xilinx.com>
| -rw-r--r-- | meta-xilinx-core/recipes-bsp/fpga-manager-script/files/fpgautil.c | 464 | ||||
| -rw-r--r-- | meta-xilinx-core/recipes-bsp/fpga-manager-script/fpga-manager-script_1.0.bb | 23 |
2 files changed, 487 insertions, 0 deletions
diff --git a/meta-xilinx-core/recipes-bsp/fpga-manager-script/files/fpgautil.c b/meta-xilinx-core/recipes-bsp/fpga-manager-script/files/fpgautil.c new file mode 100644 index 00000000..0b77569d --- /dev/null +++ b/meta-xilinx-core/recipes-bsp/fpga-manager-script/files/fpgautil.c | |||
| @@ -0,0 +1,464 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * Copyright (C) 2019-2020 Xilinx, Inc. All rights reserved. | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 6 | * this software and associated documentation files (the "Software"), to deal in | ||
| 7 | * the Software without restriction, including without limitation the rights to | ||
| 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
| 9 | * of the Software, and to permit persons to whom the Software is furnished to do | ||
| 10 | * so, subject to the following conditions: | ||
| 11 | * | ||
| 12 | * The above copyright notice and this permission notice shall be included in all | ||
| 13 | * copies or substantial portions of the Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 21 | * SOFTWARE. | ||
| 22 | * | ||
| 23 | ******************************************************************************/ | ||
| 24 | /*****************************************************************************/ | ||
| 25 | /** | ||
| 26 | * @file: fpgautil.c | ||
| 27 | * Simple command line tool to load fpga via overlay or through sysfs interface | ||
| 28 | * and read fpga configuration using Xilinx Zynq/ZynqMP fpga manager | ||
| 29 | * Author: Appana Durga Kedareswara Rao <appanad@xilinx.com> | ||
| 30 | * Author: Nava kishore Manne <navam@xilinx.com> | ||
| 31 | */ | ||
| 32 | #include <stdbool.h> | ||
| 33 | #include <stdio.h> | ||
| 34 | #include <stdlib.h> | ||
| 35 | #include <string.h> | ||
| 36 | #include <unistd.h> | ||
| 37 | #include <string.h> | ||
| 38 | #include <signal.h> | ||
| 39 | #include <getopt.h> | ||
| 40 | #include <poll.h> | ||
| 41 | #include <ctype.h> | ||
| 42 | #include <libgen.h> | ||
| 43 | #include <time.h> | ||
| 44 | #include <errno.h> | ||
| 45 | #include <sys/time.h> | ||
| 46 | #include <sys/stat.h> | ||
| 47 | |||
| 48 | #define OVERLAY 1 | ||
| 49 | #define FPGA_SYSFS 2 | ||
| 50 | #define READBACK 3 | ||
| 51 | #define ENCRYPTION_USERKEY_EN (0x20U) | ||
| 52 | |||
| 53 | int fpga_getplatform() | ||
| 54 | { | ||
| 55 | char fpstr[100]; | ||
| 56 | FILE *fptr; | ||
| 57 | char *zynqmpstr = "Xilinx ZynqMP FPGA Manager"; | ||
| 58 | |||
| 59 | if ((fptr = fopen("/sys/class/fpga_manager/fpga0/name", "r")) == NULL) | ||
| 60 | { | ||
| 61 | printf("Error! opening file"); | ||
| 62 | // Program exits if file pointer returns NULL. | ||
| 63 | exit(1); | ||
| 64 | } | ||
| 65 | |||
| 66 | // reads text until newline | ||
| 67 | fscanf(fptr,"%[^\n]", fpstr); | ||
| 68 | fclose(fptr); | ||
| 69 | |||
| 70 | if (!strcmp(zynqmpstr, fpstr)) | ||
| 71 | return 1; | ||
| 72 | else | ||
| 73 | return 0; | ||
| 74 | |||
| 75 | } | ||
| 76 | |||
| 77 | void print_usage(char *prg) | ||
| 78 | { | ||
| 79 | int iszynqmp = fpga_getplatform(); | ||
| 80 | |||
| 81 | fprintf(stderr, "\n%s: FPGA Utility for Loading/reading PL Configuration\n\n", prg); | ||
| 82 | fprintf(stderr, "Usage: %s -b <bin file path> -o <dtbo file path>\n\r", prg); | ||
| 83 | fprintf(stderr, "\n"); | ||
| 84 | fprintf(stderr, "Options: -b <binfile> (Bin file path)\n"); | ||
| 85 | fprintf(stderr, " -o <dtbofile> (DTBO file path)\n"); | ||
| 86 | fprintf(stderr, " -f <flags> Optional: <Bitstream type flags>\n"); | ||
| 87 | fprintf(stderr, " f := <Full | Partial > \n"); | ||
| 88 | fprintf(stderr, " -n <Fpga region info> FPGA Regions represent FPGA's\n"); | ||
| 89 | fprintf(stderr, " and partial reconfiguration\n"); | ||
| 90 | fprintf(stderr, " regions of FPGA's in the\n"); | ||
| 91 | fprintf(stderr, " Device Tree\n"); | ||
| 92 | if (iszynqmp) | ||
| 93 | { | ||
| 94 | fprintf(stderr, " Default: <Full>\n"); | ||
| 95 | fprintf(stderr, " -s <secure flags> Optional: <Secure flags>\n"); | ||
| 96 | fprintf(stderr, " s := <AuthDDR | AuthOCM | EnUsrKey | EnDevKey | AuthEnUsrKeyDDR | AuthEnUsrKeyOCM | AuthEnDevKeyDDR | AuthEnDevKeyOCM>\n"); | ||
| 97 | fprintf(stderr, " -k <AesKey> Optional: <AES User Key>\n"); | ||
| 98 | fprintf(stderr, " -r <Readback> Optional: <file name>\n"); | ||
| 99 | fprintf(stderr, " Default: By default Read back contents will be stored in readback.bin file\n"); | ||
| 100 | fprintf(stderr, " -t Optional: <Readback Type>\n"); | ||
| 101 | fprintf(stderr, " 0 - Configuration Register readback\n"); | ||
| 102 | fprintf(stderr, " 1 - Configuration Data Frames readback\n"); | ||
| 103 | fprintf(stderr, " Default: 0 (Configuration register readback)\n"); | ||
| 104 | fprintf(stderr, " -R Optional: Remove overlay from a live tree\n"); | ||
| 105 | } | ||
| 106 | |||
| 107 | fprintf(stderr, " \n"); | ||
| 108 | fprintf(stderr, "Examples:\n"); | ||
| 109 | fprintf(stderr, "(Load Full bitstream using Overlay)\n"); | ||
| 110 | fprintf(stderr, "%s -b top.bit.bin -o can.dtbo -f Full -n Full \n", prg); | ||
| 111 | fprintf(stderr, "(Load Partial bitstream using Overlay)\n"); | ||
| 112 | fprintf(stderr, "%s -b rm0.bit.bin -o rm0.dtbo -f Partial -n PR0\n", prg); | ||
| 113 | fprintf(stderr, "(Load Full bitstream using sysfs interface)\n"); | ||
| 114 | fprintf(stderr, "%s -b top.bit.bin -f Full\n", prg); | ||
| 115 | fprintf(stderr, "(Load Partial bitstream using sysfs interface)\n"); | ||
| 116 | fprintf(stderr, "%s -b rm0.bit.bin -f Partial\n", prg); | ||
| 117 | if (iszynqmp) | ||
| 118 | { | ||
| 119 | fprintf(stderr, "(Load Authenticated bitstream through the sysfs interface)\n"); | ||
| 120 | fprintf(stderr, "%s -b top.bit.bin -f Full -s AuthDDR \n", prg); | ||
| 121 | fprintf(stderr, "(Load Parital Encrypted Userkey bitstream using Overlay)\n"); | ||
| 122 | fprintf(stderr, "%s -b top.bit.bin -o pl.dtbo -f Partial -s EnUsrKey -k <32byte key value>\n", prg); | ||
| 123 | fprintf(stderr, "(Read PL Configuration Registers)\n"); | ||
| 124 | fprintf(stderr, "%s -b top.bit.bin -r\n", prg); | ||
| 125 | } | ||
| 126 | fprintf(stderr, " \n"); | ||
| 127 | } | ||
| 128 | |||
| 129 | int gettime(struct timeval t0, struct timeval t1) | ||
| 130 | { | ||
| 131 | return ((t1.tv_sec - t0.tv_sec) * 1000.0f + (t1.tv_usec -t0.tv_usec) / 1000.0f); | ||
| 132 | } | ||
| 133 | |||
| 134 | int fpga_state() | ||
| 135 | { | ||
| 136 | FILE *fptr; | ||
| 137 | char buf[10]; | ||
| 138 | char *state_operating = "operating"; | ||
| 139 | char *state_unknown = "unknown"; | ||
| 140 | |||
| 141 | system("cat /sys/class/fpga_manager/fpga0/state >> state.txt"); | ||
| 142 | fptr = fopen("state.txt", "r"); | ||
| 143 | if (fptr) { | ||
| 144 | fgets(buf, 10, fptr); | ||
| 145 | fclose(fptr); | ||
| 146 | system("rm state.txt"); | ||
| 147 | if ((strncmp(buf, state_operating, 9) == 0) || (strncmp(buf, state_unknown, 7) == 0)) | ||
| 148 | return 0; | ||
| 149 | else | ||
| 150 | return 1; | ||
| 151 | } | ||
| 152 | |||
| 153 | return 1; | ||
| 154 | } | ||
| 155 | |||
| 156 | static int fpga_overlay_check(char *cmd, char *state) | ||
| 157 | { | ||
| 158 | char buf[512]; | ||
| 159 | FILE *fptr; | ||
| 160 | int len; | ||
| 161 | |||
| 162 | system(cmd); | ||
| 163 | len = strlen(state) + 1; | ||
| 164 | fptr = fopen("state.txt", "r"); | ||
| 165 | if (fptr) { | ||
| 166 | fgets(buf, len, fptr); | ||
| 167 | fclose(fptr); | ||
| 168 | system("rm state.txt"); | ||
| 169 | if (!strcmp(buf, state)) | ||
| 170 | return 0; | ||
| 171 | else | ||
| 172 | return 1; | ||
| 173 | } | ||
| 174 | |||
| 175 | return 1; | ||
| 176 | } | ||
| 177 | |||
| 178 | struct fpgaflag { | ||
| 179 | char *flag; | ||
| 180 | unsigned int value; | ||
| 181 | }; | ||
| 182 | |||
| 183 | static struct fpgaflag flagdump[] = { | ||
| 184 | {.flag = "Full", .value = 0x0}, | ||
| 185 | {.flag = "Partial", .value = 0x1}, | ||
| 186 | {.flag = "AuthDDR", .value = 0x40}, | ||
| 187 | {.flag = "AuthOCM", .value = 0x80}, | ||
| 188 | {.flag = "EnUsrKey", .value = 0x20}, | ||
| 189 | {.flag = "EnDevKey", .value = 0x4}, | ||
| 190 | {.flag = "AuthEnUsrKeyDDR", .value = 0x60}, | ||
| 191 | {.flag = "AuthEnUsrKeyOCM", .value = 0xA0}, | ||
| 192 | {.flag = "AuthEnDevKeyDDR", .value = 0x44}, | ||
| 193 | {.flag = "AuthEnDevKeyOCM", .value = 0x84}, | ||
| 194 | {} | ||
| 195 | }; | ||
| 196 | |||
| 197 | static int cmd_flags(int argc, const char *name) | ||
| 198 | { | ||
| 199 | int valid_flag = 0; | ||
| 200 | int flag = 0; | ||
| 201 | struct fpgaflag *p = flagdump; | ||
| 202 | |||
| 203 | while (p->flag) { | ||
| 204 | if (!strcmp(name, p->flag)) { | ||
| 205 | flag = p->value; | ||
| 206 | break; | ||
| 207 | } | ||
| 208 | p++; | ||
| 209 | } | ||
| 210 | |||
| 211 | return flag; | ||
| 212 | } | ||
| 213 | |||
| 214 | static int isvalid_flags(int argc, const char *name, bool is_secure) | ||
| 215 | { | ||
| 216 | int valid_flag = 0; | ||
| 217 | int count = 0; | ||
| 218 | struct fpgaflag *p; | ||
| 219 | |||
| 220 | if (!is_secure) | ||
| 221 | p = flagdump; | ||
| 222 | else | ||
| 223 | p = &flagdump[2]; | ||
| 224 | |||
| 225 | while (p->flag) { | ||
| 226 | if (!strcmp(name, p->flag)) | ||
| 227 | return 0; | ||
| 228 | else if ((!is_secure) && (++count == 2)) | ||
| 229 | return 1; | ||
| 230 | p++; | ||
| 231 | } | ||
| 232 | |||
| 233 | return 1; | ||
| 234 | } | ||
| 235 | |||
| 236 | int main(int argc, char **argv) | ||
| 237 | { | ||
| 238 | int ret; | ||
| 239 | int iszynqmp = fpga_getplatform(); | ||
| 240 | char *binfile = NULL, *overlay = NULL, *AesKey = NULL, *flag = NULL, *partial_overlay = NULL; | ||
| 241 | char *region = NULL, *Module[100] = {0}; | ||
| 242 | int opt, flags = 0, flow = 0,rm_overlay = 0, readback_type = 0, sflags = 0; | ||
| 243 | char command[2048], folder[512], *token, *tmp, *tmp1, *tmp2 , *tmp3; | ||
| 244 | const char *filename = "readback", *name; | ||
| 245 | struct stat sb; | ||
| 246 | double time; | ||
| 247 | struct timeval t1, t0; | ||
| 248 | |||
| 249 | if (argc == 1) { | ||
| 250 | print_usage(basename(argv[0])); | ||
| 251 | return 1; | ||
| 252 | } | ||
| 253 | |||
| 254 | while ((opt = getopt(argc, argv, "o:b:n:f:s:p:k:rt::Rh?:")) != -1) { | ||
| 255 | switch (opt) { | ||
| 256 | case 'o': | ||
| 257 | overlay = optarg; | ||
| 258 | flow = OVERLAY; | ||
| 259 | break; | ||
| 260 | case 'b': | ||
| 261 | binfile = optarg; | ||
| 262 | if (!(flow == OVERLAY)) | ||
| 263 | flow = FPGA_SYSFS; | ||
| 264 | break; | ||
| 265 | case 'n': | ||
| 266 | region = optarg; | ||
| 267 | break; | ||
| 268 | case 'f': | ||
| 269 | if (flow == OVERLAY) { | ||
| 270 | name = argv[6]; | ||
| 271 | flags = cmd_flags(argc, name); | ||
| 272 | } else if (flow == FPGA_SYSFS) { | ||
| 273 | name = argv[4]; | ||
| 274 | flags = cmd_flags(argc, name); | ||
| 275 | } | ||
| 276 | |||
| 277 | ret = isvalid_flags(argc, name, false); | ||
| 278 | if (ret) { | ||
| 279 | printf("Error: Invalid arugments :%s\n", strerror(1)); | ||
| 280 | print_usage(basename(argv[0])); | ||
| 281 | return -EINVAL; | ||
| 282 | } | ||
| 283 | |||
| 284 | flags += sflags; | ||
| 285 | break; | ||
| 286 | case 's': | ||
| 287 | if (flow == OVERLAY) { | ||
| 288 | name = argv[8]; | ||
| 289 | sflags = cmd_flags(argc, name); | ||
| 290 | } else if (flow == FPGA_SYSFS) { | ||
| 291 | name = argv[6]; | ||
| 292 | sflags = cmd_flags(argc, name); | ||
| 293 | } | ||
| 294 | |||
| 295 | ret = isvalid_flags(argc, name, true); | ||
| 296 | if (ret) { | ||
| 297 | printf("Error: Invalid arugments :%s\n", strerror(1)); | ||
| 298 | print_usage(basename(argv[0])); | ||
| 299 | return -EINVAL; | ||
| 300 | } | ||
| 301 | |||
| 302 | flags += sflags; | ||
| 303 | break; | ||
| 304 | case 'p': | ||
| 305 | partial_overlay = optarg; | ||
| 306 | break; | ||
| 307 | case 'k': | ||
| 308 | AesKey = optarg; | ||
| 309 | break; | ||
| 310 | case 't': | ||
| 311 | if (optarg == NULL && argv[4] != NULL) | ||
| 312 | readback_type = atoi(argv[4]); | ||
| 313 | break; | ||
| 314 | case 'r': | ||
| 315 | if (optarg == NULL && argv[2] != NULL) | ||
| 316 | filename = argv[2]; | ||
| 317 | flow = READBACK; | ||
| 318 | break; | ||
| 319 | case 'R': | ||
| 320 | rm_overlay = 1; | ||
| 321 | break; | ||
| 322 | case '?': | ||
| 323 | case 'h': | ||
| 324 | default: | ||
| 325 | print_usage(basename(argv[0])); | ||
| 326 | return 1; | ||
| 327 | break; | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 331 | if(region != NULL) | ||
| 332 | snprintf(folder, sizeof(folder), "/configfs/device-tree/overlays/%s", region); | ||
| 333 | else if (!(flags & 1)) | ||
| 334 | snprintf(folder, sizeof(folder), "/configfs/device-tree/overlays/full"); | ||
| 335 | else if (overlay != NULL) { | ||
| 336 | printf("Error: Provide valid Overlay region info\n\r"); | ||
| 337 | return 1; | ||
| 338 | } | ||
| 339 | system("mkdir -p /lib/firmware"); | ||
| 340 | if (rm_overlay) { | ||
| 341 | if (((stat(folder, &sb) == 0) && S_ISDIR(sb.st_mode))) { | ||
| 342 | snprintf(command, sizeof(command), "rmdir %s", folder); | ||
| 343 | system(command); | ||
| 344 | } | ||
| 345 | return 0; | ||
| 346 | } | ||
| 347 | |||
| 348 | if (flow == OVERLAY) { | ||
| 349 | if (((stat(folder, &sb) == 0) && S_ISDIR(sb.st_mode))) { | ||
| 350 | printf("Error: Overlay already exists in the live tree\n\r"); | ||
| 351 | return 1; | ||
| 352 | } | ||
| 353 | |||
| 354 | if (((stat("/configfs/device-tree/", &sb) == 0) && S_ISDIR(sb.st_mode))) { | ||
| 355 | } else { | ||
| 356 | system("mkdir /configfs"); | ||
| 357 | system("mount -t configfs configfs /configfs"); | ||
| 358 | } | ||
| 359 | |||
| 360 | if (binfile != NULL) { | ||
| 361 | snprintf(command, sizeof(command), "cp %s /lib/firmware", binfile); | ||
| 362 | system(command); | ||
| 363 | } | ||
| 364 | |||
| 365 | snprintf(command, sizeof(command), "cp %s /lib/firmware", overlay); | ||
| 366 | system(command); | ||
| 367 | tmp = strdup(overlay); | ||
| 368 | while((token = strsep(&tmp, "/"))) { | ||
| 369 | tmp1 = token; | ||
| 370 | } | ||
| 371 | |||
| 372 | if (binfile != NULL) { | ||
| 373 | snprintf(command, sizeof(command), "echo %x > /sys/class/fpga_manager/fpga0/flags", flags); | ||
| 374 | system(command); | ||
| 375 | if (ENCRYPTION_USERKEY_EN & flags) { | ||
| 376 | snprintf(command, sizeof(command), "echo %s > /sys/class/fpga_manager/fpga0/key", AesKey); | ||
| 377 | system(command); | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | snprintf(command, sizeof(command), "mkdir %s", folder); | ||
| 382 | system(command); | ||
| 383 | snprintf(command, sizeof(command), "echo -n %s > %s/path", tmp1, folder); | ||
| 384 | gettimeofday(&t0, NULL); | ||
| 385 | system(command); | ||
| 386 | gettimeofday(&t1, NULL); | ||
| 387 | time = gettime(t0, t1); | ||
| 388 | |||
| 389 | snprintf(command, sizeof(command), "cat %s/path >> state.txt", folder); | ||
| 390 | ret = fpga_overlay_check(command, tmp1); | ||
| 391 | if (ret) { | ||
| 392 | printf("Failed to apply Overlay\n\r"); | ||
| 393 | } | ||
| 394 | |||
| 395 | /* Delete Bin file and DTBO file*/ | ||
| 396 | snprintf(command, sizeof(command), "rm /lib/firmware/%s", tmp1); | ||
| 397 | system(command); | ||
| 398 | if (binfile != NULL) { | ||
| 399 | tmp = strdup(binfile); | ||
| 400 | while((token = strsep(&tmp, "/"))) { | ||
| 401 | tmp1 = token; | ||
| 402 | } | ||
| 403 | snprintf(command, sizeof(command), "rm /lib/firmware/%s", tmp1); | ||
| 404 | system(command); | ||
| 405 | } | ||
| 406 | |||
| 407 | /* FPGA state check */ | ||
| 408 | if (binfile != NULL) { | ||
| 409 | if (!fpga_state()) { | ||
| 410 | printf("Time taken to load BIN is %f Milli Seconds\n\r", time); | ||
| 411 | printf("BIN FILE loaded through FPGA manager successfully\n\r"); | ||
| 412 | } else { | ||
| 413 | printf("BIN FILE loading through FPGA manager failed\n\r"); | ||
| 414 | } | ||
| 415 | } | ||
| 416 | } else if (flow == FPGA_SYSFS) { | ||
| 417 | if (argc < 3) { | ||
| 418 | printf("%s: For more information run %s -h\n", strerror(22), basename(argv[0])); | ||
| 419 | return 1; | ||
| 420 | } | ||
| 421 | snprintf(command, sizeof(command), "cp %s /lib/firmware", binfile); | ||
| 422 | system(command); | ||
| 423 | snprintf(command, sizeof(command), "echo %x > /sys/class/fpga_manager/fpga0/flags", flags); | ||
| 424 | system(command); | ||
| 425 | if (ENCRYPTION_USERKEY_EN & flags) { | ||
| 426 | snprintf(command, sizeof(command), "echo %s > /sys/class/fpga_manager/fpga0/key", AesKey); | ||
| 427 | system(command); | ||
| 428 | } | ||
| 429 | tmp = strdup(binfile); | ||
| 430 | while((token = strsep(&tmp, "/"))) { | ||
| 431 | tmp1 = token; | ||
| 432 | } | ||
| 433 | snprintf(command, sizeof(command), "echo %s > /sys/class/fpga_manager/fpga0/firmware", tmp1); | ||
| 434 | gettimeofday(&t0, NULL); | ||
| 435 | system(command); | ||
| 436 | gettimeofday(&t1, NULL); | ||
| 437 | time = gettime(t0, t1); | ||
| 438 | |||
| 439 | /* Delete Bin file and DTBO file*/ | ||
| 440 | snprintf(command, sizeof(command), "rm /lib/firmware/%s", tmp1); | ||
| 441 | system(command); | ||
| 442 | |||
| 443 | /* FPGA state check */ | ||
| 444 | if (!fpga_state()) { | ||
| 445 | printf("Time taken to load BIN is %f Milli Seconds\n\r", time); | ||
| 446 | printf("BIN FILE loaded through FPGA manager successfully\n\r"); | ||
| 447 | } else { | ||
| 448 | printf("BIN FILE loading through FPGA manager failed\n\r"); | ||
| 449 | } | ||
| 450 | } else if (flow == READBACK) { | ||
| 451 | if (readback_type > 1) { | ||
| 452 | printf("Invalid arugments :%s\n", strerror(1)); | ||
| 453 | printf("For more information run %s -h\n", basename(argv[0])); | ||
| 454 | return -EINVAL; | ||
| 455 | } | ||
| 456 | snprintf(command, sizeof(command), "echo %x > /sys/module/zynqmp_fpga/parameters/readback_type", readback_type); | ||
| 457 | system(command); | ||
| 458 | snprintf(command, sizeof(command), "cat /sys/kernel/debug/fpga/fpga0/image >> %s.bin", filename); | ||
| 459 | system(command); | ||
| 460 | printf("Readback contents are stored in the file %s.bin\n\r", filename); | ||
| 461 | } | ||
| 462 | |||
| 463 | return 0; | ||
| 464 | } | ||
diff --git a/meta-xilinx-core/recipes-bsp/fpga-manager-script/fpga-manager-script_1.0.bb b/meta-xilinx-core/recipes-bsp/fpga-manager-script/fpga-manager-script_1.0.bb new file mode 100644 index 00000000..416edf17 --- /dev/null +++ b/meta-xilinx-core/recipes-bsp/fpga-manager-script/fpga-manager-script_1.0.bb | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | SUMMARY = "Install user script to support fpga-manager" | ||
| 2 | DESCRIPTION = "Install user script that loads and unloads overlays using kernel fpga-manager" | ||
| 3 | LICENSE = "Proprietary" | ||
| 4 | LIC_FILES_CHKSUM = "file://${WORKDIR}/fpgautil.c;beginline=1;endline=24;md5=8010e59a286b1e3a73a9fdd93bd18778" | ||
| 5 | |||
| 6 | SRC_URI = "\ | ||
| 7 | file://fpgautil.c \ | ||
| 8 | " | ||
| 9 | S = "${WORKDIR}" | ||
| 10 | |||
| 11 | FILESEXTRAPATHS:prepend := "${THISDIR}/files:" | ||
| 12 | |||
| 13 | do_compile() { | ||
| 14 | ${CC} ${LDFLAGS} fpgautil.c -o fpgautil | ||
| 15 | } | ||
| 16 | |||
| 17 | do_install() { | ||
| 18 | install -Dm 0755 ${S}/fpgautil ${D}${bindir}/fpgautil | ||
| 19 | } | ||
| 20 | |||
| 21 | FILES:${PN} = "\ | ||
| 22 | ${bindir}/fpgautil \ | ||
| 23 | " | ||
