Commit c7be3e5a796a7b5c92035013d89e8182c7aab6bb

Authored by Neil Armstrong
Committed by Tom Rini
1 parent 5ff2ee44ee

ARM: arch-meson: build memory banks using reported memory from registers

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>

Showing 12 changed files with 136 additions and 9 deletions Side-by-side Diff

arch/arm/include/asm/arch-meson/gxbb.h
... ... @@ -7,9 +7,26 @@
7 7 #ifndef __GXBB_H__
8 8 #define __GXBB_H__
9 9  
  10 +#define GXBB_FIRMWARE_MEM_SIZE 0x1000000
  11 +
  12 +#define GXBB_AOBUS_BASE 0xc8100000
10 13 #define GXBB_PERIPHS_BASE 0xc8834400
11 14 #define GXBB_HIU_BASE 0xc883c000
12 15 #define GXBB_ETH_BASE 0xc9410000
  16 +
  17 +/* Always-On Peripherals registers */
  18 +#define GXBB_AO_ADDR(off) (GXBB_AOBUS_BASE + ((off) << 2))
  19 +
  20 +#define GXBB_AO_SEC_GP_CFG0 GXBB_AO_ADDR(0x90)
  21 +#define GXBB_AO_SEC_GP_CFG3 GXBB_AO_ADDR(0x93)
  22 +#define GXBB_AO_SEC_GP_CFG4 GXBB_AO_ADDR(0x94)
  23 +#define GXBB_AO_SEC_GP_CFG5 GXBB_AO_ADDR(0x95)
  24 +
  25 +#define GXBB_AO_MEM_SIZE_MASK 0xFFFF0000
  26 +#define GXBB_AO_MEM_SIZE_SHIFT 16
  27 +#define GXBB_AO_BL31_RSVMEM_SIZE_MASK 0xFFFF0000
  28 +#define GXBB_AO_BL31_RSVMEM_SIZE_SHIFT 16
  29 +#define GXBB_AO_BL32_RSVMEM_SIZE_MASK 0xFFFF
13 30  
14 31 /* Peripherals registers */
15 32 #define GXBB_PERIPHS_ADDR(off) (GXBB_PERIPHS_BASE + ((off) << 2))
arch/arm/include/asm/arch-meson/mem.h
  1 +/*
  2 + * Copyright (C) 2016 BayLibre, SAS
  3 + * Author: Neil Armstrong <narmstrong@baylibre.com>
  4 + *
  5 + * SPDX-License-Identifier: GPL-2.0+
  6 + */
  7 +
  8 +#ifndef __MESON_MEM_H__
  9 +#define __MESON_MEM_H__
  10 +
  11 +/* Configure the reserved memory zones exported by the secure registers
  12 + * into EFI and DTB reserved memory entries.
  13 + */
  14 +void meson_gx_init_reserved_memory(void *fdt);
  15 +
  16 +#endif /* __MESON_MEM_H__ */
arch/arm/mach-meson/board.c
... ... @@ -11,6 +11,9 @@
11 11 #include <asm/arch/sm.h>
12 12 #include <asm/armv8/mmu.h>
13 13 #include <asm/unaligned.h>
  14 +#include <linux/sizes.h>
  15 +#include <efi_loader.h>
  16 +#include <asm/io.h>
14 17  
15 18 DECLARE_GLOBAL_DATA_PTR;
16 19  
17 20  
... ... @@ -34,15 +37,70 @@
34 37 return 0;
35 38 }
36 39  
37   -int dram_init_banksize(void)
  40 +phys_size_t get_effective_memsize(void)
38 41 {
39   - /* Reserve first 16 MiB of RAM for firmware */
40   - gd->bd->bi_dram[0].start = 0x1000000;
41   - gd->bd->bi_dram[0].size = 0xf000000;
42   - /* Reserve 2 MiB for ARM Trusted Firmware (BL31) */
43   - gd->bd->bi_dram[1].start = 0x10000000;
44   - gd->bd->bi_dram[1].size = gd->ram_size - 0x10200000;
45   - return 0;
  42 + /* Size is reported in MiB, convert it in bytes */
  43 + return ((readl(GXBB_AO_SEC_GP_CFG0) & GXBB_AO_MEM_SIZE_MASK)
  44 + >> GXBB_AO_MEM_SIZE_SHIFT) * SZ_1M;
  45 +}
  46 +
  47 +static void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
  48 +{
  49 + int ret;
  50 +
  51 + ret = fdt_add_mem_rsv(fdt, start, size);
  52 + if (ret)
  53 + printf("Could not reserve zone @ 0x%llx\n", start);
  54 +
  55 + if (IS_ENABLED(CONFIG_EFI_LOADER)) {
  56 + efi_add_memory_map(start,
  57 + ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
  58 + EFI_RESERVED_MEMORY_TYPE, false);
  59 + }
  60 +}
  61 +
  62 +void meson_gx_init_reserved_memory(void *fdt)
  63 +{
  64 + u64 bl31_size, bl31_start;
  65 + u64 bl32_size, bl32_start;
  66 + u32 reg;
  67 +
  68 + /*
  69 + * Get ARM Trusted Firmware reserved memory zones in :
  70 + * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
  71 + * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
  72 + * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
  73 + */
  74 +
  75 + reg = readl(GXBB_AO_SEC_GP_CFG3);
  76 +
  77 + bl31_size = ((reg & GXBB_AO_BL31_RSVMEM_SIZE_MASK)
  78 + >> GXBB_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
  79 + bl32_size = (reg & GXBB_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
  80 +
  81 + bl31_start = readl(GXBB_AO_SEC_GP_CFG5);
  82 + bl32_start = readl(GXBB_AO_SEC_GP_CFG4);
  83 +
  84 + /*
  85 + * Early Meson GXBB Firmware revisions did not provide the reserved
  86 + * memory zones in the registers, keep fixed memory zone handling.
  87 + */
  88 + if (IS_ENABLED(CONFIG_MESON_GXBB) &&
  89 + !reg && !bl31_start && !bl32_start) {
  90 + bl31_start = 0x10000000;
  91 + bl31_size = 0x200000;
  92 + }
  93 +
  94 + /* Add first 16MiB reserved zone */
  95 + meson_board_add_reserved_memory(fdt, 0, GXBB_FIRMWARE_MEM_SIZE);
  96 +
  97 + /* Add BL31 reserved zone */
  98 + if (bl31_start && bl31_size)
  99 + meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);
  100 +
  101 + /* Add BL32 reserved zone */
  102 + if (bl32_start && bl32_size)
  103 + meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
46 104 }
47 105  
48 106 void reset_cpu(ulong addr)
board/amlogic/khadas-vim/khadas-vim.c
... ... @@ -9,6 +9,7 @@
9 9 #include <dm.h>
10 10 #include <asm/io.h>
11 11 #include <asm/arch/gxbb.h>
  12 +#include <asm/arch/mem.h>
12 13 #include <asm/arch/sm.h>
13 14 #include <asm/arch/eth.h>
14 15  
... ... @@ -44,6 +45,13 @@
44 45 if (len == EFUSE_SN_SIZE)
45 46 env_set("serial#", serial);
46 47 }
  48 +
  49 + return 0;
  50 +}
  51 +
  52 +int ft_board_setup(void *blob, bd_t *bd)
  53 +{
  54 + meson_gx_init_reserved_memory(blob);
47 55  
48 56 return 0;
49 57 }
board/amlogic/libretech-cc/libretech-cc.c
... ... @@ -11,6 +11,7 @@
11 11 #include <asm/arch/gxbb.h>
12 12 #include <asm/arch/sm.h>
13 13 #include <asm/arch/eth.h>
  14 +#include <asm/arch/mem.h>
14 15  
15 16 #define EFUSE_SN_OFFSET 20
16 17 #define EFUSE_SN_SIZE 16
... ... @@ -48,6 +49,13 @@
48 49 if (len == EFUSE_SN_SIZE)
49 50 env_set("serial#", serial);
50 51 }
  52 +
  53 + return 0;
  54 +}
  55 +
  56 +int ft_board_setup(void *blob, bd_t *bd)
  57 +{
  58 + meson_gx_init_reserved_memory(blob);
51 59  
52 60 return 0;
53 61 }
board/amlogic/odroid-c2/odroid-c2.c
... ... @@ -10,6 +10,7 @@
10 10 #include <asm/arch/gxbb.h>
11 11 #include <asm/arch/sm.h>
12 12 #include <asm/arch/eth.h>
  13 +#include <asm/arch/mem.h>
13 14  
14 15 #define EFUSE_SN_OFFSET 20
15 16 #define EFUSE_SN_SIZE 16
... ... @@ -51,6 +52,13 @@
51 52 if (len == EFUSE_SN_SIZE)
52 53 env_set("serial#", serial);
53 54 }
  55 +
  56 + return 0;
  57 +}
  58 +
  59 +int ft_board_setup(void *blob, bd_t *bd)
  60 +{
  61 + meson_gx_init_reserved_memory(blob);
54 62  
55 63 return 0;
56 64 }
board/amlogic/p212/p212.c
... ... @@ -11,6 +11,7 @@
11 11 #include <asm/arch/gxbb.h>
12 12 #include <asm/arch/sm.h>
13 13 #include <asm/arch/eth.h>
  14 +#include <asm/arch/mem.h>
14 15  
15 16 #define EFUSE_SN_OFFSET 20
16 17 #define EFUSE_SN_SIZE 16
... ... @@ -43,6 +44,13 @@
43 44 if (len == EFUSE_SN_SIZE)
44 45 env_set("serial#", serial);
45 46 }
  47 +
  48 + return 0;
  49 +}
  50 +
  51 +int ft_board_setup(void *blob, bd_t *bd)
  52 +{
  53 + meson_gx_init_reserved_memory(blob);
46 54  
47 55 return 0;
48 56 }
configs/khadas-vim_defconfig
... ... @@ -17,6 +17,7 @@
17 17 CONFIG_CMD_GPIO=y
18 18 # CONFIG_CMD_SETEXPR is not set
19 19 CONFIG_OF_CONTROL=y
  20 +CONFIG_OF_BOARD_SETUP=y
20 21 CONFIG_DM_GPIO=y
21 22 CONFIG_DM_MMC=y
22 23 CONFIG_MMC_MESON_GX=y
configs/libretech-cc_defconfig
... ... @@ -17,6 +17,7 @@
17 17 CONFIG_CMD_GPIO=y
18 18 # CONFIG_CMD_SETEXPR is not set
19 19 CONFIG_OF_CONTROL=y
  20 +CONFIG_OF_BOARD_SETUP=y
20 21 CONFIG_DM_GPIO=y
21 22 CONFIG_DM_MMC=y
22 23 CONFIG_MMC_MESON_GX=y
configs/odroid-c2_defconfig
... ... @@ -16,6 +16,7 @@
16 16 CONFIG_CMD_MMC=y
17 17 # CONFIG_CMD_SETEXPR is not set
18 18 CONFIG_OF_CONTROL=y
  19 +CONFIG_OF_BOARD_SETUP=y
19 20 CONFIG_NET_RANDOM_ETHADDR=y
20 21 CONFIG_DM_GPIO=y
21 22 CONFIG_DM_I2C=y
configs/p212_defconfig
... ... @@ -17,6 +17,7 @@
17 17 CONFIG_CMD_GPIO=y
18 18 # CONFIG_CMD_SETEXPR is not set
19 19 CONFIG_OF_CONTROL=y
  20 +CONFIG_OF_BOARD_SETUP=y
20 21 CONFIG_DM_GPIO=y
21 22 CONFIG_DM_MMC=y
22 23 CONFIG_MMC_MESON_GX=y
include/configs/meson-gxbb-common.h
... ... @@ -10,7 +10,7 @@
10 10  
11 11 #define CONFIG_CPU_ARMV8
12 12 #define CONFIG_REMAKE_ELF
13   -#define CONFIG_NR_DRAM_BANKS 2
  13 +#define CONFIG_NR_DRAM_BANKS 1
14 14 #define CONFIG_ENV_SIZE 0x2000
15 15 #define CONFIG_SYS_MAXARGS 32
16 16 #define CONFIG_SYS_MALLOC_LEN (32 << 20)