IOC mediator: add RTC feature

This patch implements RTC feature that UOS can set RTC wakeup timer
to IOC firmware with a specific time before enter S3/S5. IOC mediator
also needs to indicate RTC wakeup reason to UOS after exit S3/S5.

Tracked-On: #1213
Signed-off-by: Yuan Liu <yuan1.liu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Yuan Liu 2018-08-16 16:37:09 +08:00 committed by lijinxia
parent 42d9b24a54
commit ca75d506b7
2 changed files with 84 additions and 6 deletions

View File

@ -12,6 +12,7 @@
#include <stdbool.h>
#include "ioc.h"
#include "monitor.h"
/*
* Debug printf
@ -645,11 +646,22 @@ cbc_process_wakeup_reason(struct cbc_pkt *pkt)
*/
pkt->reason = reason;
if (pkt->uos_active)
if (pkt->uos_active) {
reason |= CBC_WK_RSN_SOC;
else
/* Unset RTC bit if UOS sends active heartbeat */
reason &= ~CBC_WK_RSN_RTC;
} else {
reason &= ~CBC_WK_RSN_SOC;
/*
* Set RTC bit when bootup or resuming reason is
* RTC wakeup reason, and hold the bit until UOS
* sends active heartbeat.
*/
reason |= pkt->ioc->boot_reason & CBC_WK_RSN_RTC;
}
/* Update periodic wakeup reason */
cbc_update_wakeup_reason(pkt, reason);
@ -657,6 +669,45 @@ cbc_process_wakeup_reason(struct cbc_pkt *pkt)
cbc_send_pkt(pkt);
}
/*
* CBC update RTC timer
*/
static void
cbc_update_rtc_timer(uint16_t value, uint8_t unit)
{
time_t timestamp = 0;
if (!value) {
DPRINTF("%s", "ioc sets RTC timer failure, timer is 0\r\n");
return;
}
switch (unit) {
case CBC_RTC_TIMER_U_SEC:
timestamp += value;
break;
case CBC_RTC_TIMER_U_MIN:
timestamp += value * 60;
break;
case CBC_RTC_TIMER_U_HOUR:
timestamp += value * 60 * 60;
break;
case CBC_RTC_TIMER_U_DAY:
timestamp += value * 60 * 60 * 24;
break;
case CBC_RTC_TIMER_U_WEEK:
timestamp += value * 60 * 60 * 24 * 7;
break;
default:
DPRINTF("ioc sets RTC timer failure, invalid timer unit:%d\r\n",
unit);
return;
}
/* Call RTC interface of VM monitor */
set_wakeup_timer(timestamp);
}
/*
* CBC heartbeat processing is main entry for Rx(UOS->IOC) lifecycle service.
*/
@ -668,11 +719,15 @@ cbc_process_heartbeat(struct cbc_pkt *pkt)
cmd = pkt->req->buf[CBC_SRV_POS];
payload = pkt->req->buf + CBC_PAYLOAD_POS;
if (cmd != CBC_SC_HB) {
DPRINTF("Only handle heartbeat cmd, the cmd:%d\r\n", cmd);
return;
if (cmd == CBC_SC_HB) {
cbc_update_heartbeat(pkt, payload[0], payload[1]);
} else if (cmd == CBC_SC_RTC) {
uint16_t timer = payload[0] | payload[1] << 8;
cbc_update_rtc_timer(timer, payload[2]);
}
cbc_update_heartbeat(pkt, payload[0], payload[1]);
DPRINTF("ioc discards the lifecycle rx cmd: %d\r\n", cmd);
}
/*
@ -901,6 +956,7 @@ cbc_tx_handler(struct cbc_pkt *pkt)
pkt->uos_active = true;
} else if (pkt->req->rtype == CBC_REQ_T_UOS_INACTIVE) {
cbc_update_wakeup_reason(pkt, CBC_WK_RSN_SHUTDOWN);
cbc_send_pkt(pkt);
/* Disable UOS active flag */

View File

@ -181,6 +181,7 @@ enum cbc_system_control_command {
CBC_SC_HB = 2, /* Heartbeat */
CBC_SC_BOOTSEL = 3, /* Boot selector */
CBC_SC_SPRS_HB = 4, /* Suppress heartbeat check */
CBC_SC_RTC = 5, /* Set RTC wakeup timer */
CBC_SC_MAX
};
@ -220,6 +221,27 @@ enum cbc_sus_stat_action {
CBC_SS_MAX
};
/*
* CBC system control - RTC: command type.
* RTC Message
* +------------------+-------------+-------------+-------------+
* | SystemControlCMD | Timer value | Timer value | Granularity |
* | SVC-Header: 5 | Bits 0...7 | Bits 8...15 | 0 - seconds |
* | | | | 1 - minutes |
* | | | | 2 - hours |
* | | | | 3 - days |
* | | | | 4 - week |
* | 8b | 8b | 8b | 8b |
* +------------------+-------------+-------------+-------------+
*/
enum cbc_rtc_timer_unit {
CBC_RTC_TIMER_U_SEC,
CBC_RTC_TIMER_U_MIN,
CBC_RTC_TIMER_U_HOUR,
CBC_RTC_TIMER_U_DAY,
CBC_RTC_TIMER_U_WEEK,
};
/*
* CBC rx signal identity definition.
*/