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

Update main with v1.0/staging #61

Merged
merged 9 commits into from
Nov 8, 2024
Merged
2 changes: 1 addition & 1 deletion doc/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Nix can and will build everything from source if it can't find a cached version,

Clone the sonata software repository, *making sure to recursively clone submodules as well*, then navigate into it.
```sh
git clone --branch v0.4 \
git clone --branch v1.0 \
--recurse-submodule \
https://github.com/lowRISC/sonata-software.git
cd sonata-software
Expand Down
14 changes: 12 additions & 2 deletions examples/all/i2c_example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ static void read_temperature_sensor_value(Mmio<OpenTitanI2c> i2c,
const uint8_t RegIdx)
{
uint8_t buf[2] = {RegIdx, 0};
i2c->blocking_write(0x48, buf, 1, false);
if (!i2c->blocking_write(0x48, buf, 1, false))
{
Debug::log("Could not write the {} address", regName);
return;
}
if (i2c->blocking_read(0x48, buf, 2u))
{
int16_t regValue = static_cast<int16_t>((buf[0] << 8) | buf[1]);
Expand All @@ -29,13 +33,18 @@ static void read_temperature_sensor_value(Mmio<OpenTitanI2c> i2c,
else
{
Debug::log("Could not read the {}", regName);
return;
}
}

static void id_eeprom_report(Mmio<OpenTitanI2c> i2c, const uint8_t IdAddr)
{
uint8_t addr[2] = {0};
i2c->blocking_write(0x50u, addr, 2, true);
if (!i2c->blocking_write(0x50u, addr, 2, true))
{
Debug::log("Could not write the ID EEPROM address");
return;
}

static uint8_t data[0x80];
// Initialize the buffer to known contents in case of read issues.
Expand All @@ -44,6 +53,7 @@ static void id_eeprom_report(Mmio<OpenTitanI2c> i2c, const uint8_t IdAddr)
if (!i2c->blocking_read(IdAddr, data, sizeof(data)))
{
Debug::log("Failed to read EEPROM ID of device at address {}", IdAddr);
return;
}

Debug::log("EEPROM ID of device at address {}:", IdAddr);
Expand Down
2 changes: 1 addition & 1 deletion examples/all/led_walk_raw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void __cheri_compartment("led_walk_raw") start_walking()
{
Debug::log("Look pretty LEDs!");

auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);

int count = 0;
bool switchOn = true;
Expand Down
36 changes: 30 additions & 6 deletions examples/all/proximity_sensor_example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ static void setup_proximity_sensor(Mmio<OpenTitanI2c> i2c, const uint8_t Addr)

buf[0] = ApdS9960Id;

i2c->blocking_write(ApdS9960I2cAddress, buf, 1, false);
if (!i2c->blocking_write(ApdS9960I2cAddress, buf, 1, false))
{
Debug::log("Failed to write proximity sensor address");
return;
}
bool success = i2c->blocking_read(ApdS9960I2cAddress, buf, 1);
Debug::Assert(success, "Failed to read proximity sensor ID");

Expand All @@ -46,35 +50,55 @@ static void setup_proximity_sensor(Mmio<OpenTitanI2c> i2c, const uint8_t Addr)
// Disable everything
buf[0] = ApdS9960Enable;
buf[1] = 0x0;
i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true);
if (!i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true))
{
Debug::log("Failed to write proximity sensor address");
return;
}
// Wait for all engines to go idle
thread_millisecond_wait(25);

// Set PEN (proximity enable) and PON (power on)
buf[0] = ApdS9960Enable;
buf[1] = 0x5;
i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true);
if (!i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true))
{
Debug::log("Failed to write proximity sensor address");
return;
}
// Wait for power on
thread_millisecond_wait(10);

// Set proximity gain to 8x
buf[0] = ApdS9960CR1;
buf[1] = 0x0c;
i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true);
if (!i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true))
{
Debug::log("Failed to write proximity sensor address");
return;
}

// Set proximity pulse length to 4us and pulse count to 16us
// (experimentially determined, other values may work better!)
buf[0] = ApdS9960Ppc;
buf[1] = 0x04;
i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true);
if (!i2c->blocking_write(ApdS9960I2cAddress, buf, 2, true))
{
Debug::log("Failed to write proximity sensor address");
return;
}
}

static uint8_t read_proximity_sensor(Mmio<OpenTitanI2c> i2c)
{
uint8_t buf[1];

buf[0] = ApdS9960Pdata;
i2c->blocking_write(ApdS9960I2cAddress, buf, 1, false);
if (!i2c->blocking_write(ApdS9960I2cAddress, buf, 1, false))
{
Debug::log("Failed to write proximity sensor address");
return 0;
}
if (!i2c->blocking_read(ApdS9960I2cAddress, buf, 1))
{
Debug::log("Failed to read proximity sensor value");
Expand Down
3 changes: 3 additions & 0 deletions examples/automotive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ SPDX-License-Identifier: Apache-2.0

## Description

**Note: this demo is currently not updated for the latest 1.0 hardware changes,
and as such will not work.**

The Sonata automotive demo is a demo designed around an automotive context,
which is run in two different environments - one on the Sonata board running
CHERIoT RTOS with CHERIoT enabled, and another running baremetal on Sonata
Expand Down
12 changes: 6 additions & 6 deletions examples/automotive/cheri/receive.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <compartment.h>
#include <debug.hh>
#include <platform-ethernet.hh>
#include <platform-gpio.hh>
#include <platform-pwm.hh>
#include <thread.h>

Expand All @@ -13,8 +14,7 @@

#include "common.hh"

using Debug = ConditionalDebug<true, "Automotive-Receive">;
using SonataPwm = SonataPulseWidthModulation;
using Debug = ConditionalDebug<true, "Automotive-Receive">;
using namespace CHERI;
using namespace sonata::lcd;

Expand Down Expand Up @@ -63,9 +63,9 @@ struct CarInfo
};

// Driver structs/classes
EthernetDevice *ethernet;
SonataLcd *lcd;
volatile SonataGPIO *gpio;
EthernetDevice *ethernet;
SonataLcd *lcd;
volatile SonataGpioBoard *gpio;

// Sets the operating mode that the demo is running in. Default is passthrough.
DemoMode operatingMode = DemoModePassthrough;
Expand Down Expand Up @@ -505,7 +505,7 @@ void update_demo_simulation(CarInfo *carInfo, Point centre)
// Initialise the LCD & GPIO drivers
lcd = new SonataLcd();
lcd->clean(BACKGROUND_COLOUR);
gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);

// Start the main loop
main_demo_loop();
Expand Down
5 changes: 3 additions & 2 deletions examples/automotive/cheri/send.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <debug.hh>
#include <platform-adc.hh>
#include <platform-ethernet.hh>
#include <platform-gpio.hh>
#include <thread.h>

#include "../../../libraries/lcd.hh"
Expand Down Expand Up @@ -282,7 +283,7 @@ void lcd_draw_img(uint32_t x,
*/
uint8_t read_joystick()
{
auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);
return static_cast<uint8_t>(gpio->read_joystick());
}

Expand All @@ -294,7 +295,7 @@ uint8_t read_joystick()
*/
bool read_pedal_digital()
{
auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);
return (gpio->input & (1 << 13)) > 0;
}

Expand Down
18 changes: 9 additions & 9 deletions examples/snake/snake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class SnakeGame
* @param gpio The Sonata GPIO driver to use for I/O operations.
* @param lcd The LCD that will be drawn to.
*/
void wait_for_start(volatile SonataGPIO *gpio, SonataLcd *lcd)
void wait_for_start(volatile SonataGpioBoard *gpio, SonataLcd *lcd)
{
Size displaySize = lcd->resolution();
Point centre = {displaySize.width / 2, displaySize.height / 2};
Expand Down Expand Up @@ -224,8 +224,8 @@ class SnakeGame
bool joystick_in_direction(SonataJoystick joystick,
SonataJoystick direction)
{
return (static_cast<uint8_t>(joystick) &
static_cast<uint8_t>(direction)) > 0;
return (static_cast<uint16_t>(joystick) &
static_cast<uint16_t>(direction)) > 0;
};

/**
Expand All @@ -235,7 +235,7 @@ class SnakeGame
*
* @param gpio The Sonata GPIO driver to use for I/O operations.
*/
Direction read_joystick(volatile SonataGPIO *gpio)
Direction read_joystick(volatile SonataGpioBoard *gpio)
{
SonataJoystick joystickState = gpio->read_joystick();
// The joystick can be in many possible directions - we check directions
Expand Down Expand Up @@ -282,7 +282,7 @@ class SnakeGame
* @param milliseconds The time to wait for in milliseconds.
* @param gpio The Sonata GPIO driver to use for I/O operations.
*/
void wait_with_input(uint32_t milliseconds, volatile SonataGPIO *gpio)
void wait_with_input(uint32_t milliseconds, volatile SonataGpioBoard *gpio)
{
const uint32_t CyclesPerMillisecond = CPU_TIMER_HZ / 1000;
const uint32_t Cycles = milliseconds * CyclesPerMillisecond;
Expand Down Expand Up @@ -461,7 +461,7 @@ class SnakeGame
* @param position The integer tile position (x, y) to draw at.
* @return true if the game is still active, false if the game is over.
*/
bool update_game_state(volatile SonataGPIO *gpio, SonataLcd *lcd)
bool update_game_state(volatile SonataGpioBoard *gpio, SonataLcd *lcd)
{
currentDirection = read_joystick(gpio);

Expand Down Expand Up @@ -525,7 +525,7 @@ class SnakeGame
* @param gpio The Sonata GPIO driver to use for I/O operations
* @param lcd The LCD that will be drawn to.
*/
void main_game_loop(volatile SonataGPIO *gpio, SonataLcd *lcd)
void main_game_loop(volatile SonataGpioBoard *gpio, SonataLcd *lcd)
{
const uint32_t CyclesPerMillisecond = CPU_TIMER_HZ / 1000;
uint64_t currentTime = rdcycle64();
Expand Down Expand Up @@ -581,7 +581,7 @@ class SnakeGame
* @param gpio The Sonata GPIO driver to use for I/O operations.
* @param lcd The LCD that will be drawn to.
*/
void run_game(volatile SonataGPIO *gpio, SonataLcd *lcd)
void run_game(volatile SonataGpioBoard *gpio, SonataLcd *lcd)
{
wait_for_start(gpio, lcd);
initialise_game();
Expand Down Expand Up @@ -650,7 +650,7 @@ compartment_error_handler(ErrorState *frame, size_t mcause, size_t mtval)
// Thread entry point.
void __cheri_compartment("snake") snake()
{
auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);
auto lcd = SonataLcd();
Debug::log("Detected display resolution: {} {}",
static_cast<int>(lcd.resolution().width),
Expand Down
2 changes: 1 addition & 1 deletion exercises/firmware_auditing/part_1/sealed_capability.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ static constexpr size_t ArrSize = 32;

void __cheri_compartment("sealed_capability") do_things()
{
auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);

uint32_t arr[ArrSize];
// Comment the above line and uncomment the below line to allocate on the
Expand Down
4 changes: 2 additions & 2 deletions exercises/hardware_access_control/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The sources of these compartments can be found in [`exercises/hardware_access_co

Let's look inside `blinky_raw`.
It uses the RTOS' `MMIO_CAPABILITY` macro to get the capability that grants it access to the GPIO MMIO region.
This magic macro will handle adding the MMIO region to the compartment's imports and mapping it to a type, in this case `SonataGPIO` (from [`platform-gpio.hh`][]).
This magic macro will handle adding the MMIO region to the compartment's imports and mapping it to a type, in this case `SonataGpioBoard` (from [`platform-gpio.hh`][]).
*For more information on this macro, see [the drivers section of CHERIoT programmers guide][].*

[the drivers section of CHERIoT programmers guide]: https://cheriot.org/book/top-drivers-top.html#mmio_capabilities
Expand Down Expand Up @@ -154,7 +154,7 @@ One can browse the other functions available as part of the compartment package
## Part ∞

Where to go from here...
- There are input devices available through `SonataGPIO`.
- There are input devices available through `SonataGpioBoard`.
You could have a go at adding these to the `gpio_access` compartment.
- The interactions with `ledTaken` global in the `gpio_access` compartment aren't thread safe.
You could take a look at `cheriot-rtos/examples/06.producer-consumer/` to learn how to use a futex to make it thread safe.
Expand Down
2 changes: 1 addition & 1 deletion exercises/hardware_access_control/part_1/blinky_raw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void __cheri_compartment("blinky_raw") start_blinking()
{
Debug::log("Look a blinking LED!");

auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);

while (true)
{
Expand Down
2 changes: 1 addition & 1 deletion exercises/hardware_access_control/part_1/led_walk_raw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void __cheri_compartment("led_walk_raw") start_walking()
{
Debug::log("Look walking LEDs!");

auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);

size_t ledIdx = NumLeds - 1;
while (true)
Expand Down
2 changes: 1 addition & 1 deletion exercises/hardware_access_control/part_2/gpio_access.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static auto key()
*/
static auto gpio()
{
static auto gpio = MMIO_CAPABILITY(SonataGPIO, gpio);
static auto gpio = MMIO_CAPABILITY(SonataGpioBoard, gpio_board);
return gpio;
}

Expand Down
2 changes: 1 addition & 1 deletion exercises/hardware_access_control/part_3/gpio_access.rego
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package gpio_access
# Checks only `gpio_access` has access to the GPIO MMIO
default only_gpio_access_has_access := false
only_gpio_access_has_access {
data.compartment.mmio_allow_list("gpio", { "gpio_access" })
data.compartment.mmio_allow_list("gpio_board", { "gpio_access" })
}

# Checks only `blinky_dynamic` and `led_walk_dynamic` have access
Expand Down
Loading