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