blob: a87d44bea9d76d76e7dc0cef21ae5c6f28cf6be1 [file] [log] [blame]
// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT
#include "hello.h"
#include <debug.hh>
#include <fail-simulator-on-error.h>
#include <futex.h>
#include <string_view>
/// Expose debugging features unconditionally for this compartment.
using Debug = ConditionalDebug<true, "UART compartment">;
// Import some useful things from the CHERI namespace.
using namespace CHERI;
/// Write a message to the UART.
void write(const char *msg)
{
// Word containing the lock, this is 0 for unlocked, 1 for locked.
static uint32_t lockWord = 0;
with_interrupts_disabled([]() {
// Check the word is 0, if it isn't then yield. We may be woken after
// another thread that manages to get the lock and so we need to retry
// in a loop.
while (lockWord != 0)
{
futex_wait(&lockWord, 0);
}
lockWord = 1;
});
// Make sure that this is a valid readable capability.
if (check_pointer<PermissionSet{Permission::Load}>(msg))
{
// Don't assume that there's a null terminator.
std::string_view message{msg,
static_cast<size_t>(Capability{msg}.bounds())};
Debug::log("{}", message);
}
// Release the lock.
lockWord = 0;
futex_wake(&lockWord, -1);
}