[coreboot-gerrit] Patch set updated for coreboot: 9b56bb7 coreboot: add cbmem based on imd library

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Wed Apr 1 21:30:03 CEST 2015


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

-gerrit

commit 9b56bb7aae76e0d04402a124c54e4b53fecc210b
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Mar 5 21:18:33 2015 -0600

    coreboot: add cbmem based on imd library
    
    Utilize the newly introduced imd library for an alternative
    implemenation of the cbmem API. It relies on
    PLATFORM_HAS_EARLY_WRITABLE_GLOBALS to use the imd library.
    
    Change-Id: Icfa8eae91d18072cc023ac05639360f3b1d5fa93
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/include/cbmem.h     |  13 ---
 src/lib/Makefile.inc    |   9 +-
 src/lib/cbmem_common.c  |  59 +++++++-------
 src/lib/dynamic_cbmem.c |  54 ++++++------
 src/lib/imd_cbmem.c     | 212 ++++++++++++++++++++++++++++++++++++++++++++++++
 util/cbmem/cbmem.c      |   4 +
 6 files changed, 281 insertions(+), 70 deletions(-)

diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index 10d058a..702978b 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -85,11 +85,6 @@
 #include <stddef.h>
 #include <stdint.h>
 
-struct cbmem_id_to_name {
-	u32 id;
-	const char *name;
-};
-
 #define CBMEM_ID_TO_NAME_TABLE				 \
 	{ CBMEM_ID_FREESPACE,		"FREE SPACE " }, \
 	{ CBMEM_ID_GDT,			"GDT        " }, \
@@ -138,13 +133,6 @@ struct cbmem_entry;
  * dynamic cbmem infrastructure allocates new regions below the last allocated
  * region. Regions are defined by a cbmem_entry struct that is opaque. Regions
  * may be removed, but the last one added is the only that can be removed.
- *
- * Dynamic cbmem has two allocators within it. All allocators use a top down
- * allocation scheme. However, there are 2 modes for each allocation depending
- * on the requested size. There are large allocations and small allocations.
- * An allocation is considered to be small when it is less than or equal to
- * DYN_CBMEM_ALIGN_SIZE / 2. The smaller allocations are fit into a larger
- * allocation region.
  */
 
 #define DYN_CBMEM_ALIGN_SIZE (4096)
@@ -198,7 +186,6 @@ void cbmem_fail_resume(void);
 /* Add the cbmem memory used to the memory map at boot. */
 void cbmem_add_bootmem(void);
 void cbmem_list(void);
-void cbmem_print_entry(int n, u32 id, u64 start, u64 size);
 #endif /* __PRE_RAM__ */
 
 /* These are for compatibility with old boards only. Any new chipset and board
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 736fa9b..f49cf8b 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -89,8 +89,13 @@ ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c
 ramstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c
 ramstage-$(CONFIG_TERTIARY_BOARD_ID) += tristate_gpios.c
 
-romstage-y += cbmem_common.c dynamic_cbmem.c
-ramstage-y += cbmem_common.c dynamic_cbmem.c
+romstage-y += cbmem_common.c
+romstage-$(CONFIG_PLATFORM_NO_EARLY_WRITABLE_GLOBALS) += dynamic_cbmem.c
+romstage-$(CONFIG_PLATFORM_HAS_EARLY_WRITABLE_GLOBALS) += imd_cbmem.c
+
+ramstage-y += cbmem_common.c
+ramstage-$(CONFIG_PLATFORM_NO_EARLY_WRITABLE_GLOBALS) += dynamic_cbmem.c
+ramstage-$(CONFIG_PLATFORM_HAS_EARLY_WRITABLE_GLOBALS) += imd_cbmem.c
 
 romstage-y += imd.c
 ramstage-y += imd.c
diff --git a/src/lib/cbmem_common.c b/src/lib/cbmem_common.c
index c3e8383..51f61a9 100644
--- a/src/lib/cbmem_common.c
+++ b/src/lib/cbmem_common.c
@@ -18,39 +18,15 @@
  */
 #include <console/console.h>
 #include <cbmem.h>
-#include <stdlib.h>
+#include <bootstate.h>
+#if IS_ENABLED(CONFIG_ARCH_X86) && !IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
+#include <arch/acpi.h>
+#endif
 
 /* FIXME: Remove after CBMEM_INIT_HOOKS. */
 #include <console/cbmem_console.h>
 #include <timestamp.h>
 
-#ifndef __PRE_RAM__
-
-static const struct cbmem_id_to_name cbmem_ids[] = { CBMEM_ID_TO_NAME_TABLE };
-
-void cbmem_print_entry(int n, u32 id, u64 base, u64 size)
-{
-	int i;
-	const char *name;
-
-	name = NULL;
-	for (i = 0; i < ARRAY_SIZE(cbmem_ids); i++) {
-		if (cbmem_ids[i].id == id) {
-			name = cbmem_ids[i].name;
-			break;
-		}
-	}
-
-	if (name == NULL)
-		printk(BIOS_DEBUG, "%08x ", id);
-	else
-		printk(BIOS_DEBUG, "%s", name);
-	printk(BIOS_DEBUG, "%2d. ", n);
-	printk(BIOS_DEBUG, "%08llx ", base);
-	printk(BIOS_DEBUG, "%08llx\n", size);
-}
-
-#endif /* !__PRE_RAM__ */
 
 /* FIXME: Replace with CBMEM_INIT_HOOKS API. */
 #if !IS_ENABLED(CONFIG_ARCH_X86)
@@ -67,3 +43,30 @@ void __attribute__((weak)) cbmem_fail_resume(void)
 {
 }
 #endif
+
+#if !defined(__PRE_RAM__)
+
+#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
+/* selected cbmem can be initialized early in ramstage. Additionally, that
+ * means cbmem console can be reinitialized early as well. The post_device
+ * function is empty since cbmem was initialized early in ramstage. */
+static void init_cbmem_pre_device(void *unused)
+{
+	cbmem_initialize();
+}
+
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, init_cbmem_pre_device, NULL);
+#else
+
+static void init_cbmem_post_device(void *unused)
+{
+	if (acpi_is_wakeup())
+		cbmem_initialize();
+	else
+		cbmem_initialize_empty();
+}
+
+BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY,
+			init_cbmem_post_device, NULL);
+#endif
+#endif /* !defined(__PRE_RAM__) */
diff --git a/src/lib/dynamic_cbmem.c b/src/lib/dynamic_cbmem.c
index 3b008c7..cff8f7d 100644
--- a/src/lib/dynamic_cbmem.c
+++ b/src/lib/dynamic_cbmem.c
@@ -24,9 +24,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include <arch/early_variables.h>
-#if IS_ENABLED(CONFIG_ARCH_X86) && !IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
-#include <arch/acpi.h>
-#endif
 #ifndef UINT_MAX
 #define UINT_MAX 4294967295U
 #endif
@@ -426,30 +423,6 @@ void *cbmem_entry_start(const struct cbmem_entry *entry)
 
 #if !defined(__PRE_RAM__)
 
-#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
-/* selected cbmem can be initialized early in ramstage. Additionally, that
- * means cbmem console can be reinitialized early as well. The post_device
- * function is empty since cbmem was initialized early in ramstage. */
-static void init_cbmem_pre_device(void *unused)
-{
-	cbmem_initialize();
-}
-
-BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, init_cbmem_pre_device, NULL);
-#else
-
-static void init_cbmem_post_device(void *unused)
-{
-	if (acpi_is_wakeup())
-		cbmem_initialize();
-	else
-		cbmem_initialize_empty();
-}
-
-BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY,
-			init_cbmem_post_device, NULL);
-#endif
-
 void cbmem_add_bootmem(void)
 {
 	uintptr_t base;
@@ -460,6 +433,33 @@ void cbmem_add_bootmem(void)
 	bootmem_add_range(base, top - base, LB_MEM_TABLE);
 }
 
+static const struct {
+	u32 id;
+	const char *name;
+} cbmem_ids[] = { CBMEM_ID_TO_NAME_TABLE };
+
+static void cbmem_print_entry(int n, u32 id, u64 base, u64 size)
+{
+	int i;
+	const char *name;
+
+	name = NULL;
+	for (i = 0; i < ARRAY_SIZE(cbmem_ids); i++) {
+		if (cbmem_ids[i].id == id) {
+			name = cbmem_ids[i].name;
+			break;
+		}
+	}
+
+	if (name == NULL)
+		printk(BIOS_DEBUG, "%08x ", id);
+	else
+		printk(BIOS_DEBUG, "%s", name);
+	printk(BIOS_DEBUG, "%2d. ", n);
+	printk(BIOS_DEBUG, "%08llx ", base);
+	printk(BIOS_DEBUG, "%08llx\n", size);
+}
+
 void cbmem_list(void)
 {
 	unsigned int i;
diff --git a/src/lib/imd_cbmem.c b/src/lib/imd_cbmem.c
new file mode 100644
index 0000000..bdce86f
--- /dev/null
+++ b/src/lib/imd_cbmem.c
@@ -0,0 +1,212 @@
+/*
+ * 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 <bootstate.h>
+#include <bootmem.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <imd.h>
+#include <rules.h>
+#include <string.h>
+#include <stdlib.h>
+#include <arch/early_variables.h>
+#if IS_ENABLED(CONFIG_ARCH_X86) && !IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
+#include <arch/acpi.h>
+#endif
+
+/* The root region is at least DYN_CBMEM_ALIGN_SIZE . */
+#define ROOT_MIN_SIZE DYN_CBMEM_ALIGN_SIZE
+#define LG_ALIGN ROOT_MIN_SIZE
+
+static struct imd imd_cbmem CAR_GLOBAL = { };
+
+static inline struct imd *cbmem_get_imd(void)
+{
+	return car_get_var_ptr(&imd_cbmem);
+}
+
+#if ENV_RAMSTAGE
+void cbmem_set_top(void *ramtop)
+{
+	struct imd *imd = cbmem_get_imd();
+
+	imd_handle_init(imd, ramtop);
+}
+#endif
+
+static inline const struct cbmem_entry *imd_to_cbmem(const struct imd_entry *e)
+{
+	return (const struct cbmem_entry *)e;
+}
+
+static inline const struct imd_entry *cbmem_to_imd(const struct cbmem_entry *e)
+{
+	return (const struct imd_entry *)e;
+}
+
+void cbmem_initialize_empty(void)
+{
+	struct imd *imd;
+
+	imd = cbmem_get_imd();
+
+	imd_handle_init(imd, cbmem_top());
+
+	printk(BIOS_DEBUG, "CBMEM: ");
+
+	if (imd_create_empty(imd, ROOT_MIN_SIZE, LG_ALIGN))
+		return;
+
+	/* Complete migration to CBMEM. */
+	cbmem_run_init_hooks();
+}
+
+static inline int cbmem_fail_recovery(void)
+{
+	cbmem_initialize_empty();
+	cbmem_fail_resume();
+	return 1;
+}
+
+int cbmem_initialize(void)
+{
+	struct imd *imd;
+
+	imd = cbmem_get_imd();
+
+	imd_handle_init(imd, cbmem_top());
+
+	if (imd_recover(imd) != 0)
+		return cbmem_fail_recovery();
+
+#if defined(__PRE_RAM__)
+	/*
+	 * Lock the imd in romstage on a recovery. The assumption is that
+	 * if the imd area was recovered in romstage then S3 resume path
+	 * is being taken.
+	 */
+	imd_lockdown(imd);
+#endif
+
+	/* Complete migration to CBMEM. */
+	cbmem_run_init_hooks();
+
+	/* Recovery successful. */
+	return 0;
+}
+
+int cbmem_recovery(int is_wakeup)
+{
+	int rv = 0;
+	if (!is_wakeup)
+		cbmem_initialize_empty();
+	else
+		rv = cbmem_initialize();
+	return rv;
+}
+
+const struct cbmem_entry *cbmem_entry_add(u32 id, u64 size64)
+{
+	struct imd *imd;
+	const struct imd_entry *e;
+
+	imd = cbmem_get_imd();
+
+	e = imd_entry_find_or_add(imd, id, size64);
+
+	return imd_to_cbmem(e);
+}
+
+void *cbmem_add(u32 id, u64 size)
+{
+	const struct cbmem_entry *entry;
+
+	entry = cbmem_entry_add(id, size);
+
+	if (entry == NULL)
+		return NULL;
+
+	return cbmem_entry_start(entry);
+}
+
+/* Retrieve a region provided a given id. */
+const struct cbmem_entry *cbmem_entry_find(u32 id)
+{
+	struct imd *imd;
+	const struct imd_entry *e;
+
+	imd = cbmem_get_imd();
+
+	e = imd_entry_find(imd, id);
+
+	return imd_to_cbmem(e);
+}
+
+void *cbmem_find(u32 id)
+{
+	const struct cbmem_entry *entry;
+
+	entry = cbmem_entry_find(id);
+
+	if (entry == NULL)
+		return NULL;
+
+	return cbmem_entry_start(entry);
+}
+
+/* Remove a reserved region. Returns 0 on success, < 0 on error. Note: A region
+ * cannot be removed unless it was the last one added. */
+int cbmem_entry_remove(const struct cbmem_entry *entry)
+{
+	const struct imd_entry *e = cbmem_to_imd(entry);
+
+	return imd_entry_remove(cbmem_get_imd(), e);
+}
+
+u64 cbmem_entry_size(const struct cbmem_entry *entry)
+{
+	const struct imd_entry *e = cbmem_to_imd(entry);
+
+	return imd_entry_size(cbmem_get_imd(), e);
+}
+
+void *cbmem_entry_start(const struct cbmem_entry *entry)
+{
+	const struct imd_entry *e = cbmem_to_imd(entry);
+
+	return imd_entry_at(cbmem_get_imd(), e);
+}
+
+#if ENV_RAMSTAGE
+void cbmem_add_bootmem(void)
+{
+	void *base = NULL;
+	size_t size = 0;
+
+	imd_region_used(cbmem_get_imd(), &base, &size);
+	bootmem_add_range((uintptr_t)base, size, LB_MEM_TABLE);
+}
+
+void cbmem_list(void)
+{
+	static const struct imd_lookup lookup[] = { CBMEM_ID_TO_NAME_TABLE };
+
+	imd_print_entries(cbmem_get_imd(), lookup, ARRAY_SIZE(lookup));
+}
+#endif /* __PRE_RAM__ */
diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c
index 4314d30..afcc98f 100644
--- a/util/cbmem/cbmem.c
+++ b/util/cbmem/cbmem.c
@@ -598,6 +598,10 @@ struct cbmem_entry {
 	uint64_t size;
 } __attribute__((packed));
 
+struct cbmem_id_to_name {
+	uint32_t id;
+	const char *name;
+};
 static const struct cbmem_id_to_name cbmem_ids[] = { CBMEM_ID_TO_NAME_TABLE };
 
 void cbmem_print_entry(int n, uint32_t id, uint64_t base, uint64_t size)



More information about the coreboot-gerrit mailing list