From nobody Sat Sep 6 14:55:36 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=1756938149; cv=none; d=zohomail.com; s=zohoarc; b=d1+v+K4aITcBfTHQljFHHbS0Px17bRWnJfR+WswcHUMNunkgFA1yBK76sxMQdJBYT93lpUYtHwRHxZvMpDlOzRZfKJb+BTzKGZhAk1vPi0I837khyMlh+LFzhAiwzDIoFSRwvDZe6+lB9TugrtE6AH8dCpmZnS4IGl+e87yW1po= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756938149; 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=7YmXbfGBvimAKdLcD+dHyCW8+I0vDsbzJdW19c8VFSA=; b=fURXU0eOckWcRnKU+VsYKijyuJS8XVb2q8hAsHoCX+FglD7embyiU+7Ir+tyFa+zRGZrOk4LGXucevmP9DBQpAJTY9zTen3PnmrW5pIc9An3GrDvzAds/eK54JuHgMMSibF/Y0Z7uGJkhQIrF6LrhkiG3VjD6vMGNGP4L0OcKiI= 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 1756938149808236.29224727856558; Wed, 3 Sep 2025 15:22:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utvrH-0005Dw-4I; Wed, 03 Sep 2025 18:21:39 -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 <3SbW4aAkKCuIPMbMEScERKSSKPI.GSQUIQY-HIZIPRSRKRY.SVK@flex--lixiaoyan.bounces.google.com>) id 1utvBN-0005jO-Mi for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:21 -0400 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3SbW4aAkKCuIPMbMEScERKSSKPI.GSQUIQY-HIZIPRSRKRY.SVK@flex--lixiaoyan.bounces.google.com>) id 1utvBL-0003S5-Ta for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:21 -0400 Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-e931c30dc0eso634923276.0 for ; Wed, 03 Sep 2025 14:38:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1756935497; x=1757540297; 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=7YmXbfGBvimAKdLcD+dHyCW8+I0vDsbzJdW19c8VFSA=; b=gAsmMsqz0f1DObFDFhkAhJGGmCVkZ0g3L8Th4/BSZCdEvj4yAk8stmSYqBrrUUbm1W O2qFzIa8uSe6Qd4X0bsiN10LFBwC+WYe19SZLtUKJ6Kp0x1ShpSLkx/wkEawF0ht1+PF aAtwMhNYYpzJ9vb8tSiyEuXNgXQ4M/XaInwd13YsWkq1uUZ/GUPmxTaG9kLQ4DYudYuC ABlb/C+xYsdOsyIWrTyHGiFE8+uVI9M/ZAaeVQ9ccFPuwWknbb4lbSVtKfoiLJTaW2aU 5S9WAY7zXItqxbOg/bWbrRlpcmNlRJpINbxszDLEScJoBvmqNYiva9zYTtY/GFez/n5C Fvsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756935497; x=1757540297; 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=7YmXbfGBvimAKdLcD+dHyCW8+I0vDsbzJdW19c8VFSA=; b=VnesSrUI8FuQRD+YpOiXmpgbegwWN3JJxGiyoHhBzhjIGGD47Gy0cjN6MyDmkrmwZ2 tRoPmQcTfTCv+I0mXi+5LBAS05tY/XD39MCbYFQqfuiWViinRuig7IyshPrbR0bp4rZB QjM72HtU/T9Twxk6hg2+ITTg5myT9DkC052hA60s/XNutL5mxzeXnpx9Y14O0nPrzi5O aDXGUA3WlVFU3UjUpwATNHQZosdOIe46b7kFlij6c0JGXVclyrmhu1t5SEOxvFx3q1T8 qtZfPyozqVmFJuIypQdhLA+EWIa6oqOzsCL+XwG88o/evjE1tchxVJRb36vdHzKtSO// glVw== X-Forwarded-Encrypted: i=1; AJvYcCVvaser6aC/NBx7WyhZZxu+VPnwgPMvJIBNW/avn140m5/EWCQgANxyRO+UIOta9QtsCVH36tQ7Mm2F@nongnu.org X-Gm-Message-State: AOJu0YwktTdXV9qBX8lOuOhABmjEergNN7YVQHfZ6QgiBGnU544tLw7G web82YjW7fn5q978kDzflb0wDaevYpjn7ndw/9QXTfpmKU0SuA/6+gRmF0LGa6MFJliZFnTCG/Q aXIhWIwykO5h1brkskQ== X-Google-Smtp-Source: AGHT+IGnr80oMbMZwKeA62+/WdLQoGMgHXnxIa4mPkQDbm6ESxOgMgJRfSEzlQcjN/4REELZ42qrkChL1I7Yr2Q= X-Received: from ybey126.prod.google.com ([2002:a25:dc84:0:b0:e9d:6756:ec1f]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6902:18c4:b0:e8f:e04f:ef9d with SMTP id 3f1490d57ef6-e98a3654661mr19462528276.0.1756935497485; Wed, 03 Sep 2025 14:38:17 -0700 (PDT) Date: Wed, 3 Sep 2025 21:38:05 +0000 In-Reply-To: <20250903213809.3779860-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250903213809.3779860-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.338.gd7d06c2dae-goog Message-ID: <20250903213809.3779860-2-lixiaoyan@google.com> Subject: [PATCH 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, Felix 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::b49; envelope-from=3SbW4aAkKCuIPMbMEScERKSSKPI.GSQUIQY-HIZIPRSRKRY.SVK@flex--lixiaoyan.bounces.google.com; helo=mail-yb1-xb49.google.com X-Spam_score_int: -86 X-Spam_score: -8.7 X-Spam_bar: -------- X-Spam_report: (-8.7 / 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.938, 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-Mailman-Approved-At: Wed, 03 Sep 2025 18:21:24 -0400 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: 1756938151134116600 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.338.gd7d06c2dae-goog From nobody Sat Sep 6 14:55:36 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=1756938148; cv=none; d=zohomail.com; s=zohoarc; b=CF7Uk8puSwQ4YtBh1O2VxF0ViXt+lGp/Ja8FFp0NMfJmk9wW4+zbpdlLSByVCpWbS7HWGWBlNXSV+Hi8VFjWNPHiaYFdC/hJ4enIjglWAGaICigNre3IgGFG3pUfgwq0nT+3J7JsGia+99RywUXYUznZJtRb9s2sdOrCYvF7354= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756938148; 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=+zcM05GvvS4GHeBuorcNVf0xKSlX7M5kidK6nG2nUik=; b=SdGcyAX43sb5PIPQ8BcN8cv7afcmFebf9qS+50K1kJD3Zkn7jA8GneN0l4fQFflN50sdsXORj4AdwTCpSFsEd1Qmre4vcfWE1dRbX5EDMiJwjob5yjvlDEhIuF2yL7ekimd57TxfnsRVC58HRST8MyUOeL1QYXpKGGiYSv5guLc= 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 1756938148560360.6518161146338; Wed, 3 Sep 2025 15:22:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utvrE-0005Cv-4f; Wed, 03 Sep 2025 18:21:36 -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 <3S7W4aAkKCuQROdOGUeGTMUUMRK.IUSWKSa-JKbKRTUTMTa.UXM@flex--lixiaoyan.bounces.google.com>) id 1utvBP-0005jv-50 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:24 -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 <3S7W4aAkKCuQROdOGUeGTMUUMRK.IUSWKSa-JKbKRTUTMTa.UXM@flex--lixiaoyan.bounces.google.com>) id 1utvBN-0003Sl-Dt for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:22 -0400 Received: by mail-pg1-x549.google.com with SMTP id 41be03b00d2f7-b4f705186bbso192835a12.1 for ; Wed, 03 Sep 2025 14:38:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1756935499; x=1757540299; 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=+zcM05GvvS4GHeBuorcNVf0xKSlX7M5kidK6nG2nUik=; b=N1mcdyl+PpiO6vqJ9ku8No1mCwHCfgdwSG4eV5i1Gm7W1rgHA8nwmPcx7s6FcmSDmU Lk5yr6VyoESLnFPuNJ33mki3gJq5o7pbV7EtoDKktWExEXV5eyHWFXF2DbJVulAu0b8E CZKgIGinJ4iEdkllWElmgDYranC7XzMWwWsCvLhbYzNwrMBgZvz1glOWaF/sps7h8XuV YJeRQt0zrfWJ6oI0VvJqyuXy7mcstSBSFCwg3idsC6wkxUWsXxHK8jPcVMx/aGT0dZ16 rtWOOCqgSQ9cYmjOmahM2SFtrZ7AGHlUF4K85x3zawlZuDftTGTNHx57Ioq90oVrYicD Yeuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756935499; x=1757540299; 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=+zcM05GvvS4GHeBuorcNVf0xKSlX7M5kidK6nG2nUik=; b=LUdYxEhK8ZexedBuypZxRcDo1oPl8xSczaehe4hqU2XYBgUBPL3X4PPq9piDoDcj4x I4WTEtHQz0q2n45opA8HYpn+pJUEGNn+RuV8JZNOpAg3/2yrFqGfkbnhE9/yVv7v+J69 L70DC2oj542ERrHR8/XzkVQ9/xnHbCvW1VqkhIIhBfC24BtoDwLDoIX6FiSNWqA2dIEQ Z4p4hctFhFQbzFDfuKfK5RAb8FTOennWxK/AQvcrd61nYL5sWPNNUQy4Wn8UHYg3sVti 6n81gynhQixaUzhMz9SRubprqPD9zWh18ZlgEG4BDYYofIbHfadqzZjN39wQ4tP7cIXJ DGlQ== X-Forwarded-Encrypted: i=1; AJvYcCXtQK8Sw1qD5/OFq8ZAluRx+9Sa+1Kn2VwSZrEd1fWWRiPmITntKeang/IF3NzKkCP38oG5iUL/klMF@nongnu.org X-Gm-Message-State: AOJu0YzbXOZpgnp8kIMB2Q+jbEzIE+xGhk3JXFr6i4bn78ue7XAAdaGh oHxno3Qouqjofb7DFY/WbXuEtoscvCJLdK9XWYtDqKvx7kfCg3V77OOnMrxOhe4O5MoelDNO44o 0l4OzeIyifJZlW619Bg== X-Google-Smtp-Source: AGHT+IFcjX51J6O7Fyq91Ztstg7JQkQF43UdkglqQqw5eUmnPiM1PoCkackREdp2JddDcdT2E7C6UwTxO0nv0fY= X-Received: from pjbcz3.prod.google.com ([2002:a17:90a:d443:b0:329:b272:45a7]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:28cb:b0:327:b33e:39d5 with SMTP id 98e67ed59e1d1-328156e5d7emr23401472a91.37.1756935499113; Wed, 03 Sep 2025 14:38:19 -0700 (PDT) Date: Wed, 3 Sep 2025 21:38:06 +0000 In-Reply-To: <20250903213809.3779860-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250903213809.3779860-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.338.gd7d06c2dae-goog Message-ID: <20250903213809.3779860-3-lixiaoyan@google.com> Subject: [PATCH 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, Felix 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=3S7W4aAkKCuQROdOGUeGTMUUMRK.IUSWKSa-JKbKRTUTMTa.UXM@flex--lixiaoyan.bounces.google.com; helo=mail-pg1-x549.google.com X-Spam_score_int: -86 X-Spam_score: -8.7 X-Spam_bar: -------- X-Spam_report: (-8.7 / 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.938, 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-Mailman-Approved-At: Wed, 03 Sep 2025 18:21:25 -0400 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: 1756938151323124100 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.338.gd7d06c2dae-goog From nobody Sat Sep 6 14:55:36 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=1756938148; cv=none; d=zohomail.com; s=zohoarc; b=mW1GnJGIf1vMwAo8TRNqjq337M8LLzOKr0wk4oyawNHoyYsFYmK0GGwaVvAjU7NhmAADl3pQAJZaDoiAvrfX1Um7splIAPrrBY7Qqz+drwKs0ugQadYIz4musEqKyjyNKPRO3a28nKW4Ngp10+S3lb+4OabJbm90OqV9hIPtMw8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756938148; 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=X5hS1tZ22zNRIVkY1EfuAvsxIjxJYrjbWB6arPiOJWo=; b=b/5LfpxOTd0jEaK48ekziRWQN5EQjR4YVdogVne3sPBgvqnTtURr5XG2NWrwGlSJZYAbUWMW17+QjshDaoQf9/m8ewZ1O+3fRvZ4JBUVhT4NDJBAPWLOBU1Dv5NJOYfCcQbCZkXuoKJG9jBYVRcWpplF+AeuFmpfSxYZ7cxiMh8= 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 1756938148635259.9580902906455; Wed, 3 Sep 2025 15:22:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utvrG-0005Dq-Vl; Wed, 03 Sep 2025 18:21:39 -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 <3TLW4aAkKCuUSPePHVfHUNVVNSL.JVTXLTb-KLcLSUVUNUb.VYN@flex--lixiaoyan.bounces.google.com>) id 1utvBQ-0005k0-1i for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:24 -0400 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3TLW4aAkKCuUSPePHVfHUNVVNSL.JVTXLTb-KLcLSUVUNUb.VYN@flex--lixiaoyan.bounces.google.com>) id 1utvBO-0003TW-Il for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:23 -0400 Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-e9d6c0373a7so297123276.2 for ; Wed, 03 Sep 2025 14:38:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1756935501; x=1757540301; 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=X5hS1tZ22zNRIVkY1EfuAvsxIjxJYrjbWB6arPiOJWo=; b=zHGJ8itsOg1Au+KLlraW8NUUpcjNwsT7g9XCZpLV19rOXDH8VzBGFZSROaGoPSJyfJ kxJ/GgBIZUJ+eEoNpoGSAxjGShxoqhaKn+xkGOBB7abhV1Y+Tc2NuCZX6AC/ymKpi89o GJyInSKvJ4lhxkgK0dncs6+hA+OJ4AiNRP1bOCpf0vL8ZoJF2P+6ljQMIJBCLEBo3IId bF0uBJsTahPgYv5KnzLaaVWKD6zYvNuQSHKZaUVIAU9SqW4Y/WKPeL4P9Yf2HFZVzg21 yTvsixe1aOR/oLcQVSQIEJ3mAY5J3g8wmYx7Z7xYhSukMSvanFluKuW0jL5QTjBLhd20 bmYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756935501; x=1757540301; 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=X5hS1tZ22zNRIVkY1EfuAvsxIjxJYrjbWB6arPiOJWo=; b=hon835L8OWkJ4Ut5L44ZKQuFLgeem2FlFmIYJHkK2Hm4dcWCScA7CFvKWU/xHG9KoJ dAH3WNOF0vwvL7TNetvP0CeE3MBcoj2cdXNbzUgDO5TzHYlBFVgxCCu/0qyWjcZK4ogy yiDvARGIaCTl5zK7ks9KXjA3mDUOepmEVGlgCfZ4OtUkJzZcNK16mtXotlq5fNPVdAS7 HCcEF3G/vRv4DYJyBepItcRWwhCHgogurm0FEwpNqCzAkjr8qFboLQZ2/KaniyoMhZsc 0xievBXQ4cDwtywzTXt+vR8nlbuV8Tli1oQ7ljHPLX+Lcw0VpiF39ofB95u0B2tjnLN/ sBsw== X-Forwarded-Encrypted: i=1; AJvYcCVpXs5rTNnBIIpcAHjj57G+A9khgxNrj+GPrXJ3C27SUNbIcXDGvaB0Zn90s7I6StvSDCBod9Eysukr@nongnu.org X-Gm-Message-State: AOJu0YwUhtzm7F9WQb+sHVDNvERZphg+R8RijazyGgL7hfkGdA+hJoj7 9T5qTCZPT+lAjhbLWq7WqSzJSKMDLKX/qpFHTmuizc5XhKiPEZ1Vv1fVz0fq5wl2Vb5UjTQJKK7 Acob/t7Quw5qFTGBV6g== X-Google-Smtp-Source: AGHT+IH20bEt+lOXFlacb73BNjN3iG6qx3SuvvCV81+aK3lDiMZblYU8I9joK91/dKCzOzCRs4ptqRWaDsgvKFU= X-Received: from ybiv44.prod.google.com ([2002:a25:abaf:0:b0:e96:dd0e:6347]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6902:1004:b0:e9d:6a31:d514 with SMTP id 3f1490d57ef6-e9d6a31dacemr1383224276.44.1756935500853; Wed, 03 Sep 2025 14:38:20 -0700 (PDT) Date: Wed, 3 Sep 2025 21:38:07 +0000 In-Reply-To: <20250903213809.3779860-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250903213809.3779860-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.338.gd7d06c2dae-goog Message-ID: <20250903213809.3779860-4-lixiaoyan@google.com> Subject: [PATCH 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, Coco Li , 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::b49; envelope-from=3TLW4aAkKCuUSPePHVfHUNVVNSL.JVTXLTb-KLcLSUVUNUb.VYN@flex--lixiaoyan.bounces.google.com; helo=mail-yb1-xb49.google.com X-Spam_score_int: -86 X-Spam_score: -8.7 X-Spam_bar: -------- X-Spam_report: (-8.7 / 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.938, 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-Mailman-Approved-At: Wed, 03 Sep 2025 18:21:28 -0400 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: 1756938151316124100 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.338.gd7d06c2dae-goog From nobody Sat Sep 6 14:55:36 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=1756938172; cv=none; d=zohomail.com; s=zohoarc; b=ZX9qzeBshewE3AdiObuIFfyNY8quQVcYTjwlbGYADPoB0rFG+1aF176hrG0ShYC33KjnUH1c0xFDt9VqlW5nbyJHNhzk9Bs/yYQUVZs6ikq/NxOumJKHyGFlnfxZEXQDczP+I35ryHMsgG/aWF0uhOjrkw72Xe9ZLL6/vSTV7bA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756938172; 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=SrGT8mK3eU7NDISL1rYuOdki1JlP6DXqDgaUQmA7gFc=; b=TtPT10h+TUBlRRPRlL088zY2sXnx95rGcm/7ESyL7oWGgjjmJ2MrmYTu8E2R9TnN4hucvCR9thQrSYDOm+AUhkjk0haNandaV+fEWKlC158e+aCm+xLh65XIgRjgpWBJKF+37ECto6HYvejF9oSKc4awGRboondo53kAXOqbuU8= 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 1756938172204562.0751961998026; Wed, 3 Sep 2025 15:22:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utvrH-0005Dt-0W; Wed, 03 Sep 2025 18:21:39 -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 <3TrW4aAkKCucURgRJXhJWPXXPUN.LXVZNVd-MNeNUWXWPWd.XaP@flex--lixiaoyan.bounces.google.com>) id 1utvBT-0005lG-W1 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:28 -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 <3TrW4aAkKCucURgRJXhJWPXXPUN.LXVZNVd-MNeNUWXWPWd.XaP@flex--lixiaoyan.bounces.google.com>) id 1utvBQ-0003UP-Cq for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:27 -0400 Received: by mail-pg1-x54a.google.com with SMTP id 41be03b00d2f7-b4f705186bbso192873a12.1 for ; Wed, 03 Sep 2025 14:38:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1756935502; x=1757540302; 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=SrGT8mK3eU7NDISL1rYuOdki1JlP6DXqDgaUQmA7gFc=; b=RaijRd6EBgT8jHgRo8EgraW473OefPbS8Ave9ZzH2/DFrVkbiuYxpL+JjKZLCMUfvw f9iyd+MJyn67HhQcnnMn4NGnL3DkzgfjS0W++oCXEwh5Dd7BpGM/EW5gnU65zeGNkS2a 9Gc0tVV1Vo9AWeK0m9QXi5s4gyMztNdBsKuyTSz7vLXL49+0paBOheqCGXr6ahcMvTme i4XD26uaFulOdgrx4oHk2gzaMGXrAmZzZy60WHRZAZBgctkNADskQMl4F/EAhvTcZeOO L5VciNnMz14RcuWUu9k+DpqQd2RH0C98o1BO/apFRbGaJsgSWyg4S3J3nCoPb2dFeEb4 2Zew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756935502; x=1757540302; 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=SrGT8mK3eU7NDISL1rYuOdki1JlP6DXqDgaUQmA7gFc=; b=ittQ9adeEytVo+YpprMwMRIIWZaH7FPqDXo0/zpi/1FH9nYSOUOxOSGHVUaMvbhuuN G3SJhM7Xouc3I95uAakA/8xhdrIJqxGnV0crqtrSQaBZLyrgMbSpYeFq86cnYEqNo5fu s82s6RH20V5p0RfFNRqUi7luWl0ZH/hbfmmhQWuhxt/tlM/1qi7ol+wayzu1BH8GuTVR SYt/o/zXgYo2NhIZwFtMepmOQfUNH56JkBUzsufa46arj+gi946m1UryCV3t/Z+gobmm mUYLNQy7ygTjulhLujo8SMEwUTIxk1s7fG45IPCjsvM6JxxpsU0VX7gF4x9w7sky9wsr ILIQ== X-Forwarded-Encrypted: i=1; AJvYcCUPqnORTldZnle8dEPE48znuloFSTiV8Q95S5L0s2D/jqRDFUyUlcg5Oist/PAgoD74EIn6b+tydlK3@nongnu.org X-Gm-Message-State: AOJu0YzivM1Gzxboy7M10M7IiWCw8mbJXBynnt0GNjunaIxcZK1xM1Y2 6FCtJlvjPhH3PWpYbY6+8gLhfIGZ26FZAsIW0kg5Hj6y0mQag6nyhZh0Q7EEzz2UuDl5UCOaskq G/RLK4BY70TGuVZRAOw== X-Google-Smtp-Source: AGHT+IFsTSkspzVnAAAgmq1dmLaTpbRmvNTffAlrzXfWmaXvho6QdfgIlIDFHU+U13yoeogPg6pv7vTT4EAMrLo= X-Received: from pjbpm5.prod.google.com ([2002:a17:90b:3c45:b0:324:e6a7:84ce]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1d45:b0:325:42f8:d73f with SMTP id 98e67ed59e1d1-328156bb311mr26095868a91.17.1756935502574; Wed, 03 Sep 2025 14:38:22 -0700 (PDT) Date: Wed, 3 Sep 2025 21:38:08 +0000 In-Reply-To: <20250903213809.3779860-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250903213809.3779860-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.338.gd7d06c2dae-goog Message-ID: <20250903213809.3779860-5-lixiaoyan@google.com> Subject: [PATCH 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, Coco Li , 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=3TrW4aAkKCucURgRJXhJWPXXPUN.LXVZNVd-MNeNUWXWPWd.XaP@flex--lixiaoyan.bounces.google.com; helo=mail-pg1-x54a.google.com X-Spam_score_int: -86 X-Spam_score: -8.7 X-Spam_bar: -------- X-Spam_report: (-8.7 / 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.938, 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-Mailman-Approved-At: Wed, 03 Sep 2025 18:21:31 -0400 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: 1756938173789124100 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.338.gd7d06c2dae-goog From nobody Sat Sep 6 14:55:36 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=1756938185; cv=none; d=zohomail.com; s=zohoarc; b=m4WtjHUT9W1+Xl9U7qEZafLxb4fBpIitU0q/Yl4YwVfzVfrV4A9WQzdvjtIvZVL/3edE51koC3LnCX8UMBXk4/tIdPo6Wrdhptvcvrf22IjJweTi0cVY4NfG8pgDDOYmtYL9J5ibSqDXxr6LvsD+ZUEFJSimKW2IuLldfJZO0C4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756938185; 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=uenE3pCs9FFLs4/r5/tRBI0mdODh/rTI3ufCG8qlWUc=; b=FLv6uSd3r3v/so2BRvf2bhc9F7ziRSvwA0B4+xymLMOKzGCQUvAkQIari52e1Xt+Q1kV8us6G9cJjn3F9U7Da9QYuMKaO853n6hPIfuPKqcixvgPeobJlAiku/lt8Jdk7CWVY6xN0ty1yn3Sgzr90KkO9ZY6fUEtxB8us3ezjLo= 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 1756938185706674.3874645042531; Wed, 3 Sep 2025 15:23:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utvrI-0005EJ-5P; Wed, 03 Sep 2025 18:21:40 -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 <3ULW4aAkKCukWTiTLZjLYRZZRWP.NZXbPXf-OPgPWYZYRYf.ZcR@flex--lixiaoyan.bounces.google.com>) id 1utvBV-0005nG-BW for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:30 -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 <3ULW4aAkKCukWTiTLZjLYRZZRWP.NZXbPXf-OPgPWYZYRYf.ZcR@flex--lixiaoyan.bounces.google.com>) id 1utvBS-0003VC-AS for qemu-devel@nongnu.org; Wed, 03 Sep 2025 17:38:29 -0400 Received: by mail-pj1-x104a.google.com with SMTP id 98e67ed59e1d1-329e0a8337bso274590a91.3 for ; Wed, 03 Sep 2025 14:38:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1756935504; x=1757540304; 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=uenE3pCs9FFLs4/r5/tRBI0mdODh/rTI3ufCG8qlWUc=; b=fovB0piapkICOunFVfS8WUanMltWW2C6hKsiVb7iDLj6CI/K+Olmy37wmUS14NbtWl g7BfoQRKlcFRmJwnx+XsC0BY7cjZluEw4U0QENQ7sRQAAHBMfDhfCrA37s/XgkG3MXFD ATPfkpuWU5D++VuO3A0nuhp9SAQjZBilf0yN9uhf2be8Q/HEQnep7R6Md1lY9wdlXAko WLA2zWzm0stT5CqIAjhM34bjx0EiXjUEXMrGSp4jdWs9UNTWqzd3Acd0Yj7UqxGPLKw1 /CB4xY8U/gJD6X0TUrawjNV8ZeFXquzt85afh7r1+jOEDhFcrQ6sRVdTxq4fECyH89GO JTiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756935504; x=1757540304; 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=uenE3pCs9FFLs4/r5/tRBI0mdODh/rTI3ufCG8qlWUc=; b=SXqzSOBvyGM9Kf7H6i3h8bwPJxYSBgEKOddpmefRcDJ2QUSTDbQ4FISWiSJmKDbDl3 FeCVoVxSIFEr+XgKjntHabZlTPyXxxY8g+5LTbHLnEXFc1mWg1CIM5IjuA/g3HuoUD7E kx8PbH+os85klSIDSRoOT/KYKVY/ru6gMkorivzCxOlZ6eloBpw+tzlFEiqj6qHPnL/v a/EOQUKDBRPtyjgDz1fssXcWrTgPiw5iV7Wkjok3A6MB3T5PtlqiS2iRIPw4vLSpH19F LcIWHrMkH8onmn7eno+TSmEwE+yRXRpWPj4PgOQQMWXjCufjD6Hxmk2HA4U1bKOyCKgQ sgPA== X-Forwarded-Encrypted: i=1; AJvYcCUkCLk7jwSvs12HfwAN1TcvlZDF3tEq+1Pn7tFbrtAD8iw1Z3lPNePRlX5QPbVn8Oxdbyxy8oqvksMO@nongnu.org X-Gm-Message-State: AOJu0YyAhCKoUvUq1/676DUC4HhB03UG1F2YYEY7AcS1iue+/+iyK9Uh 50/MYzy42qQwne7tUtWKUBTg7zGQizdVNBdzVbXOvxjRR/UkklvoK1zifzfIEE9HKbO62KpYfTi K2zGQuBPuNkvybJPjhg== X-Google-Smtp-Source: AGHT+IFzkBNCdy6eibxjF6MXhtuU316d2um/jbsuFzeTSjnQJ5OvEJi+GeYPKX5HSN4hQVbLfPxOtLOlX7cxeKQ= X-Received: from pjbpm4.prod.google.com ([2002:a17:90b:3c44:b0:327:e9ca:a5ae]) (user=lixiaoyan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3810:b0:321:c85d:dd93 with SMTP id 98e67ed59e1d1-32815412be5mr23616491a91.4.1756935504281; Wed, 03 Sep 2025 14:38:24 -0700 (PDT) Date: Wed, 3 Sep 2025 21:38:09 +0000 In-Reply-To: <20250903213809.3779860-1-lixiaoyan@google.com> Mime-Version: 1.0 References: <20250903213809.3779860-1-lixiaoyan@google.com> X-Mailer: git-send-email 2.51.0.338.gd7d06c2dae-goog Message-ID: <20250903213809.3779860-6-lixiaoyan@google.com> Subject: [PATCH 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, Coco Li , 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=3ULW4aAkKCukWTiTLZjLYRZZRWP.NZXbPXf-OPgPWYZYRYf.ZcR@flex--lixiaoyan.bounces.google.com; helo=mail-pj1-x104a.google.com X-Spam_score_int: -86 X-Spam_score: -8.7 X-Spam_bar: -------- X-Spam_report: (-8.7 / 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.938, 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-Mailman-Approved-At: Wed, 03 Sep 2025 18:21:29 -0400 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: 1756938187688124100 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.338.gd7d06c2dae-goog