Exemple #1
0
/*
 * Initialize page tables for the lpae case
 */
void
init_mmu_lpae(void)
{
	unsigned	base;
	unsigned	ncpu = lsp.syspage.p->num_cpu;
	unsigned	l1_size = ncpu * ARM_LPAE_L1_SIZE;

	// Get the CPU-specific PTE descriptors - Not implemented for A15 under LPAE...
	arm_pte_setup();

	// As paddr == vaddr in startup, we require the L1/L2 tables to be allocated from memory < 4G
	// However, if calloc_ram ever starts handing out high memory, things will promptly stop working.
	// It will not be a subtle failure.

	// LPAE L1 table is only 32 bytes per cpu.  (So we can only get 512 on a single page!)
	L1_paddr = calloc_ram(l1_size, __PAGESIZE);

	if (debug_flag) {
		kprintf("LPAE: %s:%d allocated 0x%x bytes at 0x%x for L1 page table\n", __func__, __LINE__, l1_size, L1_paddr);
	}
	
	// One page per cpu for kernel L2; three pages for user L2, shared between cpus
	// We allocate user and kernel l2 pages together so we can pass both to procnto with one param
	L2_size = (ncpu * ARM_LPAE_L2_SIZE) + ARM_LPAE_USER_L2_SIZE;
	L2_paddr = calloc_ram(L2_size, __PAGESIZE);

	if (debug_flag) {
		kprintf("LPAE: %s:%d allocated 0x%x bytes at 0x%x for L2 page tables\n", __func__, __LINE__, L2_size, L2_paddr);
	}
	
	// Init the L1/L2 tables and make the kernel L2/L3 tables accessible at the specified vaddrs
	// This function uses the above globals directly; doesn't need them as params.
	arm_lpae_table_init(ARM_LPAE_KERN_L2, ARM_LPAE_KERN_L3);
	
	// Map the L1 table into virtual space
	L1_vaddr = arm_map(~0L, L1_paddr, l1_size, ARM_MAP_NOEXEC | ARM_PTE_RW | armv_chip->pte_attr);

	// Block map startup code to allow transition to virtual addresses.
	// This 1-1 mapping is also used by kdebug to access the imagefs.
	// procnto uses syspage->un.arm.startup_base/startup_size to unmap it.
	// Under LPAE we use 2MB blocks instead of v6 1MB sections

	startup_base = shdr->ram_paddr & ~ARM_LPAE_BMASK;
	startup_size = shdr->ram_size;
	for (base = startup_base; base < startup_base + startup_size; base += ARM_LPAE_BSIZE) {
		arm_lpae_bmap(base, base, ARM_PTE_RO);
	}

	/*
	 * Map RAM into the 1-1 mapping area
	 */
	lpae_map_1to1_ram();

	if (debug_flag>2) {
		kprintf("%s dump table\n", __func__);
	    dump_ptbl();
		kprintf("%s dump table done\n", __func__);
	}
		
}
Exemple #2
0
/*
 * Initialize page tables for the non-lpae case.
 */
void
init_mmu_32(void)
{
	unsigned	base;
	unsigned	ncpu = lsp.syspage.p->num_cpu;
	unsigned	L1size = ncpu * ARM_L1_SIZE;

	L2_size = ncpu * __PAGESIZE;

	/*
	 * Get the CPU-specific PTE descriptors
	 */
	arm_pte_setup();

	/*
	 * Allocate the L1 table and the "page directory" used to map L2 tables
	 */
	L1_paddr = calloc_ram(L1size, ARM_L1_SIZE);
	L2_paddr = calloc_ram(L2_size, __PAGESIZE);

	/*
	 * Make these tables accessible at vaddr ARM_PTP_BASE
	 * This function uses the above globals directly; doesn't need them as params.
	 */
	arm_pdmap(ARM_PTP_BASE);

	/*
	 * Map the real L1 table
	 */
	L1_vaddr = arm_map(~0L, L1_paddr, L1size, ARM_MAP_NOEXEC | ARM_PTE_RW | armv_chip->pte_attr);
	L1_paddr |= armv_chip->ttb_attr;

	/*
	 * Section map startup code to allow transition to virtual addresses.
	 * This 1-1 mapping is also used by kdebug to access the imagefs.
	 * procnto uses syspage->un.arm.startup_base/startup_size to unmap it.
	 */
	startup_base = shdr->ram_paddr & ~ARM_SCMASK;
	startup_size = shdr->ram_size;
	for (base = startup_base; base < startup_base + startup_size; base += ARM_SCSIZE) {
		arm_scmap(base, base, ARM_PTE_RO);
	}

	/*
	 * Map RAM into the 1-1 mapping area
	 */
	map_1to1_ram();
}
Exemple #3
0
void *
callout_memory_map(unsigned size, paddr_t phys, unsigned prot_flags)
{
    int	pf = ARM_PTE_RO | ARM_PTE_CB;

    if (prot_flags & PROT_WRITE)
        pf |= ARM_PTE_RW;
    if (prot_flags & PROT_USER)
        pf |= ARM_PTE_U;
    if (prot_flags & PROT_NOCACHE)
        pf &= ~ARM_PTE_CB;

    /*
     * FIXME: should this check if the range is already mapped?
     */
    return (void *)arm_map(~0, phys, size, pf);
}
/*
 * On ARMv7 callout_io_map() will set memory attributes to strongly ordered
 * (assuming armv_pte_v7mp.mask_nc = ARM_PTE_CB | ARM_PTE_V6_SP_TEX_MASK).
 * For ARMv7 "shareable device" memory type add ARM_PTE_B bit:
 */
uintptr_t
callout_io_map_armv7_dev(unsigned size, paddr_t phys)
{
	return arm_map(~0, phys, size, ARM_PTE_RW | ARM_MAP_NOEXEC | ARM_PTE_B);
}