This repository has been archived by the owner on Sep 24, 2020. It is now read-only.
forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
powerpc/mm: Separate ibm, dynamic-memory data from DT format
We currently have code to parse the dynamic reconfiguration LMB information from the ibm,dynamic-meory device tree property in multiple locations; numa.c, prom.c, and pseries/hotplug-memory.c. In anticipation of adding support for a version 2 of the ibm,dynamic-memory property this patch aims to separate the device tree information from the device tree format. Doing this requires a two step process to avoid a possibly very large bootmem allocation early in boot. During initial boot, new routines are provided to walk the device tree property and make a call-back for each LMB. The second step (introduced in later patches) will allocate an array of LMB information that can be used directly without needing to know the DT format. This approach provides the benefit of consolidating the device tree property parsing to a single location and (eventually) providing a common data structure for retrieving LMB information. This patch introduces a routine to walk the ibm,dynamic-memory property in the flattened device tree and updates the prom.c code to use this to initialize memory. Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
- Loading branch information
Showing
4 changed files
with
174 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* drmem.h: Power specific logical memory block representation | ||
* | ||
* Copyright 2017 IBM Corporation | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the License, or (at your option) any later version. | ||
*/ | ||
|
||
#ifndef _ASM_POWERPC_LMB_H | ||
#define _ASM_POWERPC_LMB_H | ||
|
||
struct drmem_lmb { | ||
u64 base_addr; | ||
u32 drc_index; | ||
u32 aa_index; | ||
u32 flags; | ||
}; | ||
|
||
struct drmem_lmb_info { | ||
struct drmem_lmb *lmbs; | ||
int n_lmbs; | ||
u32 lmb_size; | ||
}; | ||
|
||
extern struct drmem_lmb_info *drmem_info; | ||
|
||
#define for_each_drmem_lmb_in_range(lmb, start, end) \ | ||
for ((lmb) = (start); (lmb) <= (end); (lmb)++) | ||
|
||
#define for_each_drmem_lmb(lmb) \ | ||
for_each_drmem_lmb_in_range((lmb), \ | ||
&drmem_info->lmbs[0], \ | ||
&drmem_info->lmbs[drmem_info->n_lmbs - 1]) | ||
|
||
static inline u32 drmem_lmb_size(void) | ||
{ | ||
return drmem_info->lmb_size; | ||
} | ||
|
||
#ifdef CONFIG_PPC_PSERIES | ||
void __init walk_drmem_lmbs_early(unsigned long node, | ||
void (*func)(struct drmem_lmb *, const __be32 **)); | ||
#endif | ||
|
||
#endif /* _ASM_POWERPC_LMB_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Dynamic reconfiguration memory support | ||
* | ||
* Copyright 2017 IBM Corporation | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the License, or (at your option) any later version. | ||
*/ | ||
|
||
#define pr_fmt(fmt) "drmem: " fmt | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/of.h> | ||
#include <linux/of_fdt.h> | ||
#include <linux/memblock.h> | ||
#include <asm/prom.h> | ||
#include <asm/drmem.h> | ||
|
||
static struct drmem_lmb_info __drmem_info; | ||
struct drmem_lmb_info *drmem_info = &__drmem_info; | ||
|
||
#ifdef CONFIG_PPC_PSERIES | ||
static void __init read_drconf_v1_cell(struct drmem_lmb *lmb, | ||
const __be32 **prop) | ||
{ | ||
const __be32 *p = *prop; | ||
|
||
lmb->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p); | ||
lmb->drc_index = of_read_number(p++, 1); | ||
|
||
p++; /* skip reserved field */ | ||
|
||
lmb->aa_index = of_read_number(p++, 1); | ||
lmb->flags = of_read_number(p++, 1); | ||
|
||
*prop = p; | ||
} | ||
|
||
static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, | ||
void (*func)(struct drmem_lmb *, const __be32 **)) | ||
{ | ||
struct drmem_lmb lmb; | ||
u32 i, n_lmbs; | ||
|
||
n_lmbs = of_read_number(prop++, 1); | ||
|
||
for (i = 0; i < n_lmbs; i++) { | ||
read_drconf_v1_cell(&lmb, &prop); | ||
func(&lmb, &usm); | ||
} | ||
} | ||
|
||
void __init walk_drmem_lmbs_early(unsigned long node, | ||
void (*func)(struct drmem_lmb *, const __be32 **)) | ||
{ | ||
const __be32 *prop, *usm; | ||
int len; | ||
|
||
prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len); | ||
if (!prop || len < dt_root_size_cells * sizeof(__be32)) | ||
return; | ||
|
||
drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop); | ||
|
||
usm = of_get_flat_dt_prop(node, "linux,drconf-usable-memory", &len); | ||
|
||
prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &len); | ||
if (prop) | ||
__walk_drmem_v1_lmbs(prop, usm, func); | ||
|
||
memblock_dump_all(); | ||
} | ||
|
||
#endif |