Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64 sun4v: add hypervisor machine description (...



details:   https://anonhg.NetBSD.org/src/rev/fcca307a5f68
branches:  trunk
changeset: 335504:fcca307a5f68
user:      palle <palle%NetBSD.org@localhost>
date:      Sat Jan 10 22:19:26 2015 +0000

description:
sun4v: add hypervisor machine description (mdesc) functions - from OpenBSD

diffstat:

 sys/arch/sparc64/conf/files.sparc64 |    3 +-
 sys/arch/sparc64/include/mdesc.h    |   51 +++++++
 sys/arch/sparc64/sparc64/autoconf.c |    9 +-
 sys/arch/sparc64/sparc64/mdesc.c    |  237 ++++++++++++++++++++++++++++++++++++
 4 files changed, 297 insertions(+), 3 deletions(-)

diffs (truncated from 350 to 300 lines):

diff -r 4d72d311bc1e -r fcca307a5f68 sys/arch/sparc64/conf/files.sparc64
--- a/sys/arch/sparc64/conf/files.sparc64       Sat Jan 10 17:16:01 2015 +0000
+++ b/sys/arch/sparc64/conf/files.sparc64       Sat Jan 10 22:19:26 2015 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.sparc64,v 1.145 2014/02/01 17:01:35 nakayama Exp $
+#      $NetBSD: files.sparc64,v 1.146 2015/01/10 22:19:26 palle Exp $
 
 # @(#)files.sparc64    8.1 (Berkeley) 7/19/93
 # sparc64-specific configuration info
@@ -249,6 +249,7 @@
 file   arch/sparc64/sparc64/ipifuncs.c         multiprocessor
 file   arch/sparc64/sparc64/lock_stubs.s
 file   arch/sparc64/sparc64/hvcall.S           sun4v
+file   arch/sparc64/sparc64/mdesc.c            sun4v
 
 file   arch/sparc64/sparc64/db_interface.c     ddb | kgdb
 file   arch/sparc64/sparc64/db_machdep.c       ddb
diff -r 4d72d311bc1e -r fcca307a5f68 sys/arch/sparc64/include/mdesc.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc64/include/mdesc.h  Sat Jan 10 22:19:26 2015 +0000
@@ -0,0 +1,51 @@
+/*     $NetBSD: mdesc.h,v 1.1 2015/01/10 22:19:26 palle Exp $  */
+/*     $OpenBSD: mdesc.h,v 1.3 2014/11/30 22:26:14 kettenis Exp $      */
+/*
+ * Copyright (c) 2009 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct md_header {
+       uint32_t        transport_version;
+       uint32_t        node_blk_sz;
+       uint32_t        name_blk_sz;
+       uint32_t        data_blk_sz;
+};
+
+struct md_element {
+       uint8_t         tag;
+       uint8_t         name_len;
+       uint16_t        _reserved_field;
+       uint32_t        name_offset;
+       union {
+               struct {
+                       uint32_t        data_len;
+                       uint32_t        data_offset;
+               } y;
+               uint64_t        val;
+       } d;
+};
+
+#ifdef _KERNEL
+extern vaddr_t mdesc;
+extern size_t mdesc_len;
+
+void    mdesc_init(void);
+uint64_t mdesc_get_prop_val(int, const char *);
+const char *mdesc_get_prop_str(int, const char *);
+const char *mdesc_get_prop_data(int, const char *, size_t *);
+int    mdesc_find(const char *, uint64_t);
+int    mdesc_find_child(int, const char *, uint64_t);
+int    mdesc_find_node(const char *);
+#endif
diff -r 4d72d311bc1e -r fcca307a5f68 sys/arch/sparc64/sparc64/autoconf.c
--- a/sys/arch/sparc64/sparc64/autoconf.c       Sat Jan 10 17:16:01 2015 +0000
+++ b/sys/arch/sparc64/sparc64/autoconf.c       Sat Jan 10 22:19:26 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.c,v 1.200 2014/10/18 08:33:27 snj Exp $ */
+/*     $NetBSD: autoconf.c,v 1.201 2015/01/10 22:19:26 palle Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.200 2014/10/18 08:33:27 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.201 2015/01/10 22:19:26 palle Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -93,6 +93,7 @@
 #include <machine/bootinfo.h>
 #include <sparc64/sparc64/cache.h>
 #include <sparc64/sparc64/timerreg.h>
+#include <machine/mdesc.h>
 
 #include <dev/ata/atavar.h>
 #include <dev/pci/pcivar.h>
@@ -469,6 +470,10 @@
 void
 cpu_configure(void)
 {
+       
+       if (CPU_ISSUN4V)
+               mdesc_init();
+       
        bool userconf = (boothowto & RB_USERCONF) != 0;
 
        /* fetch boot device settings */
diff -r 4d72d311bc1e -r fcca307a5f68 sys/arch/sparc64/sparc64/mdesc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc64/sparc64/mdesc.c  Sat Jan 10 22:19:26 2015 +0000
@@ -0,0 +1,237 @@
+/*     $NetBSD: mdesc.c,v 1.1 2015/01/10 22:19:26 palle Exp $  */
+/*     $OpenBSD: mdesc.c,v 1.7 2014/11/30 22:26:15 kettenis Exp $      */
+/*
+ * Copyright (c) 2009 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+#include <uvm/uvm_page.h>
+
+#include <machine/autoconf.h>
+#include <machine/hypervisor.h>
+#include <machine/mdesc.h>
+
+vaddr_t mdesc;
+paddr_t mdesc_pa;
+size_t mdesc_len;
+
+void
+mdesc_init(void)
+{
+       struct pglist mlist;
+       struct vm_page *m;
+       psize_t len, size;
+       paddr_t pa;
+       vaddr_t va;
+       int err;
+
+       hv_mach_desc((paddr_t)NULL, &len);
+       KASSERT(len != 0);
+
+again:
+       size = round_page(len);
+
+       TAILQ_INIT(&mlist);
+       err = uvm_pglistalloc(len, 0, -1, PAGE_SIZE, 0, &mlist, 1, 0);
+       if (err)
+               panic("%s: out of memory", __func__);
+ 
+       len = size;
+       pa = VM_PAGE_TO_PHYS(TAILQ_FIRST(&mlist));
+       err = hv_mach_desc(pa, &len);
+       if (err != H_EOK)
+               goto fail;
+
+       va = (vaddr_t)uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY);
+       if (va == 0)
+               panic("%s: out of memory", __func__);
+
+       mdesc = (vaddr_t)va;
+       mdesc_pa = pa;
+       mdesc_len = len;
+
+       TAILQ_FOREACH(m, &mlist, pageq.queue) {
+               pa = VM_PAGE_TO_PHYS(m);
+               pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
+               va += PAGE_SIZE;
+       }
+       pmap_update(pmap_kernel());
+
+       return;
+
+fail:
+       uvm_pglistfree(&mlist);
+
+       /*
+        * If the machine description was updated while we were trying
+        * to fetch it, the allocated buffer may have been to small.
+        * Try again in that case.
+        */
+       if (err == H_EINVAL && len > size)
+               goto again;
+
+       return;
+}
+
+uint64_t
+mdesc_get_prop_val(int idx, const char *name)
+{
+       struct md_header *hdr;
+       struct md_element *elem;
+       const char *name_blk;
+       const char *str;
+
+       hdr = (struct md_header *)mdesc;
+       elem = (struct md_element *)(mdesc + sizeof(struct md_header));
+       name_blk = (char *)mdesc + sizeof(struct md_header) + hdr->node_blk_sz;
+
+       while (elem[idx].tag != 'E') {
+               str = name_blk + elem[idx].name_offset;
+               if (elem[idx].tag == 'v' && strcmp(str, name) == 0)
+                       return (elem[idx].d.val);
+               idx++;
+       }
+
+       return (-1);
+}
+
+const char *
+mdesc_get_prop_str(int idx, const char *name)
+{
+       struct md_header *hdr;
+       struct md_element *elem;
+       const char *name_blk;
+       const char *data_blk;
+       const char *str;
+
+       hdr = (struct md_header *)mdesc;
+       elem = (struct md_element *)(mdesc + sizeof(struct md_header));
+       name_blk = (char *)mdesc + sizeof(struct md_header) + hdr->node_blk_sz;
+       data_blk = name_blk + hdr->name_blk_sz;
+
+       while (elem[idx].tag != 'E') {
+               str = name_blk + elem[idx].name_offset;
+               if (elem[idx].tag == 's' && strcmp(str, name) == 0)
+                       return (data_blk + elem[idx].d.y.data_offset);
+               idx++;
+       }
+
+       return (NULL);
+}
+
+const char *
+mdesc_get_prop_data(int idx, const char *name, size_t *len)
+{
+       struct md_header *hdr;
+       struct md_element *elem;
+       const char *name_blk;
+       const char *data_blk;
+       const char *str;
+
+       hdr = (struct md_header *)mdesc;
+       elem = (struct md_element *)(mdesc + sizeof(struct md_header));
+       name_blk = (char *)mdesc + sizeof(struct md_header) + hdr->node_blk_sz;
+       data_blk = name_blk + hdr->name_blk_sz;
+
+       while (elem[idx].tag != 'E') {
+               str = name_blk + elem[idx].name_offset;
+               if (elem[idx].tag == 'd' && strcmp(str, name) == 0) {
+                       *len = elem[idx].d.y.data_len;
+                       return (data_blk + elem[idx].d.y.data_offset);
+               }
+               idx++;
+       }
+
+       return (NULL);
+}
+
+int
+mdesc_find(const char *name, uint64_t cfg_handle)
+{
+       struct md_header *hdr;
+       struct md_element *elem;
+       const char *str;
+       uint64_t val;
+       int idx;
+
+       hdr = (struct md_header *)mdesc;
+       (void)hdr; /* XXX avoid compiler warning */
+       elem = (struct md_element *)(mdesc + sizeof(struct md_header));
+
+       for (idx = 0; elem[idx].tag == 'N'; idx = elem[idx].d.val) {
+               str = mdesc_get_prop_str(idx, "name");
+               val = mdesc_get_prop_val(idx, "cfg-handle");
+               if (str && strcmp(str, name) == 0 && val == cfg_handle)
+                       return (idx);
+       }
+
+       return (-1);
+}
+



Home | Main Index | Thread Index | Old Index