aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnanth N Mavinakayanahalli <ananth@in.ibm.com>2015-02-16 22:12:58 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-02-18 11:57:50 +1100
commit2233891f71e5a282b2d4f66dcdc866a6697ffd8f (patch)
tree3e343968f12c02475400846927f2094c8b2fb699
parentc48f1a3d7df2dec1c157f1b12b4925bfd666b710 (diff)
downloadskiboot-2233891f71e5a282b2d4f66dcdc866a6697ffd8f.zip
skiboot-2233891f71e5a282b2d4f66dcdc866a6697ffd8f.tar.gz
skiboot-2233891f71e5a282b2d4f66dcdc866a6697ffd8f.tar.bz2
hostservices: Cache lids prior to first load request
... to prevent any potential poller recursions during lid load. With this change: ... [10810950484,5] CUPD: P side ML Keyword = FW830.00 [10832756491,6] HBRT: 1 lids to load [10832762732,7] FSP: Fetch data id: 05 sid: 81e00430 to 0x306cf500(0x100000 bytes) [10832766825,7] FSP: 0x00100000 bytes balign=306cf000 boff=500 bsize=101000 [10857829395,5] CUPD: Marker LID id : size : status = 0x80a08001 : 0x5d0 : 0x0 [10966464432,7] FSP: -> rc=0x00 off: 00000000 twritten: 0007fb80 [10966468418,7] HBRT: LID 0x81e00430 successfully loaded, len=0x31b83db8 ... [19485180658,7] HBRT: stopOCCs() rc = 0 [19582727570,6] OCC: Got OCC Load message, scope=0x2 dbob=0x0 seq=0x10 [19582732660,7] HBRT: OCC Load requested [19582734678,7] HBRT: Calling loadOCC() homer 0000000401400000, occ_common_area 0000000400800000, chip 0000 [19582803643,6] HBRT: Lid load request for 0x81e00430 [19582806532,7] HBRT: Serviced from cache, len=0x7fb80 [19582996931,7] HBRT: -> rc = 0 [19582999113,7] HBRT: Calling loadOCC() homer 0000000401c00000, occ_common_area 0000000400800000, chip 0001 [19583097594,6] HBRT: Lid load request for 0x81e00430 [19583100343,7] HBRT: Serviced from cache, len=0x7fb80 [19583274638,7] HBRT: -> rc = 0 [19583277114,6] HBRT: OCC Start requested V2: Address Vasant's comments (bz reference and OPAL_NO_MEM) Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--core/hostservices.c117
-rw-r--r--core/init.c3
-rw-r--r--include/hostservices.h1
3 files changed, 89 insertions, 32 deletions
diff --git a/core/hostservices.c b/core/hostservices.c
index 952f6b8..ad19e15 100644
--- a/core/hostservices.c
+++ b/core/hostservices.c
@@ -386,36 +386,26 @@ static int hservice_scom_write(uint64_t chip_id, uint64_t addr,
return xscom_write(chip_id, addr, val);
}
-static int hservice_lid_load(uint32_t lid, void **buf, size_t *len)
+struct hbrt_lid {
+ void *load_addr;
+ size_t len;
+ uint32_t id;
+ struct list_node link;
+};
+static LIST_HEAD(hbrt_lid_list);
+
+/* TODO: Few of the following routines can be generalized */
+static int __hservice_lid_load(uint32_t lid, void **buf, size_t *len)
{
int rc;
- static void *lid_cache;
- static size_t lid_cache_len;
- static uint32_t lid_cache_id;
-
- prlog(PR_INFO, "HBRT: LID load request for 0x%08x\n", lid);
/* Adjust LID side first or we get a cache mismatch */
lid = fsp_adjust_lid_side(lid);
- /* Check for cache */
- if (lid_cache && lid_cache_id == lid) {
- *buf = lid_cache;
- *len = lid_cache_len;
- prlog(PR_DEBUG, "HBRT: Serviced from cache, len=0x%lx\n",
- lid_cache_len);
- return 0;
- }
-
- /* Cache mismatch, discard old one */
- if (lid_cache) {
- prlog(PR_DEBUG, "HBRT: Cache mismatch, discarding old"
- " 0x%08x\n", lid_cache_id);
- free(lid_cache);
- lid_cache = NULL;
- }
-
- /* Allocate a new buffer and load the LID into it */
+ /*
+ * Allocate a new buffer and load the LID into it
+ * XXX: We currently use the same size for each HBRT lid.
+ */
*buf = malloc(HBRT_LOAD_LID_SIZE);
*len = HBRT_LOAD_LID_SIZE;
rc = fsp_fetch_data(0, FSP_DATASET_NONSP_LID, lid, 0, *buf, len);
@@ -424,17 +414,80 @@ static int hservice_lid_load(uint32_t lid, void **buf, size_t *len)
*len = 0;
*buf = realloc(*buf, *len);
- /* We managed, let's cache it */
- if (rc == 0 && *len) {
- lid_cache = *buf;
- lid_cache_len = *len;
- lid_cache_id = lid;
+ prlog(PR_DEBUG, "HBRT: LID 0x%08x successfully loaded, len=0x%lx\n",
+ lid, (unsigned long)len);
- prlog(PR_DEBUG, "HBRT: LID 0x%08x successfully loaded and"
- " cached, len=0x%lx\n", lid, lid_cache_len);
+ return rc;
+}
+
+static int __hservice_lid_preload(const uint32_t lid)
+{
+ struct hbrt_lid *hlid;
+ void *buf;
+ size_t len;
+ int rc;
+
+ hlid = zalloc(sizeof(struct hbrt_lid));
+ if (!hlid) {
+ prerror("HBRT: Could not allocate struct hbrt_lid\n");
+ return OPAL_NO_MEM;
}
- return rc;
+ rc = __hservice_lid_load(lid, &buf, &len);
+ if (rc) {
+ free(hlid);
+ return rc;
+ }
+
+ hlid->load_addr = buf;
+ hlid->len = len;
+ hlid->id = lid;
+ list_add_tail(&hbrt_lid_list, &hlid->link);
+
+ return 0;
+}
+
+/* Find and preload all lids needed by hostservices */
+void hservices_lid_preload(void)
+{
+ const uint32_t *lid_list = NULL;
+ size_t num_lids;
+
+ if (!hservice_runtime)
+ return;
+
+ lid_list = (const uint32_t *)hservice_runtime->get_lid_list(&num_lids);
+ if (!lid_list) {
+ prerror("HBRT: get_lid_list() returned NULL\n");
+ return;
+ }
+
+ prlog(PR_INFO, "HBRT: %d lids to load\n", (int)num_lids);
+
+ /* Currently HBRT needs only one (OCC) lid */
+ while (num_lids--)
+ __hservice_lid_preload(lid_list[num_lids]);
+}
+
+static int hservice_lid_load(uint32_t lid, void **buf, size_t *len)
+{
+ struct hbrt_lid *hlid;
+
+ prlog(PR_INFO, "HBRT: Lid load request for 0x%08x\n", lid);
+
+ if (list_empty(&hbrt_lid_list)) /* Should not happen */
+ hservices_lid_preload();
+
+ list_for_each(&hbrt_lid_list, hlid, link) {
+ if (hlid->id == lid) {
+ *buf = hlid->load_addr;
+ *len = hlid->len;
+ prlog(PR_DEBUG, "HBRT: Serviced from cache,"
+ " len=0x%lx\n", hlid->len);
+ return 0;
+ }
+ }
+ return -ENOENT;
}
static int hservice_lid_unload(void *buf __unused)
diff --git a/core/init.c b/core/init.c
index f76d6c3..42b56c1 100644
--- a/core/init.c
+++ b/core/init.c
@@ -641,6 +641,9 @@ void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu)
if (platform.init)
platform.init();
+ /* Preload hostservices lids */
+ hservices_lid_preload();
+
/* Setup dummy console nodes if it's enabled */
if (dummy_console_enabled())
dummy_console_add_nodes();
diff --git a/include/hostservices.h b/include/hostservices.h
index 7279c8e..c8958a3 100644
--- a/include/hostservices.h
+++ b/include/hostservices.h
@@ -18,6 +18,7 @@
#define __HOSTSERVICES_H
bool hservices_init(void);
+void hservices_lid_preload(void);
int host_services_occ_load(void);
int host_services_occ_start(void);