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