arch/powerpc/kernel/dt_cpu_ftrs.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/dt_cpu_ftrs.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/dt_cpu_ftrs.c
Extension
.c
Size
27633 bytes
Lines
1129
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source 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 dt_cpu_feature {
	const char *name;
	uint32_t isa;
	uint32_t usable_privilege;
	uint32_t hv_support;
	uint32_t os_support;
	uint32_t hfscr_bit_nr;
	uint32_t fscr_bit_nr;
	uint32_t hwcap_bit_nr;
	/* fdt parsing */
	unsigned long node;
	int enabled;
	int disabled;
};

#define MMU_FTRS_HASH_BASE (MMU_FTRS_POWER8)

#define COMMON_USER_BASE	(PPC_FEATURE_32 | PPC_FEATURE_64 | \
				 PPC_FEATURE_ARCH_2_06 |\
				 PPC_FEATURE_ICACHE_SNOOP)
#define COMMON_USER2_BASE	(PPC_FEATURE2_ARCH_2_07 | \
				 PPC_FEATURE2_ISEL)
/*
 * Set up the base CPU
 */

static int hv_mode;

static struct {
	u64	lpcr;
	u64	hfscr;
	u64	fscr;
	u64	pcr;
} system_registers;

static void (*init_pmu_registers)(void);

static void __restore_cpu_cpufeatures(void)
{
	mtspr(SPRN_LPCR, system_registers.lpcr);
	if (hv_mode) {
		mtspr(SPRN_LPID, 0);
		mtspr(SPRN_AMOR, ~0);
		mtspr(SPRN_HFSCR, system_registers.hfscr);
		mtspr(SPRN_PCR, system_registers.pcr);
	}
	mtspr(SPRN_FSCR, system_registers.fscr);

	if (init_pmu_registers)
		init_pmu_registers();
}

static char dt_cpu_name[64];

static struct cpu_spec __initdata base_cpu_spec = {
	.cpu_name		= NULL,
	.cpu_features		= CPU_FTRS_DT_CPU_BASE,
	.cpu_user_features	= COMMON_USER_BASE,
	.cpu_user_features2	= COMMON_USER2_BASE,
	.mmu_features		= 0,
	.icache_bsize		= 32, /* minimum block size, fixed by */
	.dcache_bsize		= 32, /* cache info init.             */
	.num_pmcs		= 0,
	.pmc_type		= PPC_PMC_DEFAULT,
	.cpu_setup		= NULL,
	.cpu_restore		= __restore_cpu_cpufeatures,
	.machine_check_early	= NULL,
	.platform		= NULL,
};

static void __init cpufeatures_setup_cpu(void)
{
	set_cur_cpu_spec(&base_cpu_spec);

	cur_cpu_spec->pvr_mask = -1;
	cur_cpu_spec->pvr_value = mfspr(SPRN_PVR);

	/* Initialize the base environment -- clear FSCR/HFSCR.  */
	hv_mode = !!(mfmsr() & MSR_HV);
	if (hv_mode) {
		cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
		mtspr(SPRN_HFSCR, 0);
	}
	mtspr(SPRN_FSCR, 0);
	mtspr(SPRN_PCR, PCR_MASK);

	/*
	 * LPCR does not get cleared, to match behaviour with secondaries
	 * in __restore_cpu_cpufeatures. Once the idle code is fixed, this
	 * could clear LPCR too.

Annotation

Implementation Notes