testing regnual
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 18 May 2012 17:07:31 +0000 (02:07 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 18 May 2012 17:07:31 +0000 (02:07 +0900)
regnual/Makefile.in [new file with mode: 0644]
regnual/regnual.c [new file with mode: 0644]
regnual/regnual.ld.in [new file with mode: 0644]

diff --git a/regnual/Makefile.in b/regnual/Makefile.in
new file mode 100644 (file)
index 0000000..58254d8
--- /dev/null
@@ -0,0 +1,182 @@
+# Makefile for reGNUal
+
+BOARD_DIR=@BOARD_DIR@
+
+##############################################################################
+# Build global options
+# NOTE: Can be overridden externally.
+#
+
+# Compiler options here.
+ifeq ($(USE_OPT),)
+  USE_OPT = -O2 -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 register caching optimization (read documentation).
+ifeq ($(USE_CURRP_CACHING),)
+  USE_CURRP_CACHING = 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 = regnual
+
+# Define linker script file here
+LDSCRIPT= regnual.ld
+
+# Imported source files
+CHIBIOS = ../ChibiOS_2.0.8
+include $(CHIBIOS)/os/hal/platforms/STM32/platform.mk
+include $(CHIBIOS)/os/hal/hal.mk
+include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/port.mk
+include $(CHIBIOS)/os/kernel/kernel.mk
+
+# C sources that can be compiled in ARM or THUMB mode depending on the global
+# setting.
+CSRC = $(PORTSRC) \
+       $(KERNSRC) \
+       $(HALSRC) \
+       $(PLATFORMSRC) \
+       $(BOARDSRC) \
+       ../boards/common/hw_config.c \
+       $(BOARD_DIR)/board.c \
+       $(CHIBIOS)/os/various/evtimer.c \
+       $(CHIBIOS)/os/various/syscalls.c \
+       regnual.c usb_lld.c
+
+# List ASM source files here
+ASMSRC = $(PORTASM) \
+         $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/vectors.s
+
+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 = -DCORTEX_USE_BASEPRI=TRUE
+
+# 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 =
+
+# 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/ARM/rules.mk
+MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
+
+distclean: clean
+       -rm -f Makefile regnual.ld
diff --git a/regnual/regnual.c b/regnual/regnual.c
new file mode 100644 (file)
index 0000000..9f1d3f8
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * regnual.c -- Firmware installation for STM32F103 Flash ROM
+ *
+ * Copyright (C) 2012 Free Software Initiative of Japan
+ * 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/>.
+ *
+ */
+
+/*
+ * ReGNUal
+ */
+
+#include "ch.h"
+#include "usb_lld.h"
+
+extern void set_led (int);
+extern void *memset (void *s, int c, size_t n);
+
+#define ENDP0_RXADDR        (0x40)
+#define ENDP0_TXADDR        (0x80)
+
+/* USB Standard Device Descriptor */
+static const uint8_t regnual_device_desc[] = {
+  18,   /* bLength */
+  USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
+  0x10, 0x01,   /* bcdUSB = 1.1 */
+  0xFF,   /* bDeviceClass: VENDOR */
+  0x00,   /* bDeviceSubClass */
+  0x00,   /* bDeviceProtocol */
+  0x40,   /* bMaxPacketSize0 */
+#include "usb-vid-pid-ver.c.inc"
+  1, /* Index of string descriptor describing manufacturer */
+  2, /* Index of string descriptor describing product */
+  3, /* Index of string descriptor describing the device's serial number */
+  0x01    /* bNumConfigurations */
+};
+
+static const uint8_t regnual_config_desc[] = {
+  9,
+  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
+  9, 0,                        /* wTotalLength: no of returned bytes */
+  0,                   /* bNumInterfaces: None, but control pipe */
+  0x01,                        /* bConfigurationValue: Configuration value */
+  0x00,                        /* iConfiguration: None */
+#if defined(USB_SELF_POWERED)
+  0xC0,                                /* bmAttributes: self powered */
+#else
+  0x80,                                /* bmAttributes: bus powered */
+#endif
+  50,                          /* MaxPower 100 mA */
+};
+
+static const uint8_t regnual_string_lang_id[] = {
+  4,                           /* bLength */
+  USB_STRING_DESCRIPTOR_TYPE,
+  0x09, 0x04                   /* LangID = 0x0409: US-English */
+};
+
+#include "usb-string-vendor-product.c.inc"
+
+static const uint8_t regnual_string_serial[] = {
+  8*2+2,
+  USB_STRING_DESCRIPTOR_TYPE,
+  /* FSIJ-0.0 */
+  'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0, 
+  '0', 0, '.', 0, '0', 0,
+};
+
+const struct Descriptor Device_Descriptor = {
+  regnual_device_desc,
+  sizeof (regnual_device_desc)
+};
+
+const struct Descriptor Config_Descriptor = {
+  regnual_config_desc,
+  sizeof (regnual_config_desc)
+};
+
+const struct Descriptor String_Descriptors[] = {
+  {regnual_string_lang_id, sizeof (regnual_string_lang_id)},
+  {gnukStringVendor, sizeof (gnukStringVendor)},
+  {gnukStringProduct, sizeof (gnukStringProduct)},
+  {regnual_string_serial, sizeof (regnual_string_serial)},
+};
+
+#define NUM_STRING_DESC (sizeof (String_Descriptors)/sizeof (struct Descriptor))
+
+static void
+regnual_device_init (void)
+{
+  usb_lld_set_configuration (0);
+  USB_Cable_Config (1);
+}
+
+static void
+regnual_device_reset (void)
+{
+  /* Set DEVICE as not configured */
+  usb_lld_set_configuration (0);
+
+  /* Current Feature initialization */
+  usb_lld_set_feature (Config_Descriptor.Descriptor[7]);
+
+  usb_lld_reset ();
+
+  /* Initialize Endpoint 0 */
+  usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
+                         64);
+}
+
+#define USB_REGNUAL_MEMINFO    0
+#define USB_REGNUAL_SEND       1
+#define USB_REGNUAL_CRC32      2
+#define USB_REGNUAL_FLASH      3
+#define USB_REGNUAL_ERASE      4
+#define USB_REGNUAL_PROTECT    5
+#define USB_REGNUAL_FINISH     6
+
+static uint8_t mem[1024];
+
+static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
+                                   uint16_t value, uint16_t index,
+                                   uint16_t len)
+{
+  uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
+
+  if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
+      && USB_SETUP_SET (req) && req_no == USB_REGNUAL_FINISH && len == 0)
+    {
+      (void)value; (void)index;
+      /* RESET MCU */
+    }
+}
+
+extern uint8_t _flash_start,  _flash_end;
+static const uint8_t *const mem_info[] = { &_flash_start,  &_flash_end, };
+
+static int
+regnual_setup (uint8_t req, uint8_t req_no,
+              uint16_t value, uint16_t index, uint16_t len)
+{
+  uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
+
+  if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
+    {
+      if (USB_SETUP_GET (req))
+       {
+         if (req_no == USB_REGNUAL_MEMINFO)
+           {
+             usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
+             return USB_SUCCESS;
+           }
+         else if (req_no == USB_REGNUAL_CRC32)
+           {
+             static uint32_t crc32_check = 0; /* calculate CRC32 for mem */
+
+             usb_lld_set_data_to_send (&crc32_check, sizeof (uint32_t));
+             return USB_SUCCESS;
+           }
+       }
+      else /* SETUP_SET */
+       {
+         if (req_no == USB_REGNUAL_SEND)
+           {
+             if (value >= 4 || value * 0x100 + index + len > 1024)
+               return USB_UNSUPPORT;
+
+             if (value == 0 && index == 0)
+               memset (mem + value * 0x100, 0xff, 1024);
+             usb_lld_set_data_to_recv (mem + value * 0x100 + index, len);
+             return USB_SUCCESS;
+           }
+         else if (req_no == USB_REGNUAL_FLASH && len == 0)
+           {
+             uint8_t *addr = (uint8_t *)(0x08000000 + value * 0x400);
+
+             /* flash write, verify */
+             return USB_SUCCESS;
+           }
+       }
+    }
+
+  return USB_UNSUPPORT;
+}
+
+static int
+regnual_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
+{
+  (void)index;
+  if (desc_type == DEVICE_DESCRIPTOR)
+    {
+      usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
+                               Device_Descriptor.Descriptor_Size);
+      return USB_SUCCESS;
+    }
+  else if (desc_type == CONFIG_DESCRIPTOR)
+    {
+      usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
+                               Config_Descriptor.Descriptor_Size);
+      return USB_SUCCESS;
+    }
+  else if (desc_type == STRING_DESCRIPTOR)
+    {
+      uint8_t desc_index = value & 0xff;
+
+      if (desc_index < NUM_STRING_DESC)
+       {
+         usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
+                           String_Descriptors[desc_index].Descriptor_Size);
+         return USB_SUCCESS;
+       }
+    }
+
+  return USB_UNSUPPORT;
+}
+
+static int regnual_usb_event (uint8_t event_type, uint16_t value)
+{
+  (void)value;
+
+  switch (event_type)
+    {
+    case USB_EVENT_ADDRESS:
+    case USB_EVENT_CONFIG:
+      return USB_SUCCESS;
+    default:
+      break;
+    }
+
+  return USB_UNSUPPORT;
+}
+
+static int regnual_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
+{
+  (void)cmd; (void)interface; (void)alt;
+  return USB_UNSUPPORT;
+}
+
+const struct usb_device_method Device_Method = {
+  regnual_device_init,
+  regnual_device_reset,
+  regnual_ctrl_write_finish,
+  regnual_setup,
+  regnual_get_descriptor,
+  regnual_usb_event,
+  regnual_interface,
+};
+
+int
+main (int argc, char *argv[])
+{
+  (void)argc; (void)argv;
+
+  set_led (0);
+
+  usb_lld_init ();
+
+  while (1)
+    {
+      set_led (1);
+      chThdSleep (MS2ST (200));
+      set_led (0);
+      chThdSleep (MS2ST (200));
+    }
+}
diff --git a/regnual/regnual.ld.in b/regnual/regnual.ld.in
new file mode 100644 (file)
index 0000000..54aceb5
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * ST32F103 memory setup.
+ */
+__main_stack_size__     = 0x0400;
+__process_stack_size__  = 0x0200;
+__stacks_total_size__   = __main_stack_size__ + __process_stack_size__;
+
+MEMORY
+{
+    flash : org = @ORIGIN@, len = @FLASH_SIZE@k
+    ram0 : org = 0x20000000, len = @REGNUAL_START@
+    ram1 : org = 0x20001300, len = 20k - @REGNUAL_START@
+}
+
+_flash_start = 0x08000000;
+_flash_end   = @FLASH_END@;
+
+__ram_start__           = ORIGIN(ram0);
+__ram_size__            = 20k;
+__ram_end__             = __ram_start__ + __ram_size__;
+
+SECTIONS
+{
+    . = 0;
+
+    .bss :
+    {
+        _bss_start = .;
+        *(.bss)
+        . = ALIGN(4);
+        *(.bss.*)
+        . = ALIGN(4);
+        *(COMMON)
+        . = ALIGN(4);
+        _bss_end = .;
+    } > ram0
+
+    .text : ALIGN(16) SUBALIGN(16)
+    {
+        _text = .;
+        KEEP(*(vectors))
+        *(.text)
+        *(.text.*)
+        *(.rodata)
+        *(.rodata.*)
+        *(.glue_7t)
+        *(.glue_7)
+        *(.gcc*)
+    } > ram1
+
+    .ctors :
+    {
+        PROVIDE(_ctors_start_ = .);
+        KEEP(*(SORT(.ctors.*)))
+        KEEP(*(.ctors))
+        PROVIDE(_ctors_end_ = .);
+    } > ram1
+
+    .dtors :
+    {
+        PROVIDE(_dtors_start_ = .);
+        KEEP(*(SORT(.dtors.*)))
+        KEEP(*(.dtors))
+        PROVIDE(_dtors_end_ = .);
+    } > ram1
+
+    .ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)}
+
+    __exidx_start = .;
+    .ARM.exidx : {*(.ARM.exidx* .gnu.linkonce.armexidx.*)} > ram1
+    __exidx_end = .;
+
+    .eh_frame_hdr : {*(.eh_frame_hdr)}
+
+    .eh_frame : ONLY_IF_RO {*(.eh_frame)}
+
+    . = ALIGN(4);
+    _etext = .;
+    _textdata = _etext;
+
+    .data :
+    {
+        _data = .;
+        *(.data)
+        . = ALIGN(4);
+        *(.data.*)
+        . = ALIGN(4);
+        *(.ramtext)
+        . = ALIGN(4);
+        _edata = .;
+    } > ram1
+
+    PROVIDE(end = .);
+    _end            = .;
+}
+
+__heap_base__   = _end;
+__heap_end__    = __ram_end__ - __stacks_total_size__;