aboutsummaryrefslogtreecommitdiffstats
path: root/plat
diff options
context:
space:
mode:
Diffstat (limited to 'plat')
-rw-r--r--plat/arm/board/fvp/fvp_common.c70
-rw-r--r--plat/arm/board/fvp/fvp_pm.c5
-rw-r--r--plat/arm/common/aarch64/arm_ehf.c24
-rw-r--r--plat/arm/common/aarch64/arm_helpers.S29
-rw-r--r--plat/arm/common/aarch64/arm_sdei.c33
-rw-r--r--plat/arm/common/arm_common.c57
-rw-r--r--plat/arm/common/arm_common.mk8
-rw-r--r--plat/arm/common/arm_gicv2.c1
-rw-r--r--plat/arm/common/arm_pm.c22
-rw-r--r--plat/arm/common/arm_tzc400.c22
-rw-r--r--plat/arm/css/common/css_pm.c2
-rw-r--r--plat/common/aarch64/plat_common.c26
-rw-r--r--plat/common/plat_gicv2.c10
-rw-r--r--plat/common/plat_gicv3.c8
-rw-r--r--plat/common/plat_psci_common.c9
15 files changed, 284 insertions, 42 deletions
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 57cc3d513..6729863d7 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -6,6 +6,7 @@
#include <arm_config.h>
#include <arm_def.h>
+#include <arm_spm_def.h>
#include <assert.h>
#include <cci.h>
#include <ccn.h>
@@ -13,6 +14,7 @@
#include <gicv2.h>
#include <mmio.h>
#include <plat_arm.h>
+#include <secure_partition.h>
#include <v2m_def.h>
#include "../fvp_def.h"
@@ -89,6 +91,9 @@ const mmap_region_t plat_arm_mmap[] = {
/* To access the Root of Trust Public Key registers. */
MAP_DEVICE2,
#endif
+#if ENABLE_SPM
+ ARM_SP_IMAGE_MMAP,
+#endif
#if ARM_BL31_IN_DRAM
ARM_MAP_BL31_SEC_DRAM,
#endif
@@ -114,9 +119,23 @@ const mmap_region_t plat_arm_mmap[] = {
MAP_DEVICE0,
MAP_DEVICE1,
ARM_V2M_MAP_MEM_PROTECT,
+#if ENABLE_SPM
+ ARM_SPM_BUF_EL3_MMAP,
+#endif
+ {0}
+};
+
+#if ENABLE_SPM && defined(IMAGE_BL31)
+const mmap_region_t plat_arm_secure_partition_mmap[] = {
+ V2M_MAP_IOFPGA_EL0, /* for the UART */
+ ARM_SP_IMAGE_MMAP,
+ ARM_SP_IMAGE_NS_BUF_MMAP,
+ ARM_SP_IMAGE_RW_MMAP,
+ ARM_SPM_BUF_EL0_MMAP,
{0}
};
#endif
+#endif
#ifdef IMAGE_BL32
const mmap_region_t plat_arm_mmap[] = {
#ifdef AARCH32
@@ -156,6 +175,57 @@ static unsigned int get_interconnect_master(void)
}
#endif
+#if ENABLE_SPM && defined(IMAGE_BL31)
+/*
+ * Boot information passed to a secure partition during initialisation. Linear
+ * indices in MP information will be filled at runtime.
+ */
+static secure_partition_mp_info_t sp_mp_info[] = {
+ [0] = {0x80000000, 0},
+ [1] = {0x80000001, 0},
+ [2] = {0x80000002, 0},
+ [3] = {0x80000003, 0},
+ [4] = {0x80000100, 0},
+ [5] = {0x80000101, 0},
+ [6] = {0x80000102, 0},
+ [7] = {0x80000103, 0},
+};
+
+const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+ .h.type = PARAM_SP_IMAGE_BOOT_INFO,
+ .h.version = VERSION_1,
+ .h.size = sizeof(secure_partition_boot_info_t),
+ .h.attr = 0,
+ .sp_mem_base = ARM_SP_IMAGE_BASE,
+ .sp_mem_limit = ARM_SP_IMAGE_LIMIT,
+ .sp_image_base = ARM_SP_IMAGE_BASE,
+ .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE,
+ .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE,
+ .sp_ns_comm_buf_base = ARM_SP_IMAGE_NS_BUF_BASE,
+ .sp_shared_buf_base = PLAT_SPM_BUF_BASE,
+ .sp_image_size = ARM_SP_IMAGE_SIZE,
+ .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+ .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE,
+ .sp_ns_comm_buf_size = ARM_SP_IMAGE_NS_BUF_SIZE,
+ .sp_shared_buf_size = PLAT_SPM_BUF_SIZE,
+ .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS,
+ .num_cpus = PLATFORM_CORE_COUNT,
+ .mp_info = &sp_mp_info[0],
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+ return plat_arm_secure_partition_mmap;
+}
+
+const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+ void *cookie)
+{
+ return &plat_arm_secure_partition_boot_info;
+}
+
+#endif
+
/*******************************************************************************
* A single boot loader stack is expected to work on both the Foundation FVP
* models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index faeb1b777..13bd8f237 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -14,6 +14,7 @@
#include <plat_arm.h>
#include <platform.h>
#include <psci.h>
+#include <spe.h>
#include <v2m_def.h>
#include "drivers/pwrc/fvp_pwrc.h"
#include "fvp_def.h"
@@ -57,7 +58,7 @@ static void fvp_cluster_pwrdwn_common(void)
* On power down we need to disable statistical profiling extensions
* before exiting coherency.
*/
- arm_disable_spe();
+ spe_disable();
#endif
/* Disable coherency if this cluster is to be turned off */
@@ -398,7 +399,7 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
.system_off = fvp_system_off,
.system_reset = fvp_system_reset,
.validate_power_state = fvp_validate_power_state,
- .validate_ns_entrypoint = arm_validate_ns_entrypoint,
+ .validate_ns_entrypoint = arm_validate_psci_entrypoint,
.translate_power_state_by_mpidr = fvp_translate_power_state_by_mpidr,
.get_node_hw_state = fvp_node_hw_state,
.get_sys_suspend_power_state = fvp_get_sys_suspend_power_state,
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
new file mode 100644
index 000000000..785b7bb54
--- /dev/null
+++ b/plat/arm/common/aarch64/arm_ehf.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <ehf.h>
+#include <platform_def.h>
+
+/*
+ * Enumeration of priority levels on ARM platforms.
+ */
+ehf_pri_desc_t arm_exceptions[] = {
+#if SDEI_SUPPORT
+ /* Critical priority SDEI */
+ EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
+
+ /* Normal priority SDEI */
+ EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
+#endif
+};
+
+/* Plug in ARM exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(arm_exceptions, ARRAY_SIZE(arm_exceptions), ARM_PRI_BITS);
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index b53e60dba..9d3a10819 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -12,7 +12,6 @@
.globl plat_crash_console_putc
.globl plat_crash_console_flush
.globl platform_mem_init
- .globl arm_disable_spe
/* -----------------------------------------------------
@@ -88,34 +87,6 @@ func platform_mem_init
ret
endfunc platform_mem_init
- /* -----------------------------------------------------
- * void arm_disable_spe (void);
- * -----------------------------------------------------
- */
-#if ENABLE_SPE_FOR_LOWER_ELS
-func arm_disable_spe
- /* Detect if SPE is implemented */
- mrs x0, id_aa64dfr0_el1
- ubfx x0, x0, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH
- cmp x0, #0x1
- b.ne 1f
-
- /* Drain buffered data */
- .arch armv8.2-a+profile
- psb csync
- dsb nsh
-
- /* Disable Profiling Buffer */
- mrs x0, pmblimitr_el1
- bic x0, x0, #1
- msr pmblimitr_el1, x0
- isb
- .arch armv8-a
-1:
- ret
-endfunc arm_disable_spe
-#endif
-
/*
* Need to use coherent stack when ARM Cryptocell is used to autheticate images
* since Cryptocell uses DMA to transfer data and it is not coherent with the
diff --git a/plat/arm/common/aarch64/arm_sdei.c b/plat/arm/common/aarch64/arm_sdei.c
new file mode 100644
index 000000000..514800c3e
--- /dev/null
+++ b/plat/arm/common/aarch64/arm_sdei.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for ARM platforms */
+
+#include <ehf.h>
+#include <platform_def.h>
+#include <sdei.h>
+
+/* Private event mappings */
+static sdei_ev_map_t arm_private_sdei[] = {
+ /* Event 0 */
+ SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),
+
+ /* Dynamic private events */
+ SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t arm_shared_sdei[] = {
+ /* Dynamic shared events */
+ SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_0, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+};
+
+/* Export ARM SDEI events */
+REGISTER_SDEI_MAP(arm_private_sdei, arm_shared_sdei);
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 420a38651..bf6397377 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -11,6 +11,7 @@
#include <mmio.h>
#include <plat_arm.h>
#include <platform_def.h>
+#include <secure_partition.h>
extern const mmap_region_t plat_arm_mmap[];
@@ -79,6 +80,14 @@ void arm_setup_page_tables(uintptr_t total_base,
MT_DEVICE | MT_RW | MT_SECURE);
#endif
+#if ENABLE_SPM && defined(IMAGE_BL31)
+ /* The address of the following region is calculated by the linker. */
+ mmap_add_region(SP_IMAGE_XLAT_TABLES_START,
+ SP_IMAGE_XLAT_TABLES_START,
+ SP_IMAGE_XLAT_TABLES_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE);
+#endif
+
/* Now (re-)map the platform-specific memory regions */
mmap_add(plat_arm_get_mmap());
@@ -195,3 +204,51 @@ unsigned int plat_get_syscnt_freq2(void)
}
#endif /* ARM_SYS_CNTCTL_BASE */
+
+#if SDEI_SUPPORT
+/*
+ * Translate SDEI entry point to PA, and perform standard ARM entry point
+ * validation on it.
+ */
+int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
+{
+ uint64_t par, pa;
+ uint32_t scr_el3;
+
+ /* Doing Non-secure address translation requires SCR_EL3.NS set */
+ scr_el3 = read_scr_el3();
+ write_scr_el3(scr_el3 | SCR_NS_BIT);
+ isb();
+
+ assert((client_mode == MODE_EL2) || (client_mode == MODE_EL1));
+ if (client_mode == MODE_EL2) {
+ /*
+ * Translate entry point to Physical Address using the EL2
+ * translation regime.
+ */
+ ats1e2r(ep);
+ } else {
+ /*
+ * Translate entry point to Physical Address using the EL1&0
+ * translation regime, including stage 2.
+ */
+ ats12e1r(ep);
+ }
+ isb();
+ par = read_par_el1();
+
+ /* Restore original SCRL_EL3 */
+ write_scr_el3(scr_el3);
+ isb();
+
+ /* If the translation resulted in fault, return failure */
+ if ((par & PAR_F_MASK) != 0)
+ return -1;
+
+ /* Extract Physical Address from PAR */
+ pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT));
+
+ /* Perform NS entry point validation on the physical address */
+ return arm_validate_ns_entrypoint(pa);
+}
+#endif
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 44eb43f62..17acae52f 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -184,6 +184,14 @@ BL31_SOURCES += plat/arm/common/arm_sip_svc.c \
lib/pmf/pmf_smc.c
endif
+ifeq (${EL3_EXCEPTION_HANDLING},1)
+BL31_SOURCES += plat/arm/common/aarch64/arm_ehf.c
+endif
+
+ifeq (${SDEI_SUPPORT},1)
+BL31_SOURCES += plat/arm/common/aarch64/arm_sdei.c
+endif
+
ifneq (${TRUSTED_BOARD_BOOT},0)
# Include common TBB sources
diff --git a/plat/arm/common/arm_gicv2.c b/plat/arm/common/arm_gicv2.c
index b081fa8d9..5644c6040 100644
--- a/plat/arm/common/arm_gicv2.c
+++ b/plat/arm/common/arm_gicv2.c
@@ -51,6 +51,7 @@ void plat_arm_gic_init(void)
{
gicv2_distif_init();
gicv2_pcpu_distif_init();
+ gicv2_set_pe_target_mask(plat_my_core_pos());
gicv2_cpuif_enable();
}
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 5e7e047a5..44ac5b5d6 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -112,7 +112,7 @@ int arm_validate_power_state(unsigned int power_state,
/*******************************************************************************
* ARM standard platform handler called to check the validity of the non secure
- * entrypoint.
+ * entrypoint. Returns 0 if the entrypoint is valid, or -1 otherwise.
******************************************************************************/
int arm_validate_ns_entrypoint(uintptr_t entrypoint)
{
@@ -121,15 +121,23 @@ int arm_validate_ns_entrypoint(uintptr_t entrypoint)
* secure DRAM.
*/
if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint <
- (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE)))
- return PSCI_E_SUCCESS;
+ (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE))) {
+ return 0;
+ }
#ifndef AARCH32
if ((entrypoint >= ARM_DRAM2_BASE) && (entrypoint <
- (ARM_DRAM2_BASE + ARM_DRAM2_SIZE)))
- return PSCI_E_SUCCESS;
+ (ARM_DRAM2_BASE + ARM_DRAM2_SIZE))) {
+ return 0;
+ }
#endif
- return PSCI_E_INVALID_ADDRESS;
+ return -1;
+}
+
+int arm_validate_psci_entrypoint(uintptr_t entrypoint)
+{
+ return arm_validate_ns_entrypoint(entrypoint) == 0 ? PSCI_E_SUCCESS :
+ PSCI_E_INVALID_ADDRESS;
}
/******************************************************************************
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index e19ca673f..23c031734 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arm_def.h>
+#include <arm_spm_def.h>
#include <debug.h>
#include <platform_def.h>
#include <tzc400.h>
@@ -56,9 +57,26 @@ void arm_tzc400_setup(void)
ARM_DRAM2_BASE, ARM_DRAM2_END,
ARM_TZC_NS_DRAM_S_ACCESS,
PLAT_ARM_TZC_NS_DEV_ACCESS);
-#else
+
+#if ENABLE_SPM
+ /*
+ * Region 4 set to cover Non-Secure access to the communication buffer
+ * shared with the Secure world.
+ */
+ tzc400_configure_region(PLAT_ARM_TZC_FILTERS,
+ 4,
+ ARM_SP_IMAGE_NS_BUF_BASE,
+ (ARM_SP_IMAGE_NS_BUF_BASE +
+ ARM_SP_IMAGE_NS_BUF_SIZE) - 1,
+ TZC_REGION_S_NONE,
+ PLAT_ARM_TZC_NS_DEV_ACCESS);
+#endif
+
+#else /* if defined(EL3_PAYLOAD_BASE) */
+
/* Allow secure access only to DRAM for EL3 payloads. */
tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
+
#endif /* EL3_PAYLOAD_BASE */
/*
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 4104dd73f..4a615e1c9 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -299,7 +299,7 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
.system_off = css_system_off,
.system_reset = css_system_reset,
.validate_power_state = css_validate_power_state,
- .validate_ns_entrypoint = arm_validate_ns_entrypoint,
+ .validate_ns_entrypoint = arm_validate_psci_entrypoint,
.translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
.get_node_hw_state = css_node_hw_state,
.get_sys_suspend_power_state = css_get_sys_suspend_power_state,
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 05084e196..a87e7c673 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -3,6 +3,8 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+
+#include <arch_helpers.h>
#include <assert.h>
#include <console.h>
#include <platform.h>
@@ -20,6 +22,11 @@
#pragma weak plat_get_syscnt_freq2
#endif /* ERROR_DEPRECATED */
+#if SDEI_SUPPORT
+#pragma weak plat_sdei_handle_masked_trigger
+#pragma weak plat_sdei_validate_entry_point
+#endif
+
void bl31_plat_enable_mmu(uint32_t flags)
{
enable_mmu_el3(flags);
@@ -64,3 +71,22 @@ unsigned int plat_get_syscnt_freq2(void)
return (unsigned int)freq;
}
#endif /* ERROR_DEPRECATED */
+
+#if SDEI_SUPPORT
+/*
+ * Function that handles spurious SDEI interrupts while events are masked.
+ */
+void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr)
+{
+ WARN("Spurious SDEI interrupt %u on masked PE %lx\n", intr, mpidr);
+}
+
+/*
+ * Default Function to validate SDEI entry point, which returns success.
+ * Platforms may override this with their own validation mechanism.
+ */
+int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
+{
+ return 0;
+}
+#endif
diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c
index 05fabcab1..38e1a61e7 100644
--- a/plat/common/plat_gicv2.c
+++ b/plat/common/plat_gicv2.c
@@ -277,3 +277,13 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
{
return gicv2_set_pmr(mask);
}
+
+unsigned int plat_ic_get_interrupt_id(unsigned int raw)
+{
+ unsigned int id = (raw & INT_ID_MASK);
+
+ if (id == GIC_SPURIOUS_INTERRUPT)
+ id = INTR_ID_UNAVAILABLE;
+
+ return id;
+}
diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c
index 52ceb6a7c..030eea723 100644
--- a/plat/common/plat_gicv3.c
+++ b/plat/common/plat_gicv3.c
@@ -271,6 +271,14 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
{
return gicv3_set_pmr(mask);
}
+
+unsigned int plat_ic_get_interrupt_id(unsigned int raw)
+{
+ unsigned int id = (raw & INT_ID_MASK);
+
+ return (gicv3_is_intr_id_special_identifier(id) ?
+ INTR_ID_UNAVAILABLE : id);
+}
#endif
#ifdef IMAGE_BL32
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 95adb051c..0e818d0de 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -18,6 +18,13 @@
/* Ticks elapsed in one second by a signal of 1 MHz */
#define MHZ_TICKS_PER_SEC 1000000
+/* Maximum time-stamp value read from architectural counters */
+#ifdef AARCH32
+#define MAX_TS UINT32_MAX
+#else
+#define MAX_TS UINT64_MAX
+#endif
+
/* Following are used as ID's to capture time-stamp */
#define PSCI_STAT_ID_ENTER_LOW_PWR 0
#define PSCI_STAT_ID_EXIT_LOW_PWR 1
@@ -45,7 +52,7 @@ static u_register_t calc_stat_residency(unsigned long long pwrupts,
assert(residency_div);
if (pwrupts < pwrdnts)
- res = UINT64_MAX - pwrdnts + pwrupts;
+ res = MAX_TS - pwrdnts + pwrupts;
else
res = pwrupts - pwrdnts;