From b1c3ee27894d33d9fcfca4ea4d0ccfb6d4cfc83e Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Fri, 16 Mar 2018 14:15:39 +0100
Subject: fixed race conditions

---
 code/fe310/eos/Makefile     |  4 +++-
 code/fe310/eos/event.c      |  9 ++++++--
 code/fe310/eos/i2s.c        | 53 +++++++++++++++++++++++++++++++++++----------
 code/fe310/eos/i2s_def.h    |  2 ++
 code/fe310/eos/interrupt.c  |  6 +++++
 code/fe310/eos/net.c        |  4 +++-
 code/fe310/eos/timer.c      |  5 ++++-
 code/fe310/eos/trap_entry.S | 14 ++++++++----
 8 files changed, 76 insertions(+), 21 deletions(-)

diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile
index 6f43615..66c7d6a 100644
--- a/code/fe310/eos/Makefile
+++ b/code/fe310/eos/Makefile
@@ -1,9 +1,11 @@
+include ../../ecp/Makefile.platform
+
 FE310_HOME = /opt/my/freedom-e-sdk
 
 CC = $(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc
 AR = $(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-ar
 
-CFLAGS = -O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -DECP_DEBUG -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../..
+CFLAGS = $(CFLAGS_PL) -I../..
  
 obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o net.o ecp.o
 
diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c
index a1cf591..127e45a 100644
--- a/code/fe310/eos/event.c
+++ b/code/fe310/eos/event.c
@@ -26,11 +26,16 @@ void eos_evtq_init(void) {
 }
 
 int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len) {
-    return eos_msgq_push(&_eos_event_q, cmd, buffer, len);
+    clear_csr(mstatus, MSTATUS_MIE);
+    int ret = eos_msgq_push(&_eos_event_q, cmd, buffer, len);
+    set_csr(mstatus, MSTATUS_MIE);
+    return ret;
 }
 
 void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len) {
+    clear_csr(mstatus, MSTATUS_MIE);
     eos_msgq_pop(&_eos_event_q, cmd, buffer, len);
+    set_csr(mstatus, MSTATUS_MIE);
 }
 
 void eos_evtq_bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) {
@@ -71,7 +76,7 @@ void eos_evtq_loop(void) {
 
     while(foo) {
         clear_csr(mstatus, MSTATUS_MIE);
-        eos_evtq_pop(&cmd, &buffer, &len);
+        eos_msgq_pop(&_eos_event_q, &cmd, &buffer, &len);
         if (cmd) {
             set_csr(mstatus, MSTATUS_MIE);
             eos_evtq_handle(cmd, buffer, len);
diff --git a/code/fe310/eos/i2s.c b/code/fe310/eos/i2s.c
index 98e2ffa..64152dd 100644
--- a/code/fe310/eos/i2s.c
+++ b/code/fe310/eos/i2s.c
@@ -17,10 +17,13 @@
 
 EOSABuf _eos_i2s_mic_buf;
 EOSABuf _eos_i2s_spk_buf;
-uint16_t _eos_i2s_mic_wm;
-uint16_t _eos_i2s_spk_wm;
-uint32_t _eos_i2s_ck_period;
+uint32_t _eos_i2s_ck_period = 0;
+uint32_t _eos_i2s_mic_wm = 0;
+uint32_t _eos_i2s_spk_wm = 0;
 uint32_t _eos_i2s_mic_volume = 3;
+uint32_t _eos_i2s_spk_volume = 3;
+uint32_t _eos_i2s_mic_rd = 1;
+uint32_t _eos_i2s_spk_wr = 1;
 static eos_evt_fptr_t evt_handler[I2S_MAX_HANDLER];
 
 static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) {
@@ -109,7 +112,7 @@ void eos_i2s_init(void) {
     I2S_PWM_REG_CK(PWM_COUNT)   = 0;
     I2S_PWM_REG_CK(PWM_CMP0)    = _eos_i2s_ck_period - 1;
     I2S_PWM_REG_CK(PWM_CMP1)    = I2S_PWM_REG_CK(PWM_CMP0) / 2;
-    I2S_PWM_REG_CK(PWM_CMP2)    = I2S_PWM_REG_CK(PWM_CMP0) / 4;
+    I2S_PWM_REG_CK(PWM_CMP2)    = I2S_PWM_REG_CK(PWM_CMP0) / 2;
 
     I2S_PWM_REG_WS(PWM_CFG)     = 0;
     I2S_PWM_REG_WS(PWM_COUNT)   = 0;
@@ -176,15 +179,28 @@ uint16_t eos_i2s_mic_len(void) {
 }
 
 uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) {
-    clear_csr(mstatus, MSTATUS_MIE);
-    uint16_t ret = _abuf_read(&_eos_i2s_mic_buf, sample, ssize);
-    set_csr(mstatus, MSTATUS_MIE);
-    return ret;
+    int i;
+    uint16_t _ssize = 0;
+    
+    for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) {
+        clear_csr(mstatus, MSTATUS_MIE);
+        _ssize += _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK);
+        if ((ssize == _ssize) || (_ssize != (i+1)*I2S_ABUF_SIZE_CHUNK)) _eos_i2s_mic_rd = 1;
+        set_csr(mstatus, MSTATUS_MIE);
+    }
+    if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) {
+        clear_csr(mstatus, MSTATUS_MIE);
+        _ssize += _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize);
+        _eos_i2s_mic_rd = 1;
+        set_csr(mstatus, MSTATUS_MIE);
+    }
+    return _ssize;
 }
 
 int eos_i2s_mic_pop(uint8_t *sample) {
     clear_csr(mstatus, MSTATUS_MIE);
     int ret = _abuf_pop(&_eos_i2s_mic_buf, sample);
+    _eos_i2s_mic_rd = 1;
     set_csr(mstatus, MSTATUS_MIE);
     return ret;
 }
@@ -197,15 +213,28 @@ uint16_t eos_i2s_spk_len(void) {
 }
 
 uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) {
-    clear_csr(mstatus, MSTATUS_MIE);
-    uint16_t ret = _abuf_write(&_eos_i2s_spk_buf, sample, ssize);
-    set_csr(mstatus, MSTATUS_MIE);
-    return ret;
+    int i;
+    uint16_t _ssize = 0;
+    for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) {
+        clear_csr(mstatus, MSTATUS_MIE);
+        _ssize += _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK);
+        if ((ssize == _ssize) || (_ssize != (i+1)*I2S_ABUF_SIZE_CHUNK)) _eos_i2s_spk_wr = 1;
+        set_csr(mstatus, MSTATUS_MIE);
+    }
+    if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) {
+        clear_csr(mstatus, MSTATUS_MIE);
+        _ssize += _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize);
+        _eos_i2s_spk_wr = 1;
+        set_csr(mstatus, MSTATUS_MIE);
+    }
+    return _ssize;
+
 }
 
 int eos_i2s_spk_push(uint8_t sample) {
     clear_csr(mstatus, MSTATUS_MIE);
     int ret = _abuf_push(&_eos_i2s_spk_buf, sample);
+    _eos_i2s_spk_wr = 1;
     set_csr(mstatus, MSTATUS_MIE);
     return ret;
 }
diff --git a/code/fe310/eos/i2s_def.h b/code/fe310/eos/i2s_def.h
index 04e9c27..6f831e2 100644
--- a/code/fe310/eos/i2s_def.h
+++ b/code/fe310/eos/i2s_def.h
@@ -21,6 +21,8 @@
 
 #define I2S_SMPL_WIDTH          13
 
+#define I2S_ABUF_SIZE_CHUNK     64
+
 /* asm */
 #define I2S_ABUF_OFF_IDXR       0
 #define I2S_ABUF_OFF_IDXW       2
diff --git a/code/fe310/eos/interrupt.c b/code/fe310/eos/interrupt.c
index b8c6540..28bd8d1 100644
--- a/code/fe310/eos/interrupt.c
+++ b/code/fe310/eos/interrupt.c
@@ -26,6 +26,12 @@ uintptr_t eos_intr_handle(uintptr_t int_num) {
     return int_num;
 }
 
+void handle_m_ext_interrupt(void) {
+    plic_source int_num  = PLIC_claim_interrupt(&plic);
+    eos_intr_handle(int_num);
+    PLIC_complete_interrupt(&plic, int_num);
+}
+
 void eos_intr_init(void) {
     for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){
         ext_interrupt_handler[i] = NULL;
diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c
index 3339223..58bd5fd 100644
--- a/code/fe310/eos/net.c
+++ b/code/fe310/eos/net.c
@@ -26,6 +26,8 @@ static uint16_t evt_handler_wrapper_en = 0;
 static SPIBufQ spi_bufq;
 static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF];
 
+extern EOSMsgQ _eos_event_q;
+
 static int spi_bufq_push(unsigned char *buffer) {
     spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_w++)] = buffer;
     return EOS_OK;
@@ -162,7 +164,7 @@ static void spi_xchg_handler(void) {
         SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
         SPI1_REG(SPI_REG_IE) = 0x0;
         if (spi_state.cmd) {
-            int r = eos_evtq_push(EOS_EVT_NET | spi_state.cmd, spi_state.buf, spi_state.len_rx);
+            int r = eos_msgq_push(&_eos_event_q, EOS_EVT_NET | spi_state.cmd, spi_state.buf, spi_state.len_rx);
             if (r) spi_bufq_push(spi_state.buf);
         } else if ((spi_state.next_cnt || (spi_state.flags & SPI_FLAG_ONEW)) && (spi_state.next_buf == NULL)) {
             spi_state.next_buf = spi_state.buf;
diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c
index 915be6f..5e1b381 100644
--- a/code/fe310/eos/timer.c
+++ b/code/fe310/eos/timer.c
@@ -4,6 +4,7 @@
 #include "encoding.h"
 #include "platform.h"
 
+#include "msgq.h"
 #include "event.h"
 #include "timer.h"
 
@@ -14,6 +15,8 @@ static eos_timer_fptr_t timer_ext_handler = NULL;
 volatile uint64_t timer_next = 0;
 volatile uint64_t timer_next_evt = 0;
 
+extern EOSMsgQ _eos_event_q;
+
 void eos_timer_handle(void) {
     volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
     volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
@@ -28,7 +31,7 @@ void eos_timer_handle(void) {
         }
     }
     if (timer_next_evt && (timer_next_evt <= now)) {
-        eos_evtq_push(EOS_EVT_TIMER, NULL, 0);
+        eos_msgq_push(&_eos_event_q, EOS_EVT_TIMER, NULL, 0);
         timer_next_evt = 0;
     }
     *mtimecmp = (timer_next && timer_next_evt) ? MIN(timer_next, timer_next_evt) : (timer_next ? timer_next : timer_next_evt);
diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S
index 1c164d3..7d834f6 100644
--- a/code/fe310/eos/trap_entry.S
+++ b/code/fe310/eos/trap_entry.S
@@ -168,7 +168,7 @@ handler_sd:
   xori x8, x8, 0x55
   andi x8, x8, 0xff
 
-  # push to mic but
+  # push to mic buf
   la x9, _eos_i2s_mic_buf
   lhu x18, I2S_ABUF_OFF_IDXR(x9)
   lhu x19, I2S_ABUF_OFF_IDXW(x9)
@@ -186,16 +186,22 @@ handler_sd:
   addi x19, x19, 1
   sh x19, I2S_ABUF_OFF_IDXW(x9)
 
-  # push to event queue
+  # check for push to event queue
   la x9, _eos_i2s_mic_wm
-  lhu x20, 0(x9)
+  lw x20, 0(x9)
   beqz x20, handler_sd_exit
   
   la x9, _eos_i2s_mic_buf
   lhu x18, I2S_ABUF_OFF_IDXR(x9)
   sub x18, x19, x18
-  bne x18, x20, handler_sd_exit
+  blt x18, x20, handler_sd_exit
+
+  la x9, _eos_i2s_mic_rd
+  lw x18, 0(x9)
+  beqz x18, handler_sd_exit
+  sw x0, 0(x9)
 
+  # push to event queue
   la x9, _eos_event_q
   lbu x18, MSGQ_OFF_IDXR(x9)
   lbu x19, MSGQ_OFF_IDXW(x9)
-- 
cgit v1.2.3