[coreboot-gerrit] Patch set updated for coreboot: ad2f2a5 baytrail: cache reference code for S3 resume

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Fri May 9 17:26:37 CEST 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5013

-gerrit

commit ad2f2a5b77202a3e5ead9c0beeb20e50c5c52c52
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Dec 12 10:29:48 2013 -0800

    baytrail: cache reference code for S3 resume
    
    In order to use the same reference code on S3 resume
    that was booted the program needs to be cached. Piggy
    back on the ramstage cache to save the loaded reference
    code program.
    
    BUG=chrome-os-partner:22867
    BRANCH=None
    TEST=Built and booted. S3 resumed. Noted locations of reference
         code caching and load addresses in console.
    
    Change-Id: I90ceaf5697e8c269c3244370519d4d8a8ee2eb4a
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/179777
    Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/soc/intel/baytrail/refcode.c | 109 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 101 insertions(+), 8 deletions(-)

diff --git a/src/soc/intel/baytrail/refcode.c b/src/soc/intel/baytrail/refcode.c
index 9b5aa67..f746358 100644
--- a/src/soc/intel/baytrail/refcode.c
+++ b/src/soc/intel/baytrail/refcode.c
@@ -17,19 +17,113 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <string.h>
+#include <arch/acpi.h>
 #include <cbmem.h>
 #include <console/console.h>
 #include <cpu/x86/tsc.h>
 #include <rmodule.h>
+#include <ramstage_cache.h>
 
 #include <baytrail/ramstage.h>
 #include <baytrail/efi_wrapper.h>
 
+static inline int is_s3_resume(void)
+{
+#if CONFIG_HAVE_ACPI_RESUME
+	return acpi_slp_type == 3;
+#else
+	return 0;
+#endif
+}
+
+static inline struct ramstage_cache *next_cache(struct ramstage_cache *c)
+{
+	return (struct ramstage_cache *)&c->program[c->size];
+}
+
 static void ABI_X86 send_to_console(unsigned char b)
 {
 	console_tx_byte(b);
 }
 
+static efi_wrapper_entry_t load_refcode_from_cache(void)
+{
+	struct ramstage_cache *c;
+	long cache_size;
+
+	printk(BIOS_DEBUG, "refcode loading from cache.\n");
+
+	c = ramstage_cache_location(&cache_size);
+
+	if (!ramstage_cache_is_valid(c)) {
+		printk(BIOS_DEBUG, "Invalid ramstage cache descriptor.\n");
+		return NULL;
+	}
+
+	c = next_cache(c);
+	if (!ramstage_cache_is_valid(c)) {
+		printk(BIOS_DEBUG, "Invalid refcode cache descriptor.\n");
+		return NULL;
+	}
+
+	printk(BIOS_DEBUG, "Loading cached reference code from 0x%08x(%x)\n",
+	       c->load_address, c->size);
+	memcpy((void *)c->load_address, &c->program[0], c->size);
+
+	return (efi_wrapper_entry_t)c->entry_point;
+}
+
+static void cache_refcode(const struct rmod_stage_load *rsl)
+{
+	struct ramstage_cache *c;
+	long cache_size;
+
+	c = ramstage_cache_location(&cache_size);
+
+	if (!ramstage_cache_is_valid(c)) {
+		printk(BIOS_DEBUG, "No place to cache reference code.\n");
+		return;
+	}
+
+	/* Determine how much remaining cache available. */
+	cache_size -= c->size + sizeof(*c);
+
+	if (cache_size < (sizeof(*c) + cbmem_entry_size(rsl->cbmem_entry))) {
+		printk(BIOS_DEBUG, "Not enough cache space for ref code.\n");
+		return;
+	}
+
+	c = next_cache(c);
+	c->magic = RAMSTAGE_CACHE_MAGIC;
+	c->entry_point = (uint32_t)rsl->entry;
+	c->load_address = (uint32_t)cbmem_entry_start(rsl->cbmem_entry);
+	c->size = cbmem_entry_size(rsl->cbmem_entry);;
+
+	printk(BIOS_DEBUG, "Caching refcode at 0x%p(%x)\n",
+	       &c->program[0], c->size);
+	memcpy(&c->program[0], (void *)c->load_address, c->size);
+}
+
+static efi_wrapper_entry_t load_refcode_from_cbfs(void)
+{
+	struct rmod_stage_load refcode = {
+		.cbmem_id = CBMEM_ID_REFCODE,
+		.name = CONFIG_CBFS_PREFIX "/refcode",
+	};
+
+	printk(BIOS_DEBUG, "refcode loading from cbfs.\n");
+
+	if (rmodule_stage_load_from_cbfs(&refcode) || refcode.entry == NULL) {
+		printk(BIOS_DEBUG, "Error loading reference code.\n");
+		return NULL;
+	}
+
+	cache_refcode(&refcode);
+
+	return refcode.entry;
+}
+
 void baytrail_run_reference_code(void)
 {
 	int ret;
@@ -38,18 +132,17 @@ void baytrail_run_reference_code(void)
 		.version = EFI_WRAPPER_VER,
 		.console_out = send_to_console,
 	};
-	struct rmod_stage_load refcode = {
-		.cbmem_id = CBMEM_ID_REFCODE,
-		.name = CONFIG_CBFS_PREFIX "/refcode",
-	};
 
-	if (rmodule_stage_load_from_cbfs(&refcode) || refcode.entry == NULL) {
-		printk(BIOS_DEBUG, "Error loading reference code.\n");
-		return;
+	if (is_s3_resume()) {
+		entry = load_refcode_from_cache();
+	} else {
+		entry = load_refcode_from_cbfs();
 	}
 
+	if (entry == NULL)
+		return;
+
 	wrp.tsc_ticks_per_microsecond = tsc_freq_mhz();
-	entry = refcode.entry;
 
 	/* Call into reference code. */
 	ret = entry(&wrp);



More information about the coreboot-gerrit mailing list