@@ -593,11 +593,18 @@ u32 dt_property_get_cell(const struct dt_property *prop, u32 index)
return fdt32_to_cpu(((const u32 *)prop->prop)[index]);
}
+u64 dt_property_get_u64(const struct dt_property *prop, u32 index)
+{
+ assert(prop->len >= (index+1)*sizeof(u64));
+ /* Always aligned, so this works. */
+ return fdt64_to_cpu(((const fdt64_t *)prop->prop)[index]);
+}
+
void dt_property_set_cell(struct dt_property *prop, u32 index, u32 val)
{
assert(prop->len >= (index+1)*sizeof(u32));
/* Always aligned, so this works. */
- ((u32 *)prop->prop)[index] = cpu_to_fdt32(val);
+ ((fdt32_t *)prop->prop)[index] = cpu_to_fdt32(val);
}
/* First child of this node. */
@@ -1524,16 +1524,8 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
char name[MAX_NAME];
char compat[MAX_NAME];
uint32_t rev_class;
- __be32 reg[5];
uint8_t intpin;
bool is_pcie;
- const __be32 ranges_direct[] = {
- /* 64-bit direct mapping. We know the bridges
- * don't cover the entire address space so
- * use 0xf00... as a good compromise. */
- cpu_to_be32(0x02000000), 0x0, 0x0,
- cpu_to_be32(0x02000000), 0x0, 0x0,
- cpu_to_be32(0xf0000000), 0x0};
pci_cfg_read32(phb, pd->bdfn, PCI_CFG_REV_ID, &rev_class);
pci_cfg_read8(phb, pd->bdfn, PCI_CFG_INT_PIN, &intpin);
@@ -1609,9 +1601,7 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
* entry in the "reg" property. That's enough for Linux and we might
* even want to make this legit in future ePAPR
*/
- reg[0] = cpu_to_be32(pd->bdfn << 8);
- reg[1] = reg[2] = reg[3] = reg[4] = 0;
- dt_add_property(np, "reg", reg, sizeof(reg));
+ dt_add_property_cells(np, "reg", pd->bdfn << 8, 0, 0, 0, 0);
/* Print summary info about the device */
pci_print_summary_line(phb, pd, np, rev_class, cname);
@@ -1646,7 +1636,13 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
* (ie. an empty ranges property).
* Instead add a ranges property that explicitly translates 1:1.
*/
- dt_add_property(np, "ranges", ranges_direct, sizeof(ranges_direct));
+ dt_add_property_cells(np, "ranges",
+ /* 64-bit direct mapping. We know the bridges
+ * don't cover the entire address space so
+ * use 0xf00... as a good compromise. */
+ 0x02000000, 0x0, 0x0,
+ 0x02000000, 0x0, 0x0,
+ 0xf0000000, 0x0);
}
void __noinline pci_add_device_nodes(struct phb *phb,
@@ -95,7 +95,6 @@ static struct dt_node *io_add_phb3(const struct cechub_io_hub *hub,
unsigned int spci_xscom)
{
struct dt_node *pbcq;
- uint32_t reg[6];
unsigned int hdif_vers;
/* Get HDIF version */
@@ -109,13 +108,10 @@ static struct dt_node *io_add_phb3(const struct cechub_io_hub *hub,
/* "reg" property contains in order the PE, PCI and SPCI XSCOM
* addresses
*/
- reg[0] = cpu_to_be32(pe_xscom);
- reg[1] = cpu_to_be32(0x20);
- reg[2] = cpu_to_be32(pci_xscom);
- reg[3] = cpu_to_be32(0x05);
- reg[4] = cpu_to_be32(spci_xscom);
- reg[5] = cpu_to_be32(0x15);
- dt_add_property(pbcq, "reg", reg, sizeof(reg));
+ dt_add_property_cells(pbcq, "reg",
+ pe_xscom, 0x20,
+ pci_xscom, 0x05,
+ spci_xscom, 0x15);
/* A couple more things ... */
dt_add_property_strings(pbcq, "compatible", "ibm,power8-pbcq");
@@ -202,7 +198,6 @@ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub,
int phb_base)
{
struct dt_node *pbcq;
- uint32_t reg[4];
uint8_t active_phb_mask = hub->fab_br0_pdt;
uint32_t pe_xscom = 0x4010c00 + (pec_index * 0x0000400);
uint32_t pci_xscom = 0xd010800 + (pec_index * 0x1000000);
@@ -214,11 +209,9 @@ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub,
return NULL;
/* "reg" property contains (in order) the PE and PCI XSCOM addresses */
- reg[0] = cpu_to_be32(pe_xscom);
- reg[1] = cpu_to_be32(0x100);
- reg[2] = cpu_to_be32(pci_xscom);
- reg[3] = cpu_to_be32(0x200);
- dt_add_property(pbcq, "reg", reg, sizeof(reg));
+ dt_add_property_cells(pbcq, "reg",
+ pe_xscom, 0x100,
+ pci_xscom, 0x200);
/* The hubs themselves go under the stacks */
dt_add_property_strings(pbcq, "compatible", "ibm,power9-pbcq");
@@ -77,24 +77,21 @@ static void append_chip_id(struct dt_node *mem, u32 id)
{
struct dt_property *prop;
size_t len, i;
- be32 *p;
prop = __dt_find_property(mem, "ibm,chip-id");
if (!prop)
return;
len = prop->len >> 2;
- p = (be32*)prop->prop;
/* Check if it exists already */
for (i = 0; i < len; i++) {
- if (be32_to_cpu(p[i]) == id)
+ if (dt_property_get_cell(prop, i) == id)
return;
}
/* Add it to the list */
dt_resize_property(&prop, (len + 1) << 2);
- p = (be32 *)prop->prop;
- p[len] = cpu_to_be32(id);
+ dt_property_set_cell(prop, len, id);
}
static void update_status(struct dt_node *mem, uint32_t status)
@@ -1912,7 +1912,7 @@ static void fsp_init_links(struct dt_node *fsp_node)
u64 reg;
u32 link;
- link = be32_to_cpu(((const __be32 *)linksprop->prop)[i]);
+ link = dt_property_get_cell(linksprop, i);
fiop = &fsp->iopath[i];
fiop->psi = psi_find_link(link);
if (fiop->psi == NULL) {
@@ -5485,11 +5485,11 @@ static bool phb4_calculate_windows(struct phb4 *p)
"ibm,mmio-windows", -1);
assert(prop->len >= (2 * sizeof(uint64_t)));
- p->mm0_base = be64_to_cpu(((__be64 *)prop->prop)[0]);
- p->mm0_size = be64_to_cpu(((__be64 *)prop->prop)[1]);
+ p->mm0_base = dt_property_get_u64(prop, 0);
+ p->mm0_size = dt_property_get_u64(prop, 1);
if (prop->len > 16) {
- p->mm1_base = be64_to_cpu(((__be64 *)prop->prop)[2]);
- p->mm1_size = be64_to_cpu(((__be64 *)prop->prop)[3]);
+ p->mm1_base = dt_property_get_u64(prop, 2);
+ p->mm1_size = dt_property_get_u64(prop, 3);
}
/* Sort them so that 0 is big and 1 is small */
@@ -5601,11 +5601,11 @@ static void phb4_create(struct dt_node *np)
/* Get the various XSCOM register bases from the device-tree */
prop = dt_require_property(np, "ibm,xscom-bases", 5 * sizeof(uint32_t));
- p->pe_xscom = be32_to_cpu(((__be32 *)prop->prop)[0]);
- p->pe_stk_xscom = be32_to_cpu(((__be32 *)prop->prop)[1]);
- p->pci_xscom = be32_to_cpu(((__be32 *)prop->prop)[2]);
- p->pci_stk_xscom = be32_to_cpu(((__be32 *)prop->prop)[3]);
- p->etu_xscom = be32_to_cpu(((__be32 *)prop->prop)[4]);
+ p->pe_xscom = dt_property_get_cell(prop, 0);
+ p->pe_stk_xscom = dt_property_get_cell(prop, 1);
+ p->pci_xscom = dt_property_get_cell(prop, 2);
+ p->pci_stk_xscom = dt_property_get_cell(prop, 3);
+ p->etu_xscom = dt_property_get_cell(prop, 4);
/*
* We skip the initial PERST assertion requested by the generic code
@@ -5766,7 +5766,6 @@ static void phb4_probe_stack(struct dt_node *stk_node, uint32_t pec_index,
uint64_t val, phb_bar = 0, irq_bar = 0, bar_en;
uint64_t mmio0_bar = 0, mmio0_bmask, mmio0_sz;
uint64_t mmio1_bar = 0, mmio1_bmask, mmio1_sz;
- uint64_t reg[4];
void *foo;
__be64 mmio_win[4];
unsigned int mmio_win_sz;
@@ -5864,18 +5863,15 @@ static void phb4_probe_stack(struct dt_node *stk_node, uint32_t pec_index,
prlog_once(PR_DEBUG, "Version reg: 0x%016llx\n", in_be64(foo));
/* Create PHB node */
- reg[0] = cpu_to_be64(phb_bar);
- reg[1] = cpu_to_be64(0x1000);
- reg[2] = cpu_to_be64(irq_bar);
- reg[3] = cpu_to_be64(0x10000000);
-
np = dt_new_addr(dt_root, "pciex", phb_bar);
if (!np)
return;
dt_add_property_strings(np, "compatible", "ibm,power9-pciex", "ibm,ioda3-phb");
dt_add_property_strings(np, "device_type", "pciex");
- dt_add_property(np, "reg", reg, sizeof(reg));
+ dt_add_property_u64s(np, "reg",
+ phb_bar, 0x1000,
+ irq_bar, 0x10000000);
/* Everything else is handled later by skiboot, we just
* stick a few hints here
@@ -130,6 +130,7 @@ void dt_resize_property(struct dt_property **prop, size_t len);
void dt_property_set_cell(struct dt_property *prop, u32 index, u32 val);
u32 dt_property_get_cell(const struct dt_property *prop, u32 index);
+u64 dt_property_get_u64(const struct dt_property *prop, u32 index);
/* First child of this node. */
struct dt_node *dt_first(const struct dt_node *root);
This replaces several instances dt accesses with higher level primitives throughout the tree. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- core/device.c | 9 ++++++++- core/pci.c | 20 ++++++++------------ hdata/iohub.c | 21 +++++++-------------- hdata/memory.c | 7 ++----- hw/fsp/fsp.c | 2 +- hw/phb4.c | 28 ++++++++++++---------------- include/device.h | 1 + 7 files changed, 39 insertions(+), 49 deletions(-)