diff options
-rw-r--r-- | core/flash.c | 4 | ||||
-rw-r--r-- | core/init.c | 26 | ||||
-rw-r--r-- | core/platform.c | 33 | ||||
-rw-r--r-- | hw/fsp/fsp.c | 14 | ||||
-rw-r--r-- | hw/phb3.c | 10 | ||||
-rw-r--r-- | include/fsp.h | 4 | ||||
-rw-r--r-- | include/platform.h | 29 | ||||
-rw-r--r-- | include/skiboot.h | 4 | ||||
-rw-r--r-- | platforms/astbmc/habanero.c | 2 | ||||
-rw-r--r-- | platforms/astbmc/palmetto.c | 2 | ||||
-rw-r--r-- | platforms/ibm-fsp/apollo.c | 2 | ||||
-rw-r--r-- | 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) @@ -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, } ; |