aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/flash.c4
-rw-r--r--core/init.c26
-rw-r--r--core/platform.c33
-rw-r--r--hw/fsp/fsp.c14
-rw-r--r--hw/phb3.c10
-rw-r--r--include/fsp.h4
-rw-r--r--include/platform.h29
-rw-r--r--include/skiboot.h4
-rw-r--r--platforms/astbmc/habanero.c2
-rw-r--r--platforms/astbmc/palmetto.c2
-rw-r--r--platforms/ibm-fsp/apollo.c2
-rw-r--r--platforms/ibm-fsp/firenze.c2
12 files changed, 96 insertions, 36 deletions
diff --git a/core/flash.c b/core/flash.c
index f2d7501..270e6fc 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -522,8 +522,8 @@ end:
* load a resource from FLASH
* buf and len shouldn't account for ECC even if partition is ECCed.
*/
-bool flash_load_resource(enum resource_id id, uint32_t subid,
- void *buf, size_t *len)
+int flash_start_preload_resource(enum resource_id id, uint32_t subid,
+ void *buf, size_t *len)
{
int i, rc, part_num, part_size, part_start, size;
struct ffs_handle *ffs;
diff --git a/core/init.c b/core/init.c
index 1fd8d2e..f15ae5d 100644
--- a/core/init.c
+++ b/core/init.c
@@ -290,12 +290,19 @@ static bool load_kernel(void)
{
struct elf_hdr *kh;
size_t ksize;
+ int loaded;
/* Try to load an external kernel payload through the platform hooks */
ksize = KERNEL_LOAD_SIZE;
- if (!load_resource(RESOURCE_ID_KERNEL, RESOURCE_SUBID_NONE,
- KERNEL_LOAD_BASE,
- &ksize)) {
+ loaded = start_preload_resource(RESOURCE_ID_KERNEL,
+ RESOURCE_SUBID_NONE,
+ KERNEL_LOAD_BASE,
+ &ksize);
+ if (loaded == OPAL_SUCCESS)
+ loaded = wait_for_resource_loaded(RESOURCE_ID_KERNEL,
+ RESOURCE_SUBID_NONE);
+
+ if (loaded != OPAL_SUCCESS) {
printf("INIT: platform kernel load failed\n");
ksize = 0;
}
@@ -332,13 +339,18 @@ static bool load_kernel(void)
static void load_initramfs(void)
{
size_t size;
- bool loaded;
+ int loaded;
size = INITRAMFS_LOAD_SIZE;
- loaded = load_resource(RESOURCE_ID_INITRAMFS, RESOURCE_SUBID_NONE,
- INITRAMFS_LOAD_BASE, &size);
+ loaded = start_preload_resource(RESOURCE_ID_INITRAMFS,
+ RESOURCE_SUBID_NONE,
+ INITRAMFS_LOAD_BASE, &size);
- if (!loaded || !size)
+ if (loaded == OPAL_SUCCESS)
+ loaded = wait_for_resource_loaded(RESOURCE_ID_INITRAMFS,
+ RESOURCE_SUBID_NONE);
+
+ if (loaded != OPAL_SUCCESS || !size)
return;
printf("INIT: Initramfs loaded, size: %zu bytes\n", size);
diff --git a/core/platform.c b/core/platform.c
index 7cf9727..5369092 100644
--- a/core/platform.c
+++ b/core/platform.c
@@ -19,6 +19,8 @@
#include <opal.h>
#include <opal-api.h>
#include <console.h>
+#include <timebase.h>
+#include <cpu.h>
struct platform platform;
@@ -79,12 +81,33 @@ void probe_platform(void)
printf("PLAT: Detected %s platform\n", platform.name);
}
-bool load_resource(enum resource_id id, uint32_t subid,
- void *buf, size_t *len)
+int start_preload_resource(enum resource_id id, uint32_t subid,
+ void *buf, size_t *len)
{
- if (!platform.load_resource)
- return false;
+ if (!platform.start_preload_resource)
+ return OPAL_UNSUPPORTED;
- return platform.load_resource(id, subid, buf, len);
+ return platform.start_preload_resource(id, subid, buf, len);
+}
+
+int resource_loaded(enum resource_id id, uint32_t idx)
+{
+ if (!platform.resource_loaded)
+ return OPAL_SUCCESS;
+
+ return platform.resource_loaded(id, idx);
+}
+
+int wait_for_resource_loaded(enum resource_id id, uint32_t idx)
+{
+ int r = resource_loaded(id, idx);
+
+ while(r == OPAL_BUSY) {
+ opal_run_pollers();
+ time_wait_nopoll(msecs_to_tb(5));
+ cpu_relax();
+ r = resource_loaded(id, idx);
+ }
+ return r;
}
diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
index 779eef9..17d73b5 100644
--- a/hw/fsp/fsp.c
+++ b/hw/fsp/fsp.c
@@ -2275,8 +2275,8 @@ static struct {
{ RESOURCE_ID_CAPP, CAPP_IDX_VENICE_DD20, 0x80a02004 },
};
-bool fsp_load_resource(enum resource_id id, uint32_t idx,
- void *buf, size_t *size)
+int fsp_start_preload_resource(enum resource_id id, uint32_t idx,
+ void *buf, size_t *size)
{
uint32_t lid_no = 0, lid;
size_t tmp_size;
@@ -2292,7 +2292,7 @@ bool fsp_load_resource(enum resource_id id, uint32_t idx,
}
}
if (lid_no == 0)
- return false;
+ return OPAL_PARAMETER;
retry:
tmp_size = *size;
@@ -2306,7 +2306,7 @@ retry:
const char *ltype = dt_prop_get_def(dt_root, "lid-type", NULL);
if (!ltype || strcmp(ltype, "opal")) {
prerror("Failed to load in OPAL mode...\n");
- return false;
+ return OPAL_PARAMETER;
}
printf("Trying to load as PHYP LID...\n");
lid_no = KERNEL_LID_PHYP;
@@ -2315,13 +2315,13 @@ retry:
if (rc) {
prerror("Failed to load LID\n");
- return false;
+ return rc;
}
if (*size < tmp_size)
- return false;
+ return OPAL_INTERNAL_ERROR;
*size = tmp_size;
- return true;
+ return OPAL_SUCCESS;
}
void fsp_used_by_console(void)
diff --git a/hw/phb3.c b/hw/phb3.c
index e7127bc..32da794 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -2178,6 +2178,7 @@ static int64_t capp_lid_download(struct phb3 *p)
uint32_t index;
struct capp_lid_hdr *lid;
uint64_t rc;
+ int loaded;
rc = xscom_read_cfam_chipid(chip->id, &index);
if (rc) {
@@ -2220,7 +2221,14 @@ static int64_t capp_lid_download(struct phb3 *p)
ret = OPAL_NO_MEM;
goto end;
}
- if (!load_resource(RESOURCE_ID_CAPP, index, lid, &size)) {
+
+ loaded = start_preload_resource(RESOURCE_ID_CAPP, index,
+ lid, &size);
+ if (loaded == OPAL_SUCCESS)
+ loaded = wait_for_resource_loaded(RESOURCE_ID_CAPP,
+ index);
+
+ if (loaded != OPAL_SUCCESS) {
prerror("CAPP: Error loading ucode lid. index=%x\n", index);
ret = OPAL_RESOURCE;
free(lid);
diff --git a/include/fsp.h b/include/fsp.h
index 66fadb1..e05d7a4 100644
--- a/include/fsp.h
+++ b/include/fsp.h
@@ -722,8 +722,8 @@ extern int fsp_fetch_data(uint8_t flags, uint16_t id, uint32_t sub_id,
extern int fsp_fetch_data_queue(uint8_t flags, uint16_t id, uint32_t sub_id,
uint32_t offset, void *buffer, size_t *length,
void (*comp)(struct fsp_msg *msg)) __warn_unused_result;
-extern bool fsp_load_resource(enum resource_id id, uint32_t subid,
- void *buf, size_t *size);
+extern int fsp_start_preload_resource(enum resource_id id, uint32_t idx,
+ void *buf, size_t *size);
/* FSP console stuff */
extern void fsp_console_preinit(void);
diff --git a/include/platform.h b/include/platform.h
index bdf8bdf..2900b4e 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -129,11 +129,24 @@ struct platform {
int (*elog_commit)(struct errorlog *buf);
/*
- * Load an external resource (eg, kernel payload) into a preallocated
- * buffer. Returns true on success.
+ * Initiate loading an external resource (e.g. kernel payload, OCC)
+ * into a preallocated buffer.
+ * This is designed to asynchronously load external resources.
+ * Returns OPAL_SUCCESS or error.
*/
- bool (*load_resource)(enum resource_id id, uint32_t idx,
- void *buf, size_t *len);
+ int (*start_preload_resource)(enum resource_id id,
+ uint32_t idx,
+ void *buf, size_t *len);
+
+ /*
+ * Returns true when resource is loaded.
+ * Only has to return true once, for the
+ * preivous start_preload_resource call for this resource.
+ * If not implemented, will return true and start_preload_resource
+ * *must* have synchronously done the load.
+ * Retruns OPAL_SUCCESS, OPAL_BUSY or an error code
+ */
+ int (*resource_loaded)(enum resource_id id, uint32_t idx);
/*
* Executed just prior to handing control over to the payload.
@@ -151,7 +164,11 @@ static const struct platform __used __section(".platforms") name ##_platform
extern void probe_platform(void);
-extern bool load_resource(enum resource_id id, uint32_t subid,
- void *buf, size_t *len);
+extern int start_preload_resource(enum resource_id id, uint32_t subid,
+ void *buf, size_t *len);
+
+extern int resource_loaded(enum resource_id id, uint32_t idx);
+
+extern int wait_for_resource_loaded(enum resource_id id, uint32_t idx);
#endif /* __PLATFORM_H */
diff --git a/include/skiboot.h b/include/skiboot.h
index 0fe50e9..6cb9b2d 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -199,8 +199,8 @@ extern void occ_fsp_init(void);
/* flash support */
struct flash_chip;
extern int flash_register(struct flash_chip *chip, bool is_system_flash);
-extern bool flash_load_resource(enum resource_id id, uint32_t subid,
- void *buf, size_t *len);
+extern int flash_start_preload_resource(enum resource_id id, uint32_t subid,
+ void *buf, size_t *len);
extern bool flash_reserve(void);
extern void flash_release(void);
diff --git a/platforms/astbmc/habanero.c b/platforms/astbmc/habanero.c
index c4875ef..d56e451 100644
--- a/platforms/astbmc/habanero.c
+++ b/platforms/astbmc/habanero.c
@@ -53,6 +53,6 @@ DECLARE_PLATFORM(habanero) = {
.cec_power_down = astbmc_ipmi_power_down,
.cec_reboot = astbmc_ipmi_reboot,
.elog_commit = ipmi_elog_commit,
- .load_resource = flash_load_resource,
+ .start_preload_resource = flash_start_preload_resource,
.exit = ipmi_wdt_final_reset,
};
diff --git a/platforms/astbmc/palmetto.c b/platforms/astbmc/palmetto.c
index dee2b06..fdc449e 100644
--- a/platforms/astbmc/palmetto.c
+++ b/platforms/astbmc/palmetto.c
@@ -53,6 +53,6 @@ DECLARE_PLATFORM(palmetto) = {
.cec_power_down = astbmc_ipmi_power_down,
.cec_reboot = astbmc_ipmi_reboot,
.elog_commit = ipmi_elog_commit,
- .load_resource = flash_load_resource,
+ .start_preload_resource = flash_start_preload_resource,
.exit = ipmi_wdt_final_reset,
};
diff --git a/platforms/ibm-fsp/apollo.c b/platforms/ibm-fsp/apollo.c
index 54545de..cc62c98 100644
--- a/platforms/ibm-fsp/apollo.c
+++ b/platforms/ibm-fsp/apollo.c
@@ -60,5 +60,5 @@ DECLARE_PLATFORM(apollo) = {
.nvram_start_read = fsp_nvram_start_read,
.nvram_write = fsp_nvram_write,
.elog_commit = elog_fsp_commit,
- .load_resource = fsp_load_resource,
+ .start_preload_resource = fsp_start_preload_resource,
};
diff --git a/platforms/ibm-fsp/firenze.c b/platforms/ibm-fsp/firenze.c
index 194a19d..9a696b7 100644
--- a/platforms/ibm-fsp/firenze.c
+++ b/platforms/ibm-fsp/firenze.c
@@ -414,5 +414,5 @@ DECLARE_PLATFORM(firenze) = {
.nvram_write = fsp_nvram_write,
.occ_timeout = ibm_fsp_occ_timeout,
.elog_commit = elog_fsp_commit,
- .load_resource = fsp_load_resource,
+ .start_preload_resource = fsp_start_preload_resource,
} ;