diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h index 88212c3..dda3173 100644 --- a/include/lib/coreboot.h +++ b/include/lib/coreboot.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,6 +19,27 @@ } coreboot_serial_t; extern coreboot_serial_t coreboot_serial; +#define COREBOOT_MAX_MEMRANGES 32 /* libpayload also uses this limit */ + +typedef struct __packed { + uint64_t start; + uint64_t size; + uint32_t type; +} coreboot_memrange_t; +extern coreboot_memrange_t coreboot_memranges[COREBOOT_MAX_MEMRANGES]; + +typedef enum { + CB_MEM_NONE = 0, /* coreboot will never report this */ + CB_MEM_RAM = 1, + CB_MEM_RESERVED = 2, + CB_MEM_ACPI = 3, + CB_MEM_NVS = 4, + CB_MEM_UNUSABLE = 5, + CB_MEM_VENDOR_RSVD = 6, + CB_MEM_TABLE = 16, +} coreboot_memory_t; + +coreboot_memory_t coreboot_get_memory_type(uintptr_t address); void coreboot_table_setup(void *base); #endif /* COREBOOT_H */ diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c index 253fac2..c4cd1d7 100644 --- a/lib/coreboot/coreboot_table.c +++ b/lib/coreboot/coreboot_table.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,6 +29,7 @@ } cb_header_t; typedef enum { + CB_TAG_MEMORY = 0x1, CB_TAG_SERIAL = 0xf, CB_TAG_CBMEM_CONSOLE = 0x17, } cb_tag_t; @@ -37,11 +38,13 @@ uint32_t tag; uint32_t size; union { + coreboot_memrange_t memranges[COREBOOT_MAX_MEMRANGES]; coreboot_serial_t serial; uint64_t uint64; }; } cb_entry_t; +coreboot_memrange_t coreboot_memranges[COREBOOT_MAX_MEMRANGES]; coreboot_serial_t coreboot_serial; /* @@ -86,6 +89,23 @@ CONSOLE_FLAG_CRASH); } +coreboot_memory_t coreboot_get_memory_type(uintptr_t address) +{ + int i; + + for (i = 0; i < COREBOOT_MAX_MEMRANGES; i++) { + coreboot_memrange_t *range = &coreboot_memranges[i]; + + if (range->type == CB_MEM_NONE) + break; /* end of table reached */ + if (address >= range->start && + address - range->start < range->size) + return range->type; + } + + return CB_MEM_NONE; +} + void coreboot_table_setup(void *base) { cb_header_t *header = base; @@ -99,6 +119,7 @@ ptr = base + header->header_bytes; for (i = 0; i < header->table_entries; i++) { + size_t size; cb_entry_t *entry = ptr; if (ptr - base >= header->header_bytes + header->table_bytes) { @@ -107,6 +128,15 @@ } switch (read_le32(&entry->tag)) { + case CB_TAG_MEMORY: + size = read_le32(&entry->size) - + offsetof(cb_entry_t, memranges); + if (size > sizeof(coreboot_memranges)) { + ERROR("Need to truncate coreboot memranges!\n"); + size = sizeof(coreboot_memranges); + } + memcpy(&coreboot_memranges, &entry->memranges, size); + break; case CB_TAG_SERIAL: memcpy(&coreboot_serial, &entry->serial, sizeof(coreboot_serial));