blob: 75d3b0a539f9c814f6506144806a9fa02b2c9485 [file]
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <autoconf.h>
#include <elfloader/gen_config.h>
#include <types.h>
#include <elfloader.h>
#include <mode/structures.h>
#include <printf.h>
#include <abort.h>
/*
* Create a "boot" page table, which contains a 1:1 mapping below
* the kernel's first vaddr, and a virtual-to-physical mapping above the
* kernel's first vaddr.
*/
void init_boot_vspace(struct image_info *kernel_info)
{
word_t i;
vaddr_t first_vaddr = kernel_info->virt_region_start;
vaddr_t last_vaddr = kernel_info->virt_region_end;
paddr_t first_paddr = kernel_info->phys_region_start;
_boot_pgd_down[0] = ((uintptr_t)_boot_pud_down) | BIT(1) | BIT(0); /* its a page table */
for (i = 0; i < BIT(PUD_BITS); i++) {
_boot_pud_down[i] = (i << ARM_1GB_BLOCK_BITS)
| BIT(10) /* access flag */
| (0 << 2) /* strongly ordered memory */
| BIT(0); /* 1G block */
}
_boot_pgd_up[GET_PGD_INDEX(first_vaddr)]
= ((uintptr_t)_boot_pud_up) | BIT(1) | BIT(0); /* its a page table */
_boot_pud_up[GET_PUD_INDEX(first_vaddr)]
= ((uintptr_t)_boot_pmd_up) | BIT(1) | BIT(0); /* its a page table */
/* We only map in 1 GiB, so check that the kernel doesn't cross 1GiB boundary. */
if ((first_vaddr & ~MASK(ARM_1GB_BLOCK_BITS)) != (last_vaddr & ~MASK(ARM_1GB_BLOCK_BITS))) {
printf("We only map 1GiB, but kernel vaddr range covers multiple GiB.\n");
abort();
}
for (i = GET_PMD_INDEX(first_vaddr); i < BIT(PMD_BITS); i++) {
_boot_pmd_up[i] = first_paddr
| BIT(10) /* access flag */
#if CONFIG_MAX_NUM_NODES > 1
| (3 << 8) /* make sure the shareability is the same as the kernel's */
#endif
| (4 << 2) /* MT_NORMAL memory */
| BIT(0); /* 2M block */
first_paddr += BIT(ARM_2MB_BLOCK_BITS);
}
}
void init_hyp_boot_vspace(struct image_info *kernel_info)
{
word_t i;
word_t pmd_index;
vaddr_t first_vaddr = kernel_info->virt_region_start;
paddr_t first_paddr = kernel_info->phys_region_start;
_boot_pgd_down[0] = ((uintptr_t)_boot_pud_down) | BIT(1) | BIT(0);
for (i = 0; i < BIT(PUD_BITS); i++) {
_boot_pud_down[i] = (i << ARM_1GB_BLOCK_BITS)
| BIT(10) /* access flag */
| (0 << 2) /* strongly ordered memory */
| BIT(0); /* 1G block */
}
_boot_pgd_down[GET_PGD_INDEX(first_vaddr)]
= ((uintptr_t)_boot_pud_up) | BIT(1) | BIT(0); /* its a page table */
_boot_pud_up[GET_PUD_INDEX(first_vaddr)]
= ((uintptr_t)_boot_pmd_up) | BIT(1) | BIT(0); /* its a page table */
pmd_index = GET_PMD_INDEX(first_vaddr);
for (i = pmd_index; i < BIT(PMD_BITS); i++) {
_boot_pmd_up[i] = (((i - pmd_index) << ARM_2MB_BLOCK_BITS) + first_paddr)
| BIT(10) /* access flag */
#if CONFIG_MAX_NUM_NODES > 1
| (3 << 8)
#endif
| (4 << 2) /* MT_NORMAL memory */
| BIT(0); /* 2M block */
}
}