phys_bytes pg_load() { phys_bytes phpagedir = vir2phys(pagedir); refresh_tlb(); write_ttbr0(phpagedir); return phpagedir; }
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); }
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); }
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; }
/* * 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); }