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