port to chopstx
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "chibios"]
|
||||
path = chibios
|
||||
url = git@gitorious.org:gnuk/chibios.git
|
||||
[submodule "chopstx"]
|
||||
path = chopstx
|
||||
url = git@gitorious.org:chopstx/chopstx.git
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
2013-06-20 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/sys.c, src/sys.h, src/neug.c, rc/usb_stm32f103.c: Update
|
||||
from NeuG 0.10.
|
||||
* src/stm32f103.h: New. From NeuG 0.10.
|
||||
|
||||
2013-06-18 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (gpg_do_write_prvkey, proc_key_import, gpg_do_table)
|
||||
|
||||
1
chopstx
Submodule
1
chopstx
Submodule
Submodule chopstx added at 8447b2ba8e
@@ -177,15 +177,15 @@ static const unsigned char FSb[256] =
|
||||
V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
|
||||
|
||||
#define V(a,b,c,d) 0x##a##b##c##d
|
||||
static const uint32_t FT0[256] __attribute__((section(".sys.0"))) = { FT };
|
||||
const uint32_t FT0[256] __attribute__((section(".sys.0"))) = { FT };
|
||||
#undef V
|
||||
|
||||
#define V(a,b,c,d) 0x##b##c##d##a
|
||||
static const uint32_t FT1[256] __attribute__((section(".sys.1"))) = { FT };
|
||||
const uint32_t FT1[256] __attribute__((section(".sys.1"))) = { FT };
|
||||
#undef V
|
||||
|
||||
#define V(a,b,c,d) 0x##c##d##a##b
|
||||
static const uint32_t FT2[256] __attribute__((section(".sys.2"))) = { FT };
|
||||
const uint32_t FT2[256] __attribute__((section(".sys.2"))) = { FT };
|
||||
#undef V
|
||||
|
||||
#define V(a,b,c,d) 0x##d##a##b##c
|
||||
|
||||
205
src/Makefile.in
205
src/Makefile.in
@@ -1,91 +1,34 @@
|
||||
# Makefile for Gnuk
|
||||
|
||||
BOARD_DIR=@BOARD_DIR@
|
||||
@PINPAD_MAKE_OPTION@
|
||||
@DEBUG_MAKE_OPTION@
|
||||
|
||||
##############################################################################
|
||||
# Build global options
|
||||
# NOTE: Can be overridden externally.
|
||||
#
|
||||
|
||||
# Compiler options here.
|
||||
ifeq ($(USE_OPT),)
|
||||
USE_OPT = -O3 -Os -ggdb -fomit-frame-pointer -falign-functions=16
|
||||
endif
|
||||
|
||||
# C++ specific options here (added to USE_OPT).
|
||||
ifeq ($(USE_CPPOPT),)
|
||||
USE_CPPOPT = -fno-rtti
|
||||
endif
|
||||
|
||||
# Enable this if you want the linker to remove unused code and data
|
||||
ifeq ($(USE_LINK_GC),)
|
||||
USE_LINK_GC = yes
|
||||
endif
|
||||
|
||||
# If enabled, this option allows to compile the application in THUMB mode.
|
||||
ifeq ($(USE_THUMB),)
|
||||
USE_THUMB = yes
|
||||
endif
|
||||
|
||||
# Enable this if you want to see the full log while compiling.
|
||||
ifeq ($(USE_VERBOSE_COMPILE),)
|
||||
USE_VERBOSE_COMPILE = no
|
||||
endif
|
||||
|
||||
#
|
||||
# Build global options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Architecture or project specific options
|
||||
#
|
||||
|
||||
# Enable this if you really want to use the STM FWLib.
|
||||
ifeq ($(USE_FWLIB),)
|
||||
USE_FWLIB = no
|
||||
endif
|
||||
|
||||
#
|
||||
# Architecture or project specific options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Project, sources and paths
|
||||
#
|
||||
|
||||
# Define project name here
|
||||
PROJECT = gnuk
|
||||
|
||||
# Imported source files
|
||||
CHIBIOS = ../chibios
|
||||
include $(CHIBIOS)/os/hal/platforms/STM32F1xx/platform.mk
|
||||
include $(CHIBIOS)/os/hal/hal.mk
|
||||
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
|
||||
include $(CHIBIOS)/os/kernel/kernel.mk
|
||||
include crypt.mk
|
||||
CHOPSTX = ../chopstx
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= gnuk.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CSRC = $(PORTSRC) \
|
||||
$(KERNSRC) \
|
||||
$(HALSRC) \
|
||||
$(PLATFORMSRC) \
|
||||
$(BOARDSRC) \
|
||||
../boards/common/board-common.c \
|
||||
$(BOARD_DIR)/board.c \
|
||||
$(CHIBIOS)/os/various/evtimer.c \
|
||||
$(CHIBIOS)/os/various/syscalls.c \
|
||||
$(CRYPTSRC) \
|
||||
main.c usb_stm32f103.c adc_stm32f103.c \
|
||||
CSRC = main.c usb_stm32f103.c adc_stm32f103.c \
|
||||
usb_desc.c usb_ctrl.c \
|
||||
call-rsa.c \
|
||||
usb-icc.c openpgp.c ac.c openpgp-do.c flash.c \
|
||||
bn.c modp256.c jpc.c mod.c ec_p256.c call-ec_p256.c \
|
||||
random.c neug.c sys.c
|
||||
random.c neug.c sha256.c sys.c
|
||||
|
||||
INCDIR =
|
||||
|
||||
CRYPTDIR = ../polarssl
|
||||
CRYPTSRCDIR = $(CRYPTDIR)/library
|
||||
CRYPTINCDIR = $(CRYPTDIR)/include
|
||||
CRYPTSRC = $(CRYPTSRCDIR)/bignum.c $(CRYPTSRCDIR)/rsa.c $(CRYPTSRCDIR)/aes.c
|
||||
|
||||
CSRC += $(CRYPTSRC)
|
||||
INCDIR += $(CRYPTINCDIR)
|
||||
|
||||
@PINPAD_MAKE_OPTION@
|
||||
@DEBUG_MAKE_OPTION@
|
||||
|
||||
USE_EVENTFLAG = yes
|
||||
|
||||
ifneq ($(ENABLE_DEBUG),)
|
||||
CSRC += debug.c
|
||||
@@ -99,102 +42,28 @@ ifeq ($(ENABLE_PINPAD),dnd)
|
||||
CSRC += usb-msc.c
|
||||
endif
|
||||
|
||||
# List ASM source files here
|
||||
ASMSRC = $(PORTASM)
|
||||
###################################
|
||||
CROSS = arm-none-eabi-
|
||||
CC = $(CROSS)gcc
|
||||
LD = $(CROSS)gcc
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
|
||||
INCDIR = $(CRYPTINCDIR) \
|
||||
$(PORTINC) $(KERNINC) $(TESTINC) \
|
||||
$(HALINC) $(PLATFORMINC) ../boards/common $(BOARD_DIR) \
|
||||
$(CHIBIOS)/os/various
|
||||
|
||||
#
|
||||
# Project, sources and paths
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Compiler settings
|
||||
#
|
||||
|
||||
MCU = cortex-m3
|
||||
|
||||
#TRGT = arm-elf-
|
||||
TRGT = arm-none-eabi-
|
||||
CC = $(TRGT)gcc
|
||||
CPPC = $(TRGT)g++
|
||||
# Enable loading with g++ only if you need C++ runtime support.
|
||||
# NOTE: You can use C++ even without C++ support if you are careful. C++
|
||||
# runtime support makes code size explode.
|
||||
LD = $(TRGT)gcc
|
||||
#LD = $(TRGT)g++
|
||||
CP = $(TRGT)objcopy
|
||||
AS = $(TRGT)gcc -x assembler-with-cpp
|
||||
OD = $(TRGT)objdump
|
||||
HEX = $(CP) -O ihex
|
||||
BIN = $(CP) -O binary
|
||||
|
||||
# ARM-specific options here
|
||||
AOPT =
|
||||
|
||||
# THUMB-specific options here
|
||||
TOPT = -mthumb -DTHUMB
|
||||
|
||||
# Define C warning options here
|
||||
MCU = cortex-m3
|
||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||
# DEFS: Add
|
||||
DEFS = -DRSA_AUTH @KEYGEN_SUPPORT@ @HAVE_SYS_H@
|
||||
OPT = -O3 -Os -g
|
||||
LIBS =
|
||||
|
||||
# Define C++ warning options here
|
||||
CPPWARN = -Wall -Wextra
|
||||
#######################
|
||||
include $(CHOPSTX)/rules.mk
|
||||
|
||||
#
|
||||
# Compiler settings
|
||||
##############################################################################
|
||||
board.h:
|
||||
@echo Please run configure to have a symbolic link \'board.h\'
|
||||
@exit 1
|
||||
|
||||
##############################################################################
|
||||
# Start of default section
|
||||
#
|
||||
|
||||
# List all default C defines here, like -D_DEBUG=1
|
||||
DDEFS =
|
||||
|
||||
# List all default ASM defines here, like -D_DEBUG=1
|
||||
DADEFS =
|
||||
|
||||
# List all default directories to look for include files here
|
||||
DINCDIR =
|
||||
|
||||
# List the default directory to look for the libraries here
|
||||
DLIBDIR =
|
||||
|
||||
# List all default libraries here
|
||||
DLIBS =
|
||||
|
||||
#
|
||||
# End of default section
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Start of user section
|
||||
#
|
||||
|
||||
# List all user C define here, like -D_DEBUG=1
|
||||
UDEFS = @KEYGEN_SUPPORT@
|
||||
|
||||
# Define ASM defines here
|
||||
UADEFS =
|
||||
|
||||
# List all user directories here
|
||||
UINCDIR =
|
||||
|
||||
# List the user directory to look for the libraries here
|
||||
ULIBDIR =
|
||||
|
||||
# List all user libraries here
|
||||
ULIBS =
|
||||
|
||||
#
|
||||
# End of user defines
|
||||
##############################################################################
|
||||
|
||||
include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk
|
||||
sys.c: board.h
|
||||
|
||||
distclean: clean
|
||||
-rm -f Makefile gnuk.ld config.h *.inc
|
||||
-rm -f gnuk.ld config.h board.h Makefile \
|
||||
usb-strings.c.inc usb-vid-pid-ver.c.inc
|
||||
|
||||
5
src/ac.c
5
src/ac.c
@@ -21,8 +21,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "sha256.h"
|
||||
#include "random.h"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#define ADC_DATA_AVAILABLE ((eventmask_t)1)
|
||||
extern Thread *rng_thread;
|
||||
extern chopstx_mutex_t adc_mtx;
|
||||
extern chopstx_cond_t adc_cond;
|
||||
extern int adc_waiting;
|
||||
extern int adc_data_available;
|
||||
|
||||
void adc_init (void);
|
||||
void adc_start (void);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* adc_stm32f103.c - ADC driver for STM32F103
|
||||
*
|
||||
* Copyright (C) 2011, 2012 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of NeuG, a True Random Number Generator
|
||||
@@ -22,15 +22,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
#include "neug.h"
|
||||
#include "stm32f103.h"
|
||||
#include "adc.h"
|
||||
|
||||
#define NEUG_CRC32_COUNTS 4
|
||||
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 2
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
|
||||
#define ADC_SMPR1_SMP_VREF(n) ((n) << 21)
|
||||
#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18)
|
||||
@@ -82,6 +84,7 @@
|
||||
#define NEUG_DMA_MODE_CRC32 \
|
||||
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
|
||||
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
|
||||
| STM32_DMA_CR_MINC \
|
||||
| STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
|
||||
|
||||
#define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
|
||||
@@ -108,8 +111,10 @@
|
||||
*/
|
||||
void adc_init (void)
|
||||
{
|
||||
chSysLock ();
|
||||
rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
||||
RCC->APB2RSTR = (RCC_APB2RSTR_ADC1RST | RCC_APB2RSTR_ADC2RST);
|
||||
RCC->APB2RSTR = 0;
|
||||
|
||||
ADC1->CR1 = 0;
|
||||
ADC1->CR2 = ADC_CR2_ADON;
|
||||
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
||||
@@ -129,21 +134,48 @@ void adc_init (void)
|
||||
while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
|
||||
;
|
||||
ADC2->CR2 = 0;
|
||||
rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||
chSysUnlock ();
|
||||
RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
||||
}
|
||||
|
||||
static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags);
|
||||
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)
|
||||
{
|
||||
dmaStreamAllocate (NEUG_DMA_CHANNEL, STM32_ADC_ADC1_IRQ_PRIORITY,
|
||||
adc_lld_serve_rx_interrupt, NULL);
|
||||
dmaStreamSetPeripheral (NEUG_DMA_CHANNEL, &ADC1->DR);
|
||||
/* Use DMA channel 1. */
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
|
||||
DMA1->IFCR = 0xffffffff;
|
||||
|
||||
chSysLock ();
|
||||
|
||||
rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
||||
|
||||
ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
|
||||
| ADC_CR1_SCAN);
|
||||
@@ -169,12 +201,14 @@ void adc_start (void)
|
||||
ADC1->CR2 = 0;
|
||||
#endif
|
||||
|
||||
chSysUnlock ();
|
||||
adc_thd = chopstx_create (PRIO_ADC, __stackaddr_adc, __stacksize_adc,
|
||||
adc_intr_thread, NULL);
|
||||
}
|
||||
|
||||
static int adc_mode;
|
||||
static uint32_t *adc_ptr;
|
||||
static int adc_size;
|
||||
static uint32_t adc_buf[64];
|
||||
|
||||
static void adc_start_conversion_internal (void)
|
||||
{
|
||||
@@ -202,17 +236,19 @@ void adc_start_conversion (int mode, uint32_t *p, int size)
|
||||
|
||||
if (mode == ADC_SAMPLE_MODE)
|
||||
{
|
||||
dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, p);
|
||||
dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, size / 4);
|
||||
dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_SAMPLE);
|
||||
dmaStreamEnable (NEUG_DMA_CHANNEL);
|
||||
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
|
||||
DMA1_Channel1->CMAR = (uint32_t)p; /* SetMemory0 */
|
||||
DMA1_Channel1->CNDTR = (uint32_t)size / 4; /* counter */
|
||||
DMA1_Channel1->CCR = NEUG_DMA_MODE_SAMPLE; /*mode*/
|
||||
DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
|
||||
}
|
||||
else
|
||||
{
|
||||
dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, &CRC->DR);
|
||||
dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, NEUG_CRC32_COUNTS);
|
||||
dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_CRC32);
|
||||
dmaStreamEnable (NEUG_DMA_CHANNEL);
|
||||
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
|
||||
DMA1_Channel1->CMAR = (uint32_t)adc_buf; /* SetMemory0 */
|
||||
DMA1_Channel1->CNDTR = size; /* counter */
|
||||
DMA1_Channel1->CCR = NEUG_DMA_MODE_CRC32; /*mode*/
|
||||
DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
|
||||
}
|
||||
|
||||
adc_start_conversion_internal ();
|
||||
@@ -221,7 +257,8 @@ void adc_start_conversion (int mode, uint32_t *p, int size)
|
||||
|
||||
static void adc_stop_conversion (void)
|
||||
{
|
||||
dmaStreamDisable (NEUG_DMA_CHANNEL);
|
||||
DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
|
||||
|
||||
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
|
||||
ADC1->CR2 = 0;
|
||||
ADC2->CR2 = 0;
|
||||
@@ -239,15 +276,16 @@ void adc_stop (void)
|
||||
ADC2->CR1 = 0;
|
||||
ADC2->CR2 = 0;
|
||||
|
||||
dmaStreamRelease (NEUG_DMA_CHANNEL);
|
||||
rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
|
||||
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
|
||||
RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
||||
|
||||
chopstx_cancel (adc_thd);
|
||||
chopstx_join (adc_thd, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags)
|
||||
static void adc_lld_serve_rx_interrupt (uint32_t flags)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
|
||||
{
|
||||
/* Should never happened. If any, it's coding error. */
|
||||
@@ -262,27 +300,23 @@ static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags)
|
||||
|
||||
if (adc_mode != ADC_SAMPLE_MODE)
|
||||
{
|
||||
adc_size -= 4;
|
||||
*adc_ptr++ = CRC->DR;
|
||||
int i;
|
||||
|
||||
if (adc_size > 0)
|
||||
for (i = 0; i < adc_size;)
|
||||
{
|
||||
dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, &CRC->DR);
|
||||
dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, NEUG_CRC32_COUNTS);
|
||||
dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_CRC32);
|
||||
dmaStreamEnable (NEUG_DMA_CHANNEL);
|
||||
|
||||
adc_start_conversion_internal ();
|
||||
CRC->DR = adc_buf[i++];
|
||||
CRC->DR = adc_buf[i++];
|
||||
CRC->DR = adc_buf[i++];
|
||||
CRC->DR = adc_buf[i++];
|
||||
*adc_ptr++ = CRC->DR;
|
||||
}
|
||||
}
|
||||
|
||||
if (adc_mode == ADC_SAMPLE_MODE || adc_size <= 0)
|
||||
{
|
||||
chSysLockFromIsr();
|
||||
if (rng_thread)
|
||||
chEvtSignalFlagsI (rng_thread, ADC_DATA_AVAILABLE);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
chopstx_mutex_lock (&adc_mtx);
|
||||
adc_data_available++;
|
||||
if (adc_waiting)
|
||||
chopstx_cond_signal (&adc_cond);
|
||||
chopstx_mutex_unlock (&adc_mtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
#include "jpc-ac.h"
|
||||
#include "ec_p256.h"
|
||||
|
||||
#include "ch.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
|
||||
/* We are little endian. */
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "openpgp.h"
|
||||
#include "random.h"
|
||||
|
||||
@@ -6,4 +6,3 @@
|
||||
@PINPAD_DEFINE@
|
||||
@PINPAD_MORE_DEFINE@
|
||||
@CERTDO_DEFINE@
|
||||
#define FLASH_PAGE_SIZE @FLASH_PAGE_SIZE@
|
||||
|
||||
32
src/configure
vendored
32
src/configure
vendored
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||
#
|
||||
# Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
|
||||
# Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
#
|
||||
# This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
# Gnuk is free software: you can redistribute it and/or modify it
|
||||
@@ -86,12 +86,9 @@ Configuration:
|
||||
--target=TARGET specify target [OLIMEX_STM32_H103]
|
||||
supported targets are:
|
||||
OLIMEX_STM32_H103
|
||||
STM32_PRIMER2
|
||||
CQ_STARM
|
||||
STBEE_MINI
|
||||
STM8S_DISCOVERY
|
||||
STBEE
|
||||
FST_01
|
||||
FST_01_00
|
||||
--enable-debug debug with virtual COM port [no]
|
||||
--enable-pinpad={cir,dial}
|
||||
PIN entry support [no]
|
||||
@@ -107,13 +104,10 @@ if test "$vidpid" = "none"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BOARD_DIR=../boards/$target
|
||||
if test -d $BOARD_DIR; then
|
||||
echo "Configured for target: $target"
|
||||
else
|
||||
echo "Unsupported target \`$target'" >&2
|
||||
exit 1
|
||||
fi
|
||||
TARGET_DEFINE="#define BOARD_$target 1"
|
||||
BOARD_HEADER_FILE=board-`echo $target | tr '_[:upper:]' '-[:lower:]'`.h
|
||||
echo Header file is: $BOARD_HEADER_FILE
|
||||
ln -sf ../chopstx/board/$BOARD_HEADER_FILE board.h
|
||||
|
||||
# Flash page size in byte
|
||||
FLASH_PAGE_SIZE=1024
|
||||
@@ -172,6 +166,7 @@ else
|
||||
fi
|
||||
|
||||
# --enable-pinpad option
|
||||
MSC_SIZE="0"
|
||||
if test "$pinpad" = "no"; then
|
||||
PINPAD_MAKE_OPTION="# ENABLE_PINPAD="
|
||||
PINPAD_DEFINE="#undef PINPAD_SUPPORT"
|
||||
@@ -182,6 +177,9 @@ else
|
||||
PINPAD_DEFINE="#define PINPAD_SUPPORT 1"
|
||||
PINPAD_MORE_DEFINE="#define PINPAD_${pinpad^^[a-z]}_SUPPORT 1"
|
||||
echo "PIN pad option enabled ($pinpad)"
|
||||
if test "$pinpad" = "dnd"; then
|
||||
MSC_SIZE="0x0200"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --enable-certdo option
|
||||
@@ -250,7 +248,12 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed -e "s%@BOARD_DIR@%$BOARD_DIR%" \
|
||||
# Enable when you are sure that it's sys version 2.0.
|
||||
# Note that Gnuk 1.0 and Neug (until 0.06) uses sys version 1.0.
|
||||
# have_sys_h="-DHAVE_SYS_H"
|
||||
have_sys_h=""
|
||||
|
||||
sed -e "s%@HAVE_SYS_H@%$have_sys_h%" \
|
||||
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
|
||||
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
|
||||
-e "s%@KEYGEN_SUPPORT@%$KEYGEN_SUPPORT%" \
|
||||
@@ -260,12 +263,14 @@ if test "$certdo" = "yes"; then
|
||||
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
|
||||
-e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
|
||||
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
|
||||
-e "s/@MSC_SIZE@/$MSC_SIZE/" \
|
||||
< gnuk.ld.in > gnuk.ld
|
||||
else
|
||||
sed -e "/^@CERTDO_SUPPORT_START@$/,/^@CERTDO_SUPPORT_END@$/ d" \
|
||||
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
|
||||
-e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
|
||||
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
|
||||
-e "s/@MSC_SIZE@/$MSC_SIZE/" \
|
||||
< gnuk.ld.in > gnuk.ld
|
||||
fi
|
||||
sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
|
||||
@@ -273,6 +278,5 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
|
||||
-e "s/@PINPAD_DEFINE@/$PINPAD_DEFINE/" \
|
||||
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
|
||||
-e "s/@CERTDO_DEFINE@/$CERTDO_DEFINE/" \
|
||||
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
|
||||
< config.h.in > config.h
|
||||
exit 0
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "gnuk.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
extern void _write (const char *s, int len);
|
||||
|
||||
static void
|
||||
put_hex (uint8_t nibble)
|
||||
|
||||
9
src/debug.h
Normal file
9
src/debug.h
Normal file
@@ -0,0 +1,9 @@
|
||||
struct stdout {
|
||||
chopstx_mutex_t m;
|
||||
/**/
|
||||
chopstx_mutex_t m_dev;
|
||||
chopstx_cond_t cond_dev;
|
||||
uint8_t connected;
|
||||
};
|
||||
|
||||
extern struct stdout stdout;
|
||||
@@ -30,9 +30,12 @@
|
||||
* page(s).
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "sys.h"
|
||||
#include "gnuk.h"
|
||||
|
||||
|
||||
48
src/gnuk.h
48
src/gnuk.h
@@ -1,31 +1,3 @@
|
||||
/*
|
||||
* We declare some of libc functions here, because we will
|
||||
* remove dependency on libc in future, possibly.
|
||||
*/
|
||||
extern size_t strlen (const char *s);
|
||||
extern int strncmp(const char *s1, const char *s2, size_t n);
|
||||
extern void *memcpy (void *dest, const void *src, size_t n);
|
||||
extern void *memset (void *s, int c, size_t n);
|
||||
extern int memcmp (const void *s1, const void *s2, size_t n);
|
||||
extern void *memmove(void *dest, const void *src, size_t n);
|
||||
|
||||
/*
|
||||
* Debug functions
|
||||
*/
|
||||
extern Thread *stdout_thread;
|
||||
#define EV_TX_READY ((eventmask_t)1)
|
||||
|
||||
extern void put_byte (uint8_t b);
|
||||
extern void put_byte_with_no_nl (uint8_t b);
|
||||
extern void put_short (uint16_t x);
|
||||
extern void put_word (uint32_t x);
|
||||
extern void put_int (uint32_t x);
|
||||
extern void put_string (const char *s);
|
||||
extern void put_binary (const char *s, int len);
|
||||
|
||||
extern void _write (const char *, int);
|
||||
|
||||
|
||||
/*
|
||||
* Application layer <-> CCID layer data structure
|
||||
*/
|
||||
@@ -49,9 +21,9 @@ extern struct apdu apdu;
|
||||
#define EV_EXEC_FINISHED ((eventmask_t)2) /* GPG Execution finished */
|
||||
|
||||
/* GPG thread */
|
||||
#define EV_PINPAD_INPUT_DONE ((eventmask_t)1)
|
||||
#define EV_NOP ((eventmask_t)2)
|
||||
#define EV_CMD_AVAILABLE ((eventmask_t)4)
|
||||
#define EV_PINPAD_INPUT_DONE ((eventmask_t)1)
|
||||
#define EV_EXIT ((eventmask_t)2)
|
||||
#define EV_CMD_AVAILABLE ((eventmask_t)4)
|
||||
#define EV_VERIFY_CMD_AVAILABLE ((eventmask_t)8)
|
||||
#define EV_MODIFY_CMD_AVAILABLE ((eventmask_t)16)
|
||||
|
||||
@@ -222,6 +194,18 @@ extern int gpg_change_keystring (int who_old, const uint8_t *old_ks,
|
||||
extern struct key_data kd[3];
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_MORE 1
|
||||
/*
|
||||
* Debug functions in debug.c
|
||||
*/
|
||||
extern void put_byte (uint8_t b);
|
||||
extern void put_byte_with_no_nl (uint8_t b);
|
||||
extern void put_short (uint16_t x);
|
||||
extern void put_word (uint32_t x);
|
||||
extern void put_int (uint32_t x);
|
||||
extern void put_string (const char *s);
|
||||
extern void put_binary (const char *s, int len);
|
||||
|
||||
#define DEBUG_INFO(msg) put_string (msg)
|
||||
#define DEBUG_WORD(w) put_word (w)
|
||||
#define DEBUG_SHORT(h) put_short (h)
|
||||
@@ -396,4 +380,4 @@ extern int pinpad_getline (int msg_code, systime_t timeout);
|
||||
|
||||
#endif
|
||||
|
||||
extern uint8_t _regnual_start, __heap_end__;
|
||||
extern uint8_t _regnual_start, __heap_end__[];
|
||||
|
||||
139
src/gnuk.ld.in
139
src/gnuk.ld.in
@@ -1,34 +1,14 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ST32F103 memory setup.
|
||||
*/
|
||||
__main_stack_size__ = 0x0400;
|
||||
__process_stack_size__ = 0x0400;
|
||||
__main_stack_size__ = 0x0100; /* Exception handlers */
|
||||
__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 */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
@@ -39,7 +19,7 @@ MEMORY
|
||||
|
||||
/* __flash_start__: flash ROM start address regardless of DFU_SUPPORT */
|
||||
__flash_start__ = 0x08001000;
|
||||
__flash_end__ = ORIGIN(flash) + LENGTH(flash);
|
||||
__flash_end__ = ORIGIN(flash) + LENGTH(flash);
|
||||
|
||||
__ram_start__ = ORIGIN(ram);
|
||||
__ram_size__ = LENGTH(ram);
|
||||
@@ -49,46 +29,30 @@ SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
|
||||
.sys : ALIGN(16) SUBALIGN(16)
|
||||
.sys : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
_sys = .;
|
||||
KEEP(*(.vectors))
|
||||
. = ALIGN(16);
|
||||
*(.sys.version)
|
||||
*/sys.o(.text)
|
||||
*/sys.o(.text.*)
|
||||
*/sys.o(.rodata)
|
||||
*/sys.o(.rodata.*)
|
||||
. = ALIGN(1024);
|
||||
*(.sys.0)
|
||||
*(.sys.1)
|
||||
*(.sys.2)
|
||||
. = ALIGN(16);
|
||||
*(.sys.version)
|
||||
build/sys.o(.text)
|
||||
build/sys.o(.text.*)
|
||||
build/sys.o(.rodata)
|
||||
build/sys.o(.rodata.*)
|
||||
. = ALIGN(1024);
|
||||
*(.sys.0)
|
||||
*(.sys.1)
|
||||
*(.sys.2)
|
||||
} > flash0
|
||||
|
||||
_text = .;
|
||||
|
||||
startup : ALIGN(16) SUBALIGN(16)
|
||||
.startup : ALIGN(128) SUBALIGN(128)
|
||||
{
|
||||
KEEP(*(vectors))
|
||||
KEEP(*(.startup.vectors))
|
||||
. = ALIGN (16);
|
||||
} > flash =0xffffffff
|
||||
|
||||
constructors : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
PROVIDE(__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE(__init_array_end = .);
|
||||
} > flash
|
||||
|
||||
destructors : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
PROVIDE(__fini_array_start = .);
|
||||
KEEP(*(.fini_array))
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
PROVIDE(__fini_array_end = .);
|
||||
} > flash
|
||||
|
||||
.text : ALIGN(16) SUBALIGN(16)
|
||||
{
|
||||
*(.text.startup.*)
|
||||
@@ -120,17 +84,40 @@ 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__ = .;
|
||||
__process_stack_base__ = .;
|
||||
__main_thread_stack_base__ = .;
|
||||
. += __process_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process_stack_end__ = .;
|
||||
__main_thread_stack_end__ = .;
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
@@ -170,8 +157,8 @@ SECTIONS
|
||||
{
|
||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||
ch_certificate_start = .;
|
||||
LONG(0xffffffff);
|
||||
. += 1920;
|
||||
LONG(0xffffffff);
|
||||
. += 1920;
|
||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||
} > flash =0xffffffff
|
||||
@CERTDO_SUPPORT_END@
|
||||
@@ -179,16 +166,16 @@ SECTIONS
|
||||
.gnuk_flash :
|
||||
{
|
||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||
_data_pool = .;
|
||||
KEEP(*(.gnuk_data))
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += @FLASH_PAGE_SIZE@;
|
||||
_keystore_pool = .;
|
||||
. += 512*3;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_updatekey_store = .;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_data_pool = .;
|
||||
KEEP(*(.gnuk_data))
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += @FLASH_PAGE_SIZE@;
|
||||
_keystore_pool = .;
|
||||
. += 512*3;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_updatekey_store = .;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
} > flash =0xffffffff
|
||||
}
|
||||
|
||||
|
||||
389
src/main.c
389
src/main.c
@@ -21,141 +21,83 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <chopstx.h>
|
||||
#include <eventflag.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "adc.h"
|
||||
#include "gnuk.h"
|
||||
#include "usb_lld.h"
|
||||
#include "usb-cdc.h"
|
||||
#include "random.h"
|
||||
#include "stm32f103.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
struct stdout {
|
||||
Mutex m;
|
||||
CondVar start_cnd;
|
||||
CondVar finish_cnd;
|
||||
const char *str;
|
||||
int size;
|
||||
};
|
||||
#include "debug.h"
|
||||
|
||||
static struct stdout stdout;
|
||||
struct stdout stdout;
|
||||
|
||||
static void
|
||||
stdout_init (void)
|
||||
{
|
||||
chMtxInit (&stdout.m);
|
||||
chCondInit (&stdout.start_cnd);
|
||||
chCondInit (&stdout.finish_cnd);
|
||||
stdout.size = 0;
|
||||
stdout.str = NULL;
|
||||
chopstx_mutex_init (&stdout.m);
|
||||
chopstx_mutex_init (&stdout.m_dev);
|
||||
chopstx_cond_init (&stdout.cond_dev);
|
||||
stdout.connected = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_write (const char *s, int size)
|
||||
_write (const char *s, int len)
|
||||
{
|
||||
if (size == 0)
|
||||
int packet_len;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
chMtxLock (&stdout.m);
|
||||
while (stdout.str)
|
||||
chCondWait (&stdout.finish_cnd);
|
||||
stdout.str = s;
|
||||
stdout.size = size;
|
||||
chCondSignal (&stdout.start_cnd);
|
||||
chCondWait (&stdout.finish_cnd);
|
||||
chMtxUnlock ();
|
||||
}
|
||||
chopstx_mutex_lock (&stdout.m);
|
||||
|
||||
Thread *stdout_thread;
|
||||
uint32_t count_in;
|
||||
uint8_t buffer_in[VIRTUAL_COM_PORT_DATA_SIZE];
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
if (!stdout.connected)
|
||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
static WORKING_AREA(waSTDOUTthread, 128);
|
||||
|
||||
static msg_t
|
||||
STDOUTthread (void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
stdout_thread = chThdSelf ();
|
||||
|
||||
again:
|
||||
|
||||
while (1)
|
||||
do
|
||||
{
|
||||
if (bDeviceState == CONFIGURED)
|
||||
break;
|
||||
packet_len =
|
||||
(len < VIRTUAL_COM_PORT_DATA_SIZE) ? len : VIRTUAL_COM_PORT_DATA_SIZE;
|
||||
|
||||
chThdSleepMilliseconds (100);
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
usb_lld_write (ENDP3, s, packet_len);
|
||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
s += packet_len;
|
||||
len -= packet_len;
|
||||
}
|
||||
/* Send a Zero-Length-Packet if the last packet is full size. */
|
||||
while (len != 0 || packet_len == VIRTUAL_COM_PORT_DATA_SIZE);
|
||||
|
||||
while (1)
|
||||
{
|
||||
const char *p;
|
||||
int len;
|
||||
|
||||
if (bDeviceState != CONFIGURED)
|
||||
break;
|
||||
|
||||
chMtxLock (&stdout.m);
|
||||
if (stdout.str == NULL)
|
||||
chCondWait (&stdout.start_cnd);
|
||||
|
||||
p = stdout.str;
|
||||
len = stdout.size;
|
||||
while (1)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (len == 0)
|
||||
if (count_in != VIRTUAL_COM_PORT_DATA_SIZE)
|
||||
break;
|
||||
|
||||
if (len < VIRTUAL_COM_PORT_DATA_SIZE)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
buffer_in[i] = p[i];
|
||||
count_in = len;
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < VIRTUAL_COM_PORT_DATA_SIZE; i++)
|
||||
buffer_in[i] = p[i];
|
||||
len -= VIRTUAL_COM_PORT_DATA_SIZE;
|
||||
count_in = VIRTUAL_COM_PORT_DATA_SIZE;
|
||||
p += count_in;
|
||||
}
|
||||
|
||||
chEvtClear (EV_TX_READY);
|
||||
|
||||
usb_lld_write (ENDP3, buffer_in, count_in);
|
||||
|
||||
chEvtWaitOne (EV_TX_READY);
|
||||
}
|
||||
|
||||
stdout.str = NULL;
|
||||
stdout.size = 0;
|
||||
chCondBroadcast (&stdout.finish_cnd);
|
||||
chMtxUnlock ();
|
||||
}
|
||||
|
||||
goto again;
|
||||
return 0;
|
||||
chopstx_mutex_unlock (&stdout.m);
|
||||
}
|
||||
|
||||
void
|
||||
EP3_IN_Callback (void)
|
||||
{
|
||||
if (stdout_thread)
|
||||
chEvtSignalFlagsI (stdout_thread, EV_TX_READY);
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
chopstx_cond_signal (&stdout.cond_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
}
|
||||
|
||||
void
|
||||
EP5_OUT_Callback (void)
|
||||
{
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
usb_lld_rx_enable (ENDP5);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
}
|
||||
#else
|
||||
void
|
||||
@@ -166,18 +108,17 @@ _write (const char *s, int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
static WORKING_AREA(waUSBthread, 128);
|
||||
extern msg_t USBthread (void *arg);
|
||||
extern void *USBthread (void *arg);
|
||||
|
||||
/*
|
||||
* main thread does 1-bit LED display output
|
||||
*/
|
||||
#define MAIN_TIMEOUT_INTERVAL MS2ST(5000)
|
||||
#define MAIN_TIMEOUT_INTERVAL (5000*1000)
|
||||
|
||||
#define LED_TIMEOUT_INTERVAL MS2ST(75)
|
||||
#define LED_TIMEOUT_ZERO MS2ST(25)
|
||||
#define LED_TIMEOUT_ONE MS2ST(100)
|
||||
#define LED_TIMEOUT_STOP MS2ST(200)
|
||||
#define LED_TIMEOUT_INTERVAL (75*1000)
|
||||
#define LED_TIMEOUT_ZERO (25*1000)
|
||||
#define LED_TIMEOUT_ONE (100*1000)
|
||||
#define LED_TIMEOUT_STOP (200*1000)
|
||||
|
||||
|
||||
/* It has two-byte prefix and content is "FSIJ-1.0.1-" (2 + 11*2). */
|
||||
@@ -211,44 +152,44 @@ device_initialize_once (void)
|
||||
}
|
||||
}
|
||||
|
||||
static volatile uint8_t fatal_code;
|
||||
|
||||
static Thread *main_thread;
|
||||
static volatile uint8_t fatal_code;
|
||||
static struct eventflag led_event;
|
||||
|
||||
static void display_fatal_code (void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
set_led (1);
|
||||
chThdSleep (LED_TIMEOUT_ZERO);
|
||||
chopstx_usec_wait (LED_TIMEOUT_ZERO);
|
||||
set_led (0);
|
||||
chThdSleep (LED_TIMEOUT_INTERVAL);
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
set_led (1);
|
||||
chThdSleep (LED_TIMEOUT_ZERO);
|
||||
chopstx_usec_wait (LED_TIMEOUT_ZERO);
|
||||
set_led (0);
|
||||
chThdSleep (LED_TIMEOUT_INTERVAL);
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
set_led (1);
|
||||
chThdSleep (LED_TIMEOUT_ZERO);
|
||||
chopstx_usec_wait (LED_TIMEOUT_ZERO);
|
||||
set_led (0);
|
||||
chThdSleep (LED_TIMEOUT_STOP);
|
||||
chopstx_usec_wait (LED_TIMEOUT_STOP);
|
||||
set_led (1);
|
||||
if (fatal_code & 1)
|
||||
chThdSleep (LED_TIMEOUT_ONE);
|
||||
chopstx_usec_wait (LED_TIMEOUT_ONE);
|
||||
else
|
||||
chThdSleep (LED_TIMEOUT_ZERO);
|
||||
chopstx_usec_wait (LED_TIMEOUT_ZERO);
|
||||
set_led (0);
|
||||
chThdSleep (LED_TIMEOUT_INTERVAL);
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
set_led (1);
|
||||
if (fatal_code & 2)
|
||||
chThdSleep (LED_TIMEOUT_ONE);
|
||||
chopstx_usec_wait (LED_TIMEOUT_ONE);
|
||||
else
|
||||
chThdSleep (LED_TIMEOUT_ZERO);
|
||||
chopstx_usec_wait (LED_TIMEOUT_ZERO);
|
||||
set_led (0);
|
||||
chThdSleep (LED_TIMEOUT_INTERVAL);
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
set_led (1);
|
||||
chThdSleep (LED_TIMEOUT_STOP);
|
||||
chopstx_usec_wait (LED_TIMEOUT_STOP);
|
||||
set_led (0);
|
||||
chThdSleep (LED_TIMEOUT_INTERVAL*10);
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL*10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,10 +200,10 @@ static eventmask_t emit_led (int on_time, int off_time)
|
||||
eventmask_t m;
|
||||
|
||||
set_led (!led_inverted);
|
||||
m = chEvtWaitOneTimeout (ALL_EVENTS, on_time);
|
||||
m = eventflag_wait_timeout (&led_event, on_time);
|
||||
set_led (led_inverted);
|
||||
if (m) return m;
|
||||
if ((m = chEvtWaitOneTimeout (ALL_EVENTS, off_time)))
|
||||
if ((m = eventflag_wait_timeout (&led_event, off_time)))
|
||||
return m;
|
||||
return 0;
|
||||
}
|
||||
@@ -297,12 +238,12 @@ static eventmask_t display_status_code (void)
|
||||
|
||||
if (icc_state == ICC_STATE_WAIT)
|
||||
{
|
||||
if ((m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_STOP * 2)))
|
||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_STOP * 2)))
|
||||
return m;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_INTERVAL)))
|
||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_INTERVAL)))
|
||||
return m;
|
||||
|
||||
if ((m = emit_led (icc_state == ICC_STATE_RECEIVE?
|
||||
@@ -318,7 +259,7 @@ static eventmask_t display_status_code (void)
|
||||
void
|
||||
led_blink (int spec)
|
||||
{
|
||||
chEvtSignalFlags (main_thread, spec);
|
||||
eventflag_signal (&led_event, spec);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -338,6 +279,22 @@ calculate_regnual_entry_address (const uint8_t *addr)
|
||||
return v;
|
||||
}
|
||||
|
||||
extern uint8_t __process1_stack_base__, __process1_stack_size__;
|
||||
extern uint8_t __process5_stack_base__, __process5_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__;
|
||||
|
||||
#define PRIO_CCID 2
|
||||
#define PRIO_USB 4
|
||||
|
||||
extern void *usb_intr (void *arg);
|
||||
|
||||
static void gnuk_malloc_init (void);
|
||||
|
||||
|
||||
/*
|
||||
* Entry point.
|
||||
@@ -350,48 +307,45 @@ main (int argc, char *argv[])
|
||||
{
|
||||
unsigned int count = 0;
|
||||
uint32_t entry;
|
||||
chopstx_t usb_thd;
|
||||
chopstx_t ccid_thd;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
gnuk_malloc_init ();
|
||||
|
||||
flash_unlock ();
|
||||
device_initialize_once ();
|
||||
|
||||
halInit ();
|
||||
adc_init ();
|
||||
chSysInit ();
|
||||
|
||||
main_thread = chThdSelf ();
|
||||
eventflag_init (&led_event, chopstx_main);
|
||||
|
||||
usb_lld_init (usb_initial_feature);
|
||||
random_init ();
|
||||
|
||||
#ifdef DEBUG
|
||||
stdout_init ();
|
||||
#endif
|
||||
|
||||
ccid_thd = chopstx_create (PRIO_CCID, __stackaddr_ccid,
|
||||
__stacksize_ccid, USBthread, NULL);
|
||||
|
||||
usb_thd = chopstx_create (PRIO_USB, __stackaddr_usb, __stacksize_usb,
|
||||
usb_intr, NULL);
|
||||
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
msc_init ();
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (bDeviceState != UNCONNECTED)
|
||||
break;
|
||||
|
||||
chThdSleepMilliseconds (250);
|
||||
chopstx_usec_wait (250*1000);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
stdout_init ();
|
||||
|
||||
/*
|
||||
* Creates 'stdout' thread.
|
||||
*/
|
||||
chThdCreateStatic (waSTDOUTthread, sizeof(waSTDOUTthread),
|
||||
NORMALPRIO, STDOUTthread, NULL);
|
||||
#endif
|
||||
|
||||
chThdCreateStatic (waUSBthread, sizeof(waUSBthread),
|
||||
NORMALPRIO, USBthread, NULL);
|
||||
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
msc_init ();
|
||||
#endif
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m;
|
||||
@@ -399,17 +353,17 @@ main (int argc, char *argv[])
|
||||
if (icc_state_p != NULL && *icc_state_p == ICC_STATE_EXEC_REQUESTED)
|
||||
break;
|
||||
|
||||
m = chEvtWaitOneTimeout (ALL_EVENTS, MAIN_TIMEOUT_INTERVAL);
|
||||
m = eventflag_wait_timeout (&led_event, MAIN_TIMEOUT_INTERVAL);
|
||||
got_it:
|
||||
count++;
|
||||
switch (m)
|
||||
{
|
||||
case LED_ONESHOT:
|
||||
if ((m = emit_led (MS2ST (100), MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
if ((m = emit_led (100*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
break;
|
||||
case LED_TWOSHOTS:
|
||||
if ((m = emit_led (MS2ST (50), MS2ST (50)))) goto got_it;
|
||||
if ((m = emit_led (MS2ST (50), MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
if ((m = emit_led (50*1000, 50*1000))) goto got_it;
|
||||
if ((m = emit_led (50*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
break;
|
||||
case LED_SHOW_STATUS:
|
||||
if ((count & 0x07) != 0) continue; /* Display once for eight times */
|
||||
@@ -420,7 +374,7 @@ main (int argc, char *argv[])
|
||||
led_inverted = 1;
|
||||
break;
|
||||
case LED_FINISH_COMMAND:
|
||||
m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_STOP);
|
||||
m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_STOP);
|
||||
led_inverted = 0;
|
||||
set_led (0);
|
||||
if (m)
|
||||
@@ -436,12 +390,12 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MORE
|
||||
if (bDeviceState == CONFIGURED && (count % 10) == 0)
|
||||
if (stdout.connected && (count % 10) == 0)
|
||||
{
|
||||
DEBUG_SHORT (count / 10);
|
||||
_write ("\r\nThis is ChibiOS 2.0.8 on STM32.\r\n"
|
||||
_write ("\r\nThis is Gnuk on STM32F103.\r\n"
|
||||
"Testing USB driver.\n\n"
|
||||
"Hello world\r\n\r\n", 35+21+15);
|
||||
"Hello world\r\n\r\n", 30+21+15);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -450,10 +404,13 @@ main (int argc, char *argv[])
|
||||
|
||||
set_led (1);
|
||||
usb_lld_shutdown ();
|
||||
/* Disable SysTick */
|
||||
SysTick->CTRL = 0;
|
||||
/* Disable all interrupts */
|
||||
port_disable ();
|
||||
|
||||
/* Finish application. */
|
||||
chopstx_join (ccid_thd, NULL);
|
||||
|
||||
chopstx_cancel (usb_thd);
|
||||
chopstx_join (usb_thd, NULL);
|
||||
|
||||
/* Set vector */
|
||||
SCB->VTOR = (uint32_t)&_regnual_start;
|
||||
entry = calculate_regnual_entry_address (&_regnual_start);
|
||||
@@ -491,7 +448,115 @@ void
|
||||
fatal (uint8_t code)
|
||||
{
|
||||
fatal_code = code;
|
||||
chEvtSignalFlags (main_thread, LED_FATAL);
|
||||
eventflag_signal (&led_event, LED_FATAL);
|
||||
_write ("fatal\r\n", 7);
|
||||
for (;;);
|
||||
}
|
||||
|
||||
|
||||
extern uint8_t __heap_base__[];
|
||||
extern uint8_t __heap_end__[];
|
||||
|
||||
#define MEMORY_END (__heap_end__)
|
||||
#define ALIGN_TO_WORD(n) ((n + 3) & ~3)
|
||||
|
||||
static uint8_t *heap_p;
|
||||
static chopstx_mutex_t malloc_mtx;
|
||||
|
||||
/*
|
||||
* Assume the size of heap is less than 64KiB - 1.
|
||||
*/
|
||||
struct mem_head {
|
||||
uint16_t next_mem_offset; /* pointer to next. */
|
||||
uint16_t size;
|
||||
} __attribute__((packed));
|
||||
|
||||
static uint16_t free_mem_offset;
|
||||
#define FREE_MEM_NONE (0xffff)
|
||||
|
||||
static void
|
||||
gnuk_malloc_init (void)
|
||||
{
|
||||
chopstx_mutex_init (&malloc_mtx);
|
||||
heap_p = __heap_base__;
|
||||
free_mem_offset = FREE_MEM_NONE;
|
||||
}
|
||||
|
||||
static
|
||||
void *sbrk (size_t size)
|
||||
{
|
||||
void *p = (void *)heap_p;
|
||||
|
||||
if ((size_t)(__heap_end__ - heap_p) < size)
|
||||
return NULL;
|
||||
|
||||
heap_p += size;
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
gnuk_malloc (size_t size)
|
||||
{
|
||||
struct mem_head *m;
|
||||
uint16_t mem_offset;
|
||||
uint16_t *mem_offset_prev;
|
||||
|
||||
size = ALIGN_TO_WORD (size);
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
DEBUG_INFO ("malloc: ");
|
||||
DEBUG_SHORT (size);
|
||||
mem_offset_prev = &free_mem_offset;
|
||||
mem_offset = free_mem_offset;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (mem_offset == FREE_MEM_NONE)
|
||||
{
|
||||
m = sbrk (size + sizeof (struct mem_head));
|
||||
if (m)
|
||||
{
|
||||
m->next_mem_offset = FREE_MEM_NONE;
|
||||
m->size = size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m = (struct mem_head *)(__heap_base__ + mem_offset);
|
||||
if (m->size >= size)
|
||||
{
|
||||
*mem_offset_prev = m->next_mem_offset;
|
||||
m->next_mem_offset = FREE_MEM_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
mem_offset_prev = &m->next_mem_offset;
|
||||
mem_offset = m->next_mem_offset;
|
||||
}
|
||||
|
||||
chopstx_mutex_unlock (&malloc_mtx);
|
||||
if (m == NULL)
|
||||
{
|
||||
DEBUG_WORD (0);
|
||||
return m;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WORD ((uint32_t)(m+1));
|
||||
return (void *)(m + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gnuk_free (void *p)
|
||||
{
|
||||
struct mem_head *m = ((struct mem_head *)p) - 1;
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
DEBUG_INFO ("free: ");
|
||||
DEBUG_SHORT (m->size);
|
||||
DEBUG_WORD ((uint32_t)p);
|
||||
m->next_mem_offset = free_mem_offset;
|
||||
free_mem_offset = (uint16_t)((uint8_t *)m - __heap_base__);
|
||||
chopstx_mutex_unlock (&malloc_mtx);
|
||||
}
|
||||
|
||||
131
src/neug.c
131
src/neug.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* neug.c - random number generation (from NeuG/src/random.c)
|
||||
*
|
||||
* Copyright (C) 2011, 2012 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of NeuG, a True Random Number Generator
|
||||
@@ -22,18 +22,20 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h> /* for memcpy */
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "sys.h"
|
||||
#include "neug.h"
|
||||
#include "stm32f103.h"
|
||||
#include "adc.h"
|
||||
#include "sha256.h"
|
||||
|
||||
Thread *rng_thread;
|
||||
#define ADC_DATA_AVAILABLE ((eventmask_t)1)
|
||||
chopstx_mutex_t adc_mtx;
|
||||
chopstx_cond_t adc_cond;
|
||||
int adc_waiting;
|
||||
int adc_data_available;
|
||||
|
||||
static uint32_t adc_buf[SHA256_BLOCK_SIZE/sizeof (uint32_t)];
|
||||
|
||||
@@ -95,7 +97,8 @@ static void ep_fill_initial_string (void)
|
||||
|
||||
static void ep_init (int mode)
|
||||
{
|
||||
chEvtClearFlags (ADC_DATA_AVAILABLE);
|
||||
adc_data_available = 0;
|
||||
|
||||
if (mode == NEUG_MODE_RAW)
|
||||
{
|
||||
ep_round = EP_ROUND_RAW;
|
||||
@@ -356,9 +359,9 @@ static void noise_source_continuous_test (uint8_t noise)
|
||||
*/
|
||||
struct rng_rb {
|
||||
uint32_t *buf;
|
||||
Mutex m;
|
||||
CondVar data_available;
|
||||
CondVar space_available;
|
||||
chopstx_mutex_t m;
|
||||
chopstx_cond_t data_available;
|
||||
chopstx_cond_t space_available;
|
||||
uint8_t head, tail;
|
||||
uint8_t size;
|
||||
unsigned int full :1;
|
||||
@@ -369,9 +372,9 @@ static void rb_init (struct rng_rb *rb, uint32_t *p, uint8_t size)
|
||||
{
|
||||
rb->buf = p;
|
||||
rb->size = size;
|
||||
chMtxInit (&rb->m);
|
||||
chCondInit (&rb->data_available);
|
||||
chCondInit (&rb->space_available);
|
||||
chopstx_mutex_init (&rb->m);
|
||||
chopstx_cond_init (&rb->data_available);
|
||||
chopstx_cond_init (&rb->space_available);
|
||||
rb->head = rb->tail = 0;
|
||||
rb->full = 0;
|
||||
rb->empty = 1;
|
||||
@@ -401,27 +404,41 @@ static uint32_t rb_del (struct rng_rb *rb)
|
||||
}
|
||||
|
||||
uint8_t neug_mode;
|
||||
static int rng_should_terminate;
|
||||
static chopstx_t rng_thread;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Random number generation thread.
|
||||
*/
|
||||
static msg_t rng (void *arg)
|
||||
static void *
|
||||
rng (void *arg)
|
||||
{
|
||||
struct rng_rb *rb = (struct rng_rb *)arg;
|
||||
|
||||
rng_thread = chThdSelf ();
|
||||
rng_should_terminate = 0;
|
||||
chopstx_mutex_init (&adc_mtx);
|
||||
chopstx_cond_init (&adc_cond);
|
||||
|
||||
/* Enable ADCs */
|
||||
adc_start ();
|
||||
|
||||
ep_init (NEUG_MODE_CONDITIONED);
|
||||
|
||||
while (!chThdShouldTerminate ())
|
||||
while (!rng_should_terminate)
|
||||
{
|
||||
int n;
|
||||
int mode = neug_mode;
|
||||
|
||||
chEvtWaitOne (ADC_DATA_AVAILABLE); /* Get ADC sampling. */
|
||||
chopstx_mutex_lock (&adc_mtx);
|
||||
if (!adc_data_available)
|
||||
{
|
||||
adc_waiting = 1;
|
||||
chopstx_cond_wait (&adc_cond, &adc_mtx);
|
||||
adc_waiting = 0;
|
||||
}
|
||||
adc_data_available = 0;
|
||||
chopstx_mutex_unlock (&adc_mtx);
|
||||
|
||||
if ((n = ep_process (mode)))
|
||||
{
|
||||
@@ -438,9 +455,9 @@ static msg_t rng (void *arg)
|
||||
|
||||
vp = ep_output (mode);
|
||||
|
||||
chMtxLock (&rb->m);
|
||||
chopstx_mutex_lock (&rb->m);
|
||||
while (rb->full)
|
||||
chCondWait (&rb->space_available);
|
||||
chopstx_cond_wait (&rb->space_available, &rb->m);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
@@ -449,18 +466,22 @@ static msg_t rng (void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
chCondSignal (&rb->data_available);
|
||||
chMtxUnlock ();
|
||||
chopstx_cond_signal (&rb->data_available);
|
||||
chopstx_mutex_unlock (&rb->m);
|
||||
}
|
||||
}
|
||||
|
||||
adc_stop ();
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct rng_rb the_ring_buffer;
|
||||
static WORKING_AREA(wa_rng, 256);
|
||||
|
||||
extern uint8_t __process2_stack_base__, __process2_stack_size__;
|
||||
const uint32_t __stackaddr_rng = (uint32_t)&__process2_stack_base__;
|
||||
const size_t __stacksize_rng = (size_t)&__process2_stack_size__;
|
||||
#define PRIO_RNG 2
|
||||
|
||||
/**
|
||||
* @brief Initialize NeuG.
|
||||
@@ -484,7 +505,9 @@ neug_init (uint32_t *buf, uint8_t size)
|
||||
|
||||
neug_mode = NEUG_MODE_CONDITIONED;
|
||||
rb_init (rb, buf, size);
|
||||
chThdCreateStatic (wa_rng, sizeof (wa_rng), NORMALPRIO, rng, rb);
|
||||
|
||||
rng_thread = chopstx_create (PRIO_RNG, __stackaddr_rng, __stacksize_rng,
|
||||
rng, rb);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -495,11 +518,11 @@ neug_flush (void)
|
||||
{
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
|
||||
chMtxLock (&rb->m);
|
||||
chopstx_mutex_lock (&rb->m);
|
||||
while (!rb->empty)
|
||||
(void)rb_del (rb);
|
||||
chCondSignal (&rb->space_available);
|
||||
chMtxUnlock ();
|
||||
chopstx_cond_signal (&rb->space_available);
|
||||
chopstx_mutex_unlock (&rb->m);
|
||||
}
|
||||
|
||||
|
||||
@@ -511,10 +534,10 @@ neug_kick_filling (void)
|
||||
{
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
|
||||
chMtxLock (&rb->m);
|
||||
chopstx_mutex_lock (&rb->m);
|
||||
if (!rb->full)
|
||||
chCondSignal (&rb->space_available);
|
||||
chMtxUnlock ();
|
||||
chopstx_cond_signal (&rb->space_available);
|
||||
chopstx_mutex_unlock (&rb->m);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -529,13 +552,13 @@ neug_get (int kick)
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
uint32_t v;
|
||||
|
||||
chMtxLock (&rb->m);
|
||||
chopstx_mutex_lock (&rb->m);
|
||||
while (rb->empty)
|
||||
chCondWait (&rb->data_available);
|
||||
chopstx_cond_wait (&rb->data_available, &rb->m);
|
||||
v = rb_del (rb);
|
||||
if (kick)
|
||||
chCondSignal (&rb->space_available);
|
||||
chMtxUnlock ();
|
||||
chopstx_cond_signal (&rb->space_available);
|
||||
chopstx_mutex_unlock (&rb->m);
|
||||
|
||||
return v;
|
||||
}
|
||||
@@ -546,15 +569,15 @@ neug_get_nonblock (uint32_t *p)
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
int r = 0;
|
||||
|
||||
chMtxLock (&rb->m);
|
||||
chopstx_mutex_lock (&rb->m);
|
||||
if (rb->empty)
|
||||
{
|
||||
r = -1;
|
||||
chCondSignal (&rb->space_available);
|
||||
chopstx_cond_signal (&rb->space_available);
|
||||
}
|
||||
else
|
||||
*p = rb_del (rb);
|
||||
chMtxUnlock ();
|
||||
chopstx_mutex_unlock (&rb->m);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -564,7 +587,7 @@ int neug_consume_random (void (*proc) (uint32_t, int))
|
||||
int i = 0;
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
|
||||
chMtxLock (&rb->m);
|
||||
chopstx_mutex_lock (&rb->m);
|
||||
while (!rb->empty)
|
||||
{
|
||||
uint32_t v;
|
||||
@@ -573,8 +596,8 @@ int neug_consume_random (void (*proc) (uint32_t, int))
|
||||
proc (v, i);
|
||||
i++;
|
||||
}
|
||||
chCondSignal (&rb->space_available);
|
||||
chMtxUnlock ();
|
||||
chopstx_cond_signal (&rb->space_available);
|
||||
chopstx_mutex_unlock (&rb->m);
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -584,22 +607,18 @@ neug_wait_full (void)
|
||||
{
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
|
||||
chMtxLock (&rb->m);
|
||||
chopstx_mutex_lock (&rb->m);
|
||||
while (!rb->full)
|
||||
chCondWait (&rb->data_available);
|
||||
chMtxUnlock ();
|
||||
chopstx_cond_wait (&rb->data_available, &rb->m);
|
||||
chopstx_mutex_unlock (&rb->m);
|
||||
}
|
||||
|
||||
void
|
||||
neug_fini (void)
|
||||
{
|
||||
if (rng_thread)
|
||||
{
|
||||
chThdTerminate (rng_thread);
|
||||
neug_get (1);
|
||||
chThdWait (rng_thread);
|
||||
rng_thread = NULL;
|
||||
}
|
||||
rng_should_terminate = 1;
|
||||
neug_get (1);
|
||||
chopstx_join (rng_thread, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -610,8 +629,14 @@ neug_mode_select (uint8_t mode)
|
||||
|
||||
neug_wait_full ();
|
||||
|
||||
while (rng_thread->p_state != THD_STATE_WTCOND)
|
||||
chThdSleep (MS2ST (1));
|
||||
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 ();
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "gnuk.h"
|
||||
#include "openpgp.h"
|
||||
|
||||
@@ -22,15 +22,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <chopstx.h>
|
||||
#include <eventflag.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "sys.h"
|
||||
#include "openpgp.h"
|
||||
#include "sha256.h"
|
||||
#include "random.h"
|
||||
|
||||
static struct eventflag *openpgp_comm;
|
||||
|
||||
#define ADMIN_PASSWD_MINLEN 8
|
||||
|
||||
#define CLS(a) a.cmd_apdu_head[0]
|
||||
@@ -1081,7 +1087,7 @@ cmd_external_authenticate (void)
|
||||
return;
|
||||
}
|
||||
|
||||
chThdTerminate (chThdSelf ());
|
||||
eventflag_signal (openpgp_comm, EV_EXIT); /* signal to self. */
|
||||
set_res_sw (0xff, 0xff);
|
||||
DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
|
||||
}
|
||||
@@ -1161,18 +1167,17 @@ process_command_apdu (void)
|
||||
}
|
||||
}
|
||||
|
||||
msg_t
|
||||
void *
|
||||
GPGthread (void *arg)
|
||||
{
|
||||
Thread *icc_thread = (Thread *)arg;
|
||||
struct eventflag *ccid_comm = (struct eventflag *)arg;
|
||||
openpgp_comm = ccid_comm + 1;
|
||||
|
||||
gpg_init ();
|
||||
|
||||
chEvtClearFlags (ALL_EVENTS);
|
||||
|
||||
while (!chThdShouldTerminate ())
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m = chEvtWaitOne (ALL_EVENTS);
|
||||
eventmask_t m = eventflag_wait (openpgp_comm);
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
int len, pw_len, newpw_len;
|
||||
#endif
|
||||
@@ -1259,16 +1264,16 @@ GPGthread (void *arg)
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
else if (m == EV_NOP)
|
||||
continue;
|
||||
else if (m == EV_EXIT)
|
||||
break;
|
||||
|
||||
led_blink (LED_START_COMMAND);
|
||||
process_command_apdu ();
|
||||
led_blink (LED_FINISH_COMMAND);
|
||||
done:
|
||||
chEvtSignalFlags (icc_thread, EV_EXEC_FINISHED);
|
||||
eventflag_signal (ccid_comm, EV_EXEC_FINISHED);
|
||||
}
|
||||
|
||||
gpg_fini ();
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "neug.h"
|
||||
|
||||
|
||||
13
src/stdlib.h
13
src/stdlib.h
@@ -1,10 +1,13 @@
|
||||
/*
|
||||
* stdlib.h replacement, so that we can replace malloc functions
|
||||
* stdlib.h replacement to replace malloc functions
|
||||
*/
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#include "ch.h"
|
||||
#include "chheap.h"
|
||||
#define malloc(size) chHeapAlloc (NULL, size)
|
||||
#define free(p) chHeapFree (p)
|
||||
#include <stddef.h> /* NULL */
|
||||
|
||||
#define malloc(size) gnuk_malloc (size)
|
||||
#define free(p) gnuk_free (p)
|
||||
|
||||
void *gnuk_malloc (size_t);
|
||||
void gnuk_free (void *);
|
||||
|
||||
204
src/stm32f103.h
Normal file
204
src/stm32f103.h
Normal file
@@ -0,0 +1,204 @@
|
||||
#define PERIPH_BASE 0x40000000
|
||||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
|
||||
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
|
||||
|
||||
#define RCC_APB2RSTR_ADC1RST 0x00000200
|
||||
#define RCC_APB2RSTR_ADC2RST 0x00000400
|
||||
|
||||
struct RCC {
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t CIR;
|
||||
volatile uint32_t APB2RSTR;
|
||||
volatile uint32_t APB1RSTR;
|
||||
volatile uint32_t AHBENR;
|
||||
volatile uint32_t APB2ENR;
|
||||
volatile uint32_t APB1ENR;
|
||||
volatile uint32_t BDCR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
|
||||
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
|
||||
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
|
||||
|
||||
#define RCC_AHBENR_DMA1EN 0x00000001
|
||||
#define RCC_AHBENR_CRCEN 0x00000040
|
||||
|
||||
#define RCC_APB2ENR_ADC1EN 0x00000200
|
||||
#define RCC_APB2ENR_ADC2EN 0x00000400
|
||||
|
||||
#define CRC_CR_RESET 0x00000001
|
||||
|
||||
struct CRC {
|
||||
volatile uint32_t DR;
|
||||
volatile uint8_t IDR;
|
||||
uint8_t RESERVED0;
|
||||
uint16_t RESERVED1;
|
||||
volatile uint32_t CR;
|
||||
};
|
||||
|
||||
#define CRC_BASE (AHBPERIPH_BASE + 0x3000)
|
||||
static struct CRC *const CRC = ((struct CRC *const)CRC_BASE);
|
||||
|
||||
|
||||
struct ADC {
|
||||
volatile uint32_t SR;
|
||||
volatile uint32_t CR1;
|
||||
volatile uint32_t CR2;
|
||||
volatile uint32_t SMPR1;
|
||||
volatile uint32_t SMPR2;
|
||||
volatile uint32_t JOFR1;
|
||||
volatile uint32_t JOFR2;
|
||||
volatile uint32_t JOFR3;
|
||||
volatile uint32_t JOFR4;
|
||||
volatile uint32_t HTR;
|
||||
volatile uint32_t LTR;
|
||||
volatile uint32_t SQR1;
|
||||
volatile uint32_t SQR2;
|
||||
volatile uint32_t SQR3;
|
||||
volatile uint32_t JSQR;
|
||||
volatile uint32_t JDR1;
|
||||
volatile uint32_t JDR2;
|
||||
volatile uint32_t JDR3;
|
||||
volatile uint32_t JDR4;
|
||||
volatile uint32_t DR;
|
||||
};
|
||||
|
||||
#define ADC1_BASE (APB2PERIPH_BASE + 0x2400)
|
||||
#define ADC2_BASE (APB2PERIPH_BASE + 0x2800)
|
||||
|
||||
static struct ADC *const ADC1 = (struct ADC *const)ADC1_BASE;
|
||||
static struct ADC *const ADC2 = (struct ADC *const)ADC2_BASE;
|
||||
|
||||
#define ADC_CR1_DUALMOD_0 0x00010000
|
||||
#define ADC_CR1_DUALMOD_1 0x00020000
|
||||
#define ADC_CR1_DUALMOD_2 0x00040000
|
||||
#define ADC_CR1_DUALMOD_3 0x00080000
|
||||
|
||||
#define ADC_CR1_SCAN 0x00000100
|
||||
|
||||
#define ADC_CR2_ADON 0x00000001
|
||||
#define ADC_CR2_CONT 0x00000002
|
||||
#define ADC_CR2_CAL 0x00000004
|
||||
#define ADC_CR2_RSTCAL 0x00000008
|
||||
#define ADC_CR2_DMA 0x00000100
|
||||
#define ADC_CR2_ALIGN 0x00000800
|
||||
#define ADC_CR2_EXTSEL 0x000E0000
|
||||
#define ADC_CR2_EXTSEL_0 0x00020000
|
||||
#define ADC_CR2_EXTSEL_1 0x00040000
|
||||
#define ADC_CR2_EXTSEL_2 0x00080000
|
||||
#define ADC_CR2_EXTTRIG 0x00100000
|
||||
#define ADC_CR2_SWSTART 0x00400000
|
||||
#define ADC_CR2_TSVREFE 0x00800000
|
||||
|
||||
struct DMA_Channel {
|
||||
volatile uint32_t CCR;
|
||||
volatile uint32_t CNDTR;
|
||||
volatile uint32_t CPAR;
|
||||
volatile uint32_t CMAR;
|
||||
};
|
||||
|
||||
struct DMA {
|
||||
volatile uint32_t ISR;
|
||||
volatile uint32_t IFCR;
|
||||
};
|
||||
|
||||
#define STM32_DMA_CR_MINC DMA_CCR1_MINC
|
||||
#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1
|
||||
#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1
|
||||
#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE
|
||||
#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE
|
||||
#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE
|
||||
#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
|
||||
#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
|
||||
#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
|
||||
|
||||
#define STM32_DMA_ISR_MASK 0x0F
|
||||
#define STM32_DMA_CCR_RESET_VALUE 0x00000000
|
||||
#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL
|
||||
#define STM32_DMA_CR_PL(n) ((n) << 12)
|
||||
|
||||
#define DMA_CCR1_EN 0x00000001
|
||||
#define DMA_CCR1_TCIE 0x00000002
|
||||
#define DMA_CCR1_HTIE 0x00000004
|
||||
#define DMA_CCR1_TEIE 0x00000008
|
||||
#define DMA_CCR1_DIR 0x00000010
|
||||
#define DMA_CCR1_CIRC 0x00000020
|
||||
#define DMA_CCR1_PINC 0x00000040
|
||||
#define DMA_CCR1_MINC 0x00000080
|
||||
#define DMA_CCR1_PSIZE 0x00000300
|
||||
#define DMA_CCR1_PSIZE_0 0x00000100
|
||||
#define DMA_CCR1_PSIZE_1 0x00000200
|
||||
#define DMA_CCR1_MSIZE 0x00000C00
|
||||
#define DMA_CCR1_MSIZE_0 0x00000400
|
||||
#define DMA_CCR1_MSIZE_1 0x00000800
|
||||
#define DMA_CCR1_PL 0x00003000
|
||||
#define DMA_CCR1_PL_0 0x00001000
|
||||
#define DMA_CCR1_PL_1 0x00002000
|
||||
#define DMA_CCR1_MEM2MEM 0x00004000
|
||||
|
||||
#define DMA_ISR_GIF1 0x00000001
|
||||
#define DMA_ISR_TCIF1 0x00000002
|
||||
#define DMA_ISR_HTIF1 0x00000004
|
||||
#define DMA_ISR_TEIF1 0x00000008
|
||||
#define DMA_ISR_GIF2 0x00000010
|
||||
#define DMA_ISR_TCIF2 0x00000020
|
||||
#define DMA_ISR_HTIF2 0x00000040
|
||||
#define DMA_ISR_TEIF2 0x00000080
|
||||
#define DMA_ISR_GIF3 0x00000100
|
||||
#define DMA_ISR_TCIF3 0x00000200
|
||||
#define DMA_ISR_HTIF3 0x00000400
|
||||
#define DMA_ISR_TEIF3 0x00000800
|
||||
#define DMA_ISR_GIF4 0x00001000
|
||||
#define DMA_ISR_TCIF4 0x00002000
|
||||
#define DMA_ISR_HTIF4 0x00004000
|
||||
#define DMA_ISR_TEIF4 0x00008000
|
||||
#define DMA_ISR_GIF5 0x00010000
|
||||
#define DMA_ISR_TCIF5 0x00020000
|
||||
#define DMA_ISR_HTIF5 0x00040000
|
||||
#define DMA_ISR_TEIF5 0x00080000
|
||||
#define DMA_ISR_GIF6 0x00100000
|
||||
#define DMA_ISR_TCIF6 0x00200000
|
||||
#define DMA_ISR_HTIF6 0x00400000
|
||||
#define DMA_ISR_TEIF6 0x00800000
|
||||
#define DMA_ISR_GIF7 0x01000000
|
||||
#define DMA_ISR_TCIF7 0x02000000
|
||||
#define DMA_ISR_HTIF7 0x04000000
|
||||
#define DMA_ISR_TEIF7 0x08000000
|
||||
|
||||
#define DMA1_BASE (AHBPERIPH_BASE + 0x0000)
|
||||
static struct DMA *const DMA1 = (struct DMA *const)DMA1_BASE;
|
||||
|
||||
#define DMA1_Channel1_BASE (AHBPERIPH_BASE + 0x0008)
|
||||
static struct DMA_Channel *const DMA1_Channel1 =
|
||||
(struct DMA_Channel *const)DMA1_Channel1_BASE;
|
||||
|
||||
/* System Control Block */
|
||||
struct SCB
|
||||
{
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMFAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t ADR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
uint32_t RESERVED0[5];
|
||||
volatile uint32_t CPACR;
|
||||
};
|
||||
|
||||
#define SCS_BASE 0xE000E000
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = (struct SCB *const)SCB_BASE;
|
||||
432
src/sys.c
432
src/sys.c
@@ -1,62 +1,330 @@
|
||||
/*
|
||||
* sys.c - system services at the first flash ROM blocks
|
||||
* sys.c - system routines for the initial page for STM32F103.
|
||||
*
|
||||
* Copyright (C) 2012 Free Software Initiative of Japan
|
||||
* Copyright (C) 2013 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
*
|
||||
* Gnuk is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* Copying and distribution of this file, with or without modification,
|
||||
* are permitted in any medium without royalty provided the copyright
|
||||
* notice and this notice are preserved. This file is offered as-is,
|
||||
* without any warranty.
|
||||
*
|
||||
* When the flash ROM is protected, we cannot modify the initial page.
|
||||
* We put some system routines (which is useful for any program) here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "board.h"
|
||||
#include "usb_lld.h"
|
||||
|
||||
extern uint8_t __flash_start__, __flash_end__;
|
||||
|
||||
#define CORTEX_PRIORITY_BITS 4
|
||||
#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
|
||||
#define USB_LP_CAN1_RX0_IRQn 20
|
||||
#define STM32_USB_IRQ_PRIORITY 11
|
||||
|
||||
|
||||
#define STM32_SW_PLL (2 << 0)
|
||||
#define STM32_PLLSRC_HSE (1 << 16)
|
||||
|
||||
#define STM32_PLLXTPRE_DIV1 (0 << 17)
|
||||
#define STM32_PLLXTPRE_DIV2 (1 << 17)
|
||||
|
||||
#define STM32_HPRE_DIV1 (0 << 4)
|
||||
|
||||
#define STM32_PPRE1_DIV2 (4 << 8)
|
||||
|
||||
#define STM32_PPRE2_DIV1 (0 << 11)
|
||||
#define STM32_PPRE2_DIV2 (4 << 11)
|
||||
|
||||
#define STM32_ADCPRE_DIV4 (1 << 14)
|
||||
#define STM32_ADCPRE_DIV6 (2 << 14)
|
||||
|
||||
#define STM32_USBPRE_DIV1P5 (0 << 22)
|
||||
|
||||
#define STM32_MCO_NOCLOCK (0 << 24)
|
||||
|
||||
#define STM32_SW STM32_SW_PLL
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSE
|
||||
#define STM32_HPRE STM32_HPRE_DIV1
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV2
|
||||
#define STM32_PPRE2 STM32_PPRE2_DIV1
|
||||
#define STM32_ADCPRE STM32_ADCPRE_DIV6
|
||||
#define STM32_MCOSEL STM32_MCO_NOCLOCK
|
||||
#define STM32_USBPRE STM32_USBPRE_DIV1P5
|
||||
|
||||
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
|
||||
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
|
||||
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
|
||||
#define STM32_SYSCLK STM32_PLLCLKOUT
|
||||
#define STM32_HCLK (STM32_SYSCLK / 1)
|
||||
|
||||
#define STM32_FLASHBITS 0x00000012
|
||||
|
||||
struct NVIC {
|
||||
uint32_t ISER[8];
|
||||
uint32_t unused1[24];
|
||||
uint32_t ICER[8];
|
||||
uint32_t unused2[24];
|
||||
uint32_t ISPR[8];
|
||||
uint32_t unused3[24];
|
||||
uint32_t ICPR[8];
|
||||
uint32_t unused4[24];
|
||||
uint32_t IABR[8];
|
||||
uint32_t unused5[56];
|
||||
uint32_t IPR[60];
|
||||
};
|
||||
|
||||
static struct NVIC *const NVICBase = ((struct NVIC *const)0xE000E100);
|
||||
#define NVIC_ISER(n) (NVICBase->ISER[n >> 5])
|
||||
#define NVIC_ICPR(n) (NVICBase->ICPR[n >> 5])
|
||||
#define NVIC_IPR(n) (NVICBase->IPR[n >> 2])
|
||||
|
||||
static void
|
||||
nvic_enable_vector (uint32_t n, uint32_t prio)
|
||||
{
|
||||
unsigned int sh = (n & 3) << 3;
|
||||
|
||||
NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (prio << sh);
|
||||
NVIC_ICPR (n) = 1 << (n & 0x1F);
|
||||
NVIC_ISER (n) = 1 << (n & 0x1F);
|
||||
}
|
||||
|
||||
|
||||
#define PERIPH_BASE 0x40000000
|
||||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
|
||||
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
|
||||
|
||||
struct RCC {
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t CIR;
|
||||
volatile uint32_t APB2RSTR;
|
||||
volatile uint32_t APB1RSTR;
|
||||
volatile uint32_t AHBENR;
|
||||
volatile uint32_t APB2ENR;
|
||||
volatile uint32_t APB1ENR;
|
||||
volatile uint32_t BDCR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
|
||||
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
|
||||
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
|
||||
|
||||
#define RCC_APB1ENR_USBEN 0x00800000
|
||||
#define RCC_APB1RSTR_USBRST 0x00800000
|
||||
|
||||
#define RCC_CR_HSION 0x00000001
|
||||
#define RCC_CR_HSIRDY 0x00000002
|
||||
#define RCC_CR_HSITRIM 0x000000F8
|
||||
#define RCC_CR_HSEON 0x00010000
|
||||
#define RCC_CR_HSERDY 0x00020000
|
||||
#define RCC_CR_PLLON 0x01000000
|
||||
#define RCC_CR_PLLRDY 0x02000000
|
||||
|
||||
#define RCC_CFGR_SWS 0x0000000C
|
||||
#define RCC_CFGR_SWS_HSI 0x00000000
|
||||
|
||||
#define RCC_AHBENR_CRCEN 0x0040
|
||||
|
||||
struct FLASH {
|
||||
volatile uint32_t ACR;
|
||||
volatile uint32_t KEYR;
|
||||
volatile uint32_t OPTKEYR;
|
||||
volatile uint32_t SR;
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t AR;
|
||||
volatile uint32_t RESERVED;
|
||||
volatile uint32_t OBR;
|
||||
volatile uint32_t WRPR;
|
||||
};
|
||||
|
||||
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
|
||||
static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE);
|
||||
|
||||
static void
|
||||
clock_init (void)
|
||||
{
|
||||
/* HSI setup */
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
while (!(RCC->CR & RCC_CR_HSIRDY))
|
||||
;
|
||||
RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION;
|
||||
RCC->CFGR = 0;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
|
||||
;
|
||||
|
||||
/* HSE setup */
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR & RCC_CR_HSERDY))
|
||||
;
|
||||
|
||||
/* PLL setup */
|
||||
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR & RCC_CR_PLLRDY))
|
||||
;
|
||||
|
||||
/* Clock settings */
|
||||
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
|
||||
| STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
|
||||
|
||||
/* Flash setup */
|
||||
FLASH->ACR = STM32_FLASHBITS;
|
||||
|
||||
/* CRC */
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
|
||||
/* Switching on the configured clock source. */
|
||||
RCC->CFGR |= STM32_SW;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
|
||||
;
|
||||
}
|
||||
|
||||
#define RCC_APB2ENR_IOPAEN 0x00000004
|
||||
#define RCC_APB2RSTR_IOPARST 0x00000004
|
||||
#define RCC_APB2ENR_IOPBEN 0x00000008
|
||||
#define RCC_APB2RSTR_IOPBRST 0x00000008
|
||||
#define RCC_APB2ENR_IOPCEN 0x00000010
|
||||
#define RCC_APB2RSTR_IOPCRST 0x00000010
|
||||
#define RCC_APB2ENR_IOPDEN 0x00000020
|
||||
#define RCC_APB2RSTR_IOPDRST 0x00000020
|
||||
|
||||
|
||||
struct GPIO {
|
||||
volatile uint32_t CRL;
|
||||
volatile uint32_t CRH;
|
||||
volatile uint32_t IDR;
|
||||
volatile uint32_t ODR;
|
||||
volatile uint32_t BSRR;
|
||||
volatile uint32_t BRR;
|
||||
volatile uint32_t LCKR;
|
||||
};
|
||||
|
||||
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
|
||||
#define GPIOA ((struct GPIO *) GPIOA_BASE)
|
||||
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
|
||||
#define GPIOB ((struct GPIO *) GPIOB_BASE)
|
||||
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
|
||||
#define GPIOC ((struct GPIO *) GPIOC_BASE)
|
||||
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
|
||||
#define GPIOD ((struct GPIO *) GPIOD_BASE)
|
||||
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
|
||||
#define GPIOE ((struct GPIO *) GPIOE_BASE)
|
||||
|
||||
static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
|
||||
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
|
||||
|
||||
static void
|
||||
gpio_init (void)
|
||||
{
|
||||
/* Enable GPIO clock. */
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOP_EN;
|
||||
RCC->APB2RSTR = RCC_APB2RSTR_IOP_RST;
|
||||
RCC->APB2RSTR = 0;
|
||||
|
||||
GPIO_USB->ODR = VAL_GPIO_ODR;
|
||||
GPIO_USB->CRH = VAL_GPIO_CRH;
|
||||
GPIO_USB->CRL = VAL_GPIO_CRL;
|
||||
|
||||
#if GPIO_USB_BASE != GPIO_LED_BASE
|
||||
GPIO_LED->ODR = VAL_GPIO_LED_ODR;
|
||||
GPIO_LED->CRH = VAL_GPIO_LED_CRH;
|
||||
GPIO_LED->CRL = VAL_GPIO_LED_CRL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
usb_cable_config (int enable)
|
||||
{
|
||||
#if defined(SET_USB_CONDITION)
|
||||
if (SET_USB_CONDITION (enable))
|
||||
palSetPad (IOPORT_USB, GPIO_USB);
|
||||
#if defined(GPIO_USB_SET_TO_ENABLE)
|
||||
if (enable)
|
||||
GPIO_USB->BSRR = (1 << GPIO_USB_SET_TO_ENABLE);
|
||||
else
|
||||
palClearPad (IOPORT_USB, GPIO_USB);
|
||||
GPIO_USB->BRR = (1 << GPIO_USB_SET_TO_ENABLE);
|
||||
#elif defined(GPIO_USB_CLEAR_TO_ENABLE)
|
||||
if (enable)
|
||||
GPIO_USB->BRR = (1 << GPIO_USB_CLEAR_TO_ENABLE);
|
||||
else
|
||||
GPIO_USB->BSRR = (1 << GPIO_USB_CLEAR_TO_ENABLE);
|
||||
#else
|
||||
(void)enable;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
set_led (int on)
|
||||
{
|
||||
if (SET_LED_CONDITION (on))
|
||||
palSetPad (IOPORT_LED, GPIO_LED);
|
||||
#if defined(GPIO_LED_CLEAR_TO_EMIT)
|
||||
if (on)
|
||||
GPIO_LED->BRR = (1 << GPIO_LED_CLEAR_TO_EMIT);
|
||||
else
|
||||
palClearPad (IOPORT_LED, GPIO_LED);
|
||||
GPIO_LED->BSRR = (1 << GPIO_LED_CLEAR_TO_EMIT);
|
||||
#else
|
||||
if (on)
|
||||
GPIO_LED->BSRR = (1 << GPIO_LED_SET_TO_EMIT);
|
||||
else
|
||||
GPIO_LED->BRR = (1 << GPIO_LED_SET_TO_EMIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void wait (int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
asm volatile ("" : : "r" (i) : "memory");
|
||||
}
|
||||
|
||||
#define USB_IRQ 20
|
||||
#define USB_IRQ_PRIORITY ((11) << 4)
|
||||
|
||||
static void
|
||||
usb_lld_sys_shutdown (void)
|
||||
{
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
|
||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
||||
usb_cable_config (0);
|
||||
}
|
||||
|
||||
static void
|
||||
usb_lld_sys_init (void)
|
||||
{
|
||||
if ((RCC->APB1ENR & RCC_APB1ENR_USBEN)
|
||||
&& (RCC->APB1RSTR & RCC_APB1RSTR_USBRST) == 0)
|
||||
/* Make sure the device is disconnected, even after core reset. */
|
||||
{
|
||||
usb_lld_sys_shutdown ();
|
||||
/* Disconnect requires SE0 (>= 2.5uS). */
|
||||
wait (300);
|
||||
}
|
||||
|
||||
usb_cable_config (1);
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
||||
nvic_enable_vector (USB_LP_CAN1_RX0_IRQn,
|
||||
CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
|
||||
/*
|
||||
* Note that we also have other IRQ(s):
|
||||
* USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
|
||||
* USBWakeUp_IRQn (suspend/resume)
|
||||
*/
|
||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
||||
RCC->APB1RSTR = 0;
|
||||
}
|
||||
|
||||
#define FLASH_KEY1 0x45670123UL
|
||||
#define FLASH_KEY2 0xCDEF89ABUL
|
||||
|
||||
static void
|
||||
enum flash_status
|
||||
{
|
||||
FLASH_BUSY = 1,
|
||||
FLASH_ERROR_PG,
|
||||
FLASH_ERROR_WRP,
|
||||
FLASH_COMPLETE,
|
||||
FLASH_TIMEOUT
|
||||
};
|
||||
|
||||
static void __attribute__ ((used))
|
||||
flash_unlock (void)
|
||||
{
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
@@ -64,6 +332,25 @@ flash_unlock (void)
|
||||
}
|
||||
|
||||
|
||||
#define intr_disable() asm volatile ("cpsid i" : : : "memory")
|
||||
#define intr_enable() asm volatile ("cpsie i" : : : "memory")
|
||||
|
||||
#define FLASH_SR_BSY 0x01
|
||||
#define FLASH_SR_PGERR 0x04
|
||||
#define FLASH_SR_WRPRTERR 0x10
|
||||
#define FLASH_SR_EOP 0x20
|
||||
|
||||
#define FLASH_CR_PG 0x0001
|
||||
#define FLASH_CR_PER 0x0002
|
||||
#define FLASH_CR_MER 0x0004
|
||||
#define FLASH_CR_OPTPG 0x0010
|
||||
#define FLASH_CR_OPTER 0x0020
|
||||
#define FLASH_CR_STRT 0x0040
|
||||
#define FLASH_CR_LOCK 0x0080
|
||||
#define FLASH_CR_OPTWRE 0x0200
|
||||
#define FLASH_CR_ERRIE 0x0400
|
||||
#define FLASH_CR_EOPIE 0x1000
|
||||
|
||||
static int
|
||||
flash_wait_for_last_operation (uint32_t timeout)
|
||||
{
|
||||
@@ -90,7 +377,7 @@ flash_program_halfword (uint32_t addr, uint16_t data)
|
||||
|
||||
status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
|
||||
|
||||
port_disable ();
|
||||
intr_disable ();
|
||||
if (status == 0)
|
||||
{
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
@@ -100,7 +387,7 @@ flash_program_halfword (uint32_t addr, uint16_t data)
|
||||
status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
|
||||
FLASH->CR &= ~FLASH_CR_PG;
|
||||
}
|
||||
port_enable ();
|
||||
intr_enable ();
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -112,7 +399,7 @@ flash_erase_page (uint32_t addr)
|
||||
|
||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
||||
|
||||
port_disable ();
|
||||
intr_disable ();
|
||||
if (status == 0)
|
||||
{
|
||||
FLASH->CR |= FLASH_CR_PER;
|
||||
@@ -122,7 +409,7 @@ flash_erase_page (uint32_t addr)
|
||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
||||
FLASH->CR &= ~FLASH_CR_PER;
|
||||
}
|
||||
port_enable ();
|
||||
intr_enable ();
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -139,6 +426,8 @@ flash_check_blank (const uint8_t *p_start, size_t size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern uint8_t __flash_start__, __flash_end__;
|
||||
|
||||
static int
|
||||
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
|
||||
{
|
||||
@@ -175,7 +464,7 @@ flash_protect (void)
|
||||
|
||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
||||
|
||||
port_disable ();
|
||||
intr_disable ();
|
||||
if (status == 0)
|
||||
{
|
||||
FLASH->OPTKEYR = FLASH_KEY1;
|
||||
@@ -187,7 +476,7 @@ flash_protect (void)
|
||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
||||
FLASH->CR &= ~FLASH_CR_OPTER;
|
||||
}
|
||||
port_enable ();
|
||||
intr_enable ();
|
||||
|
||||
if (status != 0)
|
||||
return 0;
|
||||
@@ -196,7 +485,6 @@ flash_protect (void)
|
||||
return (option_bytes_value & 0xff) == 0xff ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
static void __attribute__((naked))
|
||||
flash_erase_all_and_exec (void (*entry)(void))
|
||||
{
|
||||
@@ -219,39 +507,32 @@ flash_erase_all_and_exec (void (*entry)(void))
|
||||
for (;;);
|
||||
}
|
||||
|
||||
static void
|
||||
nvic_enable_vector (uint32_t n, uint32_t prio)
|
||||
struct SCB
|
||||
{
|
||||
unsigned int sh = (n & 3) << 3;
|
||||
volatile uint32_t CPUID;
|
||||
volatile uint32_t ICSR;
|
||||
volatile uint32_t VTOR;
|
||||
volatile uint32_t AIRCR;
|
||||
volatile uint32_t SCR;
|
||||
volatile uint32_t CCR;
|
||||
volatile uint8_t SHP[12];
|
||||
volatile uint32_t SHCSR;
|
||||
volatile uint32_t CFSR;
|
||||
volatile uint32_t HFSR;
|
||||
volatile uint32_t DFSR;
|
||||
volatile uint32_t MMFAR;
|
||||
volatile uint32_t BFAR;
|
||||
volatile uint32_t AFSR;
|
||||
volatile uint32_t PFR[2];
|
||||
volatile uint32_t DFR;
|
||||
volatile uint32_t ADR;
|
||||
volatile uint32_t MMFR[4];
|
||||
volatile uint32_t ISAR[5];
|
||||
};
|
||||
|
||||
NVIC_IPR (n >> 2) = (NVIC_IPR(n >> 2) & ~(0xFF << sh)) | (prio << sh);
|
||||
NVIC_ICPR (n >> 5) = 1 << (n & 0x1F);
|
||||
NVIC_ISER (n >> 5) = 1 << (n & 0x1F);
|
||||
}
|
||||
|
||||
static void
|
||||
usb_lld_sys_init (void)
|
||||
{
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
||||
nvic_enable_vector (USB_LP_CAN1_RX0_IRQn,
|
||||
CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
|
||||
/*
|
||||
* Note that we also have other IRQ(s):
|
||||
* USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
|
||||
* USBWakeUp_IRQn (suspend/resume)
|
||||
*/
|
||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
||||
RCC->APB1RSTR = 0;
|
||||
|
||||
usb_cable_config (1);
|
||||
}
|
||||
|
||||
static void
|
||||
usb_lld_sys_shutdown (void)
|
||||
{
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
|
||||
usb_cable_config (0);
|
||||
}
|
||||
#define SCS_BASE (0xE000E000)
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
||||
static struct SCB *const SCB = ((struct SCB *const) SCB_BASE);
|
||||
|
||||
#define SYSRESETREQ 0x04
|
||||
static void
|
||||
@@ -259,11 +540,14 @@ nvic_system_reset (void)
|
||||
{
|
||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ);
|
||||
asm volatile ("dsb");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
static void __attribute__ ((naked))
|
||||
reset (void)
|
||||
{
|
||||
extern const unsigned long *FT0, *FT1, *FT2;
|
||||
|
||||
asm volatile ("cpsid i\n\t" /* Mask all interrupts. */
|
||||
"mov.w r0, #0xed00\n\t" /* r0 = SCR */
|
||||
"movt r0, #0xe000\n\t"
|
||||
@@ -278,6 +562,11 @@ reset (void)
|
||||
"ldr r0, [r1]\n\t" /* Reset handler. */
|
||||
"bx r0\n"
|
||||
: /* no output */ : /* no input */ : "memory");
|
||||
|
||||
/* Never reach here. */
|
||||
/* Artificial entry to refer FT0, FT1, and FT2. */
|
||||
asm volatile (""
|
||||
: : "r" (FT0), "r" (FT1), "r" (FT2));
|
||||
}
|
||||
|
||||
typedef void (*handler)(void);
|
||||
@@ -297,11 +586,14 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
|
||||
usb_lld_sys_init,
|
||||
usb_lld_sys_shutdown,
|
||||
nvic_system_reset,
|
||||
clock_init,
|
||||
gpio_init,
|
||||
NULL,
|
||||
};
|
||||
|
||||
const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
|
||||
3*2+2, /* bLength */
|
||||
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/
|
||||
/* sys version: "1.0" */
|
||||
'1', 0, '.', 0, '0', 0,
|
||||
/* sys version: "2.0" */
|
||||
'2', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
22
src/sys.h
22
src/sys.h
@@ -1,7 +1,7 @@
|
||||
extern const uint8_t sys_version[8];
|
||||
|
||||
typedef void (*handler)(void);
|
||||
extern handler vector[14];
|
||||
extern handler vector[16];
|
||||
|
||||
static inline const uint8_t *
|
||||
unique_device_id (void)
|
||||
@@ -93,3 +93,23 @@ nvic_system_reset (void)
|
||||
{
|
||||
(*vector[12]) ();
|
||||
}
|
||||
|
||||
/*
|
||||
* Users can override INLINE by 'attribute((used))' to have an
|
||||
* implementation defined.
|
||||
*/
|
||||
#if !defined(INLINE)
|
||||
#define INLINE __inline__
|
||||
#endif
|
||||
|
||||
static INLINE void
|
||||
clock_init (void)
|
||||
{
|
||||
(*vector[13]) ();
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
gpio_init (void)
|
||||
{
|
||||
(*vector[14]) ();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* usb-icc.c -- USB CCID/ICCD protocol handling
|
||||
* usb-icc.c -- USB CCID protocol handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
|
||||
* Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -21,14 +21,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <chopstx.h>
|
||||
#include <eventflag.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "usb_lld.h"
|
||||
|
||||
/*
|
||||
* USB buffer size of USB-ICC driver
|
||||
* USB buffer size of USB-CCID driver
|
||||
*/
|
||||
#if MAX_RES_APDU_DATA_SIZE > MAX_CMD_APDU_DATA_SIZE
|
||||
#define USB_BUF_SIZE (MAX_RES_APDU_DATA_SIZE+5)
|
||||
@@ -189,14 +193,16 @@ struct ccid {
|
||||
uint8_t sw1sw2[2];
|
||||
uint8_t chained_cls_ins_p1_p2[4];
|
||||
|
||||
Thread *icc_thread;
|
||||
Thread *application;
|
||||
|
||||
/* lower layer */
|
||||
struct ep_out *epo;
|
||||
struct ep_in *epi;
|
||||
|
||||
/* from both layers */
|
||||
struct eventflag ccid_comm;
|
||||
|
||||
/* upper layer */
|
||||
struct eventflag openpgp_comm;
|
||||
chopstx_t application;
|
||||
struct apdu *a;
|
||||
};
|
||||
|
||||
@@ -242,7 +248,7 @@ static void ccid_reset (struct ccid *c)
|
||||
}
|
||||
|
||||
static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
|
||||
struct apdu *a, Thread *t)
|
||||
struct apdu *a, chopstx_t thd)
|
||||
{
|
||||
icc_state_p = &c->icc_state;
|
||||
|
||||
@@ -257,8 +263,9 @@ static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
|
||||
memset (&c->icc_header, 0, sizeof (struct icc_header));
|
||||
c->sw1sw2[0] = 0x90;
|
||||
c->sw1sw2[1] = 0x00;
|
||||
c->icc_thread = t;
|
||||
c->application = NULL;
|
||||
eventflag_init (&c->ccid_comm, thd);
|
||||
c->application = 0;
|
||||
eventflag_init (&c->openpgp_comm, 0);
|
||||
c->epi = epi;
|
||||
c->epo = epo;
|
||||
c->a = a;
|
||||
@@ -310,7 +317,7 @@ static void notify_tx (struct ep_in *epi)
|
||||
struct ccid *c = (struct ccid *)epi->priv;
|
||||
|
||||
/* The sequence of Bulk-IN transactions finished */
|
||||
chEvtSignalFlagsI (c->icc_thread, EV_TX_FINISHED);
|
||||
eventflag_signal (&c->ccid_comm, EV_TX_FINISHED);
|
||||
}
|
||||
|
||||
static void no_buf (struct ep_in *epi, size_t len)
|
||||
@@ -403,7 +410,7 @@ static void notify_icc (struct ep_out *epo)
|
||||
struct ccid *c = (struct ccid *)epo->priv;
|
||||
|
||||
c->err = epo->err;
|
||||
chEvtSignalFlagsI (c->icc_thread, EV_RX_DATA_READY);
|
||||
eventflag_signal (&c->ccid_comm, EV_RX_DATA_READY);
|
||||
}
|
||||
|
||||
static int end_icc_rx (struct ep_out *epo, size_t orig_len)
|
||||
@@ -617,8 +624,6 @@ static void icc_abdata (struct ep_out *epo, size_t len)
|
||||
static void
|
||||
icc_prepare_receive (struct ccid *c)
|
||||
{
|
||||
DEBUG_INFO ("Rx ready\r\n");
|
||||
|
||||
c->epo->err = 0;
|
||||
c->epo->buf = (uint8_t *)&c->icc_header;
|
||||
c->epo->buf_len = sizeof (struct icc_header);
|
||||
@@ -626,6 +631,7 @@ icc_prepare_receive (struct ccid *c)
|
||||
c->epo->next_buf = icc_abdata;
|
||||
c->epo->end_rx = end_icc_rx;
|
||||
usb_lld_rx_enable (c->epo->ep_num);
|
||||
DEBUG_INFO ("Rx ready\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -736,8 +742,12 @@ static void icc_error (struct ccid *c, int offset)
|
||||
usb_lld_write (c->epi->ep_num, icc_reply, ICC_MSG_HEADER_SIZE);
|
||||
}
|
||||
|
||||
static WORKING_AREA(waGPGthread, 128*16);
|
||||
extern msg_t GPGthread (void *arg);
|
||||
extern void *GPGthread (void *arg);
|
||||
|
||||
extern uint8_t __process3_stack_base__, __process3_stack_size__;
|
||||
const uint32_t __stackaddr_gpg = (uint32_t)&__process3_stack_base__;
|
||||
const size_t __stacksize_gpg = (size_t)&__process3_stack_size__;
|
||||
#define PRIO_GPG 1
|
||||
|
||||
|
||||
/* Send back ATR (Answer To Reset) */
|
||||
@@ -747,10 +757,10 @@ icc_power_on (struct ccid *c)
|
||||
size_t size_atr = sizeof (ATR);
|
||||
uint8_t p[ICC_MSG_HEADER_SIZE];
|
||||
|
||||
if (c->application == NULL)
|
||||
c->application = chThdCreateStatic (waGPGthread, sizeof(waGPGthread),
|
||||
NORMALPRIO, GPGthread,
|
||||
(void *)c->icc_thread);
|
||||
if (c->application == 0)
|
||||
c->application = chopstx_create (PRIO_GPG, __stackaddr_gpg,
|
||||
__stacksize_gpg,
|
||||
GPGthread, (void *)&c->ccid_comm);
|
||||
|
||||
p[0] = ICC_DATA_BLOCK_RET;
|
||||
p[1] = size_atr;
|
||||
@@ -812,10 +822,9 @@ icc_power_off (struct ccid *c)
|
||||
{
|
||||
if (c->application)
|
||||
{
|
||||
chThdTerminate (c->application);
|
||||
chEvtSignalFlags (c->application, EV_NOP);
|
||||
chThdWait (c->application);
|
||||
c->application = NULL;
|
||||
eventflag_signal (&c->openpgp_comm, EV_EXIT);
|
||||
chopstx_join (c->application, NULL);
|
||||
c->application = 0;
|
||||
}
|
||||
|
||||
c->icc_state = ICC_STATE_START; /* This status change should be here */
|
||||
@@ -1138,7 +1147,7 @@ icc_handle_data (struct ccid *c)
|
||||
c->a->res_apdu_data_len = 0;
|
||||
c->a->res_apdu_data = &icc_buffer[5];
|
||||
|
||||
chEvtSignalFlags (c->application, EV_CMD_AVAILABLE);
|
||||
eventflag_signal (&c->openpgp_comm, EV_CMD_AVAILABLE);
|
||||
next_state = ICC_STATE_EXECUTE;
|
||||
}
|
||||
}
|
||||
@@ -1197,7 +1206,7 @@ icc_handle_data (struct ccid *c)
|
||||
c->a->res_apdu_data_len = 0;
|
||||
c->a->res_apdu_data = &c->p[5];
|
||||
|
||||
chEvtSignalFlags (c->application, EV_VERIFY_CMD_AVAILABLE);
|
||||
eventflag_signal (&c->openpgp_comm, EV_VERIFY_CMD_AVAILABLE);
|
||||
next_state = ICC_STATE_EXECUTE;
|
||||
}
|
||||
else if (c->p[10-10] == 0x01) /* PIN Modification */
|
||||
@@ -1231,7 +1240,7 @@ icc_handle_data (struct ccid *c)
|
||||
c->a->res_apdu_data_len = 0;
|
||||
c->a->res_apdu_data = &icc_buffer[5];
|
||||
|
||||
chEvtSignalFlags (c->application, EV_MODIFY_CMD_AVAILABLE);
|
||||
eventflag_signal (&c->openpgp_comm, EV_MODIFY_CMD_AVAILABLE);
|
||||
next_state = ICC_STATE_EXECUTE;
|
||||
}
|
||||
else
|
||||
@@ -1283,36 +1292,44 @@ icc_handle_timeout (struct ccid *c)
|
||||
return next_state;
|
||||
}
|
||||
|
||||
#define USB_ICC_TIMEOUT MS2ST(1950)
|
||||
#define USB_ICC_TIMEOUT (1950*1000)
|
||||
|
||||
|
||||
static struct ccid ccid;
|
||||
|
||||
#define GPG_THREAD_TERMINATED 0xffff
|
||||
|
||||
msg_t
|
||||
static void *ccid_thread (chopstx_t) __attribute__ ((noinline));
|
||||
|
||||
void * __attribute__ ((naked))
|
||||
USBthread (void *arg)
|
||||
{
|
||||
chopstx_t thd;
|
||||
(void)arg;
|
||||
|
||||
asm ("mov %0, sp" : "=r" (thd));
|
||||
return ccid_thread (thd);
|
||||
}
|
||||
|
||||
static void *
|
||||
ccid_thread (chopstx_t thd)
|
||||
{
|
||||
struct ep_in *epi = &endpoint_in;
|
||||
struct ep_out *epo = &endpoint_out;
|
||||
struct ccid *c = &ccid;
|
||||
struct apdu *a = &apdu;
|
||||
|
||||
(void)arg;
|
||||
|
||||
epi_init (epi, ENDP1, notify_tx, c);
|
||||
epo_init (epo, ENDP1, notify_icc, c);
|
||||
ccid_init (c, epi, epo, a, chThdSelf ());
|
||||
ccid_init (c, epi, epo, a, thd);
|
||||
apdu_init (a);
|
||||
|
||||
chEvtClearFlags (ALL_EVENTS);
|
||||
|
||||
icc_prepare_receive (c);
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m;
|
||||
|
||||
m = chEvtWaitOneTimeout (ALL_EVENTS, USB_ICC_TIMEOUT);
|
||||
m = eventflag_wait_timeout (&c->ccid_comm, USB_ICC_TIMEOUT);
|
||||
|
||||
if (m == EV_RX_DATA_READY)
|
||||
c->icc_state = icc_handle_data (c);
|
||||
@@ -1373,5 +1390,5 @@ USBthread (void *arg)
|
||||
c->icc_state = icc_handle_timeout (c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
151
src/usb_ctrl.c
151
src/usb_ctrl.c
@@ -24,12 +24,20 @@
|
||||
/* Packet size of USB Bulk transfer for full speed */
|
||||
#define GNUK_MAX_PACKET_SIZE 64
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
#include "usb_lld.h"
|
||||
#include "usb_conf.h"
|
||||
#include "gnuk.h"
|
||||
#include "stm32f103.h"
|
||||
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
#include "usb-cdc.h"
|
||||
@@ -50,7 +58,7 @@ static struct line_coding line_coding = {
|
||||
};
|
||||
|
||||
static int
|
||||
vcom_port_data_setup (uint8_t req, uint8_t req_no)
|
||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
@@ -68,8 +76,29 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||
/* Do nothing and success */
|
||||
return USB_SUCCESS;
|
||||
{
|
||||
uint8_t connected_saved = stdout.connected;
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
if (stdout.connected == 0)
|
||||
/* It's Open call */
|
||||
stdout.connected++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stdout.connected)
|
||||
/* Close call */
|
||||
stdout.connected = 0;
|
||||
}
|
||||
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
if (stdout.connected != connected_saved)
|
||||
chopstx_cond_signal (&stdout.cond_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
@@ -182,7 +211,7 @@ static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
|
||||
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
|
||||
#endif
|
||||
|
||||
static const uint8_t *const mem_info[] = { &_regnual_start, &__heap_end__, };
|
||||
static const uint8_t *const mem_info[] = { &_regnual_start, __heap_end__, };
|
||||
|
||||
#define USB_FSIJ_GNUK_MEMINFO 0
|
||||
#define USB_FSIJ_GNUK_DOWNLOAD 1
|
||||
@@ -239,7 +268,7 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (addr < &_regnual_start || addr + len > &__heap_end__)
|
||||
if (addr < &_regnual_start || addr + len > __heap_end__)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (index + len < 256)
|
||||
@@ -261,51 +290,53 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
}
|
||||
}
|
||||
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||
if (index == 0)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
||||
{
|
||||
usb_lld_set_data_to_send (freq_table, sizeof (freq_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_CCID_REQ_GET_DATA_RATES)
|
||||
{
|
||||
usb_lld_set_data_to_send (data_rate_table,
|
||||
sizeof (data_rate_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req_no == USB_CCID_REQ_ABORT)
|
||||
/* wValue: bSeq, bSlot */
|
||||
/* Abortion is not supported in Gnuk */
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
||||
{
|
||||
usb_lld_set_data_to_send (freq_table, sizeof (freq_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_CCID_REQ_GET_DATA_RATES)
|
||||
{
|
||||
usb_lld_set_data_to_send (data_rate_table,
|
||||
sizeof (data_rate_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req_no == USB_CCID_REQ_ABORT)
|
||||
/* wValue: bSeq, bSlot */
|
||||
/* Abortion is not supported in Gnuk */
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
else if (index == 1)
|
||||
return vcom_port_data_setup (req, req_no);
|
||||
else if (index == 1)
|
||||
return vcom_port_data_setup (req, req_no, value);
|
||||
#endif
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
else if (index == MSC_INTERFACE_NO)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == MSC_GET_MAX_LUN_COMMAND)
|
||||
{
|
||||
usb_lld_set_data_to_send (lun_table, sizeof (lun_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (req_no == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||
/* Should call resetting MSC thread, something like msc_reset() */
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (index == MSC_INTERFACE_NO)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == MSC_GET_MAX_LUN_COMMAND)
|
||||
{
|
||||
usb_lld_set_data_to_send (lun_table, sizeof (lun_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (req_no == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||
/* Should call resetting MSC thread, something like msc_reset() */
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
@@ -398,13 +429,25 @@ int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
|
||||
}
|
||||
|
||||
|
||||
CH_IRQ_HANDLER (Vector90)
|
||||
{
|
||||
CH_IRQ_PROLOGUE();
|
||||
chSysLockFromIsr();
|
||||
#define INTR_REQ_USB 20
|
||||
|
||||
void *
|
||||
usb_intr (void *arg)
|
||||
{
|
||||
chopstx_intr_t interrupt;
|
||||
|
||||
(void)arg;
|
||||
usb_lld_init (usb_initial_feature);
|
||||
chopstx_claim_irq (&interrupt, INTR_REQ_USB);
|
||||
usb_interrupt_handler ();
|
||||
|
||||
chSysUnlockFromIsr();
|
||||
CH_IRQ_EPILOGUE();
|
||||
while (1)
|
||||
{
|
||||
chopstx_intr_wait (&interrupt);
|
||||
|
||||
/* Process interrupt. */
|
||||
usb_interrupt_handler ();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
* usb_desc.c - USB Descriptor
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "usb_lld.h"
|
||||
#include "usb_conf.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifdef FREE_STANDING
|
||||
#include "types.h"
|
||||
#else
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#include "sys.h"
|
||||
#include "usb_lld.h"
|
||||
|
||||
@@ -83,15 +83,15 @@ static struct DATA_INFO *const data_p = &data_info;
|
||||
#define PMA_ADDR (0x40006000UL) /* USB_IP Packet Memory Area base address */
|
||||
|
||||
/* Control register */
|
||||
#define CNTR ((__IO uint16_t *)(REG_BASE + 0x40))
|
||||
#define CNTR ((volatile uint16_t *)(REG_BASE + 0x40))
|
||||
/* Interrupt status register */
|
||||
#define ISTR ((__IO uint16_t *)(REG_BASE + 0x44))
|
||||
#define ISTR ((volatile uint16_t *)(REG_BASE + 0x44))
|
||||
/* Frame number register */
|
||||
#define FNR ((__IO uint16_t *)(REG_BASE + 0x48))
|
||||
#define FNR ((volatile uint16_t *)(REG_BASE + 0x48))
|
||||
/* Device address register */
|
||||
#define DADDR ((__IO uint16_t *)(REG_BASE + 0x4C))
|
||||
#define DADDR ((volatile uint16_t *)(REG_BASE + 0x4C))
|
||||
/* Buffer Table address register */
|
||||
#define BTABLE ((__IO uint16_t *)(REG_BASE + 0x50))
|
||||
#define BTABLE ((volatile uint16_t *)(REG_BASE + 0x50))
|
||||
|
||||
#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */
|
||||
#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */
|
||||
|
||||
Reference in New Issue
Block a user