Support GNU/Linux target by main and neug routine.
[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
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 extern uint8_t _regnual_start, __heap_end__;
228
229 static const uint8_t *const mem_info[] = { &_regnual_start,  &__heap_end__, };
230
231 /* USB vendor requests to control pipe */
232 #define USB_FSIJ_MEMINFO          0
233 #define USB_FSIJ_DOWNLOAD         1
234 #define USB_FSIJ_EXEC             2
235 #define USB_NEUG_SET_PASSWD     253
236 #define USB_NEUG_GET_INFO       254
237 #define USB_NEUG_EXIT           255 /* Ask to exit and to receive reGNUal */
238
239 uint8_t neug_passwd[33] __attribute__ ((section(".passwd"))) = {
240   0xff,
241   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
242   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
243   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
244 };
245 static uint8_t usbbuf[64];
246
247 #define DEFAULT_PASSWD "12345678"
248 #define DEFAULT_PASSWD_LEN 8
249
250 static void set_passwd (void)
251 {
252   flash_unlock ();
253   if (neug_passwd[0] != 0xff)
254     flash_erase_page ((uintptr_t)neug_passwd);
255   if (usbbuf[0] == DEFAULT_PASSWD_LEN
256       && !memcmp (usbbuf + 1, DEFAULT_PASSWD, DEFAULT_PASSWD_LEN))
257     return;
258   flash_write ((uintptr_t)neug_passwd, usbbuf, usbbuf[0] + 1);
259 }
260
261 #ifndef GNU_LINUX_EMULATION
262 static uint32_t rbit (uint32_t v)
263 {
264   uint32_t r;
265
266   asm ("rbit    %0, %1" : "=r" (r) : "r" (v));
267   return r;
268 }
269 #endif
270
271 /* After calling this function, CRC module remain enabled.  */
272 static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
273 {
274 #ifdef GNU_LINUX_EMULATION
275   /* CRC32 calculation comes here.  */
276   (void)dev;
277   (void)end_p;
278 #else
279   uint32_t crc32 = *end_p;
280   const uint32_t *p;
281
282   RCC->AHBENR |= RCC_AHBENR_CRCEN;
283   CRC->CR = CRC_CR_RESET;
284
285   for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
286     CRC->DR = rbit (*p);
287
288   if ((rbit (CRC->DR) ^ crc32) == 0xffffffff)
289     return usb_lld_ctrl_ack (dev);
290 #endif
291
292   return -1;
293 }
294
295
296 #define NEUG_SPECIAL_BITRATE 110
297
298 struct line_coding
299 {
300   uint32_t bitrate;
301   uint8_t format;
302   uint8_t paritytype;
303   uint8_t datatype;
304 } __attribute__((packed));
305
306 static struct line_coding line_coding = {
307   115200, /* baud rate: 115200    */
308   0x00,   /* stop bits: 1         */
309   0x00,   /* parity:    none      */
310   0x08    /* bits:      8         */
311 };
312
313 #define CDC_CTRL_DTR            0x0001
314
315 static void
316 usb_ctrl_write_finish (struct usb_dev *dev)
317 {
318   struct device_req *arg = &dev->dev_req;
319   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
320
321   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
322       && USB_SETUP_SET (arg->type))
323     {
324       if (arg->request == USB_FSIJ_EXEC)
325         {
326           chopstx_mutex_lock (&usb_mtx);
327           if (fsij_device_state == FSIJ_DEVICE_EXITED)
328             {
329               usb_lld_prepare_shutdown (); /* No further USB communication */
330               fsij_device_state = FSIJ_DEVICE_EXEC_REQUESTED;
331             }
332           chopstx_mutex_unlock (&usb_mtx);
333         }
334       else if (arg->request == USB_NEUG_SET_PASSWD)
335         set_passwd ();
336       else if (arg->request == USB_NEUG_EXIT)
337         {
338           if ((neug_passwd[0] == 0xff && usbbuf[0] == DEFAULT_PASSWD_LEN
339                && !memcmp (usbbuf + 1, DEFAULT_PASSWD, DEFAULT_PASSWD_LEN))
340               || (neug_passwd[0] == usbbuf[0]
341                   && !memcmp (neug_passwd+1, usbbuf+1, neug_passwd[0])))
342             {
343               chopstx_mutex_lock (&usb_mtx);
344               fsij_device_state = FSIJ_DEVICE_NEUG_EXIT_REQUESTED;
345               chopstx_cond_signal (&usb_cnd);
346               chopstx_mutex_unlock (&usb_mtx);
347             }
348         }
349     }
350   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0
351            && USB_SETUP_SET (arg->type))
352     {
353       if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
354         {
355           /* Open/close the connection.  */
356           chopstx_mutex_lock (&usb_mtx);
357           connected = (arg->value & CDC_CTRL_DTR)? 1 : 0;
358           chopstx_cond_signal (&usb_cnd);
359           chopstx_mutex_unlock (&usb_mtx);
360         }
361 #ifdef FRAUCHEKY_SUPPORT
362       else if (running_neug && arg->request == USB_CDC_REQ_SET_LINE_CODING)
363         {
364           chopstx_mutex_lock (&usb_mtx);
365           if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
366             {
367               fsij_device_state = FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED;
368               chopstx_cond_signal (&usb_cnd);
369             }
370           else if (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
371             fsij_device_state = FSIJ_DEVICE_RUNNING;
372           chopstx_mutex_unlock (&usb_mtx);
373         }
374       else if (!running_neug && arg->request == MSC_MASS_STORAGE_RESET_COMMAND)
375         fraucheky_setup_endpoints_for_interface (0);
376 #endif
377     }
378 }
379
380
381 static int
382 vcom_port_data_setup (struct usb_dev *dev)
383 {
384   struct device_req *arg = &dev->dev_req;
385
386   if (USB_SETUP_GET (arg->type))
387     {
388       if (arg->request == USB_CDC_REQ_GET_LINE_CODING)
389         return usb_lld_ctrl_send (dev, &line_coding, sizeof(line_coding));
390     }
391   else  /* USB_SETUP_SET (req) */
392     {
393       if (arg->request == USB_CDC_REQ_SET_LINE_CODING
394           && arg->len == sizeof (line_coding))
395         return usb_lld_ctrl_recv (dev, &line_coding, sizeof (line_coding));
396       else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
397         return usb_lld_ctrl_ack (dev);
398     }
399
400   return -1;
401 }
402
403 static int
404 usb_setup (struct usb_dev *dev)
405 {
406   struct device_req *arg = &dev->dev_req;
407   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
408
409   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
410     {
411       if (USB_SETUP_GET (arg->type))
412         {
413           if (arg->request == USB_FSIJ_MEMINFO)
414             {
415               chopstx_mutex_lock (&usb_mtx);
416               if (fsij_device_state != FSIJ_DEVICE_EXITED)
417                 {
418                   chopstx_mutex_unlock (&usb_mtx);
419                   return -1;
420                 }
421               chopstx_mutex_unlock (&usb_mtx);
422               return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
423             }
424           else if (arg->request == USB_NEUG_GET_INFO)
425             {
426               if (arg->index == 0)
427                 return usb_lld_ctrl_send (dev, &neug_mode, sizeof (uint8_t));
428               else if (arg->index == 1)
429                 return usb_lld_ctrl_send (dev, &neug_err_cnt, sizeof (uint16_t));
430               else if (arg->index == 2)
431                 return usb_lld_ctrl_send (dev, &neug_err_cnt_rc, sizeof (uint16_t));
432               else if (arg->index == 3)
433                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p64, sizeof (uint16_t));
434               else if (arg->index == 4)
435                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p4k, sizeof (uint16_t));
436               else if (arg->index == 5)
437                 return usb_lld_ctrl_send (dev, &neug_rc_max, sizeof (uint16_t));
438               else if (arg->index == 6)
439                 return usb_lld_ctrl_send (dev, &neug_p64_max, sizeof (uint16_t));
440               else if (arg->index == 7)
441                 return usb_lld_ctrl_send (dev, &neug_p4k_max, sizeof (uint16_t));
442               else
443                 return -1;
444             }
445         }
446       else /* SETUP_SET */
447         {
448           uint8_t *addr = (uint8_t *)(0x20000000UL + arg->value * 0x100 + arg->index);
449
450           if (arg->request == USB_FSIJ_DOWNLOAD)
451             {
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             }
468           else if (arg->request == USB_FSIJ_EXEC && arg->len == 0)
469             {
470               chopstx_mutex_lock (&usb_mtx);
471               if (fsij_device_state != FSIJ_DEVICE_EXITED)
472                 {
473                   chopstx_mutex_unlock (&usb_mtx);
474                   return -1;
475                 }
476               chopstx_mutex_unlock (&usb_mtx);
477
478               if (((uintptr_t)addr & 0x03))
479                 return -1;
480
481               return download_check_crc32 (dev, (uint32_t *)addr);
482             }
483           else if (arg->request == USB_NEUG_SET_PASSWD && arg->len <= 32)
484             {
485               usbbuf[0] = arg->len;
486               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
487             }
488           else if (arg->request == USB_NEUG_EXIT && arg->len <= 32)
489             {
490               chopstx_mutex_lock (&usb_mtx);
491               if (fsij_device_state != FSIJ_DEVICE_RUNNING)
492                 {
493                   chopstx_mutex_unlock (&usb_mtx);
494                   return -1;
495                 }
496               chopstx_mutex_unlock (&usb_mtx);
497
498               usbbuf[0] = arg->len;
499               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
500             }
501         }
502     }
503   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
504            && arg->index == 0)
505     {
506 #ifdef FRAUCHEKY_SUPPORT
507       if (running_neug)
508         return vcom_port_data_setup (dev);
509       else
510         return fraucheky_setup (dev);
511 #else
512       return vcom_port_data_setup (dev);
513 #endif
514     }
515
516   return -1;
517 }
518
519 static int
520 usb_get_descriptor (struct usb_dev *dev)
521 {
522   struct device_req *arg = &dev->dev_req;
523   uint8_t rcp = arg->type & RECIPIENT;
524   uint8_t desc_type = (arg->value >> 8);
525   uint8_t desc_index = (arg->value & 0xff);
526
527 #ifdef FRAUCHEKY_SUPPORT
528   if (!running_neug)
529     return fraucheky_get_descriptor (dev);
530 #endif
531
532   if (rcp != DEVICE_RECIPIENT)
533     return -1;
534
535   if (desc_type == DEVICE_DESCRIPTOR)
536     return usb_lld_ctrl_send (dev,
537                               vcom_device_desc, sizeof (vcom_device_desc));
538   else if (desc_type == CONFIG_DESCRIPTOR)
539     return usb_lld_ctrl_send (dev,
540                               vcom_config_desc, sizeof (vcom_config_desc));
541   else if (desc_type == STRING_DESCRIPTOR)
542     {
543       const uint8_t *str;
544       int size;
545
546       switch (desc_index)
547         {
548         case 0:
549           str = vcom_string0;
550           size = sizeof (vcom_string0);
551           break;
552         case 1:
553           str = neug_string_vendor;
554           size = sizeof (neug_string_vendor);
555           break;
556         case 2:
557           str = neug_string_product;
558           size = sizeof (neug_string_product);
559           break;
560         case 3:
561           str = neug_string_serial;
562           size = sizeof (neug_string_serial);
563           break;
564         case 4:
565           str = neug_revision_detail;
566           size = sizeof (neug_revision_detail);
567           break;
568         case 5:
569           str = neug_config_options;
570           size = sizeof (neug_config_options);
571           break;
572         case 6:
573           str = sys_version;
574           size = sizeof (sys_version);
575           break;
576 #ifdef USE_SYS3
577         case 7:
578           {
579             int i;
580             str = usbbuf;
581             for (i = 0; i < (int)sizeof (usbbuf)/2 - 2; i++)
582               {
583                 if (sys_board_name[i] == 0)
584                   break;
585
586                 usbbuf[i*2+2] = sys_board_name[i];
587                 usbbuf[i*2+3] = 0;
588               }
589             usbbuf[0] = i*2 + 2;
590             usbbuf[1] = STRING_DESCRIPTOR;
591             size = i*2 + 2;
592           }
593           break;
594 #endif
595         default:
596           return -1;
597         }
598
599       return usb_lld_ctrl_send (dev, str, size);
600     }
601
602   return -1;
603 }
604
605 static void
606 neug_setup_endpoints_for_interface (struct usb_dev *dev,
607                                     uint16_t interface, int stop)
608 {
609   if (interface == 0)
610     {
611 #ifdef FRAUCHEKY_SUPPORT
612       if (running_neug)
613         {
614           if (!stop)
615 #ifdef GNU_LINUX_EMULATION
616             usb_lld_setup_endp (dev, ENDP2, 0, 1);
617 #else
618             usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
619 #endif
620           else
621             usb_lld_stall_tx (ENDP2);
622         }
623       else
624         fraucheky_setup_endpoints_for_interface (stop);
625 #else
626       if (!stop)
627 #ifdef GNU_LINUX_EMULATION
628         usb_lld_setup_endp (dev, ENDP2, 0, 1);
629 #else
630         usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
631 #endif
632       else
633         usb_lld_stall_tx (ENDP2);
634 #endif
635     }
636   else if (interface == 1)
637     {
638       if (!stop)
639         {
640 #ifdef GNU_LINUX_EMULATION
641           usb_lld_setup_endp (dev, ENDP1, 0, 1);
642           usb_lld_setup_endp (dev, ENDP3, 1, 0);
643 #else
644           usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
645           usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
646 #endif
647           /* Start with no data receiving (ENDP3 not enabled) */
648         }
649       else
650         {
651           usb_lld_stall_tx (ENDP1);
652           usb_lld_stall_rx (ENDP3);
653         }
654     }
655 }
656
657 static int
658 usb_set_configuration (struct usb_dev *dev)
659 {
660   int i;
661   uint8_t current_conf;
662
663   current_conf = usb_lld_current_configuration (dev);
664   if (current_conf == 0)
665     {
666       if (dev->dev_req.value != 1)
667         return -1;
668
669       usb_lld_set_configuration (dev, 1);
670       for (i = 0; i < NUM_INTERFACES; i++)
671         neug_setup_endpoints_for_interface (dev, i, 0);
672       chopstx_mutex_lock (&usb_mtx);
673       bDeviceState = CONFIGURED;
674       chopstx_mutex_unlock (&usb_mtx);
675     }
676   else if (current_conf != dev->dev_req.value)
677     {
678       if (dev->dev_req.value != 0)
679         return -1;
680
681       usb_lld_set_configuration (dev, 0);
682       for (i = 0; i < NUM_INTERFACES; i++)
683         neug_setup_endpoints_for_interface (dev, i, 1);
684       chopstx_mutex_lock (&usb_mtx);
685       bDeviceState = ADDRESSED;
686       chopstx_cond_signal (&usb_cnd);
687       chopstx_mutex_unlock (&usb_mtx);
688     }
689
690   /* Do nothing when current_conf == value */
691   return usb_lld_ctrl_ack (dev);
692 }
693
694
695 static int
696 usb_set_interface (struct usb_dev *dev)
697 {
698   uint16_t interface = dev->dev_req.index;
699   uint16_t alt = dev->dev_req.value;
700
701   if (interface >= NUM_INTERFACES)
702     return -1;
703
704   if (alt != 0)
705     return -1;
706   else
707     {
708       neug_setup_endpoints_for_interface (dev, interface, 0);
709       return usb_lld_ctrl_ack (dev);
710     }
711 }
712
713 static int
714 usb_get_interface (struct usb_dev *dev)
715 {
716   const uint8_t zero = 0;
717   uint16_t interface = dev->dev_req.index;
718
719   if (interface >= NUM_INTERFACES)
720     return -1;
721
722   return usb_lld_ctrl_send (dev, &zero, 1);
723 }
724
725
726 static int
727 usb_get_status_interface (struct usb_dev *dev)
728 {
729   const uint16_t status_info = 0;
730   uint16_t interface = dev->dev_req.index;
731
732   if (interface >= NUM_INTERFACES)
733     return -1;
734
735   return usb_lld_ctrl_send (dev, &status_info, 2);
736 }
737
738 static void usb_tx_done (uint8_t ep_num, uint16_t len);
739 static void usb_rx_ready (uint8_t ep_num, uint16_t len);
740
741
742 #define INTR_REQ_USB 20
743 #define PRIO_USB 3
744
745 static void *
746 usb_main (void *arg)
747 {
748   chopstx_intr_t interrupt;
749   struct usb_dev dev;
750   int e;
751
752   (void)arg;
753   usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED);
754   chopstx_claim_irq (&interrupt, INTR_REQ_USB);
755   goto event_handle;    /* For old SYS < 3.0 */
756
757   while (1)
758     {
759       chopstx_intr_wait (&interrupt);
760
761       if (interrupt.ready)
762         {
763           uint8_t ep_num;
764
765         event_handle:
766           e = usb_lld_event_handler (&dev);
767           ep_num = USB_EVENT_ENDP (e);
768
769           if (ep_num != 0)
770             {
771               if (USB_EVENT_TXRX (e))
772                 usb_tx_done (ep_num, USB_EVENT_LEN (e));
773               else
774                 usb_rx_ready (ep_num, USB_EVENT_LEN (e));
775             }
776           else
777             switch (USB_EVENT_ID (e))
778               {
779               case USB_EVENT_DEVICE_RESET:
780                 usb_device_reset (&dev);
781                 continue;
782
783               case USB_EVENT_DEVICE_ADDRESSED:
784                 chopstx_mutex_lock (&usb_mtx);
785                 bDeviceState = ADDRESSED;
786                 chopstx_cond_signal (&usb_cnd);
787                 chopstx_mutex_unlock (&usb_mtx);
788                 continue;
789
790               case USB_EVENT_GET_DESCRIPTOR:
791                 if (usb_get_descriptor (&dev) < 0)
792                   usb_lld_ctrl_error (&dev);
793                 continue;
794
795               case USB_EVENT_SET_CONFIGURATION:
796                 if (usb_set_configuration (&dev) < 0)
797                   usb_lld_ctrl_error (&dev);
798                 continue;
799
800               case USB_EVENT_SET_INTERFACE:
801                 if (usb_set_interface (&dev) < 0)
802                   usb_lld_ctrl_error (&dev);
803                 continue;
804
805               case USB_EVENT_CTRL_REQUEST:
806                 /* Device specific device request.  */
807                 if (usb_setup (&dev) < 0)
808                   usb_lld_ctrl_error (&dev);
809                 continue;
810
811               case USB_EVENT_GET_STATUS_INTERFACE:
812                 if (usb_get_status_interface (&dev) < 0)
813                   usb_lld_ctrl_error (&dev);
814                 continue;
815
816               case USB_EVENT_GET_INTERFACE:
817                 if (usb_get_interface (&dev) < 0)
818                   usb_lld_ctrl_error (&dev);
819                 continue;
820
821               case USB_EVENT_SET_FEATURE_DEVICE:
822               case USB_EVENT_SET_FEATURE_ENDPOINT:
823               case USB_EVENT_CLEAR_FEATURE_DEVICE:
824               case USB_EVENT_CLEAR_FEATURE_ENDPOINT:
825                 usb_lld_ctrl_ack (&dev);
826                 continue;
827
828               case USB_EVENT_CTRL_WRITE_FINISH:
829                 /* Control WRITE transfer finished.  */
830                 usb_ctrl_write_finish (&dev);
831                 continue;
832
833               case USB_EVENT_OK:
834               case USB_EVENT_DEVICE_SUSPEND:
835               default:
836                 continue;
837               }
838         }
839     }
840
841   return NULL;
842 }
843
844 #define ID_OFFSET (2+SERIALNO_STR_LEN*2)
845 static void fill_serial_no_by_unique_id (void)
846 {
847   extern const uint8_t * unique_device_id (void);
848   uint8_t *p = &neug_string_serial[ID_OFFSET];
849   const uint8_t *u = unique_device_id () + 8;
850   int i;
851
852   for (i = 0; i < 4; i++)
853     {
854       uint8_t b = u[3-i];
855       uint8_t nibble;
856
857       nibble = (b >> 4);
858       nibble += (nibble >= 10 ? ('A' - 10) : '0');
859       p[i*4] = nibble;
860       p[i*4+1] = 0;
861       nibble = (b & 0x0f);
862       nibble += (nibble >= 10 ? ('A' - 10) : '0');
863       p[i*4+2] = nibble;
864       p[i*4+3] = 0;
865     }
866 }
867
868
869 static void
870 usb_tx_done (uint8_t ep_num, uint16_t len)
871 {
872   if (ep_num == ENDP1)
873     {
874       chopstx_mutex_lock (&usb_mtx);
875       chopstx_cond_signal (&usb_cnd);
876       chopstx_mutex_unlock (&usb_mtx);
877     }
878   else if (ep_num == ENDP2)
879     {
880       /* INTERRUPT Transfer done */
881     }
882 #ifdef FRAUCHEKY_SUPPORT
883   else if (ep_num == ENDP6)
884     EP6_IN_Callback (len);
885 #else
886   (void)len;
887 #endif
888 }
889
890 static uint8_t endp3_buf[64];
891
892 static void
893 usb_rx_ready (uint8_t ep_num, uint16_t len)
894 {
895   if (ep_num == ENDP3)
896 #ifdef GNU_LINUX_EMULATION
897     usb_lld_rx_enable_buf (ENDP3, endp3_buf, 64);
898 #else
899     usb_lld_rx_enable (ENDP3);
900 #endif
901 #ifdef FRAUCHEKY_SUPPORT
902   else if (ep_num == ENDP6)
903     EP6_OUT_Callback (len);
904 #else
905   (void)len;
906 #endif
907 }
908 \f
909 typedef uint32_t eventmask_t;
910 #define ALL_EVENTS (~0)
911
912 struct event_flag {
913   chopstx_mutex_t mutex;
914   chopstx_cond_t cond;
915   eventmask_t flag;
916 };
917
918 static void event_flag_init (struct event_flag *ev)
919 {
920   ev->flag = 0;
921   chopstx_mutex_init (&ev->mutex);
922   chopstx_cond_init (&ev->cond);
923 }
924
925
926 static eventmask_t event_flag_waitone (struct event_flag *ev, eventmask_t m)
927 {
928   int n;
929
930   chopstx_mutex_lock (&ev->mutex);
931   while (!(ev->flag & m))
932     chopstx_cond_wait (&ev->cond, &ev->mutex);
933
934   n = __builtin_ffs ((ev->flag & m));
935   ev->flag &= ~(1 << (n - 1));
936   chopstx_mutex_unlock (&ev->mutex);
937
938   return (1 << (n - 1));
939 }
940
941 static void event_flag_signal (struct event_flag *ev, eventmask_t m)
942 {
943   chopstx_mutex_lock (&ev->mutex);
944   ev->flag |= m;
945   chopstx_cond_signal (&ev->cond);
946   chopstx_mutex_unlock (&ev->mutex);
947 }
948
949 #ifdef GNU_LINUX_EMULATION
950 extern char __process1_stack_base__[4096];
951 extern char __process3_stack_base__[4096];
952 #define STACK_SIZE_LED (sizeof __process1_stack_base__)
953 #define STACK_SIZE_USB (sizeof __process3_stack_base__)
954 #else
955 extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
956 extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
957 #define STACK_SIZE_LED ((uintptr_t)__process1_stack_size__)
958 #define STACK_SIZE_USB ((uintptr_t)__process3_stack_size__)
959 #endif
960
961 #define STACK_ADDR_LED ((uintptr_t)__process1_stack_base__)
962 #define STACK_ADDR_USB ((uintptr_t)__process3_stack_base__)
963
964
965 #define PRIO_LED 3
966 static struct event_flag led_event;
967
968 #define LED_ONESHOT_SHORT       ((eventmask_t)1)
969 #define LED_TWOSHOTS            ((eventmask_t)2)
970 #define LED_ONESHOT_LONG        ((eventmask_t)4)
971
972 /*
973  * LED blinker: When notified, let LED emit for 100ms.
974  */
975 static void *
976 led_blinker (void *arg)
977 {
978   (void)arg;
979
980   set_led (0);
981
982   while (1)
983     {
984       eventmask_t m;
985
986       m = event_flag_waitone (&led_event, ALL_EVENTS);
987
988       set_led (1);
989       if (m == LED_ONESHOT_SHORT)
990         chopstx_usec_wait (100*1000);
991       else if (m == LED_TWOSHOTS)
992         {
993           chopstx_usec_wait (50*1000);
994           set_led (0);
995           chopstx_usec_wait (50*1000);
996           set_led (1);
997           chopstx_usec_wait (50*1000);
998         }
999       else
1000         chopstx_usec_wait (250*1000);
1001       set_led (0);
1002     }
1003
1004   return NULL;
1005 }
1006 \f
1007 #define RANDOM_BYTES_LENGTH 64
1008 static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)];
1009
1010 #ifdef GNU_LINUX_EMULATION
1011 static uint8_t endp1_buf[RANDOM_BYTES_LENGTH];
1012 #endif
1013
1014 static void copy_to_tx (uint32_t v, int i)
1015 {
1016 #ifdef GNU_LINUX_EMULATION
1017   memcpy (&endp1_buf[i], &v, 4);
1018 #else
1019   usb_lld_txcpy (&v, ENDP1, i * 4, 4);
1020 #endif
1021 }
1022
1023 /*
1024  * In Gnuk 1.0.[12], reGNUal was not relocatable.
1025  * Now, it's relocatable, but we need to calculate its entry address
1026  * based on it's pre-defined address.
1027  */
1028 #define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
1029 static uint32_t
1030 calculate_regnual_entry_address (const uint8_t *addr)
1031 {
1032   const uint8_t *p = addr + 4;
1033   uintptr_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
1034
1035   v -= REGNUAL_START_ADDRESS_COMPATIBLE;
1036   v += (uintptr_t)addr;
1037   return v;
1038 }
1039
1040
1041 static int
1042 check_usb_status (void *arg)
1043 {
1044   (void)arg;
1045
1046   return (connected || bDeviceState != CONFIGURED
1047           || fsij_device_state != FSIJ_DEVICE_RUNNING);
1048 }
1049
1050
1051 #ifdef GNU_LINUX_EMULATION
1052 #define main emulated_main
1053 #endif
1054
1055 /*
1056  * Entry point.
1057  *
1058  * NOTE: the main function is already a thread in the system on entry.
1059  */
1060 int
1061 main (int argc, char **argv)
1062 {
1063   uintptr_t entry;
1064   chopstx_t led_thread, usb_thd;
1065   unsigned int count;
1066
1067   (void)argc;
1068   (void)argv;
1069
1070   fill_serial_no_by_unique_id ();
1071
1072   adc_init ();
1073
1074   event_flag_init (&led_event);
1075
1076   chopstx_mutex_init (&usb_mtx);
1077   chopstx_cond_init (&usb_cnd);
1078
1079 #ifdef FRAUCHEKY_SUPPORT
1080   if (fraucheky_enabled ())
1081     {
1082     go_fraucheky:
1083       bDeviceState = UNCONNECTED;
1084       running_neug = 0;
1085       usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1086                                 usb_main, NULL);
1087       while (bDeviceState != CONFIGURED)
1088         chopstx_usec_wait (250*1000);
1089       set_led (1);
1090       fraucheky_main ();
1091       chopstx_cancel (usb_thd);
1092       chopstx_join (usb_thd, NULL);
1093       usb_lld_shutdown ();
1094       bDeviceState = UNCONNECTED;
1095     }
1096
1097   running_neug = 1;
1098 #endif
1099
1100   led_thread = chopstx_create (PRIO_LED, STACK_ADDR_LED, STACK_SIZE_LED,
1101                                led_blinker, NULL);
1102
1103   usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1104                             usb_main, NULL);
1105
1106   neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
1107
1108   chopstx_mutex_lock (&usb_mtx);
1109
1110  not_configured:
1111   count = 0;
1112   /* Initial run-up */
1113   while (count < NEUG_PRE_LOOP || bDeviceState != CONFIGURED)
1114     {
1115       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1116         break;
1117
1118       chopstx_mutex_unlock (&usb_mtx);
1119       neug_wait_full ();
1120       neug_flush ();
1121
1122       if ((count & 0x0007) == 0)
1123         event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1124       chopstx_usec_wait (25*1000);
1125       count++;
1126       chopstx_mutex_lock (&usb_mtx);
1127     }
1128
1129   /* Holding USB_MTX...  */
1130   while (1)
1131     {
1132       int last_was_fullsizepacket = 0;
1133
1134       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1135         break;
1136
1137       chopstx_mutex_unlock (&usb_mtx);
1138       while (1)
1139         {
1140           uint32_t usec = 5000*1000;
1141           chopstx_poll_cond_t poll_desc;
1142           struct chx_poll_head *pd_array[1] = {
1143             (struct chx_poll_head *)&poll_desc
1144           };
1145
1146           poll_desc.type = CHOPSTX_POLL_COND;
1147           poll_desc.ready = 0;
1148           poll_desc.cond = &usb_cnd;
1149           poll_desc.mutex = &usb_mtx;
1150           poll_desc.check = check_usb_status;
1151           poll_desc.arg = NULL;
1152
1153           if (chopstx_poll (&usec, 1, pd_array))
1154             break;
1155
1156           /* Timeout */
1157           neug_flush ();
1158           neug_mode_select (line_coding.paritytype);
1159           event_flag_signal (&led_event, LED_TWOSHOTS);
1160         }
1161
1162       chopstx_mutex_lock (&usb_mtx);
1163       if (bDeviceState != CONFIGURED)
1164         goto not_configured;
1165
1166       /* The connection opened.  */
1167       count = 0;
1168
1169       while (1)
1170         {
1171           int i;
1172
1173           chopstx_mutex_unlock (&usb_mtx);
1174           /*
1175            * No parity is standard.  It means providing conditioned output.
1176            * When parity enabled, it means to provide raw output
1177            * (CRC32 filtered when odd, direct sample of ADC when even).
1178            *
1179            * line_coding.paritytype:
1180            *   0: None, 1: Odd, 2: Even
1181            */
1182           neug_mode_select (line_coding.paritytype);
1183
1184           if ((count & 0x03ff) == 0)
1185             event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1186
1187           i = neug_consume_random (copy_to_tx);
1188
1189           if (i == 0 && !last_was_fullsizepacket)
1190             {    /* Only send ZLP when the last packet was fullsize.  */
1191               neug_wait_full ();
1192
1193               chopstx_mutex_lock (&usb_mtx);
1194               if (bDeviceState != CONFIGURED || !connected
1195                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1196                 break;
1197             }
1198           else
1199             {
1200               if (i == 64/4)
1201                 last_was_fullsizepacket = 1;
1202               else
1203                 last_was_fullsizepacket = 0;
1204
1205               chopstx_mutex_lock (&usb_mtx);
1206               if (bDeviceState != CONFIGURED || !connected
1207                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1208                 break;
1209
1210               /* Prepare sending random data.  */
1211 #ifdef GNU_LINUX_EMULATION
1212               usb_lld_tx_enable_buf (ENDP1, endp1_buf, i * 4);
1213 #else
1214               usb_lld_tx_enable (ENDP1, i * 4);
1215 #endif
1216               chopstx_cond_wait (&usb_cnd, &usb_mtx);
1217               count++;
1218             }
1219         }
1220     }
1221
1222   chopstx_mutex_unlock (&usb_mtx);
1223
1224   chopstx_cancel (led_thread);
1225   chopstx_join (led_thread, NULL);
1226
1227   /*
1228    * We come here, because of FSIJ_DEVICE_NEUG_EXIT_REQUESTED
1229    * or FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED.
1230    */
1231   neug_fini ();
1232
1233   chopstx_mutex_lock (&usb_mtx);
1234 #ifdef FRAUCHEKY_SUPPORT
1235   if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
1236     {
1237       while (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
1238         {
1239           chopstx_mutex_unlock (&usb_mtx);
1240           set_led (1);
1241           chopstx_usec_wait (500*1000);
1242           set_led (0);
1243           chopstx_usec_wait (500*1000);
1244           chopstx_mutex_lock (&usb_mtx);
1245         }
1246
1247       usb_lld_prepare_shutdown ();
1248       chopstx_mutex_unlock (&usb_mtx);
1249       chopstx_cancel (usb_thd);
1250       chopstx_join (usb_thd, NULL);
1251       usb_lld_shutdown ();
1252       goto go_fraucheky;
1253     }
1254 #endif
1255
1256   fsij_device_state = FSIJ_DEVICE_EXITED;
1257
1258   while (fsij_device_state == FSIJ_DEVICE_EXITED)
1259     {
1260       chopstx_mutex_unlock (&usb_mtx);
1261       chopstx_usec_wait (500*1000);
1262       chopstx_mutex_lock (&usb_mtx);
1263     }
1264   chopstx_mutex_unlock (&usb_mtx);
1265
1266   flash_unlock ();              /* Flash unlock should be done here */
1267   set_led (1);
1268   usb_lld_shutdown ();
1269
1270   /* Finish application.  */
1271   chopstx_cancel (usb_thd);
1272   chopstx_join (usb_thd, NULL);
1273
1274 #ifndef GNU_LINUX_EMULATION
1275   /* Set vector */
1276   SCB->VTOR = (uintptr_t)&_regnual_start;
1277 #endif
1278   entry = calculate_regnual_entry_address (&_regnual_start);
1279 #ifdef DFU_SUPPORT
1280 #define FLASH_SYS_START_ADDR 0x08000000
1281 #define FLASH_SYS_END_ADDR (0x08000000+0x1000)
1282 #define CHIP_ID_REG ((uint32_t *)0xE0042000)
1283   {
1284     extern uint8_t _sys;
1285     uint32_t addr;
1286     handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
1287     void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
1288     uint32_t flash_page_size = 1024; /* 1KiB default */
1289
1290    if ((*CHIP_ID_ADDR)&0x07 == 0x04) /* High dencity device.  */
1291      flash_page_size += 0x0400; /* It's 2KiB. */
1292
1293     /* Kill DFU */
1294     for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
1295          addr += flash_page_size)
1296       flash_erase_page (addr);
1297
1298     /* copy system service routines */
1299     flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
1300
1301     /* Leave NeuG to exec reGNUal */
1302     (*func) ((void (*)(void))entry);
1303     for (;;);
1304   }
1305 #else
1306   /* Leave NeuG to exec reGNUal */
1307   flash_erase_all_and_exec ((void (*)(void))entry);
1308 #endif
1309
1310   /* Never reached */
1311   return 0;
1312 }