Coreboot generic CBFS media API does not support multiple media access instances, but it should. With this fix the CBFS context (memory cache for SPI accesses) is shared among all open media access streams. A better memory management scheme might be required, but for now this fix allows to support booting deptcharge and accessing VPD through two independent CBFS media streams. BUG=chrome-os-partner:32152 TEST=no exception is thrown when the second stream is opened Change-Id: I62889089b4832c9e9760ef24ecc517220d8f3ec4 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 691f9794805d04beff349f1bc60ac9d7530d7cbf Original-Change-Id: Ib9d9d1f5209c2e515a95d7acbf4a8ac1255d3f8a Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/219441 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/8897 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
100 lines
2.5 KiB
C
100 lines
2.5 KiB
C
/*
|
|
* This file is part of the coreboot project.
|
|
*
|
|
* Copyright 2014 Google Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/*
|
|
* This file provides a common CBFS wrapper for SPI storage. SPI driver
|
|
* context is expanded with the buffer descriptor used to store data read from
|
|
* SPI.
|
|
*/
|
|
|
|
#include <cbfs.h>
|
|
#include <spi_flash.h>
|
|
|
|
/* SPI flash as CBFS media. */
|
|
struct cbfs_spi_context {
|
|
struct spi_flash *spi_flash_info;
|
|
struct cbfs_simple_buffer buffer;
|
|
};
|
|
|
|
static struct cbfs_spi_context spi_context;
|
|
|
|
static int cbfs_media_open(struct cbfs_media *media)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int cbfs_media_close(struct cbfs_media *media)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static size_t cbfs_media_read(struct cbfs_media *media,
|
|
void *dest, size_t offset,
|
|
size_t count)
|
|
{
|
|
struct cbfs_spi_context *context = media->context;
|
|
|
|
return context->spi_flash_info->read
|
|
(context->spi_flash_info, offset, count, dest) ? 0 : count;
|
|
}
|
|
|
|
static void *cbfs_media_map(struct cbfs_media *media,
|
|
size_t offset, size_t count)
|
|
{
|
|
struct cbfs_spi_context *context = media->context;
|
|
|
|
return cbfs_simple_buffer_map(&context->buffer, media, offset, count);
|
|
}
|
|
|
|
static void *cbfs_media_unmap(struct cbfs_media *media,
|
|
const void *address)
|
|
{
|
|
struct cbfs_spi_context *context = media->context;
|
|
|
|
return cbfs_simple_buffer_unmap(&context->buffer, address);
|
|
}
|
|
|
|
static int init_cbfs_media_context(void)
|
|
{
|
|
if (!spi_context.spi_flash_info) {
|
|
|
|
spi_context.spi_flash_info = spi_flash_probe
|
|
(CONFIG_BOOT_MEDIA_SPI_BUS, 0);
|
|
|
|
if (!spi_context.spi_flash_info)
|
|
return -1;
|
|
|
|
spi_context.buffer.buffer = (void *)CONFIG_CBFS_CACHE_ADDRESS;
|
|
spi_context.buffer.size = CONFIG_CBFS_CACHE_SIZE;
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
int init_default_cbfs_media(struct cbfs_media *media)
|
|
{
|
|
media->context = &spi_context;
|
|
media->open = cbfs_media_open;
|
|
media->close = cbfs_media_close;
|
|
media->read = cbfs_media_read;
|
|
media->map = cbfs_media_map;
|
|
media->unmap = cbfs_media_unmap;
|
|
|
|
return init_cbfs_media_context();
|
|
}
|