diff options
author | Aaron Durbin <adurbin@chromium.org> | 2015-05-15 13:15:34 -0500 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2015-05-26 22:32:47 +0200 |
commit | c6588c5af94e568bddd8111c3fca736f464042cf (patch) | |
tree | 0efa16d6948cfde369932fd18dec46102f807c2f /src/soc/nvidia | |
parent | def0fb57dfd91e6599c622a7b2769164a5c02ef0 (diff) |
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.inc | 4 | ||||
-rw-r--r-- | src/soc/nvidia/tegra124/cbfs.c | 29 | ||||
-rw-r--r-- | src/soc/nvidia/tegra124/include/soc/spi.h | 5 | ||||
-rw-r--r-- | src/soc/nvidia/tegra124/spi.c | 116 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/Makefile.inc | 4 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/cbfs.c | 28 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/include/soc/spi.h | 5 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/spi.c | 116 |
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); +} |