mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-03 04:39:50 +00:00
IOC mediator: support IOC lifecycle
This patch implements the IOC lifecycle virtualization. In native environment, lifecycle is uesed for SoC system power control, likes enter/exit S3/S5. So these related messages can not forward directly between physical IOC and Guest OS, they need to be mapped to VM pause, exit and launch. Signed-off-by: Liu Yuan <yuan1.liu@intel.com> Reviewed-by: Wang Yu <yu1.wang@intel.com> Reviewed-by: Liu Shuo <shuo.a.liu@intel.com> Reviewed-by: Zhao Yakui <yakui.zhao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
a1d7cae148
commit
61db2c78cc
@ -968,6 +968,7 @@ ioc_rx_thread(void *arg)
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
packet.cfg = &ioc->rx_config;
|
||||
packet.boot_reason = ioc_boot_reason;
|
||||
for (;;) {
|
||||
pthread_mutex_lock(&ioc->rx_mtx);
|
||||
while (SIMPLEQ_EMPTY(&ioc->rx_qhead)) {
|
||||
@ -1019,6 +1020,7 @@ ioc_tx_thread(void *arg)
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
packet.cfg = &ioc->tx_config;
|
||||
packet.boot_reason = ioc_boot_reason;
|
||||
for (;;) {
|
||||
pthread_mutex_lock(&ioc->tx_mtx);
|
||||
while (SIMPLEQ_EMPTY(&ioc->tx_qhead)) {
|
||||
|
@ -346,6 +346,40 @@ cbc_send_pkt(struct cbc_pkt *pkt)
|
||||
DPRINTF("ioc xmit failed on channel id=%d\n\r", id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update heartbeat state.
|
||||
*/
|
||||
static void
|
||||
cbc_update_heartbeat(struct cbc_pkt *pkt, uint8_t cmd, uint8_t sus_action)
|
||||
{
|
||||
uint8_t stat;
|
||||
|
||||
(void) sus_action;
|
||||
|
||||
/*
|
||||
* If heartbeat state switches(active/inactive), update the new state
|
||||
* value based on heartbeat commands.
|
||||
* The default state is inactive.
|
||||
*/
|
||||
if (cmd == CBC_HB_ACTIVE || cmd == CBC_HB_STANDBY ||
|
||||
cmd == CBC_HB_INITIAL)
|
||||
stat = 1;
|
||||
else
|
||||
stat = 0;
|
||||
|
||||
/* Default heartbeat state is zero, that means not active */
|
||||
if (stat != pkt->hb_state) {
|
||||
/*
|
||||
* Route the cbc request to the tx thread
|
||||
* and request type is SOC state update
|
||||
*/
|
||||
pkt->qtype = CBC_QUEUE_T_TX;
|
||||
pkt->req->rtype = CBC_REQ_T_SOC;
|
||||
pkt->req->buf[0] = stat;
|
||||
pkt->hb_state = stat;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update wakeup reason value and notify UOS immediately.
|
||||
* Some events can change the wakeup reason include periodic wakeup reason
|
||||
@ -355,6 +389,37 @@ cbc_send_pkt(struct cbc_pkt *pkt)
|
||||
static void
|
||||
cbc_update_wakeup_reason(struct cbc_pkt *pkt, uint32_t reason)
|
||||
{
|
||||
uint8_t *payload;
|
||||
|
||||
/* TODO: VMM requests S3/S5 do not implement yet */
|
||||
if (pkt->soc_active) {
|
||||
pkt->boot_reason = 0;
|
||||
reason |= CBC_WK_RSN_SOC;
|
||||
} else
|
||||
reason &= ~CBC_WK_RSN_SOC;
|
||||
reason &= CBC_WK_RSN_ALL;
|
||||
|
||||
if (pkt->boot_reason != 0)
|
||||
reason = pkt->boot_reason;
|
||||
|
||||
pkt->reason = reason;
|
||||
|
||||
/* Wakeup reason only has three bytes in CBC payload */
|
||||
payload = pkt->req->buf + CBC_PAYLOAD_POS;
|
||||
payload[0] = reason;
|
||||
payload[1] = reason >> 8;
|
||||
payload[2] = reason >> 16;
|
||||
|
||||
/* For CBC address layer header packing */
|
||||
pkt->req->id = IOC_NATIVE_LFCC;
|
||||
|
||||
/* Fill service header */
|
||||
pkt->req->buf[CBC_SRV_POS] = CBC_SC_WK_RSN;
|
||||
pkt->req->srv_len = 4;
|
||||
pkt->req->link_len = 0;
|
||||
|
||||
/* Send the CBC packet */
|
||||
cbc_send_pkt(pkt);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -364,6 +429,25 @@ cbc_update_wakeup_reason(struct cbc_pkt *pkt, uint32_t reason)
|
||||
static void
|
||||
cbc_process_lifecycle(struct cbc_pkt *pkt)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t *payload;
|
||||
uint32_t reason;
|
||||
|
||||
cmd = pkt->req->buf[CBC_SRV_POS];
|
||||
payload = pkt->req->buf + CBC_PAYLOAD_POS;
|
||||
switch (cmd) {
|
||||
case CBC_SC_WK_RSN:
|
||||
reason = payload[0] | (payload[1] << 8) | (payload[2] << 16);
|
||||
cbc_update_wakeup_reason(pkt, reason);
|
||||
break;
|
||||
case CBC_SC_HB:
|
||||
cbc_update_heartbeat(pkt, payload[0], payload[1]);
|
||||
break;
|
||||
default:
|
||||
DPRINTF("ioc lifecycle command=%d can not be handled\r\n",
|
||||
cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -662,6 +662,7 @@ struct cbc_pkt {
|
||||
uint8_t soc_active; /* Record soc state */
|
||||
uint8_t hb_state; /* Record Heartbeat state */
|
||||
uint32_t reason; /* Record current wakeup reason */
|
||||
uint32_t boot_reason; /* Record boot up wakeup reason */
|
||||
struct cbc_request *req; /* CBC packet data */
|
||||
struct cbc_config *cfg; /* CBC and whitelist configurations */
|
||||
enum cbc_queue_type qtype; /* Routes cbc_request to queue */
|
||||
|
Loading…
Reference in New Issue
Block a user