Various improvements to generate logical domain configurations that are
authorkettenis <kettenis@openbsd.org>
Sun, 16 Sep 2018 12:17:05 +0000 (12:17 +0000)
committerkettenis <kettenis@openbsd.org>
Sun, 16 Sep 2018 12:17:05 +0000 (12:17 +0000)
accepted by more modern firmwares.  In particular on SPARC T3 machines.

Tested on a t1k and t5120.

usr.sbin/ldomctl/config.c
usr.sbin/ldomctl/ldomctl.h
usr.sbin/ldomctl/mdesc.c
usr.sbin/ldomctl/mdesc.h

index 6ad09f4..3aad5e0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.22 2017/01/17 22:10:55 krw Exp $ */
+/*     $OpenBSD: config.c,v 1.23 2018/09/16 12:17:05 kettenis Exp $    */
 
 /*
  * Copyright (c) 2012 Mark Kettenis
@@ -74,6 +74,7 @@ uint64_t max_devices = 16;
 
 uint64_t rombase;
 uint64_t romsize;
+uint64_t uartbase;
 
 uint64_t max_page_size;
 
@@ -284,6 +285,22 @@ pri_alloc_memory(uint64_t base, uint64_t size)
        return NULL;
 }
 
+void
+pri_delete_devalias(struct md *md)
+{
+       struct md_node *node;
+
+       /*
+        * There may be multiple "devalias" nodes.  Only remove the one
+        * that resides under the "openboot" node.
+        */
+       node = md_find_node(protomd, "openboot");
+       assert(node);
+       node = md_find_subnode(protomd, node, "devalias");
+       if (node)
+               md_delete_node(protomd, node);
+}
+
 void
 pri_init(struct md *md)
 {
@@ -324,7 +341,7 @@ pri_init(struct md *md)
                                continue;
                        if (!md_get_prop_val(md, node2, "offset", &offset) ||
                            !md_get_prop_val(md, node2, "size", &size))
-                                       continue;
+                               continue;
                        rombase = base + offset;
                        romsize = size;
                }
@@ -340,13 +357,13 @@ pri_init(struct md *md)
 
        protomd = md_copy(md);
        md_find_delete_node(protomd, "components");
-       md_find_delete_node(protomd, "devalias");
        md_find_delete_node(protomd, "domain-services");
        md_find_delete_node(protomd, "channel-devices");
        md_find_delete_node(protomd, "channel-endpoints");
        md_find_delete_node(protomd, "firmware");
        md_find_delete_node(protomd, "ldc_endpoints");
        md_find_delete_node(protomd, "memory-segments");
+       pri_delete_devalias(protomd);
        md_collect_garbage(protomd);
        md_write(protomd, "protomd");
 
@@ -498,8 +515,9 @@ hvmd_init_console(struct md *md, struct md_node *node)
        if (resource_id >= max_guests)
                errx(1, "resource_id larger than max_guests");
 
-       console = xmalloc(sizeof(*console));
+       console = xzalloc(sizeof(*console));
        md_get_prop_val(md, node, "ino", &console->ino);
+       md_get_prop_val(md, node, "uartbase", &console->uartbase);
        console->resource_id = resource_id;
        consoles[resource_id] = console;
        console->hv_node = node;
@@ -564,6 +582,7 @@ hvmd_init_device(struct md *md, struct md_node *node)
        device = xzalloc(sizeof(*device));
        md_get_prop_val(md, node, "gid", &device->gid);
        md_get_prop_val(md, node, "cfghandle", &device->cfghandle);
+       md_get_prop_val(md, node, "rcid", &device->rcid);
        device->resource_id = resource_id;
        if (strcmp(node->name->str, "pcie_bus") == 0)
                pcie_busses[resource_id] = device;
@@ -737,16 +756,11 @@ hvmd_init(struct md *md)
        md_get_prop_val(md, node, "tod", &tod);
        md_get_prop_val(md, node, "erpt-pa", &erpt_pa);
        md_get_prop_val(md, node, "erpt-size", &erpt_size);
+       md_get_prop_val(md, node, "uartbase", &uartbase);
 
-       node = md_find_node(md, "frag_space");
-       md_get_prop_val(md, node, "fragsize", &fragsize);
-       TAILQ_INIT(&frag_mblocks);
-       TAILQ_FOREACH(prop, &node->prop_list, link) {
-               if (prop->tag == MD_PROP_ARC &&
-                   strcmp(prop->name->str, "fwd") == 0)
-                       hvmd_init_frag(md, prop->d.arc.node);
-       }
-       pri_alloc_memory(0, fragsize);
+       node = md_find_node(md, "platform");
+       if (node)
+               md_get_prop_val(md, node, "stick-frequency", &stick_frequency);
 
        node = md_find_node(md, "hvmd_mblock");
        if (node) {
@@ -757,6 +771,18 @@ hvmd_init(struct md *md)
                pri_alloc_memory(hvmd_mblock->membase, hvmd_mblock->memsize);
        }
 
+       node = md_find_node(md, "frag_space");
+       md_get_prop_val(md, node, "fragsize", &fragsize);
+       if (fragsize == 0)
+               fragsize = md_maxsize;
+       TAILQ_INIT(&frag_mblocks);
+       TAILQ_FOREACH(prop, &node->prop_list, link) {
+               if (prop->tag == MD_PROP_ARC &&
+                   strcmp(prop->name->str, "fwd") == 0)
+                       hvmd_init_frag(md, prop->d.arc.node);
+       }
+       pri_alloc_memory(0, fragsize);
+
        node = md_find_node(md, "consoles");
        TAILQ_FOREACH(prop, &node->prop_list, link) {
                if (prop->tag == MD_PROP_ARC &&
@@ -901,6 +927,7 @@ hvmd_finalize_device(struct md *md, struct device *device, const char *name)
        md_add_prop_val(md, node, "resource_id", device->resource_id);
        md_add_prop_val(md, node, "cfghandle", device->cfghandle);
        md_add_prop_val(md, node, "gid", device->gid);
+       md_add_prop_val(md, node, "rcid", device->rcid);
        device->hv_node = node;
 }
 
@@ -1031,6 +1058,11 @@ hvmd_finalize_console(struct md *md, struct console *console)
        md_add_prop_val(md, node, "ino", console->ino);
        console->hv_node = node;
 
+       if (console->uartbase) {
+               md_add_prop_val(md, node, "uartbase", console->uartbase);
+               return;
+       }
+
        TAILQ_FOREACH(endpoint, &console->guest->endpoint_list, link) {
                if (endpoint->rx_ino == console->ino) {
                        md_link_node(md, node, endpoint->hv_node);
@@ -1086,6 +1118,7 @@ hvmd_finalize_guest(struct md *md, struct guest *guest)
        md_add_prop_val(md, node, "mdpa", guest->mdpa);
        md_add_prop_val(md, node, "rombase", rombase);
        md_add_prop_val(md, node, "romsize", romsize);
+       md_add_prop_val(md, node, "uartbase", uartbase);
        guest->hv_node = node;
 
        node = md_add_node(md, "virtual_devices");
@@ -1803,11 +1836,11 @@ guest_add_devalias(struct guest *guest, const char *name, const char *path)
        struct md_node *parent;
        struct md_node *node;
 
-       node = md_find_node(md, "devalias");
-       if (node == NULL) {
-               parent = md_find_node(md, "openboot");
-               assert(parent);
+       parent = md_find_node(md, "openboot");
+       assert(parent);
 
+       node = md_find_subnode(md, parent, "devalias");
+       if (node == NULL) {
                node = md_add_node(md, "devalias");
                md_link_node(md, parent, node);
        }
@@ -2196,7 +2229,6 @@ guest_finalize(struct guest *guest)
        struct md_node *child;
        struct cpu *cpu;
        uint64_t pid;
-       uint64_t id;
        const char *name;
        char *path;
 
@@ -2236,25 +2268,23 @@ guest_finalize(struct guest *guest)
                }
        }
 
-       md_collect_garbage(md);
-
        node = md_find_node(md, "memory");
-       md_get_prop_val(md, node, "memory-generation-id#", &id);
-       md_delete_node(md, node);
-       md_collect_garbage(md);
-
-       parent = md_find_node(md, "root");
-       assert(parent);
+       TAILQ_FOREACH_SAFE(prop, &node->prop_list, link, prop2) {
+               if (prop->tag == MD_PROP_ARC &&
+                   strcmp(prop->name->str, "fwd") == 0) {
+                       node2 = prop->d.arc.node;
+                       md_delete_node(md, node2);
+               }
+       }
 
-       node = md_add_node(md, "memory");
-       md_add_prop_val(md, node, "memory-generation-id#", id);
-       md_link_node(md, parent, node);
+       md_collect_garbage(md);
 
+       parent = md_find_node(md, "memory");
        TAILQ_FOREACH(mblock, &guest->mblock_list, link) {
                child = md_add_node(md, "mblock");
                md_add_prop_val(md, child, "base", mblock->realbase);
                md_add_prop_val(md, child, "size", mblock->memsize);
-               md_link_node(md, node, child);
+               md_link_node(md, parent, child);
        }
 
        xasprintf(&path, "%s.md", guest->name);
index cae073f..ce917a6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ldomctl.h,v 1.5 2012/12/01 10:39:38 kettenis Exp $    */
+/*     $OpenBSD: ldomctl.h,v 1.6 2018/09/16 12:17:05 kettenis Exp $    */
 
 /*
  * Copyright (c) 2012 Mark Kettenis
@@ -22,6 +22,7 @@ struct guest;
 struct console {
        uint64_t ino;
        uint64_t resource_id;
+       uint64_t uartbase;
 
        struct guest *guest;
        struct ldc_endpoint *client_endpoint;
@@ -44,6 +45,7 @@ struct device {
        uint64_t gid;
        uint64_t cfghandle;
        uint64_t resource_id;
+       uint64_t rcid;
 
        struct guest *guest;
        struct md_node *hv_node;
index cb6a044..8f2dfbd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mdesc.c,v 1.10 2018/07/12 14:46:45 kettenis Exp $     */
+/*     $OpenBSD: mdesc.c,v 1.11 2018/09/16 12:17:05 kettenis Exp $     */
 
 /*
  * Copyright (c) 2012 Mark Kettenis
@@ -122,6 +122,21 @@ md_find_node(struct md *md, const char *name)
        return NULL;
 }
 
+struct md_node *
+md_find_subnode(struct md *md, struct md_node *node, const char *name)
+{
+       struct md_prop *prop;
+
+       TAILQ_FOREACH(prop, &node->prop_list, link) {
+               if (prop->tag == MD_PROP_ARC &&
+                   strcmp(prop->name->str, "fwd") == 0 &&
+                   strcmp(prop->d.arc.node->name->str, name) == 0)
+                       return prop->d.arc.node;
+       }
+
+       return NULL;
+}
+
 struct md_node *
 md_add_node(struct md *md, const char *name)
 {
@@ -315,15 +330,6 @@ md_find_delete_node(struct md *md, const char *name)
                md_delete_node(md, node);
 }
 
-void
-md_find_delete_nodes(struct md *md, const char *name)
-{
-       struct md_node *node;
-
-       while ((node = md_find_node(md, name)))
-               md_delete_node(md, node);
-}
-
 struct md *
 md_alloc(void)
 {
index ec78d95..48972b2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mdesc.h,v 1.6 2018/07/12 14:46:45 kettenis Exp $      */
+/*     $OpenBSD: mdesc.h,v 1.7 2018/09/16 12:17:05 kettenis Exp $      */
 
 /*
  * Copyright (c) 2012 Mark Kettenis
@@ -112,6 +112,7 @@ struct md_prop *md_add_prop_arc(struct md *, struct md_node *,
 void md_delete_prop(struct md *, struct md_node *, struct md_prop *);
 
 struct md_node *md_find_node(struct md *, const char *);
+struct md_node *md_find_subnode(struct md *, struct md_node *, const char *);
 struct md_node *md_add_node(struct md *, const char *);
 void md_link_node(struct md *, struct md_node *, struct md_node *);
 struct md_prop *md_find_prop(struct md *, struct md_node *, const char *);
@@ -125,7 +126,6 @@ bool md_get_prop_data(struct md *, struct md_node *, const char *,
 
 void md_delete_node(struct md *, struct md_node *);
 void md_find_delete_node(struct md *, const char *);
-void md_find_delete_nodes(struct md *, const char *);
 
 void md_collect_garbage(struct md *);