VirtualBox

Changeset 94091 in vbox for trunk/src/VBox/Runtime/r3/darwin


Ignore:
Timestamp:
Mar 4, 2022 9:28:14 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150336
Message:

IPRT: Better RTMpGetDescription for darwin.arm (first M1 has two clusters of 4 cores with different energy characteristics and names). bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/darwin/RTMpGetDescription-generic.cpp

    r94087 r94091  
    3535
    3636#include <sys/sysctl.h>
     37#if defined(RT_ARCH_ARM64)
     38# include <IOKit/IOKitLib.h>
     39#endif
    3740
    3841
     
    4851
    4952    /*
     53     * For ARM there are typically two different types of cores, so look up the
     54     * processor in the IODeviceTree and get the core name and type from there
     55     * if we can.
     56     */
     57    char   szExtra[256];
     58    size_t cchExtra = 0;
     59
     60#if defined(RT_ARCH_ARM64)
     61    char szArmCpuPath[64];
     62    RTStrPrintf(szArmCpuPath, sizeof(szArmCpuPath), "IODeviceTree:/cpus/cpu%u", idCpu);
     63    io_registry_entry_t hIoRegEntry = IORegistryEntryFromPath(kIOMasterPortDefault, szArmCpuPath);
     64    if (hIoRegEntry != MACH_PORT_NULL)
     65    {
     66        /* This property is typically "E" or "P".  Don't know why it's mapped
     67           to a CFDataRef rather than a CFStringRef... */
     68        CFTypeRef hValRef = IORegistryEntryCreateCFProperty(hIoRegEntry, CFSTR("cluster-type"), kCFAllocatorDefault, kNilOptions);
     69        if (hValRef)
     70        {
     71            if (CFGetTypeID(hValRef) == CFDataGetTypeID())
     72            {
     73                size_t const          cbData = CFDataGetLength((CFDataRef)hValRef);
     74                uint8_t const * const pbData = (uint8_t const *)CFDataGetBytePtr((CFDataRef)hValRef);
     75                if (cbData > 0 && pbData != NULL)
     76                {
     77                    int rc = RTStrValidateEncodingEx((const char *)pbData, cbData, RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
     78                    AssertMsgRC(rc, ("%p LB %#zx: %.*Rhxs\n", pbData, cbData, cbData, pbData));
     79                    if (RT_SUCCESS(rc))
     80                    {
     81                        RTStrCopy(&szExtra[1], sizeof(szExtra) - 1, (const char *)pbData);
     82                        szExtra[0] = ' ';
     83                        cchExtra = strlen(szExtra);
     84                    }
     85                }
     86            }
     87            else
     88                AssertMsgFailed(("%p=%#lx\n", hValRef, CFGetTypeID(hValRef)));
     89
     90            CFRelease(hValRef);
     91        }
     92
     93        /* The compatible property is an "array" of zero terminated strings.
     94           For the M1 mini the first entry is either "apple,firestorm" (P cores)
     95           or "apple,icestorm" (E cores).  We extract the bits after the comma
     96           and append it to the extra string. (Again, dunno why it's a CFDataRef.) */
     97        hValRef = IORegistryEntryCreateCFProperty(hIoRegEntry, CFSTR("compatible"), kCFAllocatorDefault, 0);
     98        if (hValRef)
     99        {
     100            if (CFGetTypeID(hValRef) == CFDataGetTypeID())
     101            {
     102                size_t const          cbData = CFDataGetLength((CFDataRef)hValRef);
     103                uint8_t const * const pbData = (uint8_t const *)CFDataGetBytePtr((CFDataRef)hValRef);
     104                if (cbData > 0 && pbData != NULL)
     105                {
     106                    Assert(pbData[cbData - 1] == '\0');
     107                    if (pbData[cbData - 1] == '\0')
     108                    {
     109                        size_t offData = 0;
     110                        while (offData < cbData)
     111                        {
     112                            const char  *psz = (const char *)&pbData[offData];
     113                            size_t const cch = strlen(psz);
     114
     115                            if (RTStrStartsWith(psz, "apple,"))
     116                            {
     117                                psz += sizeof("apple,") - 1;
     118                                psz = RTStrStripL(psz);
     119                                if (*psz)
     120                                {
     121                                    if (RTStrIsValidEncoding(psz))
     122                                        cchExtra += RTStrPrintf(&szExtra[cchExtra], sizeof(szExtra) - cchExtra, " (%s)", psz);
     123                                    else
     124                                        AssertFailed();
     125                                }
     126                            }
     127
     128                            /* advance */
     129                            offData += cch + 1;
     130                        }
     131                    }
     132                }
     133            }
     134            else
     135                AssertMsgFailed(("%p=%#lx\n", hValRef, CFGetTypeID(hValRef)));
     136            CFRelease(hValRef);
     137        }
     138
     139        IOObjectRelease(hIoRegEntry);
     140    }
     141#endif
     142    szExtra[cchExtra] = '\0';
     143
     144    /*
    50145     * Just use the sysctl machdep.cpu.brand_string value for now.
    51146     */
    52     /** @todo on arm this is very boring and there are two different types of
    53      *        cores in the system, "E" and "P" cores. The I/O registry can
    54      *        be used to find out which @a idCpu is.  There are also codename
    55      *        available there. */
    56147    char szBrand[128] = {0};
    57148    size_t cb = sizeof(szBrand);
     
    61152
    62153    char *pszStripped = RTStrStrip(szBrand);
    63     if (*pszStripped)
    64         return RTStrCopy(pszBuf, cbBuf, pszStripped);
    65     return RTStrCopy(pszBuf, cbBuf, "Unknown");
     154    if (*pszStripped == '\0')
     155        pszStripped = strcpy(szBrand, "Unknown");
     156
     157    rc = RTStrCopy(pszBuf, cbBuf, pszStripped);
     158    if (cchExtra > 0 && RT_SUCCESS(rc))
     159        rc = RTStrCat(pszBuf, cbBuf, szExtra);
     160    return rc;
    66161}
    67162RT_EXPORT_SYMBOL(RTMpGetDescription);
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