From nobody Sun Oct 26 22:32:32 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=1760491221; cv=none; d=zohomail.com; s=zohoarc; b=eKgCSMHhqqVZYCkc4nMCZ0Wl7U4q/9vQph+AhwHtqnIgkQyeokgzdti4b76AowQZ9LfQFz8EsIZaQnmNH/7g2rLATSmYdioDLTv47hkA/acEoTGbBinAAo3uOGPxTA2W+WkHdgRqkT6UAs1zQngxeMX4LTd0Uq0ODz3QEWZ2BlQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760491221; 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=br1b472i1wUs/pSTcxpYafrcAix2wuzSuhGHbD2r6is=; b=RQD+I+QMZusJmtKAbCwMv9/2sw2TCdMyGuFUosy4xynvWMTNlTF2Mml1V1RhlKvFeLjkCNfgDE+GYfNEYnlAciTVGgEYVHt7oW4wJ+jPmWMitva17fDVO2MHf3I+UPhgux4+uKgrzUCTk/nCNfgvh2uJx9/z2soJsP2WO6eH1Kg= 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 176049122135344.58817599545239; Tue, 14 Oct 2025 18:20:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v8qA6-0000Pn-PJ; Tue, 14 Oct 2025 21:18:42 -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 <3a_buaAkKCmILIXIAOYANGOOGLE.COMQEMU-DEVELNONGNU.ORG@flex--lixiaoyan.bounces.google.com>) id 1v8qA5-0000Oe-8E for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:41 -0400 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3a_buaAkKCmILIXIAOYANGOOGLE.COMQEMU-DEVELNONGNU.ORG@flex--lixiaoyan.bounces.google.com>) id 1v8qA1-0003CX-Rr for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:40 -0400 Received: by mail-pf1-x44a.google.com with SMTP id d2e1a72fcca58-7900f597d08so8378330b3a.1 for ; Tue, 14 Oct 2025 18:18:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760491115; x=1761095915; 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=br1b472i1wUs/pSTcxpYafrcAix2wuzSuhGHbD2r6is=; b=XxiI9HYMZTh3lWtTqjXNgfDEwm5BZ6/9gl3y0s5aTO6wJPRPjW6cYNgyvrFS9FmyVw ZML/Ml9CcGjk47PLudmj5xHT/l41SZmzzAsJuMk5fZAc4v/MukPrezd6ZgREce1kMxh1 EH8vQjk++i8ofS9TFda3KPJTv8IN5EHZv1YBseKg6UAaRJ/3cKFqmU3xcYAWJZJZNep8 csdEZE+jlcbpybizY6AMU91sRJhRP1iNsvkaDXHJc1uw252vmFfyRAlR2kq/LD1TWX4x WWf+LlxNFMHZ40RBR6TgoGjfmC435W3fzg6yJWV6FV29AZGqExFDrJY6KQ9hQ5YmxiTY HjEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760491115; x=1761095915; 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=br1b472i1wUs/pSTcxpYafrcAix2wuzSuhGHbD2r6is=; b=YTKpL34/IdpXfUwm6SyuyUisEMyjAT37triJ09vUlVtnCpXMD3Y4aFVws7Meg9ee+1 ARNQyHffGyTEmCAlNmN1xO9JZKhsMfh0qPIRPB3RioqLrGwteNUWwD5s1cSnFe0rCYsa Ozv1yBrE1qBSHR2PE1a9QHWjNYORo5DZ2BQyTsk6f6RGEEbZTN9WsLJxQRUVMapm2QXM eyl1pvsR3J3FX58b/XydpZcvWGqkFwsGkMFwv0MfsBUAzClKcaChdOOXVxni3jfsnfgf h2XHs+oLEgFt3H1AAe5v+T93oBOj89wNCo07gqPi5AparOAATpl+kXWWigNOCmKP9B1r 5EHQ== X-Forwarded-Encrypted: i=1; AJvYcCU+IxekBmTCs669yryvEuExbYeNKhfqYB9SG5ng7/u4djqUmgEElrUMjJ0gUY96tMvhcK06irqwD+z3@nongnu.org X-Gm-Message-State: AOJu0YwAJe4kDeip5KocF7HnZGOZVd26AwcHYXFCtuozBx/MzH02rYCn lVxlI+fHnbd7MxuNCLQSbhKgPwnzuLq3hZYFTwHmjv2nKKXhD5XSU0MljJjv6rm827N2F72LC35 NvrTzcgc1TK1+Bt2uFQ== X-Google-Smtp-Source: AGHT+IHbk/xA1p5r1qAbvU3M8yXXgmw/JxqWiFcRjPO95okkaM3zslpG4i9/gx+EzUEtjArn8d56QLt19ZZROyc= X-Received: from pjzb22.prod.google.com ([2002:a17:90a:e396:b0:338:3770:a496]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:3383:b0:2f1:a8f0:9631 with SMTP id adf61e73a8af0-32da80bb5fcmr35583758637.10.1760491115532; Tue, 14 Oct 2025 18:18:35 -0700 (PDT) Date: Wed, 15 Oct 2025 01:18:25 +0000 In-Reply-To: <20251015011830.1688468-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20251015011830.1688468-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251015011830.1688468-2-lixiaoyan@google.com> Subject: [PATCH v2 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, philmd@linaro.org 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::44a; envelope-from=3a_buaAkKCmILIXIAOYANGOOGLE.COMQEMU-DEVELNONGNU.ORG@flex--lixiaoyan.bounces.google.com; helo=mail-pf1-x44a.google.com X-Spam_score_int: -88 X-Spam_score: -8.9 X-Spam_bar: -------- X-Spam_report: (-8.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.269, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.998, 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: 1760491224212158500 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. The changes to qobject is to index gpios with array indices on top of acces= sing with registers. This allows for easier gpio access, especially in tests with complex behavi= ors that requires large number of gpios at a time, like fault injection and= networking behaviors. Indexing multiple gpios at once allows qmp/side band client to no longer ha= rdcode and populate register names and manipulate them faster. Signed-off-by: Felix Wu Reviewed-by: Andrew Jeffery --- 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.788.g6d19910ace-goog From nobody Sun Oct 26 22:32:32 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=1760491257; cv=none; d=zohomail.com; s=zohoarc; b=HvSkBo+0fxgq85p51cbzWgytbcmLrF0BHgN2e0tXJpq5rw4yF600nSyC7hnNty1rkK8wH2cQPjFfn7xALs0qeg8xxGK7zwLc6r9Se9NbBjLahhZv/Jcd2QKJb3ZPd0ADvdZcXx7gijHtMp6hVQ/+HuitEzYrX8oZOQMj4mRsByU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760491257; 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=CPQs+PsbgO0P6AZuHEwWkT67RFWoD7TQs6ylOThGD/E=; b=aNQ0zjXPTAw6UJ8rY00pfNRjo2A4x7PtGf9H6msyw61/USNKTtpMGrf5r0GLHRsYfQBmSd2IrDGNO9v8KPRvIc2FmVp7D//kGD16DpbaPiRO+4dVfIzJIMafb9mp61zBcp4n1gwMoDGisGoUbfU7fRLcYOm4xToiKaHxTuqHM1U= 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 1760491257069230.85833908248912; Tue, 14 Oct 2025 18:20:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v8qA8-0000Qv-FW; Tue, 14 Oct 2025 21:18:44 -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 <3bfbuaAkKCmQNKZKCQaCPIQQING.EQOSGOW-FGXGNPQPIPW.QTI@flex--lixiaoyan.bounces.google.com>) id 1v8qA5-0000PJ-Uc for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:42 -0400 Received: from mail-pg1-x54a.google.com ([2607:f8b0:4864:20::54a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3bfbuaAkKCmQNKZKCQaCPIQQING.EQOSGOW-FGXGNPQPIPW.QTI@flex--lixiaoyan.bounces.google.com>) id 1v8qA3-0003Cm-LX for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:41 -0400 Received: by mail-pg1-x54a.google.com with SMTP id 41be03b00d2f7-b57cf8dba28so10333602a12.1 for ; Tue, 14 Oct 2025 18:18:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760491117; x=1761095917; 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=CPQs+PsbgO0P6AZuHEwWkT67RFWoD7TQs6ylOThGD/E=; b=Bn58UuaDYu/9ayiqy1eaqKB+QDYNrSeFfkWNC0/G0uG1usOCg2Z0Z2Y9qLPJf5JFme 0ax7NjwMpfTwklQt4JrgxhFN07Yq2p8G3h2kl5Q1lcGfH5E7WDCEw3xq4OlegTUu8AEY 57YAkBvO1qVghJVRV0bQQkcImv8rfKJk/jFRuJVXT1qsnqs7qZLMEFF4Z2Aj34iR3NNH 2eyzb4650cuxq/M01jkhFNwyxM859CRGS/z9ZF9PjXcU2CuwR6VlxboMj1w/bmxFScHF D3iMx5sWUyyzQbsskXcfDi/NEVMytcfRMK8WTwmUllxSUT6itpBxioA58H0hWllZmpuy QWPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760491117; x=1761095917; 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=CPQs+PsbgO0P6AZuHEwWkT67RFWoD7TQs6ylOThGD/E=; b=wo5SyS2EZiFZGXoJrMidj1BG0NcDcaR4fI3hy1Hd0SkCF09eF//MlzY0aWqfutwbqb 0VEKAbRPdP3eVm4EyITRaTHn8lbzYENrAKSPVEMD51/QJhpuNGrH+DpGc84tGGFwmdpq 7emsXWxMPhrFcPe9KTEpUJc+0rxyV97xNryRwrpAxBl133jT4TOGEgPknKiKgH5cpBwI CnJVLKgyuhbhZn/ZPhq4CFEymLeKEc6HB5BDc+hAueIWRu5Sp/GOb4qJVV9c0pgjuoBG hXqdN1DIZX0vED40PIDMITnd77/lvQ4IBNxcJ7oWUpK+EY57Ht9omq+IU//2Ab9cKNtx VXzA== X-Forwarded-Encrypted: i=1; AJvYcCUELsowQLmJixNK6GmZt7D90cNknh69XM4QRpt8PkuCc7dF78+0NmLTqvGtLFZI2WrIsgspkgZs7yxD@nongnu.org X-Gm-Message-State: AOJu0YybrUq/OxHVr/oZ8w9N0Vc6bOyW7WEy3N7aw7jlnSrUldj4J1+b b2GpPwMUwYQoECmsmDdi7JH/219N3MEo4gJd6SM7aLm4H8vUaqWuSx4s1BT/Ovz9rwBGxZLnhom XC09Huz9asZLgDAXNZA== X-Google-Smtp-Source: AGHT+IFry+Tx4jNARET6jdIzh7caqsmh28sD+VHmqU3izgHWU3OMXaqVC4Lqukc/HZvWXUYV6Pdxseox259GEfQ= X-Received: from plxd12.prod.google.com ([2002:a17:902:ef0c:b0:269:ab8c:6531]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2b03:b0:264:70e9:dcb8 with SMTP id d9443c01a7336-2902739f408mr327738495ad.55.1760491117364; Tue, 14 Oct 2025 18:18:37 -0700 (PDT) Date: Wed, 15 Oct 2025 01:18:26 +0000 In-Reply-To: <20251015011830.1688468-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20251015011830.1688468-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251015011830.1688468-3-lixiaoyan@google.com> Subject: [PATCH v2 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, philmd@linaro.org 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::54a; envelope-from=3bfbuaAkKCmQNKZKCQaCPIQQING.EQOSGOW-FGXGNPQPIPW.QTI@flex--lixiaoyan.bounces.google.com; helo=mail-pg1-x54a.google.com X-Spam_score_int: -88 X-Spam_score: -8.9 X-Spam_bar: -------- X-Spam_report: (-8.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.269, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.998, 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: 1760491258622158500 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 Reviewed-by: C=C3=A9dric Le Goater --- 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.788.g6d19910ace-goog From nobody Sun Oct 26 22:32:32 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=1760491195; cv=none; d=zohomail.com; s=zohoarc; b=ICaP/WBaFjCoGrmGZSuIYX1ioYuYe/MbLggMoQm8GIRmI7a+EQHGNktZ1375fDiLG3V3NNzy2FBDzXor5o8KeHYYp6Qk3G29wTxygOZEQCpZ/IvI5nlSGSTlP9aIzrtMKooIXyuVmOn5cQT/DIW+eV1hGujpdhntUFnBnxTooP8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760491195; 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=tFcrpMNqUzSK5xY1pNPFjqerwuvA1GbCVm02DaoYGWw=; b=gjHiNnwo5Z7D5YgzM0/ZO5tG6qQyOBut4OMII7IAc9bcV6Gq2dIy4goU+8rHtXKl5jUo1gPpd2QaYnFgdHsk6UNx8RnmkeOzjg5sfpxZrByupzoxbPMPqI/ydadZeVJevoc3d1+0Rt1QixcQcUVTrqosh2lbwaAVi4EV68nAnQM= 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 1760491195151461.6218604980186; Tue, 14 Oct 2025 18:19:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v8qA9-0000RD-6k; Tue, 14 Oct 2025 21:18:45 -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 <3b_buaAkKCmYPMbMEScERKSSKPI.GSQUIQY-HIZIPRSRKRY.SVK@flex--lixiaoyan.bounces.google.com>) id 1v8qA8-0000Q9-4j for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:44 -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 <3b_buaAkKCmYPMbMEScERKSSKPI.GSQUIQY-HIZIPRSRKRY.SVK@flex--lixiaoyan.bounces.google.com>) id 1v8qA6-0003DB-BM for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:43 -0400 Received: by mail-pj1-x1049.google.com with SMTP id 98e67ed59e1d1-33428befd39so22936813a91.0 for ; Tue, 14 Oct 2025 18:18:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760491119; x=1761095919; 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=tFcrpMNqUzSK5xY1pNPFjqerwuvA1GbCVm02DaoYGWw=; b=Dhg7rMZniMNCdmiLpWuOYbbQ1V6hAftFwweWxGzonOKqOV+kX/1MDiZeGpYslRn12f HrQ7elrVlPQqhFVoNQlLDd6XM0NdMDyu8qcPwbrX4BpCRYViX6kea3VRiI2EcSwwRi7O Aye07CgUS9RSe80SIqppN5vohke74yzMxdpAna8uNHMJDejUN6ARtDh2IbHLSQHqujzd 1HSfajy4HlRti6Dqfq9aOhslycSfjoXGSl2UvCq8uambVKUWVzCoW10UaN6SfeSwhbvS dHqDjCjtnVHcDNjJYoCh7vNpT5AqC05dw2Mkn+XJLh0jTmruFJ4e0p+HYpf1EITjHVFB Jbyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760491119; x=1761095919; 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=tFcrpMNqUzSK5xY1pNPFjqerwuvA1GbCVm02DaoYGWw=; b=sHMoUmo6UtBpfouuyqY1lwOSnUKXy0Bx5UW3ehnLJFUrQC1Z0xgu7sj4TfJKly+s32 Ddow55f1Z8t8tbU1DOrm+RbTLZxYQ/eLstr/3ywXJluvzqaxTqI16mu86rh46UI4ykJG 66s7DTp7yDRXSbi5eapE0zl3JKtiSyjSaCcCINz4w+VGX2ADNKM9y/MA8LGuKARzD6Gv TxVHqej3SCtVZTiH7GYaKYXsUseWFDTdqA/0MZ5V2Ort+ktXg89ZKzwwtYBF+K/UGaeM UqzDhAopQBGRp0B91h3gt17G7bwAERjcvgzH+VWoZXoiUs4Gy8dDsdvN77EcZg0ks1e3 iYLQ== X-Forwarded-Encrypted: i=1; AJvYcCWcXFjPPhTg2EYjpR+9vD5kzm0QgBgMZF4hkUD4BlqnQWpSvyJINZr31vnrImJea4bhUL5Fw5ugYF30@nongnu.org X-Gm-Message-State: AOJu0Yyr6/EacfY5q2Hde1pTQG8Xq7qqumB+Y7Ksn7zBWYpN7zscxFXW M2nOOpsnl6IqeHzxhPr+LzNt+G8cy5TZ6lowNLbtAGHo/7/yoI0iBFg6CdLxwyjlyoja+GvJPO2 E3hbvplHQBeb3PlWR6g== X-Google-Smtp-Source: AGHT+IFZhDR+vh+kuynIcVAxf3GbvjB/ncgWkyQSmW0gDVUzvv6yS2h499GC8W5hXkls5C1vc5Jx5D8QVwS7qww= X-Received: from pjblt11.prod.google.com ([2002:a17:90b:354b:b0:33b:51fe:1a8d]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1648:b0:32e:e18a:368c with SMTP id 98e67ed59e1d1-33b51106a8emr38759811a91.7.1760491119120; Tue, 14 Oct 2025 18:18:39 -0700 (PDT) Date: Wed, 15 Oct 2025 01:18:27 +0000 In-Reply-To: <20251015011830.1688468-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20251015011830.1688468-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251015011830.1688468-4-lixiaoyan@google.com> Subject: [PATCH v2 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, philmd@linaro.org, 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=3b_buaAkKCmYPMbMEScERKSSKPI.GSQUIQY-HIZIPRSRKRY.SVK@flex--lixiaoyan.bounces.google.com; helo=mail-pj1-x1049.google.com X-Spam_score_int: -88 X-Spam_score: -8.9 X-Spam_bar: -------- X-Spam_report: (-8.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.269, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.998, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, 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: 1760491198315154100 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.788.g6d19910ace-goog From nobody Sun Oct 26 22:32:32 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=1760491196; cv=none; d=zohomail.com; s=zohoarc; b=F3A/wmzbIp44Mv0Htf1c+/tV3QGhSid1XvFJygBy+e3VLZnevtcXp48qC6yFz0UtgpFk7GjJR2xaRxXwksMapyPUFWqPbfg7gey39KaxuxiYIgoX5ddtHVNakRoqrduvg0j45ubq+djydTe8IhKg8+GQICxHg2Wt6i5+JkG5fjo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760491196; 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=eVtsatoZMAyWklDZk+xoLWyrBthGxAc11mIvq/IWMzw=; b=duVVchWO7hA6q4prkPMyYWlVabc+9oKR+0zpBc9/FbXISmA39IL+QVbAgxBJzMGLHrZixgHBemdj+B7hRjVpQ/fM6h3b6jdUQRhOxNhY3YQA3v1kFiIuesG9zhTS722GyNhFy+JisbK1iLQqDl7fzjW0f2V3+/hMTnbwbozVX54= 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 1760491196643889.9159697362301; Tue, 14 Oct 2025 18:19:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v8qAC-0000SF-PU; Tue, 14 Oct 2025 21:18:48 -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 <3cPbuaAkKCmcQNcNFTdFSLTTLQJ.HTRVJRZ-IJaJQSTSLSZ.TWL@flex--lixiaoyan.bounces.google.com>) id 1v8qAA-0000Rw-W3 for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:47 -0400 Received: from mail-pg1-x54a.google.com ([2607:f8b0:4864:20::54a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3cPbuaAkKCmcQNcNFTdFSLTTLQJ.HTRVJRZ-IJaJQSTSLSZ.TWL@flex--lixiaoyan.bounces.google.com>) id 1v8qA7-0003Dj-Gl for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:46 -0400 Received: by mail-pg1-x54a.google.com with SMTP id 41be03b00d2f7-b55443b4110so289906a12.1 for ; Tue, 14 Oct 2025 18:18:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760491121; x=1761095921; 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=eVtsatoZMAyWklDZk+xoLWyrBthGxAc11mIvq/IWMzw=; b=Lv2H0z4PzfTo56pzG+qbm5wU3ooAQft2oSd+/t9+VxWDi6j/xFApBdJ2dy/Nb6lKcI mj7KkoAvPiEgcpQVYCStVaJYRdja7dg6eYzNFGJfTE0GezlvCDfWrIJioco85GTqjjQY QIFrJRZzhSbX3sMulYAWf1a/Pxc2fVYMxUqEhw88HouVODHnhaNPYSjtKH6fP4ASHcKt QxJ3suRTyxYMnBJr1+FGUPcR8YIrP9pydVEYlWny8+p1TlN/paSIzkqMWzzWg18/EdP+ W6xarRCX+/BDbMFBO+A3cmwc6wBuetjVx+uxMEEgG+4g9RInKKeFh4RCTH6byR2PFNMG /1eA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760491121; x=1761095921; 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=eVtsatoZMAyWklDZk+xoLWyrBthGxAc11mIvq/IWMzw=; b=Av/wCXfVrSJsmUoKL67Phf7avCiuA2Kn5GMeb2vqroptp6eIck1tP5QJ7U8smv+WLV HXKLlICE+zSaz9iMEKPPYzEIXrgRETBoBQqAWuU8LoPs19kScgAsa6O9HiMQC9hAeK0h YQ0IcOngTivL1gXRVlRByHCzlpuULGiZ4DZDptaJh0R9wtOLfwM+gZIZe6d3j48c49by /4hL21EK9Z/aiMSgjq7IRVxQ9GVrXp1eO3AxLWQieBuhBCguzSF0t01OyyuFDU7BY4gd sX4HO71ypRaI0upJEeSO1n23FuhZsrjgejwovbFtPVP0CS8QtMhCfZ4aArHnGF5+qorO 1NSw== X-Forwarded-Encrypted: i=1; AJvYcCUbuCsrGhRm8vqtAbl609TY9GTp8O28b2w1CL3LeBRPCmuRzPIxktk+mv9U70+7f5B/COIkZ2L3aH2w@nongnu.org X-Gm-Message-State: AOJu0YwpanYPPuFn5VorGMCqBkN2P/XGH8cZOW6HugUJdD7+H/Fekrs7 qvSvjyfmfFVo1GmVSFAFIqBJ3LsPy8L4QhqXtYJo8LnG1A3hvrgWwdXXTYUbE9QQ4Q1qa+fjg8K Wr6eN4GwKTS6RN544AQ== X-Google-Smtp-Source: AGHT+IE+bNMBhXEp7rbrz+0VF8BRk8bJhPAtNgmrKxD03yUV7e1XektPbpKX3OCcfU3O/DD0LmYu+FdjOzUIvxQ= X-Received: from pgvm3.prod.google.com ([2002:a65:62c3:0:b0:b66:e6b4:6629]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:7a49:b0:32d:b924:e5f2 with SMTP id adf61e73a8af0-32db9250c46mr32298763637.28.1760491120907; Tue, 14 Oct 2025 18:18:40 -0700 (PDT) Date: Wed, 15 Oct 2025 01:18:28 +0000 In-Reply-To: <20251015011830.1688468-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20251015011830.1688468-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251015011830.1688468-5-lixiaoyan@google.com> Subject: [PATCH v2 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, philmd@linaro.org, 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::54a; envelope-from=3cPbuaAkKCmcQNcNFTdFSLTTLQJ.HTRVJRZ-IJaJQSTSLSZ.TWL@flex--lixiaoyan.bounces.google.com; helo=mail-pg1-x54a.google.com X-Spam_score_int: -88 X-Spam_score: -8.9 X-Spam_bar: -------- X-Spam_report: (-8.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.269, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.998, 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: 1760491200090154100 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.788.g6d19910ace-goog From nobody Sun Oct 26 22:32:32 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=1760491197; cv=none; d=zohomail.com; s=zohoarc; b=V5buPsZr8EL5JmvRgaNm7T2QdDPxlial9j/FiO8HhdyTp6O5MRZqLtKHJz8B7Nj0vikyoP1xWSwLWf5xtP8gPbGUwSe2PeVkvdx/j+VeC54Z9K4Mc1Br05d5W12fjGfZVh9P1j51C75w//zsNASxsxUxMkQB9aTvjAHa/yfcNvM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760491197; 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=Q7/3ZvEpKFWHtnVX2g4BdVcaLMqo1fyjcOBAgiuCIWc=; b=AypwWrRtoXlpUsN474iUEPuKaGGkjlxsaQRZWa0Tut2yVyaD1Nr0UDxaBdlDDdP6IiM0E8bYj2zOIZe86lYmy8dqGEbpwgZzEfWXuvOxRinlE5lX+IFXTAGV3TLlo+OPHBS+WSVrJJ/nuazfJx6DBZvjpsD4TNTD9fAmUqdbf5E= 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 1760491197948912.1181968463969; Tue, 14 Oct 2025 18:19:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v8qAK-0000Tv-4I; Tue, 14 Oct 2025 21:18:56 -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 <3cvbuaAkKCmkSPePHVfHUNVVNSL.JVTXLTb-KLcLSUVUNUb.VYN@flex--lixiaoyan.bounces.google.com>) id 1v8qAH-0000TN-M9 for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:54 -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 <3cvbuaAkKCmkSPePHVfHUNVVNSL.JVTXLTb-KLcLSUVUNUb.VYN@flex--lixiaoyan.bounces.google.com>) id 1v8qA9-0003EF-El for qemu-devel@nongnu.org; Tue, 14 Oct 2025 21:18:52 -0400 Received: by mail-pl1-x649.google.com with SMTP id d9443c01a7336-27eeb9730d9so109929325ad.0 for ; Tue, 14 Oct 2025 18:18:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760491123; x=1761095923; 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=Q7/3ZvEpKFWHtnVX2g4BdVcaLMqo1fyjcOBAgiuCIWc=; b=OB+W8QRY2sfBoBKrOVcMUMSN4HGI9oponbyMhUJTXIyJkovWL+VaPDv9ighQsZJxcN mccGaKHhy8gGigharufFNOtIULacv9y4caBz9aJC1GZFU1Ifp2aBt4xDP4Nfyj0iMqWX KjOIN+b/DMAdMVerjnunF+8eanzFwnIGmOnqyB7k+jA84sOJQbbDSpAK7WgEcne6G/K7 N2o7nihzZQjQFWI9zWoup6LaJ7rO7APf+Irb0fCUi6ZYut5lEjiiCDN35rrGwn62exWE /orBaN7f1dYE/a5e3IB4JT0/csS1QdtF5xLPnFMuzp1ZWVzchJvxAu7jkSkU1FoFODhr rcDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760491123; x=1761095923; 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=Q7/3ZvEpKFWHtnVX2g4BdVcaLMqo1fyjcOBAgiuCIWc=; b=UtmTRbBFHtX2Pi+bSMhYExwkjMKHTJLEMPQB70VakuzQQdWuQustvABXc02WDYXhRV xIz57p1+EyNElMyiM7UXrTdREkPlawUgVWSEU3JRl+6kUKba2+YPKN9Mq8d6++0zin0g wpZdq8RAcgMai+sTggVX+MxwEYbFte0H2D5IvbzNGjNEYPnPsAn7AM9LxDnLBuvqDVpp UjGHgJis5O8JdXOhlM5Fce5D/vje95lAuc290GASIyaqldCFrRw5wXTgy/htPob8FFLE Z3IOQnatjot7f+gAxRtg8awmRSP08yt6O4hXoM1vWjo+W25zJ51uPBnT6nnu9MaZep88 1uug== X-Forwarded-Encrypted: i=1; AJvYcCXbmvi3MTyl4M8pKBCJGDRmjWigVWdWyhPhGBmjFdXDqKdMJrpXbKEnrItAlxbVGyxS9T6Oyq0E/Jjd@nongnu.org X-Gm-Message-State: AOJu0YxJEkB0zxWs0+XVytVrdIvfLCHzXoqtHB7h6j+taiLY1U81irAz ohiEPC21o4sOVoo0qsJvIJZ1xNQT1Y3GXyyzeg7EqXfe4VcuAV8IT3olF2tCARNvm19KQnd8TmZ 40SCVo8tCHqpp5NEJ7w== X-Google-Smtp-Source: AGHT+IEAdrtGFaLFJ2pKtaMTcnKO4Iux0rfrD29OGpC4I1D/3asjXup5T3qscAu9V0fIZzl8UTisLBOAAM0/SSQ= X-Received: from plsq3.prod.google.com ([2002:a17:902:bd83:b0:27e:ec80:30c6]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:d54c:b0:26e:62c9:1cc4 with SMTP id d9443c01a7336-29027356c83mr273672705ad.4.1760491122665; Tue, 14 Oct 2025 18:18:42 -0700 (PDT) Date: Wed, 15 Oct 2025 01:18:29 +0000 In-Reply-To: <20251015011830.1688468-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20251015011830.1688468-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251015011830.1688468-6-lixiaoyan@google.com> Subject: [PATCH v2 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, philmd@linaro.org, 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::649; envelope-from=3cvbuaAkKCmkSPePHVfHUNVVNSL.JVTXLTb-KLcLSUVUNUb.VYN@flex--lixiaoyan.bounces.google.com; helo=mail-pl1-x649.google.com X-Spam_score_int: -88 X-Spam_score: -8.9 X-Spam_bar: -------- X-Spam_report: (-8.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.269, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_FROM=0.998, 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: 1760491199727154100 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 | 119 +++++++++++++++++--- include/hw/gpio/npcm8xx_sgpio.h | 4 +- tests/qtest/npcm8xx_sgpio-test.c | 180 ++++++++++++++++++++++++++----- 3 files changed, 259 insertions(+), 44 deletions(-) diff --git a/hw/gpio/npcm8xx_sgpio.c b/hw/gpio/npcm8xx_sgpio.c index f7d6bbf672..fac24a2d8e 100644 --- a/hw/gpio/npcm8xx_sgpio.c +++ b/hw/gpio/npcm8xx_sgpio.c @@ -22,11 +22,14 @@ #include "migration/vmstate.h" #include "qapi/error.h" #include "qapi/visitor.h" +#include "qemu/bitops.h" #include "qemu/log.h" #include "qemu/module.h" #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 +129,67 @@ 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 +/* + * 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] & (uint8_t)half_unshuffle32(type); + /* 1-0 transitions */ + sts |=3D (~p[i]) & (d[i] & (uint8_t)half_unshuffle32(type >> 1)); + + 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 +205,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 +340,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 +415,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 +486,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.788.g6d19910ace-goog