| // 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); | |
| } |