VirtualBox

Changeset 26764 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Feb 24, 2010 7:25:10 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
58021
Message:

HPET: status register implemented, 8-byte accesses implemented (Karmic kernel uses those)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevHPET.cpp

    r26495 r26764  
    3838 *   - interaction with RTC and PIT in legacy mode not yet fully implemented
    3939 *     (HPET part OK, PDM and PIT/RTC to be done)
    40  *   - status register writes not implemented
    4140 *   - statistics not implemented
    4241 */
     
    382381      {
    383382        Log4(("HPET: raising IRQ %d\n", irq));
    384         PDMDevHlpISASetIrq(pTimer->CTX_SUFF(pHpet)->CTX_SUFF(pDevIns),
    385                            irq, PDM_IRQ_LEVEL_FLIP_FLOP);
     383        if ((pTimer->u64Config & HPET_TIMER_TYPE_LEVEL) == 0)
     384        {
     385            pTimer->CTX_SUFF(pHpet)->u64Isr |= (1 <<  pTimer->u8TimerNumber);
     386            PDMDevHlpISASetIrq(pTimer->CTX_SUFF(pHpet)->CTX_SUFF(pDevIns),
     387                               irq, PDM_IRQ_LEVEL_FLIP_FLOP);
     388        }
    386389      }
    387390}
     
    464467                u64Ticks = pThis->u64HpetCounter;
    465468            /** @todo: is it correct? */
    466             *pValue = (iIndex == HPET_COUNTER) ?  (uint32_t)u64Ticks : (uint32_t)(u64Ticks >> 32);
     469            *pValue = (iIndex == HPET_COUNTER) ? (uint32_t)u64Ticks : (uint32_t)(u64Ticks >> 32);
    467470            break;
    468471        }
     
    669672        {
    670673            Log(("write HPET_STATUS: %x\n", iNewValue));
    671             /** @todo: need to implement, see p. 14 of HPET spec */
    672             LogRel(("HPET_STATUS writes unimplemented\n"));
     674            // clear ISR for all set bits in iNewValue, see p. 14 of HPET spec
     675            pThis->u64Isr &= ~((uint64_t)iNewValue);
     676            break;
     677        }
     678        case HPET_STATUS + 4:
     679        {
     680            Log(("write HPET_STATUS + 4: %x\n", iNewValue));
     681            if (iNewValue != 0)
     682                LogRel(("Writing HPET_STATUS + 4 with non-zero, ignored\n"));
    673683            break;
    674684        }
     
    725735            else
    726736                rc = configRegRead32(pThis, iIndex, (uint32_t*)pv);
     737            break;
     738        }
     739        case 8:
     740        {
     741            union {
     742                uint32_t u32[2];
     743                uint64_t u64;
     744            } value;
     745
     746            /* Unaligned accesses not allowed */
     747            if (iIndex % 8 != 0)
     748            {
     749                AssertMsgFailed(("Unaligned HPET read access\n"));
     750                rc = VERR_INTERNAL_ERROR;
     751                break;
     752            }
     753            // for 8-byte accesses we just split them, happens under lock anyway
     754            if ((iIndex >= 0x100) && (iIndex < 0x400))
     755            {
     756                uint32_t iTimer = (iIndex - 0x100) / 0x20;
     757                uint32_t iTimerReg = (iIndex - 0x100) % 0x20;
     758
     759                rc = timerRegRead32(pThis, iTimer, iTimerReg, &value.u32[0]);
     760                if (RT_UNLIKELY(rc != VINF_SUCCESS))
     761                    break;
     762                rc = timerRegRead32(pThis, iTimer, iTimerReg + 4, &value.u32[1]);
     763            }
     764            else
     765            {
     766                rc = configRegRead32(pThis, iIndex, &value.u32[0]);
     767                if (RT_UNLIKELY(rc != VINF_SUCCESS))
     768                    break;
     769                rc = configRegRead32(pThis, iIndex+4, &value.u32[1]);
     770            }
     771            if (rc == VINF_SUCCESS)
     772                *(uint64_t*)pv = value.u64;
    727773            break;
    728774        }
     
    771817            else
    772818                rc = configRegWrite32(pThis, iIndex, *(uint32_t*)pv);
     819            break;
     820        }
     821        case 8:
     822        {
     823            union {
     824                uint32_t u32[2];
     825                uint64_t u64;
     826            } value;
     827
     828            /* Unaligned accesses not allowed */
     829            if (iIndex % 8 != 0)
     830            {
     831                AssertMsgFailed(("Unaligned HPET write access\n"));
     832                rc = VERR_INTERNAL_ERROR;
     833                break;
     834            }
     835            value.u64 = *(uint64_t*)pv;
     836            // for 8-byte accesses we just split them, happens under lock anyway
     837            if ((iIndex >= 0x100) && (iIndex < 0x400))
     838            {
     839                uint32_t iTimer = (iIndex - 0x100) / 0x20;
     840                uint32_t iTimerReg = (iIndex - 0x100) % 0x20;
     841
     842                rc = timerRegWrite32(pThis, iTimer, iTimerReg, value.u32[0]);
     843                if (RT_UNLIKELY(rc != VINF_SUCCESS))
     844                    break;
     845                rc = timerRegWrite32(pThis, iTimer, iTimerReg + 4, value.u32[1]);
     846            }
     847            else
     848            {
     849                rc = configRegWrite32(pThis, iIndex, value.u32[0]);
     850                if (RT_UNLIKELY(rc != VINF_SUCCESS))
     851                    break;
     852                rc = configRegWrite32(pThis, iIndex+4, value.u32[1]);
     853            }
    773854            break;
    774855        }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette