<font size=2 face="sans-serif">Yes, we need this right now to get the
HOMER access to work on multi-proc systems. The instance number will
match the associate chip in this case.</font>
<br><font size=2 face="sans-serif"><br>
--<br>
Dan Crowell<br>
Senior Software Engineer - Power Systems Enablement Firmware<br>
IBM Rochester: t/l 553-2987<br>
dcrowell@us.ibm.com</font>
<br>
<br>
<br>
<br><font size=1 color=#5f5f5f face="sans-serif">From:
</font><font size=1 face="sans-serif">Patrick Williams III/Rochester/IBM</font>
<br><font size=1 color=#5f5f5f face="sans-serif">To:
</font><font size=1 face="sans-serif">"Jeremy Kerr"
<jk@ozlabs.org></font>
<br><font size=1 color=#5f5f5f face="sans-serif">Cc:
</font><font size=1 face="sans-serif">"skiboot@lists.ozlabs.org"
<skiboot@lists.ozlabs.org>, Daniel M Crowell/Rochester/IBM@ibmus</font>
<br><font size=1 color=#5f5f5f face="sans-serif">Date:
</font><font size=1 face="sans-serif">06/30/2015 03:40 AM</font>
<br><font size=1 color=#5f5f5f face="sans-serif">Subject:
</font><font size=1 face="sans-serif">Re: [Skiboot]
[RFC, PATCH] external/opal-prd: Allow
instance numbers for PRD ranges</font>
<br>
<hr noshade>
<br>
<br>
<br><font size=3>Do we have a case of needing this upcoming? Even
on multi-socket systems, we currently make a single VPD section (which
already handles multiple Centaurs) so the need isn't coming to mind for
me. </font>
<br>
<br><font size=3>I would think we would tend to want them numbered in decreasing
order instead of increasing because the devtree, etc. is built from high
address down. <br>
</font>
<br><font size=3>Patrick Williams</font>
<br><font size=3>Sent from my iPhone</font>
<br><font size=3><br>
On Jun 30, 2015, at 3:03 AM, Jeremy Kerr <</font><a href=mailto:jk@ozlabs.org><font size=3 color=blue><u>jk@ozlabs.org</u></font></a><font size=3>>
wrote:<br>
</font>
<br><font size=3>We have a provision for multiple instances of the same
PRD range. For<br>
example, multiple-socket systems may have a PRD range per socket.<br>
<br>
This change adds an 'int instance' argument to the get_reserved_mem()<br>
call, allowing HBRT to request a specific instance of a range. We bump<br>
the hinterface version in indicate that this new parameter is<br>
present.<br>
<br>
These ranges can be provided by ibm,prd-instance properties in the<br>
reserved-memory nodes. If these are provided, they'll be used, otherwise<br>
opal-prd will number the instances automatically, based on increading<br>
physical addreses.<br>
<br>
Signed-off-by: Jeremy Kerr <</font><a href=mailto:jk@ozlabs.org><font size=3 color=blue><u>jk@ozlabs.org</u></font></a><font size=3>><br>
<br>
---<br>
external/opal-prd/hostboot-interface.h | 3 <br>
external/opal-prd/opal-prd.c | 122
+++++++++++++++++++++++--<br>
external/opal-prd/thunk.S |
2 <br>
3 files changed, 117 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/external/opal-prd/hostboot-interface.h b/external/opal-prd/hostboot-interface.h<br>
index a518f50..3c162aa 100644<br>
--- a/external/opal-prd/hostboot-interface.h<br>
+++ b/external/opal-prd/hostboot-interface.h<br>
@@ -117,10 +117,11 @@ struct host_interfaces {<br>
* name.<br>
*<br>
* @param[in] Devtree name (ex. "ibm,hbrt-vpd-image")<br>
+ * @param[in] Devtree instance<br>
* @return physical address of region (or NULL).<br>
* @platform FSP,OpenPOWER<br>
*/<br>
- uint64_t (*get_reserved_mem)(const char*);<br>
+ uint64_t (*get_reserved_mem)(const char *name, uint32_t
instance);<br>
<br>
/**<br>
* @brief Force a core to be awake, or clear the force<br>
diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c<br>
index 9f686c5..98fd86b 100644<br>
--- a/external/opal-prd/opal-prd.c<br>
+++ b/external/opal-prd/opal-prd.c<br>
@@ -60,6 +60,8 @@ struct prd_range {<br>
const char *name;<br>
uint64_t physaddr;<br>
uint64_t size;<br>
+ bool multiple;<br>
+ uint32_t instance;<br>
};<br>
<br>
struct opal_prd_ctx {<br>
@@ -68,6 +70,7 @@ struct opal_prd_ctx {<br>
struct opal_prd_info info;<br>
struct prd_range *ranges;<br>
int n_ranges;<br>
+ bool fw_range_instances;<br>
long page_size;<br>
void *code_addr;<br>
size_t code_size;<br>
@@ -127,7 +130,7 @@ struct func_desc {<br>
void *toc;<br>
} hbrt_entry;<br>
<br>
-static struct prd_range *find_range(const char *name)<br>
+static struct prd_range *find_range(const char *name, uint32_t instance)<br>
{<br>
struct prd_range *range;<br>
unsigned int i;<br>
@@ -135,8 +138,13 @@ static struct prd_range *find_range(const char *name)<br>
for (i = 0; i < ctx->n_ranges; i++) {<br>
range = &ctx->ranges[i];<br>
<br>
- if (!strcmp(range->name, name))<br>
- return range;<br>
+ if (strcmp(range->name, name))<br>
+ continue;<br>
+<br>
+ if (range->multiple && range->instance
!= instance)<br>
+ continue;<br>
+<br>
+ return range;<br>
}<br>
<br>
return NULL;<br>
@@ -273,7 +281,7 @@ int hservice_scom_write(uint64_t chip_id, uint64_t
addr,<br>
return 0;<br>
}<br>
<br>
-uint64_t hservice_get_reserved_mem(const char *name)<br>
+uint64_t hservice_get_reserved_mem(const char *name, uint32_t instance)<br>
{<br>
uint64_t align_physaddr, offset;<br>
struct prd_range *range;<br>
@@ -281,7 +289,7 @@ uint64_t hservice_get_reserved_mem(const char *name)<br>
<br>
pr_debug("IMAGE: hservice_get_reserved_mem: %s", name);<br>
<br>
- range = find_range(name);<br>
+ range = find_range(name, instance);<br>
if (!range) {<br>
pr_log(LOG_WARNING, "IMAGE: get_reserved_mem:
"<br>
"no such range %s",
name);<br>
@@ -672,7 +680,7 @@ static int map_hbrt_physmem(struct opal_prd_ctx *ctx,
const char *name)<br>
struct prd_range *range;<br>
void *buf;<br>
<br>
- range = find_range(name);<br>
+ range = find_range(name, 0);<br>
if (!range) {<br>
pr_log(LOG_ERR, "IMAGE: can't find code region
%s", name);<br>
return -1;<br>
@@ -770,11 +778,12 @@ static int open_and_read(const char *path, void **bufp,
int *lenp)<br>
static int prd_init_one_range(struct opal_prd_ctx *ctx, const char *path,<br>
struct dirent *dirent)<br>
{<br>
- char *label_path, *reg_path;<br>
+ char *label_path, *reg_path, *instance_path;<br>
struct prd_range *range;<br>
int label_len, len, rc;<br>
- char *label;<br>
+ __be32 *instance;<br>
__be64 *reg;<br>
+ char *label;<br>
void *buf;<br>
<br>
rc = asprintf(&label_path, "%s/%s/ibm,prd-label",
path, dirent->d_name);<br>
@@ -783,6 +792,13 @@ static int prd_init_one_range(struct opal_prd_ctx
*ctx, const char *path,<br>
"node: %m");<br>
return -1;<br>
}<br>
+ rc = asprintf(&instance_path, "%s/%s/ibm,prd-instance",<br>
+ path, dirent->d_name);<br>
+ if (rc < 0) {<br>
+ pr_log(LOG_ERR, "FW: error creating 'ibm,prd-instance'
path "<br>
+ "node: %m");<br>
+ return -1;<br>
+ }<br>
rc = asprintf(®_path, "%s/%s/reg", path, dirent->d_name);<br>
if (rc < 0) {<br>
pr_log(LOG_ERR, "FW: error creating 'reg' path
"<br>
@@ -823,16 +839,97 @@ static int prd_init_one_range(struct opal_prd_ctx
*ctx, const char *path,<br>
range->name = strndup(label, label_len);<br>
range->physaddr = be64toh(reg[0]);<br>
range->size = be64toh(reg[1]);<br>
+<br>
+ /* optional instance */<br>
+ rc = open_and_read(instance_path, &buf, &len);<br>
+ if (!rc && len == sizeof(*instance)) {<br>
+ range->multiple = true;<br>
+ range->instance = be32toh(*instance);<br>
+ ctx->fw_range_instances = true;<br>
+ }<br>
rc = 0;<br>
<br>
out_free:<br>
free(reg);<br>
free(label);<br>
+ free(instance_path);<br>
free(reg_path);<br>
free(label_path);<br>
return rc;<br>
}<br>
<br>
+static int compare_ranges(const void *ap, const void *bp)<br>
+{<br>
+ const struct prd_range *a = ap, *b = bp;<br>
+ int rc;<br>
+<br>
+ rc = strcmp(a->name, b->name);<br>
+ if (rc)<br>
+ return rc;<br>
+<br>
+ if (a->physaddr < b->physaddr)<br>
+ return -1;<br>
+ else if (a->physaddr > b->physaddr)<br>
+ return 1;<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
+static void assign_range_instances(struct opal_prd_ctx *ctx)<br>
+{<br>
+ int i;<br>
+<br>
+ if (!ctx->n_ranges)<br>
+ return;<br>
+<br>
+ ctx->ranges[0].multiple = false;<br>
+ ctx->ranges[0].instance = 0;<br>
+<br>
+ for (i = 1; i < ctx->n_ranges; i++) {<br>
+ struct prd_range *cur, *prev;<br>
+<br>
+ cur = &ctx->ranges[i];<br>
+ prev = &ctx->ranges[i-1];<br>
+<br>
+ if (!strcmp(cur->name, prev->name))
{<br>
+ prev->multiple = true;<br>
+ cur->multiple = true;<br>
+ cur->instance = prev->instance
+ 1;<br>
+ } else {<br>
+ cur->multiple = false;<br>
+ cur->instance = 0;<br>
+ }<br>
+ }<br>
+}<br>
+<br>
+static void print_ranges(struct opal_prd_ctx *ctx)<br>
+{<br>
+ int i;<br>
+<br>
+ if (ctx->n_ranges == 0)<br>
+ pr_log(LOG_INFO, "FW: No PRD ranges");<br>
+<br>
+ pr_log(LOG_DEBUG, "FW: %d PRD ranges, instances assigned
by %s",<br>
+ ctx->n_ranges,<br>
+ ctx->fw_range_instances ?
"firmware" : "userspace");<br>
+<br>
+ for (i = 0; i < ctx->n_ranges; i++) {<br>
+ struct prd_range *range = &ctx->ranges[i];<br>
+ char instance_str[20];<br>
+<br>
+ if (range->multiple)<br>
+ snprintf(instance_str, sizeof(instance_str),<br>
+ "
[%d]", range->instance);<br>
+ else<br>
+ instance_str[0] = '\0';<br>
+<br>
+ pr_log(LOG_DEBUG, "FW: %016lx-%016lx
%s%s", range->physaddr,<br>
+ range->physaddr
+ range->size - 1,<br>
+ range->name,<br>
+ instance_str);<br>
+ }<br>
+}<br>
+<br>
static int prd_init_ranges(struct opal_prd_ctx *ctx)<br>
{<br>
struct dirent *dirent;<br>
@@ -865,6 +962,15 @@ static int prd_init_ranges(struct opal_prd_ctx *ctx)<br>
}<br>
<br>
rc = 0;<br>
+ /* sort ranges and assign instance numbers for duplicates
(if the<br>
+ * firmware doesn't number instances for us) */<br>
+ qsort(ctx->ranges, ctx->n_ranges, sizeof(struct prd_range),<br>
+ compare_ranges);<br>
+<br>
+ if (!ctx->fw_range_instances)<br>
+ assign_range_instances(ctx);<br>
+<br>
+ print_ranges(ctx);<br>
<br>
out_free:<br>
free(path);<br>
diff --git a/external/opal-prd/thunk.S b/external/opal-prd/thunk.S<br>
index ab1e737..bd347f3 100644<br>
--- a/external/opal-prd/thunk.S<br>
+++ b/external/opal-prd/thunk.S<br>
@@ -156,7 +156,7 @@ name##_thunk:
;\<br>
.globl hinterface<br>
hinterface:<br>
/* HBRT interface version */<br>
- .llong 1<br>
+ .llong 2<br>
<br>
/* Callout pointers */<br>
CALLBACK_THUNK(hservice_puts)<br>
_______________________________________________<br>
Skiboot mailing list</font><font size=3 color=blue><u><br>
</u></font><a href=mailto:Skiboot@lists.ozlabs.org><font size=3 color=blue><u>Skiboot@lists.ozlabs.org</u></font></a><font size=3 color=blue><u><br>
</u></font><a href=https://lists.ozlabs.org/listinfo/skiboot><font size=3 color=blue><u>https://lists.ozlabs.org/listinfo/skiboot</u></font></a>
<br>