diff options
author | Olivier Deprez <olivier.deprez@arm.com> | 2022-04-04 17:24:36 +0200 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2022-04-04 17:24:36 +0200 |
commit | c394fcc734fd49221030564df51df58db25540f8 (patch) | |
tree | 0b75c952f0bf4406df0d7ea59d40a7734105e465 /spm/cactus/cactus_tests | |
parent | 968a869e90b1f1dc8ddb70cd1f0cca657f885e27 (diff) | |
parent | ff33cd11268a91bf7fa88b10f08eaf9c74c24fc5 (diff) |
Merge changes from topic "mp/sec_intr_management"
* changes:
test(interrupts): check if last service interrupt is Trusted Wdog timer
feat(interrupts): query last serviced interrupt
test(interrupts): use custom handler for interrupt
feat(interrupts): support for registering custom handler
refactor(interrupts): enhance secure interrupt handling test
Diffstat (limited to 'spm/cactus/cactus_tests')
-rw-r--r-- | spm/cactus/cactus_tests/cactus_test_interrupts.c | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/spm/cactus/cactus_tests/cactus_test_interrupts.c b/spm/cactus/cactus_tests/cactus_test_interrupts.c index ced5dca..dc64512 100644 --- a/spm/cactus/cactus_tests/cactus_test_interrupts.c +++ b/spm/cactus/cactus_tests/cactus_test_interrupts.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Arm Limited. All rights reserved. + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,16 @@ #include <platform.h> +/* Secure virtual interrupt that was last handled by Cactus SP. */ +extern uint32_t last_serviced_interrupt[PLATFORM_CORE_COUNT]; +static int flag_set; + +static void sec_wdog_interrupt_handled(void) +{ + expect(flag_set, 0); + flag_set = 1; +} + CACTUS_CMD_HANDLER(sleep_cmd, CACTUS_SLEEP_CMD) { uint64_t time_lapsed; @@ -101,3 +111,70 @@ CACTUS_CMD_HANDLER(twdog_cmd, CACTUS_TWDOG_START_CMD) return cactus_success_resp(vm_id, source, time_ms); } + +bool handle_twdog_interrupt_sp_sleep(uint32_t sleep_time, uint64_t *time_lapsed) +{ + sp_register_interrupt_tail_end_handler(sec_wdog_interrupt_handled, + IRQ_TWDOG_INTID); + *time_lapsed += sp_sleep_elapsed_time(sleep_time); + + if (flag_set == 0) { + return false; + } + + /* Reset the flag and unregister the handler. */ + flag_set = 0; + sp_unregister_interrupt_tail_end_handler(IRQ_TWDOG_INTID); + + return true; +} + +CACTUS_CMD_HANDLER(sleep_twdog_cmd, CACTUS_SLEEP_TRIGGER_TWDOG_CMD) +{ + uint64_t time_lapsed = 0; + uint32_t sleep_time = cactus_get_sleep_time(*args) / 2; + uint64_t time_ms = cactus_get_wdog_trigger_duration(*args); + + VERBOSE("Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args), + sleep_time); + + if (!handle_twdog_interrupt_sp_sleep(sleep_time, &time_lapsed)) { + goto fail; + } + + /* Lapsed time should be at least equal to sleep time. */ + VERBOSE("Sleep complete: %llu\n", time_lapsed); + + VERBOSE("Starting TWDOG: %llums\n", time_ms); + sp805_twdog_refresh(); + sp805_twdog_start((time_ms * ARM_SP805_TWDG_CLK_HZ) / 1000); + + VERBOSE("2nd Request to sleep %x for %ums.\n", ffa_dir_msg_dest(*args), + sleep_time); + + if (!handle_twdog_interrupt_sp_sleep(sleep_time, &time_lapsed)) { + goto fail; + } + + /* Lapsed time should be at least equal to sleep time. */ + VERBOSE("2nd Sleep complete: %llu\n", time_lapsed); + + return cactus_response(ffa_dir_msg_dest(*args), + ffa_dir_msg_source(*args), + time_lapsed); +fail: + /* Test failed. */ + ERROR("Watchdog interrupt not handled\n"); + return cactus_error_resp(ffa_dir_msg_dest(*args), + ffa_dir_msg_source(*args), + CACTUS_ERROR_TEST); +} + +CACTUS_CMD_HANDLER(interrupt_serviced_cmd, CACTUS_LAST_INTERRUPT_SERVICED_CMD) +{ + unsigned int core_pos = get_current_core_id(); + + return cactus_response(ffa_dir_msg_dest(*args), + ffa_dir_msg_source(*args), + last_serviced_interrupt[core_pos]); +} |