vbe: Move reading the nvdata into the common file

All VBE methods read non-volatile data, so move this function into a
common file.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/boot/vbe_common.c b/boot/vbe_common.c
index 8bbcc37..672878f 100644
--- a/boot/vbe_common.c
+++ b/boot/vbe_common.c
@@ -9,6 +9,7 @@
 #include <blk.h>
 #include <memalign.h>
 #include <spl.h>
+#include <u-boot/crc.h>
 #include "vbe_common.h"
 
 int vbe_get_blk(const char *storage, struct udevice **blkp)
@@ -59,3 +60,43 @@
 
 	return 0;
 }
+
+int vbe_read_nvdata(struct udevice *blk, ulong offset, ulong size, u8 *buf)
+{
+	uint hdr_ver, hdr_size, data_size, crc;
+	const struct vbe_nvdata *nvd;
+
+	/* we can use an assert() here since we already read only one block */
+	assert(size <= MMC_MAX_BLOCK_LEN);
+
+	/*
+	 * We can use an assert() here since reading the wrong block will just
+	 * cause invalid state to be (safely) read. If the crc passes, then we
+	 * obtain invalid state and it will likely cause booting to fail.
+	 *
+	 * VBE relies on valid values being in U-Boot's devicetree, so this
+	 * should not every be wrong on a production device.
+	 */
+	assert(!(offset & (MMC_MAX_BLOCK_LEN - 1)));
+
+	if (offset & (MMC_MAX_BLOCK_LEN - 1))
+		return log_msg_ret("get", -EBADF);
+	offset /= MMC_MAX_BLOCK_LEN;
+
+	if (blk_read(blk, offset, 1, buf) != 1)
+		return log_msg_ret("read", -EIO);
+	nvd = (struct vbe_nvdata *)buf;
+	hdr_ver = (nvd->hdr & NVD_HDR_VER_MASK) >> NVD_HDR_VER_SHIFT;
+	hdr_size = (nvd->hdr & NVD_HDR_SIZE_MASK) >> NVD_HDR_SIZE_SHIFT;
+	if (hdr_ver != NVD_HDR_VER_CUR)
+		return log_msg_ret("hdr", -EPERM);
+	data_size = 1 << hdr_size;
+	if (!data_size || data_size > sizeof(*nvd))
+		return log_msg_ret("sz", -EPERM);
+
+	crc = crc8(0, buf + 1, data_size - 1);
+	if (crc != nvd->crc8)
+		return log_msg_ret("crc", -EPERM);
+
+	return 0;
+}