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 2 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 68typedef struct { 69 const char* name; 70 void* opaque; 71 GoldfishPipeFuncs funcs; 72} PipeService; 73 74typedef struct { 75 int count; 76 PipeService services[MAX_PIPE_SERVICES]; 77} PipeServices; 78 79static PipeServices _pipeServices[1]; 80 81void 82goldfish_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 104static const PipeService* 105goldfish_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 127typedef struct PipeDevice PipeDevice; 128 129typedef 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 */ 143static void* pipeConnector_new(Pipe* pipe); 144 145static Pipe* 146pipe_new0(PipeDevice* dev) 147{ 148 Pipe* pipe; 149 ANEW0(pipe); 150 pipe->device = dev; 151 return pipe; 152} 153 154static Pipe* 155pipe_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 163static Pipe** 164pipe_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 178static Pipe** 179pipe_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 193static Pipe** 194pipe_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 208static void 209pipe_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 220static void 221pipe_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 251static Pipe* 252pipe_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 299static void 300pipe_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 */ 322typedef struct { 323 Pipe* pipe; 324 char buffer[128]; 325 int buffpos; 326} PipeConnector; 327 328static const GoldfishPipeFuncs pipeConnector_funcs; // forward 329 330void* 331pipeConnector_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 341static void 342pipeConnector_close( void* opaque ) 343{ 344 PipeConnector* pcon = opaque; 345 AFREE(pcon); 346} 347 348static int 349pipeConnector_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 433static int 434pipeConnector_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers ) 435{ 436 return PIPE_ERROR_IO; 437} 438 439static unsigned 440pipeConnector_poll( void* opaque ) 441{ 442 return PIPE_POLL_OUT; 443} 444 445static void 446pipeConnector_wakeOn( void* opaque, int flags ) 447{ 448 /* nothing, really should never happen */ 449} 450 451static void 452pipeConnector_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 459static void* 460pipeConnector_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 477static 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 501typedef struct { 502 void* hwpipe; 503} ZeroPipe; 504 505static void* 506zeroPipe_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 516static void 517zeroPipe_close( void* opaque ) 518{ 519 ZeroPipe* zpipe = opaque; 520 521 D("%s: hwpipe=%p", __FUNCTION__, zpipe->hwpipe); 522 AFREE(zpipe); 523} 524 525static int 526zeroPipe_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 537static int 538zeroPipe_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 550static unsigned 551zeroPipe_poll( void* opaque ) 552{ 553 return PIPE_POLL_IN | PIPE_POLL_OUT; 554} 555 556static void 557zeroPipe_wakeOn( void* opaque, int flags ) 558{ 559 /* nothing to do here */ 560} 561 562static 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 588typedef 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 597static void 598pingPongPipe_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 607static void* 608pingPongPipe_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 618static void 619pingPongPipe_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 629static int 630pingPongPipe_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 693static int 694pingPongPipe_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 737static unsigned 738pingPongPipe_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 752static void 753pingPongPipe_wakeOn( void* opaque, int flags ) 754{ 755 PingPongPipe* pipe = opaque; 756 pipe->flags |= (unsigned)flags; 757} 758 759static 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 783typedef 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 */ 793static void throttlePipe_timerFunc( void* opaque ); 794 795static void* 796throttlePipe_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 809static void 810throttlePipe_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 819static void 820throttlePipe_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 842static void 843throttlePipe_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 871static int 872throttlePipe_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 890static int 891throttlePipe_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 908static unsigned 909throttlePipe_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 923static void 924throttlePipe_wakeOn( void* opaque, int flags ) 925{ 926 ThrottlePipe* pipe = opaque; 927 pingPongPipe_wakeOn(&pipe->pingpong, flags); 928} 929 930static 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 948struct 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 uint64_t params_addr; 964}; 965 966static void 967pipeDevice_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 1075static 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 case PIPE_REG_PARAMS_ADDR_HIGH: 1101 s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL << 32) ) | 1102 ((uint64_t)value << 32); 1103 break; 1104 1105 case PIPE_REG_PARAMS_ADDR_LOW: 1106 s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL) ) | value; 1107 break; 1108 1109 case PIPE_REG_ACCESS_PARAMS: 1110 { 1111 struct access_params aps; 1112 uint32_t cmd; 1113 1114 /* Don't touch aps.result if anything wrong */ 1115 if (s->params_addr == 0) 1116 break; 1117 1118 cpu_physical_memory_read(s->params_addr, (void*)&aps, 1119 sizeof(struct access_params)); 1120 1121 /* sync pipe device state from batch buffer */ 1122 s->channel = aps.channel; 1123 s->size = aps.size; 1124 s->address = aps.address; 1125 cmd = aps.cmd; 1126 if ((cmd != PIPE_CMD_READ_BUFFER) && (cmd != PIPE_CMD_WRITE_BUFFER)) 1127 break; 1128 1129 pipeDevice_doCommand(s, cmd); 1130 aps.result = s->status; 1131 cpu_physical_memory_write(s->params_addr, (void*)&aps, 1132 sizeof(struct access_params)); 1133 } 1134 break; 1135 1136 default: 1137 D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset, 1138 offset, value, value); 1139 break; 1140 } 1141} 1142 1143/* I/O read */ 1144static uint32_t pipe_dev_read(void *opaque, target_phys_addr_t offset) 1145{ 1146 PipeDevice *dev = (PipeDevice *)opaque; 1147 1148 switch (offset) { 1149 case PIPE_REG_STATUS: 1150 DR("%s: REG_STATUS status=%d (0x%x)", __FUNCTION__, dev->status, dev->status); 1151 return dev->status; 1152 1153 case PIPE_REG_CHANNEL: 1154 if (dev->signaled_pipes != NULL) { 1155 Pipe* pipe = dev->signaled_pipes; 1156 DR("%s: channel=0x%x wanted=%d", __FUNCTION__, 1157 pipe->channel, pipe->wanted); 1158 dev->wakes = pipe->wanted; 1159 pipe->wanted = 0; 1160 dev->signaled_pipes = pipe->next_waked; 1161 pipe->next_waked = NULL; 1162 if (dev->signaled_pipes == NULL) { 1163 goldfish_device_set_irq(&dev->dev, 0, 0); 1164 DD("%s: lowering IRQ", __FUNCTION__); 1165 } 1166 return pipe->channel; 1167 } 1168 DR("%s: no signaled channels", __FUNCTION__); 1169 return 0; 1170 1171 case PIPE_REG_WAKES: 1172 DR("%s: wakes %d", __FUNCTION__, dev->wakes); 1173 return dev->wakes; 1174 1175 case PIPE_REG_PARAMS_ADDR_HIGH: 1176 return dev->params_addr >> 32; 1177 1178 case PIPE_REG_PARAMS_ADDR_LOW: 1179 return dev->params_addr & 0xFFFFFFFFUL; 1180 1181 default: 1182 D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset); 1183 } 1184 return 0; 1185} 1186 1187static CPUReadMemoryFunc *pipe_dev_readfn[] = { 1188 pipe_dev_read, 1189 pipe_dev_read, 1190 pipe_dev_read 1191}; 1192 1193static CPUWriteMemoryFunc *pipe_dev_writefn[] = { 1194 pipe_dev_write, 1195 pipe_dev_write, 1196 pipe_dev_write 1197}; 1198 1199static void 1200goldfish_pipe_save( QEMUFile* file, void* opaque ) 1201{ 1202 PipeDevice* dev = opaque; 1203 Pipe* pipe; 1204 1205 qemu_put_be32(file, dev->address); 1206 qemu_put_be32(file, dev->size); 1207 qemu_put_be32(file, dev->status); 1208 qemu_put_be32(file, dev->channel); 1209 qemu_put_be32(file, dev->wakes); 1210 qemu_put_be64(file, dev->params_addr); 1211 1212 /* Count the number of pipe connections */ 1213 int count = 0; 1214 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) 1215 count++; 1216 1217 qemu_put_sbe32(file, count); 1218 1219 /* Now save each pipe one after the other */ 1220 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) { 1221 pipe_save(pipe, file); 1222 } 1223} 1224 1225static int 1226goldfish_pipe_load( QEMUFile* file, void* opaque, int version_id ) 1227{ 1228 PipeDevice* dev = opaque; 1229 Pipe* pipe; 1230 1231 if (version_id != GOLDFISH_PIPE_SAVE_VERSION) 1232 return -EINVAL; 1233 1234 dev->address = qemu_get_be32(file); 1235 dev->size = qemu_get_be32(file); 1236 dev->status = qemu_get_be32(file); 1237 dev->channel = qemu_get_be32(file); 1238 dev->wakes = qemu_get_be32(file); 1239 dev->params_addr = qemu_get_be64(file); 1240 1241 /* Count the number of pipe connections */ 1242 int count = qemu_get_sbe32(file); 1243 1244 /* Load all pipe connections */ 1245 for ( ; count > 0; count-- ) { 1246 pipe = pipe_load(dev, file); 1247 if (pipe == NULL) { 1248 return -EIO; 1249 } 1250 pipe->next = dev->pipes; 1251 dev->pipes = pipe; 1252 } 1253 1254 /* Now we need to wake/close all relevant pipes */ 1255 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) { 1256 if (pipe->wanted != 0) 1257 goldfish_pipe_wake(pipe, pipe->wanted); 1258 if (pipe->closed != 0) 1259 goldfish_pipe_close(pipe); 1260 } 1261 return 0; 1262} 1263 1264/* initialize the trace device */ 1265void pipe_dev_init() 1266{ 1267 PipeDevice *s; 1268 1269 s = (PipeDevice *) qemu_mallocz(sizeof(*s)); 1270 1271 s->dev.name = "qemu_pipe"; 1272 s->dev.id = -1; 1273 s->dev.base = 0; // will be allocated dynamically 1274 s->dev.size = 0x2000; 1275 s->dev.irq = 0; 1276 s->dev.irq_count = 1; 1277 1278 goldfish_device_add(&s->dev, pipe_dev_readfn, pipe_dev_writefn, s); 1279 1280 register_savevm( "goldfish_pipe", 0, GOLDFISH_PIPE_SAVE_VERSION, 1281 goldfish_pipe_save, goldfish_pipe_load, s); 1282 1283#if DEBUG_ZERO_PIPE 1284 goldfish_pipe_add_type("zero", NULL, &zeroPipe_funcs); 1285#endif 1286#if DEBUG_PINGPONG_PIPE 1287 goldfish_pipe_add_type("pingpong", NULL, &pingPongPipe_funcs); 1288#endif 1289#if DEBUG_THROTTLE_PIPE 1290 goldfish_pipe_add_type("throttle", NULL, &throttlePipe_funcs); 1291#endif 1292} 1293 1294void 1295goldfish_pipe_wake( void* hwpipe, unsigned flags ) 1296{ 1297 Pipe* pipe = hwpipe; 1298 Pipe** lookup; 1299 PipeDevice* dev = pipe->device; 1300 1301 DD("%s: channel=0x%x flags=%d", __FUNCTION__, pipe->channel, flags); 1302 1303 /* If not already there, add to the list of signaled pipes */ 1304 lookup = pipe_list_findp_waked(&dev->signaled_pipes, pipe); 1305 if (!*lookup) { 1306 pipe->next_waked = dev->signaled_pipes; 1307 dev->signaled_pipes = pipe; 1308 } 1309 pipe->wanted |= (unsigned)flags; 1310 1311 /* Raise IRQ to indicate there are items on our list ! */ 1312 goldfish_device_set_irq(&dev->dev, 0, 1); 1313 DD("%s: raising IRQ", __FUNCTION__); 1314} 1315 1316void 1317goldfish_pipe_close( void* hwpipe ) 1318{ 1319 Pipe* pipe = hwpipe; 1320 1321 D("%s: channel=0x%x (closed=%d)", __FUNCTION__, pipe->channel, pipe->closed); 1322 1323 if (!pipe->closed) { 1324 pipe->closed = 1; 1325 goldfish_pipe_wake( hwpipe, PIPE_WAKE_CLOSED ); 1326 } 1327} 1328