forked from CHERIoT-Platform/cheriot-rtos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
uart.cc
42 lines (38 loc) · 1.19 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
// 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);
}