do not edit — generated by btf.
git.druid.rocksindexdruid520kaboomsrc/drivers/cpu.nsc

src/drivers/cpu.nsc


/*
 * cpu identification via the cpuid instruction (cpu_asm.s). vendor and
 * brand strings only -- no feature-flag decoding (leaf 1's edx/ecx
 * bits, leaf 7's ebx/ecx/edx, ...), matching this kernel's own "ship
 * the real minimal version" pattern; extend if something ever needs a
 * specific flag rather than building a whole bitfield table nothing
 * reads yet.
 */
 
void cpuid(u32 leaf, ptr out);
 
void
cpu_byte_set(ptr base, u64 index, u8 val)
{
	u64 wordoff;
	u64 byteoff;
	u64 word;
 
	wordoff = index & ~(u64)7;
	byteoff = index & (u64)7;
	word = (u64)*(base + wordoff);
	word = word & ~((u64)0xff << (byteoff * (u64)8));
	word = word | ((u64)val << (byteoff * (u64)8));
	*(base + wordoff) = (i64)word;
}
 
/* unpacks one cpuid result register (a full zero-extended 8-byte word
 * here -- see cpu_asm.s) into 4 ascii bytes at dst[dst_off..+3],
 * little-endian (the byte order cpuid's own register-as-string
 * convention always uses, for both the vendor and brand strings). */
void
cpu_copy_reg_bytes(ptr dst, u64 dst_off, u64 reg)
{
	u64 i;
	u8 b;
 
	i = 0;
	while(i < (u64)4)
	{
		b = (u8)((reg >> (i * (u64)8)) & (u64)0xff);
		cpu_byte_set(dst, dst_off + i, b);
		i = i + (u64)1;
	}
}
 
/* fills buf (room for 13 bytes) with the 12-char vendor id string
 * ("GenuineIntel", "AuthenticAMD", "TCGTCGTCGTCG" under plain qemu
 * tcg, ...) plus a null terminator. cpuid leaf 0's own well-known
 * quirk: the string's bytes come back in ebx,edx,ecx register order,
 * not the eax,ebx,ecx,edx order every other multi-register cpuid
 * result (including the brand string below) uses. */
global void
cpu_vendor(ptr buf)
{
	i8 result[32];
	ptr r;
 
	cpuid((u32)0, &result[0]);
	r = &result[0];
	cpu_copy_reg_bytes(buf, (u64)0, (u64)*(r + 8));  /* ebx */
	cpu_copy_reg_bytes(buf, (u64)4, (u64)*(r + 24)); /* edx */
	cpu_copy_reg_bytes(buf, (u64)8, (u64)*(r + 16)); /* ecx */
	cpu_byte_set(buf, (u64)12, (u8)0);
}
 
/* fills buf (room for 49 bytes) with the 48-char brand string
 * ("Intel(R) Core(TM) ...", often space-padded by the cpu itself)
 * plus a null terminator, from cpuid's 3 extended leaves
 * (0x80000002-0x80000004), each contributing 16 bytes in normal
 * eax,ebx,ecx,edx order. doesn't check leaf 0x80000000's own max-leaf
 * return first -- every cpu qemu emulates supports these, and a real
 * cpu old enough not to would have failed this kernel's boot far
 * earlier for unrelated reasons. */
global void
cpu_brand(ptr buf)
{
	i8 result[32];
	ptr r;
	u64 off;
	u32 leaf;
	i32 li;
 
	r = &result[0];
	off = 0;
	li = 0;
	while(li < 3)
	{
		leaf = (u32)(0x80000002 + li);
		cpuid(leaf, r);
		cpu_copy_reg_bytes(buf, off, (u64)*(r + 0));
		off = off + (u64)4;
		cpu_copy_reg_bytes(buf, off, (u64)*(r + 8));
		off = off + (u64)4;
		cpu_copy_reg_bytes(buf, off, (u64)*(r + 16));
		off = off + (u64)4;
		cpu_copy_reg_bytes(buf, off, (u64)*(r + 24));
		off = off + (u64)4;
		li = li + 1;
	}
	cpu_byte_set(buf, off, (u8)0);
}
powered by btf.