Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added gpiolib and sonata_gpio_demo_image #13

Merged
merged 4 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions compartments/gpiolib.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright lowRISC Contributors.
// SPDX-License-Identifier: Apache-2.0

#include "gpiolib.hh"
#include <platform-gpio.hh>
#include <timeout.hh>
#include <token.h>

/// The number of LEDs available.
static constexpr uint8_t NumLeds = 8;
/// A mask of the LEDs that have been aquired.
static uint8_t ledTaken = 0x0;

/**
* A handle showing ownership of the LED at the held index.
*/
struct LedHandle
{
uint8_t index;
};

/**
* Get a token key for use sealing LedHandles.
*/
static auto key()
{
static auto key = token_key_new();
return key;
}

/**
* Get a pointer to the GPIO MMIO region.
*/
static auto gpio()
{
static auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
return gpio;
}

/**
* Aquire a handle to the LED at the given index.
*/
auto aquire_led(uint8_t index) -> std::optional<LedHandle *>
{
if (NumLeds <= index)
return {};

// We should use some sort of lock here...
const uint8_t LedBit = 1 << index;
if (0 != (ledTaken & LedBit))
return {};
ledTaken |= LedBit;

// Allocate an LedHandle to the heap and receive a sealed and unsealed key
// pointing to this allocation
auto [unsealed, sealed] =
blocking_forever<token_allocate<LedHandle>>(MALLOC_CAPABILITY, key());
if (sealed == nullptr)
{
return {};
}
unsealed->index = index;
return sealed.get();
}

/**
* Unseal a handle with our led token key.
*/
static auto unseal_handle(LedHandle *handle) -> std::optional<LedHandle *>
{
const auto unsealed = token_unseal(key(), Sealed<LedHandle>{handle});
if (nullptr == unsealed)
{
return {};
}
return unsealed;
}

/**
* Toggle the LED of the given handle.
*/
bool toggle_led(LedHandle *handle)
{
if (auto unsealedHandle = unseal_handle(handle))
{
gpio()->led_toggle(unsealedHandle.value()->index);
return true;
}
else
{
return false;
}
};

/**
* Reliquish ownership of the LED of the given handle.
*/
void release_led(LedHandle *handle)
{
if (auto unsealedHandle = unseal_handle(handle))
{
// We should use some sort of lock here...
const uint8_t LedBit = 1 << unsealedHandle.value()->index;
ledTaken &= ~LedBit;
}
// The allocator checks validity before destroying so we don't have to.
token_obj_destroy(MALLOC_CAPABILITY, key(), reinterpret_cast<SObj>(handle));
}
12 changes: 12 additions & 0 deletions compartments/gpiolib.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright lowRISC Contributors.
// SPDX-License-Identifier: Apache-2.0

#include <compartment.h>
#include <optional>

struct LedHandle;

__cheri_compartment("gpiolib") auto aquire_led(uint8_t value)
-> std::optional<LedHandle *>;
__cheri_compartment("gpiolib") void release_led(LedHandle *);
__cheri_compartment("gpiolib") bool toggle_led(LedHandle *);
38 changes: 19 additions & 19 deletions compartments/led_walk.cc
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
// Copyright lowRISC Contributors.
// SPDX-License-Identifier: Apache-2.0

#include <compartment.h>
#include "gpiolib.hh"
#include <debug.hh>
#include <platform-gpio.hh>
#include <thread.h>
#include <vector>

/// Expose debugging features unconditionally for this compartment.
using Debug = ConditionalDebug<true, "led walk compartment">;

static constexpr uint32_t num_leds = 8;
using Debug = ConditionalDebug<true, "Led Walk">;

/// Thread entry point.
void __cheri_compartment("led_walk") start_walking()
{
Debug::log("Look pretty LEDs!");
std::vector<LedHandle *> leds;
for (uint8_t num = 0; num < 8; ++num)
{
auto led = aquire_led(num);
Debug::Assert(led.has_value(), "LED {} couldn't be aquired", num);
leds.push_back(led.value());
};

auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
Debug::log(" LED 3 Handle: {}", leds[3]);
release_led(leds[3]);
Debug::log("Destroyed LED 3 Handle: {}", leds[3]);
leds[3] = aquire_led(3).value();
Debug::log(" New LED 3 Handle: {}", leds[3]);

int count = 0;
bool switch_on = true;
while (true)
{
if (switch_on)
for (auto led : leds)
{
gpio->led_on(count);
bool success = toggle_led(led);
Debug::Assert(success, "Failed to toggle an LED");
thread_millisecond_wait(500);
}
else
{
gpio->led_off(count);
};
thread_millisecond_wait(500);
switch_on = (count == num_leds - 1) ? !switch_on : switch_on;
count = (count < num_leds - 1) ? count + 1 : 0;
}
}
37 changes: 37 additions & 0 deletions compartments/led_walk_raw.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright lowRISC Contributors.
// SPDX-License-Identifier: Apache-2.0

#include <compartment.h>
#include <debug.hh>
#include <platform-gpio.hh>
#include <thread.h>

/// Expose debugging features unconditionally for this compartment.
using Debug = ConditionalDebug<true, "Led Walk Raw">;

static constexpr uint32_t NumLeds = 8;

/// Thread entry point.
void __cheri_compartment("led_walk_raw") start_walking()
{
Debug::log("Look pretty LEDs!");

auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);

int count = 0;
bool switchOn = true;
while (true)
{
if (switchOn)
{
gpio->led_on(count);
}
else
{
gpio->led_off(count);
};
thread_millisecond_wait(500);
switchOn = (count == NumLeds - 1) ? !switchOn : switchOn;
count = (count < NumLeds - 1) ? count + 1 : 0;
}
}
Loading
Loading