Skip to content

Commit 9d2605d

Browse files
committed
pbio/drv: Handle cache ops for EV3 drivers
This allows the main memory to be write-back cached.
1 parent cd36c58 commit 9d2605d

File tree

5 files changed

+43
-11
lines changed

5 files changed

+43
-11
lines changed

lib/pbio/drv/block_device/block_device_ev3.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "block_device_ev3.h"
3535

3636
#include <pbdrv/block_device.h>
37+
#include <pbdrv/cache.h>
3738
#include <pbdrv/clock.h>
3839
#include <pbdrv/compiler.h>
3940
#include <pbdrv/gpio.h>
@@ -103,6 +104,10 @@ static struct {
103104
uint8_t spi_cmd_buf_tx[SPI_CMD_BUF_SZ];
104105
// This is used to hold the replies to commands to the SPI peripheral.
105106
uint8_t spi_cmd_buf_rx[SPI_CMD_BUF_SZ];
107+
// This stores the RX buffer address so that we clean the cache when DMA is complete
108+
uint32_t rx_user_buf_addr;
109+
// This stores the RX buffer size;
110+
uint32_t rx_user_buf_sz;
106111
} spi_dev;
107112

108113
static uint32_t last_spi_dma_complete_time;
@@ -114,6 +119,10 @@ static void spi_dma_complete(void) {
114119
}
115120
SPIIntDisable(SOC_SPI_0_REGS, SPI_DMA_REQUEST_ENA_INT);
116121
pbio_os_request_poll();
122+
pbdrv_cache_prepare_after_dma(spi_dev.spi_cmd_buf_rx, SPI_CMD_BUF_SZ);
123+
if (spi_dev.rx_user_buf_addr && spi_dev.rx_user_buf_sz) {
124+
pbdrv_cache_prepare_after_dma((void *)spi_dev.rx_user_buf_addr, spi_dev.rx_user_buf_sz);
125+
}
117126
last_spi_dma_complete_time = pbdrv_clock_get_ms();
118127
}
119128

@@ -351,16 +360,21 @@ static pbio_error_t spi_begin_for_flash(
351360

352361
spi_dev.status = SPI_STATUS_WAIT_RX;
353362

363+
// Prevent write to spi_dev.status from being reordered
364+
pbdrv_compiler_memory_barrier();
365+
354366
uint32_t tx = spi0_last_dat1_for_flash(cmd[0]);
355367
SPIIntEnable(SOC_SPI_0_REGS, SPI_RECV_INT);
356368
HWREG(SOC_SPI_0_REGS + SPI_SPIDAT1) = tx;
357369
} else {
358-
memcpy(&spi_dev.spi_cmd_buf_tx, cmd, cmd_len);
370+
memcpy(PBDRV_UNCACHED_ADDR(spi_dev.spi_cmd_buf_tx), cmd, cmd_len);
371+
spi_dev.rx_user_buf_addr = (uint32_t)user_data_rx;
372+
spi_dev.rx_user_buf_sz = user_data_len;
359373

360374
if (user_data_len == 0) {
361375
// Only a command, no user data
362376

363-
spi_dev.tx_last_word = spi0_last_dat1_for_flash(cmd[cmd_len - 1]);
377+
PBDRV_UNCACHED(spi_dev.tx_last_word) = spi0_last_dat1_for_flash(cmd[cmd_len - 1]);
364378

365379
// TX everything except last byte
366380
ps.p.srcAddr = (unsigned int)(&spi_dev.spi_cmd_buf_tx);
@@ -418,7 +432,8 @@ static pbio_error_t spi_begin_for_flash(
418432
edma3_set_param(EDMA3_CHA_SPI0_TX, &ps);
419433

420434
if (user_data_tx) {
421-
spi_dev.tx_last_word = spi0_last_dat1_for_flash(user_data_tx[user_data_len - 1]);
435+
pbdrv_cache_prepare_before_dma(user_data_tx, user_data_len);
436+
PBDRV_UNCACHED(spi_dev.tx_last_word) = spi0_last_dat1_for_flash(user_data_tx[user_data_len - 1]);
422437

423438
// TX all but the last byte
424439
ps.p.srcAddr = (unsigned int)(user_data_tx);
@@ -434,7 +449,7 @@ static pbio_error_t spi_begin_for_flash(
434449
ps.p.opt = EDMA3CC_OPT_TCINTEN | (EDMA3_CHA_SPI0_TX << EDMA3CC_OPT_TCC_SHIFT);
435450
edma3_set_param(127, &ps);
436451
} else {
437-
spi_dev.tx_last_word = spi0_last_dat1_for_flash(0);
452+
PBDRV_UNCACHED(spi_dev.tx_last_word) = spi0_last_dat1_for_flash(0);
438453

439454
// TX all but the last byte
440455
ps.p.srcAddr = (unsigned int)(&spi_dev.tx_dummy_byte);
@@ -487,7 +502,7 @@ static pbio_error_t spi_begin_for_flash(
487502

488503
spi_dev.status = SPI_STATUS_WAIT_TX | SPI_STATUS_WAIT_RX;
489504

490-
// TODO: eventually needs DMA cache management
505+
// Prevent write to spi_dev.status from being reordered
491506
pbdrv_compiler_memory_barrier();
492507

493508
EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_TX, EDMA3_TRIG_MODE_EVENT);
@@ -804,9 +819,14 @@ static pbio_error_t pbdrv_block_device_ev3_spi_begin_for_adc(const uint32_t *cmd
804819
ps.p.opt = EDMA3CC_OPT_TCINTEN | (EDMA3_CHA_SPI0_RX << EDMA3CC_OPT_TCC_SHIFT);
805820
edma3_set_param(EDMA3_CHA_SPI0_RX, &ps);
806821

822+
// We play dangerously and don't flush the cache for commands (since they're const)
823+
// but we do need to flush the cache for the data which is read.
824+
spi_dev.rx_user_buf_addr = (uint32_t)data;
825+
spi_dev.rx_user_buf_sz = sizeof(uint16_t) * len;
826+
807827
spi_dev.status = SPI_STATUS_WAIT_TX | SPI_STATUS_WAIT_RX;
808828

809-
// TODO: eventually needs DMA cache management
829+
// Prevent write to spi_dev.status from being reordered
810830
pbdrv_compiler_memory_barrier();
811831

812832
EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_TX, EDMA3_TRIG_MODE_EVENT);

lib/pbio/drv/display/display_ev3.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <stdio.h>
1414
#include <string.h>
1515

16+
#include <pbdrv/cache.h>
1617
#include <pbdrv/display.h>
1718
#include <pbdrv/gpio.h>
1819

@@ -363,6 +364,8 @@ void pbdrv_display_st7586s_write_data_begin(uint8_t *data, uint32_t size) {
363364
spi_status = SPI_STATUS_WAIT;
364365
pbdrv_gpio_out_low(&pin_lcd_cs);
365366

367+
pbdrv_cache_prepare_before_dma(data, size);
368+
366369
// Parameter object must be volatile since it is copied byte-by-byte in the
367370
// TI API, causing it to be optimized out.
368371
volatile EDMA3CCPaRAMEntry paramSet = {

lib/pbio/drv/uart/uart_ev3.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <contiki.h>
1515
#include <contiki-lib.h>
1616

17+
#include <pbdrv/cache.h>
1718
#include <pbdrv/uart.h>
1819

1920
#include <pbio/busy_count.h>
@@ -220,6 +221,8 @@ pbio_error_t pbdrv_uart_write_hw(pbio_os_state_t *state, pbdrv_uart_dev_t *uart,
220221
.opt = EDMA3CC_OPT_DAM | ((pdata->sys_int_uart_tx_int_id << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC) | (1 << EDMA3CC_OPT_TCINTEN_SHIFT),
221222
};
222223

224+
pbdrv_cache_prepare_before_dma(uart->write_buf, length);
225+
223226
// Save configuration and start transfer.
224227
EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pdata->sys_int_uart_tx_int_id, (EDMA3CCPaRAMEntry *)&paramSet);
225228
EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, pdata->sys_int_uart_tx_int_id, EDMA3_TRIG_MODE_EVENT);

lib/pbio/drv/usb/usb_ev3.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <string.h>
1414

1515
#include <pbdrv/bluetooth.h>
16+
#include <pbdrv/cache.h>
1617
#include <pbdrv/compiler.h>
1718
#include <pbdrv/usb.h>
1819
#include <pbio/os.h>
@@ -283,7 +284,7 @@ static uint32_t cppi_linking_ram[CPPI_DESC_COUNT];
283284

284285
// Fill in the CPPI DMA descriptor to receive a packet
285286
static void usb_setup_rx_dma_desc(void) {
286-
cppi_descriptors[CPPI_DESC_RX] = (usb_cppi_hpd_t) {
287+
PBDRV_UNCACHED(cppi_descriptors[CPPI_DESC_RX]) = (usb_cppi_hpd_t) {
287288
.word0 = {
288289
.hostPktType = CPPI_HOST_PACKET_DESCRIPTOR_TYPE,
289290
},
@@ -307,7 +308,7 @@ static void usb_setup_rx_dma_desc(void) {
307308

308309
// Fill in the CPPI DMA descriptor to send a packet
309310
static void usb_setup_tx_dma_desc(int tx_type, void *buf, uint32_t buf_len) {
310-
cppi_descriptors[tx_type] = (usb_cppi_hpd_t) {
311+
PBDRV_UNCACHED(cppi_descriptors[tx_type]) = (usb_cppi_hpd_t) {
311312
.word0 = {
312313
.hostPktType = CPPI_HOST_PACKET_DESCRIPTOR_TYPE,
313314
.pktLength = buf_len,
@@ -904,11 +905,13 @@ static pbio_error_t pbdrv_usb_ev3_process_thread(pbio_os_state_t *state, void *c
904905
// (which is technically allowed by the as-if rule).
905906
pbdrv_compiler_memory_barrier();
906907

907-
uint32_t usb_rx_sz = cppi_descriptors[CPPI_DESC_RX].word0.pktLength;
908+
uint32_t usb_rx_sz = PBDRV_UNCACHED(cppi_descriptors[CPPI_DESC_RX].word0).pktLength;
908909
pbio_pybricks_error_t result;
909910
bool usb_send_response = false;
910911
// Skip empty commands, or commands sent when previous response is still busy
911912
if (usb_rx_sz && !usb_tx_response_is_not_ready) {
913+
pbdrv_cache_prepare_after_dma(ep1_rx_buf, sizeof(ep1_rx_buf));
914+
912915
switch (ep1_rx_buf[0]) {
913916
case PBIO_PYBRICKS_OUT_EP_MSG_SUBSCRIBE:
914917
pbio_os_timer_set(&keepalive_timer, 1000);
@@ -928,6 +931,7 @@ static pbio_error_t pbdrv_usb_ev3_process_thread(pbio_os_state_t *state, void *c
928931

929932
if (usb_send_response) {
930933
usb_tx_response_is_not_ready = true;
934+
pbdrv_cache_prepare_before_dma(ep1_tx_response_buf, sizeof(ep1_tx_response_buf));
931935
usb_setup_tx_dma_desc(CPPI_DESC_TX_RESPONSE, ep1_tx_response_buf, PBIO_PYBRICKS_USB_MESSAGE_SIZE(sizeof(uint32_t)));
932936
}
933937

@@ -944,6 +948,7 @@ static pbio_error_t pbdrv_usb_ev3_process_thread(pbio_os_state_t *state, void *c
944948
uint32_t usb_status_sz = PBIO_PYBRICKS_USB_MESSAGE_SIZE(pbsys_status_get_status_report(&ep1_tx_status_buf[1]));
945949

946950
usb_tx_status_is_not_ready = true;
951+
pbdrv_cache_prepare_before_dma(ep1_tx_status_buf, sizeof(ep1_tx_status_buf));
947952
usb_setup_tx_dma_desc(CPPI_DESC_TX_STATUS, ep1_tx_status_buf, usb_status_sz);
948953

949954
prev_status_flags = new_status_flags;
@@ -1124,6 +1129,7 @@ pbio_error_t pbdrv_usb_stdout_tx(const uint8_t *data, uint32_t *size) {
11241129
memcpy(ptr, data, *size);
11251130

11261131
usb_tx_stdout_is_not_ready = true;
1132+
pbdrv_cache_prepare_before_dma(ep1_tx_stdout_buf, sizeof(ep1_tx_stdout_buf));
11271133
usb_setup_tx_dma_desc(CPPI_DESC_TX_STDOUT, ep1_tx_stdout_buf, 2 + *size);
11281134

11291135
return PBIO_SUCCESS;

lib/pbio/platform/ev3/platform.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,8 @@ static void mmu_init(void) {
721721
// Off-chip main DDR RAM
722722
for (unsigned int i = 0; i < SYSTEM_RAM_SZ_MB; i++) {
723723
uint32_t addr = 0xC0000000 + i * MMU_SECTION_SZ;
724-
// TODO: Enable caching once DMA code is upgraded to handle cache
725-
l1_page_table[addr >> MMU_SECTION_SHIFT] = MMU_L1_SECTION(addr, 0, 1, 0, 0);
724+
// Enable write-back caching
725+
l1_page_table[addr >> MMU_SECTION_SHIFT] = MMU_L1_SECTION(addr, 0, 1, 1, 1);
726726
}
727727
// Off-chip main DDR RAM, uncacheable mirror @ 0xD0000000
728728
for (unsigned int i = 0; i < SYSTEM_RAM_SZ_MB; i++) {

0 commit comments

Comments
 (0)