Fix for GNU/Linux
[gnuk/neug.git] / src / main.c
1 /*
2  * main.c - main routine of neug
3  *
4  * Main routine:
5  * Copyright (C) 2011, 2012, 2013, 2015, 2016, 2017
6  *               Free Software Initiative of Japan
7  * Author: NIIBE Yutaka <gniibe@fsij.org>
8  *
9  * This file is a part of NeuG, a True Random Number Generator
10  * implementation.
11  *
12  * NeuG is free software: you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * NeuG is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20  * License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  *
25  */
26
27
28 #include <stdint.h>
29 #include <string.h>
30 #include <chopstx.h>
31
32 #include "config.h"
33 #include "neug.h"
34 #include "usb_lld.h"
35 #include "sys.h"
36 #ifndef GNU_LINUX_EMULATION
37 #include "mcu/stm32f103.h"
38 #endif
39 #include "adc.h"
40
41 enum {
42   FSIJ_DEVICE_RUNNING = 0,
43   FSIJ_DEVICE_EXITED,
44   FSIJ_DEVICE_EXEC_REQUESTED,
45   /**/
46   FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED = 254,
47   FSIJ_DEVICE_NEUG_EXIT_REQUESTED = 255
48 };
49
50 #ifdef FRAUCHEKY_SUPPORT
51 static uint8_t running_neug;
52 extern void EP6_IN_Callback (uint16_t len);
53 extern void EP6_OUT_Callback (uint16_t len);
54 #endif
55
56 static chopstx_mutex_t usb_mtx;
57 static chopstx_cond_t usb_cnd;
58 static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
59 static uint8_t fsij_device_state = FSIJ_DEVICE_RUNNING;
60 static uint8_t connected;
61
62
63 #define ENDP0_RXADDR        (0x40)
64 #define ENDP0_TXADDR        (0x80)
65 #define ENDP1_TXADDR        (0xc0)
66 #define ENDP2_TXADDR        (0x100)
67 #define ENDP3_RXADDR        (0x140)
68
69 #define USB_CDC_REQ_SET_LINE_CODING             0x20
70 #define USB_CDC_REQ_GET_LINE_CODING             0x21
71 #define USB_CDC_REQ_SET_CONTROL_LINE_STATE      0x22
72 #define USB_CDC_REQ_SEND_BREAK                  0x23
73
74 /* USB Device Descriptor */
75 static const uint8_t vcom_device_desc[18] = {
76   18,   /* bLength */
77   DEVICE_DESCRIPTOR,            /* bDescriptorType */
78   0x10, 0x01,                   /* bcdUSB = 1.1 */
79   0x02,                         /* bDeviceClass (CDC).              */
80   0x00,                         /* bDeviceSubClass.                 */
81   0x00,                         /* bDeviceProtocol.                 */
82   0x40,                         /* bMaxPacketSize.                  */
83 #include "usb-vid-pid-ver.c.inc"
84   1,                            /* iManufacturer.                   */
85   2,                            /* iProduct.                        */
86   3,                            /* iSerialNumber.                   */
87   1                             /* bNumConfigurations.              */
88 };
89
90 #define VCOM_FEATURE_BUS_POWERED        0x80
91
92 /* Configuration Descriptor tree for a CDC.*/
93 static const uint8_t vcom_config_desc[67] = {
94   9,
95   CONFIG_DESCRIPTOR,            /* bDescriptorType: Configuration   */
96   /* Configuration Descriptor.*/
97   67, 0x00,                     /* wTotalLength.                    */
98   0x02,                         /* bNumInterfaces.                  */
99   0x01,                         /* bConfigurationValue.             */
100   0,                            /* iConfiguration.                  */
101   VCOM_FEATURE_BUS_POWERED,     /* bmAttributes.                    */
102   50,                           /* bMaxPower (100mA).               */
103   /* Interface Descriptor.*/
104   9,
105   INTERFACE_DESCRIPTOR,
106   0x00,            /* bInterfaceNumber.                */
107   0x00,            /* bAlternateSetting.               */
108   0x01,            /* bNumEndpoints.                   */
109   0x02,            /* bInterfaceClass (Communications Interface Class,
110                       CDC section 4.2).  */
111   0x02,            /* bInterfaceSubClass (Abstract Control Model, CDC
112                       section 4.3).  */
113   0x01,            /* bInterfaceProtocol (AT commands, CDC section
114                       4.4).  */
115   0,               /* iInterface.                      */
116   /* Header Functional Descriptor (CDC section 5.2.3).*/
117   5,          /* bLength.                         */
118   0x24,       /* bDescriptorType (CS_INTERFACE).  */
119   0x00,       /* bDescriptorSubtype (Header Functional Descriptor). */
120   0x10, 0x01, /* bcdCDC.                          */
121   /* Call Management Functional Descriptor. */
122   5,            /* bFunctionLength.                 */
123   0x24,         /* bDescriptorType (CS_INTERFACE).  */
124   0x01,         /* bDescriptorSubtype (Call Management Functional
125                    Descriptor). */
126   0x03,         /* bmCapabilities (D0+D1).          */
127   0x01,         /* bDataInterface.                  */
128   /* ACM Functional Descriptor.*/
129   4,            /* bFunctionLength.                 */
130   0x24,         /* bDescriptorType (CS_INTERFACE).  */
131   0x02,         /* bDescriptorSubtype (Abstract Control Management
132                    Descriptor).  */
133   0x02,         /* bmCapabilities.                  */
134   /* Union Functional Descriptor.*/
135   5,            /* bFunctionLength.                 */
136   0x24,         /* bDescriptorType (CS_INTERFACE).  */
137   0x06,         /* bDescriptorSubtype (Union Functional
138                    Descriptor).  */
139   0x00,         /* bMasterInterface (Communication Class
140                    Interface).  */
141   0x01,         /* bSlaveInterface0 (Data Class Interface).  */
142   /* Endpoint 2 Descriptor.*/
143   7,
144   ENDPOINT_DESCRIPTOR,
145   ENDP2|0x80,    /* bEndpointAddress.    */
146   0x03,          /* bmAttributes (Interrupt).        */
147   0x08, 0x00,    /* wMaxPacketSize.                  */
148   0xFF,          /* bInterval.                       */
149   /* Interface Descriptor.*/
150   9,
151   INTERFACE_DESCRIPTOR,          /* bDescriptorType: */
152   0x01,          /* bInterfaceNumber.                */
153   0x00,          /* bAlternateSetting.               */
154   0x02,          /* bNumEndpoints.                   */
155   0x0A,          /* bInterfaceClass (Data Class Interface, CDC section 4.5). */
156   0x00,          /* bInterfaceSubClass (CDC section 4.6). */
157   0x00,          /* bInterfaceProtocol (CDC section 4.7). */
158   0x00,          /* iInterface.                      */
159   /* Endpoint 3 Descriptor.*/
160   7,
161   ENDPOINT_DESCRIPTOR,          /* bDescriptorType: Endpoint */
162   ENDP3,    /* bEndpointAddress. */
163   0x02,                         /* bmAttributes (Bulk).             */
164   0x40, 0x00,                   /* wMaxPacketSize.                  */
165   0x00,                         /* bInterval.                       */
166   /* Endpoint 1 Descriptor.*/
167   7,
168   ENDPOINT_DESCRIPTOR,          /* bDescriptorType: Endpoint */
169   ENDP1|0x80,                   /* bEndpointAddress. */
170   0x02,                         /* bmAttributes (Bulk).             */
171   0x40, 0x00,                   /* wMaxPacketSize.                  */
172   0x00                          /* bInterval.                       */
173 };
174
175
176 /*
177  * U.S. English language identifier.
178  */
179 static const uint8_t vcom_string0[4] = {
180   4,                            /* bLength */
181   STRING_DESCRIPTOR,
182   0x09, 0x04                    /* LangID = 0x0409: US-English */
183 };
184
185 #include "usb-strings.c.inc"
186
187 static void neug_setup_endpoints_for_interface (struct usb_dev *dev,
188                                                 uint16_t interface, int stop);
189 #ifdef FRAUCHEKY_SUPPORT
190 #define MSC_MASS_STORAGE_RESET_COMMAND 0xFF
191 extern int fraucheky_enabled (void);
192 extern void fraucheky_main (void);
193
194 extern void fraucheky_setup_endpoints_for_interface (int stop);
195 extern int fraucheky_setup (struct usb_dev *dev);
196 extern int fraucheky_get_descriptor (struct usb_dev *dev);
197 #endif
198
199 #define NUM_INTERFACES 2
200
201 static void
202 usb_device_reset (struct usb_dev *dev)
203 {
204   int i;
205
206   usb_lld_reset (dev, VCOM_FEATURE_BUS_POWERED);
207
208   /* Initialize Endpoint 0.  */
209 #ifdef GNU_LINUX_EMULATION
210   usb_lld_setup_endp (dev, ENDP0, 1, 1);
211 #else
212   usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
213 #endif
214
215   /* Stop the interface */
216   for (i = 0; i < NUM_INTERFACES; i++)
217     neug_setup_endpoints_for_interface (dev, i, 1);
218
219   /* Notify upper layer.  */
220   chopstx_mutex_lock (&usb_mtx);
221   bDeviceState = ATTACHED;
222   connected = 0;
223   chopstx_cond_signal (&usb_cnd);
224   chopstx_mutex_unlock (&usb_mtx);
225 }
226
227 #ifndef GNU_LINUX_EMULATION
228 extern uint8_t _regnual_start, __heap_end__;
229
230 static const uint8_t *const mem_info[] = { &_regnual_start,  &__heap_end__, };
231 #endif
232
233 /* USB vendor requests to control pipe */
234 #define USB_FSIJ_MEMINFO          0
235 #define USB_FSIJ_DOWNLOAD         1
236 #define USB_FSIJ_EXEC             2
237 #define USB_NEUG_SET_PASSWD     253
238 #define USB_NEUG_GET_INFO       254
239 #define USB_NEUG_EXIT           255 /* Ask to exit and to receive reGNUal */
240
241 #define DEFAULT_PASSWD "12345678"
242 #define DEFAULT_PASSWD_LEN 8
243
244 uint8_t neug_passwd[33] __attribute__ ((section(".passwd"))) = {
245   0xff,
246   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
247   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
248   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
249 };
250 static uint8_t usbbuf[64];
251
252 #ifndef GNU_LINUX_EMULATION
253 static void set_passwd (void)
254 {
255   flash_unlock ();
256   if (neug_passwd[0] != 0xff)
257     flash_erase_page ((uintptr_t)neug_passwd);
258   if (usbbuf[0] == DEFAULT_PASSWD_LEN
259       && !memcmp (usbbuf + 1, DEFAULT_PASSWD, DEFAULT_PASSWD_LEN))
260     return;
261   flash_write ((uintptr_t)neug_passwd, usbbuf, usbbuf[0] + 1);
262 }
263
264
265 /* After calling this function, CRC module remain enabled.  */
266 static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
267 {
268   uint32_t crc32 = *end_p;
269   const uint32_t *p;
270
271   crc32_rv_reset ();
272
273   for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
274     crc32_rv_step (rbit (*p));
275
276   if ((rbit (crc32_rv_get ()) ^ crc32) == 0xffffffff)
277     return usb_lld_ctrl_ack (dev);
278
279   return -1;
280 }
281 #endif
282
283
284 #define NEUG_SPECIAL_BITRATE 110
285
286 struct line_coding
287 {
288   uint32_t bitrate;
289   uint8_t format;
290   uint8_t paritytype;
291   uint8_t datatype;
292 } __attribute__((packed));
293
294 static struct line_coding line_coding = {
295   115200, /* baud rate: 115200    */
296   0x00,   /* stop bits: 1         */
297   0x00,   /* parity:    none      */
298   0x08    /* bits:      8         */
299 };
300
301 #define CDC_CTRL_DTR            0x0001
302
303 static void
304 usb_ctrl_write_finish (struct usb_dev *dev)
305 {
306   struct device_req *arg = &dev->dev_req;
307   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
308
309   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
310       && USB_SETUP_SET (arg->type))
311     {
312       if (arg->request == USB_FSIJ_EXEC)
313         {
314           chopstx_mutex_lock (&usb_mtx);
315           if (fsij_device_state == FSIJ_DEVICE_EXITED)
316             {
317               usb_lld_prepare_shutdown (); /* No further USB communication */
318               fsij_device_state = FSIJ_DEVICE_EXEC_REQUESTED;
319             }
320           chopstx_mutex_unlock (&usb_mtx);
321         }
322 #ifndef GNU_LINUX_EMULATION
323       else if (arg->request == USB_NEUG_SET_PASSWD)
324         set_passwd ();
325 #endif
326       else if (arg->request == USB_NEUG_EXIT)
327         {
328           if ((neug_passwd[0] == 0xff && usbbuf[0] == DEFAULT_PASSWD_LEN
329                && !memcmp (usbbuf + 1, DEFAULT_PASSWD, DEFAULT_PASSWD_LEN))
330 #ifndef GNU_LINUX_EMULATION
331               || (neug_passwd[0] == usbbuf[0]
332                   && !memcmp (neug_passwd+1, usbbuf+1, neug_passwd[0]))
333 #endif
334               )
335             {
336               chopstx_mutex_lock (&usb_mtx);
337               fsij_device_state = FSIJ_DEVICE_NEUG_EXIT_REQUESTED;
338               chopstx_cond_signal (&usb_cnd);
339               chopstx_mutex_unlock (&usb_mtx);
340             }
341         }
342     }
343   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0
344            && USB_SETUP_SET (arg->type))
345     {
346       if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
347         {
348           /* Open/close the connection.  */
349           chopstx_mutex_lock (&usb_mtx);
350           connected = (arg->value & CDC_CTRL_DTR)? 1 : 0;
351           chopstx_cond_signal (&usb_cnd);
352           chopstx_mutex_unlock (&usb_mtx);
353         }
354 #ifdef FRAUCHEKY_SUPPORT
355       else if (running_neug && arg->request == USB_CDC_REQ_SET_LINE_CODING)
356         {
357           chopstx_mutex_lock (&usb_mtx);
358           if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
359             {
360               fsij_device_state = FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED;
361               chopstx_cond_signal (&usb_cnd);
362             }
363           else if (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
364             fsij_device_state = FSIJ_DEVICE_RUNNING;
365           chopstx_mutex_unlock (&usb_mtx);
366         }
367       else if (!running_neug && arg->request == MSC_MASS_STORAGE_RESET_COMMAND)
368         fraucheky_setup_endpoints_for_interface (0);
369 #endif
370     }
371 }
372
373
374 static int
375 vcom_port_data_setup (struct usb_dev *dev)
376 {
377   struct device_req *arg = &dev->dev_req;
378
379   if (USB_SETUP_GET (arg->type))
380     {
381       if (arg->request == USB_CDC_REQ_GET_LINE_CODING)
382         return usb_lld_ctrl_send (dev, &line_coding, sizeof(line_coding));
383     }
384   else  /* USB_SETUP_SET (req) */
385     {
386       if (arg->request == USB_CDC_REQ_SET_LINE_CODING
387           && arg->len == sizeof (line_coding))
388         return usb_lld_ctrl_recv (dev, &line_coding, sizeof (line_coding));
389       else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
390         return usb_lld_ctrl_ack (dev);
391     }
392
393   return -1;
394 }
395
396 static int
397 usb_setup (struct usb_dev *dev)
398 {
399   struct device_req *arg = &dev->dev_req;
400   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
401
402   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
403     {
404       if (USB_SETUP_GET (arg->type))
405         {
406           if (arg->request == USB_FSIJ_MEMINFO)
407             {
408 #ifdef GNU_LINUX_EMULATION
409               return -1;
410 #else
411               chopstx_mutex_lock (&usb_mtx);
412               if (fsij_device_state != FSIJ_DEVICE_EXITED)
413                 {
414                   chopstx_mutex_unlock (&usb_mtx);
415                   return -1;
416                 }
417               chopstx_mutex_unlock (&usb_mtx);
418               return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
419 #endif
420             }
421           else if (arg->request == USB_NEUG_GET_INFO)
422             {
423               if (arg->index == 0)
424                 return usb_lld_ctrl_send (dev, &neug_mode, sizeof (uint8_t));
425               else if (arg->index == 1)
426                 return usb_lld_ctrl_send (dev, &neug_err_cnt, sizeof (uint16_t));
427               else if (arg->index == 2)
428                 return usb_lld_ctrl_send (dev, &neug_err_cnt_rc, sizeof (uint16_t));
429               else if (arg->index == 3)
430                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p64, sizeof (uint16_t));
431               else if (arg->index == 4)
432                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p4k, sizeof (uint16_t));
433               else if (arg->index == 5)
434                 return usb_lld_ctrl_send (dev, &neug_rc_max, sizeof (uint16_t));
435               else if (arg->index == 6)
436                 return usb_lld_ctrl_send (dev, &neug_p64_max, sizeof (uint16_t));
437               else if (arg->index == 7)
438                 return usb_lld_ctrl_send (dev, &neug_p4k_max, sizeof (uint16_t));
439               else
440                 return -1;
441             }
442         }
443       else /* SETUP_SET */
444         {
445           uint8_t *addr = (uint8_t *)(0x20000000UL + arg->value * 0x100 + arg->index);
446
447           if (arg->request == USB_FSIJ_DOWNLOAD)
448             {
449 #ifdef GNU_LINUX_EMULATION
450               return -1;
451 #else
452               chopstx_mutex_lock (&usb_mtx);
453               if (fsij_device_state != FSIJ_DEVICE_EXITED)
454                 {
455                   chopstx_mutex_unlock (&usb_mtx);
456                   return -1;
457                 }
458               chopstx_mutex_unlock (&usb_mtx);
459
460               if (addr < &_regnual_start || addr + arg->len > &__heap_end__)
461                 return -1;
462
463               if (arg->index + arg->len < 256)
464                 memset (addr + arg->index + arg->len, 0, 256 - (arg->index + arg->len));
465
466               return usb_lld_ctrl_recv (dev, addr, arg->len);
467 #endif
468             }
469           else if (arg->request == USB_FSIJ_EXEC && arg->len == 0)
470             {
471 #ifdef GNU_LINUX_EMULATION
472               return -1;
473 #else
474               chopstx_mutex_lock (&usb_mtx);
475               if (fsij_device_state != FSIJ_DEVICE_EXITED)
476                 {
477                   chopstx_mutex_unlock (&usb_mtx);
478                   return -1;
479                 }
480               chopstx_mutex_unlock (&usb_mtx);
481
482               if (((uintptr_t)addr & 0x03))
483                 return -1;
484
485               return download_check_crc32 (dev, (uint32_t *)addr);
486 #endif
487             }
488           else if (arg->request == USB_NEUG_SET_PASSWD && arg->len <= 32)
489             {
490               usbbuf[0] = arg->len;
491               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
492             }
493           else if (arg->request == USB_NEUG_EXIT && arg->len <= 32)
494             {
495               chopstx_mutex_lock (&usb_mtx);
496               if (fsij_device_state != FSIJ_DEVICE_RUNNING)
497                 {
498                   chopstx_mutex_unlock (&usb_mtx);
499                   return -1;
500                 }
501               chopstx_mutex_unlock (&usb_mtx);
502
503               usbbuf[0] = arg->len;
504               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
505             }
506         }
507     }
508   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
509            && arg->index == 0)
510     {
511 #ifdef FRAUCHEKY_SUPPORT
512       if (running_neug)
513         return vcom_port_data_setup (dev);
514       else
515         return fraucheky_setup (dev);
516 #else
517       return vcom_port_data_setup (dev);
518 #endif
519     }
520
521   return -1;
522 }
523
524 static int
525 usb_get_descriptor (struct usb_dev *dev)
526 {
527   struct device_req *arg = &dev->dev_req;
528   uint8_t rcp = arg->type & RECIPIENT;
529   uint8_t desc_type = (arg->value >> 8);
530   uint8_t desc_index = (arg->value & 0xff);
531
532 #ifdef FRAUCHEKY_SUPPORT
533   if (!running_neug)
534     return fraucheky_get_descriptor (dev);
535 #endif
536
537   if (rcp != DEVICE_RECIPIENT)
538     return -1;
539
540   if (desc_type == DEVICE_DESCRIPTOR)
541     return usb_lld_ctrl_send (dev,
542                               vcom_device_desc, sizeof (vcom_device_desc));
543   else if (desc_type == CONFIG_DESCRIPTOR)
544     return usb_lld_ctrl_send (dev,
545                               vcom_config_desc, sizeof (vcom_config_desc));
546   else if (desc_type == STRING_DESCRIPTOR)
547     {
548       const uint8_t *str;
549       int size;
550
551       switch (desc_index)
552         {
553         case 0:
554           str = vcom_string0;
555           size = sizeof (vcom_string0);
556           break;
557         case 1:
558           str = neug_string_vendor;
559           size = sizeof (neug_string_vendor);
560           break;
561         case 2:
562           str = neug_string_product;
563           size = sizeof (neug_string_product);
564           break;
565         case 3:
566           str = neug_string_serial;
567           size = sizeof (neug_string_serial);
568           break;
569         case 4:
570           str = neug_revision_detail;
571           size = sizeof (neug_revision_detail);
572           break;
573         case 5:
574           str = neug_config_options;
575           size = sizeof (neug_config_options);
576           break;
577         case 6:
578           str = sys_version;
579           size = sizeof (sys_version);
580           break;
581 #ifdef USE_SYS3
582         case 7:
583           {
584             int i;
585             str = usbbuf;
586             for (i = 0; i < (int)sizeof (usbbuf)/2 - 2; i++)
587               {
588                 if (sys_board_name[i] == 0)
589                   break;
590
591                 usbbuf[i*2+2] = sys_board_name[i];
592                 usbbuf[i*2+3] = 0;
593               }
594             usbbuf[0] = i*2 + 2;
595             usbbuf[1] = STRING_DESCRIPTOR;
596             size = i*2 + 2;
597           }
598           break;
599 #endif
600         default:
601           return -1;
602         }
603
604       return usb_lld_ctrl_send (dev, str, size);
605     }
606
607   return -1;
608 }
609
610 static void
611 neug_setup_endpoints_for_interface (struct usb_dev *dev,
612                                     uint16_t interface, int stop)
613 {
614 #if !defined(GNU_LINUX_EMULATION)
615   (void)dev;
616 #endif
617   
618   if (interface == 0)
619     {
620 #ifdef FRAUCHEKY_SUPPORT
621       if (running_neug)
622         {
623           if (!stop)
624 #ifdef GNU_LINUX_EMULATION
625             usb_lld_setup_endp (dev, ENDP2, 0, 1);
626 #else
627             usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
628 #endif
629           else
630             usb_lld_stall_tx (ENDP2);
631         }
632       else
633         fraucheky_setup_endpoints_for_interface (stop);
634 #else
635       if (!stop)
636 #ifdef GNU_LINUX_EMULATION
637         usb_lld_setup_endp (dev, ENDP2, 0, 1);
638 #else
639         usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
640 #endif
641       else
642         usb_lld_stall_tx (ENDP2);
643 #endif
644     }
645   else if (interface == 1)
646     {
647       if (!stop)
648         {
649 #ifdef GNU_LINUX_EMULATION
650           usb_lld_setup_endp (dev, ENDP1, 0, 1);
651           usb_lld_setup_endp (dev, ENDP3, 1, 0);
652 #else
653           usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
654           usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
655 #endif
656           /* Start with no data receiving (ENDP3 not enabled) */
657         }
658       else
659         {
660           usb_lld_stall_tx (ENDP1);
661           usb_lld_stall_rx (ENDP3);
662         }
663     }
664 }
665
666 static int
667 usb_set_configuration (struct usb_dev *dev)
668 {
669   int i;
670   uint8_t current_conf;
671
672   current_conf = usb_lld_current_configuration (dev);
673   if (current_conf == 0)
674     {
675       if (dev->dev_req.value != 1)
676         return -1;
677
678       usb_lld_set_configuration (dev, 1);
679       for (i = 0; i < NUM_INTERFACES; i++)
680         neug_setup_endpoints_for_interface (dev, i, 0);
681       chopstx_mutex_lock (&usb_mtx);
682       bDeviceState = CONFIGURED;
683       chopstx_mutex_unlock (&usb_mtx);
684     }
685   else if (current_conf != dev->dev_req.value)
686     {
687       if (dev->dev_req.value != 0)
688         return -1;
689
690       usb_lld_set_configuration (dev, 0);
691       for (i = 0; i < NUM_INTERFACES; i++)
692         neug_setup_endpoints_for_interface (dev, i, 1);
693       chopstx_mutex_lock (&usb_mtx);
694       bDeviceState = ADDRESSED;
695       chopstx_cond_signal (&usb_cnd);
696       chopstx_mutex_unlock (&usb_mtx);
697     }
698
699   /* Do nothing when current_conf == value */
700   return usb_lld_ctrl_ack (dev);
701 }
702
703
704 static int
705 usb_set_interface (struct usb_dev *dev)
706 {
707   uint16_t interface = dev->dev_req.index;
708   uint16_t alt = dev->dev_req.value;
709
710   if (interface >= NUM_INTERFACES)
711     return -1;
712
713   if (alt != 0)
714     return -1;
715   else
716     {
717       neug_setup_endpoints_for_interface (dev, interface, 0);
718       return usb_lld_ctrl_ack (dev);
719     }
720 }
721
722 static int
723 usb_get_interface (struct usb_dev *dev)
724 {
725   const uint8_t zero = 0;
726   uint16_t interface = dev->dev_req.index;
727
728   if (interface >= NUM_INTERFACES)
729     return -1;
730
731   return usb_lld_ctrl_send (dev, &zero, 1);
732 }
733
734
735 static int
736 usb_get_status_interface (struct usb_dev *dev)
737 {
738   const uint16_t status_info = 0;
739   uint16_t interface = dev->dev_req.index;
740
741   if (interface >= NUM_INTERFACES)
742     return -1;
743
744   return usb_lld_ctrl_send (dev, &status_info, 2);
745 }
746
747 static void usb_tx_done (uint8_t ep_num, uint16_t len);
748 static void usb_rx_ready (uint8_t ep_num, uint16_t len);
749
750
751 #ifdef GNU_LINUX_EMULATION
752 #include <signal.h>
753 #define INTR_REQ_USB SIGUSR1
754 #else
755 #define INTR_REQ_USB 20
756 #endif
757
758 #define PRIO_USB 3
759
760 static void *
761 usb_main (void *arg)
762 {
763   chopstx_intr_t interrupt;
764   struct usb_dev dev;
765   int e;
766
767   (void)arg;
768   usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED);
769   chopstx_claim_irq (&interrupt, INTR_REQ_USB);
770   goto event_handle;    /* For old SYS < 3.0 */
771
772   while (1)
773     {
774       chopstx_intr_wait (&interrupt);
775
776       if (interrupt.ready)
777         {
778           uint8_t ep_num;
779
780         event_handle:
781           e = usb_lld_event_handler (&dev);
782           ep_num = USB_EVENT_ENDP (e);
783
784           if (ep_num != 0)
785             {
786               if (USB_EVENT_TXRX (e))
787                 usb_tx_done (ep_num, USB_EVENT_LEN (e));
788               else
789                 usb_rx_ready (ep_num, USB_EVENT_LEN (e));
790             }
791           else
792             switch (USB_EVENT_ID (e))
793               {
794               case USB_EVENT_DEVICE_RESET:
795                 usb_device_reset (&dev);
796                 continue;
797
798               case USB_EVENT_DEVICE_ADDRESSED:
799                 chopstx_mutex_lock (&usb_mtx);
800                 bDeviceState = ADDRESSED;
801                 chopstx_cond_signal (&usb_cnd);
802                 chopstx_mutex_unlock (&usb_mtx);
803                 continue;
804
805               case USB_EVENT_GET_DESCRIPTOR:
806                 if (usb_get_descriptor (&dev) < 0)
807                   usb_lld_ctrl_error (&dev);
808                 continue;
809
810               case USB_EVENT_SET_CONFIGURATION:
811                 if (usb_set_configuration (&dev) < 0)
812                   usb_lld_ctrl_error (&dev);
813                 continue;
814
815               case USB_EVENT_SET_INTERFACE:
816                 if (usb_set_interface (&dev) < 0)
817                   usb_lld_ctrl_error (&dev);
818                 continue;
819
820               case USB_EVENT_CTRL_REQUEST:
821                 /* Device specific device request.  */
822                 if (usb_setup (&dev) < 0)
823                   usb_lld_ctrl_error (&dev);
824                 continue;
825
826               case USB_EVENT_GET_STATUS_INTERFACE:
827                 if (usb_get_status_interface (&dev) < 0)
828                   usb_lld_ctrl_error (&dev);
829                 continue;
830
831               case USB_EVENT_GET_INTERFACE:
832                 if (usb_get_interface (&dev) < 0)
833                   usb_lld_ctrl_error (&dev);
834                 continue;
835
836               case USB_EVENT_SET_FEATURE_DEVICE:
837               case USB_EVENT_SET_FEATURE_ENDPOINT:
838               case USB_EVENT_CLEAR_FEATURE_DEVICE:
839               case USB_EVENT_CLEAR_FEATURE_ENDPOINT:
840                 usb_lld_ctrl_ack (&dev);
841                 continue;
842
843               case USB_EVENT_CTRL_WRITE_FINISH:
844                 /* Control WRITE transfer finished.  */
845                 usb_ctrl_write_finish (&dev);
846                 continue;
847
848               case USB_EVENT_OK:
849               case USB_EVENT_DEVICE_SUSPEND:
850               default:
851                 continue;
852               }
853         }
854     }
855
856   return NULL;
857 }
858
859 #define ID_OFFSET (2+SERIALNO_STR_LEN*2)
860 static void fill_serial_no_by_unique_id (void)
861 {
862   extern const uint8_t * unique_device_id (void);
863   uint8_t *p = &neug_string_serial[ID_OFFSET];
864   const uint8_t *u = unique_device_id () + 8;
865   int i;
866
867   for (i = 0; i < 4; i++)
868     {
869       uint8_t b = u[3-i];
870       uint8_t nibble;
871
872       nibble = (b >> 4);
873       nibble += (nibble >= 10 ? ('A' - 10) : '0');
874       p[i*4] = nibble;
875       p[i*4+1] = 0;
876       nibble = (b & 0x0f);
877       nibble += (nibble >= 10 ? ('A' - 10) : '0');
878       p[i*4+2] = nibble;
879       p[i*4+3] = 0;
880     }
881 }
882
883
884 static void
885 usb_tx_done (uint8_t ep_num, uint16_t len)
886 {
887   if (ep_num == ENDP1)
888     {
889       chopstx_mutex_lock (&usb_mtx);
890       chopstx_cond_signal (&usb_cnd);
891       chopstx_mutex_unlock (&usb_mtx);
892     }
893   else if (ep_num == ENDP2)
894     {
895       /* INTERRUPT Transfer done */
896     }
897 #ifdef FRAUCHEKY_SUPPORT
898   else if (ep_num == ENDP6)
899     EP6_IN_Callback (len);
900 #else
901   (void)len;
902 #endif
903 }
904
905 #ifdef GNU_LINUX_EMULATION
906 static uint8_t endp3_buf[64];
907 #endif
908
909 static void
910 usb_rx_ready (uint8_t ep_num, uint16_t len)
911 {
912   if (ep_num == ENDP3)
913 #ifdef GNU_LINUX_EMULATION
914     usb_lld_rx_enable_buf (ENDP3, endp3_buf, 64);
915 #else
916     usb_lld_rx_enable (ENDP3);
917 #endif
918 #ifdef FRAUCHEKY_SUPPORT
919   else if (ep_num == ENDP6)
920     EP6_OUT_Callback (len);
921 #else
922   (void)len;
923 #endif
924 }
925 \f
926 typedef uint32_t eventmask_t;
927 #define ALL_EVENTS (~0)
928
929 struct event_flag {
930   chopstx_mutex_t mutex;
931   chopstx_cond_t cond;
932   eventmask_t flag;
933 };
934
935 static void event_flag_init (struct event_flag *ev)
936 {
937   ev->flag = 0;
938   chopstx_mutex_init (&ev->mutex);
939   chopstx_cond_init (&ev->cond);
940 }
941
942
943 static eventmask_t event_flag_waitone (struct event_flag *ev, eventmask_t m)
944 {
945   int n;
946
947   chopstx_mutex_lock (&ev->mutex);
948   while (!(ev->flag & m))
949     chopstx_cond_wait (&ev->cond, &ev->mutex);
950
951   n = __builtin_ffs ((ev->flag & m));
952   ev->flag &= ~(1 << (n - 1));
953   chopstx_mutex_unlock (&ev->mutex);
954
955   return (1 << (n - 1));
956 }
957
958 static void event_flag_signal (struct event_flag *ev, eventmask_t m)
959 {
960   chopstx_mutex_lock (&ev->mutex);
961   ev->flag |= m;
962   chopstx_cond_signal (&ev->cond);
963   chopstx_mutex_unlock (&ev->mutex);
964 }
965
966 #ifdef GNU_LINUX_EMULATION
967 static char __process1_stack_base__[4096];
968 static char __process3_stack_base__[4096];
969 #define STACK_SIZE_LED (sizeof __process1_stack_base__)
970 #define STACK_SIZE_USB (sizeof __process3_stack_base__)
971 #else
972 extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
973 extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
974 #define STACK_SIZE_LED ((uintptr_t)__process1_stack_size__)
975 #define STACK_SIZE_USB ((uintptr_t)__process3_stack_size__)
976 #endif
977
978 #define STACK_ADDR_LED ((uintptr_t)__process1_stack_base__)
979 #define STACK_ADDR_USB ((uintptr_t)__process3_stack_base__)
980
981
982 #define PRIO_LED 3
983 static struct event_flag led_event;
984
985 #define LED_ONESHOT_SHORT       ((eventmask_t)1)
986 #define LED_TWOSHOTS            ((eventmask_t)2)
987 #define LED_ONESHOT_LONG        ((eventmask_t)4)
988
989 /*
990  * LED blinker: When notified, let LED emit for 100ms.
991  */
992 static void *
993 led_blinker (void *arg)
994 {
995   (void)arg;
996
997   set_led (0);
998
999   while (1)
1000     {
1001       eventmask_t m;
1002
1003       m = event_flag_waitone (&led_event, ALL_EVENTS);
1004
1005       set_led (1);
1006       if (m == LED_ONESHOT_SHORT)
1007         chopstx_usec_wait (100*1000);
1008       else if (m == LED_TWOSHOTS)
1009         {
1010           chopstx_usec_wait (50*1000);
1011           set_led (0);
1012           chopstx_usec_wait (50*1000);
1013           set_led (1);
1014           chopstx_usec_wait (50*1000);
1015         }
1016       else
1017         chopstx_usec_wait (250*1000);
1018       set_led (0);
1019     }
1020
1021   return NULL;
1022 }
1023 \f
1024 #define RANDOM_BYTES_LENGTH 64
1025 static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)];
1026
1027 #ifdef GNU_LINUX_EMULATION
1028 static uint8_t endp1_buf[RANDOM_BYTES_LENGTH];
1029 #endif
1030
1031 static void copy_to_tx (uint32_t v, int i)
1032 {
1033 #ifdef GNU_LINUX_EMULATION
1034   memcpy (&endp1_buf[i*4], &v, 4);
1035 #else
1036   usb_lld_txcpy (&v, ENDP1, i * 4, 4);
1037 #endif
1038 }
1039
1040 #ifndef GNU_LINUX_EMULATION
1041 /*
1042  * In Gnuk 1.0.[12], reGNUal was not relocatable.
1043  * Now, it's relocatable, but we need to calculate its entry address
1044  * based on it's pre-defined address.
1045  */
1046 #define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
1047 static uint32_t
1048 calculate_regnual_entry_address (const uint8_t *addr)
1049 {
1050   const uint8_t *p = addr + 4;
1051   uintptr_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
1052
1053   v -= REGNUAL_START_ADDRESS_COMPATIBLE;
1054   v += (uintptr_t)addr;
1055   return v;
1056 }
1057 #endif
1058
1059
1060 static int
1061 check_usb_status (void *arg)
1062 {
1063   (void)arg;
1064
1065   return (connected || bDeviceState != CONFIGURED
1066           || fsij_device_state != FSIJ_DEVICE_RUNNING);
1067 }
1068
1069
1070 #ifdef GNU_LINUX_EMULATION
1071 #include <stdlib.h>
1072
1073 #define main emulated_main
1074 #endif
1075
1076 /*
1077  * Entry point.
1078  *
1079  * NOTE: the main function is already a thread in the system on entry.
1080  */
1081 int
1082 main (int argc, char **argv)
1083 {
1084 #ifndef GNU_LINUX_EMULATION
1085   uintptr_t entry;
1086 #endif
1087   chopstx_t led_thread, usb_thd;
1088   unsigned int count;
1089
1090   (void)argc;
1091   (void)argv;
1092
1093   fill_serial_no_by_unique_id ();
1094
1095   adc_init ();
1096
1097   event_flag_init (&led_event);
1098
1099   chopstx_mutex_init (&usb_mtx);
1100   chopstx_cond_init (&usb_cnd);
1101
1102 #ifdef FRAUCHEKY_SUPPORT
1103   if (fraucheky_enabled ())
1104     {
1105     go_fraucheky:
1106       bDeviceState = UNCONNECTED;
1107       running_neug = 0;
1108       usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1109                                 usb_main, NULL);
1110       while (bDeviceState != CONFIGURED)
1111         chopstx_usec_wait (250*1000);
1112       set_led (1);
1113       fraucheky_main ();
1114       chopstx_cancel (usb_thd);
1115       chopstx_join (usb_thd, NULL);
1116       usb_lld_shutdown ();
1117       bDeviceState = UNCONNECTED;
1118     }
1119
1120   running_neug = 1;
1121 #endif
1122
1123   led_thread = chopstx_create (PRIO_LED, STACK_ADDR_LED, STACK_SIZE_LED,
1124                                led_blinker, NULL);
1125
1126   usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1127                             usb_main, NULL);
1128
1129   neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
1130
1131   chopstx_mutex_lock (&usb_mtx);
1132
1133  not_configured:
1134   count = 0;
1135   /* Initial run-up */
1136   while (count < NEUG_PRE_LOOP || bDeviceState != CONFIGURED)
1137     {
1138       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1139         break;
1140
1141       chopstx_mutex_unlock (&usb_mtx);
1142       neug_wait_full ();
1143       neug_flush ();
1144
1145       if ((count & 0x0007) == 0)
1146         event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1147       chopstx_usec_wait (25*1000);
1148       count++;
1149       chopstx_mutex_lock (&usb_mtx);
1150     }
1151
1152   /* Holding USB_MTX...  */
1153   while (1)
1154     {
1155       int last_was_fullsizepacket = 0;
1156
1157       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1158         break;
1159
1160       chopstx_mutex_unlock (&usb_mtx);
1161       while (1)
1162         {
1163           uint32_t usec = 5000*1000;
1164           chopstx_poll_cond_t poll_desc;
1165           struct chx_poll_head *pd_array[1] = {
1166             (struct chx_poll_head *)&poll_desc
1167           };
1168
1169           poll_desc.type = CHOPSTX_POLL_COND;
1170           poll_desc.ready = 0;
1171           poll_desc.cond = &usb_cnd;
1172           poll_desc.mutex = &usb_mtx;
1173           poll_desc.check = check_usb_status;
1174           poll_desc.arg = NULL;
1175
1176           if (chopstx_poll (&usec, 1, pd_array))
1177             break;
1178
1179           /* Timeout */
1180           neug_flush ();
1181           neug_mode_select (line_coding.paritytype);
1182           event_flag_signal (&led_event, LED_TWOSHOTS);
1183         }
1184
1185       chopstx_mutex_lock (&usb_mtx);
1186       if (bDeviceState != CONFIGURED)
1187         goto not_configured;
1188
1189       /* The connection opened.  */
1190       count = 0;
1191
1192       while (1)
1193         {
1194           int i;
1195
1196           chopstx_mutex_unlock (&usb_mtx);
1197           /*
1198            * No parity is standard.  It means providing conditioned output.
1199            * When parity enabled, it means to provide raw output
1200            * (CRC32 filtered when odd, direct sample of ADC when even).
1201            *
1202            * line_coding.paritytype:
1203            *   0: None, 1: Odd, 2: Even
1204            */
1205           neug_mode_select (line_coding.paritytype);
1206
1207           if ((count & 0x03ff) == 0)
1208             event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1209
1210           i = neug_consume_random (copy_to_tx);
1211
1212           if (i == 0 && !last_was_fullsizepacket)
1213             {    /* Only send ZLP when the last packet was fullsize.  */
1214               neug_wait_full ();
1215
1216               chopstx_mutex_lock (&usb_mtx);
1217               if (bDeviceState != CONFIGURED || !connected
1218                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1219                 break;
1220             }
1221           else
1222             {
1223               if (i == 64/4)
1224                 last_was_fullsizepacket = 1;
1225               else
1226                 last_was_fullsizepacket = 0;
1227
1228               chopstx_mutex_lock (&usb_mtx);
1229               if (bDeviceState != CONFIGURED || !connected
1230                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1231                 break;
1232
1233               /* Prepare sending random data.  */
1234 #ifdef GNU_LINUX_EMULATION
1235               usb_lld_tx_enable_buf (ENDP1, endp1_buf, i * 4);
1236 #else
1237               usb_lld_tx_enable (ENDP1, i * 4);
1238 #endif
1239               chopstx_cond_wait (&usb_cnd, &usb_mtx);
1240               count++;
1241             }
1242         }
1243     }
1244
1245   chopstx_mutex_unlock (&usb_mtx);
1246
1247   chopstx_cancel (led_thread);
1248   chopstx_join (led_thread, NULL);
1249
1250   /*
1251    * We come here, because of FSIJ_DEVICE_NEUG_EXIT_REQUESTED
1252    * or FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED.
1253    */
1254   neug_fini ();
1255
1256   chopstx_mutex_lock (&usb_mtx);
1257 #ifdef FRAUCHEKY_SUPPORT
1258   if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
1259     {
1260       while (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
1261         {
1262           chopstx_mutex_unlock (&usb_mtx);
1263           set_led (1);
1264           chopstx_usec_wait (500*1000);
1265           set_led (0);
1266           chopstx_usec_wait (500*1000);
1267           chopstx_mutex_lock (&usb_mtx);
1268         }
1269
1270       usb_lld_prepare_shutdown ();
1271       chopstx_mutex_unlock (&usb_mtx);
1272       chopstx_cancel (usb_thd);
1273       chopstx_join (usb_thd, NULL);
1274       usb_lld_shutdown ();
1275       goto go_fraucheky;
1276     }
1277 #endif
1278
1279   fsij_device_state = FSIJ_DEVICE_EXITED;
1280
1281   while (fsij_device_state == FSIJ_DEVICE_EXITED)
1282     {
1283       chopstx_mutex_unlock (&usb_mtx);
1284       chopstx_usec_wait (500*1000);
1285       chopstx_mutex_lock (&usb_mtx);
1286     }
1287   chopstx_mutex_unlock (&usb_mtx);
1288
1289   flash_unlock ();              /* Flash unlock should be done here */
1290   set_led (1);
1291   usb_lld_shutdown ();
1292
1293   /* Finish application.  */
1294   chopstx_cancel (usb_thd);
1295   chopstx_join (usb_thd, NULL);
1296
1297 #ifdef GNU_LINUX_EMULATION
1298   exit (0);
1299 #else
1300   /* Set vector */
1301   SCB->VTOR = (uintptr_t)&_regnual_start;
1302   entry = calculate_regnual_entry_address (&_regnual_start);
1303 #ifdef DFU_SUPPORT
1304 #define FLASH_SYS_START_ADDR 0x08000000
1305 #define FLASH_SYS_END_ADDR (0x08000000+0x1000)
1306 #define CHIP_ID_REG ((uint32_t *)0xE0042000)
1307   {
1308     extern uint8_t _sys;
1309     uint32_t addr;
1310     handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
1311     void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
1312     uint32_t flash_page_size = 1024; /* 1KiB default */
1313
1314    if ((*CHIP_ID_ADDR)&0x07 == 0x04) /* High dencity device.  */
1315      flash_page_size += 0x0400; /* It's 2KiB. */
1316
1317     /* Kill DFU */
1318     for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
1319          addr += flash_page_size)
1320       flash_erase_page (addr);
1321
1322     /* copy system service routines */
1323     flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
1324
1325     /* Leave NeuG to exec reGNUal */
1326     (*func) ((void (*)(void))entry);
1327     for (;;);
1328   }
1329 #else
1330   /* Leave NeuG to exec reGNUal */
1331   flash_erase_all_and_exec ((void (*)(void))entry);
1332 #endif
1333 #endif
1334
1335   /* Never reached */
1336   return 0;
1337 }