Index: common/cmd_cros.c |
diff --git a/common/cmd_cros.c b/common/cmd_cros.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..59637b83aba1bb197196bedc03392fceebab45d6 |
--- /dev/null |
+++ b/common/cmd_cros.c |
@@ -0,0 +1,168 @@ |
+/* |
+ * Copyright 2010, Google Inc. |
+ * All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are |
+ * met: |
+ * |
+ * * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following disclaimer |
+ * in the documentation and/or other materials provided with the |
+ * distribution. |
+ * * Neither the name of Google Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived from |
+ * this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ * |
+ * Alternatively, this software may be distributed under the terms of the |
+ * GNU General Public License ("GPL") version 2 as published by the Free |
+ * Software Foundation. |
+ */ |
+ |
+/* |
+ * Support Chrome OS Verify Boot |
+ */ |
+#include <common.h> |
+#include <command.h> |
+#include <part.h> |
+#include <boot_device.h> |
+ |
+#define USAGE(ret, cmdtp, fmt, args...) do { \ |
+ printf(fmt, args); \ |
+ cmd_usage(cmdtp); \ |
+ return (ret); \ |
+} while (0); |
+ |
+block_dev_desc_t *get_bootdev(void); |
+int set_bootdev(char *ifname, int dev, int part); |
+ |
+int do_cros (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
+int do_bootdev (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
+int do_cros_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); |
+ |
+U_BOOT_CMD(cros, CONFIG_SYS_MAXARGS, 1, do_cros, |
+ "perform action (try \"cros help\")", |
+ "[action [args...]]\n - perform action with arguments" |
+); |
+ |
+cmd_tbl_t cmd_cros_sub[] = { |
+ U_BOOT_CMD_MKENT(bootdev, 4, 1, do_bootdev, |
+ "show/set/read/write boot device", |
+ "[sub-action args...]\n - perform sub-action\n" |
+ "\n" |
+ "Subactions:\n" |
+ " - show boot device (when no sub-action)\n" |
+ "set iface dev [part]\n - set boot device\n" |
+ "read addr block count\n - read from boot device\n" |
+ "write addr block count\n - write to boot device"), |
+ U_BOOT_CMD_MKENT(help, 1, 1, do_cros_help, |
+ "show this message", |
+ "[action]") |
+}; |
+ |
+int do_cros(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
+{ |
+ cmd_tbl_t *c; |
+ |
+ if (argc < 2) |
+ USAGE(0, cmdtp, "Missing action\n"); |
+ |
+ c = find_cmd_tbl(argv[1], &cmd_cros_sub[0], ARRAY_SIZE(cmd_cros_sub)); |
+ if (!c) |
+ USAGE(1, cmdtp, "Unrecognized action: %s\n", argv[1]); |
+ |
+ return c->cmd(c, flag, argc - 1, argv + 1); |
+} |
+ |
+int do_bootdev(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
+{ |
+ enum { |
+ SET, READ, WRITE |
+ } opcode; |
+ |
+ block_dev_desc_t *dev_desc; |
+ int dev, part, retcode; |
+ uint64_t blk, cnt; |
+ void *buf; |
+ |
+ if (argc < 2) { /* show boot device information */ |
+ if ((dev_desc = get_bootdev()) == NULL) |
+ puts("No boot device set\n"); |
+ else |
+ dev_print(dev_desc); |
+ return 0; |
+ } |
+ |
+ if (!strcmp(argv[1], "set")) |
+ opcode = SET; |
+ else if (!strcmp(argv[1], "read")) |
+ opcode = READ; |
+ else if (!strcmp(argv[1], "write")) |
+ opcode = WRITE; |
+ else |
+ USAGE(1, cmdpt, "Unrecognized action: %s\n", argv[1]); |
+ |
+ /* apply De Morgan's laws on |
+ * !((argc == 4 && opcode == SET) || argc == 5) */ |
+ if ((argc != 4 || opcode != SET) && argc != 5) |
+ USAGE(1, cmdtp, "Wrong number of arguments\n"); |
+ |
+ if (opcode == SET) { |
+ dev = (int) simple_strtoul(argv[3], NULL, 16); |
+ part = (argc == 5) ? |
+ 0 : (int) simple_strtoul(argv[4], NULL, 16); |
+ |
+ if (set_bootdev(argv[2], dev, part)) { |
+ puts("Set bootdev failed\n"); |
+ return 1; |
+ } |
+ |
+ return 0; |
+ } |
+ |
+ /* assert(opcode == READ || opcode == WRITE); */ |
+ |
+ buf = (void *) simple_strtoul(argv[2], NULL, 16); |
+ blk = (uint64_t) simple_strtoul(argv[3], NULL, 16); |
+ cnt = (uint64_t) simple_strtoul(argv[4], NULL, 16); |
+ |
+ retcode = (opcode == READ) ? |
+ BootDeviceReadLBA(blk, cnt, buf) : |
+ BootDeviceWriteLBA(blk, cnt, buf); |
+ |
+ if (retcode) |
+ USAGE(1, cmdtp, opcode == READ ? |
+ "Read failed\n" : "Write failed\n"); |
+ |
+ return 0; |
+} |
+ |
+int do_cros_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
+{ |
+ cmd_tbl_t *c; |
+ |
+ if (argc < 2) |
+ return _do_help(&cmd_cros_sub[0], ARRAY_SIZE(cmd_cros_sub), |
+ cmdtp, flag, argc, argv); |
+ |
+ c = find_cmd_tbl(argv[1], &cmd_cros_sub[0], ARRAY_SIZE(cmd_cros_sub)); |
+ if (!c) |
+ USAGE(1, cmdtp, "Unrecognized action: %s\n", argv[1]); |
+ |
+ cmd_usage(c); |
+ return 0; |
+} |