arch/x86/kernel/cpu/microcode/intel.c

Source file repositories/reference/linux-study-clean/arch/x86/kernel/cpu/microcode/intel.c

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/cpu/microcode/intel.c
Extension
.c
Size
27479 bytes
Lines
1053
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct extended_signature {
	unsigned int	sig;
	unsigned int	pf;
	unsigned int	cksum;
};

struct extended_sigtable {
	unsigned int			count;
	unsigned int			cksum;
	unsigned int			reserved[3];
	struct extended_signature	sigs[];
};

/**
 * struct staging_state - Track the current staging process state
 *
 * @mmio_base:		MMIO base address for staging
 * @ucode_len:		Total size of the microcode image
 * @chunk_size:		Size of each data piece
 * @bytes_sent:		Total bytes transmitted so far
 * @offset:		Current offset in the microcode image
 */
struct staging_state {
	void __iomem		*mmio_base;
	unsigned int		ucode_len;
	unsigned int		chunk_size;
	unsigned int		bytes_sent;
	unsigned int		offset;
};

#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
#define EXT_HEADER_SIZE		(sizeof(struct extended_sigtable))
#define EXT_SIGNATURE_SIZE	(sizeof(struct extended_signature))

static inline unsigned int get_totalsize(struct microcode_header_intel *hdr)
{
	return hdr->datasize ? hdr->totalsize : DEFAULT_UCODE_TOTALSIZE;
}

static inline unsigned int exttable_size(struct extended_sigtable *et)
{
	return et->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE;
}


/*
 * Use CPUID to generate a "vfm" value. Useful before cpuinfo_x86
 * structures are populated.
 */
static u32 intel_cpuid_vfm(void)
{
	u32 eax   = cpuid_eax(1);
	u32 fam   = x86_family(eax);
	u32 model = x86_model(eax);

	return IFM(fam, model);
}

u32 intel_get_platform_id(void)
{
	unsigned int val[2];

	if (x86_hypervisor_present)
		return 0;

	/*
	 * This can be called early. Use CPUID directly instead of
	 * relying on cpuinfo_x86 which may not be fully initialized.
	 * The PII does not have MSR_IA32_PLATFORM_ID. Everything
	 * before _it_ has no microcode (for Linux at least).
	 */
	if (intel_cpuid_vfm() <= INTEL_PENTIUM_II_KLAMATH)
		return 0;

	/* get processor flags from MSR 0x17 */
	native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);

	return (val[1] >> 18) & 7;
}

void intel_collect_cpu_info(struct cpu_signature *sig)
{
	sig->sig = cpuid_eax(1);
	sig->rev = intel_get_microcode_revision();
	sig->pf  = 1 << intel_get_platform_id();
}
EXPORT_SYMBOL_GPL(intel_collect_cpu_info);

static inline bool cpu_signatures_match(struct cpu_signature *s1, unsigned int sig2,
					unsigned int pf2)

Annotation

Implementation Notes