diff mbox series

[RESEND,v7,19/22] HIOMAP: Reset bmc mbox in MPIPL path

Message ID 20190416142856.22351-1-hegdevasant@linux.vnet.ibm.com
State Superseded
Headers show
Series None | expand

Commit Message

Vasant Hegde April 16, 2019, 2:28 p.m. UTC
During boot SBE and early hostboot does not use HIOMAP protocol to get image
from PNOR. Instead it expects PNOR TOC and Hostboot Boot Loader to be
available at particular address in LPC bus. mbox daemon in BMC side takes
care of this during normal boot. Once boot is complete mbox daemon switches
to normal mode.

During normal reboot, BMC side mbox daemon gets notification and takes care of
loading PNOR TOC and HBBL to LPC bus again.

In MPIPL path, OPAL calls SBE S0 interrupt to initiate MPIPL. BMC will not be
aware of this. But SBE expects PNOR TOC and HBBL to be available in LPC bus at
predefined address. Hence call HIOMAP Reset from OPAL in assert path.

This needs working LPC and IPMI driver in OPAL. If we have issue in these
drivers then we may not be able to reset BMC MBOX properly. Hence MPIPL may
fail. We have to live with this until we find a way to intiate BMC on MPIPL.

CC: Andrew Jeffery <andrew@aj.id.au>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
@Andrew,
  Does this looks good?

-Vasant

 core/flash.c                     |  14 +++-
 hw/sbe-p9.c                      |   6 ++
 include/skiboot.h                |   3 +-
 libflash/blocklevel.h            |   1 +
 libflash/ipmi-hiomap.c           |  32 +++++++-
 libflash/ipmi-hiomap.h           |   2 +-
 libflash/mbox-flash.c            |  29 ++++++-
 libflash/mbox-flash.h            |   2 +-
 libflash/test/mbox-server.c      |   1 +
 libflash/test/test-ipmi-hiomap.c | 169 +++++++++++++++++++++++++++++++++++++++
 10 files changed, 253 insertions(+), 6 deletions(-)

Comments

Andrew Jeffery April 18, 2019, 6:47 a.m. UTC | #1
On Tue, 16 Apr 2019, at 23:59, Vasant Hegde wrote:
> During boot SBE and early hostboot does not use HIOMAP protocol to get image
> from PNOR. Instead it expects PNOR TOC and Hostboot Boot Loader to be
> available at particular address in LPC bus. mbox daemon in BMC side takes
> care of this during normal boot. Once boot is complete mbox daemon switches
> to normal mode.
> 
> During normal reboot, BMC side mbox daemon gets notification and takes care of
> loading PNOR TOC and HBBL to LPC bus again.
> 
> In MPIPL path, OPAL calls SBE S0 interrupt to initiate MPIPL. BMC will not be
> aware of this. But SBE expects PNOR TOC and HBBL to be available in LPC bus at
> predefined address. Hence call HIOMAP Reset from OPAL in assert path.
> 
> This needs working LPC and IPMI driver in OPAL. If we have issue in these
> drivers then we may not be able to reset BMC MBOX properly. Hence MPIPL may
> fail. We have to live with this until we find a way to intiate BMC on MPIPL.
> 
> CC: Andrew Jeffery <andrew@aj.id.au>
> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
> ---
> @Andrew,
>   Does this looks good?
> 
> -Vasant
> 
>  core/flash.c                     |  14 +++-
>  hw/sbe-p9.c                      |   6 ++
>  include/skiboot.h                |   3 +-
>  libflash/blocklevel.h            |   1 +
>  libflash/ipmi-hiomap.c           |  32 +++++++-
>  libflash/ipmi-hiomap.h           |   2 +-
>  libflash/mbox-flash.c            |  29 ++++++-
>  libflash/mbox-flash.h            |   2 +-
>  libflash/test/mbox-server.c      |   1 +
>  libflash/test/test-ipmi-hiomap.c | 169 +++++++++++++++++++++++++++++++++++++++
>  10 files changed, 253 insertions(+), 6 deletions(-)
> 
> diff --git a/core/flash.c b/core/flash.c
> index 1ed426076..6471a1efb 100644
> --- a/core/flash.c
> +++ b/core/flash.c
> @@ -1,4 +1,4 @@
> -/* Copyright 2013-2018 IBM Corp.
> +/* Copyright 2013-2019 IBM Corp.
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -23,6 +23,7 @@
>  #include <device.h>
>  #include <libflash/libflash.h>
>  #include <libflash/libffs.h>
> +#include <libflash/ipmi-hiomap.h>
>  #include <libflash/blocklevel.h>
>  #include <libflash/ecc.h>
>  #include <libstb/secureboot.h>
> @@ -74,6 +75,17 @@ void flash_release(void)
>  	unlock(&flash_lock);
>  }
>  
> +bool flash_unregister(void)
> +{
> +	struct blocklevel_device *bl = system_flash->bl;
> +
> +	if (bl->exit)
> +		return bl->exit(bl);
> +
> +	prlog(PR_NOTICE, "FLASH: Unregister flash device is not supported\n");
> +	return true;
> +}
> +
>  static int flash_nvram_info(uint32_t *total_size)
>  {
>  	int rc;
> diff --git a/hw/sbe-p9.c b/hw/sbe-p9.c
> index 694375a5a..c5e439701 100644
> --- a/hw/sbe-p9.c
> +++ b/hw/sbe-p9.c
> @@ -965,6 +965,12 @@ void p9_sbe_terminate(void)
>  	if (!dt_find_by_path(opal_node, "dump"))
>  		return;
>  
> +	/* Unregister flash. It will request BMC MBOX reset */
> +	if (!flash_unregister()) {
> +		prlog(PR_DEBUG, "Failed to reset BMC MBOX\n");
> +		return;
> +	}
> +
>  	dt_for_each_compatible(dt_root, xn, "ibm,xscom") {
>  		chip_id = dt_get_chip_id(xn);
>  
> diff --git a/include/skiboot.h b/include/skiboot.h
> index e828b1584..6cdc04942 100644
> --- a/include/skiboot.h
> +++ b/include/skiboot.h
> @@ -1,4 +1,4 @@
> -/* Copyright 2013-2014 IBM Corp.
> +/* Copyright 2013-2019 IBM Corp.
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -226,6 +226,7 @@ extern int flash_start_preload_resource(enum 
> resource_id id, uint32_t subid,
>  extern int flash_resource_loaded(enum resource_id id, uint32_t idx);
>  extern bool flash_reserve(void);
>  extern void flash_release(void);
> +extern bool flash_unregister(void);
>  #define FLASH_SUBPART_ALIGNMENT 0x1000
>  #define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT
>  extern int flash_subpart_info(void *part_header, uint32_t header_len,
> diff --git a/libflash/blocklevel.h b/libflash/blocklevel.h
> index ba42c83d0..a9b94e085 100644
> --- a/libflash/blocklevel.h
> +++ b/libflash/blocklevel.h
> @@ -47,6 +47,7 @@ struct blocklevel_device {
>  	int (*erase)(struct blocklevel_device *bl, uint64_t pos, uint64_t 
> len);
>  	int (*get_info)(struct blocklevel_device *bl, const char **name, 
> uint64_t *total_size,
>  			uint32_t *erase_granule);
> +	bool (*exit)(struct blocklevel_device *bl);
>  
>  	/*
>  	 * Keep the erase mask so that blocklevel_erase() can do sanity 
> checking
> diff --git a/libflash/ipmi-hiomap.c b/libflash/ipmi-hiomap.c
> index 9174eabd2..1bfa0d45d 100644
> --- a/libflash/ipmi-hiomap.c
> +++ b/libflash/ipmi-hiomap.c
> @@ -223,6 +223,7 @@ static void ipmi_hiomap_cmd_cb(struct ipmi_msg *msg)
>  	case HIOMAP_C_FLUSH:
>  	case HIOMAP_C_ACK:
>  	case HIOMAP_C_ERASE:
> +	case HIOMAP_C_RESET:
>  		if (msg->resp_size != 2) {
>  			prerror("%u: Unexpected response size: %u\n", msg->data[0],
>  				msg->resp_size);
> @@ -529,6 +530,29 @@ static int hiomap_erase(struct ipmi_hiomap *ctx, 
> uint64_t offset,
>  	return 0;
>  }
>  
> +static bool hiomap_reset(struct ipmi_hiomap *ctx)
> +{
> +	RESULT_INIT(res, ctx);
> +	unsigned char req[2];
> +	struct ipmi_msg *msg;
> +
> +	prlog(PR_NOTICE, "Reset\n");
> +
> +	req[0] = HIOMAP_C_RESET;
> +	req[1] = ++ctx->seq;
> +	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
> +		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
> +			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2);
> +	ipmi_queue_msg_sync(msg);
> +
> +	if (res.cc != IPMI_CC_NO_ERROR) {
> +		prlog(PR_ERR, "%s failed: %d\n", __func__, res.cc);
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>  static void hiomap_event(uint8_t events, void *context)
>  {
>  	struct ipmi_hiomap *ctx = context;
> @@ -919,6 +943,7 @@ int ipmi_hiomap_init(struct blocklevel_device **bl)
>  	ctx->bl.write = &ipmi_hiomap_write;
>  	ctx->bl.erase = &ipmi_hiomap_erase;
>  	ctx->bl.get_info = &ipmi_hiomap_get_flash_info;
> +	ctx->bl.exit = &ipmi_hiomap_exit;
>  
>  	hiomap_init(ctx);
>  
> @@ -968,11 +993,16 @@ err:
>  	return rc;
>  }
>  
> -void ipmi_hiomap_exit(struct blocklevel_device *bl)
> +bool ipmi_hiomap_exit(struct blocklevel_device *bl)
>  {
> +	bool status = true;
> +
>  	struct ipmi_hiomap *ctx;
>  	if (bl) {
>  		ctx = container_of(bl, struct ipmi_hiomap, bl);
> +		status = hiomap_reset(ctx);
>  		free(ctx);
>  	}
> +
> +	return status;
>  }
> diff --git a/libflash/ipmi-hiomap.h b/libflash/ipmi-hiomap.h
> index edd4ee0a3..d2ce54693 100644
> --- a/libflash/ipmi-hiomap.h
> +++ b/libflash/ipmi-hiomap.h
> @@ -53,6 +53,6 @@ struct ipmi_hiomap {
>  };
>  
>  int ipmi_hiomap_init(struct blocklevel_device **bl);
> -void ipmi_hiomap_exit(struct blocklevel_device *bl);
> +bool ipmi_hiomap_exit(struct blocklevel_device *bl);
>  
>  #endif /* __LIBFLASH_IPMI_HIOMAP_H */
> diff --git a/libflash/mbox-flash.c b/libflash/mbox-flash.c
> index 11ec90523..34d1615be 100644
> --- a/libflash/mbox-flash.c
> +++ b/libflash/mbox-flash.c
> @@ -816,6 +816,28 @@ static int mbox_flash_read(struct 
> blocklevel_device *bl, uint64_t pos,
>  	return rc;
>  }
>  
> +static bool mbox_flash_reset(struct blocklevel_device *bl)
> +{
> +	int rc;
> +	struct mbox_flash_data *mbox_flash;
> +	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_RESET_STATE);
> +
> +	prlog(PR_NOTICE, "MBOX reset\n");
> +	mbox_flash = container_of(bl, struct mbox_flash_data, bl);
> +
> +	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
> +	if (rc) {
> +		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX RESET msg\n");
> +		return false;
> +	}
> +	if (wait_for_bmc(mbox_flash, mbox_flash->timeout)) {
> +		prlog(PR_ERR, "Error waiting for BMC\n");
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>  static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,
>  		uint64_t *total_size, uint32_t *erase_granule)
>  {
> @@ -1151,6 +1173,7 @@ int mbox_flash_init(struct blocklevel_device **bl)
>  	mbox_flash->bl.write = &mbox_flash_write;
>  	mbox_flash->bl.erase = &mbox_flash_erase_v2;
>  	mbox_flash->bl.get_info = &mbox_flash_get_info;
> +	mbox_flash->bl.exit = &mbox_flash_exit;
>  
>  	if (bmc_mbox_get_attn_reg() & MBOX_ATTN_BMC_REBOOT)
>  		rc = handle_reboot(mbox_flash);
> @@ -1167,11 +1190,15 @@ int mbox_flash_init(struct blocklevel_device **bl)
>  	return 0;
>  }
>  
> -void mbox_flash_exit(struct blocklevel_device *bl)
> +bool mbox_flash_exit(struct blocklevel_device *bl)
>  {
> +	bool status = true;
>  	struct mbox_flash_data *mbox_flash;
>  	if (bl) {
> +		status = mbox_flash_reset(bl);
>  		mbox_flash = container_of(bl, struct mbox_flash_data, bl);
>  		free(mbox_flash);
>  	}
> +
> +	return status;
>  }
> diff --git a/libflash/mbox-flash.h b/libflash/mbox-flash.h
> index 34b4f651d..ba5dc769a 100644
> --- a/libflash/mbox-flash.h
> +++ b/libflash/mbox-flash.h
> @@ -19,7 +19,7 @@
>  
>  int mbox_flash_lock(struct blocklevel_device *bl, uint64_t pos, uint64_t len);
>  int mbox_flash_init(struct blocklevel_device **bl);
> -void mbox_flash_exit(struct blocklevel_device *bl);
> +bool mbox_flash_exit(struct blocklevel_device *bl);
>  #endif /* __LIBFLASH_MBOX_FLASH_H */
>  
>  
> diff --git a/libflash/test/mbox-server.c b/libflash/test/mbox-server.c
> index e03578834..d0d0e0938 100644
> --- a/libflash/test/mbox-server.c
> +++ b/libflash/test/mbox-server.c
> @@ -286,6 +286,7 @@ int bmc_mbox_enqueue(struct bmc_mbox_msg *msg,
>  	switch (msg->command) {
>  		case MBOX_C_RESET_STATE:
>  			prlog(PR_INFO, "RESET_STATE\n");
> +			server_state.win_type = WIN_CLOSED;
>  			rc = open_window(msg, false, 0, LPC_BLOCKS);
>  			memset(msg->args, 0, sizeof(msg->args));
>  			break;
> diff --git a/libflash/test/test-ipmi-hiomap.c 
> b/libflash/test/test-ipmi-hiomap.c
> index e1bc5ef38..18da7346c 100644
> --- a/libflash/test/test-ipmi-hiomap.c
> +++ b/libflash/test/test-ipmi-hiomap.c
> @@ -476,10 +476,101 @@ static const struct scenario_event 
> hiomap_erase_qs0l1_call = {
>  	},
>  };
>  
> +static const struct scenario_event hiomap_reset_call_seq_4 = {
> +	.type = scenario_cmd,
> +	.c = {
> +		.req = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 4,
> +		},
> +		.cc = IPMI_CC_NO_ERROR,
> +		.resp = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 4,
> +		},
> +	},
> +};
> +
> +static const struct scenario_event hiomap_reset_call_seq_5 = {
> +	.type = scenario_cmd,
> +	.c = {
> +		.req = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 5,
> +		},
> +		.cc = IPMI_CC_NO_ERROR,
> +		.resp = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 5,
> +		},
> +	},
> +};
> +
> +static const struct scenario_event hiomap_reset_call_seq_6 = {
> +	.type = scenario_cmd,
> +	.c = {
> +		.req = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 6,
> +		},
> +		.cc = IPMI_CC_NO_ERROR,
> +		.resp = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 6,
> +		},
> +	},
> +};
> +
> +static const struct scenario_event hiomap_reset_call_seq_7 = {
> +	.type = scenario_cmd,
> +	.c = {
> +		.req = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 7,
> +		},
> +		.cc = IPMI_CC_NO_ERROR,
> +		.resp = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 7,
> +		},
> +	},
> +};
> +
> +static const struct scenario_event hiomap_reset_call_seq_9 = {
> +	.type = scenario_cmd,
> +	.c = {
> +		.req = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 9,
> +		},
> +		.cc = IPMI_CC_NO_ERROR,
> +		.resp = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 9,
> +		},
> +	},
> +};
> +
> +static const struct scenario_event hiomap_reset_call_seq_a = {
> +	.type = scenario_cmd,
> +	.c = {
> +		.req = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 0xa,
> +		},
> +		.cc = IPMI_CC_NO_ERROR,
> +		.resp = {
> +			.cmd = HIOMAP_C_RESET,
> +			.seq = 0xa,
> +		},
> +	},
> +};

I wish this wasn't as dumb as it looks, but these are tests, so I'm not
terribly fussed. I'll have a think about it though.

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> +
>  static const struct scenario_event scenario_hiomap_init[] = {
>  	{ .type = scenario_event_p, .p = &hiomap_ack_call, },
>  	{ .type = scenario_event_p, .p = &hiomap_get_info_call, },
>  	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -498,6 +589,7 @@ static const struct scenario_event 
> scenario_hiomap_event_daemon_ready[] = {
>  	{ .type = scenario_event_p, .p = &hiomap_get_info_call, },
>  	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
>  	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -520,6 +612,7 @@ static const struct scenario_event 
> scenario_hiomap_event_daemon_stopped[] = {
>  	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
>  	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
>  	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_PROTOCOL_RESET } 
> },
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -543,6 +636,7 @@ static const struct scenario_event 
> scenario_hiomap_event_daemon_restarted[] = {
>  	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
>  	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_PROTOCOL_RESET } 
> },
>  	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -572,6 +666,7 @@ scenario_hiomap_event_daemon_lost_flash_control[] = {
>  					| HIOMAP_E_FLASH_LOST),
>  		}
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -677,6 +772,7 @@ 
> scenario_hiomap_event_daemon_regained_flash_control_dirty[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -819,6 +915,7 @@ static const struct scenario_event 
> scenario_hiomap_protocol_reset_recovery[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_9, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -851,6 +948,7 @@ scenario_hiomap_protocol_read_one_block[] = {
>  		.type = scenario_event_p,
>  		.p = &hiomap_create_read_window_qs0l1_rs0l1_call,
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -924,6 +1022,7 @@ scenario_hiomap_protocol_read_two_blocks[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -976,6 +1075,7 @@ scenario_hiomap_protocol_read_one_block_twice[] = {
>  		.type = scenario_event_p,
>  		.p = &hiomap_create_read_window_qs0l1_rs0l1_call,
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1011,6 +1111,7 @@ scenario_hiomap_protocol_event_before_action[] = {
>  					HIOMAP_E_FLASH_LOST,
>  		}
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1044,6 +1145,7 @@ scenario_hiomap_protocol_event_during_read[] = {
>  					HIOMAP_E_FLASH_LOST,
>  		}
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1079,6 +1181,7 @@ scenario_hiomap_protocol_write_one_block[] = {
>  	},
>  	{ .type = scenario_event_p, .p = &hiomap_mark_dirty_qs0l1_call, },
>  	{ .type = scenario_event_p, .p = &hiomap_flush_call, },
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1163,6 +1266,7 @@ scenario_hiomap_protocol_write_two_blocks[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_a, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1245,6 +1349,7 @@ scenario_hiomap_protocol_write_one_block_twice[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_9, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1298,6 +1403,7 @@ scenario_hiomap_protocol_event_during_write[] = {
>  					HIOMAP_E_FLASH_LOST,
>  		}
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1339,6 +1445,7 @@ scenario_hiomap_protocol_erase_one_block[] = {
>  		.type = scenario_event_p,
>  		.p = &hiomap_flush_call,
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1387,6 +1494,7 @@ scenario_hiomap_protocol_erase_two_blocks[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_a, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1446,6 +1554,7 @@ scenario_hiomap_protocol_erase_one_block_twice[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_9, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1513,6 +1622,7 @@ scenario_hiomap_protocol_event_during_erase[] = {
>  					HIOMAP_E_FLASH_LOST,
>  		}
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1617,6 +1727,7 @@ scenario_hiomap_protocol_get_flash_info[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1643,6 +1754,7 @@ scenario_hiomap_protocol_persistent_error[] = {
>  	{ .type = scenario_event_p, .p = &hiomap_get_info_call, },
>  	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
>  	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_PROTOCOL_RESET } },
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1741,6 +1853,7 @@ scenario_hiomap_create_read_window_error[] = {
>  			.cc = IPMI_INVALID_COMMAND_ERR,
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1782,6 +1895,7 @@ scenario_hiomap_create_write_window_error[] = {
>  			.cc = IPMI_INVALID_COMMAND_ERR,
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1826,6 +1940,7 @@ static const struct scenario_event 
> scenario_hiomap_mark_dirty_error[] = {
>  			.cc = IPMI_INVALID_COMMAND_ERR,
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1867,6 +1982,7 @@ static const struct scenario_event 
> scenario_hiomap_flush_error[] = {
>  			.cc = IPMI_INVALID_COMMAND_ERR,
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -1917,6 +2033,7 @@ static const struct scenario_event 
> scenario_hiomap_erase_error[] = {
>  			.cc = IPMI_INVALID_COMMAND_ERR,
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2137,6 +2254,7 @@ scenario_hiomap_create_read_window_malformed_small[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2184,6 +2302,7 @@ scenario_hiomap_create_read_window_malformed_large[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2230,6 +2349,7 @@ scenario_hiomap_create_write_window_malformed_small[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2277,6 +2397,7 @@ scenario_hiomap_create_write_window_malformed_large[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2326,6 +2447,7 @@ scenario_hiomap_mark_dirty_malformed_small[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2376,6 +2498,7 @@ scenario_hiomap_mark_dirty_malformed_large[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2422,6 +2545,7 @@ scenario_hiomap_flush_malformed_small[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2469,6 +2593,7 @@ scenario_hiomap_flush_malformed_large[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2518,6 +2643,7 @@ scenario_hiomap_erase_malformed_small[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2563,6 +2689,7 @@ scenario_hiomap_erase_malformed_large[] = {
>  			},
>  		},
>  	},
> +	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2768,6 +2895,20 @@ scenario_hiomap_protocol_recovery_failure_ack[] = {
>  			},
>  		},
>  	},
> +	{
> +		.type = scenario_cmd,
> +		.c = {
> +			.req = {
> +				.cmd = HIOMAP_C_RESET,
> +				.seq = 14,
> +			},
> +			.cc = IPMI_CC_NO_ERROR,
> +			.resp = {
> +				.cmd = HIOMAP_C_RESET,
> +				.seq = 14,
> +			},
> +		},
> +	},
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -2938,6 +3079,20 @@ scenario_hiomap_protocol_recovery_failure_get_info[] = {
>  			},
>  		},
>  	},
> +	{
> +		.type = scenario_cmd,
> +		.c = {
> +			.req = {
> +				.cmd = HIOMAP_C_RESET,
> +				.seq = 15,
> +			},
> +			.cc = IPMI_CC_NO_ERROR,
> +			.resp = {
> +				.cmd = HIOMAP_C_RESET,
> +				.seq = 15,
> +			},
> +		},
> +	},
>  	SCENARIO_SENTINEL,
>  };
>  
> @@ -3107,6 +3262,20 @@ 
> scenario_hiomap_protocol_recovery_failure_get_flash_info[] = {
>  			},
>  		},
>  	},
> +	{
> +		.type = scenario_cmd,
> +		.c = {
> +			.req = {
> +				.cmd = HIOMAP_C_RESET,
> +				.seq = 16,
> +			},
> +			.cc = IPMI_CC_NO_ERROR,
> +			.resp = {
> +				.cmd = HIOMAP_C_RESET,
> +				.seq = 16,
> +			},
> +		},
> +	},
>  	SCENARIO_SENTINEL,
>  };
>  
> -- 
> 2.14.3
> 
>
diff mbox series

Patch

diff --git a/core/flash.c b/core/flash.c
index 1ed426076..6471a1efb 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -1,4 +1,4 @@ 
-/* Copyright 2013-2018 IBM Corp.
+/* Copyright 2013-2019 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ 
 #include <device.h>
 #include <libflash/libflash.h>
 #include <libflash/libffs.h>
+#include <libflash/ipmi-hiomap.h>
 #include <libflash/blocklevel.h>
 #include <libflash/ecc.h>
 #include <libstb/secureboot.h>
@@ -74,6 +75,17 @@  void flash_release(void)
 	unlock(&flash_lock);
 }
 
+bool flash_unregister(void)
+{
+	struct blocklevel_device *bl = system_flash->bl;
+
+	if (bl->exit)
+		return bl->exit(bl);
+
+	prlog(PR_NOTICE, "FLASH: Unregister flash device is not supported\n");
+	return true;
+}
+
 static int flash_nvram_info(uint32_t *total_size)
 {
 	int rc;
diff --git a/hw/sbe-p9.c b/hw/sbe-p9.c
index 694375a5a..c5e439701 100644
--- a/hw/sbe-p9.c
+++ b/hw/sbe-p9.c
@@ -965,6 +965,12 @@  void p9_sbe_terminate(void)
 	if (!dt_find_by_path(opal_node, "dump"))
 		return;
 
+	/* Unregister flash. It will request BMC MBOX reset */
+	if (!flash_unregister()) {
+		prlog(PR_DEBUG, "Failed to reset BMC MBOX\n");
+		return;
+	}
+
 	dt_for_each_compatible(dt_root, xn, "ibm,xscom") {
 		chip_id = dt_get_chip_id(xn);
 
diff --git a/include/skiboot.h b/include/skiboot.h
index e828b1584..6cdc04942 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -1,4 +1,4 @@ 
-/* Copyright 2013-2014 IBM Corp.
+/* Copyright 2013-2019 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -226,6 +226,7 @@  extern int flash_start_preload_resource(enum resource_id id, uint32_t subid,
 extern int flash_resource_loaded(enum resource_id id, uint32_t idx);
 extern bool flash_reserve(void);
 extern void flash_release(void);
+extern bool flash_unregister(void);
 #define FLASH_SUBPART_ALIGNMENT 0x1000
 #define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT
 extern int flash_subpart_info(void *part_header, uint32_t header_len,
diff --git a/libflash/blocklevel.h b/libflash/blocklevel.h
index ba42c83d0..a9b94e085 100644
--- a/libflash/blocklevel.h
+++ b/libflash/blocklevel.h
@@ -47,6 +47,7 @@  struct blocklevel_device {
 	int (*erase)(struct blocklevel_device *bl, uint64_t pos, uint64_t len);
 	int (*get_info)(struct blocklevel_device *bl, const char **name, uint64_t *total_size,
 			uint32_t *erase_granule);
+	bool (*exit)(struct blocklevel_device *bl);
 
 	/*
 	 * Keep the erase mask so that blocklevel_erase() can do sanity checking
diff --git a/libflash/ipmi-hiomap.c b/libflash/ipmi-hiomap.c
index 9174eabd2..1bfa0d45d 100644
--- a/libflash/ipmi-hiomap.c
+++ b/libflash/ipmi-hiomap.c
@@ -223,6 +223,7 @@  static void ipmi_hiomap_cmd_cb(struct ipmi_msg *msg)
 	case HIOMAP_C_FLUSH:
 	case HIOMAP_C_ACK:
 	case HIOMAP_C_ERASE:
+	case HIOMAP_C_RESET:
 		if (msg->resp_size != 2) {
 			prerror("%u: Unexpected response size: %u\n", msg->data[0],
 				msg->resp_size);
@@ -529,6 +530,29 @@  static int hiomap_erase(struct ipmi_hiomap *ctx, uint64_t offset,
 	return 0;
 }
 
+static bool hiomap_reset(struct ipmi_hiomap *ctx)
+{
+	RESULT_INIT(res, ctx);
+	unsigned char req[2];
+	struct ipmi_msg *msg;
+
+	prlog(PR_NOTICE, "Reset\n");
+
+	req[0] = HIOMAP_C_RESET;
+	req[1] = ++ctx->seq;
+	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
+		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
+			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2);
+	ipmi_queue_msg_sync(msg);
+
+	if (res.cc != IPMI_CC_NO_ERROR) {
+		prlog(PR_ERR, "%s failed: %d\n", __func__, res.cc);
+		return false;
+	}
+
+	return true;
+}
+
 static void hiomap_event(uint8_t events, void *context)
 {
 	struct ipmi_hiomap *ctx = context;
@@ -919,6 +943,7 @@  int ipmi_hiomap_init(struct blocklevel_device **bl)
 	ctx->bl.write = &ipmi_hiomap_write;
 	ctx->bl.erase = &ipmi_hiomap_erase;
 	ctx->bl.get_info = &ipmi_hiomap_get_flash_info;
+	ctx->bl.exit = &ipmi_hiomap_exit;
 
 	hiomap_init(ctx);
 
@@ -968,11 +993,16 @@  err:
 	return rc;
 }
 
-void ipmi_hiomap_exit(struct blocklevel_device *bl)
+bool ipmi_hiomap_exit(struct blocklevel_device *bl)
 {
+	bool status = true;
+
 	struct ipmi_hiomap *ctx;
 	if (bl) {
 		ctx = container_of(bl, struct ipmi_hiomap, bl);
+		status = hiomap_reset(ctx);
 		free(ctx);
 	}
+
+	return status;
 }
diff --git a/libflash/ipmi-hiomap.h b/libflash/ipmi-hiomap.h
index edd4ee0a3..d2ce54693 100644
--- a/libflash/ipmi-hiomap.h
+++ b/libflash/ipmi-hiomap.h
@@ -53,6 +53,6 @@  struct ipmi_hiomap {
 };
 
 int ipmi_hiomap_init(struct blocklevel_device **bl);
-void ipmi_hiomap_exit(struct blocklevel_device *bl);
+bool ipmi_hiomap_exit(struct blocklevel_device *bl);
 
 #endif /* __LIBFLASH_IPMI_HIOMAP_H */
diff --git a/libflash/mbox-flash.c b/libflash/mbox-flash.c
index 11ec90523..34d1615be 100644
--- a/libflash/mbox-flash.c
+++ b/libflash/mbox-flash.c
@@ -816,6 +816,28 @@  static int mbox_flash_read(struct blocklevel_device *bl, uint64_t pos,
 	return rc;
 }
 
+static bool mbox_flash_reset(struct blocklevel_device *bl)
+{
+	int rc;
+	struct mbox_flash_data *mbox_flash;
+	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_RESET_STATE);
+
+	prlog(PR_NOTICE, "MBOX reset\n");
+	mbox_flash = container_of(bl, struct mbox_flash_data, bl);
+
+	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
+	if (rc) {
+		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX RESET msg\n");
+		return false;
+	}
+	if (wait_for_bmc(mbox_flash, mbox_flash->timeout)) {
+		prlog(PR_ERR, "Error waiting for BMC\n");
+		return false;
+	}
+
+	return true;
+}
+
 static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,
 		uint64_t *total_size, uint32_t *erase_granule)
 {
@@ -1151,6 +1173,7 @@  int mbox_flash_init(struct blocklevel_device **bl)
 	mbox_flash->bl.write = &mbox_flash_write;
 	mbox_flash->bl.erase = &mbox_flash_erase_v2;
 	mbox_flash->bl.get_info = &mbox_flash_get_info;
+	mbox_flash->bl.exit = &mbox_flash_exit;
 
 	if (bmc_mbox_get_attn_reg() & MBOX_ATTN_BMC_REBOOT)
 		rc = handle_reboot(mbox_flash);
@@ -1167,11 +1190,15 @@  int mbox_flash_init(struct blocklevel_device **bl)
 	return 0;
 }
 
-void mbox_flash_exit(struct blocklevel_device *bl)
+bool mbox_flash_exit(struct blocklevel_device *bl)
 {
+	bool status = true;
 	struct mbox_flash_data *mbox_flash;
 	if (bl) {
+		status = mbox_flash_reset(bl);
 		mbox_flash = container_of(bl, struct mbox_flash_data, bl);
 		free(mbox_flash);
 	}
+
+	return status;
 }
diff --git a/libflash/mbox-flash.h b/libflash/mbox-flash.h
index 34b4f651d..ba5dc769a 100644
--- a/libflash/mbox-flash.h
+++ b/libflash/mbox-flash.h
@@ -19,7 +19,7 @@ 
 
 int mbox_flash_lock(struct blocklevel_device *bl, uint64_t pos, uint64_t len);
 int mbox_flash_init(struct blocklevel_device **bl);
-void mbox_flash_exit(struct blocklevel_device *bl);
+bool mbox_flash_exit(struct blocklevel_device *bl);
 #endif /* __LIBFLASH_MBOX_FLASH_H */
 
 
diff --git a/libflash/test/mbox-server.c b/libflash/test/mbox-server.c
index e03578834..d0d0e0938 100644
--- a/libflash/test/mbox-server.c
+++ b/libflash/test/mbox-server.c
@@ -286,6 +286,7 @@  int bmc_mbox_enqueue(struct bmc_mbox_msg *msg,
 	switch (msg->command) {
 		case MBOX_C_RESET_STATE:
 			prlog(PR_INFO, "RESET_STATE\n");
+			server_state.win_type = WIN_CLOSED;
 			rc = open_window(msg, false, 0, LPC_BLOCKS);
 			memset(msg->args, 0, sizeof(msg->args));
 			break;
diff --git a/libflash/test/test-ipmi-hiomap.c b/libflash/test/test-ipmi-hiomap.c
index e1bc5ef38..18da7346c 100644
--- a/libflash/test/test-ipmi-hiomap.c
+++ b/libflash/test/test-ipmi-hiomap.c
@@ -476,10 +476,101 @@  static const struct scenario_event hiomap_erase_qs0l1_call = {
 	},
 };
 
+static const struct scenario_event hiomap_reset_call_seq_4 = {
+	.type = scenario_cmd,
+	.c = {
+		.req = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 4,
+		},
+		.cc = IPMI_CC_NO_ERROR,
+		.resp = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 4,
+		},
+	},
+};
+
+static const struct scenario_event hiomap_reset_call_seq_5 = {
+	.type = scenario_cmd,
+	.c = {
+		.req = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 5,
+		},
+		.cc = IPMI_CC_NO_ERROR,
+		.resp = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 5,
+		},
+	},
+};
+
+static const struct scenario_event hiomap_reset_call_seq_6 = {
+	.type = scenario_cmd,
+	.c = {
+		.req = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 6,
+		},
+		.cc = IPMI_CC_NO_ERROR,
+		.resp = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 6,
+		},
+	},
+};
+
+static const struct scenario_event hiomap_reset_call_seq_7 = {
+	.type = scenario_cmd,
+	.c = {
+		.req = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 7,
+		},
+		.cc = IPMI_CC_NO_ERROR,
+		.resp = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 7,
+		},
+	},
+};
+
+static const struct scenario_event hiomap_reset_call_seq_9 = {
+	.type = scenario_cmd,
+	.c = {
+		.req = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 9,
+		},
+		.cc = IPMI_CC_NO_ERROR,
+		.resp = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 9,
+		},
+	},
+};
+
+static const struct scenario_event hiomap_reset_call_seq_a = {
+	.type = scenario_cmd,
+	.c = {
+		.req = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 0xa,
+		},
+		.cc = IPMI_CC_NO_ERROR,
+		.resp = {
+			.cmd = HIOMAP_C_RESET,
+			.seq = 0xa,
+		},
+	},
+};
+
 static const struct scenario_event scenario_hiomap_init[] = {
 	{ .type = scenario_event_p, .p = &hiomap_ack_call, },
 	{ .type = scenario_event_p, .p = &hiomap_get_info_call, },
 	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
 	SCENARIO_SENTINEL,
 };
 
@@ -498,6 +589,7 @@  static const struct scenario_event scenario_hiomap_event_daemon_ready[] = {
 	{ .type = scenario_event_p, .p = &hiomap_get_info_call, },
 	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
 	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
 	SCENARIO_SENTINEL,
 };
 
@@ -520,6 +612,7 @@  static const struct scenario_event scenario_hiomap_event_daemon_stopped[] = {
 	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
 	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
 	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_PROTOCOL_RESET } },
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
 	SCENARIO_SENTINEL,
 };
 
@@ -543,6 +636,7 @@  static const struct scenario_event scenario_hiomap_event_daemon_restarted[] = {
 	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
 	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_PROTOCOL_RESET } },
 	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_DAEMON_READY } },
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_4, },
 	SCENARIO_SENTINEL,
 };
 
@@ -572,6 +666,7 @@  scenario_hiomap_event_daemon_lost_flash_control[] = {
 					| HIOMAP_E_FLASH_LOST),
 		}
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -677,6 +772,7 @@  scenario_hiomap_event_daemon_regained_flash_control_dirty[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
 	SCENARIO_SENTINEL,
 };
 
@@ -819,6 +915,7 @@  static const struct scenario_event scenario_hiomap_protocol_reset_recovery[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_9, },
 	SCENARIO_SENTINEL,
 };
 
@@ -851,6 +948,7 @@  scenario_hiomap_protocol_read_one_block[] = {
 		.type = scenario_event_p,
 		.p = &hiomap_create_read_window_qs0l1_rs0l1_call,
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -924,6 +1022,7 @@  scenario_hiomap_protocol_read_two_blocks[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -976,6 +1075,7 @@  scenario_hiomap_protocol_read_one_block_twice[] = {
 		.type = scenario_event_p,
 		.p = &hiomap_create_read_window_qs0l1_rs0l1_call,
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1011,6 +1111,7 @@  scenario_hiomap_protocol_event_before_action[] = {
 					HIOMAP_E_FLASH_LOST,
 		}
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1044,6 +1145,7 @@  scenario_hiomap_protocol_event_during_read[] = {
 					HIOMAP_E_FLASH_LOST,
 		}
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1079,6 +1181,7 @@  scenario_hiomap_protocol_write_one_block[] = {
 	},
 	{ .type = scenario_event_p, .p = &hiomap_mark_dirty_qs0l1_call, },
 	{ .type = scenario_event_p, .p = &hiomap_flush_call, },
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1163,6 +1266,7 @@  scenario_hiomap_protocol_write_two_blocks[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_a, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1245,6 +1349,7 @@  scenario_hiomap_protocol_write_one_block_twice[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_9, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1298,6 +1403,7 @@  scenario_hiomap_protocol_event_during_write[] = {
 					HIOMAP_E_FLASH_LOST,
 		}
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1339,6 +1445,7 @@  scenario_hiomap_protocol_erase_one_block[] = {
 		.type = scenario_event_p,
 		.p = &hiomap_flush_call,
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1387,6 +1494,7 @@  scenario_hiomap_protocol_erase_two_blocks[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_a, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1446,6 +1554,7 @@  scenario_hiomap_protocol_erase_one_block_twice[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_9, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1513,6 +1622,7 @@  scenario_hiomap_protocol_event_during_erase[] = {
 					HIOMAP_E_FLASH_LOST,
 		}
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1617,6 +1727,7 @@  scenario_hiomap_protocol_get_flash_info[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1643,6 +1754,7 @@  scenario_hiomap_protocol_persistent_error[] = {
 	{ .type = scenario_event_p, .p = &hiomap_get_info_call, },
 	{ .type = scenario_event_p, .p = &hiomap_get_flash_info_call, },
 	{ .type = scenario_sel, .s = { .bmc_state = HIOMAP_E_PROTOCOL_RESET } },
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1741,6 +1853,7 @@  scenario_hiomap_create_read_window_error[] = {
 			.cc = IPMI_INVALID_COMMAND_ERR,
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1782,6 +1895,7 @@  scenario_hiomap_create_write_window_error[] = {
 			.cc = IPMI_INVALID_COMMAND_ERR,
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1826,6 +1940,7 @@  static const struct scenario_event scenario_hiomap_mark_dirty_error[] = {
 			.cc = IPMI_INVALID_COMMAND_ERR,
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1867,6 +1982,7 @@  static const struct scenario_event scenario_hiomap_flush_error[] = {
 			.cc = IPMI_INVALID_COMMAND_ERR,
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
 	SCENARIO_SENTINEL,
 };
 
@@ -1917,6 +2033,7 @@  static const struct scenario_event scenario_hiomap_erase_error[] = {
 			.cc = IPMI_INVALID_COMMAND_ERR,
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2137,6 +2254,7 @@  scenario_hiomap_create_read_window_malformed_small[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2184,6 +2302,7 @@  scenario_hiomap_create_read_window_malformed_large[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2230,6 +2349,7 @@  scenario_hiomap_create_write_window_malformed_small[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2277,6 +2397,7 @@  scenario_hiomap_create_write_window_malformed_large[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_5, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2326,6 +2447,7 @@  scenario_hiomap_mark_dirty_malformed_small[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2376,6 +2498,7 @@  scenario_hiomap_mark_dirty_malformed_large[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2422,6 +2545,7 @@  scenario_hiomap_flush_malformed_small[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2469,6 +2593,7 @@  scenario_hiomap_flush_malformed_large[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_7, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2518,6 +2643,7 @@  scenario_hiomap_erase_malformed_small[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2563,6 +2689,7 @@  scenario_hiomap_erase_malformed_large[] = {
 			},
 		},
 	},
+	{ .type = scenario_event_p, .p = &hiomap_reset_call_seq_6, },
 	SCENARIO_SENTINEL,
 };
 
@@ -2768,6 +2895,20 @@  scenario_hiomap_protocol_recovery_failure_ack[] = {
 			},
 		},
 	},
+	{
+		.type = scenario_cmd,
+		.c = {
+			.req = {
+				.cmd = HIOMAP_C_RESET,
+				.seq = 14,
+			},
+			.cc = IPMI_CC_NO_ERROR,
+			.resp = {
+				.cmd = HIOMAP_C_RESET,
+				.seq = 14,
+			},
+		},
+	},
 	SCENARIO_SENTINEL,
 };
 
@@ -2938,6 +3079,20 @@  scenario_hiomap_protocol_recovery_failure_get_info[] = {
 			},
 		},
 	},
+	{
+		.type = scenario_cmd,
+		.c = {
+			.req = {
+				.cmd = HIOMAP_C_RESET,
+				.seq = 15,
+			},
+			.cc = IPMI_CC_NO_ERROR,
+			.resp = {
+				.cmd = HIOMAP_C_RESET,
+				.seq = 15,
+			},
+		},
+	},
 	SCENARIO_SENTINEL,
 };
 
@@ -3107,6 +3262,20 @@  scenario_hiomap_protocol_recovery_failure_get_flash_info[] = {
 			},
 		},
 	},
+	{
+		.type = scenario_cmd,
+		.c = {
+			.req = {
+				.cmd = HIOMAP_C_RESET,
+				.seq = 16,
+			},
+			.cc = IPMI_CC_NO_ERROR,
+			.resp = {
+				.cmd = HIOMAP_C_RESET,
+				.seq = 16,
+			},
+		},
+	},
 	SCENARIO_SENTINEL,
 };