arch/powerpc/kernel/prom.c

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

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/prom.c
Extension
.c
Size
28600 bytes
Lines
1049
Domain
Architecture Layer
Bucket
arch/powerpc
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 ibm_feature {
	unsigned long	cpu_features;	/* CPU_FTR_xxx bit */
	unsigned long	mmu_features;	/* MMU_FTR_xxx bit */
	unsigned int	cpu_user_ftrs;	/* PPC_FEATURE_xxx bit */
	unsigned int	cpu_user_ftrs2;	/* PPC_FEATURE2_xxx bit */
	unsigned char	pabyte;		/* byte number in ibm,pa/pi-features */
	unsigned char	pabit;		/* bit number (big-endian) */
	unsigned char	clear;		/* if 1, pa bit set => clear feature */
};

static struct ibm_feature ibm_pa_features[] __initdata = {
	{ .pabyte = 0,  .pabit = 0, .cpu_user_ftrs = PPC_FEATURE_HAS_MMU },
	{ .pabyte = 0,  .pabit = 1, .cpu_user_ftrs = PPC_FEATURE_HAS_FPU },
	{ .pabyte = 0,  .pabit = 3, .cpu_features  = CPU_FTR_CTRL },
	{ .pabyte = 0,  .pabit = 6, .cpu_features  = CPU_FTR_NOEXECUTE },
	{ .pabyte = 1,  .pabit = 2, .mmu_features  = MMU_FTR_CI_LARGE_PAGE },
#ifdef CONFIG_PPC_RADIX_MMU
	{ .pabyte = 40, .pabit = 0, .mmu_features  = MMU_FTR_TYPE_RADIX | MMU_FTR_GTSE },
#endif
	{ .pabyte = 5,  .pabit = 0, .cpu_features  = CPU_FTR_REAL_LE,
				    .cpu_user_ftrs = PPC_FEATURE_TRUE_LE },
	/*
	 * If the kernel doesn't support TM (ie CONFIG_PPC_TRANSACTIONAL_MEM=n),
	 * we don't want to turn on TM here, so we use the *_COMP versions
	 * which are 0 if the kernel doesn't support TM.
	 */
	{ .pabyte = 22, .pabit = 0, .cpu_features = CPU_FTR_TM_COMP,
	  .cpu_user_ftrs2 = PPC_FEATURE2_HTM_COMP | PPC_FEATURE2_HTM_NOSC_COMP },

	{ .pabyte = 64, .pabit = 0, .cpu_features = CPU_FTR_DAWR1 },
	{ .pabyte = 68, .pabit = 5, .cpu_features = CPU_FTR_DEXCR_NPHIE },
};

/*
 * ibm,pi-features property provides the support of processor specific
 * options not described in ibm,pa-features. Right now use byte 0, bit 3
 * which indicates the occurrence of DSI interrupt when the paste operation
 * on the suspended NX window.
 */
static struct ibm_feature ibm_pi_features[] __initdata = {
	{ .pabyte = 0, .pabit = 3, .mmu_features  = MMU_FTR_NX_DSI },
	{ .pabyte = 0, .pabit = 4, .cpu_features  = CPU_FTR_DBELL, .clear = 1 },
};

static void __init scan_features(unsigned long node, const unsigned char *ftrs,
				 unsigned long tablelen,
				 struct ibm_feature *fp,
				 unsigned long ft_size)
{
	unsigned long i, len, bit;

	/* find descriptor with type == 0 */
	for (;;) {
		if (tablelen < 3)
			return;
		len = 2 + ftrs[0];
		if (tablelen < len)
			return;		/* descriptor 0 not found */
		if (ftrs[1] == 0)
			break;
		tablelen -= len;
		ftrs += len;
	}

	/* loop over bits we know about */
	for (i = 0; i < ft_size; ++i, ++fp) {
		if (fp->pabyte >= ftrs[0])
			continue;
		bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
		if (bit && !fp->clear) {
			cur_cpu_spec->cpu_features |= fp->cpu_features;
			cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
			cur_cpu_spec->cpu_user_features2 |= fp->cpu_user_ftrs2;
			cur_cpu_spec->mmu_features |= fp->mmu_features;
		} else if (bit == fp->clear) {
			cur_cpu_spec->cpu_features &= ~fp->cpu_features;
			cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
			cur_cpu_spec->cpu_user_features2 &= ~fp->cpu_user_ftrs2;
			cur_cpu_spec->mmu_features &= ~fp->mmu_features;
		}
	}
}

static void __init check_cpu_features(unsigned long node, char *name,
				      struct ibm_feature *fp,
				      unsigned long size)
{
	const unsigned char *pa_ftrs;
	int tablelen;

Annotation

Implementation Notes