Skip to content

Commit 48067b1

Browse files
yliu80lijinxia
authored andcommitted
IOC mediator: Implement VM monitor operations
This patch implements VM monitor operations including stop/suspend/resume. For other VM monitor operations(pause/unpause/query), IOC mediator would not register callbacks for them since there is no requirements from VM Manager. Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Reviewed-by: Yu Wang <yu1.wang@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
1 parent 32fccb2 commit 48067b1

File tree

3 files changed

+169
-5
lines changed

3 files changed

+169
-5
lines changed

devicemodel/hw/platform/ioc.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
#include "ioc.h"
6969
#include "vmmapi.h"
70+
#include "monitor.h"
7071

7172
/* For debugging log to a file */
7273
static int ioc_debug;
@@ -126,6 +127,38 @@ static int dummy1_sfd = -1;
126127
static int dummy2_sfd = -1;
127128
#endif
128129

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+
129162
/*
130163
* IOC State Transfer
131164
*
@@ -1301,6 +1334,72 @@ ioc_is_platform_supported(void)
13011334
return stat(IOC_NP_ESIG, &st);
13021335
}
13031336

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+
13041403
/*
13051404
* To get IOC bootup reason and virtual UART path for communication
13061405
* between IOC mediator and virtual UART.
@@ -1367,6 +1466,14 @@ ioc_init(struct vmctx *ctx)
13671466
if (ioc->epfd < 0)
13681467
goto alloc_err;
13691468

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+
13701477
/*
13711478
* Put all buffered CBC requests on the free queue, the free queue is
13721479
* used to be a cbc_request buffer.

devicemodel/hw/platform/ioc_cbc.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ cbc_update_wakeup_reason(struct cbc_pkt *pkt, uint32_t reason)
601601

602602
/*
603603
* Mask the bits of wakeup reason that are not allowed by IOC mediator.
604-
* Only allow Ignition button, cardoor, RTC and SoC currently.
604+
* Only allow Ignition button, cardoor, RTC, SOC and force S5 currently.
605605
*/
606606
reason &= CBC_WK_RSN_ALL;
607607

@@ -814,6 +814,45 @@ cbc_rx_handler(struct cbc_pkt *pkt)
814814
}
815815
}
816816

817+
/*
818+
* Convert VM request to the wakeup reason.
819+
*/
820+
static bool
821+
send_wakeup_reason_of_vm_request(struct cbc_pkt *pkt)
822+
{
823+
uint32_t reason;
824+
825+
switch (pkt->ioc->vm_req) {
826+
case VM_REQ_STOP:
827+
/*
828+
* Force S5 and SoC bits are set for emulating
829+
* shutdown wakeup reason that VM initiates stop
830+
*/
831+
reason = CBC_WK_RSN_FS5 | CBC_WK_RSN_SOC;
832+
break;
833+
case VM_REQ_SUSPEND:
834+
/*
835+
* Only SoC bit is set for emulating suspend
836+
* wakeup reason that VM initiates suspend.
837+
*/
838+
reason = CBC_WK_RSN_SOC;
839+
break;
840+
default:
841+
/*
842+
* There is no need to emulate wakeup reasons for VM_REQ_RESUME
843+
* and VM_REQ_NONE VM requests since VM manager just only asks
844+
* IOC mediator to emulate ignition off wakeup reason for
845+
* VM_REQ_STOP and VM_REQ_SUSPEND, otherwise call primary
846+
* periodic wakeup reason.
847+
*/
848+
return false;
849+
}
850+
851+
cbc_update_wakeup_reason(pkt, reason);
852+
cbc_send_pkt(pkt);
853+
return true;
854+
}
855+
817856
/*
818857
* Tx handler mainly processes tx direction data flow,
819858
* the tx direction is that native CBC cdevs -> virtual UART.
@@ -824,7 +863,12 @@ cbc_tx_handler(struct cbc_pkt *pkt)
824863
if (pkt->req->rtype == CBC_REQ_T_PROT && pkt->ioc->cbc_enable) {
825864
switch (pkt->req->id) {
826865
case IOC_NATIVE_LFCC:
827-
cbc_process_wakeup_reason(pkt);
866+
/* Check VM request firstly */
867+
if (send_wakeup_reason_of_vm_request(pkt) == false) {
868+
869+
/* Primary periodic wakeup reason */
870+
cbc_process_wakeup_reason(pkt);
871+
}
828872
break;
829873
case IOC_NATIVE_SIGNAL:
830874
cbc_process_signal(pkt);

devicemodel/include/ioc.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,19 @@
7777
#define CBC_WK_RSN_BTN (1 << 5) /* CBC wakeup reason field button */
7878
#define CBC_WK_RSN_RTC (1 << 9) /* CBC wakeup reason field rtc */
7979
#define CBC_WK_RSN_DOR (1 << 11) /* CBC wakeup reason field cardoor */
80+
#define CBC_WK_RSN_FS5 (1 << 22) /* CBC wakeup reason field force S5 */
8081
#define CBC_WK_RSN_SOC (1 << 23) /* CBC wakeup reason field soc */
8182

8283
/* CBC wakeup reason filed suspend or shutdown */
8384
#define CBC_WK_RSN_SHUTDOWN (0)
8485

8586
/*
86-
* IOC mediator permits button, rtc and cardoor wakeup reasons which comes from
87-
* IOC firmware, others will be masked.
87+
* IOC mediator permits ignition button, cardoor, RTC, SOC and force S5 wakeup
88+
* reasons which comes from IOC firmware, others will be masked.
8889
*/
8990
#define CBC_WK_RSN_ALL \
90-
(CBC_WK_RSN_BTN | CBC_WK_RSN_RTC | CBC_WK_RSN_DOR | CBC_WK_RSN_SOC)
91+
(CBC_WK_RSN_BTN | CBC_WK_RSN_RTC | CBC_WK_RSN_DOR | CBC_WK_RSN_SOC | \
92+
CBC_WK_RSN_FS5)
9193

9294
/*
9395
* CBC ring buffer is used to buffer bytes before build one complete CBC frame.
@@ -660,6 +662,16 @@ enum ioc_event_type {
660662
IOC_E_RESUME
661663
};
662664

665+
/*
666+
* VM request types.
667+
*/
668+
enum vm_request_type {
669+
VM_REQ_NONE,
670+
VM_REQ_STOP,
671+
VM_REQ_SUSPEND,
672+
VM_REQ_RESUME
673+
};
674+
663675
/*
664676
* CBC packet is mainly structure for CBC protocol process.
665677
*/
@@ -691,6 +703,7 @@ struct ioc_dev {
691703
int epfd; /* Epoll fd */
692704
int32_t evt_fd; /* Pipe write fd to trigger one event */
693705
uint32_t boot_reason; /* Boot or resume wakeup reason */
706+
enum vm_request_type vm_req; /* Request from VM Manager (acrnctl) */
694707
enum ioc_state_type state; /* IOC state type */
695708
struct epoll_event *evts; /* Epoll events table */
696709
struct cbc_request *pool; /* CBC requests pool */

0 commit comments

Comments
 (0)