aboutsummaryrefslogtreecommitdiff
path: root/platforms/astbmc
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2015-02-03 09:51:00 +1030
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-02-05 12:29:51 +1100
commit698044a77116bff651da24b30a773f8b963839f0 (patch)
tree877b601dfe9dc12a7bf923a358ada1b23ecf6885 /platforms/astbmc
parent31e6f3938b0789b0c9457979f422dfd675c4c2d4 (diff)
downloadskiboot-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/astbmc')
-rw-r--r--platforms/astbmc/astbmc.h1
-rw-r--r--platforms/astbmc/habanero.c1
-rw-r--r--platforms/astbmc/palmetto.c1
-rw-r--r--platforms/astbmc/pnor.c56
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;
+}