qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH v1 4/4] target-arm: Compute page size based on A


From: vijayak
Subject: [Qemu-devel] [RFC PATCH v1 4/4] target-arm: Compute page size based on ARM target cpu type
Date: Mon, 13 Jun 2016 14:38:35 +0530

From: Vijaya Kumar K <address@hidden>

Replace TARGET_PAGE_BITS with arm_target_page_size function
in order to fetch page size at run-time.

Introduced MachineClass callback to compute target page
size at the early boot before memory initialization.
This callback is currently implemented for ARM platforms.
Based on cpu_model, the page size is updated in
target_page_bits which is defined as TARGET_PAGE_BITS.

Signed-off-by: Vijaya Kumar K <address@hidden>
---
 hw/arm/virt.c       |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/boards.h |    1 +
 target-arm/cpu.h    |   12 +++++++-----
 vl.c                |    7 +++++++
 4 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 73113cf..37aab33 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -90,6 +90,12 @@ typedef struct {
     int32_t gic_version;
 } VirtMachineState;
 
+/*
+ * Holds TARGET_AARCH_64_PAGE_BITS or TARGET_ARM_PAGE_BITS
+ * based on the the cpu type emulated at runtime.
+ */
+static uint32_t target_page_bits;
+
 #define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("virt")
 #define VIRT_MACHINE(obj) \
     OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
@@ -1099,6 +1105,47 @@ void virt_guest_info_machine_done(Notifier *notifier, 
void *data)
     virt_build_smbios(&guest_info_state->info);
 }
 
+static void machvirt_update_target_page_size(const char *cpu_model)
+{
+    char **cpustr;
+    ObjectClass *oc, *parent;
+    const char *parent_type;
+    /* Set to default page size */
+    uint32_t page_bits = TARGET_ARM_PAGE_BITS;
+
+    cpustr = g_strsplit(cpu_model, ",", 2);
+    if (!strcmp(cpustr[0], "host")) {
+#ifdef __aarch64__
+        page_bits = TARGET_AARCH64_PAGE_BITS;
+#else
+        page_bits = TARGET_ARM_PAGE_BITS;
+#endif
+        goto out;
+    }
+
+    oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
+    if (!oc) {
+        oc = cpu_class_by_name(TYPE_AARCH64_CPU, cpustr[0]);
+        if (!oc)
+           goto out;
+    }
+
+    parent = object_class_get_parent(oc);
+    if (!parent)
+       goto out;
+
+    parent_type = object_class_get_name(parent);
+    if (!strcmp(parent_type, TYPE_AARCH64_CPU))
+       page_bits = TARGET_AARCH64_PAGE_BITS;
+out:
+    target_page_bits = page_bits;
+}
+
+uint32_t arm_get_target_page_bits(void)
+{
+    return target_page_bits;
+}
+
 static void machvirt_init(MachineState *machine)
 {
     VirtMachineState *vms = VIRT_MACHINE(machine);
@@ -1376,6 +1423,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
     mc->block_default_type = IF_VIRTIO;
     mc->no_cdrom = 1;
     mc->pci_allow_0_address = true;
+    mc->update_target_page_size = machvirt_update_target_page_size;
 }
 
 static const TypeInfo virt_machine_info = {
diff --git a/include/hw/boards.h b/include/hw/boards.h
index d268bd0..1e8abb6 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -124,6 +124,7 @@ struct MachineClass {
                                            DeviceState *dev);
     unsigned (*cpu_index_to_socket_id)(unsigned cpu_index);
     CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
+    void (*update_target_page_size)(const char *cpu_model);
 };
 
 /**
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 17d8051..f593620 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1743,14 +1743,16 @@ bool write_cpustate_to_list(ARMCPU *cpu);
 #define ARM_CPUID_TI915T      0x54029152
 #define ARM_CPUID_TI925T      0x54029252
 
-#if defined(CONFIG_USER_ONLY)
-#define TARGET_PAGE_BITS 12
-#else
+uint32_t arm_get_target_page_bits(void);
+/*
+ * Minimum page size for aarch64 is 4K
+ */
+#define TARGET_AARCH64_PAGE_BITS 12
 /* The ARM MMU allows 1k pages.  */
 /* ??? Linux doesn't actually use these, and they're deprecated in recent
    architecture revisions.  Maybe a configure option to disable them.  */
-#define TARGET_PAGE_BITS 10
-#endif
+#define TARGET_ARM_PAGE_BITS 10
+#define TARGET_PAGE_BITS arm_get_target_page_bits()
 
 #if defined(TARGET_AARCH64)
 #  define TARGET_PHYS_ADDR_SPACE_BITS 48
diff --git a/vl.c b/vl.c
index b6da265..a317cf1 100644
--- a/vl.c
+++ b/vl.c
@@ -4045,6 +4045,13 @@ int main(int argc, char **argv, char **envp)
     object_property_add_child(object_get_root(), "machine",
                               OBJECT(current_machine), &error_abort);
 
+    /*
+     * Compute target page size dynamically if arch supports
+     * multiple page sizes. Ex: ARM
+     */
+    if (machine_class->update_target_page_size)
+        machine_class->update_target_page_size(cpu_model);
+
     init_l1_page_table_param();
 
     cpu_exec_init_all();
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]