From 4b655364d426f8429b063d9746c754beca6f7d1f Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 14 Mar 2018 18:31:22 +0100 Subject: fixed concerning new asm trap entry --- code/fe310/eos/Makefile | 12 +-- code/fe310/eos/ecp.c | 22 ++--- code/fe310/eos/eos.h | 1 + code/fe310/eos/event.c | 82 +++++++++------- code/fe310/eos/event.h | 16 ++- code/fe310/eos/interrupt.c | 33 +++++-- code/fe310/eos/interrupt.h | 6 +- code/fe310/eos/net.c | 240 ++++++++++++++++++++++++++------------------- code/fe310/eos/net.h | 4 +- code/fe310/eos/spi.h | 22 ++++- code/fe310/eos/timer.c | 21 ++-- 11 files changed, 269 insertions(+), 190 deletions(-) (limited to 'code') diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile index 573bca7..43313fd 100644 --- a/code/fe310/eos/Makefile +++ b/code/fe310/eos/Makefile @@ -1,11 +1,11 @@ -FE310_HOME=/opt/my/freedom-e-sdk +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 +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 -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../.. - -obj = msgq.o event.o interrupt.o timer.o net.o eos.o ecp.o +CFLAGS = -O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../.. + +obj = eos.o msgq.o event.o interrupt.o timer.o net.o ecp.o %.o: %.c %.h diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c index b50e0d7..9301555 100644 --- a/code/fe310/eos/ecp.c +++ b/code/fe310/eos/ecp.c @@ -12,20 +12,11 @@ static ECPSocket *_sock = NULL; -static unsigned char net_buf_reserved = 0; static void timer_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { - int ok = eos_net_acquire(net_buf_reserved); - if (ok) { - ecp_cts_t next = ecp_timer_exe(_sock); - if (next) { - uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; - eos_timer_set(tick, 1); - } - eos_net_release(1); - net_buf_reserved = 0; - } else { - net_buf_reserved = 1; - eos_evtq_push(EOS_EVT_TIMER, NULL, 0); + ecp_cts_t next = ecp_timer_exe(_sock); + if (next) { + uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; + eos_timer_set(tick, 1); } } @@ -60,9 +51,8 @@ int ecp_init(ECPContext *ctx) { rv = ecp_ctx_create_vconn(ctx); if (rv) return rv; - eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler); - eos_evtq_set_handler(EOS_EVT_MASK_NET | EOS_NET_CMD_PKT, packet_handler); - + eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler, EOS_EVT_FLAG_WRAP); + eos_net_set_handler(EOS_NET_CMD_PKT, packet_handler, 0); return ECP_OK; } diff --git a/code/fe310/eos/eos.h b/code/fe310/eos/eos.h index 938030e..8ca73e5 100644 --- a/code/fe310/eos/eos.h +++ b/code/fe310/eos/eos.h @@ -1,5 +1,6 @@ #define EOS_OK 0 #define EOS_ERR_Q_FULL -10 +#define EOS_ERR_Q_EMPTY -11 void eos_init(void); void eos_start(void); diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c index 25f1fa1..a1cf591 100644 --- a/code/fe310/eos/event.c +++ b/code/fe310/eos/event.c @@ -1,56 +1,65 @@ +#include #include +#include #include "encoding.h" #include "platform.h" -#include "eos.h" -#include "msgq.h" #include "net.h" -#include "timer.h" +#include "msgq.h" #include "event.h" -static EOSMsgQ event_q; +EOSMsgQ _eos_event_q; static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q]; -static eos_evt_fptr_t evt_net_handler[EOS_NET_MAX_CMD]; -static eos_evt_fptr_t evt_timer_handler = NULL; -static eos_evt_fptr_t evt_ui_handler = NULL; - -static void bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { - printf("bad handler: %d\n", cmd); -} +static eos_evt_fptr_t evt_handler[EOS_EVT_MAX_EVT]; +static uint16_t evt_handler_wrapper_acq = 0; +static uint16_t evt_handler_wrapper_en = 0; void eos_evtq_init(void) { int i; - for (i=0; i> 4) > EOS_EVT_MAX_EVT) { + eos_evtq_bad_handler(cmd, buffer, len); + } else { + unsigned char idx = ((cmd & EOS_EVT_MASK) >> 4) - 1; + uint16_t flag = (uint16_t)1 << idx; + if (flag & evt_handler_wrapper_en) { + eos_evtq_handler_wrapper(cmd, buffer, len, &evt_handler_wrapper_acq, flag, evt_handler[idx]); } else { - bad_handler(cmd, buffer, len); + evt_handler[idx](cmd, buffer, len); } - } else if (cmd == EOS_EVT_TIMER) { - evt_timer_handler(cmd, buffer, len); - } else if (cmd == EOS_EVT_UI) { - evt_ui_handler(cmd, buffer, len); } } @@ -58,7 +67,7 @@ void eos_evtq_loop(void) { unsigned char cmd; unsigned char *buffer; uint16_t len; - volatile int foo = 1; + int foo = 1; while(foo) { clear_csr(mstatus, MSTATUS_MIE); @@ -68,18 +77,17 @@ void eos_evtq_loop(void) { eos_evtq_handle(cmd, buffer, len); clear_csr(mstatus, MSTATUS_MIE); } else { - // asm volatile ("wfi"); + asm volatile ("wfi"); } set_csr(mstatus, MSTATUS_MIE); } } -void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler) { - if (cmd & EOS_EVT_MASK_NET) { - evt_net_handler[cmd & ~EOS_EVT_MASK_NET] = handler; - } else if (cmd == EOS_EVT_TIMER) { - evt_timer_handler = handler; - } else if (cmd == EOS_EVT_UI) { - evt_ui_handler = handler; +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags) { + if (flags & EOS_EVT_FLAG_WRAP) { + uint16_t flag = (uint16_t)1 << (((cmd & EOS_EVT_MASK) >> 4) - 1); + evt_handler_wrapper_en |= flag; } -} \ No newline at end of file + evt_handler[((cmd & EOS_EVT_MASK) >> 4) - 1] = handler; +} + diff --git a/code/fe310/eos/event.h b/code/fe310/eos/event.h index 21079b4..ce71c0b 100644 --- a/code/fe310/eos/event.h +++ b/code/fe310/eos/event.h @@ -1,9 +1,15 @@ #include -#define EOS_EVT_MASK_NET 0x80 -#define EOS_EVT_TIMER 0x01 -#define EOS_EVT_UI 0x02 +#define EOS_EVT_FLAG_WRAP 0x1 +#define EOS_EVT_NET 0x10 +#define EOS_EVT_TIMER 0x20 +#define EOS_EVT_AUDIO 0x30 +#define EOS_EVT_UI 0x40 + +#define EOS_EVT_MASK 0xF0 + +#define EOS_EVT_MAX_EVT 4 #define EOS_EVT_SIZE_Q 4 typedef void (*eos_evt_fptr_t) (unsigned char, unsigned char *, uint16_t); @@ -11,6 +17,8 @@ typedef void (*eos_evt_fptr_t) (unsigned char, unsigned char *, uint16_t); void eos_evtq_init(void); int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len); void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len); +void eos_evtq_bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_evtq_handler_wrapper(unsigned char cmd, unsigned char *buffer, uint16_t len, uint16_t *flags_acq, uint16_t flag, eos_evt_fptr_t f); void eos_evtq_handle(unsigned char cmd, unsigned char *buffer, uint16_t len); void eos_evtq_loop(void); -void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler); \ No newline at end of file +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags); diff --git a/code/fe310/eos/interrupt.c b/code/fe310/eos/interrupt.c index def1a24..77ab6d5 100644 --- a/code/fe310/eos/interrupt.c +++ b/code/fe310/eos/interrupt.c @@ -1,6 +1,4 @@ -#include #include -#include #include #include @@ -15,15 +13,16 @@ static plic_instance_t plic; static eos_intr_fptr_t ext_interrupt_handler[PLIC_NUM_INTERRUPTS]; -void handle_m_ext_interrupt(void) { - plic_source int_num = PLIC_claim_interrupt(&plic); - if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num])) { +uintptr_t eos_intr_handle(uintptr_t int_num) { + // plic_source int_num = PLIC_claim_interrupt(&plic); + if ((int_num >=1) && (int_num < PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num])) { ext_interrupt_handler[int_num](); } else { - printf("handle_m_ext_interrupt error\n\n"); - exit(1 + (uintptr_t) int_num); + write(1, "error\n", 6); + exit(int_num); } - PLIC_complete_interrupt(&plic, int_num); + // PLIC_complete_interrupt(&plic, int_num); + return int_num; } void eos_intr_init(void) { @@ -46,8 +45,24 @@ void eos_intr_init(void) { set_csr(mstatus, MSTATUS_MIE); } -void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) { +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) { ext_interrupt_handler[int_num] = handler; + PLIC_set_priority(&plic, int_num, priority); PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_set_priority(uint8_t int_num, uint8_t priority) { PLIC_set_priority(&plic, int_num, priority); } + +void eos_intr_enable(uint8_t int_num) { + PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_disable(uint8_t int_num) { + PLIC_disable_interrupt(&plic, int_num); +} + +void eos_intr_mask(uint8_t priority) { + PLIC_set_threshold(&plic, priority); +} diff --git a/code/fe310/eos/interrupt.h b/code/fe310/eos/interrupt.h index 7ef81b8..3ccfb21 100644 --- a/code/fe310/eos/interrupt.h +++ b/code/fe310/eos/interrupt.h @@ -5,4 +5,8 @@ typedef void (*eos_intr_fptr_t) (void); void eos_intr_init(void); -void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler); +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler); +void eos_intr_set_priority(uint8_t int_num, uint8_t priority); +void eos_intr_enable(uint8_t int_num); +void eos_intr_disable(uint8_t int_num); +void eos_intr_mask(uint8_t priority); \ No newline at end of file diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c index 080da72..4588485 100644 --- a/code/fe310/eos/net.c +++ b/code/fe310/eos/net.c @@ -10,7 +10,6 @@ #include "eos.h" #include "msgq.h" -#include "event.h" #include "interrupt.h" #include "net.h" #include "spi.h" @@ -19,18 +18,18 @@ #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) #define SPI_BUFQ_IDX_MASK(IDX) ((IDX) & (SPI_SIZE_BUFQ - 1)) -static volatile uint8_t spi_res = 0; -static volatile uint8_t spi_res_next = 0; -static volatile unsigned char *spi_res_buf = NULL; - static EOSMsgQ spi_sndq; static EOSMsgItem spi_sndq_array[SPI_SIZE_BUFQ]; +static eos_evt_fptr_t evt_handler[EOS_NET_MAX_CMD]; +static uint16_t evt_handler_wrapper_acq = 0; +static uint16_t evt_handler_wrapper_en = 0; static SPIBufQ spi_bufq; static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF]; static int spi_bufq_push(unsigned char *buffer) { spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_w++)] = buffer; + return EOS_OK; } static unsigned char *spi_bufq_pop(void) { @@ -38,45 +37,43 @@ static unsigned char *spi_bufq_pop(void) { return spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_r++)]; } -static volatile uint8_t spi_rdy = 0; -static volatile uint8_t spi_cts = 0; -static volatile uint8_t spi_rts = 0; -static SPIBuffer spi_buffer; +static SPIState spi_state; static void spi_reset(void) { int i; - volatile uint32_t r; - spi_cts = 0; + spi_state.flags &= ~SPI_FLAG_CTS; + spi_state.flags |= SPI_FLAG_RST; // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); SPI1_REG(SPI_REG_TXFIFO) = 0; - while ((r = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; + SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(0); + SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; } static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) { - volatile uint32_t r1, r2; - - spi_cts = 0; - spi_buffer.buffer = buffer; - spi_buffer.len_rx = 0; - spi_buffer.idx_tx = 0; - spi_buffer.idx_rx = 0; - - if (spi_res_buf == NULL) { + spi_state.flags &= ~SPI_FLAG_CTS; + spi_state.flags |= SPI_FLAG_INIT; + if (spi_state.next_buf == NULL) { if (cmd & EOS_NET_CMD_FLAG_ONEW) { - spi_res_next = 1; - } else if (spi_res) { + spi_state.flags |= SPI_FLAG_ONEW; + } else if (spi_state.next_cnt) { cmd |= EOS_NET_CMD_FLAG_ONEW; } } else if (cmd & EOS_NET_CMD_FLAG_ONEW) { cmd &= ~EOS_NET_CMD_FLAG_ONEW; } + spi_state.cmd = cmd; + spi_state.buf = buffer; + spi_state.len_tx = len; + spi_state.len_rx = 0; + spi_state.idx_tx = 0; + spi_state.idx_rx = 0; + // before starting a transaction, set SPI peripheral to desired mode SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; @@ -86,30 +83,8 @@ static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) { while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); SPI1_REG(SPI_REG_TXFIFO) = len & 0xFF; - while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - while ((r2 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - - if (cmd & EOS_NET_CMD_FLAG_ONEW) { - r1 = 0; - r2 = 0; - } - - spi_buffer.cmd = ((r1 & 0xFF) >> 3); - spi_buffer.len_rx = ((r1 & 0x07) << 8); - - spi_buffer.len_rx |= (r2 & 0xFF); - spi_buffer.len = MAX(len, spi_buffer.len_rx); - - // Work around esp32 bug - if (spi_buffer.len < 6) { - spi_buffer.len = 6; - } else if ((spi_buffer.len + 2) % 4 != 0) { - spi_buffer.len = ((spi_buffer.len + 2)/4 + 1) * 4 - 2; - } - - SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_CHUNK/2); - SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(SPI_SIZE_CHUNK - 1); - SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM | SPI_IP_RXWM; + SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(1); + SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; } static int spi_xchg_next(unsigned char *_buffer) { @@ -120,7 +95,7 @@ static int spi_xchg_next(unsigned char *_buffer) { eos_msgq_pop(&spi_sndq, &cmd, &buffer, &len); if (cmd) { spi_xchg(cmd, buffer, len); - } else if (spi_rts) { + } else if (spi_state.flags & SPI_FLAG_RTS) { if (_buffer == NULL) _buffer = spi_bufq_pop(); if (_buffer) { spi_xchg(0, _buffer, 0); @@ -131,47 +106,82 @@ static int spi_xchg_next(unsigned char *_buffer) { } static void spi_xchg_handler(void) { + volatile uint32_t r1, r2; int i; + if (spi_state.flags & SPI_FLAG_RST) { + while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; + SPI1_REG(SPI_REG_IE) = 0x0; + spi_state.flags &= ~SPI_FLAG_RST; + + return; + } else if (spi_state.flags & SPI_FLAG_INIT) { + while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + while ((r2 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + + if (spi_state.cmd & EOS_NET_CMD_FLAG_ONEW) { + r1 = 0; + r2 = 0; + } + + spi_state.cmd = ((r1 & 0xFF) >> 3); + spi_state.len_rx = ((r1 & 0x07) << 8); + spi_state.len_rx |= (r2 & 0xFF); + spi_state.len = MAX(spi_state.len_tx, spi_state.len_rx); + + // Work around esp32 bug + if (spi_state.len < 6) { + spi_state.len = 6; + } else if ((spi_state.len + 2) % 4 != 0) { + spi_state.len = ((spi_state.len + 2)/4 + 1) * 4 - 2; + } + + SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_CHUNK/2); + SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(SPI_SIZE_CHUNK - 1); + SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM | SPI_IP_RXWM; + spi_state.flags &= ~SPI_FLAG_INIT; + } + if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) { - uint16_t sz_chunk = MIN(spi_buffer.len - spi_buffer.idx_tx, SPI_SIZE_CHUNK); + uint16_t sz_chunk = MIN(spi_state.len - spi_state.idx_tx, SPI_SIZE_CHUNK); for (i=0; i EOS_NET_MAX_CMD) { + eos_evtq_bad_handler(cmd, buffer, len); + } else { + unsigned char idx = (cmd & ~EOS_EVT_MASK) - 1; + uint16_t flag = (uint16_t)1 << idx; + if (flag & evt_handler_wrapper_en) { + eos_evtq_handler_wrapper(cmd, buffer, len, &evt_handler_wrapper_acq, flag, evt_handler[idx]); + } else { + evt_handler[idx](cmd, buffer, len); + } } } + void eos_net_init(void) { int i; @@ -201,23 +226,30 @@ void eos_net_init(void) { for (i=0; i +#include "event.h" #define EOS_NET_CMD_FLAG_ONEW 0x10 @@ -7,11 +8,12 @@ #define EOS_NET_CMD_SCAN 3 #define EOS_NET_CMD_PKT 4 -#define EOS_NET_MAX_CMD 8 +#define EOS_NET_MAX_CMD 4 void eos_net_init(void); void eos_net_start(uint32_t sckdiv); void eos_net_stop(void); +void eos_net_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags); int eos_net_reserve(unsigned char *buffer); int eos_net_acquire(unsigned char reserved); int eos_net_release(unsigned char reserved); diff --git a/code/fe310/eos/spi.h b/code/fe310/eos/spi.h index 7e281b8..55ff846 100644 --- a/code/fe310/eos/spi.h +++ b/code/fe310/eos/spi.h @@ -10,19 +10,31 @@ #define SPI_SIZE_BUF 1500 #define SPI_SIZE_CHUNK 4 -#define SPI_SIZE_BUFQ 4 +#define SPI_SIZE_BUFQ 2 #define SPI_GPIO_RTS_OFFSET PIN_8_OFFSET #define SPI_GPIO_CTS_OFFSET PIN_7_OFFSET #define SPI_IOF_MASK (((uint32_t)1 << IOF_SPI1_SCK) | ((uint32_t)1 << IOF_SPI1_MOSI) | ((uint32_t)1 << IOF_SPI1_MISO)) -typedef struct SPIBuffer { - unsigned char cmd; - unsigned char *buffer; + +#define SPI_FLAG_RDY 0x01 +#define SPI_FLAG_RST 0x02 +#define SPI_FLAG_RTS 0x04 +#define SPI_FLAG_CTS 0x08 +#define SPI_FLAG_INIT 0x10 +#define SPI_FLAG_ONEW 0x20 + +typedef struct SPIState { + uint8_t flags; uint16_t len; + uint16_t len_tx; uint16_t len_rx; uint16_t idx_tx; uint16_t idx_rx; -} SPIBuffer; + unsigned char cmd; + unsigned char *buf; + uint8_t next_cnt; + unsigned char *next_buf; +} SPIState; typedef struct SPIBufQ { uint8_t idx_r; diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c index 0a07ed9..9e2ae9d 100644 --- a/code/fe310/eos/timer.c +++ b/code/fe310/eos/timer.c @@ -13,7 +13,7 @@ static eos_timer_fptr_t timer_ext_handler = NULL; volatile uint64_t timer_next = 0; volatile uint64_t timer_next_evt = 0; -void handle_m_time_interrupt(void) { +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); uint64_t now = *mtime; @@ -44,10 +44,9 @@ void eos_timer_set(uint32_t tick, unsigned char is_evt) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - clear_csr(mstatus, MSTATUS_MIE); + clear_csr(mie, MIP_MTIP); uint64_t now = *mtime; - uint64_t then = *mtimecmp; uint64_t next = now + tick; if (is_evt) { if ((timer_next_evt == 0) || (next < timer_next_evt)) timer_next_evt = next; @@ -56,16 +55,15 @@ void eos_timer_set(uint32_t tick, unsigned char is_evt) { if ((timer_next == 0) || (next < timer_next)) timer_next = next; next = timer_next_evt ? MIN(timer_next, timer_next_evt) : timer_next; } - if ((then == 0) || (next < then)) *mtimecmp = next; - if (then == 0) set_csr(mie, MIP_MTIP); + if ((*mtimecmp == 0) || (next < *mtimecmp)) *mtimecmp = next; - set_csr(mstatus, MSTATUS_MIE); + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } void eos_timer_clear(unsigned char is_evt) { volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - clear_csr(mstatus, MSTATUS_MIE); + clear_csr(mie, MIP_MTIP); if (is_evt) { timer_next_evt = 0; @@ -74,13 +72,14 @@ void eos_timer_clear(unsigned char is_evt) { timer_next = 0; *mtimecmp = timer_next_evt; } - if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); - set_csr(mstatus, MSTATUS_MIE); + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } void eos_timer_set_handler(eos_timer_fptr_t handler) { - clear_csr(mstatus, MSTATUS_MIE); + volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + + clear_csr(mie, MIP_MTIP); timer_ext_handler = handler; - set_csr(mstatus, MSTATUS_MIE); + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } -- cgit v1.2.3