From: Zhikang Zhang <zhikang.zhang@nxp.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC,v2 2/2] NVMe: add nvme commands
Date: Fri, 21 Apr 2017 11:01:29 +0800 [thread overview]
Message-ID: <1492743689-40341-3-git-send-email-zhikang.zhang@nxp.com> (raw)
In-Reply-To: <1492743689-40341-1-git-send-email-zhikang.zhang@nxp.com>
Add nvme commands in U-Boot command line.
1. "nvme list" - show all available NVMe blk devices
2. "nvme info" - show current or a specific NVMe blk device
3. "nvme device" - show or set current device
4. "nvme part" - print partition table
5. "nvme read" - read data from NVMe blk device
6. "nvme write" - write data to NVMe blk device
Signed-off-by: Zhikang Zhang <zhikang.zhang@nxp.com>
Signed-off-by: Wenbin Song <wenbin.song@nxp.com>
---
Changes for v2:
- remove the calling of "initialie" in fuction "do_nvmecops"
- change the function "do_nvme_info" to support BLK uclass
---
cmd/Kconfig | 9 +++
cmd/Makefile | 1 +
cmd/nvme.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
disk/part.c | 6 ++
doc/README.nvme | 54 ++++++++++++++++++
5 files changed, 243 insertions(+)
create mode 100644 cmd/nvme.c
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 13dc46a..e30814b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -502,6 +502,15 @@ config CMD_USB
help
USB support.
+config CMD_NVME
+ bool "NVMe"
+ depends on NVME
+ help
+ NVMe support.
+ This enables nvme commands in command line
+ You can use comamnd "nvme" to show what commands it supports
+ such as "nvme info" "nvme list".
+
config CMD_DFU
bool "dfu"
select USB_FUNCTION_DFU
diff --git a/cmd/Makefile b/cmd/Makefile
index 97c862f..941100e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_CMD_REISER) += reiser.o
obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o
obj-$(CONFIG_SANDBOX) += host.o
obj-$(CONFIG_CMD_SATA) += sata.o
+obj-$(CONFIG_CMD_NVME) += nvme.o
obj-$(CONFIG_CMD_SF) += sf.o
obj-$(CONFIG_SCSI) += scsi.o disk.o
obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
diff --git a/cmd/nvme.c b/cmd/nvme.c
new file mode 100644
index 0000000..8dc1f14
--- /dev/null
+++ b/cmd/nvme.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2017 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <part.h>
+#include <nvme.h>
+#include <linux/math64.h>
+
+static int nvme_curr_device;
+
+static int do_nvme_list(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ blk_list_devices(IF_TYPE_NVME);
+ return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_info(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ int devnum;
+ struct udevice *udev;
+ int ret;
+ if (argc > 1)
+ devnum = (int)simple_strtoul(argv[1], NULL, 10);
+ else
+ devnum = nvme_curr_device;
+ ret = blk_get_device(IF_TYPE_NVME, devnum, &udev);
+ if (ret < 0)
+ return ret;
+
+ nvme_print_info(udev);
+ return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_device(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ if (argc > 1) {
+ int devnum = (int)simple_strtoul(argv[1], NULL, 10);
+ if (!blk_show_device(IF_TYPE_NVME, devnum)) {
+ nvme_curr_device = devnum;
+ printf("... is now current device\n");
+ } else {
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ blk_show_device(IF_TYPE_NVME, nvme_curr_device);
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_part(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ if (argc > 1) {
+ int devnum = (int)simple_strtoul(argv[2], NULL, 10);
+ if (blk_print_part_devnum(IF_TYPE_NVME, devnum)) {
+ printf("\nNVME device %d not available\n", devnum);
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ blk_print_part_devnum(IF_TYPE_NVME, nvme_curr_device);
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_nvme_read(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ unsigned long time;
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ ulong addr = simple_strtoul(argv[1], NULL, 16);
+ ulong cnt = simple_strtoul(argv[3], NULL, 16);
+ ulong n;
+ lbaint_t blk = simple_strtoul(argv[2], NULL, 16);
+
+ printf("\nNVME read: device %d block # %ld, count %ld ... ",
+ nvme_curr_device, blk, cnt);
+
+ time = get_timer(0);
+ n = blk_read_devnum(IF_TYPE_NVME, nvme_curr_device, blk,
+ cnt, (ulong *)addr);
+ time = get_timer(time);
+
+ printf("read: %s\n", (n == cnt) ? "OK" : "ERROR");
+ printf("%lu bytes read in %lu ms", cnt * 512, time);
+ if (time > 0) {
+ puts(" (");
+ print_size(div_u64(cnt * 512, time) * 1000, "/s");
+ puts(")");
+ }
+ puts("\n");
+ return (n == cnt) ? 0 : 1;
+}
+
+static int do_nvme_write(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ unsigned long time;
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ ulong addr = simple_strtoul(argv[1], NULL, 16);
+ ulong cnt = simple_strtoul(argv[3], NULL, 16);
+ ulong n;
+ lbaint_t blk = simple_strtoul(argv[2], NULL, 16);
+
+ printf("\nNVME write: device %d block # %ld, count %ld ... ",
+ nvme_curr_device, blk, cnt);
+
+ time = get_timer(0);
+ n = blk_write_devnum(IF_TYPE_NVME, nvme_curr_device, blk,
+ cnt, (ulong *)addr);
+ time = get_timer(time);
+
+ printf("write: %s\n", (n == cnt) ? "OK" : "ERROR");
+ printf("%lu bytes read in %lu ms", cnt * 512, time);
+ if (time > 0) {
+ puts(" (");
+ print_size(div_u64(cnt * 512, time) * 1000, "/s");
+ puts(")");
+ }
+ puts("\n");
+ return (n == cnt) ? 0 : 1;
+}
+
+static cmd_tbl_t cmd_nvme[] = {
+ U_BOOT_CMD_MKENT(list, 1, 1, do_nvme_list, "", ""),
+ U_BOOT_CMD_MKENT(info, 2, 1, do_nvme_info, "", ""),
+ U_BOOT_CMD_MKENT(device, 2, 1, do_nvme_device, "", ""),
+ U_BOOT_CMD_MKENT(part, 2, 1, do_nvme_part, "", ""),
+ U_BOOT_CMD_MKENT(write, 4, 0, do_nvme_write, "", ""),
+ U_BOOT_CMD_MKENT(read, 4, 0, do_nvme_read, "", "")
+};
+
+static int do_nvmecops(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ cmd_tbl_t *cp;
+
+ cp = find_cmd_tbl(argv[1], cmd_nvme, ARRAY_SIZE(cmd_nvme));
+
+ argc--;
+ argv++;
+
+ if (cp == NULL || argc > cp->maxargs)
+ return CMD_RET_USAGE;
+
+ if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
+ return CMD_RET_SUCCESS;
+
+ return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+ nvme, 8, 1, do_nvmecops,
+ "NVME sub system",
+ "\nnvme list - show all available NVME blk devices\n"
+ "nvme info [dev]- show current or a specific NVME blk device\n"
+ "nvme device [dev] - show or set current device\n"
+ "nvme part [dev] - print partition table\n"
+ "nvme read addr blk# cnt\n"
+ "nvme write addr blk# cnt"
+);
diff --git a/disk/part.c b/disk/part.c
index cd44702..983104e 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -140,6 +140,12 @@ void dev_print (struct blk_desc *dev_desc)
case IF_TYPE_DOC:
puts("device type DOC\n");
return;
+ case IF_TYPE_NVME:
+ printf("Vendor: %s Rev: %s Prod: %s\n",
+ dev_desc->vendor,
+ dev_desc->revision,
+ dev_desc->product);
+ break;
case IF_TYPE_UNKNOWN:
puts("device type unknown\n");
return;
diff --git a/doc/README.nvme b/doc/README.nvme
index b429715..9ecb314 100644
--- a/doc/README.nvme
+++ b/doc/README.nvme
@@ -28,3 +28,57 @@ You can also get/set other features through standard commands.
NVMe Config Switches:
---------------------
CONFIG_NVME enables basic NVMe device support
+CONFIG_CMD_NVME enables basic NVMe command
+
+
+NVMe usage in U-boot:
+---------------------
+
+Two ways to operate the hard disk
+
+* Raw read/write block from/to NVMe hard disk;
+* load read file from ext2/fat/ext4 filesytems in hard disk
+
+1 How to know the information of all the NVMe hard disk?
+
+ => nvme info
+
+2 How to list all of the NVMe hard disks?
+
+ => nvme list
+
+Device 0: Vendor: 0x8086 Rev: 8DV10131 Prod: CVFT535600LS400BGN
+ Type: Hard Disk
+ Capacity: 381554.0 MB = 372.6 GB (781422768 x 512)
+
+3 How to raw write the kernel.itb to a NVMe hard disk?
+
+ Notes: Hard disk sectors are normally 512 bytes, so
+ 0x1000 sectors = 2 MBytes
+
+ wirte kernel.itb
+ => tftp 80000000 /tftpboot/kernel.itb
+ => nvme write 80000000 0 11000
+
+4 How to raw read the kernel.itb from a NVMe hard disk?
+
+ load kernel.itb
+ => nvme read a0000000 0 11000
+
+ boot
+ => bootm a0000000
+
+5 How to load image from fat filesystem in U-boot?
+
+ U-boot doesn't support fat write to hard disk, so
+ the files must be written by other means (e.g. linux).
+
+ => fatls nvme 0:1
+ 32376967 kernel.itb
+ 22929408 100m
+
+ 2 file(s), 0 dir(s)
+
+ => fatload nvme 0:1 a0000000 /kernel.itb
+
+ => bootm a0000000
--
2.1.0.27.g96db324
prev parent reply other threads:[~2017-04-21 3:01 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-21 3:01 [U-Boot] (no subject) Zhikang Zhang
2017-04-21 3:01 ` [U-Boot] [RFC,v2 1/2] NVMe: add NVMe driver support Zhikang Zhang
2017-04-21 3:01 ` Zhikang Zhang [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1492743689-40341-3-git-send-email-zhikang.zhang@nxp.com \
--to=zhikang.zhang@nxp.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.