[coreboot] Patch set updated for coreboot: 814a13c Extend CBFS to support arbitrary ROM source media.
Hung-Te Lin (hungte@chromium.org)
gerrit at coreboot.org
Fri Jan 25 01:57:02 CET 2013
Hung-Te Lin (hungte at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2182
-gerrit
commit 814a13c9c6033fb338a52086fef3df42b45de591
Author: Hung-Te Lin <hungte at chromium.org>
Date: Tue Jan 22 18:57:56 2013 +0800
Extend CBFS to support arbitrary ROM source media.
Summary:
CBFS functions now all take a new "media source" parameter; use
CBFS_DEFAULT_MEDIA if you simply want to load from main firmware.
API Changes:
cbfs_find => cbfs_get_file
cbfs_find_file => cbfs_get_file_content
CBFS used to work only on memory-mapped ROM (all x86). For platforms like ARM,
the ROM may come from USB, UART, or SPI -- any serial devices and not available
for memory mapping.
To support these devices (or allowing CBFS to read from multiple source
at the same time), CBFS operations are now virtual-ized into "cbfs_media". To
simplify porting existing code, every media source must support both "reading
into pre-allocated memory (read)" and "read and return an allocated buffer
(map)". For devices without native memory-mapped ROM, "cbfs_simple_buffer*"
provides simple memory mapping simulation.
Every CBFS function now takes a cbfs_media* as parameter. CBFS_DEFAULT_MEDIA
is defined for CBFS functions to automatically initialize a per-board default
media (CBFS will internally calls init_default_cbfs_media). Also revised CBFS
function names relying on memory mapped backend (ex, "cbfs_find" => actually
loads files). Now we only have two getters:
struct cbfs_file *entry = cbfs_get_file(media, name);
void *data = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, name, type);
Test results:
- Verified to work on ARM (loaded romstage properly for Google/Snow).
- Verified to work on x86/qemu.
Change-Id: Iac911ded25a6f2feffbf3101a81364625bb07746
Signed-off-by: Hung-Te Lin <hungte at chromium.org>
---
src/arch/armv7/boot/coreboot_table.c | 4 +-
src/arch/armv7/bootblock_simple.c | 4 +-
src/arch/armv7/include/arch/cbfs.h | 101 +++----
src/arch/x86/boot/coreboot_table.c | 4 +-
src/arch/x86/boot/smbios.c | 14 +-
src/arch/x86/lib/Makefile.inc | 3 +
src/arch/x86/lib/cbfs_and_run.c | 2 +-
src/arch/x86/lib/rom_media.c | 62 +++++
src/cpu/intel/microcode/microcode.c | 5 +-
src/cpu/samsung/exynos5-common/Makefile.inc | 4 +-
src/cpu/samsung/exynos5-common/spi.c | 233 +++++++++++++++++
src/cpu/samsung/exynos5-common/spi.h | 13 +
src/cpu/samsung/exynos5-common/spl_boot.c | 291 ---------------------
src/cpu/samsung/exynos5250/Kconfig | 8 +
src/cpu/via/nano/update_ucode.c | 2 +-
src/device/oprom/realmode/x86.c | 8 +-
src/device/oprom/yabel/vbe.c | 4 +-
src/device/pci_rom.c | 9 +-
src/drivers/pc80/mc146818rtc.c | 6 +-
src/include/cbfs.h | 32 ++-
src/include/cbfs_core.h | 69 +++--
src/lib/cbfs.c | 75 +++++-
src/lib/cbfs_core.c | 196 ++++++++------
src/lib/hardwaremain.c | 5 +-
src/lib/selfboot.c | 9 -
src/mainboard/google/snow/bootblock.c | 253 +-----------------
src/mainboard/samsung/lumpy/romstage.c | 2 +-
.../amd/agesa/family15tn/fam15tn_callouts.c | 4 +-
src/northbridge/intel/i82830/vga.c | 2 +-
src/northbridge/intel/sandybridge/raminit.c | 4 +-
30 files changed, 669 insertions(+), 759 deletions(-)
diff --git a/src/arch/armv7/boot/coreboot_table.c b/src/arch/armv7/boot/coreboot_table.c
index 86a004d..b2d88aa 100644
--- a/src/arch/armv7/boot/coreboot_table.c
+++ b/src/arch/armv7/boot/coreboot_table.c
@@ -640,7 +640,9 @@ unsigned long write_coreboot_table(
#if CONFIG_USE_OPTION_TABLE
{
- struct cmos_option_table *option_table = cbfs_find_file("cmos_layout.bin", 0x1aa);
+ struct cmos_option_table *option_table = cbfs_get_file_content(
+ CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
+ CBFS_COMPONENT_CMOS_LAYOUT);
if (option_table) {
struct lb_record *rec_dest = lb_new_record(head);
/* Copy the option config table, it's already a lb_record... */
diff --git a/src/arch/armv7/bootblock_simple.c b/src/arch/armv7/bootblock_simple.c
index af76d4c..d97075e 100644
--- a/src/arch/armv7/bootblock_simple.c
+++ b/src/arch/armv7/bootblock_simple.c
@@ -45,7 +45,9 @@ void main(unsigned long bist)
}
printk(BIOS_INFO, "bootblock main(): loading romstage\n");
- romstage_entry = loadstage(target1);
+ romstage_entry = (unsigned long)cbfs_load_stage(
+ CBFS_DEFAULT_MEDIA, target1);
+
printk(BIOS_INFO, "bootblock main(): jumping to romstage\n");
if (romstage_entry) bootblock_exit(romstage_entry);
hlt();
diff --git a/src/arch/armv7/include/arch/cbfs.h b/src/arch/armv7/include/arch/cbfs.h
index f060643..e34a0d2 100644
--- a/src/arch/armv7/include/arch/cbfs.h
+++ b/src/arch/armv7/include/arch/cbfs.h
@@ -20,82 +20,41 @@
#ifndef __INCLUDE_ARCH_CBFS__
#define __INCLUDE_ARCH_CBFS__
-#include <string.h>
-#include <types.h>
#include <cbfs_core.h>
#include <arch/byteorder.h>
-#include <arch/cbfs.h>
+// TODO FIXME This file is only for providing CBFS function in bootblock.
+// Should be removed once bootblock can link lib/* files.
+#include "lib/cbfs.c"
-static int cbfs_check_magic(struct cbfs_file *file)
-{
- return strcmp(file->magic, CBFS_FILE_MAGIC) ? 0 : 1;
+// mem* and ulzma are now workarounds for bootblock compilation.
+void *memcpy(void *dest, const void *src, size_t n) {
+ char *d = (char *)dest;
+ const char *s = (const char*)src;
+ while (n-- > 0)
+ *d++ = *s++;
+ return dest;
}
-static unsigned long loadstage(const char* target)
-{
- unsigned long offset, align;
- struct cbfs_header *header = (struct cbfs_header *)(CONFIG_BOOTBLOCK_BASE + 0x40);
- /* FIXME: magic offsets */
- // if (ntohl(header->magic) != CBFS_HEADER_MAGIC)
- // printk(BIOS_ERR, "ERROR: No valid CBFS header found!\n");
+void *memset(void *dest, int c, size_t n) {
+ char *d = (char*)dest;
+ while (n-- > 0)
+ *d++ = c;
+ return dest;
+}
+
+int memcmp(const void *ptr1, const void *ptr2, size_t n) {
+ const char *s1 = (const char*)ptr1, *s2 = (const char*)ptr2;
+ int c;
+ while (n-- > 0)
+ if ((c = *s1++ - *s2++))
+ return c;
+ return 0;
+}
- offset = ntohl(header->offset);
- align = ntohl(header->align);
- printk(BIOS_INFO, "cbfs header (0x%p)\n", header);
- printk(BIOS_INFO, "\tmagic: 0x%08x\n", ntohl(header->magic));
- printk(BIOS_INFO, "\tversion: 0x%08x\n", ntohl(header->version));
- printk(BIOS_INFO, "\tromsize: 0x%08x\n", ntohl(header->romsize));
- printk(BIOS_INFO, "\tbootblocksize: 0x%08x\n", ntohl(header->bootblocksize));
- printk(BIOS_INFO, "\talign: 0x%08x\n", ntohl(header->align));
- printk(BIOS_INFO, "\toffset: 0x%08x\n", ntohl(header->offset));
- while(1) {
- struct cbfs_file *file;
- struct cbfs_stage *stage;
- /* FIXME: SPI image hack */
- file = (struct cbfs_file *)(offset + CONFIG_SPI_IMAGE_HACK);
- if (!cbfs_check_magic(file)) {
- printk(BIOS_INFO, "magic is wrong, file: %p\n", file);
- return 0;
- }
- if (!strcmp(CBFS_NAME(file), target)) {
- uint32_t load, entry;
- printk(BIOS_INFO, "CBFS name matched, offset: %p\n", file);
- printk(BIOS_INFO, "\tmagic: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- file->magic[0], file->magic[1], file->magic[2], file->magic[3],
- file->magic[4], file->magic[5], file->magic[6], file->magic[7]);
- printk(BIOS_INFO, "\tlen: 0x%08x\n", ntohl(file->len));
- printk(BIOS_INFO, "\ttype: 0x%08x\n", ntohl(file->type));
- printk(BIOS_INFO, "\tchecksum: 0x%08x\n", ntohl(file->checksum));
- printk(BIOS_INFO, "\toffset: 0x%08x\n", ntohl(file->offset));
- /* exploit the fact that this is all word-aligned. */
- stage = CBFS_SUBHEADER(file);
- load = stage->load;
- entry = stage->entry;
- int i;
- u32 *to = (void *)load;
- u32 *from = (void *)((u8 *)stage+sizeof(*stage));
- /* we could do memmove/memset here. But the math gets messy.
- * far easier just to do what we want.
- */
- printk(BIOS_INFO, "entry: 0x%08x, load: 0x%08x, "
- "len: 0x%08x, memlen: 0x%08x\n", entry,
- load, stage->len, stage->memlen);
- for(i = 0; i < stage->len; i += 4)
- *to++ = *from++;
- for(; i < stage->memlen; i += 4)
- *to++ = 0;
- return entry;
- }
- int flen = ntohl(file->len);
- int foffset = ntohl(file->offset);
- unsigned long oldoffset = offset;
- offset = ALIGN(offset + foffset + flen, align);
- printk(BIOS_INFO, "offset: 0x%08lx\n", offset);
- if (offset <= oldoffset)
- return 0;
- if (offset > CONFIG_ROMSTAGE_SIZE)
- return 0;
- }
+unsigned long ulzma(unsigned char *src, unsigned char *dest) {
+ // TODO remove this.
+ return -1;
}
-#endif
+
+#endif // __INCLUDE_ARCH_CBFS__
diff --git a/src/arch/x86/boot/coreboot_table.c b/src/arch/x86/boot/coreboot_table.c
index 8dccd77..04fba47 100644
--- a/src/arch/x86/boot/coreboot_table.c
+++ b/src/arch/x86/boot/coreboot_table.c
@@ -638,7 +638,9 @@ unsigned long write_coreboot_table(
#if CONFIG_USE_OPTION_TABLE
{
- struct cmos_option_table *option_table = cbfs_find_file("cmos_layout.bin", 0x1aa);
+ struct cmos_option_table *option_table = cbfs_get_file_content(
+ CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
+ CBFS_COMPONENT_CMOS_LAYOUT);
if (option_table) {
struct lb_record *rec_dest = lb_new_record(head);
/* Copy the option config table, it's already a lb_record... */
diff --git a/src/arch/x86/boot/smbios.c b/src/arch/x86/boot/smbios.c
index 72e70ba..314816e 100644
--- a/src/arch/x86/boot/smbios.c
+++ b/src/arch/x86/boot/smbios.c
@@ -120,7 +120,6 @@ static int smbios_processor_name(char *start)
static int smbios_write_type0(unsigned long *current, int handle)
{
- struct cbfs_header *hdr;
struct smbios_type0 *t = (struct smbios_type0 *)*current;
int len = sizeof(struct smbios_type0);
@@ -143,8 +142,17 @@ static int smbios_write_type0(unsigned long *current, int handle)
vboot_data->vbt10 = (u32)t->eos + (version_offset - 1);
#endif
- if ((hdr = get_cbfs_header()) != (struct cbfs_header *)0xffffffff)
- t->bios_rom_size = (ntohl(hdr->romsize) / 65535) - 1;
+ // TODO cache the value or always trust CONFIG_ROM_SIZE?
+ {
+ const struct cbfs_header *header;
+ header = cbfs_get_header(CBFS_DEFAULT_MEDIA);
+ if (header != CBFS_HEADER_INVALID_ADDRESS)
+ t->bios_rom_size = (ntohl(header->romsize) / 65535) - 1;
+ else
+ t->bios_rom_size = (CONFIG_ROM_SIZE / 65535) - 1;
+ }
+
+
t->system_bios_major_release = 4;
t->bios_characteristics =
BIOS_CHARACTERISTICS_PCI_SUPPORTED |
diff --git a/src/arch/x86/lib/Makefile.inc b/src/arch/x86/lib/Makefile.inc
index 2186072..f4dc8b8 100644
--- a/src/arch/x86/lib/Makefile.inc
+++ b/src/arch/x86/lib/Makefile.inc
@@ -8,13 +8,16 @@ ramstage-$(CONFIG_IOAPIC) += ioapic.c
ramstage-y += memset.c
ramstage-y += memcpy.c
ramstage-y += ebda.c
+ramstage-y += rom_media.c
romstage-y += romstage_console.c
romstage-y += cbfs_and_run.c
romstage-y += memset.c
romstage-y += memcpy.c
+romstage-y += rom_media.c
smm-y += memset.c
smm-y += memcpy.c
+smm-y += rom_media.c
$(obj)/arch/x86/lib/console.ramstage.o :: $(obj)/build.h
diff --git a/src/arch/x86/lib/cbfs_and_run.c b/src/arch/x86/lib/cbfs_and_run.c
index 1f87e7a..a023141 100644
--- a/src/arch/x86/lib/cbfs_and_run.c
+++ b/src/arch/x86/lib/cbfs_and_run.c
@@ -28,7 +28,7 @@ static void cbfs_and_run_core(const char *filename, unsigned ebp)
timestamp_add_now(TS_START_COPYRAM);
print_debug("Loading image.\n");
- dst = cbfs_load_stage(filename);
+ dst = cbfs_load_stage(CBFS_DEFAULT_MEDIA, filename);
if ((void *)dst == (void *) -1)
die("FATAL: Essential component is missing.\n");
diff --git a/src/arch/x86/lib/rom_media.c b/src/arch/x86/lib/rom_media.c
new file mode 100644
index 0000000..707b7f4
--- /dev/null
+++ b/src/arch/x86/lib/rom_media.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <cbfs.h>
+
+// Implementation of memory-mapped ROM media source on X86.
+
+static int x86_rom_open(struct cbfs_media *media) {
+ return 0;
+}
+
+static void *x86_rom_map(struct cbfs_media *media, size_t offset, size_t count) {
+ void *ptr = (void*)((uint32_t)0x0 - CONFIG_ROM_SIZE + offset);
+ return ptr;
+}
+
+static void *x86_rom_unmap(struct cbfs_media *media, const void *address) {
+ return NULL;
+}
+
+static size_t x86_rom_read(struct cbfs_media *media, void *dest, size_t offset,
+ size_t count) {
+ void *ptr = x86_rom_map(media, offset, count);
+ memcpy(dest, ptr, count);
+ x86_rom_unmap(media, ptr);
+ return count;
+}
+
+static int x86_rom_close(struct cbfs_media *media) {
+ return 0;
+}
+
+int init_default_cbfs_media(struct cbfs_media *media) {
+ media->context = (void*)CONFIG_ROM_SIZE;
+ media->open = x86_rom_open;
+ media->close = x86_rom_close;
+ media->map = x86_rom_map;
+ media->unmap = x86_rom_unmap;
+ media->read = x86_rom_read;
+ // TODO revise rom size by searching for cbfs_header->romsize.
+ return 0;
+}
diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c
index 15d6513..713a6df 100644
--- a/src/cpu/intel/microcode/microcode.c
+++ b/src/cpu/intel/microcode/microcode.c
@@ -166,8 +166,9 @@ void intel_update_microcode_from_cbfs(void)
#ifdef __PRE_RAM__
microcode_blob = walkcbfs((char *) MICROCODE_CBFS_FILE);
#else
- microcode_blob = cbfs_find_file(MICROCODE_CBFS_FILE,
- CBFS_TYPE_MICROCODE);
+ microcode_blob = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+ MICROCODE_CBFS_FILE,
+ CBFS_TYPE_MICROCODE);
#endif
intel_update_microcode(microcode_blob);
}
diff --git a/src/cpu/samsung/exynos5-common/Makefile.inc b/src/cpu/samsung/exynos5-common/Makefile.inc
index cad6cb3..d919347 100644
--- a/src/cpu/samsung/exynos5-common/Makefile.inc
+++ b/src/cpu/samsung/exynos5-common/Makefile.inc
@@ -1,2 +1,2 @@
-#romstage-y += soc.c
-romstage-y += spl_boot.c
+romstage-y += spi.c
+ramstage-y += spi.c
diff --git a/src/cpu/samsung/exynos5-common/spi.c b/src/cpu/samsung/exynos5-common/spi.c
new file mode 100644
index 0000000..ce64b5f
--- /dev/null
+++ b/src/cpu/samsung/exynos5-common/spi.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* FIXME(dhendrix): pulled in a lot of extra crap such as partition and string
+ libs*/
+#include <assert.h>
+#include <common.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <console/console.h>
+#include <console/loglevel.h>
+
+#include <config.h>
+#include <spi.h>
+
+#include <cpu/samsung/exynos5250/gpio.h>
+#include <cpu/samsung/exynos5250/clk.h>
+#include <cpu/samsung/exynos5250/cpu.h>
+#include <cpu/samsung/exynos5250/periph.h>
+#include <cpu/samsung/exynos5250/pinmux.h>
+
+#include <cpu/samsung/exynos5-common/cpu.h>
+#include <cpu/samsung/exynos5-common/exynos5-common.h>
+#include <cpu/samsung/exynos5-common/spi.h>
+
+#include <system.h>
+#include <arch/io.h>
+#include <lib.h>
+
+#define OM_STAT (0x1f << 1)
+#define EXYNOS_BASE_SPI1 ((void *)0x12d30000)
+
+static void exynos_spi_rx_tx(struct exynos_spi *regs, int todo,
+ void *dinp, void const *doutp, int i)
+{
+ int rx_lvl, tx_lvl;
+ uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
+ uint out_bytes, in_bytes;
+
+ out_bytes = in_bytes = todo;
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
+
+ while (in_bytes) {
+ uint32_t spi_sts;
+ int temp;
+
+ spi_sts = readl(®s->spi_sts);
+ rx_lvl = ((spi_sts >> 15) & 0x7f);
+ tx_lvl = ((spi_sts >> 6) & 0x7f);
+ while (tx_lvl < 32 && out_bytes) {
+ temp = 0xffffffff;
+ writel(temp, ®s->tx_data);
+ out_bytes -= 4;
+ tx_lvl += 4;
+ }
+ while (rx_lvl >= 4 && in_bytes) {
+ temp = readl(®s->rx_data);
+ if (rxp)
+ *rxp++ = temp;
+ in_bytes -= 4;
+ rx_lvl -= 4;
+ }
+ }
+}
+
+int exynos_spi_open(struct exynos_spi *regs)
+{
+ clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
+ /* set the spi1 GPIO */
+// exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
+ gpio_cfg_pin(GPIO_A24, 0x2);
+ gpio_cfg_pin(GPIO_A25, 0x2);
+ gpio_cfg_pin(GPIO_A26, 0x2);
+ gpio_cfg_pin(GPIO_A27, 0x2);
+
+ /* set pktcnt and enable it */
+ writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
+ /* set FB_CLK_SEL */
+ writel(SPI_FB_DELAY_180, ®s->fb_clk);
+ /* set CH_WIDTH and BUS_WIDTH as word */
+ setbits_le32(®s->mode_cfg,
+ SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
+ clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+ /* clear rx and tx channel if set priveously */
+ clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+ setbits_le32(®s->swap_cfg,
+ SPI_RX_SWAP_EN | SPI_RX_BYTE_SWAP | SPI_RX_HWORD_SWAP);
+
+ /* do a soft reset */
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+
+ /* now set rx and tx channel ON */
+ setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+ clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
+ return 0;
+}
+
+int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
+{
+ int upto, todo;
+ int i;
+ /* Send read instruction (0x3h) followed by a 24 bit addr */
+ writel((SF_READ_DATA_CMD << 24) | off, ®s->tx_data);
+
+ /* waiting for TX done */
+ while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE));
+
+ for (upto = 0, i = 0; upto < len; upto += todo, i++) {
+ todo = MIN(len - upto, (1 << 15));
+ exynos_spi_rx_tx(regs, todo, dest, (void *)(off), i);
+ }
+
+ setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
+
+ /*
+ * Let put controller mode to BYTE as
+ * SPI driver does not support WORD mode yet
+ */
+ clrbits_le32(®s->mode_cfg,
+ SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
+ writel(0, ®s->swap_cfg);
+
+ return len;
+}
+
+int exynos_spi_close(struct exynos_spi *regs)
+{
+ /*
+ * Flush spi tx, rx fifos and reset the SPI controller
+ * and clear rx/tx channel
+ */
+ clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+ return 0;
+}
+
+// SPI as CBFS media.
+struct exynos_spi_media {
+ struct exynos_spi *regs;
+ struct cbfs_simple_buffer buffer;
+};
+
+static int exynos_spi_cbfs_open(struct cbfs_media *media) {
+ struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+ printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_open\n");
+ return exynos_spi_open(spi->regs);
+}
+
+static int exynos_spi_cbfs_close(struct cbfs_media *media) {
+ struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+ printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_close\n");
+ return exynos_spi_close(spi->regs);
+}
+
+static size_t exynos_spi_cbfs_read(struct cbfs_media *media, void *dest,
+ size_t offset, size_t count) {
+ struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+ int bytes;
+ printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_read\n");
+ bytes = exynos_spi_read(spi->regs, dest, count, offset);
+ // Flush and re-open the device.
+ exynos_spi_close(spi->regs);
+ exynos_spi_open(spi->regs);
+ return bytes;
+}
+
+static void *exynos_spi_cbfs_map(struct cbfs_media *media, size_t offset,
+ size_t count) {
+ struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+ printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_map\n");
+ return cbfs_simple_buffer_map(&spi->buffer, media, offset, count);
+}
+
+static void *exynos_spi_cbfs_unmap(struct cbfs_media *media,
+ const void *address) {
+ struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+ printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_unmap\n");
+ return cbfs_simple_buffer_unmap(&spi->buffer, address);
+}
+
+int initialize_exynos_spi_cbfs_media(struct cbfs_media *media,
+ void *buffer_address,
+ size_t buffer_size) {
+ // TODO Replace static variable to support multiple streams.
+ static struct exynos_spi_media context;
+ printk(BIOS_SPEW, "SPI: initialize_exynos_spi_cbfs_media\n");
+
+ context.regs = EXYNOS_BASE_SPI1;
+ context.buffer.allocated = context.buffer.last_allocate = 0;
+ context.buffer.buffer = buffer_address;
+ context.buffer.size = buffer_size;
+ media->context = (void*)&context;
+ media->open = exynos_spi_cbfs_open;
+ media->close = exynos_spi_cbfs_close;
+ media->read = exynos_spi_cbfs_read;
+ media->map = exynos_spi_cbfs_map;
+ media->unmap = exynos_spi_cbfs_unmap;
+
+ return 0;
+}
+
+int init_default_cbfs_media(struct cbfs_media *media) {
+ // TODO make 0x17000 (size of cache) a Kconfig variable, or calculate by
+ // top of IRAM.
+ return initialize_exynos_spi_cbfs_media(
+ media, (void*)CONFIG_CBFS_CACHE_ADDRESS, 0x17000);
+}
diff --git a/src/cpu/samsung/exynos5-common/spi.h b/src/cpu/samsung/exynos5-common/spi.h
index 3f36759..e021888 100644
--- a/src/cpu/samsung/exynos5-common/spi.h
+++ b/src/cpu/samsung/exynos5-common/spi.h
@@ -22,6 +22,9 @@
#ifndef __ASSEMBLER__
+// This driver serves as a CBFS media source.
+#include <cbfs.h>
+
/* SPI peripheral register map; padded to 64KB */
struct exynos_spi {
unsigned int ch_cfg; /* 0x00 */
@@ -85,5 +88,15 @@ struct exynos_spi {
#define SPI_RX_BYTE_SWAP (1 << 6)
#define SPI_RX_HWORD_SWAP (1 << 7)
+/* API */
+int exynos_spi_open(struct exynos_spi *regs);
+int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off);
+int exynos_spi_close(struct exynos_spi *regs);
+
+/* Serve as CBFS Media */
+int initialize_exynos_spi_cbfs_media(struct cbfs_media *media,
+ void *buffer_address,
+ size_t buffer_size);
+
#endif /* __ASSEMBLER__ */
#endif
diff --git a/src/cpu/samsung/exynos5-common/spl_boot.c b/src/cpu/samsung/exynos5-common/spl_boot.c
index ecff871..1e264e3 100644
--- a/src/cpu/samsung/exynos5-common/spl_boot.c
+++ b/src/cpu/samsung/exynos5-common/spl_boot.c
@@ -55,9 +55,6 @@
#include <arch/io.h>
-/* FIXME(dhendrix): clean out u-boot global data stuff */
-//DECLARE_GLOBAL_DATA_PTR;
-
#define OM_STAT (0x1f << 1)
/**
@@ -102,117 +99,6 @@ static int config_branch_prediction(int set_cr_z)
return cr & CR_Z;
}
-#if 0
-static void spi_rx_tx(struct exynos_spi *regs, int todo,
- void *dinp, void const *doutp, int i)
-{
- uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
- int rx_lvl, tx_lvl;
- uint out_bytes, in_bytes;
-
- out_bytes = in_bytes = todo;
- setbits_le32(®s->ch_cfg, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_CH_RST);
- writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
-
- while (in_bytes) {
- uint32_t spi_sts;
- int temp;
-
- spi_sts = readl(®s->spi_sts);
- rx_lvl = ((spi_sts >> 15) & 0x7f);
- tx_lvl = ((spi_sts >> 6) & 0x7f);
- while (tx_lvl < 32 && out_bytes) {
- temp = 0xffffffff;
- writel(temp, ®s->tx_data);
- out_bytes -= 4;
- tx_lvl += 4;
- }
- while (rx_lvl >= 4 && in_bytes) {
- temp = readl(®s->rx_data);
- if (rxp)
- *rxp++ = temp;
- in_bytes -= 4;
- rx_lvl -= 4;
- }
- }
-}
-#endif
-
-/* FIXME(dhendrix): feels like exynos_spi_copy should go somewhere else... */
-#if 0
-/**
- * Copy uboot from spi flash to RAM
- *
- * @parma uboot_size size of u-boot to copy
- */
-static void exynos_spi_copy(unsigned int uboot_size)
-{
- int upto, todo;
- int i;
-// struct exynos_spi *regs = (struct exynos_spi *)samsung_get_base_spi1();
- struct exynos_spi *regs = (struct exynos_spi *)0x12d30000;
-
- clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
- /* set the spi1 GPIO */
- exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
-
- /* set pktcnt and enable it */
- writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
- /* set FB_CLK_SEL */
- writel(SPI_FB_DELAY_180, ®s->fb_clk);
- /* set CH_WIDTH and BUS_WIDTH as word */
- setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
- SPI_MODE_BUS_WIDTH_WORD);
- clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
-
- /* clear rx and tx channel if set priveously */
- clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
-
- setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
- SPI_RX_BYTE_SWAP |
- SPI_RX_HWORD_SWAP);
-
- /* do a soft reset */
- setbits_le32(®s->ch_cfg, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_CH_RST);
-
- /* now set rx and tx channel ON */
- setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
- clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
-
- /* Send read instruction (0x3h) followed by a 24 bit addr */
- writel((SF_READ_DATA_CMD << 24) | SPI_FLASH_UBOOT_POS, ®s->tx_data);
-
- /* waiting for TX done */
- while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE));
-
- for (upto = 0, i = 0; upto < uboot_size; upto += todo, i++) {
- todo = MIN(uboot_size - upto, (1 << 15));
- spi_rx_tx(regs, todo, (void *)(CONFIG_SYS_TEXT_BASE),
- (void *)(SPI_FLASH_UBOOT_POS), i);
- }
-
- setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
-
- /*
- * Let put controller mode to BYTE as
- * SPI driver does not support WORD mode yet
- */
- clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
- SPI_MODE_BUS_WIDTH_WORD);
- writel(0, ®s->swap_cfg);
-
- /*
- * Flush spi tx, rx fifos and reset the SPI controller
- * and clear rx/tx channel
- */
- clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
-}
-#endif
-
/* Copy U-Boot image to RAM */
static void copy_uboot_to_ram(void)
{
@@ -272,34 +158,6 @@ static void copy_uboot_to_ram(void)
debug("U-Boot copied\n");
}
-#if 0
-/**
- * Set up the U-Boot global_data pointer
- *
- * This sets the address of the global data, and sets up basic values.
- *
- * @param gdp Value to give to gd
- */
-static void setup_global_data(gd_t *gdp)
-{
- gd = gdp;
- memzero((void *)gd, sizeof(gd_t));
- gd->flags |= GD_FLG_RELOC;
- gd->baudrate = CONFIG_BAUDRATE;
- gd->have_console = 1;
-}
-#endif
-
-#if 0
-/* Tell the loaded U-Boot that it was loaded from SPL */
-static void exynos5_set_spl_marker(void)
-{
- uint32_t *marker = (uint32_t *)CONFIG_SPL_MARKER;
-
- *marker = EXYNOS5_SPL_MARKER;
-}
-#endif
-
/* Board-specific call to see if wakeup is allowed. */
static int __def_board_wakeup_permitted(void)
{
@@ -308,152 +166,3 @@ static int __def_board_wakeup_permitted(void)
int board_wakeup_permitted(void)
__attribute__((weak, alias("__def_board_wakeup_permitted")));
-void board_init_f(void)
-{
- /*
- * The gd struct is only needed for serial initialization. Since this
- * function is called in SPL u-boot. We store the gd struct in the
- * stack instead of the default memory region which may not be
- * initialized.
- */
-// __attribute__((aligned(8))) gd_t local_gd;
-// __attribute__((noreturn)) void (*uboot)(void);
-
-// exynos5_set_spl_marker();
-// setup_global_data(&local_gd);
-
- /*
- * Init subsystems, and resume if required. For a normal boot this
- * will set up the UART and display a message.
- */
- if (lowlevel_init_subsystems()) {
- if (!board_wakeup_permitted())
- power_reset();
- power_exit_wakeup();
- }
-
-// printk(BIOS_INFO, "\n\nU-Boot SPL, board rev %u\n", board_get_revision());
-
- copy_uboot_to_ram();
- /* Jump to U-Boot image */
-// uboot = (void *)CONFIG_SYS_TEXT_BASE;
-// uboot();
- /* Never returns Here */
-// printk(BIOS_ERR, "%s: u-boot jump failed", __func__);
- printk(BIOS_INFO, "%s: we should not be here...", __func__);
- hlt();
-}
-
-/* Place Holders */
-void board_init_r(gd_t *id, ulong dest_addr)
-{
- /* Function attribute is no-return */
- /* This Function never executes */
- while (1)
- ;
-}
-
-//void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {}
-
-#if 0
-/*
- * The following functions are required when linking console library to SPL.
- *
- * Enabling UART in SPL u-boot requires console library. But some
- * functions we needed in the console library depends on a bunch
- * of library in libgeneric, like lib/ctype.o, lib/div64.o, lib/string.o,
- * and lib/vsprintf.o. Adding them makes the SPL u-boot too large and not
- * fit into the expected size.
- *
- * So we mock these functions in SPL, i.e. vsprintf(), panic(), etc.,
- * in order to cut its dependency.
- */
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
- char *str = buf, *s;
- ulong u;
-
- /*
- * We won't implement all full functions of vsprintf().
- * We only implement %s and %u, and ignore others and directly use
- * the original format string as its result.
- */
-
- while (*fmt) {
- if (*fmt != '%') {
- *str++ = *fmt++;
- continue;
- }
- fmt++;
- switch (*fmt) {
- case '%':
- *str++ = *fmt++;
- break;
- case 's':
- fmt++;
- s = va_arg(args, char *);
- while (*s)
- *str++ = *s++;
- break;
- case 'u':
- fmt++;
- u = va_arg(args, ulong);
- s = simple_itoa(u);
- while (*s)
- *str++ = *s++;
- break;
- default:
- /* Print the original string for unsupported formats */
- *str++ = '%';
- *str++ = *fmt++;
- }
- }
- *str = '\0';
- return str - buf;
-}
-#endif
-
-#if 0
-void panic(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vprintf(fmt, args);
- putc('\n');
- va_end(args);
-#if defined(CONFIG_PANIC_HANG)
- hang();
-#else
- udelay(100000); /* allow messages to go out */
- do_reset(NULL, 0, 0, NULL);
-#endif
- while (1)
- ;
-}
-#endif
-
-#if 0
-void __assert_fail(const char *assertion, const char *file, unsigned line,
- const char *function)
-{
- /* This will not return */
- panic("%s:%u: %s: Assertion `%s' failed.", file, line, function,
- assertion);
-}
-#endif
-
-#if 0
-char *simple_itoa(ulong i)
-{
- /* 21 digits plus null terminator, good for 64-bit or smaller ints */
- static char local[22] __attribute__((section(".data")));
- char *p = &local[21];
-
- *p-- = '\0';
- do {
- *p-- = '0' + i % 10;
- i /= 10;
- } while (i > 0);
- return p + 1;
-}
-#endif
diff --git a/src/cpu/samsung/exynos5250/Kconfig b/src/cpu/samsung/exynos5250/Kconfig
index f5beddc..2c417cb 100644
--- a/src/cpu/samsung/exynos5250/Kconfig
+++ b/src/cpu/samsung/exynos5250/Kconfig
@@ -48,6 +48,14 @@ config ROMSTAGE_SIZE
hex
default 0x10000
+config CBFS_HEADER_ROM_OFFSET
+ hex "offset of master CBFS header in ROM"
+ default 0x2040
+
+config CBFS_CACHE_ADDRESS
+ hex "memory address to put CBFS cache data"
+ default 0x02060000
+
# FIXME: This is for copying SPI content into SRAM temporarily and
# will be removed when we have the SPI streaming driver implemented.
config SPI_IMAGE_HACK
diff --git a/src/cpu/via/nano/update_ucode.c b/src/cpu/via/nano/update_ucode.c
index 8f7ee22..d5757f8 100644
--- a/src/cpu/via/nano/update_ucode.c
+++ b/src/cpu/via/nano/update_ucode.c
@@ -105,7 +105,7 @@ unsigned int nano_update_ucode(void)
const struct cbfs_file *cbfs_ucode;
u32 fms = cpuid_eax(0x1);
- cbfs_ucode = cbfs_find("cpu_microcode_blob.bin");
+ cbfs_ucode = cbfs_get_file(CBFS_DEFAULT_MEDIA, "cpu_microcode_blob.bin");
/* Oops, did you forget to include the microcode ? */
if(cbfs_ucode == NULL) {
printk(BIOS_ALERT, "WARNING: No microcode file found in CBFS. "
diff --git a/src/device/oprom/realmode/x86.c b/src/device/oprom/realmode/x86.c
index 697d869..07eff0d 100644
--- a/src/device/oprom/realmode/x86.c
+++ b/src/device/oprom/realmode/x86.c
@@ -248,8 +248,9 @@ void vbe_set_graphics(void)
#if CONFIG_BOOTSPLASH
struct jpeg_decdata *decdata;
decdata = malloc(sizeof(*decdata));
- unsigned char *jpeg = cbfs_find_file("bootsplash.jpg",
- CBFS_TYPE_BOOTSPLASH);
+ unsigned char *jpeg = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+ "bootsplash.jpg",
+ CBFS_TYPE_BOOTSPLASH);
if (!jpeg) {
printk(BIOS_DEBUG, "VBE: No bootsplash found.\n");
return;
@@ -366,7 +367,8 @@ void do_vsmbios(void)
printk(BIOS_SPEW, "VSA: Real mode stub @%p: %d bytes\n", REALMODE_BASE,
(u32)&__realmode_code_size);
- if ((unsigned int)cbfs_load_stage("vsa") != VSA2_ENTRY_POINT) {
+ if ((unsigned int)cbfs_load_stage(CBFS_DEFAULT_MEDIA, "vsa") !=
+ VSA2_ENTRY_POINT) {
printk(BIOS_ERR, "Failed to load VSA.\n");
return;
}
diff --git a/src/device/oprom/yabel/vbe.c b/src/device/oprom/yabel/vbe.c
index 9dbe07c..5952dae 100644
--- a/src/device/oprom/yabel/vbe.c
+++ b/src/device/oprom/yabel/vbe.c
@@ -725,7 +725,9 @@ void vbe_set_graphics(void)
* cares. */
// int imagesize = 1024*768*2;
- unsigned char *jpeg = cbfs_find_file("bootsplash.jpg", CBFS_TYPE_BOOTSPLASH);
+ unsigned char *jpeg = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+ "bootsplash.jpg",
+ CBFS_TYPE_BOOTSPLASH);
if (!jpeg) {
DEBUG_PRINTF_VBE("Could not find bootsplash.jpg\n");
return;
diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c
index fe67515..bb0d760 100644
--- a/src/device/pci_rom.c
+++ b/src/device/pci_rom.c
@@ -35,7 +35,8 @@ struct rom_header *pci_rom_probe(struct device *dev)
struct pci_data *rom_data;
/* If it's in FLASH, then don't check device for ROM. */
- rom_header = cbfs_load_optionrom(dev->vendor, dev->device, NULL);
+ rom_header = cbfs_load_optionrom(CBFS_DEFAULT_MEDIA, dev->vendor,
+ dev->device, NULL);
u32 vendev = (dev->vendor << 16) | dev->device;
u32 mapped_vendev = vendev;
@@ -45,8 +46,10 @@ struct rom_header *pci_rom_probe(struct device *dev)
if (!rom_header) {
if (vendev != mapped_vendev) {
- rom_header = cbfs_load_optionrom(mapped_vendev >> 16,
- mapped_vendev & 0xffff , NULL);
+ rom_header = cbfs_load_optionrom(
+ CBFS_DEFAULT_MEDIA,
+ mapped_vendev >> 16,
+ mapped_vendev & 0xffff, NULL);
}
}
diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c
index d8d1778..5ffa9d7 100644
--- a/src/drivers/pc80/mc146818rtc.c
+++ b/src/drivers/pc80/mc146818rtc.c
@@ -190,7 +190,8 @@ int get_option(void *dest, const char *name)
namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
/* find the requested entry record */
- ct=cbfs_find_file("cmos_layout.bin", CBFS_COMPONENT_CMOS_LAYOUT);
+ ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
+ CBFS_COMPONENT_CMOS_LAYOUT);
if (!ct) {
printk(BIOS_ERR, "RTC: cmos_layout.bin could not be found. "
"Options are disabled\n");
@@ -268,7 +269,8 @@ int set_option(const char *name, void *value)
namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
/* find the requested entry record */
- ct=cbfs_find_file("cmos_layout.bin", CBFS_COMPONENT_CMOS_LAYOUT);
+ ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
+ CBFS_COMPONENT_CMOS_LAYOUT);
if (!ct) {
printk(BIOS_ERR, "cmos_layout.bin could not be found. Options are disabled\n");
return(-2);
diff --git a/src/include/cbfs.h b/src/include/cbfs.h
index b33e932..c194538 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -52,11 +52,35 @@
#include "cbfs_core.h"
#include <boot/coreboot_tables.h>
-void *cbfs_load_payload(struct lb_memory *lb_mem, const char *name);
-void *cbfs_load_stage(const char *name);
-int cbfs_execute_stage(const char *name);
-void *cbfs_load_optionrom(u16 vendor, u16 device, void * dest);
+int cbfs_execute_stage(struct cbfs_media *media, const char *name);
+void *cbfs_load_optionrom(struct cbfs_media *media, u16 vendor, u16 device,
+ void * dest);
+void *cbfs_load_payload(struct cbfs_media *media, const char *name);
+void *cbfs_load_stage(struct cbfs_media *media, const char *name);
+
+/* Simple buffer for streaming media. */
+struct cbfs_simple_buffer {
+ char *buffer;
+ size_t allocated;
+ size_t size;
+ size_t last_allocate;
+};
+
+void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
+ struct cbfs_media *media,
+ size_t offset, size_t count);
+
+void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
+ const void *address);
+
+// Utility functions
int run_address(void *f);
+
+/* Defined in src/lib/selfboot.c */
int selfboot(struct lb_memory *mem, struct cbfs_payload *payload);
+
+/* Defined in individual arch / board implementation. */
+int init_default_cbfs_media(struct cbfs_media *media);
+
#endif
diff --git a/src/include/cbfs_core.h b/src/include/cbfs_core.h
index a3c54b1..a90a8cf 100644
--- a/src/include/cbfs_core.h
+++ b/src/include/cbfs_core.h
@@ -50,6 +50,8 @@
#ifndef _CBFS_CORE_H_
#define _CBFS_CORE_H_
+#include <stddef.h>
+
/** These are standard values for the known compression
alogrithms that coreboot knows about for stages and
payloads. Of course, other CBFS users can use whatever
@@ -74,24 +76,18 @@
#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa
#define CBFS_COMPONENT_CMOS_LAYOUT 0x01aa
-
-/** this is the master cbfs header - it need to be
- located somewhere in the bootblock. Where it
- actually lives is up to coreboot. On x86, a
- pointer to this header will live at 0xFFFFFFFC,
- so we can easily find it. */
-
#define CBFS_HEADER_MAGIC 0x4F524243
-#if CONFIG_ARCH_X86
-#define CBFS_HEADPTR_ADDR 0xFFFFFFFC
-#elif CONFIG_ARCH_ARMV7
-/* FIXME: This could also be 0xFFFF0000 with HIVECS enabled */
-#define CBFS_HEADPTR_ADDR 0x0000000C
-#endif
#define CBFS_HEADER_VERSION1 0x31313131
#define CBFS_HEADER_VERSION2 0x31313132
#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2
+#define CBFS_HEADER_INVALID_ADDRESS ((void*)(0xffffffff))
+
+/** this is the master cbfs header - it need to be located somewhere available
+ to bootblock (to load romstage). Where it actually lives is up to coreboot.
+ On x86, a pointer to this header will live at 0xFFFFFFFC.
+ For other platforms, you need to define CONFIG_CBFS_HEADER_ROM_OFFSET */
+
struct cbfs_header {
uint32_t magic;
uint32_t version;
@@ -181,16 +177,49 @@ struct cbfs_optionrom {
#define CBFS_NAME(_c) (((char *) (_c)) + sizeof(struct cbfs_file))
#define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) )
-/* returns pointer to file inside CBFS or NULL */
-struct cbfs_file *cbfs_find(const char *name);
+#define CBFS_MEDIA_INVALID_MAP_ADDRESS ((void*)(0xffffffff))
+#define CBFS_DEFAULT_MEDIA ((void*)(0x0))
+
+/* Media for CBFS to load files. */
+struct cbfs_media {
+
+ /* implementation dependent context, to hold resource references */
+ void *context;
-/* returns pointer to file data inside CBFS */
-void *cbfs_get_file(const char *name);
+ /* opens media and returns 0 on success, -1 on failure */
+ int (*open)(struct cbfs_media *media);
-/* returns pointer to file data inside CBFS after if type is correct */
-void *cbfs_find_file(const char *name, int type);
+ /* returns number of bytes read from media into dest, starting from
+ * offset for count of bytes */
+ size_t (*read)(struct cbfs_media *media, void *dest, size_t offset,
+ size_t count);
+
+ /* returns a pointer to memory with count of bytes from media source
+ * starting from offset, or CBFS_MEDIA_INVALID_MAP_ADDRESS on failure.
+ * Note: mapped data can't be free unless unmap is called, even if you
+ * do close first. */
+ void * (*map)(struct cbfs_media *media, size_t offset, size_t count);
+
+ /* returns NULL and releases the memory by address, which was allocated
+ * by map */
+ void * (*unmap)(struct cbfs_media *media, const void *address);
+
+ /* closes media and returns 0 on success, -1 on failure. */
+ int (*close)(struct cbfs_media *media);
+};
+
+/* returns pointer to a file entry inside CBFS or NULL */
+struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name);
+
+/* returns pointer to file content inside CBFS after if type is correct */
+void *cbfs_get_file_content(struct cbfs_media *media, const char *name,
+ int type);
/* returns 0 on success, -1 on failure */
int cbfs_decompress(int algo, void *src, void *dst, int len);
-struct cbfs_header *get_cbfs_header(void);
+
+/* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS
+ * on failure */
+const struct cbfs_header *cbfs_get_header(struct cbfs_media *media);
+
#endif
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 98672d4..04efefd 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -28,18 +28,25 @@
#ifndef __SMM__
#define CBFS_CORE_WITH_LZMA
#endif
-#define phys_to_virt(x) (void*)(x)
-#define virt_to_phys(x) (uint32_t)(x)
+#ifndef ERROR
#define ERROR(x...) printk(BIOS_ERR, "CBFS: " x)
+#endif
+#ifndef LOG
#define LOG(x...) printk(BIOS_INFO, "CBFS: " x)
+#endif
#if CONFIG_DEBUG_CBFS
#define DEBUG(x...) printk(BIOS_SPEW, "CBFS: " x)
#else
#define DEBUG(x...)
#endif
-// FIXME: romstart/romend are fine on x86, but not on ARM
-#define romstart() 0xffffffff
-#define romend() 0
+
+#if CONFIG_CBFS_HEADER_ROM_OFFSET
+# define CBFS_HEADER_ROM_ADDRESS (CONFIG_CBFS_HEADER_ROM_OFFSET)
+#else
+// Indirect address: only works on 32bit top-aligned systems.
+# define CBFS_HEADER_ROM_ADDRESS \
+ ((uint32_t)CONFIG_ROM_SIZE + *(uint32_t*)0xfffffffc)
+#endif
#include "cbfs_core.c"
@@ -57,7 +64,8 @@ static void tohex16(unsigned int val, char* dest)
dest[3]=tohex4(val & 0xf);
}
-void *cbfs_load_optionrom(u16 vendor, u16 device, void * dest)
+void *cbfs_load_optionrom(struct cbfs_media *media,
+ u16 vendor, u16 device, void *dest)
{
char name[17]="pciXXXX,XXXX.rom";
struct cbfs_optionrom *orom;
@@ -67,7 +75,7 @@ void *cbfs_load_optionrom(u16 vendor, u16 device, void * dest)
tohex16(device, name+8);
orom = (struct cbfs_optionrom *)
- cbfs_find_file(name, CBFS_TYPE_OPTIONROM);
+ cbfs_get_file_content(media, name, CBFS_TYPE_OPTIONROM);
if (orom == NULL)
return NULL;
@@ -94,10 +102,10 @@ void *cbfs_load_optionrom(u16 vendor, u16 device, void * dest)
return dest;
}
-void * cbfs_load_stage(const char *name)
+void * cbfs_load_stage(struct cbfs_media *media, const char *name)
{
struct cbfs_stage *stage = (struct cbfs_stage *)
- cbfs_find_file(name, CBFS_TYPE_STAGE);
+ cbfs_get_file_content(media, name, CBFS_TYPE_STAGE);
/* this is a mess. There is no ntohll. */
/* for now, assume compatible byte order until we solve this. */
u32 entry;
@@ -126,10 +134,10 @@ void * cbfs_load_stage(const char *name)
return (void *) entry;
}
-int cbfs_execute_stage(const char *name)
+int cbfs_execute_stage(struct cbfs_media *media, const char *name)
{
struct cbfs_stage *stage = (struct cbfs_stage *)
- cbfs_find_file(name, CBFS_TYPE_STAGE);
+ cbfs_get_file_content(media, name, CBFS_TYPE_STAGE);
if (stage == NULL)
return 1;
@@ -145,6 +153,50 @@ int cbfs_execute_stage(const char *name)
return run_address((void *) (intptr_t)ntohll(stage->entry));
}
+void *cbfs_load_payload(struct cbfs_media *media, const char *name)
+{
+ return (struct cbfs_payload *)cbfs_get_file_content(
+ media, name, CBFS_TYPE_PAYLOAD);
+}
+
+/* Simple buffer */
+
+void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
+ struct cbfs_media *media,
+ size_t offset, size_t count) {
+ void *address = buffer->buffer + buffer->allocated;;
+ DEBUG("simple_buffer_map(offset=%d, count=%d): "
+ "allocated=%d, size=%d, last_allocate=%d\n",
+ offset, count, buffer->allocated, buffer->size,
+ buffer->last_allocate);
+ if (buffer->allocated + count >= buffer->size)
+ return CBFS_MEDIA_INVALID_MAP_ADDRESS;
+ if (media->read(media, address, offset, count) != count) {
+ ERROR("simple_buffer: fail to read %zd bytes from 0x%zx\n",
+ count, offset);
+ return CBFS_MEDIA_INVALID_MAP_ADDRESS;
+ }
+ buffer->allocated += count;
+ buffer->last_allocate = count;
+ return address;
+}
+
+void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
+ const void *address) {
+ // TODO Add simple buffer management so we can free more than last
+ // allocated one.
+ DEBUG("simple_buffer_unmap(address=0x%p): "
+ "allocated=%d, size=%d, last_allocate=%d\n",
+ address, buffer->allocated, buffer->size,
+ buffer->last_allocate);
+ if ((buffer->buffer + buffer->allocated - buffer->last_allocate) ==
+ address) {
+ buffer->allocated -= buffer->last_allocate;
+ buffer->last_allocate = 0;
+ }
+ return NULL;
+}
+
/**
* run_address is passed the address of a function taking no parameters and
* jumps to it, returning the result.
@@ -158,4 +210,5 @@ int run_address(void *f)
v = f;
return v();
}
+
#endif
diff --git a/src/lib/cbfs_core.c b/src/lib/cbfs_core.c
index 15cb68e..95cb0bd 100644
--- a/src/lib/cbfs_core.c
+++ b/src/lib/cbfs_core.c
@@ -27,14 +27,15 @@
* SUCH DAMAGE.
*/
-/* The CBFS core requires a couple of #defines or functions to adapt it to the target environment:
+/* The CBFS core requires a couple of #defines or functions to adapt it to the
+ * target environment:
*
* CBFS_CORE_WITH_LZMA (must be #define)
* if defined, ulzma() must exist for decompression of data streams
*
- * phys_to_virt(x), virt_to_phys(x)
- * translate physical addresses to virtual and vice versa
- * can be idempotent if no mapping is necessary.
+ * CBFS_HEADER_ROM_ADDRESS
+ * ROM address (offset) of CBFS header. Underlying CBFS media may interpret
+ * it in other way so we call this "address".
*
* ERROR(x...)
* print an error message x (in printf format)
@@ -45,105 +46,135 @@
* DEBUG(x...)
* print a debug message x (in printf format)
*
- * romstart()
- * returns the start address of the ROM image, or 0xffffffff if ROM is
- * top-aligned. This is a physical address.
- *
- * romend()
- * returns the highest address of the ROM image + 1, for use if
- * romstart() == 0xffffffff. This is a physical address.
*/
-#include <cbfs_core.h>
-
+#include <cbfs.h>
+#include <assert.h>
-/* returns pointer to master header or 0xffffffff if not found */
-struct cbfs_header *get_cbfs_header(void)
+/* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS
+ * on failure */
+const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
{
- struct cbfs_header *header;
-
- /* find header */
- if (romstart() == 0xffffffff) {
- header = (struct cbfs_header*)phys_to_virt(*(uint32_t*)phys_to_virt(romend() + CBFS_HEADPTR_ADDR));
- } else {
- // FIXME: where's the master header on ARM (our current bottom-aligned platform)?
- header = NULL;
+ const struct cbfs_header *header;
+ struct cbfs_media default_media;
+
+ if (media == CBFS_DEFAULT_MEDIA) {
+ media = &default_media;
+ if (init_default_cbfs_media(media) != 0) {
+ ERROR("Failed to initializee default media.\n");
+ return NULL;
+ }
+ }
+
+ media->open(media);
+ DEBUG("CBFS_HEADER_ROM_ADDRESS: 0x%x/0x%x\n", CBFS_HEADER_ROM_ADDRESS,
+ CONFIG_ROM_SIZE);
+ header = media->map(media, CBFS_HEADER_ROM_ADDRESS, sizeof(*header));
+ media->close(media);
+
+ if (header == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
+ ERROR("Failed to load CBFS header from 0x%x\n",
+ CBFS_HEADER_ROM_ADDRESS);
+ return CBFS_HEADER_INVALID_ADDRESS;
}
+
if (CBFS_HEADER_MAGIC != ntohl(header->magic)) {
- ERROR("Could not find valid CBFS master header at %p: %x vs %x.\n", header, CBFS_HEADER_MAGIC, ntohl(header->magic));
+ ERROR("Could not find valid CBFS master header at %x: "
+ "%x vs %x.\n", CBFS_HEADER_ROM_ADDRESS, CBFS_HEADER_MAGIC,
+ ntohl(header->magic));
if (header->magic == 0xffffffff) {
ERROR("Maybe ROM is not mapped properly?\n");
}
- return (void*)0xffffffff;
+ return CBFS_HEADER_INVALID_ADDRESS;
}
return header;
}
-// by must be power-of-two
-#define CBFS_ALIGN(val, by) (typeof(val))((uint32_t)(val + by - 1) & (uint32_t)~(by - 1))
-#define CBFS_ALIGN_UP(val, by) CBFS_ALIGN(val + 1, by)
-
/* public API starts here*/
-struct cbfs_file *cbfs_find(const char *name)
+struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name)
{
- struct cbfs_header *header = get_cbfs_header();
- if (header == (void*)0xffffffff) return NULL;
-
- LOG("Looking for '%s'\n", name);
-
- void *data, *dataend, *origdata;
- /* find first entry */
- if (romstart() == 0xffffffff) {
- data = (void*)phys_to_virt(romend()) - ntohl(header->romsize) + ntohl(header->offset);
- dataend = (void*)phys_to_virt(romend());
- } else {
- data = (void*)phys_to_virt(romstart()) + ntohl(header->offset);
- dataend = (void*)phys_to_virt(romstart()) + ntohl(header->romsize);
- }
- dataend -= ntohl(header->bootblocksize);
-
- int align = ntohl(header->align);
-
- origdata = data;
- while ((data < (dataend - 1)) && (data >= origdata)) {
- struct cbfs_file *file = data;
- if (memcmp(CBFS_FILE_MAGIC, file->magic, strlen(CBFS_FILE_MAGIC)) != 0) {
- // no file header found. corruption?
- // proceed in aligned steps to resynchronize
- LOG("ERROR: No file header found at %p, attempting to recover by searching for header\n", data);
- data = phys_to_virt(CBFS_ALIGN_UP(virt_to_phys(data), align));
- continue;
- }
- DEBUG("Check '%s'\n", CBFS_NAME(file));
- if (strcmp(CBFS_NAME(file), name) == 0) {
- LOG("found.\n");
- return file;
- }
- void *olddata = data;
- data = phys_to_virt(CBFS_ALIGN(virt_to_phys(data) + ntohl(file->len) + ntohl(file->offset), align));
- if (olddata > data) {
- LOG("Something is wrong here. File chain moved from %p to %p\n", olddata, data);
+ const char *file_name;
+ uint32_t offset, align, romsize, name_len;
+ const struct cbfs_header *header;
+ struct cbfs_file file, *file_ptr;
+ struct cbfs_media default_media;
+
+ if (media == CBFS_DEFAULT_MEDIA) {
+ media = &default_media;
+ if (init_default_cbfs_media(media) != 0) {
+ ERROR("Failed to initializee default media.\n");
return NULL;
}
}
- return NULL;
-}
-
-void *cbfs_get_file(const char *name)
-{
- struct cbfs_file *file = cbfs_find(name);
- if (file == NULL) {
- ERROR("Could not find file '%s'.\n", name);
+ if (CBFS_HEADER_INVALID_ADDRESS == (header = cbfs_get_header(media)))
return NULL;
- }
- return (void*)CBFS_SUBHEADER(file);
+ // Logical offset (for source media) of first file.
+ offset = ntohl(header->offset);
+ align = ntohl(header->align);
+
+ // TODO header->romsize seems broken now on ARM.
+ // Let's trust CONFIG_ROM_SIZE.
+#if CONFIG_ROM_SIZE
+ romsize = CONFIG_ROM_SIZE;
+#else
+ romsize = ntohl(header->romsize);
+#endif
+ DEBUG("offset: 0x%x, align: %d, romsize: %d\n", offset, align, romsize);
+
+ LOG("Looking for '%s' starting from 0x%x.\n", name, offset);
+ media->open(media);
+ while (offset < romsize &&
+ media->read(media, &file, offset, sizeof(file)) == sizeof(file)) {
+ if (memcmp(CBFS_FILE_MAGIC, file.magic,
+ sizeof(file.magic)) != 0) {
+ uint32_t new_align = align;
+ if (offset % align)
+ new_align += align - (offset % align);
+ ERROR("ERROR: No file header found at 0x%xx - "
+ "try next aligned address: 0x%x.\n", offset,
+ offset + new_align);
+ offset += new_align;
+ continue;
+ }
+ name_len = ntohl(file.offset) - sizeof(file);
+ DEBUG(" - load entry 0x%x file name (%d bytes)...\n", offset,
+ name_len);
+
+ // load file name (arbitrary length).
+ file_name = (const char*)media->map(
+ media, offset + sizeof(file), name_len);
+ if (file_name == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
+ ERROR("ERROR: Failed to get filename: 0x%x.\n", offset);
+ } else if (strcmp(file_name, name) == 0) {
+ int file_offset = ntohl(file.offset),
+ file_len = ntohl(file.len);
+ LOG("Found file (offset=0x%x, len=%d).\n",
+ offset + file_offset, file_len);
+ media->unmap(media, file_name);
+ file_ptr = media->map(media, offset,
+ file_offset + file_len);
+ media->close(media);
+ return file_ptr;
+ } else {
+ LOG(" (unmatched file @0x%x: %s)\n", offset, file_name);
+ media->unmap(media, file_name);
+ }
+
+ // Move to next file.
+ offset += ntohl(file.len) + ntohl(file.offset);
+ if (offset % align)
+ offset += align - (offset % align);
+ }
+ media->close(media);
+ ERROR("ERROR: Not found.\n");
+ return NULL;
}
-void *cbfs_find_file(const char *name, int type)
+void *cbfs_get_file_content(struct cbfs_media *media, const char *name, int type)
{
- struct cbfs_file *file = cbfs_find(name);
+ struct cbfs_file *file = cbfs_get_file(media, name);
if (file == NULL) {
ERROR("Could not find file '%s'.\n", name);
@@ -151,7 +182,8 @@ void *cbfs_find_file(const char *name, int type)
}
if (ntohl(file->type) != type) {
- ERROR("File '%s' is of type %x, but we requested %x.\n", name, ntohl(file->type), type);
+ ERROR("File '%s' is of type %x, but we requested %x.\n", name,
+ ntohl(file->type), type);
return NULL;
}
@@ -172,7 +204,9 @@ int cbfs_decompress(int algo, void *src, void *dst, int len)
return -1;
#endif
default:
- ERROR("tried to decompress %d bytes with algorithm #%x, but that algorithm id is unsupported.\n", len, algo);
+ ERROR("tried to decompress %d bytes with algorithm #%x,"
+ "but that algorithm id is unsupported.\n", len,
+ algo);
return -1;
}
}
diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c
index eed243a..85c05f5 100644
--- a/src/lib/hardwaremain.c
+++ b/src/lib/hardwaremain.c
@@ -59,6 +59,7 @@ void hardwaremain(int boot_complete);
void hardwaremain(int boot_complete)
{
struct lb_memory *lb_mem;
+ void *payload;
timestamp_stash(TS_START_RAMSTAGE);
post_code(POST_ENTRY_RAMSTAGE);
@@ -141,8 +142,8 @@ void hardwaremain(int boot_complete)
timestamp_add_now(TS_LOAD_PAYLOAD);
- void *payload;
- payload = cbfs_load_payload(lb_mem, CONFIG_CBFS_PREFIX "/payload");
+ payload = cbfs_load_payload(CBFS_DEFAULT_MEDIA,
+ CONFIG_CBFS_PREFIX "/payload");
if (! payload)
die("Could not find a payload\n");
diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c
index c5fb62a..56124da 100644
--- a/src/lib/selfboot.c
+++ b/src/lib/selfboot.c
@@ -536,12 +536,3 @@ out:
return 0;
}
-void *cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
-{
- struct cbfs_payload *payload;
-
- payload = (struct cbfs_payload *)cbfs_find_file(name, CBFS_TYPE_PAYLOAD);
-
- return payload;
-}
-
diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c
index d5ee0a3..e9fc13e 100644
--- a/src/mainboard/google/snow/bootblock.c
+++ b/src/mainboard/google/snow/bootblock.c
@@ -17,11 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define uchar unsigned char
-#define uint unsigned int
-
#include <stdlib.h>
#include <types.h>
+#include <assert.h>
+#include <arch/armv7/include/common.h>
#include <arch/io.h>
#include "cpu/samsung/exynos5250/clk.h"
#include "cpu/samsung/exynos5250/cpu.h"
@@ -34,6 +33,7 @@
#include "cpu/samsung/s5p-common/s3c24x0_i2c.h"
#include "cpu/samsung/exynos5-common/spi.h"
#include "cpu/samsung/exynos5-common/uart.h"
+#include "cbfs_core.h"
#include <device/i2c.h>
#include <drivers/maxim/max77686/max77686.h>
@@ -42,87 +42,9 @@
#define EXYNOS5_CLOCK_BASE 0x10010000
-/* FIXME(dhendrix): Can we move this SPI stuff elsewhere? */
-static void spi_rx_tx(struct exynos_spi *regs, int todo,
- void *dinp, void const *doutp, int i)
-{
- unsigned int *rxp = (unsigned int *)(dinp + (i * (32 * 1024)));
- int rx_lvl, tx_lvl;
- unsigned int out_bytes, in_bytes;
-
- out_bytes = in_bytes = todo;
- setbits_le32(®s->ch_cfg, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_CH_RST);
- writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
-
- while (in_bytes) {
- uint32_t spi_sts;
- int temp;
-
- spi_sts = readl(®s->spi_sts);
- rx_lvl = ((spi_sts >> 15) & 0x7f);
- tx_lvl = ((spi_sts >> 6) & 0x7f);
- while (tx_lvl < 32 && out_bytes) {
- temp = 0xffffffff;
- writel(temp, ®s->tx_data);
- out_bytes -= 4;
- tx_lvl += 4;
- }
- while (rx_lvl >= 4 && in_bytes) {
- temp = readl(®s->rx_data);
- if (rxp)
- *rxp++ = temp;
- in_bytes -= 4;
- rx_lvl -= 4;
- }
- }
-}
+// TODO Move this to Makefile.inc once we support adding bootblock stage files.
+#include "cpu/samsung/exynos5-common/spi.c"
-#if 0
-void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
-{
- struct exynos5_clock *clk =
- (struct exynos5_clock *)samsung_get_base_clock();
- unsigned shift;
- unsigned mask = 0xff;
- u32 *reg;
-
- /*
- * For now we only handle a very small subset of peipherals here.
- * Others will need to (and do) mangle the clock registers
- * themselves, At some point it is hoped that this function can work
- * from a table or calculated register offset / mask. For now this
- * is at least better than spreading clock control code around
- * U-Boot.
- */
- switch (periph_id) {
- case PERIPH_ID_SPI0:
- reg = &clk->div_peric1;
- shift = 8;
- break;
- case PERIPH_ID_SPI1:
- reg = &clk->div_peric1;
- shift = 24;
- break;
- case PERIPH_ID_SPI2:
- reg = &clk->div_peric2;
- shift = 8;
- break;
- case PERIPH_ID_SPI3:
- reg = &clk->sclk_div_isp;
- shift = 4;
- break;
- case PERIPH_ID_SPI4:
- reg = &clk->sclk_div_isp;
- shift = 16;
- break;
- default:
- debug("%s: Unsupported peripheral ID %d\n", __func__,
- periph_id);
- return;
- }
-}
-#endif
void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
{
struct exynos5_clock *clk =
@@ -136,43 +58,6 @@ void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
clrsetbits_le32(reg, mask << shift, (divisor & mask) << shift);
}
-#if 0
-void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor)
-{
- struct exynos5_clock *clk =
- (struct exynos5_clock *)samsung_get_base_clock();
- unsigned shift;
- unsigned mask = 0xff;
- u32 *reg;
-
- switch (periph_id) {
- case PERIPH_ID_SPI0:
- reg = &clk->div_peric1;
- shift = 0;
- break;
- case PERIPH_ID_SPI1:
- reg = &clk->div_peric1;
- shift = 16;
- break;
- case PERIPH_ID_SPI2:
- reg = &clk->div_peric2;
- shift = 0;
- break;
- case PERIPH_ID_SPI3:
- reg = &clk->sclk_div_isp;
- shift = 0;
- break;
- case PERIPH_ID_SPI4:
- reg = &clk->sclk_div_isp;
- shift = 12;
- break;
- default:
- debug("%s: Unsupported peripheral ID %d\n", __func__,
- periph_id);
- return;
- }
-}
-#endif
void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor)
{
struct exynos5_clock *clk =
@@ -249,44 +134,6 @@ static int clock_calc_best_scalar(unsigned int main_scaler_bits,
return best_main_scalar;
}
-#if 0
-int clock_set_rate(enum periph_id periph_id, unsigned int rate)
-{
- int main;
- unsigned int fine;
-
- switch (periph_id) {
- case PERIPH_ID_SPI0:
- case PERIPH_ID_SPI1:
- case PERIPH_ID_SPI2:
- case PERIPH_ID_SPI3:
- case PERIPH_ID_SPI4:
- main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
- if (main < 0) {
- debug("%s: Cannot set clock rate for periph %d",
- __func__, periph_id);
- return -1;
- }
- clock_ll_set_ratio(periph_id, main - 1);
- clock_ll_set_pre_ratio(periph_id, fine - 1);
- break;
- default:
- debug("%s: Unsupported peripheral ID %d\n", __func__,
- periph_id);
- return -1;
- }
- main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
- if (main < 0) {
- debug("%s: Cannot set clock rate for periph %d",
- __func__, periph_id);
- return -1;
- }
- clock_ll_set_ratio(PERIPH_ID_SPI1, main - 1);
- clock_ll_set_pre_ratio(PERIPH_ID_SPI1, fine - 1);
-
- return 0;
-}
-#endif
int clock_set_rate(enum periph_id periph_id, unsigned int rate)
{
int main;
@@ -358,77 +205,6 @@ void gpio_cfg_pin(int gpio, int cfg)
writel(value, &bank->con);
}
-//static void exynos_spi_copy(unsigned int uboot_size)
-static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int len)
-{
- int upto, todo;
- int i;
-// struct exynos_spi *regs = (struct exynos_spi *)samsung_get_base_spi1();
- struct exynos_spi *regs = (struct exynos_spi *)0x12d30000;
-
- clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
- /* set the spi1 GPIO */
-// exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
- gpio_cfg_pin(GPIO_A24, 0x2);
- gpio_cfg_pin(GPIO_A25, 0x2);
- gpio_cfg_pin(GPIO_A26, 0x2);
- gpio_cfg_pin(GPIO_A27, 0x2);
-
- /* set pktcnt and enable it */
- writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt);
- /* set FB_CLK_SEL */
- writel(SPI_FB_DELAY_180, ®s->fb_clk);
- /* set CH_WIDTH and BUS_WIDTH as word */
- setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
- SPI_MODE_BUS_WIDTH_WORD);
- clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
-
- /* clear rx and tx channel if set priveously */
- clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
-
- setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
- SPI_RX_BYTE_SWAP |
- SPI_RX_HWORD_SWAP);
-
- /* do a soft reset */
- setbits_le32(®s->ch_cfg, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_CH_RST);
-
- /* now set rx and tx channel ON */
- setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
- clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
-
- /* Send read instruction (0x3h) followed by a 24 bit addr */
- writel((SF_READ_DATA_CMD << 24) | spi_addr, ®s->tx_data);
-
- /* waiting for TX done */
- while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE));
-
- for (upto = 0, i = 0; upto < len; upto += todo, i++) {
- todo = MIN(len - upto, (1 << 15));
- spi_rx_tx(regs, todo, (void *)(sram_addr),
- (void *)(spi_addr), i);
- }
-
- setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
-
- /*
- * Let put controller mode to BYTE as
- * SPI driver does not support WORD mode yet
- */
- clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
- SPI_MODE_BUS_WIDTH_WORD);
- writel(0, ®s->swap_cfg);
-
- /*
- * Flush spi tx, rx fifos and reset the SPI controller
- * and clear rx/tx channel
- */
- clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_CH_RST);
- clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
-}
-
/* Pull mode */
#define EXYNOS_GPIO_PULL_NONE 0x0
#define EXYNOS_GPIO_PULL_DOWN 0x1
@@ -850,21 +626,15 @@ void do_barriers(void)
);
}
-void sdelay(unsigned long loops);
-void sdelay(unsigned long loops)
-{
- __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
- "bne 1b":"=r" (loops):"0"(loops));
-}
-
/* is this right? meh, it seems to work well enough... */
void my_udelay(unsigned int n);
void my_udelay(unsigned int n)
{
- sdelay(n * 1000);
+ n *= 1000;
+ __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+ "bne 1b":"=r" (n):"0"(n));
}
-
void i2c_init(int speed, int slaveadd)
{
struct s3c24x0_i2c_bus *i2c = &i2c0;
@@ -2141,13 +1911,6 @@ void bootblock_mainboard_init(void)
do_serial();
printk(BIOS_INFO, "%s: UART initialized\n", __func__);
- /* Copy romstage data from SPI ROM to SRAM */
- printk(BIOS_INFO, "Copying romstage:\n"
- "\tSPI offset: 0x%06x\n"
- "\tiRAM offset: 0x%08x\n"
- "\tSize: 0x%x\n",
- 0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
- copy_romstage(0x0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
#if 0
/* FIXME: dump SRAM content for sanity checking */
uint32_t u;
diff --git a/src/mainboard/samsung/lumpy/romstage.c b/src/mainboard/samsung/lumpy/romstage.c
index 5600cf6..9bc193b 100644
--- a/src/mainboard/samsung/lumpy/romstage.c
+++ b/src/mainboard/samsung/lumpy/romstage.c
@@ -301,7 +301,7 @@ void main(unsigned long bist)
break;
}
- spd_file = cbfs_find("spd.bin");
+ spd_file = cbfs_get_file(CBFS_DEFAULT_MEDIA, "spd.bin");
if (!spd_file)
die("SPD data not found.");
if (spd_file->len < (spd_index + 1) * 256)
diff --git a/src/northbridge/amd/agesa/family15tn/fam15tn_callouts.c b/src/northbridge/amd/agesa/family15tn/fam15tn_callouts.c
index 7c3b0ac..8c5605c 100644
--- a/src/northbridge/amd/agesa/family15tn/fam15tn_callouts.c
+++ b/src/northbridge/amd/agesa/family15tn/fam15tn_callouts.c
@@ -398,7 +398,9 @@ AGESA_STATUS fam15tn_DefaultRet (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
AGESA_STATUS fam15tn_HookGfxGetVbiosImage(UINT32 Func, UINT32 FchData, VOID *ConfigPrt)
{
GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt;
- pVbiosImageInfo->ImagePtr = cbfs_find_file("pci"CONFIG_VGA_BIOS_ID".rom", CBFS_TYPE_OPTIONROM);
+ pVbiosImageInfo->ImagePtr = cbfs_get_file_content(
+ CBFS_DEFAULT_MEDIA, "pci"CONFIG_VGA_BIOS_ID".rom",
+ CBFS_TYPE_OPTIONROM);
/* printk(BIOS_DEBUG, "IMGptr=%x\n", pVbiosImageInfo->ImagePtr); */
return pVbiosImageInfo->ImagePtr == NULL ? AGESA_WARNING : AGESA_SUCCESS;
}
diff --git a/src/northbridge/intel/i82830/vga.c b/src/northbridge/intel/i82830/vga.c
index 1ec7f87..40e7d9d 100644
--- a/src/northbridge/intel/i82830/vga.c
+++ b/src/northbridge/intel/i82830/vga.c
@@ -32,7 +32,7 @@
static void vga_init(device_t dev)
{
printk(BIOS_INFO, "Starting Graphics Initialization\n");
- struct cbfs_file *file = cbfs_find("mbi.bin");
+ struct cbfs_file *file = cbfs_get_file(CBFS_DEFAULT_MEDIA, "mbi.bin");
void *mbi = NULL;
unsigned int mbi_len = 0;
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c
index b5a1c23..f25aaa1 100644
--- a/src/northbridge/intel/sandybridge/raminit.c
+++ b/src/northbridge/intel/sandybridge/raminit.c
@@ -252,7 +252,9 @@ void sdram_initialize(struct pei_data *pei_data)
pei_data->tx_byte = console_tx_byte;
/* Locate and call UEFI System Agent binary. */
- entry = (unsigned long)cbfs_find_file("mrc.bin", 0xab);
+ /* TODO make MRC blob (0xab?) defined in cbfs_core.h. */
+ entry = (unsigned long)cbfs_get_file_content(
+ CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab);
if (entry) {
int rv;
asm volatile (
More information about the coreboot
mailing list