-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathuart.cc
51 lines (44 loc) · 1.48 KB
/
uart.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 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);
}