mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-11 13:56:30 +00:00
c7be3e5a79
As discussed at [1], the Amlogic Meson GX SoCs can embed a BL31 firmware and a secondary BL32 firmware. Since mid-2017, the reserved memory address of the BL31 firmware was moved and grown for security reasons. But mainline U-Boot and Linux has the old address and size fixed. These SoCs have a register interface to get the two firmware reserved memory start and sizes. This patch adds a dynamic reservation of the memory zones in the device tree bootmem reserved memory zone used by the kernel in early boot. To be complete, the memory zones are also added to the EFI reserved zones. Depends on patchset "Add support for Amlogic GXL Based SBCs" at [2]. [1] http://lists.infradead.org/pipermail/linux-amlogic/2017-October/004860.html [2] http://lists.infradead.org/pipermail/linux-amlogic/2017-November/005410.html Changes since v1: - switched the #if to if(IS_ENABLED()) to compile all code paths - renamed function to meson_board_add_reserved_memory() - added a mem.h header with comment - updated all boards ft_board_setup() Changes since RFC v2: - reduced preprocessor load - kept Odroid-C2 static memory mapping as exception Changes since RFC v1: - switch to fdt rsv mem table and efi reserve memory - replaced in_le32 by readl() Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> [trini: Fix warning on khadas-vim over missing <asm/arch/mem.h> Signed-off-by: Tom Rini <trini@konsulko.com>
131 lines
3 KiB
C
131 lines
3 KiB
C
/*
|
|
* (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <libfdt.h>
|
|
#include <linux/err.h>
|
|
#include <asm/arch/gxbb.h>
|
|
#include <asm/arch/sm.h>
|
|
#include <asm/armv8/mmu.h>
|
|
#include <asm/unaligned.h>
|
|
#include <linux/sizes.h>
|
|
#include <efi_loader.h>
|
|
#include <asm/io.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
int dram_init(void)
|
|
{
|
|
const fdt64_t *val;
|
|
int offset;
|
|
int len;
|
|
|
|
offset = fdt_path_offset(gd->fdt_blob, "/memory");
|
|
if (offset < 0)
|
|
return -EINVAL;
|
|
|
|
val = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
|
|
if (len < sizeof(*val) * 2)
|
|
return -EINVAL;
|
|
|
|
/* Use unaligned access since cache is still disabled */
|
|
gd->ram_size = get_unaligned_be64(&val[1]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
phys_size_t get_effective_memsize(void)
|
|
{
|
|
/* Size is reported in MiB, convert it in bytes */
|
|
return ((readl(GXBB_AO_SEC_GP_CFG0) & GXBB_AO_MEM_SIZE_MASK)
|
|
>> GXBB_AO_MEM_SIZE_SHIFT) * SZ_1M;
|
|
}
|
|
|
|
static void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
|
|
{
|
|
int ret;
|
|
|
|
ret = fdt_add_mem_rsv(fdt, start, size);
|
|
if (ret)
|
|
printf("Could not reserve zone @ 0x%llx\n", start);
|
|
|
|
if (IS_ENABLED(CONFIG_EFI_LOADER)) {
|
|
efi_add_memory_map(start,
|
|
ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
|
|
EFI_RESERVED_MEMORY_TYPE, false);
|
|
}
|
|
}
|
|
|
|
void meson_gx_init_reserved_memory(void *fdt)
|
|
{
|
|
u64 bl31_size, bl31_start;
|
|
u64 bl32_size, bl32_start;
|
|
u32 reg;
|
|
|
|
/*
|
|
* Get ARM Trusted Firmware reserved memory zones in :
|
|
* - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
|
|
* - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
|
|
* - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
|
|
*/
|
|
|
|
reg = readl(GXBB_AO_SEC_GP_CFG3);
|
|
|
|
bl31_size = ((reg & GXBB_AO_BL31_RSVMEM_SIZE_MASK)
|
|
>> GXBB_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
|
|
bl32_size = (reg & GXBB_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
|
|
|
|
bl31_start = readl(GXBB_AO_SEC_GP_CFG5);
|
|
bl32_start = readl(GXBB_AO_SEC_GP_CFG4);
|
|
|
|
/*
|
|
* Early Meson GXBB Firmware revisions did not provide the reserved
|
|
* memory zones in the registers, keep fixed memory zone handling.
|
|
*/
|
|
if (IS_ENABLED(CONFIG_MESON_GXBB) &&
|
|
!reg && !bl31_start && !bl32_start) {
|
|
bl31_start = 0x10000000;
|
|
bl31_size = 0x200000;
|
|
}
|
|
|
|
/* Add first 16MiB reserved zone */
|
|
meson_board_add_reserved_memory(fdt, 0, GXBB_FIRMWARE_MEM_SIZE);
|
|
|
|
/* Add BL31 reserved zone */
|
|
if (bl31_start && bl31_size)
|
|
meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);
|
|
|
|
/* Add BL32 reserved zone */
|
|
if (bl32_start && bl32_size)
|
|
meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
|
|
}
|
|
|
|
void reset_cpu(ulong addr)
|
|
{
|
|
psci_system_reset();
|
|
}
|
|
|
|
static struct mm_region gxbb_mem_map[] = {
|
|
{
|
|
.virt = 0x0UL,
|
|
.phys = 0x0UL,
|
|
.size = 0x80000000UL,
|
|
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
|
PTE_BLOCK_INNER_SHARE
|
|
}, {
|
|
.virt = 0x80000000UL,
|
|
.phys = 0x80000000UL,
|
|
.size = 0x80000000UL,
|
|
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
|
PTE_BLOCK_NON_SHARE |
|
|
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
|
}, {
|
|
/* List terminator */
|
|
0,
|
|
}
|
|
};
|
|
|
|
struct mm_region *mem_map = gxbb_mem_map;
|