summaryrefslogtreecommitdiff
path: root/arch/x86/lib/e820.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/lib/e820.c')
-rw-r--r--arch/x86/lib/e820.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/x86/lib/e820.c b/arch/x86/lib/e820.c
index d478b7486e3..bcc5f6f3044 100644
--- a/arch/x86/lib/e820.c
+++ b/arch/x86/lib/e820.c
@@ -3,13 +3,39 @@
* Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
*/
+#define LOG_CATEGORY LOGC_ARCH
+
#include <efi_loader.h>
#include <lmb.h>
+#include <log.h>
#include <asm/e820.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
+static const char *const e820_type_name[E820_COUNT] = {
+ [E820_RAM] = "RAM",
+ [E820_RESERVED] = "Reserved",
+ [E820_ACPI] = "ACPI",
+ [E820_NVS] = "ACPI NVS",
+ [E820_UNUSABLE] = "Unusable",
+};
+
+void e820_dump(struct e820_entry *entries, uint count)
+{
+ int i;
+
+ printf("%12s %10s %s\n", "Addr", "Size", "Type");
+ for (i = 0; i < count; i++) {
+ struct e820_entry *entry = &entries[i];
+
+ printf("%12llx %10llx %s\n", entry->addr, entry->size,
+ entry->type < E820_COUNT ?
+ e820_type_name[entry->type] :
+ simple_itoa(entry->type));
+ }
+}
+
/*
* Install a default e820 table with 4 entries as follows:
*
@@ -37,6 +63,50 @@ __weak unsigned int install_e820_map(unsigned int max_entries,
return 4;
}
+void e820_init(struct e820_ctx *ctx, struct e820_entry *entries,
+ int max_entries)
+{
+ memset(ctx, '\0', sizeof(*ctx));
+ ctx->entries = entries;
+ ctx->max_entries = max_entries;
+}
+
+void e820_add(struct e820_ctx *ctx, enum e820_type type, u64 addr, u64 size)
+{
+ struct e820_entry *entry = &ctx->entries[ctx->count++];
+
+ if (ctx->count <= ctx->max_entries) {
+ entry->addr = addr;
+ entry->size = size;
+ entry->type = type;
+ }
+ ctx->addr = addr + size;
+}
+
+void e820_next(struct e820_ctx *ctx, enum e820_type type, u64 size)
+{
+ e820_add(ctx, type, ctx->addr, size);
+}
+
+void e820_to_addr(struct e820_ctx *ctx, enum e820_type type, u64 addr)
+{
+ e820_next(ctx, type, addr - ctx->addr);
+}
+
+int e820_finish(struct e820_ctx *ctx)
+{
+ if (ctx->count > ctx->max_entries) {
+ printf("e820 has %d entries but room for only %d\n", ctx->count,
+ ctx->max_entries);
+ panic("e820 table too large");
+ }
+ log_debug("e820 map installed, n=%d\n", ctx->count);
+ if (_DEBUG)
+ e820_dump(ctx->entries, ctx->count);
+
+ return ctx->count;
+}
+
#if CONFIG_IS_ENABLED(EFI_LOADER)
void efi_add_known_memory(void)
{