blob: 35278e79fb83fe1928b3b061feb9549e9e413bf3 [file] [log] [blame]
// 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);
}