From d27a0d690152a4335dde07a17a777b7c0f7a4ed9 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sun, 16 Sep 2018 12:17:05 +0000 Subject: [PATCH] Various improvements to generate logical domain configurations that are accepted by more modern firmwares. In particular on SPARC T3 machines. Tested on a t1k and t5120. --- usr.sbin/ldomctl/config.c | 90 +++++++++++++++++++++++++------------- usr.sbin/ldomctl/ldomctl.h | 4 +- usr.sbin/ldomctl/mdesc.c | 26 ++++++----- usr.sbin/ldomctl/mdesc.h | 4 +- 4 files changed, 81 insertions(+), 43 deletions(-) diff --git a/usr.sbin/ldomctl/config.c b/usr.sbin/ldomctl/config.c index 6ad09f4c299..3aad5e0f73a 100644 --- a/usr.sbin/ldomctl/config.c +++ b/usr.sbin/ldomctl/config.c @@ -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); diff --git a/usr.sbin/ldomctl/ldomctl.h b/usr.sbin/ldomctl/ldomctl.h index cae073f1f7f..ce917a69a1c 100644 --- a/usr.sbin/ldomctl/ldomctl.h +++ b/usr.sbin/ldomctl/ldomctl.h @@ -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; diff --git a/usr.sbin/ldomctl/mdesc.c b/usr.sbin/ldomctl/mdesc.c index cb6a0445b4f..8f2dfbd55d8 100644 --- a/usr.sbin/ldomctl/mdesc.c +++ b/usr.sbin/ldomctl/mdesc.c @@ -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) { diff --git a/usr.sbin/ldomctl/mdesc.h b/usr.sbin/ldomctl/mdesc.h index ec78d951c66..48972b2e5e3 100644 --- a/usr.sbin/ldomctl/mdesc.h +++ b/usr.sbin/ldomctl/mdesc.h @@ -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 *); -- 2.20.1