[coreboot-gerrit] Patch set updated for coreboot: d786d0a CBMEM: Add cbmem_locate_table()

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Fri Sep 6 15:29:37 CEST 2013


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3558

-gerrit

commit d786d0afec0808d3ec4a188fc3e7ba97523ed7ce
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Wed Sep 4 13:31:39 2013 +0300

    CBMEM: Add cbmem_locate_table()
    
    For both romstage and ramstage, this calls an arch-specific function
    get_cbmem_table() to resolve the base and size of CBMEM region. In ramstage,
    the result is cached as the query may be relatively slow involving multiple PCI
    configuration reads.
    
    For x86 CBMEM tables are located right below top of low ram and
    have fixed size of HIGH_MEMORY_SIZE in EARLY_CBMEM_INIT implementation.
    
    Change-Id: Ie8d16eb30cd5c3860fff243f36bd4e7d8827a782
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/arch/x86/boot/Makefile.inc |  2 ++
 src/arch/x86/boot/cbmem.c      | 21 ++++++++++++++++
 src/include/cbmem.h            |  1 +
 src/lib/cbmem.c                | 54 ++++++++++++++++++++++++------------------
 4 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/src/arch/x86/boot/Makefile.inc b/src/arch/x86/boot/Makefile.inc
index 9334839..d3a5f21 100644
--- a/src/arch/x86/boot/Makefile.inc
+++ b/src/arch/x86/boot/Makefile.inc
@@ -1,3 +1,5 @@
+romstage-y += cbmem.c
+
 ramstage-y += boot.c
 ramstage-$(CONFIG_MULTIBOOT) += multiboot.c
 ramstage-y += gdt.c
diff --git a/src/arch/x86/boot/cbmem.c b/src/arch/x86/boot/cbmem.c
index 6ec005d..333ca55 100644
--- a/src/arch/x86/boot/cbmem.c
+++ b/src/arch/x86/boot/cbmem.c
@@ -18,7 +18,28 @@
 #include <console/console.h>
 #include <cbmem.h>
 
+unsigned long __attribute__((weak)) get_top_of_ram(void)
+{
+	printk(BIOS_WARNING, "WARNING: you need to define get_top_of_ram() for your chipset\n");
+	return 0;
+}
+
 #if !CONFIG_DYNAMIC_CBMEM
+void get_cbmem_table(uint64_t *base, uint64_t *size)
+{
+	uint64_t top_of_ram = get_top_of_ram();
+
+	if (top_of_ram >= HIGH_MEMORY_SIZE) {
+		*base = top_of_ram - HIGH_MEMORY_SIZE;
+		*size = HIGH_MEMORY_SIZE;
+	} else {
+		*base = 0;
+		*size = 0;
+	}
+}
+#endif
+
+#if !CONFIG_DYNAMIC_CBMEM && !defined(__PRE_RAM__)
 /* This is for compatibility with old boards only. Any new chipset and board
  * must implement get_top_of_ram() for both romstage and ramstage to support
  * features like CAR_MIGRATION and CBMEM_CONSOLE.
diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index 96b9da8..4ee0b2e 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -140,6 +140,7 @@ int cbmem_base_check(void);
 void cbmem_init(u64 baseaddr, u64 size);
 int cbmem_reinit(u64 baseaddr);
 
+void get_cbmem_table(uint64_t *base, uint64_t *size);
 extern struct cbmem_entry *get_cbmem_toc(void);
 
 #endif /* CONFIG_DYNAMIC_CBMEM */
diff --git a/src/lib/cbmem.c b/src/lib/cbmem.c
index 41d80b8..c69a8e6 100644
--- a/src/lib/cbmem.c
+++ b/src/lib/cbmem.c
@@ -45,30 +45,48 @@ struct cbmem_entry {
 #ifndef __PRE_RAM__
 uint64_t high_tables_base = 0;
 uint64_t high_tables_size = 0;
-static struct cbmem_entry *bss_cbmem_toc;
+#endif
 
-struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void)
+void __attribute__((weak)) set_cbmem_toc(struct cbmem_entry * x)
 {
-	return bss_cbmem_toc;
+	/* do nothing, this should be called by chipset to save TOC in NVRAM */
 }
 
-void __attribute__((weak)) set_cbmem_toc(struct cbmem_entry * x)
+#if !defined(__PRE_RAM__)
+static void cbmem_trace_location(uint64_t base, uint64_t size, const char *s)
 {
-	/* do nothing, this should be called by chipset to save TOC in NVRAM */
+	if (base && size && s) {
+		printk(BIOS_DEBUG, "CBMEM region %llx-%llx (%s)\n",
+			base, base + size - 1, s);
+	}
 }
+#endif
+
+static void cbmem_locate_table(uint64_t *base, uint64_t *size)
+{
+#ifdef __PRE_RAM__
+	get_cbmem_table(base, size);
 #else
+	if (!(high_tables_base && high_tables_size)) {
+		get_cbmem_table(&high_tables_base, &high_tables_size);
+		cbmem_trace_location(high_tables_base, high_tables_size, __FUNCTION__);
+	}
+	*base = high_tables_base;
+	*size = high_tables_size;
+#endif
+}
 
 struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void)
 {
-	printk(BIOS_WARNING, "WARNING: you need to define get_cbmem_toc() for your chipset\n");
-	return NULL;
+	uint64_t base, size;
+	cbmem_locate_table(&base, &size);
+	return (struct cbmem_entry *)(unsigned long)base;
 }
-#endif
 
 #if !defined(__PRE_RAM__)
 void cbmem_late_set_table(uint64_t base, uint64_t size)
 {
-	printk(BIOS_DEBUG, "CBMEM region %llx-%llx (%s)\n", base, base+size-1, __FUNCTION__);
+	cbmem_trace_location(base, size, __FUNCTION__);
 	high_tables_base = base;
 	high_tables_size = size;
 }
@@ -89,10 +107,6 @@ void cbmem_init(u64 baseaddr, u64 size)
 	struct cbmem_entry *cbmem_toc;
 	cbmem_toc = (struct cbmem_entry *)(unsigned long)baseaddr;
 
-#ifndef __PRE_RAM__
-	bss_cbmem_toc = cbmem_toc;
-#endif
-
 	printk(BIOS_DEBUG, "Initializing CBMEM area to 0x%llx (%lld bytes)\n",
 	       baseaddr, size);
 
@@ -123,10 +137,6 @@ int cbmem_reinit(u64 baseaddr)
 	printk(BIOS_DEBUG, "Re-Initializing CBMEM area to 0x%lx\n",
 	       (unsigned long)baseaddr);
 
-#ifndef __PRE_RAM__
-	bss_cbmem_toc = cbmem_toc;
-#endif
-
 	return (cbmem_toc[0].magic == CBMEM_MAGIC);
 }
 
@@ -219,21 +229,19 @@ void *cbmem_find(u32 id)
 /* Returns True if it was not initialized before. */
 int cbmem_initialize(void)
 {
+	uint64_t base = 0, size = 0;
 	int rv = 0;
 
-#ifdef __PRE_RAM__
-	uint64_t high_tables_base = get_top_of_ram() - HIGH_MEMORY_SIZE;
-	uint64_t high_tables_size = HIGH_MEMORY_SIZE;
-#endif
+	cbmem_locate_table(&base, &size);
 
 	/* We expect the romstage to always initialize it. */
-	if (!cbmem_reinit(high_tables_base)) {
+	if (!cbmem_reinit(base)) {
 #if CONFIG_HAVE_ACPI_RESUME && !defined(__PRE_RAM__)
 		/* Something went wrong, our high memory area got wiped */
 		if (acpi_slp_type == 3 || acpi_slp_type == 2)
 			acpi_slp_type = 0;
 #endif
-		cbmem_init(high_tables_base, high_tables_size);
+		cbmem_init(base, size);
 		rv = 1;
 	}
 #ifndef __PRE_RAM__



More information about the coreboot-gerrit mailing list