summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--firmware/include/vboot_api.h45
-rw-r--r--firmware/stub/vboot_api_stub_stream.c87
3 files changed, 134 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 2f7db8c0..a3592ab7 100644
--- a/Makefile
+++ b/Makefile
@@ -323,7 +323,8 @@ VBSF_SRCS += \
VBSLK_SRCS += \
firmware/stub/vboot_api_stub.c \
- firmware/stub/vboot_api_stub_disk.c
+ firmware/stub/vboot_api_stub_disk.c \
+ firmware/stub/vboot_api_stub_stream.c
FWLIB2_SRCS += \
firmware/2lib/2stub.c
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index 9b053715..526c1e4a 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -620,6 +620,51 @@ VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
uint64_t lba_count, const void *buffer);
+/* Streaming read interface */
+typedef void *VbExStream_t;
+
+/**
+ * Open a stream on a disk
+ *
+ * @param handle Disk to open the stream against
+ * @param lba_start Starting sector offset within the disk to stream from
+ * @param lba_count Maximum extent of the stream in sectors
+ * @param stream out-paramter for the generated stream
+ *
+ * @return Error code, or VBERROR_SUCCESS.
+ *
+ * lba_start and lba_count are subject to disk type-dependent alignment
+ * restrictions. An invalid value will lead to an error code. In particular,
+ * on raw NAND devices, lba_start and lba_count must be page-aligned after
+ * subtracting the offset of the GPT.
+ */
+VbError_t VbExStreamOpen(VbExDiskHandle_t handle, uint64_t lba_start,
+ uint64_t lba_count, VbExStream_t *stream_ptr);
+
+/**
+ * Read from a stream on a disk
+ *
+ * @param stream Stream to read from
+ * @param bytes Number of bytes to read
+ * @param buffer Destination to read into
+ *
+ * @return Error code, or VBERROR_SUCCESS. Failure to read as much data as
+ * requested is an error.
+ *
+ * bytes is subject to disk type-dependent alignment restrictions. An invalid
+ * value will lead to an error code. In particular, on raw NAND devices, bytes
+ * must be a page multiple.
+ */
+VbError_t VbExStreamRead(VbExStream_t stream, uint32_t bytes, void *buffer);
+
+/**
+ * Close a stream
+ *
+ * @param stream Stream to close
+ */
+void VbExStreamClose(VbExStream_t stream);
+
+
/*****************************************************************************/
/* Display */
diff --git a/firmware/stub/vboot_api_stub_stream.c b/firmware/stub/vboot_api_stub_stream.c
new file mode 100644
index 00000000..525c8f78
--- /dev/null
+++ b/firmware/stub/vboot_api_stub_stream.c
@@ -0,0 +1,87 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Stub implementations of stream APIs.
+ */
+
+#include <stdint.h>
+
+#define _STUB_IMPLEMENTATION_
+
+#include "vboot_api.h"
+
+/* The stub implementation assumes 512-byte disk sectors */
+#define LBA_BYTES 512
+
+/* Internal struct to simulate a stream for sector-based disks */
+struct disk_stream {
+ /* Disk handle */
+ VbExDiskHandle_t handle;
+
+ /* Next sector to read */
+ uint64_t sector;
+
+ /* Number of sectors left in partition */
+ uint64_t sectors_left;
+};
+
+VbError_t VbExStreamOpen(VbExDiskHandle_t handle, uint64_t lba_start,
+ uint64_t lba_count, VbExStream_t *stream)
+{
+ struct disk_stream *s;
+
+ if (!handle) {
+ *stream = NULL;
+ return VBERROR_UNKNOWN;
+ }
+
+ s = VbExMalloc(sizeof(*s));
+ s->handle = handle;
+ s->sector = lba_start;
+ s->sectors_left = lba_count;
+
+ *stream = (void *)s;
+
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExStreamRead(VbExStream_t stream, uint32_t bytes, void *buffer)
+{
+ struct disk_stream *s = (struct disk_stream *)stream;
+ uint64_t sectors;
+ VbError_t rv;
+
+ if (!s)
+ return VBERROR_UNKNOWN;
+
+ /* For now, require reads to be a multiple of the LBA size */
+ if (bytes % LBA_BYTES)
+ return VBERROR_UNKNOWN;
+
+ /* Fail on overflow */
+ sectors = bytes / LBA_BYTES;
+ if (sectors > s->sectors_left)
+ return VBERROR_UNKNOWN;
+
+ rv = VbExDiskRead(s->handle, s->sector, sectors, buffer);
+ if (rv != VBERROR_SUCCESS)
+ return rv;
+
+ s->sector += sectors;
+ s->sectors_left -= sectors;
+
+ return VBERROR_SUCCESS;
+}
+
+void VbExStreamClose(VbExStream_t stream)
+{
+ struct disk_stream *s = (struct disk_stream *)stream;
+
+ /* Allow freeing a null pointer */
+ if (!s)
+ return;
+
+ VbExFree(s);
+ return;
+}