| // Copyright Microsoft and CHERIoT Contributors. |
| // SPDX-License-Identifier: MIT |
| |
| #include "hello.h" |
| #include <debug.hh> |
| #include <futex.h> |
| #include <locks.hh> |
| #include <platform-uart.hh> |
| |
| /// Expose debugging features unconditionally for this compartment. |
| using Debug = ConditionalDebug<true, "UART compartment">; |
| |
| // Import some useful things from the CHERI namespace. |
| using namespace CHERI; |
| |
| FlagLock lock; |
| |
| extern "C" ErrorRecoveryBehaviour |
| compartment_error_handler(ErrorState *frame, size_t mcause, size_t mtval) |
| { |
| auto [exceptionCode, registerNumber] = extract_cheri_mtval(mtval); |
| void *faultingRegister = nullptr; |
| if (registerNumber == RegisterNumber::PCC) |
| { |
| faultingRegister = frame->pcc; |
| } |
| else if ((registerNumber > RegisterNumber::CZR) && |
| (registerNumber <= RegisterNumber::CA5)) |
| { |
| // The registers array does not include cnull. |
| faultingRegister = frame->registers[int(registerNumber) - 1]; |
| } |
| // Make sure that we have a new line before the debug output. |
| // This uses the UART driver directly to write a single byte. |
| MMIO_CAPABILITY(Uart, uart)->blocking_write('\n'); |
| |
| Debug::log("Detected {} trying to write to UART. Register {} contained " |
| "invalid value: {}", |
| exceptionCode, |
| registerNumber, |
| faultingRegister); |
| lock.unlock(); |
| return ErrorRecoveryBehaviour::ForceUnwind; |
| } |
| |
| /// Write a message to the UART. |
| void write(const char *msg) |
| { |
| LockGuard g{lock}; |
| Debug::log("Message provided by caller: {}", msg); |
| } |