]> git.proxmox.com Git - mirror_qemu.git/commitdiff
PPC: E500: create multiple envs
authorAlexander Graf <agraf@suse.de>
Wed, 20 Jul 2011 23:41:16 +0000 (01:41 +0200)
committerAlexander Graf <agraf@suse.de>
Thu, 6 Oct 2011 07:43:33 +0000 (09:43 +0200)
When creating a VM, we should go through smp_cpus and create a virtual CPU for
every CPU the user requested. This patch adds support for that and moves some
code around to make that more convenient.

Signed-off-by: Alexander Graf <agraf@suse.de>
hw/ppce500_mpc8544ds.c

index 1274a3e1ebdd73bdc515acdf936c73ad0f7f8917..8d05587514cad00838da34fbb2d83c07ead2216e 100644 (file)
@@ -226,7 +226,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
                          const char *cpu_model)
 {
     PCIBus *pci_bus;
-    CPUState *env;
+    CPUState *env = NULL;
     uint64_t elf_entry;
     uint64_t elf_lowaddr;
     target_phys_addr_t entry=0;
@@ -240,24 +240,40 @@ static void mpc8544ds_init(ram_addr_t ram_size,
     qemu_irq *irqs, *mpic;
     DeviceState *dev;
     struct boot_info *boot_info;
+    CPUState *firstenv = NULL;
 
-    /* Setup CPU */
+    /* Setup CPUs */
     if (cpu_model == NULL) {
         cpu_model = "e500v2_v30";
     }
 
-    env = cpu_ppc_init(cpu_model);
-    if (!env) {
-        fprintf(stderr, "Unable to initialize CPU!\n");
-        exit(1);
-    }
+    for (i = 0; i < smp_cpus; i++) {
+        qemu_irq *input;
+        env = cpu_ppc_init(cpu_model);
+        if (!env) {
+            fprintf(stderr, "Unable to initialize CPU!\n");
+            exit(1);
+        }
+
+        if (!firstenv) {
+            firstenv = env;
+        }
 
-    /* XXX register timer? */
-    ppc_emb_timers_init(env, 400000000, PPC_INTERRUPT_DECR);
-    ppc_dcr_init(env, NULL, NULL);
+        env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
 
-    /* Register reset handler */
-    qemu_register_reset(mpc8544ds_cpu_reset, env);
+        /* XXX register timer? */
+        ppc_emb_timers_init(env, 400000000, PPC_INTERRUPT_DECR);
+        ppc_dcr_init(env, NULL, NULL);
+        /* XXX Enable DEC interrupts - probably wrong in the backend */
+        env->spr[SPR_40x_TCR] = 1 << 26;
+
+        /* Register reset handler */
+        boot_info = g_malloc0(sizeof(struct boot_info));
+        qemu_register_reset(mpc8544ds_cpu_reset, env);
+        env->load_info = boot_info;
+    }
+
+    env = firstenv;
 
     /* Fixup Memory size on a alignment boundary */
     ram_size &= ~(RAM_SIZES_ALIGN - 1);
@@ -336,8 +352,6 @@ static void mpc8544ds_init(ram_addr_t ram_size,
         }
     }
 
-    boot_info = g_malloc0(sizeof(struct boot_info));
-
     /* If we're loading a kernel directly, we must load the device tree too. */
     if (kernel_filename) {
 #ifndef CONFIG_FDT
@@ -350,10 +364,10 @@ static void mpc8544ds_init(ram_addr_t ram_size,
             exit(1);
         }
 
+        boot_info = env->load_info;
         boot_info->entry = entry;
         boot_info->dt_base = dt_base;
     }
-    env->load_info = boot_info;
 
     if (kvm_enabled()) {
         kvmppc_init();