Olivier Deprez | c8f6a67 | 2022-01-13 13:44:53 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2022, Arm Limited. All rights reserved. |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | #include <stdbool.h> |
| 7 | |
| 8 | #include <arch_helpers.h> |
| 9 | #include <debug.h> |
| 10 | #include <sync.h> |
| 11 | |
| 12 | static exception_handler_t custom_sync_exception_handler; |
| 13 | |
| 14 | void register_custom_sync_exception_handler(exception_handler_t handler) |
| 15 | { |
| 16 | custom_sync_exception_handler = handler; |
| 17 | } |
| 18 | |
| 19 | void unregister_custom_sync_exception_handler(void) |
| 20 | { |
| 21 | custom_sync_exception_handler = NULL; |
| 22 | } |
| 23 | |
| 24 | bool tftf_sync_exception_handler(void) |
| 25 | { |
| 26 | uint64_t elr_elx = IS_IN_EL2() ? read_elr_el2() : read_elr_el1(); |
| 27 | bool resume = false; |
| 28 | |
| 29 | if (custom_sync_exception_handler == NULL) { |
| 30 | return false; |
| 31 | } |
| 32 | |
| 33 | resume = custom_sync_exception_handler(); |
| 34 | |
| 35 | if (resume) { |
| 36 | /* Move ELR to next instruction to allow tftf to continue */ |
| 37 | if (IS_IN_EL2()) { |
| 38 | write_elr_el2(elr_elx + 4U); |
| 39 | } else { |
| 40 | write_elr_el1(elr_elx + 4U); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | return resume; |
| 45 | } |