arch/arm/mm/pmsa-v8.c

Source file repositories/reference/linux-study-clean/arch/arm/mm/pmsa-v8.c

File Facts

System
Linux kernel
Corpus path
arch/arm/mm/pmsa-v8.c
Extension
.c
Size
6835 bytes
Lines
309
Domain
Architecture Layer
Bucket
arch/arm
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

if (first) {
			phys_addr_t phys_offset = PHYS_OFFSET;

			/*
			 * Initially only use memory continuous from
			 * PHYS_OFFSET */
			if (reg_start != phys_offset)
				panic("First memory bank must be contiguous from PHYS_OFFSET");
			mem_end = reg_end;
			first = false;
		} else {
			/*
			 * memblock auto merges contiguous blocks, remove
			 * all blocks afterwards in one go (we can't remove
			 * blocks separately while iterating)
			 */
			pr_notice("Ignoring RAM after %pa, memory at %pa ignored\n",
				  &mem_end, &reg_start);
			memblock_remove(reg_start, 0 - reg_start);
			break;
		}
	}
}

static int __init __mpu_max_regions(void)
{
	static int max_regions;
	u32 mpuir;

	if (max_regions)
		return max_regions;

	mpuir = read_cpuid_mputype();

	max_regions  = (mpuir & MPUIR_DREGION_SZMASK) >> MPUIR_DREGION;

	return max_regions;
}

static int __init __pmsav8_setup_region(unsigned int number, u32 bar, u32 lar)
{
	if (number > mpu_max_regions
	    || number >= MPU_MAX_REGIONS)
		return -ENOENT;

	dsb();
	prsel_write(number);
	isb();
	prbar_write(bar);
	prlar_write(lar);

	mpu_rgn_info.rgns[number].prbar = bar;
	mpu_rgn_info.rgns[number].prlar = lar;

	mpu_rgn_info.used++;

	return 0;
}

static int __init pmsav8_setup_ram(unsigned int number, phys_addr_t start,phys_addr_t end)
{
	u32 bar, lar;

	if (is_region_fixed(number))
		return -EINVAL;

	bar = start;
	lar = (end - 1) & ~(PMSAv8_MINALIGN - 1);

	bar |= PMSAv8_AP_PL1RW_PL0RW | PMSAv8_RGN_SHARED;
	lar |= PMSAv8_LAR_IDX(PMSAv8_RGN_NORMAL) | PMSAv8_LAR_EN;

	return __pmsav8_setup_region(number, bar, lar);
}

static int __init pmsav8_setup_io(unsigned int number, phys_addr_t start,phys_addr_t end)
{
	u32 bar, lar;

	if (is_region_fixed(number))
		return -EINVAL;

	bar = start;
	lar = (end - 1) & ~(PMSAv8_MINALIGN - 1);

	bar |= PMSAv8_AP_PL1RW_PL0RW | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN;
	lar |= PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN;

	return __pmsav8_setup_region(number, bar, lar);
}

Annotation

Implementation Notes