[coreboot-gerrit] Patch set updated for coreboot: 23e580b coreboot: add cbmem based on imd library
Aaron Durbin (adurbin@google.com)
gerrit at coreboot.org
Wed Apr 1 21:44:07 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 23e580bb92b9da91139abb26e661515408a40d0b
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