Example #1
0
void vm_enable_paging(void)
{
        u32_t sctlr;

	write_ttbcr(0);

	/* Set all Domains to Client */
	write_dacr(0x55555555);

	sctlr = read_sctlr();

	/* Enable MMU */
	sctlr |= SCTLR_M;

	/* TRE set to zero (default reset value): TEX[2:0] are used, plus C and B bits.*/
	sctlr &= ~SCTLR_TRE;

	/* AFE set to zero (default reset value): not using simplified model. */
	sctlr &= ~SCTLR_AFE;

	/* Enable instruction and data cache */
	sctlr |= SCTLR_C;
	sctlr |= SCTLR_I;
	write_sctlr(sctlr);
}
Example #2
0
void vm_enable_paging(void)
{
        u32_t sctlr;

	write_ttbcr(0);

	/* Set all Domains to Client */
	write_dacr(0x55555555);

	sctlr = read_sctlr();

	/* Enable MMU */
	sctlr |= (SCTLR_M);

	/* Enable instruction and data cache */
	sctlr |= SCTLR_C;
	sctlr |= SCTLR_I;
	write_sctlr(sctlr);
}
Example #3
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;
}
Example #4
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);
}