void core_init_mmu_regs(void) { uint32_t ttbcr = TTBCR_EAE; uint32_t mair; mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX); write_mair0(mair); ttbcr |= TTBCR_XRGNX_WBWA << TTBCR_IRGN0_SHIFT; ttbcr |= TTBCR_XRGNX_WBWA << TTBCR_ORGN0_SHIFT; ttbcr |= TTBCR_SHX_ISH << TTBCR_SH0_SHIFT; /* Disable the use of TTBR1 */ ttbcr |= TTBCR_EPD1; /* TTBCR.A1 = 0 => ASID is stored in TTBR0 */ write_ttbcr(ttbcr); write_ttbr0_64bit((paddr_t)l1_xlation_table[get_core_pos()]); write_ttbr1_64bit(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); }