Changeset 87280 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Jan 15, 2021 4:29:06 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/darwin/mp-darwin.cpp
r87198 r87280 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #define LOG_GROUP RTLOGGROUP_ SYSTEM31 #define LOG_GROUP RTLOGGROUP_DEFAULT /*RTLOGGROUP_SYSTEM*/ 32 32 #include <iprt/types.h> 33 33 … … 40 40 #include <mach/mach.h> 41 41 42 #include <CoreFoundation/CFBase.h> 43 #include <IOKit/IOKitLib.h> 44 /*#include <IOKit/IOBSD.h> 45 #include <IOKit/storage/IOStorageDeviceCharacteristics.h> 46 #include <IOKit/storage/IOBlockStorageDevice.h> 47 #include <IOKit/storage/IOMedia.h> 48 #include <IOKit/storage/IOCDMedia.h> 49 #include <IOKit/scsi/SCSITaskLib.h> 50 #include <SystemConfiguration/SystemConfiguration.h> 51 #include <mach/mach_error.h> 52 #include <sys/param.h> 53 #include <paths.h>*/ 54 42 55 #include <iprt/mp.h> 43 56 #include <iprt/cpuset.h> 44 57 #include <iprt/assert.h> 58 #include <iprt/log.h> 45 59 #include <iprt/string.h> 46 60 … … 246 260 247 261 262 /** 263 * Worker for RTMpGetMaxFrequency. 264 * @returns Non-zero frequency in MHz on success, 0 on failure. 265 */ 266 static uint32_t rtMpDarwinGetMaxFrequencyFromIOService(io_service_t hCpu) 267 { 268 io_struct_inband_t Buf = {0}; 269 uint32_t cbActual = sizeof(Buf); 270 kern_return_t krc = IORegistryEntryGetProperty(hCpu, "clock-frequency", Buf, &cbActual); 271 Log2(("rtMpDarwinGetMaxFrequencyFromIOService: krc=%d; cbActual=%#x %.16Rhxs\n", krc, cbActual, Buf)); 272 if (krc == kIOReturnSuccess) 273 { 274 switch (cbActual) 275 { 276 case sizeof(uint32_t): 277 return RT_BE2H_U32(*(uint32_t *)Buf) / 1000; 278 case sizeof(uint64_t): 279 AssertFailed(); 280 return RT_BE2H_U64(*(uint64_t *)Buf) / 1000; 281 default: 282 AssertFailed(); 283 } 284 } 285 return 0; 286 } 287 288 248 289 RTDECL(uint32_t) RTMpGetMaxFrequency(RTCPUID idCpu) 249 290 { … … 271 312 if (rc != -1 && cCpus >= 1) 272 313 return cCpus; 314 315 /* 316 * The above does not work for Apple M1 / xnu 20.1.0, so go look at the I/O registry instead. 317 * 318 * A sample ARM layout: 319 * | +-o cpu1@1 <class IOPlatformDevice, id 0x100000110, registered, matched, active, busy 0 (182 ms), retain 8> 320 * | | +-o AppleARMCPU <class AppleARMCPU, id 0x10000021b, registered, matched, active, busy 0 (1 ms), retain 6> 321 * | +-o cpu2@2 <class IOPlatformDevice, id 0x100000111, registered, matched, active, busy 0 (175 ms), retain 8> 322 * | | +-o AppleARMCPU <class AppleARMCPU, id 0x10000021c, registered, matched, active, busy 0 (3 ms), retain 6> 323 * | +-o cpu3@3 <class IOPlatformDevice, id 0x100000112, registered, matched, active, busy 0 (171 ms), retain 8> 324 * | | +-o AppleARMCPU <class AppleARMCPU, id 0x10000021d, registered, matched, active, busy 0 (1 ms), retain 6> 325 * | +-o cpu4@100 <class IOPlatformDevice, id 0x100000113, registered, matched, active, busy 0 (171 ms), retain 8> 326 * | | +-o AppleARMCPU <class AppleARMCPU, id 0x10000021e, registered, matched, active, busy 0 (1 ms), retain 6> 327 * | +-o cpu5@101 <class IOPlatformDevice, id 0x100000114, registered, matched, active, busy 0 (179 ms), retain 8> 328 * | | +-o AppleARMCPU <class AppleARMCPU, id 0x10000021f, registered, matched, active, busy 0 (9 ms), retain 6> 329 * | +-o cpu6@102 <class IOPlatformDevice, id 0x100000115, registered, matched, active, busy 0 (172 ms), retain 8> 330 * | | +-o AppleARMCPU <class AppleARMCPU, id 0x100000220, registered, matched, active, busy 0 (1 ms), retain 6> 331 * | +-o cpu7@103 <class IOPlatformDevice, id 0x100000116, registered, matched, active, busy 0 (175 ms), retain 8> 332 * | | +-o AppleARMCPU <class AppleARMCPU, id 0x100000221, registered, matched, active, busy 0 (5 ms), retain 6> 333 * | +-o cpus <class IOPlatformDevice, id 0x10000010e, registered, matched, active, busy 0 (12 ms), retain 15> 334 * 335 */ 336 337 /* Assume names on the form "cpu<N>" are only for CPUs. */ 338 char szCpuName[32]; 339 RTStrPrintf(szCpuName, sizeof(szCpuName), "cpu%u", idCpu); 340 CFMutableDictionaryRef hMatchingDict = IOServiceNameMatching(szCpuName); 341 AssertReturn(hMatchingDict, 0); 342 343 /* Just get the first one. */ 344 io_object_t hCpu = IOServiceGetMatchingService(kIOMasterPortDefault, hMatchingDict); 345 if (hCpu != 0) 346 { 347 uint32_t uCpuFrequency = rtMpDarwinGetMaxFrequencyFromIOService(hCpu); 348 IOObjectRelease(hCpu); 349 if (uCpuFrequency) 350 return uCpuFrequency; 351 } 352 353 #if 1 /* Just in case... */ 354 /* Create a matching dictionary for searching for CPU services in the IOKit. */ 355 # if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32) 356 hMatchingDict = IOServiceMatching("AppleARMCPU"); 357 # elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 358 hMatchingDict = IOServiceMatching("AppleACPICPU"); 359 # else 360 # error "Port me!" 361 # endif 362 AssertReturn(hMatchingDict, 0); 363 364 /* Perform the search and get a collection of Apple CPU services. */ 365 io_iterator_t hCpuServices = IO_OBJECT_NULL; 366 IOReturn irc = IOServiceGetMatchingServices(kIOMasterPortDefault, hMatchingDict, &hCpuServices); 367 AssertMsgReturn(irc == kIOReturnSuccess, ("irc=%d\n", irc), 0); 368 hMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */ 369 370 /* Enumerate the matching services. */ 371 uint32_t uCpuFrequency = 0; 372 io_object_t hCurCpu; 373 while (uCpuFrequency == 0 && (hCurCpu = IOIteratorNext(hCpuServices)) != IO_OBJECT_NULL) 374 { 375 io_object_t hParent = (io_object_t)0; 376 irc = IORegistryEntryGetParentEntry(hCurCpu, kIOServicePlane, &hParent); 377 if (irc == kIOReturnSuccess && hParent) 378 { 379 uCpuFrequency = rtMpDarwinGetMaxFrequencyFromIOService(hParent); 380 IOObjectRelease(hParent); 381 } 382 IOObjectRelease(hCurCpu); 383 } 384 IOObjectRelease(hCpuServices); 385 #endif 386 273 387 AssertFailed(); 274 388 return 0; 275 389 } 390
Note:
See TracChangeset
for help on using the changeset viewer.