x86: Add a new API for e820
The existing mechanism is pretty painful as it requires manual calculations for anything but a trivial setup. Add a new API for adding e820 entries. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
#define E820MAX 128 /* number of entries in E820MAP */
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#define E820_RAM 1
|
||||
#define E820_RESERVED 2
|
||||
#define E820_ACPI 3
|
||||
@@ -10,9 +12,21 @@
|
||||
#define E820_UNUSABLE 5
|
||||
#define E820_COUNT 6 /* Number of types */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#else
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Available e820 memory-region types */
|
||||
enum e820_type {
|
||||
E820_RAM = 1,
|
||||
E820_RESERVED,
|
||||
E820_ACPI,
|
||||
E820_NVS,
|
||||
E820_UNUSABLE,
|
||||
|
||||
E820_COUNT,
|
||||
};
|
||||
|
||||
struct e820_entry {
|
||||
__u64 addr; /* start of memory segment */
|
||||
__u64 size; /* size of memory segment */
|
||||
@@ -22,10 +36,81 @@ struct e820_entry {
|
||||
#define ISA_START_ADDRESS 0xa0000
|
||||
#define ISA_END_ADDRESS 0x100000
|
||||
|
||||
/**
|
||||
* Context to use for e820_add()
|
||||
*
|
||||
* @entries: Table being filled in
|
||||
* @addr: Current address we are up to
|
||||
* @count: Number of entries added to @entries so far
|
||||
* @max_entries: Maximum number of entries allowed
|
||||
*/
|
||||
struct e820_ctx {
|
||||
struct e820_entry *entries;
|
||||
u64 addr;
|
||||
int count;
|
||||
int max_entries;
|
||||
};
|
||||
|
||||
/**
|
||||
* e820_init() - Start setting up an e820 table
|
||||
*
|
||||
* @ctx: Context to set up
|
||||
* @entries: Place to put entries
|
||||
* @max_entries: Maximum size of @entries
|
||||
*/
|
||||
void e820_init(struct e820_ctx *ctx, struct e820_entry *entries,
|
||||
int max_entries);
|
||||
|
||||
/**
|
||||
* e820_add() - Add an entry to the table
|
||||
*
|
||||
* @ctx: Context
|
||||
* @type: Type of entry
|
||||
* @addr: Start address of entry
|
||||
* @size Size of entry
|
||||
*/
|
||||
void e820_add(struct e820_ctx *ctx, enum e820_type type, u64 addr, u64 size);
|
||||
|
||||
/**
|
||||
* e820_to_addr() - Add an entry that covers the space up to a given address
|
||||
*
|
||||
* @ctx: Context
|
||||
* @type: Type of entry
|
||||
* @end_addr: Address where the entry should finish
|
||||
*/
|
||||
void e820_to_addr(struct e820_ctx *ctx, enum e820_type type, u64 end_addr);
|
||||
|
||||
/**
|
||||
* e820_next() - Add an entry that carries on from the last one
|
||||
*
|
||||
* @ctx: Context
|
||||
* @type: Type of entry
|
||||
* @size Size of entry
|
||||
*/
|
||||
void e820_next(struct e820_ctx *ctx, enum e820_type type, u64 size);
|
||||
|
||||
/**
|
||||
* e820_finish() - Finish the table
|
||||
*
|
||||
* Checks the table is not too large, panics if so
|
||||
*
|
||||
* @ctx: Context
|
||||
* Returns: Number of entries
|
||||
*/
|
||||
int e820_finish(struct e820_ctx *ctx);
|
||||
|
||||
/* Implementation-defined function to install an e820 map */
|
||||
unsigned int install_e820_map(unsigned int max_entries,
|
||||
struct e820_entry *);
|
||||
|
||||
/**
|
||||
* e820_dump() - Dump the e820 table
|
||||
*
|
||||
* @entries: Pointer to start of table
|
||||
* @count: Number of entries in the table
|
||||
*/
|
||||
void e820_dump(struct e820_entry *entries, uint count);
|
||||
|
||||
/**
|
||||
* cb_install_e820_map() - Install e820 map provided by coreboot sysinfo
|
||||
*
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
* 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>
|
||||
|
||||
@@ -60,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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user