diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | firmware/include/vboot_api.h | 45 | ||||
-rw-r--r-- | firmware/stub/vboot_api_stub_stream.c | 87 |
3 files changed, 134 insertions, 1 deletions
@@ -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; +} |