xref: /openbmc/hiomapd/control.c (revision 0297e5b82ea1bf8b151f8208c5f28a121d82eb4c)
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 "backend.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  	/* We don't let the host access flash if the daemon is suspened */
40  	if (context->state & STATE_SUSPENDED) {
41  		return -EBUSY;
42  	}
43  
44  	/* FIXME: Comment below is wrong: windows_reset_all() does not flush! */
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  	return protocol_reset(context);
51  }
52  
53  int control_kill(struct mbox_context *context)
54  {
55  	context->terminate = 1;
56  
57  	MSG_INFO("DBUS Kill - Exiting...\n");
58  
59  	return 0;
60  }
61  
62  int control_modified(struct mbox_context *context)
63  {
64  	/* Flash has been modified - can no longer trust our erased bytemap */
65  	backend_set_bytemap(&context->backend, 0, context->backend.flash_size,
66  			    FLASH_DIRTY);
67  
68  	/* Force daemon to reload all windows -> Set BMC event to notify host */
69  	if (windows_reset_all(context)) {
70  		protocol_events_set(context, BMC_EVENT_WINDOW_RESET);
71  	}
72  
73  	return 0;
74  }
75  
76  int control_suspend(struct mbox_context *context)
77  {
78  	int rc;
79  
80  	if (context->state & STATE_SUSPENDED) {
81  		/* Already Suspended */
82  		return 0;
83  	}
84  
85  	/* Nothing to check - Just set the bit to notify the host */
86  	rc = protocol_events_set(context, BMC_EVENT_FLASH_CTRL_LOST);
87  	if (rc < 0) {
88  		return rc;
89  	}
90  
91  	context->state |= STATE_SUSPENDED;
92  
93  	return rc;
94  }
95  
96  int control_resume(struct mbox_context *context, bool modified)
97  {
98  	int rc;
99  
100  	if (!(context->state & STATE_SUSPENDED)) {
101  		/* We weren't suspended... */
102  		return 0;
103  	}
104  
105  	if (modified) {
106  		/* Call the flash modified handler */
107  		control_modified(context);
108  	}
109  
110  	/* Clear the bit and send the BMC Event to the host */
111  	rc = protocol_events_clear(context, BMC_EVENT_FLASH_CTRL_LOST);
112  	if (rc < 0) {
113  		return rc;
114  	}
115  	context->state &= ~STATE_SUSPENDED;
116  
117  	return rc;
118  }
119