Re: vmd(4) fw_cfg support

2018-12-10 Thread Carlos Cardenas
On Mon, Dec 10, 2018 at 05:52:43PM +0100, Claudio Jeker wrote:
> This adds the fw_cfg interface that QEMU is using to pass data to the
> BIOS. It implements both IO port access and DMA access. SeaBIOS will use
> the latter if available. This should be useful for adding ACPI tables or
> SMBIOS data.
> 
> This requires the latest vmm-firmware (which I just commited) and the
> vmm(4) diff I just sent out to work correctly.
> 
> Since fw_cfg requires to zero out DMA memory I extended write_mem to do
> this if a NULL pointer is used for buf. I felt this is something which may
> be generally useful.
> -- 
> :wq Claudio

Very nice...

ok ccardenas@

+--+
Carlos



Re: vmd(4) fw_cfg support

2018-12-10 Thread Mike Larkin
On Mon, Dec 10, 2018 at 05:52:43PM +0100, Claudio Jeker wrote:
> This adds the fw_cfg interface that QEMU is using to pass data to the
> BIOS. It implements both IO port access and DMA access. SeaBIOS will use
> the latter if available. This should be useful for adding ACPI tables or
> SMBIOS data.
> 
> This requires the latest vmm-firmware (which I just commited) and the
> vmm(4) diff I just sent out to work correctly.
> 
> Since fw_cfg requires to zero out DMA memory I extended write_mem to do
> this if a NULL pointer is used for buf. I felt this is something which may
> be generally useful.
> -- 
> :wq Claudio
> 
> 

This reads ok to me. Thanks Claudio.

-ml

> Index: Makefile
> ===
> RCS file: /cvs/src/usr.sbin/vmd/Makefile,v
> retrieving revision 1.20
> diff -u -p -r1.20 Makefile
> --- Makefile  9 Sep 2018 04:09:32 -   1.20
> +++ Makefile  8 Dec 2018 06:59:17 -
> @@ -6,7 +6,7 @@ PROG= vmd
>  SRCS=vmd.c control.c log.c priv.c proc.c config.c vmm.c
>  SRCS+=   vm.c loadfile_elf.c pci.c virtio.c i8259.c mc146818.c
>  SRCS+=   ns8250.c i8253.c vmboot.c ufs.c disklabel.c dhcp.c 
> packet.c
> -SRCS+=   parse.y atomicio.c vioscsi.c vioraw.c vioqcow2.c
> +SRCS+=   parse.y atomicio.c vioscsi.c vioraw.c vioqcow2.c 
> fw_cfg.c
>  
>  CFLAGS+= -Wall -I${.CURDIR}
>  CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
> Index: fw_cfg.c
> ===
> RCS file: fw_cfg.c
> diff -N fw_cfg.c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ fw_cfg.c  10 Dec 2018 16:39:55 -
> @@ -0,0 +1,434 @@
> +/*   $OpenBSD$   */
> +/*
> + * Copyright (c) 2018 Claudio Jeker 
> + *
> + * 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 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +#include "atomicio.h"
> +#include "proc.h"
> +#include "vmd.h"
> +#include "vmm.h"
> +#include "fw_cfg.h"
> +
> +#define  FW_CFG_SIGNATURE0x
> +#define  FW_CFG_ID   0x0001
> +#define  FW_CFG_NOGRAPHIC0x0004
> +#define  FW_CFG_FILE_DIR 0x0019
> +#define  FW_CFG_FILE_FIRST   0x0020
> +
> +#define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* QEMU CFG */
> +
> +struct fw_cfg_dma_access {
> + uint32_tcontrol;
> +#define FW_CFG_DMA_ERROR 0x0001
> +#define FW_CFG_DMA_READ  0x0002
> +#define FW_CFG_DMA_SKIP  0x0004
> +#define FW_CFG_DMA_SELECT0x0008
> +#define FW_CFG_DMA_WRITE 0x0010  /* not implemented */
> + uint32_tlength;
> + uint64_taddress;
> +};
> +
> +struct fw_cfg_file {
> + uint32_tsize;
> + uint16_tselector;
> + uint16_treserved;
> + charname[56];
> +};
> +
> +extern char *__progname;
> +
> +static struct fw_cfg_state {
> + size_t offset;
> + size_t size;
> + uint8_t *data;
> +} fw_cfg_state;
> +
> +static uint64_t  fw_cfg_dma_addr;
> +
> +static int   fw_cfg_select_file(uint16_t);
> +static void  fw_cfg_file_dir(void);
> +
> +void
> +fw_cfg_init(struct vmop_create_params *vmc)
> +{
> + const char *bootorder = NULL;
> + unsigned int sd = 0;
> +
> + /* do not double print chars on serial port */
> + fw_cfg_add_file("etc/screen-and-debug", &sd, sizeof(sd));
> +
> + switch (vmc->vmc_bootdevice) {
> + case VMBOOTDEV_DISK:
> + bootorder = "/pci@i0cf8/*@2\nHALT";
> + break;
> + case VMBOOTDEV_CDROM:
> + bootorder = "/pci@i0cf8/*@4/*@0/*@0,100\nHALT";
> + break;
> + case VMBOOTDEV_NET:
> + /* XXX not yet */
> + bootorder = "HALT";
> + break;
> + }
> + if (bootorder)
> + fw_cfg_add_file("bootorder", bootorder, strlen(bootorder) + 1);
> +}
> +
> +int
> +fw_cfg_dump(int fd)
> +{
> + log_debug("%s: sending fw_cfg state", __func__);
> + if (atomicio(vwrite, fd, &fw_cfg_dma_addr,
> + sizeof(fw_cfg_dma_addr)) != sizeof(fw_cfg_dma_addr)) {
> + log_warnx("%s: error writing fw_cfg to fd", __func__);
> + return -1;
> + }
> + if (atomicio(v

vmd(4) fw_cfg support

2018-12-10 Thread Claudio Jeker
This adds the fw_cfg interface that QEMU is using to pass data to the
BIOS. It implements both IO port access and DMA access. SeaBIOS will use
the latter if available. This should be useful for adding ACPI tables or
SMBIOS data.

This requires the latest vmm-firmware (which I just commited) and the
vmm(4) diff I just sent out to work correctly.

Since fw_cfg requires to zero out DMA memory I extended write_mem to do
this if a NULL pointer is used for buf. I felt this is something which may
be generally useful.
-- 
:wq Claudio


Index: Makefile
===
RCS file: /cvs/src/usr.sbin/vmd/Makefile,v
retrieving revision 1.20
diff -u -p -r1.20 Makefile
--- Makefile9 Sep 2018 04:09:32 -   1.20
+++ Makefile8 Dec 2018 06:59:17 -
@@ -6,7 +6,7 @@ PROG=   vmd
 SRCS=  vmd.c control.c log.c priv.c proc.c config.c vmm.c
 SRCS+= vm.c loadfile_elf.c pci.c virtio.c i8259.c mc146818.c
 SRCS+= ns8250.c i8253.c vmboot.c ufs.c disklabel.c dhcp.c packet.c
-SRCS+= parse.y atomicio.c vioscsi.c vioraw.c vioqcow2.c
+SRCS+= parse.y atomicio.c vioscsi.c vioraw.c vioqcow2.c fw_cfg.c
 
 CFLAGS+=   -Wall -I${.CURDIR}
 CFLAGS+=   -Wstrict-prototypes -Wmissing-prototypes
Index: fw_cfg.c
===
RCS file: fw_cfg.c
diff -N fw_cfg.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ fw_cfg.c10 Dec 2018 16:39:55 -
@@ -0,0 +1,434 @@
+/* $OpenBSD$   */
+/*
+ * Copyright (c) 2018 Claudio Jeker 
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "atomicio.h"
+#include "proc.h"
+#include "vmd.h"
+#include "vmm.h"
+#include "fw_cfg.h"
+
+#defineFW_CFG_SIGNATURE0x
+#defineFW_CFG_ID   0x0001
+#defineFW_CFG_NOGRAPHIC0x0004
+#defineFW_CFG_FILE_DIR 0x0019
+#defineFW_CFG_FILE_FIRST   0x0020
+
+#define FW_CFG_DMA_SIGNATURE   0x51454d5520434647ULL /* QEMU CFG */
+
+struct fw_cfg_dma_access {
+   uint32_tcontrol;
+#define FW_CFG_DMA_ERROR   0x0001
+#define FW_CFG_DMA_READ0x0002
+#define FW_CFG_DMA_SKIP0x0004
+#define FW_CFG_DMA_SELECT  0x0008
+#define FW_CFG_DMA_WRITE   0x0010  /* not implemented */
+   uint32_tlength;
+   uint64_taddress;
+};
+
+struct fw_cfg_file {
+   uint32_tsize;
+   uint16_tselector;
+   uint16_treserved;
+   charname[56];
+};
+
+extern char *__progname;
+
+static struct fw_cfg_state {
+   size_t offset;
+   size_t size;
+   uint8_t *data;
+} fw_cfg_state;
+
+static uint64_tfw_cfg_dma_addr;
+
+static int fw_cfg_select_file(uint16_t);
+static voidfw_cfg_file_dir(void);
+
+void
+fw_cfg_init(struct vmop_create_params *vmc)
+{
+   const char *bootorder = NULL;
+   unsigned int sd = 0;
+
+   /* do not double print chars on serial port */
+   fw_cfg_add_file("etc/screen-and-debug", &sd, sizeof(sd));
+
+   switch (vmc->vmc_bootdevice) {
+   case VMBOOTDEV_DISK:
+   bootorder = "/pci@i0cf8/*@2\nHALT";
+   break;
+   case VMBOOTDEV_CDROM:
+   bootorder = "/pci@i0cf8/*@4/*@0/*@0,100\nHALT";
+   break;
+   case VMBOOTDEV_NET:
+   /* XXX not yet */
+   bootorder = "HALT";
+   break;
+   }
+   if (bootorder)
+   fw_cfg_add_file("bootorder", bootorder, strlen(bootorder) + 1);
+}
+
+int
+fw_cfg_dump(int fd)
+{
+   log_debug("%s: sending fw_cfg state", __func__);
+   if (atomicio(vwrite, fd, &fw_cfg_dma_addr,
+   sizeof(fw_cfg_dma_addr)) != sizeof(fw_cfg_dma_addr)) {
+   log_warnx("%s: error writing fw_cfg to fd", __func__);
+   return -1;
+   }
+   if (atomicio(vwrite, fd, &fw_cfg_state.offset,
+   sizeof(fw_cfg_state.offset)) != sizeof(fw_cfg_state.offset)) {
+   log_warnx("%s: error writing fw_cfg to fd", __func__);
+   return -1;
+   }
+   if (atomicio(vwrite, fd, &fw_cfg_state.size,
+   sizeof(fw_cfg_state.size)) != si