Skip to contentSkip to conversation

CPU architecture selection

PATCH In review Paul Brook 2 participants 4 messages Mar 26, 2005 Kbuild

lore
Share & tools
lore

Paul Brook

author
#0 lore raw

PATCH 1/1 CPU architecture selection

The attached patch adds a -cpu commandline option to qemu to allow the user to select what type of CPU is emulated. It currently only does anything useful for arm targets, but it should be easy to hook other targets into the same mechanism.

I implemented the selection as a bitmask. This allows users to select a CPU by the features it provides, and also allows creation of convenient aliases for common CPUs.

Paul

? a.out
? bar
? check_ops
? foo
? foo2
? gdbstub.h
? p2
? patch.stuff
? qemu-arm
? qemu-mkcow
? qplex
? qplex-wip-20050226.tar.bz2
? qplex-wip-20050228.tar.bz2
? qplex-wip-20050306.tar.bz2
? qplex-wip-20050313.tar.bz2
? qplex20050213.tar.bz2
? qplex20050214.tar.bz2
? qplex20050215.tar.bz2
? qplex20050216.tar.bz2
? qplex20050220.tar.bz2
? qplex20050221.tar.bz2
? qplex20050222.tar.bz2
? qplex20050223.tar.bz2
? qplex20050224.tar.bz2
? qplex20050226.tar.bz2
? qplex20050228.tar.bz2
? qplex20050313.tar.bz2
? qplex20050314.tar.bz2
? qplex20050321.tar.bz2
? test.c
? tmp.cow
? vmdk2raw
? fpu/libm
? linux-user/p
? target-arm/p
? target-i386/p
? target-ppc/p
Index: Makefile.target
===================================================================
RCS file: /cvsroot/qemu/qemu/Makefile.target,v
retrieving revision 1.62

Makefile.target +1 -1
diff -u -p -r1.62 Makefile.target
@@ -238,7 +238,7 @@ OBJS+= libqemu.a
 
 # cpu emulator library
 LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
-        translate.o op.o 
+        translate.o op.o cpu-util.o
 ifdef CONFIG_SOFTFLOAT
 LIBOBJS+=fpu/softfloat.o
 else

Index: cpu-all.h
===================================================================
RCS file: /cvsroot/qemu/qemu/cpu-all.h,v
retrieving revision 1.42

cpu-all.h +15 -0
diff -u -p -r1.42 cpu-all.h
@@ -760,4 +760,19 @@ void cpu_physical_memory_reset_dirty(tar
 void dump_exec_info(FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
 
+/* Architecture flags for different CPU variants.  */
+typedef unsigned int cpu_archflags;
+struct cpu_arches
+{
+  const char * name;
+  cpu_archflags flags;
+};
+extern const struct cpu_arches cpu_arches[NUM_CPU_ARCHES];
+extern cpu_archflags current_cpu_archflags;
+void parse_cpu_archflags (const char *);
+void parse_cpu_archflags (const char *);
+void show_available_archflags (void);
+
+#define HAVE_ARCH(x) ((current_cpu_archflags & CPU_ARCH_ ## x) != 0)
+
 #endif /* CPU_ALL_H */

Index: cpu-util.c
===================================================================
RCS file: cpu-util.c

cpu-util.c new file +84 -0

84 lines not on this page · raw message

Index: vl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.c,v
retrieving revision 1.124

vl.c +14 -1
diff -u -p -r1.124 vl.c
@@ -2784,6 +2784,7 @@ void help(void)
            "                (default is CL-GD5446 PCI VGA)\n"
 #endif
            "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
+	   "-cpu cpu        set the emulated CPU variant (default=%s)\n"
            "\n"
            "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -2800,7 +2801,9 @@ void help(void)
            DEFAULT_RAM_SIZE,
            DEFAULT_NETWORK_SCRIPT,
            DEFAULT_GDBSTUB_PORT,
-           "/tmp/qemu.log");
+           "/tmp/qemu.log",
+           CPU_DEFAULT_ARCH);
+    show_available_archflags ();
 #ifndef CONFIG_SOFTMMU
     printf("\n"
            "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
@@ -2864,6 +2867,7 @@ enum {
     QEMU_OPTION_full_screen,
     QEMU_OPTION_pidfile,
     QEMU_OPTION_no_kqemu,
+    QEMU_OPTION_cpu,
 };
 
 typedef struct QEMUOption {
@@ -2936,6 +2940,7 @@ const QEMUOption qemu_options[] = {
     /* temporary options */
     { "pci", 0, QEMU_OPTION_pci },
     { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
+    { "cpu", HAS_ARG, QEMU_OPTION_cpu },
     { NULL },
 };
 
@@ -3014,6 +3019,7 @@ int main(int argc, char **argv)
     char parallel_devices[MAX_PARALLEL_PORTS][128];
     int parallel_device_index;
     const char *loadvm = NULL;
+    int set_cpu = 0;
     
 #if !defined(CONFIG_SOFTMMU)
     /* we never want that malloc() uses mmap() */
@@ -3383,6 +3389,10 @@ int main(int argc, char **argv)
             case QEMU_OPTION_pidfile:
                 create_pidfile(optarg);
                 break;
+            case QEMU_OPTION_cpu:
+                parse_cpu_archflags(optarg);
+                set_cpu = 1;
+                break;
 #ifdef USE_KQEMU
             case QEMU_OPTION_no_kqemu:
                 kqemu_allowed = 0;
@@ -3459,6 +3469,9 @@ int main(int argc, char **argv)
         }
     }
 
+    if (set_cpu)
+	parse_cpu_archflags(CPU_DEFAULT_ARCH);
+
     /* init the memory */
     phys_ram_size = ram_size + vga_ram_size + bios_size;
 

Index: linux-user/main.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v
retrieving revision 1.62

main.c +18 -3
diff -u -p -r1.62 main.c
@@ -330,7 +330,8 @@ void cpu_loop(CPUARMState *env)
                 /* we get the opcode */
                 opcode = ldl_raw((uint8_t *)env->regs[15]);
                 
-                if (EmulateAll(opcode, &ts->fpa, env->regs) == 0) {
+                if ((current_cpu_archflags & CPU_ARCH_FPA) == 0
+		    || EmulateAll(opcode, &ts->fpa, env->regs) == 0) {
                     info.si_signo = SIGILL;
                     info.si_errno = 0;
                     info.si_code = TARGET_ILL_ILLOPN;
@@ -942,11 +943,14 @@ void usage(void)
            "-no-code-copy   disable code copy acceleration\n"
 #endif
            "-d options   activate log (logfile=%s)\n"
-           "-p pagesize  set the host page size to 'pagesize'\n",
+           "-p pagesize  set the host page size to 'pagesize'\n"
+           "-cpu cpu     set the emulated CPU variant (default=%s)\n",
            TARGET_ARCH,
            interp_prefix, 
            x86_stack_size,
-           DEBUG_LOGFILE);
+           DEBUG_LOGFILE,
+           CPU_DEFAULT_ARCH);
+    show_available_archflags ();
     _exit(1);
 }
 
@@ -967,6 +971,7 @@ int main(int argc, char **argv)
     CPUState *env;
     int optind;
     const char *r;
+    int set_cpu = 0;
     
     if (argc <= 1)
         usage();
@@ -1020,6 +1025,14 @@ int main(int argc, char **argv)
                 fprintf(stderr, "page size must be a power of two\n");
                 exit(1);
             }
+        } else if (!strncmp(r, "cpu", 3)) {
+            if (r[3] != '=' && (r[3] != 0 || optind >= argc))
+                break;
+            if (r[3] == '=')
+                parse_cpu_archflags(&r[4]);
+            else
+                parse_cpu_archflags(argv[optind++]);
+            set_cpu = 1;
         } else 
 #ifdef USE_CODE_COPY
         if (!strcmp(r, "no-code-copy")) {
@@ -1043,6 +1056,8 @@ int main(int argc, char **argv)
     /* Scan interp_prefix dir for replacement files. */
     init_paths(interp_prefix);
 
+    if (!set_cpu)
+	parse_cpu_archflags(CPU_DEFAULT_ARCH);
     /* NOTE: we need to init the CPU at this stage to get
        qemu_host_page_size */
     env = cpu_init();

Index: target-arm/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.8

cpu.h +14 -0
diff -u -p -r1.8 cpu.h
@@ -103,6 +103,20 @@ struct siginfo;
 int cpu_arm_signal_handler(int host_signum, struct siginfo *info, 
                            void *puc);
 
+#define NUM_CPU_ARCHES	10
+#define CPU_ARCH_4	(1 << 0)
+#define CPU_ARCH_T	(1 << 1)
+#define CPU_ARCH_5	(1 << 2)
+#define CPU_ARCH_5E	(1 << 3)
+#define CPU_ARCH_J	(1 << 4)
+#define CPU_ARCH_6	(1 << 5)
+#define CPU_ARCH_VFPs	(1 << 6)
+#define CPU_ARCH_VFPd	(1 << 7)
+#define CPU_ARCH_VFP2	(1 << 8)
+#define CPU_ARCH_FPA	(1 << 9)
+
+#define CPU_DEFAULT_ARCH "armv5te+fpa+vfp2"
+
 #define TARGET_PAGE_BITS 12
 #include "cpu-all.h"
 

Index: target-arm/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/translate.c,v retrieving revision 1.18

translate.c +55 -2

156 lines not on this page · raw message

Index: target-i386/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.28

cpu.h +3 -0
diff -u -p -r1.28 cpu.h
@@ -634,6 +634,9 @@ void cpu_x86_update_cr0(CPUX86State *env
 #define X86_DUMP_FPU  0x0001 /* dump FPU state too */
 #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
 
+#define NUM_CPU_ARCHES	1
+#define CPU_DEFAULT_ARCH "i686"
+
 #define TARGET_PAGE_BITS 12
 #include "cpu-all.h"
 

Index: target-i386/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/translate.c,v retrieving revision 1.47

translate.c +5 -0
diff -u -p -r1.47 translate.c
@@ -29,6 +29,11 @@
 #include "exec-all.h"
 #include "disas.h"
 
+const struct cpu_arches cpu_arches[NUM_CPU_ARCHES] = 
+{
+    {"i686", 0}
+};
+
 /* XXX: move that elsewhere */
 static uint16_t *gen_opc_ptr;
 static uint32_t *gen_opparam_ptr;

Index: target-ppc/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-ppc/cpu.h,v
retrieving revision 1.16

cpu.h +3 -0
diff -u -p -r1.16 cpu.h
@@ -193,6 +193,9 @@ uint32_t cpu_ppc_load_decr (CPUPPCState 
 void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
 #endif
 
+#define NUM_CPU_ARCHES	1
+#define CPU_DEFAULT_ARCH "g3"
+
 #define TARGET_PAGE_BITS 12
 #include "cpu-all.h"
 

Index: target-ppc/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-ppc/translate.c,v retrieving revision 1.28

translate.c +5 -0
diff -u -p -r1.28 translate.c
@@ -30,6 +30,11 @@
 //#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 
+const struct cpu_arches cpu_arches[NUM_CPU_ARCHES] = 
+{
+    {"g3", 0}
+};
+
 enum {
 #define DEF(s, n, copy_size) INDEX_op_ ## s,
 #include "opc.h"

Index: target-sparc/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.16

cpu.h +3 -0
diff -u -p -r1.16 cpu.h
@@ -195,6 +195,9 @@ void cpu_set_cwp(CPUSPARCState *env1, in
 struct siginfo;
 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc);
 
+#define NUM_CPU_ARCHES	1
+#define CPU_DEFAULT_ARCH "sparc"
+
 #define TARGET_PAGE_BITS 12 /* 4k */
 #include "cpu-all.h"
 

Index: target-sparc/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-sparc/translate.c,v retrieving revision 1.19

translate.c +5 -0
diff -u -p -r1.19 translate.c
@@ -42,6 +42,11 @@
 
 #define DEBUG_DISAS
 
+const struct cpu_arches cpu_arches[NUM_CPU_ARCHES] = 
+{
+    {"sparc", 0}
+};
+
 #define DYNAMIC_PC  1 /* dynamic pc value */
 #define JUMP_PC     2 /* dynamic pc value which takes only two values
                          according to jump_pc[T2] */
#1 lore raw
Quoted 8 lines · Paul Brook

The attached patch adds a -cpu commandline option to qemu to allow the user to select what type of CPU is emulated. It currently only does anything useful for arm targets, but it should be easy to hook other targets into the same mechanism.

I implemented the selection as a bitmask. This allows users to select a CPU by the features it provides, and also allows creation of convenient aliases for common CPUs.

there is a cpu_ppc_register function in target-ppc/translate.c which does what's needed for emulated PPC selection.
The CPU is registered from the emulated board definition, ie in hw/ppc_prep.c or hw/ppc_chrp.c.
Your patch conflicts with this code.

It seems to me that cpu selection should go in board definitions, like all the rest of emulated hardware selection, then have nothing to do in target-xxx/translate.c.

Signature · 2 lines
J. Mayer <[email protected]>
Never organized
author
#2 lore raw
Quoted 10 lines · J. Mayer
Quoted 8 lines · Paul Brook

The attached patch adds a -cpu commandline option to qemu to allow the user to select what type of CPU is emulated. It currently only does anything useful for arm targets, but it should be easy to hook other targets into the same mechanism.

I implemented the selection as a bitmask. This allows users to select a CPU by the features it provides, and also allows creation of convenient aliases for common CPUs.

Quoted 5 lines

there is a cpu_ppc_register function in target-ppc/translate.c which does what's needed for emulated PPC selection.
The CPU is registered from the emulated board definition, ie in hw/ppc_prep.c or hw/ppc_chrp.c.
Your patch conflicts with this code.

Hmm, I hadn't spotted that. I'll see if I can merge them.

Quoted 3 lines

It seems to me that cpu selection should go in board definitions, like all the rest of emulated hardware selection, then have nothing to do in target-xxx/translate.c.

I'm not sure what you mean.

I guess it makes makes sense for the board to be able to specify the default cpu. That's pretty much independent of the rest of the implementation though. I'd have thought CPU choice should be fairly independent of the rest of the hardware. There's also user mode where we don't emulate any system hardware.

Paul

#3 lore raw
Quoted 23 lines · Paul Brook
Quoted 10 lines · J. Mayer
Quoted 8 lines · Paul Brook

The attached patch adds a -cpu commandline option to qemu to allow the user to select what type of CPU is emulated. It currently only does anything useful for arm targets, but it should be easy to hook other targets into the same mechanism.

I implemented the selection as a bitmask. This allows users to select a CPU by the features it provides, and also allows creation of convenient aliases for common CPUs.

Quoted 5 lines

there is a cpu_ppc_register function in target-ppc/translate.c which does what's needed for emulated PPC selection.
The CPU is registered from the emulated board definition, ie in hw/ppc_prep.c or hw/ppc_chrp.c.
Your patch conflicts with this code.

Hmm, I hadn't spotted that. I'll see if I can merge them.

Quoted 3 lines

It seems to me that cpu selection should go in board definitions, like all the rest of emulated hardware selection, then have nothing to do in target-xxx/translate.c.

Quoted 6 lines

I'm not sure what you mean.

I guess it makes makes sense for the board to be able to specify the default cpu. That's pretty much independent of the rest of the implementation though. I'd have thought CPU choice should be fairly independent of the rest of the hardware.

You are wrong here: CPU choice & emulated board are strongly dependent. I'll give you a few examples:
- if I want to emulate a MPC850 board, then I have to emulate the PPC850 core.
No choice here.
- If I want to emulate an IBM pseries machine, it's a complete nonsense to select a 32 bit
CPU, as the platform is 64 bits.
- if I want to emulate a Pegasos board, I need to have the choice between G3 & G4.
MorphOS would surelly not run on any other PPC, but the two choices
exist.

Then, the CPU selection is to be done at the same level as the rest of the emulated board's hardware.

Quoted 1 line

There's also user mode where we don't emulate any system hardware.

This is a _very_ special case, then it has to be treated its own way (in linux-user directory).

Signature · 2 lines
J. Mayer <[email protected]>
Never organized