From patchwork Tue May 10 06:04:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12844572 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A6ABAC4332F for ; Tue, 10 May 2022 06:05:32 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.325177.547636 (Exim 4.92) (envelope-from ) id 1noIzd-00084N-Ag; Tue, 10 May 2022 06:05:09 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 325177.547636; Tue, 10 May 2022 06:05:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzd-00084G-7o; Tue, 10 May 2022 06:05:09 +0000 Received: by outflank-mailman (input) for mailman id 325177; Tue, 10 May 2022 06:05:08 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzb-0007z7-TW for xen-devel@lists.xen.org; Tue, 10 May 2022 06:05:08 +0000 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [2607:f8b0:4864:20::632]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 1b61a37a-d027-11ec-8fc4-03012f2f19d4; Tue, 10 May 2022 08:04:53 +0200 (CEST) Received: by mail-pl1-x632.google.com with SMTP id n8so15878727plh.1 for ; Mon, 09 May 2022 23:05:04 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id y7-20020a170902b48700b0015e8d4eb2d5sm945764plr.287.2022.05.09.23.05.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 May 2022 23:05:01 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 1b61a37a-d027-11ec-8fc4-03012f2f19d4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BFckj9YfDJ61q1eBueMecImTvynCt5bpUOPgONXR2+I=; b=VmD81tx1qhFdTJ3yJqAZlYYVX/2/bqKI7qgHYaWH15qkRgQjm3Ec8ytBI9S1NfNNtT oWfdsQFa43UmXZ/lf36tjVtGf58oS+eo8qB3jfQj3snX2/94Zu6S3DKRpLQX8hxge40W 1dprtTWO8bqrw3G6KI6JbV41NKO0cACe95Qv4E1s+Q8dEumDyjRbESCyry7sKv3YGJGO S+ztpmHMkpuBEq56jXQaJaVC+olDVIp/fPyfKeFSw5veyRFENa8OHwMGBEO2h6ePGzVs fXerO/QQaEcr/ymtwWvSQ1BL0Kroiltbv3gJY2xetu4jfIEzm9S+RDCa5BnIBB3ZklDc ta/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BFckj9YfDJ61q1eBueMecImTvynCt5bpUOPgONXR2+I=; b=j1WzjpgOd9eVEn7uo1bTE+DKRw3XmPlDd2NSxGwrN6UVGZOD7UFjPkgDhD0NWKhloQ 9ov5RH9lBxJlSi4QHT6zYj9f2LXdEakCPf/k1B/8b+otoI7L3z7V0OGJj94qPFpze5C/ KhmnzK1QarYflN+yPdauhALcTzqph6dVEvuDCJq0FDIeGZEMaY2+In+Pg5+FmpINw7Z5 DioiaWn3Jw6i8+yB0eGIozw57WpWULW74Ep7gdd92IT/jQAKTGnZ1Jb/HgHAkOGHrzj5 3x9NOIjtaKyBjNVoNYOXmZV6C+hICGdiM2NX3Kl8XvsB0KuPCsCSexx+j81mn338TB5V QkMg== X-Gm-Message-State: AOAM5320cJEAVjzlu1wZ7Mq00Mzvm/8nZPLgnnHtjab9E83aHCsb3my7 2/RrESRkRdky3Ezz+dZD5tYTiDidBUMiOQ== X-Google-Smtp-Source: ABdhPJzWkYCoIzBMXoxeV9//CjBVxE2XQjNCmGmzVecsd1JqpI+QmhCOMOpZVHWgw+6gwFL8VeJH8w== X-Received: by 2002:a17:90a:9914:b0:1db:d10f:1fcf with SMTP id b20-20020a17090a991400b001dbd10f1fcfmr29740584pjp.241.1652162702586; Mon, 09 May 2022 23:05:02 -0700 (PDT) From: Viresh Kumar To: xen-devel@lists.xen.org Cc: Viresh Kumar , Vincent Guittot , stratos-dev@op-lists.linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Stabellini , Mathieu Poirier , Mike Holmes , Oleksandr Tyshchenko , Wei Liu , Juergen Gross , Julien Grall Subject: [PATCH V2 1/6] libxl: Add support for Virtio I2C device Date: Tue, 10 May 2022 11:34:46 +0530 Message-Id: X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 This patch adds basic support for configuring and assisting virtio-mmio based virtio-i2c backend (emualator) which is intended to run out of Qemu and could be run in any domain. An example of domain configuration for Virtio I2c: i2c = [ "" ] Please note, this patch is not enough for virtio-i2c to work on Xen (Arm), as for every Virtio device we need to allocate Virtio MMIO params (IRQ and memory region) and pass them to the backend, also update Guest device-tree. A subsequent patch will add these missing bits. For the current patch, the default "irq" and "base" are just written to the Xenstore. Signed-off-by: Viresh Kumar --- tools/golang/xenlight/helpers.gen.go | 110 ++++++++++ tools/golang/xenlight/types.gen.go | 27 +++ tools/include/libxl.h | 32 +++ tools/include/libxl_utils.h | 3 + tools/libs/light/Makefile | 1 + tools/libs/light/libxl_create.c | 13 ++ tools/libs/light/libxl_dm.c | 19 +- tools/libs/light/libxl_i2c.c | 236 ++++++++++++++++++++++ tools/libs/light/libxl_internal.h | 1 + tools/libs/light/libxl_types.idl | 26 +++ tools/libs/light/libxl_types_internal.idl | 1 + tools/ocaml/libs/xl/genwrap.py | 1 + tools/ocaml/libs/xl/xenlight_stubs.c | 1 + tools/xl/Makefile | 2 +- tools/xl/xl.h | 3 + tools/xl/xl_cmdtable.c | 15 ++ tools/xl/xl_i2c.c | 143 +++++++++++++ tools/xl/xl_parse.c | 80 ++++++++ tools/xl/xl_parse.h | 1 + tools/xl/xl_sxp.c | 2 + 20 files changed, 714 insertions(+), 3 deletions(-) create mode 100644 tools/libs/light/libxl_i2c.c create mode 100644 tools/xl/xl_i2c.c diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go index b746ff108131..ad23b0969abd 100644 --- a/tools/golang/xenlight/helpers.gen.go +++ b/tools/golang/xenlight/helpers.gen.go @@ -1215,6 +1215,9 @@ x.Usbdevice = C.GoString(tmp.usbdevice) if err := x.VkbDevice.fromC(&tmp.vkb_device);err != nil { return fmt.Errorf("converting field VkbDevice: %v", err) } +if err := x.I2cDevice.fromC(&tmp.i2c_device);err != nil { +return fmt.Errorf("converting field I2cDevice: %v", err) +} x.Soundhw = C.GoString(tmp.soundhw) if err := x.XenPlatformPci.fromC(&tmp.xen_platform_pci);err != nil { return fmt.Errorf("converting field XenPlatformPci: %v", err) @@ -1532,6 +1535,9 @@ hvm.usbdevice = C.CString(tmp.Usbdevice)} if err := tmp.VkbDevice.toC(&hvm.vkb_device); err != nil { return fmt.Errorf("converting field VkbDevice: %v", err) } +if err := tmp.I2cDevice.toC(&hvm.i2c_device); err != nil { +return fmt.Errorf("converting field I2cDevice: %v", err) +} if tmp.Soundhw != "" { hvm.soundhw = C.CString(tmp.Soundhw)} if err := tmp.XenPlatformPci.toC(&hvm.xen_platform_pci); err != nil { @@ -1722,6 +1728,46 @@ xc.multi_touch_num_contacts = C.uint32_t(x.MultiTouchNumContacts) return nil } +// NewDeviceI2c returns an instance of DeviceI2c initialized with defaults. +func NewDeviceI2c() (*DeviceI2c, error) { +var ( +x DeviceI2c +xc C.libxl_device_i2c) + +C.libxl_device_i2c_init(&xc) +defer C.libxl_device_i2c_dispose(&xc) + +if err := x.fromC(&xc); err != nil { +return nil, err } + +return &x, nil} + +func (x *DeviceI2c) fromC(xc *C.libxl_device_i2c) error { + x.BackendDomid = Domid(xc.backend_domid) +x.BackendDomname = C.GoString(xc.backend_domname) +x.Devid = Devid(xc.devid) +x.BackendType = I2cBackend(xc.backend_type) +x.Irq = uint32(xc.irq) +x.Base = uint64(xc.base) + + return nil} + +func (x *DeviceI2c) toC(xc *C.libxl_device_i2c) (err error){defer func(){ +if err != nil{ +C.libxl_device_i2c_dispose(xc)} +}() + +xc.backend_domid = C.libxl_domid(x.BackendDomid) +if x.BackendDomname != "" { +xc.backend_domname = C.CString(x.BackendDomname)} +xc.devid = C.libxl_devid(x.Devid) +xc.backend_type = C.libxl_i2c_backend(x.BackendType) +xc.irq = C.uint32_t(x.Irq) +xc.base = C.uint64_t(x.Base) + + return nil + } + // NewDeviceDisk returns an instance of DeviceDisk initialized with defaults. func NewDeviceDisk() (*DeviceDisk, error) { var ( @@ -2835,6 +2881,15 @@ if err := x.Vkbs[i].fromC(&v); err != nil { return fmt.Errorf("converting field Vkbs: %v", err) } } } +x.I2cs = nil +if n := int(xc.num_i2cs); n > 0 { +cI2cs := (*[1<<28]C.libxl_device_i2c)(unsafe.Pointer(xc.i2cs))[:n:n] +x.I2cs = make([]DeviceI2c, n) +for i, v := range cI2cs { +if err := x.I2cs[i].fromC(&v); err != nil { +return fmt.Errorf("converting field I2cs: %v", err) } +} +} x.Vtpms = nil if n := int(xc.num_vtpms); n > 0 { cVtpms := (*[1<<28]C.libxl_device_vtpm)(unsafe.Pointer(xc.vtpms))[:n:n] @@ -2996,6 +3051,16 @@ return fmt.Errorf("converting field Vkbs: %v", err) } } } +if numI2cs := len(x.I2cs); numI2cs > 0 { +xc.i2cs = (*C.libxl_device_i2c)(C.malloc(C.ulong(numI2cs)*C.sizeof_libxl_device_i2c)) +xc.num_i2cs = C.int(numI2cs) +cI2cs := (*[1<<28]C.libxl_device_i2c)(unsafe.Pointer(xc.i2cs))[:numI2cs:numI2cs] +for i,v := range x.I2cs { +if err := v.toC(&cI2cs[i]); err != nil { +return fmt.Errorf("converting field I2cs: %v", err) +} +} +} if numVtpms := len(x.Vtpms); numVtpms > 0 { xc.vtpms = (*C.libxl_device_vtpm)(C.malloc(C.ulong(numVtpms)*C.sizeof_libxl_device_vtpm)) xc.num_vtpms = C.int(numVtpms) @@ -3683,6 +3748,51 @@ if err != nil{ C.libxl_vkbinfo_dispose(xc)} }() +if x.Backend != "" { +xc.backend = C.CString(x.Backend)} +xc.backend_id = C.uint32_t(x.BackendId) +if x.Frontend != "" { +xc.frontend = C.CString(x.Frontend)} +xc.frontend_id = C.uint32_t(x.FrontendId) +xc.devid = C.libxl_devid(x.Devid) +xc.state = C.int(x.State) +xc.evtch = C.int(x.Evtch) +xc.rref = C.int(x.Rref) + + return nil + } + +// NewI2cinfo returns an instance of I2cinfo initialized with defaults. +func NewI2cinfo() (*I2cinfo, error) { +var ( +x I2cinfo +xc C.libxl_i2cinfo) + +C.libxl_i2cinfo_init(&xc) +defer C.libxl_i2cinfo_dispose(&xc) + +if err := x.fromC(&xc); err != nil { +return nil, err } + +return &x, nil} + +func (x *I2cinfo) fromC(xc *C.libxl_i2cinfo) error { + x.Backend = C.GoString(xc.backend) +x.BackendId = uint32(xc.backend_id) +x.Frontend = C.GoString(xc.frontend) +x.FrontendId = uint32(xc.frontend_id) +x.Devid = Devid(xc.devid) +x.State = int(xc.state) +x.Evtch = int(xc.evtch) +x.Rref = int(xc.rref) + + return nil} + +func (x *I2cinfo) toC(xc *C.libxl_i2cinfo) (err error){defer func(){ +if err != nil{ +C.libxl_i2cinfo_dispose(xc)} +}() + if x.Backend != "" { xc.backend = C.CString(x.Backend)} xc.backend_id = C.uint32_t(x.BackendId) diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go index b1e84d525843..c232e4811ac3 100644 --- a/tools/golang/xenlight/types.gen.go +++ b/tools/golang/xenlight/types.gen.go @@ -241,6 +241,11 @@ VkbBackendQemu VkbBackend = 1 VkbBackendLinux VkbBackend = 2 ) +type I2cBackend int +const( +I2cBackendVirtio I2cBackend = 0 +) + type Passthrough int const( PassthroughDefault Passthrough = 0 @@ -568,6 +573,7 @@ Usb Defbool Usbversion int Usbdevice string VkbDevice Defbool +I2cDevice Defbool Soundhw string XenPlatformPci Defbool UsbdeviceList StringList @@ -630,6 +636,15 @@ MultiTouchHeight uint32 MultiTouchNumContacts uint32 } +type DeviceI2c struct { +BackendDomid Domid +BackendDomname string +Devid Devid +BackendType I2cBackend +Irq uint32 +Base uint64 +} + type DeviceDisk struct { BackendDomid Domid BackendDomname string @@ -913,6 +928,7 @@ Rdms []DeviceRdm Dtdevs []DeviceDtdev Vfbs []DeviceVfb Vkbs []DeviceVkb +I2cs []DeviceI2c Vtpms []DeviceVtpm P9S []DeviceP9 Pvcallsifs []DevicePvcallsif @@ -1067,6 +1083,17 @@ Evtch int Rref int } +type I2cinfo struct { +Backend string +BackendId uint32 +Frontend string +FrontendId uint32 +Devid Devid +State int +Evtch int +Rref int +} + type Numainfo struct { Size uint64 Free uint64 diff --git a/tools/include/libxl.h b/tools/include/libxl.h index 51a9b6cfaceb..4d19194c3dc2 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -800,6 +800,15 @@ typedef struct libxl__ctx libxl_ctx; */ #define LIBXL_HAVE_BUILDINFO_VKB_DEVICE 1 +/* + * LIBXL_HAVE_BUILDINFO_I2C_DEVICE + * + * If this is defined, then the libxl_domain_build_info structure will + * contain a boolean hvm.i2c_device which instructs libxl whether to include + * a i2c at build time or not. + */ +#define LIBXL_HAVE_BUILDINFO_I2C_DEVICE 1 + /* * LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST * @@ -2368,6 +2377,29 @@ int libxl_device_vkb_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_vkbinfo *vkbinfo) LIBXL_EXTERNAL_CALLERS_ONLY; +/* I2C */ +int libxl_device_i2c_add(libxl_ctx *ctx, uint32_t domid, libxl_device_i2c *i2c, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_i2c_remove(libxl_ctx *ctx, uint32_t domid, + libxl_device_i2c *i2c, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_i2c_destroy(libxl_ctx *ctx, uint32_t domid, + libxl_device_i2c *i2c, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +libxl_device_i2c *libxl_device_i2c_list(libxl_ctx *ctx, + uint32_t domid, int *num) + LIBXL_EXTERNAL_CALLERS_ONLY; +void libxl_device_i2c_list_free(libxl_device_i2c* list, int num) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_i2c_getinfo(libxl_ctx *ctx, uint32_t domid, + const libxl_device_i2c *i2c, + libxl_i2cinfo *i2cinfo) + LIBXL_EXTERNAL_CALLERS_ONLY; + /* Framebuffer */ int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, const libxl_asyncop_how *ao_how) diff --git a/tools/include/libxl_utils.h b/tools/include/libxl_utils.h index 46918aea847f..72b7796b7e4b 100644 --- a/tools/include/libxl_utils.h +++ b/tools/include/libxl_utils.h @@ -83,6 +83,9 @@ int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t domid, int libxl_devid_to_device_vkb(libxl_ctx *ctx, uint32_t domid, int devid, libxl_device_vkb *vkb); +int libxl_devid_to_device_i2c(libxl_ctx *ctx, uint32_t domid, + int devid, libxl_device_i2c *i2c); + int libxl_devid_to_device_vdispl(libxl_ctx *ctx, uint32_t domid, int devid, libxl_device_vdispl *vdispl); diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile index 453bea006723..dca46846e586 100644 --- a/tools/libs/light/Makefile +++ b/tools/libs/light/Makefile @@ -112,6 +112,7 @@ SRCS-y += libxl_vdispl.c SRCS-y += libxl_pvcalls.c SRCS-y += libxl_vsnd.c SRCS-y += libxl_vkb.c +SRCS-y += libxl_i2c.c SRCS-y += libxl_genid.c SRCS-y += _libxl_types.c SRCS-y += libxl_flask.c diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c index 69ec405858a8..d604171e504c 100644 --- a/tools/libs/light/libxl_create.c +++ b/tools/libs/light/libxl_create.c @@ -363,6 +363,7 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc, libxl_defbool_setdefault(&b_info->u.hvm.altp2m, false); libxl_defbool_setdefault(&b_info->u.hvm.usb, false); libxl_defbool_setdefault(&b_info->u.hvm.vkb_device, true); + libxl_defbool_setdefault(&b_info->u.hvm.i2c_device, true); libxl_defbool_setdefault(&b_info->u.hvm.xen_platform_pci, true); libxl_defbool_setdefault(&b_info->u.hvm.spice.enable, false); @@ -1755,6 +1756,7 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, libxl__device_console console; libxl__device device; libxl_device_vkb vkb; + libxl_device_i2c i2c; init_console_info(gc, &console, 0); console.backend_domid = state->console_domid; @@ -1767,6 +1769,12 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, libxl_device_vkb_dispose(&vkb); } + if (libxl_defbool_val(d_config->b_info.u.hvm.i2c_device)) { + libxl_device_i2c_init(&i2c); + libxl__device_add(gc, domid, &libxl__i2c_devtype, &i2c); + libxl_device_i2c_dispose(&i2c); + } + dcs->sdss.dm.guest_domid = domid; if (libxl_defbool_val(d_config->b_info.device_model_stubdomain)) libxl__spawn_stub_dm(egc, &dcs->sdss); @@ -1799,6 +1807,11 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, &d_config->vkbs[i]); } + for (i = 0; i < d_config->num_i2cs; i++) { + libxl__device_add(gc, domid, &libxl__i2c_devtype, + &d_config->i2cs[i]); + } + if (d_config->b_info.arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART) { init_console_info(gc, &vuart, 0); vuart.backend_domid = state->console_domid; diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c index 1864ee30f0a2..9340ae4628a2 100644 --- a/tools/libs/light/libxl_dm.c +++ b/tools/libs/light/libxl_dm.c @@ -2095,7 +2095,8 @@ static void libxl__dm_vifs_from_hvm_guest_config(libxl__gc *gc, static int libxl__vfb_and_vkb_from_hvm_guest_config(libxl__gc *gc, const libxl_domain_config *guest_config, libxl_device_vfb *vfb, - libxl_device_vkb *vkb) + libxl_device_vkb *vkb, + libxl_device_i2c *i2c) { const libxl_domain_build_info *b_info = &guest_config->b_info; @@ -2104,6 +2105,7 @@ static int libxl__vfb_and_vkb_from_hvm_guest_config(libxl__gc *gc, libxl_device_vfb_init(vfb); libxl_device_vkb_init(vkb); + libxl_device_i2c_init(i2c); vfb->backend_domid = 0; vfb->devid = 0; @@ -2114,6 +2116,9 @@ static int libxl__vfb_and_vkb_from_hvm_guest_config(libxl__gc *gc, vkb->backend_domid = 0; vkb->devid = 0; + i2c->backend_domid = 0; + i2c->devid = 0; + return 0; } @@ -2276,6 +2281,7 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss) int ret; libxl_device_vfb *vfb; libxl_device_vkb *vkb; + libxl_device_i2c *i2c; char **args; struct xs_permissions perm[2]; xs_transaction_t t; @@ -2348,11 +2354,14 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss) || libxl_defbool_val(guest_config->b_info.u.hvm.sdl.enable)) { GCNEW(vfb); GCNEW(vkb); - libxl__vfb_and_vkb_from_hvm_guest_config(gc, guest_config, vfb, vkb); + GCNEW(i2c); + libxl__vfb_and_vkb_from_hvm_guest_config(gc, guest_config, vfb, vkb, i2c); dm_config->vfbs = vfb; dm_config->num_vfbs = 1; dm_config->vkbs = vkb; dm_config->num_vkbs = 1; + dm_config->i2cs = i2c; + dm_config->num_i2cs = 1; } if (guest_config->b_info.stubdomain_kernel && @@ -2494,6 +2503,12 @@ static void spawn_stub_launch_dm(libxl__egc *egc, if (ret) goto out; } + if (dm_config->num_i2cs) { + ret = libxl__device_add(gc, dm_domid, &libxl__i2c_devtype, + &dm_config->i2cs[0]); + if (ret) goto out; + } + if (guest_config->b_info.u.hvm.serial) { num_console++; } else if (guest_config->b_info.u.hvm.serial_list) { diff --git a/tools/libs/light/libxl_i2c.c b/tools/libs/light/libxl_i2c.c new file mode 100644 index 000000000000..fd13c07826ff --- /dev/null +++ b/tools/libs/light/libxl_i2c.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2022 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_internal.h" + +#include + +static int libxl__device_i2c_setdefault(libxl__gc *gc, uint32_t domid, + libxl_device_i2c *i2c, bool hotplug) +{ + if (i2c->backend_type != LIBXL_I2C_BACKEND_VIRTIO) { + i2c->backend_type = LIBXL_I2C_BACKEND_VIRTIO; + } + + return libxl__resolve_domid(gc, i2c->backend_domname, &i2c->backend_domid); +} + +static int libxl__device_i2c_dm_needed(void *e, uint32_t domid) +{ + libxl_device_i2c *elem = e; + + return elem->backend_type == LIBXL_I2C_BACKEND_VIRTIO; +} + +static int libxl__set_xenstore_i2c(libxl__gc *gc, uint32_t domid, + libxl_device_i2c *i2c, + flexarray_t *back, flexarray_t *front, + flexarray_t *ro_front) +{ + flexarray_append_pair(back, "irq", GCSPRINTF("%u", i2c->irq)); + flexarray_append_pair(back, "base", GCSPRINTF("%lu", i2c->base)); + + flexarray_append_pair(front, "irq", GCSPRINTF("%u", i2c->irq)); + flexarray_append_pair(front, "base", GCSPRINTF("%lu", i2c->base)); + + return 0; +} + +static int libxl__i2c_from_xenstore(libxl__gc *gc, const char *libxl_path, + libxl_devid devid, + libxl_device_i2c *i2c) +{ + const char *be_path, *fe_path, *tmp; + libxl__device dev; + int rc; + + i2c->devid = devid; + + rc = libxl__xs_read_mandatory(gc, XBT_NULL, + GCSPRINTF("%s/backend", libxl_path), + &be_path); + if (rc) goto out; + + rc = libxl__xs_read_mandatory(gc, XBT_NULL, + GCSPRINTF("%s/frontend", libxl_path), + &fe_path); + if (rc) goto out; + + rc = libxl__backendpath_parse_domid(gc, be_path, &i2c->backend_domid); + if (rc) goto out; + + rc = libxl__parse_backend_path(gc, be_path, &dev); + if (rc) goto out; + + i2c->backend_type = LIBXL_I2C_BACKEND_VIRTIO; + + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/irq", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + i2c->irq = strtoul(tmp, NULL, 0); + } + + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/base", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + i2c->base = strtoul(tmp, NULL, 0); + } + + rc = 0; + +out: + + return rc; +} + +static int libxl__device_from_i2c(libxl__gc *gc, uint32_t domid, + libxl_device_i2c *type, libxl__device *device) +{ + device->backend_devid = type->devid; + device->backend_domid = type->backend_domid; + device->backend_kind = LIBXL__DEVICE_KIND_I2C; + device->devid = type->devid; + device->domid = domid; + device->kind = LIBXL__DEVICE_KIND_I2C; + + return 0; +} + +int libxl_device_i2c_add(libxl_ctx *ctx, uint32_t domid, libxl_device_i2c *i2c, + const libxl_asyncop_how *ao_how) +{ + AO_CREATE(ctx, domid, ao_how); + int rc; + + rc = libxl__device_add(gc, domid, &libxl__i2c_devtype, i2c); + if (rc) { + LOGD(ERROR, domid, "Unable to add i2c device"); + goto out; + } + +out: + libxl__ao_complete(egc, ao, rc); + return AO_INPROGRESS; +} + +int libxl_devid_to_device_i2c(libxl_ctx *ctx, uint32_t domid, + int devid, libxl_device_i2c *i2c) +{ + GC_INIT(ctx); + + libxl_device_i2c *i2cs = NULL; + int n, i; + int rc; + + libxl_device_i2c_init(i2c); + + i2cs = libxl__device_list(gc, &libxl__i2c_devtype, domid, &n); + + if (!i2cs) { rc = ERROR_NOTFOUND; goto out; } + + for (i = 0; i < n; ++i) { + if (devid == i2cs[i].devid) { + libxl_device_i2c_copy(ctx, i2c, &i2cs[i]); + rc = 0; + goto out; + } + } + + rc = ERROR_NOTFOUND; + +out: + + if (i2cs) + libxl__device_list_free(&libxl__i2c_devtype, i2cs, n); + + GC_FREE; + return rc; +} + +int libxl_device_i2c_getinfo(libxl_ctx *ctx, uint32_t domid, + const libxl_device_i2c *i2c, + libxl_i2cinfo *info) +{ + GC_INIT(ctx); + char *libxl_path, *dompath, *devpath; + char *val; + int rc; + + libxl_i2cinfo_init(info); + dompath = libxl__xs_get_dompath(gc, domid); + info->devid = i2c->devid; + + devpath = libxl__domain_device_frontend_path(gc, domid, info->devid, + LIBXL__DEVICE_KIND_I2C); + libxl_path = libxl__domain_device_libxl_path(gc, domid, info->devid, + LIBXL__DEVICE_KIND_I2C); + + info->backend = xs_read(ctx->xsh, XBT_NULL, + GCSPRINTF("%s/backend", libxl_path), + NULL); + if (!info->backend) { rc = ERROR_FAIL; goto out; } + + rc = libxl__backendpath_parse_domid(gc, info->backend, &info->backend_id); + if (rc) goto out; + + val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", devpath)); + info->state = val ? strtoul(val, NULL, 10) : -1; + + info->frontend = xs_read(ctx->xsh, XBT_NULL, + GCSPRINTF("%s/frontend", libxl_path), + NULL); + info->frontend_id = domid; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/"XENKBD_FIELD_EVT_CHANNEL, devpath)); + info->evtch = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/"XENKBD_FIELD_RING_GREF, devpath)); + info->rref = val ? strtoul(val, NULL, 10) : -1; + + rc = 0; + +out: + GC_FREE; + return rc; +} + +static LIBXL_DEFINE_UPDATE_DEVID(i2c) + +#define libxl__add_i2cs NULL +#define libxl_device_i2c_compare NULL + +LIBXL_DEFINE_DEVICE_LIST(i2c) +LIBXL_DEFINE_DEVICE_REMOVE(i2c) + +DEFINE_DEVICE_TYPE_STRUCT(i2c, I2C, i2cs, + .skip_attach = 1, + .dm_needed = libxl__device_i2c_dm_needed, + .set_xenstore_config = (device_set_xenstore_config_fn_t) + libxl__set_xenstore_i2c, + .from_xenstore = (device_from_xenstore_fn_t)libxl__i2c_from_xenstore +); + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index bdef5a605ea9..b4dfbe7e5db1 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -4001,6 +4001,7 @@ static inline int *libxl__device_type_get_num( extern const libxl__device_type libxl__vfb_devtype; extern const libxl__device_type libxl__vkb_devtype; +extern const libxl__device_type libxl__i2c_devtype; extern const libxl__device_type libxl__disk_devtype; extern const libxl__device_type libxl__nic_devtype; extern const libxl__device_type libxl__vtpm_devtype; diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index 2a42da2f7d78..e9454e669224 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -266,6 +266,10 @@ libxl_vkb_backend = Enumeration("vkb_backend", [ (2, "LINUX") ]) +libxl_i2c_backend = Enumeration("i2c_backend", [ + (0, "VIRTIO") + ]) + libxl_passthrough = Enumeration("passthrough", [ (0, "default"), (1, "disabled"), @@ -614,6 +618,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ # - "mouse" for PS/2 protocol relative mouse ("usbdevice", string), ("vkb_device", libxl_defbool), + ("i2c_device", libxl_defbool), ("soundhw", string), ("xen_platform_pci", libxl_defbool), ("usbdevice_list", libxl_string_list), @@ -691,6 +696,15 @@ libxl_device_vkb = Struct("device_vkb", [ ("multi_touch_num_contacts", uint32) ]) +libxl_device_i2c = Struct("device_i2c", [ + ("backend_domid", libxl_domid), + ("backend_domname", string), + ("devid", libxl_devid), + ("backend_type", libxl_i2c_backend), + ("irq", uint32), + ("base", uint64) + ]) + libxl_device_disk = Struct("device_disk", [ ("backend_domid", libxl_domid), ("backend_domname", string), @@ -960,6 +974,7 @@ libxl_domain_config = Struct("domain_config", [ ("dtdevs", Array(libxl_device_dtdev, "num_dtdevs")), ("vfbs", Array(libxl_device_vfb, "num_vfbs")), ("vkbs", Array(libxl_device_vkb, "num_vkbs")), + ("i2cs", Array(libxl_device_i2c, "num_i2cs")), ("vtpms", Array(libxl_device_vtpm, "num_vtpms")), ("p9s", Array(libxl_device_p9, "num_p9s")), ("pvcallsifs", Array(libxl_device_pvcallsif, "num_pvcallsifs")), @@ -1121,6 +1136,17 @@ libxl_vkbinfo = Struct("vkbinfo", [ ("rref", integer) ], dir=DIR_OUT) +libxl_i2cinfo = Struct("i2cinfo", [ + ("backend", string), + ("backend_id", uint32), + ("frontend", string), + ("frontend_id", uint32), + ("devid", libxl_devid), + ("state", integer), + ("evtch", integer), + ("rref", integer) + ], dir=DIR_OUT) + # NUMA node characteristics: size and free are how much memory it has, and how # much of it is free, respectively. dists is an array of distances from this # node to each other node. diff --git a/tools/libs/light/libxl_types_internal.idl b/tools/libs/light/libxl_types_internal.idl index 3593e21dbb64..1b87d1480bf9 100644 --- a/tools/libs/light/libxl_types_internal.idl +++ b/tools/libs/light/libxl_types_internal.idl @@ -32,6 +32,7 @@ libxl__device_kind = Enumeration("device_kind", [ (14, "PVCALLS"), (15, "VSND"), (16, "VINPUT"), + (17, "I2C"), ]) libxl__console_backend = Enumeration("console_backend", [ diff --git a/tools/ocaml/libs/xl/genwrap.py b/tools/ocaml/libs/xl/genwrap.py index 7bf26bdcd831..a9db0b97d80f 100644 --- a/tools/ocaml/libs/xl/genwrap.py +++ b/tools/ocaml/libs/xl/genwrap.py @@ -36,6 +36,7 @@ DEVICE_LIST = [ ("list", ["ctx", "domid", "t list"]), functions = { # ( name , [type1,type2,....] ) "device_vfb": DEVICE_FUNCTIONS, "device_vkb": DEVICE_FUNCTIONS, + "device_i2c": DEVICE_FUNCTIONS, "device_disk": DEVICE_FUNCTIONS + DEVICE_LIST + [ ("insert", ["ctx", "t", "domid", "?async:'a", "unit", "unit"]), ("of_vdev", ["ctx", "domid", "string", "t"]), diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c index 45b8af61c74a..cdf473f4ed57 100644 --- a/tools/ocaml/libs/xl/xenlight_stubs.c +++ b/tools/ocaml/libs/xl/xenlight_stubs.c @@ -707,6 +707,7 @@ DEVICE_ADDREMOVE(disk) DEVICE_ADDREMOVE(nic) DEVICE_ADDREMOVE(vfb) DEVICE_ADDREMOVE(vkb) +DEVICE_ADDREMOVE(i2c) DEVICE_ADDREMOVE(pci) _DEVICE_ADDREMOVE(disk, cdrom, insert) diff --git a/tools/xl/Makefile b/tools/xl/Makefile index b7f439121a3a..06801962f11e 100644 --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -23,7 +23,7 @@ XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o XL_OBJS += xl_sched.o xl_pci.o xl_vcpu.o xl_cdrom.o xl_mem.o XL_OBJS += xl_info.o xl_console.o xl_misc.o XL_OBJS += xl_vmcontrol.o xl_saverestore.o xl_migrate.o -XL_OBJS += xl_vdispl.o xl_vsnd.o xl_vkb.o +XL_OBJS += xl_vdispl.o xl_vsnd.o xl_vkb.o xl_i2c.o $(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog) $(XL_OBJS): CFLAGS += $(CFLAGS_XL) diff --git a/tools/xl/xl.h b/tools/xl/xl.h index c5c4bedbdd5d..210bc1b6d47a 100644 --- a/tools/xl/xl.h +++ b/tools/xl/xl.h @@ -177,6 +177,9 @@ int main_vsnddetach(int argc, char **argv); int main_vkbattach(int argc, char **argv); int main_vkblist(int argc, char **argv); int main_vkbdetach(int argc, char **argv); +int main_i2cattach(int argc, char **argv); +int main_i2clist(int argc, char **argv); +int main_i2cdetach(int argc, char **argv); int main_usbctrl_attach(int argc, char **argv); int main_usbctrl_detach(int argc, char **argv); int main_usbdev_attach(int argc, char **argv); diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c index 661323d4884e..30bd614fc275 100644 --- a/tools/xl/xl_cmdtable.c +++ b/tools/xl/xl_cmdtable.c @@ -406,6 +406,21 @@ const struct cmd_spec cmd_table[] = { "Destroy a domain's virtual keyboard device", " ", }, + { "i2c-attach", + &main_i2cattach, 1, 1, + "Create a new virtual i2c device", + " ...", + }, + { "i2c-list", + &main_i2clist, 0, 0, + "List virtual i2c devices for a domain", + "", + }, + { "i2c-detach", + &main_i2cdetach, 0, 1, + "Destroy a domain's virtual i2c device", + " ", + }, { "vdispl-attach", &main_vdisplattach, 1, 1, "Create a new virtual display device", diff --git a/tools/xl/xl_i2c.c b/tools/xl/xl_i2c.c new file mode 100644 index 000000000000..a916d05604f2 --- /dev/null +++ b/tools/xl/xl_i2c.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2022 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include + +#include +#include +#include + +#include "xl.h" +#include "xl_utils.h" +#include "xl_parse.h" + +int main_i2cattach(int argc, char **argv) +{ + int opt; + int rc; + uint32_t domid; + libxl_device_i2c i2c; + + SWITCH_FOREACH_OPT(opt, "", NULL, "i2c-attach", 2) { + /* No options */ + } + + libxl_device_i2c_init(&i2c); + domid = find_domain(argv[optind++]); + + for (argv += optind, argc -= optind; argc > 0; ++argv, --argc) { + rc = parse_i2c_config(&i2c, *argv); + if (rc) goto out; + } + + if (dryrun_only) { + char *json = libxl_device_i2c_to_json(ctx, &i2c); + printf("i2c: %s\n", json); + free(json); + goto done; + } + + if (libxl_device_i2c_add(ctx, domid, &i2c, 0)) { + fprintf(stderr, "libxl_device_i2c_add failed.\n"); + rc = ERROR_FAIL; goto out; + } + +done: + rc = 0; + +out: + libxl_device_i2c_dispose(&i2c); + return rc; +} + +int main_i2clist(int argc, char **argv) +{ + int opt; + libxl_device_i2c *i2cs; + libxl_i2cinfo i2cinfo; + int nb, i; + + SWITCH_FOREACH_OPT(opt, "", NULL, "i2c-list", 1) { + /* No options */ + } + + /* Idx BE Hdl Sta evch ref ID BE-type BE-path */ + printf("%-3s %-2s %-6s %-5s %-6s %6s %-10s %-10s %-30s\n", + "Idx", "BE", "handle", "state", "evt-ch", "ref", + "ID", "BE-type", "BE-path"); + for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) { + uint32_t domid = find_domain(*argv); + i2cs = libxl_device_i2c_list(ctx, domid, &nb); + if (!i2cs) { + continue; + } + for (i = 0; i < nb; ++i) { + if (libxl_device_i2c_getinfo(ctx, domid, &i2cs[i], &i2cinfo) == 0) { + printf("%-3d %-2d %6d %5d %6d %6d %-10s %-30s\n", + i2cinfo.devid, i2cinfo.backend_id, + i2cinfo.devid, i2cinfo.state, i2cinfo.evtch, + i2cinfo.rref, + libxl_i2c_backend_to_string(i2cs[i].backend_type), + i2cinfo.backend); + libxl_i2cinfo_dispose(&i2cinfo); + } + } + libxl_device_i2c_list_free(i2cs, nb); + } + return 0; +} + +int main_i2cdetach(int argc, char **argv) +{ + uint32_t domid, devid; + int opt, rc; + libxl_device_i2c i2c; + + SWITCH_FOREACH_OPT(opt, "", NULL, "i2c-detach", 2) { + /* No options */ + } + + domid = find_domain(argv[optind++]); + devid = atoi(argv[optind++]); + + libxl_device_i2c_init(&i2c); + + if (libxl_devid_to_device_i2c(ctx, domid, devid, &i2c)) { + fprintf(stderr, "Error: Device %d not connected.\n", devid); + rc = ERROR_FAIL; + goto out; + } + + rc = libxl_device_i2c_remove(ctx, domid, &i2c, 0); + if (rc) { + fprintf(stderr, "libxl_device_i2c_remove failed.\n"); + rc = ERROR_FAIL; + goto out; + } + + rc = 0; + +out: + libxl_device_i2c_dispose(&i2c); + return rc; +} + + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index b98c0de378b6..95483e551c38 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1204,6 +1204,74 @@ static void parse_vkb_list(const XLU_Config *config, if (rc) exit(EXIT_FAILURE); } +int parse_i2c_config(libxl_device_i2c *i2c, char *token) +{ + char *oparg; + + if (MATCH_OPTION("backend", token, oparg)) { + i2c->backend_domname = strdup(oparg); + } else if (MATCH_OPTION("backend-type", token, oparg)) { + libxl_i2c_backend backend_type; + if (libxl_i2c_backend_from_string(oparg, &backend_type)) { + fprintf(stderr, "Unknown backend_type \"%s\" in i2c spec\n", + oparg); + return -1; + } + i2c->backend_type = backend_type; + } else if (MATCH_OPTION("irq", token, oparg)) { + i2c->irq = strtoul(oparg, NULL, 0); + } else if (MATCH_OPTION("base", token, oparg)) { + i2c->base = strtoul(oparg, NULL, 0); + } else { + fprintf(stderr, "Unknown string \"%s\" in i2c spec\n", token); + return -1; + } + + return 0; +} + +static void parse_i2c_list(const XLU_Config *config, + libxl_domain_config *d_config) +{ + XLU_ConfigList *i2cs; + const char *item; + char *buf = NULL; + int rc; + + if (!xlu_cfg_get_list (config, "i2c", &i2cs, 0, 0)) { + int entry = 0; + while ((item = xlu_cfg_get_listitem(i2cs, entry)) != NULL) { + libxl_device_i2c *i2c; + char *p; + + i2c = ARRAY_EXTEND_INIT(d_config->i2cs, + d_config->num_i2cs, + libxl_device_i2c_init); + + buf = strdup(item); + + p = strtok (buf, ","); + while (p != NULL) + { + while (*p == ' ') p++; + + rc = parse_i2c_config(i2c, p); + if (rc) goto out; + + p = strtok (NULL, ","); + } + + entry++; + } + } + + rc = 0; + +out: + free(buf); + if (rc) exit(EXIT_FAILURE); +} + void parse_config_data(const char *config_source, const char *config_data, int config_len, @@ -2305,13 +2373,16 @@ void parse_config_data(const char *config_source, d_config->num_vfbs = 0; d_config->num_vkbs = 0; + d_config->num_i2cs = 0; d_config->vfbs = NULL; d_config->vkbs = NULL; + d_config->i2cs = NULL; if (!xlu_cfg_get_list (config, "vfb", &cvfbs, 0, 0)) { while ((buf = xlu_cfg_get_listitem (cvfbs, d_config->num_vfbs)) != NULL) { libxl_device_vfb *vfb; libxl_device_vkb *vkb; + libxl_device_i2c *i2c; char *buf2 = strdup(buf); char *p, *p2; @@ -2322,6 +2393,9 @@ void parse_config_data(const char *config_source, vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs, libxl_device_vkb_init); + i2c = ARRAY_EXTEND_INIT(d_config->i2cs, d_config->num_i2cs, + libxl_device_i2c_init); + p = strtok(buf2, ","); if (!p) goto skip_vfb; @@ -2579,6 +2653,7 @@ void parse_config_data(const char *config_source, if (vnc_enabled) { libxl_device_vfb *vfb; libxl_device_vkb *vkb; + libxl_device_i2c *i2c; vfb = ARRAY_EXTEND_INIT(d_config->vfbs, d_config->num_vfbs, libxl_device_vfb_init); @@ -2586,6 +2661,9 @@ void parse_config_data(const char *config_source, vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs, libxl_device_vkb_init); + i2c = ARRAY_EXTEND_INIT(d_config->i2cs, d_config->num_i2cs, + libxl_device_i2c_init); + parse_top_level_vnc_options(config, &vfb->vnc); parse_top_level_sdl_options(config, &vfb->sdl); xlu_cfg_replace_string (config, "keymap", &vfb->keymap, 0); @@ -2700,6 +2778,7 @@ void parse_config_data(const char *config_source, exit(-ERROR_FAIL); } xlu_cfg_get_defbool(config, "vkb_device", &b_info->u.hvm.vkb_device, 0); + xlu_cfg_get_defbool(config, "i2c_device", &b_info->u.hvm.i2c_device, 0); xlu_cfg_replace_string (config, "soundhw", &b_info->u.hvm.soundhw, 0); xlu_cfg_get_defbool(config, "xen_platform_pci", &b_info->u.hvm.xen_platform_pci, 0); @@ -2748,6 +2827,7 @@ void parse_config_data(const char *config_source, } parse_vkb_list(config, d_config); + parse_i2c_list(config, d_config); xlu_cfg_get_defbool(config, "xend_suspend_evtchn_compat", &c_info->xend_suspend_evtchn_compat, 0); diff --git a/tools/xl/xl_parse.h b/tools/xl/xl_parse.h index bab2861f8c3e..4b972d525199 100644 --- a/tools/xl/xl_parse.h +++ b/tools/xl/xl_parse.h @@ -36,6 +36,7 @@ int parse_nic_config(libxl_device_nic *nic, XLU_Config **config, char *token); int parse_vdispl_config(libxl_device_vdispl *vdispl, char *token); int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec); int parse_vkb_config(libxl_device_vkb *vkb, char *token); +int parse_i2c_config(libxl_device_i2c *i2c, char *token); int match_option_size(const char *prefix, size_t len, char *arg, char **argopt); diff --git a/tools/xl/xl_sxp.c b/tools/xl/xl_sxp.c index 359a0015709e..a44c765aa515 100644 --- a/tools/xl/xl_sxp.c +++ b/tools/xl/xl_sxp.c @@ -140,6 +140,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh) fprintf(fh, "\t\t\t(usbdevice %s)\n", b_info->u.hvm.usbdevice); fprintf(fh, "\t\t\t(vkb_device %s)\n", libxl_defbool_to_string(b_info->u.hvm.vkb_device)); + fprintf(fh, "\t\t\t(i2c_device %s)\n", + libxl_defbool_to_string(b_info->u.hvm.i2c_device)); fprintf(fh, "\t\t)\n"); break; case LIBXL_DOMAIN_TYPE_PV: From patchwork Tue May 10 06:04:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12844571 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 269DBC433FE for ; Tue, 10 May 2022 06:05:31 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.325178.547648 (Exim 4.92) (envelope-from ) id 1noIzf-0008LN-Qk; Tue, 10 May 2022 06:05:11 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 325178.547648; Tue, 10 May 2022 06:05:11 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzf-0008LG-M0; Tue, 10 May 2022 06:05:11 +0000 Received: by outflank-mailman (input) for mailman id 325178; Tue, 10 May 2022 06:05:10 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzd-0007ob-TE for xen-devel@lists.xen.org; Tue, 10 May 2022 06:05:10 +0000 Received: from mail-pg1-x52b.google.com (mail-pg1-x52b.google.com [2607:f8b0:4864:20::52b]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 23aae201-d027-11ec-a406-831a346695d4; Tue, 10 May 2022 08:05:07 +0200 (CEST) Received: by mail-pg1-x52b.google.com with SMTP id s16so3726784pgs.3 for ; Mon, 09 May 2022 23:05:07 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id u67-20020a626046000000b0050dc762814esm9751334pfb.40.2022.05.09.23.05.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 May 2022 23:05:05 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 23aae201-d027-11ec-a406-831a346695d4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HyzuOp/tvITGfFX9GJge8V/26LSsI0eF8GbficmNu7U=; b=M67x4/R6jdy471wEvDx2Ve38kbtBlyYrBJXglB/TFrMRgV1dBgfFZK8iIqQ2Ket3VS o67j+LHFwD4JxoM/NhqQPry9PFxr/pl/XwgRMbtjL9Nrf+Vw+B5M0cD6ci0s4AIzivSW yfVNhsjgLuC0EQEO/jiBjc+2WTTyyOzDrPt2HlsYie06sDeQ2Sep8PIrpw8vg/dqokJv FPbfmcUcqOsI/N7aYBrgLoZZxMMwSwpDAMON4qftJbqCheNLaO52rp+n2JbyMNc/e/vd tP61jErQOkjzzzaQhtbfyPWKkYKihCuPZIKM6KJiQwztqUKRK65kXFOVw+Wy/VDJ3G/S pxBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HyzuOp/tvITGfFX9GJge8V/26LSsI0eF8GbficmNu7U=; b=cjDOYvihfifQCsuXZtg8Ux1nBAQYqSJVna0qhV4SjKQcWt5Whc/LyVTpiG0KEsTuH2 NfVQwIF3ip8r1qsj/feexYokyoxZkMmoynFzoe8kc3vhePa4NlJfxI9bkGjucQMN2XgU Tagp2+YZqJi/VPpjeLaXSdf1yu6iQmA7KKFxr0GHznbmG51wISR+s9QZCgTBqRA9cfZS 32QT3dYzkOnG7dVL/ClFfEPG7Pnr4+yopcJkworfIqrVmMPt/djV6Dt56lZ4QlNRDVsT No8RSVbeWD1sQSqOWC/0BBjQBpQBzhsgyX8WkYNmhWYSQMcriuJPJWmicqzMV1/okTXf nzhg== X-Gm-Message-State: AOAM533YI6yLlidOK+8AOqMP2wXM4gmgF37pUdBz2lxskLFag/aiSHzl aJN0U6iM0ueeE8c3tcCYI6uG43zcufE25Q== X-Google-Smtp-Source: ABdhPJyNA//hYlvOjkaQBC1aLhOM4ZNdmASuAYyWnwX7TpT86LK5x4woDWmunCqOZS2h/Fm76aQWUQ== X-Received: by 2002:a63:e155:0:b0:3c6:7514:6c0d with SMTP id h21-20020a63e155000000b003c675146c0dmr11777055pgk.249.1652162705486; Mon, 09 May 2022 23:05:05 -0700 (PDT) From: Viresh Kumar To: xen-devel@lists.xen.org Cc: Viresh Kumar , Vincent Guittot , stratos-dev@op-lists.linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Stabellini , Mathieu Poirier , Mike Holmes , Oleksandr Tyshchenko , Wei Liu , Juergen Gross , Julien Grall Subject: [PATCH V2 2/6] libxl: Add support for Virtio GPIO device Date: Tue, 10 May 2022 11:34:47 +0530 Message-Id: <48d5e96ab0f1c1e85f77144e31ca199e04c00e9b.1652162646.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 This patch adds basic support for configuring and assisting virtio-mmio based virtio-gpio backend (emualator) which is intended to run out of Qemu and could be run in any domain. An example of domain configuration for Virtio Gpio: gpio = [ "" ] Please note, this patch is not enough for virtio-gpio to work on Xen (Arm), as for every Virtio device we need to allocate Virtio MMIO params (IRQ and memory region) and pass them to the backend, also update Guest device-tree. A subsequent patch will add these missing bits. For the current patch, the default "irq" and "base" are just written to the Xenstore. Signed-off-by: Viresh Kumar --- tools/golang/xenlight/helpers.gen.go | 110 ++++++++++ tools/golang/xenlight/types.gen.go | 27 +++ tools/include/libxl.h | 32 +++ tools/include/libxl_utils.h | 3 + tools/libs/light/Makefile | 1 + tools/libs/light/libxl_create.c | 13 ++ tools/libs/light/libxl_dm.c | 17 +- tools/libs/light/libxl_gpio.c | 236 ++++++++++++++++++++++ tools/libs/light/libxl_internal.h | 1 + tools/libs/light/libxl_types.idl | 26 +++ tools/libs/light/libxl_types_internal.idl | 1 + tools/ocaml/libs/xl/genwrap.py | 1 + tools/ocaml/libs/xl/xenlight_stubs.c | 1 + tools/xl/Makefile | 2 +- tools/xl/xl.h | 3 + tools/xl/xl_cmdtable.c | 15 ++ tools/xl/xl_gpio.c | 143 +++++++++++++ tools/xl/xl_parse.c | 80 ++++++++ tools/xl/xl_parse.h | 1 + tools/xl/xl_sxp.c | 2 + 20 files changed, 713 insertions(+), 2 deletions(-) create mode 100644 tools/libs/light/libxl_gpio.c create mode 100644 tools/xl/xl_gpio.c diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go index ad23b0969abd..ed880cad3fa7 100644 --- a/tools/golang/xenlight/helpers.gen.go +++ b/tools/golang/xenlight/helpers.gen.go @@ -1215,6 +1215,9 @@ x.Usbdevice = C.GoString(tmp.usbdevice) if err := x.VkbDevice.fromC(&tmp.vkb_device);err != nil { return fmt.Errorf("converting field VkbDevice: %v", err) } +if err := x.GpioDevice.fromC(&tmp.gpio_device);err != nil { +return fmt.Errorf("converting field GpioDevice: %v", err) +} if err := x.I2cDevice.fromC(&tmp.i2c_device);err != nil { return fmt.Errorf("converting field I2cDevice: %v", err) } @@ -1535,6 +1538,9 @@ hvm.usbdevice = C.CString(tmp.Usbdevice)} if err := tmp.VkbDevice.toC(&hvm.vkb_device); err != nil { return fmt.Errorf("converting field VkbDevice: %v", err) } +if err := tmp.GpioDevice.toC(&hvm.gpio_device); err != nil { +return fmt.Errorf("converting field GpioDevice: %v", err) +} if err := tmp.I2cDevice.toC(&hvm.i2c_device); err != nil { return fmt.Errorf("converting field I2cDevice: %v", err) } @@ -1728,6 +1734,46 @@ xc.multi_touch_num_contacts = C.uint32_t(x.MultiTouchNumContacts) return nil } +// NewDeviceGpio returns an instance of DeviceGpio initialized with defaults. +func NewDeviceGpio() (*DeviceGpio, error) { +var ( +x DeviceGpio +xc C.libxl_device_gpio) + +C.libxl_device_gpio_init(&xc) +defer C.libxl_device_gpio_dispose(&xc) + +if err := x.fromC(&xc); err != nil { +return nil, err } + +return &x, nil} + +func (x *DeviceGpio) fromC(xc *C.libxl_device_gpio) error { + x.BackendDomid = Domid(xc.backend_domid) +x.BackendDomname = C.GoString(xc.backend_domname) +x.Devid = Devid(xc.devid) +x.BackendType = GpioBackend(xc.backend_type) +x.Irq = uint32(xc.irq) +x.Base = uint64(xc.base) + + return nil} + +func (x *DeviceGpio) toC(xc *C.libxl_device_gpio) (err error){defer func(){ +if err != nil{ +C.libxl_device_gpio_dispose(xc)} +}() + +xc.backend_domid = C.libxl_domid(x.BackendDomid) +if x.BackendDomname != "" { +xc.backend_domname = C.CString(x.BackendDomname)} +xc.devid = C.libxl_devid(x.Devid) +xc.backend_type = C.libxl_gpio_backend(x.BackendType) +xc.irq = C.uint32_t(x.Irq) +xc.base = C.uint64_t(x.Base) + + return nil + } + // NewDeviceI2c returns an instance of DeviceI2c initialized with defaults. func NewDeviceI2c() (*DeviceI2c, error) { var ( @@ -2881,6 +2927,15 @@ if err := x.Vkbs[i].fromC(&v); err != nil { return fmt.Errorf("converting field Vkbs: %v", err) } } } +x.Gpios = nil +if n := int(xc.num_gpios); n > 0 { +cGpios := (*[1<<28]C.libxl_device_gpio)(unsafe.Pointer(xc.gpios))[:n:n] +x.Gpios = make([]DeviceGpio, n) +for i, v := range cGpios { +if err := x.Gpios[i].fromC(&v); err != nil { +return fmt.Errorf("converting field Gpios: %v", err) } +} +} x.I2cs = nil if n := int(xc.num_i2cs); n > 0 { cI2cs := (*[1<<28]C.libxl_device_i2c)(unsafe.Pointer(xc.i2cs))[:n:n] @@ -3051,6 +3106,16 @@ return fmt.Errorf("converting field Vkbs: %v", err) } } } +if numGpios := len(x.Gpios); numGpios > 0 { +xc.gpios = (*C.libxl_device_gpio)(C.malloc(C.ulong(numGpios)*C.sizeof_libxl_device_gpio)) +xc.num_gpios = C.int(numGpios) +cGpios := (*[1<<28]C.libxl_device_gpio)(unsafe.Pointer(xc.gpios))[:numGpios:numGpios] +for i,v := range x.Gpios { +if err := v.toC(&cGpios[i]); err != nil { +return fmt.Errorf("converting field Gpios: %v", err) +} +} +} if numI2cs := len(x.I2cs); numI2cs > 0 { xc.i2cs = (*C.libxl_device_i2c)(C.malloc(C.ulong(numI2cs)*C.sizeof_libxl_device_i2c)) xc.num_i2cs = C.int(numI2cs) @@ -3748,6 +3813,51 @@ if err != nil{ C.libxl_vkbinfo_dispose(xc)} }() +if x.Backend != "" { +xc.backend = C.CString(x.Backend)} +xc.backend_id = C.uint32_t(x.BackendId) +if x.Frontend != "" { +xc.frontend = C.CString(x.Frontend)} +xc.frontend_id = C.uint32_t(x.FrontendId) +xc.devid = C.libxl_devid(x.Devid) +xc.state = C.int(x.State) +xc.evtch = C.int(x.Evtch) +xc.rref = C.int(x.Rref) + + return nil + } + +// NewGpioinfo returns an instance of Gpioinfo initialized with defaults. +func NewGpioinfo() (*Gpioinfo, error) { +var ( +x Gpioinfo +xc C.libxl_gpioinfo) + +C.libxl_gpioinfo_init(&xc) +defer C.libxl_gpioinfo_dispose(&xc) + +if err := x.fromC(&xc); err != nil { +return nil, err } + +return &x, nil} + +func (x *Gpioinfo) fromC(xc *C.libxl_gpioinfo) error { + x.Backend = C.GoString(xc.backend) +x.BackendId = uint32(xc.backend_id) +x.Frontend = C.GoString(xc.frontend) +x.FrontendId = uint32(xc.frontend_id) +x.Devid = Devid(xc.devid) +x.State = int(xc.state) +x.Evtch = int(xc.evtch) +x.Rref = int(xc.rref) + + return nil} + +func (x *Gpioinfo) toC(xc *C.libxl_gpioinfo) (err error){defer func(){ +if err != nil{ +C.libxl_gpioinfo_dispose(xc)} +}() + if x.Backend != "" { xc.backend = C.CString(x.Backend)} xc.backend_id = C.uint32_t(x.BackendId) diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go index c232e4811ac3..cb959d5fa87a 100644 --- a/tools/golang/xenlight/types.gen.go +++ b/tools/golang/xenlight/types.gen.go @@ -241,6 +241,11 @@ VkbBackendQemu VkbBackend = 1 VkbBackendLinux VkbBackend = 2 ) +type GpioBackend int +const( +GpioBackendVirtio GpioBackend = 0 +) + type I2cBackend int const( I2cBackendVirtio I2cBackend = 0 @@ -573,6 +578,7 @@ Usb Defbool Usbversion int Usbdevice string VkbDevice Defbool +GpioDevice Defbool I2cDevice Defbool Soundhw string XenPlatformPci Defbool @@ -636,6 +642,15 @@ MultiTouchHeight uint32 MultiTouchNumContacts uint32 } +type DeviceGpio struct { +BackendDomid Domid +BackendDomname string +Devid Devid +BackendType GpioBackend +Irq uint32 +Base uint64 +} + type DeviceI2c struct { BackendDomid Domid BackendDomname string @@ -928,6 +943,7 @@ Rdms []DeviceRdm Dtdevs []DeviceDtdev Vfbs []DeviceVfb Vkbs []DeviceVkb +Gpios []DeviceGpio I2cs []DeviceI2c Vtpms []DeviceVtpm P9S []DeviceP9 @@ -1083,6 +1099,17 @@ Evtch int Rref int } +type Gpioinfo struct { +Backend string +BackendId uint32 +Frontend string +FrontendId uint32 +Devid Devid +State int +Evtch int +Rref int +} + type I2cinfo struct { Backend string BackendId uint32 diff --git a/tools/include/libxl.h b/tools/include/libxl.h index 4d19194c3dc2..f2fe616dee18 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -800,6 +800,15 @@ typedef struct libxl__ctx libxl_ctx; */ #define LIBXL_HAVE_BUILDINFO_VKB_DEVICE 1 +/* + * LIBXL_HAVE_BUILDINFO_GPIO_DEVICE + * + * If this is defined, then the libxl_domain_build_info structure will + * contain a boolean hvm.gpio_device which instructs libxl whether to include + * a gpio at build time or not. + */ +#define LIBXL_HAVE_BUILDINFO_GPIO_DEVICE 1 + /* * LIBXL_HAVE_BUILDINFO_I2C_DEVICE * @@ -2377,6 +2386,29 @@ int libxl_device_vkb_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_vkbinfo *vkbinfo) LIBXL_EXTERNAL_CALLERS_ONLY; +/* GPIO */ +int libxl_device_gpio_add(libxl_ctx *ctx, uint32_t domid, libxl_device_gpio *gpio, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_gpio_remove(libxl_ctx *ctx, uint32_t domid, + libxl_device_gpio *gpio, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_gpio_destroy(libxl_ctx *ctx, uint32_t domid, + libxl_device_gpio *gpio, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +libxl_device_gpio *libxl_device_gpio_list(libxl_ctx *ctx, + uint32_t domid, int *num) + LIBXL_EXTERNAL_CALLERS_ONLY; +void libxl_device_gpio_list_free(libxl_device_gpio* list, int num) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_gpio_getinfo(libxl_ctx *ctx, uint32_t domid, + const libxl_device_gpio *gpio, + libxl_gpioinfo *gpioinfo) + LIBXL_EXTERNAL_CALLERS_ONLY; + /* I2C */ int libxl_device_i2c_add(libxl_ctx *ctx, uint32_t domid, libxl_device_i2c *i2c, const libxl_asyncop_how *ao_how) diff --git a/tools/include/libxl_utils.h b/tools/include/libxl_utils.h index 72b7796b7e4b..91f5c68172cb 100644 --- a/tools/include/libxl_utils.h +++ b/tools/include/libxl_utils.h @@ -83,6 +83,9 @@ int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t domid, int libxl_devid_to_device_vkb(libxl_ctx *ctx, uint32_t domid, int devid, libxl_device_vkb *vkb); +int libxl_devid_to_device_gpio(libxl_ctx *ctx, uint32_t domid, + int devid, libxl_device_gpio *gpio); + int libxl_devid_to_device_i2c(libxl_ctx *ctx, uint32_t domid, int devid, libxl_device_i2c *i2c); diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile index dca46846e586..6caa15cc1148 100644 --- a/tools/libs/light/Makefile +++ b/tools/libs/light/Makefile @@ -112,6 +112,7 @@ SRCS-y += libxl_vdispl.c SRCS-y += libxl_pvcalls.c SRCS-y += libxl_vsnd.c SRCS-y += libxl_vkb.c +SRCS-y += libxl_gpio.c SRCS-y += libxl_i2c.c SRCS-y += libxl_genid.c SRCS-y += _libxl_types.c diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c index d604171e504c..836d43bd3f03 100644 --- a/tools/libs/light/libxl_create.c +++ b/tools/libs/light/libxl_create.c @@ -363,6 +363,7 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc, libxl_defbool_setdefault(&b_info->u.hvm.altp2m, false); libxl_defbool_setdefault(&b_info->u.hvm.usb, false); libxl_defbool_setdefault(&b_info->u.hvm.vkb_device, true); + libxl_defbool_setdefault(&b_info->u.hvm.gpio_device, true); libxl_defbool_setdefault(&b_info->u.hvm.i2c_device, true); libxl_defbool_setdefault(&b_info->u.hvm.xen_platform_pci, true); @@ -1756,6 +1757,7 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, libxl__device_console console; libxl__device device; libxl_device_vkb vkb; + libxl_device_gpio gpio; libxl_device_i2c i2c; init_console_info(gc, &console, 0); @@ -1769,6 +1771,12 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, libxl_device_vkb_dispose(&vkb); } + if (libxl_defbool_val(d_config->b_info.u.hvm.gpio_device)) { + libxl_device_gpio_init(&gpio); + libxl__device_add(gc, domid, &libxl__gpio_devtype, &gpio); + libxl_device_gpio_dispose(&gpio); + } + if (libxl_defbool_val(d_config->b_info.u.hvm.i2c_device)) { libxl_device_i2c_init(&i2c); libxl__device_add(gc, domid, &libxl__i2c_devtype, &i2c); @@ -1807,6 +1815,11 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, &d_config->vkbs[i]); } + for (i = 0; i < d_config->num_gpios; i++) { + libxl__device_add(gc, domid, &libxl__gpio_devtype, + &d_config->gpios[i]); + } + for (i = 0; i < d_config->num_i2cs; i++) { libxl__device_add(gc, domid, &libxl__i2c_devtype, &d_config->i2cs[i]); diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c index 9340ae4628a2..124b73f1dd00 100644 --- a/tools/libs/light/libxl_dm.c +++ b/tools/libs/light/libxl_dm.c @@ -2096,6 +2096,7 @@ static int libxl__vfb_and_vkb_from_hvm_guest_config(libxl__gc *gc, const libxl_domain_config *guest_config, libxl_device_vfb *vfb, libxl_device_vkb *vkb, + libxl_device_gpio *gpio, libxl_device_i2c *i2c) { const libxl_domain_build_info *b_info = &guest_config->b_info; @@ -2105,6 +2106,7 @@ static int libxl__vfb_and_vkb_from_hvm_guest_config(libxl__gc *gc, libxl_device_vfb_init(vfb); libxl_device_vkb_init(vkb); + libxl_device_gpio_init(gpio); libxl_device_i2c_init(i2c); vfb->backend_domid = 0; @@ -2116,6 +2118,9 @@ static int libxl__vfb_and_vkb_from_hvm_guest_config(libxl__gc *gc, vkb->backend_domid = 0; vkb->devid = 0; + gpio->backend_domid = 0; + gpio->devid = 0; + i2c->backend_domid = 0; i2c->devid = 0; @@ -2281,6 +2286,7 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss) int ret; libxl_device_vfb *vfb; libxl_device_vkb *vkb; + libxl_device_gpio *gpio; libxl_device_i2c *i2c; char **args; struct xs_permissions perm[2]; @@ -2354,12 +2360,15 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss) || libxl_defbool_val(guest_config->b_info.u.hvm.sdl.enable)) { GCNEW(vfb); GCNEW(vkb); + GCNEW(gpio); GCNEW(i2c); - libxl__vfb_and_vkb_from_hvm_guest_config(gc, guest_config, vfb, vkb, i2c); + libxl__vfb_and_vkb_from_hvm_guest_config(gc, guest_config, vfb, vkb, gpio, i2c); dm_config->vfbs = vfb; dm_config->num_vfbs = 1; dm_config->vkbs = vkb; dm_config->num_vkbs = 1; + dm_config->gpios = gpio; + dm_config->num_gpios = 1; dm_config->i2cs = i2c; dm_config->num_i2cs = 1; } @@ -2503,6 +2512,12 @@ static void spawn_stub_launch_dm(libxl__egc *egc, if (ret) goto out; } + if (dm_config->num_gpios) { + ret = libxl__device_add(gc, dm_domid, &libxl__gpio_devtype, + &dm_config->gpios[0]); + if (ret) goto out; + } + if (dm_config->num_i2cs) { ret = libxl__device_add(gc, dm_domid, &libxl__i2c_devtype, &dm_config->i2cs[0]); diff --git a/tools/libs/light/libxl_gpio.c b/tools/libs/light/libxl_gpio.c new file mode 100644 index 000000000000..2bf68deb3850 --- /dev/null +++ b/tools/libs/light/libxl_gpio.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2022 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_internal.h" + +#include + +static int libxl__device_gpio_setdefault(libxl__gc *gc, uint32_t domid, + libxl_device_gpio *gpio, bool hotplug) +{ + if (gpio->backend_type != LIBXL_GPIO_BACKEND_VIRTIO) { + gpio->backend_type = LIBXL_GPIO_BACKEND_VIRTIO; + } + + return libxl__resolve_domid(gc, gpio->backend_domname, &gpio->backend_domid); +} + +static int libxl__device_gpio_dm_needed(void *e, uint32_t domid) +{ + libxl_device_gpio *elem = e; + + return elem->backend_type == LIBXL_GPIO_BACKEND_VIRTIO; +} + +static int libxl__set_xenstore_gpio(libxl__gc *gc, uint32_t domid, + libxl_device_gpio *gpio, + flexarray_t *back, flexarray_t *front, + flexarray_t *ro_front) +{ + flexarray_append_pair(back, "irq", GCSPRINTF("%u", gpio->irq)); + flexarray_append_pair(back, "base", GCSPRINTF("%lu", gpio->base)); + + flexarray_append_pair(front, "irq", GCSPRINTF("%u", gpio->irq)); + flexarray_append_pair(front, "base", GCSPRINTF("%lu", gpio->base)); + + return 0; +} + +static int libxl__gpio_from_xenstore(libxl__gc *gc, const char *libxl_path, + libxl_devid devid, + libxl_device_gpio *gpio) +{ + const char *be_path, *fe_path, *tmp; + libxl__device dev; + int rc; + + gpio->devid = devid; + + rc = libxl__xs_read_mandatory(gc, XBT_NULL, + GCSPRINTF("%s/backend", libxl_path), + &be_path); + if (rc) goto out; + + rc = libxl__xs_read_mandatory(gc, XBT_NULL, + GCSPRINTF("%s/frontend", libxl_path), + &fe_path); + if (rc) goto out; + + rc = libxl__backendpath_parse_domid(gc, be_path, &gpio->backend_domid); + if (rc) goto out; + + rc = libxl__parse_backend_path(gc, be_path, &dev); + if (rc) goto out; + + gpio->backend_type = LIBXL_GPIO_BACKEND_VIRTIO; + + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/irq", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + gpio->irq = strtoul(tmp, NULL, 0); + } + + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/base", be_path), &tmp); + if (rc) goto out; + + if (tmp) { + gpio->base = strtoul(tmp, NULL, 0); + } + + rc = 0; + +out: + + return rc; +} + +static int libxl__device_from_gpio(libxl__gc *gc, uint32_t domid, + libxl_device_gpio *type, libxl__device *device) +{ + device->backend_devid = type->devid; + device->backend_domid = type->backend_domid; + device->backend_kind = LIBXL__DEVICE_KIND_GPIO; + device->devid = type->devid; + device->domid = domid; + device->kind = LIBXL__DEVICE_KIND_GPIO; + + return 0; +} + +int libxl_device_gpio_add(libxl_ctx *ctx, uint32_t domid, libxl_device_gpio *gpio, + const libxl_asyncop_how *ao_how) +{ + AO_CREATE(ctx, domid, ao_how); + int rc; + + rc = libxl__device_add(gc, domid, &libxl__gpio_devtype, gpio); + if (rc) { + LOGD(ERROR, domid, "Unable to add gpio device"); + goto out; + } + +out: + libxl__ao_complete(egc, ao, rc); + return AO_INPROGRESS; +} + +int libxl_devid_to_device_gpio(libxl_ctx *ctx, uint32_t domid, + int devid, libxl_device_gpio *gpio) +{ + GC_INIT(ctx); + + libxl_device_gpio *gpios = NULL; + int n, i; + int rc; + + libxl_device_gpio_init(gpio); + + gpios = libxl__device_list(gc, &libxl__gpio_devtype, domid, &n); + + if (!gpios) { rc = ERROR_NOTFOUND; goto out; } + + for (i = 0; i < n; ++i) { + if (devid == gpios[i].devid) { + libxl_device_gpio_copy(ctx, gpio, &gpios[i]); + rc = 0; + goto out; + } + } + + rc = ERROR_NOTFOUND; + +out: + + if (gpios) + libxl__device_list_free(&libxl__gpio_devtype, gpios, n); + + GC_FREE; + return rc; +} + +int libxl_device_gpio_getinfo(libxl_ctx *ctx, uint32_t domid, + const libxl_device_gpio *gpio, + libxl_gpioinfo *info) +{ + GC_INIT(ctx); + char *libxl_path, *dompath, *devpath; + char *val; + int rc; + + libxl_gpioinfo_init(info); + dompath = libxl__xs_get_dompath(gc, domid); + info->devid = gpio->devid; + + devpath = libxl__domain_device_frontend_path(gc, domid, info->devid, + LIBXL__DEVICE_KIND_GPIO); + libxl_path = libxl__domain_device_libxl_path(gc, domid, info->devid, + LIBXL__DEVICE_KIND_GPIO); + + info->backend = xs_read(ctx->xsh, XBT_NULL, + GCSPRINTF("%s/backend", libxl_path), + NULL); + if (!info->backend) { rc = ERROR_FAIL; goto out; } + + rc = libxl__backendpath_parse_domid(gc, info->backend, &info->backend_id); + if (rc) goto out; + + val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", devpath)); + info->state = val ? strtoul(val, NULL, 10) : -1; + + info->frontend = xs_read(ctx->xsh, XBT_NULL, + GCSPRINTF("%s/frontend", libxl_path), + NULL); + info->frontend_id = domid; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/"XENKBD_FIELD_EVT_CHANNEL, devpath)); + info->evtch = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/"XENKBD_FIELD_RING_GREF, devpath)); + info->rref = val ? strtoul(val, NULL, 10) : -1; + + rc = 0; + +out: + GC_FREE; + return rc; +} + +static LIBXL_DEFINE_UPDATE_DEVID(gpio) + +#define libxl__add_gpios NULL +#define libxl_device_gpio_compare NULL + +LIBXL_DEFINE_DEVICE_LIST(gpio) +LIBXL_DEFINE_DEVICE_REMOVE(gpio) + +DEFINE_DEVICE_TYPE_STRUCT(gpio, GPIO, gpios, + .skip_attach = 1, + .dm_needed = libxl__device_gpio_dm_needed, + .set_xenstore_config = (device_set_xenstore_config_fn_t) + libxl__set_xenstore_gpio, + .from_xenstore = (device_from_xenstore_fn_t)libxl__gpio_from_xenstore +); + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index b4dfbe7e5db1..7bbd9601ea7c 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -4001,6 +4001,7 @@ static inline int *libxl__device_type_get_num( extern const libxl__device_type libxl__vfb_devtype; extern const libxl__device_type libxl__vkb_devtype; +extern const libxl__device_type libxl__gpio_devtype; extern const libxl__device_type libxl__i2c_devtype; extern const libxl__device_type libxl__disk_devtype; extern const libxl__device_type libxl__nic_devtype; diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index e9454e669224..b5a5cb99c2b4 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -266,6 +266,10 @@ libxl_vkb_backend = Enumeration("vkb_backend", [ (2, "LINUX") ]) +libxl_gpio_backend = Enumeration("gpio_backend", [ + (0, "VIRTIO") + ]) + libxl_i2c_backend = Enumeration("i2c_backend", [ (0, "VIRTIO") ]) @@ -618,6 +622,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ # - "mouse" for PS/2 protocol relative mouse ("usbdevice", string), ("vkb_device", libxl_defbool), + ("gpio_device", libxl_defbool), ("i2c_device", libxl_defbool), ("soundhw", string), ("xen_platform_pci", libxl_defbool), @@ -696,6 +701,15 @@ libxl_device_vkb = Struct("device_vkb", [ ("multi_touch_num_contacts", uint32) ]) +libxl_device_gpio = Struct("device_gpio", [ + ("backend_domid", libxl_domid), + ("backend_domname", string), + ("devid", libxl_devid), + ("backend_type", libxl_gpio_backend), + ("irq", uint32), + ("base", uint64) + ]) + libxl_device_i2c = Struct("device_i2c", [ ("backend_domid", libxl_domid), ("backend_domname", string), @@ -974,6 +988,7 @@ libxl_domain_config = Struct("domain_config", [ ("dtdevs", Array(libxl_device_dtdev, "num_dtdevs")), ("vfbs", Array(libxl_device_vfb, "num_vfbs")), ("vkbs", Array(libxl_device_vkb, "num_vkbs")), + ("gpios", Array(libxl_device_gpio, "num_gpios")), ("i2cs", Array(libxl_device_i2c, "num_i2cs")), ("vtpms", Array(libxl_device_vtpm, "num_vtpms")), ("p9s", Array(libxl_device_p9, "num_p9s")), @@ -1136,6 +1151,17 @@ libxl_vkbinfo = Struct("vkbinfo", [ ("rref", integer) ], dir=DIR_OUT) +libxl_gpioinfo = Struct("gpioinfo", [ + ("backend", string), + ("backend_id", uint32), + ("frontend", string), + ("frontend_id", uint32), + ("devid", libxl_devid), + ("state", integer), + ("evtch", integer), + ("rref", integer) + ], dir=DIR_OUT) + libxl_i2cinfo = Struct("i2cinfo", [ ("backend", string), ("backend_id", uint32), diff --git a/tools/libs/light/libxl_types_internal.idl b/tools/libs/light/libxl_types_internal.idl index 1b87d1480bf9..3bb79c2a063a 100644 --- a/tools/libs/light/libxl_types_internal.idl +++ b/tools/libs/light/libxl_types_internal.idl @@ -33,6 +33,7 @@ libxl__device_kind = Enumeration("device_kind", [ (15, "VSND"), (16, "VINPUT"), (17, "I2C"), + (18, "GPIO"), ]) libxl__console_backend = Enumeration("console_backend", [ diff --git a/tools/ocaml/libs/xl/genwrap.py b/tools/ocaml/libs/xl/genwrap.py index a9db0b97d80f..ffab4b362d2a 100644 --- a/tools/ocaml/libs/xl/genwrap.py +++ b/tools/ocaml/libs/xl/genwrap.py @@ -36,6 +36,7 @@ DEVICE_LIST = [ ("list", ["ctx", "domid", "t list"]), functions = { # ( name , [type1,type2,....] ) "device_vfb": DEVICE_FUNCTIONS, "device_vkb": DEVICE_FUNCTIONS, + "device_gpio": DEVICE_FUNCTIONS, "device_i2c": DEVICE_FUNCTIONS, "device_disk": DEVICE_FUNCTIONS + DEVICE_LIST + [ ("insert", ["ctx", "t", "domid", "?async:'a", "unit", "unit"]), diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c index cdf473f4ed57..0114cc22a1b6 100644 --- a/tools/ocaml/libs/xl/xenlight_stubs.c +++ b/tools/ocaml/libs/xl/xenlight_stubs.c @@ -707,6 +707,7 @@ DEVICE_ADDREMOVE(disk) DEVICE_ADDREMOVE(nic) DEVICE_ADDREMOVE(vfb) DEVICE_ADDREMOVE(vkb) +DEVICE_ADDREMOVE(gpio) DEVICE_ADDREMOVE(i2c) DEVICE_ADDREMOVE(pci) _DEVICE_ADDREMOVE(disk, cdrom, insert) diff --git a/tools/xl/Makefile b/tools/xl/Makefile index 06801962f11e..34ff203bfd86 100644 --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -23,7 +23,7 @@ XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o XL_OBJS += xl_sched.o xl_pci.o xl_vcpu.o xl_cdrom.o xl_mem.o XL_OBJS += xl_info.o xl_console.o xl_misc.o XL_OBJS += xl_vmcontrol.o xl_saverestore.o xl_migrate.o -XL_OBJS += xl_vdispl.o xl_vsnd.o xl_vkb.o xl_i2c.o +XL_OBJS += xl_vdispl.o xl_vsnd.o xl_vkb.o xl_gpio.o xl_i2c.o $(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog) $(XL_OBJS): CFLAGS += $(CFLAGS_XL) diff --git a/tools/xl/xl.h b/tools/xl/xl.h index 210bc1b6d47a..b2110b125ae4 100644 --- a/tools/xl/xl.h +++ b/tools/xl/xl.h @@ -177,6 +177,9 @@ int main_vsnddetach(int argc, char **argv); int main_vkbattach(int argc, char **argv); int main_vkblist(int argc, char **argv); int main_vkbdetach(int argc, char **argv); +int main_gpioattach(int argc, char **argv); +int main_gpiolist(int argc, char **argv); +int main_gpiodetach(int argc, char **argv); int main_i2cattach(int argc, char **argv); int main_i2clist(int argc, char **argv); int main_i2cdetach(int argc, char **argv); diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c index 30bd614fc275..20bfedb74a7b 100644 --- a/tools/xl/xl_cmdtable.c +++ b/tools/xl/xl_cmdtable.c @@ -406,6 +406,21 @@ const struct cmd_spec cmd_table[] = { "Destroy a domain's virtual keyboard device", " ", }, + { "gpio-attach", + &main_gpioattach, 1, 1, + "Create a new virtual gpio device", + " ...", + }, + { "gpio-list", + &main_gpiolist, 0, 0, + "List virtual gpio devices for a domain", + "", + }, + { "gpio-detach", + &main_gpiodetach, 0, 1, + "Destroy a domain's virtual gpio device", + " ", + }, { "i2c-attach", &main_i2cattach, 1, 1, "Create a new virtual i2c device", diff --git a/tools/xl/xl_gpio.c b/tools/xl/xl_gpio.c new file mode 100644 index 000000000000..85c0b25411c7 --- /dev/null +++ b/tools/xl/xl_gpio.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2022 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include + +#include +#include +#include + +#include "xl.h" +#include "xl_utils.h" +#include "xl_parse.h" + +int main_gpioattach(int argc, char **argv) +{ + int opt; + int rc; + uint32_t domid; + libxl_device_gpio gpio; + + SWITCH_FOREACH_OPT(opt, "", NULL, "gpio-attach", 2) { + /* No options */ + } + + libxl_device_gpio_init(&gpio); + domid = find_domain(argv[optind++]); + + for (argv += optind, argc -= optind; argc > 0; ++argv, --argc) { + rc = parse_gpio_config(&gpio, *argv); + if (rc) goto out; + } + + if (dryrun_only) { + char *json = libxl_device_gpio_to_json(ctx, &gpio); + printf("gpio: %s\n", json); + free(json); + goto done; + } + + if (libxl_device_gpio_add(ctx, domid, &gpio, 0)) { + fprintf(stderr, "libxl_device_gpio_add failed.\n"); + rc = ERROR_FAIL; goto out; + } + +done: + rc = 0; + +out: + libxl_device_gpio_dispose(&gpio); + return rc; +} + +int main_gpiolist(int argc, char **argv) +{ + int opt; + libxl_device_gpio *gpios; + libxl_gpioinfo gpioinfo; + int nb, i; + + SWITCH_FOREACH_OPT(opt, "", NULL, "gpio-list", 1) { + /* No options */ + } + + /* Idx BE Hdl Sta evch ref ID BE-type BE-path */ + printf("%-3s %-2s %-6s %-5s %-6s %6s %-10s %-10s %-30s\n", + "Idx", "BE", "handle", "state", "evt-ch", "ref", + "ID", "BE-type", "BE-path"); + for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) { + uint32_t domid = find_domain(*argv); + gpios = libxl_device_gpio_list(ctx, domid, &nb); + if (!gpios) { + continue; + } + for (i = 0; i < nb; ++i) { + if (libxl_device_gpio_getinfo(ctx, domid, &gpios[i], &gpioinfo) == 0) { + printf("%-3d %-2d %6d %5d %6d %6d %-10s %-30s\n", + gpioinfo.devid, gpioinfo.backend_id, + gpioinfo.devid, gpioinfo.state, gpioinfo.evtch, + gpioinfo.rref, + libxl_gpio_backend_to_string(gpios[i].backend_type), + gpioinfo.backend); + libxl_gpioinfo_dispose(&gpioinfo); + } + } + libxl_device_gpio_list_free(gpios, nb); + } + return 0; +} + +int main_gpiodetach(int argc, char **argv) +{ + uint32_t domid, devid; + int opt, rc; + libxl_device_gpio gpio; + + SWITCH_FOREACH_OPT(opt, "", NULL, "gpio-detach", 2) { + /* No options */ + } + + domid = find_domain(argv[optind++]); + devid = atoi(argv[optind++]); + + libxl_device_gpio_init(&gpio); + + if (libxl_devid_to_device_gpio(ctx, domid, devid, &gpio)) { + fprintf(stderr, "Error: Device %d not connected.\n", devid); + rc = ERROR_FAIL; + goto out; + } + + rc = libxl_device_gpio_remove(ctx, domid, &gpio, 0); + if (rc) { + fprintf(stderr, "libxl_device_gpio_remove failed.\n"); + rc = ERROR_FAIL; + goto out; + } + + rc = 0; + +out: + libxl_device_gpio_dispose(&gpio); + return rc; +} + + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 95483e551c38..7ab4f22821c4 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1204,6 +1204,74 @@ static void parse_vkb_list(const XLU_Config *config, if (rc) exit(EXIT_FAILURE); } +int parse_gpio_config(libxl_device_gpio *gpio, char *token) +{ + char *oparg; + + if (MATCH_OPTION("backend", token, oparg)) { + gpio->backend_domname = strdup(oparg); + } else if (MATCH_OPTION("backend-type", token, oparg)) { + libxl_gpio_backend backend_type; + if (libxl_gpio_backend_from_string(oparg, &backend_type)) { + fprintf(stderr, "Unknown backend_type \"%s\" in gpio spec\n", + oparg); + return -1; + } + gpio->backend_type = backend_type; + } else if (MATCH_OPTION("irq", token, oparg)) { + gpio->irq = strtoul(oparg, NULL, 0); + } else if (MATCH_OPTION("base", token, oparg)) { + gpio->base = strtoul(oparg, NULL, 0); + } else { + fprintf(stderr, "Unknown string \"%s\" in gpio spec\n", token); + return -1; + } + + return 0; +} + +static void parse_gpio_list(const XLU_Config *config, + libxl_domain_config *d_config) +{ + XLU_ConfigList *gpios; + const char *item; + char *buf = NULL; + int rc; + + if (!xlu_cfg_get_list (config, "gpio", &gpios, 0, 0)) { + int entry = 0; + while ((item = xlu_cfg_get_listitem(gpios, entry)) != NULL) { + libxl_device_gpio *gpio; + char *p; + + gpio = ARRAY_EXTEND_INIT(d_config->gpios, + d_config->num_gpios, + libxl_device_gpio_init); + + buf = strdup(item); + + p = strtok (buf, ","); + while (p != NULL) + { + while (*p == ' ') p++; + + rc = parse_gpio_config(gpio, p); + if (rc) goto out; + + p = strtok (NULL, ","); + } + + entry++; + } + } + + rc = 0; + +out: + free(buf); + if (rc) exit(EXIT_FAILURE); +} + int parse_i2c_config(libxl_device_i2c *i2c, char *token) { char *oparg; @@ -2373,15 +2441,18 @@ void parse_config_data(const char *config_source, d_config->num_vfbs = 0; d_config->num_vkbs = 0; + d_config->num_gpios = 0; d_config->num_i2cs = 0; d_config->vfbs = NULL; d_config->vkbs = NULL; + d_config->gpios = NULL; d_config->i2cs = NULL; if (!xlu_cfg_get_list (config, "vfb", &cvfbs, 0, 0)) { while ((buf = xlu_cfg_get_listitem (cvfbs, d_config->num_vfbs)) != NULL) { libxl_device_vfb *vfb; libxl_device_vkb *vkb; + libxl_device_gpio *gpio; libxl_device_i2c *i2c; char *buf2 = strdup(buf); @@ -2393,6 +2464,9 @@ void parse_config_data(const char *config_source, vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs, libxl_device_vkb_init); + gpio = ARRAY_EXTEND_INIT(d_config->gpios, d_config->num_gpios, + libxl_device_gpio_init); + i2c = ARRAY_EXTEND_INIT(d_config->i2cs, d_config->num_i2cs, libxl_device_i2c_init); @@ -2653,6 +2727,7 @@ void parse_config_data(const char *config_source, if (vnc_enabled) { libxl_device_vfb *vfb; libxl_device_vkb *vkb; + libxl_device_gpio *gpio; libxl_device_i2c *i2c; vfb = ARRAY_EXTEND_INIT(d_config->vfbs, d_config->num_vfbs, @@ -2661,6 +2736,9 @@ void parse_config_data(const char *config_source, vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs, libxl_device_vkb_init); + gpio = ARRAY_EXTEND_INIT(d_config->gpios, d_config->num_gpios, + libxl_device_gpio_init); + i2c = ARRAY_EXTEND_INIT(d_config->i2cs, d_config->num_i2cs, libxl_device_i2c_init); @@ -2778,6 +2856,7 @@ void parse_config_data(const char *config_source, exit(-ERROR_FAIL); } xlu_cfg_get_defbool(config, "vkb_device", &b_info->u.hvm.vkb_device, 0); + xlu_cfg_get_defbool(config, "gpio_device", &b_info->u.hvm.gpio_device, 0); xlu_cfg_get_defbool(config, "i2c_device", &b_info->u.hvm.i2c_device, 0); xlu_cfg_replace_string (config, "soundhw", &b_info->u.hvm.soundhw, 0); xlu_cfg_get_defbool(config, "xen_platform_pci", @@ -2827,6 +2906,7 @@ void parse_config_data(const char *config_source, } parse_vkb_list(config, d_config); + parse_gpio_list(config, d_config); parse_i2c_list(config, d_config); xlu_cfg_get_defbool(config, "xend_suspend_evtchn_compat", diff --git a/tools/xl/xl_parse.h b/tools/xl/xl_parse.h index 4b972d525199..6e041abe5d50 100644 --- a/tools/xl/xl_parse.h +++ b/tools/xl/xl_parse.h @@ -36,6 +36,7 @@ int parse_nic_config(libxl_device_nic *nic, XLU_Config **config, char *token); int parse_vdispl_config(libxl_device_vdispl *vdispl, char *token); int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec); int parse_vkb_config(libxl_device_vkb *vkb, char *token); +int parse_gpio_config(libxl_device_gpio *gpio, char *token); int parse_i2c_config(libxl_device_i2c *i2c, char *token); int match_option_size(const char *prefix, size_t len, diff --git a/tools/xl/xl_sxp.c b/tools/xl/xl_sxp.c index a44c765aa515..632e1f338d09 100644 --- a/tools/xl/xl_sxp.c +++ b/tools/xl/xl_sxp.c @@ -140,6 +140,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh) fprintf(fh, "\t\t\t(usbdevice %s)\n", b_info->u.hvm.usbdevice); fprintf(fh, "\t\t\t(vkb_device %s)\n", libxl_defbool_to_string(b_info->u.hvm.vkb_device)); + fprintf(fh, "\t\t\t(gpio_device %s)\n", + libxl_defbool_to_string(b_info->u.hvm.gpio_device)); fprintf(fh, "\t\t\t(i2c_device %s)\n", libxl_defbool_to_string(b_info->u.hvm.i2c_device)); fprintf(fh, "\t\t)\n"); From patchwork Tue May 10 06:04:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12844570 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 69FCBC433F5 for ; Tue, 10 May 2022 06:05:29 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.325179.547655 (Exim 4.92) (envelope-from ) id 1noIzg-0008TC-Eo; Tue, 10 May 2022 06:05:12 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 325179.547655; Tue, 10 May 2022 06:05:12 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzg-0008QY-6C; Tue, 10 May 2022 06:05:12 +0000 Received: by outflank-mailman (input) for mailman id 325179; Tue, 10 May 2022 06:05:11 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIze-0007ob-TK for xen-devel@lists.xen.org; Tue, 10 May 2022 06:05:11 +0000 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [2607:f8b0:4864:20::102b]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 25223eee-d027-11ec-a406-831a346695d4; Tue, 10 May 2022 08:05:09 +0200 (CEST) Received: by mail-pj1-x102b.google.com with SMTP id cx11-20020a17090afd8b00b001d9fe5965b3so1176648pjb.3 for ; Mon, 09 May 2022 23:05:09 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id g17-20020a170902d5d100b0015e8d4eb1f0sm1027055plh.58.2022.05.09.23.05.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 May 2022 23:05:07 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 25223eee-d027-11ec-a406-831a346695d4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=svVS82OvBdmvv7JLfSbwnD8mRf2Q0xw4MKyZG61zwPs=; b=bZHc71ib68Kyd06jqtULLoUCaA3zns/ci74fepqyPN3W8EsEXTQcdBKGX1HPQ1u1/h U7YfPdGh8YBaWTrGEEHDS/ma/YUWpv4Jv3+RKulsB9cWgKHacDoHGaSz6FwBKNVPjDj1 AzuzYPvDkEe9YyCuSGzeh1Kx5PdBaO+zzQgXkphqf9xX2cVMr4Ea9OBMsBeuClFxup1k ESpZwGz+8FTsGWOV+VzjaWO0Czk6dA8ETlBi+1VaiMfQ/Hud/0tvof9yXgP7NuT/WIG4 /j3FvDFe9t25WEr9yb1zgRBSeDd620fn9u6+UAkPS4yFqhZpGSqdB1U4r6/kEvbs2EgZ Ezuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=svVS82OvBdmvv7JLfSbwnD8mRf2Q0xw4MKyZG61zwPs=; b=nTzvYPlP0AWNuH2p/llEe97CdN6Dcdn+VSWW4Ht/0S/4gnOqFNbEOkun7igIFLULGq b/psYNC/2hjlXbgg8EV+y2Umx/dohdnIemhbEob84OEroILcC5tZk0pPbxEgoZ901PZQ MgLwmZaBXhDP66lu26LKQFBjpVT2A2yH7kHYanb1fcmnEH9hVmmtrDnzdizHnpZUSR4l 3tT1kDV3hPxlxzsqNz8SWNsgULkoH6gvdep5/WwgUTa+JSEB2WAlF1qj2P50BJOc6br+ 9Rc9wie0ofjasgqvu1/5reoV03/v7wdPUU5B7S2qzWWvvgWeOwBkoKvu8CS8EhvpI9M0 VuSg== X-Gm-Message-State: AOAM532BLOLGrvtVJyriGc6F2Uk9R6XSkOTYnCPTwrYBT++xok+Q+TYP 20Jq+iKTTtJKmJ2cdFnwGp67BGcvmL7cgA== X-Google-Smtp-Source: ABdhPJw0NKJ4Q/0dkxs8PCIcoIpZRhB2dwZKfpWje1lHYFkWpSYYwaA1BNIRtzlezkm2oH3TFk6mBw== X-Received: by 2002:a17:902:a981:b0:156:229d:6834 with SMTP id bh1-20020a170902a98100b00156229d6834mr18791093plb.128.1652162708233; Mon, 09 May 2022 23:05:08 -0700 (PDT) From: Viresh Kumar To: xen-devel@lists.xen.org Cc: Viresh Kumar , Vincent Guittot , stratos-dev@op-lists.linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Stabellini , Mathieu Poirier , Mike Holmes , Oleksandr Tyshchenko , Wei Liu , Juergen Gross , Julien Grall , Oleksandr Tyshchenko Subject: [PATCH V2 3/6] libxl: arm: Create alloc_virtio_mmio_params() Date: Tue, 10 May 2022 11:34:48 +0530 Message-Id: <32fa4a77c76187f68b074ff1cc81d8de5f683638.1652162646.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Create a separate routine to allocate base and irq for a device as the same code will be required for each device type. Suggested-by: Oleksandr Tyshchenko Signed-off-by: Viresh Kumar --- tools/libs/light/libxl_arm.c | 41 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index 37403a2cebb1..6b95ded82dc3 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -48,6 +48,24 @@ static uint32_t alloc_virtio_mmio_irq(libxl__gc *gc, uint32_t *virtio_mmio_irq) return irq; } +static int alloc_virtio_mmio_params(libxl__gc *gc, uint64_t *base, + uint32_t *irq, uint64_t *virtio_mmio_base, + uint32_t *virtio_mmio_irq) +{ + *base = alloc_virtio_mmio_base(gc, virtio_mmio_base); + if (!*base) + return ERROR_FAIL; + + *irq = alloc_virtio_mmio_irq(gc, virtio_mmio_irq); + if (!*irq) + return ERROR_FAIL; + + LOG(DEBUG, "Allocate Virtio MMIO params: IRQ %u BASE 0x%"PRIx64, *irq, + *base); + + return 0; +} + static const char *gicv_to_string(libxl_gic_version gic_version) { switch (gic_version) { @@ -85,25 +103,18 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, libxl_device_disk *disk = &d_config->disks[i]; if (disk->specification == LIBXL_DISK_SPECIFICATION_VIRTIO) { - disk->base = alloc_virtio_mmio_base(gc, &virtio_mmio_base); - if (!disk->base) - return ERROR_FAIL; - - disk->irq = alloc_virtio_mmio_irq(gc, &virtio_mmio_irq); - if (!disk->irq) - return ERROR_FAIL; - - if (virtio_irq < disk->irq) - virtio_irq = disk->irq; - virtio_enabled = true; - - LOG(DEBUG, "Allocate Virtio MMIO params for Vdev %s: IRQ %u BASE 0x%"PRIx64, - disk->vdev, disk->irq, disk->base); + int rc = alloc_virtio_mmio_params(gc, &disk->base, &disk->irq, + &virtio_mmio_base, &virtio_mmio_irq); + if (rc) + return rc; } } - if (virtio_enabled) + if (virtio_mmio_irq != GUEST_VIRTIO_MMIO_SPI_FIRST) { + virtio_irq = virtio_mmio_irq - 1; nr_spis += (virtio_irq - 32) + 1; + virtio_enabled = true; + } for (i = 0; i < d_config->b_info.num_irqs; i++) { uint32_t irq = d_config->b_info.irqs[i]; From patchwork Tue May 10 06:04:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12844568 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A36E8C4332F for ; Tue, 10 May 2022 06:05:28 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.325180.547670 (Exim 4.92) (envelope-from ) id 1noIzi-0000UG-Kh; Tue, 10 May 2022 06:05:14 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 325180.547670; Tue, 10 May 2022 06:05:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzi-0000U3-HU; Tue, 10 May 2022 06:05:14 +0000 Received: by outflank-mailman (input) for mailman id 325180; Tue, 10 May 2022 06:05:13 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzg-0007ob-PR for xen-devel@lists.xen.org; Tue, 10 May 2022 06:05:12 +0000 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [2607:f8b0:4864:20::533]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 26a1bf24-d027-11ec-a406-831a346695d4; Tue, 10 May 2022 08:05:12 +0200 (CEST) Received: by mail-pg1-x533.google.com with SMTP id a191so13834968pge.2 for ; Mon, 09 May 2022 23:05:12 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id g8-20020a1709029f8800b0015e8d4eb277sm971751plq.193.2022.05.09.23.05.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 May 2022 23:05:10 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 26a1bf24-d027-11ec-a406-831a346695d4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PPqz95lztCC38dTJHeWNR5iEVbeizZheBx488usygyI=; b=vMHmiiogda0eo2/FDg6G7b/iTEveRUAuIW2QZ0etiRM4FaQNA6XkuU+P+GXpnXf+5b enCYqyc1TUOUd26J0sLkxH/e6wIA6yU4ZJptcid0h+KsWU+69ifJTbbgyTivLDvgG6SH L1PodZd2PtLXYXUtl8DwkcGyBom3cTecCzSEdwlaTIfNAV2tlorluAa0qsJuYkYap1RD OnRZiBUkmd+c/5JNSKaAfpCaNouATNjXvBRXBeIetFY+k9GyV91ls6DnwguiUVny6z7P LYMpAaKnKKeLCeweY8nJHftRFAIZf4olPFXkC6rRKP5HqP38WlRQ94l+yuRDulWPETzY 7EyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PPqz95lztCC38dTJHeWNR5iEVbeizZheBx488usygyI=; b=wqFfOkEHmjwZvEpgj7z60JbdSmePlxHgdzMLBvGsYpT4HzZvIfoDOvdjizzLtvtnLW 37UHPNljVw8kRDK4F/vqAEvAbTjt2olJ70w6eIHq7xLfDr75bYwkXev9Wn6J3MntIT3M CpcHcCWdM3sBEZ3gd+50lO2Kc1jyX2V7VH3yKqHAh0xPb12+oIz3PNoIVjjybo4FZAsv LpKj33LMKbA7yEmKokF9vc9C8DIJuoow8pHOIRnExDxVfk+VxIxyzi2X31qGnwhdGNQv h0FsrH3oql33Sk5vEPo7/+YnCXt6N5QqtRDGfV2HvOE+oLBw+IaravqPx6uDwTbSKeXl Wmew== X-Gm-Message-State: AOAM530DOH2XUMJ76s73PBKGM90BBWKppchh/UpP+iMYXamfLj3sogAI b/Fb8drxjux6ATwflnSF7tMtDKFS5r7d6g== X-Google-Smtp-Source: ABdhPJzcx6XKRkhlGQEGnNBK9sTlPxZap2TWqCwx24Uvq6gyUKoCCpT28whgCMXvS+N9E7dqP+t5aQ== X-Received: by 2002:a63:a50e:0:b0:3c6:d417:6704 with SMTP id n14-20020a63a50e000000b003c6d4176704mr4793374pgf.526.1652162710796; Mon, 09 May 2022 23:05:10 -0700 (PDT) From: Viresh Kumar To: xen-devel@lists.xen.org Cc: Viresh Kumar , Vincent Guittot , stratos-dev@op-lists.linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Stabellini , Mathieu Poirier , Mike Holmes , Oleksandr Tyshchenko , Wei Liu , Juergen Gross , Julien Grall Subject: [PATCH V2 4/6] libxl: arm: Split make_virtio_mmio_node() Date: Tue, 10 May 2022 11:34:49 +0530 Message-Id: <65dfe45db3829990335c0c5307d4bcfb40647986.1652162646.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 make_virtio_mmio_node() creates the DT node for simple MMIO devices currently, i.e. the ones that don't require any additional properties. In order to allow using it for other complex device types, split the functionality into two, one where the fdt node isn't closed and the other one to create a simple DT node. Signed-off-by: Viresh Kumar --- tools/libs/light/libxl_arm.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index 6b95ded82dc3..3a038d388cf0 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -872,8 +872,8 @@ static int make_vpci_node(libxl__gc *gc, void *fdt, } -static int make_virtio_mmio_node(libxl__gc *gc, void *fdt, - uint64_t base, uint32_t irq) +static int make_virtio_mmio_node_common(libxl__gc *gc, void *fdt, uint64_t base, + uint32_t irq) { int res; gic_interrupt intr; @@ -895,13 +895,18 @@ static int make_virtio_mmio_node(libxl__gc *gc, void *fdt, res = fdt_property_interrupts(gc, fdt, &intr, 1); if (res) return res; - res = fdt_property(fdt, "dma-coherent", NULL, 0); - if (res) return res; + return fdt_property(fdt, "dma-coherent", NULL, 0); +} - res = fdt_end_node(fdt); +static int make_virtio_mmio_node_simple(libxl__gc *gc, void *fdt, uint64_t base, + uint32_t irq) +{ + int res; + + res = make_virtio_mmio_node_common(gc, fdt, base, irq); if (res) return res; - return 0; + return fdt_end_node(fdt); } static const struct arch_info *get_arch_info(libxl__gc *gc, @@ -1216,7 +1221,7 @@ static int libxl__prepare_dtb(libxl__gc *gc, libxl_domain_config *d_config, libxl_device_disk *disk = &d_config->disks[i]; if (disk->specification == LIBXL_DISK_SPECIFICATION_VIRTIO) - FDT( make_virtio_mmio_node(gc, fdt, disk->base, disk->irq) ); + FDT( make_virtio_mmio_node_simple(gc, fdt, disk->base, disk->irq) ); } if (pfdt) From patchwork Tue May 10 06:04:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12844567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 69FFEC43219 for ; Tue, 10 May 2022 06:05:29 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.325181.547681 (Exim 4.92) (envelope-from ) id 1noIzk-0000oB-TZ; Tue, 10 May 2022 06:05:16 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 325181.547681; Tue, 10 May 2022 06:05:16 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzk-0000nu-Q1; Tue, 10 May 2022 06:05:16 +0000 Received: by outflank-mailman (input) for mailman id 325181; Tue, 10 May 2022 06:05:15 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzj-0007z7-DY for xen-devel@lists.xen.org; Tue, 10 May 2022 06:05:15 +0000 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [2607:f8b0:4864:20::1035]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 21985c21-d027-11ec-8fc4-03012f2f19d4; Tue, 10 May 2022 08:05:03 +0200 (CEST) Received: by mail-pj1-x1035.google.com with SMTP id qe3-20020a17090b4f8300b001dc24e4da73so1083663pjb.1 for ; Mon, 09 May 2022 23:05:14 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id w25-20020a637b19000000b003c659b92b8fsm6944713pgc.32.2022.05.09.23.05.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 May 2022 23:05:12 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 21985c21-d027-11ec-8fc4-03012f2f19d4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ao4t6jWg9wZG5OnDiYaWDYf/ncDqRjTgOzFX6e4AW7A=; b=UPx3Q2aoAHaO3I1yFQqVelKV/6W5jaFEHonFI7K1vNYNSPZkKKorN4QpzncTrf/2+q oUX0TV661jcRoXXPwoBVkN0rhopAQv4JB2iwi8/fJGkoQXFV+W3u5X6ik1UyxhgOS440 RVyiptw3alpJWWCv9Gi5behftA8O/ZlTpM2ZSeDh0tzVbWozho5AiN/BuyPQKi9dEjw8 yvgFl8NHEv75UfxAT99tj1NuEj3fJzgzH+KbIxN3dVE+gOIWjecxz2oN4xJucv5cam4L EkZ9qlIlNkekjeF63g93oIWXfGIniHiIBEwaBFLXy/irr7WwfL0tTzjFkFvzILpfBE8x cC7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ao4t6jWg9wZG5OnDiYaWDYf/ncDqRjTgOzFX6e4AW7A=; b=oQ7PWMxN2PyQtoCVIbQh1TD2NGeA1lDRlHAVwIyO5/R8bPc2JUCr8vpxBxyoUFylcv iOYbF91PvBy51n0N5/Pwcvy5A/vYidDge3Kp4hWRvXFiET7K4bpb7aH+J8ZvtXfLKn2S PkeBMTjt+wAWZhuD1fHlC4b1ND97pKbgRX6CU3OcGWy5/nU5hivwlLpJNUmYY/aV/JZx KO2PO50uWF7oc7EFt3CDJr+M+PWaulHQxcQxccoPJFcAO9BGmSwvAEh9XD1UhbyeIytS +dsMACc1UYwwhD6uYq+qvU8y2Kf2aoGnE/1MkSjjMEXLsjHsgSqqkSauftgHDS4xIoJ0 IBhA== X-Gm-Message-State: AOAM532kKwptW2VeUUrfTVM1aJ7e9t0ML9ZR/Z3FaPifYTk+kjKpDZ/K z9+2h9bUPUhb6L9y5DTtq3q/GWIXX11h3Q== X-Google-Smtp-Source: ABdhPJyfZUHybYDgF9ZHX0pJJsJ84E9YhfxmEXMI2wt9ElM159gGUSMwD5S4ScHo0c4LarwHE9MEYw== X-Received: by 2002:a17:90a:d308:b0:1dc:eff1:d74e with SMTP id p8-20020a17090ad30800b001dceff1d74emr15672286pju.109.1652162713277; Mon, 09 May 2022 23:05:13 -0700 (PDT) From: Viresh Kumar To: xen-devel@lists.xen.org Cc: Viresh Kumar , Vincent Guittot , stratos-dev@op-lists.linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Stabellini , Mathieu Poirier , Mike Holmes , Oleksandr Tyshchenko , Wei Liu , Juergen Gross , Julien Grall Subject: [PATCH V2 5/6] libxl: Allocate MMIO params for I2c device and update DT Date: Tue, 10 May 2022 11:34:50 +0530 Message-Id: X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 This patch allocates Virtio MMIO params (IRQ and memory region) and pass them to the backend, also update Guest device-tree based on Virtio I2C DT bindings [1]. [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/i2c/i2c-virtio.yaml Signed-off-by: Viresh Kumar --- tools/libs/light/libxl_arm.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index 3a038d388cf0..d085c7cf4dbd 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -110,6 +110,15 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, } } + for (i = 0; i < d_config->num_i2cs; i++) { + libxl_device_i2c *i2c = &d_config->i2cs[i]; + + int rc = alloc_virtio_mmio_params(gc, &i2c->base, &i2c->irq, + &virtio_mmio_base, &virtio_mmio_irq); + if (rc) + return rc; + } + if (virtio_mmio_irq != GUEST_VIRTIO_MMIO_SPI_FIRST) { virtio_irq = virtio_mmio_irq - 1; nr_spis += (virtio_irq - 32) + 1; @@ -909,6 +918,26 @@ static int make_virtio_mmio_node_simple(libxl__gc *gc, void *fdt, uint64_t base, return fdt_end_node(fdt); } +static int make_virtio_mmio_node_i2c(libxl__gc *gc, void *fdt, + uint64_t base, uint32_t irq) +{ + int res; + + res = make_virtio_mmio_node_common(gc, fdt, base, irq); + if (res) return res; + + res = fdt_begin_node(fdt, "i2c"); + if (res) return res; + + res = fdt_property_compat(gc, fdt, 1, "virtio,device22"); + if (res) return res; + + res = fdt_end_node(fdt); + if (res) return res; + + return fdt_end_node(fdt); +} + static const struct arch_info *get_arch_info(libxl__gc *gc, const struct xc_dom_image *dom) { @@ -1224,6 +1253,11 @@ static int libxl__prepare_dtb(libxl__gc *gc, libxl_domain_config *d_config, FDT( make_virtio_mmio_node_simple(gc, fdt, disk->base, disk->irq) ); } + for (i = 0; i < d_config->num_i2cs; i++) { + libxl_device_i2c *i2c = &d_config->i2cs[i]; + FDT( make_virtio_mmio_node_i2c(gc, fdt, i2c->base, i2c->irq) ); + } + if (pfdt) FDT( copy_partial_fdt(gc, fdt, pfdt) ); From patchwork Tue May 10 06:04:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12844569 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 932AEC433EF for ; Tue, 10 May 2022 06:05:29 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.325182.547692 (Exim 4.92) (envelope-from ) id 1noIzn-00019b-7a; Tue, 10 May 2022 06:05:19 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 325182.547692; Tue, 10 May 2022 06:05:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzn-00019P-3p; Tue, 10 May 2022 06:05:19 +0000 Received: by outflank-mailman (input) for mailman id 325182; Tue, 10 May 2022 06:05:18 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1noIzm-0007z7-44 for xen-devel@lists.xen.org; Tue, 10 May 2022 06:05:18 +0000 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [2607:f8b0:4864:20::1029]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 232c783a-d027-11ec-8fc4-03012f2f19d4; Tue, 10 May 2022 08:05:06 +0200 (CEST) Received: by mail-pj1-x1029.google.com with SMTP id w17-20020a17090a529100b001db302efed6so1258812pjh.4 for ; Mon, 09 May 2022 23:05:17 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id i63-20020a636d42000000b003c14af5062esm9489879pgc.70.2022.05.09.23.05.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 May 2022 23:05:15 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 232c783a-d027-11ec-8fc4-03012f2f19d4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LdUL/a7ibfgZJBH8Cwv9KTcb3UJUgKsljFq91lvqCvU=; b=k181qsg4Qqs42nA6b8nsKIeuG8Fdeh1LZm41PT3KKx6dGkeV/r8YFGCtyV57yQuzjo kIptadhPH57dwBQtf0tn1kRKYhyF+sC+KZvhttghy8dnvrYJAA0A1v93+Ovo28q34zvS cRhJFtZh4Fn015Q9ZING6/pjkd9+PBoKa9vaYQzXm1hkOqrVS2ACRbwKNts1dVD1z4KR hOzxtV7WYkIHKmgTbJwg7DkSfa7EKdrNqf60YoeJItsYva2LqK2puY+vy9S/pdxYSfrB YWLg1q8SjkmLT9ZUp74vAzgRJJd9HUrhVd/hLn2sSDCEXOeKnHoCihy8S7gK1in4dNWL ZOMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LdUL/a7ibfgZJBH8Cwv9KTcb3UJUgKsljFq91lvqCvU=; b=gzoozIml9x0MjzhbJ4PpqUYaaFlJVkAsb4r5X8U5R5Z4TbLBMA+Zr9RarJ6ZN6XN6j vWdi+X0pwfQ2ypDlNaX41nzBY2IzEPzZz/8NoIvgcNiuOU2KOwSSc9j2LQfsl0Rzbl7B 6ic4sB2+03ylata/CVWszOiZhVzMOJf0yvz2SqBTE38KXw84ugbqP/FsjW3lvnJ5SLo6 /pXP6L7IRmeNC8h7VSGes+B1h+PIDHsSalqB4hMHznOUKh/Z9BT+pGQPuZiXWSWmlTmj SwnkQTw1uAJsg185gL1MPux24uMP6FQWN0v3U4EfTp0DD5oSofYMntZfjq7Eg59sazWz BJkQ== X-Gm-Message-State: AOAM533XgfFtaAnDZcVBT+NOMAQG+qSn8mP/t9U91hRJjCcqCTmgHWzi EIH9Yi9E+29EfOkB8FYTtiZzXIiyFmM1ZQ== X-Google-Smtp-Source: ABdhPJw/ICaJJRhvcX/HWYXMOuOkkNrEi+Qx5x4tMRG+zUNhqhq33zc7z7WNf7qxwb1Sgq1hPehPuw== X-Received: by 2002:a17:902:70c9:b0:15f:a78:fd15 with SMTP id l9-20020a17090270c900b0015f0a78fd15mr9855184plt.12.1652162715940; Mon, 09 May 2022 23:05:15 -0700 (PDT) From: Viresh Kumar To: xen-devel@lists.xen.org Cc: Viresh Kumar , Vincent Guittot , stratos-dev@op-lists.linaro.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Stabellini , Mathieu Poirier , Mike Holmes , Oleksandr Tyshchenko , Wei Liu , Juergen Gross , Julien Grall Subject: [PATCH V2 6/6] libxl: Allocate MMIO params for GPIO device and update DT Date: Tue, 10 May 2022 11:34:51 +0530 Message-Id: <5bae7f1e7fe2415f075e71353e3ca12f8f662b05.1652162646.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 This patch allocates Virtio MMIO params (IRQ and memory region) and pass them to the backend, also update Guest device-tree based on Virtio GPIO DT bindings [1]. [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio-virtio.yaml Signed-off-by: Viresh Kumar --- tools/libs/light/libxl_arm.c | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index d085c7cf4dbd..2f23430a3ea3 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -119,6 +119,15 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, return rc; } + for (i = 0; i < d_config->num_gpios; i++) { + libxl_device_gpio *gpio = &d_config->gpios[i]; + + int rc = alloc_virtio_mmio_params(gc, &gpio->base, &gpio->irq, + &virtio_mmio_base, &virtio_mmio_irq); + if (rc) + return rc; + } + if (virtio_mmio_irq != GUEST_VIRTIO_MMIO_SPI_FIRST) { virtio_irq = virtio_mmio_irq - 1; nr_spis += (virtio_irq - 32) + 1; @@ -938,6 +947,38 @@ static int make_virtio_mmio_node_i2c(libxl__gc *gc, void *fdt, return fdt_end_node(fdt); } +static int make_virtio_mmio_node_gpio(libxl__gc *gc, void *fdt, + uint64_t base, uint32_t irq) +{ + int res; + + res = make_virtio_mmio_node_common(gc, fdt, base, irq); + if (res) return res; + + res = fdt_begin_node(fdt, "gpio"); + if (res) return res; + + res = fdt_property_compat(gc, fdt, 1, "virtio,device29"); + if (res) return res; + + res = fdt_property(fdt, "gpio-controller", NULL, 0); + if (res) return res; + + res = fdt_property_cell(fdt, "#gpio-cells", 2); + if (res) return res; + + res = fdt_property(fdt, "interrupt-controller", NULL, 0); + if (res) return res; + + res = fdt_property_cell(fdt, "#interrupt-cells", 2); + if (res) return res; + + res = fdt_end_node(fdt); + if (res) return res; + + return fdt_end_node(fdt); +} + static const struct arch_info *get_arch_info(libxl__gc *gc, const struct xc_dom_image *dom) { @@ -1253,6 +1294,11 @@ static int libxl__prepare_dtb(libxl__gc *gc, libxl_domain_config *d_config, FDT( make_virtio_mmio_node_simple(gc, fdt, disk->base, disk->irq) ); } + for (i = 0; i < d_config->num_gpios; i++) { + libxl_device_gpio *gpio = &d_config->gpios[i]; + FDT( make_virtio_mmio_node_gpio(gc, fdt, gpio->base, gpio->irq) ); + } + for (i = 0; i < d_config->num_i2cs; i++) { libxl_device_i2c *i2c = &d_config->i2cs[i]; FDT( make_virtio_mmio_node_i2c(gc, fdt, i2c->base, i2c->irq) );