From: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
To: Michael Bringmann <mwb@linux.vnet.ibm.com>,
linuxppc-dev@lists.ozlabs.org
Cc: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Subject: Re: [PATCH 2/8] powerpc/memory: Parse new memory property to register blocks.
Date: Mon, 25 Jul 2016 16:54:22 -0700 [thread overview]
Message-ID: <5796A6AE.3030005@linux.vnet.ibm.com> (raw)
In-Reply-To: <789c4437-b600-7348-fc75-27a077ac6eeb@linux.vnet.ibm.com>
On 07/25/2016 03:21 PM, Michael Bringmann wrote:
> powerpc/memory: Add parallel routines to parse the new property
> "ibm,dynamic-memory-v2" property when it is present, and then to
> register the relevant memory blocks with the operating system.
> This property format is intended to provide a more compact
> representation of memory when communicating with the front end
> processor, especially when describing vast amounts of RAM.
>
> Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
> ---
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index 7f436ba..b9a1534 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -69,6 +69,8 @@ struct boot_param_header {
> * OF address retreival & translation
> */
>
> +extern int n_mem_addr_cells;
> +
> /* Parse the ibm,dma-window property of an OF node into the busno, phys and
> * size parameters.
> */
> @@ -81,8 +83,9 @@ extern void of_instantiate_rtc(void);
> extern int of_get_ibm_chip_id(struct device_node *np);
>
> /* The of_drconf_cell struct defines the layout of the LMB array
> - * specified in the device tree property
> - * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory
> + * specified in the device tree properties,
> + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory
> + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory-v2
> */
> struct of_drconf_cell {
> u64 base_addr;
> @@ -92,9 +95,39 @@ struct of_drconf_cell {
> u32 flags;
> };
>
> -#define DRCONF_MEM_ASSIGNED 0x00000008
> -#define DRCONF_MEM_AI_INVALID 0x00000040
> -#define DRCONF_MEM_RESERVED 0x00000080
> +#define DRCONF_MEM_ASSIGNED 0x00000008
> +#define DRCONF_MEM_AI_INVALID 0x00000040
> +#define DRCONF_MEM_RESERVED 0x00000080
> +
> + /* It is important to note that this structure can not
> + * be safely mapped onto the memory containing the
> + * 'ibm,dynamic-memory-v2'. This structure represents
> + * the order of the fields stored, but compiler alignment
> + * may insert extra bytes of padding between the fields
> + * 'num_seq_lmbs' and 'base_addr'.
> + */
The "packed" attribute should prevent the struct from being padded.
struct of_drconf_cell_v2 {
...
} __attribute__((packed));
or, simply
struct of_drconf_cell_v2 {
...
} __packed;
-Tyrel
> +struct of_drconf_cell_v2 {
> + u32 num_seq_lmbs;
> + u64 base_addr;
> + u32 drc_index;
> + u32 aa_index;
> + u32 flags;
> +};
> +
> +
> +static inline int dyn_mem_v2_len(int entries)
> +{
> + int drconf_v2_cells = (n_mem_addr_cells + 4);
> + int drconf_v2_cells_len = (drconf_v2_cells * sizeof(unsigned int));
> + return (((entries) * drconf_v2_cells_len) +
> + (1 * sizeof(unsigned int)));
> +}
> +
> +extern void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem,
> + const __be32 **cellp);
> +extern void read_one_drc_info(int **info, char **drc_type, char **drc_name,
> + unsigned long int *fdi_p, unsigned long int *nsl_p,
> + unsigned long int *si_p, unsigned long int *ldi_p);
>
> /*
> * There are two methods for telling firmware what our capabilities are.
> diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
> index 669a15e..ad294ce 100644
> --- a/arch/powerpc/mm/numa.c
> +++ b/arch/powerpc/mm/numa.c
> @@ -405,6 +405,24 @@ static void read_drconf_cell(struct of_drconf_cell *drmem, const __be32 **cellp)
>
> *cellp = cp + 4;
> }
> +
> + /*
> + * Retrieve and validate the ibm,dynamic-memory property of the device tree.
> + * Read the next memory block set entry from the ibm,dynamic-memory-v2 property
> + * and return the information in the provided of_drconf_cell_v2 structure.
> + */
> +void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem, const __be32 **cellp)
> +{
> + const __be32 *cp = (const __be32 *)*cellp;
> + drmem->num_seq_lmbs = be32_to_cpu(*cp++);
> + drmem->base_addr = read_n_cells(n_mem_addr_cells, &cp);
> + drmem->drc_index = be32_to_cpu(*cp++);
> + drmem->aa_index = be32_to_cpu(*cp++);
> + drmem->flags = be32_to_cpu(*cp++);
> +
> + *cellp = cp;
> +}
> +EXPORT_SYMBOL(read_drconf_cell_v2);
>
> /*
> * Retrieve and validate the ibm,dynamic-memory property of the device tree.
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 946e34f..a55bc1e 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -56,6 +56,7 @@
> #include <asm/opal.h>
> #include <asm/fadump.h>
> #include <asm/debug.h>
> +#include <asm/firmware.h>
>
> #include <mm/mmu_decl.h>
>
> @@ -441,12 +442,12 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node,
>
> #ifdef CONFIG_PPC_PSERIES
> /*
> - * Interpret the ibm,dynamic-memory property in the
> - * /ibm,dynamic-reconfiguration-memory node.
> + * Interpret the ibm,dynamic-memory property/ibm,dynamic-memory-v2
> + * in the /ibm,dynamic-reconfiguration-memory node.
> * This contains a list of memory blocks along with NUMA affinity
> * information.
> */
> -static int __init early_init_dt_scan_drconf_memory(unsigned long node)
> +static int __init early_init_dt_scan_drconf_memory_v1(unsigned long node)
> {
> const __be32 *dm, *ls, *usm;
> int l;
> @@ -516,6 +517,105 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node)
> memblock_dump_all();
> return 0;
> }
> +
> +static int __init early_init_dt_scan_drconf_memory_v2(unsigned long node)
> +{
> + const __be32 *dm, *ls, *usm;
> + int l;
> + unsigned long num_sets;
> + u64 size, base, memblock_size;
> + unsigned int is_kexec_kdump = 0, rngs;
> +
> + ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
> + if (ls == NULL || l < dt_root_size_cells * sizeof(__be32))
> + return 0;
> + memblock_size = dt_mem_next_cell(dt_root_size_cells, &ls);
> +
> + dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory-v2", &l);
> + if (dm == NULL || l < sizeof(__be32))
> + return 0;
> +
> + num_sets = of_read_number(dm++, 1);
> + if (l < (num_sets * (dt_root_addr_cells + 4) + 1) * sizeof(__be32))
> + return 0;
> +
> + /* check if this is a kexec/kdump kernel. */
> + usm = of_get_flat_dt_prop(node, "linux,drconf-usable-memory", &l);
> + if (usm != NULL)
> + is_kexec_kdump = 1;
> +
> + if (n_mem_addr_cells == 0)
> + n_mem_addr_cells = dt_root_addr_cells;
> +
> + for (; num_sets != 0; --num_sets) {
> + struct of_drconf_cell_v2 drmem;
> + unsigned long nsl;
> +
> + read_drconf_cell_v2(&drmem, &dm);
> + base = drmem.base_addr;
> + nsl = drmem.num_seq_lmbs;
> + size = memblock_size;
> +
> + /* SKip this block if the reserved bit is set in flags
> + * or if the block is not assigned to this partition
> + */
> + if ((drmem.flags & DRCONF_MEM_RESERVED) ||
> + !(drmem.flags & DRCONF_MEM_ASSIGNED))
> + continue;
> +
> + for (; nsl != 0; nsl--) {
> + size = memblock_size;
> + rngs = 1;
> + if (is_kexec_kdump)
> + /*
> + * For each memblock in ibm,dynamic-memory,
> + * a corresponding entry in
> + * linux,drconf-usable-memory property
> + * contains a counter 'p' followed by 'p'
> + * (base, size) duple. Now read the counter
> + * from linux,drconf-usable-memory property
> + */
> + rngs = dt_mem_next_cell(dt_root_size_cells,
> + &usm);
> +
> + if (rngs) {
> + do {
> + if (is_kexec_kdump) {
> + base = dt_mem_next_cell(
> + dt_root_addr_cells,
> + &usm);
> + size = dt_mem_next_cell(
> + dt_root_size_cells,
> + &usm);
> + }
> + if (iommu_is_off) {
> + if (base >= 0x80000000ul)
> + continue;
> + if ((base + size) >
> + 0x80000000ul)
> + size = 0x80000000ul -
> + base;
> + }
> + memblock_add(base, size);
> + } while (--rngs);
> + }
> +
> + base += size;
> + }
> + }
> +
> + memblock_dump_all();
> + return 0;
> +}
> +
> +static int __init early_init_dt_scan_drconf_memory(unsigned long node)
> +{
> + if (firmware_has_feature(FW_FEATURE_RPS_DM2))
> + return early_init_dt_scan_drconf_memory_v2(node);
> + else
> + return early_init_dt_scan_drconf_memory_v1(node);
> +}
> +
> #else
> #define early_init_dt_scan_drconf_memory(node) 0
> #endif /* CONFIG_PPC_PSERIES */
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
prev parent reply other threads:[~2016-07-25 23:54 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-25 22:21 [PATCH 2/8] powerpc/memory: Parse new memory property to register blocks Michael Bringmann
2016-07-25 23:54 ` Tyrel Datwyler [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5796A6AE.3030005@linux.vnet.ibm.com \
--to=tyreld@linux.vnet.ibm.com \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mwb@linux.vnet.ibm.com \
--cc=nfont@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.