📄 bfload.c
字号:
upci_reset(); printf( "Finished!\n" ); return 0;}// NOTE: can only list PCI devices, no EPP devicesvoid list_devices(void) { int r; int pci_index; int num_pci_devices; int num_boards; r = upci_scan_bus(); if (r < 0) { errmsg(__func__,"upci error scanning bus"); exit(EC_SYS); } num_pci_devices = r; num_boards = sizeof(board_info_table) / sizeof(struct board_info); for (pci_index = 0; pci_index < num_pci_devices; pci_index ++) { struct upci_dev_info p; int board_index; upci_get_device_info(&p, pci_index); // see if this pci device is in the board table for (board_index = 0; board_index < num_boards; board_index ++) { struct board_info *board = &board_info_table[board_index]; if (board->io_type != IO_TYPE_PCI) continue; if (board->io.pci.vendor_id != p.vendor_id) continue; if (board->io.pci.device_id != p.device_id) continue; if (board->io.pci.ss_vendor_id != p.ss_vendor_id) continue; if (board->io.pci.ss_device_id != p.ss_device_id) continue; printf("%s at PCI %02x:%02x.%x\n", board->board_type, p.bus, p.dev, p.func); } } exit(EC_OK);}/************************************************************************/static void errmsg(const char *funct, const char *fmt, ...){ va_list vp; va_start(vp, fmt); fprintf(stderr, "ERROR in %s(): ", funct); vfprintf(stderr, fmt, vp); fprintf(stderr, "\n");}static void usage(void) { printf("usage:\n"); printf(" bfload help\n"); printf(" bfload list\n"); printf(" bfload BoardType[:BoardIdentifier]=BitFile\n"); printf(" bfload <filename> [<card>]\n"); printf("\n"); printf("help: Show this usage information.\n"); printf("\n"); printf("list: List PCI Anything I/O boards detected on this system.\n"); printf("\n"); printf("The 'BoardType[:BoardIdentifier]=BitFile' command-line format is the\n"); printf("prefered way to program an FPGA:\n"); printf(" BoardType is one of the supported board types.\n"); printf(" BoardIdentifier specifies which board of that type to program.\n"); printf(" The format depends on the board type. For PCI boards it's an\n"); printf(" integer specifying the N'th board of that type (default 0). For EPP\n"); printf(" boards it's 'IOAddr[,IOAddrHigh]' (default is '0x378', IOAddrHigh\n"); printf(" defaults to IOAddr + 0x400).\n"); printf(" BitFile is the FPGA program to send.\n"); printf("\n"); printf("The '<filename> [<card>]' command-line format is deprecated and will be\n"); printf("removed in a future version of bfload:\n"); printf(" <filename> - name of bitfile\n"); printf(" <cardnum> - card number (default is 0)\n"); printf("\n"); printf("Loads an FPGA configuration from a bitfile into a\n"); printf("Mesa 5i20 or 5i22 FPGA. If the bitfile contains HAL driver\n"); printf("config data, writes that data to the FPGA's RAM.\n"); printf("The type of card is deduced from the FPGA type info in the bitfile.\n"); printf("Card types are numbered independently\n"); printf("\n");}int program_pci_board(struct board_info *board, char *device_id, struct bitfile *bf);int program_epp_board(struct board_info *board, char *device_id, struct bitfile *bf);int program(char *device_type, char *device_id, char *filename) { struct bitfile *bf; char *bitfile_chip; struct bitfile_chunk *ch; struct board_info *board; int found_device_type; int num_boards; int i, r; // // open the bitfile // bf = open_bitfile_or_die(filename); // chunk 'b' has the bitfile's target device, the chip type it's for ch = bitfile_find_chunk(bf, 'b', 0); bitfile_chip = (char *)(ch->body); // // look up the device type that the caller requested in our table of // known device types // num_boards = sizeof(board_info_table) / sizeof(struct board_info); board = NULL; found_device_type = 0; for (i = 0; i < num_boards; i ++) { if (strcmp(board_info_table[i].board_type, device_type) == 0) { found_device_type = 1; if (strcmp(board_info_table[i].chip_type, bitfile_chip) == 0) { board = &board_info_table[i]; break; } } } if (!found_device_type) { printf("board type '%s' is unknown\n", device_type); return -1; } if (board == NULL) { printf("chip type incompatibility\n"); printf("board type '%s' is not available with bitfile's FPGA type '%s'\n", device_type, bitfile_chip); return -1; } // // At this point the program has identified the board type (it's in // "board") and read in the bitfile (it's in "bf"). // // Next we need to parse the device_id to find out *which* board of the // required type we're supposed to program. // r = 0; switch (board->io_type) { case IO_TYPE_PCI: r = program_pci_board(board, device_id, bf); break; case IO_TYPE_EPP: r = program_epp_board(board, device_id, bf); break; default: printf("don't know how to parse %s device id '%s'\n", board->board_type, device_id); return -1; } if (r != 0) { return -1; } printf("it worked!\n"); exit(0);}int program_pci_board(struct board_info *board, char *device_id, struct bitfile *bf) { struct bitfile_chunk *ch; int board_num; struct upci_dev_info info; int r; if (device_id == NULL) { board_num = 0; } else { char *endp; board_num = strtol(device_id, &endp, 0); if (*endp != '\0') { printf("error parsing board number from '%s'\n", device_id); return EC_BADCL; } } // // find the PCI board // r = upci_scan_bus(); if (r < 0) { errmsg(__func__, "PCI bus data missing"); return EC_SYS; } info.vendor_id = board->io.pci.vendor_id; info.device_id = board->io.pci.device_id; info.ss_vendor_id = board->io.pci.ss_vendor_id; info.ss_device_id = board->io.pci.ss_device_id; info.instance = board_num; board->io.pci.upci_devnum = upci_find_device(&info); if (board->io.pci.upci_devnum < 0) { errmsg(__func__, "%s board #%d not found", board->board_type, board_num); return EC_HDW; } upci_print_device_info(board->io.pci.upci_devnum); // // program the board with the bitfile // /* chunk 'e' has the bitstream */ ch = bitfile_find_chunk(bf, 'e', 0); printf ("Loading configuration %s into %s:%d board...\n", bf->filename, board->board_type, board_num); r = board->program_funct(board, ch); if (r != 0) { errmsg(__func__, "configuration did not load"); return EC_HDW; } /* do we need to HAL driver data to the FGPA RAM? */ // HostMot2 does not use this ch = bitfile_find_chunk(bf, 'r', 0); if (ch != NULL) { printf ("Writing data to FPGA RAM\n"); r = write_fpga_ram(board, ch); if (r != 0) { errmsg(__func__, "RAM data could not be loaded"); return EC_HDW; } } upci_reset(); return 0;}int program_epp_board(struct board_info *board, char *device_id, struct bitfile *bf) { struct bitfile_chunk *ch; int r; // this snippet of code is nasty // i hate doing text parsing in c if (device_id == NULL) { // use default io addr for parallel port } else { // Format: io_addr[,io_addr_lo] char *endp; char *endp2; board->io.epp.io_addr = strtol(device_id, &endp, 0); if (endp == device_id) { printf("cannot parse EPP address from '%s'\n", device_id); return EC_BADCL; } if (*endp == '\0') { board->io.epp.io_addr_hi = board->io.epp.io_addr + 0x400; } else { if (*endp != ',') { printf("cannot parse EPP address from '%s'\n", device_id); return EC_BADCL; } endp ++; if (*endp == '\0') { board->io.epp.io_addr_hi = board->io.epp.io_addr + 0x400; } else { board->io.epp.io_addr_hi = strtol(endp, &endp2, 0); if (*endp2 != '\0') { printf("cannot parse EPP address from '%s'\n", device_id); return EC_BADCL; } } } } printf("%s board at 0x%04x,0x%04x\n", board->board_type, board->io.epp.io_addr, board->io.epp.io_addr_hi); // get access the the parport i/o addresses if (iopl(3) != 0) { printf("error getting I/O port access: %s\n", strerror(errno)); return EC_SYS; } // // program the board with the bitfile // /* chunk 'e' has the bitstream */ ch = bitfile_find_chunk(bf, 'e', 0); printf( "Loading configuration %s into %s:0x%04x,0x%04x board...\n", bf->filename, board->board_type, board->io.epp.io_addr, board->io.epp.io_addr_hi ); r = board->program_funct(board, ch); if (r != 0) { errmsg(__func__, "configuration did not load"); return EC_HDW; } return 0;}// try to execute a new-style programming command// new style is: CardType[:CardID]=FileNameint parse_program_command(char *cmd) { char *filename; char *device_type; char *device_id; struct stat stat_buf; int r; printf("trying to parse '%s' as a new-style command-line...\n", cmd); // first parse out the filename filename = strchr(cmd, '='); if (filename == NULL) return -1; *filename = '\0'; filename ++; r = stat(filename, &stat_buf); if (r != 0) { errmsg(__func__, "error stating '%s': %s\n", filename, strerror(errno)); return -1; } // parse out the device id device_id = strchr(cmd, ':'); if (device_id != NULL) { *device_id = '\0'; device_id ++; if (*device_id == '\0') { device_id = NULL; } } device_type = cmd; if (*device_type == '\0') { errmsg(__func__, "no device type specified\n"); return -1; } return program(device_type, device_id, filename);}static int parse_cmdline(unsigned argc, char *argv[]){ struct stat stat_buf; int r; if (argc == 2) { if (strcmp(argv[1], "list") == 0) { list_devices(); exit(EC_OK); } else if (strcmp(argv[1], "help") == 0) { usage(); exit(EC_OK); } } if ((argc != 2) && (argc != 3)) { usage(); return -1; } // // try to detect if it's a new-style or old-style command-line // old style is: FileName [CardNum] // new style is: CardType[:CardID]=FileName // r = stat(argv[1], &stat_buf); if (r == 0) { // looks like an old-style command-line printf("\n"); printf("WARNING: You're using the old-style command-line. This is deprecated, and\n"); printf("support for it will go away in a future version of bfload!\n"); printf("Run 'bfload help' to learn about the new-style command-line.\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -