From 7abdb51f8fa1d43372bfc9ec00bf1ea485f8aaf7 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 3 Mar 2016 17:48:32 +0100 Subject: [PATCH] ringbuffer: Make ring buffer access irq-save We have to temporarily disable nterrupts when performing rinbuffer operations, as the ring buffer is used both from IRQ as well as process context. --- firmware/Makefile | 4 +- firmware/src_board/board_lowlevel.c | 8 ++++ firmware/src_board/iso7816_4.c | 2 - firmware/src_simtrace/card_emu.c | 2 + firmware/src_simtrace/host_communication.c | 2 + firmware/src_simtrace/mode_cardemu.c | 5 ++ firmware/src_simtrace/ringbuffer.c | 54 +++++++++++++++++----- 7 files changed, 61 insertions(+), 16 deletions(-) diff --git a/firmware/Makefile b/firmware/Makefile index 216d6328..59fcf873 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -48,7 +48,7 @@ MEMORIES = flash # TRACE_LEVEL_ERROR 2 # TRACE_LEVEL_FATAL 1 # TRACE_LEVEL_NO_TRACE 0 -TRACE_LEVEL = 1 +TRACE_LEVEL = 4 #FIXME: Remove this variable NOAUTOCALLBACK=no @@ -110,7 +110,7 @@ CFLAGS += -Wmissing-format-attribute -Wno-deprecated-declarations CFLAGS += #-Wpacked CFLAGS += -Wredundant-decls -Wnested-externs -Winline #-Wlong-long CFLAGS += -Wunreachable-code -CFLAGS += -Wcast-align +#CFLAGS += -Wcast-align #CFLAGS += -std=c11 CFLAGS += -Wmissing-noreturn #CFLAGS += -Wconversion diff --git a/firmware/src_board/board_lowlevel.c b/firmware/src_board/board_lowlevel.c index f288fc04..c67bf910 100644 --- a/firmware/src_board/board_lowlevel.c +++ b/firmware/src_board/board_lowlevel.c @@ -77,10 +77,16 @@ * This includes EFC and master clock configuration. * It also enable a low level on the pin NRST triggers a user reset. */ +#define _LED_GREN (1 << 18) +#define _LED_RED (1 << 17) extern WEAK void LowLevelInit( void ) { uint32_t timeout = 0; + PIOA->PIO_PER |= _LED_RED | _LED_GREN; + PIOA->PIO_OER |= _LED_RED | _LED_GREN; + PIOA->PIO_CODR |= _LED_RED | _LED_GREN; + /* Set 3 FWS for Embedded Flash Access */ EFC->EEFC_FMR = EEFC_FMR_FWS(3); @@ -110,6 +116,8 @@ extern WEAK void LowLevelInit( void ) timeout = 0; while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT)); + PIOA->PIO_SODR = _LED_RED; + /* "switch" to main clock as master clock source (should already be the case */ PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK; /* wait for master clock to be ready */ diff --git a/firmware/src_board/iso7816_4.c b/firmware/src_board/iso7816_4.c index d71e1568..5362a4e1 100644 --- a/firmware/src_board/iso7816_4.c +++ b/firmware/src_board/iso7816_4.c @@ -129,8 +129,6 @@ uint32_t ISO7816_SendChar( uint8_t CharToSend, Usart_info *usart ) Usart *us_base = usart->base; uint32_t us_id = usart->id; - TRACE_DEBUG("***Send char: 0x%X\n\r", CharToSend); - if( usart->state == USART_RCV ) { us_base->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK; usart->state = USART_SEND; diff --git a/firmware/src_simtrace/card_emu.c b/firmware/src_simtrace/card_emu.c index dd0899fa..83769437 100644 --- a/firmware/src_simtrace/card_emu.c +++ b/firmware/src_simtrace/card_emu.c @@ -17,6 +17,8 @@ * */ +#define TRACE_LEVEL 6 + #include #include #include diff --git a/firmware/src_simtrace/host_communication.c b/firmware/src_simtrace/host_communication.c index 653916ff..05f79990 100644 --- a/firmware/src_simtrace/host_communication.c +++ b/firmware/src_simtrace/host_communication.c @@ -1,3 +1,5 @@ +//#define TRACE_LEVEL 6 + #include "board.h" #include "req_ctx.h" #include "linuxlist.h" diff --git a/firmware/src_simtrace/mode_cardemu.c b/firmware/src_simtrace/mode_cardemu.c index 3b0c3d21..1f46d9b3 100644 --- a/firmware/src_simtrace/mode_cardemu.c +++ b/firmware/src_simtrace/mode_cardemu.c @@ -1,3 +1,5 @@ +#define TRACE_LEVEL 6 + #include "board.h" #include "simtrace.h" #include "ringbuffer.h" @@ -250,6 +252,9 @@ void mode_cardemu_exit(void) { TRACE_ENTRY(); + /* FIXME: stop tc_fdt */ + /* FIXME: release all rctx, unlink them from any queue */ + PIO_DisableIt(&pin_usim1_rst); PIO_DisableIt(&pin_usim1_vcc); diff --git a/firmware/src_simtrace/ringbuffer.c b/firmware/src_simtrace/ringbuffer.c index 1669fdc7..71fe4ede 100644 --- a/firmware/src_simtrace/ringbuffer.c +++ b/firmware/src_simtrace/ringbuffer.c @@ -1,16 +1,27 @@ #include "ringbuffer.h" #include "trace.h" +#include "utils.h" void rbuf_reset(volatile ringbuf * rb) { + unsigned long state; + + local_irq_save(state); rb->ird = 0; rb->iwr = 0; + local_irq_restore(state); } uint8_t rbuf_read(volatile ringbuf * rb) { - uint8_t val = rb->buf[rb->ird]; + unsigned long state; + uint8_t val; + + local_irq_save(state); + val = rb->buf[rb->ird]; rb->ird = (rb->ird + 1) % RING_BUFLEN; + local_irq_restore(state); + return val; } @@ -19,22 +30,41 @@ uint8_t rbuf_peek(volatile ringbuf * rb) return rb->buf[rb->ird]; } -void rbuf_write(volatile volatile ringbuf * rb, uint8_t item) -{ - if (!rbuf_is_full(rb)) { - rb->buf[rb->iwr] = item; - rb->iwr = (rb->iwr + 1) % RING_BUFLEN; - } else { - TRACE_ERROR("Ringbuffer full, losing bytes!"); - } -} - bool rbuf_is_empty(volatile ringbuf * rb) { return rb->ird == rb->iwr; } -bool rbuf_is_full(volatile ringbuf * rb) +static bool __rbuf_is_full(volatile ringbuf * rb) { return rb->ird == (rb->iwr + 1) % RING_BUFLEN; } + +bool rbuf_is_full(volatile ringbuf * rb) +{ + unsigned long state; + bool rc; + + local_irq_save(state); + rc = rb->ird == (rb->iwr + 1) % RING_BUFLEN; + local_irq_restore(state); + + return rc; +} + +void rbuf_write(volatile volatile ringbuf * rb, uint8_t item) +{ + unsigned long state; + + local_irq_save(state); + if (!__rbuf_is_full(rb)) { + rb->buf[rb->iwr] = item; + rb->iwr = (rb->iwr + 1) % RING_BUFLEN; + local_irq_restore(state); + } else { + local_irq_restore(state); + TRACE_ERROR("Ringbuffer full, losing bytes!"); + } +} + +