[SeaBIOS] [RFC PATCH v2 20/21] Implement -dimms, -dimmspop command line options

Vasilis Liaskovitis vasilis.liaskovitis at profitbricks.com
Wed Jul 11 12:32:05 CEST 2012


Implement batch dimm creation command line options. These could be useful for
not bloating the command line with a large number of dimms.

syntax: -dimms pfx=poolid,size=sz,num=n
Will create numdimms dimms with ids poolid0, ..., poolidn-1. Each dimm has a
size of sz.
    
Implement -dimmpop option to populate dimms at bootup
syntax: -dimmpop pfx=poolid,num=n
This will populate n dimms with ids poolid0, ..., poolidn-1.

(live-migration could break here without patch 12/21: -dimmspop
needs to be reworked to support populating of individual dimms with
same prefix, and not only a range of dimms starting from 0)

Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis at profitbricks.com>
---
 hw/dimm.c       |    9 ++++++
 hw/dimm.h       |    2 +-
 qemu-config.c   |   45 ++++++++++++++++++++++++++++
 qemu-options.hx |   10 ++++++
 vl.c            |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 150 insertions(+), 2 deletions(-)

diff --git a/hw/dimm.c b/hw/dimm.c
index 2115567..6e324d3 100644
--- a/hw/dimm.c
+++ b/hw/dimm.c
@@ -187,6 +187,15 @@ void dimm_calc_offsets(dimm_calcoffset_fn calcfn)
     }
 }
 
+int dimm_set_populated(DimmState *s)
+{
+    if (s) {
+        s->populated = true;
+        return 0;
+    }    
+    else return -1;
+}
+
 /* used to populate and activate dimms at boot time */
 void dimm_scan_populated(void)
 {
diff --git a/hw/dimm.h b/hw/dimm.h
index b563e3f..0fdf59b 100644
--- a/hw/dimm.h
+++ b/hw/dimm.h
@@ -60,6 +60,6 @@ void dimm_activate(DimmState *slot);
 void dimm_deactivate(DimmState *slot);
 void dimm_scan_populated(void);
 void dimm_notify(uint32_t idx, uint32_t event);
-
+int dimm_set_populated(DimmState *s);
 
 #endif
diff --git a/qemu-config.c b/qemu-config.c
index 4abc31b..7f63186 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -650,6 +650,49 @@ static QemuOptsList qemu_dimm_opts = {
         { /* end of list */ }
     },
 };
+
+static QemuOptsList qemu_dimms_opts = {
+    .name = "dimms",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_dimms_opts.head),
+    .desc = {
+        {
+            .name = "pfx",
+            .type = QEMU_OPT_STRING,
+            .help = "prefix of ids for these dimm devices",
+        },{
+            .name = "size",
+            .type = QEMU_OPT_SIZE,
+            .help = "memory size for these dimm",
+        },{
+            .name = "num",
+            .type = QEMU_OPT_NUMBER,
+            .help = "number of dimm devices in this pool",
+        },{
+            .name = "node",
+            .type = QEMU_OPT_NUMBER,
+            .help = "NUMA node number (i.e. proximity) for these dimms",
+        },
+        { /* end of list */ }
+    },
+};
+
+static QemuOptsList qemu_dimmspop_opts = {
+    .name = "dimmspop",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_dimmspop_opts.head),
+    .desc = {
+        {
+            .name = "pfx",
+            .type = QEMU_OPT_STRING,
+            .help = "pool prefix for this dimm device",
+        },{
+            .name = "num",
+            .type = QEMU_OPT_SIZE,
+            .help = "number of dimm devices to populate",
+        },
+        { /* end of list */ }
+    },
+};
+
 static QemuOptsList *vm_config_groups[32] = {
     &qemu_drive_opts,
     &qemu_chardev_opts,
@@ -666,6 +709,8 @@ static QemuOptsList *vm_config_groups[32] = {
     &qemu_boot_opts,
     &qemu_iscsi_opts,
     &qemu_dimm_opts,
+    &qemu_dimms_opts,
+    &qemu_dimmspop_opts,
     NULL,
 };
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 61909f7..0a9326e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2752,3 +2752,13 @@ DEF("dimm", HAS_ARG, QEMU_OPTION_dimm,
         "-dimm id=dimmid,size=sz,node=nd,populated=on|off\n"
         "specify memory dimm device with name dimmid, size sz on node nd",
         QEMU_ARCH_ALL)
+
+DEF("dimms", HAS_ARG, QEMU_OPTION_dimms,
+        "-dimms pfx=id,size=sz,node=nd\n"
+        "specify pool of num memory dimm devices of size sz each on node nd",
+        QEMU_ARCH_ALL)
+
+DEF("dimmspop", HAS_ARG, QEMU_OPTION_dimmspop,
+        "-dimmspop pfx=id,num=n\n"
+        "populate n dimms of pool id (dimms with ids id0,...,idn-1) at system startup",
+        QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index efe915e..37752be 100644
--- a/vl.c
+++ b/vl.c
@@ -538,6 +538,65 @@ static void configure_dimm(QemuOpts *opts)
     nb_hp_dimms++;
 }
 
+static void configure_dimms(QemuOpts *opts)
+{
+    const char *value, *pfx, *id;
+    uint64_t size, node;
+    int num, dimm;
+    char buf[32];
+
+    id = qemu_opts_id(opts);
+    value = qemu_opt_get(opts, "pfx");
+    if (!value) {
+        fprintf(stderr, "qemu: invalid prefix for dimm pool '%s'\n", id);
+        exit(1);
+    }
+    pfx = value;
+
+    size = qemu_opt_get_size(opts, "size", DEFAULT_DIMMSIZE);
+    num = qemu_opt_get_number(opts, "num", 1);
+    node = qemu_opt_get_number(opts, "node", 0);
+
+    for (dimm = 0; dimm < num; dimm++) {
+        if (nb_hp_dimms == MAX_DIMMS) {
+            fprintf(stderr, "qemu: maximum number of DIMMs (%d) exceeded\n",
+                    MAX_DIMMS);
+            exit(1);
+        }
+        sprintf(buf, "%s%d", pfx, dimm);
+        dimm_create(g_strdup(buf), size, node, nb_hp_dimms, false);
+        nb_hp_dimms++;
+    }
+}
+
+/* populate dimms at startup */ 
+static void configure_dimmspop(QemuOpts *opts)
+{
+    const char *value, *pfx, *id;
+    int num, dimm;
+    char buf[32];
+
+    id = qemu_opts_id(opts);
+    value = qemu_opt_get(opts, "pfx");
+    if (!value) {
+        fprintf(stderr, "qemu: invalid prefix for dimm pool '%s'\n", id);
+        exit(1);
+    }
+    pfx = value;
+    value = qemu_opt_get(opts, "num");
+    if (!value) {
+        fprintf(stderr, "qemu: number not defined for dimm pool '%s'\n", pfx);
+        exit(1);
+    }
+    else num = atoi(value);
+    for (dimm = 0; dimm < num; dimm++) {
+        sprintf(buf, "%s%d", pfx, dimm);
+        if (dimm_set_populated(dimm_find_from_name(buf)) < 0) {
+            fprintf(stderr, "qemu: dimm %s not defined for dimm pool '%s'\n",
+                    buf, pfx);
+        }
+    }
+}
 static void configure_rtc(QemuOpts *opts)
 {
     const char *value;
@@ -2293,7 +2352,9 @@ int main(int argc, char **argv, char **envp)
     int cyls, heads, secs, translation;
     QemuOpts *hda_opts = NULL, *opts, *machine_opts;
     QemuOpts *dimm_opts[MAX_DIMMS];
-    int nb_dimm_opts = 0;
+    QemuOpts *dimms_opts[MAX_DIMMS];
+    QemuOpts *dimmspop_opts[MAX_DIMMS];
+    int nb_dimm_opts = 0, nb_dimms_opts = 0, nb_dimmspop_opts = 0;
     QemuOptsList *olist;
     int optind;
     const char *optarg;
@@ -3233,6 +3294,22 @@ int main(int argc, char **argv, char **envp)
                 }
                 nb_dimm_opts++;
                 break;
+            case QEMU_OPTION_dimms:
+                dimms_opts[nb_dimms_opts] =
+                    qemu_opts_parse(qemu_find_opts("dimms"), optarg, 0);
+                if (!dimms_opts[nb_dimms_opts]) {
+                    exit(1);
+                }
+                nb_dimms_opts++;
+                break;
+            case QEMU_OPTION_dimmspop:
+                dimmspop_opts[nb_dimmspop_opts] =
+                    qemu_opts_parse(qemu_find_opts("dimmspop"), optarg, 0);
+                if (!dimmspop_opts[nb_dimmspop_opts]) {
+                    exit(1);
+                }
+                nb_dimmspop_opts++;
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
@@ -3552,6 +3629,13 @@ int main(int argc, char **argv, char **envp)
 
     for (i = 0; i < nb_dimm_opts; i++)
         configure_dimm(dimm_opts[i]);
+
+    for (i = 0; i < nb_dimms_opts; i++)
+        configure_dimms(dimms_opts[i]);
+
+    for (i = 0; i < nb_dimmspop_opts; i++)
+        configure_dimmspop(dimmspop_opts[i]);
+
     qdev_machine_init();
 
     machine->init(ram_size, boot_devices,
-- 
1.7.9




More information about the SeaBIOS mailing list