aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2015-03-23 12:36:28 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-03-23 12:36:28 +1100
commitc4730fb25a6ffd24aa2f9d505510dd45bc6f318c (patch)
treeed338263c59a403fad8b6639fb40ae6bda2b792a /core
parentf333144c9eb8d9c776c2592dc1449b6d38dd757f (diff)
downloadskiboot-c4730fb25a6ffd24aa2f9d505510dd45bc6f318c.zip
skiboot-c4730fb25a6ffd24aa2f9d505510dd45bc6f318c.tar.gz
skiboot-c4730fb25a6ffd24aa2f9d505510dd45bc6f318c.tar.bz2
Change load_resource() API to be all about preloading.
No functional changes in what happens, just have two calls, one for queueing preload the other for waiting until it has loaded. future patches will introduce platform specific queueing. Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/flash.c4
-rw-r--r--core/init.c26
-rw-r--r--core/platform.c33
3 files changed, 49 insertions, 14 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;
}