xref: /openbmc/hiomapd/control.c (revision 68a24c9ea5ce11c87fab22a3f4648c7d88c98fee)
168023074SAndrew Jeffery // SPDX-License-Identifier: Apache-2.0
268023074SAndrew Jeffery // Copyright (C) 2018 IBM Corp.
368023074SAndrew Jeffery #include <errno.h>
468023074SAndrew Jeffery #include <stdlib.h>
568023074SAndrew Jeffery 
65320f6e0SAndrew Jeffery #include "backend.h"
726558dbbSAndrew Jeffery #include "common.h"
868023074SAndrew Jeffery #include "dbus.h"
9cd18611eSAndrew Jeffery #include "lpc.h"
105320f6e0SAndrew Jeffery #include "mboxd.h"
115320f6e0SAndrew Jeffery #include "protocol.h"
12f593b1bdSAndrew Jeffery #include "windows.h"
1368023074SAndrew Jeffery 
control_ping(struct mbox_context * context)14*68a24c9eSPatrick Williams int control_ping(struct mbox_context *context __attribute__((unused)))
1568023074SAndrew Jeffery {
1668023074SAndrew Jeffery 	return 0;
1768023074SAndrew Jeffery }
1868023074SAndrew Jeffery 
control_daemon_state(struct mbox_context * context)1968023074SAndrew Jeffery int control_daemon_state(struct mbox_context *context)
2068023074SAndrew Jeffery {
2168023074SAndrew Jeffery 	return (context->state & STATE_SUSPENDED) ?
2268023074SAndrew Jeffery 		DAEMON_STATE_SUSPENDED : DAEMON_STATE_ACTIVE;
2368023074SAndrew Jeffery }
2468023074SAndrew Jeffery 
control_lpc_state(struct mbox_context * context)2568023074SAndrew Jeffery int control_lpc_state(struct mbox_context *context)
2668023074SAndrew Jeffery {
2768023074SAndrew Jeffery 	if ((context->state & MAPS_MEM) && !(context->state & MAPS_FLASH)) {
2868023074SAndrew Jeffery 		return LPC_STATE_MEM;
2968023074SAndrew Jeffery 	} else if (!(context->state & MAPS_MEM) &&
3068023074SAndrew Jeffery 		   (context->state & MAPS_FLASH)) {
3168023074SAndrew Jeffery 		return LPC_STATE_FLASH;
3268023074SAndrew Jeffery 	}
3368023074SAndrew Jeffery 
3468023074SAndrew Jeffery 	return LPC_STATE_INVALID;
3568023074SAndrew Jeffery }
3668023074SAndrew Jeffery 
control_reset(struct mbox_context * context)3768023074SAndrew Jeffery int control_reset(struct mbox_context *context)
3868023074SAndrew Jeffery {
3968023074SAndrew Jeffery 	/* We don't let the host access flash if the daemon is suspened */
4068023074SAndrew Jeffery 	if (context->state & STATE_SUSPENDED) {
4168023074SAndrew Jeffery 		return -EBUSY;
4268023074SAndrew Jeffery 	}
4368023074SAndrew Jeffery 
44cda29646SAndrew Jeffery 	/* FIXME: Comment below is wrong: windows_reset_all() does not flush! */
4568023074SAndrew Jeffery 	/*
4668023074SAndrew Jeffery 	 * This will close (and flush) the current window and reset the lpc bus
4768023074SAndrew Jeffery 	 * mapping back to flash, or memory in case we're using a virtual pnor.
4868023074SAndrew Jeffery 	 * Better set the bmc event to notify the host of this.
4968023074SAndrew Jeffery 	 */
50f69760daSAndrew Jeffery 	return protocol_reset(context);
5168023074SAndrew Jeffery }
5268023074SAndrew Jeffery 
control_kill(struct mbox_context * context)5368023074SAndrew Jeffery int control_kill(struct mbox_context *context)
5468023074SAndrew Jeffery {
5568023074SAndrew Jeffery 	context->terminate = 1;
5668023074SAndrew Jeffery 
5768023074SAndrew Jeffery 	MSG_INFO("DBUS Kill - Exiting...\n");
5868023074SAndrew Jeffery 
5968023074SAndrew Jeffery 	return 0;
6068023074SAndrew Jeffery }
6168023074SAndrew Jeffery 
control_modified(struct mbox_context * context)6268023074SAndrew Jeffery int control_modified(struct mbox_context *context)
6368023074SAndrew Jeffery {
6468023074SAndrew Jeffery 	/* Flash has been modified - can no longer trust our erased bytemap */
650297e5b8SAndrew Jeffery 	backend_set_bytemap(&context->backend, 0, context->backend.flash_size,
66f1e547c7SEvan Lojewski 			    FLASH_DIRTY);
6768023074SAndrew Jeffery 
6868023074SAndrew Jeffery 	/* Force daemon to reload all windows -> Set BMC event to notify host */
692ebfd20fSAndrew Jeffery 	if (windows_reset_all(context)) {
702ebfd20fSAndrew Jeffery 		protocol_events_set(context, BMC_EVENT_WINDOW_RESET);
712ebfd20fSAndrew Jeffery 	}
7268023074SAndrew Jeffery 
7368023074SAndrew Jeffery 	return 0;
7468023074SAndrew Jeffery }
7568023074SAndrew Jeffery 
control_suspend(struct mbox_context * context)7668023074SAndrew Jeffery int control_suspend(struct mbox_context *context)
7768023074SAndrew Jeffery {
7868023074SAndrew Jeffery 	int rc;
7968023074SAndrew Jeffery 
8068023074SAndrew Jeffery 	if (context->state & STATE_SUSPENDED) {
8168023074SAndrew Jeffery 		/* Already Suspended */
82ef9e62d3SAndrew Jeffery 		return 0;
8368023074SAndrew Jeffery 	}
8468023074SAndrew Jeffery 
8568023074SAndrew Jeffery 	/* Nothing to check - Just set the bit to notify the host */
862ebfd20fSAndrew Jeffery 	rc = protocol_events_set(context, BMC_EVENT_FLASH_CTRL_LOST);
8768023074SAndrew Jeffery 	if (rc < 0) {
8868023074SAndrew Jeffery 		return rc;
8968023074SAndrew Jeffery 	}
9068023074SAndrew Jeffery 
9168023074SAndrew Jeffery 	context->state |= STATE_SUSPENDED;
9268023074SAndrew Jeffery 
9368023074SAndrew Jeffery 	return rc;
9468023074SAndrew Jeffery }
9568023074SAndrew Jeffery 
control_resume(struct mbox_context * context,bool modified)9668023074SAndrew Jeffery int control_resume(struct mbox_context *context, bool modified)
9768023074SAndrew Jeffery {
9868023074SAndrew Jeffery 	int rc;
9968023074SAndrew Jeffery 
10068023074SAndrew Jeffery 	if (!(context->state & STATE_SUSPENDED)) {
10168023074SAndrew Jeffery 		/* We weren't suspended... */
102ef9e62d3SAndrew Jeffery 		return 0;
10368023074SAndrew Jeffery 	}
10468023074SAndrew Jeffery 
10568023074SAndrew Jeffery 	if (modified) {
10668023074SAndrew Jeffery 		/* Call the flash modified handler */
10768023074SAndrew Jeffery 		control_modified(context);
10868023074SAndrew Jeffery 	}
10968023074SAndrew Jeffery 
11068023074SAndrew Jeffery 	/* Clear the bit and send the BMC Event to the host */
1112ebfd20fSAndrew Jeffery 	rc = protocol_events_clear(context, BMC_EVENT_FLASH_CTRL_LOST);
11268023074SAndrew Jeffery 	if (rc < 0) {
113ef9e62d3SAndrew Jeffery 		return rc;
11468023074SAndrew Jeffery 	}
11568023074SAndrew Jeffery 	context->state &= ~STATE_SUSPENDED;
11668023074SAndrew Jeffery 
11768023074SAndrew Jeffery 	return rc;
11868023074SAndrew Jeffery }
1195320f6e0SAndrew Jeffery 
control_set_backend(struct mbox_context * context,struct backend * backend,void * data)1205320f6e0SAndrew Jeffery int control_set_backend(struct mbox_context *context, struct backend *backend,
1215320f6e0SAndrew Jeffery 			void *data)
1225320f6e0SAndrew Jeffery {
1232ecad07cSAndrew Jeffery 	struct backend successor;
1245320f6e0SAndrew Jeffery 	int rc;
1255320f6e0SAndrew Jeffery 
1265320f6e0SAndrew Jeffery 	if (context->state & STATE_SUSPENDED)
1275320f6e0SAndrew Jeffery 		return -EINVAL;
1285320f6e0SAndrew Jeffery 
1295320f6e0SAndrew Jeffery 	rc = protocol_events_clear(context, BMC_EVENT_DAEMON_READY);
1305320f6e0SAndrew Jeffery 	if (rc < 0)
1315320f6e0SAndrew Jeffery 		return rc;
1325320f6e0SAndrew Jeffery 
1332ecad07cSAndrew Jeffery 	rc = backend_init(&successor, backend, data);
1345320f6e0SAndrew Jeffery 	if (rc < 0)
1355320f6e0SAndrew Jeffery 		return rc;
1365320f6e0SAndrew Jeffery 
1372ecad07cSAndrew Jeffery 	backend_free(&context->backend);
1382ecad07cSAndrew Jeffery 
1392ecad07cSAndrew Jeffery 	context->backend = successor;
1402ecad07cSAndrew Jeffery 
1415320f6e0SAndrew Jeffery 	rc = __protocol_reset(context);
1425320f6e0SAndrew Jeffery 	if (rc < 0)
1435320f6e0SAndrew Jeffery 		return rc;
1445320f6e0SAndrew Jeffery 
1455320f6e0SAndrew Jeffery 	return protocol_events_set(context,
1465320f6e0SAndrew Jeffery 			BMC_EVENT_DAEMON_READY | BMC_EVENT_PROTOCOL_RESET);
1475320f6e0SAndrew Jeffery }
148