1 /*
2  * Copyright (c) 2014 Brian Swetland
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <sys/types.h>
31 
32 #include "liblkboot.h"
33 
usage(void)34 void usage(void)
35 {
36     fprintf(stderr,
37             "usage: lkboot <hostname> <command> ...\n"
38             "\n"
39             "       lkboot <hostname> flash <partition> <filename>\n"
40             "       lkboot <hostname> erase <partition>\n"
41             "       lkboot <hostname> remove <partition>\n"
42             "       lkboot <hostname> fpga <bitfile>\n"
43             "       lkboot <hostname> boot <binary>\n"
44             "       lkboot <hostname> getsysparam <name>\n"
45             "       lkboot <hostname> reboot\n"
46             "       lkboot <hostname> :<commandname> [ <arg>* ]\n"
47             "\n"
48             "NOTE: If <hostname> is 'jtag', lkboot will attempt to use\n"
49             "       a tool 'zynq-dcc' to communicate with the device.\n"
50             "       Make sure it is in your path.\n"
51             "\n"
52            );
53     exit(1);
54 }
55 
printsysparam(void * data,int len)56 void printsysparam(void *data, int len)
57 {
58     unsigned char *x = data;
59     int i;
60     for (i = 0; i < len; i++) {
61         if ((x[i] < ' ') || (x[1] > 127)) goto printhex;
62     }
63     write(STDERR_FILENO, "\"", 1);
64     write(STDERR_FILENO, data, len);
65     write(STDERR_FILENO, "\"\n", 2);
66     return;
67 printhex:
68     fprintf(stderr, "[");
69     for (i = 0; i < len; i++) fprintf(stderr, " %02x", x[i]);
70     fprintf(stderr, " ]\n");
71 }
72 
main(int argc,char ** argv)73 int main(int argc, char **argv)
74 {
75     const char *host = argv[1];
76     const char *cmd = argv[2];
77     const char *args = argv[3];
78     const char *fn = NULL;
79     int fd = -1;
80 
81     if (argc == 3) {
82         if (!strcmp(cmd, "reboot")) {
83             return lkboot_txn(host, cmd, fd, "");
84         } else if (cmd[0] == ':') {
85             return lkboot_txn(host, cmd + 1, fd, "");
86         } else {
87             usage();
88         }
89     }
90 
91     if (argc < 4) usage();
92 
93     if (!strcmp(cmd, "flash")) {
94         if (argc < 5) usage();
95         fn = argv[4];
96     } else if (!strcmp(cmd, "fpga")) {
97         fn = args;
98         args = "";
99     } else if (!strcmp(cmd, "boot")) {
100         fn = args;
101         args = "";
102     } else if (!strcmp(cmd, "erase")) {
103     } else if (!strcmp(cmd, "remove")) {
104     } else if (!strcmp(cmd, "getsysparam")) {
105         if (lkboot_txn(host, cmd, -1, args) == 0) {
106             void *rbuf = NULL;
107             printsysparam(rbuf, lkboot_get_reply(&rbuf));
108             return 0;
109         } else {
110             return -1;
111         }
112     } else if (cmd[0] == ':') {
113         return lkboot_txn(host, cmd + 1, -1, args);
114     } else {
115         usage();
116     }
117     if (fn) {
118         if ((fd = open(fn, O_RDONLY)) < 0) {
119             fprintf(stderr, "error; cannot open '%s'\n", fn);
120             return -1;
121         }
122     }
123     return lkboot_txn(host, cmd, fd, args);
124 }
125