diff options
author | Aaron Durbin <adurbin@chromium.org> | 2014-03-31 11:59:58 -0500 |
---|---|---|
committer | Aaron Durbin <adurbin@google.com> | 2014-04-02 17:01:01 +0200 |
commit | ab180d85f76e8e8cc68ead2f0c89f29b9fe5fd53 (patch) | |
tree | 3ec0c9a34d5bd3e43199601e205052752236514e | |
parent | a270586d4b077149ab1eb1823ccb17c90f840ec7 (diff) | |
download | coreboot-ab180d85f76e8e8cc68ead2f0c89f29b9fe5fd53.tar.xz |
util/cbmem: handle larger than 1MiB mappings for console
In some cases the cbmem console can be larger than the default
mapping size of 1MiB. Therefore, add the ability to do a mapping
that is larger than the default mapping using map_memory_size().
The console printing code will unconditionally map the console based
on the size it finds in the cbmem entry.
Change-Id: I016420576b9523ce81195160ae86ad16952b761c
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/5440
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
-rw-r--r-- | util/cbmem/cbmem.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c index dd80c08753..9ad121467d 100644 --- a/util/cbmem/cbmem.c +++ b/util/cbmem/cbmem.c @@ -79,19 +79,45 @@ static u16 ipchcksum(const void *addr, unsigned size) * functions always maps 1MB at a time and can only map one area at once. */ static void *mapped_virtual; -static void *map_memory(u64 physical) +static size_t mapped_size; + +static inline size_t size_to_mib(size_t sz) +{ + return sz >> 20; +} + +static void unmap_memory(void) +{ + if (mapped_virtual == NULL) { + fprintf(stderr, "Error unmapping memory\n"); + return; + } + debug("Unmapping %zuMB of virtual memory at %p.\n", + size_to_mib(mapped_size), mapped_virtual); + munmap(mapped_virtual, mapped_size); + mapped_virtual = NULL; + mapped_size = 0; +} + +static void *map_memory_size(u64 physical, size_t size) { void *v; off_t p; u64 page = getpagesize(); - int padding; + size_t padding; + + if (mapped_virtual != NULL) + unmap_memory(); /* Mapped memory must be aligned to page size */ p = physical & ~(page - 1); + padding = physical & (page-1); + size += padding; - debug("Mapping 1MB of physical memory at 0x%jx.\n", (intmax_t)p); + debug("Mapping %zuMB of physical memory at 0x%jx.\n", + size_to_mib(size), (intmax_t)p); - v = mmap(NULL, MAP_BYTES, PROT_READ, MAP_SHARED, fd, p); + v = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, p); if (v == MAP_FAILED) { fprintf(stderr, "Failed to mmap /dev/mem: %s\n", @@ -101,26 +127,20 @@ static void *map_memory(u64 physical) /* Remember what we actually mapped ... */ mapped_virtual = v; + mapped_size = size; /* ... but return address to the physical memory that was requested */ - padding = physical & (page-1); if (padding) - debug(" ... padding virtual address with 0x%x bytes.\n", + debug(" ... padding virtual address with 0x%zx bytes.\n", padding); v += padding; return v; } -static void unmap_memory(void) +static void *map_memory(u64 physical) { - if (mapped_virtual == NULL) { - fprintf(stderr, "Error unmapping memory\n"); - return; - } - debug("Unmapping 1MB of virtual memory at %p.\n", mapped_virtual); - munmap(mapped_virtual, MAP_BYTES); - mapped_virtual = NULL; + return map_memory_size(physical, MAP_BYTES); } /* @@ -464,6 +484,8 @@ static void dump_console(void) exit(1); } + console_p = map_memory_size((unsigned long)console.cbmem_addr, + size + sizeof(size) + sizeof(cursor)); memcpy(console_c, console_p + 8, size); console_c[size] = 0; |