VirtualBox

Changeset 106461 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Oct 17, 2024 2:57:44 PM (4 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
165280
Message:

Additions/common/VBoxGuest: Implement support for the MMIO request interface on Windows for win.arm64 support, bugref:10734

Location:
trunk/src/VBox/Additions/common/VBoxGuest
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk

    r106324 r106461  
    9292   VBoxGuest_LDFLAGS.x86 = -Entry:DriverEntry@8
    9393   VBoxGuest_LDFLAGS.amd64 = -Entry:DriverEntry
     94   VBoxGuest_LDFLAGS.arm64 = -Entry:DriverEntry
    9495   ifeq ($(KBUILD_TARGET_ARCH),x86)
    9596    VBoxGuest_SDKS       = ReorderCompilerIncs $(VBOX_WINDDK_GST_NT4)
     
    101102        $(PATH_SDK_$(VBOX_WINDDK_GST)_LIB)/hal.lib
    102103    ifneq ($(VBOX_VCC_CC_GUARD_CF),)
    103      VBoxGuest_LIBS    += \
     104     VBoxGuest_LIBS.x86 += \
    104105        $(PATH_SDK_$(VBOX_WINDDK_GST)_LIB)/BufferOverflowK.lib
     106     VBoxGuest_LIBS.amd64 += \
     107        $(PATH_SDK_$(VBOX_WINDDK_GST)_LIB)/BufferOverflowK.lib
     108     VBoxGuest_LIBS.arm64 += \
     109        $(PATH_SDK_$(VBOX_WINDDK_GST)_LIB)/BufferOverflowFastFailK.lib
    105110    endif
    106111   else
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp

    r106173 r106461  
    4747
    4848#include <iprt/asm.h>
    49 #include <iprt/asm-amd64-x86.h>
     49#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     50# include <iprt/asm-amd64-x86.h>
     51#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_X86)
     52# include <iprt/asm-arm.h>
     53#else
     54# error "Port me"
     55#endif
    5056#include <iprt/buildconfig.h>
    5157#include <iprt/critsect.h>
     
    145151    /** Length of VMMDev memory.   */
    146152    ULONG                   cbVmmDevMemory;
     153
     154    /** Physical address and length of the optional VMMDev MMIO request interface. */
     155    PHYSICAL_ADDRESS        GCPhysMmioReq;
     156    /** Length of the optional VMMDev MMIO request interface.   */
     157    ULONG                   cbMmioReq;
    147158
    148159    /** Device state. */
     
    770781                             pPartialData->u.Memory.Start.QuadPart, pPartialData->u.Memory.Length));
    771782                }
     783                else if ((pPartialData->Flags & CM_RESOURCE_MEMORY_WRITEABILITY_MASK) == CM_RESOURCE_MEMORY_READ_WRITE)
     784                {
     785                    /* Treat as MMIO request interface. */
     786                    /* Save physical MMIO base + length for VMMDev. */
     787                    pDevExt->GCPhysMmioReq = pPartialData->u.Memory.Start;
     788                    pDevExt->cbMmioReq     = (ULONG)pPartialData->u.Memory.Length;
     789
     790                    if (!fTranslated)
     791                    {
     792                        /* Technically we need to make the HAL translate the address.  since we
     793                           didn't used to do this and it probably just returns the input address,
     794                           we allow ourselves to ignore failures. */
     795                        ULONG               uAddressSpace = 0;
     796                        PHYSICAL_ADDRESS    PhysAddr = pPartialData->u.Memory.Start;
     797                        if (HalTranslateBusAddress(pResList->List->InterfaceType, pResList->List->BusNumber, PhysAddr,
     798                                                   &uAddressSpace, &PhysAddr))
     799                        {
     800                            Log(("HalTranslateBusAddress(%#RX64) -> %RX64, type %#x\n",
     801                                 pPartialData->u.Memory.Start.QuadPart, PhysAddr.QuadPart, uAddressSpace));
     802                            if (pPartialData->u.Memory.Start.QuadPart != PhysAddr.QuadPart)
     803                                pDevExt->GCPhysMmioReq = PhysAddr;
     804                        }
     805                        else
     806                            Log(("HalTranslateBusAddress(%#RX64) -> failed!\n", pPartialData->u.Memory.Start.QuadPart));
     807                    }
     808
     809                    LogFunc(("Found memory range for VMMDev MMIO request interface! Base = %#RX64, Length = %08x\n",
     810                             pPartialData->u.Memory.Start.QuadPart, pPartialData->u.Memory.Length));
     811                }
    772812                else
    773813                    LogFunc(("Ignoring memory: Flags=%08x Base=%#RX64\n",
     
    937977
    938978/**
     979 * Unmaps the MMIO request interface range from kernel space.
     980 *
     981 * @param   pDevExt     The device extension.
     982 */
     983static void vgdrvNtUnmapVMMDevMmioReq(PVBOXGUESTDEVEXTWIN pDevExt)
     984{
     985    LogFlowFunc(("pMmioReq = %#p\n", pDevExt->Core.pMmioReq));
     986    if (pDevExt->Core.pMmioReq)
     987    {
     988        MmUnmapIoSpace((void*)pDevExt->Core.pMmioReq, pDevExt->cbMmioReq);
     989        pDevExt->Core.pMmioReq = NULL;
     990        pDevExt->Core.pMmioReqFast = NULL;
     991    }
     992
     993    pDevExt->GCPhysMmioReq.QuadPart = 0;
     994    pDevExt->cbMmioReq              = 0;
     995}
     996
     997
     998/**
    939999 * Maps the I/O space from VMMDev to virtual kernel address space.
    9401000 *
     
    9811041                 rc = STATUS_UNSUCCESSFUL;
    9821042             }
     1043         }
     1044         else
     1045             rc = STATUS_UNSUCCESSFUL;
     1046    }
     1047    return rc;
     1048}
     1049
     1050
     1051/**
     1052 * Maps the I/O space from VMMDev to virtual kernel address space.
     1053 *
     1054 * @return NTSTATUS
     1055 *
     1056 * @param pDevExt           The device extension.
     1057 * @param GCPhysMmioReq     Physical address to map.
     1058 * @param cbToMap           Number of bytes to map.
     1059 * @param ppvMmioReq        Pointer of mapped I/O base.
     1060 */
     1061static NTSTATUS vgdrvNtMapVMMDevMmioReq(PVBOXGUESTDEVEXTWIN pDevExt, PHYSICAL_ADDRESS GCPhysMmioReq, ULONG cbToMap,
     1062                                        void **ppvMmioReq)
     1063{
     1064    AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
     1065    AssertPtrReturn(ppvMmioReq, VERR_INVALID_POINTER);
     1066
     1067    NTSTATUS rc = STATUS_SUCCESS;
     1068    if (GCPhysMmioReq.QuadPart != 0)
     1069    {
     1070         void *pvMmioReq = MmMapIoSpace(GCPhysMmioReq, cbToMap, MmNonCached);
     1071         LogFlowFunc(("pvMmioReq = %p\n", pvMmioReq));
     1072         if (pvMmioReq)
     1073         {
     1074            /* Save results. */
     1075            *ppvMmioReq = pvMmioReq;
     1076            LogFlowFunc(("MMIO request interface found and mapped! pvMmioReq = 0x%p\n", pvMmioReq));
    9831077         }
    9841078         else
     
    10681162            pDevExt->Core.pVMMDevMemory = (VMMDevMemory *)pvMMIOBase;
    10691163
    1070             LogFunc(("pvMMIOBase=0x%p, pDevExt=0x%p, pDevExt->Core.pVMMDevMemory=0x%p\n",
    1071                      pvMMIOBase, pDevExt, pDevExt ? pDevExt->Core.pVMMDevMemory : NULL));
    1072 
    1073             int vrc = VGDrvCommonInitDevExtResources(&pDevExt->Core,
    1074                                                      pDevExt->Core.IOPortBase,
    1075                                                      NULL /*pvMmioReq*/,
    1076                                                      pvMMIOBase, cbMMIO,
    1077                                                      vgdrvNtVersionToOSType(g_enmVGDrvNtVer),
    1078                                                      VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
    1079             if (RT_SUCCESS(vrc))
     1164            void *pvMmioReq = NULL;
     1165            rcNt = vgdrvNtMapVMMDevMmioReq(pDevExt, pDevExt->GCPhysMmioReq, pDevExt->cbMmioReq, &pvMmioReq);
     1166            if (NT_SUCCESS(rcNt))
    10801167            {
    1081 
    1082                 vrc = VbglR0GRAlloc((VMMDevRequestHeader **)&pDevExt->pPowerStateRequest,
    1083                                     sizeof(VMMDevPowerStateRequest), VMMDevReq_SetPowerStatus);
     1168                LogFunc(("pvMMIOBase=0x%p, pDevExt=0x%p, pDevExt->Core.pVMMDevMemory=0x%p\n",
     1169                         pvMMIOBase, pDevExt, pDevExt ? pDevExt->Core.pVMMDevMemory : NULL));
     1170
     1171                int vrc = VGDrvCommonInitDevExtResources(&pDevExt->Core,
     1172                                                         pDevExt->Core.IOPortBase,
     1173                                                         pvMmioReq,
     1174                                                         pvMMIOBase, cbMMIO,
     1175                                                         vgdrvNtVersionToOSType(g_enmVGDrvNtVer),
     1176                                                         VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
    10841177                if (RT_SUCCESS(vrc))
    10851178                {
    1086                     /*
    1087                      * Register DPC and ISR.
    1088                      */
    1089                     LogFlowFunc(("Initializing DPC/ISR (pDevObj=%p)...\n", pDevExt->pDeviceObject));
    1090                     IoInitializeDpcRequest(pDevExt->pDeviceObject, vgdrvNtDpcHandler);
    1091 
    1092                     ULONG uInterruptVector = pDevExt->uInterruptVector;
    1093                     KIRQL uHandlerIrql     = (KIRQL)pDevExt->uInterruptLevel;
    1094 #ifdef TARGET_NT4
    1095                     if (!pIrp)
     1179
     1180                    vrc = VbglR0GRAlloc((VMMDevRequestHeader **)&pDevExt->pPowerStateRequest,
     1181                                        sizeof(VMMDevPowerStateRequest), VMMDevReq_SetPowerStatus);
     1182                    if (RT_SUCCESS(vrc))
    10961183                    {
    1097                         /* NT4: Get an interrupt vector.  Only proceed if the device provides an interrupt. */
    1098                         if (   uInterruptVector
    1099                             || pDevExt->uInterruptLevel)
     1184                        /*
     1185                         * Register DPC and ISR.
     1186                         */
     1187                        LogFlowFunc(("Initializing DPC/ISR (pDevObj=%p)...\n", pDevExt->pDeviceObject));
     1188                        IoInitializeDpcRequest(pDevExt->pDeviceObject, vgdrvNtDpcHandler);
     1189
     1190                        ULONG uInterruptVector = pDevExt->uInterruptVector;
     1191                        KIRQL uHandlerIrql     = (KIRQL)pDevExt->uInterruptLevel;
     1192    #ifdef TARGET_NT4
     1193                        if (!pIrp)
    11001194                        {
    1101                             LogFlowFunc(("Getting interrupt vector (HAL): Bus=%u, IRQL=%u, Vector=%u\n",
    1102                                          pDevExt->uBus, pDevExt->uInterruptLevel, pDevExt->uInterruptVector));
    1103                             uInterruptVector = HalGetInterruptVector(g_enmVGDrvNtVer == VGDRVNTVER_WINNT310 ? Isa : PCIBus,
    1104                                                                      pDevExt->uBus,
    1105                                                                      pDevExt->uInterruptLevel,
    1106                                                                      pDevExt->uInterruptVector,
    1107                                                                      &uHandlerIrql,
    1108                                                                      &pDevExt->fInterruptAffinity);
    1109                             LogFlowFunc(("HalGetInterruptVector returns vector=%u\n", uInterruptVector));
     1195                            /* NT4: Get an interrupt vector.  Only proceed if the device provides an interrupt. */
     1196                            if (   uInterruptVector
     1197                                || pDevExt->uInterruptLevel)
     1198                            {
     1199                                LogFlowFunc(("Getting interrupt vector (HAL): Bus=%u, IRQL=%u, Vector=%u\n",
     1200                                             pDevExt->uBus, pDevExt->uInterruptLevel, pDevExt->uInterruptVector));
     1201                                uInterruptVector = HalGetInterruptVector(g_enmVGDrvNtVer == VGDRVNTVER_WINNT310 ? Isa : PCIBus,
     1202                                                                         pDevExt->uBus,
     1203                                                                         pDevExt->uInterruptLevel,
     1204                                                                         pDevExt->uInterruptVector,
     1205                                                                         &uHandlerIrql,
     1206                                                                         &pDevExt->fInterruptAffinity);
     1207                                LogFlowFunc(("HalGetInterruptVector returns vector=%u\n", uInterruptVector));
     1208                            }
     1209                            else
     1210                                LogFunc(("Device does not provide an interrupt!\n"));
     1211                        }
     1212    #endif
     1213                        if (uInterruptVector)
     1214                        {
     1215                            LogFlowFunc(("Connecting interrupt (IntVector=%#u), uHandlerIrql=%u) ...\n",
     1216                                         uInterruptVector, uHandlerIrql));
     1217
     1218                            rcNt = IoConnectInterrupt(&pDevExt->pInterruptObject,                 /* Out: interrupt object. */
     1219                                                      vgdrvNtIsrHandler,                          /* Our ISR handler. */
     1220                                                      pDevExt,                                    /* Device context. */
     1221                                                      NULL,                                       /* Optional spinlock. */
     1222                                                      uInterruptVector,                           /* Interrupt vector. */
     1223                                                      uHandlerIrql,                               /* Irql. */
     1224                                                      uHandlerIrql,                               /* SynchronizeIrql. */
     1225                                                      pDevExt->enmInterruptMode,                  /* LevelSensitive or Latched. */
     1226                                                      TRUE,                                       /* Shareable interrupt. */
     1227                                                      pDevExt->fInterruptAffinity,                /* CPU affinity. */
     1228                                                      FALSE);                                     /* Don't save FPU stack. */
     1229                            if (NT_ERROR(rcNt))
     1230                                LogFunc(("Could not connect interrupt: rcNt=%#x!\n", rcNt));
    11101231                        }
    11111232                        else
    1112                             LogFunc(("Device does not provide an interrupt!\n"));
    1113                     }
    1114 #endif
    1115                     if (uInterruptVector)
    1116                     {
    1117                         LogFlowFunc(("Connecting interrupt (IntVector=%#u), uHandlerIrql=%u) ...\n",
    1118                                      uInterruptVector, uHandlerIrql));
    1119 
    1120                         rcNt = IoConnectInterrupt(&pDevExt->pInterruptObject,                 /* Out: interrupt object. */
    1121                                                   vgdrvNtIsrHandler,                          /* Our ISR handler. */
    1122                                                   pDevExt,                                    /* Device context. */
    1123                                                   NULL,                                       /* Optional spinlock. */
    1124                                                   uInterruptVector,                           /* Interrupt vector. */
    1125                                                   uHandlerIrql,                               /* Irql. */
    1126                                                   uHandlerIrql,                               /* SynchronizeIrql. */
    1127                                                   pDevExt->enmInterruptMode,                  /* LevelSensitive or Latched. */
    1128                                                   TRUE,                                       /* Shareable interrupt. */
    1129                                                   pDevExt->fInterruptAffinity,                /* CPU affinity. */
    1130                                                   FALSE);                                     /* Don't save FPU stack. */
    1131                         if (NT_ERROR(rcNt))
    1132                             LogFunc(("Could not connect interrupt: rcNt=%#x!\n", rcNt));
     1233                            LogFunc(("No interrupt vector found!\n"));
     1234                        if (NT_SUCCESS(rcNt))
     1235                        {
     1236                            /*
     1237                             * Once we've read configuration from register and host, we're finally read.
     1238                             */
     1239                            /** @todo clean up guest ring-3 logging, keeping it separate from the kernel to avoid sharing limits with it. */
     1240                            pDevExt->Core.fLoggingEnabled = true;
     1241                            vgdrvNtReadConfiguration(pDevExt);
     1242
     1243                            /* Ready to rumble! */
     1244                            LogRelFunc(("Device is ready!\n"));
     1245                            pDevExt->enmDevState     = VGDRVNTDEVSTATE_OPERATIONAL;
     1246                            pDevExt->enmPrevDevState = VGDRVNTDEVSTATE_OPERATIONAL;
     1247                            return STATUS_SUCCESS;
     1248                        }
     1249
     1250                        pDevExt->pInterruptObject = NULL;
     1251
     1252                        VbglR0GRFree(&pDevExt->pPowerStateRequest->header);
     1253                        pDevExt->pPowerStateRequest = NULL;
    11331254                    }
    11341255                    else
    1135                         LogFunc(("No interrupt vector found!\n"));
    1136                     if (NT_SUCCESS(rcNt))
    11371256                    {
    1138                         /*
    1139                          * Once we've read configuration from register and host, we're finally read.
    1140                          */
    1141                         /** @todo clean up guest ring-3 logging, keeping it separate from the kernel to avoid sharing limits with it. */
    1142                         pDevExt->Core.fLoggingEnabled = true;
    1143                         vgdrvNtReadConfiguration(pDevExt);
    1144 
    1145                         /* Ready to rumble! */
    1146                         LogRelFunc(("Device is ready!\n"));
    1147                         pDevExt->enmDevState     = VGDRVNTDEVSTATE_OPERATIONAL;
    1148                         pDevExt->enmPrevDevState = VGDRVNTDEVSTATE_OPERATIONAL;
    1149                         return STATUS_SUCCESS;
     1257                        LogFunc(("Alloc for pPowerStateRequest failed, vrc=%Rrc\n", vrc));
     1258                        rcNt = STATUS_UNSUCCESSFUL;
    11501259                    }
    11511260
    1152                     pDevExt->pInterruptObject = NULL;
    1153 
    1154                     VbglR0GRFree(&pDevExt->pPowerStateRequest->header);
    1155                     pDevExt->pPowerStateRequest = NULL;
     1261                    VGDrvCommonDeleteDevExtResources(&pDevExt->Core);
    11561262                }
    11571263                else
    11581264                {
    1159                     LogFunc(("Alloc for pPowerStateRequest failed, vrc=%Rrc\n", vrc));
    1160                     rcNt = STATUS_UNSUCCESSFUL;
     1265                    LogFunc(("Could not init device extension resources: vrc=%Rrc\n", vrc));
     1266                    rcNt = STATUS_DEVICE_CONFIGURATION_ERROR;
    11611267                }
    1162 
    1163                 VGDrvCommonDeleteDevExtResources(&pDevExt->Core);
     1268                vgdrvNtUnmapVMMDevMmioReq(pDevExt);
    11641269            }
    11651270            else
    1166             {
    1167                 LogFunc(("Could not init device extension resources: vrc=%Rrc\n", vrc));
    1168                 rcNt = STATUS_DEVICE_CONFIGURATION_ERROR;
    1169             }
     1271                LogFunc(("Could not map MMIO request interface of VMMDec, rcNt=%#x\n", rcNt));
    11701272            vgdrvNtUnmapVMMDevMemory(pDevExt);
    11711273        }
     
    16541756    if (pDevExt->Core.uInitState == VBOXGUESTDEVEXT_INIT_STATE_RESOURCES)
    16551757        VGDrvCommonDeleteDevExtResources(&pDevExt->Core);
     1758    vgdrvNtUnmapVMMDevMmioReq(pDevExt);
    16561759    vgdrvNtUnmapVMMDevMemory(pDevExt);
    16571760}
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r106061 r106461  
    44474447#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    44484448                AssertReleaseFailed(); /* No port I/O on ARM. */
     4449                fEvents = 0;
    44494450#else
    44504451# error "I have no memory of this architecture"
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