aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commonlib/include/commonlib/coreboot_tables.h13
-rw-r--r--src/include/cbmem.h4
-rw-r--r--src/include/imd.h16
-rw-r--r--src/lib/coreboot_table.c3
-rw-r--r--src/lib/imd.c44
-rw-r--r--src/lib/imd_cbmem.c43
6 files changed, 119 insertions, 4 deletions
diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h
index 2ed4d7f277..5e0c87c99d 100644
--- a/src/commonlib/include/commonlib/coreboot_tables.h
+++ b/src/commonlib/include/commonlib/coreboot_tables.h
@@ -308,6 +308,19 @@ struct lb_boot_media_params {
uint64_t boot_media_size;
};
+/*
+ * There can be more than one of these records as there is one per cbmem entry.
+ */
+#define LB_TAG_CBMEM_ENTRY 0x0031
+struct lb_cbmem_entry {
+ uint32_t tag;
+ uint32_t size;
+
+ uint64_t address;
+ uint32_t entry_size;
+ uint32_t id;
+};
+
#define LB_TAG_SERIALNO 0x002a
#define MAX_SERIALNO_LENGTH 32
diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index 0825f2936f..efaa44f9c9 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -37,6 +37,7 @@
#ifndef __ASSEMBLER__
#include <stddef.h>
#include <stdint.h>
+#include <boot/coreboot_tables.h>
struct cbmem_entry;
@@ -114,12 +115,11 @@ typedef void (* const cbmem_init_hook_t)(int is_recovery);
void cbmem_run_init_hooks(int is_recovery);
void cbmem_fail_resume(void);
-#ifndef __PRE_RAM__
/* Ramstage only functions. */
/* Add the cbmem memory used to the memory map at boot. */
void cbmem_add_bootmem(void);
void cbmem_list(void);
-#endif /* __PRE_RAM__ */
+void cbmem_add_records_to_cbtable(struct lb_header *header);
#if ENV_RAMSTAGE
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_) static cbmem_init_hook_t \
diff --git a/src/include/imd.h b/src/include/imd.h
index 90a0dd5a90..6575312f3d 100644
--- a/src/include/imd.h
+++ b/src/include/imd.h
@@ -120,6 +120,9 @@ size_t imd_entry_size(const struct imd *imd, const struct imd_entry *entry);
/* Returns pointer to region described by entry or NULL on failure. */
void *imd_entry_at(const struct imd *imd, const struct imd_entry *entry);
+/* Returns id for the imd entry. */
+uint32_t imd_entry_id(const struct imd *imd, const struct imd_entry *entry);
+
/* Attempt to remove entry from imd. */
int imd_entry_remove(const struct imd *imd, const struct imd_entry *entry);
@@ -132,6 +135,13 @@ struct imd_lookup {
int imd_print_entries(const struct imd *imd, const struct imd_lookup *lookup,
size_t size);
+struct imd_cursor;
+/* Initialize an imd_cursor object to walk the IMD entries. */
+int imd_cursor_init(const struct imd *imd, struct imd_cursor *cursor);
+
+/* Retrieve the next imd entry the cursor is referencing. Returns NULL when
+ * no more entries exist. */
+const struct imd_entry *imd_cursor_next(struct imd_cursor *cursor);
/*
* The struct imd is a handle for working with an in-memory directory.
@@ -148,4 +158,10 @@ struct imd {
struct imdr sm;
};
+struct imd_cursor {
+ size_t current_imdr;
+ size_t current_entry;
+ const struct imdr *imdr[2];
+};
+
#endif /* _IMD_H_ */
diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
index 8ffc69836c..258a4a53b7 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -538,6 +538,9 @@ unsigned long write_coreboot_table(
lb_boot_media_params(head);
+ /* Add all cbmem entries into the coreboot tables. */
+ cbmem_add_records_to_cbtable(head);
+
/* Remember where my valid memory ranges are */
return lb_table_fini(head);
}
diff --git a/src/lib/imd.c b/src/lib/imd.c
index bbfbced9c8..2ad9cd8934 100644
--- a/src/lib/imd.c
+++ b/src/lib/imd.c
@@ -623,6 +623,11 @@ void *imd_entry_at(const struct imd *imd, const struct imd_entry *entry)
return imdr_entry_at(imdr, entry);
}
+uint32_t imd_entry_id(const struct imd *imd, const struct imd_entry *entry)
+{
+ return entry->id;
+}
+
int imd_entry_remove(const struct imd *imd, const struct imd_entry *entry)
{
struct imd_root *r;
@@ -698,3 +703,42 @@ int imd_print_entries(const struct imd *imd, const struct imd_lookup *lookup,
return 0;
}
+
+int imd_cursor_init(const struct imd *imd, struct imd_cursor *cursor)
+{
+ if (imd == NULL || cursor == NULL)
+ return -1;
+
+ memset(cursor, 0, sizeof(*cursor));
+
+ cursor->imdr[0] = &imd->lg;
+ cursor->imdr[1] = &imd->sm;
+
+ return 0;
+}
+
+const struct imd_entry *imd_cursor_next(struct imd_cursor *cursor)
+{
+ struct imd_root *r;
+ const struct imd_entry *e;
+
+ if (cursor->current_imdr >= ARRAY_SIZE(cursor->imdr))
+ return NULL;
+
+ r = imdr_root(cursor->imdr[cursor->current_imdr]);
+
+ if (r == NULL)
+ return NULL;
+
+ if (cursor->current_entry >= r->num_entries) {
+ /* Try next imdr. */
+ cursor->current_imdr++;
+ cursor->current_entry = 0;
+ return imd_cursor_next(cursor);
+ }
+
+ e = &r->entries[cursor->current_entry];
+ cursor->current_entry++;
+
+ return e;
+}
diff --git a/src/lib/imd_cbmem.c b/src/lib/imd_cbmem.c
index 7cc34f5878..49faad97b4 100644
--- a/src/lib/imd_cbmem.c
+++ b/src/lib/imd_cbmem.c
@@ -263,7 +263,6 @@ void *cbmem_entry_start(const struct cbmem_entry *entry)
return imd_entry_at(imd, cbmem_to_imd(entry));
}
-#if ENV_RAMSTAGE
void cbmem_add_bootmem(void)
{
void *base = NULL;
@@ -273,10 +272,50 @@ void cbmem_add_bootmem(void)
bootmem_add_range((uintptr_t)base, size, LB_MEM_TABLE);
}
+#if ENV_RAMSTAGE
+/*
+ * -fdata-sections doesn't work so well on read only strings. They all
+ * get put in the same section even though those strings may never be
+ * referenced in the final binary.
+ */
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__ */
+#endif
+
+void cbmem_add_records_to_cbtable(struct lb_header *header)
+{
+ struct imd_cursor cursor;
+ struct imd *imd;
+
+ imd = cbmem_get_imd();
+
+ if (imd_cursor_init(imd, &cursor))
+ return;
+
+ while (1) {
+ const struct imd_entry *e;
+ struct lb_cbmem_entry *lbe;
+ uint32_t id;
+
+ e = imd_cursor_next(&cursor);
+
+ if (e == NULL)
+ break;
+
+ id = imd_entry_id(imd, e);
+ /* Don't add these metadata entries. */
+ if (id == CBMEM_ID_IMD_ROOT || id == CBMEM_ID_IMD_SMALL)
+ continue;
+
+ lbe = (struct lb_cbmem_entry *)lb_new_record(header);
+ lbe->tag = LB_TAG_CBMEM_ENTRY;
+ lbe->size = sizeof(*lbe);
+ lbe->address = (uintptr_t)imd_entry_at(imd, e);
+ lbe->entry_size = imd_entry_size(imd, e);
+ lbe->id = id;
+ }
+}