@@ -223,3 +223,81 @@ static int64_t opal_flash_erase(uint64_t id, uint64_t offset, uint64_t size,
opal_call(OPAL_FLASH_READ, opal_flash_read, 5);
opal_call(OPAL_FLASH_WRITE, opal_flash_write, 5);
opal_call(OPAL_FLASH_ERASE, opal_flash_erase, 4);
+
+/* flash resource API */
+
+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 flash_load_resource(enum resource_id id, void *buf, size_t *len)
+{
+ int i, rc, part_num, part_size, part_start;
+ struct ffs_handle *ffs;
+ struct flash *flash;
+ const char *name;
+ bool status;
+
+ status = false;
+
+ lock(&flash_lock);
+
+ if (!system_flash)
+ goto out_unlock;
+
+ flash = system_flash;
+
+ 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("FLASH: Couldn't find partition for id %d\n", id);
+ goto out_unlock;
+ }
+
+ rc = ffs_open_flash(flash->chip, 0, flash->size, &ffs);
+ if (rc) {
+ prerror("FLASH: Can't open ffs handle\n");
+ goto out_unlock;
+ }
+
+ rc = ffs_lookup_part(ffs, name, &part_num);
+ if (rc) {
+ prerror("FLASH: No %s partition\n", name);
+ goto out_free_ffs;
+ }
+ rc = ffs_part_info(ffs, part_num, NULL,
+ &part_start, &part_size, NULL);
+ if (rc) {
+ prerror("FLASH: Failed to get %s partition info\n", name);
+ goto out_free_ffs;
+ }
+
+ if (part_size > *len) {
+ prerror("FLASH: %s image too large (%d > %zd)\n", name,
+ part_size, *len);
+ goto out_free_ffs;
+ }
+
+ rc = flash_read(flash->chip, part_start, buf, part_size);
+ if (rc) {
+ prerror("FLASH: failed to read %s partition\n", name);
+ goto out_free_ffs;
+ }
+
+ *len = part_size;
+ status = true;
+
+out_free_ffs:
+ ffs_close(ffs);
+out_unlock:
+ unlock(&flash_lock);
+ return status;
+}
@@ -24,6 +24,5 @@ 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 */
@@ -49,5 +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,
+ .load_resource = flash_load_resource,
};
@@ -51,6 +51,6 @@ 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,
+ .load_resource = flash_load_resource,
.exit = ipmi_wdt_final_reset,
};
@@ -84,58 +84,4 @@ 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;
-}