@@ -139,6 +139,59 @@ static int dummy1_sfd = -1;
139
139
static int dummy2_sfd = -1 ;
140
140
#endif
141
141
142
+ /*
143
+ * IOC State Transfer
144
+ *
145
+ * +-----------+ RESUME EVENT +-----------+
146
+ * | INIT +<---------------------------+ SUSPENDED |
147
+ * +-----+-----+ +-----------+
148
+ * | ^
149
+ * | |
150
+ * |HB ACTIVE |SHUTDOWN
151
+ * |EVENT |EVENT
152
+ * | |
153
+ * | |
154
+ * v RAM REFRESH EVENT/ |
155
+ * +-----+-----+ HB INACTIVE EVENT +-----+-----+
156
+ * | ACTIVE +--------------------------->+SUSPENDING |
157
+ * +-----------+ +-----------+
158
+ *
159
+ * INIT state: The state is IOC mediator initialized IOC state, all of CBC
160
+ * protocol packats are handler normally. In this state, UOS has
161
+ * not yet sent active heartbeat.
162
+ *
163
+ * ACTIVE state: Enter this state if HB ACTIVE event is triggered that indicates
164
+ * UOS state has been active and need to set the bit 23(SoC active
165
+ * bit) in the wakeup reason.
166
+ *
167
+ * SUSPENDING state: Enter this state if RAM REFRESH event or HB INACTIVE event
168
+ * is triggered, the related event handler needs to set the
169
+ * suspend or shutdown to PM DM and begin to drop the queued
170
+ * CBC protocol packets.
171
+ *
172
+ * SUSPENDED state: Enter this state if SHUTDOWN event is triggered to close all
173
+ * native CBC char devices. The IOC mediator will be enter to
174
+ * sleeping until RESUME event is triggered that re-opens
175
+ * closed native CBC char devices and transfer to INIT state.
176
+ */
177
+ static int process_hb_active_event (struct ioc_dev * ioc );
178
+ static int process_ram_refresh_event (struct ioc_dev * ioc );
179
+ static int process_hb_inactive_event (struct ioc_dev * ioc );
180
+ static int process_shutdown_event (struct ioc_dev * ioc );
181
+ static int process_resume_event (struct ioc_dev * ioc );
182
+ static struct ioc_state_info ioc_state_tbl [] = {
183
+ {IOC_S_INIT , IOC_S_ACTIVE , IOC_E_HB_ACTIVE ,
184
+ process_hb_active_event },
185
+ {IOC_S_ACTIVE , IOC_S_SUSPENDING , IOC_E_RAM_REFRESH ,
186
+ process_ram_refresh_event },
187
+ {IOC_S_ACTIVE , IOC_S_SUSPENDING , IOC_E_HB_INACTIVE ,
188
+ process_hb_inactive_event },
189
+ {IOC_S_SUSPENDING , IOC_S_SUSPENDED , IOC_E_SHUTDOWN ,
190
+ process_shutdown_event },
191
+ {IOC_S_SUSPENDED , IOC_S_INIT , IOC_E_RESUME ,
192
+ process_resume_event },
193
+ };
194
+
142
195
/*
143
196
* IOC channels definition.
144
197
*/
@@ -163,6 +216,7 @@ static struct ioc_ch_info ioc_ch_tbl[] = {
163
216
{IOC_INIT_FD , IOC_NP_RAW10 , IOC_NATIVE_RAW10 , IOC_CH_ON },
164
217
{IOC_INIT_FD , IOC_NP_RAW11 , IOC_NATIVE_RAW11 , IOC_CH_ON },
165
218
{IOC_INIT_FD , IOC_DP_NONE , IOC_VIRTUAL_UART , IOC_CH_ON },
219
+ {IOC_INIT_FD , IOC_DP_NONE , IOC_LOCAL_EVENT , IOC_CH_ON }
166
220
#ifdef IOC_DUMMY
167
221
{IOC_INIT_FD , IOC_NP_FLF , IOC_NATIVE_DUMMY0 , IOC_CH_ON },
168
222
{IOC_INIT_FD , IOC_NP_FSIG , IOC_NATIVE_DUMMY1 , IOC_CH_ON },
@@ -564,6 +618,7 @@ ioc_ch_init(struct ioc_dev *ioc)
564
618
{
565
619
int i , fd ;
566
620
struct ioc_ch_info * chl ;
621
+ int pipe_fds [2 ];
567
622
568
623
for (i = 0 , chl = ioc_ch_tbl ; i < ARRAY_SIZE (ioc_ch_tbl ); i ++ , chl ++ ) {
569
624
if (chl -> stat == IOC_CH_OFF )
@@ -578,6 +633,15 @@ ioc_ch_init(struct ioc_dev *ioc)
578
633
case IOC_VIRTUAL_UART :
579
634
fd = ioc_open_virtual_uart (virtual_uart_path );
580
635
break ;
636
+ case IOC_LOCAL_EVENT :
637
+ if (!pipe (pipe_fds )) {
638
+ fd = pipe_fds [0 ];
639
+ ioc -> evt_fd = pipe_fds [1 ];
640
+ } else {
641
+ fd = IOC_INIT_FD ;
642
+ DPRINTF ("%s" , "ioc open event fd failed\r\n" );
643
+ }
644
+ break ;
581
645
#ifdef IOC_DUMMY
582
646
/*
583
647
* TODO: check open if success for dummy fd
@@ -606,7 +670,8 @@ ioc_ch_init(struct ioc_dev *ioc)
606
670
* if can not open lifecycle or virtual UART
607
671
* ioc needs to exit initilization with failure
608
672
*/
609
- if (fd < 0 && (i == IOC_NATIVE_LFCC || i == IOC_VIRTUAL_UART ))
673
+ if (fd < 0 && (i == IOC_NATIVE_LFCC || i == IOC_VIRTUAL_UART ||
674
+ i == IOC_LOCAL_EVENT ))
610
675
return -1 ;
611
676
612
677
chl -> fd = fd ;
@@ -702,6 +767,85 @@ cbc_request_dequeue(struct ioc_dev *ioc, enum cbc_queue_type qtype)
702
767
return free ;
703
768
}
704
769
770
+ /*
771
+ * Process hb active event before transfer to next state
772
+ */
773
+ static int
774
+ process_hb_active_event (struct ioc_dev * ioc )
775
+ {
776
+ /* TODO: Need implementation */
777
+ return 0 ;
778
+ }
779
+
780
+ /*
781
+ * Process ram refresh event before transfer to next state
782
+ */
783
+ static int
784
+ process_ram_refresh_event (struct ioc_dev * ioc )
785
+ {
786
+ /* TODO: Need implementation */
787
+ return 0 ;
788
+ }
789
+
790
+ /*
791
+ * Process hb inactive event before transfer to next state
792
+ */
793
+ static int
794
+ process_hb_inactive_event (struct ioc_dev * ioc )
795
+ {
796
+ /* TODO: Need implementation */
797
+ return 0 ;
798
+ }
799
+
800
+ /*
801
+ * Process shutdown reason event before transfer to next state
802
+ */
803
+ static int
804
+ process_shutdown_event (struct ioc_dev * ioc )
805
+ {
806
+ /* TODO: Need implementation */
807
+ return 0 ;
808
+ }
809
+
810
+ /*
811
+ * Process resume event before transfer to next state
812
+ */
813
+ static int
814
+ process_resume_event (struct ioc_dev * ioc )
815
+ {
816
+ /* TODO: Need implementation */
817
+ return 0 ;
818
+ }
819
+
820
+ /*
821
+ * Process IOC local events
822
+ */
823
+ static void
824
+ ioc_process_events (struct ioc_dev * ioc , enum ioc_ch_id id )
825
+ {
826
+ int i ;
827
+ uint8_t evt ;
828
+
829
+ /* Get one event */
830
+ if (ioc_ch_recv (id , & evt , sizeof (evt )) < 0 ) {
831
+ DPRINTF ("%s" , "ioc state gets event failed\r\n" );
832
+ return ;
833
+ }
834
+
835
+ for (i = 0 ; i < ARRAY_SIZE (ioc_state_tbl ); i ++ ) {
836
+ if (evt == ioc_state_tbl [i ].evt &&
837
+ ioc -> state == ioc_state_tbl [i ].cur_stat ) {
838
+ if (ioc_state_tbl [i ].handler &&
839
+ ioc_state_tbl [i ].handler (ioc ) == 0 )
840
+ ioc -> state = ioc_state_tbl [i ].next_stat ;
841
+ else
842
+ DPRINTF ("ioc state switching failed,%d->%d\r\n" ,
843
+ ioc_state_tbl [i ].cur_stat ,
844
+ ioc_state_tbl [i ].next_stat );
845
+ }
846
+ }
847
+ }
848
+
705
849
/*
706
850
* Build a cbc_request with CBC link frame and add the cbc_request to
707
851
* the rx queue tail.
@@ -816,6 +960,9 @@ ioc_dispatch(struct ioc_dev *ioc, struct ioc_ch_info *chl)
816
960
case IOC_VIRTUAL_UART :
817
961
ioc_process_rx (ioc , chl -> id );
818
962
break ;
963
+ case IOC_LOCAL_EVENT :
964
+ ioc_process_events (ioc , chl -> id );
965
+ break ;
819
966
default :
820
967
DPRINTF ("ioc dispatch got wrong channel:%d\r\n" , chl -> id );
821
968
break ;
@@ -881,6 +1028,7 @@ ioc_rx_thread(void *arg)
881
1028
memset (& packet , 0 , sizeof (packet ));
882
1029
packet .cfg = & ioc -> rx_config ;
883
1030
packet .boot_reason = ioc_boot_reason ;
1031
+
884
1032
for (;;) {
885
1033
pthread_mutex_lock (& ioc -> rx_mtx );
886
1034
while (SIMPLEQ_EMPTY (& ioc -> rx_qhead )) {
@@ -933,6 +1081,7 @@ ioc_tx_thread(void *arg)
933
1081
memset (& packet , 0 , sizeof (packet ));
934
1082
packet .cfg = & ioc -> tx_config ;
935
1083
packet .boot_reason = ioc_boot_reason ;
1084
+
936
1085
for (;;) {
937
1086
pthread_mutex_lock (& ioc -> tx_mtx );
938
1087
while (SIMPLEQ_EMPTY (& ioc -> tx_qhead )) {
@@ -1095,12 +1244,19 @@ ioc_init(struct vmctx *ctx)
1095
1244
for (i = 0 ; i < IOC_MAX_REQUESTS ; i ++ )
1096
1245
SIMPLEQ_INSERT_TAIL (& ioc -> free_qhead , ioc -> pool + i , me_queue );
1097
1246
1247
+ /* Initialize IOC state */
1248
+ ioc -> state = IOC_S_INIT ;
1249
+
1250
+ /* Set event fd to default value */
1251
+ ioc -> evt_fd = IOC_INIT_FD ;
1252
+
1098
1253
/*
1099
1254
* Initialize native CBC cdev and virtual UART.
1100
1255
*/
1101
1256
if (ioc_ch_init (ioc ) != 0 )
1102
1257
goto chl_err ;
1103
1258
1259
+
1104
1260
/* Initlialize CBC rx/tx signal and group whitelists */
1105
1261
wlist_init_signal (cbc_rx_signal_table , ARRAY_SIZE (cbc_rx_signal_table ),
1106
1262
wlist_rx_signal_table ,
@@ -1175,6 +1331,8 @@ ioc_init(struct vmctx *ctx)
1175
1331
chl_err :
1176
1332
ioc_ch_deinit ();
1177
1333
pthread_mutex_destroy (& ioc -> free_mtx );
1334
+ if (ioc -> evt_fd >= 0 )
1335
+ close (ioc -> evt_fd );
1178
1336
close (ioc -> epfd );
1179
1337
alloc_err :
1180
1338
free (ioc -> evts );
@@ -1200,6 +1358,8 @@ ioc_deinit(struct vmctx *ctx)
1200
1358
}
1201
1359
ioc_kill_workers (ioc );
1202
1360
ioc_ch_deinit ();
1361
+ if (ioc -> evt_fd >= 0 )
1362
+ close (ioc -> evt_fd );
1203
1363
close (ioc -> epfd );
1204
1364
free (ioc -> evts );
1205
1365
free (ioc -> pool );
0 commit comments