VirtualBox

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


Ignore:
Timestamp:
Sep 1, 2019 11:03:34 PM (5 years ago)
Author:
vboxsync
Message:

VMM,Devices: Some PDM device model refactoring. bugref:9218

Location:
trunk/src/VBox/Devices/PC
Files:
10 edited

Legend:

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

    r78571 r80531  
    41784178}
    41794179
     4180#endif /* IN_RING3 */
     4181
    41804182/**
    41814183 * The device registration structure.
     
    41834185const PDMDEVREG g_DeviceACPI =
    41844186{
    4185     /* u32Version */
    4186     PDM_DEVREG_VERSION,
    4187     /* szName */
    4188     "acpi",
    4189     /* szRCMod */
    4190     "VBoxDDRC.rc",
    4191     /* szR0Mod */
    4192     "VBoxDDR0.r0",
    4193     /* pszDescription */
    4194     "Advanced Configuration and Power Interface",
    4195     /* fFlags */
    4196     PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
    4197     /* fClass */
    4198     PDM_DEVREG_CLASS_ACPI,
    4199     /* cMaxInstances */
    4200     ~0U,
    4201     /* cbInstance */
    4202     sizeof(ACPIState),
    4203     /* pfnConstruct */
    4204     acpiR3Construct,
    4205     /* pfnDestruct */
    4206     acpiR3Destruct,
    4207     /* pfnRelocate */
    4208     acpiR3Relocate,
    4209     /* pfnMemSetup */
    4210     acpiR3MemSetup,
    4211     /* pfnPowerOn */
    4212     NULL,
    4213     /* pfnReset */
    4214     acpiR3Reset,
    4215     /* pfnSuspend */
    4216     NULL,
    4217     /* pfnResume */
    4218     acpiR3Resume,
    4219     /* pfnAttach */
    4220     acpiR3Attach,
    4221     /* pfnDetach */
    4222     acpiR3Detach,
    4223     /* pfnQueryInterface. */
    4224     NULL,
    4225     /* pfnInitComplete */
    4226     NULL,
    4227     /* pfnPowerOff */
    4228     NULL,
    4229     /* pfnSoftReset */
    4230     NULL,
    4231     /* u32VersionEnd */
    4232     PDM_DEVREG_VERSION
     4187    /* .u32Version = */             PDM_DEVREG_VERSION,
     4188    /* .uReserved0 = */             0,
     4189    /* .szName = */                 "acpi",
     4190    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
     4191    /* .fClass = */                 PDM_DEVREG_CLASS_ACPI,
     4192    /* .cMaxInstances = */          ~0U,
     4193    /* .uSharedVersion = */         42,
     4194    /* .cbInstanceShared = */       sizeof(ACPIState),
     4195    /* .cbInstanceCC = */           0,
     4196    /* .cbInstanceRC = */           0,
     4197    /* .uReserved1 = */             0,
     4198    /* .pszDescription = */         "Advanced Configuration and Power Interface",
     4199#if defined(IN_RING3)
     4200    /* .pszRCMod = */               "VBoxDDRC.rc",
     4201    /* .pszR0Mod = */               "VBoxDDR0.r0",
     4202    /* .pfnConstruct = */           acpiR3Construct,
     4203    /* .pfnDestruct = */            acpiR3Destruct,
     4204    /* .pfnRelocate = */            acpiR3Relocate,
     4205    /* .pfnMemSetup = */            acpiR3MemSetup,
     4206    /* .pfnPowerOn = */             NULL,
     4207    /* .pfnReset = */               acpiR3Reset,
     4208    /* .pfnSuspend = */             NULL,
     4209    /* .pfnResume = */              acpiR3Resume,
     4210    /* .pfnAttach = */              acpiR3Attach,
     4211    /* .pfnDetach = */              acpiR3Detach,
     4212    /* .pfnQueryInterface = */      NULL,
     4213    /* .pfnInitComplete = */        NULL,
     4214    /* .pfnPowerOff = */            NULL,
     4215    /* .pfnSoftReset = */           NULL,
     4216    /* .pfnReserved0 = */           NULL,
     4217    /* .pfnReserved1 = */           NULL,
     4218    /* .pfnReserved2 = */           NULL,
     4219    /* .pfnReserved3 = */           NULL,
     4220    /* .pfnReserved4 = */           NULL,
     4221    /* .pfnReserved5 = */           NULL,
     4222    /* .pfnReserved6 = */           NULL,
     4223    /* .pfnReserved7 = */           NULL,
     4224#elif defined(IN_RING0)
     4225    /* .pfnEarlyConstruct = */      NULL,
     4226    /* .pfnConstruct = */           NULL,
     4227    /* .pfnDestruct = */            NULL,
     4228    /* .pfnFinalDestruct = */       NULL,
     4229    /* .pfnRequest = */             NULL,
     4230    /* .pfnReserved0 = */           NULL,
     4231    /* .pfnReserved1 = */           NULL,
     4232    /* .pfnReserved2 = */           NULL,
     4233    /* .pfnReserved3 = */           NULL,
     4234    /* .pfnReserved4 = */           NULL,
     4235    /* .pfnReserved5 = */           NULL,
     4236    /* .pfnReserved6 = */           NULL,
     4237    /* .pfnReserved7 = */           NULL,
     4238#elif defined(IN_RC)
     4239    /* .pfnConstruct = */           NULL,
     4240    /* .pfnReserved0 = */           NULL,
     4241    /* .pfnReserved1 = */           NULL,
     4242    /* .pfnReserved2 = */           NULL,
     4243    /* .pfnReserved3 = */           NULL,
     4244    /* .pfnReserved4 = */           NULL,
     4245    /* .pfnReserved5 = */           NULL,
     4246    /* .pfnReserved6 = */           NULL,
     4247    /* .pfnReserved7 = */           NULL,
     4248#else
     4249# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     4250#endif
     4251    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    42334252};
    42344253
    4235 #endif /* IN_RING3 */
    42364254#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
  • trunk/src/VBox/Devices/PC/DevDMA.cpp

    r78572 r80531  
    11201120}
    11211121
     1122#endif /* IN_RING3 */
     1123
    11221124/**
    11231125 * The device registration structure.
     
    11251127const PDMDEVREG g_DeviceDMA =
    11261128{
    1127     /* u32Version */
    1128     PDM_DEVREG_VERSION,
    1129     /* szName */
    1130     "8237A",
    1131     /* szRCMod */
    1132     "VBoxDDRC.rc",
    1133     /* szR0Mod */
    1134     "VBoxDDR0.r0",
    1135     /* pszDescription */
    1136     "DMA Controller Device",
    1137     /* fFlags */
    1138     PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
    1139     /* fClass */
    1140     PDM_DEVREG_CLASS_DMA,
    1141     /* cMaxInstances */
    1142     1,
    1143     /* cbInstance */
    1144     sizeof(DMAState),
    1145     /* pfnConstruct */
    1146     dmaConstruct,
    1147     /* pfnDestruct */
    1148     NULL,
    1149     /* pfnRelocate */
    1150     NULL,
    1151     /* pfnMemSetup */
    1152     NULL,
    1153     /* pfnPowerOn */
    1154     NULL,
    1155     /* pfnReset */
    1156     dmaReset,
    1157     /* pfnSuspend */
    1158     NULL,
    1159     /* pfnResume */
    1160     NULL,
    1161     /* pfnAttach */
    1162     NULL,
    1163     /* pfnDetach */
    1164     NULL,
    1165     /* pfnQueryInterface. */
    1166     NULL,
    1167     /* pfnInitComplete */
    1168     NULL,
    1169     /* pfnPowerOff */
    1170     NULL,
    1171     /* pfnSoftReset */
    1172     NULL,
    1173     /* u32VersionEnd */
    1174     PDM_DEVREG_VERSION
     1129    /* .u32Version = */             PDM_DEVREG_VERSION,
     1130    /* .uReserved0 = */             0,
     1131    /* .szName = */                 "8237A",
     1132    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
     1133    /* .fClass = */                 PDM_DEVREG_CLASS_DMA,
     1134    /* .cMaxInstances = */          1,
     1135    /* .uSharedVersion = */         42,
     1136    /* .cbInstanceShared = */       sizeof(DMAState),
     1137    /* .cbInstanceCC = */           0,
     1138    /* .cbInstanceRC = */           0,
     1139    /* .uReserved1 = */             0,
     1140    /* .pszDescription = */         "DMA Controller Device",
     1141#if defined(IN_RING3)
     1142    /* .pszRCMod = */               "VBoxDDRC.rc",
     1143    /* .pszR0Mod = */               "VBoxDDR0.r0",
     1144    /* .pfnConstruct = */           dmaConstruct,
     1145    /* .pfnDestruct = */            NULL,
     1146    /* .pfnRelocate = */            NULL,
     1147    /* .pfnMemSetup = */            NULL,
     1148    /* .pfnPowerOn = */             NULL,
     1149    /* .pfnReset = */               dmaReset,
     1150    /* .pfnSuspend = */             NULL,
     1151    /* .pfnResume = */              NULL,
     1152    /* .pfnAttach = */              NULL,
     1153    /* .pfnDetach = */              NULL,
     1154    /* .pfnQueryInterface = */      NULL,
     1155    /* .pfnInitComplete = */        NULL,
     1156    /* .pfnPowerOff = */            NULL,
     1157    /* .pfnSoftReset = */           NULL,
     1158    /* .pfnReserved0 = */           NULL,
     1159    /* .pfnReserved1 = */           NULL,
     1160    /* .pfnReserved2 = */           NULL,
     1161    /* .pfnReserved3 = */           NULL,
     1162    /* .pfnReserved4 = */           NULL,
     1163    /* .pfnReserved5 = */           NULL,
     1164    /* .pfnReserved6 = */           NULL,
     1165    /* .pfnReserved7 = */           NULL,
     1166#elif defined(IN_RING0)
     1167    /* .pfnEarlyConstruct = */      NULL,
     1168    /* .pfnConstruct = */           NULL,
     1169    /* .pfnDestruct = */            NULL,
     1170    /* .pfnFinalDestruct = */       NULL,
     1171    /* .pfnRequest = */             NULL,
     1172    /* .pfnReserved0 = */           NULL,
     1173    /* .pfnReserved1 = */           NULL,
     1174    /* .pfnReserved2 = */           NULL,
     1175    /* .pfnReserved3 = */           NULL,
     1176    /* .pfnReserved4 = */           NULL,
     1177    /* .pfnReserved5 = */           NULL,
     1178    /* .pfnReserved6 = */           NULL,
     1179    /* .pfnReserved7 = */           NULL,
     1180#elif defined(IN_RC)
     1181    /* .pfnConstruct = */           NULL,
     1182    /* .pfnReserved0 = */           NULL,
     1183    /* .pfnReserved1 = */           NULL,
     1184    /* .pfnReserved2 = */           NULL,
     1185    /* .pfnReserved3 = */           NULL,
     1186    /* .pfnReserved4 = */           NULL,
     1187    /* .pfnReserved5 = */           NULL,
     1188    /* .pfnReserved6 = */           NULL,
     1189    /* .pfnReserved7 = */           NULL,
     1190#else
     1191# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     1192#endif
     1193    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    11751194};
    1176 #endif /* IN_RING3 */
     1195
    11771196#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    11781197
  • trunk/src/VBox/Devices/PC/DevHPET.cpp

    r79686 r80531  
    14721472}
    14731473
     1474#endif /* IN_RING3 */
    14741475
    14751476/**
     
    14781479const PDMDEVREG g_DeviceHPET =
    14791480{
    1480     /* u32Version */
    1481     PDM_DEVREG_VERSION,
    1482     /* szName */
    1483     "hpet",
    1484     /* szRCMod */
    1485     "VBoxDDRC.rc",
    1486     /* szR0Mod */
    1487     "VBoxDDR0.r0",
    1488     /* pszDescription */
    1489     " High Precision Event Timer (HPET) Device",
    1490     /* fFlags */
    1491     PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36
    1492     | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
    1493     /* fClass */
    1494     PDM_DEVREG_CLASS_PIT,
    1495     /* cMaxInstances */
    1496     1,
    1497     /* cbInstance */
    1498     sizeof(HPET),
    1499     /* pfnConstruct */
    1500     hpetR3Construct,
    1501     /* pfnDestruct */
    1502     NULL,
    1503     /* pfnRelocate */
    1504     hpetR3Relocate,
    1505     /* pfnMemSetup */
    1506     NULL,
    1507     /* pfnPowerOn */
    1508     NULL,
    1509     /* pfnReset */
    1510     hpetR3Reset,
    1511     /* pfnSuspend */
    1512     NULL,
    1513     /* pfnResume */
    1514     NULL,
    1515     /* pfnAttach */
    1516     NULL,
    1517     /* pfnDetach */
    1518     NULL,
    1519     /* pfnQueryInterface. */
    1520     NULL,
    1521     /* pfnInitComplete */
    1522     NULL,
    1523     /* pfnPowerOff */
    1524     NULL,
    1525     /* pfnSoftReset */
    1526     NULL,
    1527     /* u32VersionEnd */
    1528     PDM_DEVREG_VERSION
     1481    /* .u32Version = */             PDM_DEVREG_VERSION,
     1482    /* .uReserved0 = */             0,
     1483    /* .szName = */                 "hpet",
     1484    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
     1485    /* .fClass = */                 PDM_DEVREG_CLASS_PIT,
     1486    /* .cMaxInstances = */          1,
     1487    /* .uSharedVersion = */         42,
     1488    /* .cbInstanceShared = */       sizeof(HPET),
     1489    /* .cbInstanceCC = */           0,
     1490    /* .cbInstanceRC = */           0,
     1491    /* .uReserved1 = */             0,
     1492    /* .pszDescription = */         "High Precision Event Timer (HPET) Device",
     1493#if defined(IN_RING3)
     1494    /* .pszRCMod = */               "VBoxDDRC.rc",
     1495    /* .pszR0Mod = */               "VBoxDDR0.r0",
     1496    /* .pfnConstruct = */           hpetR3Construct,
     1497    /* .pfnDestruct = */            NULL,
     1498    /* .pfnRelocate = */            hpetR3Relocate,
     1499    /* .pfnMemSetup = */            NULL,
     1500    /* .pfnPowerOn = */             NULL,
     1501    /* .pfnReset = */               hpetR3Reset,
     1502    /* .pfnSuspend = */             NULL,
     1503    /* .pfnResume = */              NULL,
     1504    /* .pfnAttach = */              NULL,
     1505    /* .pfnDetach = */              NULL,
     1506    /* .pfnQueryInterface = */      NULL,
     1507    /* .pfnInitComplete = */        NULL,
     1508    /* .pfnPowerOff = */            NULL,
     1509    /* .pfnSoftReset = */           NULL,
     1510    /* .pfnReserved0 = */           NULL,
     1511    /* .pfnReserved1 = */           NULL,
     1512    /* .pfnReserved2 = */           NULL,
     1513    /* .pfnReserved3 = */           NULL,
     1514    /* .pfnReserved4 = */           NULL,
     1515    /* .pfnReserved5 = */           NULL,
     1516    /* .pfnReserved6 = */           NULL,
     1517    /* .pfnReserved7 = */           NULL,
     1518#elif defined(IN_RING0)
     1519    /* .pfnEarlyConstruct = */      NULL,
     1520    /* .pfnConstruct = */           NULL,
     1521    /* .pfnDestruct = */            NULL,
     1522    /* .pfnFinalDestruct = */       NULL,
     1523    /* .pfnRequest = */             NULL,
     1524    /* .pfnReserved0 = */           NULL,
     1525    /* .pfnReserved1 = */           NULL,
     1526    /* .pfnReserved2 = */           NULL,
     1527    /* .pfnReserved3 = */           NULL,
     1528    /* .pfnReserved4 = */           NULL,
     1529    /* .pfnReserved5 = */           NULL,
     1530    /* .pfnReserved6 = */           NULL,
     1531    /* .pfnReserved7 = */           NULL,
     1532#elif defined(IN_RC)
     1533    /* .pfnConstruct = */           NULL,
     1534    /* .pfnReserved0 = */           NULL,
     1535    /* .pfnReserved1 = */           NULL,
     1536    /* .pfnReserved2 = */           NULL,
     1537    /* .pfnReserved3 = */           NULL,
     1538    /* .pfnReserved4 = */           NULL,
     1539    /* .pfnReserved5 = */           NULL,
     1540    /* .pfnReserved6 = */           NULL,
     1541    /* .pfnReserved7 = */           NULL,
     1542#else
     1543# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     1544#endif
     1545    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    15291546};
    15301547
    1531 #endif /* IN_RING3 */
    15321548#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    15331549
  • trunk/src/VBox/Devices/PC/DevIoApic.cpp

    r76553 r80531  
    13671367}
    13681368
     1369#endif /* IN_RING3 */
    13691370
    13701371/**
     
    13731374const PDMDEVREG g_DeviceIOAPIC =
    13741375{
    1375     /* u32Version */
    1376     PDM_DEVREG_VERSION,
    1377     /* szName */
    1378     "ioapic",
    1379     /* szRCMod */
    1380     "VBoxDDRC.rc",
    1381     /* szR0Mod */
    1382     "VBoxDDR0.r0",
    1383     /* pszDescription */
    1384     "I/O Advanced Programmable Interrupt Controller (IO-APIC) Device",
    1385     /* fFlags */
    1386       PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36
    1387     | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
    1388     /* fClass */
    1389     PDM_DEVREG_CLASS_PIC,
    1390     /* cMaxInstances */
    1391     1,
    1392     /* cbInstance */
    1393     sizeof(IOAPIC),
    1394     /* pfnConstruct */
    1395     ioapicR3Construct,
    1396     /* pfnDestruct */
    1397     ioapicR3Destruct,
    1398     /* pfnRelocate */
    1399     ioapicR3Relocate,
    1400     /* pfnMemSetup */
    1401     NULL,
    1402     /* pfnPowerOn */
    1403     NULL,
    1404     /* pfnReset */
    1405     ioapicR3Reset,
    1406     /* pfnSuspend */
    1407     NULL,
    1408     /* pfnResume */
    1409     NULL,
    1410     /* pfnAttach */
    1411     NULL,
    1412     /* pfnDetach */
    1413     NULL,
    1414     /* pfnQueryInterface. */
    1415     NULL,
    1416     /* pfnInitComplete */
    1417     NULL,
    1418     /* pfnPowerOff */
    1419     NULL,
    1420     /* pfnSoftReset */
    1421     NULL,
    1422     /* u32VersionEnd */
    1423     PDM_DEVREG_VERSION
     1376    /* .u32Version = */             PDM_DEVREG_VERSION,
     1377    /* .uReserved0 = */             0,
     1378    /* .szName = */                 "ioapic",
     1379    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
     1380    /* .fClass = */                 PDM_DEVREG_CLASS_PIC,
     1381    /* .cMaxInstances = */          1,
     1382    /* .uSharedVersion = */         42,
     1383    /* .cbInstanceShared = */       sizeof(IOAPIC),
     1384    /* .cbInstanceCC = */           0,
     1385    /* .cbInstanceRC = */           0,
     1386    /* .uReserved1 = */             0,
     1387    /* .pszDescription = */         "I/O Advanced Programmable Interrupt Controller (IO-APIC) Device",
     1388#if defined(IN_RING3)
     1389    /* .pszRCMod = */               "VBoxDDRC.rc",
     1390    /* .pszR0Mod = */               "VBoxDDR0.r0",
     1391    /* .pfnConstruct = */           ioapicR3Construct,
     1392    /* .pfnDestruct = */            ioapicR3Destruct,
     1393    /* .pfnRelocate = */            ioapicR3Relocate,
     1394    /* .pfnMemSetup = */            NULL,
     1395    /* .pfnPowerOn = */             NULL,
     1396    /* .pfnReset = */               ioapicR3Reset,
     1397    /* .pfnSuspend = */             NULL,
     1398    /* .pfnResume = */              NULL,
     1399    /* .pfnAttach = */              NULL,
     1400    /* .pfnDetach = */              NULL,
     1401    /* .pfnQueryInterface = */      NULL,
     1402    /* .pfnInitComplete = */        NULL,
     1403    /* .pfnPowerOff = */            NULL,
     1404    /* .pfnSoftReset = */           NULL,
     1405    /* .pfnReserved0 = */           NULL,
     1406    /* .pfnReserved1 = */           NULL,
     1407    /* .pfnReserved2 = */           NULL,
     1408    /* .pfnReserved3 = */           NULL,
     1409    /* .pfnReserved4 = */           NULL,
     1410    /* .pfnReserved5 = */           NULL,
     1411    /* .pfnReserved6 = */           NULL,
     1412    /* .pfnReserved7 = */           NULL,
     1413#elif defined(IN_RING0)
     1414    /* .pfnEarlyConstruct = */      NULL,
     1415    /* .pfnConstruct = */           NULL,
     1416    /* .pfnDestruct = */            NULL,
     1417    /* .pfnFinalDestruct = */       NULL,
     1418    /* .pfnRequest = */             NULL,
     1419    /* .pfnReserved0 = */           NULL,
     1420    /* .pfnReserved1 = */           NULL,
     1421    /* .pfnReserved2 = */           NULL,
     1422    /* .pfnReserved3 = */           NULL,
     1423    /* .pfnReserved4 = */           NULL,
     1424    /* .pfnReserved5 = */           NULL,
     1425    /* .pfnReserved6 = */           NULL,
     1426    /* .pfnReserved7 = */           NULL,
     1427#elif defined(IN_RC)
     1428    /* .pfnConstruct = */           NULL,
     1429    /* .pfnReserved0 = */           NULL,
     1430    /* .pfnReserved1 = */           NULL,
     1431    /* .pfnReserved2 = */           NULL,
     1432    /* .pfnReserved3 = */           NULL,
     1433    /* .pfnReserved4 = */           NULL,
     1434    /* .pfnReserved5 = */           NULL,
     1435    /* .pfnReserved6 = */           NULL,
     1436    /* .pfnReserved7 = */           NULL,
     1437#else
     1438# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     1439#endif
     1440    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    14241441};
    14251442
    1426 #endif /* IN_RING3 */
    14271443
    14281444#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
  • trunk/src/VBox/Devices/PC/DevLpc-new.cpp

    r76553 r80531  
    382382}
    383383
     384#endif /* IN_RING3 */
    384385
    385386/**
     
    388389const PDMDEVREG g_DeviceLPC =
    389390{
    390     /* u32Version */
    391     PDM_DEVREG_VERSION,
    392     /* szName */
    393     "lpc",
    394     /* szRCMod */
    395     "",
    396     /* szR0Mod */
    397     "",
    398     /* pszDescription */
    399     "Low Pin Count (LPC) Bus",
    400     /* fFlags */
    401     PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36,
    402     /* fClass */
    403     PDM_DEVREG_CLASS_MISC,
    404     /* cMaxInstances */
    405     1,
    406     /* cbInstance */
    407     sizeof(LPCSTATE),
    408     /* pfnConstruct */
    409     lpcConstruct,
    410     /* pfnDestruct */
    411     NULL,
    412     /* pfnRelocate */
    413     NULL,
    414     /* pfnMemSetup */
    415     NULL,
    416     /* pfnPowerOn */
    417     NULL,
    418     /* pfnReset */
    419     NULL,
    420     /* pfnSuspend */
    421     NULL,
    422     /* pfnResume */
    423     NULL,
    424     /* pfnAttach */
    425     NULL,
    426     /* pfnDetach */
    427     NULL,
    428     /* pfnQueryInterface. */
    429     NULL,
    430     /* pfnInitComplete */
    431     NULL,
    432     /* pfnPowerOff */
    433     NULL,
    434     /* pfnSoftReset */
    435     NULL,
    436     /* u32VersionEnd */
    437     PDM_DEVREG_VERSION
     391    /* .u32Version = */             PDM_DEVREG_VERSION,
     392    /* .uReserved0 = */             0,
     393    /* .szName = */                 "lpc",
     394    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
     395    /* .fClass = */                 PDM_DEVREG_CLASS_MISC,
     396    /* .cMaxInstances = */          1,
     397    /* .uSharedVersion = */         42,
     398    /* .cbInstanceShared = */       sizeof(LPCSTATE),
     399    /* .cbInstanceCC = */           0,
     400    /* .cbInstanceRC = */           0,
     401    /* .uReserved1 = */             0,
     402    /* .pszDescription = */         "Low Pin Count (LPC) Bus",
     403#if defined(IN_RING3)
     404    /* .pszRCMod = */               "",
     405    /* .pszR0Mod = */               "",
     406    /* .pfnConstruct = */           lpcConstruct,
     407    /* .pfnDestruct = */            NULL,
     408    /* .pfnRelocate = */            NULL,
     409    /* .pfnMemSetup = */            NULL,
     410    /* .pfnPowerOn = */             NULL,
     411    /* .pfnReset = */               NULL,
     412    /* .pfnSuspend = */             NULL,
     413    /* .pfnResume = */              NULL,
     414    /* .pfnAttach = */              NULL,
     415    /* .pfnDetach = */              NULL,
     416    /* .pfnQueryInterface = */      NULL,
     417    /* .pfnInitComplete = */        NULL,
     418    /* .pfnPowerOff = */            NULL,
     419    /* .pfnSoftReset = */           NULL,
     420    /* .pfnReserved0 = */           NULL,
     421    /* .pfnReserved1 = */           NULL,
     422    /* .pfnReserved2 = */           NULL,
     423    /* .pfnReserved3 = */           NULL,
     424    /* .pfnReserved4 = */           NULL,
     425    /* .pfnReserved5 = */           NULL,
     426    /* .pfnReserved6 = */           NULL,
     427    /* .pfnReserved7 = */           NULL,
     428#elif defined(IN_RING0)
     429    /* .pfnEarlyConstruct = */      NULL,
     430    /* .pfnConstruct = */           NULL,
     431    /* .pfnDestruct = */            NULL,
     432    /* .pfnFinalDestruct = */       NULL,
     433    /* .pfnRequest = */             NULL,
     434    /* .pfnReserved0 = */           NULL,
     435    /* .pfnReserved1 = */           NULL,
     436    /* .pfnReserved2 = */           NULL,
     437    /* .pfnReserved3 = */           NULL,
     438    /* .pfnReserved4 = */           NULL,
     439    /* .pfnReserved5 = */           NULL,
     440    /* .pfnReserved6 = */           NULL,
     441    /* .pfnReserved7 = */           NULL,
     442#elif defined(IN_RC)
     443    /* .pfnConstruct = */           NULL,
     444    /* .pfnReserved0 = */           NULL,
     445    /* .pfnReserved1 = */           NULL,
     446    /* .pfnReserved2 = */           NULL,
     447    /* .pfnReserved3 = */           NULL,
     448    /* .pfnReserved4 = */           NULL,
     449    /* .pfnReserved5 = */           NULL,
     450    /* .pfnReserved6 = */           NULL,
     451    /* .pfnReserved7 = */           NULL,
     452#else
     453# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     454#endif
     455    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    438456};
    439457
    440 #endif /* IN_RING3 */
    441458#endif /* VBOX_DEVICE_STRUCT_TESTCASE */
    442459
  • trunk/src/VBox/Devices/PC/DevPIC.cpp

    r78599 r80531  
    10371037}
    10381038
     1039#endif /* IN_RING3 */
    10391040
    10401041/**
     
    10431044const PDMDEVREG g_DeviceI8259 =
    10441045{
    1045     /* u32Version */
    1046     PDM_DEVREG_VERSION,
    1047     /* szName */
    1048     "i8259",
    1049     /* szRCMod */
    1050     "VBoxDDRC.rc",
    1051     /* szR0Mod */
    1052     "VBoxDDR0.r0",
    1053     /* pszDescription */
    1054     "Intel 8259 Programmable Interrupt Controller (PIC) Device.",
    1055     /* fFlags */
    1056     PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
    1057     /* fClass */
    1058     PDM_DEVREG_CLASS_PIC,
    1059     /* cMaxInstances */
    1060     1,
    1061     /* cbInstance */
    1062     sizeof(DEVPIC),
    1063     /* pfnConstruct */
    1064     picConstruct,
    1065     /* pfnDestruct */
    1066     NULL,
    1067     /* pfnRelocate */
    1068     picRelocate,
    1069     /* pfnMemSetup */
    1070     NULL,
    1071     /* pfnPowerOn */
    1072     NULL,
    1073     /* pfnReset */
    1074     picReset,
    1075     /* pfnSuspend */
    1076     NULL,
    1077     /* pfnResume */
    1078     NULL,
    1079     /* pfnAttach */
    1080     NULL,
    1081     /* pfnDetach */
    1082     NULL,
    1083     /* pfnQueryInterface. */
    1084     NULL,
    1085     /* pfnInitComplete */
    1086     NULL,
    1087     /* pfnPowerOff */
    1088     NULL,
    1089     /* pfnSoftReset */
    1090     NULL,
    1091     /* u32VersionEnd */
    1092     PDM_DEVREG_VERSION
     1046    /* .u32Version = */             PDM_DEVREG_VERSION,
     1047    /* .uReserved0 = */             0,
     1048    /* .szName = */                 "i8259",
     1049    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
     1050    /* .fClass = */                 PDM_DEVREG_CLASS_PIC,
     1051    /* .cMaxInstances = */          1,
     1052    /* .uSharedVersion = */         42,
     1053    /* .cbInstanceShared = */       sizeof(DEVPIC),
     1054    /* .cbInstanceCC = */           0,
     1055    /* .cbInstanceRC = */           0,
     1056    /* .uReserved1 = */             0,
     1057    /* .pszDescription = */         "Intel 8259 Programmable Interrupt Controller (PIC) Device.",
     1058#if defined(IN_RING3)
     1059    /* .pszRCMod = */               "VBoxDDRC.rc",
     1060    /* .pszR0Mod = */               "VBoxDDR0.r0",
     1061    /* .pfnConstruct = */           picConstruct,
     1062    /* .pfnDestruct = */            NULL,
     1063    /* .pfnRelocate = */            picRelocate,
     1064    /* .pfnMemSetup = */            NULL,
     1065    /* .pfnPowerOn = */             NULL,
     1066    /* .pfnReset = */               picReset,
     1067    /* .pfnSuspend = */             NULL,
     1068    /* .pfnResume = */              NULL,
     1069    /* .pfnAttach = */              NULL,
     1070    /* .pfnDetach = */              NULL,
     1071    /* .pfnQueryInterface = */      NULL,
     1072    /* .pfnInitComplete = */        NULL,
     1073    /* .pfnPowerOff = */            NULL,
     1074    /* .pfnSoftReset = */           NULL,
     1075    /* .pfnReserved0 = */           NULL,
     1076    /* .pfnReserved1 = */           NULL,
     1077    /* .pfnReserved2 = */           NULL,
     1078    /* .pfnReserved3 = */           NULL,
     1079    /* .pfnReserved4 = */           NULL,
     1080    /* .pfnReserved5 = */           NULL,
     1081    /* .pfnReserved6 = */           NULL,
     1082    /* .pfnReserved7 = */           NULL,
     1083#elif defined(IN_RING0)
     1084    /* .pfnEarlyConstruct = */      NULL,
     1085    /* .pfnConstruct = */           NULL,
     1086    /* .pfnDestruct = */            NULL,
     1087    /* .pfnFinalDestruct = */       NULL,
     1088    /* .pfnRequest = */             NULL,
     1089    /* .pfnReserved0 = */           NULL,
     1090    /* .pfnReserved1 = */           NULL,
     1091    /* .pfnReserved2 = */           NULL,
     1092    /* .pfnReserved3 = */           NULL,
     1093    /* .pfnReserved4 = */           NULL,
     1094    /* .pfnReserved5 = */           NULL,
     1095    /* .pfnReserved6 = */           NULL,
     1096    /* .pfnReserved7 = */           NULL,
     1097#elif defined(IN_RC)
     1098    /* .pfnConstruct = */           NULL,
     1099    /* .pfnReserved0 = */           NULL,
     1100    /* .pfnReserved1 = */           NULL,
     1101    /* .pfnReserved2 = */           NULL,
     1102    /* .pfnReserved3 = */           NULL,
     1103    /* .pfnReserved4 = */           NULL,
     1104    /* .pfnReserved5 = */           NULL,
     1105    /* .pfnReserved6 = */           NULL,
     1106    /* .pfnReserved7 = */           NULL,
     1107#else
     1108# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     1109#endif
     1110    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    10931111};
    10941112
    1095 #endif /* IN_RING3 */
    10961113#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    10971114
  • trunk/src/VBox/Devices/PC/DevPcArch.cpp

    r76553 r80531  
    288288const PDMDEVREG g_DevicePcArch =
    289289{
    290     /* u32Version */
    291     PDM_DEVREG_VERSION,
    292     /* szName */
    293     "pcarch",
    294     /* szRCMod */
    295     "",
    296     /* szR0Mod */
    297     "",
    298     /* pszDescription */
    299     "PC Architecture Device",
    300     /* fFlags */
    301     PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
    302     /* fClass */
    303     PDM_DEVREG_CLASS_ARCH,
    304     /* cMaxInstances */
    305     1,
    306     /* cbInstance */
    307     sizeof(DEVPCARCH),
    308     /* pfnConstruct */
    309     pcarchConstruct,
    310     /* pfnDestruct */
    311     NULL,
    312     /* pfnRelocate */
    313     NULL,
    314     /* pfnMemSetup */
    315     NULL,
    316     /* pfnPowerOn */
    317     NULL,
    318     /* pfnReset */
    319     NULL,
    320     /* pfnSuspend */
    321     NULL,
    322     /* pfnResume */
    323     NULL,
    324     /* pfnAttach */
    325     NULL,
    326     /* pfnDetach */
    327     NULL,
    328     /* pfnQueryInterface. */
    329     NULL,
    330     /* pfnInitComplete. */
    331     pcarchInitComplete,
    332     /* pfnPowerOff */
    333     NULL,
    334     /* pfnSoftReset */
    335     NULL,
    336     /* u32VersionEnd */
    337     PDM_DEVREG_VERSION
     290    /* .u32Version = */             PDM_DEVREG_VERSION,
     291    /* .uReserved0 = */             0,
     292    /* .szName = */                 "pcarch",
     293    /* .fFlags = */                 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
     294    /* .fClass = */                 PDM_DEVREG_CLASS_ARCH,
     295    /* .cMaxInstances = */          1,
     296    /* .uSharedVersion = */         42,
     297    /* .cbInstanceShared = */       sizeof(DEVPCARCH),
     298    /* .cbInstanceCC = */           0,
     299    /* .cbInstanceRC = */           0,
     300    /* .uReserved1 = */             0,
     301    /* .pszDescription = */         "PC Architecture Device",
     302#if defined(IN_RING3)
     303    /* .pszRCMod = */               "",
     304    /* .pszR0Mod = */               "",
     305    /* .pfnConstruct = */           pcarchConstruct,
     306    /* .pfnDestruct = */            NULL,
     307    /* .pfnRelocate = */            NULL,
     308    /* .pfnMemSetup = */            NULL,
     309    /* .pfnPowerOn = */             NULL,
     310    /* .pfnReset = */               NULL,
     311    /* .pfnSuspend = */             NULL,
     312    /* .pfnResume = */              NULL,
     313    /* .pfnAttach = */              NULL,
     314    /* .pfnDetach = */              NULL,
     315    /* .pfnQueryInterface = */      NULL,
     316    /* .pfnInitComplete = */        pcarchInitComplete,
     317    /* .pfnPowerOff = */            NULL,
     318    /* .pfnSoftReset = */           NULL,
     319    /* .pfnReserved0 = */           NULL,
     320    /* .pfnReserved1 = */           NULL,
     321    /* .pfnReserved2 = */           NULL,
     322    /* .pfnReserved3 = */           NULL,
     323    /* .pfnReserved4 = */           NULL,
     324    /* .pfnReserved5 = */           NULL,
     325    /* .pfnReserved6 = */           NULL,
     326    /* .pfnReserved7 = */           NULL,
     327#elif defined(IN_RING0)
     328    /* .pfnEarlyConstruct = */      NULL,
     329    /* .pfnConstruct = */           NULL,
     330    /* .pfnDestruct = */            NULL,
     331    /* .pfnFinalDestruct = */       NULL,
     332    /* .pfnRequest = */             NULL,
     333    /* .pfnReserved0 = */           NULL,
     334    /* .pfnReserved1 = */           NULL,
     335    /* .pfnReserved2 = */           NULL,
     336    /* .pfnReserved3 = */           NULL,
     337    /* .pfnReserved4 = */           NULL,
     338    /* .pfnReserved5 = */           NULL,
     339    /* .pfnReserved6 = */           NULL,
     340    /* .pfnReserved7 = */           NULL,
     341#elif defined(IN_RC)
     342    /* .pfnConstruct = */           NULL,
     343    /* .pfnReserved0 = */           NULL,
     344    /* .pfnReserved1 = */           NULL,
     345    /* .pfnReserved2 = */           NULL,
     346    /* .pfnReserved3 = */           NULL,
     347    /* .pfnReserved4 = */           NULL,
     348    /* .pfnReserved5 = */           NULL,
     349    /* .pfnReserved6 = */           NULL,
     350    /* .pfnReserved7 = */           NULL,
     351#else
     352# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     353#endif
     354    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    338355};
    339356
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r80293 r80531  
    18001800const PDMDEVREG g_DevicePcBios =
    18011801{
    1802     /* u32Version */
    1803     PDM_DEVREG_VERSION,
    1804     /* szName */
    1805     "pcbios",
    1806     /* szRCMod */
    1807     "",
    1808     /* szR0Mod */
    1809     "",
    1810     /* pszDescription */
    1811     "PC BIOS Device",
    1812     /* fFlags */
    1813     PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64,
    1814     /* fClass */
    1815     PDM_DEVREG_CLASS_ARCH_BIOS,
    1816     /* cMaxInstances */
    1817     1,
    1818     /* cbInstance */
    1819     sizeof(DEVPCBIOS),
    1820     /* pfnConstruct */
    1821     pcbiosConstruct,
    1822     /* pfnDestruct */
    1823     pcbiosDestruct,
    1824     /* pfnRelocate */
    1825     NULL,
    1826     /* pfnMemSetup */
    1827     pcbiosMemSetup,
    1828     /* pfnPowerOn */
    1829     NULL,
    1830     /* pfnReset */
    1831     pcbiosReset,
    1832     /* pfnSuspend */
    1833     NULL,
    1834     /* pfnResume */
    1835     NULL,
    1836     /* pfnAttach */
    1837     NULL,
    1838     /* pfnDetach */
    1839     NULL,
    1840     /* pfnQueryInterface. */
    1841     NULL,
    1842     /* pfnInitComplete. */
    1843     pcbiosInitComplete,
    1844     /* pfnPowerOff */
    1845     NULL,
    1846     /* pfnSoftReset */
    1847     NULL,
    1848     /* u32VersionEnd */
    1849     PDM_DEVREG_VERSION
     1802    /* .u32Version = */             PDM_DEVREG_VERSION,
     1803    /* .uReserved0 = */             0,
     1804    /* .szName = */                 "pcbios",
     1805    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
     1806    /* .fClass = */                 PDM_DEVREG_CLASS_ARCH_BIOS,
     1807    /* .cMaxInstances = */          1,
     1808    /* .uSharedVersion = */         42,
     1809    /* .cbInstanceShared = */       sizeof(DEVPCBIOS),
     1810    /* .cbInstanceCC = */           0,
     1811    /* .cbInstanceRC = */           0,
     1812    /* .uReserved1 = */             0,
     1813    /* .pszDescription = */         "PC BIOS Device",
     1814#if defined(IN_RING3)
     1815    /* .pszRCMod = */               "",
     1816    /* .pszR0Mod = */               "",
     1817    /* .pfnConstruct = */           pcbiosConstruct,
     1818    /* .pfnDestruct = */            pcbiosDestruct,
     1819    /* .pfnRelocate = */            NULL,
     1820    /* .pfnMemSetup = */            pcbiosMemSetup,
     1821    /* .pfnPowerOn = */             NULL,
     1822    /* .pfnReset = */               pcbiosReset,
     1823    /* .pfnSuspend = */             NULL,
     1824    /* .pfnResume = */              NULL,
     1825    /* .pfnAttach = */              NULL,
     1826    /* .pfnDetach = */              NULL,
     1827    /* .pfnQueryInterface = */      NULL,
     1828    /* .pfnInitComplete = */        pcbiosInitComplete,
     1829    /* .pfnPowerOff = */            NULL,
     1830    /* .pfnSoftReset = */           NULL,
     1831    /* .pfnReserved0 = */           NULL,
     1832    /* .pfnReserved1 = */           NULL,
     1833    /* .pfnReserved2 = */           NULL,
     1834    /* .pfnReserved3 = */           NULL,
     1835    /* .pfnReserved4 = */           NULL,
     1836    /* .pfnReserved5 = */           NULL,
     1837    /* .pfnReserved6 = */           NULL,
     1838    /* .pfnReserved7 = */           NULL,
     1839#elif defined(IN_RING0)
     1840    /* .pfnEarlyConstruct = */      NULL,
     1841    /* .pfnConstruct = */           NULL,
     1842    /* .pfnDestruct = */            NULL,
     1843    /* .pfnFinalDestruct = */       NULL,
     1844    /* .pfnRequest = */             NULL,
     1845    /* .pfnReserved0 = */           NULL,
     1846    /* .pfnReserved1 = */           NULL,
     1847    /* .pfnReserved2 = */           NULL,
     1848    /* .pfnReserved3 = */           NULL,
     1849    /* .pfnReserved4 = */           NULL,
     1850    /* .pfnReserved5 = */           NULL,
     1851    /* .pfnReserved6 = */           NULL,
     1852    /* .pfnReserved7 = */           NULL,
     1853#elif defined(IN_RC)
     1854    /* .pfnConstruct = */           NULL,
     1855    /* .pfnReserved0 = */           NULL,
     1856    /* .pfnReserved1 = */           NULL,
     1857    /* .pfnReserved2 = */           NULL,
     1858    /* .pfnReserved3 = */           NULL,
     1859    /* .pfnReserved4 = */           NULL,
     1860    /* .pfnReserved5 = */           NULL,
     1861    /* .pfnReserved6 = */           NULL,
     1862    /* .pfnReserved7 = */           NULL,
     1863#else
     1864# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     1865#endif
     1866    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    18501867};
    18511868
  • trunk/src/VBox/Devices/PC/DevPit-i8254.cpp

    r76553 r80531  
    15221522}
    15231523
     1524#endif /* IN_RING3 */
    15241525
    15251526/**
     
    15281529const PDMDEVREG g_DeviceI8254 =
    15291530{
    1530     /* u32Version */
    1531     PDM_DEVREG_VERSION,
    1532     /* szName */
    1533     "i8254",
    1534     /* szRCMod */
    1535     "VBoxDDRC.rc",
    1536     /* szR0Mod */
    1537     "VBoxDDR0.r0",
    1538     /* pszDescription */
    1539     "Intel 8254 Programmable Interval Timer (PIT) And Dummy Speaker Device",
    1540     /* fFlags */
    1541     PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
    1542     /* fClass */
    1543     PDM_DEVREG_CLASS_PIT,
    1544     /* cMaxInstances */
    1545     1,
    1546     /* cbInstance */
    1547     sizeof(PITSTATE),
    1548     /* pfnConstruct */
    1549     pitConstruct,
    1550     /* pfnDestruct */
    1551     NULL,
    1552     /* pfnRelocate */
    1553     pitRelocate,
    1554     /* pfnMemSetup */
    1555     NULL,
    1556     /* pfnPowerOn */
    1557     NULL,
    1558     /* pfnReset */
    1559     pitReset,
    1560     /* pfnSuspend */
    1561     NULL,
    1562     /* pfnResume */
    1563     NULL,
    1564     /* pfnAttach */
    1565     NULL,
    1566     /* pfnDetach */
    1567     NULL,
    1568     /* pfnQueryInterface */
    1569     NULL,
    1570     /* pfnInitComplete */
    1571     NULL,
    1572     /* pfnPowerOff */
    1573     NULL,
    1574     /* pfnSoftReset */
    1575     NULL,
    1576     /* u32VersionEnd */
    1577     PDM_DEVREG_VERSION
     1531    /* .u32Version = */             PDM_DEVREG_VERSION,
     1532    /* .uReserved0 = */             0,
     1533    /* .szName = */                 "i8254",
     1534    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
     1535    /* .fClass = */                 PDM_DEVREG_CLASS_PIT,
     1536    /* .cMaxInstances = */          1,
     1537    /* .uSharedVersion = */         42,
     1538    /* .cbInstanceShared = */       sizeof(PITSTATE),
     1539    /* .cbInstanceCC = */           0,
     1540    /* .cbInstanceRC = */           0,
     1541    /* .uReserved1 = */             0,
     1542    /* .pszDescription = */         "Intel 8254 Programmable Interval Timer (PIT) And Dummy Speaker Device",
     1543#if defined(IN_RING3)
     1544    /* .pszRCMod = */               "VBoxDDRC.rc",
     1545    /* .pszR0Mod = */               "VBoxDDR0.r0",
     1546    /* .pfnConstruct = */           pitConstruct,
     1547    /* .pfnDestruct = */            NULL,
     1548    /* .pfnRelocate = */            pitRelocate,
     1549    /* .pfnMemSetup = */            NULL,
     1550    /* .pfnPowerOn = */             NULL,
     1551    /* .pfnReset = */               pitReset,
     1552    /* .pfnSuspend = */             NULL,
     1553    /* .pfnResume = */              NULL,
     1554    /* .pfnAttach = */              NULL,
     1555    /* .pfnDetach = */              NULL,
     1556    /* .pfnQueryInterface = */      NULL,
     1557    /* .pfnInitComplete = */        NULL,
     1558    /* .pfnPowerOff = */            NULL,
     1559    /* .pfnSoftReset = */           NULL,
     1560    /* .pfnReserved0 = */           NULL,
     1561    /* .pfnReserved1 = */           NULL,
     1562    /* .pfnReserved2 = */           NULL,
     1563    /* .pfnReserved3 = */           NULL,
     1564    /* .pfnReserved4 = */           NULL,
     1565    /* .pfnReserved5 = */           NULL,
     1566    /* .pfnReserved6 = */           NULL,
     1567    /* .pfnReserved7 = */           NULL,
     1568#elif defined(IN_RING0)
     1569    /* .pfnEarlyConstruct = */      NULL,
     1570    /* .pfnConstruct = */           NULL,
     1571    /* .pfnDestruct = */            NULL,
     1572    /* .pfnFinalDestruct = */       NULL,
     1573    /* .pfnRequest = */             NULL,
     1574    /* .pfnReserved0 = */           NULL,
     1575    /* .pfnReserved1 = */           NULL,
     1576    /* .pfnReserved2 = */           NULL,
     1577    /* .pfnReserved3 = */           NULL,
     1578    /* .pfnReserved4 = */           NULL,
     1579    /* .pfnReserved5 = */           NULL,
     1580    /* .pfnReserved6 = */           NULL,
     1581    /* .pfnReserved7 = */           NULL,
     1582#elif defined(IN_RC)
     1583    /* .pfnConstruct = */           NULL,
     1584    /* .pfnReserved0 = */           NULL,
     1585    /* .pfnReserved1 = */           NULL,
     1586    /* .pfnReserved2 = */           NULL,
     1587    /* .pfnReserved3 = */           NULL,
     1588    /* .pfnReserved4 = */           NULL,
     1589    /* .pfnReserved5 = */           NULL,
     1590    /* .pfnReserved6 = */           NULL,
     1591    /* .pfnReserved7 = */           NULL,
     1592#else
     1593# error "Not in IN_RING3, IN_RING0 or IN_RC!"
     1594#endif
     1595    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    15781596};
    15791597
    1580 #endif /* IN_RING3 */
    15811598#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
  • trunk/src/VBox/Devices/PC/DevRTC.cpp

    r76553 r80531  
    129129};
    130130
     131#if 0 /* new / old style device selector */
    131132
    132133typedef struct RTCSTATE
     
    137138    struct my_tm current_tm;
    138139    /** The configured IRQ. */
    139     int32_t irq;
     140    int32_t                 irq;
    140141    /** The configured I/O port base. */
    141     RTIOPORT IOPortBase;
     142    RTIOPORT                IOPortBase;
    142143    /** Use UTC or local time initially. */
    143     bool fUTC;
     144    bool                    fUTC;
    144145    /** Disabled by HPET legacy mode. */
    145     bool fDisabledByHpet;
     146    bool                    fDisabledByHpet;
    146147    /* periodic timer */
    147148    int64_t next_periodic_time;
     
    149150    int64_t next_second_time;
    150151
    151     /** Pointer to the device instance - R3 Ptr. */
    152     PPDMDEVINSR3 pDevInsR3;
    153     /** The periodic timer (rtcTimerPeriodic) - R3 Ptr. */
    154     PTMTIMERR3 pPeriodicTimerR3;
    155     /** The second timer (rtcTimerSecond) - R3 Ptr. */
    156     PTMTIMERR3 pSecondTimerR3;
    157     /** The second second timer (rtcTimerSecond2) - R3 Ptr. */
    158     PTMTIMERR3 pSecondTimer2R3;
    159 
    160     /** Pointer to the device instance - R0 Ptr. */
    161     PPDMDEVINSR0 pDevInsR0;
    162     /** The periodic timer (rtcTimerPeriodic) - R0 Ptr. */
    163     PTMTIMERR0 pPeriodicTimerR0;
    164     /** The second timer (rtcTimerSecond) - R0 Ptr. */
    165     PTMTIMERR0 pSecondTimerR0;
    166     /** The second second timer (rtcTimerSecond2) - R0 Ptr. */
    167     PTMTIMERR0 pSecondTimer2R0;
    168 
    169     /** Pointer to the device instance - RC Ptr. */
    170     PPDMDEVINSRC pDevInsRC;
    171     /** The periodic timer (rtcTimerPeriodic) - RC Ptr. */
    172     PTMTIMERRC pPeriodicTimerRC;
    173     /** The second timer (rtcTimerSecond) - RC Ptr. */
    174     PTMTIMERRC pSecondTimerRC;
    175     /** The second second timer (rtcTimerSecond2) - RC Ptr. */
    176     PTMTIMERRC pSecondTimer2RC;
    177 
    178     /** The RTC registration structure. */
    179     PDMRTCREG RtcReg;
    180     /** The RTC device helpers. */
    181     R3PTRTYPE(PCPDMRTCHLP) pRtcHlpR3;
     152    /** The periodic timer (rtcTimerPeriodic). */
     153    TMTIMERHANDLE           hPeriodicTimer;
     154    /** The second timer (rtcTimerSecond). */
     155    TMTIMERHANDLE           hSecondTimer;
     156    /** The second second timer (rtcTimerSecond2). */
     157    TMTIMERHANDLE           hSecondTimer2;
     158    /** The I/O port range handle. */
     159    IOMIOPORTHANDLE         hIoPorts;
     160
    182161    /** Number of release log entries. Used to prevent flooding. */
    183     uint32_t cRelLogEntries;
     162    uint32_t                cRelLogEntries;
    184163    /** The current/previous logged timer period. */
    185     int32_t CurLogPeriod;
     164    int32_t                 CurLogPeriod;
    186165    /** The current/previous hinted timer period. */
    187     int32_t CurHintPeriod;
     166    int32_t                 CurHintPeriod;
    188167    /** How many consecutive times the UIP has been seen. */
    189     int32_t cUipSeen;
    190 
    191     /** HPET legacy mode notification interface. */
    192     PDMIHPETLEGACYNOTIFY  IHpetLegacyNotify;
     168    int32_t                 cUipSeen;
    193169
    194170    /** Number of IRQs that's been raised. */
     
    200176typedef RTCSTATE *PRTCSTATE;
    201177
     178
     179/**
     180 * RTC ring-3 instance data.
     181 */
     182typedef struct RTCSTATER3
     183{
     184    /** Pointer to the device instance. */
     185    PPDMDEVINSR3            pDevInsR3;
     186
     187    /** The RTC registration structure. */
     188    PDMRTCREG               RtcReg;
     189    /** The RTC device helpers. */
     190    R3PTRTYPE(PCPDMRTCHLP)  pRtcHlpR3;
     191
     192    /** Pointer to the shared state (for the IHpetLegacyNotify callback). */
     193    PRTCSTATE               pShared;
     194    /** HPET legacy mode notification interface. */
     195    PDMIHPETLEGACYNOTIFY    IHpetLegacyNotify;
     196} RTCSTATER3;
     197/** Pointer to the ring-3 RTC device instance data. */
     198typedef RTCSTATER3 *PRTCSTATER3;
     199
     200
     201/**
     202 * RTC ring-0 instance data.
     203 * @note Not needed, but serves as example for testing the new model.
     204 */
     205typedef struct RTCSTATER0
     206{
     207    /** Pointer to the device instance. */
     208    PPDMDEVINSR0            pDevInsR0;
     209} RTCSTATER0;
     210/** Pointer to the ring-0 RTC device instance data. */
     211typedef RTCSTATER0 *PRTCSTATER0;
     212
     213
     214/**
     215 * RTC raw-mode instance data.
     216 * @note Not needed, but serves as example for testing the new model.
     217 */
     218typedef struct RTCSTATERC
     219{
     220    /** Pointer to the device instance. */
     221    PPDMDEVINSRC            pDevInsRC;
     222} RTCSTATERC;
     223/** Pointer to the raw-mode RTC device instance data. */
     224typedef RTCSTATERC *PRTCSTATERC;
     225
     226
     227/** @def PRTCSTATECC
     228 * Pointer to the instance data for the current context. */
     229#ifdef IN_RING3
     230typedef  RTCSTATER3  RTCSTATECC;
     231typedef PRTCSTATER3 PRTCSTATECC;
     232#elif defined(IN_RING0)
     233typedef  RTCSTATER0  RTCSTATECC;
     234typedef PRTCSTATER0 PRTCSTATECC;
     235#elif defined(IN_RING0)
     236typedef  RTCSTATERC  RTCSTATECC;
     237typedef PRTCSTATERC PRTCSTATECC;
     238# error "Not IN_RING3, IN_RING0 or IN_RC"
     239#endif
     240
     241
    202242#ifndef VBOX_DEVICE_STRUCT_TESTCASE
    203243
    204 static void rtc_timer_update(PRTCSTATE pThis, int64_t current_time)
     244static void rtc_timer_update(PPDMDEVINS pDevIns, PRTCSTATE pThis, int64_t current_time)
    205245{
    206246    int period_code, period;
     
    208248    uint32_t freq;
    209249
    210     Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
    211     Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
     250    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
     251    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
    212252
    213253    period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
     
    220260        period = 1 << (period_code - 1);
    221261        /* compute 32 kHz clock */
    222         freq = TMTimerGetFreq(pThis->CTX_SUFF(pPeriodicTimer));
     262        freq = PDMDevHlpTimerGetFreq(pDevIns, pThis->hPeriodicTimer);
    223263
    224264        cur_clock = ASMMultU64ByU32DivByU32(current_time, 32768, freq);
    225265        next_irq_clock = (cur_clock & ~(uint64_t)(period - 1)) + period;
    226266        pThis->next_periodic_time = ASMMultU64ByU32DivByU32(next_irq_clock, freq, 32768) + 1;
    227         TMTimerSet(pThis->CTX_SUFF(pPeriodicTimer), pThis->next_periodic_time);
     267        PDMDevHlpTimerSet(pDevIns, pThis->hPeriodicTimer, pThis->next_periodic_time);
    228268
    229269#ifdef IN_RING3
     
    239279#endif
    240280            pThis->CurHintPeriod = period;
    241             TMTimerSetFrequencyHint(pThis->CTX_SUFF(pPeriodicTimer), _32K / period);
     281            PDMDevHlpTimerSetFrequencyHint(pDevIns, pThis->hPeriodicTimer, _32K / period);
    242282        }
    243283    }
     
    245285    {
    246286#ifdef IN_RING3
    247         if (TMTimerIsActive(pThis->CTX_SUFF(pPeriodicTimer)) && pThis->cRelLogEntries++ < 64)
     287        if (PDMDevHlpTimerIsActive(pDevIns, pThis->hPeriodicTimer) && pThis->cRelLogEntries++ < 64)
    248288            LogRel(("RTC: Stopped the periodic timer\n"));
    249289#endif
    250         TMTimerStop(pThis->CTX_SUFF(pPeriodicTimer));
    251     }
    252 }
    253 
    254 
    255 static void rtc_raise_irq(PRTCSTATE pThis, uint32_t iLevel)
     290        PDMDevHlpTimerStop(pDevIns, pThis->hPeriodicTimer);
     291    }
     292    RT_NOREF(pDevIns);
     293}
     294
     295
     296static void rtc_raise_irq(PPDMDEVINS pDevIns, PRTCSTATE pThis, uint32_t iLevel)
    256297{
    257298    if (!pThis->fDisabledByHpet)
    258299    {
    259         PDMDevHlpISASetIrq(pThis->CTX_SUFF(pDevIns), pThis->irq, iLevel);
     300        PDMDevHlpISASetIrq(pDevIns, pThis->irq, iLevel);
    260301        if (iLevel)
    261302            STAM_COUNTER_INC(&pThis->StatRTCIrq);
     
    347388            case RTC_REG_C:
    348389                *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
    349                 rtc_raise_irq(pThis, 0);
     390                rtc_raise_irq(pDevIns, pThis, 0);
    350391                pThis->cmos_data[RTC_REG_C] = 0x00;
    351392                break;
     
    382423           a timely fashion. */
    383424        if (u32 == RTC_REG_A)
    384             TMTimerGet(pThis->CTX_SUFF(pSecondTimer));
     425            PDMDevHlpTimerGet(pDevIns, pThis->hSecondTimer);
    385426    }
    386427    else
     
    418459                   we're letting IOM do the locking, we must not return without
    419460                   holding the device lock.*/
    420                 PDMCritSectLeave(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo));
    421                 int rc1 = TMTimerLock(pThis->CTX_SUFF(pPeriodicTimer), VINF_SUCCESS /* must get it */);
    422                 int rc2 = PDMCritSectEnter(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
     461                PDMDevHlpCritSectLeave(pDevIns, pDevIns->CTX_SUFF(pCritSectRo));
     462                int rc1 = PDMDevHlpTimerLock(pDevIns, pThis->hPeriodicTimer, VINF_SUCCESS /* must get it */);
     463                int rc2 = PDMDevHlpCritSectEnter(pDevIns, pDevIns->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
    423464                AssertRCReturn(rc1, rc1);
    424                 AssertRCReturnStmt(rc2, TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer)), rc2);
     465                AssertRCReturnStmt(rc2, PDMDevHlpTimerUnlock(pDevIns, pThis->hPeriodicTimer), rc2);
    425466
    426467                if (idx == RTC_REG_A)
     
    449490                }
    450491
    451                 rtc_timer_update(pThis, TMTimerGet(pThis->CTX_SUFF(pPeriodicTimer)));
    452 
    453                 TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer));
     492                rtc_timer_update(pDevIns, pThis, PDMDevHlpTimerGet(pDevIns, pThis->hPeriodicTimer));
     493
     494                PDMDevHlpTimerUnlock(pDevIns, pThis->hPeriodicTimer);
    454495                /* the caller leaves the other lock. */
    455496                break;
     
    558599    RT_NOREF2(pTimer, pvUser);
    559600    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
    560     Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
    561     Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
    562 
    563     rtc_timer_update(pThis, pThis->next_periodic_time);
     601    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hPeriodicTimer));
     602    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
     603    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
     604
     605    rtc_timer_update(pDevIns, pThis, pThis->next_periodic_time);
    564606    STAM_COUNTER_INC(&pThis->StatRTCTimerCB);
    565607    pThis->cmos_data[RTC_REG_C] |= 0xc0;
    566608
    567     rtc_raise_irq(pThis, 1);
     609    rtc_raise_irq(pDevIns, pThis, 1);
    568610}
    569611
     
    638680static DECLCALLBACK(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    639681{
     682    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     683
     684    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
     685    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
     686    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hSecondTimer));
     687    RT_NOREF(pvUser);
     688
     689    /* if the oscillator is not in normal operation, we do not update */
     690    if ((pThis->cmos_data[RTC_REG_A] & 0x70) != 0x20)
     691    {
     692        pThis->next_second_time += PDMDevHlpTimerGetFreq(pDevIns, pThis->hSecondTimer);
     693        PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer, pThis->next_second_time);
     694    }
     695    else
     696    {
     697        rtc_next_second(&pThis->current_tm);
     698
     699        if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
     700        {
     701            /* update in progress bit */
     702            Log2(("RTC: UIP %x -> 1\n", !!(pThis->cmos_data[RTC_REG_A] & REG_A_UIP)));
     703            pThis->cmos_data[RTC_REG_A] |= REG_A_UIP;
     704        }
     705
     706        /* 244140 ns = 8 / 32768 seconds */
     707        uint64_t delay = PDMDevHlpTimerFromNano(pDevIns, pThis->hSecondTimer2, 244140);
     708        PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer2, pThis->next_second_time + delay);
     709    }
     710}
     711
     712
     713/* Used by rtc_set_date and rtcTimerSecond2. */
     714static void rtc_copy_date(PRTCSTATE pThis)
     715{
     716    const struct my_tm *tm = &pThis->current_tm;
     717
     718    pThis->cmos_data[RTC_SECONDS] = to_bcd(pThis, tm->tm_sec);
     719    pThis->cmos_data[RTC_MINUTES] = to_bcd(pThis, tm->tm_min);
     720    if (pThis->cmos_data[RTC_REG_B] & 0x02)
     721    {
     722        /* 24 hour format */
     723        pThis->cmos_data[RTC_HOURS] = to_bcd(pThis, tm->tm_hour);
     724    }
     725    else
     726    {
     727        /* 12 hour format */
     728        int h = tm->tm_hour % 12;
     729        pThis->cmos_data[RTC_HOURS] = to_bcd(pThis, h ? h : 12);
     730        if (tm->tm_hour >= 12)
     731            pThis->cmos_data[RTC_HOURS] |= 0x80;
     732    }
     733    pThis->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(pThis, tm->tm_wday);
     734    pThis->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(pThis, tm->tm_mday);
     735    pThis->cmos_data[RTC_MONTH] = to_bcd(pThis, tm->tm_mon + 1);
     736    pThis->cmos_data[RTC_YEAR] = to_bcd(pThis, tm->tm_year % 100);
     737}
     738
     739
     740/**
     741 * @callback_method_impl{FNTMTIMERDEV, Second2 timer.}
     742 */
     743static DECLCALLBACK(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     744{
     745    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     746
     747    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
     748    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
     749    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hSecondTimer2));
     750    RT_NOREF2(pTimer, pvUser);
     751
     752    if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
     753        rtc_copy_date(pThis);
     754
     755    /* check alarm */
     756    if (pThis->cmos_data[RTC_REG_B] & REG_B_AIE)
     757    {
     758        if (   (   (pThis->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0
     759                || from_bcd(pThis, pThis->cmos_data[RTC_SECONDS_ALARM]) == pThis->current_tm.tm_sec)
     760            && (   (pThis->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0
     761                || from_bcd(pThis, pThis->cmos_data[RTC_MINUTES_ALARM]) == pThis->current_tm.tm_min)
     762            && (   (pThis->cmos_data[RTC_HOURS_ALARM  ] & 0xc0) == 0xc0
     763                || from_bcd(pThis, pThis->cmos_data[RTC_HOURS_ALARM  ]) == pThis->current_tm.tm_hour)
     764            )
     765        {
     766            pThis->cmos_data[RTC_REG_C] |= 0xa0;
     767            rtc_raise_irq(pDevIns, pThis, 1);
     768        }
     769    }
     770
     771    /* update ended interrupt */
     772    if (pThis->cmos_data[RTC_REG_B] & REG_B_UIE)
     773    {
     774        pThis->cmos_data[RTC_REG_C] |= 0x90;
     775        rtc_raise_irq(pDevIns, pThis, 1);
     776    }
     777
     778    /* clear update in progress bit */
     779    Log2(("RTC: UIP %x -> 0\n", !!(pThis->cmos_data[RTC_REG_A] & REG_A_UIP)));
     780    pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
     781
     782    pThis->next_second_time += PDMDevHlpTimerGetFreq(pDevIns, pThis->hSecondTimer);
     783    PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer, pThis->next_second_time);
     784}
     785
     786
     787/* -=-=-=-=-=- Saved State -=-=-=-=-=- */
     788
     789
     790/**
     791 * @callback_method_impl{FNSSMDEVLIVEEXEC}
     792 */
     793static DECLCALLBACK(int) rtcLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
     794{
     795    RT_NOREF1(uPass);
     796    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     797    PRTCSTATE     pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     798
     799    pHlp->pfnSSMPutU8(    pSSM, pThis->irq);
     800    pHlp->pfnSSMPutIOPort(pSSM, pThis->IOPortBase);
     801    pHlp->pfnSSMPutBool(  pSSM, pThis->fUTC);
     802
     803    return VINF_SSM_DONT_CALL_AGAIN;
     804}
     805
     806
     807/**
     808 * @callback_method_impl{FNSSMDEVSAVEEXEC}
     809 */
     810static DECLCALLBACK(int) rtcSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     811{
     812    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     813    PRTCSTATE     pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     814
     815    /* The config. */
     816    rtcLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
     817
     818    /* The state. */
     819    pHlp->pfnSSMPutMem(pSSM, pThis->cmos_data, CMOS_BANK_SIZE);
     820    pHlp->pfnSSMPutU8(pSSM, pThis->cmos_index[0]);
     821
     822    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_sec);
     823    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_min);
     824    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_hour);
     825    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_wday);
     826    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_mday);
     827    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_mon);
     828    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_year);
     829
     830    PDMDevHlpTimerSave(pDevIns, pThis->hPeriodicTimer, pSSM);
     831
     832    pHlp->pfnSSMPutS64(pSSM, pThis->next_periodic_time);
     833
     834    pHlp->pfnSSMPutS64(pSSM, pThis->next_second_time);
     835    PDMDevHlpTimerSave(pDevIns, pThis->hSecondTimer, pSSM);
     836    PDMDevHlpTimerSave(pDevIns, pThis->hSecondTimer2, pSSM);
     837
     838    pHlp->pfnSSMPutBool(pSSM, pThis->fDisabledByHpet);
     839
     840    pHlp->pfnSSMPutMem(pSSM, &pThis->cmos_data[CMOS_BANK_SIZE], CMOS_BANK_SIZE);
     841    return pHlp->pfnSSMPutU8(pSSM, pThis->cmos_index[1]);
     842}
     843
     844
     845/**
     846 * @callback_method_impl{FNSSMDEVLOADEXEC}
     847 */
     848static DECLCALLBACK(int) rtcLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     849{
     850    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     851    PRTCSTATE     pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     852    int           rc;
     853
     854    if (    uVersion != RTC_SAVED_STATE_VERSION
     855        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_32PRE
     856        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_31
     857        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_30)
     858        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     859
     860    /* The config. */
     861    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_30)
     862    {
     863        uint8_t u8Irq;
     864        rc = pHlp->pfnSSMGetU8(pSSM, &u8Irq);
     865        AssertRCReturn(rc, rc);
     866        if (u8Irq != pThis->irq)
     867            return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - u8Irq: saved=%#x config=%#x"), u8Irq, pThis->irq);
     868
     869        RTIOPORT IOPortBase;
     870        rc = pHlp->pfnSSMGetIOPort(pSSM, &IOPortBase);
     871        AssertRCReturn(rc, rc);
     872        if (IOPortBase != pThis->IOPortBase)
     873            return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - IOPortBase: saved=%RTiop config=%RTiop"), IOPortBase, pThis->IOPortBase);
     874
     875        bool fUTC;
     876        rc = pHlp->pfnSSMGetBool(pSSM, &fUTC);
     877        AssertRCReturn(rc, rc);
     878        if (fUTC != pThis->fUTC)
     879            LogRel(("RTC: Config mismatch - fUTC: saved=%RTbool config=%RTbool\n", fUTC, pThis->fUTC));
     880    }
     881
     882    if (uPass != SSM_PASS_FINAL)
     883        return VINF_SUCCESS;
     884
     885    /* The state. */
     886    pHlp->pfnSSMGetMem(pSSM, pThis->cmos_data, CMOS_BANK_SIZE);
     887    pHlp->pfnSSMGetU8(pSSM, &pThis->cmos_index[0]);
     888
     889    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_sec);
     890    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_min);
     891    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_hour);
     892    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_wday);
     893    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_mday);
     894    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_mon);
     895    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_year);
     896
     897    PDMDevHlpTimerLoad(pDevIns, pThis->hPeriodicTimer, pSSM);
     898
     899    pHlp->pfnSSMGetS64(pSSM, &pThis->next_periodic_time);
     900
     901    pHlp->pfnSSMGetS64(pSSM, &pThis->next_second_time);
     902    PDMDevHlpTimerLoad(pDevIns, pThis->hSecondTimer, pSSM);
     903    PDMDevHlpTimerLoad(pDevIns, pThis->hSecondTimer2, pSSM);
     904
     905    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_31)
     906         pHlp->pfnSSMGetBool(pSSM, &pThis->fDisabledByHpet);
     907
     908    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_32PRE)
     909    {
     910        /* Second CMOS bank. */
     911        pHlp->pfnSSMGetMem(pSSM, &pThis->cmos_data[CMOS_BANK_SIZE], CMOS_BANK_SIZE);
     912        pHlp->pfnSSMGetU8(pSSM, &pThis->cmos_index[1]);
     913    }
     914
     915    int period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
     916    if (    period_code != 0
     917        &&  (pThis->cmos_data[RTC_REG_B] & REG_B_PIE))
     918    {
     919        if (period_code <= 2)
     920            period_code += 7;
     921        int period = 1 << (period_code - 1);
     922        LogRel(("RTC: period=%#x (%d) %u Hz (restore)\n", period, period, _32K / period));
     923        PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS);
     924        PDMDevHlpTimerSetFrequencyHint(pDevIns, pThis->hPeriodicTimer, _32K / period);
     925        PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
     926        pThis->CurLogPeriod  = period;
     927        pThis->CurHintPeriod = period;
     928    }
     929    else
     930    {
     931        LogRel(("RTC: Stopped the periodic timer (restore)\n"));
     932        pThis->CurLogPeriod  = 0;
     933        pThis->CurHintPeriod = 0;
     934    }
     935    pThis->cRelLogEntries = 0;
     936
     937    return VINF_SUCCESS;
     938}
     939
     940
     941/* -=-=-=-=-=- PDM Interface provided by the RTC device  -=-=-=-=-=- */
     942
     943/**
     944 * Calculate and update the standard CMOS checksum.
     945 *
     946 * @param   pThis       Pointer to the RTC state data.
     947 */
     948static void rtcCalcCRC(PRTCSTATE pThis)
     949{
     950    uint16_t u16 = 0;
     951    for (unsigned i = RTC_CRC_START; i <= RTC_CRC_LAST; i++)
     952        u16 += pThis->cmos_data[i];
     953
     954    pThis->cmos_data[RTC_CRC_LOW]  = u16 & 0xff;
     955    pThis->cmos_data[RTC_CRC_HIGH] = (u16 >> 8) & 0xff;
     956}
     957
     958
     959/**
     960 * @interface_method_impl{PDMRTCREG,pfnWrite}
     961 */
     962static DECLCALLBACK(int) rtcCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
     963{
     964    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     965    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->pCritSectRoR3));
     966    if (iReg < RT_ELEMENTS(pThis->cmos_data))
     967    {
     968        pThis->cmos_data[iReg] = u8Value;
     969
     970        /* does it require checksum update? */
     971        if (    iReg >= RTC_CRC_START
     972            &&  iReg <= RTC_CRC_LAST)
     973            rtcCalcCRC(pThis);
     974
     975        return VINF_SUCCESS;
     976    }
     977
     978    AssertMsgFailed(("iReg=%d\n", iReg));
     979    return VERR_INVALID_PARAMETER;
     980}
     981
     982
     983/**
     984 * @interface_method_impl{PDMRTCREG,pfnRead}
     985 */
     986static DECLCALLBACK(int) rtcCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
     987{
     988    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     989    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->pCritSectRoR3));
     990
     991    if (iReg < RT_ELEMENTS(pThis->cmos_data))
     992    {
     993        *pu8Value = pThis->cmos_data[iReg];
     994        return VINF_SUCCESS;
     995    }
     996    AssertMsgFailed(("iReg=%d\n", iReg));
     997    return VERR_INVALID_PARAMETER;
     998}
     999
     1000
     1001/**
     1002 * @interface_method_impl{PDMIHPETLEGACYNOTIFY,pfnModeChanged}
     1003 */
     1004static DECLCALLBACK(void) rtcHpetLegacyNotify_ModeChanged(PPDMIHPETLEGACYNOTIFY pInterface, bool fActivated)
     1005{
     1006    PRTCSTATECC pThisCC = RT_FROM_MEMBER(pInterface, RTCSTATER3, IHpetLegacyNotify);
     1007    PPDMDEVINS pDevIns = pThisCC->pDevInsR3;
     1008    PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
     1009
     1010    pThisCC->pShared->fDisabledByHpet = fActivated;
     1011
     1012    PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
     1013}
     1014
     1015
     1016
     1017/* -=-=-=-=-=- IBase -=-=-=-=-=- */
     1018
     1019/**
     1020 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     1021 */
     1022static DECLCALLBACK(void *) rtcQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     1023{
     1024    PPDMDEVINS  pDevIns = RT_FROM_MEMBER(pInterface, PDMDEVINS, IBase);
     1025    PRTCSTATECC pThisCC = PDMINS_2_DATA_CC(pDevIns, PRTCSTATECC);
     1026    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE,             &pDevIns->IBase);
     1027    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHPETLEGACYNOTIFY, &pThisCC->IHpetLegacyNotify);
     1028    return NULL;
     1029}
     1030
     1031
     1032/* -=-=-=-=-=- PDMDEVREG -=-=-=-=-=- */
     1033
     1034static void rtc_set_memory(PRTCSTATE pThis, int addr, int val)
     1035{
     1036    if (addr >= 0 && addr <= 127)
     1037        pThis->cmos_data[addr] = val;
     1038}
     1039
     1040
     1041static void rtc_set_date(PRTCSTATE pThis, const struct my_tm *tm)
     1042{
     1043    pThis->current_tm = *tm;
     1044    rtc_copy_date(pThis);
     1045}
     1046
     1047
     1048/**
     1049 * @interface_method_impl{PDMDEVREG,pfnInitComplete}
     1050 *
     1051 * Used to set the clock.
     1052 */
     1053static DECLCALLBACK(int)  rtcInitComplete(PPDMDEVINS pDevIns)
     1054{
     1055    /** @todo this should be (re)done at power on if we didn't load a state... */
     1056    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1057
     1058    /*
     1059     * Set the CMOS date/time.
     1060     */
     1061    RTTIMESPEC  Now;
     1062    PDMDevHlpTMUtcNow(pDevIns, &Now);
     1063    RTTIME Time;
     1064    if (pThis->fUTC)
     1065        RTTimeExplode(&Time, &Now);
     1066    else
     1067        RTTimeLocalExplode(&Time, &Now);
     1068
     1069    struct my_tm Tm;
     1070    memset(&Tm, 0, sizeof(Tm));
     1071    Tm.tm_year = Time.i32Year - 1900;
     1072    Tm.tm_mon  = Time.u8Month - 1;
     1073    Tm.tm_mday = Time.u8MonthDay;
     1074    Tm.tm_wday = (Time.u8WeekDay + 1 + 7) % 7; /* 0 = Monday -> Sunday */
     1075    Tm.tm_yday = Time.u16YearDay - 1;
     1076    Tm.tm_hour = Time.u8Hour;
     1077    Tm.tm_min  = Time.u8Minute;
     1078    Tm.tm_sec  = Time.u8Second;
     1079
     1080    rtc_set_date(pThis, &Tm);
     1081
     1082    int iYear = to_bcd(pThis, (Tm.tm_year / 100) + 19); /* tm_year is 1900 based */
     1083    rtc_set_memory(pThis, 0x32, iYear);                 /* 32h - Century Byte (BCD value for the century */
     1084    rtc_set_memory(pThis, 0x37, iYear);                 /* 37h - (IBM PS/2) Date Century Byte */
     1085
     1086    /*
     1087     * Recalculate the checksum just in case.
     1088     */
     1089    rtcCalcCRC(pThis);
     1090
     1091    Log(("CMOS bank 0: \n%16.128Rhxd\n", &pThis->cmos_data[0]));
     1092    Log(("CMOS bank 1: \n%16.128Rhxd\n", &pThis->cmos_data[CMOS_BANK_SIZE]));
     1093    return VINF_SUCCESS;
     1094}
     1095
     1096
     1097/**
     1098 * @interface_method_impl{PDMDEVREG,pfnRelocate}
     1099 */
     1100static DECLCALLBACK(void) rtcRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     1101{
     1102    RT_NOREF1(offDelta);
     1103    PRTCSTATERC pThisRC = PDMINS_2_DATA_RC(pDevIns, PRTCSTATERC);
     1104    pThisRC->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     1105}
     1106
     1107
     1108/**
     1109 * @interface_method_impl{PDMDEVREG,pfnReset}
     1110 */
     1111static DECLCALLBACK(void) rtcReset(PPDMDEVINS pDevIns)
     1112{
     1113    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1114
     1115    /* Reset index values (important for second bank). */
     1116    pThis->cmos_index[0] = 0;
     1117    pThis->cmos_index[1] = CMOS_BANK_SIZE;   /* Point to start of second bank. */
     1118}
     1119
     1120
     1121/**
     1122 * @interface_method_impl{PDMDEVREG,pfnConstruct}
     1123 */
     1124static DECLCALLBACK(int)  rtcConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
     1125{
     1126    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     1127    PCPDMDEVHLPR3 pHlp    = pDevIns->pHlpR3;
     1128    PRTCSTATE     pThis   = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1129    PRTCSTATECC   pThisCC = PDMINS_2_DATA_CC(pDevIns, PRTCSTATECC);
     1130    int           rc;
     1131    Assert(iInstance == 0); RT_NOREF(iInstance);
     1132
     1133    /*
     1134     * Validate configuration.
     1135     */
     1136    PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "Irq|Base|UseUTC", "");
     1137
     1138    /*
     1139     * Init the data.
     1140     */
     1141    uint8_t u8Irq;
     1142    rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Irq", &u8Irq, 8);
     1143    if (RT_FAILURE(rc))
     1144        return PDMDEV_SET_ERROR(pDevIns, rc,
     1145                                N_("Configuration error: Querying \"Irq\" as a uint8_t failed"));
     1146    pThis->irq = u8Irq;
     1147
     1148    rc = pHlp->pfnCFGMQueryPortDef(pCfg, "Base", &pThis->IOPortBase, 0x70);
     1149    if (RT_FAILURE(rc))
     1150        return PDMDEV_SET_ERROR(pDevIns, rc,
     1151                                N_("Configuration error: Querying \"Base\" as a RTIOPORT failed"));
     1152
     1153    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "UseUTC", &pThis->fUTC, false);
     1154    if (RT_FAILURE(rc))
     1155        return PDMDEV_SET_ERROR(pDevIns, rc,
     1156                                N_("Configuration error: Querying \"UseUTC\" as a bool failed"));
     1157
     1158    Log(("RTC: Irq=%#x Base=%#x fR0Enabled=%RTbool fRCEnabled=%RTbool\n",
     1159         u8Irq, pThis->IOPortBase, pDevIns->fR0Enabled, pDevIns->fRCEnabled));
     1160
     1161
     1162    pThis->cmos_data[RTC_REG_A] = 0x26;
     1163    pThis->cmos_data[RTC_REG_B] = 0x02;
     1164    pThis->cmos_data[RTC_REG_C] = 0x00;
     1165    pThis->cmos_data[RTC_REG_D] = 0x80;
     1166    pThis->fDisabledByHpet      = false;
     1167    pThis->cmos_index[1]        = CMOS_BANK_SIZE;   /* Point to start of second bank. */
     1168
     1169    pThisCC->pDevInsR3                          = pDevIns;
     1170    pThisCC->RtcReg.u32Version                  = PDM_RTCREG_VERSION;
     1171    pThisCC->RtcReg.pfnRead                     = rtcCMOSRead;
     1172    pThisCC->RtcReg.pfnWrite                    = rtcCMOSWrite;
     1173    pThisCC->IHpetLegacyNotify.pfnModeChanged   = rtcHpetLegacyNotify_ModeChanged;
     1174
     1175    /* IBase */
     1176    pDevIns->IBase.pfnQueryInterface            = rtcQueryInterface;
     1177
     1178    /*
     1179     * Create timers.
     1180     */
     1181    /* Periodic timer. */
     1182    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerPeriodic, pThis,
     1183                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Periodic", &pThis->hPeriodicTimer);
     1184    AssertRCReturn(rc, rc);
     1185
     1186    /* Seconds timer. */
     1187    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond, pThis,
     1188                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second", &pThis->hSecondTimer);
     1189    AssertRCReturn(rc, rc);
     1190
     1191    /* The second2 timer, this is always active. */
     1192    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond2, pThis,
     1193                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second2", &pThis->hSecondTimer2);
     1194    AssertRCReturn(rc, rc);
     1195
     1196    pThis->next_second_time = PDMDevHlpTimerGet(pDevIns, pThis->hSecondTimer2)
     1197                            + (PDMDevHlpTimerGetFreq(pDevIns, pThis->hSecondTimer2) * 99) / 100;
     1198    rc = PDMDevHlpTimerLock(pDevIns, pThis->hSecondTimer2, VERR_IGNORED);
     1199    AssertRCReturn(rc, rc);
     1200    rc = PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer2, pThis->next_second_time);
     1201    PDMDevHlpTimerUnlock(pDevIns, pThis->hSecondTimer2);
     1202    AssertRCReturn(rc, rc);
     1203
     1204    /*
     1205     * Register I/O ports.
     1206     */
     1207    rc = PDMDevHlpIoPortCreateAndMap(pDevIns, pThis->IOPortBase, 4, rtcIOPortWrite, rtcIOPortRead, NULL /*pvUser*/,
     1208                                     "MC146818 RTC/CMOS", &pThis->hIoPorts);
     1209    AssertRCReturn(rc, rc);
     1210
     1211    /*
     1212     * Register the saved state.
     1213     */
     1214    rc = PDMDevHlpSSMRegister3(pDevIns, RTC_SAVED_STATE_VERSION, sizeof(*pThis), rtcLiveExec, rtcSaveExec, rtcLoadExec);
     1215    AssertRCReturn(rc, rc);
     1216
     1217    /*
     1218     * Register ourselves as the RTC/CMOS with PDM.
     1219     */
     1220    rc = PDMDevHlpRTCRegister(pDevIns, &pThisCC->RtcReg, &pThisCC->pRtcHlpR3);
     1221    AssertRCReturn(rc, rc);
     1222
     1223    /*
     1224     * Register debugger info callback.
     1225     */
     1226    PDMDevHlpDBGFInfoRegister(pDevIns, "cmos1", "Display CMOS Bank 1 Info (0x0e-0x7f). No arguments. See also rtc.", rtcCmosBankInfo);
     1227    PDMDevHlpDBGFInfoRegister(pDevIns, "cmos2", "Display CMOS Bank 2 Info (0x0e-0x7f). No arguments.", rtcCmosBank2Info);
     1228    PDMDevHlpDBGFInfoRegister(pDevIns, "rtc",   "Display CMOS RTC (0x00-0x0d). No arguments. See also cmos1 & cmos2", rtcCmosClockInfo);
     1229
     1230    /*
     1231     * Register statistics.
     1232     */
     1233    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRTCIrq,      STAMTYPE_COUNTER, "/TM/RTC/Irq",      STAMUNIT_OCCURENCES,  "The number of times a RTC interrupt was triggered.");
     1234    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRTCTimerCB,  STAMTYPE_COUNTER, "/TM/RTC/TimerCB",  STAMUNIT_OCCURENCES,  "The number of times the RTC timer callback ran.");
     1235
     1236    return VINF_SUCCESS;
     1237}
     1238
     1239#else /* !IN_RING3 */
     1240
     1241static DECLCALLBACK(int)  rtcRZConstruct(PPDMDEVINS pDevIns)
     1242{
     1243    PRTCSTATE   pThis   = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1244    PRTCSTATER0 pThisCC = PDMINS_2_DATA_CC(pDevIns, PRTCSTATECC);
     1245    pThisCC->CTX_SUFF(pDevIns) = pDevIns;
     1246
     1247    int rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->hIoPorts, rtcIOPortWrite, rtcIOPortRead, NULL /*pvUser*/);
     1248    AssertRCReturn(rc, rc);
     1249
     1250    return VINF_SUCCESS;
     1251}
     1252
     1253#endif /* !IN_RING3 */
     1254
     1255/**
     1256 * The device registration structure.
     1257 */
     1258const PDMDEVREG g_DeviceMC146818 =
     1259{
     1260    /* .u32Version = */             PDM_DEVREG_VERSION,
     1261    /* .uReserved0 = */             0,
     1262    /* .szName = */                 "mc146818",
     1263    /* .fFlags = */                 PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_NEW_STYLE
     1264                                    | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
     1265    /* .fClass = */                 PDM_DEVREG_CLASS_RTC,
     1266    /* .cMaxInstances = */          1,
     1267    /* .uSharedVersion = */         1,
     1268    /* .cbInstanceShared = */       sizeof(RTCSTATE),
     1269    /* .cbInstanceCC = */           sizeof(RTCSTATECC),
     1270    /* .cbInstanceRC = */           sizeof(RTCSTATERC),
     1271    /* .uReserved1 = */             0,
     1272    /* .pszDescription = */         "Motorola MC146818 RTC/CMOS Device.",
     1273#ifdef IN_RING3
     1274    /* .pszRCMod = */               "VBoxDDRC.rc",
     1275    /* .pszR0Mod = */               "VBoxDDR0.r0",
     1276    /* .pfnConstruct = */           rtcConstruct,
     1277    /* .pfnDestruct = */            NULL,
     1278    /* .pfnRelocate = */            rtcRelocate,
     1279    /* .pfnMemSetup = */            NULL,
     1280    /* .pfnPowerOn = */             NULL,
     1281    /* .pfnReset = */               rtcReset,
     1282    /* .pfnSuspend = */             NULL,
     1283    /* .pfnResume = */              NULL,
     1284    /* .pfnAttach = */              NULL,
     1285    /* .pfnDetach = */              NULL,
     1286    /* .pfnQueryInterface = */      NULL,
     1287    /* .pfnInitComplete = */        rtcInitComplete,
     1288    /* .pfnPowerOff = */            NULL,
     1289    /* .pfnSoftReset = */           NULL,
     1290    /* .pfnReserved0 = */           NULL,
     1291    /* .pfnReserved1 = */           NULL,
     1292    /* .pfnReserved2 = */           NULL,
     1293    /* .pfnReserved3 = */           NULL,
     1294    /* .pfnReserved4 = */           NULL,
     1295    /* .pfnReserved5 = */           NULL,
     1296    /* .pfnReserved6 = */           NULL,
     1297    /* .pfnReserved7 = */           NULL,
     1298#elif defined(IN_RING0)
     1299    /* .pfnEarlyConstruct = */      NULL,
     1300    /* .pfnConstruct = */           rtcRZConstruct,
     1301    /* .pfnDestruct = */            NULL,
     1302    /* .pfnFinalDestruct = */       NULL,
     1303    /* .pfnRequest = */             NULL,
     1304    /* .pfnReserved0 = */           NULL,
     1305    /* .pfnReserved1 = */           NULL,
     1306    /* .pfnReserved2 = */           NULL,
     1307    /* .pfnReserved3 = */           NULL,
     1308    /* .pfnReserved4 = */           NULL,
     1309    /* .pfnReserved5 = */           NULL,
     1310    /* .pfnReserved6 = */           NULL,
     1311    /* .pfnReserved7 = */           NULL,
     1312#elif defined(IN_RC)
     1313    /* .pfnConstruct = */           rtcRZConstruct,
     1314    /* .pfnReserved0 = */           NULL,
     1315    /* .pfnReserved1 = */           NULL,
     1316    /* .pfnReserved2 = */           NULL,
     1317    /* .pfnReserved3 = */           NULL,
     1318    /* .pfnReserved4 = */           NULL,
     1319    /* .pfnReserved5 = */           NULL,
     1320    /* .pfnReserved6 = */           NULL,
     1321    /* .pfnReserved7 = */           NULL,
     1322#else
     1323# error "Not IN_RING3, IN_RING0 nor IN_RC!"
     1324#endif
     1325    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
     1326};
     1327
     1328#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
     1329
     1330#else /* OLD STYLE DEVICE: */
     1331
     1332typedef struct RTCSTATE
     1333{
     1334    uint8_t cmos_data[256];
     1335    uint8_t cmos_index[2];
     1336    uint8_t Alignment0[6];
     1337    struct my_tm current_tm;
     1338    /** The configured IRQ. */
     1339    int32_t irq;
     1340    /** The configured I/O port base. */
     1341    RTIOPORT IOPortBase;
     1342    /** Use UTC or local time initially. */
     1343    bool fUTC;
     1344    /** Disabled by HPET legacy mode. */
     1345    bool fDisabledByHpet;
     1346    /* periodic timer */
     1347    int64_t next_periodic_time;
     1348    /* second update */
     1349    int64_t next_second_time;
     1350
     1351    /** Pointer to the device instance - R3 Ptr. */
     1352    PPDMDEVINSR3 pDevInsR3;
     1353    /** The periodic timer (rtcTimerPeriodic) - R3 Ptr. */
     1354    PTMTIMERR3 pPeriodicTimerR3;
     1355    /** The second timer (rtcTimerSecond) - R3 Ptr. */
     1356    PTMTIMERR3 pSecondTimerR3;
     1357    /** The second second timer (rtcTimerSecond2) - R3 Ptr. */
     1358    PTMTIMERR3 pSecondTimer2R3;
     1359
     1360    /** Pointer to the device instance - R0 Ptr. */
     1361    PPDMDEVINSR0 pDevInsR0;
     1362    /** The periodic timer (rtcTimerPeriodic) - R0 Ptr. */
     1363    PTMTIMERR0 pPeriodicTimerR0;
     1364    /** The second timer (rtcTimerSecond) - R0 Ptr. */
     1365    PTMTIMERR0 pSecondTimerR0;
     1366    /** The second second timer (rtcTimerSecond2) - R0 Ptr. */
     1367    PTMTIMERR0 pSecondTimer2R0;
     1368
     1369    /** Pointer to the device instance - RC Ptr. */
     1370    PPDMDEVINSRC pDevInsRC;
     1371    /** The periodic timer (rtcTimerPeriodic) - RC Ptr. */
     1372    PTMTIMERRC pPeriodicTimerRC;
     1373    /** The second timer (rtcTimerSecond) - RC Ptr. */
     1374    PTMTIMERRC pSecondTimerRC;
     1375    /** The second second timer (rtcTimerSecond2) - RC Ptr. */
     1376    PTMTIMERRC pSecondTimer2RC;
     1377
     1378    /** The RTC registration structure. */
     1379    PDMRTCREG RtcReg;
     1380    /** The RTC device helpers. */
     1381    R3PTRTYPE(PCPDMRTCHLP) pRtcHlpR3;
     1382    /** Number of release log entries. Used to prevent flooding. */
     1383    uint32_t cRelLogEntries;
     1384    /** The current/previous logged timer period. */
     1385    int32_t CurLogPeriod;
     1386    /** The current/previous hinted timer period. */
     1387    int32_t CurHintPeriod;
     1388    /** How many consecutive times the UIP has been seen. */
     1389    int32_t cUipSeen;
     1390
     1391    /** HPET legacy mode notification interface. */
     1392    PDMIHPETLEGACYNOTIFY  IHpetLegacyNotify;
     1393
     1394    /** Number of IRQs that's been raised. */
     1395    STAMCOUNTER             StatRTCIrq;
     1396    /** Number of times the timer callback handler ran. */
     1397    STAMCOUNTER             StatRTCTimerCB;
     1398} RTCSTATE;
     1399/** Pointer to the RTC device state. */
     1400typedef RTCSTATE *PRTCSTATE;
     1401
     1402#ifndef VBOX_DEVICE_STRUCT_TESTCASE
     1403
     1404static void rtc_timer_update(PRTCSTATE pThis, int64_t current_time)
     1405{
     1406    int period_code, period;
     1407    uint64_t cur_clock, next_irq_clock;
     1408    uint32_t freq;
     1409
     1410    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
     1411    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
     1412
     1413    period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
     1414    if (   period_code != 0
     1415        && (pThis->cmos_data[RTC_REG_B] & REG_B_PIE))
     1416    {
     1417        if (period_code <= 2)
     1418            period_code += 7;
     1419        /* period in 32 kHz cycles */
     1420        period = 1 << (period_code - 1);
     1421        /* compute 32 kHz clock */
     1422        freq = TMTimerGetFreq(pThis->CTX_SUFF(pPeriodicTimer));
     1423
     1424        cur_clock = ASMMultU64ByU32DivByU32(current_time, 32768, freq);
     1425        next_irq_clock = (cur_clock & ~(uint64_t)(period - 1)) + period;
     1426        pThis->next_periodic_time = ASMMultU64ByU32DivByU32(next_irq_clock, freq, 32768) + 1;
     1427        TMTimerSet(pThis->CTX_SUFF(pPeriodicTimer), pThis->next_periodic_time);
     1428
     1429#ifdef IN_RING3
     1430        if (RT_UNLIKELY(period != pThis->CurLogPeriod))
     1431#else
     1432        if (RT_UNLIKELY(period != pThis->CurHintPeriod))
     1433#endif
     1434        {
     1435#ifdef IN_RING3
     1436            if (pThis->cRelLogEntries++ < 64)
     1437                LogRel(("RTC: period=%#x (%d) %u Hz\n", period, period, _32K / period));
     1438            pThis->CurLogPeriod  = period;
     1439#endif
     1440            pThis->CurHintPeriod = period;
     1441            TMTimerSetFrequencyHint(pThis->CTX_SUFF(pPeriodicTimer), _32K / period);
     1442        }
     1443    }
     1444    else
     1445    {
     1446#ifdef IN_RING3
     1447        if (TMTimerIsActive(pThis->CTX_SUFF(pPeriodicTimer)) && pThis->cRelLogEntries++ < 64)
     1448            LogRel(("RTC: Stopped the periodic timer\n"));
     1449#endif
     1450        TMTimerStop(pThis->CTX_SUFF(pPeriodicTimer));
     1451    }
     1452}
     1453
     1454
     1455static void rtc_raise_irq(PRTCSTATE pThis, uint32_t iLevel)
     1456{
     1457    if (!pThis->fDisabledByHpet)
     1458    {
     1459        PDMDevHlpISASetIrq(pThis->CTX_SUFF(pDevIns), pThis->irq, iLevel);
     1460        if (iLevel)
     1461            STAM_COUNTER_INC(&pThis->StatRTCIrq);
     1462    }
     1463}
     1464
     1465
     1466#ifdef IN_RING3
     1467DECLINLINE(int) to_bcd(PRTCSTATE pThis, int a)
     1468{
     1469    if (pThis->cmos_data[RTC_REG_B] & 0x04)
     1470        return a;
     1471    return ((a / 10) << 4) | (a % 10);
     1472}
     1473#endif
     1474
     1475
     1476DECLINLINE(int) from_bcd(PRTCSTATE pThis, int a)
     1477{
     1478    if (pThis->cmos_data[RTC_REG_B] & 0x04)
     1479        return a;
     1480    return ((a >> 4) * 10) + (a & 0x0f);
     1481}
     1482
     1483
     1484static void rtc_set_time(PRTCSTATE pThis)
     1485{
     1486    struct my_tm *tm = &pThis->current_tm;
     1487
     1488    tm->tm_sec  = from_bcd(pThis, pThis->cmos_data[RTC_SECONDS]);
     1489    tm->tm_min  = from_bcd(pThis, pThis->cmos_data[RTC_MINUTES]);
     1490    tm->tm_hour = from_bcd(pThis, pThis->cmos_data[RTC_HOURS] & 0x7f);
     1491    if (!(pThis->cmos_data[RTC_REG_B] & 0x02))
     1492    {
     1493        tm->tm_hour %= 12;
     1494        if (pThis->cmos_data[RTC_HOURS] & 0x80)
     1495            tm->tm_hour += 12;
     1496    }
     1497    tm->tm_wday = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_WEEK]);
     1498    tm->tm_mday = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_MONTH]);
     1499    tm->tm_mon  = from_bcd(pThis, pThis->cmos_data[RTC_MONTH]) - 1;
     1500    tm->tm_year = from_bcd(pThis, pThis->cmos_data[RTC_YEAR]) + 100;
     1501}
     1502
     1503
     1504/* -=-=-=-=-=- I/O Port Handlers -=-=-=-=-=- */
     1505
     1506
     1507/**
     1508 * @callback_method_impl{FNIOMIOPORTIN}
     1509 */
     1510PDMBOTHCBDECL(int) rtcIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb)
     1511{
     1512    NOREF(pvUser);
     1513    if (cb != 1)
     1514        return VERR_IOM_IOPORT_UNUSED;
     1515
     1516    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1517    if ((uPort & 1) == 0)
     1518        *pu32 = 0xff;
     1519    else
     1520    {
     1521        unsigned bank = (uPort >> 1) & 1;
     1522        switch (pThis->cmos_index[bank])
     1523        {
     1524            case RTC_SECONDS:
     1525            case RTC_MINUTES:
     1526            case RTC_HOURS:
     1527            case RTC_DAY_OF_WEEK:
     1528            case RTC_DAY_OF_MONTH:
     1529            case RTC_MONTH:
     1530            case RTC_YEAR:
     1531                *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
     1532                break;
     1533
     1534            case RTC_REG_A:
     1535                if (pThis->cmos_data[RTC_REG_A] & REG_A_UIP)
     1536                    ++pThis->cUipSeen;
     1537                else
     1538                    pThis->cUipSeen = 0;
     1539                if (pThis->cUipSeen >= 250)
     1540                {
     1541                    pThis->cmos_data[pThis->cmos_index[0]] &= ~REG_A_UIP;
     1542                    pThis->cUipSeen = 0;
     1543                }
     1544                *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
     1545                break;
     1546
     1547            case RTC_REG_C:
     1548                *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
     1549                rtc_raise_irq(pThis, 0);
     1550                pThis->cmos_data[RTC_REG_C] = 0x00;
     1551                break;
     1552
     1553            default:
     1554                *pu32 = pThis->cmos_data[pThis->cmos_index[bank]];
     1555                break;
     1556        }
     1557
     1558        Log(("CMOS: Read bank %d idx %#04x: %#04x\n", bank, pThis->cmos_index[bank], *pu32));
     1559    }
     1560
     1561    return VINF_SUCCESS;
     1562}
     1563
     1564
     1565/**
     1566 * @callback_method_impl{FNIOMIOPORTOUT}
     1567 */
     1568PDMBOTHCBDECL(int) rtcIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb)
     1569{
     1570    NOREF(pvUser);
     1571    if (cb != 1)
     1572        return VINF_SUCCESS;
     1573
     1574    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1575    uint32_t bank = (uPort >> 1) & 1;
     1576    if ((uPort & 1) == 0)
     1577    {
     1578        pThis->cmos_index[bank] = (u32 & 0x7f) + (bank * CMOS_BANK_SIZE);
     1579
     1580        /* HACK ALERT! Attempt to trigger VM_FF_TIMER and/or VM_FF_TM_VIRTUAL_SYNC
     1581           for forcing the pSecondTimer2 timer to run be run and clear UIP in
     1582           a timely fashion. */
     1583        if (u32 == RTC_REG_A)
     1584            TMTimerGet(pThis->CTX_SUFF(pSecondTimer));
     1585    }
     1586    else
     1587    {
     1588        Log(("CMOS: Write bank %d idx %#04x: %#04x (old %#04x)\n", bank,
     1589             pThis->cmos_index[bank], u32, pThis->cmos_data[pThis->cmos_index[bank]]));
     1590
     1591        int const idx = pThis->cmos_index[bank];
     1592        switch (idx)
     1593        {
     1594            case RTC_SECONDS_ALARM:
     1595            case RTC_MINUTES_ALARM:
     1596            case RTC_HOURS_ALARM:
     1597                pThis->cmos_data[pThis->cmos_index[0]] = u32;
     1598                break;
     1599
     1600            case RTC_SECONDS:
     1601            case RTC_MINUTES:
     1602            case RTC_HOURS:
     1603            case RTC_DAY_OF_WEEK:
     1604            case RTC_DAY_OF_MONTH:
     1605            case RTC_MONTH:
     1606            case RTC_YEAR:
     1607                pThis->cmos_data[pThis->cmos_index[0]] = u32;
     1608                /* if in set mode, do not update the time */
     1609                if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
     1610                    rtc_set_time(pThis);
     1611                break;
     1612
     1613            case RTC_REG_A:
     1614            case RTC_REG_B:
     1615            {
     1616                /* We need to acquire the clock lock, because of lock ordering
     1617                   issues this means having to release the device lock.  Since
     1618                   we're letting IOM do the locking, we must not return without
     1619                   holding the device lock.*/
     1620                PDMCritSectLeave(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo));
     1621                int rc1 = TMTimerLock(pThis->CTX_SUFF(pPeriodicTimer), VINF_SUCCESS /* must get it */);
     1622                int rc2 = PDMCritSectEnter(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
     1623                AssertRCReturn(rc1, rc1);
     1624                AssertRCReturnStmt(rc2, TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer)), rc2);
     1625
     1626                if (idx == RTC_REG_A)
     1627                {
     1628                    /* UIP bit is read only */
     1629                    pThis->cmos_data[RTC_REG_A] = (u32                        & ~REG_A_UIP)
     1630                                                | (pThis->cmos_data[RTC_REG_A] & REG_A_UIP);
     1631                }
     1632                else
     1633                {
     1634                    if (u32 & REG_B_SET)
     1635                    {
     1636                        /* set mode: reset UIP mode */
     1637                        pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
     1638#if 0 /* This is probably wrong as it breaks changing the time/date in OS/2. */
     1639                        u32 &= ~REG_B_UIE;
     1640#endif
     1641                    }
     1642                    else
     1643                    {
     1644                        /* if disabling set mode, update the time */
     1645                        if (pThis->cmos_data[RTC_REG_B] & REG_B_SET)
     1646                            rtc_set_time(pThis);
     1647                    }
     1648                    pThis->cmos_data[RTC_REG_B] = u32;
     1649                }
     1650
     1651                rtc_timer_update(pThis, TMTimerGet(pThis->CTX_SUFF(pPeriodicTimer)));
     1652
     1653                TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer));
     1654                /* the caller leaves the other lock. */
     1655                break;
     1656            }
     1657
     1658            case RTC_REG_C:
     1659            case RTC_REG_D:
     1660                /* cannot write to them */
     1661                break;
     1662
     1663            default:
     1664                pThis->cmos_data[pThis->cmos_index[bank]] = u32;
     1665                break;
     1666        }
     1667    }
     1668
     1669    return VINF_SUCCESS;
     1670}
     1671
     1672#ifdef IN_RING3
     1673
     1674/* -=-=-=-=-=- Debug Info Handlers  -=-=-=-=-=- */
     1675
     1676/**
     1677 * @callback_method_impl{FNDBGFHANDLERDEV,
     1678 *      Dumps the cmos Bank Info.}
     1679 */
     1680static DECLCALLBACK(void) rtcCmosBankInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     1681{
     1682    RT_NOREF1(pszArgs);
     1683    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1684
     1685    pHlp->pfnPrintf(pHlp,
     1686                    "First CMOS bank, offsets 0x0E - 0x7F\n"
     1687                    "Offset %02x : --- use 'info rtc' to show CMOS clock ---", 0);
     1688    for (unsigned iCmos = CMOS_BANK_LOWER_LIMIT; iCmos <= CMOS_BANK_UPPER_LIMIT; iCmos++)
     1689    {
     1690        if ((iCmos & 15) == 0)
     1691            pHlp->pfnPrintf(pHlp, "Offset %02x : %02x", iCmos, pThis->cmos_data[iCmos]);
     1692        else if ((iCmos & 15) == 8)
     1693            pHlp->pfnPrintf(pHlp, "-%02x", pThis->cmos_data[iCmos]);
     1694        else if ((iCmos & 15) == 15)
     1695            pHlp->pfnPrintf(pHlp, " %02x\n", pThis->cmos_data[iCmos]);
     1696        else
     1697            pHlp->pfnPrintf(pHlp, " %02x", pThis->cmos_data[iCmos]);
     1698    }
     1699}
     1700
     1701/**
     1702 * @callback_method_impl{FNDBGFHANDLERDEV,
     1703 *      Dumps the cmos Bank2 Info.}
     1704 */
     1705static DECLCALLBACK(void) rtcCmosBank2Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     1706{
     1707    RT_NOREF1(pszArgs);
     1708    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1709
     1710    pHlp->pfnPrintf(pHlp, "Second CMOS bank, offsets 0x80 - 0xFF\n");
     1711    for (uint16_t iCmos = CMOS_BANK2_LOWER_LIMIT; iCmos <= CMOS_BANK2_UPPER_LIMIT; iCmos++)
     1712    {
     1713        if ((iCmos & 15) == 0)
     1714            pHlp->pfnPrintf(pHlp, "Offset %02x : %02x", iCmos, pThis->cmos_data[iCmos]);
     1715        else if ((iCmos & 15) == 8)
     1716            pHlp->pfnPrintf(pHlp, "-%02x", pThis->cmos_data[iCmos]);
     1717        else if ((iCmos & 15) == 15)
     1718            pHlp->pfnPrintf(pHlp, " %02x\n", pThis->cmos_data[iCmos]);
     1719        else
     1720            pHlp->pfnPrintf(pHlp, " %02x", pThis->cmos_data[iCmos]);
     1721    }
     1722}
     1723
     1724/**
     1725 * @callback_method_impl{FNDBGFHANDLERDEV,
     1726 *      Dumps the cmos RTC Info.}
     1727 */
     1728static DECLCALLBACK(void) rtcCmosClockInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     1729{
     1730    RT_NOREF1(pszArgs);
     1731    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1732    uint8_t u8Sec   = from_bcd(pThis, pThis->cmos_data[RTC_SECONDS]);
     1733    uint8_t u8Min   = from_bcd(pThis, pThis->cmos_data[RTC_MINUTES]);
     1734    uint8_t u8Hr    = from_bcd(pThis, pThis->cmos_data[RTC_HOURS] & 0x7f);
     1735    if (   !(pThis->cmos_data[RTC_REG_B] & 0x02)
     1736        && (pThis->cmos_data[RTC_HOURS] & 0x80))
     1737        u8Hr += 12;
     1738    uint8_t u8Day   = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_MONTH]);
     1739    uint8_t u8Month = from_bcd(pThis, pThis->cmos_data[RTC_MONTH]) ;
     1740    uint8_t u8Year  = from_bcd(pThis, pThis->cmos_data[RTC_YEAR]);
     1741    pHlp->pfnPrintf(pHlp, "Time: %02u:%02u:%02u  Date: %02u-%02u-%02u\n",
     1742                    u8Hr, u8Min, u8Sec, u8Year, u8Month, u8Day);
     1743    pHlp->pfnPrintf(pHlp, "REG A=%02x B=%02x C=%02x D=%02x\n",
     1744                    pThis->cmos_data[RTC_REG_A], pThis->cmos_data[RTC_REG_B],
     1745                    pThis->cmos_data[RTC_REG_C], pThis->cmos_data[RTC_REG_D]);
     1746}
     1747
     1748
     1749
     1750/* -=-=-=-=-=- Timers and their support code  -=-=-=-=-=- */
     1751
     1752
     1753/**
     1754 * @callback_method_impl{FNTMTIMERDEV, periodic}
     1755 */
     1756static DECLCALLBACK(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     1757{
     1758    RT_NOREF2(pTimer, pvUser);
     1759    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     1760    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
     1761    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
     1762
     1763    rtc_timer_update(pThis, pThis->next_periodic_time);
     1764    STAM_COUNTER_INC(&pThis->StatRTCTimerCB);
     1765    pThis->cmos_data[RTC_REG_C] |= 0xc0;
     1766
     1767    rtc_raise_irq(pThis, 1);
     1768}
     1769
     1770
     1771/* month is between 0 and 11. */
     1772static int get_days_in_month(int month, int year)
     1773{
     1774    static const int days_tab[12] =
     1775    {
     1776        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
     1777    };
     1778    int d;
     1779
     1780    if ((unsigned )month >= 12)
     1781        return 31;
     1782
     1783    d = days_tab[month];
     1784    if (month == 1)
     1785    {
     1786        if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
     1787            d++;
     1788    }
     1789    return d;
     1790}
     1791
     1792
     1793/* update 'tm' to the next second */
     1794static void rtc_next_second(struct my_tm *tm)
     1795{
     1796    int days_in_month;
     1797
     1798    tm->tm_sec++;
     1799    if ((unsigned)tm->tm_sec >= 60)
     1800    {
     1801        tm->tm_sec = 0;
     1802        tm->tm_min++;
     1803        if ((unsigned)tm->tm_min >= 60)
     1804        {
     1805            tm->tm_min = 0;
     1806            tm->tm_hour++;
     1807            if ((unsigned)tm->tm_hour >= 24)
     1808            {
     1809                tm->tm_hour = 0;
     1810                /* next day */
     1811                tm->tm_wday++;
     1812                if ((unsigned)tm->tm_wday >= 7)
     1813                    tm->tm_wday = 0;
     1814                days_in_month = get_days_in_month(tm->tm_mon,
     1815                                                  tm->tm_year + 1900);
     1816                tm->tm_mday++;
     1817                if (tm->tm_mday < 1)
     1818                    tm->tm_mday = 1;
     1819                else if (tm->tm_mday > days_in_month)
     1820                {
     1821                    tm->tm_mday = 1;
     1822                    tm->tm_mon++;
     1823                    if (tm->tm_mon >= 12)
     1824                    {
     1825                        tm->tm_mon = 0;
     1826                        tm->tm_year++;
     1827                    }
     1828                }
     1829            }
     1830        }
     1831    }
     1832}
     1833
     1834
     1835/**
     1836 * @callback_method_impl{FNTMTIMERDEV, Second timer.}
     1837 */
     1838static DECLCALLBACK(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     1839{
    6401840    RT_NOREF2(pTimer, pvUser);
    6411841    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
     
    12392439}
    12402440
     2441#endif /* IN_RING3 */
    12412442
    12422443/**
     
    12452446const PDMDEVREG g_DeviceMC146818 =
    12462447{
    1247     /* u32Version */
    1248     PDM_DEVREG_VERSION,
    1249     /* szName */
    1250     "mc146818",
    1251     /* szRCMod */
    1252     "VBoxDDRC.rc",
    1253     /* szR0Mod */
    1254     "VBoxDDR0.r0",
    1255     /* pszDescription */
    1256     "Motorola MC146818 RTC/CMOS Device.",
    1257     /* fFlags */
    1258     PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
    1259     /* fClass */
    1260     PDM_DEVREG_CLASS_RTC,
    1261     /* cMaxInstances */
    1262     1,
    1263     /* cbInstance */
    1264     sizeof(RTCSTATE),
    1265     /* pfnConstruct */
    1266     rtcConstruct,
    1267     /* pfnDestruct */
    1268     NULL,
    1269     /* pfnRelocate */
    1270     rtcRelocate,
    1271     /* pfnMemSetup */
    1272     NULL,
    1273     /* pfnPowerOn */
    1274     NULL,
    1275     /* pfnReset */
    1276     rtcReset,
    1277     /* pfnSuspend */
    1278     NULL,
    1279     /* pfnResume */
    1280     NULL,
    1281     /* pfnAttach */
    1282     NULL,
    1283     /* pfnDetach */
    1284     NULL,
    1285     /* pfnQueryInterface */
    1286     NULL,
    1287     /* pfnInitComplete */
    1288     rtcInitComplete,
    1289     /* pfnPowerOff */
    1290     NULL,
    1291     /* pfnSoftReset */
    1292     NULL,
    1293     /* u32VersionEnd */
    1294     PDM_DEVREG_VERSION
     2448    /* .u32Version = */             PDM_DEVREG_VERSION,
     2449    /* .uReserved0 = */             0,
     2450    /* .szName = */                 "mc146818",
     2451    /* .fFlags = */                 PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
     2452    /* .fClass = */                 PDM_DEVREG_CLASS_RTC,
     2453    /* .cMaxInstances = */          1,
     2454    /* .uSharedVersion = */         1,
     2455    /* .cbInstanceShared = */       sizeof(RTCSTATE),
     2456    /* .cbInstanceCC = */           0,
     2457    /* .cbInstanceRC = */           0,
     2458    /* .uReserved1 = */             0,
     2459    /* .pszDescription = */         "Motorola MC146818 RTC/CMOS Device.",
     2460#ifdef IN_RING3
     2461    /* .pszRCMod = */               "VBoxDDRC.rc",
     2462    /* .pszR0Mod = */               "VBoxDDR0.r0",
     2463    /* .pfnConstruct = */           rtcConstruct,
     2464    /* .pfnDestruct = */            NULL,
     2465    /* .pfnRelocate = */            rtcRelocate,
     2466    /* .pfnMemSetup = */            NULL,
     2467    /* .pfnPowerOn = */             NULL,
     2468    /* .pfnReset = */               rtcReset,
     2469    /* .pfnSuspend = */             NULL,
     2470    /* .pfnResume = */              NULL,
     2471    /* .pfnAttach = */              NULL,
     2472    /* .pfnDetach = */              NULL,
     2473    /* .pfnQueryInterface = */      NULL,
     2474    /* .pfnInitComplete = */        rtcInitComplete,
     2475    /* .pfnPowerOff = */            NULL,
     2476    /* .pfnSoftReset = */           NULL,
     2477    /* .pfnReserved0 = */           NULL,
     2478    /* .pfnReserved1 = */           NULL,
     2479    /* .pfnReserved2 = */           NULL,
     2480    /* .pfnReserved3 = */           NULL,
     2481    /* .pfnReserved4 = */           NULL,
     2482    /* .pfnReserved5 = */           NULL,
     2483    /* .pfnReserved6 = */           NULL,
     2484    /* .pfnReserved7 = */           NULL,
     2485#elif defined(IN_RING0)
     2486    /* .pfnEarlyConstruct = */      NULL,
     2487    /* .pfnConstruct = */           NULL,
     2488    /* .pfnDestruct = */            NULL,
     2489    /* .pfnFinalDestruct = */       NULL,
     2490    /* .pfnRequest = */             NULL,
     2491    /* .pfnReserved0 = */           NULL,
     2492    /* .pfnReserved1 = */           NULL,
     2493    /* .pfnReserved2 = */           NULL,
     2494    /* .pfnReserved3 = */           NULL,
     2495    /* .pfnReserved4 = */           NULL,
     2496    /* .pfnReserved5 = */           NULL,
     2497    /* .pfnReserved6 = */           NULL,
     2498    /* .pfnReserved7 = */           NULL,
     2499#elif defined(IN_RC)
     2500    /* .pfnConstruct = */           NULL,
     2501    /* .pfnReserved0 = */           NULL,
     2502    /* .pfnReserved1 = */           NULL,
     2503    /* .pfnReserved2 = */           NULL,
     2504    /* .pfnReserved3 = */           NULL,
     2505    /* .pfnReserved4 = */           NULL,
     2506    /* .pfnReserved5 = */           NULL,
     2507    /* .pfnReserved6 = */           NULL,
     2508    /* .pfnReserved7 = */           NULL,
     2509#else
     2510# error "Not IN_RING3, IN_RING0 nor IN_RC!"
     2511#endif
     2512    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
    12952513};
    12962514
    1297 #endif /* IN_RING3 */
    12982515#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    12992516
     2517
     2518#endif /* OLD STYLE DEVICE */
Note: See TracChangeset for help on using the changeset viewer.

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