[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PULL 20/52] spapr: Locate RTAS and device-tree based on real
From: |
Alexander Graf |
Subject: |
[Qemu-ppc] [PULL 20/52] spapr: Locate RTAS and device-tree based on real RMA |
Date: |
Thu, 4 Sep 2014 19:20:08 +0200 |
From: Benjamin Herrenschmidt <address@hidden>
We currently calculate the final RTAS and FDT location based on
the early estimate of the RMA size, cropped to 256M on KVM since
we only know the real RMA size at reset time which happens much
later in the boot process.
This means the FDT and RTAS end up right below 256M while they
could be much higher, using precious RMA space and limiting
what the OS bootloader can put there which has proved to be
a problem with some OSes (such as when using very large initrd's)
Fortunately, we do the actual copy of the device-tree into guest
memory much later, during reset, late enough to be able to do it
using the final RMA value, we just need to move the calculation
to the right place.
However, RTAS is still loaded too early, so we change the code to
load the tiny blob into qemu memory early on, and then copy it into
guest memory at reset time. It's small enough that the memory usage
doesn't matter.
Signed-off-by: Benjamin Herrenschmidt <address@hidden>
[aik: fixed errors from checkpatch.pl, defined RTAS_MAX_ADDR]
Signed-off-by: Alexey Kardashevskiy <address@hidden>
[agraf: fix compilation on 32bit hosts]
Signed-off-by: Alexander Graf <address@hidden>
---
hw/ppc/spapr.c | 34 ++++++++++++++++++++++------------
include/hw/ppc/spapr.h | 3 ++-
2 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 27e64cc..a916c4e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -71,6 +71,7 @@
*/
#define FDT_MAX_SIZE 0x40000
#define RTAS_MAX_SIZE 0x10000
+#define RTAS_MAX_ADDR 0x80000000 /* RTAS must stay below that */
#define FW_MAX_SIZE 0x400000
#define FW_FILE_NAME "slof.bin"
#define FW_OVERHEAD 0x2800000
@@ -854,16 +855,30 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
static void ppc_spapr_reset(void)
{
PowerPCCPU *first_ppc_cpu;
+ uint32_t rtas_limit;
/* Reset the hash table & recalc the RMA */
spapr_reset_htab(spapr);
qemu_devices_reset();
+ /*
+ * We place the device tree and RTAS just below either the top of the RMA,
+ * or just below 2GB, whichever is lowere, so that it can be
+ * processed with 32-bit real mode code if necessary
+ */
+ rtas_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR);
+ spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE;
+ spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE;
+
/* Load the fdt */
spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
spapr->rtas_size);
+ /* Copy RTAS over */
+ cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
+ spapr->rtas_size);
+
/* Set up the entry state */
first_ppc_cpu = POWERPC_CPU(first_cpu);
first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
@@ -1283,7 +1298,7 @@ static void ppc_spapr_init(MachineState *machine)
hwaddr node0_size = spapr_node0_size();
uint32_t initrd_base = 0;
long kernel_size = 0, initrd_size = 0;
- long load_limit, rtas_limit, fw_size;
+ long load_limit, fw_size;
bool kernel_le = false;
char *filename;
@@ -1328,13 +1343,8 @@ static void ppc_spapr_init(MachineState *machine)
exit(1);
}
- /* We place the device tree and RTAS just below either the top of the RMA,
- * or just below 2GB, whichever is lowere, so that it can be
- * processed with 32-bit real mode code if necessary */
- rtas_limit = MIN(spapr->rma_size, 0x80000000);
- spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE;
- spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE;
- load_limit = spapr->fdt_addr - FW_OVERHEAD;
+ /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
+ load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
/* We aim for a hash table of size 1/128 the size of RAM. The
* normal rule of thumb is 1/64 the size of RAM, but that's much
@@ -1402,14 +1412,14 @@ static void ppc_spapr_init(MachineState *machine)
}
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
- spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,
- rtas_limit - spapr->rtas_addr);
- if (spapr->rtas_size < 0) {
+ spapr->rtas_size = get_image_size(filename);
+ spapr->rtas_blob = g_malloc(spapr->rtas_size);
+ if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
exit(1);
}
if (spapr->rtas_size > RTAS_MAX_SIZE) {
- hw_error("RTAS too big ! 0x%lx bytes (max is 0x%x)\n",
+ hw_error("RTAS too big ! 0x%zx bytes (max is 0x%x)\n",
spapr->rtas_size, RTAS_MAX_SIZE);
exit(1);
}
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 7fff979..36e8e51 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -24,7 +24,8 @@ typedef struct sPAPREnvironment {
hwaddr rma_size;
int vrma_adjust;
hwaddr fdt_addr, rtas_addr;
- long rtas_size;
+ ssize_t rtas_size;
+ void *rtas_blob;
void *fdt_skel;
target_ulong entry_point;
uint64_t rtc_offset;
--
1.8.1.4
- [Qemu-ppc] [PULL 01/52] PPC: KVM: Fix g3beige and mac99 when HV is loaded, (continued)
- [Qemu-ppc] [PULL 01/52] PPC: KVM: Fix g3beige and mac99 when HV is loaded, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 18/52] spapr: Fix ibm, associativity for memory nodes, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 10/52] spapr: add uuid/host details to device tree, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 14/52] spapr: Use DT memory node rendering helper for other nodes, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 02/52] ppc: spapr-rtas - implement os-term rtas call, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 19/52] loader: Add load_image_size() to replace load_image(), Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 21/52] ppc: debug stub: Get trap instruction opcode from KVM, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 23/52] ppc: Add software breakpoint support, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 05/52] linux-user: Enable Signal Handlers on PPC64, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 06/52] linux-user: Properly Dereference PPC64 ELFv1 Signal Handler Pointer, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 20/52] spapr: Locate RTAS and device-tree based on real RMA,
Alexander Graf <=
- [Qemu-ppc] [PULL 22/52] ppc: synchronize excp_vectors for injecting exception, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 11/52] PPC: mac99: Move NVRAM to page boundary when necessary, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 27/52] target-ppc: Bug Fix: rlwnm, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 24/52] ppc: Add hw breakpoint watchpoint support, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 26/52] target-ppc: Bug Fix: rlwinm, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 33/52] target-ppc: Bug Fix: srad, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 25/52] ppc/spapr: Fix MAX_CPUS to 255, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 30/52] target-ppc: Bug Fix: mullw, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 37/52] PPC: mac_nvram: Remove unused functions, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 35/52] PPC: KVM: Use vm check_extension for pv hcall, Alexander Graf, 2014/09/04