From 96722f750ac761e3d9e286b9212fe7eb6d232883 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Tue, 4 Feb 2014 10:24:34 -0600 Subject: [PATCH] baytrail: implement alternative payload loading Similarly to lynxpoint payload loading can be made faster by taking advantage of the spi controller's caching and prefetching. Provide the same mechanism as lynxpoint to provide a 30ms payload loading savings. The speed up isn't as dramatic as lynxpoint presumably because baytrail is an SoC without the DMI communication overhead. Regardless, payload loading decreases from ~55ms to ~25ms. BUG=chrome-os-partner:25385 BRANCH=baytrail TEST=Built and did numerous reboots. Observe time savings. Change-Id: I5726d41559a8b4facb4bfdb7e629d04819dc9d37 Signed-off-by: Aaron Durbin Reviewed-on: https://chromium-review.googlesource.com/184853 Reviewed-by: Duncan Laurie --- src/soc/intel/baytrail/Kconfig | 1 + src/soc/intel/baytrail/Makefile.inc | 1 + src/soc/intel/baytrail/spi_loading.c | 102 +++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 src/soc/intel/baytrail/spi_loading.c diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig index 0940eaa8ab..66f0baf8d0 100644 --- a/src/soc/intel/baytrail/Kconfig +++ b/src/soc/intel/baytrail/Kconfig @@ -8,6 +8,7 @@ if SOC_INTEL_BAYTRAIL config CPU_SPECIFIC_OPTIONS def_bool y + select ALT_CBFS_LOAD_PAYLOAD select CACHE_MRC_SETTINGS select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM select CACHE_ROM diff --git a/src/soc/intel/baytrail/Makefile.inc b/src/soc/intel/baytrail/Makefile.inc index ca8ebc0276..f540ac1f4f 100644 --- a/src/soc/intel/baytrail/Makefile.inc +++ b/src/soc/intel/baytrail/Makefile.inc @@ -51,6 +51,7 @@ romstage-y += stage_cache.c ramstage-$(CONFIG_ELOG) += elog.c ramstage-y += hda.c ramstage-y += hda_verb.c +ramstage-$(CONFIG_ALT_CBFS_LOAD_PAYLOAD) += spi_loading.c # Remove as ramstage gets fleshed out ramstage-y += placeholders.c diff --git a/src/soc/intel/baytrail/spi_loading.c b/src/soc/intel/baytrail/spi_loading.c new file mode 100644 index 0000000000..5ac8aa1234 --- /dev/null +++ b/src/soc/intel/baytrail/spi_loading.c @@ -0,0 +1,102 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +#define CACHELINE_SIZE 64 +#define INTRA_CACHELINE_MASK (CACHELINE_SIZE - 1) +#define CACHELINE_MASK (~INTRA_CACHELINE_MASK) + +/* + * Mirror the payload file to the default SMM location if it is small enough. + * The default SMM region can be used since no one is using the memory at this + * location at this stage in the boot. + */ +static inline void *spi_mirror(void *file_start, int file_len) +{ + int alignment_diff; + char *src; + char *dest = (void *)SMM_DEFAULT_BASE; + + alignment_diff = (INTRA_CACHELINE_MASK & (long)file_start); + + /* + * Adjust file length so that the start and end points are aligned to a + * cacheline. Coupled with the ROM caching in the CPU the SPI hardware + * will read and cache full length cachelines. It will also prefetch + * data as well. Once things are mirrored in memory all accesses should + * hit the CPUs cache. + */ + file_len += alignment_diff; + file_len = ALIGN(file_len, CACHELINE_SIZE); + + printk(BIOS_DEBUG, "Payload aligned size: 0x%x\n", file_len); + + /* + * Just pass back the pointer to ROM space if the file is larger + * than the RAM mirror region. + */ + if (file_len > SMM_DEFAULT_SIZE) + return file_start; + + src = (void *)(CACHELINE_MASK & (long)file_start); + /* + * Note that if mempcy is not using 32-bit moves the performance will + * degrade because the SPI hardware prefetchers look for + * cacheline-aligned 32-bit accesses to kick in. + */ + memcpy(dest, src, file_len); + + /* Provide pointer into mirrored space. */ + return &dest[alignment_diff]; +} + +void *cbfs_load_payload(struct cbfs_media *media, const char *name) +{ + int file_len; + void *file_start; + struct cbfs_file *file; + + file_start = vboot_get_payload(&file_len); + + if (file_start != NULL) + return spi_mirror(file_start, file_len); + + file = cbfs_get_file(media, name); + + if (file == NULL) + return NULL; + + if (ntohl(file->type) != CBFS_TYPE_PAYLOAD) + return NULL; + + file_len = ntohl(file->len); + + file_start = CBFS_SUBHEADER(file); + + return spi_mirror(file_start, file_len); +}