#include #include #include #include #include #include #define LEVEL2_TABLE_ENTRIES 256 static union TARMV8MMU_LEVEL2_DESCRIPTOR *l2_table; static size_t mem = 0; extern uint8_t _etext; static union TARMV8MMU_LEVEL3_DESCRIPTOR * new_level_l3_table(uintptr_t base_addr) { union TARMV8MMU_LEVEL3_DESCRIPTOR *l3_table = (union TARMV8MMU_LEVEL3_DESCRIPTOR *)gilbraltar_palloc(); for (unsigned page = 0; page < ARMV8MMU_TABLE_ENTRIES; page++) { struct TARMV8MMU_LEVEL3_PAGE_DESCRIPTOR *desc = &l3_table[page].page; desc->value11 = 3; desc->attr_indx = ATTR_INDX_NORMAL; desc->ns = 0; desc->ap = ATTR_IB_AP_RW_EL1; desc->sh = ATTR_IB_SH_INNER_SHAREABLE; desc->af = 1; desc->ng = 0; desc->reserved0_1 = 0; desc->output_addr = ARMV8MMUL3PAGEADDR(base_addr); desc->reserved0_2 = 0; desc->continuous = 0; desc->pxn = 0; desc->uxn = 1; desc->ignored = 0; if (base_addr >= (uint64_t)&_etext) { desc->pxn = 1; if ((base_addr >= mem && base_addr < GIGABYTE) || base_addr > (8 * GIGABYTE - 1)) { desc->attr_indx = ATTR_INDX_DEVICE; desc->sh = ATTR_IB_SH_OUTER_SHAREABLE; } else if (base_addr >= MEM_COHERENT_REGION && base_addr < MEM_HEAP_START) { desc->attr_indx = ATTR_INDX_COHERENT; desc->sh = ATTR_IB_SH_OUTER_SHAREABLE; } } base_addr += ARMV8MMU_LEVEL3_PAGE_SIZE; } return (l3_table); } uintptr_t gilbraltar_translation_table_base(void) { return ((uintptr_t)l2_table); } void gilbraltar_translation_table_init(size_t size) { l2_table = (union TARMV8MMU_LEVEL2_DESCRIPTOR *)gilbraltar_palloc(); gilbraltar_log(DEBUG, "L2 table allocated.\r\n"); memset(l2_table, 0, PAGE_SIZE); for (unsigned entry = 0; entry < LEVEL2_TABLE_ENTRIES; entry++) { uint64_t base_addr = (uint64_t)entry * ARMV8MMU_TABLE_ENTRIES * ARMV8MMU_LEVEL3_PAGE_SIZE; if (base_addr >= 8 * GIGABYTE && !(MEM_IOMEM_AXI_START <= base_addr && base_addr <= MEM_IOMEM_AXI_END) && !(MEM_IOMEM_SOC_START <= base_addr && base_addr <= MEM_IOMEM_SOC_END) && !(MEM_IOMEM_PCIE_START <= base_addr && base_addr <= MEM_IOMEM_PCIE_END)) continue; // as far as we can gilbraltar_log(DEBUG, "New L3 table.\r\n"); union TARMV8MMU_LEVEL3_DESCRIPTOR *l3_table = new_level_l3_table(base_addr); struct TARMV8MMU_LEVEL2_TABLE_DESCRIPTOR *desc = &l2_table[entry].table; desc->value11 = 3; desc->ignored1 = 0; desc->table_addr = ARMV8MMUL2TABLEADDR((uint64_t)l3_table); desc->reserved0 = 0; desc->ignored2 = 0; desc->pxn_table = 0; desc->uxn_table = 0; desc->ap_table = AP_TABLE_ALL_ACCESS; desc->ns_table = 0; } data_sync_barrier(); }