Changeset 37475 in vbox
- Timestamp:
- Jun 15, 2011 4:42:55 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmdev.h
r37466 r37475 1074 1074 1075 1075 /** 1076 * Write MSR in APIC range.1076 * Write to a MSR in APIC range. 1077 1077 * 1078 1078 * @returns VBox status code. 1079 1079 * @param pDevIns Device instance of the APIC. 1080 1080 * @param idCpu Target CPU. 1081 * @param u32Reg MSR to write. 1082 * @param u64Value Value to write. 1081 * @param u32Reg The MSR begin written to. 1082 * @param u64Value The value to write. 1083 * 1084 * @remarks Unlike the other callbacks, the PDM lock is not taken before 1085 * calling this method. 1083 1086 */ 1084 1087 DECLR3CALLBACKMEMBER(int, pfnWriteMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value)); 1085 1088 1086 1089 /** 1087 * Read MSR in APIC range.1090 * Read from a MSR in APIC range. 1088 1091 * 1089 1092 * @returns VBox status code. … … 1091 1094 * @param idCpu Target CPU. 1092 1095 * @param u32Reg MSR to read. 1093 * @param pu64Value Value read.1096 * @param pu64Value Where to return the read value. 1094 1097 */ 1095 1098 DECLR3CALLBACKMEMBER(int, pfnReadMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value)); … … 1098 1101 * Private interface between the IOAPIC and APIC. 1099 1102 * 1100 * This is a low-level, APIC/IOAPIC implementation specific interface 1101 * which is registered with PDM only because it makes life so much1102 * simpler right now (GC bits). This is a bad bad hack! The correct1103 * w ay of doing this would involve some way of querying GC interfaces1104 * and relocating them.Perhaps doing some kind of device init in GC...1103 * This is a low-level, APIC/IOAPIC implementation specific interface which 1104 * is registered with PDM only because it makes life so much simpler right 1105 * now (GC bits). This is a bad bad hack! The correct way of doing this 1106 * would involve some way of querying GC interfaces and relocating them. 1107 * Perhaps doing some kind of device init in GC... 1105 1108 * 1106 1109 * @returns status code. -
trunk/src/VBox/Devices/PC/DevAPIC.cpp
r37466 r37475 79 79 #define APIC_UNLOCK(pThis) \ 80 80 PDMCritSectLeave((pThis)->CTX_SUFF(pCritSect)) 81 82 /** @def APIC_AND_TM_LOCK 83 * Acquires the virtual sync clock lock as well as the PDM lock. */ 84 #define APIC_AND_TM_LOCK(a_pDev, a_pAcpi, rcBusy) \ 85 do { \ 86 int rc2 = TMTimerLock((a_pAcpi)->CTX_SUFF(pTimer), (rcBusy)); \ 87 if (rc2 != VINF_SUCCESS) \ 88 return rc2; \ 89 rc2 = PDMCritSectEnter((a_pDev)->CTX_SUFF(pCritSect), (rcBusy)); \ 90 if (rc2 != VINF_SUCCESS) \ 91 { \ 92 TMTimerUnlock((a_pAcpi)->CTX_SUFF(pTimer)); \ 93 return rc2; \ 94 } \ 95 } while (0) 96 97 /** @def APIC_AND_TM_UNLOCK 98 * Releases the PDM lock as well as the TM virtual sync clock lock. */ 99 #define APIC_AND_TM_UNLOCK(a_pDev, a_pAcpi) \ 100 do { \ 101 TMTimerUnlock((a_pAcpi)->CTX_SUFF(pTimer)); \ 102 PDMCritSectLeave((a_pDev)->CTX_SUFF(pCritSect)); \ 103 } while (0) 104 81 105 82 106 /** @def IOAPIC_LOCK … … 575 599 576 600 /** 577 * x2APIC MSR write interface.601 * Writes to an APIC register via MMIO or MSR. 578 602 * 579 * @returns VBox status code. 580 * 581 * @param pDevIns The device instance. 582 * @param idCpu The ID of the virtual CPU and thereby APIC index. 583 * @param u32Reg Register to write (ecx). 584 * @param u64Value The value to write (eax:edx / rax). 585 * 603 * @returns Strict VBox status code. 604 * @param pDev The PDM device instance. 605 * @param pApic The APIC being written to. 606 * @param iReg The APIC register index. 607 * @param u64Value The value being written. 608 * @param rcBusy The busy return code to employ. See 609 * PDMCritSectEnter for a description. 610 * @param fMsr Set if called via MSR, clear if MMIO. 586 611 */ 587 PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value) 588 { 589 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 590 Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect))); 612 static int acpiWriteRegister(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t u64Value, 613 int rcBusy, bool fMsr) 614 { 615 Assert(!PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect))); 616 591 617 int rc = VINF_SUCCESS; 592 593 if (dev->enmVersion < PDMAPICVERSION_X2APIC) 594 return VERR_EM_INTERPRETER; 595 596 APICState *pThis = getLapicById(dev, idCpu); 597 598 uint32_t index = (u32Reg - MSR_IA32_APIC_START) & 0xff; 599 switch (index) 618 switch (iReg) 600 619 { 601 620 case 0x02: 602 pThis->id = (u64Value >> 24); 603 break; 621 APIC_LOCK(pDev, rcBusy); 622 pApic->id = (u64Value >> 24); /** @todo r=bird: Is the range supposed to be 40 bits??? */ 623 APIC_UNLOCK(pDev); 624 break; 625 604 626 case 0x03: 605 break; 627 /* read only, ignore write. */ 628 break; 629 606 630 case 0x08: 607 apic_update_tpr(dev, pThis, u64Value); 608 break; 631 APIC_LOCK(pDev, rcBusy); 632 apic_update_tpr(pDev, pApic, u64Value); 633 APIC_UNLOCK(pDev); 634 break; 635 609 636 case 0x09: case 0x0a: 610 Log(("apicWriteMSR: write to read-only register %d ignored\n", index)); 611 break; 637 Log(("acpiWriteRegister: write to read-only register %d ignored\n", iReg)); 638 break; 639 612 640 case 0x0b: /* EOI */ 613 apic_eoi(dev, pThis); 614 break; 641 APIC_LOCK(pDev, rcBusy); 642 apic_eoi(pDev, pApic); 643 APIC_UNLOCK(pDev); 644 break; 645 615 646 case 0x0d: 616 pThis->log_dest = u64Value >> 24; 617 break; 647 APIC_LOCK(pDev, rcBusy); 648 pApic->log_dest = (u64Value >> 24) & 0xff; 649 APIC_UNLOCK(pDev); 650 break; 651 618 652 case 0x0e: 619 pThis->dest_mode = u64Value >> 28; 620 break; 653 APIC_LOCK(pDev, rcBusy); 654 pApic->dest_mode = u64Value >> 28; /** @todo r=bird: range? This used to be 32-bit before morphed into an MSR handler. */ 655 APIC_UNLOCK(pDev); 656 break; 657 621 658 case 0x0f: 622 pThis->spurious_vec = u64Value & 0x1ff; 623 apic_update_irq(dev, pThis); 624 break; 659 APIC_LOCK(pDev, rcBusy); 660 pApic->spurious_vec = u64Value & 0x1ff; 661 apic_update_irq(pDev, pApic); 662 APIC_UNLOCK(pDev); 663 break; 664 625 665 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: 626 666 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: 627 667 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: 628 668 case 0x28: 629 Log(("a picWriteMSR: write to read-only register %d ignored\n", index));669 Log(("acpiWriteRegister: write to read-only register %d ignored\n", iReg)); 630 670 break; 631 671 632 672 case 0x30: 633 /* Here one of the differences with regular APIC: ICR is single 64-bit register */ 634 pThis->icr[0] = (uint32_t)u64Value; 635 pThis->icr[1] = (uint32_t)(u64Value >> 32); 636 rc = apic_deliver(dev, pThis, (pThis->icr[1] >> 24) & 0xff, (pThis->icr[0] >> 11) & 1, 637 (pThis->icr[0] >> 8) & 7, (pThis->icr[0] & 0xff), 638 (pThis->icr[0] >> 14) & 1, (pThis->icr[0] >> 15) & 1); 639 break; 673 APIC_LOCK(pDev, rcBusy); 674 pApic->icr[0] = (uint32_t)u64Value; 675 if (fMsr) /* Here one of the differences with regular APIC: ICR is single 64-bit register */ 676 pApic->icr[1] = (uint32_t)(u64Value >> 32); 677 rc = apic_deliver(pDev, pApic, (pApic->icr[1] >> 24) & 0xff, (pApic->icr[0] >> 11) & 1, 678 (pApic->icr[0] >> 8) & 7, (pApic->icr[0] & 0xff), 679 (pApic->icr[0] >> 14) & 1, (pApic->icr[0] >> 15) & 1); 680 APIC_UNLOCK(pDev); 681 break; 682 683 case 0x31: 684 APIC_LOCK(pDev, rcBusy); 685 if (!fMsr) 686 pApic->icr[1] = (uint64_t)u64Value; 687 else 688 pApic->esr |= ESR_ILLEGAL_ADDRESS; 689 APIC_UNLOCK(pDev); 690 break; 691 640 692 case 0x32 + APIC_LVT_TIMER: 641 693 AssertCompile(APIC_LVT_TIMER == 0); 642 apicTimerSetLvt(dev, pThis, u64Value); 694 APIC_AND_TM_LOCK(pDev, pApic, rcBusy); 695 apicTimerSetLvt(pDev, pApic, u64Value); 696 APIC_AND_TM_UNLOCK(pDev, pApic); 643 697 break; 644 698 645 699 case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: 646 pThis->lvt[index - 0x32] = u64Value; 647 break; 700 APIC_LOCK(pDev, rcBusy); 701 pApic->lvt[iReg - 0x32] = u64Value; 702 APIC_UNLOCK(pDev); 703 break; 704 648 705 case 0x38: 649 apicTimerSetInitialCount(dev, pThis, u64Value); 650 break; 706 APIC_AND_TM_LOCK(pDev, pApic, rcBusy); 707 apicTimerSetInitialCount(pDev, pApic, u64Value); 708 APIC_AND_TM_UNLOCK(pDev, pApic); 709 break; 710 651 711 case 0x39: 652 Log(("apicWriteMSR: write to read-only register %d ignored\n", index)); 653 break; 712 Log(("acpiWriteRegister: write to read-only register %d ignored\n", iReg)); 713 break; 714 654 715 case 0x3e: 655 716 { 656 int v; 657 pThis->divide_conf = u64Value & 0xb; 658 v = (pThis->divide_conf & 3) | ((pThis->divide_conf >> 1) & 4); 659 pThis->count_shift = (v + 1) & 7; 717 APIC_LOCK(pDev, rcBusy); 718 pApic->divide_conf = u64Value & 0xb; 719 int v = (pApic->divide_conf & 3) | ((pApic->divide_conf >> 1) & 4); 720 pApic->count_shift = (v + 1) & 7; 721 APIC_UNLOCK(pDev); 660 722 break; 661 723 } 724 662 725 case 0x3f: 663 { 664 /* Self IPI, see x2APIC book 2.4.5 */ 665 int vector = u64Value & 0xff; 666 rc = apic_bus_deliver(dev, 667 1 << getLapicById(dev, idCpu)->id /* Self */, 668 0 /* Delivery mode - fixed */, 669 vector, 670 0 /* Polarity - conform to the bus */, 671 0 /* Trigger mode - edge */); 672 break; 673 } 726 if (fMsr) 727 { 728 /* Self IPI, see x2APIC book 2.4.5 */ 729 APIC_LOCK(pDev, rcBusy); 730 int vector = u64Value & 0xff; 731 rc = apic_bus_deliver(pDev, 732 1 << pApic->id /* Self */, 733 0 /* Delivery mode - fixed */, 734 vector, 735 0 /* Polarity - conform to the bus */, 736 0 /* Trigger mode - edge */); 737 APIC_UNLOCK(pDev); 738 break; 739 } 740 /* else: fall thru */ 674 741 default: 675 AssertMsgFailed((" apicWriteMSR: unknown index %x\n", index));676 p This->esr |= ESR_ILLEGAL_ADDRESS;742 AssertMsgFailed(("unknown iReg %x\n", iReg)); 743 pApic->esr |= ESR_ILLEGAL_ADDRESS; 677 744 break; 678 745 } … … 682 749 683 750 /** 684 * x2APIC MSR read interface. 685 * 686 * @returns VBox status code. 687 * 688 * @param pDevIns The device instance. 689 * @param idCpu The ID of the virtual CPU and thereby APIC index. 690 * @param u32Reg Register to write (ecx). 691 * @param pu64Value Where to return the value (eax:edx / rax). 751 * @interface_method_impl{PDMAPICREG,pfnWriteMSRR3} 752 */ 753 PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value) 754 { 755 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 756 if (pDev->enmVersion < PDMAPICVERSION_X2APIC) 757 return VERR_EM_INTERPRETER; /** @todo tell the caller to raise hell (\#GP(0)). */ 758 759 APICState *pApic = getLapicById(pDev, idCpu); 760 uint32_t iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff; 761 return acpiWriteRegister(pDev, pApic, iReg, u64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/); 762 } 763 764 765 /** 766 * @interface_method_impl{PDMAPICREG,pfnReadMSRR3} 692 767 */ 693 768 PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value) … … 1078 1153 s->spurious_vec = 0xff; 1079 1154 s->log_dest = 0; 1080 s->dest_mode = 0xff; 1155 s->dest_mode = 0xff; /** @todo 0xff???? */ 1081 1156 memset(s->isr, 0, sizeof(s->isr)); 1082 1157 memset(s->tmr, 0, sizeof(s->tmr)); … … 1316 1391 { 1317 1392 STAM_COUNTER_INC(&pThis->StatTimerSetLvt); 1318 1319 /* Acquire the timer lock w/ lock order kludge. */1320 PDMCritSectLeave(dev->CTX_SUFF(pCritSect));1321 TMTimerLock(pThis->CTX_SUFF(pTimer), VINF_SUCCESS);1322 PDMCritSectEnter(dev->CTX_SUFF(pCritSect), VINF_SUCCESS);1323 1393 1324 1394 /* … … 1407 1477 else 1408 1478 STAM_COUNTER_INC(&pThis->StatTimerSetLvtNoRelevantChange); 1409 1410 TMTimerUnlock(pThis->CTX_SUFF(pTimer));1411 1479 } 1412 1480 … … 1535 1603 } 1536 1604 1537 static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, RTGCPHYS addr, uint32_t val)1538 {1539 int rc = VINF_SUCCESS;1540 int index;1541 1542 #ifdef DEBUG_APIC1543 Log(("CPU%d: APIC write: %08x = %08x\n", s->phys_id, (uint32_t)addr, val));1544 #endif1545 1546 index = (addr >> 4) & 0xff;1547 1548 switch(index) {1549 case 0x02:1550 s->id = (val >> 24);1551 break;1552 case 0x03:1553 Log(("apic_mem_writel: write to version register; ignored\n"));1554 break;1555 case 0x08:1556 apic_update_tpr(dev, s, val);1557 break;1558 case 0x09:1559 case 0x0a:1560 Log(("apic_mem_writel: write to read-only register %d ignored\n", index));1561 break;1562 case 0x0b: /* EOI */1563 apic_eoi(dev, s);1564 break;1565 case 0x0d:1566 s->log_dest = val >> 24;1567 break;1568 case 0x0e:1569 s->dest_mode = val >> 28;1570 break;1571 case 0x0f:1572 s->spurious_vec = val & 0x1ff;1573 apic_update_irq(dev, s);1574 break;1575 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:1576 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:1577 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:1578 case 0x28:1579 Log(("apic_mem_writel: write to read-only register %d ignored\n", index));1580 break;1581 1582 case 0x30:1583 s->icr[0] = val;1584 rc = apic_deliver(dev, s, (s->icr[1] >> 24) & 0xff,1585 (s->icr[0] >> 11) & 1,1586 (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),1587 (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);1588 break;1589 case 0x31:1590 s->icr[1] = val;1591 break;1592 case 0x32 + APIC_LVT_TIMER:1593 AssertCompile(APIC_LVT_TIMER == 0);1594 apicTimerSetLvt(dev, s, val);1595 break;1596 case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:1597 {1598 int n = index - 0x32;1599 s->lvt[n] = val;1600 }1601 break;1602 case 0x38:1603 apicTimerSetInitialCount(dev, s, val);1604 break;1605 case 0x39:1606 Log(("apic_mem_writel: write to read-only register %d ignored\n", index));1607 break;1608 case 0x3e:1609 {1610 int v;1611 s->divide_conf = val & 0xb;1612 v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);1613 s->count_shift = (v + 1) & 7;1614 }1615 break;1616 default:1617 AssertMsgFailed(("apic_mem_writel: unknown index %x\n", index));1618 s->esr |= ESR_ILLEGAL_ADDRESS;1619 break;1620 }1621 return rc;1622 }1623 1624 1605 #ifdef IN_RING3 1625 1606 … … 2014 1995 2015 1996 case 4: 2016 { 2017 int rc; 2018 APIC_LOCK(dev, VINF_IOM_HC_MMIO_WRITE); 2019 rc = apic_mem_writel(dev, s, GCPhysAddr, *(uint32_t *)pv); 2020 APIC_UNLOCK(dev); 2021 return rc; 2022 } 1997 /* It does its own locking. */ 1998 return acpiWriteRegister(dev, s, (GCPhysAddr >> 4) & 0xff, *(uint32_t const *)pv, 1999 VINF_IOM_HC_MMIO_WRITE, false /*fMsr*/); 2023 2000 2024 2001 default: -
trunk/src/VBox/Devices/PC/DevPit-i8254.cpp
r35853 r37475 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2011 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as -
trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
r37452 r37475 315 315 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns)) 316 316 { 317 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR)); 318 pdmLock(pVM); 319 pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, u64Value); 320 pdmUnlock(pVM); 321 return VINF_SUCCESS; 317 AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR)); 318 return pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, u64Value); 322 319 } 323 320 return VERR_PDM_NO_APIC_INSTANCE; … … 338 335 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns)) 339 336 { 340 Assert (pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR));341 pdmLock(pVM); 342 pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value);343 pdmUnlock(pVM); 344 return VINF_SUCCESS;337 AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)); 338 pdmLock(pVM); 339 int rc = pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value); 340 pdmUnlock(pVM); 341 return rc; 345 342 } 346 343 return VERR_PDM_NO_APIC_INSTANCE;
Note:
See TracChangeset
for help on using the changeset viewer.