[Qemu-devel] [PATCH 2/2] machine opts framework

2010-03-24 Thread Glauber Costa
This patch adds initial support for the -machine option, that allows
command line specification of machine attributes (always relying on safe
defaults). Besides its value per-se, it is the saner way we found to
allow for enabling/disabling of kvm's in-kernel irqchip.

A machine with in-kernel-irqchip could be specified as:
-machine irqchip=apic-kvm
And one without it:
-machine irqchip=apic

To demonstrate how it'd work, this patch introduces a choice between
pic and apic, pic being the old-style isa thing. 

---
 hw/boards.h |   10 ++
 hw/pc.c |   45 +++--
 qemu-config.c   |   16 
 qemu-config.h   |1 +
 qemu-options.hx |9 +
 vl.c|   54 ++
 6 files changed, 129 insertions(+), 6 deletions(-)

diff --git a/hw/boards.h b/hw/boards.h
index 6f0f0d7..831728c 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -12,6 +12,15 @@ typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
  const char *initrd_filename,
  const char *cpu_model);
 
+typedef void (QEMUIrqchipFunc)(void *opaque);
+
+typedef struct QEMUIrqchip {
+const char *name;
+QEMUIrqchipFunc *init; 
+int used;
+int is_default;
+} QEMUIrqchip;
+
 typedef struct QEMUMachine {
 const char *name;
 const char *alias;
@@ -28,6 +37,7 @@ typedef struct QEMUMachine {
 no_sdcard:1;
 int is_default;
 GlobalProperty *compat_props;
+QEMUIrqchip *irqchip;
 struct QEMUMachine *next;
 } QEMUMachine;
 
diff --git a/hw/pc.c b/hw/pc.c
index ba14df0..43ec022 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -752,21 +752,43 @@ int cpu_is_bsp(CPUState *env)
 return env-cpu_index == 0;
 }
 
+static void qemu_apic_init(void *opaque)
+{
+CPUState *env = opaque;
+if (!(env-cpuid_features  CPUID_APIC)) {
+fprintf(stderr, CPU lacks APIC cpuid flag\n);
+exit(1);
+}
+env-cpuid_apic_id = env-cpu_index;
+/* APIC reset callback resets cpu */
+apic_init(env);
+}
+
+static void qemu_pic_init(void *opaque)
+{
+CPUState *env = opaque;
+
+if (smp_cpus  1) {
+fprintf(stderr, PIC can't support smp systems\n);
+exit(1);
+}
+qemu_register_reset((QEMUResetHandler*)cpu_reset, env);
+}
+
 static CPUState *pc_new_cpu(const char *cpu_model)
 {
 CPUState *env;
+QEMUIrqchip *ic;
 
 env = cpu_init(cpu_model);
 if (!env) {
 fprintf(stderr, Unable to find x86 CPU definition\n);
 exit(1);
 }
-if ((env-cpuid_features  CPUID_APIC) || smp_cpus  1) {
-env-cpuid_apic_id = env-cpu_index;
-/* APIC reset callback resets cpu */
-apic_init(env);
-} else {
-qemu_register_reset((QEMUResetHandler*)cpu_reset, env);
+
+for (ic = current_machine-irqchip; ic-name != NULL; ic++) {
+if (ic-used)
+ic-init(env);
 }
 return env;
 }
@@ -1074,6 +1096,17 @@ static QEMUMachine pc_machine = {
 .desc = Standard PC,
 .init = pc_init_pci,
 .max_cpus = 255,
+.irqchip = (QEMUIrqchip[]){
+{
+.name = apic,
+.init = qemu_apic_init,
+.is_default = 1,
+},{
+.name = pic,
+.init = qemu_pic_init,
+},
+{ /* end of list */ },
+},
 .is_default = 1,
 };
 
diff --git a/qemu-config.c b/qemu-config.c
index 150157c..2b985a9 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -296,6 +296,21 @@ QemuOptsList qemu_cpudef_opts = {
 },
 };
 
+QemuOptsList qemu_machine_opts = {
+.name = M,
+.head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
+.desc = {
+{
+.name = mach,
+.type = QEMU_OPT_STRING,
+},{
+.name = irqchip,
+.type = QEMU_OPT_STRING,
+},
+{ /* end of list */ }
+},
+};
+
 static QemuOptsList *lists[] = {
 qemu_drive_opts,
 qemu_chardev_opts,
@@ -306,6 +321,7 @@ static QemuOptsList *lists[] = {
 qemu_global_opts,
 qemu_mon_opts,
 qemu_cpudef_opts,
+qemu_machine_opts,
 NULL,
 };
 
diff --git a/qemu-config.h b/qemu-config.h
index f217c58..ea302f0 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -10,6 +10,7 @@ extern QemuOptsList qemu_rtc_opts;
 extern QemuOptsList qemu_global_opts;
 extern QemuOptsList qemu_mon_opts;
 extern QemuOptsList qemu_cpudef_opts;
+extern QemuOptsList qemu_machine_opts;
 
 QemuOptsList *qemu_find_opts(const char *group);
 int qemu_set_option(const char *str);
diff --git a/qemu-options.hx b/qemu-options.hx
index 8450b45..585ecd2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -34,6 +34,15 @@ STEXI
 Select the emulated @var{machine} (@code{-M ?} for list)
 ETEXI
 
+DEF(machine, HAS_ARG, QEMU_OPTION_machine,
+-machine mach=m[,irqchip=chip]\n
+select emulated machine (-machine ? for list)\n)
+STEXI
+...@item -machine 

Re: [Qemu-devel] [PATCH 2/2] machine opts framework

2010-03-24 Thread Anthony Liguori

On 03/24/2010 02:26 PM, Glauber Costa wrote:

This patch adds initial support for the -machine option, that allows
command line specification of machine attributes (always relying on safe
defaults). Besides its value per-se, it is the saner way we found to
allow for enabling/disabling of kvm's in-kernel irqchip.

A machine with in-kernel-irqchip could be specified as:
-machine irqchip=apic-kvm
And one without it:
-machine irqchip=apic

To demonstrate how it'd work, this patch introduces a choice between
pic and apic, pic being the old-style isa thing.
   


I started from a different place.  See machine-qemuopts in my staging tree.

I think we should combine efforts.

Regards,

Anthony Liguori


---
  hw/boards.h |   10 ++
  hw/pc.c |   45 +++--
  qemu-config.c   |   16 
  qemu-config.h   |1 +
  qemu-options.hx |9 +
  vl.c|   54 ++
  6 files changed, 129 insertions(+), 6 deletions(-)

diff --git a/hw/boards.h b/hw/boards.h
index 6f0f0d7..831728c 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -12,6 +12,15 @@ typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
   const char *initrd_filename,
   const char *cpu_model);

+typedef void (QEMUIrqchipFunc)(void *opaque);
+
+typedef struct QEMUIrqchip {
+const char *name;
+QEMUIrqchipFunc *init;
+int used;
+int is_default;
+} QEMUIrqchip;
+
  typedef struct QEMUMachine {
  const char *name;
  const char *alias;
@@ -28,6 +37,7 @@ typedef struct QEMUMachine {
  no_sdcard:1;
  int is_default;
  GlobalProperty *compat_props;
+QEMUIrqchip *irqchip;
  struct QEMUMachine *next;
  } QEMUMachine;

diff --git a/hw/pc.c b/hw/pc.c
index ba14df0..43ec022 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -752,21 +752,43 @@ int cpu_is_bsp(CPUState *env)
  return env-cpu_index == 0;
  }

+static void qemu_apic_init(void *opaque)
+{
+CPUState *env = opaque;
+if (!(env-cpuid_features  CPUID_APIC)) {
+fprintf(stderr, CPU lacks APIC cpuid flag\n);
+exit(1);
+}
+env-cpuid_apic_id = env-cpu_index;
+/* APIC reset callback resets cpu */
+apic_init(env);
+}
+
+static void qemu_pic_init(void *opaque)
+{
+CPUState *env = opaque;
+
+if (smp_cpus  1) {
+fprintf(stderr, PIC can't support smp systems\n);
+exit(1);
+}
+qemu_register_reset((QEMUResetHandler*)cpu_reset, env);
+}
+
  static CPUState *pc_new_cpu(const char *cpu_model)
  {
  CPUState *env;
+QEMUIrqchip *ic;

  env = cpu_init(cpu_model);
  if (!env) {
  fprintf(stderr, Unable to find x86 CPU definition\n);
  exit(1);
  }
-if ((env-cpuid_features  CPUID_APIC) || smp_cpus  1) {
-env-cpuid_apic_id = env-cpu_index;
-/* APIC reset callback resets cpu */
-apic_init(env);
-} else {
-qemu_register_reset((QEMUResetHandler*)cpu_reset, env);
+
+for (ic = current_machine-irqchip; ic-name != NULL; ic++) {
+if (ic-used)
+ic-init(env);
  }
  return env;
  }
@@ -1074,6 +1096,17 @@ static QEMUMachine pc_machine = {
  .desc = Standard PC,
  .init = pc_init_pci,
  .max_cpus = 255,
+.irqchip = (QEMUIrqchip[]){
+{
+.name = apic,
+.init = qemu_apic_init,
+.is_default = 1,
+},{
+.name = pic,
+.init = qemu_pic_init,
+},
+{ /* end of list */ },
+},
  .is_default = 1,
  };

diff --git a/qemu-config.c b/qemu-config.c
index 150157c..2b985a9 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -296,6 +296,21 @@ QemuOptsList qemu_cpudef_opts = {
  },
  };

+QemuOptsList qemu_machine_opts = {
+.name = M,
+.head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
+.desc = {
+{
+.name = mach,
+.type = QEMU_OPT_STRING,
+},{
+.name = irqchip,
+.type = QEMU_OPT_STRING,
+},
+{ /* end of list */ }
+},
+};
+
  static QemuOptsList *lists[] = {
  qemu_drive_opts,
  qemu_chardev_opts,
@@ -306,6 +321,7 @@ static QemuOptsList *lists[] = {
  qemu_global_opts,
  qemu_mon_opts,
  qemu_cpudef_opts,
+qemu_machine_opts,
  NULL,
  };

diff --git a/qemu-config.h b/qemu-config.h
index f217c58..ea302f0 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -10,6 +10,7 @@ extern QemuOptsList qemu_rtc_opts;
  extern QemuOptsList qemu_global_opts;
  extern QemuOptsList qemu_mon_opts;
  extern QemuOptsList qemu_cpudef_opts;
+extern QemuOptsList qemu_machine_opts;

  QemuOptsList *qemu_find_opts(const char *group);
  int qemu_set_option(const char *str);
diff --git a/qemu-options.hx b/qemu-options.hx
index 8450b45..585ecd2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -34,6 +34,15 @@ STEXI
  Select the 

Re: [Qemu-devel] [PATCH 2/2] machine opts framework

2010-03-24 Thread Glauber Costa
On Wed, Mar 24, 2010 at 02:43:35PM -0500, Anthony Liguori wrote:
 On 03/24/2010 02:26 PM, Glauber Costa wrote:
 This patch adds initial support for the -machine option, that allows
 command line specification of machine attributes (always relying on safe
 defaults). Besides its value per-se, it is the saner way we found to
 allow for enabling/disabling of kvm's in-kernel irqchip.
 
 A machine with in-kernel-irqchip could be specified as:
  -machine irqchip=apic-kvm
 And one without it:
  -machine irqchip=apic
 
 To demonstrate how it'd work, this patch introduces a choice between
 pic and apic, pic being the old-style isa thing.
 
 I started from a different place.  See machine-qemuopts in my staging tree.
 
 I think we should combine efforts.
 
 Regards,
 

Absolutely. I see little overlap between what we did. Just a comment on yours:

-static void an5206_init(ram_addr_t ram_size,
- const char *boot_device,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model)
+static void an5206_init(QemuOpts *opts)
 {

Since we're changing init functions anyway, I believe we should also pass
a pointer to the machine structure. With that, we can avoing using the global
current_machine.




Re: [Qemu-devel] [PATCH 2/2] machine opts framework

2010-03-24 Thread Anthony Liguori

On 03/24/2010 03:58 PM, Glauber Costa wrote:

On Wed, Mar 24, 2010 at 02:43:35PM -0500, Anthony Liguori wrote:
   

On 03/24/2010 02:26 PM, Glauber Costa wrote:
 

This patch adds initial support for the -machine option, that allows
command line specification of machine attributes (always relying on safe
defaults). Besides its value per-se, it is the saner way we found to
allow for enabling/disabling of kvm's in-kernel irqchip.

A machine with in-kernel-irqchip could be specified as:
-machine irqchip=apic-kvm
And one without it:
-machine irqchip=apic

To demonstrate how it'd work, this patch introduces a choice between
pic and apic, pic being the old-style isa thing.
   

I started from a different place.  See machine-qemuopts in my staging tree.

I think we should combine efforts.

Regards,

 

Absolutely. I see little overlap between what we did. Just a comment on yours:

-static void an5206_init(ram_addr_t ram_size,
- const char *boot_device,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model)
+static void an5206_init(QemuOpts *opts)
  {

Since we're changing init functions anyway, I believe we should also pass
a pointer to the machine structure. With that, we can avoing using the global
current_machine.
   


Yes, I had the same thought.  For instance, with isa-pc is just pc_init 
with an extra parameter.  If we had a structure like:


typedef struct QEMUPCMachine
{
   QEMUMachine parent;
   int pci_enabled;
} QEMUPCMachine;

Then you wouldn't need those dispatch functions.  Not a huge win for x86 
but for sparc and some arm boards, it's pretty significant.


Regards,

Anthony Liguori