You may remember my blog about XCPM for unsupported Processors and I thought about having another look. This time I looked at the Developer Previews of High Sierra and this is what I found. Let’s start with the switch table of _xcpm_bootstrap:
Ok. Let’s do the math:
0xffffffff - (0xfffffe5a - 0x01) = 0x1a6 // case 0 (0x3c - 0x3c = 0x00/0) 0xffffff80003a6334 - 0x1a6 = 0xffffff80003a618e 0xffffffff - (0xfffffedc - 0x01) = 0x124 // case 1 (0x3d - 0x3c = 0x01/1) 0xffffff80003a6334 - 0x124 = 0xffffff80003a6210 0xffffffff - (0xfffffef5 - 0x01) = 0x10b // case 9 (0x45 - 0x3c = 0x09/9) 0xffffff80003a6334 - 0x10b = 0xffffff80003a6229 0xffffffff - (0xffffff0b - 0x01) = 0xf5 // case 10 (0x46 - 0x3c = 0x0a/10) 0xffffff80003a6334 - 0xf5 = 0xffffff80003a623f 0xffffffff - (0xffffff2c - 0x01) = 0xd4 // case 11 (0x47 - 0x3c = 0x0b/11) 0xffffff80003a6334 - 0xd4 = 0xffffff80003a6260 0xffffffff - (0xfffffed0 - 0x01) = 0x130 // case 18 (0x4e - 0x3c = 0x12/18) 0xffffff80003a6334 - 0x130 = 0xffffff80003a6204 0xffffffff - (0xffffff38 - 0x01) = 0xc8 // case 25 (0x55 - 0x3c = 0x19/25) 0xffffff80003a6334 - 0xc8 = 0xffffff80003a626c 0xffffffff - (0xfffffec1 - 0x01) = 0x13f // case 33 (0x5d - 0x3c = 0x21/33) 0xffffff80003a6334 - 0x13f = 0xffffff80003a61f5 0xffffffff - (0xfffffe73 - 0x01) = 0x18d // case 34 (0x5e - 0x3c = 0x22/34) 0xffffff80003a6334 - 0x18d = 0xffffff80003a61a7
Now we have the offsets and type of processors. And they all match. You can check that yourself below – this is a code snippet of _xcpm_bootstrap in the High Sierra kernel:
ffffff80003a6173 movl %ebx, %eax ffffff80003a6175 addb $-0x3c, %al ffffff80003a6177 cmpb $0x22, %al ffffff80003a6179 ja 0xffffff80003a619d ffffff80003a617b movzbl %al, %eax ffffff80003a617e leaq 0x1af(%rip), %rcx ffffff80003a6185 movslq (%rcx,%rax,4), %rax ffffff80003a6189 addq %rcx, %rax ffffff80003a618c jmpq *%rax ffffff80003a618e movl $0x4, _xcpm_hwp_idle_epp(%rip) // case 0: 0x3c = HASWELL ffffff80003a6198 jmp 0xffffff80003a6249 ffffff80003a619d cmpb $-0x72, %bl // 0x8e = KABYLAKE ffffff80003a61a0 je 0xffffff80003a6204 ffffff80003a61a2 cmpb $-0x62, %bl // 0x9e = KABYLAKE_DT ffffff80003a61a5 jne 0xffffff80003a61f5 ffffff80003a61a7 movq 0x752fa2(%rip), %rdi // case 34: 0x5E - SKYLAKE_DT and KABYLAKE_DT ffffff80003a61ae testq %rdi, %rdi ffffff80003a61b1 jne 0xffffff80003a61c8 ffffff80003a61b3 movq 0x729ed6(%rip), %rax ffffff80003a61ba movq 0x488(%rax), %rdi ffffff80003a61c1 movq %rdi, 0x752f88(%rip) ffffff80003a61c8 addq $0x2, %rdi ffffff80003a61cc movl $0x2, %esi ffffff80003a61d1 callq 0xffffff800037e070 ffffff80003a61d6 orl $0x4000, %eax ffffff80003a61db movzwl %ax, %eax ffffff80003a61de cmpl $0x5910, %eax ffffff80003a61e3 jne 0xffffff80003a62a1 ffffff80003a61e9 movl $0x2000, _xcpm_hwp_idle_epp(%rip) ffffff80003a61f3 jmp 0xffffff80003a621a ffffff80003a61f5 movl $0x0, 0x6f8aa9(%rip) // case 33: exit ffffff80003a61ff jmp 0xffffff80003a6329 ffffff80003a6204 movl $0x200, _xcpm_hwp_idle_epp(%rip) // case 18: 0x4e = SKYLAKE and KABYLAKE ffffff80003a620e jmp 0xffffff80003a621a ffffff80003a6210 movl $0x80, _xcpm_hwp_idle_epp(%rip) // case 1: 0x3d = BROADWELL ffffff80003a621a movl $0x1, 0x689cf0(%rip) ffffff80003a6224 jmp 0xffffff80003a62b5 ffffff80003a6229 movl $0x10, _xcpm_hwp_idle_epp(%rip) // case 9: 0x45 = HASWELL_ULT ffffff80003a6233 movl $0x1, 0x689cd7(%rip) ffffff80003a623d jmp 0xffffff80003a6249 ffffff80003a623f movl $0x8, _xcpm_hwp_idle_epp(%rip) // case 10: 0x46 = CRYSTALWELL ffffff80003a6249 movl $0x1, 0x689cc9(%rip) ffffff80003a6253 movq $0x0, 0x689d32(%rip) ffffff80003a625e jmp 0xffffff80003a62b5 ffffff80003a6260 movl $0x40, _xcpm_hwp_idle_epp(%rip) // case 11: 0x47 = BROADWELL_H ffffff80003a626a jmp 0xffffff80003a62b5 ffffff80003a626c movl $0x4000, _xcpm_hwp_idle_epp(%rip) // case 25: 0x55 = SKYLAKE_X ffffff80003a6276 movl $0x0, 0x689c94(%rip) ffffff80003a6280 movq $0x989680, 0x689c35(%rip) ffffff80003a628b movl $0x1, 0x689de3(%rip) ffffff80003a6295 movl $0x1, _xcpm_ubpc_enabled(%rip) ffffff80003a629f jmp 0xffffff80003a62b5 ffffff80003a62a1 movl $0x1000, _xcpm_hwp_idle_epp(%rip) ffffff80003a62ab movl $0x0, 0x689c5f(%rip) ffffff80003a62b5 incl _xcpm_bootstrap_count(%rip) ffffff80003a62bb leaq 0x5d1fa1(%rip), %rdi ## literal pool for: "-xcpm" ffffff80003a62c2 leaq -0x14(%rbp), %rsi ffffff80003a62c6 movl $0x4, %edx ffffff80003a62cb xorl %ecx, %ecx ffffff80003a62cd callq 0xffffff80008ff2c0 ffffff80003a62d2 movl $0x1, 0x6f89cc(%rip) ffffff80003a62dc leaq 0x5d1f86(%rip), %rdi ## literal pool for: "-xcpm_assert" ffffff80003a62e3 leaq _xcpm_assert_enable(%rip), %rsi ffffff80003a62ea movl $0x4, %edx ffffff80003a62ef xorl %ecx, %ecx ffffff80003a62f1 callq 0xffffff80008ff2c0 ffffff80003a62f6 leaq 0x5d1f79(%rip), %rdi ## literal pool for: "-xcpm_assert_trace" ffffff80003a62fd leaq _xcpm_assert_trace(%rip), %rsi ffffff80003a6304 movl $0x4, %edx ffffff80003a6309 xorl %ecx, %ecx ffffff80003a630b callq 0xffffff80008ff2c0 ffffff80003a6310 movl 0x190(%r14), %eax ffffff80003a6317 cmpl 0x194(%r14), %eax ffffff80003a631e sbbl %eax, %eax ffffff80003a6320 andl $0x1, %eax ffffff80003a6323 movl %eax, _xcpm_SMT_platform(%rip) ffffff80003a6329 addq $0x10, %rsp ffffff80003a632d popq %rbx ffffff80003a632e popq %r14 ffffff80003a6330 popq %rbp ffffff80003a6331 retq
The next step is to combine the data and merge it into another table.
Note: If you don’t understand what we do here, then follow the link at the top of this blog article.
Note the new one in the above table. But wait. Let’s make another table. One that shows you what it is:
Well. Wasn’t that easy?
The next time I will do the same for _cpuid_set_info. That one is even more interesting, but I ran out of time…
Edit: It’s nice that the High Sierra kernel supports the Skylake X processor, and it works, but they do lack support for ECC memory, so it isn’t immediately clear why Apple did this. I mean. It cannot, as it stands right now, with the currently available Intel processors, be for the iMac Pro. My best guess is that it will be used for a new / updated Apple product. Presumably also for the yet to be released Xeon processors that will be used in the iMac Pro.
Yes of course. The Kabylake (0x8e) and Kabylake desktop (0x9e) processors are also supported, but Apple isn’t using the switch table for these. They may add it at a later date, but right now, they use simple cmp’s for it. One thing though. There is an additional check for 0x5910 for the Kabylake desktop parts. Note that 0x5912 (one example) is a Kabylake with IGPU.
p.s. I don’t have a hack handy right now (only my MacBook Pro) so I cannot verify if the Skylake X is using 0x5910 or some other processor is using it. Any takers?
Update:
I checked a data sheet of the Intel® Xeon® Processor Scalable family and they also use 0x55 to identify the processor model (CPUID 0x5065x). The only difference is that the stepping ID is either two or four. Not zero.
In other words. Apple could, in theory, use the big Xeon’s after all. Maybe only for the next Mac Pro, but we don’t know that. Only Apple could tell us that, and we all know this, that is never going to happen. That is why I have decided to have a closer look at the used Microcode. That should help.
Update-2: I checked the Intel microcode in the accidentally released firmware and found 0x50652 (stepping B-0) and that is definitely not a Skylake X processor – the B-0 stepping of the Intel® Xeon® Processor Scalable Family is CPUID 0x50652 and the H-0 stepping 0x50654.
haha easy? I’m completely ignorant about this sort of thing, but…
I have an X299 i7-7900x hack with no kext or kernel patches running, only npci 2000 in boot args and it’s running with full speedstep, all USB ports and HDMI sound. So I guess that supports your findings 🙂
Not exactly. I did test the Intel i9-7900X and what you see may not be what you think that it is. Just take a look at the output of AppleIntelInfo.kext and you’ll be surprised.
Edit: What I was trying to say was that what you are seeing is HWP at work. Not XCPM. For that you need boot argument xcpm=1 with a supported board-id (for the plist) or a patched plist. If you select a board-id that doesn’t set HWP to enable, or not do that from the boot loader, then nothing flies anymore.
Did they also lifted the pointless CPU CORE Max limit in there by any chance? 🙂
I checked the firmware yesterday and found a limit (check) for 64 cores so I guess not.
Thank you very much. I guess back at the drawing board with that 🙂
If they raise the limit we could see something like this in a desktop or mobile device.
https://www.parallella.org/2016/10/05/epiphany-v-a-1024-core-64-bit-risc-processor/
Hey piker,
So if there is the correct jump for 0x55 then do have any guess why I can’t boot with my Skylake-X 7820x? I am stuck at the pluses with no errors if I don’t use a fakecpuid.
Any idea how to debug this?
Thank you.
I tried to see what happens in the kernel, but whit no fakecpuid, the kernel is not even loaded (after debugmachkernel, no output), with fakecpuid, there is output, starting from === system boot.
So what happens before kernel is loaded? boot.efi? can that disable the cpu?
Hey so on 10.13 in this file:
https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/i386/cpuid.h.auto.html
The skylake_w (or x) cpuid is behind a condition check, do you anything about this?
This looks like a toggle to create a special build for imac pro, and only include it in that build. I guess there is no way around this, until this drops down to normal builds.