[Skiboot] [PATCH 1/2] Change load_resource() API to be all about preloading.

Stewart Smith stewart at linux.vnet.ibm.com
Tue Mar 24 14:31:16 AEDT 2015


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 at linux.vnet.ibm.com>
---
 core/flash.c                |    4 ++--
 core/init.c                 |   26 +++++++++++++++++++-------
 core/platform.c             |   33 ++++++++++++++++++++++++++++-----
 hw/fsp/fsp.c                |   14 +++++++-------
 hw/phb3.c                   |   10 +++++++++-
 include/fsp.h               |    4 ++--
 include/platform.h          |   29 +++++++++++++++++++++++------
 include/skiboot.h           |    4 ++--
 platforms/astbmc/habanero.c |    2 +-
 platforms/astbmc/palmetto.c |    2 +-
 platforms/ibm-fsp/apollo.c  |    2 +-
 platforms/ibm-fsp/firenze.c |    2 +-
 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,
 } ;
-- 
1.7.10.4



More information about the Skiboot mailing list