| git.druid.rocks | index | druid520 | kaboom | src/ | drivers/ | cpu_asm.s |
src/drivers/cpu_asm.s
/*
* cpuid -- nsc has no inline asm (same gap as every other "needs a
* real instruction" driver here, see io.s's own note), so this is the
* one hand-written wrapper cpu.nsc calls through.
*
* cpuid(leaf: %edi, out: %rsi): sets eax=leaf, ecx=0 (no caller here
* ever needs a real subleaf), executes cpuid, and writes eax/ebx/ecx/
* edx as four zero-extended 8-byte words at out[0]/out[8]/out[16]/
* out[24] -- the same "every value crossing the asm/nsc boundary is a
* full 8-byte word" convention this whole kernel uses (nsc's `*p` is
* always a full 8-byte load/store, never 32-bit-granular). rbx is
* callee-saved per sysv and cpuid clobbers it, so it's the only
* register that needs saving here -- rsi (out) is never touched by
* cpuid itself.
*/
.section .text
.global cpuid
.type cpuid, @function
cpuid:
push %rbx
movl %edi, %eax
xorl %ecx, %ecx
cpuid
movq %rax, 0(%rsi)
movq %rbx, 8(%rsi)
movq %rcx, 16(%rsi)
movq %rdx, 24(%rsi)
pop %rbx
ret