diff --git a/ChangeLog b/ChangeLog index 54160ad..cec8bd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2013-07-19 Niibe Yutaka + * src/gnuk.ld.in: Layout change following NeuG. + + * src/neug.c, src/adc.h, src/adc_stm32f103.c: Update from NeuG. + * src/main.c [DFU_SUPPORT] (main): Fix calling flash_erase_all_and_exec. diff --git a/src/adc.h b/src/adc.h index 2ed9bf6..177ccca 100644 --- a/src/adc.h +++ b/src/adc.h @@ -10,3 +10,4 @@ void adc_stop (void); #define ADC_SAMPLE_MODE 0 #define ADC_CRC32_MODE 1 void adc_start_conversion (int mode, uint32_t *p, int size); +void adc_wait (chopstx_intr_t *intr); diff --git a/src/adc_stm32f103.c b/src/adc_stm32f103.c index 88480de..db5afe3 100644 --- a/src/adc_stm32f103.c +++ b/src/adc_stm32f103.c @@ -137,36 +137,6 @@ void adc_init (void) RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN); } -extern uint8_t __process4_stack_base__, __process4_stack_size__; -const uint32_t __stackaddr_adc = (uint32_t)&__process4_stack_base__; -const size_t __stacksize_adc = (size_t)&__process4_stack_size__; -#define PRIO_ADC 3 - -static void adc_lld_serve_rx_interrupt (uint32_t flags); - -#define INTR_REQ_DMA1_Channel1 11 -static void * -adc_intr_thread (void *arg) -{ - chopstx_intr_t interrupt; - - (void)arg; - chopstx_claim_irq (&interrupt, INTR_REQ_DMA1_Channel1); - - while (1) - { - uint32_t flags; - - chopstx_intr_wait (&interrupt); - flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */ - DMA1->IFCR = STM32_DMA_ISR_MASK; /* Clear interrupt of channel 1. */ - adc_lld_serve_rx_interrupt (flags); - } - - return NULL; -} - -static chopstx_t adc_thd; void adc_start (void) { @@ -200,9 +170,6 @@ void adc_start (void) ADC2->CR2 = 0; ADC1->CR2 = 0; #endif - - adc_thd = chopstx_create (PRIO_ADC, __stackaddr_adc, __stacksize_adc, - adc_intr_thread, NULL); } static int adc_mode; @@ -278,9 +245,6 @@ void adc_stop (void) RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN); - - chopstx_cancel (adc_thd); - chopstx_join (adc_thd, NULL); } @@ -311,12 +275,16 @@ static void adc_lld_serve_rx_interrupt (uint32_t flags) *adc_ptr++ = CRC->DR; } } - - chopstx_mutex_lock (&adc_mtx); - adc_data_available++; - if (adc_waiting) - chopstx_cond_signal (&adc_cond); - chopstx_mutex_unlock (&adc_mtx); } } } + +void adc_wait (chopstx_intr_t *intr) +{ + uint32_t flags; + + chopstx_intr_wait (intr); + flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */ + DMA1->IFCR = STM32_DMA_ISR_MASK; /* Clear interrupt of channel 1. */ + adc_lld_serve_rx_interrupt (flags); +} diff --git a/src/gnuk.ld.in b/src/gnuk.ld.in index c6dce32..afc5aae 100644 --- a/src/gnuk.ld.in +++ b/src/gnuk.ld.in @@ -6,9 +6,8 @@ __process0_stack_size__ = 0x0100; /* main */ __process1_stack_size__ = 0x0140; /* ccid */ __process2_stack_size__ = 0x0180; /* rng */ __process3_stack_size__ = 0x0b00; /* gpg */ -__process4_stack_size__ = 0x0100; /* intr: adc dma */ -__process5_stack_size__ = 0x0100; /* intr: usb */ -__process6_stack_size__ = @MSC_SIZE@; /* msc */ +__process4_stack_size__ = 0x0100; /* intr: usb */ +__process5_stack_size__ = @MSC_SIZE@; /* msc */ MEMORY { @@ -84,40 +83,36 @@ SECTIONS .stacks : { - . = ALIGN(8); - __process6_stack_base__ = .; - . += __process6_stack_size__; - . = ALIGN(8); - __process6_stack_end__ = .; - __process5_stack_base__ = .; - . += __process5_stack_size__; - . = ALIGN(8); - __process5_stack_end__ = .; - __process4_stack_base__ = .; - . += __process4_stack_size__; - . = ALIGN(8); - __process4_stack_end__ = .; - __process3_stack_base__ = .; - . += __process3_stack_size__; - . = ALIGN(8); - __process3_stack_end__ = .; - __process2_stack_base__ = .; - . += __process2_stack_size__; - . = ALIGN(8); - __process2_stack_end__ = .; - __process1_stack_base__ = .; - . += __process1_stack_size__; - . = ALIGN(8); - __process1_stack_end__ = .; - __process0_stack_base__ = .; - . += __process0_stack_size__; - . = ALIGN(8); - __process0_stack_end__ = .; . = ALIGN(8); __main_stack_base__ = .; . += __main_stack_size__; . = ALIGN(8); __main_stack_end__ = .; + __process0_stack_base__ = .; + . += __process0_stack_size__; + . = ALIGN(8); + __process0_stack_end__ = .; + __process1_stack_base__ = .; + . += __process1_stack_size__; + . = ALIGN(8); + __process1_stack_end__ = .; + __process2_stack_base__ = .; + . += __process2_stack_size__; + . = ALIGN(8); + __process2_stack_end__ = .; + __process3_stack_base__ = .; + . += __process3_stack_size__; + . = ALIGN(8); + __process3_stack_end__ = .; + __process4_stack_base__ = .; + . += __process4_stack_size__; + . = ALIGN(8); + __process4_stack_end__ = .; + __process5_stack_base__ = .; + . += __process5_stack_size__; + . = ALIGN(8); + __process5_stack_end__ = .; + . = ALIGN(8); } > ram .data : diff --git a/src/main.c b/src/main.c index 123f405..f39a4b2 100644 --- a/src/main.c +++ b/src/main.c @@ -280,13 +280,13 @@ calculate_regnual_entry_address (const uint8_t *addr) } extern uint8_t __process1_stack_base__, __process1_stack_size__; -extern uint8_t __process5_stack_base__, __process5_stack_size__; +extern uint8_t __process4_stack_base__, __process4_stack_size__; const uint32_t __stackaddr_ccid = (uint32_t)&__process1_stack_base__; const size_t __stacksize_ccid = (size_t)&__process1_stack_size__; -const uint32_t __stackaddr_usb = (uint32_t)&__process5_stack_base__; -const size_t __stacksize_usb = (size_t)&__process5_stack_size__; +const uint32_t __stackaddr_usb = (uint32_t)&__process4_stack_base__; +const size_t __stacksize_usb = (size_t)&__process4_stack_size__; #define PRIO_CCID 2 #define PRIO_USB 4 diff --git a/src/neug.c b/src/neug.c index 7e8065f..7731c60 100644 --- a/src/neug.c +++ b/src/neug.c @@ -1,5 +1,5 @@ /* - * neug.c - random number generation (from NeuG/src/random.c) + * neug.c - true random number generation * * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan * Author: NIIBE Yutaka @@ -32,10 +32,14 @@ #include "adc.h" #include "sha256.h" -chopstx_mutex_t adc_mtx; -chopstx_cond_t adc_cond; -int adc_waiting; -int adc_data_available; +static chopstx_mutex_t mode_mtx; +static chopstx_cond_t mode_cond; + +/* + * ADC finish interrupt + */ +#define INTR_REQ_DMA1_Channel1 11 + static uint32_t adc_buf[SHA256_BLOCK_SIZE/sizeof (uint32_t)]; @@ -97,8 +101,6 @@ static void ep_fill_initial_string (void) static void ep_init (int mode) { - adc_data_available = 0; - if (mode == NEUG_MODE_RAW) { ep_round = EP_ROUND_RAW; @@ -415,30 +417,36 @@ static void * rng (void *arg) { struct rng_rb *rb = (struct rng_rb *)arg; + chopstx_intr_t adc_intr; + int mode = neug_mode; rng_should_terminate = 0; - chopstx_mutex_init (&adc_mtx); - chopstx_cond_init (&adc_cond); + chopstx_mutex_init (&mode_mtx); + chopstx_cond_init (&mode_cond); /* Enable ADCs */ adc_start (); + chopstx_claim_irq (&adc_intr, INTR_REQ_DMA1_Channel1); - ep_init (NEUG_MODE_CONDITIONED); - + ep_init (mode); while (!rng_should_terminate) { int n; - int mode = neug_mode; - chopstx_mutex_lock (&adc_mtx); - if (!adc_data_available) + adc_wait (&adc_intr); + + chopstx_mutex_lock (&mode_mtx); + if (mode != neug_mode) { - adc_waiting = 1; - chopstx_cond_wait (&adc_cond, &adc_mtx); - adc_waiting = 0; + mode = neug_mode; + + noise_source_cnt_max_reset (); + + /* Discarding data available, re-initiate from the start. */ + ep_init (mode); + chopstx_cond_signal (&mode_cond); } - adc_data_available = 0; - chopstx_mutex_unlock (&adc_mtx); + chopstx_mutex_unlock (&mode_mtx); if ((n = ep_process (mode))) { @@ -472,6 +480,7 @@ rng (void *arg) } adc_stop (); + chopstx_release_irq (&adc_intr); return NULL; } @@ -629,17 +638,12 @@ neug_mode_select (uint8_t mode) neug_wait_full (); - chopstx_mutex_lock (&adc_mtx); - while (adc_waiting == 0) - { - chopstx_mutex_unlock (&adc_mtx); - chopstx_usec_wait (1000); - chopstx_mutex_lock (&adc_mtx); - } - chopstx_mutex_unlock (&adc_mtx); - - ep_init (mode); - noise_source_cnt_max_reset (); + chopstx_mutex_lock (&mode_mtx); neug_mode = mode; neug_flush (); + chopstx_cond_wait (&mode_cond, &mode_mtx); + chopstx_mutex_unlock (&mode_mtx); + + neug_wait_full (); + neug_flush (); }