From nobody Sun Sep 28 16:32:24 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1758762050; cv=none; d=zohomail.com; s=zohoarc; b=mcgAYwBiWAphSEBzNwX0AUq8d4z1wggw7Za0jGilWi57dvLXqvZlzqVScBKEyWMWZW533GS3d7WJWWs1Jc1/DTWYqY+3rHA9sp0MZKRYRg5yV6lY7Tnp9OA+SELlIEFckDJVjsHDqDO7idOS/69/SKjd0jcXoRpALE+fHzd0sbY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758762050; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=yBZzaq4OPnrNzR5BlCDzRnqVDQ5Ky610bUSrxowzc/0=; b=LKv1ZFvZsJsL4RJ0WZSrC8R7QVyu1S+YOPcqT7+nYg5h60eSPC064pjTsjv2FRPtIh7/GMJ8+b0YfFRxKqWu3VXq/4HljWciHthDXn3NtCuau3hDzIYHuOZsq4ycq/3vv0jY1wQX9mAw18ejisXZQbk1CdSlikYZF9cyOxub4aw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758762050394558.1745890044551; Wed, 24 Sep 2025 18:00:50 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v1aJv-0001jW-KG; Wed, 24 Sep 2025 20:58:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3vZPUaAkKCoQtq5qiw6ivowwotm.kwuymu2-lm3mtvwvov2.wzo@flex--lixiaoyan.bounces.google.com>) id 1v1aJt-0001is-P5 for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:49 -0400 Received: from mail-pj1-x104a.google.com ([2607:f8b0:4864:20::104a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3vZPUaAkKCoQtq5qiw6ivowwotm.kwuymu2-lm3mtvwvov2.wzo@flex--lixiaoyan.bounces.google.com>) id 1v1aJm-0004lw-2P for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:47 -0400 Received: by mail-pj1-x104a.google.com with SMTP id 98e67ed59e1d1-32eae48beaaso364850a91.0 for ; Wed, 24 Sep 2025 17:58:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758761917; x=1759366717; darn=nongnu.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=yBZzaq4OPnrNzR5BlCDzRnqVDQ5Ky610bUSrxowzc/0=; b=CQsQ6BmnUIVnvT0CZuWFPH8hA4HFYeDe56PajwX2m73NtCLWwfKpgiasXshEZgIBQf W7bTpxlQWbcPeGOyb21IA4eEPUJRc3yV+swgPEUpH06YP0oBRvW9d0ddxrevXQ4Xk3Z5 wITi0vbCiJXBrqXc1YByHIWKz/4qnNLnHknK78wR8aZKdOa4peRxGBZrXPKe0y0ItBCx aDNiM+K6+MgBzDaZYbCz4yeYJkNkynTHG1HdA98eQRWhch0mUfjDXrRfKU7osNzc5jxk racybRQfsHbYr9xNeeoa7mPzWiOi4ZYVBqtg/XK0kGCfqjAbg7lrHCa8RbL5OpJq2AQj SgKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758761917; x=1759366717; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yBZzaq4OPnrNzR5BlCDzRnqVDQ5Ky610bUSrxowzc/0=; b=vGaHFd/3CsbSVCVZhHEURJviZhFY96vSC5i7N5X9EIoeTnfzas2iHUX91g7Zz6Jyfs F5J/RdvyIe96CKwiCvMoyAuIpOXzFyXTDGoxvkb7GxCssWJXnbQlac1v0cGsu+mJznUu iqMlmdPF3LNP2p/nqVdH88MIQKqwHy61x7gUfOjUo0lZBurIxrsiQL+6Gh54lV3DSUbz 5Wi+RLsvZhG9J0n+pnDpo+qMSlEUiZ+Bp1mQXWQwhcHDwbOdDoFJntmT7xhHfwGyYEV8 byaowFaQAUZ65XKHKgy2ZmD2yCk3skLOHB4vwFmPJxbGMwEJUEHLcHYllLqXQbxarfCp vgvg== X-Forwarded-Encrypted: i=1; AJvYcCVW7/Sk/n2ayda7vp3ikMGcviCdOwmq33NAh+htURgrkNruuY+TXu4B1/7ByDOiKAVrAUYCMfPhwj7D@nongnu.org X-Gm-Message-State: AOJu0YxSH+a8ylVmrUFUOCUjzIAnypJl+neYcKjJH3W5+gmqa0y1wrtC WmhB86a8dXhWFbYJvwcfQIRWem7PcmTubKzLR508kuIFkZ6uR+e4IdFEPb4LF6JdpzhOO+Wnlni 5GwgcRvik6mlhd5L0wg== X-Google-Smtp-Source: AGHT+IHjVh5Hcl5LmRu88onDqyDDdsuWzXcT4ON0E3PEKUbh2975IlIaQWr1vFOhf9RNVZt4mdgdgZWuOl3VAU4= X-Received: from plgk12.prod.google.com ([2002:a17:902:ce0c:b0:269:8538:446e]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:c94f:b0:24c:7b94:2f87 with SMTP id d9443c01a7336-27ed49d0885mr17118235ad.14.1758761917549; Wed, 24 Sep 2025 17:58:37 -0700 (PDT) Date: Thu, 25 Sep 2025 00:58:28 +0000 In-Reply-To: <20250925005832.3708492-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250925005832.3708492-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.536.g15c5d4f767-goog Message-ID: <20250925005832.3708492-2-lixiaoyan@google.com> Subject: [PATCH v1 1/5] hw/gpio: Add property for ASPEED GPIO in 32 bits basis From: Coco Li To: peter.maydell@linaro.org, clg@kaod.org Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, lixiaoyan@google.com, flwu@google.com, andrew@codeconstruct.com.au Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::104a; envelope-from=3vZPUaAkKCoQtq5qiw6ivowwotm.kwuymu2-lm3mtvwvov2.wzo@flex--lixiaoyan.bounces.google.com; helo=mail-pj1-x104a.google.com X-Spam_score_int: -85 X-Spam_score: -8.6 X-Spam_bar: -------- X-Spam_report: (-8.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1758762052181116600 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Felix Wu Added 32 bits property for ASPEED GPIO. Previously it can only be access in= bitwise manner. This change gives ASPEED similar behavior as Nuvoton. Signed-off-by: Felix Wu --- hw/gpio/aspeed_gpio.c | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c index 609a556908..2d78bf9515 100644 --- a/hw/gpio/aspeed_gpio.c +++ b/hw/gpio/aspeed_gpio.c @@ -1308,6 +1308,57 @@ static void aspeed_gpio_2700_write(void *opaque, hwa= ddr offset, } =20 /* Setup functions */ +static void aspeed_gpio_set_set(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + uint32_t set_val =3D 0; + AspeedGPIOState *s =3D ASPEED_GPIO(obj); + AspeedGPIOClass *agc =3D ASPEED_GPIO_GET_CLASS(s); + int set_idx =3D 0; + + if (!visit_type_uint32(v, name, &set_val, errp)) { + return; + } + + if (sscanf(name, "gpio-set[%d]", &set_idx) !=3D 1) { + error_setg(errp, "%s: error reading %s", __func__, name); + return; + } + + if (set_idx >=3D agc->nr_gpio_sets || set_idx < 0) { + error_setg(errp, "%s: invalid set_idx %s", __func__, name); + return; + } + + aspeed_gpio_update(s, &s->sets[set_idx], set_val, + ~s->sets[set_idx].direction); +} + +static void aspeed_gpio_get_set(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + uint32_t set_val =3D 0; + AspeedGPIOState *s =3D ASPEED_GPIO(obj); + AspeedGPIOClass *agc =3D ASPEED_GPIO_GET_CLASS(s); + int set_idx =3D 0; + + if (sscanf(name, "gpio-set[%d]", &set_idx) !=3D 1) { + error_setg(errp, "%s: error reading %s", __func__, name); + return; + } + + if (set_idx >=3D agc->nr_gpio_sets || set_idx < 0) { + error_setg(errp, "%s: invalid set_idx %s", __func__, name); + return; + } + + set_val =3D s->sets[set_idx].data_value; + visit_type_uint32(v, name, &set_val, errp); +} + +/****************** Setup functions ******************/ static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = =3D { [0] =3D {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} }, [1] =3D {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} }, @@ -1435,6 +1486,12 @@ static void aspeed_gpio_init(Object *obj) g_free(name); } } + + for (int i =3D 0; i < agc->nr_gpio_sets; i++) { + char *name =3D g_strdup_printf("gpio-set[%d]", i); + object_property_add(obj, name, "uint32", aspeed_gpio_get_set, + aspeed_gpio_set_set, NULL, NULL); + } } =20 static const VMStateDescription vmstate_gpio_regs =3D { --=20 2.51.0.536.g15c5d4f767-goog From nobody Sun Sep 28 16:32:24 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1758762060; cv=none; d=zohomail.com; s=zohoarc; b=LLHlBxwsvez0fidXLUtrQ0Ti3DR1TER5l8Ps72N5kcZgzl0zj8M39GNXih65ILZdQ7WbTmn/7K3DkiI3mUZTeyPPiFWDURebH1Av2SMn9KKAQsGqT7cRoGbee7oolDC85Pjq6ZZSxvX8mrVqMyWOKGSBDxtIQ33/Ds2orKd5I/8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758762060; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=lga1qICQBDebNyrMenzq4J/gBbkdWk9MbgAOL5tW2hc=; b=ni6oHME/aFEHfUlMrQEcwFT5PeO/VAZNKHqjQJgDfe4X41kUm3wOoXEFPb+ga2mntXJtaTXw0ujbK1OV+mv/xrkha9esPWaLBoo49kST/D2L/1+34VYMIGNh308w5oTFdDdyLcj0cJzSJKCN2HdWlePPT39pqqV5AzRODpq81E4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758762060049817.2494647605637; Wed, 24 Sep 2025 18:01:00 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v1aK4-0001m2-DG; Wed, 24 Sep 2025 20:59:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3v5PUaAkKCoYvs7sky8kxqyyqvo.myw0ow4-no5ovxyxqx4.y1q@flex--lixiaoyan.bounces.google.com>) id 1v1aJz-0001kP-0b for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:55 -0400 Received: from mail-pl1-x649.google.com ([2607:f8b0:4864:20::649]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3v5PUaAkKCoYvs7sky8kxqyyqvo.myw0ow4-no5ovxyxqx4.y1q@flex--lixiaoyan.bounces.google.com>) id 1v1aJp-0004md-EO for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:54 -0400 Received: by mail-pl1-x649.google.com with SMTP id d9443c01a7336-2681642efd9so2940835ad.2 for ; Wed, 24 Sep 2025 17:58:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758761919; x=1759366719; darn=nongnu.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=lga1qICQBDebNyrMenzq4J/gBbkdWk9MbgAOL5tW2hc=; b=YbRxg5kSyUrH76H+HSLLJPw6Umg2RAcyS0KGCU1Gya33/RjuI4aRr0nLi8OVuN47NF 2CggQTUqxoG3igoGOLl3K6oVLGm/q+2c/ma9pnVMji5idQmP9P1ZdsJQLgnZmg8OOXvh zNxKDTllamBJV1TWc+dlIGOwUHSPYK5SGbiTt9DSTqEKkfo5Wvm+xMP/DRrTeaI9ooxB IDd5KbZAmRJMrifmb5PaVXz/i/7JvEy7YTzfElJpGiWyjc+AQVcgXIt8xJKHgRQjdbHo gFIuFZvP/y/eWXwVQYS90HqHnUOIoVFk0XnJ+j1hp6PnJG6hMz0F6/0/VdfitwsesUme RFUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758761919; x=1759366719; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=lga1qICQBDebNyrMenzq4J/gBbkdWk9MbgAOL5tW2hc=; b=h0VqK7O3QjJNYJTWsyF/rew7KdPLSOSdmbMRvuJlhVmIUkWWfuH22U93Sj1OT9bRzS Sl+ZlNHom8qhirlTThRwk2Hb1hcEHH3CZ3PW/VV9oAHJVDQbmzCNKGg0zfB9XgtthpL9 aQ3zExY03W2Z9iIEUCuOi1o9DbjOh9CxRHxgAr98zrWE4Kma0pR8NkZh+12qctjbCX5K Di1isnMQ37tqp3VRr+qNEjtEsqMXeecyGG2Rk4jrRBuEwiWv9jWP7X2Vv+ntkgygJVEn dxVN+fZGZ1iYkBEzmIKtCReJO7XMtzy90o8CKvEMtHKkmxv4qE4at75ltTppDhgcXopD oA5A== X-Forwarded-Encrypted: i=1; AJvYcCXgPvQdqmAeOZEA6i/RtmYHoROdW7jxox85ogN+0JUOrDERM+uut6RGXyLGAiGTxgPdulGYFFEWmRyA@nongnu.org X-Gm-Message-State: AOJu0YxFs0y90EuUUig31d27ruQHqQRAQv0tCceOgHxZ2rI7kfSYLKTz uZz+8QN+FlvwKXFnWBt6pIYC6wx633BA/vPj4oWr9CW2DW/XtP4/7ESAajrPNedqFEPJ6ZqcpL2 fj6QYG+ONqfSL/+ivlw== X-Google-Smtp-Source: AGHT+IHPvj8Ik2PkoH5xfsw+BrdiJR0kI8M82wKzRnXn0UXvZIb5008FnsBov2Zx7ruYAuJLueRK/TwDBbUSbNE= X-Received: from plq1.prod.google.com ([2002:a17:903:2f81:b0:260:6fd2:4165]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:110e:b0:271:b6b3:71ef with SMTP id d9443c01a7336-27ed4a471b4mr18227265ad.43.1758761919306; Wed, 24 Sep 2025 17:58:39 -0700 (PDT) Date: Thu, 25 Sep 2025 00:58:29 +0000 In-Reply-To: <20250925005832.3708492-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250925005832.3708492-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.536.g15c5d4f767-goog Message-ID: <20250925005832.3708492-3-lixiaoyan@google.com> Subject: [PATCH v1 2/5] tests/qtest: Add qtest for for ASPEED GPIO gpio-set property From: Coco Li To: peter.maydell@linaro.org, clg@kaod.org Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, lixiaoyan@google.com, flwu@google.com, andrew@codeconstruct.com.au Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::649; envelope-from=3v5PUaAkKCoYvs7sky8kxqyyqvo.myw0ow4-no5ovxyxqx4.y1q@flex--lixiaoyan.bounces.google.com; helo=mail-pl1-x649.google.com X-Spam_score_int: -85 X-Spam_score: -8.6 X-Spam_bar: -------- X-Spam_report: (-8.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1758762062305116600 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Felix Wu - Added qtests to test gpio-set property for ASPEED. - Added function to get uint in qdict. Signed-off-by: Felix Wu --- include/qobject/qdict.h | 1 + qobject/qdict.c | 13 ++++ tests/qtest/aspeed_gpio-test.c | 105 ++++++++++++++++++++++++++++++--- 3 files changed, 110 insertions(+), 9 deletions(-) diff --git a/include/qobject/qdict.h b/include/qobject/qdict.h index 903e6e5462..861996f08d 100644 --- a/include/qobject/qdict.h +++ b/include/qobject/qdict.h @@ -57,6 +57,7 @@ void qdict_put_str(QDict *qdict, const char *key, const c= har *value); =20 double qdict_get_double(const QDict *qdict, const char *key); int64_t qdict_get_int(const QDict *qdict, const char *key); +uint64_t qdict_get_uint(const QDict *qdict, const char *key); bool qdict_get_bool(const QDict *qdict, const char *key); QList *qdict_get_qlist(const QDict *qdict, const char *key); QDict *qdict_get_qdict(const QDict *qdict, const char *key); diff --git a/qobject/qdict.c b/qobject/qdict.c index a90ac9ae2f..0dafe6d421 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -209,6 +209,19 @@ int64_t qdict_get_int(const QDict *qdict, const char *= key) return qnum_get_int(qobject_to(QNum, qdict_get(qdict, key))); } =20 +/** + * qdict_get_uint(): Get an unsigned integer mapped by 'key' + * + * This function assumes that 'key' exists and it stores a + * QNum representable as uint. + * + * Return unsigned integer mapped by 'key'. + */ +uint64_t qdict_get_uint(const QDict *qdict, const char *key) +{ + return qnum_get_uint(qobject_to(QNum, qdict_get(qdict, key))); +} + /** * qdict_get_bool(): Get a bool mapped by 'key' * diff --git a/tests/qtest/aspeed_gpio-test.c b/tests/qtest/aspeed_gpio-test.c index 12675d4cbb..c2f9ca2298 100644 --- a/tests/qtest/aspeed_gpio-test.c +++ b/tests/qtest/aspeed_gpio-test.c @@ -27,28 +27,115 @@ #include "qemu/timer.h" #include "qobject/qdict.h" #include "libqtest-single.h" +#include "qemu/typedefs.h" =20 #define AST2600_GPIO_BASE 0x1E780000 =20 #define GPIO_ABCD_DATA_VALUE 0x000 #define GPIO_ABCD_DIRECTION 0x004 =20 +static uint32_t qtest_qom_get_uint32(QTestState *s, const char *path, + const char *property) +{ + QDict *r; + + uint32_t res; + r =3D qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': " + "{ 'path': %s, 'property': %s } }", path, property); + res =3D qdict_get_uint(r, "return"); + qobject_unref(r); + + return res; +} + +static void qtest_qom_set_uint32(QTestState *s, const char *path, + const char *property, uint32_t value) +{ + QDict *r; + + r =3D qtest_qmp(s, "{ 'execute': 'qom-set', 'arguments': " + "{ 'path': %s, 'property': %s, 'value': %" PRIu32 " }= }", + path, property, value); + qobject_unref(r); +} + +static const char *resp_get_error(QDict *r, const char* error_key) +{ + QDict *qdict; + + g_assert(r); + + qdict =3D qdict_get_qdict(r, "error"); + if (qdict) { + return qdict_get_str(qdict, error_key); + } + + return NULL; +} + +static bool qtest_qom_check_error(QTestState *s, const char *path, + const char *property, const char *error_= msg, + const char *error_msg_key) +{ + QDict *r; + bool b; + + r =3D qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': " + "{ 'path': %s, 'property': %s } }", path, property); + b =3D g_str_equal(resp_get_error(r, error_msg_key), error_msg); + qobject_unref(r); + + return b; +} + static void test_set_colocated_pins(const void *data) { QTestState *s =3D (QTestState *)data; - + const char path[] =3D "/machine/soc/gpio"; /* * gpioV4-7 occupy bits within a single 32-bit value, so we want to ma= ke * sure that modifying one doesn't affect the other. */ - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV4", true); - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV5", false); - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV6", true); - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV7", false); - g_assert(qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV4")); - g_assert(!qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV5")); - g_assert(qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV6")); - g_assert(!qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV7")); + qtest_qom_set_bool(s, path, "gpioV4", true); + qtest_qom_set_bool(s, path, "gpioV5", false); + qtest_qom_set_bool(s, path, "gpioV6", true); + qtest_qom_set_bool(s, path, "gpioV7", false); + g_assert(qtest_qom_get_bool(s, path, "gpioV4")); + g_assert(!qtest_qom_get_bool(s, path, "gpioV5")); + g_assert(qtest_qom_get_bool(s, path, "gpioV6")); + g_assert(!qtest_qom_get_bool(s, path, "gpioV7")); + + /* + * Testing the gpio-set[%d] properties, using individual gpio boolean + * properties to do cross check. + * We use gpioR4-7 for test, Setting them to be 0b1010. + */ + qtest_qom_set_uint32(s, path, "gpio-set[4]", 0x0); + g_assert(qtest_qom_get_uint32(s, path, "gpio-set[4]") =3D=3D 0x0); + qtest_qom_set_uint32(s, path, "gpio-set[4]", 0xa000); + g_assert(qtest_qom_get_uint32(s, path, "gpio-set[4]") =3D=3D 0xa000); + + g_assert(!qtest_qom_get_bool(s, path, "gpioR4")); + g_assert(qtest_qom_get_bool(s, path, "gpioR5")); + g_assert(!qtest_qom_get_bool(s, path, "gpioR6")); + g_assert(qtest_qom_get_bool(s, path, "gpioR7")); + + /* + * Testing the invalid indexing, the response info should contain foll= owing + * info: + * {key: "class", value: "GenericError"} + * + * For pins, it should follow "gpio%2[A-Z]%1d" or "gpio%3[18A-E]%1d" f= ormat. + */ + const char error_msg[] =3D "GenericError"; + const char error_msg_key[] =3D "class"; + + g_assert(qtest_qom_check_error(s, path, "gpioR+1", error_msg, + error_msg_key)); + g_assert(qtest_qom_check_error(s, path, "gpio-set[99]", error_msg, + error_msg_key)); + g_assert(qtest_qom_check_error(s, path, "gpio-set[-3]", error_msg, + error_msg_key)); } =20 static void test_set_input_pins(const void *data) --=20 2.51.0.536.g15c5d4f767-goog From nobody Sun Sep 28 16:32:24 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1758762053; cv=none; d=zohomail.com; s=zohoarc; b=iQHP2B+LgMKk9wAZcv/XNhmc/As0Z4T2nBv7QA7WMY27P9S8TvsIYzkCYr1SUjiEqJlNulWgN2D+hjc9RPiIb29uthIVjJFT+tW0VlXaNnvtEaQuiK84DSMggw7HqwrM3i0Mu/y4ftCy2voXZythid8Skgw8V700kKMi9sjXQ0I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758762053; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wya99TQHepjllZHYg3chFlfHlvWpGiWN+a2T8JQ02C0=; b=a8Sh4p2pkfMuS0785TD/17fQtEFzfnUR6NvwHD4bUKZytIZZ5kv9re0MhYh8tl2GDaxiYVpuSMqVtTTEXjHdl4+a0RVbG1skquknsGHWaDkt85FbQKewmTOzKV0CRMPtjJrHgZKHym+mlQGn0p42WF8RxjDfR2iTsD8hTTUYgJo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758762053505607.901047955667; Wed, 24 Sep 2025 18:00:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v1aK5-0001na-Tj; Wed, 24 Sep 2025 20:59:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3wZPUaAkKCogxu9um0Amzs00sxq.o0y2qy6-pq7qxz0zsz6.03s@flex--lixiaoyan.bounces.google.com>) id 1v1aK3-0001mt-SF for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:59:00 -0400 Received: from mail-pj1-x104a.google.com ([2607:f8b0:4864:20::104a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3wZPUaAkKCogxu9um0Amzs00sxq.o0y2qy6-pq7qxz0zsz6.03s@flex--lixiaoyan.bounces.google.com>) id 1v1aJt-0004nD-Hm for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:58 -0400 Received: by mail-pj1-x104a.google.com with SMTP id 98e67ed59e1d1-32eae48beaaso364901a91.0 for ; Wed, 24 Sep 2025 17:58:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758761921; x=1759366721; darn=nongnu.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=wya99TQHepjllZHYg3chFlfHlvWpGiWN+a2T8JQ02C0=; b=y7IPdqvTacY5WedXeNXF61LjHCwawsnSOXaK1rJenxKhCbYv+QPkXVoaM3h/2InIhV 5Bkp/8zBF9Wu0LrqaILM6IsMrvzI/g3x7ESNGq/HQxhEpmy4WvUr7LZ+9cOO74ZMeh1E AVkr/nF3wpOiL6QNN2pa9e4xOZiVh/Pj0JyzcTmSaD5j382lHfe4M/PTSq9O8iLNkLX3 CBFc4xjM9RgQorrwzWHWxrnE49g6nkEkyaDO1mYpqIoYsykMPAMa2RyY28Qn9qAiMDcZ GGthUFwuK6wpOBhGyy2p0lxFK2FHoBlGjX+pI+dwAM7q8j95lExQzQrqVVv93sxx55F3 OvvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758761921; x=1759366721; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wya99TQHepjllZHYg3chFlfHlvWpGiWN+a2T8JQ02C0=; b=RXHn+SeVjgfOAC+Ojjv8YzxZsadga2/eWeezPGuFvDBQcogTKxn6eMq3w/kLYrcaZl uRHjhOa9deeyv8cC5lochK2xuWb/E0+cNPn4WgisEGBQszRFjgwHN8sF9Q1vhSaj8feb rAgv5lSbF8no4yJIZxTjif+rbTfoTWWmD5F3VZDXBT9JC4BzDhLZAbfuYqD6wDu4VLUe JAzz2C6BD2xC6w9z4yTWrekDaKM+PM1PHASZpwfK2HbS2UHgadlgwZdpg+sNksPMTLce JMQEfaZINYRXKy8b1eCc8zO94Njw38Vk+NmYlWBfYxPizbx7efltQxnPg662rjUbKuMX sbqQ== X-Forwarded-Encrypted: i=1; AJvYcCX1gAl5+0ssJ0R4gwAyvkd9uSmHmYB53vr937ql4s3N5GsAV3lxMJmbICyXj80JGUVaZvq9XVPCqnmc@nongnu.org X-Gm-Message-State: AOJu0Yyij1m4wLZTn6ZBmCOvTkb4/dEjP51FTW48yo0h33LgWaESJFOS ixuvPn2gzBB6VsSMQ+yF3yiJQL5kkUK91Orwd/Mn8CTBzoT/bygwzu2IW3zM1C2EtGmEuJwCgTQ ZmntaWBoFfFPGEtw2wA== X-Google-Smtp-Source: AGHT+IHCYsOlyBzJTBP5k0mS8oNBvgkV4CfV75lBGVnNid6o8lA/mBSMk0qPpw1KGeA3uzJWx7IuVVVAzgcBV/g= X-Received: from pjnu2.prod.google.com ([2002:a17:90a:8902:b0:32d:e096:fcd5]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:110e:b0:271:b6b3:71ef with SMTP id d9443c01a7336-27ed4a471b4mr18227985ad.43.1758761921087; Wed, 24 Sep 2025 17:58:41 -0700 (PDT) Date: Thu, 25 Sep 2025 00:58:30 +0000 In-Reply-To: <20250925005832.3708492-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250925005832.3708492-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.536.g15c5d4f767-goog Message-ID: <20250925005832.3708492-4-lixiaoyan@google.com> Subject: [PATCH v1 3/5] hw/arm/npcm8xx.c: Add all IRQ ENUMs From: Coco Li To: peter.maydell@linaro.org, clg@kaod.org Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, lixiaoyan@google.com, flwu@google.com, andrew@codeconstruct.com.au, Hao Wu Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::104a; envelope-from=3wZPUaAkKCogxu9um0Amzs00sxq.o0y2qy6-pq7qxz0zsz6.03s@flex--lixiaoyan.bounces.google.com; helo=mail-pj1-x104a.google.com X-Spam_score_int: -85 X-Spam_score: -8.6 X-Spam_bar: -------- X-Spam_report: (-8.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, T_SPF_HELO_TEMPERROR=0.01, UPPERCASE_50_75=0.008, USER_IN_DEF_DKIM_WL=-7.5 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1758762054136116600 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the process of implementing serial gpio and adding the corresponding ENUMs, also complete the list for npcm8xx. Signed-off-by: Coco Li Reviewed-by: Hao Wu --- hw/arm/npcm8xx.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/hw/arm/npcm8xx.c b/hw/arm/npcm8xx.c index a276fea698..10887d07fa 100644 --- a/hw/arm/npcm8xx.c +++ b/hw/arm/npcm8xx.c @@ -92,8 +92,14 @@ enum NPCM8xxInterrupt { NPCM8XX_GMAC2_IRQ, NPCM8XX_GMAC3_IRQ, NPCM8XX_GMAC4_IRQ, - NPCM8XX_MMC_IRQ =3D 26, + NPCM8XX_ESPI_IRQ, + NPCM8XX_SIOX0_IRQ, + NPCM8XX_SIOX1_IRQ, + NPCM8XX_MC_IRQ =3D 25, + NPCM8XX_MMC_IRQ, NPCM8XX_PSPI_IRQ =3D 28, + NPCM8XX_VDMA_IRQ, + NPCM8XX_MCTP_IRQ, NPCM8XX_TIMER0_IRQ =3D 32, /* Timer Module 0 */ NPCM8XX_TIMER1_IRQ, NPCM8XX_TIMER2_IRQ, @@ -116,6 +122,14 @@ enum NPCM8xxInterrupt { NPCM8XX_OHCI1_IRQ, NPCM8XX_EHCI2_IRQ, NPCM8XX_OHCI2_IRQ, + NPCM8XX_SPI1_IRQ =3D 82, + NPCM8XX_RNG_IRQ =3D 84, + NPCM8XX_SPI0_IRQ =3D 85, + NPCM8XX_SPI3_IRQ =3D 87, + NPCM8XX_GDMA0_IRQ =3D 88, + NPCM8XX_GDMA1_IRQ, + NPCM8XX_GDMA2_IRQ, + NPCM8XX_OTP_IRQ =3D 92, NPCM8XX_PWM0_IRQ =3D 93, /* PWM module 0 */ NPCM8XX_PWM1_IRQ, /* PWM module 1 */ NPCM8XX_MFT0_IRQ =3D 96, /* MFT module 0 */ @@ -128,6 +142,11 @@ enum NPCM8xxInterrupt { NPCM8XX_MFT7_IRQ, /* MFT module 7 */ NPCM8XX_PCI_MBOX1_IRQ =3D 105, NPCM8XX_PCI_MBOX2_IRQ, + NPCM8XX_GPIO231_IRQ =3D 108, + NPCM8XX_GPIO233_IRQ, + NPCM8XX_GPIO234_IRQ, + NPCM8XX_GPIO93_IRQ, + NPCM8XX_GPIO94_IRQ, NPCM8XX_GPIO0_IRQ =3D 116, NPCM8XX_GPIO1_IRQ, NPCM8XX_GPIO2_IRQ, @@ -163,6 +182,12 @@ enum NPCM8xxInterrupt { NPCM8XX_SMBUS24_IRQ, NPCM8XX_SMBUS25_IRQ, NPCM8XX_SMBUS26_IRQ, + NPCM8XX_FLM0_IRQ =3D 160, + NPCM8XX_FLM1_IRQ, + NPCM8XX_FLM2_IRQ, + NPCM8XX_FLM3_IRQ, + NPCM8XX_JMT1_IRQ =3D 188, + NPCM8XX_JMT2_IRQ, NPCM8XX_UART0_IRQ =3D 192, NPCM8XX_UART1_IRQ, NPCM8XX_UART2_IRQ, @@ -170,6 +195,22 @@ enum NPCM8xxInterrupt { NPCM8XX_UART4_IRQ, NPCM8XX_UART5_IRQ, NPCM8XX_UART6_IRQ, + NPCM8XX_I3C0_IRQ =3D 224, + NPCM8XX_I3C1_IRQ, + NPCM8XX_I3C2_IRQ, + NPCM8XX_I3C3_IRQ, + NPCM8XX_I3C4_IRQ, + NPCM8XX_I3C5_IRQ, + NPCM8XX_A35INTERR_IRQ =3D 240, + NPCM8XX_A35EXTERR_IRQ, + NPCM8XX_PMU0_IRQ, + NPCM8XX_PMU1_IRQ, + NPCM8XX_PMU2_IRQ, + NPCM8XX_PMU3_IRQ, + NPCM8XX_CTI0_IRQ, + NPCM8XX_CTI1_IRQ, + NPCM8XX_CTI2_IRQ, + NPCM8XX_CTI3_IRQ, }; =20 /* Total number of GIC interrupts, including internal Cortex-A35 interrupt= s. */ --=20 2.51.0.536.g15c5d4f767-goog From nobody Sun Sep 28 16:32:24 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1758762075; cv=none; d=zohomail.com; s=zohoarc; b=KDAcZcKEZZNkK2sKKa6ZQBdJy0Y8bvrQ2fPn6rnQlf1EZOvDY/qZWrLw8rIW0B+fhP77+iHw1FrsNecYT32S5gszKfnED/ZzCM9VTWOayHK3czBiZ7Kmxi2TMVWuKfjoXtWwlmVfIh0pe29S4z7AJk3C5qOZNjL7duGTM1jkJZc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758762075; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=IUcVb+wUDv2vQQ6NwJq/sdFvcEeFqSqZ81IDTDRRxg4=; b=IJfiUajMt2dBA3HiGMevoSF48cMXqulPFxHKasp/hXKeLYG7XeKdijFBcmDn84NNo6YzIoijTrq+m7Wf21q9d+GI09Yia4+mSZg7MbupqX25sbwzhVpFFxv8AD1Lt7wUmbcHVnDIPvu74+8OxMnLfpcElGoN3GhlsRRTrIcOplc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758762075182472.61693999638885; Wed, 24 Sep 2025 18:01:15 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v1aK5-0001nV-7T; Wed, 24 Sep 2025 20:59:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3wpPUaAkKCokyvAvn1Bn0t11tyr.p1z3rz7-qr8ry010t07.14t@flex--lixiaoyan.bounces.google.com>) id 1v1aK2-0001ld-1E for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:58 -0400 Received: from mail-pg1-x549.google.com ([2607:f8b0:4864:20::549]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3wpPUaAkKCokyvAvn1Bn0t11tyr.p1z3rz7-qr8ry010t07.14t@flex--lixiaoyan.bounces.google.com>) id 1v1aJt-0004np-HT for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:57 -0400 Received: by mail-pg1-x549.google.com with SMTP id 41be03b00d2f7-b522037281bso232773a12.3 for ; Wed, 24 Sep 2025 17:58:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758761923; x=1759366723; darn=nongnu.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=IUcVb+wUDv2vQQ6NwJq/sdFvcEeFqSqZ81IDTDRRxg4=; b=KNWM3tL0u09Ja24ORR2SIZiLCLEXPgTmx6oLQeBJ9QfAii3zKhVdsJt6nmr1FQ0Vco r8BQjDA/DtcsuZtsKB0K0molP5Hjafi4MYWzLt6su9C9GjF7lEtSTJQ2g17eXNZFIYVZ EYpTA53w+n9Gqt5KJNXjmLHXwvkMAV6ZnSzm9VOyolLVXBSEQAlRxfM2Tw4gYBBiKQtk Z/7UfmnzaGrRddHoJycGnFOOcgEpIcBkggc+rGBY3EDrlPhCDp1I9DRLim9GeUptGpFR XXrfLesi3QGlG5IDPYqtWsVKHAF5Ymx8/QJhwREouFRnXQlBhW9NE9bm2s9uWHf1P5ae smgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758761923; x=1759366723; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=IUcVb+wUDv2vQQ6NwJq/sdFvcEeFqSqZ81IDTDRRxg4=; b=JSDBXoxWQOUmxxoXzwEgMACLY89zOTrysoEYXPQSs7SJyMQsX0X2eFyNYbkT7COvqF K/a7msHvZbXu4y1RR2rSZFPudYiq3jTp/vVY65rxlYrNXIUVxzYWB+ZcENYpcEjd0mEQ kumyzS4AYKD2luSnWS0erx8hBrUYmhgaXIXXUUzvYzX52lbjTp0bgUsICkRL9ZxmgwPL 0yKx/5DsFNMQm4yqd2wzwnfVxjpzyfWMwACuie3Mof6HdIL/+cSvarZEitsvZYv1C2Dw y93zH8ix2FrArEXzTEpx3jB8n2/Vj3+K0QieFHtnaZl9je0fzJlQTc8whDwG8+IJzU1n zmfA== X-Forwarded-Encrypted: i=1; AJvYcCUMsG2DvjZ6y89MbvrUAjtNE+zJxOjFk8CzD2iIsR7UjnhGN4Dv/wsisRTNmwr7NK0oMyF+yx0aNIKp@nongnu.org X-Gm-Message-State: AOJu0Yw7GPAylZG4jci59LxrNPC2WQbKLzjocUuHk7Y3gJpwjDzfpMyS 6aOPxd0Iq9ViQft9umcSTst1mAnNDG+S4FvLC3CTTH5XlditKuOsH/5ZdyoqgjIVEws7WynIZRq iLp1GzM+8v+s+RIturw== X-Google-Smtp-Source: AGHT+IE91GMKgUNRYEccwI3RL7nMQPQuyBT5sB5gYZMkw1yr5xfsr9sA6FS1N+5ts5APG4RXSGcOOUr9mgj/+Bc= X-Received: from plbkd11.prod.google.com ([2002:a17:903:13cb:b0:269:91b2:4d0c]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:ecc8:b0:279:fa:30fe with SMTP id d9443c01a7336-27ed4a57523mr18683545ad.26.1758761922766; Wed, 24 Sep 2025 17:58:42 -0700 (PDT) Date: Thu, 25 Sep 2025 00:58:31 +0000 In-Reply-To: <20250925005832.3708492-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250925005832.3708492-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.536.g15c5d4f767-goog Message-ID: <20250925005832.3708492-5-lixiaoyan@google.com> Subject: [PATCH v1 4/5] hw/gpio/npcm8xx: Implement SIOX (SPGIO) device for NPCM without input pin logic From: Coco Li To: peter.maydell@linaro.org, clg@kaod.org Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, lixiaoyan@google.com, flwu@google.com, andrew@codeconstruct.com.au, Hao Wu Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::549; envelope-from=3wpPUaAkKCokyvAvn1Bn0t11tyr.p1z3rz7-qr8ry010t07.14t@flex--lixiaoyan.bounces.google.com; helo=mail-pg1-x549.google.com X-Spam_score_int: -85 X-Spam_score: -8.6 X-Spam_bar: -------- X-Spam_report: (-8.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1758762076557116600 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Signed-off-by: Coco Li Reviewed-by: Hao Wu --- hw/arm/npcm8xx.c | 23 +- hw/gpio/meson.build | 1 + hw/gpio/npcm8xx_sgpio.c | 425 +++++++++++++++++++++++++++++++ hw/gpio/trace-events | 4 + include/hw/arm/npcm8xx.h | 2 + include/hw/gpio/npcm8xx_sgpio.h | 45 ++++ tests/qtest/meson.build | 3 +- tests/qtest/npcm8xx_sgpio-test.c | 100 ++++++++ 8 files changed, 600 insertions(+), 3 deletions(-) create mode 100644 hw/gpio/npcm8xx_sgpio.c create mode 100644 include/hw/gpio/npcm8xx_sgpio.h create mode 100644 tests/qtest/npcm8xx_sgpio-test.c diff --git a/hw/arm/npcm8xx.c b/hw/arm/npcm8xx.c index 10887d07fa..ae72c6d54b 100644 --- a/hw/arm/npcm8xx.c +++ b/hw/arm/npcm8xx.c @@ -369,6 +369,11 @@ static const struct { }, }; =20 +static const hwaddr npcm8xx_sgpio_addr[] =3D { + 0xf0101000, + 0xf0102000, +}; + static const struct { const char *name; hwaddr regs_addr; @@ -474,6 +479,11 @@ static void npcm8xx_init(Object *obj) } =20 =20 + for (i =3D 0; i < ARRAY_SIZE(s->sgpio); i++) { + object_initialize_child(obj, "sgpio[*]", + &s->sgpio[i], TYPE_NPCM8XX_SGPIO); + } + for (i =3D 0; i < ARRAY_SIZE(s->smbus); i++) { object_initialize_child(obj, "smbus[*]", &s->smbus[i], TYPE_NPCM7XX_SMBUS); @@ -671,6 +681,17 @@ static void npcm8xx_realize(DeviceState *dev, Error **= errp) npcm8xx_irq(s, NPCM8XX_GPIO0_IRQ + i)); } =20 + /* Serial SIOX modules. Cannot fail. */ + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_sgpio_addr) !=3D ARRAY_SIZE(s->sg= pio)); + for (i =3D 0; i < ARRAY_SIZE(s->sgpio); i++) { + Object *obj =3D OBJECT(&s->sgpio[i]); + + sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm8xx_sgpio_addr[i]); + sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0, + npcm8xx_irq(s, NPCM8XX_SIOX0_IRQ + i)); + } + /* SMBus modules. Cannot fail. */ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_smbus_addr) !=3D ARRAY_SIZE(s->sm= bus)); for (i =3D 0; i < ARRAY_SIZE(s->smbus); i++) { @@ -818,8 +839,6 @@ static void npcm8xx_realize(DeviceState *dev, Error **e= rrp) create_unimplemented_device("npcm8xx.bt", 0xf0030000, 4 * = KiB); create_unimplemented_device("npcm8xx.espi", 0xf009f000, 4 * = KiB); create_unimplemented_device("npcm8xx.peci", 0xf0100000, 4 * = KiB); - create_unimplemented_device("npcm8xx.siox[1]", 0xf0101000, 4 * = KiB); - create_unimplemented_device("npcm8xx.siox[2]", 0xf0102000, 4 * = KiB); create_unimplemented_device("npcm8xx.tmps", 0xf0188000, 4 * = KiB); create_unimplemented_device("npcm8xx.viru1", 0xf0204000, 4 * = KiB); create_unimplemented_device("npcm8xx.viru2", 0xf0205000, 4 * = KiB); diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build index 74840619c0..8a3879983c 100644 --- a/hw/gpio/meson.build +++ b/hw/gpio/meson.build @@ -18,3 +18,4 @@ system_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: file= s('stm32l4x5_gpio.c')) system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c')) system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c')) system_ss.add(when: 'CONFIG_PCF8574', if_true: files('pcf8574.c')) +system_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx_sgpio.c')) diff --git a/hw/gpio/npcm8xx_sgpio.c b/hw/gpio/npcm8xx_sgpio.c new file mode 100644 index 0000000000..f7d6bbf672 --- /dev/null +++ b/hw/gpio/npcm8xx_sgpio.c @@ -0,0 +1,425 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Nuvoton Serial I/O EXPANSION INTERFACE (SOIX) + * + * Copyright 2025 Google LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 General Public License for more details. + */ + +#include "qemu/osdep.h" + +#include "hw/gpio/npcm8xx_sgpio.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "migration/vmstate.h" +#include "qapi/error.h" +#include "qapi/visitor.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/units.h" +#include "trace.h" + +#define NPCM8XX_SGPIO_RD_MODE_MASK 0x6 +#define NPCM8XX_SGPIO_RD_MODE_PERIODIC 0x4 +#define NPCM8XX_SGPIO_RD_MODE_ON_DEMAND 0x0 +#define NPCM8XX_SGPIO_IOXCTS_IOXIF_EN BIT(7) +#define NPCM8XX_SGPIO_IOXCTS_WR_PEND BIT(6) +#define NPCM8XX_SGPIO_IOXCTS_DATA16W BIT(3) +#define NPCM8XX_SGPIO_REGS_SIZE (4 * KiB) + +#define NPCM8XX_SGPIO_IXOEVCFG_FALLING BIT(1) +#define NPCM8XX_SGPIO_IXOEVCFG_RISING BIT(0) +#define NPCM8XX_SGPIO_IXOEVCFG_BOTH (NPCM8XX_SGPIO_IXOEVCFG_FALLING | \ + NPCM8XX_SGPIO_IXOEVCFG_RISING) + +#define IXOEVCFG_MASK 0x3 + +/* 8-bit register indices, with the event config registers being 16-bit */ +enum NPCM8xxSGPIORegister { + NPCM8XX_SGPIO_XDOUT0, + NPCM8XX_SGPIO_XDOUT1, + NPCM8XX_SGPIO_XDOUT2, + NPCM8XX_SGPIO_XDOUT3, + NPCM8XX_SGPIO_XDOUT4, + NPCM8XX_SGPIO_XDOUT5, + NPCM8XX_SGPIO_XDOUT6, + NPCM8XX_SGPIO_XDOUT7, + NPCM8XX_SGPIO_XDIN0, + NPCM8XX_SGPIO_XDIN1, + NPCM8XX_SGPIO_XDIN2, + NPCM8XX_SGPIO_XDIN3, + NPCM8XX_SGPIO_XDIN4, + NPCM8XX_SGPIO_XDIN5, + NPCM8XX_SGPIO_XDIN6, + NPCM8XX_SGPIO_XDIN7, + NPCM8XX_SGPIO_XEVCFG0 =3D 0x10, + NPCM8XX_SGPIO_XEVCFG1 =3D 0x12, + NPCM8XX_SGPIO_XEVCFG2 =3D 0x14, + NPCM8XX_SGPIO_XEVCFG3 =3D 0x16, + NPCM8XX_SGPIO_XEVCFG4 =3D 0x18, + NPCM8XX_SGPIO_XEVCFG5 =3D 0x1a, + NPCM8XX_SGPIO_XEVCFG6 =3D 0x1c, + NPCM8XX_SGPIO_XEVCFG7 =3D 0x1e, + NPCM8XX_SGPIO_XEVSTS0 =3D 0x20, + NPCM8XX_SGPIO_XEVSTS1, + NPCM8XX_SGPIO_XEVSTS2, + NPCM8XX_SGPIO_XEVSTS3, + NPCM8XX_SGPIO_XEVSTS4, + NPCM8XX_SGPIO_XEVSTS5, + NPCM8XX_SGPIO_XEVSTS6, + NPCM8XX_SGPIO_XEVSTS7, + NPCM8XX_SGPIO_IOXCTS, + NPCM8XX_SGPIO_IOXINDR, + NPCM8XX_SGPIO_IOXCFG1, + NPCM8XX_SGPIO_IOXCFG2, + NPCM8XX_SGPIO_IOXDATR =3D 0x2d, + NPCM8XX_SGPIO_REGS_END, +}; + +static uint8_t npcm8xx_sgpio_get_in_port(NPCM8xxSGPIOState *s) +{ + uint8_t p; + + p =3D s->regs[NPCM8XX_SGPIO_IOXCFG2] & 0xf; + if (p > 8) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Trying to set more the allowed input ports %d\n", + DEVICE(s)->canonical_path, p); + } + + return p; +} + +static uint8_t npcm8xx_sgpio_get_out_port(NPCM8xxSGPIOState *s) +{ + uint8_t p; + + p =3D (s->regs[NPCM8XX_SGPIO_IOXCFG2] >> 4) & 0xf; + if (p > 8) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Trying to set more the allowed output ports %d\n= ", + DEVICE(s)->canonical_path, p); + } + + return p; +} + +static bool npcm8xx_sgpio_is_16bit(NPCM8xxSGPIOState *s) +{ + return s->regs[NPCM8XX_SGPIO_IOXCTS] & NPCM8XX_SGPIO_IOXCTS_DATA16W; +} + +static uint64_t npcm8xx_sgpio_regs_read_with_cfg(NPCM8xxSGPIOState *s, + hwaddr reg) +{ + bool rd_word =3D npcm8xx_sgpio_is_16bit(s); + uint64_t value; + + if (rd_word) { + value =3D ((uint16_t)s->regs[reg] << 8) | s->regs[reg + 1]; + } else { + value =3D s->regs[reg]; + } + + return value; +} + +static void npcm8xx_sgpio_update_event(NPCM8xxSGPIOState *s, uint64_t diff) +{ + /* TODO in upcoming patch */ +} + +static void npcm8xx_sgpio_update_pins_in(NPCM8xxSGPIOState *s, uint64_t di= ff) +{ + /* TODO in upcoming patch */ +} + +static void npcm8xx_sgpio_update_pins_out(NPCM8xxSGPIOState *s, hwaddr reg) +{ + uint8_t nout, dout; + + if (~(s->regs[NPCM8XX_SGPIO_IOXCTS] & NPCM8XX_SGPIO_IOXCTS_IOXIF_EN)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Device disabled, transaction out aborted\n", + DEVICE(s)->canonical_path); + } + + nout =3D npcm8xx_sgpio_get_out_port(s); + dout =3D reg - NPCM8XX_SGPIO_XDOUT0; + if (dout >=3D nout) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Accessing XDOUT%d when NOUT is %d\n", + DEVICE(s)->canonical_path, dout, nout); + } + s->pin_out_level[dout] =3D s->regs[NPCM8XX_SGPIO_XDOUT0 + dout]; + /* unset WR_PEND */ + s->regs[NPCM8XX_SGPIO_IOXCTS] &=3D ~0x40; +} + +static uint64_t npcm8xx_sgpio_regs_read(void *opaque, hwaddr addr, + unsigned int size) +{ + NPCM8xxSGPIOState *s =3D opaque; + uint8_t rd_mode =3D s->regs[NPCM8XX_SGPIO_IOXCTS] & + NPCM8XX_SGPIO_RD_MODE_MASK; + hwaddr reg =3D addr / sizeof(uint8_t); + uint8_t nout, nin, din, dout; + uint64_t value =3D 0; + + switch (reg) { + case NPCM8XX_SGPIO_XDOUT0 ... NPCM8XX_SGPIO_XDOUT7: + nout =3D npcm8xx_sgpio_get_out_port(s); + dout =3D reg - NPCM8XX_SGPIO_XDOUT0; + + if (dout >=3D nout) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Accessing XDOUT%d when NOUT is %d\n", + DEVICE(s)->canonical_path, dout, nout); + break; + } + + value =3D npcm8xx_sgpio_regs_read_with_cfg(s, reg); + break; + + case NPCM8XX_SGPIO_XDIN0 ... NPCM8XX_SGPIO_XDIN7: + nin =3D npcm8xx_sgpio_get_in_port(s); + din =3D reg - NPCM8XX_SGPIO_XDIN0; + + if (din >=3D nin) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Accessing XDIN%d when NIN is %d\n", + DEVICE(s)->canonical_path, din, nin); + break; + } + + switch (rd_mode) { + case NPCM8XX_SGPIO_RD_MODE_PERIODIC: + /* XDIN are up-to-date from scanning, return directly. */ + value =3D npcm8xx_sgpio_regs_read_with_cfg(s, reg); + break; + case NPCM8XX_SGPIO_RD_MODE_ON_DEMAND: + /* + * IOX_SCAN write behavior is unimplemented. + * Event generation is also umimplemented. + */ + qemu_log_mask(LOG_UNIMP, + "%s: On Demand with Polling reading mode is not im= plemented.\n", + __func__); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown read mode\n", __fu= nc__); + } + break; + + case NPCM8XX_SGPIO_XEVCFG0 ... NPCM8XX_SGPIO_XEVCFG7: + value =3D ((uint64_t)s->regs[reg] << 8) | s->regs[reg + 1]; + break; + + case NPCM8XX_SGPIO_XEVSTS0 ... NPCM8XX_SGPIO_XEVSTS7: + value =3D npcm8xx_sgpio_regs_read_with_cfg(s, reg); + break; + + case NPCM8XX_SGPIO_IOXCTS ... NPCM8XX_SGPIO_IOXDATR: + value =3D s->regs[reg]; + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: read from invalid offset 0x%" HWADDR_PRIx "\n", + DEVICE(s)->canonical_path, addr); + break; + } + + trace_npcm8xx_sgpio_read(DEVICE(s)->canonical_path, addr, value); + + return value; +} + +static void npcm8xx_sgpio_regs_write(void *opaque, hwaddr addr, uint64_t v, + unsigned int size) +{ + hwaddr reg =3D addr / sizeof(uint8_t); + uint8_t hi_val =3D (uint8_t)(v >> 8); + NPCM8xxSGPIOState *s =3D opaque; + uint8_t value =3D (uint8_t) v; + uint8_t diff; + + trace_npcm8xx_sgpio_write(DEVICE(s)->canonical_path, addr, v); + + switch (reg) { + case NPCM8XX_SGPIO_XDOUT0 ... NPCM8XX_SGPIO_XDOUT7: + /* Set WR_PEND bit */ + s->regs[NPCM8XX_SGPIO_IOXCTS] |=3D 0x40; + if (npcm8xx_sgpio_is_16bit(s)) { + if ((reg - NPCM8XX_SGPIO_XDOUT0) % 2) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: write unaligned 16 bit register @ 0x%" + HWADDR_PRIx "\n", + DEVICE(s)->canonical_path, addr); + break; + } + s->regs[reg] =3D hi_val; + s->regs[reg + 1] =3D value; + npcm8xx_sgpio_update_pins_out(s, reg + 1); + } else { + s->regs[reg] =3D value; + } + npcm8xx_sgpio_update_pins_out(s, reg); + break; + + /* 2 byte long regs */ + case NPCM8XX_SGPIO_XEVCFG0 ... NPCM8XX_SGPIO_XEVCFG7: + if (~(s->regs[NPCM8XX_SGPIO_IOXCTS] & NPCM8XX_SGPIO_IOXCTS_IOXIF_E= N)) { + s->regs[reg] =3D hi_val; + s->regs[reg + 1] =3D value; + } + break; + + case NPCM8XX_SGPIO_XEVSTS0 ... NPCM8XX_SGPIO_XEVSTS7: + if (npcm8xx_sgpio_is_16bit(s)) { + if ((reg - NPCM8XX_SGPIO_XEVSTS0) % 2) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: write unaligned 16 bit register @ 0x%" + HWADDR_PRIx "\n", + DEVICE(s)->canonical_path, addr); + break; + } + s->regs[reg] ^=3D hi_val; + s->regs[reg + 1] ^=3D value; + npcm8xx_sgpio_update_event(s, 0); + } else { + s->regs[reg] ^=3D value; + npcm8xx_sgpio_update_event(s, 0); + } + break; + + case NPCM8XX_SGPIO_IOXCTS: + /* Make sure RO bit WR_PEND is not written to */ + value &=3D ~NPCM8XX_SGPIO_IOXCTS_WR_PEND; + diff =3D s->regs[reg] ^ value; + s->regs[reg] =3D value; + if ((s->regs[NPCM8XX_SGPIO_IOXCTS] & NPCM8XX_SGPIO_IOXCTS_IOXIF_EN= ) && + (diff & NPCM8XX_SGPIO_RD_MODE_MASK)) { + /* reset RD_MODE if attempting to write with IOXIF_EN enabled = */ + s->regs[reg] ^=3D (diff & NPCM8XX_SGPIO_RD_MODE_MASK); + } + break; + + case NPCM8XX_SGPIO_IOXINDR: + /* + * Only relevant to SIOX1. + * HSIOX unimplemented for both, set value and do nothing. + */ + s->regs[reg] =3D value; + break; + + case NPCM8XX_SGPIO_IOXCFG1: + case NPCM8XX_SGPIO_IOXCFG2: + if (~(s->regs[NPCM8XX_SGPIO_IOXCTS] & NPCM8XX_SGPIO_IOXCTS_IOXIF_E= N)) { + s->regs[reg] =3D value; + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: trying to write to register @ 0x%" + HWADDR_PRIx "while IOXIF_EN is enabled\n", + DEVICE(s)->canonical_path, addr); + } + break; + + case NPCM8XX_SGPIO_XDIN0 ... NPCM8XX_SGPIO_XDIN7: + case NPCM8XX_SGPIO_IOXDATR: + /* IOX_SCAN is unimplemented given no on-demand mode */ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: write to read-only register @ 0x%" HWADDR_PRIx "\= n", + DEVICE(s)->canonical_path, addr); + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: write to invalid offset 0x%" HWADDR_PRIx "\n", + DEVICE(s)->canonical_path, addr); + break; + } +} + +static const MemoryRegionOps npcm8xx_sgpio_regs_ops =3D { + .read =3D npcm8xx_sgpio_regs_read, + .write =3D npcm8xx_sgpio_regs_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 2, + .unaligned =3D false, + }, +}; + +static void npcm8xx_sgpio_enter_reset(Object *obj, ResetType type) +{ + NPCM8xxSGPIOState *s =3D NPCM8XX_SGPIO(obj); + + memset(s->regs, 0, sizeof(s->regs)); +} + +static void npcm8xx_sgpio_hold_reset(Object *obj, ResetType type) +{ + NPCM8xxSGPIOState *s =3D NPCM8XX_SGPIO(obj); + + npcm8xx_sgpio_update_pins_in(s, -1); +} + +static void npcm8xx_sgpio_init(Object *obj) +{ + NPCM8xxSGPIOState *s =3D NPCM8XX_SGPIO(obj); + + memory_region_init_io(&s->mmio, obj, &npcm8xx_sgpio_regs_ops, s, + "regs", NPCM8XX_SGPIO_REGS_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); + + /* TODO: Add input GPIO pins */ +} + +static const VMStateDescription vmstate_npcm8xx_sgpio =3D { + .name =3D "npcm8xx-sgpio", + .version_id =3D 0, + .minimum_version_id =3D 0, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT8_ARRAY(pin_in_level, NPCM8xxSGPIOState, + NPCM8XX_SGPIO_NR_PINS / NPCM8XX_SGPIO_MAX_PORT= S), + VMSTATE_UINT8_ARRAY(pin_out_level, NPCM8xxSGPIOState, + NPCM8XX_SGPIO_NR_PINS / NPCM8XX_SGPIO_MAX_PORT= S), + VMSTATE_UINT8_ARRAY(regs, NPCM8xxSGPIOState, NPCM8XX_SGPIO_NR_REGS= ), + VMSTATE_END_OF_LIST(), + }, +}; + +static void npcm8xx_sgpio_class_init(ObjectClass *klass, const void *data) +{ + ResettableClass *reset =3D RESETTABLE_CLASS(klass); + DeviceClass *dc =3D DEVICE_CLASS(klass); + + QEMU_BUILD_BUG_ON(NPCM8XX_SGPIO_REGS_END > NPCM8XX_SGPIO_NR_REGS); + + dc->desc =3D "NPCM8xx SIOX Controller"; + dc->vmsd =3D &vmstate_npcm8xx_sgpio; + reset->phases.enter =3D npcm8xx_sgpio_enter_reset; + reset->phases.hold =3D npcm8xx_sgpio_hold_reset; +} + +static const TypeInfo npcm8xx_sgpio_types[] =3D { + { + .name =3D TYPE_NPCM8XX_SGPIO, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(NPCM8xxSGPIOState), + .class_init =3D npcm8xx_sgpio_class_init, + .instance_init =3D npcm8xx_sgpio_init, + }, +}; +DEFINE_TYPES(npcm8xx_sgpio_types); diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events index cea896b28f..5a3625cabc 100644 --- a/hw/gpio/trace-events +++ b/hw/gpio/trace-events @@ -12,6 +12,10 @@ npcm7xx_gpio_set_input(const char *id, int32_t line, int= 32_t level) "%s line: %" npcm7xx_gpio_set_output(const char *id, int32_t line, int32_t level) "%s l= ine: %" PRIi32 " level: %" PRIi32 npcm7xx_gpio_update_events(const char *id, uint32_t evst, uint32_t even) "= %s evst: 0x%08" PRIx32 " even: 0x%08" PRIx32 =20 +# npcm8xx_sgpio.c +npcm8xx_sgpio_read(const char *id, uint64_t offset, uint64_t value) " %s o= ffset: 0x%04" PRIx64 " value 0x%08" PRIx64 +npcm8xx_sgpio_write(const char *id, uint64_t offset, uint64_t value) " %s = offset: 0x%04" PRIx64 " value 0x%08" PRIx64 + # nrf51_gpio.c nrf51_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0= x%" PRIx64 nrf51_gpio_write(uint64_t offset, uint64_t value) "offset 0x%" PRIx64 " va= lue 0x%" PRIx64 diff --git a/include/hw/arm/npcm8xx.h b/include/hw/arm/npcm8xx.h index a8377db490..2d177329b8 100644 --- a/include/hw/arm/npcm8xx.h +++ b/include/hw/arm/npcm8xx.h @@ -21,6 +21,7 @@ #include "hw/cpu/cluster.h" #include "hw/gpio/npcm7xx_gpio.h" #include "hw/i2c/npcm7xx_smbus.h" +#include "hw/gpio/npcm8xx_sgpio.h" #include "hw/intc/arm_gic_common.h" #include "hw/mem/npcm7xx_mc.h" #include "hw/misc/npcm_clk.h" @@ -104,6 +105,7 @@ struct NPCM8xxState { NPCMPCSState pcs; NPCM7xxSDHCIState mmc; NPCMPSPIState pspi; + NPCM8xxSGPIOState sgpio[2]; }; =20 struct NPCM8xxClass { diff --git a/include/hw/gpio/npcm8xx_sgpio.h b/include/hw/gpio/npcm8xx_sgpi= o.h new file mode 100644 index 0000000000..cce844951e --- /dev/null +++ b/include/hw/gpio/npcm8xx_sgpio.h @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Nuvoton NPCM8xx General Purpose Input / Output (GPIO) + * + * Copyright 2025 Google LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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 General Public License for more details. + */ +#ifndef NPCM8XX_SGPIO_H +#define NPCM8XX_SGPIO_H + +#include "hw/sysbus.h" + +/* Number of pins managed by each controller. */ +#define NPCM8XX_SGPIO_NR_PINS (64) + +/* + * Number of registers in our device state structure. Don't change this wi= thout + * incrementing the version_id in the vmstate. + */ +#define NPCM8XX_SGPIO_NR_REGS (0x2e) +#define NPCM8XX_SGPIO_MAX_PORTS 8 + +typedef struct NPCM8xxSGPIOState { + SysBusDevice parent; + + MemoryRegion mmio; + qemu_irq irq; + + uint8_t pin_in_level[NPCM8XX_SGPIO_MAX_PORTS]; + uint8_t pin_out_level[NPCM8XX_SGPIO_MAX_PORTS]; + uint8_t regs[NPCM8XX_SGPIO_NR_REGS]; +} NPCM8xxSGPIOState; + +#define TYPE_NPCM8XX_SGPIO "npcm8xx-sgpio" +OBJECT_DECLARE_SIMPLE_TYPE(NPCM8xxSGPIOState, NPCM8XX_SGPIO) + +#endif /* NPCM8XX_SGPIO_H */ diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 669d07c06b..12737ad21f 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -212,7 +212,8 @@ qtests_npcm7xx =3D \ 'npcm7xx_watchdog_timer-test'] + \ (slirp.found() ? ['npcm7xx_emc-test'] : []) qtests_npcm8xx =3D \ - ['npcm_gmac-test'] + ['npcm_gmac-test', + 'npcm8xx_sgpio-test',] qtests_aspeed =3D \ ['aspeed_gpio-test', 'aspeed_hace-test', diff --git a/tests/qtest/npcm8xx_sgpio-test.c b/tests/qtest/npcm8xx_sgpio-t= est.c new file mode 100644 index 0000000000..b0b11b3481 --- /dev/null +++ b/tests/qtest/npcm8xx_sgpio-test.c @@ -0,0 +1,100 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * QTest testcase for the Nuvoton NPCM8xx I/O EXPANSION INTERFACE (SOIX) + * modules. + * + * Copyright 2025 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WIT= HOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "qemu/osdep.h" +#include "libqtest-single.h" + +#define NR_SGPIO_DEVICES 8 +#define SGPIO(x) (0xf0101000 + (x) * 0x1000) +#define SGPIO_IRQ(x) (19 + (x)) + +/* SGPIO registers */ +#define GP_N_XDOUT(x) (0x00 + x) +#define GP_N_XDIN(x) (0x08 + x) +#define GP_N_XEVCFG(x) (0x10 + (x) * 0x2) +#define GP_N_XEVSTS(x) (0x20 + x) +#define GP_N_IOXCTS 0x28 +#define GP_N_IOXINDR 0x29 +#define GP_N_IOXCFG1 0x2a +#define GP_N_IOXCFG2 0x2b +#define GP_N_RD_MODE_PERIODIC 0x4 +#define GP_N_IOXIF_EN 0x80 + + +/* Restore the SGPIO controller to a sensible default state. */ +static void sgpio_reset(int n) +{ + int i; + + for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { + writel(SGPIO(n) + GP_N_XDOUT(i), 0x00000000); + writel(SGPIO(n) + GP_N_XEVCFG(i), 0x00000000); + writel(SGPIO(n) + GP_N_XEVSTS(i), 0x00000000); + } + writel(SGPIO(n) + GP_N_IOXCTS, 0x00000000); + writel(SGPIO(n) + GP_N_IOXINDR, 0x00000000); + writel(SGPIO(n) + GP_N_IOXCFG1, 0x00000000); + writel(SGPIO(n) + GP_N_IOXCFG2, 0x00000000); +} + +static void test_read_dout_byte(void) +{ + int i; + + sgpio_reset(0); + + /* set all 8 output devices */ + writel(SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES << 4); + for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { + writel(SGPIO(0) + GP_N_XDOUT(i), 0xff); + g_assert_cmphex(readb(SGPIO(0) + GP_N_XDOUT(i)), =3D=3D, 0xff); + } +} + +static void test_read_dout_word(void) +{ + int i; + + sgpio_reset(0); + /* set all 8 output devices */ + writel(SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES << 4); + /* set 16 bit aligned access */ + writel(SGPIO(0) + GP_N_IOXCTS, 1 << 3); + for (i =3D 0; i < NR_SGPIO_DEVICES / 2; ++i) { + writel(SGPIO(0) + GP_N_XDOUT(i * 2), 0xf0f0); + g_assert_cmphex(readw(SGPIO(0) + GP_N_XDOUT(i * 2)), =3D=3D, 0xf0f= 0); + } +} + +int main(int argc, char **argv) +{ + int ret; + + g_test_init(&argc, &argv, NULL); + g_test_set_nonfatal_assertions(); + + qtest_add_func("/npcm8xx_sgpio/read_dout_byte", test_read_dout_byte); + qtest_add_func("/npcm8xx_sgpio/read_dout_word", test_read_dout_word); + + qtest_start("-machine npcm845-evb"); + qtest_irq_intercept_in(global_qtest, "/machine/soc/sgpio"); + ret =3D g_test_run(); + qtest_end(); + + return ret; +} --=20 2.51.0.536.g15c5d4f767-goog From nobody Sun Sep 28 16:32:24 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1758762066; cv=none; d=zohomail.com; s=zohoarc; b=CTWVHpeAEko200mVnSy+8x5hS/cNzIcTYRjUEoDVxv8u32IVY5+Oc63kojFbV70sudkSHs/Fo9Tzi57CM3jThCsUhNLwPzwjSPU/b9P8vgV0HTnMya/laQbvQOiUPfg1encly0t45qZsSSR/HkCGcrofnP0pM7f2qQ9OXI9saxY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1758762066; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=JC2tyBwDbTtLyJuJJ5U199BdhhyBvX83zBJAVQtcgVY=; b=gukFWIGIyKa6BTNRu5aOFhptap8k+8kUQISvSJ9PzaxyC7sNXI8Js8Ks+iX5CwFE5aXqBDpixi6iQo5LHct1uoKcnY/RF8ryi1lkdqDZED+nXWaBBOERsS4J0IqBtrXGTIq60kgE2kjxt5LFu7+gc45CNgmDQZJwxeIQ2ShboWI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1758762066879904.68736662529; Wed, 24 Sep 2025 18:01:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v1aK5-0001nY-HH; Wed, 24 Sep 2025 20:59:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3xJPUaAkKCos0xCxp3Dp2v33v0t.r315t19-stAt0232v29.36v@flex--lixiaoyan.bounces.google.com>) id 1v1aJz-0001l2-OT for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:56 -0400 Received: from mail-pj1-x1049.google.com ([2607:f8b0:4864:20::1049]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3xJPUaAkKCos0xCxp3Dp2v33v0t.r315t19-stAt0232v29.36v@flex--lixiaoyan.bounces.google.com>) id 1v1aJt-0004oZ-HT for qemu-devel@nongnu.org; Wed, 24 Sep 2025 20:58:55 -0400 Received: by mail-pj1-x1049.google.com with SMTP id 98e67ed59e1d1-32ee4998c50so375674a91.3 for ; Wed, 24 Sep 2025 17:58:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758761924; x=1759366724; darn=nongnu.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=JC2tyBwDbTtLyJuJJ5U199BdhhyBvX83zBJAVQtcgVY=; b=twxScCEJ0uoLKVmn0sPbQndO5uFAhFI2SDxy+BhEjouUE6uqwBsiUJW8f8ZJezCCjL oeLwHNSbpq/grkxhMA1Q3UWdfEHBbd+m09NW8q517EYcXJL4kyBEeb1HKNdW1gwVGw8c 57DsVdrMhdUpZp9IE4kPvZ5veSJTnWb0pHGtZcd/maxUNJ7ADSDW8mJnEk13+Eh9q22X l2qFQj8U8Mx7zG/Giv/RuyBpeJzODAtqZHU0WeYBgdvzE4g8DKyYS97XitpXzSkuBlnc gUQpHYGFa8iHg9Auc58zCU7d955025RqwyS/qugeFxij9qMYKIyJvW4VW18lMolQjrO0 kflA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758761924; x=1759366724; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JC2tyBwDbTtLyJuJJ5U199BdhhyBvX83zBJAVQtcgVY=; b=FGbvtatPGKkvxZuOKRw4mwCpzluUwgXML3YiYVExVeSJHywYDcf9ya2ZGXRK5JP3Rk raXzUna8r2yzo99yv12qYNOO8bIazDiTLX/PJz2+ozAwSZJzDUCj808pCMb0PRAyv4yd pEZcZIabViBn2K6Gtq7zXhZyns78kJAwugWEz9tewxLyV72WMRUXt20TH7D2j2pxi2oN Pa0Pa0/oCstpkrB6PU2xTxNdyZh9sYuacxBfP+2bIhq6xQyQ266tXjQvnasqSJUsMPfZ BGIT6xh9TSnWJbrSgQ+/MQR3I4fq+xtPta28VC1jjmono2sl5bDNImdjOHrsQSdCB954 3Tuw== X-Forwarded-Encrypted: i=1; AJvYcCU5Z4DN5r0P/TtGoAvckUejtbBlIYDBbIzUne6e9ccKpYzgM7fjSK/xzwPsOHAMdL6NitoP6fzPHjQT@nongnu.org X-Gm-Message-State: AOJu0YwPKNHwHxxJmv6iUOt/Qz8VgU1mQgW0Qcd9L0geCrByNtidWmF5 9+ZADKr2o5DtCd5+MuN7GAWGiKVbgkD5iPaBKU7YWl6zM+pHRFI6tOLJqIh5HxlaOXPZHKLjJEN DzAGuPKqMgSqexZ6fnA== X-Google-Smtp-Source: AGHT+IFPtnsbb/a8d7iK38lSjb14fz0YzKE6gfdngbSqAdV0Gtc0B5GHonozGUl+tIVKT3piqSfVCS8BdbCAy58= X-Received: from pjb15.prod.google.com ([2002:a17:90b:2f0f:b0:32e:8ba7:b496]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3b4c:b0:32b:8b8d:c2c6 with SMTP id 98e67ed59e1d1-3342a261343mr1708790a91.14.1758761924451; Wed, 24 Sep 2025 17:58:44 -0700 (PDT) Date: Thu, 25 Sep 2025 00:58:32 +0000 In-Reply-To: <20250925005832.3708492-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250925005832.3708492-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.536.g15c5d4f767-goog Message-ID: <20250925005832.3708492-6-lixiaoyan@google.com> Subject: [PATCH v1 5/5] hw/gpio/npcm8xx: Implement npcm sgpio device input pin logic From: Coco Li To: peter.maydell@linaro.org, clg@kaod.org Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, lixiaoyan@google.com, flwu@google.com, andrew@codeconstruct.com.au, Hao Wu Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1049; envelope-from=3xJPUaAkKCos0xCxp3Dp2v33v0t.r315t19-stAt0232v29.36v@flex--lixiaoyan.bounces.google.com; helo=mail-pj1-x1049.google.com X-Spam_score_int: -85 X-Spam_score: -8.6 X-Spam_bar: -------- X-Spam_report: (-8.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1758762068470116601 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Signed-off-by: Coco Li Reviewed-by: Hao Wu --- hw/gpio/npcm8xx_sgpio.c | 134 ++++++++++++++++++++--- include/hw/gpio/npcm8xx_sgpio.h | 4 +- tests/qtest/npcm8xx_sgpio-test.c | 180 ++++++++++++++++++++++++++----- 3 files changed, 274 insertions(+), 44 deletions(-) diff --git a/hw/gpio/npcm8xx_sgpio.c b/hw/gpio/npcm8xx_sgpio.c index f7d6bbf672..3b626a44e5 100644 --- a/hw/gpio/npcm8xx_sgpio.c +++ b/hw/gpio/npcm8xx_sgpio.c @@ -27,6 +27,8 @@ #include "qemu/units.h" #include "trace.h" =20 +#include + #define NPCM8XX_SGPIO_RD_MODE_MASK 0x6 #define NPCM8XX_SGPIO_RD_MODE_PERIODIC 0x4 #define NPCM8XX_SGPIO_RD_MODE_ON_DEMAND 0x0 @@ -126,24 +128,83 @@ static uint64_t npcm8xx_sgpio_regs_read_with_cfg(NPCM= 8xxSGPIOState *s, if (rd_word) { value =3D ((uint16_t)s->regs[reg] << 8) | s->regs[reg + 1]; } else { - value =3D s->regs[reg]; + value =3D (uint8_t) s->regs[reg]; } =20 return value; } =20 +static uint8_t get_even_bits(uint16_t n) +{ + n &=3D 0x5555; + + n =3D (n | (n >> 1)) & 0x3333; + n =3D (n | (n >> 2)) & 0x0F0F; + n =3D (n | (n >> 4)) & 0x00FF; + + return (uint8_t)n; +} + +static uint8_t get_odd_bits(uint16_t n) +{ + return get_even_bits(n >> 1); +} + +/* + * For each pin, event can be generated from one of 3 conditions. + * + * | 1 | 0 | event configuration + * ----------------------------- + * | 0 | 0 | disabled + * | 0 | 1 | 0-1 transition + * | 1 | 0 | 1-0 transition + * | 1 | 1 | even by any transition + */ + static void npcm8xx_sgpio_update_event(NPCM8xxSGPIOState *s, uint64_t diff) { - /* TODO in upcoming patch */ + uint8_t *d =3D (uint8_t *)&(diff); + uint8_t *p =3D (uint8_t *)&s->pin_in_level; + uint16_t type; + uint8_t sts; + int i; + + for (i =3D 0; i < npcm8xx_sgpio_get_in_port(s); ++i) { + type =3D ((uint16_t)s->regs[NPCM8XX_SGPIO_XEVCFG0 + 2 * i] << 8) | + s->regs[NPCM8XX_SGPIO_XEVCFG0 + 2 * i + 1]; + + /* 0-1 transitions */ + sts =3D p[i] & d[i] & get_even_bits(type); + /* 1-0 transitions */ + sts |=3D (~p[i]) & (d[i] & get_odd_bits(type)); + + s->regs[NPCM8XX_SGPIO_XEVSTS0 + i] =3D sts; + + /* Generate event if the event status register tells us so */ + qemu_set_irq(s->irq, !!(s->regs[NPCM8XX_SGPIO_XEVSTS0 + i])); + } } =20 -static void npcm8xx_sgpio_update_pins_in(NPCM8xxSGPIOState *s, uint64_t di= ff) +static void npcm8xx_sgpio_update_pins_in(NPCM8xxSGPIOState *s, uint64_t va= lue) { - /* TODO in upcoming patch */ + uint8_t *nv =3D (uint8_t *)&value; + uint8_t *ov =3D (uint8_t *)&s->pin_in_level; + uint64_t diff =3D s->pin_in_level ^ value; + int i; + + for (i =3D 0; i < npcm8xx_sgpio_get_in_port(s); ++i) { + if (ov[i] =3D=3D nv[i]) { + continue; + } + s->regs[NPCM8XX_SGPIO_XDIN0 + i] =3D nv[i]; + } + s->pin_in_level =3D value; + npcm8xx_sgpio_update_event(s, diff); } =20 static void npcm8xx_sgpio_update_pins_out(NPCM8xxSGPIOState *s, hwaddr reg) { + uint8_t *p =3D (uint8_t *)&s->pin_out_level; uint8_t nout, dout; =20 if (~(s->regs[NPCM8XX_SGPIO_IOXCTS] & NPCM8XX_SGPIO_IOXCTS_IOXIF_EN)) { @@ -159,7 +220,7 @@ static void npcm8xx_sgpio_update_pins_out(NPCM8xxSGPIOS= tate *s, hwaddr reg) "%s: Accessing XDOUT%d when NOUT is %d\n", DEVICE(s)->canonical_path, dout, nout); } - s->pin_out_level[dout] =3D s->regs[NPCM8XX_SGPIO_XDOUT0 + dout]; + p[dout] =3D s->regs[reg]; /* unset WR_PEND */ s->regs[NPCM8XX_SGPIO_IOXCTS] &=3D ~0x40; } @@ -294,10 +355,8 @@ static void npcm8xx_sgpio_regs_write(void *opaque, hwa= ddr addr, uint64_t v, } s->regs[reg] ^=3D hi_val; s->regs[reg + 1] ^=3D value; - npcm8xx_sgpio_update_event(s, 0); } else { s->regs[reg] ^=3D value; - npcm8xx_sgpio_update_event(s, 0); } break; =20 @@ -371,19 +430,70 @@ static void npcm8xx_sgpio_hold_reset(Object *obj, Res= etType type) { NPCM8xxSGPIOState *s =3D NPCM8XX_SGPIO(obj); =20 - npcm8xx_sgpio_update_pins_in(s, -1); + npcm8xx_sgpio_update_pins_in(s, 0); +} + +static void npcm8xx_sgpio_set_input_lo(void *opaque, int line, int level) +{ + NPCM8xxSGPIOState *s =3D opaque; + + g_assert(line >=3D 0 && line < NPCM8XX_SGPIO_NR_PINS / 2); + + npcm8xx_sgpio_update_pins_in(s, BIT(line) && level); +} + +static void npcm8xx_sgpio_set_input_hi(void *opaque, int line, int level) +{ + NPCM8xxSGPIOState *s =3D opaque; + uint64_t line_ull =3D line; + + g_assert(line >=3D NPCM8XX_SGPIO_NR_PINS / 2 && line < NPCM8XX_SGPIO_N= R_PINS); + + npcm8xx_sgpio_update_pins_in(s, BIT(line_ull << 32) && level); +} + +static void npcm8xx_sgpio_get_pins_in(Object *obj, Visitor *v, const char = *name, + void *opaque, Error **errp) +{ + NPCM8xxSGPIOState *s =3D NPCM8XX_SGPIO(obj); + + visit_type_uint64(v, name, &s->pin_in_level, errp); +} + +static void npcm8xx_sgpio_set_pins_in(Object *obj, Visitor *v, const char = *name, + void *opaque, Error **errp) +{ + NPCM8xxSGPIOState *s =3D NPCM8XX_SGPIO(obj); + uint64_t new_pins_in; + + if (!visit_type_uint64(v, name, &new_pins_in, errp)) { + return; + } + + npcm8xx_sgpio_update_pins_in(s, new_pins_in); } =20 static void npcm8xx_sgpio_init(Object *obj) { NPCM8xxSGPIOState *s =3D NPCM8XX_SGPIO(obj); + DeviceState *dev =3D DEVICE(obj); =20 memory_region_init_io(&s->mmio, obj, &npcm8xx_sgpio_regs_ops, s, "regs", NPCM8XX_SGPIO_REGS_SIZE); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); =20 - /* TODO: Add input GPIO pins */ + /* There are total 64 input pins that can be set */ + QEMU_BUILD_BUG_ON(NPCM8XX_SGPIO_NR_PINS > + sizeof(s->pin_in_level) * CHAR_BIT); + qdev_init_gpio_in(dev, npcm8xx_sgpio_set_input_hi, + NPCM8XX_SGPIO_NR_PINS / 2); + qdev_init_gpio_in(dev, npcm8xx_sgpio_set_input_lo, + NPCM8XX_SGPIO_NR_PINS / 2); + + object_property_add(obj, "sgpio-pins-in", "uint64", + npcm8xx_sgpio_get_pins_in, npcm8xx_sgpio_set_pins_= in, + NULL, NULL); } =20 static const VMStateDescription vmstate_npcm8xx_sgpio =3D { @@ -391,10 +501,8 @@ static const VMStateDescription vmstate_npcm8xx_sgpio = =3D { .version_id =3D 0, .minimum_version_id =3D 0, .fields =3D (const VMStateField[]) { - VMSTATE_UINT8_ARRAY(pin_in_level, NPCM8xxSGPIOState, - NPCM8XX_SGPIO_NR_PINS / NPCM8XX_SGPIO_MAX_PORT= S), - VMSTATE_UINT8_ARRAY(pin_out_level, NPCM8xxSGPIOState, - NPCM8XX_SGPIO_NR_PINS / NPCM8XX_SGPIO_MAX_PORT= S), + VMSTATE_UINT64(pin_in_level, NPCM8xxSGPIOState), + VMSTATE_UINT64(pin_out_level, NPCM8xxSGPIOState), VMSTATE_UINT8_ARRAY(regs, NPCM8xxSGPIOState, NPCM8XX_SGPIO_NR_REGS= ), VMSTATE_END_OF_LIST(), }, diff --git a/include/hw/gpio/npcm8xx_sgpio.h b/include/hw/gpio/npcm8xx_sgpi= o.h index cce844951e..05dfafcb5e 100644 --- a/include/hw/gpio/npcm8xx_sgpio.h +++ b/include/hw/gpio/npcm8xx_sgpio.h @@ -34,8 +34,8 @@ typedef struct NPCM8xxSGPIOState { MemoryRegion mmio; qemu_irq irq; =20 - uint8_t pin_in_level[NPCM8XX_SGPIO_MAX_PORTS]; - uint8_t pin_out_level[NPCM8XX_SGPIO_MAX_PORTS]; + uint64_t pin_in_level; + uint64_t pin_out_level; uint8_t regs[NPCM8XX_SGPIO_NR_REGS]; } NPCM8xxSGPIOState; =20 diff --git a/tests/qtest/npcm8xx_sgpio-test.c b/tests/qtest/npcm8xx_sgpio-t= est.c index b0b11b3481..b26109600c 100644 --- a/tests/qtest/npcm8xx_sgpio-test.c +++ b/tests/qtest/npcm8xx_sgpio-test.c @@ -36,65 +36,187 @@ #define GP_N_IOXIF_EN 0x80 =20 =20 +static void qtest_qom_set_uint64(QTestState *s, const char *path, + const char *property, uint64_t value) +{ + QDict *r; + QDict *qdict; + + r =3D qtest_qmp(s, "{ 'execute': 'qom-set', 'arguments': " + "{ 'path': %s, 'property': %s, 'value': %" PRIu64 " }= }", + path, property, value); + + qdict =3D qdict_get_qdict(r, "error"); + if (qdict) { + printf("DEBUG: set error: %s\n", qdict_get_try_str(qdict, "desc")); + } + + qobject_unref(r); +} + + +static uint64_t qtest_qom_get_uint64(QTestState *s, const char *path, + const char *property) +{ + QDict *r; + + uint64_t res; + r =3D qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': " + "{ 'path': %s, 'property': %s } }", path, property); + + res =3D qdict_get_uint(r, "return"); + qobject_unref(r); + + return res; +} + /* Restore the SGPIO controller to a sensible default state. */ -static void sgpio_reset(int n) +static void sgpio_reset(QTestState *s, int n) { int i; =20 for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { - writel(SGPIO(n) + GP_N_XDOUT(i), 0x00000000); - writel(SGPIO(n) + GP_N_XEVCFG(i), 0x00000000); - writel(SGPIO(n) + GP_N_XEVSTS(i), 0x00000000); + qtest_writeq(s, SGPIO(n) + GP_N_XDOUT(i), 0x0); + qtest_writeq(s, SGPIO(n) + GP_N_XEVCFG(i), 0x0); + qtest_writeq(s, SGPIO(n) + GP_N_XEVSTS(i), 0x0); } - writel(SGPIO(n) + GP_N_IOXCTS, 0x00000000); - writel(SGPIO(n) + GP_N_IOXINDR, 0x00000000); - writel(SGPIO(n) + GP_N_IOXCFG1, 0x00000000); - writel(SGPIO(n) + GP_N_IOXCFG2, 0x00000000); + qtest_writeq(s, SGPIO(n) + GP_N_IOXCTS, 0x0); + qtest_writeq(s, SGPIO(n) + GP_N_IOXINDR, 0x0); + qtest_writeq(s, SGPIO(n) + GP_N_IOXCFG1, 0x0); + qtest_writeq(s, SGPIO(n) + GP_N_IOXCFG2, 0x0); } =20 -static void test_read_dout_byte(void) +static void test_read_dout_byte(const char *machine) { + QTestState *s =3D qtest_init(machine); int i; =20 - sgpio_reset(0); + sgpio_reset(s, 0); =20 /* set all 8 output devices */ - writel(SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES << 4); + qtest_writeq(s, SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES << 4); for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { - writel(SGPIO(0) + GP_N_XDOUT(i), 0xff); - g_assert_cmphex(readb(SGPIO(0) + GP_N_XDOUT(i)), =3D=3D, 0xff); + qtest_writeq(s, SGPIO(0) + GP_N_XDOUT(i), 0xff); + g_assert_cmphex(qtest_readb(s, SGPIO(0) + GP_N_XDOUT(i)), =3D=3D, = 0xff); } + qtest_quit(s); } =20 -static void test_read_dout_word(void) +static void test_read_dout_word(const char *machine) { + QTestState *s =3D qtest_init(machine); int i; =20 - sgpio_reset(0); + sgpio_reset(s, 0); /* set all 8 output devices */ - writel(SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES << 4); + qtest_writeq(s, SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES << 4); /* set 16 bit aligned access */ - writel(SGPIO(0) + GP_N_IOXCTS, 1 << 3); + qtest_writeq(s, SGPIO(0) + GP_N_IOXCTS, 1 << 3); for (i =3D 0; i < NR_SGPIO_DEVICES / 2; ++i) { - writel(SGPIO(0) + GP_N_XDOUT(i * 2), 0xf0f0); - g_assert_cmphex(readw(SGPIO(0) + GP_N_XDOUT(i * 2)), =3D=3D, 0xf0f= 0); + qtest_writeq(s, SGPIO(0) + GP_N_XDOUT(i * 2), 0xf0f0); + g_assert_cmphex(qtest_readw(s, SGPIO(0) + GP_N_XDOUT(i * 2)), + =3D=3D, 0xf0f0); } + qtest_quit(s); } =20 -int main(int argc, char **argv) +static void test_events_din_rising_edge(const char *machine) { - int ret; + QTestState *s =3D qtest_init(machine); + const char path[] =3D "/machine/soc/sgpio[0]"; + int i; + + /* clear all inputs */ + sgpio_reset(s, 0); + + /* set all 8 input devices */ + qtest_writel(s, SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES); + + /* set event detection type to be on the rising edge*/ + for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { + qtest_writel(s, SGPIO(0) + GP_N_XEVCFG(i), 0x5555); + } + /* Set periodic reading mode, the only accepted mode */ + qtest_writel(s, SGPIO(0) + GP_N_IOXCTS, GP_N_RD_MODE_PERIODIC); + /* enable device, set IOXIF_EN */ + qtest_writel(s, SGPIO(0) + GP_N_IOXCTS, + GP_N_IOXIF_EN | GP_N_RD_MODE_PERIODIC); + + qtest_irq_intercept_in(s, "/machine/soc/gic"); + + /* raise all input pin values */ + qtest_qom_set_uint64(s, path, "sgpio-pins-in", 0xffffffffffffffff); + g_assert(qtest_qom_get_uint64(s, path, "sgpio-pins-in") + =3D=3D 0xffffffffffffffff); + + /* set event status to implicitly change pins */ + for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { + g_assert_cmphex(qtest_readb(s, SGPIO(0) + GP_N_XDIN(i)), =3D=3D, 0= xff); + g_assert_cmphex(qtest_readb(s, SGPIO(0) + GP_N_XEVSTS(i)), =3D=3D,= 0xff); + g_assert_true(qtest_get_irq(s, SGPIO_IRQ(0))); + } =20 + qtest_quit(s); +} + +static void test_events_din_falling_edge(const char *machine) +{ + QTestState *s =3D qtest_init(machine); + const char path[] =3D "/machine/soc/sgpio[0]"; + int i; + + /* clear all inputs */ + sgpio_reset(s, 0); + + /* set all 8 input devices */ + qtest_writel(s, SGPIO(0) + GP_N_IOXCFG2, NR_SGPIO_DEVICES); + + /* set event detection type to be on the falling edge*/ + for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { + qtest_writel(s, SGPIO(0) + GP_N_XEVCFG(i), 0xaaaa); + } + /* Set periodic reading mode, the only accepted mode */ + qtest_writel(s, SGPIO(0) + GP_N_IOXCTS, GP_N_RD_MODE_PERIODIC); + /* enable device, set IOXIF_EN */ + qtest_writel(s, SGPIO(0) + GP_N_IOXCTS, + GP_N_IOXIF_EN | GP_N_RD_MODE_PERIODIC); + + qtest_irq_intercept_in(s, "/machine/soc/gic"); + + /* raise all input pin values */ + qtest_qom_set_uint64(s, path, "sgpio-pins-in", 0xffffffffffffffff); + g_assert(qtest_qom_get_uint64(s, path, "sgpio-pins-in") + =3D=3D 0xffffffffffffffff); + + /* reset all input pin values */ + qtest_qom_set_uint64(s, path, "sgpio-pins-in", 0x0); + g_assert(qtest_qom_get_uint64(s, path, "sgpio-pins-in") =3D=3D 0x0); + + /* set event status to implicitly change pins */ + for (i =3D 0; i < NR_SGPIO_DEVICES; ++i) { + g_assert_cmphex(qtest_readb(s, SGPIO(0) + GP_N_XDIN(i)), =3D=3D, 0= x00); + g_assert_cmphex(qtest_readb(s, SGPIO(0) + GP_N_XEVSTS(i)), =3D=3D,= 0xff); + g_assert_true(qtest_get_irq(s, SGPIO_IRQ(0))); + } + + qtest_quit(s); +} + + +static void test_npcm8xx(void) +{ + test_read_dout_byte("-machine npcm845-evb"); + test_read_dout_word("-machine npcm845-evb"); + test_events_din_rising_edge("-machine npcm845-evb"); + test_events_din_falling_edge("-machine npcm845-evb"); +} + +int main(int argc, char **argv) +{ g_test_init(&argc, &argv, NULL); g_test_set_nonfatal_assertions(); =20 - qtest_add_func("/npcm8xx_sgpio/read_dout_byte", test_read_dout_byte); - qtest_add_func("/npcm8xx_sgpio/read_dout_word", test_read_dout_word); - - qtest_start("-machine npcm845-evb"); - qtest_irq_intercept_in(global_qtest, "/machine/soc/sgpio"); - ret =3D g_test_run(); - qtest_end(); + qtest_add_func("/npcm8xx/sgpio", test_npcm8xx); =20 - return ret; + return g_test_run(); } --=20 2.51.0.536.g15c5d4f767-goog