diff options
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | libraries/libprof/README.txt | 2 | ||||
-rw-r--r-- | libraries/libprof/profil.c | 17 | ||||
-rw-r--r-- | libraries/libtfm/Makefile | 34 | ||||
-rw-r--r-- | libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c | 2 | ||||
-rw-r--r-- | projects/bootloader/bootloader.c | 1 | ||||
-rw-r--r-- | projects/cli-test/mgmt-keystore.c | 4 | ||||
-rw-r--r-- | projects/hsm/hsm.c | 52 | ||||
-rw-r--r-- | projects/hsm/mgmt-keystore.c | 4 | ||||
-rw-r--r-- | projects/hsm/mgmt-task.c | 13 | ||||
-rw-r--r-- | stm-init.c | 8 | ||||
-rw-r--r-- | stm-init.h | 4 | ||||
-rw-r--r-- | stm-uart.c | 2 |
13 files changed, 109 insertions, 55 deletions
@@ -91,13 +91,14 @@ SIZE=$(PREFIX)size # The Alpha is a development platform, so set GCC optimization to a # level suitable for debugging. Recent versions of GCC have a special -# optimization setting -Og for exactly this purpose, so we use it, along -# with the flag to enable gdb symbols. +# optimization setting -Og for exactly this purpose, so we use it, +# along with the flag to enable gdb symbols. Note that some libraries +# (in particular, libtfm) may need different optimization settings, +# which is why this needs to remain a separate makefile variable. # -# If you really want optimization without debugging support, try -O2 or -# (maybe) -O3. +# If you really want optimization without debugging support, try -O2 +# or -O3. -#STM32_CFLAGS_OPTIMIZATION ?= -O2 STM32_CFLAGS_OPTIMIZATION ?= -ggdb -Og # whew, that's a lot of cflags @@ -116,6 +117,9 @@ CFLAGS += -I$(MBED_DIR)/targets/cmsis/TARGET_STM/TARGET_STM32F4 CFLAGS += -I$(MBED_DIR)/targets/cmsis/TARGET_STM/TARGET_STM32F4/$(BOARD) CFLAGS += -I$(MBED_DIR)/targets/hal/TARGET_STM/TARGET_STM32F4 CFLAGS += -I$(MBED_DIR)/targets/hal/TARGET_STM/TARGET_STM32F4/$(BOARD) +ifdef DO_TASK_METRICS +CFLAGS += -DDO_TASK_METRICS +endif %.o : %.c $(CC) $(CFLAGS) -c -o $@ $< @@ -123,7 +127,11 @@ CFLAGS += -I$(MBED_DIR)/targets/hal/TARGET_STM/TARGET_STM32F4/$(BOARD) %.o : %.S $(CC) $(CFLAGS) -c -o $@ $< +ifdef DO_PROFILING +all: hsm +else all: board-test cli-test libhal-test hsm bootloader +endif $(MBED_DIR)/libstmf4.a: .FORCE $(MAKE) -C $(MBED_DIR) @@ -151,9 +159,6 @@ libhal-test: $(BOARD_OBJS) $(LIBS) $(LIBHAL_BLD)/libhal.a .FORCE ifdef DO_PROFILING CFLAGS += -pg -DDO_PROFILING -endif -ifdef DO_TASK_METRICS -CFLAGS += -DDO_TASK_METRICS hsm: $(BOARD_OBJS) $(LIBS) $(LIBHAL_BLD)/libhal.a $(LIBCLI_BLD)/libcli.a $(LIBPROF_BLD)/libprof.a .FORCE $(MAKE) -C projects/hsm else diff --git a/libraries/libprof/README.txt b/libraries/libprof/README.txt index 1fe378c..f0b8ee8 100644 --- a/libraries/libprof/README.txt +++ b/libraries/libprof/README.txt @@ -52,7 +52,7 @@ In the OpenOCD console, enable semihosting: In another window, start the debugger: - $ sw/stm32/bin/debug projects/hsm/hsm + $ ../../bin/debug hsm In the CLI, type `profile start`, then start the unit test or whatever will be exercising the hsm. Afterwards, in the CLI, type `profile stop`. diff --git a/libraries/libprof/profil.c b/libraries/libprof/profil.c index 0654879..b0d8d55 100644 --- a/libraries/libprof/profil.c +++ b/libraries/libprof/profil.c @@ -25,27 +25,30 @@ static struct profinfo prof = { PROFILE_NOT_INIT, 0, 0, 0, 0 }; -extern void set_SysTick_hook(void (*hook)(void)); - /* sample the current program counter */ -static void SysTick_hook(void) { - size_t pc = (size_t)((uint32_t *)__get_MSP())[8]; - if (pc >= prof.lowpc && pc < prof.highpc) { +void profil_callback(void) { + if (prof.state == PROFILE_ON) { + /* The interrupt mechanism pushes xPSR, PC, LR, R12, and R3-R0 onto the + * stack, so PC is the 6th word from the top at that point. However, the + * normal function entry code pushes registers as well, so the stack + * offset right now depends on the call tree that got us here. + */ + size_t pc = (size_t)((uint32_t *)__get_MSP())[6 + 6]; + if (pc >= prof.lowpc && pc < prof.highpc) { size_t idx = PROFIDX (pc, prof.lowpc, prof.scale); prof.counter[idx]++; + } } } /* Stop profiling to the profiling buffer pointed to by p. */ static int profile_off (struct profinfo *p) { - set_SysTick_hook(NULL); p->state = PROFILE_OFF; return 0; } /* Create a timer thread and pass it a pointer P to the profiling buffer. */ static int profile_on (struct profinfo *p) { - set_SysTick_hook(SysTick_hook); p->state = PROFILE_ON; return 0; /* ok */ } diff --git a/libraries/libtfm/Makefile b/libraries/libtfm/Makefile index 6da552d..5be45f4 100644 --- a/libraries/libtfm/Makefile +++ b/libraries/libtfm/Makefile @@ -10,10 +10,38 @@ BITS := 8192 HDR := ${LIBTFM_SRC}/tomsfastmath/src/headers/tfm.h LIB := tomsfastmath/libtfm.a -#CFLAGS += -DTFM_X86 -#CFLAGS += -DTFM_NO_ASM +# See sw/thirdparty/libtfm/Makefile for compilation options. Note +# that libtfm platform-specific assembly code has opinions on the +# optimization level (and appears to be best tested with -O3). -CFLAGS += -fPIC -Wall -W -Wshadow -I${LIBTFM_SRC}/tomsfastmath/src/headers -g3 -DFP_MAX_SIZE="(${BITS}*2+(8*DIGIT_BIT))" +# Using $(subst...) here is a kludge. A cleaner approach might be for +# sw/stm32/Makefile to build up the non-variant parts of CFLAGS in a +# different variable before merging the variant and non-variant parts +# into CFLAGS, which would give us a clean copy of the non-variant +# parts to use when constructing our own CFLAGS. Later. + +# The ARM assembly code in libtfm still generates a lot of warnings of the form: +# +# warning: matching constraint does not allow a register [enabled by default] +# +# This is just a warning, the resulting library appears to work +# correctly, and the fix appears to require a nasty intervention in +# the guts of the libtfm assembly code, so we live with the warning +# for now, at least until we confirm that it hasn't already been fixed +# in a newer version of libtfm. + +ifdef DO_PROFILING +# arm-none-eabi-gcc: error: -pg and -fomit-frame-pointer are incompatible +STM32_LIBTFM_CFLAGS_OPTIMIZATION := -O3 -funroll-loops +else +STM32_LIBTFM_CFLAGS_OPTIMIZATION := -O3 -funroll-loops -fomit-frame-pointer +endif + +CFLAGS := $(subst ${STM32_CFLAGS_OPTIMIZATION},${STM32_LIBTFM_CFLAGS_OPTIMIZATION},${CFLAGS}) +CFLAGS += -DTFM_ARM -Dasm=__asm__ -Wa,-mimplicit-it=thumb +CFLAGS += -I${LIBTFM_SRC}/tomsfastmath/src/headers +CFLAGS += -DFP_MAX_SIZE="(${BITS}*2+(8*DIGIT_BIT))" +CFLAGS += -Wall -W -Wshadow TARGETS := $(notdir ${HDR} ${LIB}) diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c index 4629e44..b8b6fce 100644 --- a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/TARGET_CRYPTECH_ALPHA/stm32f4xx_it.c @@ -79,7 +79,7 @@ void set_SysTick_hook(void (*hook)(void)) void SysTick_Handler(void) { HAL_IncTick(); - SysTick_hook(); + HAL_SYSTICK_IRQHandler(); } /******************************************************************************/ diff --git a/projects/bootloader/bootloader.c b/projects/bootloader/bootloader.c index c0f981f..ead87d0 100644 --- a/projects/bootloader/bootloader.c +++ b/projects/bootloader/bootloader.c @@ -41,6 +41,7 @@ /* stub these out to avoid linker error */ void fpgacfg_init(void) { } void sdram_init(void) { } +void *hal_allocate_static_memory(const size_t size) { return 0; } /* Linker symbols are strange in C. Make regular pointers for sanity. */ __IO uint32_t *dfu_control = &CRYPTECH_DFU_CONTROL; diff --git a/projects/cli-test/mgmt-keystore.c b/projects/cli-test/mgmt-keystore.c index e11ef76..18447c8 100644 --- a/projects/cli-test/mgmt-keystore.c +++ b/projects/cli-test/mgmt-keystore.c @@ -340,12 +340,12 @@ static int cmd_keystore_erase(struct cli_def *cli, const char *command, char *ar return CLI_ERROR; } - if ((err = hal_ks_init(hal_ks_token_driver, 0)) != LIBHAL_OK) { + if ((err = hal_ks_init(hal_ks_token, 0)) != LIBHAL_OK) { cli_print(cli, "Failed to reinitialize token keystore: %s", hal_error_string(err)); return CLI_ERROR; } - if ((err = hal_ks_init(hal_ks_volatile_driver, 0)) != LIBHAL_OK) { + if ((err = hal_ks_init(hal_ks_volatile, 0)) != LIBHAL_OK) { cli_print(cli, "Failed to reinitialize memory keystore: %s", hal_error_string(err)); return CLI_ERROR; } diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c index 33342c0..5ef2ccc 100644 --- a/projects/hsm/hsm.c +++ b/projects/hsm/hsm.c @@ -244,25 +244,43 @@ static void RxCallback(uint8_t c) } } -static uint8_t uart_rx[2]; /* current character received from UART */ -static uint32_t uart_rx_idx = 0; - -/* UART DMA half-complete and complete callbacks. With a 2-character DMA - * buffer, one or the other of these will fire on each incoming character. - * Under heavy load, these will sometimes fire in the wrong order, but the - * data are in the right order in the DMA buffer, so we have a flip-flop - * buffer index that doesn't depend on the order of the callbacks. +/* A ring buffer for the UART DMA receiver. In theory, it should get at most + * 92 characters per 1ms tick, but we're going to up-size it for safety. */ -void HAL_UART2_RxHalfCpltCallback(UART_HandleTypeDef *huart) -{ - RxCallback(uart_rx[uart_rx_idx]); - uart_rx_idx ^= 1; -} +#ifndef RPC_UART_RECVBUF_SIZE +#define RPC_UART_RECVBUF_SIZE 1024 /* must be a power of 2 */ +#endif +#define RPC_UART_RECVBUF_MASK (RPC_UART_RECVBUF_SIZE - 1) + +typedef struct { + uint32_t ridx; + uint8_t buf[RPC_UART_RECVBUF_SIZE]; +} uart_ringbuf_t; + +volatile uart_ringbuf_t uart_ringbuf = {0, {0}}; -void HAL_UART2_RxCpltCallback(UART_HandleTypeDef *huart) +#define RINGBUF_RIDX(rb) (rb.ridx & RPC_UART_RECVBUF_MASK) +#define RINGBUF_WIDX(rb) (sizeof(rb.buf) - __HAL_DMA_GET_COUNTER(huart_user.hdmarx)) +#define RINGBUF_COUNT(rb) ((RINGBUF_WIDX(rb) - RINGBUF_RIDX(rb)) & RPC_UART_RECVBUF_MASK) +#define RINGBUF_READ(rb, dst) {dst = rb.buf[RINGBUF_RIDX(rb)]; rb.ridx++;} + +size_t uart_rx_max = 0; + +void HAL_SYSTICK_Callback(void) { - RxCallback(uart_rx[uart_rx_idx]); - uart_rx_idx ^= 1; +#ifdef DO_PROFILING + extern void profil_callback(void); + profil_callback(); +#endif + + size_t count = RINGBUF_COUNT(uart_ringbuf); + if (uart_rx_max < count) uart_rx_max = count; + + while (RINGBUF_COUNT(uart_ringbuf)) { + uint8_t c; + RINGBUF_READ(uart_ringbuf, c); + RxCallback(c); + } } /* Send one character over the UART. This is called from @@ -430,7 +448,7 @@ int main(void) Error_Handler(); /* Start the UART receiver. */ - if (HAL_UART_Receive_DMA(&huart_user, uart_rx, 2) != CMSIS_HAL_OK) + if (HAL_UART_Receive_DMA(&huart_user, (uint8_t *) uart_ringbuf.buf, sizeof(uart_ringbuf.buf)) != CMSIS_HAL_OK) Error_Handler(); /* Launch other tasks (csprng warm-up task?) diff --git a/projects/hsm/mgmt-keystore.c b/projects/hsm/mgmt-keystore.c index f24f49b..0104265 100644 --- a/projects/hsm/mgmt-keystore.c +++ b/projects/hsm/mgmt-keystore.c @@ -304,12 +304,12 @@ static int cmd_keystore_erase(struct cli_def *cli, const char *command, char *ar return CLI_ERROR; } - if ((err = hal_ks_init(hal_ks_token_driver, 0)) != LIBHAL_OK) { + if ((err = hal_ks_init(hal_ks_token, 0)) != LIBHAL_OK) { cli_print(cli, "Failed to reinitialize token keystore: %s", hal_error_string(err)); return CLI_ERROR; } - if ((err = hal_ks_init(hal_ks_volatile_driver, 0)) != LIBHAL_OK) { + if ((err = hal_ks_init(hal_ks_volatile, 0)) != LIBHAL_OK) { cli_print(cli, "Failed to reinitialize memory keystore: %s", hal_error_string(err)); return CLI_ERROR; } diff --git a/projects/hsm/mgmt-task.c b/projects/hsm/mgmt-task.c index 1658a80..4668585 100644 --- a/projects/hsm/mgmt-task.c +++ b/projects/hsm/mgmt-task.c @@ -63,8 +63,12 @@ static int cmd_task_show(struct cli_def *cli, const char *command, char *argv[], } cli_print(cli, " "); - cli_print(cli, "request queue current length: %d", request_queue_len()); - cli_print(cli, "request queue maximum length: %d", request_queue_max()); + cli_print(cli, "RPC request queue current length: %u", request_queue_len()); + cli_print(cli, "RPC request queue maximum length: %u", request_queue_max()); + + extern size_t uart_rx_max; + cli_print(cli, " "); + cli_print(cli, "UART receive queue maximum length: %u", uart_rx_max); return CLI_OK; } @@ -95,7 +99,10 @@ void configure_cli_task(struct cli_def *cli) struct cli_command *c = cli_register_command(cli, NULL, "task", NULL, 0, 0, NULL); /* task show */ - struct cli_command *c_show = cli_register_command(cli, c, "show", cmd_task_show, 0, 0, "Show the active tasks"); +#ifdef DO_TASK_METRICS + struct cli_command *c_show = +#endif + cli_register_command(cli, c, "show", cmd_task_show, 0, 0, "Show the active tasks"); #ifdef DO_TASK_METRICS /* task show metrics */ @@ -115,10 +115,6 @@ static void MX_GPIO_Init(void) } #endif -#ifdef CMSIS_RTOS -#include "cmsis_os.h" -#endif - /** * @brief This function is executed in case of error occurrence. * @param None @@ -129,10 +125,6 @@ void Error_Handler(void) #ifdef HAL_GPIO_MODULE_ENABLED HAL_GPIO_WritePin(LED_PORT, LED_RED, GPIO_PIN_SET); #endif -#ifdef CMSIS_RTOS - //osThreadSetPriority(osThreadGetId(), osPriorityIdle); - osThreadTerminate(osThreadGetId()); -#endif while (1) { ; } } @@ -39,7 +39,7 @@ /* Functions used to make GPIO pin setup (in stm-init.c) easier */ -inline void gpio_output(GPIO_TypeDef* output_port, uint16_t output_pins, GPIO_PinState output_level) +static inline void gpio_output(GPIO_TypeDef* output_port, uint16_t output_pins, GPIO_PinState output_level) { GPIO_InitTypeDef GPIO_InitStruct; @@ -54,7 +54,7 @@ inline void gpio_output(GPIO_TypeDef* output_port, uint16_t output_pins, GPIO_Pi HAL_GPIO_Init(output_port, &GPIO_InitStruct); } -inline void gpio_input(GPIO_TypeDef* input_port, uint16_t input_pin, GPIO_PinState input_pull) +static inline void gpio_input(GPIO_TypeDef* input_port, uint16_t input_pin, GPIO_PinState input_pull) { GPIO_InitTypeDef GPIO_InitStruct; @@ -124,7 +124,7 @@ void uart_set_default(stm_uart_port_t port) default_uart = port; } -inline UART_HandleTypeDef *_which_uart(stm_uart_port_t port) +static inline UART_HandleTypeDef *_which_uart(stm_uart_port_t port) { if (port == STM_UART_USER) { return &huart_user; |