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