blob: 0fb29116b820cd407ced00dcc829efd94b04db8a [file] [log] [blame]
Andrew Walbrandfb73372022-04-21 10:52:27 +00001// 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
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010017use crate::helpers::page_4kb_of;
Andrew Walbrandfb73372022-04-21 10:52:27 +000018use core::arch::asm;
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010019use vmbase::console;
Andrew Walbrandd74b902022-04-14 16:12:50 +000020use vmbase::{console::emergency_write_str, eprintln, power::reboot};
Andrew Walbrandfb73372022-04-21 10:52:27 +000021
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010022const ESR_32BIT_EXT_DABT: u64 = 0x96000010;
23const UART_PAGE: u64 = page_4kb_of(console::BASE_ADDRESS as u64);
24
Andrew Walbrandfb73372022-04-21 10:52:27 +000025#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010026extern "C" fn sync_exception_current(_elr: u64, _spsr: u64) {
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010027 let esr = read_esr();
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010028 let far = read_far();
29 // Don't print to the UART if we're handling the exception it could raise.
30 if esr != ESR_32BIT_EXT_DABT || page_4kb_of(far) != UART_PAGE {
31 emergency_write_str("sync_exception_current\n");
32 print_esr(esr);
33 }
Andrew Walbrandd74b902022-04-14 16:12:50 +000034 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000035}
36
37#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010038extern "C" fn irq_current(_elr: u64, _spsr: u64) {
Andrew Walbrandfb73372022-04-21 10:52:27 +000039 emergency_write_str("irq_current\n");
Andrew Walbrandd74b902022-04-14 16:12:50 +000040 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000041}
42
43#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010044extern "C" fn fiq_current(_elr: u64, _spsr: u64) {
Andrew Walbrandfb73372022-04-21 10:52:27 +000045 emergency_write_str("fiq_current\n");
Andrew Walbrandd74b902022-04-14 16:12:50 +000046 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000047}
48
49#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010050extern "C" fn serr_current(_elr: u64, _spsr: u64) {
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010051 let esr = read_esr();
Andrew Walbrandfb73372022-04-21 10:52:27 +000052 emergency_write_str("serr_current\n");
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010053 print_esr(esr);
Andrew Walbrandd74b902022-04-14 16:12:50 +000054 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000055}
56
57#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010058extern "C" fn sync_lower(_elr: u64, _spsr: u64) {
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010059 let esr = read_esr();
Andrew Walbrandfb73372022-04-21 10:52:27 +000060 emergency_write_str("sync_lower\n");
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010061 print_esr(esr);
Andrew Walbrandd74b902022-04-14 16:12:50 +000062 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000063}
64
65#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010066extern "C" fn irq_lower(_elr: u64, _spsr: u64) {
Andrew Walbrandfb73372022-04-21 10:52:27 +000067 emergency_write_str("irq_lower\n");
Andrew Walbrandd74b902022-04-14 16:12:50 +000068 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000069}
70
71#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010072extern "C" fn fiq_lower(_elr: u64, _spsr: u64) {
Andrew Walbrandfb73372022-04-21 10:52:27 +000073 emergency_write_str("fiq_lower\n");
Andrew Walbrandd74b902022-04-14 16:12:50 +000074 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000075}
76
77#[no_mangle]
Pierre-Clément Tosi8cbd4b72022-08-11 13:59:31 +010078extern "C" fn serr_lower(_elr: u64, _spsr: u64) {
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010079 let esr = read_esr();
Andrew Walbrandfb73372022-04-21 10:52:27 +000080 emergency_write_str("serr_lower\n");
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010081 print_esr(esr);
Andrew Walbrandd74b902022-04-14 16:12:50 +000082 reboot();
Andrew Walbrandfb73372022-04-21 10:52:27 +000083}
84
85#[inline]
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010086fn read_esr() -> u64 {
Andrew Walbrandfb73372022-04-21 10:52:27 +000087 let mut esr: u64;
88 unsafe {
89 asm!("mrs {esr}, esr_el1", esr = out(reg) esr);
90 }
Pierre-Clément Tosi94e9d602022-08-22 17:51:40 +010091 esr
92}
93
94#[inline]
95fn print_esr(esr: u64) {
Andrew Walbrandfb73372022-04-21 10:52:27 +000096 eprintln!("esr={:#08x}", esr);
97}
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +010098
99#[inline]
100fn read_far() -> u64 {
101 let mut far: u64;
102 unsafe {
103 asm!("mrs {far}, far_el1", far = out(reg) far);
104 }
105 far
106}