diff options
author | Joel Stanley <joel@jms.id.au> | 2015-02-03 09:51:00 +1030 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-02-05 12:29:51 +1100 |
commit | 698044a77116bff651da24b30a773f8b963839f0 (patch) | |
tree | 877b601dfe9dc12a7bf923a358ada1b23ecf6885 /platforms | |
parent | 31e6f3938b0789b0c9457979f422dfd675c4c2d4 (diff) | |
download | skiboot-698044a77116bff651da24b30a773f8b963839f0.zip skiboot-698044a77116bff651da24b30a773f8b963839f0.tar.gz skiboot-698044a77116bff651da24b30a773f8b963839f0.tar.bz2 |
astbmc: Allow loading of payload from flash
To date BMC platforms have had their payload built in to the skiboot
binary. This patch adds the option of loading from a flash partition
instead.
This has been tested on palmetto with a separate skiboot and
kernel+rootfs partition. In the future we may have separate kernel and
rootfs, which should just work. For now this is what we see when booting:
[10648940943,5] INIT: Kernel loaded, size: 15728640 bytes (0 = unknown
preload)
[10649094578,5] INIT: 32-bit kernel entry at 0x2001015c
[10649170607,3] PLAT: No ROOTFS partition in PNOR
If the partition named cannot be found, the core loading logic will fall
back to using the built-in payload. In this case, the user gets the
following messages:
[2214557191,3] PLAT: No KERNEL partition in PNOR.
[2220486159,5] INIT: platform kernel load failed.
[2221293286,5] Using built-in kernel.
[2265861935,5] INIT: Kernel loaded, size: 14706638 bytes (0 = unknown
preload).
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'platforms')
-rw-r--r-- | platforms/astbmc/astbmc.h | 1 | ||||
-rw-r--r-- | platforms/astbmc/habanero.c | 1 | ||||
-rw-r--r-- | platforms/astbmc/palmetto.c | 1 | ||||
-rw-r--r-- | platforms/astbmc/pnor.c | 56 |
4 files changed, 58 insertions, 1 deletions
diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h index cee475a..7e33f61 100644 --- a/platforms/astbmc/astbmc.h +++ b/platforms/astbmc/astbmc.h @@ -24,5 +24,6 @@ extern int64_t astbmc_ipmi_power_down(uint64_t request); extern void astbmc_init(void); extern void astbmc_ext_irq(unsigned int chip_id); extern int pnor_init(void); +extern bool pnor_load_resource(enum resource_id id, void *buf, size_t *len); #endif /* __ASTBMC_H */ diff --git a/platforms/astbmc/habanero.c b/platforms/astbmc/habanero.c index d442d1f..a19aafd 100644 --- a/platforms/astbmc/habanero.c +++ b/platforms/astbmc/habanero.c @@ -49,4 +49,5 @@ DECLARE_PLATFORM(habanero) = { .external_irq = astbmc_ext_irq, .cec_power_down = astbmc_ipmi_power_down, .cec_reboot = astbmc_ipmi_reboot, + .load_resource = pnor_load_resource, }; diff --git a/platforms/astbmc/palmetto.c b/platforms/astbmc/palmetto.c index a0030e8..cfa7236 100644 --- a/platforms/astbmc/palmetto.c +++ b/platforms/astbmc/palmetto.c @@ -51,4 +51,5 @@ DECLARE_PLATFORM(palmetto) = { .cec_power_down = astbmc_ipmi_power_down, .cec_reboot = astbmc_ipmi_reboot, .elog_commit = ipmi_elog_commit, + .load_resource = pnor_load_resource, }; diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c index f6e7a5d..2cdb29b 100644 --- a/platforms/astbmc/pnor.c +++ b/platforms/astbmc/pnor.c @@ -14,7 +14,6 @@ * limitations under the License. */ - #include <skiboot.h> #include <device.h> #include <console.h> @@ -85,3 +84,58 @@ int pnor_init(void) return rc; } +static const struct { + enum resource_id id; + char name[PART_NAME_MAX+1]; +} part_name_map[] = { + { RESOURCE_ID_KERNEL, "KERNEL" }, + { RESOURCE_ID_INITRAMFS, "ROOTFS" }, +}; + +bool pnor_load_resource(enum resource_id id, void *buf, size_t *len) +{ + int i, rc, part_num, part_size, part_start; + const char *name; + + if (!pnor_ffs || !pnor_chip) + return false; + + for (i = 0, name = NULL; i < ARRAY_SIZE(part_name_map); i++) { + if (part_name_map[i].id == id) { + name = part_name_map[i].name; + break; + } + } + if (!name) { + prerror("PLAT: Couldn't find partition for id %d\n", id); + return false; + } + + rc = ffs_lookup_part(pnor_ffs, name, &part_num); + if (rc) { + prerror("PLAT: No %s partition in PNOR\n", name); + return false; + } + rc = ffs_part_info(pnor_ffs, part_num, NULL, + &part_start, &part_size, NULL); + if (rc) { + prerror("PLAT: Failed to get %s partition info\n", name); + return false; + } + + if (part_size > *len) { + prerror("PLAT: %s image too large (%d > %zd)\n", name, + part_size, *len); + return false; + } + + rc = flash_read(pnor_chip, part_start, buf, part_size); + if (rc) { + prerror("PLAT: failed to read %s partition\n", name); + return false; + } + + *len = part_size; + + return true; +} |