cbmem: stop assuming 1MiB of memory can be mapped

The default mapping size is 1MiB of ram. However, not
all systems allow 1MiB of memory to mapped depending on
the kernel's memory map. Therefore, be explicit about
the sizes to mmap().

The only path that wasn't cleaned up was the coverage path
as that needs to handle dynamic cbmem. The correct way to
fix that is to add a global like the timestamps that is set
while parsing cbtable.

BUG=chrome-os-partner:31355
BRANCH=None
TEST=Can cbmem -ltc on ryu.

Change-Id: I548afa5ddbe0a859f52bc2ab2d0931186ee378a5
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: df4991ce1da7f0c25e99d84222cbc8d3189d0d66
Original-Change-Id: I27b70ae8a8fba168d1c1829bbef0135c7b651eac
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/221971
Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Original-Tested-by: Furquan Shaikh <furquan@chromium.org>
Original-Commit-Queue: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: http://review.coreboot.org/8829
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Aaron Durbin 2014-10-07 14:56:35 -05:00 committed by Patrick Georgi
parent 29df70f081
commit b58f9e3a30
1 changed files with 33 additions and 20 deletions

View File

@ -180,13 +180,14 @@ static struct lb_cbmem_ref parse_cbmem_ref(struct lb_cbmem_ref *cbmem_ref)
return ret; return ret;
} }
static int parse_cbtable(u64 address) static int parse_cbtable(u64 address, size_t table_size)
{ {
int i, found = 0; int i, found = 0;
void *buf; void *buf;
debug("Looking for coreboot table at %" PRIx64 "\n", address); debug("Looking for coreboot table at %" PRIx64 " %zd bytes.\n",
buf = map_memory(address); address, table_size);
buf = map_memory_size(address, table_size);
/* look at every 16 bytes within 4K of the base */ /* look at every 16 bytes within 4K of the base */
@ -252,7 +253,7 @@ static int parse_cbtable(u64 address)
*(struct lb_forward *) lbr_p; *(struct lb_forward *) lbr_p;
debug(" Found forwarding entry.\n"); debug(" Found forwarding entry.\n");
unmap_memory(); unmap_memory();
return parse_cbtable(lbf_p.forward); return parse_cbtable(lbf_p.forward, table_size);
} }
default: default:
break; break;
@ -434,16 +435,22 @@ static void dump_timestamps(void)
{ {
int i; int i;
struct timestamp_table *tst_p; struct timestamp_table *tst_p;
size_t size;
if (timestamps.tag != LB_TAG_TIMESTAMPS) { if (timestamps.tag != LB_TAG_TIMESTAMPS) {
fprintf(stderr, "No timestamps found in coreboot table.\n"); fprintf(stderr, "No timestamps found in coreboot table.\n");
return; return;
} }
tst_p = (struct timestamp_table *) size = sizeof(*tst_p);
map_memory((unsigned long)timestamps.cbmem_addr); tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size);
printf("%d entries total:\n\n", tst_p->num_entries); printf("%d entries total:\n\n", tst_p->num_entries);
size += tst_p->num_entries * sizeof(tst_p->entries[0]);
unmap_memory();
tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size);
for (i = 0; i < tst_p->num_entries; i++) { for (i = 0; i < tst_p->num_entries; i++) {
const struct timestamp_entry *tse_p = tst_p->entries + i; const struct timestamp_entry *tse_p = tst_p->entries + i;
timestamp_print_entry(tse_p->entry_id, tse_p->entry_stamp, timestamp_print_entry(tse_p->entry_id, tse_p->entry_stamp,
@ -466,7 +473,8 @@ static void dump_console(void)
return; return;
} }
console_p = map_memory((unsigned long)console.cbmem_addr); console_p = map_memory_size((unsigned long)console.cbmem_addr,
2 * sizeof(uint32_t));
/* The in-memory format of the console area is: /* The in-memory format of the console area is:
* u32 size * u32 size
* u32 cursor * u32 cursor
@ -481,6 +489,7 @@ static void dump_console(void)
if (size > cursor) if (size > cursor)
size = cursor; size = cursor;
console_c = malloc(size + 1); console_c = malloc(size + 1);
unmap_memory();
if (!console_c) { if (!console_c) {
fprintf(stderr, "Not enough memory for console.\n"); fprintf(stderr, "Not enough memory for console.\n");
exit(1); exit(1);
@ -508,7 +517,7 @@ static void hexdump(unsigned long memory, int length)
uint8_t *m; uint8_t *m;
int all_zero = 0; int all_zero = 0;
m = map_memory((intptr_t)memory); m = map_memory_size((intptr_t)memory, length);
if (length > MAP_BYTES) { if (length > MAP_BYTES) {
printf("Truncating hex dump from %d to %d bytes\n\n", printf("Truncating hex dump from %d to %d bytes\n\n",
@ -658,7 +667,7 @@ static void dump_cbmem_toc(void)
start = unpack_lb64(cbmem.start); start = unpack_lb64(cbmem.start);
cbmem_area = map_memory(start); cbmem_area = map_memory_size(start, unpack_lb64(cbmem.size));
entries = (struct cbmem_entry *)cbmem_area; entries = (struct cbmem_entry *)cbmem_area;
if (entries[0].magic == CBMEM_MAGIC) { if (entries[0].magic == CBMEM_MAGIC) {
@ -671,16 +680,12 @@ static void dump_cbmem_toc(void)
rootptr -= sizeof(struct cbmem_root_pointer); rootptr -= sizeof(struct cbmem_root_pointer);
unmap_memory(); unmap_memory();
struct cbmem_root_pointer *r = struct cbmem_root_pointer *r =
(struct cbmem_root_pointer *)map_memory(rootptr); map_memory_size(rootptr, sizeof(*r));
if (r->magic == CBMEM_POINTER_MAGIC) { if (r->magic == CBMEM_POINTER_MAGIC) {
struct cbmem_root *root; struct cbmem_root *root;
uint64_t rootaddr = r->root; uint64_t rootaddr = r->root;
unmap_memory(); unmap_memory();
/* Note that this only works because our default mmap root = map_memory_size(rootaddr, ROOT_MIN_SIZE);
* size is 1MiB which happens to be larger than the
* root entry size which is default to be 4KiB.
*/
root = (struct cbmem_root *)map_memory(rootaddr);
dump_dynamic_cbmem_toc(root); dump_dynamic_cbmem_toc(root);
} else } else
fprintf(stderr, "No valid coreboot CBMEM root pointer found.\n"); fprintf(stderr, "No valid coreboot CBMEM root pointer found.\n");
@ -1036,8 +1041,9 @@ int main(int argc, char** argv)
} }
int i; int i;
u8 *baseaddr_buffer = alloca(addr_cells * 4); size_t size_to_read = addr_cells * 4 + size_cells * 4;
if (read(fd, baseaddr_buffer, addr_cells * 4) < 0) { u8 *dtbuffer = alloca(size_to_read);
if (read(fd, dtbuffer, size_to_read) < 0) {
perror(reg); perror(reg);
return 1; return 1;
} }
@ -1047,17 +1053,24 @@ int main(int argc, char** argv)
u64 baseaddr = 0; u64 baseaddr = 0;
for (i = 0; i < addr_cells * 4; i++) { for (i = 0; i < addr_cells * 4; i++) {
baseaddr <<= 8; baseaddr <<= 8;
baseaddr |= baseaddr_buffer[i]; baseaddr |= *dtbuffer;
dtbuffer++;
}
u64 cb_table_size = 0;
for (i = 0; i < size_cells * 4; i++) {
cb_table_size <<= 8;
cb_table_size |= *dtbuffer;
dtbuffer++;
} }
parse_cbtable(baseaddr); parse_cbtable(baseaddr, cb_table_size);
#else #else
int j; int j;
static const int possible_base_addresses[] = { 0, 0xf0000 }; static const int possible_base_addresses[] = { 0, 0xf0000 };
/* Find and parse coreboot table */ /* Find and parse coreboot table */
for (j = 0; j < ARRAY_SIZE(possible_base_addresses); j++) { for (j = 0; j < ARRAY_SIZE(possible_base_addresses); j++) {
if (parse_cbtable(possible_base_addresses[j])) if (parse_cbtable(possible_base_addresses[j], MAP_BYTES))
break; break;
} }
#endif #endif