aboutsummaryrefslogtreecommitdiff
path: root/hw/spapr.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/spapr.c')
-rw-r--r--hw/spapr.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/hw/spapr.c b/hw/spapr.c
index c24c92b1a0..57140d231d 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -52,12 +52,15 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
sPAPREnvironment *spapr,
target_phys_addr_t initrd_base,
target_phys_addr_t initrd_size,
- const char *kernel_cmdline)
+ const char *kernel_cmdline,
+ long hash_shift)
{
void *fdt;
uint64_t mem_reg_property[] = { 0, cpu_to_be64(ramsize) };
uint32_t start_prop = cpu_to_be32(initrd_base);
uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
+ uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
+ char hypertas_prop[] = "hcall-pft\0hcall-term";
int i;
char *modelname;
int ret;
@@ -145,6 +148,8 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
* full emu, for kvm we should copy it from the host */
_FDT((fdt_property_cell(fdt, "clock-frequency", 1000000000)));
_FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr)));
+ _FDT((fdt_property(fdt, "ibm,pft-size",
+ pft_size_prop, sizeof(pft_size_prop))));
_FDT((fdt_property_string(fdt, "status", "okay")));
_FDT((fdt_property(fdt, "64-bit", NULL, 0)));
@@ -160,6 +165,14 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
_FDT((fdt_end_node(fdt)));
+ /* RTAS */
+ _FDT((fdt_begin_node(fdt, "rtas")));
+
+ _FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas_prop,
+ sizeof(hypertas_prop))));
+
+ _FDT((fdt_end_node(fdt)));
+
/* vdevice */
_FDT((fdt_begin_node(fdt, "vdevice")));
@@ -208,12 +221,13 @@ static void ppc_spapr_init(ram_addr_t ram_size,
const char *cpu_model)
{
CPUState *envs[MAX_CPUS];
- void *fdt;
+ void *fdt, *htab;
int i;
ram_addr_t ram_offset;
target_phys_addr_t fdt_addr;
uint32_t kernel_base, initrd_base;
- long kernel_size, initrd_size;
+ long kernel_size, initrd_size, htab_size;
+ long pteg_shift = 17;
int fdt_size;
spapr = qemu_malloc(sizeof(*spapr));
@@ -250,6 +264,18 @@ static void ppc_spapr_init(ram_addr_t ram_size,
ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", ram_size);
cpu_register_physical_memory(0, ram_size, ram_offset);
+ /* allocate hash page table. For now we always make this 16mb,
+ * later we should probably make it scale to the size of guest
+ * RAM */
+ htab_size = 1ULL << (pteg_shift + 7);
+ htab = qemu_mallocz(htab_size);
+
+ for (i = 0; i < smp_cpus; i++) {
+ envs[i]->external_htab = htab;
+ envs[i]->htab_base = -1;
+ envs[i]->htab_mask = htab_size - 1;
+ }
+
spapr->vio_bus = spapr_vio_bus_init();
for (i = 0; i < MAX_SERIAL_PORTS; i++) {
@@ -296,7 +322,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
/* Prepare the device tree */
fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
- initrd_base, initrd_size, kernel_cmdline);
+ initrd_base, initrd_size, kernel_cmdline,
+ pteg_shift + 7);
assert(fdt != NULL);
cpu_physical_memory_write(fdt_addr, fdt, fdt_size);