port to chopstx
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 20 Jun 2013 07:19:49 +0000 (16:19 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 20 Jun 2013 07:19:49 +0000 (16:19 +0900)
30 files changed:
.gitmodules
ChangeLog
chopstx [new submodule]
polarssl/library/aes.c
src/Makefile.in
src/ac.c
src/adc.h
src/adc_stm32f103.c
src/call-ec_p256.c
src/call-rsa.c
src/config.h.in
src/configure
src/debug.c
src/debug.h [new file with mode: 0644]
src/flash.c
src/gnuk.h
src/gnuk.ld.in
src/main.c
src/neug.c
src/openpgp-do.c
src/openpgp.c
src/random.c
src/stdlib.h
src/stm32f103.h [new file with mode: 0644]
src/sys.c
src/sys.h
src/usb-icc.c
src/usb_ctrl.c
src/usb_desc.c
src/usb_stm32f103.c

index ad61fd3..2917670 100644 (file)
@@ -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
index 8c85c90..8baa98b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
diff --git a/chopstx b/chopstx
new file mode 160000 (submodule)
index 0000000..8447b2b
--- /dev/null
+++ b/chopstx
@@ -0,0 +1 @@
+Subproject commit 8447b2ba8e7caf10f0c986f629bf457d3db7c5e7
index ece7ee5..2a46f72 100644 (file)
@@ -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
index a9f3ee3..3975ea1 100644 (file)
@@ -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)
-
-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
-CWARN = -Wall -Wextra -Wstrict-prototypes
-
-# Define C++ warning options here
-CPPWARN = -Wall -Wextra
-
-#
-# Compiler settings
-##############################################################################
-
-##############################################################################
-# Start of default section
-#
-
-# List all default C defines here, like -D_DEBUG=1
-DDEFS =
+###################################
+CROSS = arm-none-eabi-
+CC   = $(CROSS)gcc
+LD   = $(CROSS)gcc
+OBJCOPY   = $(CROSS)objcopy
 
-# 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 =
+MCU   = cortex-m3
+CWARN = -Wall -Wextra -Wstrict-prototypes
+# DEFS: Add  
+DEFS  = -DRSA_AUTH @KEYGEN_SUPPORT@ @HAVE_SYS_H@
+OPT   = -O3 -Os -g
+LIBS  =
 
-# List all user libraries here
-ULIBS =
+#######################
+include $(CHOPSTX)/rules.mk
 
-#
-# End of user defines
-##############################################################################
+board.h:
+       @echo Please run configure to have a symbolic link \'board.h\'
+       @exit 1
 
-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
index 8011f26..fc40ac5 100644 (file)
--- a/src/ac.c
+++ b/src/ac.c
  *
  */
 
+#include <stdint.h>
+#include <string.h>
+
 #include "config.h"
-#include "ch.h"
+
 #include "gnuk.h"
 #include "sha256.h"
 #include "random.h"
index 366f22e..2ed9bf6 100644 (file)
--- a/src/adc.h
+++ b/src/adc.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);
index 8566968..88480de 100644 (file)
@@ -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
  *
  */
 
-#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)     \
  */
 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
 
-void adc_start (void)
+static void adc_lld_serve_rx_interrupt (uint32_t flags);
+
+#define INTR_REQ_DMA1_Channel1 11
+static void *
+adc_intr_thread (void *arg)
 {
-  dmaStreamAllocate (NEUG_DMA_CHANNEL, STM32_ADC_ADC1_IRQ_PRIORITY,
-                    adc_lld_serve_rx_interrupt, NULL);
-  dmaStreamSetPeripheral (NEUG_DMA_CHANNEL, &ADC1->DR);
+  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;
 
-  chSysLock ();
+void adc_start (void)
+{
+  /* Use DMA channel 1.  */
+  RCC->AHBENR |= RCC_AHBENR_DMA1EN;
+  DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
+  DMA1->IFCR = 0xffffffff;
 
-  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);
        }
     }
 }
index a929fb1..3cce2ae 100644 (file)
@@ -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.  */
index 89ebf16..4d47423 100644 (file)
  *
  */
 
+#include <stdint.h>
+#include <string.h>
 #include <stdlib.h>
 #include "config.h"
-#include "ch.h"
+
 #include "gnuk.h"
 #include "openpgp.h"
 #include "random.h"
index cb61d1b..37fbb30 100644 (file)
@@ -6,4 +6,3 @@
 @PINPAD_DEFINE@
 @PINPAD_MORE_DEFINE@
 @CERTDO_DEFINE@
-#define FLASH_PAGE_SIZE        @FLASH_PAGE_SIZE@
index a5636b7..b01f563 100755 (executable)
@@ -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
index 43978a8..2de4092 100644 (file)
  *
  */
 
-#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)
diff --git a/src/debug.h b/src/debug.h
new file mode 100644 (file)
index 0000000..091c0c5
--- /dev/null
@@ -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;
index bc62b9b..850b870 100644 (file)
  *       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"
 
index d0c0226..9601981 100644 (file)
@@ -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__[];
index aeeddcf..c6dce32 100644 (file)
@@ -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
 }
 
index 79cd59a..d0edfe0 100644 (file)
  *
  */
 
+#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)
-    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 ();
-}
-
-Thread *stdout_thread;
-uint32_t count_in;
-uint8_t buffer_in[VIRTUAL_COM_PORT_DATA_SIZE];
+  int packet_len;
 
-static WORKING_AREA(waSTDOUTthread, 128);
+  if (len == 0)
+    return;
 
-static msg_t
-STDOUTthread (void *arg)
-{
-  (void)arg;
-  stdout_thread = chThdSelf ();
+  chopstx_mutex_lock (&stdout.m);
 
- again:
+  chopstx_mutex_lock (&stdout.m_dev);
+  if (!stdout.connected)
+    chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
+  chopstx_mutex_unlock (&stdout.m_dev);
 
-  while (1)
+  do
     {
-      if (bDeviceState == CONFIGURED)
-       break;
-
-      chThdSleepMilliseconds (100);
-    }
-
-  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;
-           }
+      packet_len =
+       (len < VIRTUAL_COM_PORT_DATA_SIZE) ? len : VIRTUAL_COM_PORT_DATA_SIZE;
 
-         chEvtClear (EV_TX_READY);
+      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);
 
-         usb_lld_write (ENDP3, buffer_in, count_in);
-
-         chEvtWaitOne (EV_TX_READY);
-       }
-
-      stdout.str = NULL;
-      stdout.size = 0;
-      chCondBroadcast (&stdout.finish_cnd);
-      chMtxUnlock ();
+      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);
 
-  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,47 +307,44 @@ 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 ();
 
-  while (1)
-    {
-      if (bDeviceState != UNCONNECTED)
-       break;
-
-      chThdSleepMilliseconds (250);
-    }
-
 #ifdef DEBUG
   stdout_init ();
-
-  /*
-   * Creates 'stdout' thread.
-   */
-  chThdCreateStatic (waSTDOUTthread, sizeof(waSTDOUTthread),
-                    NORMALPRIO, STDOUTthread, NULL);
 #endif
 
-  chThdCreateStatic (waUSBthread, sizeof(waUSBthread),
-                    NORMALPRIO, USBthread, NULL);
+  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;
+
+      chopstx_usec_wait (250*1000);
+    }
 
   while (1)
     {
@@ -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);
+}
index 91636ca..7e8065f 100644 (file)
@@ -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
  *
  */
 
-#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 ();
index 426b3d0..e6e5c3b 100644 (file)
  *
  */
 
+#include <stdint.h>
+#include <string.h>
 #include <stdlib.h>
 
 #include "config.h"
-#include "ch.h"
+
 #include "sys.h"
 #include "gnuk.h"
 #include "openpgp.h"
index 8f5c31f..2007a2e 100644 (file)
  *
  */
 
+#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;
 }
index d2dca77..13ed2a4 100644 (file)
  *
  */
 
+#include <stdint.h>
+#include <string.h>
+
 #include "config.h"
-#include "ch.h"
+
 #include "gnuk.h"
 #include "neug.h"
 
index c55e0ac..886794e 100644 (file)
@@ -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 *);
diff --git a/src/stm32f103.h b/src/stm32f103.h
new file mode 100644 (file)
index 0000000..a4ecaa1
--- /dev/null
@@ -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;
index 7e70df1..36184b7 100644 (file)
--- a/src/sys.c
+++ b/src/sys.c
 /*
- * 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;
-
-  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;
+  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];
+};
 
-  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,
 };
index 3884c95..25d33f1 100644 (file)
--- a/src/sys.h
+++ b/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]) ();
+}
index ec20658..ba2bc54 100644 (file)
@@ -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.
  *
  */
 
+#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;
 }
index 51a7d45..968824b 100644 (file)
 /* 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)
+#define INTR_REQ_USB 20
+
+void *
+usb_intr (void *arg)
 {
-  CH_IRQ_PROLOGUE();
-  chSysLockFromIsr();
+  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;
 }
index 482f9b5..c99b9e4 100644 (file)
@@ -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"
index 74f5acf..b75dfdb 100644 (file)
@@ -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) */