Skip to content

Commit cdaadba

Browse files
committed
ports/cheriot-rtos: Cleaned up peripherals; moved to HAL Compartment.
Signed-off-by: Jacob Trevor <[email protected]>
1 parent 36be122 commit cdaadba

File tree

10 files changed

+192
-61
lines changed

10 files changed

+192
-61
lines changed

ports/cheriot-rtos/Makefile

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,34 +54,39 @@ SRC_C = mp_entry.c \
5454
machine_spi.c \
5555
machine_i2c.c
5656

57-
SRC_CXX = hal/i2c.cpp hal/uart.cpp hal/timer.cpp
57+
SRC_CXX =
5858

5959
SRC_QSTR += shared/readline/readline.c shared/runtime/pyexec.c mp_entry.c machine_pin.c machine_spi.c machine_i2c.c
6060

6161
SRC_HAL_C = shared/runtime/stdout_helpers.c
62-
SRC_HAL_CXX = uart_core.cpp
62+
SRC_HAL_CXX = uart_core.cpp hal/i2c.cpp hal/uart.cpp hal/timer.cpp
6363

6464
SRC_MAIN_C =
6565
SRC_MAIN_CXX = main.cpp
6666

67-
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
68-
OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o))
69-
OBJ += $(PY_O)
67+
OBJ_VM += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
68+
OBJ_VM += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o))
69+
OBJ_VM += $(PY_O)
7070

7171
OBJ_HAL += $(addprefix $(BUILD)/, $(SRC_HAL_C:.c=.o))
7272
OBJ_HAL += $(addprefix $(BUILD)/, $(SRC_HAL_CXX:.cpp=.o))
7373

7474
OBJ_MAIN += $(addprefix $(BUILD)/, $(SRC_MAIN_C:.c=.o))
7575
OBJ_MAIN += $(addprefix $(BUILD)/, $(SRC_MAIN_CXX:.cpp=.o))
76+
77+
OBJ += $(OBJ_VM)
78+
OBJ += $(OBJ_HAL)
79+
OBJ += $(OBJ_MAIN)
7680

77-
$(OBJ): CFLAGS += -DMP_VM_COMP -cheri-compartment=mp_vm
81+
$(OBJ_VM): CFLAGS += -DMP_VM_COMP -cheri-compartment=mp_vm
7882
$(OBJ_HAL): CFLAGS += -cheri-compartment=mp_hal
7983
$(OBJ_MAIN): CFLAGS += -cheri-compartment=main
8084
$(BUILD)/mp_entry.o: CFLAGS += -UCHERIOT_NO_AMBIENT_MALLOC
85+
$(BUILD)/hal/i2c.o: CFLAGS += -Wno-unused-variable
8186

8287
all: $(BUILD)/micropython.uf2
8388

84-
all_objects : $(OBJ) $(OBJ_HAL) $(OBJ_MAIN)
89+
all_objects : $(OBJ_VM) $(OBJ_HAL) $(OBJ_MAIN)
8590
.PHONY: all all_objects
8691

8792
$(BUILD)/_frozen_mpy.c: $(TOP)/tests/frozen/frozentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h
@@ -91,7 +96,7 @@ $(BUILD)/_frozen_mpy.c: $(TOP)/tests/frozen/frozentest.mpy $(BUILD)/genhdr/qstrd
9196
$(BUILD)/xmake.lua: xmake.lua.top xmake.lua.bottom
9297
cat xmake.lua.top > $@
9398
echo "compartment(\"mp_vm\")" >> $@
94-
for OFILE in $(patsubst $(BUILD)/%,%,$(OBJ)) ; do echo " add_files(\"$$OFILE\", {rule = \"utils.merge.object\"})" >> $@ ; done
99+
for OFILE in $(patsubst $(BUILD)/%,%,$(OBJ_VM)) ; do echo " add_files(\"$$OFILE\", {rule = \"utils.merge.object\"})" >> $@ ; done
95100
echo "compartment(\"mp_hal\")" >> $@
96101
for OFILE in $(patsubst $(BUILD)/%,%,$(OBJ_HAL)) ; do echo " add_files(\"$$OFILE\", {rule = \"utils.merge.object\"})" >> $@ ; done
97102
echo "compartment(\"main\")" >> $@

ports/cheriot-rtos/hal/i2c.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
#include <stdio.h>
22
#include <platform-i2c.hh>
33

4-
extern "C" void i2c_setup(volatile OpenTitanI2c *i2c, uint32_t freq_kHz) {
4+
#include "mphalport.h"
5+
6+
void MP_HAL_FUNC i2c_setup(volatile OpenTitanI2c *i2c, uint32_t freq_kHz) {
57
i2c->reset_fifos();
68
i2c->host_mode_set();
79
i2c->speed_set(freq_kHz);
810
}
911

10-
extern "C" bool i2c_blocking_read(volatile OpenTitanI2c *i2c, uint8_t addr, uint8_t *buf, uint32_t len) {
12+
bool MP_HAL_FUNC i2c_blocking_read(volatile OpenTitanI2c *i2c, uint8_t addr, uint8_t *buf, uint32_t len) {
1113
return i2c->blocking_read(addr, buf, len);
1214
}
1315

14-
extern "C" bool i2c_check_success(volatile OpenTitanI2c *i2c) {
16+
bool MP_HAL_FUNC i2c_check_success(volatile OpenTitanI2c *i2c) {
1517
while (!i2c->format_is_empty()) {
1618
}
1719
if (i2c->interrupt_is_asserted(OpenTitanI2cInterrupt::Nak)) {
@@ -21,13 +23,13 @@ extern "C" bool i2c_check_success(volatile OpenTitanI2c *i2c) {
2123
return true;
2224
}
2325

24-
extern "C" bool i2c_blocking_write(volatile OpenTitanI2c *i2c, uint8_t addr, uint8_t *buf, uint32_t len, bool skipStop) {
26+
bool MP_HAL_FUNC i2c_blocking_write(volatile OpenTitanI2c *i2c, uint8_t addr, uint8_t *buf, uint32_t len, bool skipStop) {
2527
i2c->blocking_write(addr, buf, len, skipStop);
2628
return i2c_check_success(i2c);
2729
}
2830

2931

30-
extern "C" bool i2c_send_address(volatile OpenTitanI2c *i2c, uint8_t addr) {
32+
bool MP_HAL_FUNC i2c_send_address(volatile OpenTitanI2c *i2c, uint8_t addr) {
3133
i2c->blocking_write_byte(OpenTitanI2c::FormatDataStart | OpenTitanI2c::FormatDataStop | (addr << 1) | 1u);
3234
return i2c_check_success(i2c);
3335
}

ports/cheriot-rtos/hal/timer.cpp

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,83 @@
1-
#include <platform-timer.hh>
1+
#include <cheri.hh>
2+
#include <stdint.h>
3+
#include <utils.hh>
24

3-
extern "C" uint64_t get_time() {
5+
#include "mphalport.h"
6+
7+
class StandardClint : private utils::NoCopyNoMove
8+
{
9+
public:
10+
/**
11+
* Initialise the interface.
12+
*/
13+
static void init() {
14+
// This needs to be csr_read(mhartid) if we support multicore
15+
// systems, but we don't plan to any time soon.
16+
constexpr uint32_t HartId = 0;
17+
18+
auto setField = [&](auto &field, size_t offset, size_t size) {
19+
CHERI::Capability capability{MMIO_CAPABILITY(uint32_t, clint)};
20+
capability.address() += offset;
21+
capability.bounds() = size;
22+
field = capability;
23+
};
24+
setField(pmtimer, StandardClint::ClintMtime, 2 * sizeof(uint32_t));
25+
setField(pmtimercmp,
26+
StandardClint::ClintMtimecmp + HartId * 8,
27+
2 * sizeof(uint32_t));
28+
}
29+
30+
static uint64_t time() {
31+
// The timer is little endian, so the high 32 bits are after the low 32
32+
// bits. We can't do atomic 64-bit loads and so we have to read these
33+
// separately.
34+
volatile uint32_t *timerHigh = pmtimer + 1;
35+
uint32_t timeLow, timeHigh;
36+
37+
// Read the current time. Loop until the high 32 bits are stable.
38+
do
39+
{
40+
timeHigh = *timerHigh;
41+
timeLow = *pmtimer;
42+
} while (timeHigh != *timerHigh);
43+
return (uint64_t(timeHigh) << 32) | timeLow;
44+
}
45+
46+
private:
47+
#ifdef IBEX_SAFE
48+
/**
49+
* The Ibex-SAFE platform doesn't implement a complete CLINT, only the
50+
* timer part (which is all that we use). Its offsets within the CLINT
51+
* region are different.
52+
*/
53+
static constexpr size_t ClintMtime = 0x10;
54+
static constexpr size_t ClintMtimecmp = 0x18;
55+
#else
56+
/**
57+
* The standard RISC-V CLINT is a large memory-mapped device and places the
58+
* timers a long way in.
59+
*/
60+
static constexpr size_t ClintMtimecmp = 0x4000U;
61+
static constexpr size_t ClintMtime = 0xbff8U;
62+
#endif
63+
64+
static inline volatile uint32_t *pmtimercmp;
65+
static inline volatile uint32_t *pmtimer;
66+
};
67+
68+
using TimerCore = StandardClint;
69+
70+
71+
uint64_t MP_HAL_FUNC get_time() {
472
StandardClint::init();
573
return StandardClint::time();
674
}
775

8-
// extern "C" void set_next(uint64_t next_time) {
76+
// void MP_HAL_FUNC set_next(uint64_t next_time) {
977
// StandardClint::init();
1078
// StandardClint::setnext(next_time);
1179
// }
1280

13-
// extern "C" void clear() {
81+
// void MP_HAL_FUNC clear() {
1482
// StandardClient::clear();
1583
// }

ports/cheriot-rtos/hal/timer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "py/obj.h"
2+
#include "mphalport.h"
23

34
#define CLOCK_FREQ_KHZ (50000)
45
#define MS_TO_CLOCK_CYCLES(x) (x * CLOCK_FREQ_KHZ) // clock 50mHz
56

6-
extern "C" uint64_t get_time();
7+
uint64_t MP_HAL_FUNC get_time();

ports/cheriot-rtos/hal/uart.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
#include <platform-uart.hh>
22

3+
#include "mphalport.h"
34
#include "timer.h"
45

5-
extern "C" uint8_t uart_get_rx_level(volatile OpenTitanUart<115'200> *block) {
6+
uint8_t MP_HAL_FUNC uart_get_rx_level(volatile OpenTitanUart *block) {
67
return block->receive_fifo_level();
78
}
89

9-
extern "C" uint8_t uart_get_tx_level(volatile OpenTitanUart<115'200> *block) {
10+
uint8_t MP_HAL_FUNC uart_get_tx_level(volatile OpenTitanUart *block) {
1011
return block->transmit_fifo_level();
1112
}
1213

13-
extern "C" bool uart_is_readable(volatile OpenTitanUart<115'200> *block) {
14+
bool MP_HAL_FUNC uart_is_readable(volatile OpenTitanUart *block) {
1415
return block->can_read();
1516
}
1617

17-
extern "C" bool uart_is_writable(volatile OpenTitanUart<115'200> *block) {
18+
bool MP_HAL_FUNC uart_is_writable(volatile OpenTitanUart *block) {
1819
return block->can_write();
1920
}
2021

21-
extern "C" bool uart_timeout_read(volatile OpenTitanUart<115'200> *block, uint8_t *out, uint32_t timeout_ms) {
22+
bool MP_HAL_FUNC uart_timeout_read(volatile OpenTitanUart *block, uint8_t *out, uint32_t timeout_ms) {
2223
uint32_t t_end = get_time() + MS_TO_CLOCK_CYCLES(timeout_ms);
2324

2425
while (!block->can_read()) {
@@ -27,14 +28,14 @@ extern "C" bool uart_timeout_read(volatile OpenTitanUart<115'200> *block, uint8_
2728
}
2829
}
2930

30-
*out = block->rData;
31+
*out = block->readData;
3132
return true;
3233
}
3334

34-
extern "C" void uart_blocking_write(volatile OpenTitanUart<115'200> *block, uint8_t data) {
35+
void MP_HAL_FUNC uart_blocking_write(volatile OpenTitanUart *block, uint8_t data) {
3536
block->blocking_write(data);
3637
}
3738

38-
extern "C" void uart_init(volatile OpenTitanUart<115'200> *block, uint32_t baudrate) {
39+
void MP_HAL_FUNC uart_init(volatile OpenTitanUart *block, uint32_t baudrate) {
3940
block->init(baudrate);
4041
}

ports/cheriot-rtos/machine_i2c.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,29 @@
44
#include "py/runtime.h"
55
#include "extmod/modmachine.h"
66

7-
typedef struct OpenTitanI2c open_titan_i2c_t;
7+
#include "mphalport.h"
8+
9+
#define I2C_DEFAULT_FREQ (400000)
10+
11+
#define SPI_0_ADDR (0x80200000)
12+
#define SPI_1_ADDR (0x80201000)
813

9-
extern void i2c_setup(volatile open_titan_i2c_t *i2c, uint32_t freq_kHz);
10-
extern bool i2c_send_address(volatile open_titan_i2c_t *i2c, uint8_t addr);
11-
extern bool i2c_blocking_read(volatile open_titan_i2c_t *i2c, uint8_t addr, uint8_t *buf, uint32_t len);
12-
extern bool i2c_blocking_write(volatile open_titan_i2c_t *i2c, uint8_t addr, uint8_t *buf, uint32_t len, bool skipStop);
1314

1415
typedef struct _machine_i2c_obj_t {
1516
mp_obj_base_t base;
1617
volatile open_titan_i2c_t *i2c_block;
1718
} machine_i2c_obj_t;
1819

1920

20-
#define I2C_DEFAULT_FREQ (400000)
21-
22-
#define SPI_BLOCK_0 (0x80200000)
23-
#define SPI_BLOCK_1 (0x80201000)
24-
2521
static void machine_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
2622
machine_i2c_obj_t *self = (machine_i2c_obj_t *)MP_OBJ_TO_PTR(self_in);
2723
const char *name;
2824

2925
switch ((ptraddr_t)self->i2c_block) {
30-
case SPI_BLOCK_0:
26+
case SPI_0_ADDR:
3127
name = "0";
3228
break;
33-
case SPI_BLOCK_1:
29+
case SPI_1_ADDR:
3430
name = "1";
3531
break;
3632
default:

ports/cheriot-rtos/machine_pin.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
#include "py/obj.h"
55
#include "py/runtime.h"
66

7-
typedef struct {
7+
#define GPIO_GPIO_ADDR (0x80000000)
8+
#define GPIO_RPI_ADDR (0x80006000)
9+
#define GPIO_ARDUINO_ADDR (0x80007000)
10+
#define GPIO_PMOD_ADDR (0x80008000)
11+
12+
typedef struct _gpio_block_t {
813
uint32_t output;
914
uint32_t input;
1015
uint32_t debounced_input;
@@ -44,8 +49,6 @@ static uint32_t set_pin_enable(uint32_t block, uint32_t pin, bool value) {
4449
}
4550

4651
volatile gpio_block_t *get_port(const char *drv_name) {
47-
// !! MMIO_CAPABILITY names were custom hard-coded into the boards/sonata.json
48-
// !! file since the headers are currently out of date.
4952
switch (drv_name[0]) {
5053
case 'g':
5154
if (strcmp(drv_name, "gpio") == 0) {
@@ -226,13 +229,13 @@ static void machine_pin_print(const mp_print_t *print, mp_obj_t self_in,
226229
const char *name_str;
227230

228231
switch ((ptraddr_t)self->port) {
229-
case 0x80000000:
232+
case GPIO_GPIO_ADDR:
230233
name_str = "gpio";
231-
case 0x80006000:
234+
case GPIO_RPI_ADDR:
232235
name_str = "rpi";
233-
case 0x80007000:
236+
case GPIO_ARDUINO_ADDR:
234237
name_str = "arduino";
235-
case 0x80008000:
238+
case GPIO_PMOD_ADDR:
236239
name_str = "pmod";
237240
default:
238241
name_str = "Unknown port";
@@ -244,8 +247,7 @@ static void machine_pin_print(const mp_print_t *print, mp_obj_t self_in,
244247

245248
static mp_obj_t machine_pin_toggle(mp_obj_t self_in) {
246249
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
247-
// if (self->mode == MACHINE_PIN_MODE_IN) {
248-
// }
250+
// if (self->mode == MACHINE_PIN_MODE_IN) {}
249251
if (self->mode == MACHINE_PIN_MODE_OUT) {
250252
self->port->output = set_pin_value(self->port->output, self->pin, !GET_BUFFER(self));
251253
} else if (self->mode == MACHINE_PIN_MODE_OPEN_DRAIN) {

ports/cheriot-rtos/machine_spi.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#define DEFAULT_SPI_BITS (8)
1414
#define DEFAULT_SPI_FIRSTBIT (SPI_MSB_FIRST)
1515

16+
#define SPI_0_ADDR (0x80300000)
17+
#define SPI_1_ADDR (0x80301000)
18+
#define SPI_2_ADDR (0x80302000)
1619
typedef struct _spi_block_t {
1720
uint32_t interrupt_state;
1821
uint32_t interrupt_enable;
@@ -91,13 +94,13 @@ static void machine_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
9194
const char *name;
9295

9396
switch ((uint32_t)self->spi_block) {
94-
case 2150629376:
97+
case SPI_0_ADDR:
9598
name = "Flash";
9699
break;
97-
case 2150633472:
100+
case SPI_1_ADDR:
98101
name = "LCD";
99102
break;
100-
case 2150637568:
103+
case SPI_2_ADDR:
101104
name = "Ethernet";
102105
break;
103106
default:

0 commit comments

Comments
 (0)