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>
This commit is contained in:
Aaron Durbin 2014-03-31 11:59:58 -05:00 committed by Aaron Durbin
parent a270586d4b
commit ab180d85f7
1 changed files with 36 additions and 14 deletions

View File

@ -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. * functions always maps 1MB at a time and can only map one area at once.
*/ */
static void *mapped_virtual; 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; void *v;
off_t p; off_t p;
u64 page = getpagesize(); u64 page = getpagesize();
int padding; size_t padding;
if (mapped_virtual != NULL)
unmap_memory();
/* Mapped memory must be aligned to page size */ /* Mapped memory must be aligned to page size */
p = physical & ~(page - 1); 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) { if (v == MAP_FAILED) {
fprintf(stderr, "Failed to mmap /dev/mem: %s\n", fprintf(stderr, "Failed to mmap /dev/mem: %s\n",
@ -101,26 +127,20 @@ static void *map_memory(u64 physical)
/* Remember what we actually mapped ... */ /* Remember what we actually mapped ... */
mapped_virtual = v; mapped_virtual = v;
mapped_size = size;
/* ... but return address to the physical memory that was requested */ /* ... but return address to the physical memory that was requested */
padding = physical & (page-1);
if (padding) if (padding)
debug(" ... padding virtual address with 0x%x bytes.\n", debug(" ... padding virtual address with 0x%zx bytes.\n",
padding); padding);
v += padding; v += padding;
return v; return v;
} }
static void unmap_memory(void) static void *map_memory(u64 physical)
{ {
if (mapped_virtual == NULL) { return map_memory_size(physical, MAP_BYTES);
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;
} }
/* /*
@ -464,6 +484,8 @@ static void dump_console(void)
exit(1); exit(1);
} }
console_p = map_memory_size((unsigned long)console.cbmem_addr,
size + sizeof(size) + sizeof(cursor));
memcpy(console_c, console_p + 8, size); memcpy(console_c, console_p + 8, size);
console_c[size] = 0; console_c[size] = 0;