VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/darwin/RTMpGetDescription-generic.cpp@ 103914

Last change on this file since 103914 was 100108, checked in by vboxsync, 18 months ago

*: Fix build issues when setting VBOX_WITH_WARNINGS_AS_ERRORS=1 on darwin.arm64 and make it a default, bugref:10469

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: RTMpGetDescription-generic.cpp 100108 2023-06-07 20:05:13Z vboxsync $ */
2/** @file
3 * IPRT - Multiprocessor, RTMpGetDescription for darwin/arm.
4 */
5
6/*
7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/mp.h>
42#include "internal/iprt.h"
43#include <iprt/err.h>
44#include <iprt/string.h>
45
46#include <sys/sysctl.h>
47#if defined(RT_ARCH_ARM64)
48# include <IOKit/IOKitLib.h>
49#endif
50
51
52RTDECL(int) RTMpGetDescription(RTCPUID idCpu, char *pszBuf, size_t cbBuf)
53{
54 /*
55 * Check that the specified cpu is valid & online.
56 */
57 if (idCpu != NIL_RTCPUID && !RTMpIsCpuOnline(idCpu))
58 return RTMpIsCpuPossible(idCpu)
59 ? VERR_CPU_OFFLINE
60 : VERR_CPU_NOT_FOUND;
61
62 /*
63 * For ARM there are typically two different types of cores, so look up the
64 * processor in the IODeviceTree and get the core name and type from there
65 * if we can.
66 */
67 char szExtra[256];
68 size_t cchExtra = 0;
69
70#if defined(RT_ARCH_ARM64)
71 char szArmCpuPath[64];
72 RTStrPrintf(szArmCpuPath, sizeof(szArmCpuPath), "IODeviceTree:/cpus/cpu%x", idCpu); /** @todo Hex? M1 Max only has 10 cores... */
73
74 RT_GCC_NO_WARN_DEPRECATED_BEGIN
75 io_registry_entry_t hIoRegEntry = IORegistryEntryFromPath(kIOMasterPortDefault, szArmCpuPath); /* kIOMasterPortDefault: Deprecated since 12.0. */
76 RT_GCC_NO_WARN_DEPRECATED_END
77 if (hIoRegEntry != MACH_PORT_NULL)
78 {
79 /* This property is typically "E" or "P". Don't know why it's mapped
80 to a CFDataRef rather than a CFStringRef... */
81 CFTypeRef hValRef = IORegistryEntryCreateCFProperty(hIoRegEntry, CFSTR("cluster-type"), kCFAllocatorDefault, kNilOptions);
82 if (hValRef)
83 {
84 if (CFGetTypeID(hValRef) == CFDataGetTypeID())
85 {
86 size_t const cbData = CFDataGetLength((CFDataRef)hValRef);
87 uint8_t const * const pbData = (uint8_t const *)CFDataGetBytePtr((CFDataRef)hValRef);
88 if (cbData > 0 && pbData != NULL)
89 {
90 int rc = RTStrValidateEncodingEx((const char *)pbData, cbData, RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
91 AssertMsgRC(rc, ("%p LB %#zx: %.*Rhxs\n", pbData, cbData, cbData, pbData));
92 if (RT_SUCCESS(rc))
93 {
94 RTStrCopy(&szExtra[1], sizeof(szExtra) - 1, (const char *)pbData);
95 szExtra[0] = ' ';
96 cchExtra = strlen(szExtra);
97 }
98 }
99 }
100 else
101 AssertMsgFailed(("%p=%#lx\n", hValRef, CFGetTypeID(hValRef)));
102
103 CFRelease(hValRef);
104 }
105
106 /* The compatible property is an "array" of zero terminated strings.
107 For the M1 mini the first entry is either "apple,firestorm" (P cores)
108 or "apple,icestorm" (E cores). We extract the bits after the comma
109 and append it to the extra string. (Again, dunno why it's a CFDataRef.) */
110 hValRef = IORegistryEntryCreateCFProperty(hIoRegEntry, CFSTR("compatible"), kCFAllocatorDefault, 0);
111 if (hValRef)
112 {
113 if (CFGetTypeID(hValRef) == CFDataGetTypeID())
114 {
115 size_t const cbData = CFDataGetLength((CFDataRef)hValRef);
116 uint8_t const * const pbData = (uint8_t const *)CFDataGetBytePtr((CFDataRef)hValRef);
117 if (cbData > 0 && pbData != NULL)
118 {
119 Assert(pbData[cbData - 1] == '\0');
120 if (pbData[cbData - 1] == '\0')
121 {
122 size_t offData = 0;
123 while (offData < cbData)
124 {
125 const char *psz = (const char *)&pbData[offData];
126 size_t const cch = strlen(psz);
127
128 if (RTStrStartsWith(psz, "apple,"))
129 {
130 psz += sizeof("apple,") - 1;
131 psz = RTStrStripL(psz);
132 if (*psz)
133 {
134 if (RTStrIsValidEncoding(psz))
135 cchExtra += RTStrPrintf(&szExtra[cchExtra], sizeof(szExtra) - cchExtra, " (%s)", psz);
136 else
137 AssertFailed();
138 }
139 }
140
141 /* advance */
142 offData += cch + 1;
143 }
144 }
145 }
146 }
147 else
148 AssertMsgFailed(("%p=%#lx\n", hValRef, CFGetTypeID(hValRef)));
149 CFRelease(hValRef);
150 }
151
152 IOObjectRelease(hIoRegEntry);
153 }
154#endif
155 szExtra[cchExtra] = '\0';
156
157 /*
158 * Just use the sysctl machdep.cpu.brand_string value for now.
159 */
160 char szBrand[128] = {0};
161 size_t cb = sizeof(szBrand);
162 int rc = sysctlbyname("machdep.cpu.brand_string", &szBrand, &cb, NULL, 0);
163 if (rc == -1)
164 szBrand[0] = '\0';
165
166 char *pszStripped = RTStrStrip(szBrand);
167 if (*pszStripped == '\0')
168 pszStripped = strcpy(szBrand, "Unknown");
169
170 rc = RTStrCopy(pszBuf, cbBuf, pszStripped);
171 if (cchExtra > 0 && RT_SUCCESS(rc))
172 rc = RTStrCat(pszBuf, cbBuf, szExtra);
173 return rc;
174}
175RT_EXPORT_SYMBOL(RTMpGetDescription);
176
Note: See TracBrowser for help on using the repository browser.

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