Commit f69760da authored by Andrew Jeffery's avatar Andrew Jeffery

protocol: Introduce protocol_reset()

protocol_reset() encapsulates the actions necessary to return the LPC
state to what's required to boot the host. This is backend dependent;
for the mtd backend we can simply point the bridge at the host flash
AHB mapping, and for the virtual pnor we want to rearrange the content
of the LPC reserved memory (leaving the bridge pointed there). In either
case the state of the FWH address space is distured, so inform the host
as necessary.

Change-Id: Ie8efd1f703a3616c33f76f4e735c1efea039146c
Signed-off-by: Andrew Jeffery's avatarAndrew Jeffery <andrew@aj.id.au>
parent 4e75a27a
...@@ -36,8 +36,6 @@ int control_lpc_state(struct mbox_context *context) ...@@ -36,8 +36,6 @@ int control_lpc_state(struct mbox_context *context)
int control_reset(struct mbox_context *context) int control_reset(struct mbox_context *context)
{ {
int rc;
/* We don't let the host access flash if the daemon is suspened */ /* We don't let the host access flash if the daemon is suspened */
if (context->state & STATE_SUSPENDED) { if (context->state & STATE_SUSPENDED) {
return -EBUSY; return -EBUSY;
...@@ -49,18 +47,7 @@ int control_reset(struct mbox_context *context) ...@@ -49,18 +47,7 @@ int control_reset(struct mbox_context *context)
* mapping back to flash, or memory in case we're using a virtual pnor. * mapping back to flash, or memory in case we're using a virtual pnor.
* Better set the bmc event to notify the host of this. * Better set the bmc event to notify the host of this.
*/ */
if (windows_reset_all(context)) { return protocol_reset(context);
rc = protocol_events_set(context, BMC_EVENT_WINDOW_RESET);
if (rc < 0) {
return rc;
}
}
rc = lpc_reset(context);
if (rc < 0) {
return rc;
}
return 0;
} }
int control_kill(struct mbox_context *context) int control_kill(struct mbox_context *context)
......
...@@ -147,21 +147,9 @@ static int poll_loop(struct mbox_context *context) ...@@ -147,21 +147,9 @@ static int poll_loop(struct mbox_context *context)
context->terminate = true; context->terminate = true;
break; break;
case SIGHUP: case SIGHUP:
/* Host didn't request reset -> Notify it */ rc = protocol_reset(context);
if (windows_reset_all(context)) {
rc = protocol_events_set(context,
BMC_EVENT_WINDOW_RESET);
if (rc < 0) { if (rc < 0) {
MSG_ERR("Failed to notify host of reset, expect host-side corruption\n"); MSG_ERR("Failed to reset on SIGHUP\n");
break;
}
}
rc = lpc_reset(context);
if (rc < 0) {
MSG_ERR("WARNING: Failed to point the "
"LPC bus back to flash on "
"SIGHUP\nIf the host requires "
"this expect problems...\n");
} }
break; break;
default: default:
...@@ -191,15 +179,9 @@ static int poll_loop(struct mbox_context *context) ...@@ -191,15 +179,9 @@ static int poll_loop(struct mbox_context *context)
} }
} }
/* Best to reset windows and the lpc mapping for safety */ rc = protocol_reset(context);
/* Host didn't request reset -> Notify it */
windows_reset_all(context);
rc = lpc_reset(context);
/* Not much we can do if this fails */
if (rc < 0) { if (rc < 0) {
MSG_ERR("WARNING: Failed to point the LPC bus back to flash\n" MSG_ERR("Failed to reset during poll loop cleanup\n");
"If the host requires this expect problems...\n");
} }
return rc; return rc;
...@@ -407,10 +389,7 @@ int main(int argc, char **argv) ...@@ -407,10 +389,7 @@ int main(int argc, char **argv)
#endif #endif
/* Set the LPC bus mapping */ /* Set the LPC bus mapping */
rc = lpc_reset(context); __protocol_reset(context);
if (rc) {
MSG_ERR("LPC configuration failed, RESET required: %d\n", rc);
}
/* We're ready to go, alert the host */ /* We're ready to go, alert the host */
context->bmc_events |= BMC_EVENT_DAEMON_READY; context->bmc_events |= BMC_EVENT_DAEMON_READY;
......
...@@ -532,3 +532,38 @@ void protocol_free(struct mbox_context *context) ...@@ -532,3 +532,38 @@ void protocol_free(struct mbox_context *context)
{ {
return; return;
} }
/* Don't do any state manipulation, just perform the reset */
int __protocol_reset(struct mbox_context *context)
{
windows_reset_all(context);
return lpc_reset(context);
}
/* Prevent the host from performing actions whilst reset takes place */
int protocol_reset(struct mbox_context *context)
{
int rc;
rc = protocol_events_clear(context, BMC_EVENT_DAEMON_READY);
if (rc < 0) {
MSG_ERR("Failed to clear daemon ready state, reset failed\n");
return rc;
}
rc = __protocol_reset(context);
if (rc < 0) {
MSG_ERR("Failed to reset protocol, daemon remains not ready\n");
return rc;
}
rc = protocol_events_set(context,
BMC_EVENT_DAEMON_READY | BMC_EVENT_PROTOCOL_RESET);
if (rc < 0) {
MSG_ERR("Failed to set daemon ready state, daemon remains not ready\n");
return rc;
}
return 0;
}
...@@ -121,6 +121,12 @@ void protocol_free(struct mbox_context *context); ...@@ -121,6 +121,12 @@ void protocol_free(struct mbox_context *context);
int protocol_negotiate_version(struct mbox_context *context, uint8_t requested); int protocol_negotiate_version(struct mbox_context *context, uint8_t requested);
/* Sneaky reset: Don't tell the host */
int __protocol_reset(struct mbox_context *context);
/* Noisy reset: Tell the host */
int protocol_reset(struct mbox_context *context);
int protocol_events_put(struct mbox_context *context, int protocol_events_put(struct mbox_context *context,
const struct transport_ops *ops); const struct transport_ops *ops);
int protocol_events_set(struct mbox_context *context, uint8_t bmc_event); int protocol_events_set(struct mbox_context *context, uint8_t bmc_event);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment