xref: /openbmc/hiomapd/control.c (revision 457a6e5fa6a7dad50673222b09b2c7fec2ef0a97)
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright (C) 2018 IBM Corp.
3 #include <errno.h>
4 #include <stdlib.h>
5 
6 #include "dbus.h"
7 #include "mbox.h"
8 #include "flash.h"
9 #include "lpc.h"
10 #include "transport_mbox.h"
11 #include "windows.h"
12 
13 int control_ping(struct mbox_context *context)
14 {
15 	return 0;
16 }
17 
18 int control_daemon_state(struct mbox_context *context)
19 {
20 	return (context->state & STATE_SUSPENDED) ?
21 		DAEMON_STATE_SUSPENDED : DAEMON_STATE_ACTIVE;
22 }
23 
24 int control_lpc_state(struct mbox_context *context)
25 {
26 	if ((context->state & MAPS_MEM) && !(context->state & MAPS_FLASH)) {
27 		return LPC_STATE_MEM;
28 	} else if (!(context->state & MAPS_MEM) &&
29 		   (context->state & MAPS_FLASH)) {
30 		return LPC_STATE_FLASH;
31 	}
32 
33 	return LPC_STATE_INVALID;
34 }
35 
36 int control_reset(struct mbox_context *context)
37 {
38 	int rc;
39 
40 	/* We don't let the host access flash if the daemon is suspened */
41 	if (context->state & STATE_SUSPENDED) {
42 		return -EBUSY;
43 	}
44 
45 	/*
46 	 * This will close (and flush) the current window and reset the lpc bus
47 	 * mapping back to flash, or memory in case we're using a virtual pnor.
48 	 * Better set the bmc event to notify the host of this.
49 	 */
50 	windows_reset_all(context, SET_BMC_EVENT);
51 	rc = lpc_reset(context);
52 	if (rc < 0) {
53 		return rc;
54 	}
55 
56 	return 0;
57 }
58 
59 int control_kill(struct mbox_context *context)
60 {
61 	context->terminate = 1;
62 
63 	MSG_INFO("DBUS Kill - Exiting...\n");
64 
65 	return 0;
66 }
67 
68 int control_modified(struct mbox_context *context)
69 {
70 	/* Flash has been modified - can no longer trust our erased bytemap */
71 	flash_set_bytemap(context, 0, context->flash_size, FLASH_DIRTY);
72 
73 	/* Force daemon to reload all windows -> Set BMC event to notify host */
74 	windows_reset_all(context, SET_BMC_EVENT);
75 
76 	return 0;
77 }
78 
79 int control_suspend(struct mbox_context *context)
80 {
81 	int rc;
82 
83 	if (context->state & STATE_SUSPENDED) {
84 		/* Already Suspended */
85 		return 0;
86 	}
87 
88 	/* Nothing to check - Just set the bit to notify the host */
89 	rc = set_bmc_events(context, BMC_EVENT_FLASH_CTRL_LOST, SET_BMC_EVENT);
90 	if (rc < 0) {
91 		return rc;
92 	}
93 
94 	context->state |= STATE_SUSPENDED;
95 
96 	return rc;
97 }
98 
99 int control_resume(struct mbox_context *context, bool modified)
100 {
101 	int rc;
102 
103 	if (!(context->state & STATE_SUSPENDED)) {
104 		/* We weren't suspended... */
105 		return 0;
106 	}
107 
108 	if (modified) {
109 		/* Call the flash modified handler */
110 		control_modified(context);
111 	}
112 
113 	/* Clear the bit and send the BMC Event to the host */
114 	rc = clr_bmc_events(context, BMC_EVENT_FLASH_CTRL_LOST, SET_BMC_EVENT);
115 	if (rc < 0) {
116 		return rc;
117 	}
118 	context->state &= ~STATE_SUSPENDED;
119 
120 	return rc;
121 }
122