diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2014-07-16 07:10:33 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2014-07-23 10:28:01 -0400 |
commit | b4a0d8b37797663b0e523c102dbb3e4b712a720c (patch) | |
tree | f0b86308ffc3202889c4286adea1cce4f6f6d4e6 /arch/arm64/kernel/head.S | |
parent | 0f1740252bea82c972e432f4d0fb76e974d53bd3 (diff) |
arm64: Clean up the initial page table creation in head.S
This patch adds a create_table_entry macro which is used to populate pgd
and pud entries, also reducing the number of arguments for
create_pgd_entry.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Jungseok Lee <jungseoklee85@gmail.com>
Diffstat (limited to 'arch/arm64/kernel/head.S')
-rw-r--r-- | arch/arm64/kernel/head.S | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 019f81d9f1d5..a6db505411bc 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -476,43 +476,38 @@ ENDPROC(__calc_phys_offset) | |||
476 | .quad PAGE_OFFSET | 476 | .quad PAGE_OFFSET |
477 | 477 | ||
478 | /* | 478 | /* |
479 | * Macro to populate the PUD for the corresponding block entry in the next | 479 | * Macro to create a table entry to the next page. |
480 | * level (tbl) for the given virtual address in case of 4 levels. | ||
481 | * | 480 | * |
482 | * Preserves: pgd, virt | 481 | * tbl: page table address |
483 | * Corrupts: tbl, tmp1, tmp2 | 482 | * virt: virtual address |
484 | * Returns: pud | 483 | * shift: #imm page table shift |
484 | * ptrs: #imm pointers per table page | ||
485 | * | ||
486 | * Preserves: virt | ||
487 | * Corrupts: tmp1, tmp2 | ||
488 | * Returns: tbl -> next level table page address | ||
485 | */ | 489 | */ |
486 | .macro create_pud_entry, pgd, tbl, virt, pud, tmp1, tmp2 | 490 | .macro create_table_entry, tbl, virt, shift, ptrs, tmp1, tmp2 |
487 | #if CONFIG_ARM64_PGTABLE_LEVELS == 4 | 491 | lsr \tmp1, \virt, #\shift |
488 | add \tbl, \tbl, #PAGE_SIZE // bump tbl 1 page up. | 492 | and \tmp1, \tmp1, #\ptrs - 1 // table index |
489 | // to make room for pud | 493 | add \tmp2, \tbl, #PAGE_SIZE |
490 | add \pud, \pgd, #PAGE_SIZE // pgd points to pud which | 494 | orr \tmp2, \tmp2, #PMD_TYPE_TABLE // address of next table and entry type |
491 | // follows pgd | 495 | str \tmp2, [\tbl, \tmp1, lsl #3] |
492 | lsr \tmp1, \virt, #PUD_SHIFT | 496 | add \tbl, \tbl, #PAGE_SIZE // next level table page |
493 | and \tmp1, \tmp1, #PTRS_PER_PUD - 1 // PUD index | ||
494 | orr \tmp2, \tbl, #3 // PUD entry table type | ||
495 | str \tmp2, [\pud, \tmp1, lsl #3] | ||
496 | #else | ||
497 | mov \pud, \tbl | ||
498 | #endif | ||
499 | .endm | 497 | .endm |
500 | 498 | ||
501 | /* | 499 | /* |
502 | * Macro to populate the PGD (and possibily PUD) for the corresponding | 500 | * Macro to populate the PGD (and possibily PUD) for the corresponding |
503 | * block entry in the next level (tbl) for the given virtual address. | 501 | * block entry in the next level (tbl) for the given virtual address. |
504 | * | 502 | * |
505 | * Preserves: pgd, virt | 503 | * Preserves: tbl, next, virt |
506 | * Corrupts: tmp1, tmp2, tmp3 | 504 | * Corrupts: tmp1, tmp2 |
507 | * Returns: tbl -> page where block mappings can be placed | ||
508 | * (changed to make room for pud with 4 levels, preserved otherwise) | ||
509 | */ | 505 | */ |
510 | .macro create_pgd_entry, pgd, tbl, virt, tmp1, tmp2, tmp3 | 506 | .macro create_pgd_entry, tbl, virt, tmp1, tmp2 |
511 | create_pud_entry \pgd, \tbl, \virt, \tmp3, \tmp1, \tmp2 | 507 | create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2 |
512 | lsr \tmp1, \virt, #PGDIR_SHIFT | 508 | #if CONFIG_ARM64_PGTABLE_LEVELS == 4 |
513 | and \tmp1, \tmp1, #PTRS_PER_PGD - 1 // PGD index | 509 | create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2 |
514 | orr \tmp2, \tmp3, #3 // PGD entry table type | 510 | #endif |
515 | str \tmp2, [\pgd, \tmp1, lsl #3] | ||
516 | .endm | 511 | .endm |
517 | 512 | ||
518 | /* | 513 | /* |
@@ -573,10 +568,10 @@ __create_page_tables: | |||
573 | /* | 568 | /* |
574 | * Create the identity mapping. | 569 | * Create the identity mapping. |
575 | */ | 570 | */ |
576 | add x0, x25, #PAGE_SIZE // section table address | 571 | mov x0, x25 // idmap_pg_dir |
577 | ldr x3, =KERNEL_START | 572 | ldr x3, =KERNEL_START |
578 | add x3, x3, x28 // __pa(KERNEL_START) | 573 | add x3, x3, x28 // __pa(KERNEL_START) |
579 | create_pgd_entry x25, x0, x3, x1, x5, x6 | 574 | create_pgd_entry x0, x3, x5, x6 |
580 | ldr x6, =KERNEL_END | 575 | ldr x6, =KERNEL_END |
581 | mov x5, x3 // __pa(KERNEL_START) | 576 | mov x5, x3 // __pa(KERNEL_START) |
582 | add x6, x6, x28 // __pa(KERNEL_END) | 577 | add x6, x6, x28 // __pa(KERNEL_END) |
@@ -585,9 +580,9 @@ __create_page_tables: | |||
585 | /* | 580 | /* |
586 | * Map the kernel image (starting with PHYS_OFFSET). | 581 | * Map the kernel image (starting with PHYS_OFFSET). |
587 | */ | 582 | */ |
588 | add x0, x26, #PAGE_SIZE // section table address | 583 | mov x0, x26 // swapper_pg_dir |
589 | mov x5, #PAGE_OFFSET | 584 | mov x5, #PAGE_OFFSET |
590 | create_pgd_entry x26, x0, x5, x1, x3, x6 | 585 | create_pgd_entry x0, x5, x3, x6 |
591 | ldr x6, =KERNEL_END | 586 | ldr x6, =KERNEL_END |
592 | mov x3, x24 // phys offset | 587 | mov x3, x24 // phys offset |
593 | create_block_map x0, x7, x3, x5, x6 | 588 | create_block_map x0, x7, x3, x5, x6 |