Re: [PATCH 14/15] MIPS: malta: setup RAM regions via DT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Fri, May 22, 2015 at 10:51 AM, Paul Burton <paul.burton@xxxxxxxxxx> wrote:
> Move memory configuration to be performed via device tree for the Malta
> board. This moves more Malta specific code to malta-dtshim.c, leaving
> the rest of the mti-malta code a little more board-agnostic. This will
> be useful to share more code between boards, with the device tree
> providing the board specifics as intended.
>
> Since we can't rely upon Malta boards running a bootloader capable of
> handling devictrees & filling in the required information, the
> malta_dt_shim code is extended to consume the (e)memsize variables
> provided as part of the bootloader environment (or on the kernel command
> line) then generate the DT memory node using the provided values.

IMO, I think this all belongs in a shim outside of the kernel. This is
how ARM and powerpc generally deal with old or broken bootloaders. But
then MIPS is such a mess of DT code with every platform doing things
their own way.

Rob

>
> Signed-off-by: Paul Burton <paul.burton@xxxxxxxxxx>
> ---
>
>  arch/mips/boot/dts/mti/malta.dts   |   4 ++
>  arch/mips/mti-malta/malta-dtshim.c | 104 +++++++++++++++++++++++++++++++++++++
>  arch/mips/mti-malta/malta-memory.c |  88 -------------------------------
>  3 files changed, 108 insertions(+), 88 deletions(-)
>
> diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts
> index 9720c66..2fe2364 100644
> --- a/arch/mips/boot/dts/mti/malta.dts
> +++ b/arch/mips/boot/dts/mti/malta.dts
> @@ -1,5 +1,9 @@
>  /dts-v1/;
>
> +/memreserve/ 0x00000000 0x00001000;    /* reserved */
> +/memreserve/ 0x00001000 0x000ef000;    /* YAMON */
> +/memreserve/ 0x000f0000 0x00010000;    /* PIIX4 ISA memory */
> +
>  #include <dt-bindings/interrupt-controller/irq.h>
>  #include <dt-bindings/interrupt-controller/mips-gic.h>
>
> diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
> index ca33201..9074951 100644
> --- a/arch/mips/mti-malta/malta-dtshim.c
> +++ b/arch/mips/mti-malta/malta-dtshim.c
> @@ -20,6 +20,109 @@
>
>  static unsigned char fdt_buf[16 << 10] __initdata;
>
> +/* determined physical memory size, not overridden by command line args         */
> +extern unsigned long physical_memsize;
> +
> +#define MAX_MEM_ARRAY_ENTRIES 1
> +
> +static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size)
> +{
> +       unsigned long size_preio;
> +       unsigned entries;
> +
> +       entries = 1;
> +       mem_array[0] = cpu_to_be32(PHYS_OFFSET);
> +       if (config_enabled(CONFIG_EVA)) {
> +               mem_array[1] = cpu_to_be32(PHYS_OFFSET + size);
> +       } else {
> +               size_preio = min_t(unsigned long, size, 256 << 20);
> +               mem_array[1] = cpu_to_be32(PHYS_OFFSET + size_preio);
> +       }
> +
> +       BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES);
> +       return entries;
> +}
> +
> +static void __init append_memory(void *fdt, int root_off)
> +{
> +       __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES];
> +       unsigned long memsize;
> +       unsigned mem_entries;
> +       int i, err, mem_off;
> +       char *var, param_name[10], *var_names[] = {
> +               "ememsize", "memsize",
> +       };
> +
> +       /* if a memory node already exists, leave it alone */
> +       mem_off = fdt_path_offset(fdt, "/memory");
> +       if (mem_off >= 0)
> +               return;
> +
> +       /* find memory size from the bootloader environment */
> +       for (i = 0; i < ARRAY_SIZE(var_names); i++) {
> +               var = fw_getenv(var_names[i]);
> +               if (!var)
> +                       continue;
> +
> +               err = kstrtoul(var, 0, &physical_memsize);
> +               if (!err)
> +                       break;
> +
> +               pr_warn("Failed to read the '%s' env variable '%s'\n",
> +                       var_names[i], var);
> +       }
> +
> +       if (!physical_memsize) {
> +               pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
> +               physical_memsize = 32 << 20;
> +       }
> +
> +       if (config_enabled(CONFIG_CPU_BIG_ENDIAN)) {
> +               /*
> +                * SOC-it swaps, or perhaps doesn't swap, when DMA'ing
> +                * the last word of physical memory.
> +                */
> +               physical_memsize -= PAGE_SIZE;
> +       }
> +
> +       /* default to using all available RAM */
> +       memsize = physical_memsize;
> +
> +       /* allow the user to override the usable memory */
> +       for (i = 0; i < ARRAY_SIZE(var_names); i++) {
> +               snprintf(param_name, sizeof(param_name), "%s=", var_names[i]);
> +               var = strstr(arcs_cmdline, param_name);
> +               if (!var)
> +                       continue;
> +
> +               memsize = memparse(var + strlen(param_name), NULL);
> +       }
> +
> +       /* if the user says there's more RAM than we thought, believe them */
> +       physical_memsize = max_t(unsigned long, physical_memsize, memsize);
> +
> +       /* append memory to the DT */
> +       mem_off = fdt_add_subnode(fdt, root_off, "memory");
> +       if (mem_off < 0)
> +               panic("Unable to add memory node to DT: %d", mem_off);
> +
> +       err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
> +       if (err)
> +               panic("Unable to set memory node device_type: %d", err);
> +
> +       mem_entries = gen_fdt_mem_array(mem_array, physical_memsize);
> +       err = fdt_setprop(fdt, mem_off, "reg", mem_array,
> +                         mem_entries * 2 * sizeof(mem_array[0]));
> +       if (err)
> +               panic("Unable to set memory regs property: %d", err);
> +
> +       mem_entries = gen_fdt_mem_array(mem_array, memsize);
> +       err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array,
> +                         mem_entries * 2 * sizeof(mem_array[0]));
> +       if (err)
> +               panic("Unable to set linux,usable-memory property: %d", err);
> +}
> +
>  static void __init remove_gic(void *fdt)
>  {
>         int err, gic_off, i8259_off, cpu_off;
> @@ -118,6 +221,7 @@ void __init *malta_dt_shim(void *fdt)
>         if (strncmp(compat, "mti,malta", len))
>                 return fdt;
>
> +       append_memory(fdt_buf, root_off);
>         remove_gic(fdt_buf);
>
>         err = fdt_pack(fdt_buf);
> diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
> index 831f583..5203241 100644
> --- a/arch/mips/mti-malta/malta-memory.c
> +++ b/arch/mips/mti-malta/malta-memory.c
> @@ -32,97 +32,9 @@ static void free_init_pages_eva_malta(void *begin, void *end)
>
>  void __init fw_meminit(void)
>  {
> -       char *memsize_str, *ememsize_str = NULL, *ptr;
> -       unsigned long memsize = 0, ememsize = 0;
> -       unsigned long kernel_start_phys, kernel_end_phys;
> -       static char cmdline[COMMAND_LINE_SIZE] __initdata;
>         bool eva = config_enabled(CONFIG_EVA);
> -       int tmp;
>
>         free_init_pages_eva = eva ? free_init_pages_eva_malta : NULL;
> -
> -       memsize_str = fw_getenv("memsize");
> -       if (memsize_str) {
> -               tmp = kstrtoul(memsize_str, 0, &memsize);
> -               if (tmp)
> -                       pr_warn("Failed to read the 'memsize' env variable.\n");
> -       }
> -       if (eva) {
> -       /* Look for ememsize for EVA */
> -               ememsize_str = fw_getenv("ememsize");
> -               if (ememsize_str) {
> -                       tmp = kstrtoul(ememsize_str, 0, &ememsize);
> -                       if (tmp)
> -                               pr_warn("Failed to read the 'ememsize' env variable.\n");
> -               }
> -       }
> -       if (!memsize && !ememsize) {
> -               pr_warn("memsize not set in YAMON, set to default (32Mb)\n");
> -               physical_memsize = 0x02000000;
> -       } else {
> -               if (memsize > (256 << 20)) { /* memsize should be capped to 256M */
> -                       pr_warn("Unsupported memsize value (0x%lx) detected! "
> -                               "Using 0x10000000 (256M) instead\n",
> -                               memsize);
> -                       memsize = 256 << 20;
> -               }
> -               /* If ememsize is set, then set physical_memsize to that */
> -               physical_memsize = ememsize ? : memsize;
> -       }
> -
> -#ifdef CONFIG_CPU_BIG_ENDIAN
> -       /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last
> -          word of physical memory */
> -       physical_memsize -= PAGE_SIZE;
> -#endif
> -
> -       /* Check the command line for a memsize directive that overrides
> -          the physical/default amount */
> -       strcpy(cmdline, arcs_cmdline);
> -       ptr = strstr(cmdline, "memsize=");
> -       if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
> -               ptr = strstr(ptr, " memsize=");
> -       /* And now look for ememsize */
> -       if (eva) {
> -               ptr = strstr(cmdline, "ememsize=");
> -               if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
> -                       ptr = strstr(ptr, " ememsize=");
> -       }
> -
> -       if (ptr)
> -               memsize = memparse(ptr + 8 + (eva ? 1 : 0), &ptr);
> -       else
> -               memsize = physical_memsize;
> -
> -       add_memory_region(PHYS_OFFSET, 0x00001000, BOOT_MEM_RESERVED);
> -
> -       /*
> -        * YAMON may still be using the region of memory from 0x1000 to 0xfffff
> -        * if it has started secondary CPUs.
> -        */
> -       add_memory_region(PHYS_OFFSET + 0x00001000, 0x000ef000,
> -                         BOOT_MEM_ROM_DATA);
> -
> -       /*
> -        * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
> -        * south bridge and PCI access always forwarded to the ISA Bus and
> -        * BIOSCS# is always generated.
> -        * This mean that this area can't be used as DMA memory for PCI
> -        * devices.
> -        */
> -       add_memory_region(PHYS_OFFSET + 0x000f0000, 0x00010000,
> -                         BOOT_MEM_RESERVED);
> -
> -       /*
> -        * Reserve the memory used by kernel code, and allow the rest of RAM to
> -        * be used.
> -        */
> -       kernel_start_phys = PHYS_OFFSET + 0x00100000;
> -       kernel_end_phys = PHYS_OFFSET + CPHYSADDR(PFN_ALIGN(&_end));
> -       add_memory_region(kernel_start_phys, kernel_end_phys,
> -                         BOOT_MEM_RESERVED);
> -       add_memory_region(kernel_end_phys, memsize - kernel_end_phys,
> -                         BOOT_MEM_RAM);
>  }
>
>  void __init prom_free_prom_memory(void)
> --
> 2.4.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux