1 /* Copyright (C) 2011 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 ** GNU General Public License for more details.
11 */
12 #include "android/utils/panic.h"
13 #include "android/utils/system.h"
14 #include "hw/goldfish_pipe.h"
15 #include "hw/goldfish_device.h"
16 #include "qemu-timer.h"
17 #ifdef CONFIG_KVM
18 #include "kvm.h"
19 #endif
20
21 #define DEBUG 0
22
23 /* Set to 1 to debug i/o register reads/writes */
24 #define DEBUG_REGS 0
25
26 #if DEBUG >= 1
27 # define D(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
28 #else
29 # define D(...) (void)0
30 #endif
31
32 #if DEBUG >= 2
33 # define DD(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
34 #else
35 # define DD(...) (void)0
36 #endif
37
38 #if DEBUG_REGS >= 1
39 # define DR(...) D(__VA_ARGS__)
40 #else
41 # define DR(...) (void)0
42 #endif
43
44 #define E(...) fprintf(stderr, "ERROR:" __VA_ARGS__), fprintf(stderr, "\n")
45
46 /* Set to 1 to enable the 'zero' pipe type, useful for debugging */
47 #define DEBUG_ZERO_PIPE 1
48
49 /* Set to 1 to enable the 'pingpong' pipe type, useful for debugging */
50 #define DEBUG_PINGPONG_PIPE 1
51
52 /* Set to 1 to enable the 'throttle' pipe type, useful for debugging */
53 #define DEBUG_THROTTLE_PIPE 1
54
55 /* Maximum length of pipe service name, in characters (excluding final 0) */
56 #define MAX_PIPE_SERVICE_NAME_SIZE 255
57
58 #define GOLDFISH_PIPE_SAVE_VERSION 1
59
60 /***********************************************************************
61 ***********************************************************************
62 *****
63 ***** P I P E S E R V I C E R E G I S T R A T I O N
64 *****
65 *****/
66
67 #define MAX_PIPE_SERVICES 8
68 typedef struct {
69 const char* name;
70 void* opaque;
71 GoldfishPipeFuncs funcs;
72 } PipeService;
73
74 typedef struct {
75 int count;
76 PipeService services[MAX_PIPE_SERVICES];
77 } PipeServices;
78
79 static PipeServices _pipeServices[1];
80
81 void
goldfish_pipe_add_type(const char * pipeName,void * pipeOpaque,const GoldfishPipeFuncs * pipeFuncs)82 goldfish_pipe_add_type(const char* pipeName,
83 void* pipeOpaque,
84 const GoldfishPipeFuncs* pipeFuncs )
85 {
86 PipeServices* list = _pipeServices;
87 int count = list->count;
88
89 if (count >= MAX_PIPE_SERVICES) {
90 APANIC("Too many goldfish pipe services (%d)", count);
91 }
92
93 if (strlen(pipeName) > MAX_PIPE_SERVICE_NAME_SIZE) {
94 APANIC("Pipe service name too long: '%s'", pipeName);
95 }
96
97 list->services[count].name = pipeName;
98 list->services[count].opaque = pipeOpaque;
99 list->services[count].funcs = pipeFuncs[0];
100
101 list->count++;
102 }
103
104 static const PipeService*
goldfish_pipe_find_type(const char * pipeName)105 goldfish_pipe_find_type(const char* pipeName)
106 {
107 PipeServices* list = _pipeServices;
108 int count = list->count;
109 int nn;
110
111 for (nn = 0; nn < count; nn++) {
112 if (!strcmp(list->services[nn].name, pipeName)) {
113 return &list->services[nn];
114 }
115 }
116 return NULL;
117 }
118
119
120 /***********************************************************************
121 ***********************************************************************
122 *****
123 ***** P I P E C O N N E C T I O N S
124 *****
125 *****/
126
127 typedef struct PipeDevice PipeDevice;
128
129 typedef struct Pipe {
130 struct Pipe* next;
131 struct Pipe* next_waked;
132 PipeDevice* device;
133 uint32_t channel;
134 void* opaque;
135 const GoldfishPipeFuncs* funcs;
136 const PipeService* service;
137 char* args;
138 unsigned char wanted;
139 char closed;
140 } Pipe;
141
142 /* Forward */
143 static void* pipeConnector_new(Pipe* pipe);
144
145 static Pipe*
pipe_new0(PipeDevice * dev)146 pipe_new0(PipeDevice* dev)
147 {
148 Pipe* pipe;
149 ANEW0(pipe);
150 pipe->device = dev;
151 return pipe;
152 }
153
154 static Pipe*
pipe_new(uint32_t channel,PipeDevice * dev)155 pipe_new(uint32_t channel, PipeDevice* dev)
156 {
157 Pipe* pipe = pipe_new0(dev);
158 pipe->channel = channel;
159 pipe->opaque = pipeConnector_new(pipe);
160 return pipe;
161 }
162
163 static Pipe**
pipe_list_findp_channel(Pipe ** list,uint32_t channel)164 pipe_list_findp_channel( Pipe** list, uint32_t channel )
165 {
166 Pipe** pnode = list;
167 for (;;) {
168 Pipe* node = *pnode;
169 if (node == NULL || node->channel == channel) {
170 break;
171 }
172 pnode = &node->next;
173 }
174 return pnode;
175 }
176
177 #if 0
178 static Pipe**
179 pipe_list_findp_opaque( Pipe** list, void* opaque )
180 {
181 Pipe** pnode = list;
182 for (;;) {
183 Pipe* node = *pnode;
184 if (node == NULL || node->opaque == opaque) {
185 break;
186 }
187 pnode = &node->next;
188 }
189 return pnode;
190 }
191 #endif
192
193 static Pipe**
pipe_list_findp_waked(Pipe ** list,Pipe * pipe)194 pipe_list_findp_waked( Pipe** list, Pipe* pipe )
195 {
196 Pipe** pnode = list;
197 for (;;) {
198 Pipe* node = *pnode;
199 if (node == NULL || node == pipe) {
200 break;
201 }
202 pnode = &node->next_waked;
203 }
204 return pnode;
205 }
206
207
208 static void
pipe_list_remove_waked(Pipe ** list,Pipe * pipe)209 pipe_list_remove_waked( Pipe** list, Pipe* pipe )
210 {
211 Pipe** lookup = pipe_list_findp_waked(list, pipe);
212 Pipe* node = *lookup;
213
214 if (node != NULL) {
215 (*lookup) = node->next_waked;
216 node->next_waked = NULL;
217 }
218 }
219
220 static void
pipe_save(Pipe * pipe,QEMUFile * file)221 pipe_save( Pipe* pipe, QEMUFile* file )
222 {
223 if (pipe->service == NULL) {
224 /* pipe->service == NULL means we're still using a PipeConnector */
225 /* Write a zero to indicate this condition */
226 qemu_put_byte(file, 0);
227 } else {
228 /* Otherwise, write a '1' then the service name */
229 qemu_put_byte(file, 1);
230 qemu_put_string(file, pipe->service->name);
231 }
232
233 /* Now save other common data */
234 qemu_put_be32(file, (unsigned int)pipe->channel);
235 qemu_put_byte(file, (int)pipe->wanted);
236 qemu_put_byte(file, (int)pipe->closed);
237
238 /* Write 1 + args, if any, or simply 0 otherwise */
239 if (pipe->args != NULL) {
240 qemu_put_byte(file, 1);
241 qemu_put_string(file, pipe->args);
242 } else {
243 qemu_put_byte(file, 0);
244 }
245
246 if (pipe->funcs->save) {
247 pipe->funcs->save(pipe->opaque, file);
248 }
249 }
250
251 static Pipe*
pipe_load(PipeDevice * dev,QEMUFile * file)252 pipe_load( PipeDevice* dev, QEMUFile* file )
253 {
254 Pipe* pipe;
255 const PipeService* service = NULL;
256 int state = qemu_get_byte(file);
257 uint32_t channel;
258
259 if (state != 0) {
260 /* Pipe is associated with a service. */
261 char* name = qemu_get_string(file);
262 if (name == NULL)
263 return NULL;
264
265 service = goldfish_pipe_find_type(name);
266 if (service == NULL) {
267 D("No QEMU pipe service named '%s'", name);
268 AFREE(name);
269 return NULL;
270 }
271 }
272
273 channel = qemu_get_be32(file);
274 pipe = pipe_new(channel, dev);
275 pipe->wanted = qemu_get_byte(file);
276 pipe->closed = qemu_get_byte(file);
277 if (qemu_get_byte(file) != 0) {
278 pipe->args = qemu_get_string(file);
279 }
280
281 pipe->service = service;
282 if (service != NULL) {
283 pipe->funcs = &service->funcs;
284 }
285
286 if (pipe->funcs->load) {
287 pipe->opaque = pipe->funcs->load(pipe, service ? service->opaque : NULL, pipe->args, file);
288 if (pipe->opaque == NULL) {
289 AFREE(pipe);
290 return NULL;
291 }
292 } else {
293 /* Force-close the pipe on load */
294 pipe->closed = 1;
295 }
296 return pipe;
297 }
298
299 static void
pipe_free(Pipe * pipe)300 pipe_free( Pipe* pipe )
301 {
302 /* Call close callback */
303 if (pipe->funcs->close) {
304 pipe->funcs->close(pipe->opaque);
305 }
306 /* Free stuff */
307 AFREE(pipe->args);
308 AFREE(pipe);
309 }
310
311 /***********************************************************************
312 ***********************************************************************
313 *****
314 ***** P I P E C O N N E C T O R S
315 *****
316 *****/
317
318 /* These are used to handle the initial connection attempt, where the
319 * client is going to write the name of the pipe service it wants to
320 * connect to, followed by a terminating zero.
321 */
322 typedef struct {
323 Pipe* pipe;
324 char buffer[128];
325 int buffpos;
326 } PipeConnector;
327
328 static const GoldfishPipeFuncs pipeConnector_funcs; // forward
329
330 void*
pipeConnector_new(Pipe * pipe)331 pipeConnector_new(Pipe* pipe)
332 {
333 PipeConnector* pcon;
334
335 ANEW0(pcon);
336 pcon->pipe = pipe;
337 pipe->funcs = &pipeConnector_funcs;
338 return pcon;
339 }
340
341 static void
pipeConnector_close(void * opaque)342 pipeConnector_close( void* opaque )
343 {
344 PipeConnector* pcon = opaque;
345 AFREE(pcon);
346 }
347
348 static int
pipeConnector_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)349 pipeConnector_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
350 {
351 PipeConnector* pcon = opaque;
352 const GoldfishPipeBuffer* buffers_limit = buffers + numBuffers;
353 int ret = 0;
354
355 DD("%s: channel=0x%x numBuffers=%d", __FUNCTION__,
356 pcon->pipe->channel,
357 numBuffers);
358
359 while (buffers < buffers_limit) {
360 int avail;
361
362 DD("%s: buffer data (%3d bytes): '%.*s'", __FUNCTION__,
363 buffers[0].size, buffers[0].size, buffers[0].data);
364
365 if (buffers[0].size == 0) {
366 buffers++;
367 continue;
368 }
369
370 avail = sizeof(pcon->buffer) - pcon->buffpos;
371 if (avail > buffers[0].size)
372 avail = buffers[0].size;
373
374 if (avail > 0) {
375 memcpy(pcon->buffer + pcon->buffpos, buffers[0].data, avail);
376 pcon->buffpos += avail;
377 ret += avail;
378 }
379 buffers++;
380 }
381
382 /* Now check that our buffer contains a zero-terminated string */
383 if (memchr(pcon->buffer, '\0', pcon->buffpos) != NULL) {
384 /* Acceptable formats for the connection string are:
385 *
386 * pipe:<name>
387 * pipe:<name>:<arguments>
388 */
389 char* pipeName;
390 char* pipeArgs;
391
392 D("%s: connector: '%s'", __FUNCTION__, pcon->buffer);
393
394 if (memcmp(pcon->buffer, "pipe:", 5) != 0) {
395 /* Nope, we don't handle these for now. */
396 D("%s: Unknown pipe connection: '%s'", __FUNCTION__, pcon->buffer);
397 return PIPE_ERROR_INVAL;
398 }
399
400 pipeName = pcon->buffer + 5;
401 pipeArgs = strchr(pipeName, ':');
402
403 if (pipeArgs != NULL) {
404 *pipeArgs++ = '\0';
405 if (!*pipeArgs)
406 pipeArgs = NULL;
407 }
408
409 Pipe* pipe = pcon->pipe;
410 const PipeService* svc = goldfish_pipe_find_type(pipeName);
411 if (svc == NULL) {
412 D("%s: Unknown server!", __FUNCTION__);
413 return PIPE_ERROR_INVAL;
414 }
415
416 void* peer = svc->funcs.init(pipe, svc->opaque, pipeArgs);
417 if (peer == NULL) {
418 D("%s: Initialization failed!", __FUNCTION__);
419 return PIPE_ERROR_INVAL;
420 }
421
422 /* Do the evil switch now */
423 pipe->opaque = peer;
424 pipe->service = svc;
425 pipe->funcs = &svc->funcs;
426 pipe->args = ASTRDUP(pipeArgs);
427 AFREE(pcon);
428 }
429
430 return ret;
431 }
432
433 static int
pipeConnector_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)434 pipeConnector_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
435 {
436 return PIPE_ERROR_IO;
437 }
438
439 static unsigned
pipeConnector_poll(void * opaque)440 pipeConnector_poll( void* opaque )
441 {
442 return PIPE_POLL_OUT;
443 }
444
445 static void
pipeConnector_wakeOn(void * opaque,int flags)446 pipeConnector_wakeOn( void* opaque, int flags )
447 {
448 /* nothing, really should never happen */
449 }
450
451 static void
pipeConnector_save(void * pipe,QEMUFile * file)452 pipeConnector_save( void* pipe, QEMUFile* file )
453 {
454 PipeConnector* pcon = pipe;
455 qemu_put_sbe32(file, pcon->buffpos);
456 qemu_put_sbuffer(file, (const int8_t*)pcon->buffer, pcon->buffpos);
457 }
458
459 static void*
pipeConnector_load(void * hwpipe,void * pipeOpaque,const char * args,QEMUFile * file)460 pipeConnector_load( void* hwpipe, void* pipeOpaque, const char* args, QEMUFile* file )
461 {
462 PipeConnector* pcon;
463
464 int len = qemu_get_sbe32(file);
465 if (len < 0 || len > sizeof(pcon->buffer)) {
466 return NULL;
467 }
468 pcon = pipeConnector_new(hwpipe);
469 pcon->buffpos = len;
470 if (qemu_get_buffer(file, (uint8_t*)pcon->buffer, pcon->buffpos) != pcon->buffpos) {
471 AFREE(pcon);
472 return NULL;
473 }
474 return pcon;
475 }
476
477 static const GoldfishPipeFuncs pipeConnector_funcs = {
478 NULL, /* init */
479 pipeConnector_close, /* should rarely happen */
480 pipeConnector_sendBuffers, /* the interesting stuff */
481 pipeConnector_recvBuffers, /* should not happen */
482 pipeConnector_poll, /* should not happen */
483 pipeConnector_wakeOn, /* should not happen */
484 pipeConnector_save,
485 pipeConnector_load,
486 };
487
488 /***********************************************************************
489 ***********************************************************************
490 *****
491 ***** Z E R O P I P E S
492 *****
493 *****/
494
495 /* A simple pipe service that mimics /dev/zero, you can write anything to
496 * it, and you can always read any number of zeros from it. Useful for debugging
497 * the kernel driver.
498 */
499 #if DEBUG_ZERO_PIPE
500
501 typedef struct {
502 void* hwpipe;
503 } ZeroPipe;
504
505 static void*
zeroPipe_init(void * hwpipe,void * svcOpaque,const char * args)506 zeroPipe_init( void* hwpipe, void* svcOpaque, const char* args )
507 {
508 ZeroPipe* zpipe;
509
510 D("%s: hwpipe=%p", __FUNCTION__, hwpipe);
511 ANEW0(zpipe);
512 zpipe->hwpipe = hwpipe;
513 return zpipe;
514 }
515
516 static void
zeroPipe_close(void * opaque)517 zeroPipe_close( void* opaque )
518 {
519 ZeroPipe* zpipe = opaque;
520
521 D("%s: hwpipe=%p", __FUNCTION__, zpipe->hwpipe);
522 AFREE(zpipe);
523 }
524
525 static int
zeroPipe_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)526 zeroPipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
527 {
528 int ret = 0;
529 while (numBuffers > 0) {
530 ret += buffers[0].size;
531 buffers++;
532 numBuffers--;
533 }
534 return ret;
535 }
536
537 static int
zeroPipe_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)538 zeroPipe_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
539 {
540 int ret = 0;
541 while (numBuffers > 0) {
542 ret += buffers[0].size;
543 memset(buffers[0].data, 0, buffers[0].size);
544 buffers++;
545 numBuffers--;
546 }
547 return ret;
548 }
549
550 static unsigned
zeroPipe_poll(void * opaque)551 zeroPipe_poll( void* opaque )
552 {
553 return PIPE_POLL_IN | PIPE_POLL_OUT;
554 }
555
556 static void
zeroPipe_wakeOn(void * opaque,int flags)557 zeroPipe_wakeOn( void* opaque, int flags )
558 {
559 /* nothing to do here */
560 }
561
562 static const GoldfishPipeFuncs zeroPipe_funcs = {
563 zeroPipe_init,
564 zeroPipe_close,
565 zeroPipe_sendBuffers,
566 zeroPipe_recvBuffers,
567 zeroPipe_poll,
568 zeroPipe_wakeOn,
569 };
570
571 #endif /* DEBUG_ZERO */
572
573 /***********************************************************************
574 ***********************************************************************
575 *****
576 ***** P I N G P O N G P I P E S
577 *****
578 *****/
579
580 /* Similar debug service that sends back anything it receives */
581 /* All data is kept in a circular dynamic buffer */
582
583 #if DEBUG_PINGPONG_PIPE
584
585 /* Initial buffer size */
586 #define PINGPONG_SIZE 1024
587
588 typedef struct {
589 void* hwpipe;
590 uint8_t* buffer;
591 size_t size;
592 size_t pos;
593 size_t count;
594 unsigned flags;
595 } PingPongPipe;
596
597 static void
pingPongPipe_init0(PingPongPipe * pipe,void * hwpipe,void * svcOpaque)598 pingPongPipe_init0( PingPongPipe* pipe, void* hwpipe, void* svcOpaque )
599 {
600 pipe->hwpipe = hwpipe;
601 pipe->size = PINGPONG_SIZE;
602 pipe->buffer = malloc(pipe->size);
603 pipe->pos = 0;
604 pipe->count = 0;
605 }
606
607 static void*
pingPongPipe_init(void * hwpipe,void * svcOpaque,const char * args)608 pingPongPipe_init( void* hwpipe, void* svcOpaque, const char* args )
609 {
610 PingPongPipe* ppipe;
611
612 D("%s: hwpipe=%p", __FUNCTION__, hwpipe);
613 ANEW0(ppipe);
614 pingPongPipe_init0(ppipe, hwpipe, svcOpaque);
615 return ppipe;
616 }
617
618 static void
pingPongPipe_close(void * opaque)619 pingPongPipe_close( void* opaque )
620 {
621 PingPongPipe* ppipe = opaque;
622
623 D("%s: hwpipe=%p (pos=%d count=%d size=%d)", __FUNCTION__,
624 ppipe->hwpipe, ppipe->pos, ppipe->count, ppipe->size);
625 free(ppipe->buffer);
626 AFREE(ppipe);
627 }
628
629 static int
pingPongPipe_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)630 pingPongPipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
631 {
632 PingPongPipe* pipe = opaque;
633 int ret = 0;
634 int count;
635 const GoldfishPipeBuffer* buff = buffers;
636 const GoldfishPipeBuffer* buffEnd = buff + numBuffers;
637
638 count = 0;
639 for ( ; buff < buffEnd; buff++ )
640 count += buff->size;
641
642 /* Do we need to grow the pingpong buffer? */
643 while (count > pipe->size - pipe->count) {
644 size_t newsize = pipe->size*2;
645 uint8_t* newbuff = realloc(pipe->buffer, newsize);
646 int wpos = pipe->pos + pipe->count;
647 if (newbuff == NULL) {
648 break;
649 }
650 if (wpos > pipe->size) {
651 wpos -= pipe->size;
652 memcpy(newbuff + pipe->size, newbuff, wpos);
653 }
654 pipe->buffer = newbuff;
655 pipe->size = newsize;
656 D("pingpong buffer is now %d bytes", newsize);
657 }
658
659 for ( buff = buffers; buff < buffEnd; buff++ ) {
660 int avail = pipe->size - pipe->count;
661 if (avail <= 0) {
662 if (ret == 0)
663 ret = PIPE_ERROR_AGAIN;
664 break;
665 }
666 if (avail > buff->size) {
667 avail = buff->size;
668 }
669
670 int wpos = pipe->pos + pipe->count;
671 if (wpos >= pipe->size) {
672 wpos -= pipe->size;
673 }
674 if (wpos + avail <= pipe->size) {
675 memcpy(pipe->buffer + wpos, buff->data, avail);
676 } else {
677 int avail2 = pipe->size - wpos;
678 memcpy(pipe->buffer + wpos, buff->data, avail2);
679 memcpy(pipe->buffer, buff->data + avail2, avail - avail2);
680 }
681 pipe->count += avail;
682 ret += avail;
683 }
684
685 /* Wake up any waiting readers if we wrote something */
686 if (pipe->count > 0 && (pipe->flags & PIPE_WAKE_READ)) {
687 goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_READ);
688 }
689
690 return ret;
691 }
692
693 static int
pingPongPipe_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)694 pingPongPipe_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
695 {
696 PingPongPipe* pipe = opaque;
697 int ret = 0;
698
699 while (numBuffers > 0) {
700 int avail = pipe->count;
701 if (avail <= 0) {
702 if (ret == 0)
703 ret = PIPE_ERROR_AGAIN;
704 break;
705 }
706 if (avail > buffers[0].size) {
707 avail = buffers[0].size;
708 }
709
710 int rpos = pipe->pos;
711
712 if (rpos + avail <= pipe->size) {
713 memcpy(buffers[0].data, pipe->buffer + rpos, avail);
714 } else {
715 int avail2 = pipe->size - rpos;
716 memcpy(buffers[0].data, pipe->buffer + rpos, avail2);
717 memcpy(buffers[0].data + avail2, pipe->buffer, avail - avail2);
718 }
719 pipe->count -= avail;
720 pipe->pos += avail;
721 if (pipe->pos >= pipe->size) {
722 pipe->pos -= pipe->size;
723 }
724 ret += avail;
725 numBuffers--;
726 buffers++;
727 }
728
729 /* Wake up any waiting readers if we wrote something */
730 if (pipe->count < PINGPONG_SIZE && (pipe->flags & PIPE_WAKE_WRITE)) {
731 goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_WRITE);
732 }
733
734 return ret;
735 }
736
737 static unsigned
pingPongPipe_poll(void * opaque)738 pingPongPipe_poll( void* opaque )
739 {
740 PingPongPipe* pipe = opaque;
741 unsigned ret = 0;
742
743 if (pipe->count < pipe->size)
744 ret |= PIPE_POLL_OUT;
745
746 if (pipe->count > 0)
747 ret |= PIPE_POLL_IN;
748
749 return ret;
750 }
751
752 static void
pingPongPipe_wakeOn(void * opaque,int flags)753 pingPongPipe_wakeOn( void* opaque, int flags )
754 {
755 PingPongPipe* pipe = opaque;
756 pipe->flags |= (unsigned)flags;
757 }
758
759 static const GoldfishPipeFuncs pingPongPipe_funcs = {
760 pingPongPipe_init,
761 pingPongPipe_close,
762 pingPongPipe_sendBuffers,
763 pingPongPipe_recvBuffers,
764 pingPongPipe_poll,
765 pingPongPipe_wakeOn,
766 };
767
768 #endif /* DEBUG_PINGPONG_PIPE */
769
770 /***********************************************************************
771 ***********************************************************************
772 *****
773 ***** T H R O T T L E P I P E S
774 *****
775 *****/
776
777 /* Similar to PingPongPipe, but will throttle the bandwidth to test
778 * blocking I/O.
779 */
780
781 #ifdef DEBUG_THROTTLE_PIPE
782
783 typedef struct {
784 PingPongPipe pingpong;
785 double sendRate;
786 int64_t sendExpiration;
787 double recvRate;
788 int64_t recvExpiration;
789 QEMUTimer* timer;
790 } ThrottlePipe;
791
792 /* forward declaration */
793 static void throttlePipe_timerFunc( void* opaque );
794
795 static void*
throttlePipe_init(void * hwpipe,void * svcOpaque,const char * args)796 throttlePipe_init( void* hwpipe, void* svcOpaque, const char* args )
797 {
798 ThrottlePipe* pipe;
799
800 ANEW0(pipe);
801 pingPongPipe_init0(&pipe->pingpong, hwpipe, svcOpaque);
802 pipe->timer = qemu_new_timer_ns(vm_clock, throttlePipe_timerFunc, pipe);
803 /* For now, limit to 500 KB/s in both directions */
804 pipe->sendRate = 1e9 / (500*1024*8);
805 pipe->recvRate = pipe->sendRate;
806 return pipe;
807 }
808
809 static void
throttlePipe_close(void * opaque)810 throttlePipe_close( void* opaque )
811 {
812 ThrottlePipe* pipe = opaque;
813
814 qemu_del_timer(pipe->timer);
815 qemu_free_timer(pipe->timer);
816 pingPongPipe_close(&pipe->pingpong);
817 }
818
819 static void
throttlePipe_rearm(ThrottlePipe * pipe)820 throttlePipe_rearm( ThrottlePipe* pipe )
821 {
822 int64_t minExpiration = 0;
823
824 DD("%s: sendExpiration=%lld recvExpiration=%lld\n", __FUNCTION__, pipe->sendExpiration, pipe->recvExpiration);
825
826 if (pipe->sendExpiration) {
827 if (minExpiration == 0 || pipe->sendExpiration < minExpiration)
828 minExpiration = pipe->sendExpiration;
829 }
830
831 if (pipe->recvExpiration) {
832 if (minExpiration == 0 || pipe->recvExpiration < minExpiration)
833 minExpiration = pipe->recvExpiration;
834 }
835
836 if (minExpiration != 0) {
837 DD("%s: Arming for %lld\n", __FUNCTION__, minExpiration);
838 qemu_mod_timer(pipe->timer, minExpiration);
839 }
840 }
841
842 static void
throttlePipe_timerFunc(void * opaque)843 throttlePipe_timerFunc( void* opaque )
844 {
845 ThrottlePipe* pipe = opaque;
846 int64_t now = qemu_get_clock_ns(vm_clock);
847
848 DD("%s: TICK! now=%lld sendExpiration=%lld recvExpiration=%lld\n",
849 __FUNCTION__, now, pipe->sendExpiration, pipe->recvExpiration);
850
851 /* Timer has expired, signal wake up if needed */
852 int flags = 0;
853
854 if (pipe->sendExpiration && now > pipe->sendExpiration) {
855 flags |= PIPE_WAKE_WRITE;
856 pipe->sendExpiration = 0;
857 }
858 if (pipe->recvExpiration && now > pipe->recvExpiration) {
859 flags |= PIPE_WAKE_READ;
860 pipe->recvExpiration = 0;
861 }
862 flags &= pipe->pingpong.flags;
863 if (flags != 0) {
864 DD("%s: WAKE %d\n", __FUNCTION__, flags);
865 goldfish_pipe_wake(pipe->pingpong.hwpipe, flags);
866 }
867
868 throttlePipe_rearm(pipe);
869 }
870
871 static int
throttlePipe_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)872 throttlePipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
873 {
874 ThrottlePipe* pipe = opaque;
875 int ret;
876
877 if (pipe->sendExpiration > 0) {
878 return PIPE_ERROR_AGAIN;
879 }
880
881 ret = pingPongPipe_sendBuffers(&pipe->pingpong, buffers, numBuffers);
882 if (ret > 0) {
883 /* Compute next send expiration time */
884 pipe->sendExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->sendRate;
885 throttlePipe_rearm(pipe);
886 }
887 return ret;
888 }
889
890 static int
throttlePipe_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)891 throttlePipe_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
892 {
893 ThrottlePipe* pipe = opaque;
894 int ret;
895
896 if (pipe->recvExpiration > 0) {
897 return PIPE_ERROR_AGAIN;
898 }
899
900 ret = pingPongPipe_recvBuffers(&pipe->pingpong, buffers, numBuffers);
901 if (ret > 0) {
902 pipe->recvExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->recvRate;
903 throttlePipe_rearm(pipe);
904 }
905 return ret;
906 }
907
908 static unsigned
throttlePipe_poll(void * opaque)909 throttlePipe_poll( void* opaque )
910 {
911 ThrottlePipe* pipe = opaque;
912 unsigned ret = pingPongPipe_poll(&pipe->pingpong);
913
914 if (pipe->sendExpiration > 0)
915 ret &= ~PIPE_POLL_OUT;
916
917 if (pipe->recvExpiration > 0)
918 ret &= ~PIPE_POLL_IN;
919
920 return ret;
921 }
922
923 static void
throttlePipe_wakeOn(void * opaque,int flags)924 throttlePipe_wakeOn( void* opaque, int flags )
925 {
926 ThrottlePipe* pipe = opaque;
927 pingPongPipe_wakeOn(&pipe->pingpong, flags);
928 }
929
930 static const GoldfishPipeFuncs throttlePipe_funcs = {
931 throttlePipe_init,
932 throttlePipe_close,
933 throttlePipe_sendBuffers,
934 throttlePipe_recvBuffers,
935 throttlePipe_poll,
936 throttlePipe_wakeOn,
937 };
938
939 #endif /* DEBUG_THROTTLE_PIPE */
940
941 /***********************************************************************
942 ***********************************************************************
943 *****
944 ***** G O L D F I S H P I P E D E V I C E
945 *****
946 *****/
947
948 struct PipeDevice {
949 struct goldfish_device dev;
950
951 /* the list of all pipes */
952 Pipe* pipes;
953
954 /* the list of signalled pipes */
955 Pipe* signaled_pipes;
956
957 /* i/o registers */
958 uint32_t address;
959 uint32_t size;
960 uint32_t status;
961 uint32_t channel;
962 uint32_t wakes;
963 };
964
965
966 static void
pipeDevice_doCommand(PipeDevice * dev,uint32_t command)967 pipeDevice_doCommand( PipeDevice* dev, uint32_t command )
968 {
969 Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
970 Pipe* pipe = *lookup;
971 CPUState* env = cpu_single_env;
972
973 /* Check that we're referring a known pipe channel */
974 if (command != PIPE_CMD_OPEN && pipe == NULL) {
975 dev->status = PIPE_ERROR_INVAL;
976 return;
977 }
978
979 /* If the pipe is closed by the host, return an error */
980 if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
981 dev->status = PIPE_ERROR_IO;
982 return;
983 }
984
985 switch (command) {
986 case PIPE_CMD_OPEN:
987 DD("%s: CMD_OPEN channel=0x%x", __FUNCTION__, dev->channel);
988 if (pipe != NULL) {
989 dev->status = PIPE_ERROR_INVAL;
990 break;
991 }
992 pipe = pipe_new(dev->channel, dev);
993 pipe->next = dev->pipes;
994 dev->pipes = pipe;
995 dev->status = 0;
996 break;
997
998 case PIPE_CMD_CLOSE:
999 DD("%s: CMD_CLOSE channel=0x%x", __FUNCTION__, dev->channel);
1000 /* Remove from device's lists */
1001 *lookup = pipe->next;
1002 pipe->next = NULL;
1003 pipe_list_remove_waked(&dev->signaled_pipes, pipe);
1004 pipe_free(pipe);
1005 break;
1006
1007 case PIPE_CMD_POLL:
1008 dev->status = pipe->funcs->poll(pipe->opaque);
1009 DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status);
1010 break;
1011
1012 case PIPE_CMD_READ_BUFFER: {
1013 /* Translate virtual address into physical one, into emulator memory. */
1014 GoldfishPipeBuffer buffer;
1015 uint32_t address = dev->address;
1016 uint32_t page = address & TARGET_PAGE_MASK;
1017 target_phys_addr_t phys;
1018 #ifdef CONFIG_KVM
1019 if(kvm_enabled()) {
1020 cpu_synchronize_state(env, 0);
1021 }
1022 #endif
1023 phys = cpu_get_phys_page_debug(env, page);
1024 buffer.data = qemu_get_ram_ptr(phys) + (address - page);
1025 buffer.size = dev->size;
1026 dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
1027 DD("%s: CMD_READ_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
1028 __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
1029 break;
1030 }
1031
1032 case PIPE_CMD_WRITE_BUFFER: {
1033 /* Translate virtual address into physical one, into emulator memory. */
1034 GoldfishPipeBuffer buffer;
1035 uint32_t address = dev->address;
1036 uint32_t page = address & TARGET_PAGE_MASK;
1037 target_phys_addr_t phys;
1038 #ifdef CONFIG_KVM
1039 if(kvm_enabled()) {
1040 cpu_synchronize_state(env, 0);
1041 }
1042 #endif
1043 phys = cpu_get_phys_page_debug(env, page);
1044 buffer.data = qemu_get_ram_ptr(phys) + (address - page);
1045 buffer.size = dev->size;
1046 dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
1047 DD("%s: CMD_WRITE_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
1048 __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
1049 break;
1050 }
1051
1052 case PIPE_CMD_WAKE_ON_READ:
1053 DD("%s: CMD_WAKE_ON_READ channel=0x%x", __FUNCTION__, dev->channel);
1054 if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
1055 pipe->wanted |= PIPE_WAKE_READ;
1056 pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1057 }
1058 dev->status = 0;
1059 break;
1060
1061 case PIPE_CMD_WAKE_ON_WRITE:
1062 DD("%s: CMD_WAKE_ON_WRITE channel=0x%x", __FUNCTION__, dev->channel);
1063 if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
1064 pipe->wanted |= PIPE_WAKE_WRITE;
1065 pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1066 }
1067 dev->status = 0;
1068 break;
1069
1070 default:
1071 D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command);
1072 }
1073 }
1074
pipe_dev_write(void * opaque,target_phys_addr_t offset,uint32_t value)1075 static void pipe_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
1076 {
1077 PipeDevice *s = (PipeDevice *)opaque;
1078
1079 switch (offset) {
1080 case PIPE_REG_COMMAND:
1081 DR("%s: command=%d (0x%x)", __FUNCTION__, value, value);
1082 pipeDevice_doCommand(s, value);
1083 break;
1084
1085 case PIPE_REG_SIZE:
1086 DR("%s: size=%d (0x%x)", __FUNCTION__, value, value);
1087 s->size = value;
1088 break;
1089
1090 case PIPE_REG_ADDRESS:
1091 DR("%s: address=%d (0x%x)", __FUNCTION__, value, value);
1092 s->address = value;
1093 break;
1094
1095 case PIPE_REG_CHANNEL:
1096 DR("%s: channel=%d (0x%x)", __FUNCTION__, value, value);
1097 s->channel = value;
1098 break;
1099
1100 default:
1101 D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset,
1102 offset, value, value);
1103 break;
1104 }
1105 }
1106
1107 /* I/O read */
pipe_dev_read(void * opaque,target_phys_addr_t offset)1108 static uint32_t pipe_dev_read(void *opaque, target_phys_addr_t offset)
1109 {
1110 PipeDevice *dev = (PipeDevice *)opaque;
1111
1112 switch (offset) {
1113 case PIPE_REG_STATUS:
1114 DR("%s: REG_STATUS status=%d (0x%x)", __FUNCTION__, dev->status, dev->status);
1115 return dev->status;
1116
1117 case PIPE_REG_CHANNEL:
1118 if (dev->signaled_pipes != NULL) {
1119 Pipe* pipe = dev->signaled_pipes;
1120 DR("%s: channel=0x%x wanted=%d", __FUNCTION__,
1121 pipe->channel, pipe->wanted);
1122 dev->wakes = pipe->wanted;
1123 pipe->wanted = 0;
1124 dev->signaled_pipes = pipe->next_waked;
1125 pipe->next_waked = NULL;
1126 if (dev->signaled_pipes == NULL) {
1127 goldfish_device_set_irq(&dev->dev, 0, 0);
1128 DD("%s: lowering IRQ", __FUNCTION__);
1129 }
1130 return pipe->channel;
1131 }
1132 DR("%s: no signaled channels", __FUNCTION__);
1133 return 0;
1134
1135 case PIPE_REG_WAKES:
1136 DR("%s: wakes %d", __FUNCTION__, dev->wakes);
1137 return dev->wakes;
1138
1139 default:
1140 D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset);
1141 }
1142 return 0;
1143 }
1144
1145 static CPUReadMemoryFunc *pipe_dev_readfn[] = {
1146 pipe_dev_read,
1147 pipe_dev_read,
1148 pipe_dev_read
1149 };
1150
1151 static CPUWriteMemoryFunc *pipe_dev_writefn[] = {
1152 pipe_dev_write,
1153 pipe_dev_write,
1154 pipe_dev_write
1155 };
1156
1157 static void
goldfish_pipe_save(QEMUFile * file,void * opaque)1158 goldfish_pipe_save( QEMUFile* file, void* opaque )
1159 {
1160 PipeDevice* dev = opaque;
1161 Pipe* pipe;
1162
1163 qemu_put_be32(file, dev->address);
1164 qemu_put_be32(file, dev->size);
1165 qemu_put_be32(file, dev->status);
1166 qemu_put_be32(file, dev->channel);
1167 qemu_put_be32(file, dev->wakes);
1168
1169 /* Count the number of pipe connections */
1170 int count = 0;
1171 for ( pipe = dev->pipes; pipe; pipe = pipe->next )
1172 count++;
1173
1174 qemu_put_sbe32(file, count);
1175
1176 /* Now save each pipe one after the other */
1177 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1178 pipe_save(pipe, file);
1179 }
1180 }
1181
1182 static int
goldfish_pipe_load(QEMUFile * file,void * opaque,int version_id)1183 goldfish_pipe_load( QEMUFile* file, void* opaque, int version_id )
1184 {
1185 PipeDevice* dev = opaque;
1186 Pipe* pipe;
1187
1188 if (version_id != GOLDFISH_PIPE_SAVE_VERSION)
1189 return -EINVAL;
1190
1191 dev->address = qemu_get_be32(file);
1192 dev->size = qemu_get_be32(file);
1193 dev->status = qemu_get_be32(file);
1194 dev->channel = qemu_get_be32(file);
1195 dev->wakes = qemu_get_be32(file);
1196
1197 /* Count the number of pipe connections */
1198 int count = qemu_get_sbe32(file);
1199
1200 /* Load all pipe connections */
1201 for ( ; count > 0; count-- ) {
1202 pipe = pipe_load(dev, file);
1203 if (pipe == NULL) {
1204 return -EIO;
1205 }
1206 pipe->next = dev->pipes;
1207 dev->pipes = pipe;
1208 }
1209
1210 /* Now we need to wake/close all relevant pipes */
1211 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1212 if (pipe->wanted != 0)
1213 goldfish_pipe_wake(pipe, pipe->wanted);
1214 if (pipe->closed != 0)
1215 goldfish_pipe_close(pipe);
1216 }
1217 return 0;
1218 }
1219
1220 /* initialize the trace device */
pipe_dev_init()1221 void pipe_dev_init()
1222 {
1223 PipeDevice *s;
1224
1225 s = (PipeDevice *) qemu_mallocz(sizeof(*s));
1226
1227 s->dev.name = "qemu_pipe";
1228 s->dev.id = -1;
1229 s->dev.base = 0; // will be allocated dynamically
1230 s->dev.size = 0x2000;
1231 s->dev.irq = 0;
1232 s->dev.irq_count = 1;
1233
1234 goldfish_device_add(&s->dev, pipe_dev_readfn, pipe_dev_writefn, s);
1235
1236 register_savevm( "goldfish_pipe", 0, GOLDFISH_PIPE_SAVE_VERSION,
1237 goldfish_pipe_save, goldfish_pipe_load, s);
1238
1239 #if DEBUG_ZERO_PIPE
1240 goldfish_pipe_add_type("zero", NULL, &zeroPipe_funcs);
1241 #endif
1242 #if DEBUG_PINGPONG_PIPE
1243 goldfish_pipe_add_type("pingpong", NULL, &pingPongPipe_funcs);
1244 #endif
1245 #if DEBUG_THROTTLE_PIPE
1246 goldfish_pipe_add_type("throttle", NULL, &throttlePipe_funcs);
1247 #endif
1248 }
1249
1250 void
goldfish_pipe_wake(void * hwpipe,unsigned flags)1251 goldfish_pipe_wake( void* hwpipe, unsigned flags )
1252 {
1253 Pipe* pipe = hwpipe;
1254 Pipe** lookup;
1255 PipeDevice* dev = pipe->device;
1256
1257 DD("%s: channel=0x%x flags=%d", __FUNCTION__, pipe->channel, flags);
1258
1259 /* If not already there, add to the list of signaled pipes */
1260 lookup = pipe_list_findp_waked(&dev->signaled_pipes, pipe);
1261 if (!*lookup) {
1262 pipe->next_waked = dev->signaled_pipes;
1263 dev->signaled_pipes = pipe;
1264 }
1265 pipe->wanted |= (unsigned)flags;
1266
1267 /* Raise IRQ to indicate there are items on our list ! */
1268 goldfish_device_set_irq(&dev->dev, 0, 1);
1269 DD("%s: raising IRQ", __FUNCTION__);
1270 }
1271
1272 void
goldfish_pipe_close(void * hwpipe)1273 goldfish_pipe_close( void* hwpipe )
1274 {
1275 Pipe* pipe = hwpipe;
1276
1277 D("%s: channel=0x%x (closed=%d)", __FUNCTION__, pipe->channel, pipe->closed);
1278
1279 if (!pipe->closed) {
1280 pipe->closed = 1;
1281 goldfish_pipe_wake( hwpipe, PIPE_WAKE_CLOSED );
1282 }
1283 }
1284