Message ID | 20220211120747.3074-10-Jonathan.Cameron@huawei.com |
---|---|
State | Superseded |
Headers | show |
Series | CXl 2.0 emulation Support | expand |
Jonathan Cameron <Jonathan.Cameron@huawei.com> writes: > From: Ben Widawsky <ben.widawsky@intel.com> > > Errata F4 to CXL 2.0 clarified the meaning of the timer as the > sum of the value set with the timestamp set command and the number > of nano seconds since it was last set. > > Signed-off-by: Ben Widawsky <ben.widawsky@intel.com> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > --- > hw/cxl/cxl-mailbox-utils.c | 44 +++++++++++++++++++++++++++++++++++++ > include/hw/cxl/cxl_device.h | 6 +++++ > 2 files changed, 50 insertions(+) > > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c > index 8aa1b1e525..258285ab03 100644 > --- a/hw/cxl/cxl-mailbox-utils.c > +++ b/hw/cxl/cxl-mailbox-utils.c > @@ -44,6 +44,9 @@ enum { > #define CLEAR_RECORDS 0x1 > #define GET_INTERRUPT_POLICY 0x2 > #define SET_INTERRUPT_POLICY 0x3 > + TIMESTAMP = 0x03, > + #define GET 0x0 > + #define SET 0x1 > }; > > /* 8.2.8.4.5.1 Command Return Codes */ > @@ -106,9 +109,48 @@ DEFINE_MAILBOX_HANDLER_NOP(events_clear_records); > DEFINE_MAILBOX_HANDLER_ZEROED(events_get_interrupt_policy, 4); > DEFINE_MAILBOX_HANDLER_NOP(events_set_interrupt_policy); > > +/* 8.2.9.3.1 */ > +static ret_code cmd_timestamp_get(struct cxl_cmd *cmd, > + CXLDeviceState *cxl_dstate, > + uint16_t *len) > +{ > + uint64_t time, delta; > + > + if (!cxl_dstate->timestamp.set) { > + *(uint64_t *)cmd->payload = 0; > + goto done; > + } > + > + /* First find the delta from the last time the host set the time. */ > + time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); > + delta = time - cxl_dstate->timestamp.last_set; > + > + /* Then adjust the actual time */ > + stq_le_p(cmd->payload, cxl_dstate->timestamp.host_set + delta); > + > +done: Again I think an unnecessary goto for want of: uin64_t final_time = 0; if (cxl_dstate->timestamp.set) { /* First find the delta from the last time the host set the time. */ time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); delta = time - cxl_dstate->timestamp.last_set; final_time = cxl_dstate->timestamp.host_set + delta; } /* Then adjust the actual time */ stq_le_p(cmd->payload, final_time); > + *len = 8; > + return CXL_MBOX_SUCCESS; > +} > + > +/* 8.2.9.3.2 */ > +static ret_code cmd_timestamp_set(struct cxl_cmd *cmd, > + CXLDeviceState *cxl_dstate, > + uint16_t *len) > +{ > + cxl_dstate->timestamp.set = true; > + cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); > + > + cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)cmd->payload); > + > + *len = 0; > + return CXL_MBOX_SUCCESS; > +} > + > static QemuUUID cel_uuid; > > #define IMMEDIATE_CONFIG_CHANGE (1 << 1) > +#define IMMEDIATE_POLICY_CHANGE (1 << 3) > #define IMMEDIATE_LOG_CHANGE (1 << 4) > > static struct cxl_cmd cxl_cmd_set[256][256] = { > @@ -120,6 +162,8 @@ static struct cxl_cmd cxl_cmd_set[256][256] = { > cmd_events_get_interrupt_policy, 0, 0 }, > [EVENTS][SET_INTERRUPT_POLICY] = { "EVENTS_SET_INTERRUPT_POLICY", > cmd_events_set_interrupt_policy, 4, IMMEDIATE_CONFIG_CHANGE }, > + [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 }, > + [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 8, IMMEDIATE_POLICY_CHANGE }, > }; > > void cxl_process_mailbox(CXLDeviceState *cxl_dstate) > diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h > index 7fd8d0f616..8102d2a813 100644 > --- a/include/hw/cxl/cxl_device.h > +++ b/include/hw/cxl/cxl_device.h > @@ -117,6 +117,12 @@ typedef struct cxl_device_state { > size_t cel_size; > }; > > + struct { > + bool set; > + uint64_t last_set; > + uint64_t host_set; > + } timestamp; > + > /* memory region for persistent memory, HDM */ > uint64_t pmem_size; > } CXLDeviceState; Otherwise: Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 8aa1b1e525..258285ab03 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -44,6 +44,9 @@ enum { #define CLEAR_RECORDS 0x1 #define GET_INTERRUPT_POLICY 0x2 #define SET_INTERRUPT_POLICY 0x3 + TIMESTAMP = 0x03, + #define GET 0x0 + #define SET 0x1 }; /* 8.2.8.4.5.1 Command Return Codes */ @@ -106,9 +109,48 @@ DEFINE_MAILBOX_HANDLER_NOP(events_clear_records); DEFINE_MAILBOX_HANDLER_ZEROED(events_get_interrupt_policy, 4); DEFINE_MAILBOX_HANDLER_NOP(events_set_interrupt_policy); +/* 8.2.9.3.1 */ +static ret_code cmd_timestamp_get(struct cxl_cmd *cmd, + CXLDeviceState *cxl_dstate, + uint16_t *len) +{ + uint64_t time, delta; + + if (!cxl_dstate->timestamp.set) { + *(uint64_t *)cmd->payload = 0; + goto done; + } + + /* First find the delta from the last time the host set the time. */ + time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + delta = time - cxl_dstate->timestamp.last_set; + + /* Then adjust the actual time */ + stq_le_p(cmd->payload, cxl_dstate->timestamp.host_set + delta); + +done: + *len = 8; + return CXL_MBOX_SUCCESS; +} + +/* 8.2.9.3.2 */ +static ret_code cmd_timestamp_set(struct cxl_cmd *cmd, + CXLDeviceState *cxl_dstate, + uint16_t *len) +{ + cxl_dstate->timestamp.set = true; + cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + + cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)cmd->payload); + + *len = 0; + return CXL_MBOX_SUCCESS; +} + static QemuUUID cel_uuid; #define IMMEDIATE_CONFIG_CHANGE (1 << 1) +#define IMMEDIATE_POLICY_CHANGE (1 << 3) #define IMMEDIATE_LOG_CHANGE (1 << 4) static struct cxl_cmd cxl_cmd_set[256][256] = { @@ -120,6 +162,8 @@ static struct cxl_cmd cxl_cmd_set[256][256] = { cmd_events_get_interrupt_policy, 0, 0 }, [EVENTS][SET_INTERRUPT_POLICY] = { "EVENTS_SET_INTERRUPT_POLICY", cmd_events_set_interrupt_policy, 4, IMMEDIATE_CONFIG_CHANGE }, + [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 }, + [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 8, IMMEDIATE_POLICY_CHANGE }, }; void cxl_process_mailbox(CXLDeviceState *cxl_dstate) diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 7fd8d0f616..8102d2a813 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -117,6 +117,12 @@ typedef struct cxl_device_state { size_t cel_size; }; + struct { + bool set; + uint64_t last_set; + uint64_t host_set; + } timestamp; + /* memory region for persistent memory, HDM */ uint64_t pmem_size; } CXLDeviceState;