Martin Storsjö (@mstorsjo) commented about dlls/ntdll/unix/system.c:
- snprintf( path_buf, sizeof(path_buf), midr_el1_path, logical_thread_id );
- if ((fp = fopen( path_buf, "r" )))
- {
fscanf( fp, "%lx", &value );
fclose( fp );
regs[regidx++] = (struct smbios_wine_id_reg_value_arm64){ 0x4000, value };
- }
+#define STR(a) #a +#define READ_ID_REG(reg_id) \
- /* mrs x0, #reg_id */ \
- __asm__ __volatile__( ".inst " STR(0xd5300000 | reg_id << 5) "\n\t" \
"mov %0, x0" : "=r"(value) :: "x0" ); \
- regs[regidx++] = (struct smbios_wine_id_reg_value_arm64){ reg_id, value };
- /* Linux traps reads to these ID registers and emulates them. They do not vary across cores,
FYI, this isn't universally the case - Linux trapping and emulating them hasn't been around since forever.
Linux v4.11 added `HWCAP_CPUID`, and if this hwcap is enabled, the trapping is supported. (I'm not sure if there are kernels past 4.11 that don't have it set, though.) I do run wine on arm64 on a couple of old devboards that run Linux 4.4 kernels - although I haven't updated my version of Wine on them for quite a while...
Anyway, ideally, we'd check `getauxval(AT_HWCAP) & HWCAP_CPUID` before going ahead and trying to read these registers - even if few users today really run older kernels.