blob: e87e0d3493a7a434db4c374f2ff0a49796e2c19f [file] [log] [blame]
David Brazdil66fc1202022-07-04 21:48:45 +01001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Exception handlers.
16
Alice Wangf1d5efd2023-07-04 15:07:59 +000017use vmbase::{
Alice Wangf1d5efd2023-07-04 15:07:59 +000018 eprintln,
19 exceptions::{ArmException, Esr, HandleExceptionError},
20 logger,
21 memory::{handle_permission_fault, handle_translation_fault},
22 power::reboot,
23 read_sysreg,
24};
25
26fn handle_exception(exception: &ArmException) -> Result<(), HandleExceptionError> {
27 // Handle all translation faults on both read and write, and MMIO guard map
28 // flagged invalid pages or blocks that caused the exception.
29 // Handle permission faults for DBM flagged entries, and flag them as dirty on write.
30 match exception.esr {
31 Esr::DataAbortTranslationFault => handle_translation_fault(exception.far),
32 Esr::DataAbortPermissionFault => handle_permission_fault(exception.far),
33 _ => Err(HandleExceptionError::UnknownException),
34 }
35}
David Brazdil66fc1202022-07-04 21:48:45 +010036
37#[no_mangle]
Alice Wangf1d5efd2023-07-04 15:07:59 +000038extern "C" fn sync_exception_current(elr: u64, _spsr: u64) {
39 // Disable logging in exception handler to prevent unsafe writes to UART.
40 let _guard = logger::suppress();
41
42 let exception = ArmException::from_el1_regs();
43 if let Err(e) = handle_exception(&exception) {
44 exception.print("sync_exception_current", e, elr);
45 reboot()
46 }
David Brazdil66fc1202022-07-04 21:48:45 +010047}
48
49#[no_mangle]
50extern "C" fn irq_current() {
Pierre-Clément Tosi50b490a2024-06-18 20:28:29 +010051 eprintln!("irq_current");
David Brazdil66fc1202022-07-04 21:48:45 +010052 reboot();
53}
54
55#[no_mangle]
56extern "C" fn fiq_current() {
Pierre-Clément Tosi50b490a2024-06-18 20:28:29 +010057 eprintln!("fiq_current");
David Brazdil66fc1202022-07-04 21:48:45 +010058 reboot();
59}
60
61#[no_mangle]
62extern "C" fn serr_current() {
Pierre-Clément Tosi50b490a2024-06-18 20:28:29 +010063 eprintln!("serr_current");
David Brazdil66fc1202022-07-04 21:48:45 +010064 print_esr();
65 reboot();
66}
67
68#[no_mangle]
69extern "C" fn sync_lower() {
Pierre-Clément Tosi50b490a2024-06-18 20:28:29 +010070 eprintln!("sync_lower");
David Brazdil66fc1202022-07-04 21:48:45 +010071 print_esr();
72 reboot();
73}
74
75#[no_mangle]
76extern "C" fn irq_lower() {
Pierre-Clément Tosi50b490a2024-06-18 20:28:29 +010077 eprintln!("irq_lower");
David Brazdil66fc1202022-07-04 21:48:45 +010078 reboot();
79}
80
81#[no_mangle]
82extern "C" fn fiq_lower() {
Pierre-Clément Tosi50b490a2024-06-18 20:28:29 +010083 eprintln!("fiq_lower");
David Brazdil66fc1202022-07-04 21:48:45 +010084 reboot();
85}
86
87#[no_mangle]
88extern "C" fn serr_lower() {
Pierre-Clément Tosi50b490a2024-06-18 20:28:29 +010089 eprintln!("serr_lower");
David Brazdil66fc1202022-07-04 21:48:45 +010090 print_esr();
91 reboot();
92}
93
94#[inline]
95fn print_esr() {
Pierre-Clément Tosi9a7328e2023-07-07 15:51:51 +000096 let esr = read_sysreg!("esr_el1");
David Brazdil66fc1202022-07-04 21:48:45 +010097 eprintln!("esr={:#08x}", esr);
98}