From nobody Sat Feb 7 05:14:54 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1739418143; cv=none; d=zohomail.com; s=zohoarc; b=RxwZv5X+xgxAAwH+NonDwoGsd1Po1sC/yPmxDuYyIxqkfmFTa3IoByySRvwR8NY9u6gTBng5PZKGxFE2T1C06TTzhxS5qdKIQcaouP5QVjHLeTN6pVpPIW6djjVK141E/HSHe1DRe12kwSX62kc3ZgyBRRhoEqRjeqSjXuSm0bc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1739418143; h=Content-Type:Content-Transfer-Encoding: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:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=EGQTVMhMtrqqv8qWf+82C1RuZ+QLq+Mk3NWJogUrV/8=; b=AXchwBbLyFZepV4PM8saMlBD2MK5hH69eDpTZ3cPfLEDkXehA5VxxnjFFGtJtsCxbuiX7c1FzPK6HvtXqKc0iv7zPWK2MGo3H2bBpO7uTMIq/z8OZOrPh1MF17PKS85rvt7XjjHyO/YTmbSCNcM+09fbJgRWYIYv7FkN3ES0UTg= ARC-Authentication-Results: i=1; mx.zohomail.com; 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1739418143542154.33769764047418; Wed, 12 Feb 2025 19:42:23 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tiQ1g-0007Ob-NT; Wed, 12 Feb 2025 22:36:32 -0500 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 ) id 1tiQ1C-0007Cq-1V; Wed, 12 Feb 2025 22:36:03 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tiQ19-0000hG-6M; Wed, 12 Feb 2025 22:36:01 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Thu, 13 Feb 2025 11:35:35 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Thu, 13 Feb 2025 11:35:35 +0800 To: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , "open list:All patches CC here" , "open list:ASPEED BMCs" CC: , Subject: [PATCH v3 10/28] hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq index and register address Date: Thu, 13 Feb 2025 11:35:13 +0800 Message-ID: <20250213033531.3367697-11-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250213033531.3367697-1-jamin_lin@aspeedtech.com> References: <20250213033531.3367697-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Reply-to: Jamin Lin From: Jamin Lin via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1739418145607019100 Content-Type: text/plain; charset="utf-8" The INTC controller supports GICINT128 to GICINT136, mapping 1:1 to input a= nd output IRQs 0 to 8. Previously, the formula "address & 0x0f00" was used to derive the IRQ index numbers. However, the INTC controller also supports GICINT192_201, mapping 1 input I= RQ pin to 10 output IRQ pins. The pin numbers for input and output are differe= nt. It is difficult to use a formula to determine the index number of INTC model supported input and output IRQs. To simplify and improve readability, introduces the AspeedINTCIRQ structure= to save the input/output IRQ index and its enable/status register address. Introduce the "aspeed_2700_intc_irqs" table to store IRQ information for IN= TC. Introduce the "aspeed_intc_get_irq" function to retrieve the input/output I= RQ pin index from the provided status/enable register address. Signed-off-by: Jamin Lin --- hw/intc/aspeed_intc.c | 120 ++++++++++++++++++++-------------- include/hw/intc/aspeed_intc.h | 10 +++ 2 files changed, 82 insertions(+), 48 deletions(-) diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index 4e8f1e291e..59c1069294 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -34,7 +34,35 @@ REG32(GICINT135_STATUS, 0x1704) REG32(GICINT136_EN, 0x1800) REG32(GICINT136_STATUS, 0x1804) =20 -#define GICINT_STATUS_BASE R_GICINT128_STATUS +static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] =3D { + {0, 0, 1, R_GICINT128_EN, R_GICINT128_STATUS}, + {1, 1, 1, R_GICINT129_EN, R_GICINT129_STATUS}, + {2, 2, 1, R_GICINT130_EN, R_GICINT130_STATUS}, + {3, 3, 1, R_GICINT131_EN, R_GICINT131_STATUS}, + {4, 4, 1, R_GICINT132_EN, R_GICINT132_STATUS}, + {5, 5, 1, R_GICINT133_EN, R_GICINT133_STATUS}, + {6, 6, 1, R_GICINT134_EN, R_GICINT134_STATUS}, + {7, 7, 1, R_GICINT135_EN, R_GICINT135_STATUS}, + {8, 8, 1, R_GICINT136_EN, R_GICINT136_STATUS}, +}; + +static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic, + uint32_t addr) +{ + int i; + + for (i =3D 0; i < aic->irq_table_count; i++) { + if (aic->irq_table[i].enable_addr =3D=3D addr || + aic->irq_table[i].status_addr =3D=3D addr) { + return &aic->irq_table[i]; + } + } + + /* + * Invalid addr. + */ + g_assert_not_reached(); +} =20 /* * Update the state of an interrupt controller pin by setting @@ -75,15 +103,10 @@ static void aspeed_intc_set_irq(void *opaque, int irq,= int level) AspeedINTCState *s =3D (AspeedINTCState *)opaque; AspeedINTCClass *aic =3D ASPEED_INTC_GET_CLASS(s); const char *name =3D object_get_typename(OBJECT(s)); - uint32_t status_addr =3D GICINT_STATUS_BASE + ((0x100 * irq) >> 2); + const AspeedINTCIRQ *intc_irq; uint32_t select =3D 0; uint32_t enable; int i; - int inpin_idx; - int outpin_idx; - - inpin_idx =3D irq; - outpin_idx =3D irq; =20 if (irq >=3D aic->num_inpins) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n", @@ -91,15 +114,16 @@ static void aspeed_intc_set_irq(void *opaque, int irq,= int level) return; } =20 - trace_aspeed_intc_set_irq(name, inpin_idx, level); - enable =3D s->enable[inpin_idx]; + intc_irq =3D &aic->irq_table[irq]; + trace_aspeed_intc_set_irq(name, intc_irq->inpin_idx, level); + enable =3D s->enable[intc_irq->inpin_idx]; =20 if (!level) { return; } =20 for (i =3D 0; i < aic->num_lines; i++) { - if (s->orgates[inpin_idx].levels[i]) { + if (s->orgates[intc_irq->inpin_idx].levels[i]) { if (enable & BIT(i)) { select |=3D BIT(i); } @@ -112,7 +136,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, = int level) =20 trace_aspeed_intc_select(name, select); =20 - if (s->mask[inpin_idx] || s->regs[status_addr]) { + if (s->mask[intc_irq->inpin_idx] || s->regs[intc_irq->status_addr]) { /* * a. mask is not 0 means in ISR mode * sources interrupt routine are executing. @@ -121,17 +145,19 @@ static void aspeed_intc_set_irq(void *opaque, int irq= , int level) * * save source interrupt to pending variable. */ - s->pending[inpin_idx] |=3D select; - trace_aspeed_intc_pending_irq(name, inpin_idx, s->pending[inpin_id= x]); + s->pending[intc_irq->inpin_idx] |=3D select; + trace_aspeed_intc_pending_irq(name, intc_irq->inpin_idx, + s->pending[intc_irq->inpin_idx]); } else { /* * notify firmware which source interrupt are coming * by setting status register */ - s->regs[status_addr] =3D select; - trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx, - s->regs[status_addr]); - aspeed_intc_update(s, inpin_idx, outpin_idx, 1); + s->regs[intc_irq->status_addr] =3D select; + trace_aspeed_intc_trigger_irq(name, intc_irq->inpin_idx, + intc_irq->outpin_idx, + s->regs[intc_irq->status_addr]); + aspeed_intc_update(s, intc_irq->inpin_idx, intc_irq->outpin_idx, 1= ); } } =20 @@ -140,19 +166,17 @@ static void aspeed_intc_enable_handler(AspeedINTCStat= e *s, hwaddr offset, { AspeedINTCClass *aic =3D ASPEED_INTC_GET_CLASS(s); const char *name =3D object_get_typename(OBJECT(s)); + const AspeedINTCIRQ *intc_irq; uint32_t addr =3D offset >> 2; uint32_t old_enable; uint32_t change; - uint32_t irq; - int inpin_idx; =20 - irq =3D (offset & 0x0f00) >> 8; - inpin_idx =3D irq; + intc_irq =3D aspeed_intc_get_irq(aic, addr); =20 - if (inpin_idx >=3D aic->num_inpins) { + if (intc_irq->inpin_idx >=3D aic->num_inpins) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n", - __func__, inpin_idx); + __func__, intc_irq->inpin_idx); return; } =20 @@ -163,17 +187,17 @@ static void aspeed_intc_enable_handler(AspeedINTCStat= e *s, hwaddr offset, */ =20 /* disable all source interrupt */ - if (!data && !s->enable[inpin_idx]) { + if (!data && !s->enable[intc_irq->inpin_idx]) { s->regs[addr] =3D data; return; } =20 - old_enable =3D s->enable[inpin_idx]; - s->enable[inpin_idx] |=3D data; + old_enable =3D s->enable[intc_irq->inpin_idx]; + s->enable[intc_irq->inpin_idx] |=3D data; =20 /* enable new source interrupt */ - if (old_enable !=3D s->enable[inpin_idx]) { - trace_aspeed_intc_enable(name, s->enable[inpin_idx]); + if (old_enable !=3D s->enable[intc_irq->inpin_idx]) { + trace_aspeed_intc_enable(name, s->enable[intc_irq->inpin_idx]); s->regs[addr] =3D data; return; } @@ -181,11 +205,11 @@ static void aspeed_intc_enable_handler(AspeedINTCStat= e *s, hwaddr offset, /* mask and unmask source interrupt */ change =3D s->regs[addr] ^ data; if (change & data) { - s->mask[inpin_idx] &=3D ~change; - trace_aspeed_intc_unmask(name, change, s->mask[inpin_idx]); + s->mask[intc_irq->inpin_idx] &=3D ~change; + trace_aspeed_intc_unmask(name, change, s->mask[intc_irq->inpin_idx= ]); } else { - s->mask[inpin_idx] |=3D change; - trace_aspeed_intc_mask(name, change, s->mask[inpin_idx]); + s->mask[intc_irq->inpin_idx] |=3D change; + trace_aspeed_intc_mask(name, change, s->mask[intc_irq->inpin_idx]); } =20 s->regs[addr] =3D data; @@ -196,24 +220,20 @@ static void aspeed_intc_status_handler(AspeedINTCStat= e *s, hwaddr offset, { AspeedINTCClass *aic =3D ASPEED_INTC_GET_CLASS(s); const char *name =3D object_get_typename(OBJECT(s)); + const AspeedINTCIRQ *intc_irq; uint32_t addr =3D offset >> 2; - uint32_t irq; - int inpin_idx; - int outpin_idx; =20 if (!data) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n", __func__); return; } =20 - irq =3D (offset & 0x0f00) >> 8; - inpin_idx =3D irq; - outpin_idx =3D irq; + intc_irq =3D aspeed_intc_get_irq(aic, addr); =20 - if (inpin_idx >=3D aic->num_inpins) { + if (intc_irq->inpin_idx >=3D aic->num_inpins) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n", - __func__, inpin_idx); + __func__, intc_irq->inpin_idx); return; } =20 @@ -232,22 +252,24 @@ static void aspeed_intc_status_handler(AspeedINTCStat= e *s, hwaddr offset, =20 /* All source ISR execution are done */ if (!s->regs[addr]) { - trace_aspeed_intc_all_isr_done(name, inpin_idx); - if (s->pending[inpin_idx]) { + trace_aspeed_intc_all_isr_done(name, intc_irq->inpin_idx); + if (s->pending[intc_irq->inpin_idx]) { /* * handle pending source interrupt * notify firmware which source interrupt are pending * by setting status register */ - s->regs[addr] =3D s->pending[inpin_idx]; - s->pending[inpin_idx] =3D 0; - trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx, + s->regs[addr] =3D s->pending[intc_irq->inpin_idx]; + s->pending[intc_irq->inpin_idx] =3D 0; + trace_aspeed_intc_trigger_irq(name, intc_irq->inpin_idx, + intc_irq->outpin_idx, s->regs[addr]); - aspeed_intc_update(s, inpin_idx, outpin_idx, 1); + aspeed_intc_update(s, intc_irq->inpin_idx, intc_irq->outpin_id= x, 1); } else { /* clear irq */ - trace_aspeed_intc_clear_irq(name, inpin_idx, outpin_idx, 0); - aspeed_intc_update(s, inpin_idx, outpin_idx, 0); + trace_aspeed_intc_clear_irq(name, intc_irq->inpin_idx, + intc_irq->outpin_idx, 0); + aspeed_intc_update(s, intc_irq->inpin_idx, intc_irq->outpin_id= x, 0); } } } @@ -420,6 +442,8 @@ static void aspeed_2700_intc_class_init(ObjectClass *kl= ass, void *data) aic->num_outpins =3D 9; aic->mem_size =3D 0x4000; aic->reg_size =3D 0x2000; + aic->irq_table =3D aspeed_2700_intc_irqs; + aic->irq_table_count =3D ARRAY_SIZE(aspeed_2700_intc_irqs); } =20 static const TypeInfo aspeed_2700_intc_info =3D { diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h index 0bf96a81bb..abf2cae996 100644 --- a/include/hw/intc/aspeed_intc.h +++ b/include/hw/intc/aspeed_intc.h @@ -20,6 +20,14 @@ OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, AS= PEED_INTC) #define ASPEED_INTC_MAX_INPINS 9 #define ASPEED_INTC_MAX_OUTPINS 9 =20 +typedef struct AspeedINTCIRQ { + int inpin_idx; + int outpin_idx; + int num_outpins; + uint32_t enable_addr; + uint32_t status_addr; +} AspeedINTCIRQ; + struct AspeedINTCState { /*< private >*/ SysBusDevice parent_obj; @@ -46,6 +54,8 @@ struct AspeedINTCClass { uint64_t mem_size; uint64_t reg_size; const MemoryRegionOps *reg_ops; + const AspeedINTCIRQ *irq_table; + int irq_table_count; }; =20 #endif /* ASPEED_INTC_H */ --=20 2.34.1