xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys
@ 2010-07-09 10:57 Tim Deegan
  2010-07-09 10:57 ` [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore Tim Deegan
  2010-07-09 10:57 ` [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
  0 siblings, 2 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-09 10:57 UTC (permalink / raw)
  To: xen-devel

These patches add a read-only xenstore client to hvmloader, 
and use it to customize the SMBIOS strings based on xenstore keys

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore
  2010-07-09 10:57 [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
@ 2010-07-09 10:57 ` Tim Deegan
  2010-07-09 10:57 ` [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
  1 sibling, 0 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-09 10:57 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 52 bytes --]

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>



[-- Attachment #2: xen-unstable.hg-2.patch --]
[-- Type: text/x-patch, Size: 8941 bytes --]

# HG changeset patch
# User Tim Deegan <Tim.Deegan@citrix.com>
# Date 1278671249 -3600
# Node ID 62b9338150160d6f7cea3e2c386f5e6f94e1b13b
# Parent  82f8371effffc7f3f405fc524cf27c3f07d27249
Add a xenbus frontend to hvmloader so it can read values from xenstore.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>

diff -r 82f8371effff -r 62b933815016 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile	Thu Jul 08 17:54:42 2010 +0100
+++ b/tools/firmware/hvmloader/Makefile	Fri Jul 09 11:27:29 2010 +0100
@@ -29,7 +29,7 @@
 CFLAGS += $(CFLAGS_include) -I.
 
 SRCS  = hvmloader.c mp_tables.c util.c smbios.c 
-SRCS += 32bitbios_support.c smp.c cacheattr.c
+SRCS += 32bitbios_support.c smp.c cacheattr.c xenbus.c
 ifeq ($(debug),y)
 SRCS += tests.c
 endif
diff -r 82f8371effff -r 62b933815016 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c	Thu Jul 08 17:54:42 2010 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c	Fri Jul 09 11:27:29 2010 +0100
@@ -704,6 +704,7 @@
 
     printf("CPU speed is %u MHz\n", get_cpu_mhz());
 
+    xenbus_setup();
     apic_setup();
     pci_setup();
 
@@ -803,6 +804,8 @@
     bios_info->madt_lapic0_addr = madt_lapic0_addr;
     bios_info->bios32_entry = bios32_addr;
 
+    xenbus_shutdown();
+
     printf("Invoking ROMBIOS ...\n");
     return 0;
 }
diff -r 82f8371effff -r 62b933815016 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h	Thu Jul 08 17:54:42 2010 +0100
+++ b/tools/firmware/hvmloader/util.h	Fri Jul 09 11:27:29 2010 +0100
@@ -155,6 +155,18 @@
 void *mem_alloc(uint32_t size, uint32_t align);
 #define virt_to_phys(v) ((unsigned long)(v))
 
+/* Connect our xenbus client to the backend.  
+ * Call once, before any other xenbus actions. */
+void xenbus_setup(void);
+
+/* Reset the xenbus connection so the next kernel can start again. */
+void xenbus_shutdown(void);
+
+/* Read a xenstore key.  Returns a nul-terminated string (even if the XS
+ * data wasn't nul-terminated) or NULL.  The returned string is in a
+ * static buffer, so only valid until the next xenstore/xenbus operation. */
+char *xenstore_read(char *path);
+
 /* Prepare the 32bit BIOS */
 uint32_t highbios_setup(void);
 
diff -r 82f8371effff -r 62b933815016 tools/firmware/hvmloader/xenbus.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/xenbus.c	Fri Jul 09 11:27:29 2010 +0100
@@ -0,0 +1,193 @@
+/*
+ * xenbus.c: static, synchronous, read-only xenbus client for hvmloader.
+ *
+ * Copyright (c) 2009 Tim Deegan, Citrix Systems (R&D) Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "util.h"
+#include "hypercall.h"
+#include <errno.h>
+#include <xen/sched.h>
+#include <xen/event_channel.h>
+#include <xen/hvm/params.h>
+#include <xen/io/xs_wire.h>
+
+struct xenstore_domain_interface *rings; /* Shared ring with dom0 */
+evtchn_port_t event;                     /* Event-channel to dom0 */
+char payload[XENSTORE_PAYLOAD_MAX + 1];  /* Unmarshalling area */
+
+/* Connect our xenbus client to the backend.
+ * Call once, before any other xenbus actions. */
+void xenbus_setup(void)
+{
+    xen_hvm_param_t param;
+
+    /* Ask Xen where the xenbus shared page is. */
+    param.domid = DOMID_SELF;
+    param.index = HVM_PARAM_STORE_PFN;
+    ASSERT(hypercall_hvm_op(HVMOP_get_param, &param) == 0);
+    rings = (void *) (unsigned long) (param.value << PAGE_SHIFT);
+
+    /* Ask Xen where the xenbus event channel is. */
+    param.domid = DOMID_SELF;
+    param.index = HVM_PARAM_STORE_EVTCHN;
+    ASSERT(hypercall_hvm_op(HVMOP_get_param, &param) == 0);
+    event = param.value;
+
+    printf("Xenbus rings @0x%lx, event channel %lu\n",
+           (unsigned long) rings, (unsigned long) event);
+}
+
+/* Reset the xenbus connection so the next kernel can start again. 
+ * We zero out the whole ring -- the backend can handle this, and it's 
+ * not going to surprise any frontends since it's equivalent to never 
+ * having used the rings. */
+void xenbus_shutdown(void)
+{
+    ASSERT(rings);
+    memset(rings, 0, sizeof *rings);
+    rings = NULL;
+}
+
+/* Helper functions: copy data in and out of the ring */
+static void ring_write(char *data, uint32_t len)
+{
+    uint32_t part;
+    ASSERT(len <= XENSTORE_PAYLOAD_MAX);
+
+    while (len) {
+        /* Don't overrun the consumer pointer */
+        part = (XENSTORE_RING_SIZE - 1) -
+            MASK_XENSTORE_IDX(rings->req_prod - rings->req_cons);
+        /* Don't overrun the end of the ring */
+        if (part > XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod))
+            part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod);
+        /* Don't write more than we were asked for */
+        if (part > len) 
+            part = len;
+
+        memcpy(rings->req + MASK_XENSTORE_IDX(rings->req_prod), data, part);
+        barrier(); /* = wmb before prod write, rmb before next cons read */
+        rings->req_prod += part;
+        len -= part;
+
+        if (len)
+            hypercall_sched_op(SCHEDOP_yield, NULL);
+    }
+}
+
+static void ring_read(char *data, uint32_t len)
+{
+    uint32_t part;
+    ASSERT(len <= XENSTORE_PAYLOAD_MAX);
+
+    while (len) {
+        /* Don't overrun the producer pointer */
+        part = MASK_XENSTORE_IDX(rings->rsp_prod - rings->rsp_cons);
+        /* Don't overrun the end of the ring */
+        if (part > XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons))
+            part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons);
+        /* Don't read more than we were asked for */
+        if (part > len)
+            part = len;
+
+        memcpy(data, rings->rsp + MASK_XENSTORE_IDX(rings->rsp_cons), part);
+        barrier(); /* = wmb before cons write, rmb before next prod read */
+        rings->rsp_cons += part;
+        len -= part;
+        
+        if (len)
+            hypercall_sched_op(SCHEDOP_yield, NULL);
+    }
+}
+
+
+/* Send a request and wait for the answer.
+ * Returns 0 for success, or an errno for error.
+ * The answer is returned in a static buffer which is only
+ * valid until the next call of xenbus_send(). */
+static int xenbus_send(uint32_t type, uint32_t len, char *data,
+                       uint32_t *reply_len, char **reply_data)
+{
+    struct xsd_sockmsg hdr;
+    evtchn_send_t send;
+    int i;
+
+    /* Not acceptable to use xenbus before setting it up */
+    ASSERT(rings);
+
+    /* Put the request on the ring */
+    hdr.type = type;
+    hdr.req_id = 0;  /* We only ever issue one request at a time */
+    hdr.tx_id = 0;   /* We never use transactions */
+    hdr.len = len;
+    ring_write((char *) &hdr, sizeof hdr);
+    ring_write(data, len);
+
+    /* Tell the other end about the request */
+    send.port = event;
+    hypercall_event_channel_op(EVTCHNOP_send, &send);
+
+    /* Properly we should poll the event channel now but that involves
+     * mapping the shared-info page and handling the bitmaps. */
+
+    /* Pull the reply off the ring */
+    ring_read((char *) &hdr, sizeof(hdr));
+    ring_read(payload, hdr.len);
+    /* For sanity's sake, nul-terminate the answer */
+    payload[hdr.len] = '\0';
+
+    /* Handle errors */
+    if (hdr.type == XS_ERROR) {
+        *reply_len = 0;
+        for (i = 0; i < ((sizeof xsd_errors) / (sizeof xsd_errors[0])); i++)
+            if (!strcmp(xsd_errors[i].errstring, payload))
+                return xsd_errors[i].errnum;
+        /* Default error value if we couldn't decode the ASCII error */
+        return EIO;
+    }
+
+    *reply_data = payload;
+    *reply_len = hdr.len;
+    return 0;
+}
+
+
+/* Read a xenstore key.  Returns a nul-terminated string (even if the XS
+ * data wasn't nul-terminated) or NULL.  The returned string is in a
+ * static buffer, so only valid until the next xenstore/xenbus operation. */
+char *xenstore_read(char *path)
+{
+    uint32_t len = 0;
+    char *answer = NULL;
+
+    /* Include the nul in the request */
+    if (xenbus_send(XS_READ, strlen(path) + 1, path, &len, &answer))
+        return NULL;
+    /* We know xenbus_send() nul-terminates its answer, so just pass it on. */
+    return answer;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys
  2010-07-09 10:57 [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
  2010-07-09 10:57 ` [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore Tim Deegan
@ 2010-07-09 10:57 ` Tim Deegan
  1 sibling, 0 replies; 3+ messages in thread
From: Tim Deegan @ 2010-07-09 10:57 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 94 bytes --]

written at domain creation time by xapi.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>



[-- Attachment #2: xen-unstable.hg-2.patch --]
[-- Type: text/x-patch, Size: 5189 bytes --]

# HG changeset patch
# User Tim Deegan <Tim.Deegan@citrix.com>
# Date 1278671252 -3600
# Node ID 1db4a00d68296688445df0455ff21fca1af42ab7
# Parent  62b9338150160d6f7cea3e2c386f5e6f94e1b13b
HVM firmware: customize the SMBIOS strings based on xenstore keys
written at domain creation time by xapi.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>

diff -r 62b933815016 -r 1db4a00d6829 tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c	Fri Jul 09 11:27:29 2010 +0100
+++ b/tools/firmware/hvmloader/smbios.c	Fri Jul 09 11:27:32 2010 +0100
@@ -53,6 +53,8 @@
 static void *
 smbios_type_4_init(void *start, unsigned int cpu_number,
                    char *cpu_manufacturer);
+static void *
+smbios_type_11_init(void *start);
 static void *
 smbios_type_16_init(void *start, uint32_t memory_size_mb, int nr_mem_devs);
 static void *
@@ -112,6 +114,7 @@
     do_struct(smbios_type_3_init(p));
     for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ )
         do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
+    do_struct(smbios_type_11_init(p));
 
     /* Each 'memory device' covers up to 16GB of address space. */
     nr_mem_devs = (memsize + 0x3fff) >> 14;
@@ -283,6 +286,7 @@
 {
     struct smbios_type_0 *p = (struct smbios_type_0 *)start;
     static const char *smbios_release_date = __SMBIOS_DATE__;
+    const char *s;
 
     memset(p, 0, sizeof(*p));
 
@@ -309,10 +313,16 @@
     p->embedded_controller_minor = 0xff;
 
     start += sizeof(struct smbios_type_0);
-    strcpy((char *)start, "Xen");
-    start += strlen("Xen") + 1;
-    strcpy((char *)start, xen_version);
-    start += strlen(xen_version) + 1;
+    if ((s = xenstore_read("bios-strings/bios-vendor")) == NULL || *s == '\0')
+        s = "Xen";
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
+    if ((s = xenstore_read("bios-strings/bios-version")) == NULL || *s == '\0')
+        s = xen_version;
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
     strcpy((char *)start, smbios_release_date);
     start += strlen(smbios_release_date) + 1;
 
@@ -327,6 +337,7 @@
 {
     char uuid_str[37];
     struct smbios_type_1 *p = (struct smbios_type_1 *)start;
+    const char *s;
 
     memset(p, 0, sizeof(*p));
 
@@ -347,15 +358,31 @@
 
     start += sizeof(struct smbios_type_1);
     
-    strcpy((char *)start, "Xen");
-    start += strlen("Xen") + 1;
-    strcpy((char *)start, "HVM domU");
-    start += strlen("HVM domU") + 1;
-    strcpy((char *)start, xen_version);
-    start += strlen(xen_version) + 1;
+    if ((s = xenstore_read("bios-strings/system-manufacturer")) == NULL  
+        || *s == '\0')
+        s = "Xen";
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
+    if ((s = xenstore_read("bios-strings/system-product-name")) == NULL
+         || *s == '\0')
+        s = "HVM domU";
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
+    if ((s = xenstore_read("bios-strings/system-version")) == NULL
+        || *s == '\0')
+        s = xen_version;
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
     uuid_to_string(uuid_str, uuid); 
-    strcpy((char *)start, uuid_str);
-    start += strlen(uuid_str) + 1;
+    if ((s = xenstore_read("bios-strings/system-serial-number")) == NULL
+        || *s == '\0')
+        s = uuid_str;
+    strcpy((char *)start, s);
+    start += strlen(s) + 1;
+
     *((uint8_t *)start) = 0;
     
     return start+1; 
@@ -438,6 +465,45 @@
     start += strlen(cpu_manufacturer) + 1;
 
     *((uint8_t *)start) = 0;
+    return start+1;
+}
+
+/* Type 11 -- OEM Strings */
+static void *
+smbios_type_11_init(void *start) 
+{
+    struct smbios_type_11 *p = (struct smbios_type_11 *)start;
+    char path[20] = "bios-strings/oem-XX";
+    const char *s;
+    int i;
+
+    p->header.type = 11;
+    p->header.length = sizeof(struct smbios_type_11);
+    p->header.handle = 0xB00;
+
+    p->count = 0;
+
+    start += sizeof(struct smbios_type_11);
+
+    /* Pull out as many oem-* strings we find in xenstore */
+    for (i = 1; i < 100; i++) {
+        path[(sizeof path) - 3] = '0' + ((i < 10) ? i : i / 10);
+        path[(sizeof path) - 2] = (i < 10) ? '\0' : '0' + (i % 10);
+        if ((s = xenstore_read(path)) == NULL || *s == '\0')
+            break;
+        strcpy((char *)start, s);
+        start += strlen(s) + 1;
+        p->count++;
+    }
+    
+    /* Make sure there's at least one type-11 string */
+    if (p->count == 0) {
+        strcpy((char *)start, "Xen");
+        start += strlen("Xen") + 1;
+        p->count++;
+    }
+    *((uint8_t *)start) = 0;
+
     return start+1;
 }
 
diff -r 62b933815016 -r 1db4a00d6829 tools/firmware/hvmloader/smbios_types.h
--- a/tools/firmware/hvmloader/smbios_types.h	Fri Jul 09 11:27:29 2010 +0100
+++ b/tools/firmware/hvmloader/smbios_types.h	Fri Jul 09 11:27:32 2010 +0100
@@ -115,6 +115,12 @@
 	uint8_t upgrade;
 } __attribute__ ((packed));
 
+/* SMBIOS type 11 - OEM Strings */
+struct smbios_type_11 {
+   struct smbios_structure_header header;
+   uint8_t count;
+} __attribute__ ((packed));
+
 /* SMBIOS type 16 - Physical Memory Array
  *   Associated with one type 17 (Memory Device).
  */

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-07-09 10:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-09 10:57 [PATCH 0 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan
2010-07-09 10:57 ` [PATCH 1 of 2] Add a xenbus frontend to hvmloader so it can read values from xenstore Tim Deegan
2010-07-09 10:57 ` [PATCH 2 of 2] HVM firmware: customize the SMBIOS strings based on xenstore keys Tim Deegan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).