Skip to content

Commit

Permalink
hw/ppc: add a ppc_create_page_sizes_prop() helper routine
Browse files Browse the repository at this point in the history
The exact same routine will be used in PowerNV.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
  • Loading branch information
legoater authored and dgibson committed Sep 7, 2016
1 parent ce9863b commit 3654fa9
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 36 deletions.
2 changes: 1 addition & 1 deletion hw/ppc/Makefile.objs
@@ -1,5 +1,5 @@
# shared objects
obj-y += ppc.o ppc_booke.o
obj-y += ppc.o ppc_booke.o fdt.o
# IBM pSeries (sPAPR)
obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
Expand Down
49 changes: 49 additions & 0 deletions hw/ppc/fdt.c
@@ -0,0 +1,49 @@
/*
* QEMU PowerPC helper routines for the device tree.
*
* Copyright (C) 2016 IBM Corp.
*
* This code is licensed under the GPL version 2 or later. See the
* COPYING file in the top-level directory.
*/

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "target-ppc/cpu.h"

#include "hw/ppc/fdt.h"

#if defined(TARGET_PPC64)
size_t ppc_create_page_sizes_prop(CPUPPCState *env, uint32_t *prop,
size_t maxsize)
{
size_t maxcells = maxsize / sizeof(uint32_t);
int i, j, count;
uint32_t *p = prop;

for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
struct ppc_one_seg_page_size *sps = &env->sps.sps[i];

if (!sps->page_shift) {
break;
}
for (count = 0; count < PPC_PAGE_SIZES_MAX_SZ; count++) {
if (sps->enc[count].page_shift == 0) {
break;
}
}
if ((p - prop) >= (maxcells - 3 - count * 2)) {
break;
}
*(p++) = cpu_to_be32(sps->page_shift);
*(p++) = cpu_to_be32(sps->slb_enc);
*(p++) = cpu_to_be32(count);
for (j = 0; j < count; j++) {
*(p++) = cpu_to_be32(sps->enc[j].page_shift);
*(p++) = cpu_to_be32(sps->enc[j].pte_enc);
}
}

return (p - prop) * sizeof(uint32_t);
}
#endif
36 changes: 1 addition & 35 deletions hw/ppc/spapr.c
Expand Up @@ -250,40 +250,6 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
return ret;
}


static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop,
size_t maxsize)
{
size_t maxcells = maxsize / sizeof(uint32_t);
int i, j, count;
uint32_t *p = prop;

for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
struct ppc_one_seg_page_size *sps = &env->sps.sps[i];

if (!sps->page_shift) {
break;
}
for (count = 0; count < PPC_PAGE_SIZES_MAX_SZ; count++) {
if (sps->enc[count].page_shift == 0) {
break;
}
}
if ((p - prop) >= (maxcells - 3 - count * 2)) {
break;
}
*(p++) = cpu_to_be32(sps->page_shift);
*(p++) = cpu_to_be32(sps->slb_enc);
*(p++) = cpu_to_be32(count);
for (j = 0; j < count; j++) {
*(p++) = cpu_to_be32(sps->enc[j].page_shift);
*(p++) = cpu_to_be32(sps->enc[j].pte_enc);
}
}

return (p - prop) * sizeof(uint32_t);
}

static hwaddr spapr_node0_size(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
Expand Down Expand Up @@ -689,7 +655,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
_FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
}

page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop,
page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop,
sizeof(page_sizes_prop));
if (page_sizes_prop_size) {
_FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
Expand Down
5 changes: 5 additions & 0 deletions include/hw/ppc/fdt.h
Expand Up @@ -12,6 +12,8 @@

#include "qemu/error-report.h"

typedef struct CPUPPCState CPUPPCState;

#define _FDT(exp) \
do { \
int ret = (exp); \
Expand All @@ -22,4 +24,7 @@
} \
} while (0)

size_t ppc_create_page_sizes_prop(CPUPPCState *env, uint32_t *prop,
size_t maxsize);

#endif /* PPC_FDT_H */

0 comments on commit 3654fa9

Please sign in to comment.