|
67 | 67 |
|
68 | 68 | #include "ioc.h"
|
69 | 69 | #include "vmmapi.h"
|
| 70 | +#include "monitor.h" |
70 | 71 |
|
71 | 72 | /* For debugging log to a file */
|
72 | 73 | static int ioc_debug;
|
@@ -126,6 +127,38 @@ static int dummy1_sfd = -1;
|
126 | 127 | static int dummy2_sfd = -1;
|
127 | 128 | #endif
|
128 | 129 |
|
| 130 | +/* |
| 131 | + * VM Manager interfaces description. |
| 132 | + * |
| 133 | + * +---------+ +---------+ +---------+ |
| 134 | + * |IOC | VM stop |VM | |SOS | |
| 135 | + * |Mediator |<----------------+Manager | |Lifecycle| |
| 136 | + * | | | | | | |
| 137 | + * | | VM suspend | | | | |
| 138 | + * | |<----------------+ | | | |
| 139 | + * | | | | | | |
| 140 | + * | | VM resume | | | | |
| 141 | + * | |<----------------+ | | | |
| 142 | + * | |get_wakeup_reason| |get wakeup reason| | |
| 143 | + * | |for resume flow | |via unix socket | | |
| 144 | + * | +---------------->| +---------------->| | |
| 145 | + * +---------+ +---------+ +---------+ |
| 146 | + * |
| 147 | + * Only support stop/resume/suspend in IOC mediator currently. |
| 148 | + * For resume request, IOC mediator will get the wakeup reason from SOS |
| 149 | + * lifecycle service, then pass to UOS once received HB INIT from UOS. |
| 150 | + * For stop and suspend requests, they are implemented as wakeup reason of |
| 151 | + * ignition button. |
| 152 | + */ |
| 153 | +static int vm_stop_handler(void *arg); |
| 154 | +static int vm_resume_handler(void *arg); |
| 155 | +static int vm_suspend_handler(void *arg); |
| 156 | +static struct monitor_vm_ops vm_ops = { |
| 157 | + .stop = vm_stop_handler, |
| 158 | + .resume = vm_resume_handler, |
| 159 | + .suspend = vm_suspend_handler, |
| 160 | +}; |
| 161 | + |
129 | 162 | /*
|
130 | 163 | * IOC State Transfer
|
131 | 164 | *
|
@@ -1301,6 +1334,72 @@ ioc_is_platform_supported(void)
|
1301 | 1334 | return stat(IOC_NP_ESIG, &st);
|
1302 | 1335 | }
|
1303 | 1336 |
|
| 1337 | +/* |
| 1338 | + * The callback to handle with VM stop request. |
| 1339 | + * To emulate ignition off wakeup reason including set force S5 bit. |
| 1340 | + */ |
| 1341 | +static int |
| 1342 | +vm_stop_handler(void *arg) |
| 1343 | +{ |
| 1344 | + struct ioc_dev *ioc = arg; |
| 1345 | + |
| 1346 | + if (!ioc) { |
| 1347 | + DPRINTF("%s", "ioc vm stop gets NULL pointer\r\n"); |
| 1348 | + return -1; |
| 1349 | + } |
| 1350 | + ioc->vm_req = VM_REQ_STOP; |
| 1351 | + return 0; |
| 1352 | +} |
| 1353 | + |
| 1354 | +/* |
| 1355 | + * The callback to handle with VM suspend. |
| 1356 | + * To emulate ignition off wakeup reason. |
| 1357 | + */ |
| 1358 | +static int |
| 1359 | +vm_suspend_handler(void *arg) |
| 1360 | +{ |
| 1361 | + struct ioc_dev *ioc = arg; |
| 1362 | + |
| 1363 | + if (!ioc) { |
| 1364 | + DPRINTF("%s", "ioc vm suspend gets NULL pointer\r\n"); |
| 1365 | + return -1; |
| 1366 | + } |
| 1367 | + ioc->vm_req = VM_REQ_SUSPEND; |
| 1368 | + return 0; |
| 1369 | +} |
| 1370 | + |
| 1371 | +/* |
| 1372 | + * The callback to handle with VM resume. |
| 1373 | + * To get wakeup reason and trigger IOC_E_RESUME event. |
| 1374 | + */ |
| 1375 | +static int |
| 1376 | +vm_resume_handler(void *arg) |
| 1377 | +{ |
| 1378 | + struct ioc_dev *ioc = arg; |
| 1379 | + uint32_t reason; |
| 1380 | + |
| 1381 | + if (!ioc) { |
| 1382 | + DPRINTF("%s", "ioc vm resume gets NULL pointer\r\n"); |
| 1383 | + return -1; |
| 1384 | + } |
| 1385 | + |
| 1386 | + reason = get_wakeup_reason(); |
| 1387 | + if (!reason) { |
| 1388 | + DPRINTF("%s", "ioc vm resume gets invalid wakeup reason \r\n"); |
| 1389 | + return -1; |
| 1390 | + } |
| 1391 | + |
| 1392 | + /* |
| 1393 | + * Change VM request to resume for stopping the emulation of suspend |
| 1394 | + * and shutdown wakeup reasons. |
| 1395 | + */ |
| 1396 | + ioc->vm_req = VM_REQ_RESUME; |
| 1397 | + |
| 1398 | + ioc->boot_reason = reason; |
| 1399 | + ioc_update_event(ioc->evt_fd, IOC_E_RESUME); |
| 1400 | + return 0; |
| 1401 | +} |
| 1402 | + |
1304 | 1403 | /*
|
1305 | 1404 | * To get IOC bootup reason and virtual UART path for communication
|
1306 | 1405 | * between IOC mediator and virtual UART.
|
@@ -1367,6 +1466,14 @@ ioc_init(struct vmctx *ctx)
|
1367 | 1466 | if (ioc->epfd < 0)
|
1368 | 1467 | goto alloc_err;
|
1369 | 1468 |
|
| 1469 | + /* |
| 1470 | + * Register IOC mediator VM ops for stop/suspend/resume. |
| 1471 | + */ |
| 1472 | + if (monitor_register_vm_ops(&vm_ops, ioc, "ioc_dm") < 0) { |
| 1473 | + DPRINTF("%s", "ioc register to VM monitor failed\r\n"); |
| 1474 | + goto alloc_err; |
| 1475 | + } |
| 1476 | + |
1370 | 1477 | /*
|
1371 | 1478 | * Put all buffered CBC requests on the free queue, the free queue is
|
1372 | 1479 | * used to be a cbc_request buffer.
|
|
0 commit comments