1230557Sjimharris/* 2230557Sjimharris * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3230557Sjimharris * 4230557Sjimharris * SPDX-License-Identifier: GPL-2.0-only 5230557Sjimharris */ 6230557Sjimharris 7230557Sjimharris#include <autoconf.h> 8230557Sjimharris#include <elfloader/gen_config.h> 9230557Sjimharris#include <types.h> 10230557Sjimharris#include <elfloader.h> 11230557Sjimharris#include <mode/structures.h> 12230557Sjimharris#include <printf.h> 13230557Sjimharris#include <abort.h> 14230557Sjimharris 15230557Sjimharris/* 16230557Sjimharris* Create a "boot" page table, which contains a 1:1 mapping below 17230557Sjimharris* the kernel's first vaddr, and a virtual-to-physical mapping above the 18230557Sjimharris* kernel's first vaddr. 19230557Sjimharris*/ 20230557Sjimharrisvoid init_boot_vspace(struct image_info *kernel_info) 21230557Sjimharris{ 22230557Sjimharris word_t i; 23230557Sjimharris 24230557Sjimharris vaddr_t first_vaddr = kernel_info->virt_region_start; 25230557Sjimharris vaddr_t last_vaddr = kernel_info->virt_region_end; 26230557Sjimharris paddr_t first_paddr = kernel_info->phys_region_start; 27230557Sjimharris 28230557Sjimharris _boot_pgd_down[0] = ((uintptr_t)_boot_pud_down) | BIT(1) | BIT(0); /* its a page table */ 29230557Sjimharris 30230557Sjimharris for (i = 0; i < BIT(PUD_BITS); i++) { 31230557Sjimharris _boot_pud_down[i] = (i << ARM_1GB_BLOCK_BITS) 32230557Sjimharris | BIT(10) /* access flag */ 33230557Sjimharris | (0 << 2) /* strongly ordered memory */ 34230557Sjimharris | BIT(0); /* 1G block */ 35230557Sjimharris } 36230557Sjimharris 37230557Sjimharris _boot_pgd_up[GET_PGD_INDEX(first_vaddr)] 38230557Sjimharris = ((uintptr_t)_boot_pud_up) | BIT(1) | BIT(0); /* its a page table */ 39230557Sjimharris 40230557Sjimharris _boot_pud_up[GET_PUD_INDEX(first_vaddr)] 41230557Sjimharris = ((uintptr_t)_boot_pmd_up) | BIT(1) | BIT(0); /* its a page table */ 42230557Sjimharris 43230557Sjimharris /* We only map in 1 GiB, so check that the kernel doesn't cross 1GiB boundary. */ 44230557Sjimharris if ((first_vaddr & ~MASK(ARM_1GB_BLOCK_BITS)) != (last_vaddr & ~MASK(ARM_1GB_BLOCK_BITS))) { 45230557Sjimharris printf("We only map 1GiB, but kernel vaddr range covers multiple GiB.\n"); 46230557Sjimharris abort(); 47230557Sjimharris } 48230557Sjimharris for (i = GET_PMD_INDEX(first_vaddr); i < BIT(PMD_BITS); i++) { 49230557Sjimharris _boot_pmd_up[i] = first_paddr 50230557Sjimharris | BIT(10) /* access flag */ 51230557Sjimharris#if CONFIG_MAX_NUM_NODES > 1 52230557Sjimharris | (3 << 8) /* make sure the shareability is the same as the kernel's */ 53230557Sjimharris#endif 54230557Sjimharris | (4 << 2) /* MT_NORMAL memory */ 55230557Sjimharris | BIT(0); /* 2M block */ 56230557Sjimharris first_paddr += BIT(ARM_2MB_BLOCK_BITS); 57230557Sjimharris } 58230557Sjimharris} 59230557Sjimharris 60230557Sjimharrisvoid init_hyp_boot_vspace(struct image_info *kernel_info) 61230557Sjimharris{ 62230557Sjimharris word_t i; 63230557Sjimharris word_t pmd_index; 64230557Sjimharris vaddr_t first_vaddr = kernel_info->virt_region_start; 65230557Sjimharris paddr_t first_paddr = kernel_info->phys_region_start; 66230557Sjimharris _boot_pgd_down[0] = ((uintptr_t)_boot_pud_down) | BIT(1) | BIT(0); 67230557Sjimharris 68230557Sjimharris for (i = 0; i < BIT(PUD_BITS); i++) { 69230557Sjimharris _boot_pud_down[i] = (i << ARM_1GB_BLOCK_BITS) 70230557Sjimharris | BIT(10) /* access flag */ 71230557Sjimharris | (0 << 2) /* strongly ordered memory */ 72230557Sjimharris | BIT(0); /* 1G block */ 73230557Sjimharris } 74230557Sjimharris 75230557Sjimharris _boot_pgd_down[GET_PGD_INDEX(first_vaddr)] 76230557Sjimharris = ((uintptr_t)_boot_pud_up) | BIT(1) | BIT(0); /* its a page table */ 77230557Sjimharris 78230557Sjimharris _boot_pud_up[GET_PUD_INDEX(first_vaddr)] 79230557Sjimharris = ((uintptr_t)_boot_pmd_up) | BIT(1) | BIT(0); /* its a page table */ 80230557Sjimharris 81230557Sjimharris pmd_index = GET_PMD_INDEX(first_vaddr); 82230557Sjimharris for (i = pmd_index; i < BIT(PMD_BITS); i++) { 83230557Sjimharris _boot_pmd_up[i] = (((i - pmd_index) << ARM_2MB_BLOCK_BITS) + first_paddr) 84230557Sjimharris | BIT(10) /* access flag */ 85230557Sjimharris#if CONFIG_MAX_NUM_NODES > 1 86230557Sjimharris | (3 << 8) 87230557Sjimharris#endif 88230557Sjimharris | (4 << 2) /* MT_NORMAL memory */ 89230557Sjimharris | BIT(0); /* 2M block */ 90230557Sjimharris } 91230557Sjimharris} 92230557Sjimharris