Beispiel #1
0
phys_bytes pg_load()
{
	phys_bytes phpagedir = vir2phys(pagedir);
	refresh_tlb();
        write_ttbr0(phpagedir);
	return phpagedir;
}
Beispiel #2
0
static void set_ttbr(struct proc *p, u32_t ttbr, u32_t *v)
{
	/* Set process TTBR. */
	p->p_seg.p_ttbr = ttbr;
	assert(p->p_seg.p_ttbr);
	p->p_seg.p_ttbr_v = v;
	if(p == get_cpulocal_var(ptproc)) {
		write_ttbr0(p->p_seg.p_ttbr);
	}
	if(p->p_nr == VM_PROC_NR) {
		if (arch_enable_paging(p) != OK)
			panic("arch_enable_paging failed");
	}
	RTS_UNSET(p, RTS_VMINHIBIT);
}
Beispiel #3
0
void tee_mmu_switch(uint32_t ttbr0_base, uint32_t ctxid)
{
	uint32_t cpsr = read_cpsr();

	/* Disable interrupts */
	write_cpsr(cpsr | CPSR_FIA);

	/*
	 * Update the reserved Context ID and TTBR0
	 */

	dsb();	/* ARM erratum 754322 */
	write_contextidr(0);
	isb();

	write_ttbr0(ttbr0_base);
	isb();

	write_contextidr(ctxid & 0xff);
	isb();

	/* Restore interrupts */
	write_cpsr(cpsr);
}
Beispiel #4
0
void arm_mmu_setup(void)
{
	u32 s, sec, sec_tmpl = 0x0, sec_start = 0x0, sec_end = 0x0;
	u32 sctlr = read_sctlr();

	/* If MMU already enabled then return */
	if (sctlr & SCTLR_M_MASK) {
		return;
	}

	/* Reset memory for L2 */
	for (sec = 0; sec < (TTBL_L2TBL_SIZE / 4); sec++) {
		l2[sec] = 0x0;
	}

	/* Reset memory for L1 */
	for (sec = 0; sec < (TTBL_L1TBL_SIZE / 4); sec++) {
		l1[sec] = 0x0;
	}

	/* Section entry template for code */
	sec_tmpl = 0x0;
	sec_tmpl |= (TTBL_L1TBL_TTE_DOM_CHECKAP << TTBL_L1TBL_TTE_DOM_SHIFT);
	sec_tmpl |= (TTBL_AP_SRW_URW << TTBL_L1TBL_TTE_AP_SHIFT);
	sec_tmpl |= TTBL_L1TBL_TTE_C_MASK;
	sec_tmpl |= TTBL_L1TBL_TTE_TYPE_SECTION;

	/* Create section entries for code */
	sec_start = ((u32)&_code_start) & ~(TTBL_L1TBL_SECTION_PAGE_SIZE - 1);
	sec_end = ((u32)&_code_end) & ~(TTBL_L1TBL_SECTION_PAGE_SIZE - 1);
	for (sec = sec_start; 
	     sec <= sec_end; 
	     sec += TTBL_L1TBL_SECTION_PAGE_SIZE) {
		l1[sec / TTBL_L1TBL_SECTION_PAGE_SIZE] = sec_tmpl | sec;
	}
	sec_end += TTBL_L1TBL_SECTION_PAGE_SIZE;

	/* Creation section entries for exception vectors */
	if (sec_start > 0x0) {
		l1[0] = sec_tmpl | 0x0;
	}

	/* Map an additional section after code */
	sec = sec_end;
	l1[sec / TTBL_L1TBL_SECTION_PAGE_SIZE] = sec_tmpl | sec;
	sec_end += TTBL_L1TBL_SECTION_PAGE_SIZE;

	/* Section entry template for I/O */
	sec_tmpl &= ~TTBL_L1TBL_TTE_C_MASK;
	sec_tmpl |= TTBL_L1TBL_TTE_XN_MASK;

	/* Create section entries for IO */
	for (s = 0; s < arm_board_iosection_count(); s++) {
		sec = arm_board_iosection_addr(s) & 
				~(TTBL_L1TBL_SECTION_PAGE_SIZE - 1);
		l1[sec / TTBL_L1TBL_SECTION_PAGE_SIZE] = sec_tmpl | sec;
	}

	/* Map an l2 table after (code + additional section) */
	sec_tmpl = 0x0;
	sec_tmpl |= TTBL_L1TBL_TTE_TYPE_L2TBL;
	l2_mapva = sec_end;
	l1[l2_mapva / TTBL_L1TBL_SECTION_PAGE_SIZE] = sec_tmpl | (u32)(&l2);

	/* Setup test area in physical RAM */
	test_area_pa = sec_end;
	test_area_size = TTBL_L1TBL_SECTION_PAGE_SIZE;

	/* Write DACR */
	sec = 0x0;
	sec |= (TTBL_DOM_CLIENT << (2 * TTBL_L1TBL_TTE_DOM_CHECKAP));
	sec |= (TTBL_DOM_MANAGER << (2 * TTBL_L1TBL_TTE_DOM_BYPASSAP));
	sec |= (TTBL_DOM_NOACCESS << (2 * TTBL_L1TBL_TTE_DOM_NOACCESS));
	write_dacr(sec);

	/* Write TTBR0 */
	write_ttbr0((u32)&l1);

	/* Enable MMU */
	sctlr |= SCTLR_M_MASK;
	write_sctlr(sctlr);

	return;
}
Beispiel #5
0
/*
 * For coreboot's purposes, we will create a simple identity map.
 *
 * If LPAE is disabled, we will create a L1 page
 * table in RAM with 1MB section translation entries over the 4GB address space.
 * (ref: section 10.2 and example 15-4 in Cortex-A series programmer's guide)
 *
 * If LPAE is enabled, we do two level translation with one L1 table with 4
 * entries, each covering a 1GB space, and four L2 tables with 512 entries, each
 * covering a 2MB space.
 */
void mmu_init(void)
{
        if (CONFIG_ARM_LPAE) {
                pgd_t *const pgd_buff = (pgd_t*)(CONFIG_TTB_BUFFER + 16*KiB);
                pmd_t *pmd = ttb_buff;
                int i;

                printk(BIOS_DEBUG, "LPAE Translation tables are @ %p\n",
                		ttb_buff);
                ASSERT((read_mmfr0() & 0xf) >= 5);

                /*
                 * Set MAIR
                 * See B4.1.104 of ARMv7 Architecture Reference Manual
                 */
                write_mair0(
                        0x00 << (MAIR_INDX_NC*8) | /* Strongly-ordered,
                         	 	 	    * Non-Cacheable */
                        0xaa << (MAIR_INDX_WT*8) | /* Write-Thru,
                         	 	 	    * Read-Allocate */
                        0xff << (MAIR_INDX_WB*8)   /* Write-Back,
                         	 	 	    * Read/Write-Allocate */
                        );

                /*
                 * Set up L1 table
                 * Once set here, L1 table won't be modified by coreboot.
                 * See B3.6.1 of ARMv7 Architecture Reference Manual
                 */
                for (i = 0; i < 4; i++) {
                        pgd_buff[i] = ((uint32_t)pmd & PAGE_MASK) |
                                3;	/* 0b11: valid table entry */
                        pmd += BLOCK_SIZE / PAGE_SIZE;
                }

                /*
                 * Set TTBR0
                 */
                write_ttbr0((uintptr_t)pgd_buff);
        } else {
                printk(BIOS_DEBUG, "Translation table is @ %p\n", ttb_buff);

                /*
                 * Translation table base 0 address is in bits 31:14-N, where N
                 * is given by bits 2:0 in TTBCR (which we set to 0). All lower
                 * bits in this register should be zero for coreboot.
                 */
                write_ttbr0((uintptr_t)ttb_buff);
        }

	/*
	 * Set TTBCR
	 * See B4.1.153 of ARMv7 Architecture Reference Manual
	 * See B3.5.4 and B3.6.4 for how TTBR0 or TTBR1 is selected.
	 */
	write_ttbcr(
		CONFIG_ARM_LPAE << 31 |	/* EAE. 1:Enable LPAE */
		0 << 16 | 0 << 0	/* Use TTBR0 for all addresses */
		);

	/* disable domain-level checking of permissions */
	write_dacr(~0);
}