-static void set_pgtable_section(u64 *page_table, u64 index, u64 section,
- u64 memory_type, u64 attribute)
-{
- u64 value;
-
- value = section | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
- value |= PMD_ATTRINDX(memory_type);
- value |= attribute;
- page_table[index] = value;
-}
-
-static void set_pgtable_table(u64 *page_table, u64 index, u64 *table_addr)
-{
- u64 value;
-
- value = (u64)table_addr | PTE_TYPE_TABLE;
- page_table[index] = value;
-}
-
-/*
- * Set the block entries according to the information of the table.
- */
-static int set_block_entry(const struct sys_mmu_table *list,
- struct table_info *table)
-{
- u64 block_size = 0, block_shift = 0;
- u64 block_addr, index;
- int j;
-
- if (table->entry_size == BLOCK_SIZE_L1) {
- block_size = BLOCK_SIZE_L1;
- block_shift = SECTION_SHIFT_L1;
- } else if (table->entry_size == BLOCK_SIZE_L2) {
- block_size = BLOCK_SIZE_L2;
- block_shift = SECTION_SHIFT_L2;
- } else {
- return -EINVAL;
- }
-
- block_addr = list->phys_addr;
- index = (list->virt_addr - table->table_base) >> block_shift;
-
- for (j = 0; j < (list->size >> block_shift); j++) {
- set_pgtable_section(table->ptr,
- index,
- block_addr,
- list->memory_type,
- list->attribute);
- block_addr += block_size;
- index++;
- }
-
- return 0;
-}
-
-/*
- * Find the corresponding table entry for the list.
- */
-static int find_table(const struct sys_mmu_table *list,
- struct table_info *table, u64 *level0_table)
-{
- u64 index = 0, level = 0;
- u64 *level_table = level0_table;
- u64 temp_base = 0, block_size = 0, block_shift = 0;
-
- while (level < 3) {
- if (level == 0) {
- block_size = BLOCK_SIZE_L0;
- block_shift = SECTION_SHIFT_L0;
- } else if (level == 1) {
- block_size = BLOCK_SIZE_L1;
- block_shift = SECTION_SHIFT_L1;
- } else if (level == 2) {
- block_size = BLOCK_SIZE_L2;
- block_shift = SECTION_SHIFT_L2;
- }
-
- index = 0;
- while (list->virt_addr >= temp_base) {
- index++;
- temp_base += block_size;
- }
-
- temp_base -= block_size;
-
- if ((level_table[index - 1] & PTE_TYPE_MASK) ==
- PTE_TYPE_TABLE) {
- level_table = (u64 *)(level_table[index - 1] &
- ~PTE_TYPE_MASK);
- level++;
- continue;
- } else {
- if (level == 0)
- return -EINVAL;
-
- if ((list->phys_addr + list->size) >
- (temp_base + block_size * NUM_OF_ENTRY))
- return -EINVAL;
-
- /*
- * Check the address and size of the list member is
- * aligned with the block size.
- */
- if (((list->phys_addr & (block_size - 1)) != 0) ||
- ((list->size & (block_size - 1)) != 0))
- return -EINVAL;
-
- table->ptr = level_table;
- table->table_base = temp_base -
- ((index - 1) << block_shift);
- table->entry_size = block_size;
-
- return 0;
- }
- }
- return -EINVAL;
-}
-