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