summaryrefslogtreecommitdiff
path: root/src/soc/nvidia
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2015-05-15 13:15:34 -0500
committerAaron Durbin <adurbin@chromium.org>2015-05-26 22:32:47 +0200
commitc6588c5af94e568bddd8111c3fca736f464042cf (patch)
tree0efa16d6948cfde369932fd18dec46102f807c2f /src/soc/nvidia
parentdef0fb57dfd91e6599c622a7b2769164a5c02ef0 (diff)
downloadcoreboot-c6588c5af94e568bddd8111c3fca736f464042cf.tar.xz
coreboot: introduce boot_device
The boot_device is a region_device that represents the device from which coreboot retrieves and boots its stages. The existing cbfs implementations use the boot_device as the intermediary for accessing the CBFS region. Also, there's currently only support for a read-only view of the boot_device. i.e. one cannot write to the boot_device using this view. However, a writable boot_device could be added in the future. Change-Id: Ic0da796ab161b8025c90631be3423ba6473ad31c Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/10216 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/soc/nvidia')
-rw-r--r--src/soc/nvidia/tegra124/Makefile.inc4
-rw-r--r--src/soc/nvidia/tegra124/cbfs.c29
-rw-r--r--src/soc/nvidia/tegra124/include/soc/spi.h5
-rw-r--r--src/soc/nvidia/tegra124/spi.c116
-rw-r--r--src/soc/nvidia/tegra132/Makefile.inc4
-rw-r--r--src/soc/nvidia/tegra132/cbfs.c28
-rw-r--r--src/soc/nvidia/tegra132/include/soc/spi.h5
-rw-r--r--src/soc/nvidia/tegra132/spi.c116
8 files changed, 156 insertions, 151 deletions
diff --git a/src/soc/nvidia/tegra124/Makefile.inc b/src/soc/nvidia/tegra124/Makefile.inc
index 78054f4511..46ce59d757 100644
--- a/src/soc/nvidia/tegra124/Makefile.inc
+++ b/src/soc/nvidia/tegra124/Makefile.inc
@@ -2,7 +2,6 @@ ifeq ($(CONFIG_SOC_NVIDIA_TEGRA124),y)
bootblock-y += bootblock.c
bootblock-y += bootblock_asm.S
-bootblock-y += cbfs.c
bootblock-y += clock.c
bootblock-y += dma.c
bootblock-y += i2c.c
@@ -22,7 +21,6 @@ bootblock-$(CONFIG_DRIVERS_UART) += uart.c
endif
verstage-y += verstage.c
-verstage-y += cbfs.c
verstage-y += dma.c
verstage-y += monotonic_timer.c
verstage-y += spi.c
@@ -34,7 +32,6 @@ verstage-y += clock.c
verstage-y += i2c.c
verstage-y += cache.c
-romstage-y += cbfs.c
romstage-y += cbmem.c
romstage-y += clock.c
romstage-y += dma.c
@@ -51,7 +48,6 @@ romstage-y += ../tegra/pinmux.c
romstage-y += cache.c
romstage-$(CONFIG_DRIVERS_UART) += uart.c
-ramstage-y += cbfs.c
ramstage-y += cbmem.c
ramstage-y += clock.c
ramstage-y += display.c
diff --git a/src/soc/nvidia/tegra124/cbfs.c b/src/soc/nvidia/tegra124/cbfs.c
deleted file mode 100644
index d82ca9a961..0000000000
--- a/src/soc/nvidia/tegra124/cbfs.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2013 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.
- */
-
-
-#include <cbfs.h> /* This driver serves as a CBFS media source. */
-#include <soc/spi.h>
-#include <symbols.h>
-
-int init_default_cbfs_media(struct cbfs_media *media)
-{
- return initialize_tegra_spi_cbfs_media(media,
- _cbfs_cache, _cbfs_cache_size);
-}
diff --git a/src/soc/nvidia/tegra124/include/soc/spi.h b/src/soc/nvidia/tegra124/include/soc/spi.h
index ab046323b1..cfa3cd2b57 100644
--- a/src/soc/nvidia/tegra124/include/soc/spi.h
+++ b/src/soc/nvidia/tegra124/include/soc/spi.h
@@ -61,11 +61,6 @@ struct tegra_spi_channel {
enum spi_xfer_mode xfer_mode;
};
-struct cbfs_media;
-int initialize_tegra_spi_cbfs_media(struct cbfs_media *media,
- void *buffer_address,
- size_t buffer_size);
-
struct tegra_spi_channel *tegra_spi_init(unsigned int bus);
#endif /* __NVIDIA_TEGRA124_SPI_H__ */
diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c
index 683edd1cf0..0cf54956d3 100644
--- a/src/soc/nvidia/tegra124/spi.c
+++ b/src/soc/nvidia/tegra124/spi.c
@@ -21,6 +21,7 @@
#include <arch/cache.h>
#include <arch/io.h>
#include <assert.h>
+#include <boot_device.h>
#include <console/console.h>
#include <cbfs.h>
#include <delay.h>
@@ -33,6 +34,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <symbols.h>
#include <timer.h>
@@ -800,12 +802,6 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
return ret;
}
-/* SPI as CBFS media. */
-struct tegra_spi_media {
- struct spi_slave *slave;
- struct cbfs_simple_buffer buffer;
-};
-
static int tegra_spi_cbfs_open(struct cbfs_media *media)
{
DEBUG_SPI("tegra_spi_cbfs_open\n");
@@ -823,16 +819,17 @@ static int tegra_spi_cbfs_close(struct cbfs_media *media)
#define JEDEC_FAST_READ_DUAL 0x3b
#define JEDEC_FAST_READ_DUAL_OUTSIZE 0x05
-static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
- size_t offset, size_t count)
+static struct spi_slave *boot_slave;
+
+static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest,
+ size_t offset, size_t count)
{
- struct tegra_spi_media *spi = (struct tegra_spi_media *)media->context;
u8 spi_read_cmd[JEDEC_FAST_READ_DUAL_OUTSIZE];
unsigned int read_cmd_bytes;
int ret = count;
struct tegra_spi_channel *channel;
- channel = to_tegra_spi(spi->slave->bus);
+ channel = to_tegra_spi(boot_slave->bus);
if (channel->dual_mode) {
/*
@@ -853,9 +850,9 @@ static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
spi_read_cmd[2] = (offset >> 8) & 0xff;
spi_read_cmd[3] = offset & 0xff;
- spi_claim_bus(spi->slave);
+ spi_claim_bus(boot_slave);
- if (spi_xfer(spi->slave, spi_read_cmd,
+ if (spi_xfer(boot_slave, spi_read_cmd,
read_cmd_bytes, NULL, 0) < 0) {
ret = -1;
printk(BIOS_ERR, "%s: Failed to transfer %u bytes\n",
@@ -866,7 +863,7 @@ static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
if (channel->dual_mode) {
setbits_le32(&channel->regs->command1, SPI_CMD1_BOTH_EN_BIT);
}
- if (spi_xfer(spi->slave, NULL, 0, dest, count)) {
+ if (spi_xfer(boot_slave, NULL, 0, dest, count)) {
ret = -1;
printk(BIOS_ERR, "%s: Failed to transfer %u bytes\n",
__func__, count);
@@ -876,56 +873,70 @@ static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
tegra_spi_cbfs_read_exit:
/* de-assert /CS */
- spi_release_bus(spi->slave);
- return (ret < 0) ? 0 : ret;
+ spi_release_bus(boot_slave);
+ return ret;
+}
+
+static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
+ size_t offset, size_t count)
+{
+ const struct region_device *boot_dev;
+
+ boot_dev = media->context;
+
+ printk(BIOS_ERR, "%s: reading %zx bytes from %zx\n",
+ __func__, count, offset);
+ if (rdev_readat(boot_dev, dest, offset, count) < 0)
+ return 0;
+
+ return count;
}
static void *tegra_spi_cbfs_map(struct cbfs_media *media, size_t offset,
size_t count)
{
- struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context;
+ const struct region_device *boot_dev;
void *map;
+
DEBUG_SPI("tegra_spi_cbfs_map\n");
- map = cbfs_simple_buffer_map(&spi->buffer, media, offset, count);
+
+ boot_dev = media->context;
+
+ map = rdev_mmap(boot_dev, offset, count);
+
+ if (map == NULL)
+ map = (void *)-1;
+
return map;
}
static void *tegra_spi_cbfs_unmap(struct cbfs_media *media,
const void *address)
{
- struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context;
+ const struct region_device *boot_dev;
+
DEBUG_SPI("tegra_spi_cbfs_unmap\n");
- return cbfs_simple_buffer_unmap(&spi->buffer, address);
-}
-int initialize_tegra_spi_cbfs_media(struct cbfs_media *media,
- void *buffer_address,
- size_t buffer_size)
-{
- // TODO Replace static variable to support multiple streams.
- static struct tegra_spi_media context;
- static struct tegra_spi_channel *channel;
+ boot_dev = media->context;
- channel = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1];
- channel->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT;
+ rdev_munmap(boot_dev, (void *)address);
+ return NULL;
+}
+
+int init_default_cbfs_media(struct cbfs_media *media)
+{
DEBUG_SPI("Initializing CBFS media on SPI\n");
- context.slave = &channel->slave;
- context.buffer.allocated = context.buffer.last_allocate = 0;
- context.buffer.buffer = buffer_address;
- context.buffer.size = buffer_size;
- media->context = (void*)&context;
+ boot_device_init();
+
+ media->context = (void *)boot_device_ro();
media->open = tegra_spi_cbfs_open;
media->close = tegra_spi_cbfs_close;
media->read = tegra_spi_cbfs_read;
media->map = tegra_spi_cbfs_map;
media->unmap = tegra_spi_cbfs_unmap;
-#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1
- channel->dual_mode = 1;
-#endif
-
return 0;
}
@@ -937,3 +948,32 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
return &channel->slave;
}
+
+static const struct region_device_ops tegra_spi_ops = {
+ .mmap = mmap_helper_rdev_mmap,
+ .munmap = mmap_helper_rdev_munmap,
+ .readat = tegra_spi_readat,
+};
+
+static struct mmap_helper_region_device mdev =
+ MMAP_HELPER_REGION_INIT(&tegra_spi_ops, 0, CONFIG_ROM_SIZE);
+
+const struct region_device *boot_device_ro(void)
+{
+ return &mdev.rdev;
+}
+
+void boot_device_init(void)
+{
+ struct tegra_spi_channel *boot_chan;
+
+ boot_chan = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1];
+ boot_chan->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT;
+
+#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1
+ boot_chan->dual_mode = 1;
+#endif
+ boot_slave = &boot_chan->slave;
+
+ mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size);
+}
diff --git a/src/soc/nvidia/tegra132/Makefile.inc b/src/soc/nvidia/tegra132/Makefile.inc
index 365dab314f..c192055cdf 100644
--- a/src/soc/nvidia/tegra132/Makefile.inc
+++ b/src/soc/nvidia/tegra132/Makefile.inc
@@ -2,7 +2,6 @@ ifeq ($(CONFIG_SOC_NVIDIA_TEGRA132),y)
bootblock-y += bootblock.c
bootblock-y += bootblock_asm.S
-bootblock-y += cbfs.c
bootblock-y += clock.c
bootblock-y += spi.c
bootblock-y += i2c.c
@@ -23,7 +22,6 @@ bootblock-$(CONFIG_DRIVERS_UART) += uart.c
endif
verstage-y += verstage.c
-verstage-y += cbfs.c
verstage-y += dma.c
verstage-y += monotonic_timer.c
verstage-y += spi.c
@@ -39,7 +37,6 @@ verstage-y += i2c.c
romstage-y += 32bit_reset.S
romstage-y += romstage_asm.S
romstage-y += addressmap.c
-romstage-y += cbfs.c
romstage-y += cbmem.c
romstage-y += ccplex.c
romstage-y += clock.c
@@ -63,7 +60,6 @@ romstage-$(CONFIG_DRIVERS_UART) += uart.c
ramstage-y += 32bit_reset.S
ramstage-y += addressmap.c
-ramstage-y += cbfs.c
ramstage-y += cbmem.c
ramstage-y += cpu.c
ramstage-y += cpu_lib.S
diff --git a/src/soc/nvidia/tegra132/cbfs.c b/src/soc/nvidia/tegra132/cbfs.c
deleted file mode 100644
index 7aeb59bc94..0000000000
--- a/src/soc/nvidia/tegra132/cbfs.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-#include <cbfs.h> /* This driver serves as a CBFS media source. */
-#include <soc/spi.h>
-#include <symbols.h>
-
-int init_default_cbfs_media(struct cbfs_media *media)
-{
- return initialize_tegra_spi_cbfs_media(media,
- _cbfs_cache, _cbfs_cache_size);
-}
diff --git a/src/soc/nvidia/tegra132/include/soc/spi.h b/src/soc/nvidia/tegra132/include/soc/spi.h
index 2fd9562599..4c91c27c7f 100644
--- a/src/soc/nvidia/tegra132/include/soc/spi.h
+++ b/src/soc/nvidia/tegra132/include/soc/spi.h
@@ -62,11 +62,6 @@ struct tegra_spi_channel {
enum spi_xfer_mode xfer_mode;
};
-struct cbfs_media;
-int initialize_tegra_spi_cbfs_media(struct cbfs_media *media,
- void *buffer_address,
- size_t buffer_size);
-
struct tegra_spi_channel *tegra_spi_init(unsigned int bus);
#endif /* __NVIDIA_TEGRA132_SPI_H__ */
diff --git a/src/soc/nvidia/tegra132/spi.c b/src/soc/nvidia/tegra132/spi.c
index 7ca66e1ad8..1650057fab 100644
--- a/src/soc/nvidia/tegra132/spi.c
+++ b/src/soc/nvidia/tegra132/spi.c
@@ -21,6 +21,7 @@
#include <arch/cache.h>
#include <arch/io.h>
#include <assert.h>
+#include <boot_device.h>
#include <cbfs.h>
#include <console/console.h>
#include <delay.h>
@@ -33,6 +34,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <symbols.h>
#include <timer.h>
@@ -815,12 +817,6 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
return ret;
}
-/* SPI as CBFS media. */
-struct tegra_spi_media {
- struct spi_slave *slave;
- struct cbfs_simple_buffer buffer;
-};
-
static int tegra_spi_cbfs_open(struct cbfs_media *media)
{
DEBUG_SPI("tegra_spi_cbfs_open\n");
@@ -838,16 +834,17 @@ static int tegra_spi_cbfs_close(struct cbfs_media *media)
#define JEDEC_FAST_READ_DUAL 0x3b
#define JEDEC_FAST_READ_DUAL_OUTSIZE 0x05
-static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
- size_t offset, size_t count)
+static struct spi_slave *boot_slave;
+
+static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest,
+ size_t offset, size_t count)
{
- struct tegra_spi_media *spi = (struct tegra_spi_media *)media->context;
u8 spi_read_cmd[JEDEC_FAST_READ_DUAL_OUTSIZE];
unsigned int read_cmd_bytes;
int ret = count;
struct tegra_spi_channel *channel;
- channel = to_tegra_spi(spi->slave->bus);
+ channel = to_tegra_spi(boot_slave->bus);
if (channel->dual_mode) {
/*
@@ -868,9 +865,9 @@ static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
spi_read_cmd[2] = (offset >> 8) & 0xff;
spi_read_cmd[3] = offset & 0xff;
- spi_claim_bus(spi->slave);
+ spi_claim_bus(boot_slave);
- if (spi_xfer(spi->slave, spi_read_cmd,
+ if (spi_xfer(boot_slave, spi_read_cmd,
read_cmd_bytes, NULL, 0) < 0) {
ret = -1;
printk(BIOS_ERR, "%s: Failed to transfer %zu bytes\n",
@@ -881,7 +878,7 @@ static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
if (channel->dual_mode) {
setbits_le32(&channel->regs->command1, SPI_CMD1_BOTH_EN_BIT);
}
- if (spi_xfer(spi->slave, NULL, 0, dest, count)) {
+ if (spi_xfer(boot_slave, NULL, 0, dest, count)) {
ret = -1;
printk(BIOS_ERR, "%s: Failed to transfer %zu bytes\n",
__func__, count);
@@ -891,56 +888,70 @@ static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
tegra_spi_cbfs_read_exit:
/* de-assert /CS */
- spi_release_bus(spi->slave);
- return (ret < 0) ? 0 : ret;
+ spi_release_bus(boot_slave);
+ return ret;
+}
+
+static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest,
+ size_t offset, size_t count)
+{
+ const struct region_device *boot_dev;
+
+ boot_dev = media->context;
+
+ DEBUG_SPI("%s: reading %zx bytes from %zx\n", __func__, count, offset);
+
+ if (rdev_readat(boot_dev, dest, offset, count) < 0)
+ return 0;
+
+ return count;
}
static void *tegra_spi_cbfs_map(struct cbfs_media *media, size_t offset,
size_t count)
{
- struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context;
+ const struct region_device *boot_dev;
void *map;
+
DEBUG_SPI("tegra_spi_cbfs_map\n");
- map = cbfs_simple_buffer_map(&spi->buffer, media, offset, count);
+
+ boot_dev = media->context;
+
+ map = rdev_mmap(boot_dev, offset, count);
+
+ if (map == NULL)
+ map = (void *)-1;
+
return map;
}
static void *tegra_spi_cbfs_unmap(struct cbfs_media *media,
const void *address)
{
- struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context;
+ const struct region_device *boot_dev;
+
DEBUG_SPI("tegra_spi_cbfs_unmap\n");
- return cbfs_simple_buffer_unmap(&spi->buffer, address);
-}
-int initialize_tegra_spi_cbfs_media(struct cbfs_media *media,
- void *buffer_address,
- size_t buffer_size)
-{
- // TODO Replace static variable to support multiple streams.
- static struct tegra_spi_media context;
- static struct tegra_spi_channel *channel;
+ boot_dev = media->context;
- channel = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1];
- channel->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT;
+ rdev_munmap(boot_dev, (void *)address);
+ return NULL;
+}
+
+int init_default_cbfs_media(struct cbfs_media *media)
+{
DEBUG_SPI("Initializing CBFS media on SPI\n");
- context.slave = &channel->slave;
- context.buffer.allocated = context.buffer.last_allocate = 0;
- context.buffer.buffer = buffer_address;
- context.buffer.size = buffer_size;
- media->context = (void*)&context;
+ boot_device_init();
+
+ media->context = (void *)boot_device_ro();
media->open = tegra_spi_cbfs_open;
media->close = tegra_spi_cbfs_close;
media->read = tegra_spi_cbfs_read;
media->map = tegra_spi_cbfs_map;
media->unmap = tegra_spi_cbfs_unmap;
-#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1
- channel->dual_mode = 1;
-#endif
-
return 0;
}
@@ -952,3 +963,32 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
return &channel->slave;
}
+
+static const struct region_device_ops tegra_spi_ops = {
+ .mmap = mmap_helper_rdev_mmap,
+ .munmap = mmap_helper_rdev_munmap,
+ .readat = tegra_spi_readat,
+};
+
+static struct mmap_helper_region_device mdev =
+ MMAP_HELPER_REGION_INIT(&tegra_spi_ops, 0, CONFIG_ROM_SIZE);
+
+const struct region_device *boot_device_ro(void)
+{
+ return &mdev.rdev;
+}
+
+void boot_device_init(void)
+{
+ struct tegra_spi_channel *boot_chan;
+
+ boot_chan = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1];
+ boot_chan->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT;
+
+#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1
+ boot_chan->dual_mode = 1;
+#endif
+ boot_slave = &boot_chan->slave;
+
+ mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size);
+}