Changeset 44534 in vbox
- Timestamp:
- Feb 4, 2013 9:16:06 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 83581
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevDMA.cpp
r44528 r44534 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 58 58 59 59 60 /* DMA Overview and notes60 /** @page pg_dev_dma DMA Overview and notes 61 61 * 62 62 * Modern PCs typically emulate AT-compatible DMA. The IBM PC/AT used dual … … 123 123 uint8_t u8Temp; /* Temporary (mem/mem) register. */ 124 124 uint8_t u8ModeCtr; /* Mode register counter for reads. */ 125 bool bHiByte; /* Byte pointer (T/F -> high/low). */125 bool fHiByte; /* Byte pointer (T/F -> high/low). */ 126 126 uint32_t is16bit; /* True for 16-bit DMA. */ 127 127 } DMAControl; … … 197 197 dc->u8Temp = 0; 198 198 dc->u8ModeCtr = 0; 199 dc-> bHiByte = false;199 dc->fHiByte = false; 200 200 dc->u8Mask = ~0; 201 201 } … … 206 206 bool bHighByte; 207 207 208 bHighByte = !!dc-> bHiByte;209 dc-> bHiByte ^= 1;208 bHighByte = !!dc->fHiByte; 209 dc->fHiByte ^= 1; 210 210 return bHighByte; 211 211 } … … 213 213 /* DMA address registers writes and reads. */ 214 214 215 static DECLCALLBACK(int) dmaWriteAddr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, 216 uint32_t u32, unsigned cb) 215 static DECLCALLBACK(int) dmaWriteAddr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t u32, unsigned cb) 217 216 { 218 217 if (cb == 1) … … 258 257 } 259 258 260 static DECLCALLBACK(int) dmaReadAddr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, 261 uint32_t *pu32, unsigned cb) 259 static DECLCALLBACK(int) dmaReadAddr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t *pu32, unsigned cb) 262 260 { 263 261 if (cb == 1) … … 343 341 } 344 342 case CTL_W_CLRBPTR: 345 dc-> bHiByte = false;343 dc->fHiByte = false; 346 344 break; 347 345 case CTL_W_MASTRCLR: … … 370 368 } 371 369 372 static DECLCALLBACK(int) dmaReadCtl(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, 373 uint32_t *pu32, unsigned cb) 370 static DECLCALLBACK(int) dmaReadCtl(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t *pu32, unsigned cb) 374 371 { 375 372 if (cb == 1) … … 382 379 Assert((reg >= CTL_R_STAT && reg <= CTL_R_MASK)); 383 380 384 switch (reg) { 385 case CTL_R_STAT: 386 val = dc->u8Status; 387 dc->u8Status &= 0xf0; /* A read clears all TCs. */ 388 break; 389 case CTL_R_DMAREQ: 390 val = (dc->u8Status >> 4) | 0xf0; 391 break; 392 case CTL_R_CMD: 393 val = dc->u8Command; 394 break; 395 case CTL_R_MODE: 396 val = dc->ChState[dc->u8ModeCtr].u8Mode | 3; 397 dc->u8ModeCtr = (dc->u8ModeCtr + 1) & 3; 398 case CTL_R_SETBPTR: 399 dc->bHiByte = true; 400 break; 401 case CTL_R_TEMP: 402 val = dc->u8Temp; 403 break; 404 case CTL_R_CLRMODE: 405 dc->u8ModeCtr = 0; 406 break; 407 case CTL_R_MASK: 408 val = dc->u8Mask; 409 break; 410 default: 411 Assert(0); 412 break; 381 switch (reg) 382 { 383 case CTL_R_STAT: 384 val = dc->u8Status; 385 dc->u8Status &= 0xf0; /* A read clears all TCs. */ 386 break; 387 case CTL_R_DMAREQ: 388 val = (dc->u8Status >> 4) | 0xf0; 389 break; 390 case CTL_R_CMD: 391 val = dc->u8Command; 392 break; 393 case CTL_R_MODE: 394 val = dc->ChState[dc->u8ModeCtr].u8Mode | 3; 395 dc->u8ModeCtr = (dc->u8ModeCtr + 1) & 3; 396 case CTL_R_SETBPTR: 397 dc->fHiByte = true; 398 break; 399 case CTL_R_TEMP: 400 val = dc->u8Temp; 401 break; 402 case CTL_R_CLRMODE: 403 dc->u8ModeCtr = 0; 404 break; 405 case CTL_R_MASK: 406 val = dc->u8Mask; 407 break; 408 default: 409 Assert(0); 410 break; 413 411 } 414 412 … … 418 416 return VINF_SUCCESS; 419 417 } 420 else 421 return VERR_IOM_IOPORT_UNUSED; 422 } 423 424 /* DMA page registers. There are 16 R/W page registers for compatibility with 418 return VERR_IOM_IOPORT_UNUSED; 419 } 420 421 /** DMA page registers. There are 16 R/W page registers for compatibility with 425 422 * the IBM PC/AT; only some of those registers are used for DMA. The page register 426 423 * accessible via port 80h may be read to insert small delays or used as a scratch 427 424 * register by a BIOS. 428 425 */ 429 static DECLCALLBACK(int) dmaReadPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, 430 uint32_t *pu32, unsigned cb) 426 static DECLCALLBACK(int) dmaReadPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t *pu32, unsigned cb) 431 427 { 432 428 DMAControl *dc = (DMAControl *)pvUser; … … 441 437 return VINF_SUCCESS; 442 438 } 443 else if (cb == 2) 439 440 if (cb == 2) 444 441 { 445 442 reg = port & 7; … … 449 446 return VINF_SUCCESS; 450 447 } 451 else 452 return VERR_IOM_IOPORT_UNUSED; 453 } 454 455 static DECLCALLBACK(int) dmaWritePage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, 456 uint32_t u32, unsigned cb) 448 449 return VERR_IOM_IOPORT_UNUSED; 450 } 451 452 static DECLCALLBACK(int) dmaWritePage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t u32, unsigned cb) 457 453 { 458 454 DMAControl *dc = (DMAControl *)pvUser; … … 487 483 } 488 484 489 /* EISA style high page registers, for extending the DMA addresses to cover 485 /** 486 * EISA style high page registers, for extending the DMA addresses to cover 490 487 * the entire 32-bit address space. 491 488 */ 492 static DECLCALLBACK(int) dmaReadHiPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, 493 uint32_t *pu32, unsigned cb) 489 static DECLCALLBACK(int) dmaReadHiPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t *pu32, unsigned cb) 494 490 { 495 491 if (cb == 1) … … 504 500 return VINF_SUCCESS; 505 501 } 506 else 507 return VERR_IOM_IOPORT_UNUSED; 508 } 509 510 static DECLCALLBACK(int) dmaWriteHiPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, 511 uint32_t u32, unsigned cb) 502 return VERR_IOM_IOPORT_UNUSED; 503 } 504 505 static DECLCALLBACK(int) dmaWriteHiPage(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t u32, unsigned cb) 512 506 { 513 507 if (cb == 1) … … 531 525 } 532 526 533 /* Perform any pending transfers on a single DMA channel. */534 static void dmaRunChannel(DMAState * s, int ctlidx, int chidx)535 { 536 DMAControl *dc = & s->DMAC[ctlidx];527 /** Perform any pending transfers on a single DMA channel. */ 528 static void dmaRunChannel(DMAState *pThis, int ctlidx, int chidx) 529 { 530 DMAControl *dc = &pThis->DMAC[ctlidx]; 537 531 DMAChannel *ch = &dc->ChState[chidx]; 538 532 uint32_t start_cnt, end_cnt; … … 547 541 /* Addresses and counts are shifted for 16-bit channels. */ 548 542 start_cnt = ch->u16CurCount << dc->is16bit; 549 end_cnt = ch->pfnXferHandler( s->pDevIns, ch->pvUser, (ctlidx * 4) + chidx,543 end_cnt = ch->pfnXferHandler(pThis->pDevIns, ch->pvUser, (ctlidx * 4) + chidx, 550 544 start_cnt, (ch->u16BaseCount + 1) << dc->is16bit); 551 545 ch->u16CurCount = end_cnt >> dc->is16bit; … … 553 547 } 554 548 555 static bool dmaRun(PPDMDEVINS pDevIns) 556 { 557 DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *); 549 /** 550 * @interface_method_impl{PDMDMAREG,pfnRun} 551 */ 552 static DECLCALLBACK(bool) dmaRun(PPDMDEVINS pDevIns) 553 { 554 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 558 555 DMAControl *dc; 559 556 int ctlidx, chidx, mask; 557 PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED); 560 558 561 559 /* Run all controllers and channels. */ 562 560 for (ctlidx = 0; ctlidx < 2; ++ctlidx) 563 561 { 564 dc = & s->DMAC[ctlidx];562 dc = &pThis->DMAC[ctlidx]; 565 563 566 564 /* If controller is disabled, don't even bother. */ … … 572 570 mask = 1 << chidx; 573 571 if (!(dc->u8Mask & mask) && (dc->u8Status & (mask << 4))) 574 dmaRunChannel( s, ctlidx, chidx);572 dmaRunChannel(pThis, ctlidx, chidx); 575 573 } 576 574 } 575 576 PDMCritSectLeave(pDevIns->pCritSectRoR3); 577 577 return 0; 578 578 } 579 579 580 static void dmaRegister(PPDMDEVINS pDevIns, unsigned channel, 581 PFNDMATRANSFERHANDLER handler, void *pvUser) 582 { 583 DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *); 584 DMAChannel *ch = &s->DMAC[DMACH2C(channel)].ChState[channel & 3]; 585 586 LogFlow(("dmaRegister: s=%p channel=%u XferHandler=%p pvUser=%p\n", 587 s, channel, handler, pvUser)); 588 589 ch->pfnXferHandler = handler; 580 /** 581 * @interface_method_impl{PDMDMAREG,pfnRegister} 582 */ 583 static DECLCALLBACK(void) dmaRegister(PPDMDEVINS pDevIns, unsigned uChannel, 584 PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser) 585 { 586 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 587 DMAChannel *ch = &pThis->DMAC[DMACH2C(uChannel)].ChState[uChannel & 3]; 588 589 LogFlow(("dmaRegister: pThis=%p uChannel=%u pfnTransferHandler=%p pvUser=%p\n", pThis, uChannel, pfnTransferHandler, pvUser)); 590 591 PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED); 592 ch->pfnXferHandler = pfnTransferHandler; 590 593 ch->pvUser = pvUser; 591 } 592 593 /* Reverse the order of bytes in a memory buffer. */ 594 PDMCritSectLeave(pDevIns->pCritSectRoR3); 595 } 596 597 /** Reverse the order of bytes in a memory buffer. */ 594 598 static void dmaReverseBuf8(void *buf, unsigned len) 595 599 { … … 607 611 } 608 612 609 /* Reverse the order of words in a memory buffer. */613 /** Reverse the order of words in a memory buffer. */ 610 614 static void dmaReverseBuf16(void *buf, unsigned len) 611 615 { … … 625 629 } 626 630 627 static uint32_t dmaReadMemory(PPDMDEVINS pDevIns, unsigned channel, 628 void *buf, uint32_t pos, uint32_t len) 629 { 630 DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *); 631 DMAControl *dc = &s->DMAC[DMACH2C(channel)]; 632 DMAChannel *ch = &dc->ChState[channel & 3]; 631 /** 632 * @interface_method_impl{PDMDMAREG,pfnReadMemory} 633 */ 634 static DECLCALLBACK(uint32_t) dmaReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, 635 void *pvBuffer, uint32_t off, uint32_t cbBlock) 636 { 637 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 638 DMAControl *dc = &pThis->DMAC[DMACH2C(uChannel)]; 639 DMAChannel *ch = &dc->ChState[uChannel & 3]; 633 640 uint32_t page, pagehi; 634 641 uint32_t addr; 635 642 636 LogFlow(("dmaReadMemory: s=%p channel=%u buf=%p pos=%u len=%u\n", 637 s, channel, buf, pos, len)); 643 LogFlow(("dmaReadMemory: pThis=%p uChannel=%u pvBuffer=%p off=%u cbBlock=%u\n", pThis, uChannel, pvBuffer, off, cbBlock)); 644 645 PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED); 638 646 639 647 /* Build the address for this transfer. */ 640 page = dc->au8Page[DMACH2PG( channel)] & ~dc->is16bit;641 pagehi = dc->au8PageHi[DMACH2PG( channel)];648 page = dc->au8Page[DMACH2PG(uChannel)] & ~dc->is16bit; 649 pagehi = dc->au8PageHi[DMACH2PG(uChannel)]; 642 650 addr = (pagehi << 24) | (page << 16) | (ch->u16CurAddr << dc->is16bit); 643 651 644 652 if (IS_MODE_DEC(ch->u8Mode)) 645 653 { 646 PDMDevHlpPhysRead( s->pDevIns, addr - pos - len, buf, len);654 PDMDevHlpPhysRead(pThis->pDevIns, addr - off - cbBlock, pvBuffer, cbBlock); 647 655 if (dc->is16bit) 648 dmaReverseBuf16( buf, len);656 dmaReverseBuf16(pvBuffer, cbBlock); 649 657 else 650 dmaReverseBuf8( buf, len);658 dmaReverseBuf8(pvBuffer, cbBlock); 651 659 } 652 660 else 653 PDMDevHlpPhysRead(s->pDevIns, addr + pos, buf, len); 654 655 return len; 656 } 657 658 static uint32_t dmaWriteMemory(PPDMDEVINS pDevIns, unsigned channel, 659 const void *buf, uint32_t pos, uint32_t len) 660 { 661 DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *); 662 DMAControl *dc = &s->DMAC[DMACH2C(channel)]; 663 DMAChannel *ch = &dc->ChState[channel & 3]; 661 PDMDevHlpPhysRead(pThis->pDevIns, addr + off, pvBuffer, cbBlock); 662 663 PDMCritSectLeave(pDevIns->pCritSectRoR3); 664 return cbBlock; 665 } 666 667 /** 668 * @interface_method_impl{PDMDMAREG,pfnWriteMemory} 669 */ 670 static DECLCALLBACK(uint32_t) dmaWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, 671 const void *pvBuffer, uint32_t off, uint32_t cbBlock) 672 { 673 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 674 DMAControl *dc = &pThis->DMAC[DMACH2C(uChannel)]; 675 DMAChannel *ch = &dc->ChState[uChannel & 3]; 664 676 uint32_t page, pagehi; 665 677 uint32_t addr; 666 678 667 LogFlow(("dmaWriteMemory: s=%p channel=%u buf=%p pos=%u len=%u\n",668 s, channel, buf, pos, len));679 LogFlow(("dmaWriteMemory: pThis=%p uChannel=%u pvBuffer=%p off=%u cbBlock=%u\n", pThis, uChannel, pvBuffer, off, cbBlock)); 680 PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED); 669 681 670 682 /* Build the address for this transfer. */ 671 page = dc->au8Page[DMACH2PG( channel)] & ~dc->is16bit;672 pagehi = dc->au8PageHi[DMACH2PG( channel)];683 page = dc->au8Page[DMACH2PG(uChannel)] & ~dc->is16bit; 684 pagehi = dc->au8PageHi[DMACH2PG(uChannel)]; 673 685 addr = (pagehi << 24) | (page << 16) | (ch->u16CurAddr << dc->is16bit); 674 686 … … 679 691 #if 0 680 692 if (dc->is16bit) 681 dmaReverseBuf16( buf, len);693 dmaReverseBuf16(pvBuffer, cbBlock); 682 694 else 683 dmaReverseBuf8( buf, len);695 dmaReverseBuf8(pvBuffer, cbBlock); 684 696 #endif 685 PDMDevHlpPhysWrite( s->pDevIns, addr - pos - len, buf, len);697 PDMDevHlpPhysWrite(pThis->pDevIns, addr - off - cbBlock, pvBuffer, cbBlock); 686 698 } 687 699 else 688 PDMDevHlpPhysWrite(s->pDevIns, addr + pos, buf, len); 689 690 return len; 691 } 692 693 static void dmaSetDREQ(PPDMDEVINS pDevIns, unsigned channel, unsigned level) 694 { 695 DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *); 696 DMAControl *dc = &s->DMAC[DMACH2C(channel)]; 700 PDMDevHlpPhysWrite(pThis->pDevIns, addr + off, pvBuffer, cbBlock); 701 702 PDMCritSectLeave(pDevIns->pCritSectRoR3); 703 return cbBlock; 704 } 705 706 /** 707 * @interface_method_impl{PDMDMAREG,pfnSetDREQ} 708 */ 709 static DECLCALLBACK(void) dmaSetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel) 710 { 711 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 712 DMAControl *dc = &pThis->DMAC[DMACH2C(uChannel)]; 697 713 int chidx; 698 714 699 LogFlow(("dmaSetDREQ: s=%p channel=%u level=%u\n", s, channel, level)); 700 701 chidx = channel & 3; 702 if (level) 715 LogFlow(("dmaSetDREQ: pThis=%p uChannel=%u uLevel=%u\n", pThis, uChannel, uLevel)); 716 717 PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED); 718 chidx = uChannel & 3; 719 if (uLevel) 703 720 dc->u8Status |= 1 << (chidx + 4); 704 721 else 705 722 dc->u8Status &= ~(1 << (chidx + 4)); 706 } 707 708 static uint8_t dmaGetChannelMode(PPDMDEVINS pDevIns, unsigned channel) 709 { 710 DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *); 711 712 LogFlow(("dmaGetChannelMode: s=%p channel=%u\n", s, channel)); 713 714 return s->DMAC[DMACH2C(channel)].ChState[channel & 3].u8Mode; 715 } 716 723 PDMCritSectLeave(pDevIns->pCritSectRoR3); 724 } 725 726 /** 727 * @interface_method_impl{PDMDMAREG,pfnGetChannelMode} 728 */ 729 static DECLCALLBACK(uint8_t) dmaGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel) 730 { 731 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 732 733 LogFlow(("dmaGetChannelMode: pThis=%p uChannel=%u\n", pThis, uChannel)); 734 735 PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED); 736 uint8_t u8Mode = pThis->DMAC[DMACH2C(uChannel)].ChState[uChannel & 3].u8Mode; 737 PDMCritSectLeave(pDevIns->pCritSectRoR3); 738 return u8Mode; 739 } 740 741 742 /** 743 * @interface_method_impl{PDMDEVREG,pfnReset} 744 */ 717 745 static void dmaReset(PPDMDEVINS pDevIns) 718 746 { 719 DMAState * s = PDMINS_2_DATA(pDevIns, DMAState *);720 721 LogFlow(("dmaReset: s=%p\n",s));747 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 748 749 LogFlow(("dmaReset: pThis=%p\n", pThis)); 722 750 723 751 /* NB: The page and address registers are unaffected by a reset 724 752 * and in an undefined state after power-up. 725 753 */ 726 dmaClear(&s->DMAC[0]); 727 dmaClear(&s->DMAC[1]); 728 } 729 730 /* Register DMA I/O port handlers. */ 731 static void dmaIORegister(PPDMDEVINS pDevIns, bool bHighPage) 732 { 733 DMAState *s = PDMINS_2_DATA(pDevIns, DMAState *); 734 DMAControl *dc8; 735 DMAControl *dc16; 736 737 dc8 = &s->DMAC[0]; 738 dc16 = &s->DMAC[1]; 754 dmaClear(&pThis->DMAC[0]); 755 dmaClear(&pThis->DMAC[1]); 756 } 757 758 /** Register DMA I/O port handlers. */ 759 static void dmaIORegister(PPDMDEVINS pDevIns, bool fHighPage) 760 { 761 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 762 DMAControl *dc8 = &pThis->DMAC[0]; 763 DMAControl *dc16 = &pThis->DMAC[1]; 739 764 740 765 dc8->is16bit = false; … … 742 767 743 768 /* Base and current address for each channel. */ 744 PDMDevHlpIOPortRegister(s->pDevIns, 0x00, 8, dc8, 745 dmaWriteAddr, dmaReadAddr, NULL, NULL, "DMA8 Address"); 746 PDMDevHlpIOPortRegister(s->pDevIns, 0xC0, 16, dc16, 747 dmaWriteAddr, dmaReadAddr, NULL, NULL, "DMA16 Address"); 769 PDMDevHlpIOPortRegister(pThis->pDevIns, 0x00, 8, dc8, dmaWriteAddr, dmaReadAddr, NULL, NULL, "DMA8 Address"); 770 PDMDevHlpIOPortRegister(pThis->pDevIns, 0xC0, 16, dc16, dmaWriteAddr, dmaReadAddr, NULL, NULL, "DMA16 Address"); 771 748 772 /* Control registers for both DMA controllers. */ 749 PDMDevHlpIOPortRegister(s->pDevIns, 0x08, 8, dc8, 750 dmaWriteCtl, dmaReadCtl, NULL, NULL, "DMA8 Control"); 751 PDMDevHlpIOPortRegister(s->pDevIns, 0xD0, 16, dc16, 752 dmaWriteCtl, dmaReadCtl, NULL, NULL, "DMA16 Control"); 773 PDMDevHlpIOPortRegister(pThis->pDevIns, 0x08, 8, dc8, dmaWriteCtl, dmaReadCtl, NULL, NULL, "DMA8 Control"); 774 PDMDevHlpIOPortRegister(pThis->pDevIns, 0xD0, 16, dc16, dmaWriteCtl, dmaReadCtl, NULL, NULL, "DMA16 Control"); 775 753 776 /* Page registers for each channel (plus a few unused ones). */ 754 PDMDevHlpIOPortRegister(s->pDevIns, 0x80, 8, dc8, 755 dmaWritePage, dmaReadPage, NULL, NULL, "DMA8 Page"); 756 PDMDevHlpIOPortRegister(s->pDevIns, 0x88, 8, dc16, 757 dmaWritePage, dmaReadPage, NULL, NULL, "DMA16 Page"); 777 PDMDevHlpIOPortRegister(pThis->pDevIns, 0x80, 8, dc8, dmaWritePage, dmaReadPage, NULL, NULL, "DMA8 Page"); 778 PDMDevHlpIOPortRegister(pThis->pDevIns, 0x88, 8, dc16, dmaWritePage, dmaReadPage, NULL, NULL, "DMA16 Page"); 779 758 780 /* Optional EISA style high page registers (address bits 24-31). */ 759 if (bHighPage) 760 { 761 PDMDevHlpIOPortRegister(s->pDevIns, 0x480, 8, dc8, 762 dmaWriteHiPage, dmaReadHiPage, NULL, NULL, "DMA8 Page High"); 763 PDMDevHlpIOPortRegister(s->pDevIns, 0x488, 8, dc16, 764 dmaWriteHiPage, dmaReadHiPage, NULL, NULL, "DMA16 Page High"); 781 if (fHighPage) 782 { 783 PDMDevHlpIOPortRegister(pThis->pDevIns, 0x480, 8, dc8, dmaWriteHiPage, dmaReadHiPage, NULL, NULL, "DMA8 Page High"); 784 PDMDevHlpIOPortRegister(pThis->pDevIns, 0x488, 8, dc16, dmaWriteHiPage, dmaReadHiPage, NULL, NULL, "DMA16 Page High"); 765 785 } 766 786 } … … 773 793 SSMR3PutU8(pSSMHandle, dc->u8Command); 774 794 SSMR3PutU8(pSSMHandle, dc->u8Mask); 775 SSMR3PutU8(pSSMHandle, dc-> bHiByte);795 SSMR3PutU8(pSSMHandle, dc->fHiByte); 776 796 SSMR3PutU32(pSSMHandle, dc->is16bit); 777 797 SSMR3PutU8(pSSMHandle, dc->u8Status); … … 803 823 SSMR3GetU8(pSSMHandle, &dc->u8Mask); 804 824 SSMR3GetU8(pSSMHandle, &u8val); 805 dc-> bHiByte = !!u8val;825 dc->fHiByte = !!u8val; 806 826 SSMR3GetU32(pSSMHandle, &dc->is16bit); 807 827 if (version > DMA_SAVESTATE_OLD) … … 850 870 } 851 871 872 /** @callback_method_impl{FNSSMDEVSAVEEXEC} */ 852 873 static DECLCALLBACK(int) dmaSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle) 853 874 { 854 DMAState * s = PDMINS_2_DATA(pDevIns, DMAState *);855 856 dmaSaveController(pSSMHandle, & s->DMAC[0]);857 dmaSaveController(pSSMHandle, & s->DMAC[1]);875 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 876 877 dmaSaveController(pSSMHandle, &pThis->DMAC[0]); 878 dmaSaveController(pSSMHandle, &pThis->DMAC[1]); 858 879 return VINF_SUCCESS; 859 880 } 860 881 861 static DECLCALLBACK(int) dmaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, 862 863 { 864 DMAState * s = PDMINS_2_DATA(pDevIns, DMAState *);882 /** @callback_method_impl{FNSSMDEVLOADEXEC} */ 883 static DECLCALLBACK(int) dmaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass) 884 { 885 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 865 886 866 887 AssertMsgReturn(uVersion <= DMA_SAVESTATE_CURRENT, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION); 867 888 Assert(uPass == SSM_PASS_FINAL); NOREF(uPass); 868 889 869 dmaLoadController(pSSMHandle, & s->DMAC[0], uVersion);870 return dmaLoadController(pSSMHandle, & s->DMAC[1], uVersion);890 dmaLoadController(pSSMHandle, &pThis->DMAC[0], uVersion); 891 return dmaLoadController(pSSMHandle, &pThis->DMAC[1], uVersion); 871 892 } 872 893 … … 876 897 static DECLCALLBACK(int) dmaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg) 877 898 { 878 DMAState * s = PDMINS_2_DATA(pDevIns, DMAState *);899 DMAState *pThis = PDMINS_2_DATA(pDevIns, DMAState *); 879 900 bool bHighPage = false; 880 901 PDMDMACREG reg; 881 902 int rc; 882 903 883 s->pDevIns = pDevIns;904 pThis->pDevIns = pDevIns; 884 905 885 906 /* … … 906 927 reg.pfnGetChannelMode = dmaGetChannelMode; 907 928 908 rc = PDMDevHlpDMACRegister(pDevIns, ®, & s->pHlp);929 rc = PDMDevHlpDMACRegister(pDevIns, ®, &pThis->pHlp); 909 930 if (RT_FAILURE (rc)) 910 931 return rc; 911 932 912 rc = PDMDevHlpSSMRegister(pDevIns, DMA_SAVESTATE_CURRENT, sizeof(*s), 913 dmaSaveExec, dmaLoadExec); 933 rc = PDMDevHlpSSMRegister(pDevIns, DMA_SAVESTATE_CURRENT, sizeof(*pThis), dmaSaveExec, dmaLoadExec); 914 934 if (RT_FAILURE(rc)) 915 935 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.