aboutsummaryrefslogtreecommitdiff
path: root/external
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2015-08-10 17:59:49 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-08-10 17:59:49 +1000
commit31952d6fed79d9a81a6083287d380f6203af07e1 (patch)
tree612d3bc541afba9a5d2073ff86b0c54d5e5f5d1c /external
parentdbe695450a2a9196066a1cceb9e7fa5242c9f5ce (diff)
parenteca1f2193fd0d7cbb4154055048e28b2f689c448 (diff)
downloadskiboot-31952d6fed79d9a81a6083287d380f6203af07e1.zip
skiboot-31952d6fed79d9a81a6083287d380f6203af07e1.tar.gz
skiboot-31952d6fed79d9a81a6083287d380f6203af07e1.tar.bz2
Merge 'external/opal-prd: Only map each PRD range once' from branch 'stable'
Diffstat (limited to 'external')
-rw-r--r--external/opal-prd/opal-prd.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c
index 9f686c5..82d9901 100644
--- a/external/opal-prd/opal-prd.c
+++ b/external/opal-prd/opal-prd.c
@@ -60,6 +60,7 @@ struct prd_range {
const char *name;
uint64_t physaddr;
uint64_t size;
+ void *buf;
};
struct opal_prd_ctx {
@@ -275,9 +276,7 @@ int hservice_scom_write(uint64_t chip_id, uint64_t addr,
uint64_t hservice_get_reserved_mem(const char *name)
{
- uint64_t align_physaddr, offset;
struct prd_range *range;
- void *addr;
pr_debug("IMAGE: hservice_get_reserved_mem: %s", name);
@@ -288,24 +287,35 @@ uint64_t hservice_get_reserved_mem(const char *name)
return 0;
}
- pr_debug("IMAGE: Mapping 0x%016lx 0x%08lx %s",
- range->physaddr, range->size, range->name);
+ if (!range->buf) {
+ uint64_t align_physaddr, offset;
+
+ pr_debug("IMAGE: Mapping 0x%016lx 0x%08lx %s",
+ range->physaddr, range->size, range->name);
- align_physaddr = range->physaddr & ~(ctx->page_size-1);
- offset = range->physaddr & (ctx->page_size-1);
- addr = mmap(NULL, range->size, PROT_WRITE | PROT_READ,
- MAP_SHARED, ctx->fd, align_physaddr);
+ align_physaddr = range->physaddr & ~(ctx->page_size-1);
+ offset = range->physaddr & (ctx->page_size-1);
+ range->buf = mmap(NULL, range->size, PROT_WRITE | PROT_READ,
+ MAP_SHARED, ctx->fd, align_physaddr);
- if (addr == MAP_FAILED) {
- pr_log(LOG_ERR, "IMAGE: mmap of %s(0x%016lx) failed: %m",
+ if (range->buf == MAP_FAILED)
+ pr_log(LOG_ERR,
+ "IMAGE: mmap of %s(0x%016lx) failed: %m",
name, range->physaddr);
+ else
+ range->buf += offset;
+ }
+
+ if (range->buf == MAP_FAILED) {
+ pr_log(LOG_WARNING, "IMAGE: get_reserved_mem: %s has no vaddr",
+ name);
return 0;
}
pr_debug("IMAGE: hservice_get_reserved_mem: %s(0x%016lx) address %p",
- name, range->physaddr, addr);
+ name, range->physaddr, range->buf);
- return (uint64_t)addr + offset;
+ return (uint64_t)range->buf;
}
void hservice_nanosleep(uint64_t i_seconds, uint64_t i_nano_seconds)
@@ -823,6 +833,7 @@ static int prd_init_one_range(struct opal_prd_ctx *ctx, const char *path,
range->name = strndup(label, label_len);
range->physaddr = be64toh(reg[0]);
range->size = be64toh(reg[1]);
+ range->buf = NULL;
rc = 0;
out_free: