* [PATCH v3 00/28] Support AST2700 A1
@ 2025-02-13 3:35 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size Jamin Lin via
` (28 more replies)
0 siblings, 29 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
v1:
1. Refactor INTC model to support both INTC0 and INTC1.
2. Support AST2700 A1.
3. Create ast2700a0-evb machine.
v2:
To streamline the review process, split the following patch series into
three parts.
https://patchwork.kernel.org/project/qemu-devel/cover/20250121070424.2465942-1-jamin_lin@aspeedtech.com/
This patch series focuses on cleaning up the INTC model to
facilitate future support for the INTC_IO model.
v3:
1. Update and add functional test for AST2700
2. Add AST2700 INTC design guidance and its block diagram.
3. Retaining the INTC naming and introducing a new INTCIO model to support the AST2700 A1.
4. Create ast2700a1-evb machine and rename ast2700a0-evb machine
5. Fix silicon revision issue and support AST2700 A1.
With the patch applied, QEMU now supports two machines for running AST2700 SoCs:
ast2700a0-evb: Designed for AST2700 A0
ast2700a1-evb: Designed for AST2700 A1
Test information
1. QEMU version: https://github.com/qemu/qemu/commit/ffaf7f0376f8040ce9068d71ae9ae8722505c42e
2. ASPEED SDK v09.05 pre-built image
https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
ast2700-default-obmc.tar.gz (AST2700 A1)
https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-default-obmc.tar.gz
ast2700-a0-default-obmc.tar.gz (AST2700 A0)
https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-a0-default-obmc.tar.gz
Known Issue:
The HACE crypto and hash engine is enable by default since AST2700 A1.
However, aspeed_hace.c(HACE model) currently does not support the CRYPTO command.
To boot AST2700 A1, I have created a Patch 21 which temporarily resolves the
issue by sending an interrupt to notify the firmware that the cryptographic
command has completed. It is a temporary workaround to resolve the boot issue
in the Crypto Manager SelfTest.
As a result, you will encounter the following kernel warning due to the
Crypto Manager test failure. If you don't want to see these kernel warning,
please add the following settings in your kernel config.
```
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
```
```
alg: skcipher: aspeed-ctr-tdes encryption test failed (wrong result) on test vector 0, cfg="in-place (one sglist)"
[ 5.035966] alg: self-tests for ctr(des3_ede) using aspeed-ctr-tdes failed (rc=-22)
[ 5.036139] ------------[ cut here ]------------
[ 5.037188] alg: self-tests for ctr(des3_ede) using aspeed-ctr-tdes failed (rc=-22)
[ 5.037312] WARNING: CPU: 2 PID: 109 at /crypto/testmgr.c:5936 alg_test+0x42c/0x548
[ 5.038049] Modules linked in:
[ 5.038302] CPU: 2 PID: 109 Comm: cryptomgr_test Tainted: G W 6.6.52-v00.06.04-gf52a0cf7c475 #1
[ 5.038787] Hardware name: AST2700-EVB (DT)
[ 5.038988] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 5.039315] pc : alg_test+0x42c/0x548
[ 5.039505] lr : alg_test+0x42c/0x548
[ 5.039697] sp : ffffffc0825e3d50
[ 5.039862] x29: ffffffc0825e3df0 x28: 0000000000000004 x27: 0000000000000000
[ 5.040226] x26: ffffffc080bcada0 x25: ffffffc081dac9d0 x24: 0000000000000004
[ 5.040700] x23: 0000000000001285 x22: ffffff8003ded280 x21: ffffff8003ded200
[ 5.041458] x20: 00000000ffffffff x19: 00000000ffffffea x18: ffffffffffffffff
[ 5.041915] x17: 282064656c696166 x16: 20736564742d7274 x15: 00000000fffffffe
[ 5.042287] x14: 0000000000000000 x13: ffffffc081ba555c x12: 65742d666c657320
[ 5.042684] x11: 00000000fffeffff x10: ffffffc0818ff048 x9 : ffffffc0800a36e4
[ 5.043077] x8 : 000000000017ffe8 x7 : c0000000fffeffff x6 : 000000000057ffa8
[ 5.043461] x5 : 000000000000ffff x4 : 0000000000000000 x3 : 0000000000000000
[ 5.043751] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffff800415e740
[ 5.045544] Call trace:
[ 5.045693] alg_test+0x42c/0x548
[ 5.045878] cryptomgr_test+0x28/0x48
[ 5.046052] kthread+0x114/0x120
[ 5.046226] ret_from_fork+0x10/0x20
[ 5.046413] ---[ end trace 0000000000000000 ]---
[ 5.071510] alg: skcipher: aspeed-ctr-des encryption test failed (wrong result) on test vector 0, cfg="in-place (one sglist)"
[ 5.072145] alg: self-tests for ctr(des) using aspeed-ctr-des failed (rc=-22)
```
Jamin Lin (28):
hw/intc/aspeed: Support setting different memory and register size
hw/intc/aspeed: Introduce helper functions for enable and status
registers
hw/intc/aspeed: Add object type name to trace events for better
debugging
hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number
hw/intc/aspeed: Support different memory region ops
hw/intc/aspeed: Rename num_ints to num_inpins for clarity
hw/intc/aspeed: Add support for multiple output pins in INTC
hw/intc/aspeed: Refactor INTC to support separate input and output pin
indices
hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq
index and register address
hw/intc/aspeed: Introduce IRQ handler function to reduce code
duplication
hw/intc/aspeed: Add Support for Multi-Output IRQ Handling
hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon
Revisions
hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer
for AST2700
hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping
hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for
AST2700 A1
hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
hw/misc/aspeed_hace: Fix coding style
hw/misc/aspeed_hace: Add AST2700 support
hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
hw/arm/aspeed_ast27x0: Add HACE support for AST2700
test/functional/aspeed: Introduce new function to fetch assets
tests/functional/aspeed: Introduce start_ast2700_test API and update
hwmon path
tests/functional/aspeed: Update test ASPEED SDK v09.05
tests/functional/aspeed: Renamed test case and machine for AST2700 A0
tests/functional/aspeed: Add test case for AST2700 A1
docs/specs: add aspeed-intc
docs/specs/aspeed-intc.rst | 136 ++++++
docs/specs/index.rst | 1 +
hw/arm/aspeed.c | 21 +-
hw/arm/aspeed_ast27x0.c | 291 +++++++++---
hw/intc/aspeed_intc.c | 593 +++++++++++++++++++-----
hw/intc/trace-events | 25 +-
hw/misc/aspeed_hace.c | 44 +-
hw/misc/aspeed_scu.c | 5 +-
include/hw/arm/aspeed_soc.h | 3 +-
include/hw/intc/aspeed_intc.h | 32 +-
include/hw/misc/aspeed_hace.h | 1 +
include/hw/misc/aspeed_scu.h | 2 +
tests/functional/test_aarch64_aspeed.py | 47 +-
13 files changed, 963 insertions(+), 238 deletions(-)
create mode 100644 docs/specs/aspeed-intc.rst
--
2.34.1
^ permalink raw reply [flat|nested] 70+ messages in thread
* [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:33 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 02/28] hw/intc/aspeed: Introduce helper functions for enable and status registers Jamin Lin via
` (27 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
According to the AST2700 datasheet, the INTC(CPU DIE) controller has 16KB
(0x4000) of register space, and the INTCIO (I/O DIE) controller has 1KB (0x400)
of register space.
Introduced a new class attribute "mem_size" to set different memory sizes for
the INTC models in AST2700.
Introduced a new class attribute "reg_size" to set different register sizes for
the INTC models in AST2700.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 17 +++++++++++++----
include/hw/intc/aspeed_intc.h | 4 ++++
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 126b711b94..316885a27a 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -117,10 +117,11 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
{
AspeedINTCState *s = ASPEED_INTC(opaque);
+ AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
uint32_t addr = offset >> 2;
uint32_t value = 0;
- if (addr >= ASPEED_INTC_NR_REGS) {
+ if (offset >= aic->reg_size) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
__func__, offset);
@@ -143,7 +144,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
uint32_t change;
uint32_t irq;
- if (addr >= ASPEED_INTC_NR_REGS) {
+ if (offset >= aic->reg_size) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
__func__, offset);
@@ -302,10 +303,16 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
int i;
+ memory_region_init(&s->iomem_container, OBJECT(s),
+ TYPE_ASPEED_INTC ".container", aic->mem_size);
+
+ sysbus_init_mmio(sbd, &s->iomem_container);
+
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_intc_ops, s,
- TYPE_ASPEED_INTC ".regs", ASPEED_INTC_NR_REGS << 2);
+ TYPE_ASPEED_INTC ".regs", aic->reg_size);
+
+ memory_region_add_subregion(&s->iomem_container, 0x0, &s->iomem);
- sysbus_init_mmio(sbd, &s->iomem);
qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
for (i = 0; i < aic->num_ints; i++) {
@@ -344,6 +351,8 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2700 INTC Controller";
aic->num_lines = 32;
aic->num_ints = 9;
+ aic->mem_size = 0x4000;
+ aic->reg_size = 0x2000;
}
static const TypeInfo aspeed_2700_intc_info = {
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index 18cb43476c..ecaeb15aea 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -25,6 +25,8 @@ struct AspeedINTCState {
/*< public >*/
MemoryRegion iomem;
+ MemoryRegion iomem_container;
+
uint32_t regs[ASPEED_INTC_NR_REGS];
OrIRQState orgates[ASPEED_INTC_NR_INTS];
qemu_irq output_pins[ASPEED_INTC_NR_INTS];
@@ -39,6 +41,8 @@ struct AspeedINTCClass {
uint32_t num_lines;
uint32_t num_ints;
+ uint64_t mem_size;
+ uint64_t reg_size;
};
#endif /* ASPEED_INTC_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 02/28] hw/intc/aspeed: Introduce helper functions for enable and status registers
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:36 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 03/28] hw/intc/aspeed: Add object type name to trace events for better debugging Jamin Lin via
` (26 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
The behavior of the enable and status registers is almost identical between
INTC(CPU Die) and INTCIO(IO Die). To reduce duplicated code, adds
"aspeed_intc_enable_handler" functions to handle enable register write
behavior and "aspeed_intc_status_handler" functions to handle status
register write behavior.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 190 ++++++++++++++++++++++++------------------
1 file changed, 108 insertions(+), 82 deletions(-)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 316885a27a..8f9fa97acc 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -114,6 +114,112 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
}
}
+static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
+ uint64_t data)
+{
+ AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ uint32_t addr = offset >> 2;
+ uint32_t old_enable;
+ uint32_t change;
+ uint32_t irq;
+
+ irq = (offset & 0x0f00) >> 8;
+
+ if (irq >= aic->num_ints) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+ __func__, irq);
+ return;
+ }
+
+ /*
+ * The enable registers are used to enable source interrupts.
+ * They also handle masking and unmasking of source interrupts
+ * during the execution of the source ISR.
+ */
+
+ /* disable all source interrupt */
+ if (!data && !s->enable[irq]) {
+ s->regs[addr] = data;
+ return;
+ }
+
+ old_enable = s->enable[irq];
+ s->enable[irq] |= data;
+
+ /* enable new source interrupt */
+ if (old_enable != s->enable[irq]) {
+ trace_aspeed_intc_enable(s->enable[irq]);
+ s->regs[addr] = data;
+ return;
+ }
+
+ /* mask and unmask source interrupt */
+ change = s->regs[addr] ^ data;
+ if (change & data) {
+ s->mask[irq] &= ~change;
+ trace_aspeed_intc_unmask(change, s->mask[irq]);
+ } else {
+ s->mask[irq] |= change;
+ trace_aspeed_intc_mask(change, s->mask[irq]);
+ }
+
+ s->regs[addr] = data;
+}
+
+static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
+ uint64_t data)
+{
+ AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ uint32_t addr = offset >> 2;
+ uint32_t irq;
+
+ if (!data) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n", __func__);
+ return;
+ }
+
+ irq = (offset & 0x0f00) >> 8;
+
+ if (irq >= aic->num_ints) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+ __func__, irq);
+ return;
+ }
+
+ /* clear status */
+ s->regs[addr] &= ~data;
+
+ /*
+ * These status registers are used for notify sources ISR are executed.
+ * If one source ISR is executed, it will clear one bit.
+ * If it clear all bits, it means to initialize this register status
+ * rather than sources ISR are executed.
+ */
+ if (data == 0xffffffff) {
+ return;
+ }
+
+ /* All source ISR execution are done */
+ if (!s->regs[addr]) {
+ trace_aspeed_intc_all_isr_done(irq);
+ if (s->pending[irq]) {
+ /*
+ * handle pending source interrupt
+ * notify firmware which source interrupt are pending
+ * by setting status register
+ */
+ s->regs[addr] = s->pending[irq];
+ s->pending[irq] = 0;
+ trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
+ aspeed_intc_update(s, irq, 1);
+ } else {
+ /* clear irq */
+ trace_aspeed_intc_clear_irq(irq, 0);
+ aspeed_intc_update(s, irq, 0);
+ }
+ }
+}
+
static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
{
AspeedINTCState *s = ASPEED_INTC(opaque);
@@ -140,9 +246,6 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
AspeedINTCState *s = ASPEED_INTC(opaque);
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
uint32_t addr = offset >> 2;
- uint32_t old_enable;
- uint32_t change;
- uint32_t irq;
if (offset >= aic->reg_size) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -163,45 +266,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
case R_GICINT134_EN:
case R_GICINT135_EN:
case R_GICINT136_EN:
- irq = (offset & 0x0f00) >> 8;
-
- if (irq >= aic->num_ints) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
- __func__, irq);
- return;
- }
-
- /*
- * These registers are used for enable sources interrupt and
- * mask and unmask source interrupt while executing source ISR.
- */
-
- /* disable all source interrupt */
- if (!data && !s->enable[irq]) {
- s->regs[addr] = data;
- return;
- }
-
- old_enable = s->enable[irq];
- s->enable[irq] |= data;
-
- /* enable new source interrupt */
- if (old_enable != s->enable[irq]) {
- trace_aspeed_intc_enable(s->enable[irq]);
- s->regs[addr] = data;
- return;
- }
-
- /* mask and unmask source interrupt */
- change = s->regs[addr] ^ data;
- if (change & data) {
- s->mask[irq] &= ~change;
- trace_aspeed_intc_unmask(change, s->mask[irq]);
- } else {
- s->mask[irq] |= change;
- trace_aspeed_intc_mask(change, s->mask[irq]);
- }
- s->regs[addr] = data;
+ aspeed_intc_enable_handler(s, offset, data);
break;
case R_GICINT128_STATUS:
case R_GICINT129_STATUS:
@@ -212,46 +277,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
case R_GICINT134_STATUS:
case R_GICINT135_STATUS:
case R_GICINT136_STATUS:
- irq = (offset & 0x0f00) >> 8;
-
- if (irq >= aic->num_ints) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
- __func__, irq);
- return;
- }
-
- /* clear status */
- s->regs[addr] &= ~data;
-
- /*
- * These status registers are used for notify sources ISR are executed.
- * If one source ISR is executed, it will clear one bit.
- * If it clear all bits, it means to initialize this register status
- * rather than sources ISR are executed.
- */
- if (data == 0xffffffff) {
- return;
- }
-
- /* All source ISR execution are done */
- if (!s->regs[addr]) {
- trace_aspeed_intc_all_isr_done(irq);
- if (s->pending[irq]) {
- /*
- * handle pending source interrupt
- * notify firmware which source interrupt are pending
- * by setting status register
- */
- s->regs[addr] = s->pending[irq];
- s->pending[irq] = 0;
- trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
- aspeed_intc_update(s, irq, 1);
- } else {
- /* clear irq */
- trace_aspeed_intc_clear_irq(irq, 0);
- aspeed_intc_update(s, irq, 0);
- }
- }
+ aspeed_intc_status_handler(s, offset, data);
break;
default:
s->regs[addr] = data;
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 03/28] hw/intc/aspeed: Add object type name to trace events for better debugging
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 02/28] hw/intc/aspeed: Introduce helper functions for enable and status registers Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:43 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0 Jamin Lin via
` (25 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Currently, these trace events only refer to INTC. To simplify the INTC model,
both INTC(CPU Die) and INTCIO(IO Die) will share the same helper functions.
However, it is difficult to recognize whether these trace events are comes from
INTC or INTCIO. To make these trace events more readable, adds object type name
to the INTC trace events.
Update trace events to include the "name" field for better identification.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 32 +++++++++++++++++++-------------
hw/intc/trace-events | 24 ++++++++++++------------
2 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 8f9fa97acc..91d8edb261 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -39,6 +39,7 @@ REG32(GICINT136_STATUS, 0x1804)
static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
{
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
if (irq >= aic->num_ints) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
@@ -46,7 +47,7 @@ static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
return;
}
- trace_aspeed_intc_update_irq(irq, level);
+ trace_aspeed_intc_update_irq(name, irq, level);
qemu_set_irq(s->output_pins[irq], level);
}
@@ -60,6 +61,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
{
AspeedINTCState *s = (AspeedINTCState *)opaque;
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
uint32_t status_addr = GICINT_STATUS_BASE + ((0x100 * irq) >> 2);
uint32_t select = 0;
uint32_t enable;
@@ -71,7 +73,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
return;
}
- trace_aspeed_intc_set_irq(irq, level);
+ trace_aspeed_intc_set_irq(name, irq, level);
enable = s->enable[irq];
if (!level) {
@@ -90,7 +92,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
return;
}
- trace_aspeed_intc_select(select);
+ trace_aspeed_intc_select(name, select);
if (s->mask[irq] || s->regs[status_addr]) {
/*
@@ -102,14 +104,14 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
* save source interrupt to pending variable.
*/
s->pending[irq] |= select;
- trace_aspeed_intc_pending_irq(irq, s->pending[irq]);
+ trace_aspeed_intc_pending_irq(name, irq, s->pending[irq]);
} else {
/*
* notify firmware which source interrupt are coming
* by setting status register
*/
s->regs[status_addr] = select;
- trace_aspeed_intc_trigger_irq(irq, s->regs[status_addr]);
+ trace_aspeed_intc_trigger_irq(name, irq, s->regs[status_addr]);
aspeed_intc_update(s, irq, 1);
}
}
@@ -118,6 +120,7 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
uint64_t data)
{
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
uint32_t addr = offset >> 2;
uint32_t old_enable;
uint32_t change;
@@ -148,7 +151,7 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
/* enable new source interrupt */
if (old_enable != s->enable[irq]) {
- trace_aspeed_intc_enable(s->enable[irq]);
+ trace_aspeed_intc_enable(name, s->enable[irq]);
s->regs[addr] = data;
return;
}
@@ -157,10 +160,10 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
change = s->regs[addr] ^ data;
if (change & data) {
s->mask[irq] &= ~change;
- trace_aspeed_intc_unmask(change, s->mask[irq]);
+ trace_aspeed_intc_unmask(name, change, s->mask[irq]);
} else {
s->mask[irq] |= change;
- trace_aspeed_intc_mask(change, s->mask[irq]);
+ trace_aspeed_intc_mask(name, change, s->mask[irq]);
}
s->regs[addr] = data;
@@ -170,6 +173,7 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
uint64_t data)
{
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
uint32_t addr = offset >> 2;
uint32_t irq;
@@ -201,7 +205,7 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
/* All source ISR execution are done */
if (!s->regs[addr]) {
- trace_aspeed_intc_all_isr_done(irq);
+ trace_aspeed_intc_all_isr_done(name, irq);
if (s->pending[irq]) {
/*
* handle pending source interrupt
@@ -210,11 +214,11 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
*/
s->regs[addr] = s->pending[irq];
s->pending[irq] = 0;
- trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
+ trace_aspeed_intc_trigger_irq(name, irq, s->regs[addr]);
aspeed_intc_update(s, irq, 1);
} else {
/* clear irq */
- trace_aspeed_intc_clear_irq(irq, 0);
+ trace_aspeed_intc_clear_irq(name, irq, 0);
aspeed_intc_update(s, irq, 0);
}
}
@@ -224,6 +228,7 @@ static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
{
AspeedINTCState *s = ASPEED_INTC(opaque);
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
uint32_t addr = offset >> 2;
uint32_t value = 0;
@@ -235,7 +240,7 @@ static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
}
value = s->regs[addr];
- trace_aspeed_intc_read(offset, size, value);
+ trace_aspeed_intc_read(name, offset, size, value);
return value;
}
@@ -245,6 +250,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
{
AspeedINTCState *s = ASPEED_INTC(opaque);
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
uint32_t addr = offset >> 2;
if (offset >= aic->reg_size) {
@@ -254,7 +260,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
return;
}
- trace_aspeed_intc_write(offset, size, data);
+ trace_aspeed_intc_write(name, offset, size, data);
switch (addr) {
case R_GICINT128_EN:
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 3dcf147198..e9ca34755e 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -80,18 +80,18 @@ aspeed_vic_update_irq(int flags) "Raising IRQ: %d"
aspeed_vic_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
# aspeed_intc.c
-aspeed_intc_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
-aspeed_intc_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
-aspeed_intc_set_irq(int irq, int level) "Set IRQ %d: %d"
-aspeed_intc_clear_irq(int irq, int level) "Clear IRQ %d: %d"
-aspeed_intc_update_irq(int irq, int level) "Update IRQ: %d: %d"
-aspeed_intc_pending_irq(int irq, uint32_t value) "Pending IRQ: %d: 0x%x"
-aspeed_intc_trigger_irq(int irq, uint32_t value) "Trigger IRQ: %d: 0x%x"
-aspeed_intc_all_isr_done(int irq) "All source ISR execution are done: %d"
-aspeed_intc_enable(uint32_t value) "Enable: 0x%x"
-aspeed_intc_select(uint32_t value) "Select: 0x%x"
-aspeed_intc_mask(uint32_t change, uint32_t value) "Mask: 0x%x: 0x%x"
-aspeed_intc_unmask(uint32_t change, uint32_t value) "UnMask: 0x%x: 0x%x"
+aspeed_intc_read(const char *s, uint64_t offset, unsigned size, uint32_t value) "%s: From 0x%" PRIx64 " of size %u: 0x%" PRIx32
+aspeed_intc_write(const char *s, uint64_t offset, unsigned size, uint32_t data) "%s: To 0x%" PRIx64 " of size %u: 0x%" PRIx32
+aspeed_intc_set_irq(const char *s, int irq, int level) "%s: Set IRQ %d: %d"
+aspeed_intc_clear_irq(const char *s, int irq, int level) "%s: Clear IRQ %d: %d"
+aspeed_intc_update_irq(const char *s, int irq, int level) "%s: Update IRQ: %d: %d"
+aspeed_intc_pending_irq(const char *s, int irq, uint32_t value) "%s: Pending IRQ: %d: 0x%x"
+aspeed_intc_trigger_irq(const char *s, int irq, uint32_t value) "%s: Trigger IRQ: %d: 0x%x"
+aspeed_intc_all_isr_done(const char *s, int irq) "%s: All source ISR execution are done: %d"
+aspeed_intc_enable(const char *s, uint32_t value) "%s: Enable: 0x%x"
+aspeed_intc_select(const char *s, uint32_t value) "%s: Select: 0x%x"
+aspeed_intc_mask(const char *s, uint32_t change, uint32_t value) "%s: Mask: 0x%x: 0x%x"
+aspeed_intc_unmask(const char *s, uint32_t change, uint32_t value) "%s: UnMask: 0x%x: 0x%x"
# arm_gic.c
gic_enable_irq(int irq) "irq %d enabled"
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (2 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 03/28] hw/intc/aspeed: Add object type name to trace events for better debugging Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:47 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 05/28] hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number Jamin Lin via
` (24 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Currently, AST2700 SoC only supports A0. To support AST2700 A1, rename its IRQ
table and machine name.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed.c | 8 ++++----
hw/arm/aspeed_ast27x0.c | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index d9418e2b9f..6ddfdbdeba 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -1654,12 +1654,12 @@ static void ast2700_evb_i2c_init(AspeedMachineState *bmc)
TYPE_TMP105, 0x4d);
}
-static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc, void *data)
+static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
- mc->desc = "Aspeed AST2700 EVB (Cortex-A35)";
+ mc->desc = "Aspeed AST2700 A0 EVB (Cortex-A35)";
amc->soc_name = "ast2700-a0";
amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
amc->hw_strap2 = AST2700_EVB_HW_STRAP2;
@@ -1795,9 +1795,9 @@ static const TypeInfo aspeed_machine_types[] = {
.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
#ifdef TARGET_AARCH64
}, {
- .name = MACHINE_TYPE_NAME("ast2700-evb"),
+ .name = MACHINE_TYPE_NAME("ast2700a0-evb"),
.parent = TYPE_ASPEED_MACHINE,
- .class_init = aspeed_machine_ast2700_evb_class_init,
+ .class_init = aspeed_machine_ast2700a0_evb_class_init,
#endif
}, {
.name = TYPE_ASPEED_MACHINE,
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 2d0c99f159..6e3375f5d3 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -72,7 +72,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
#define AST2700_MAX_IRQ 256
/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
-static const int aspeed_soc_ast2700_irqmap[] = {
+static const int aspeed_soc_ast2700a0_irqmap[] = {
[ASPEED_DEV_UART0] = 132,
[ASPEED_DEV_UART1] = 132,
[ASPEED_DEV_UART2] = 132,
@@ -740,7 +740,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
create_unimplemented_device("ast2700.io", 0x0, 0x4000000);
}
-static void aspeed_soc_ast2700_class_init(ObjectClass *oc, void *data)
+static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void *data)
{
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-a35"),
@@ -763,7 +763,7 @@ static void aspeed_soc_ast2700_class_init(ObjectClass *oc, void *data)
sc->uarts_num = 13;
sc->num_cpus = 4;
sc->uarts_base = ASPEED_DEV_UART0;
- sc->irqmap = aspeed_soc_ast2700_irqmap;
+ sc->irqmap = aspeed_soc_ast2700a0_irqmap;
sc->memmap = aspeed_soc_ast2700_memmap;
sc->get_irq = aspeed_soc_ast2700_get_irq;
}
@@ -778,7 +778,7 @@ static const TypeInfo aspeed_soc_ast27x0_types[] = {
.name = "ast2700-a0",
.parent = TYPE_ASPEED27X0_SOC,
.instance_init = aspeed_soc_ast2700_init,
- .class_init = aspeed_soc_ast2700_class_init,
+ .class_init = aspeed_soc_ast2700a0_class_init,
},
};
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 05/28] hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (3 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:48 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 06/28] hw/intc/aspeed: Support different memory region ops Jamin Lin via
` (23 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
To improve readability, sort the IRQ table by IRQ number.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast27x0.c | 50 ++++++++++++++++++++---------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 6e3375f5d3..4862b215c1 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -73,27 +73,13 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
static const int aspeed_soc_ast2700a0_irqmap[] = {
- [ASPEED_DEV_UART0] = 132,
- [ASPEED_DEV_UART1] = 132,
- [ASPEED_DEV_UART2] = 132,
- [ASPEED_DEV_UART3] = 132,
- [ASPEED_DEV_UART4] = 8,
- [ASPEED_DEV_UART5] = 132,
- [ASPEED_DEV_UART6] = 132,
- [ASPEED_DEV_UART7] = 132,
- [ASPEED_DEV_UART8] = 132,
- [ASPEED_DEV_UART9] = 132,
- [ASPEED_DEV_UART10] = 132,
- [ASPEED_DEV_UART11] = 132,
- [ASPEED_DEV_UART12] = 132,
- [ASPEED_DEV_FMC] = 131,
[ASPEED_DEV_SDMC] = 0,
- [ASPEED_DEV_SCU] = 12,
- [ASPEED_DEV_ADC] = 130,
+ [ASPEED_DEV_HACE] = 4,
[ASPEED_DEV_XDMA] = 5,
- [ASPEED_DEV_EMMC] = 15,
- [ASPEED_DEV_GPIO] = 130,
+ [ASPEED_DEV_UART4] = 8,
+ [ASPEED_DEV_SCU] = 12,
[ASPEED_DEV_RTC] = 13,
+ [ASPEED_DEV_EMMC] = 15,
[ASPEED_DEV_TIMER1] = 16,
[ASPEED_DEV_TIMER2] = 17,
[ASPEED_DEV_TIMER3] = 18,
@@ -102,19 +88,33 @@ static const int aspeed_soc_ast2700a0_irqmap[] = {
[ASPEED_DEV_TIMER6] = 21,
[ASPEED_DEV_TIMER7] = 22,
[ASPEED_DEV_TIMER8] = 23,
- [ASPEED_DEV_WDT] = 131,
- [ASPEED_DEV_PWM] = 131,
+ [ASPEED_DEV_DP] = 28,
[ASPEED_DEV_LPC] = 128,
[ASPEED_DEV_IBT] = 128,
+ [ASPEED_DEV_KCS] = 128,
+ [ASPEED_DEV_ADC] = 130,
+ [ASPEED_DEV_GPIO] = 130,
[ASPEED_DEV_I2C] = 130,
- [ASPEED_DEV_PECI] = 133,
+ [ASPEED_DEV_FMC] = 131,
+ [ASPEED_DEV_WDT] = 131,
+ [ASPEED_DEV_PWM] = 131,
+ [ASPEED_DEV_I3C] = 131,
+ [ASPEED_DEV_UART0] = 132,
+ [ASPEED_DEV_UART1] = 132,
+ [ASPEED_DEV_UART2] = 132,
+ [ASPEED_DEV_UART3] = 132,
+ [ASPEED_DEV_UART5] = 132,
+ [ASPEED_DEV_UART6] = 132,
+ [ASPEED_DEV_UART7] = 132,
+ [ASPEED_DEV_UART8] = 132,
+ [ASPEED_DEV_UART9] = 132,
+ [ASPEED_DEV_UART10] = 132,
+ [ASPEED_DEV_UART11] = 132,
+ [ASPEED_DEV_UART12] = 132,
[ASPEED_DEV_ETH1] = 132,
[ASPEED_DEV_ETH2] = 132,
[ASPEED_DEV_ETH3] = 132,
- [ASPEED_DEV_HACE] = 4,
- [ASPEED_DEV_KCS] = 128,
- [ASPEED_DEV_DP] = 28,
- [ASPEED_DEV_I3C] = 131,
+ [ASPEED_DEV_PECI] = 133,
[ASPEED_DEV_SDHCI] = 133,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 06/28] hw/intc/aspeed: Support different memory region ops
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (4 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 05/28] hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:48 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 07/28] hw/intc/aspeed: Rename num_ints to num_inpins for clarity Jamin Lin via
` (22 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
The previous implementation set the "aspeed_intc_ops" struct, containing read
and write callbacks, to be used when I/O is performed on the INTC region.
Both "aspeed_intc_read" and "aspeed_intc_write" callback functions were used
for INTC (CPU Die).
To support the INTCIO (IO Die) model, introduces a new "reg_ops" class
attribute. This allows setting different memory region operations to support
different INTC models.
Will introduce "aspeed_intcio_read" and "aspeed_intcio_write" callback
functions are used for INTCIO.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 5 ++++-
include/hw/intc/aspeed_intc.h | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 91d8edb261..cc2426fbac 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -340,7 +340,7 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(sbd, &s->iomem_container);
- memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_intc_ops, s,
+ memory_region_init_io(&s->iomem, OBJECT(s), aic->reg_ops, s,
TYPE_ASPEED_INTC ".regs", aic->reg_size);
memory_region_add_subregion(&s->iomem_container, 0x0, &s->iomem);
@@ -358,11 +358,14 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
static void aspeed_intc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
dc->desc = "ASPEED INTC Controller";
dc->realize = aspeed_intc_realize;
device_class_set_legacy_reset(dc, aspeed_intc_reset);
dc->vmsd = NULL;
+
+ aic->reg_ops = &aspeed_intc_ops;
}
static const TypeInfo aspeed_intc_info = {
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index ecaeb15aea..749d7c55be 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -43,6 +43,7 @@ struct AspeedINTCClass {
uint32_t num_ints;
uint64_t mem_size;
uint64_t reg_size;
+ const MemoryRegionOps *reg_ops;
};
#endif /* ASPEED_INTC_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 07/28] hw/intc/aspeed: Rename num_ints to num_inpins for clarity
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (5 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 06/28] hw/intc/aspeed: Support different memory region ops Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:49 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output pins in INTC Jamin Lin via
` (21 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
To support AST2700 A1, some registers of the INTC(CPU Die) support one input
pin to multiple output pins. Renamed "num_ints" to "num_inpins" in the INTC
controller code for better clarity and consistency in naming conventions.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast27x0.c | 2 +-
hw/intc/aspeed_intc.c | 31 +++++++++++++++++--------------
include/hw/intc/aspeed_intc.h | 11 ++++++-----
3 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 4862b215c1..18e14a7914 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -520,7 +520,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
sc->memmap[ASPEED_DEV_INTC]);
/* GICINT orgates -> INTC -> GIC */
- for (i = 0; i < ic->num_ints; i++) {
+ for (i = 0; i < ic->num_inpins; i++) {
qdev_connect_gpio_out(DEVICE(&a->intc.orgates[i]), 0,
qdev_get_gpio_in(DEVICE(&a->intc), i));
sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc), i,
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index cc2426fbac..95b40e1935 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -41,8 +41,9 @@ static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
const char *name = object_get_typename(OBJECT(s));
- if (irq >= aic->num_ints) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+ if (irq >= aic->num_inpins) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Invalid input pin index: %d\n",
__func__, irq);
return;
}
@@ -54,7 +55,7 @@ static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
/*
* The address of GICINT128 to GICINT136 are from 0x1000 to 0x1804.
* Utilize "address & 0x0f00" to get the irq and irq output pin index
- * The value of irq should be 0 to num_ints.
+ * The value of irq should be 0 to num_inpins.
* The irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on.
*/
static void aspeed_intc_set_irq(void *opaque, int irq, int level)
@@ -67,8 +68,8 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
uint32_t enable;
int i;
- if (irq >= aic->num_ints) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+ if (irq >= aic->num_inpins) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n",
__func__, irq);
return;
}
@@ -128,8 +129,9 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
irq = (offset & 0x0f00) >> 8;
- if (irq >= aic->num_ints) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+ if (irq >= aic->num_inpins) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Invalid input pin index: %d\n",
__func__, irq);
return;
}
@@ -184,8 +186,9 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
irq = (offset & 0x0f00) >> 8;
- if (irq >= aic->num_ints) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+ if (irq >= aic->num_inpins) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Invalid input pin index: %d\n",
__func__, irq);
return;
}
@@ -309,8 +312,8 @@ static void aspeed_intc_instance_init(Object *obj)
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
int i;
- assert(aic->num_ints <= ASPEED_INTC_NR_INTS);
- for (i = 0; i < aic->num_ints; i++) {
+ assert(aic->num_inpins <= ASPEED_INTC_MAX_INPINS);
+ for (i = 0; i < aic->num_inpins; i++) {
object_initialize_child(obj, "intc-orgates[*]", &s->orgates[i],
TYPE_OR_IRQ);
object_property_set_int(OBJECT(&s->orgates[i]), "num-lines",
@@ -345,9 +348,9 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(&s->iomem_container, 0x0, &s->iomem);
- qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
+ qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_inpins);
- for (i = 0; i < aic->num_ints; i++) {
+ for (i = 0; i < aic->num_inpins; i++) {
if (!qdev_realize(DEVICE(&s->orgates[i]), NULL, errp)) {
return;
}
@@ -385,7 +388,7 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2700 INTC Controller";
aic->num_lines = 32;
- aic->num_ints = 9;
+ aic->num_inpins = 9;
aic->mem_size = 0x4000;
aic->reg_size = 0x2000;
}
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index 749d7c55be..5f0429c7f9 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -18,6 +18,7 @@ OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
#define ASPEED_INTC_NR_REGS (0x2000 >> 2)
#define ASPEED_INTC_NR_INTS 9
+#define ASPEED_INTC_MAX_INPINS 9
struct AspeedINTCState {
/*< private >*/
@@ -28,19 +29,19 @@ struct AspeedINTCState {
MemoryRegion iomem_container;
uint32_t regs[ASPEED_INTC_NR_REGS];
- OrIRQState orgates[ASPEED_INTC_NR_INTS];
+ OrIRQState orgates[ASPEED_INTC_MAX_INPINS];
qemu_irq output_pins[ASPEED_INTC_NR_INTS];
- uint32_t enable[ASPEED_INTC_NR_INTS];
- uint32_t mask[ASPEED_INTC_NR_INTS];
- uint32_t pending[ASPEED_INTC_NR_INTS];
+ uint32_t enable[ASPEED_INTC_MAX_INPINS];
+ uint32_t mask[ASPEED_INTC_MAX_INPINS];
+ uint32_t pending[ASPEED_INTC_MAX_INPINS];
};
struct AspeedINTCClass {
SysBusDeviceClass parent_class;
uint32_t num_lines;
- uint32_t num_ints;
+ uint32_t num_inpins;
uint64_t mem_size;
uint64_t reg_size;
const MemoryRegionOps *reg_ops;
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output pins in INTC
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (6 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 07/28] hw/intc/aspeed: Rename num_ints to num_inpins for clarity Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 5:53 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 09/28] hw/intc/aspeed: Refactor INTC to support separate input and output pin indices Jamin Lin via
` (20 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Added support for multiple output pins in the INTC controller to
accommodate the AST2700 A1.
Introduced "num_outpins" to represent the number of output pins. Updated the
IRQ handling logic to initialize and connect output pins separately from input
pins. Modified the "aspeed_soc_ast2700_realize" function to connect source
orgates to INTC and INTC to GIC128 - GIC136. Updated the "aspeed_intc_realize"
function to initialize output pins.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast27x0.c | 6 +++++-
hw/intc/aspeed_intc.c | 4 ++++
include/hw/intc/aspeed_intc.h | 5 +++--
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 18e14a7914..775e953afd 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -519,10 +519,14 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc), 0,
sc->memmap[ASPEED_DEV_INTC]);
- /* GICINT orgates -> INTC -> GIC */
+ /* source orgates -> INTC */
for (i = 0; i < ic->num_inpins; i++) {
qdev_connect_gpio_out(DEVICE(&a->intc.orgates[i]), 0,
qdev_get_gpio_in(DEVICE(&a->intc), i));
+ }
+
+ /* INTC -> GIC128 - GIC136 */
+ for (i = 0; i < ic->num_outpins; i++) {
sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc), i,
qdev_get_gpio_in(DEVICE(&a->gic),
aspeed_soc_ast2700_gic_intcmap[i].irq));
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 95b40e1935..32c4a3bb44 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -354,6 +354,9 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
if (!qdev_realize(DEVICE(&s->orgates[i]), NULL, errp)) {
return;
}
+ }
+
+ for (i = 0; i < aic->num_outpins; i++) {
sysbus_init_irq(sbd, &s->output_pins[i]);
}
}
@@ -389,6 +392,7 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2700 INTC Controller";
aic->num_lines = 32;
aic->num_inpins = 9;
+ aic->num_outpins = 9;
aic->mem_size = 0x4000;
aic->reg_size = 0x2000;
}
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index 5f0429c7f9..0bf96a81bb 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -17,8 +17,8 @@
OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
#define ASPEED_INTC_NR_REGS (0x2000 >> 2)
-#define ASPEED_INTC_NR_INTS 9
#define ASPEED_INTC_MAX_INPINS 9
+#define ASPEED_INTC_MAX_OUTPINS 9
struct AspeedINTCState {
/*< private >*/
@@ -30,7 +30,7 @@ struct AspeedINTCState {
uint32_t regs[ASPEED_INTC_NR_REGS];
OrIRQState orgates[ASPEED_INTC_MAX_INPINS];
- qemu_irq output_pins[ASPEED_INTC_NR_INTS];
+ qemu_irq output_pins[ASPEED_INTC_MAX_OUTPINS];
uint32_t enable[ASPEED_INTC_MAX_INPINS];
uint32_t mask[ASPEED_INTC_MAX_INPINS];
@@ -42,6 +42,7 @@ struct AspeedINTCClass {
uint32_t num_lines;
uint32_t num_inpins;
+ uint32_t num_outpins;
uint64_t mem_size;
uint64_t reg_size;
const MemoryRegionOps *reg_ops;
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 09/28] hw/intc/aspeed: Refactor INTC to support separate input and output pin indices
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (7 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output pins in INTC Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 6:20 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 10/28] hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq index and register address Jamin Lin via
` (19 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Refactors the INTC to distinguish between input and output pin indices,
improving interrupt handling clarity and accuracy.
Updated the functions to handle both input and output pin indices.
Added detailed logging for input and output pin indices in trace events.
These changes ensure that the INTC controller can handle multiple input and
output pins, improving support for the AST2700 A1.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 97 +++++++++++++++++++++++++++----------------
hw/intc/trace-events | 12 +++---
2 files changed, 67 insertions(+), 42 deletions(-)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 32c4a3bb44..4e8f1e291e 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -36,20 +36,32 @@ REG32(GICINT136_STATUS, 0x1804)
#define GICINT_STATUS_BASE R_GICINT128_STATUS
-static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
+/*
+ * Update the state of an interrupt controller pin by setting
+ * the specified output pin to the given level.
+ * The input pin index should be between 0 and the number of input pins.
+ * The output pin index should be between 0 and the number of output pins.
+ */
+static void aspeed_intc_update(AspeedINTCState *s, int inpin_idx,
+ int outpin_idx, int level)
{
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
const char *name = object_get_typename(OBJECT(s));
- if (irq >= aic->num_inpins) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Invalid input pin index: %d\n",
- __func__, irq);
+ if (inpin_idx >= aic->num_inpins) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n",
+ __func__, inpin_idx);
return;
}
- trace_aspeed_intc_update_irq(name, irq, level);
- qemu_set_irq(s->output_pins[irq], level);
+ if (outpin_idx >= aic->num_outpins) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid output pin index: %d\n",
+ __func__, outpin_idx);
+ return;
+ }
+
+ trace_aspeed_intc_update_irq(name, inpin_idx, outpin_idx, level);
+ qemu_set_irq(s->output_pins[outpin_idx], level);
}
/*
@@ -67,6 +79,11 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
uint32_t select = 0;
uint32_t enable;
int i;
+ int inpin_idx;
+ int outpin_idx;
+
+ inpin_idx = irq;
+ outpin_idx = irq;
if (irq >= aic->num_inpins) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n",
@@ -74,15 +91,15 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
return;
}
- trace_aspeed_intc_set_irq(name, irq, level);
- enable = s->enable[irq];
+ trace_aspeed_intc_set_irq(name, inpin_idx, level);
+ enable = s->enable[inpin_idx];
if (!level) {
return;
}
for (i = 0; i < aic->num_lines; i++) {
- if (s->orgates[irq].levels[i]) {
+ if (s->orgates[inpin_idx].levels[i]) {
if (enable & BIT(i)) {
select |= BIT(i);
}
@@ -95,7 +112,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
trace_aspeed_intc_select(name, select);
- if (s->mask[irq] || s->regs[status_addr]) {
+ if (s->mask[inpin_idx] || s->regs[status_addr]) {
/*
* a. mask is not 0 means in ISR mode
* sources interrupt routine are executing.
@@ -104,16 +121,17 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
*
* save source interrupt to pending variable.
*/
- s->pending[irq] |= select;
- trace_aspeed_intc_pending_irq(name, irq, s->pending[irq]);
+ s->pending[inpin_idx] |= select;
+ trace_aspeed_intc_pending_irq(name, inpin_idx, s->pending[inpin_idx]);
} else {
/*
* notify firmware which source interrupt are coming
* by setting status register
*/
s->regs[status_addr] = select;
- trace_aspeed_intc_trigger_irq(name, irq, s->regs[status_addr]);
- aspeed_intc_update(s, irq, 1);
+ trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx,
+ s->regs[status_addr]);
+ aspeed_intc_update(s, inpin_idx, outpin_idx, 1);
}
}
@@ -126,13 +144,15 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
uint32_t old_enable;
uint32_t change;
uint32_t irq;
+ int inpin_idx;
irq = (offset & 0x0f00) >> 8;
+ inpin_idx = irq;
- if (irq >= aic->num_inpins) {
+ if (inpin_idx >= aic->num_inpins) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Invalid input pin index: %d\n",
- __func__, irq);
+ __func__, inpin_idx);
return;
}
@@ -143,17 +163,17 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
*/
/* disable all source interrupt */
- if (!data && !s->enable[irq]) {
+ if (!data && !s->enable[inpin_idx]) {
s->regs[addr] = data;
return;
}
- old_enable = s->enable[irq];
- s->enable[irq] |= data;
+ old_enable = s->enable[inpin_idx];
+ s->enable[inpin_idx] |= data;
/* enable new source interrupt */
- if (old_enable != s->enable[irq]) {
- trace_aspeed_intc_enable(name, s->enable[irq]);
+ if (old_enable != s->enable[inpin_idx]) {
+ trace_aspeed_intc_enable(name, s->enable[inpin_idx]);
s->regs[addr] = data;
return;
}
@@ -161,11 +181,11 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
/* mask and unmask source interrupt */
change = s->regs[addr] ^ data;
if (change & data) {
- s->mask[irq] &= ~change;
- trace_aspeed_intc_unmask(name, change, s->mask[irq]);
+ s->mask[inpin_idx] &= ~change;
+ trace_aspeed_intc_unmask(name, change, s->mask[inpin_idx]);
} else {
- s->mask[irq] |= change;
- trace_aspeed_intc_mask(name, change, s->mask[irq]);
+ s->mask[inpin_idx] |= change;
+ trace_aspeed_intc_mask(name, change, s->mask[inpin_idx]);
}
s->regs[addr] = data;
@@ -178,6 +198,8 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
const char *name = object_get_typename(OBJECT(s));
uint32_t addr = offset >> 2;
uint32_t irq;
+ int inpin_idx;
+ int outpin_idx;
if (!data) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n", __func__);
@@ -185,11 +207,13 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
}
irq = (offset & 0x0f00) >> 8;
+ inpin_idx = irq;
+ outpin_idx = irq;
- if (irq >= aic->num_inpins) {
+ if (inpin_idx >= aic->num_inpins) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Invalid input pin index: %d\n",
- __func__, irq);
+ __func__, inpin_idx);
return;
}
@@ -208,21 +232,22 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
/* All source ISR execution are done */
if (!s->regs[addr]) {
- trace_aspeed_intc_all_isr_done(name, irq);
- if (s->pending[irq]) {
+ trace_aspeed_intc_all_isr_done(name, inpin_idx);
+ if (s->pending[inpin_idx]) {
/*
* handle pending source interrupt
* notify firmware which source interrupt are pending
* by setting status register
*/
- s->regs[addr] = s->pending[irq];
- s->pending[irq] = 0;
- trace_aspeed_intc_trigger_irq(name, irq, s->regs[addr]);
- aspeed_intc_update(s, irq, 1);
+ s->regs[addr] = s->pending[inpin_idx];
+ s->pending[inpin_idx] = 0;
+ trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx,
+ s->regs[addr]);
+ aspeed_intc_update(s, inpin_idx, outpin_idx, 1);
} else {
/* clear irq */
- trace_aspeed_intc_clear_irq(name, irq, 0);
- aspeed_intc_update(s, irq, 0);
+ trace_aspeed_intc_clear_irq(name, inpin_idx, outpin_idx, 0);
+ aspeed_intc_update(s, inpin_idx, outpin_idx, 0);
}
}
}
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index e9ca34755e..e97eea820b 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -82,12 +82,12 @@ aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64
# aspeed_intc.c
aspeed_intc_read(const char *s, uint64_t offset, unsigned size, uint32_t value) "%s: From 0x%" PRIx64 " of size %u: 0x%" PRIx32
aspeed_intc_write(const char *s, uint64_t offset, unsigned size, uint32_t data) "%s: To 0x%" PRIx64 " of size %u: 0x%" PRIx32
-aspeed_intc_set_irq(const char *s, int irq, int level) "%s: Set IRQ %d: %d"
-aspeed_intc_clear_irq(const char *s, int irq, int level) "%s: Clear IRQ %d: %d"
-aspeed_intc_update_irq(const char *s, int irq, int level) "%s: Update IRQ: %d: %d"
-aspeed_intc_pending_irq(const char *s, int irq, uint32_t value) "%s: Pending IRQ: %d: 0x%x"
-aspeed_intc_trigger_irq(const char *s, int irq, uint32_t value) "%s: Trigger IRQ: %d: 0x%x"
-aspeed_intc_all_isr_done(const char *s, int irq) "%s: All source ISR execution are done: %d"
+aspeed_intc_set_irq(const char *s, int inpin_idx, int level) "%s: Set IRQ %d: %d"
+aspeed_intc_clear_irq(const char *s, int inpin_idx, int outpin_idx, int level) "%s: Clear IRQ %d-%d: %d"
+aspeed_intc_update_irq(const char *s, int inpin_idx, int outpin_idx, int level) "%s: Update IRQ: %d-%d: %d"
+aspeed_intc_pending_irq(const char *s, int inpin_idx, uint32_t value) "%s: Pending IRQ: %d: 0x%x"
+aspeed_intc_trigger_irq(const char *s, int inpin_idx, int outpin_idx, uint32_t value) "%s: Trigger IRQ: %d-%d: 0x%x"
+aspeed_intc_all_isr_done(const char *s, int inpin_idx) "%s: All source ISR execution are done: %d"
aspeed_intc_enable(const char *s, uint32_t value) "%s: Enable: 0x%x"
aspeed_intc_select(const char *s, uint32_t value) "%s: Select: 0x%x"
aspeed_intc_mask(const char *s, uint32_t change, uint32_t value) "%s: Mask: 0x%x: 0x%x"
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 10/28] hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq index and register address
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (8 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 09/28] hw/intc/aspeed: Refactor INTC to support separate input and output pin indices Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 11/28] hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication Jamin Lin via
` (18 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
The INTC controller supports GICINT128 to GICINT136, mapping 1:1 to input and
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 IRQ
pin to 10 output IRQ pins. The pin numbers for input and output are different.
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 INTC.
Introduce the "aspeed_intc_get_irq" function to retrieve the input/output IRQ
pin index from the provided status/enable register address.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
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)
-#define GICINT_STATUS_BASE R_GICINT128_STATUS
+static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
+ {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 = 0; i < aic->irq_table_count; i++) {
+ if (aic->irq_table[i].enable_addr == addr ||
+ aic->irq_table[i].status_addr == addr) {
+ return &aic->irq_table[i];
+ }
+ }
+
+ /*
+ * Invalid addr.
+ */
+ g_assert_not_reached();
+}
/*
* 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 = (AspeedINTCState *)opaque;
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
const char *name = object_get_typename(OBJECT(s));
- uint32_t status_addr = GICINT_STATUS_BASE + ((0x100 * irq) >> 2);
+ const AspeedINTCIRQ *intc_irq;
uint32_t select = 0;
uint32_t enable;
int i;
- int inpin_idx;
- int outpin_idx;
-
- inpin_idx = irq;
- outpin_idx = irq;
if (irq >= 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;
}
- trace_aspeed_intc_set_irq(name, inpin_idx, level);
- enable = s->enable[inpin_idx];
+ intc_irq = &aic->irq_table[irq];
+ trace_aspeed_intc_set_irq(name, intc_irq->inpin_idx, level);
+ enable = s->enable[intc_irq->inpin_idx];
if (!level) {
return;
}
for (i = 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 |= BIT(i);
}
@@ -112,7 +136,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
trace_aspeed_intc_select(name, select);
- 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] |= select;
- trace_aspeed_intc_pending_irq(name, inpin_idx, s->pending[inpin_idx]);
+ s->pending[intc_irq->inpin_idx] |= 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] = 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] = 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);
}
}
@@ -140,19 +166,17 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
{
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
const char *name = object_get_typename(OBJECT(s));
+ const AspeedINTCIRQ *intc_irq;
uint32_t addr = offset >> 2;
uint32_t old_enable;
uint32_t change;
- uint32_t irq;
- int inpin_idx;
- irq = (offset & 0x0f00) >> 8;
- inpin_idx = irq;
+ intc_irq = aspeed_intc_get_irq(aic, addr);
- if (inpin_idx >= aic->num_inpins) {
+ if (intc_irq->inpin_idx >= 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;
}
@@ -163,17 +187,17 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
*/
/* disable all source interrupt */
- if (!data && !s->enable[inpin_idx]) {
+ if (!data && !s->enable[intc_irq->inpin_idx]) {
s->regs[addr] = data;
return;
}
- old_enable = s->enable[inpin_idx];
- s->enable[inpin_idx] |= data;
+ old_enable = s->enable[intc_irq->inpin_idx];
+ s->enable[intc_irq->inpin_idx] |= data;
/* enable new source interrupt */
- if (old_enable != s->enable[inpin_idx]) {
- trace_aspeed_intc_enable(name, s->enable[inpin_idx]);
+ if (old_enable != s->enable[intc_irq->inpin_idx]) {
+ trace_aspeed_intc_enable(name, s->enable[intc_irq->inpin_idx]);
s->regs[addr] = data;
return;
}
@@ -181,11 +205,11 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
/* mask and unmask source interrupt */
change = s->regs[addr] ^ data;
if (change & data) {
- s->mask[inpin_idx] &= ~change;
- trace_aspeed_intc_unmask(name, change, s->mask[inpin_idx]);
+ s->mask[intc_irq->inpin_idx] &= ~change;
+ trace_aspeed_intc_unmask(name, change, s->mask[intc_irq->inpin_idx]);
} else {
- s->mask[inpin_idx] |= change;
- trace_aspeed_intc_mask(name, change, s->mask[inpin_idx]);
+ s->mask[intc_irq->inpin_idx] |= change;
+ trace_aspeed_intc_mask(name, change, s->mask[intc_irq->inpin_idx]);
}
s->regs[addr] = data;
@@ -196,24 +220,20 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
{
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
const char *name = object_get_typename(OBJECT(s));
+ const AspeedINTCIRQ *intc_irq;
uint32_t addr = offset >> 2;
- uint32_t irq;
- int inpin_idx;
- int outpin_idx;
if (!data) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n", __func__);
return;
}
- irq = (offset & 0x0f00) >> 8;
- inpin_idx = irq;
- outpin_idx = irq;
+ intc_irq = aspeed_intc_get_irq(aic, addr);
- if (inpin_idx >= aic->num_inpins) {
+ if (intc_irq->inpin_idx >= 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;
}
@@ -232,22 +252,24 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
/* 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] = s->pending[inpin_idx];
- s->pending[inpin_idx] = 0;
- trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx,
+ s->regs[addr] = s->pending[intc_irq->inpin_idx];
+ s->pending[intc_irq->inpin_idx] = 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_idx, 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_idx, 0);
}
}
}
@@ -420,6 +442,8 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
aic->num_outpins = 9;
aic->mem_size = 0x4000;
aic->reg_size = 0x2000;
+ aic->irq_table = aspeed_2700_intc_irqs;
+ aic->irq_table_count = ARRAY_SIZE(aspeed_2700_intc_irqs);
}
static const TypeInfo aspeed_2700_intc_info = {
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, ASPEED_INTC)
#define ASPEED_INTC_MAX_INPINS 9
#define ASPEED_INTC_MAX_OUTPINS 9
+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;
};
#endif /* ASPEED_INTC_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 11/28] hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (9 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 10/28] hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq index and register address Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 9:17 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 12/28] hw/intc/aspeed: Add Support for Multi-Output IRQ Handling Jamin Lin via
` (17 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
The behavior of the INTC set IRQ is almost identical between INTC and INTCIO.
To reduce duplicated code, introduce the "aspeed_intc_set_irq_handler" function
to handle both INTC and INTCIO IRQ behavior.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 62 ++++++++++++++++++++++++-------------------
1 file changed, 34 insertions(+), 28 deletions(-)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 59c1069294..fd4f75805a 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -92,11 +92,40 @@ static void aspeed_intc_update(AspeedINTCState *s, int inpin_idx,
qemu_set_irq(s->output_pins[outpin_idx], level);
}
+static void aspeed_intc_set_irq_handler(AspeedINTCState *s,
+ const AspeedINTCIRQ *intc_irq,
+ uint32_t select)
+{
+ const char *name = object_get_typename(OBJECT(s));
+
+ 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.
+ * b. status register value is not 0 means previous
+ * source interrupt does not be executed, yet.
+ *
+ * save source interrupt to pending variable.
+ */
+ s->pending[intc_irq->inpin_idx] |= 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[intc_irq->status_addr] = 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);
+ }
+}
+
/*
- * The address of GICINT128 to GICINT136 are from 0x1000 to 0x1804.
- * Utilize "address & 0x0f00" to get the irq and irq output pin index
- * The value of irq should be 0 to num_inpins.
- * The irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on.
+ * GICINT128 to GICINT136 map 1:1 to input and output IRQs 0 to 8.
+ * The value of input IRQ should be between 0 and the number of inputs.
*/
static void aspeed_intc_set_irq(void *opaque, int irq, int level)
{
@@ -135,30 +164,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
}
trace_aspeed_intc_select(name, select);
-
- 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.
- * b. status register value is not 0 means previous
- * source interrupt does not be executed, yet.
- *
- * save source interrupt to pending variable.
- */
- s->pending[intc_irq->inpin_idx] |= 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[intc_irq->status_addr] = 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);
- }
+ aspeed_intc_set_irq_handler(s, intc_irq, select);
}
static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 12/28] hw/intc/aspeed: Add Support for Multi-Output IRQ Handling
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (10 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 11/28] hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700 INTCIO Controller Jamin Lin via
` (16 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
This update introduces support for handling multi-output IRQs in the AST2700
interrupt controller (INTC), specifically for GICINT192_201. GICINT192_201 maps
1:10 to input IRQ 0 and output IRQs 0 to 9. Each status bit corresponds to a
specific IRQ.
Implemented "aspeed_intc_set_irq_handler_multi_outpins" to handle IRQs with
multiple output pins. Introduced "aspeed_intc_status_handler_multi_outpins"
for managing status registers associated with multi-output IRQs.
Added new IRQ definitions for GICINT192_201 in INTC.
Adjusted the IRQ array to accommodate 10 input pins and 19 output pins,
aligning with the new GICINT192_201 mappings.
|------------------------------|
| INTC |
|inpin[0:0]--------->outpin[0] |
|inpin[0:1]--------->outpin[1] |
|inpin[0:2]--------->outpin[2] |
|inpin[0:3]--------->outpin[3] |
orgates[0]-------> |inpin[0:4]--------->outpin[4] |
|inpin[0:5]--------->outpin[5] |
|inpin[0:6]--------->outpin[6] |
|inpin[0:7]--------->outpin[7] |
|inpin[0:8]--------->outpin[8] |
|inpin[0:9]--------->outpin[9] |
| |
orgates[1]------> |inpin[1]----------->outpin[10]|
orgates[2]------> |inpin[2]----------->outpin[11]|
orgates[3]------> |inpin[3]----------->outpin[12]|
orgates[4]------> |inpin[4]----------->outpin[13]|
orgates[5]------> |inpin[5]----------->outpin[14]|
orgates[6]------> |inpin[6]----------->outpin[15]|
orgates[7]------> |inpin[7]----------->outpin[16]|
orgates[8]------> |inpin[8]----------->outpin[17]|
orgates[9]------> |inpin[9]----------->outpin[18]|
|------------------------------|
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 142 ++++++++++++++++++++++++++++++----
hw/intc/trace-events | 1 +
include/hw/intc/aspeed_intc.h | 4 +-
3 files changed, 131 insertions(+), 16 deletions(-)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index fd4f75805a..1a9e2bf8ce 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -33,17 +33,20 @@ REG32(GICINT135_EN, 0x1700)
REG32(GICINT135_STATUS, 0x1704)
REG32(GICINT136_EN, 0x1800)
REG32(GICINT136_STATUS, 0x1804)
+REG32(GICINT192_201_EN, 0x1B00)
+REG32(GICINT192_201_STATUS, 0x1B04)
static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
- {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},
+ {0, 0, 10, R_GICINT192_201_EN, R_GICINT192_201_STATUS},
+ {1, 10, 1, R_GICINT128_EN, R_GICINT128_STATUS},
+ {2, 11, 1, R_GICINT129_EN, R_GICINT129_STATUS},
+ {3, 12, 1, R_GICINT130_EN, R_GICINT130_STATUS},
+ {4, 13, 1, R_GICINT131_EN, R_GICINT131_STATUS},
+ {5, 14, 1, R_GICINT132_EN, R_GICINT132_STATUS},
+ {6, 15, 1, R_GICINT133_EN, R_GICINT133_STATUS},
+ {7, 16, 1, R_GICINT134_EN, R_GICINT134_STATUS},
+ {8, 17, 1, R_GICINT135_EN, R_GICINT135_STATUS},
+ {9, 18, 1, R_GICINT136_EN, R_GICINT136_STATUS},
};
static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic,
@@ -123,9 +126,48 @@ static void aspeed_intc_set_irq_handler(AspeedINTCState *s,
}
}
+static void aspeed_intc_set_irq_handler_multi_outpins(AspeedINTCState *s,
+ const AspeedINTCIRQ *intc_irq, uint32_t select)
+{
+ const char *name = object_get_typename(OBJECT(s));
+ int i;
+
+ for (i = 0; i < intc_irq->num_outpins; i++) {
+ if (select & BIT(i)) {
+ if (s->mask[intc_irq->inpin_idx] & BIT(i) ||
+ s->regs[intc_irq->status_addr] & BIT(i)) {
+ /*
+ * a. mask bit is not 0 means in ISR mode sources interrupt
+ * routine are executing.
+ * b. status bit is not 0 means previous source interrupt
+ * does not be executed, yet.
+ *
+ * save source interrupt to pending bit.
+ */
+ s->pending[intc_irq->inpin_idx] |= BIT(i);
+ 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 bit
+ */
+ s->regs[intc_irq->status_addr] |= BIT(i);
+ trace_aspeed_intc_trigger_irq(name, intc_irq->inpin_idx,
+ intc_irq->outpin_idx + i,
+ s->regs[intc_irq->status_addr]);
+ aspeed_intc_update(s, intc_irq->inpin_idx,
+ intc_irq->outpin_idx + i, 1);
+ }
+ }
+ }
+}
+
/*
- * GICINT128 to GICINT136 map 1:1 to input and output IRQs 0 to 8.
- * The value of input IRQ should be between 0 and the number of inputs.
+ * GICINT192_201 maps 1:10 to input IRQ 0 and output IRQs 0 to 9.
+ * GICINT128 to GICINT136 map 1:1 to input IRQs 1 to 9 and output
+ * IRQs 10 to 18. The value of input IRQ should be between 0 and
+ * the number of input pins.
*/
static void aspeed_intc_set_irq(void *opaque, int irq, int level)
{
@@ -164,7 +206,11 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
}
trace_aspeed_intc_select(name, select);
- aspeed_intc_set_irq_handler(s, intc_irq, select);
+ if (intc_irq->num_outpins > 1) {
+ aspeed_intc_set_irq_handler_multi_outpins(s, intc_irq, select);
+ } else {
+ aspeed_intc_set_irq_handler(s, intc_irq, select);
+ }
}
static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
@@ -280,6 +326,70 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
}
}
+static void aspeed_intc_status_handler_multi_outpins(AspeedINTCState *s,
+ hwaddr offset, uint64_t data)
+{
+ AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
+ const AspeedINTCIRQ *intc_irq;
+ uint32_t addr = offset >> 2;
+ int i;
+
+ if (!data) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n", __func__);
+ return;
+ }
+
+ intc_irq = aspeed_intc_get_irq(aic, addr);
+
+ if (intc_irq->inpin_idx >= aic->num_inpins) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Invalid input pin index: %d\n",
+ __func__, intc_irq->inpin_idx);
+ return;
+ }
+
+ /* clear status */
+ s->regs[addr] &= ~data;
+
+ /*
+ * The status registers are used for notify sources ISR are executed.
+ * If one source ISR is executed, it will clear one bit.
+ * If it clear all bits, it means to initialize this register status
+ * rather than sources ISR are executed.
+ */
+ if (data == 0xffffffff) {
+ return;
+ }
+
+ for (i = 0; i < intc_irq->num_outpins; i++) {
+ /* All source ISR executions are done from a specific bit */
+ if (data & BIT(i)) {
+ trace_aspeed_intc_all_isr_done_bit(name, intc_irq->inpin_idx, i);
+ if (s->pending[intc_irq->inpin_idx] & BIT(i)) {
+ /*
+ * Handle pending source interrupt.
+ * Notify firmware which source interrupt is pending
+ * by setting the status bit.
+ */
+ s->regs[addr] |= BIT(i);
+ s->pending[intc_irq->inpin_idx] &= ~BIT(i);
+ trace_aspeed_intc_trigger_irq(name, intc_irq->inpin_idx,
+ intc_irq->outpin_idx + i,
+ s->regs[addr]);
+ aspeed_intc_update(s, intc_irq->inpin_idx,
+ intc_irq->outpin_idx + i, 1);
+ } else {
+ /* clear irq for the specific bit */
+ trace_aspeed_intc_clear_irq(name, intc_irq->inpin_idx,
+ intc_irq->outpin_idx + i, 0);
+ aspeed_intc_update(s, intc_irq->inpin_idx,
+ intc_irq->outpin_idx + i, 0);
+ }
+ }
+ }
+}
+
static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
{
AspeedINTCState *s = ASPEED_INTC(opaque);
@@ -328,6 +438,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
case R_GICINT134_EN:
case R_GICINT135_EN:
case R_GICINT136_EN:
+ case R_GICINT192_201_EN:
aspeed_intc_enable_handler(s, offset, data);
break;
case R_GICINT128_STATUS:
@@ -341,6 +452,9 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
case R_GICINT136_STATUS:
aspeed_intc_status_handler(s, offset, data);
break;
+ case R_GICINT192_201_STATUS:
+ aspeed_intc_status_handler_multi_outpins(s, offset, data);
+ break;
default:
s->regs[addr] = data;
break;
@@ -444,8 +558,8 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2700 INTC Controller";
aic->num_lines = 32;
- aic->num_inpins = 9;
- aic->num_outpins = 9;
+ aic->num_inpins = 10;
+ aic->num_outpins = 19;
aic->mem_size = 0x4000;
aic->reg_size = 0x2000;
aic->irq_table = aspeed_2700_intc_irqs;
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index e97eea820b..913197a181 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -92,6 +92,7 @@ aspeed_intc_enable(const char *s, uint32_t value) "%s: Enable: 0x%x"
aspeed_intc_select(const char *s, uint32_t value) "%s: Select: 0x%x"
aspeed_intc_mask(const char *s, uint32_t change, uint32_t value) "%s: Mask: 0x%x: 0x%x"
aspeed_intc_unmask(const char *s, uint32_t change, uint32_t value) "%s: UnMask: 0x%x: 0x%x"
+aspeed_intc_all_isr_done_bit(const char *s, int inpin_idx, int bit) "%s: All source ISR execution are done from specific bit: %d-%d"
# arm_gic.c
gic_enable_irq(int irq) "irq %d enabled"
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index abf2cae996..57146db2ce 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -17,8 +17,8 @@
OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
#define ASPEED_INTC_NR_REGS (0x2000 >> 2)
-#define ASPEED_INTC_MAX_INPINS 9
-#define ASPEED_INTC_MAX_OUTPINS 9
+#define ASPEED_INTC_MAX_INPINS 10
+#define ASPEED_INTC_MAX_OUTPINS 19
typedef struct AspeedINTCIRQ {
int inpin_idx;
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (11 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 12/28] hw/intc/aspeed: Add Support for Multi-Output IRQ Handling Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 9:15 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 14/28] hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon Revisions Jamin Lin via
` (15 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Introduce a new ast2700 INTCIO class to support AST2700 INTCIO.
Added new register definitions for INTCIO, including enable and status
registers for IRQs GICINT192 through GICINT197.
Created a dedicated IRQ array for INTCIO, supporting six input pins and six
output pins, aligning with the newly defined registers.
Implemented "aspeed_intcio_read" and "aspeed_intcio_write" to handle
INTCIO-specific register access.
To GICINT196 |
ETH1 |-----------| |--------------------------|
-------->|0 | | INTCIO |
ETH2 | 4| orgates[0]------>|inpin[0]-------->outpin[0]|
-------->|1 5| orgates[1]------>|inpin[1]-------->outpin[1]|
ETH3 | 6| orgates[2]------>|inpin[2]-------->outpin[2]|
-------->|2 19| orgates[3]------>|inpin[3]-------->outpin[3]|
UART0 | 20|-->orgates[4]------>|inpin[4]-------->outpin[4]|
-------->|7 21| orgates[5]------>|inpin[5]-------->outpin[5]|
UART1 | 22| |--------------------------|
-------->|8 23|
UART2 | 24|
-------->|9 25|
UART3 | 26|
---------|10 27|
UART5 | 28|
-------->|11 29|
UART6 | |
-------->|12 30|
UART7 | 31|
-------->|13 |
UART8 | OR[0:31] |
-------->|14 |
UART9 | |
-------->|15 |
UART10 | |
-------->|16 |
UART11 | |
-------->|17 |
UART12 | |
-------->|18 |
|-----------|
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/intc/aspeed_intc.c | 121 ++++++++++++++++++++++++++++++++++
include/hw/intc/aspeed_intc.h | 1 +
2 files changed, 122 insertions(+)
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index 1a9e2bf8ce..a3bf935789 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -36,6 +36,20 @@ REG32(GICINT136_STATUS, 0x1804)
REG32(GICINT192_201_EN, 0x1B00)
REG32(GICINT192_201_STATUS, 0x1B04)
+/* INTCIO Registers */
+REG32(GICINT192_EN, 0x100)
+REG32(GICINT192_STATUS, 0x104)
+REG32(GICINT193_EN, 0x110)
+REG32(GICINT193_STATUS, 0x114)
+REG32(GICINT194_EN, 0x120)
+REG32(GICINT194_STATUS, 0x124)
+REG32(GICINT195_EN, 0x130)
+REG32(GICINT195_STATUS, 0x134)
+REG32(GICINT196_EN, 0x140)
+REG32(GICINT196_STATUS, 0x144)
+REG32(GICINT197_EN, 0x150)
+REG32(GICINT197_STATUS, 0x154)
+
static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
{0, 0, 10, R_GICINT192_201_EN, R_GICINT192_201_STATUS},
{1, 10, 1, R_GICINT128_EN, R_GICINT128_STATUS},
@@ -49,6 +63,15 @@ static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
{9, 18, 1, R_GICINT136_EN, R_GICINT136_STATUS},
};
+static AspeedINTCIRQ aspeed_2700_intcio_irqs[ASPEED_INTC_MAX_INPINS] = {
+ {0, 0, 1, R_GICINT192_EN, R_GICINT192_STATUS},
+ {1, 1, 1, R_GICINT193_EN, R_GICINT193_STATUS},
+ {2, 2, 1, R_GICINT194_EN, R_GICINT194_STATUS},
+ {3, 3, 1, R_GICINT195_EN, R_GICINT195_STATUS},
+ {4, 4, 1, R_GICINT196_EN, R_GICINT196_STATUS},
+ {5, 5, 1, R_GICINT197_EN, R_GICINT197_STATUS},
+};
+
static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic,
uint32_t addr)
{
@@ -463,6 +486,71 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
return;
}
+static uint64_t aspeed_intcio_read(void *opaque, hwaddr offset,
+ unsigned int size)
+{
+ AspeedINTCState *s = ASPEED_INTC(opaque);
+ AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
+ uint32_t addr = offset >> 2;
+ uint32_t value = 0;
+
+ if (offset >= aic->reg_size) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ return 0;
+ }
+
+ value = s->regs[addr];
+ trace_aspeed_intc_read(name, offset, size, value);
+
+ return value;
+}
+
+static void aspeed_intcio_write(void *opaque, hwaddr offset, uint64_t data,
+ unsigned size)
+{
+ AspeedINTCState *s = ASPEED_INTC(opaque);
+ AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
+ const char *name = object_get_typename(OBJECT(s));
+ uint32_t addr = offset >> 2;
+
+ if (offset >= aic->reg_size) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ return;
+ }
+
+ trace_aspeed_intc_write(name, offset, size, data);
+
+ switch (addr) {
+ case R_GICINT192_EN:
+ case R_GICINT193_EN:
+ case R_GICINT194_EN:
+ case R_GICINT195_EN:
+ case R_GICINT196_EN:
+ case R_GICINT197_EN:
+ aspeed_intc_enable_handler(s, offset, data);
+ break;
+ case R_GICINT192_STATUS:
+ case R_GICINT193_STATUS:
+ case R_GICINT194_STATUS:
+ case R_GICINT195_STATUS:
+ case R_GICINT196_STATUS:
+ case R_GICINT197_STATUS:
+ aspeed_intc_status_handler(s, offset, data);
+ break;
+ default:
+ s->regs[addr] = data;
+ break;
+ }
+
+ return;
+}
+
+
static const MemoryRegionOps aspeed_intc_ops = {
.read = aspeed_intc_read,
.write = aspeed_intc_write,
@@ -473,6 +561,16 @@ static const MemoryRegionOps aspeed_intc_ops = {
}
};
+static const MemoryRegionOps aspeed_intcio_ops = {
+ .read = aspeed_intcio_read,
+ .write = aspeed_intcio_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ }
+};
+
static void aspeed_intc_instance_init(Object *obj)
{
AspeedINTCState *s = ASPEED_INTC(obj);
@@ -572,10 +670,33 @@ static const TypeInfo aspeed_2700_intc_info = {
.class_init = aspeed_2700_intc_class_init,
};
+static void aspeed_2700_intcio_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
+
+ dc->desc = "ASPEED 2700 INTC IO Controller";
+ aic->num_lines = 32;
+ aic->num_inpins = 6;
+ aic->num_outpins = 6;
+ aic->mem_size = 0x400;
+ aic->reg_size = 0x3d8;
+ aic->reg_ops = &aspeed_intcio_ops;
+ aic->irq_table = aspeed_2700_intcio_irqs;
+ aic->irq_table_count = ARRAY_SIZE(aspeed_2700_intcio_irqs);
+}
+
+static const TypeInfo aspeed_2700_intcio_info = {
+ .name = TYPE_ASPEED_2700_INTCIO,
+ .parent = TYPE_ASPEED_INTC,
+ .class_init = aspeed_2700_intcio_class_init,
+};
+
static void aspeed_intc_register_types(void)
{
type_register_static(&aspeed_intc_info);
type_register_static(&aspeed_2700_intc_info);
+ type_register_static(&aspeed_2700_intcio_info);
}
type_init(aspeed_intc_register_types);
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index 57146db2ce..e8ead15491 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -14,6 +14,7 @@
#define TYPE_ASPEED_INTC "aspeed.intc"
#define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700"
+#define TYPE_ASPEED_2700_INTCIO TYPE_ASPEED_INTC "io" "-ast2700"
OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
#define ASPEED_INTC_NR_REGS (0x2000 >> 2)
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 14/28] hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon Revisions
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (12 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700 INTCIO Controller Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 6:35 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700 Jamin Lin via
` (14 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Added new definitions for AST2700_A1_SILICON_REV and AST2750_A1_SILICON_REV to
identify the A1 silicon revisions.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/misc/aspeed_scu.c | 2 ++
include/hw/misc/aspeed_scu.h | 2 ++
2 files changed, 4 insertions(+)
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index bac1441b06..2d9fe78926 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -559,6 +559,8 @@ static uint32_t aspeed_silicon_revs[] = {
AST2700_A0_SILICON_REV,
AST2720_A0_SILICON_REV,
AST2750_A0_SILICON_REV,
+ AST2700_A1_SILICON_REV,
+ AST2750_A1_SILICON_REV,
};
bool is_supported_silicon_rev(uint32_t silicon_rev)
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
index 356be95e45..684b48b722 100644
--- a/include/hw/misc/aspeed_scu.h
+++ b/include/hw/misc/aspeed_scu.h
@@ -54,6 +54,8 @@ struct AspeedSCUState {
#define AST2700_A0_SILICON_REV 0x06000103U
#define AST2720_A0_SILICON_REV 0x06000203U
#define AST2750_A0_SILICON_REV 0x06000003U
+#define AST2700_A1_SILICON_REV 0x06010103U
+#define AST2750_A1_SILICON_REV 0x06010003U
#define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04)
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (13 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 14/28] hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon Revisions Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 6:47 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 16/28] hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping Jamin Lin via
` (13 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
According to the design of the AST2600, it has a Silicon Revision ID Register,
specifically SCU004 and SCU014, to set the Revision ID for the AST2600.
For the AST2600 A3, SCU004 is set to 0x05030303 and SCU014 is set to 0x05030303.
In the "aspeed_ast2600_scu_reset" function, the hardcoded value
"AST2600_A3_SILICON_REV" is set in SCU004, and "s->silicon_rev" is set in
SCU014. The value of "s->silicon_rev" is set by the SOC layer via the
"silicon-rev" property.
However, the design of the AST2700 is different. There are two SCU controllers:
SCU0 (CPU Die) and SCU1 (IO Die). In the AST2700, the firmware reads the
SCU Silicon Revision ID register (SCU0_000) and the SCUIO Silicon Revision ID
register (SCU1_000) and combines them into a 64-bit value.
The combined value of SCU0_000[23:16] and SCU1_000[23:16] represents the silicon
revision. For example, the AST2700-A1 revision is "0x0601010306010103", where
SCU0_000 should be 06010103 and SCU1_000 should be 06010103.
Reference:
https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2023.10/arch/arm/mach-aspeed/ast2700/cpu-info.c
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/misc/aspeed_scu.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 2d9fe78926..b45a36a555 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -911,7 +911,6 @@ static const MemoryRegionOps aspeed_ast2700_scu_ops = {
};
static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS] = {
- [AST2700_SILICON_REV] = AST2700_A0_SILICON_REV,
[AST2700_HW_STRAP1] = 0x00000800,
[AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
[AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
@@ -940,6 +939,7 @@ static void aspeed_ast2700_scu_reset(DeviceState *dev)
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
memcpy(s->regs, asc->resets, asc->nr_regs * 4);
+ s->regs[AST2700_SILICON_REV] = s->silicon_rev;
}
static void aspeed_2700_scu_class_init(ObjectClass *klass, void *data)
@@ -1032,7 +1032,6 @@ static const MemoryRegionOps aspeed_ast2700_scuio_ops = {
};
static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
- [AST2700_SILICON_REV] = 0x06000003,
[AST2700_HW_STRAP1] = 0x00000504,
[AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
[AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 16/28] hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (14 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 17/28] hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for AST2700 A1 Jamin Lin via
` (12 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Currently, these IRQ tables support from GIC 128 - 136 for AST2700 A0.
These IRQ tables can be reused for AST2700 A1 from GIC 192 - 197.
Updates the interrupt mapping to include support for AST2700 A1 by extending
the existing mappings to the new GIC range.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast27x0.c | 82 ++++++++++++++++++++++++++---------------
1 file changed, 52 insertions(+), 30 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 775e953afd..ca4b620a1d 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -119,21 +119,27 @@ static const int aspeed_soc_ast2700a0_irqmap[] = {
};
/* GICINT 128 */
-static const int aspeed_soc_ast2700_gic128_intcmap[] = {
+/* GICINT 192 */
+static const int ast2700_gic128_gic192_intcmap[] = {
[ASPEED_DEV_LPC] = 0,
[ASPEED_DEV_IBT] = 2,
[ASPEED_DEV_KCS] = 4,
};
+/* GICINT 129 */
+/* GICINT 193 */
+
/* GICINT 130 */
-static const int aspeed_soc_ast2700_gic130_intcmap[] = {
+/* GICINT 194 */
+static const int ast2700_gic130_gic194_intcmap[] = {
[ASPEED_DEV_I2C] = 0,
[ASPEED_DEV_ADC] = 16,
[ASPEED_DEV_GPIO] = 18,
};
/* GICINT 131 */
-static const int aspeed_soc_ast2700_gic131_intcmap[] = {
+/* GICINT 195 */
+static const int ast2700_gic131_gic195_intcmap[] = {
[ASPEED_DEV_I3C] = 0,
[ASPEED_DEV_WDT] = 16,
[ASPEED_DEV_FMC] = 25,
@@ -141,7 +147,8 @@ static const int aspeed_soc_ast2700_gic131_intcmap[] = {
};
/* GICINT 132 */
-static const int aspeed_soc_ast2700_gic132_intcmap[] = {
+/* GICINT 196 */
+static const int ast2700_gic132_gic196_intcmap[] = {
[ASPEED_DEV_ETH1] = 0,
[ASPEED_DEV_ETH2] = 1,
[ASPEED_DEV_ETH3] = 2,
@@ -160,24 +167,26 @@ static const int aspeed_soc_ast2700_gic132_intcmap[] = {
};
/* GICINT 133 */
-static const int aspeed_soc_ast2700_gic133_intcmap[] = {
+/* GICINT 197 */
+static const int ast2700_gic133_gic197_intcmap[] = {
[ASPEED_DEV_SDHCI] = 1,
[ASPEED_DEV_PECI] = 4,
};
/* GICINT 128 ~ 136 */
+/* GICINT 192 ~ 201 */
struct gic_intc_irq_info {
int irq;
const int *ptr;
};
-static const struct gic_intc_irq_info aspeed_soc_ast2700_gic_intcmap[] = {
- {128, aspeed_soc_ast2700_gic128_intcmap},
+static const struct gic_intc_irq_info ast2700_gic_intcmap[] = {
+ {128, ast2700_gic128_gic192_intcmap},
{129, NULL},
- {130, aspeed_soc_ast2700_gic130_intcmap},
- {131, aspeed_soc_ast2700_gic131_intcmap},
- {132, aspeed_soc_ast2700_gic132_intcmap},
- {133, aspeed_soc_ast2700_gic133_intcmap},
+ {130, ast2700_gic130_gic194_intcmap},
+ {131, ast2700_gic131_gic195_intcmap},
+ {132, ast2700_gic132_gic196_intcmap},
+ {133, ast2700_gic133_gic197_intcmap},
{134, NULL},
{135, NULL},
{136, NULL},
@@ -189,11 +198,11 @@ static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
int i;
- for (i = 0; i < ARRAY_SIZE(aspeed_soc_ast2700_gic_intcmap); i++) {
- if (sc->irqmap[dev] == aspeed_soc_ast2700_gic_intcmap[i].irq) {
- assert(aspeed_soc_ast2700_gic_intcmap[i].ptr);
+ for (i = 0; i < ARRAY_SIZE(ast2700_gic_intcmap); i++) {
+ if (sc->irqmap[dev] == ast2700_gic_intcmap[i].irq) {
+ assert(ast2700_gic_intcmap[i].ptr);
return qdev_get_gpio_in(DEVICE(&a->intc.orgates[i]),
- aspeed_soc_ast2700_gic_intcmap[i].ptr[dev]);
+ ast2700_gic_intcmap[i].ptr[dev]);
}
}
@@ -207,16 +216,17 @@ static qemu_irq aspeed_soc_ast2700_get_irq_index(AspeedSoCState *s, int dev,
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
int i;
- for (i = 0; i < ARRAY_SIZE(aspeed_soc_ast2700_gic_intcmap); i++) {
- if (sc->irqmap[dev] == aspeed_soc_ast2700_gic_intcmap[i].irq) {
- assert(aspeed_soc_ast2700_gic_intcmap[i].ptr);
+ for (i = 0; i < ARRAY_SIZE(ast2700_gic_intcmap); i++) {
+ if (sc->irqmap[dev] == ast2700_gic_intcmap[i].irq) {
+ assert(ast2700_gic_intcmap[i].ptr);
return qdev_get_gpio_in(DEVICE(&a->intc.orgates[i]),
- aspeed_soc_ast2700_gic_intcmap[i].ptr[dev] + index);
+ ast2700_gic_intcmap[i].ptr[dev] + index);
}
}
/*
- * Invalid orgate index, device irq should be 128 to 136.
+ * Invalid OR gate index, device IRQ should be between 128 to 136
+ * and 192 to 201.
*/
g_assert_not_reached();
}
@@ -481,7 +491,6 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
AspeedSoCState *s = ASPEED_SOC(dev);
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
- AspeedINTCClass *ic = ASPEED_INTC_GET_CLASS(&a->intc);
g_autofree char *sram_name = NULL;
qemu_irq irq;
@@ -519,17 +528,18 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc), 0,
sc->memmap[ASPEED_DEV_INTC]);
- /* source orgates -> INTC */
- for (i = 0; i < ic->num_inpins; i++) {
+ /* irq sources -> orgates -> INTC */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc)->num_inpins; i++) {
qdev_connect_gpio_out(DEVICE(&a->intc.orgates[i]), 0,
- qdev_get_gpio_in(DEVICE(&a->intc), i));
+ qdev_get_gpio_in(DEVICE(&a->intc), i));
}
+ /* INTC -> GIC192 - GIC201 */
/* INTC -> GIC128 - GIC136 */
- for (i = 0; i < ic->num_outpins; i++) {
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc)->num_outpins; i++) {
sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc), i,
qdev_get_gpio_in(DEVICE(&a->gic),
- aspeed_soc_ast2700_gic_intcmap[i].irq));
+ ast2700_gic_intcmap[i].irq));
}
/* SRAM */
@@ -680,10 +690,22 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
/*
* The AST2700 I2C controller has one source INTC per bus.
- * I2C buses interrupt are connected to GICINT130_INTC
- * from bit 0 to bit 15.
- * I2C bus 0 is connected to GICINT130_INTC at bit 0.
- * I2C bus 15 is connected to GICINT130_INTC at bit 15.
+ *
+ * For AST2700 A0:
+ * I2C bus interrupts are connected to the OR gate from bit 0 to bit
+ * 15, and the OR gate output pin is connected to the input pin of
+ * GICINT130 of INTC (CPU Die). Then, the output pin is connected to
+ * the GIC.
+ *
+ * For AST2700 A1:
+ * I2C bus interrupts are connected to the OR gate from bit 0 to bit
+ * 15, and the OR gate output pin is connected to the input pin of
+ * GICINT194 of INTCIO (IO Die). Then, the output pin is connected
+ * to the INTC (CPU Die) input pin, and its output pin is connected
+ * to the GIC.
+ *
+ * I2C bus 0 is connected to the OR gate at bit 0.
+ * I2C bus 15 is connected to the OR gate at bit 15.
*/
irq = aspeed_soc_ast2700_get_irq_index(s, ASPEED_DEV_I2C, i);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 17/28] hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for AST2700 A1
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (15 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 16/28] hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support " Jamin Lin via
` (11 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
The design of INTC controllers has significantly changed in AST2700 A1.
There are a total of 480 interrupt sources in AST2700 A1. For interrupt numbers
from 0 to 127, they can route directly to PSP, SSP, and TSP. Due to the
limitation of interrupt numbers of processors, the interrupts are merged every
32 sources for interrupt numbers greater than 127.
There are two levels of interrupt controllers, INTC(CPUD Die) and INTCIO
(IO Die). The interrupt sources of INTC are the interrupt numbers from INTC_0 to
INTC_127 and interrupts from INTCIO. The interrupt sources of INTCIO are the
interrupt numbers greater than INTC_127. INTC_IO controls the interrupts
INTC_128 to INTC_319 only.
Currently, only GIC 192 to 201 are supported, and their source interrupts are
from INTCIO and connected to INTC at input pin 0 and output pins 0 to 9 for
GIC 192-201.
The design of the orgates for GICINT 196 is as follows:
It has interrupt sources ranging from 0 to 31, with its output pin connected to
INTCIO "T0 GICINT_196". The output pin is then connected to INTC "GIC_192_201"
at bit 4, and its bit 4 output should be connected to GIC 196.
The design of INTC GIC_192_201 have 10 output pins, mapped as following:
Bit 0 -> GIC 192
Bit 1 -> GIC 193
Bit 2 -> GIC 194
Bit 3 -> GIC 195
Bit 4 -> GIC 196
To support both AST2700 A1 and A0, INTC input pins 1 to 9 and output pins
10 to 18 remain to support GIC 128-136, which source interrupts from INTC.
These will be removed if we decide not to support AST2700 A0 in the future.
|-------------------------------------------------------------------------------------------------------|
| AST2700 A1 Design |
| To GICINT196 |
| |
| ETH1 |-----------| |--------------------------| |--------------| |
| -------->|0 | | INTCIO | | orgates[0] | |
| ETH2 | 4| orgates[0]------>|inpin[0]-------->outpin[0]|------->| 0 | |
| -------->|1 5| orgates[1]------>|inpin[1]-------->outpin[1]|------->| 1 | |
| ETH3 | 6| orgates[2]------>|inpin[2]-------->outpin[2]|------->| 2 | |
| -------->|2 19| orgates[3]------>|inpin[3]-------->outpin[3]|------->| 3 OR[0:9] |-----| |
| UART0 | 20|-->orgates[4]------>|inpin[4]-------->outpin[4]|------->| 4 | | |
| -------->|7 21| orgates[5]------>|inpin[5]-------->outpin[5]|------->| 5 | | |
| UART1 | 22| orgates[6]------>|inpin[6]-------->outpin[6]|------->| 6 | | |
| -------->|8 23| orgates[7]------>|inpin[7]-------->outpin[7]|------->| 7 | | |
| UART2 | 24| orgates[8]------>|inpin[8]-------->outpin[8]|------->| 8 | | |
| -------->|9 25| orgates[9]------>|inpin[9]-------->outpin[9]|------->| 9 | | |
| UART3 | 26| |--------------------------| |--------------| | |
| ---------|10 27| | |
| UART5 | 28| | |
| -------->|11 29| | |
| UART6 | | | |
| -------->|12 30| |-----------------------------------------------------------------------| |
| UART7 | 31| | |
| -------->|13 | | |
| UART8 | OR[0:31] | | |------------------------------| |----------| |
| -------->|14 | | | INTC | | GIC | |
| UART9 | | | |inpin[0:0]--------->outpin[0] |---------->|192 | |
| -------->|15 | | |inpin[0:1]--------->outpin[1] |---------->|193 | |
| UART10 | | | |inpin[0:2]--------->outpin[2] |---------->|194 | |
| -------->|16 | | |inpin[0:3]--------->outpin[3] |---------->|195 | |
| UART11 | | |--------------> |inpin[0:4]--------->outpin[4] |---------->|196 | |
| -------->|17 | |inpin[0:5]--------->outpin[5] |---------->|197 | |
| UART12 | | |inpin[0:6]--------->outpin[6] |---------->|198 | |
| -------->|18 | |inpin[0:7]--------->outpin[7] |---------->|199 | |
| |-----------| |inpin[0:8]--------->outpin[8] |---------->|200 | |
| |inpin[0:9]--------->outpin[9] |---------->|201 | |
|-------------------------------------------------------------------------------------------------------|
|-------------------------------------------------------------------------------------------------------|
| ETH1 |-----------| orgates[1]------->|inpin[1]----------->outpin[10]|---------->|128 | |
| -------->|0 | orgates[2]------->|inpin[2]----------->outpin[11]|---------->|129 | |
| ETH2 | 4| orgates[3]------->|inpin[3]----------->outpin[12]|---------->|130 | |
| -------->|1 5| orgates[4]------->|inpin[4]----------->outpin[13]|---------->|131 | |
| ETH3 | 6|---->orgates[5]------->|inpin[5]----------->outpin[14]|---------->|132 | |
| -------->|2 19| orgates[6]------->|inpin[6]----------->outpin[15]|---------->|133 | |
| UART0 | 20| orgates[7]------->|inpin[7]----------->outpin[16]|---------->|134 | |
| -------->|7 21| orgates[8]------->|inpin[8]----------->outpin[17]|---------->|135 | |
| UART1 | 22| orgates[9]------->|inpin[9]----------->outpin[18]|---------->|136 | |
| -------->|8 23| |------------------------------| |----------| |
| UART2 | 24| |
| -------->|9 25| AST2700 A0 Design |
| UART3 | 26| |
| -------->|10 27| |
| UART5 | 28| |
| -------->|11 29| GICINT132 |
| UART6 | | |
| -------->|12 30| |
| UART7 | 31| |
| -------->|13 | |
| UART8 | OR[0:31] | |
| -------->|14 | |
| UART9 | | |
| -------->|15 | |
| UART10 | | |
| -------->|16 | |
| UART11 | | |
| -------->|17 | |
| UART12 | | |
| -------->|18 | |
| |-----------| |
| |
|-------------------------------------------------------------------------------------------------------|
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast27x0.c | 84 ++++++++++++++++++++++++++++---------
include/hw/arm/aspeed_soc.h | 3 +-
2 files changed, 66 insertions(+), 21 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index ca4b620a1d..0ccec774de 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -67,6 +67,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_RTC] = 0x12C0F000,
[ASPEED_DEV_SDHCI] = 0x14080000,
[ASPEED_DEV_TIMER1] = 0x12C10000,
+ [ASPEED_DEV_INTCIO] = 0x14C18000,
};
#define AST2700_MAX_IRQ 256
@@ -177,32 +178,48 @@ static const int ast2700_gic133_gic197_intcmap[] = {
/* GICINT 192 ~ 201 */
struct gic_intc_irq_info {
int irq;
+ int intc_idx;
+ int orgate_idx;
const int *ptr;
};
static const struct gic_intc_irq_info ast2700_gic_intcmap[] = {
- {128, ast2700_gic128_gic192_intcmap},
- {129, NULL},
- {130, ast2700_gic130_gic194_intcmap},
- {131, ast2700_gic131_gic195_intcmap},
- {132, ast2700_gic132_gic196_intcmap},
- {133, ast2700_gic133_gic197_intcmap},
- {134, NULL},
- {135, NULL},
- {136, NULL},
+ {192, 1, 0, ast2700_gic128_gic192_intcmap},
+ {193, 1, 1, NULL},
+ {194, 1, 2, ast2700_gic130_gic194_intcmap},
+ {195, 1, 3, ast2700_gic131_gic195_intcmap},
+ {196, 1, 4, ast2700_gic132_gic196_intcmap},
+ {197, 1, 5, ast2700_gic133_gic197_intcmap},
+ {198, 1, 6, NULL},
+ {199, 1, 7, NULL},
+ {200, 1, 8, NULL},
+ {201, 1, 9, NULL},
+ {128, 0, 1, ast2700_gic128_gic192_intcmap},
+ {129, 0, 2, NULL},
+ {130, 0, 3, ast2700_gic130_gic194_intcmap},
+ {131, 0, 4, ast2700_gic131_gic195_intcmap},
+ {132, 0, 5, ast2700_gic132_gic196_intcmap},
+ {133, 0, 6, ast2700_gic133_gic197_intcmap},
+ {134, 0, 7, NULL},
+ {135, 0, 8, NULL},
+ {136, 0, 9, NULL},
};
static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
{
Aspeed27x0SoCState *a = ASPEED27X0_SOC(s);
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ int or_idx;
+ int idx;
int i;
for (i = 0; i < ARRAY_SIZE(ast2700_gic_intcmap); i++) {
if (sc->irqmap[dev] == ast2700_gic_intcmap[i].irq) {
assert(ast2700_gic_intcmap[i].ptr);
- return qdev_get_gpio_in(DEVICE(&a->intc.orgates[i]),
- ast2700_gic_intcmap[i].ptr[dev]);
+ or_idx = ast2700_gic_intcmap[i].orgate_idx;
+ idx = ast2700_gic_intcmap[i].intc_idx;
+ return qdev_get_gpio_in(DEVICE(&a->intc[idx].orgates[or_idx]),
+ ast2700_gic_intcmap[i].ptr[dev]);
}
}
@@ -214,12 +231,16 @@ static qemu_irq aspeed_soc_ast2700_get_irq_index(AspeedSoCState *s, int dev,
{
Aspeed27x0SoCState *a = ASPEED27X0_SOC(s);
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ int or_idx;
+ int idx;
int i;
for (i = 0; i < ARRAY_SIZE(ast2700_gic_intcmap); i++) {
if (sc->irqmap[dev] == ast2700_gic_intcmap[i].irq) {
assert(ast2700_gic_intcmap[i].ptr);
- return qdev_get_gpio_in(DEVICE(&a->intc.orgates[i]),
+ or_idx = ast2700_gic_intcmap[i].orgate_idx;
+ idx = ast2700_gic_intcmap[i].intc_idx;
+ return qdev_get_gpio_in(DEVICE(&a->intc[idx].orgates[or_idx]),
ast2700_gic_intcmap[i].ptr[dev] + index);
}
}
@@ -382,7 +403,9 @@ static void aspeed_soc_ast2700_init(Object *obj)
object_initialize_child(obj, "sli", &s->sli, TYPE_ASPEED_2700_SLI);
object_initialize_child(obj, "sliio", &s->sliio, TYPE_ASPEED_2700_SLIIO);
- object_initialize_child(obj, "intc", &a->intc, TYPE_ASPEED_2700_INTC);
+ object_initialize_child(obj, "intc", &a->intc[0], TYPE_ASPEED_2700_INTC);
+ object_initialize_child(obj, "intcio", &a->intc[1],
+ TYPE_ASPEED_2700_INTCIO);
snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname);
object_initialize_child(obj, "adc", &s->adc, typename);
@@ -521,27 +544,48 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
}
/* INTC */
- if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc), errp)) {
+ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) {
return;
}
- aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc), 0,
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[0]), 0,
sc->memmap[ASPEED_DEV_INTC]);
+ /* INTCIO */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[1]), errp)) {
+ return;
+ }
+
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[1]), 0,
+ sc->memmap[ASPEED_DEV_INTCIO]);
+
/* irq sources -> orgates -> INTC */
- for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc)->num_inpins; i++) {
- qdev_connect_gpio_out(DEVICE(&a->intc.orgates[i]), 0,
- qdev_get_gpio_in(DEVICE(&a->intc), i));
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_inpins; i++) {
+ qdev_connect_gpio_out(DEVICE(&a->intc[0].orgates[i]), 0,
+ qdev_get_gpio_in(DEVICE(&a->intc[0]), i));
}
/* INTC -> GIC192 - GIC201 */
/* INTC -> GIC128 - GIC136 */
- for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc)->num_outpins; i++) {
- sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc), i,
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_outpins; i++) {
+ assert(i < ARRAY_SIZE(ast2700_gic_intcmap));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[0]), i,
qdev_get_gpio_in(DEVICE(&a->gic),
ast2700_gic_intcmap[i].irq));
}
+ /* irq source -> orgates -> INTCIO */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_inpins; i++) {
+ qdev_connect_gpio_out(DEVICE(&a->intc[1].orgates[i]), 0,
+ qdev_get_gpio_in(DEVICE(&a->intc[1]), i));
+ }
+
+ /* INTCIO -> INTC */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_outpins; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[1]), i,
+ qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), i));
+ }
+
/* SRAM */
sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index);
if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size,
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 689f52dae8..62f75c33dc 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -128,7 +128,7 @@ struct Aspeed27x0SoCState {
AspeedSoCState parent;
ARMCPU cpu[ASPEED_CPUS_NUM];
- AspeedINTCState intc;
+ AspeedINTCState intc[2];
GICv3State gic;
MemoryRegion dram_empty;
};
@@ -195,6 +195,7 @@ enum {
ASPEED_DEV_EHCI2,
ASPEED_DEV_VIC,
ASPEED_DEV_INTC,
+ ASPEED_DEV_INTCIO,
ASPEED_DEV_SDMC,
ASPEED_DEV_SCU,
ASPEED_DEV_ADC,
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (16 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 17/28] hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for AST2700 A1 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 6:49 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 19/28] hw/misc/aspeed_hace: Fix coding style Jamin Lin via
` (10 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
The memory map for AST2700 A1 remains compatible with AST2700 A0. However, the
IRQ mapping has been updated for AST2700 A1, with GIC interrupts now ranging
from 192 to 201. Add a new IRQ map table for AST2700 A1.
Add "aspeed_soc_ast2700a1_class_init" to initialize the AST2700 A1 SoC.
Introduce "aspeed_machine_ast2700a1_evb_class_init" to initialize the
AST2700 A1 EVB.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed.c | 13 +++++++
hw/arm/aspeed_ast27x0.c | 80 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 6ddfdbdeba..c0539e5950 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -1672,6 +1672,15 @@ static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, void *data)
mc->default_ram_size = 1 * GiB;
aspeed_machine_class_init_cpus_defaults(mc);
}
+
+static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+ mc->desc = "Aspeed AST2700 A1 EVB (Cortex-A35)";
+ amc->soc_name = "ast2700-a1";
+}
#endif
static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
@@ -1798,6 +1807,10 @@ static const TypeInfo aspeed_machine_types[] = {
.name = MACHINE_TYPE_NAME("ast2700a0-evb"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_ast2700a0_evb_class_init,
+ }, {
+ .name = MACHINE_TYPE_NAME("ast2700a1-evb"),
+ .parent = MACHINE_TYPE_NAME("ast2700a0-evb"),
+ .class_init = aspeed_machine_ast2700a1_evb_class_init,
#endif
}, {
.name = TYPE_ASPEED_MACHINE,
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 0ccec774de..926b4c3e76 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -119,6 +119,52 @@ static const int aspeed_soc_ast2700a0_irqmap[] = {
[ASPEED_DEV_SDHCI] = 133,
};
+static const int aspeed_soc_ast2700a1_irqmap[] = {
+ [ASPEED_DEV_SDMC] = 0,
+ [ASPEED_DEV_HACE] = 4,
+ [ASPEED_DEV_XDMA] = 5,
+ [ASPEED_DEV_UART4] = 8,
+ [ASPEED_DEV_SCU] = 12,
+ [ASPEED_DEV_RTC] = 13,
+ [ASPEED_DEV_EMMC] = 15,
+ [ASPEED_DEV_TIMER1] = 16,
+ [ASPEED_DEV_TIMER2] = 17,
+ [ASPEED_DEV_TIMER3] = 18,
+ [ASPEED_DEV_TIMER4] = 19,
+ [ASPEED_DEV_TIMER5] = 20,
+ [ASPEED_DEV_TIMER6] = 21,
+ [ASPEED_DEV_TIMER7] = 22,
+ [ASPEED_DEV_TIMER8] = 23,
+ [ASPEED_DEV_DP] = 28,
+ [ASPEED_DEV_LPC] = 192,
+ [ASPEED_DEV_IBT] = 192,
+ [ASPEED_DEV_KCS] = 192,
+ [ASPEED_DEV_I2C] = 194,
+ [ASPEED_DEV_ADC] = 194,
+ [ASPEED_DEV_GPIO] = 194,
+ [ASPEED_DEV_FMC] = 195,
+ [ASPEED_DEV_WDT] = 195,
+ [ASPEED_DEV_PWM] = 195,
+ [ASPEED_DEV_I3C] = 195,
+ [ASPEED_DEV_UART0] = 196,
+ [ASPEED_DEV_UART1] = 196,
+ [ASPEED_DEV_UART2] = 196,
+ [ASPEED_DEV_UART3] = 196,
+ [ASPEED_DEV_UART5] = 196,
+ [ASPEED_DEV_UART6] = 196,
+ [ASPEED_DEV_UART7] = 196,
+ [ASPEED_DEV_UART8] = 196,
+ [ASPEED_DEV_UART9] = 196,
+ [ASPEED_DEV_UART10] = 196,
+ [ASPEED_DEV_UART11] = 196,
+ [ASPEED_DEV_UART12] = 196,
+ [ASPEED_DEV_ETH1] = 196,
+ [ASPEED_DEV_ETH2] = 196,
+ [ASPEED_DEV_ETH3] = 196,
+ [ASPEED_DEV_PECI] = 197,
+ [ASPEED_DEV_SDHCI] = 197,
+};
+
/* GICINT 128 */
/* GICINT 192 */
static const int ast2700_gic128_gic192_intcmap[] = {
@@ -838,6 +884,34 @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void *data)
sc->get_irq = aspeed_soc_ast2700_get_irq;
}
+static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, void *data)
+{
+ static const char * const valid_cpu_types[] = {
+ ARM_CPU_TYPE_NAME("cortex-a35"),
+ NULL
+ };
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
+
+ /* Reason: The Aspeed SoC can only be instantiated from a board */
+ dc->user_creatable = false;
+ dc->realize = aspeed_soc_ast2700_realize;
+
+ sc->name = "ast2700-a1";
+ sc->valid_cpu_types = valid_cpu_types;
+ sc->silicon_rev = AST2700_A1_SILICON_REV;
+ sc->sram_size = 0x20000;
+ sc->spis_num = 3;
+ sc->wdts_num = 8;
+ sc->macs_num = 3;
+ sc->uarts_num = 13;
+ sc->num_cpus = 4;
+ sc->uarts_base = ASPEED_DEV_UART0;
+ sc->irqmap = aspeed_soc_ast2700a1_irqmap;
+ sc->memmap = aspeed_soc_ast2700_memmap;
+ sc->get_irq = aspeed_soc_ast2700_get_irq;
+}
+
static const TypeInfo aspeed_soc_ast27x0_types[] = {
{
.name = TYPE_ASPEED27X0_SOC,
@@ -850,6 +924,12 @@ static const TypeInfo aspeed_soc_ast27x0_types[] = {
.instance_init = aspeed_soc_ast2700_init,
.class_init = aspeed_soc_ast2700a0_class_init,
},
+ {
+ .name = "ast2700-a1",
+ .parent = TYPE_ASPEED27X0_SOC,
+ .instance_init = aspeed_soc_ast2700_init,
+ .class_init = aspeed_soc_ast2700a1_class_init,
+ },
};
DEFINE_TYPES(aspeed_soc_ast27x0_types)
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 19/28] hw/misc/aspeed_hace: Fix coding style
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (17 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support " Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 6:21 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 20/28] hw/misc/aspeed_hace: Add AST2700 support Jamin Lin via
` (9 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Fix coding style issues from checkpatch.pl.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/misc/aspeed_hace.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index e3f7df2e86..18b85081c7 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -75,9 +75,12 @@ static const struct {
{ HASH_ALGO_SHA1, QCRYPTO_HASH_ALGO_SHA1 },
{ HASH_ALGO_SHA224, QCRYPTO_HASH_ALGO_SHA224 },
{ HASH_ALGO_SHA256, QCRYPTO_HASH_ALGO_SHA256 },
- { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA512, QCRYPTO_HASH_ALGO_SHA512 },
- { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA384, QCRYPTO_HASH_ALGO_SHA384 },
- { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA256, QCRYPTO_HASH_ALGO_SHA256 },
+ { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA512,
+ QCRYPTO_HASH_ALGO_SHA512 },
+ { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA384,
+ QCRYPTO_HASH_ALGO_SHA384 },
+ { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA256,
+ QCRYPTO_HASH_ALGO_SHA256 },
};
static int hash_algo_lookup(uint32_t reg)
@@ -201,7 +204,8 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
haddr = address_space_map(&s->dram_as, addr, &plen, false,
MEMTXATTRS_UNSPECIFIED);
if (haddr == NULL) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: qcrypto failed\n", __func__);
return;
}
iov[i].iov_base = haddr;
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 20/28] hw/misc/aspeed_hace: Add AST2700 support
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (18 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 19/28] hw/misc/aspeed_hace: Fix coding style Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test Jamin Lin via
` (8 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Introduce a new ast2700 class to support AST2700.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
---
hw/misc/aspeed_hace.c | 20 ++++++++++++++++++++
include/hw/misc/aspeed_hace.h | 1 +
2 files changed, 21 insertions(+)
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 18b85081c7..86422cb3be 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -552,12 +552,32 @@ static const TypeInfo aspeed_ast1030_hace_info = {
.class_init = aspeed_ast1030_hace_class_init,
};
+static void aspeed_ast2700_hace_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass);
+
+ dc->desc = "AST2700 Hash and Crypto Engine";
+
+ ahc->src_mask = 0x7FFFFFFF;
+ ahc->dest_mask = 0x7FFFFFF8;
+ ahc->key_mask = 0x7FFFFFF8;
+ ahc->hash_mask = 0x00147FFF;
+}
+
+static const TypeInfo aspeed_ast2700_hace_info = {
+ .name = TYPE_ASPEED_AST2700_HACE,
+ .parent = TYPE_ASPEED_HACE,
+ .class_init = aspeed_ast2700_hace_class_init,
+};
+
static void aspeed_hace_register_types(void)
{
type_register_static(&aspeed_ast2400_hace_info);
type_register_static(&aspeed_ast2500_hace_info);
type_register_static(&aspeed_ast2600_hace_info);
type_register_static(&aspeed_ast1030_hace_info);
+ type_register_static(&aspeed_ast2700_hace_info);
type_register_static(&aspeed_hace_info);
}
diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
index 4af9919195..d13fd3da07 100644
--- a/include/hw/misc/aspeed_hace.h
+++ b/include/hw/misc/aspeed_hace.h
@@ -18,6 +18,7 @@
#define TYPE_ASPEED_AST2500_HACE TYPE_ASPEED_HACE "-ast2500"
#define TYPE_ASPEED_AST2600_HACE TYPE_ASPEED_HACE "-ast2600"
#define TYPE_ASPEED_AST1030_HACE TYPE_ASPEED_HACE "-ast1030"
+#define TYPE_ASPEED_AST2700_HACE TYPE_ASPEED_HACE "-ast2700"
OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE)
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (19 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 20/28] hw/misc/aspeed_hace: Add AST2700 support Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 6:26 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 22/28] hw/arm/aspeed_ast27x0: Add HACE support for AST2700 Jamin Lin via
` (7 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Currently, it does not support the CRYPT command. Instead, it only sends an
interrupt to notify the firmware that the crypt command has completed.
It is a temporary workaround to resolve the boot issue in the Crypto Manager
Self Test.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/misc/aspeed_hace.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 86422cb3be..4d0999e7e9 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -59,6 +59,7 @@
/* Other cmd bits */
#define HASH_IRQ_EN BIT(9)
#define HASH_SG_EN BIT(18)
+#define CRYPT_IRQ_EN BIT(12)
/* Scatter-gather data list */
#define SG_LIST_LEN_SIZE 4
#define SG_LIST_LEN_MASK 0x0FFFFFFF
@@ -343,6 +344,13 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
qemu_irq_lower(s->irq);
}
}
+ if (data & CRYPT_IRQ) {
+ data &= ~CRYPT_IRQ;
+
+ if (s->regs[addr] & CRYPT_IRQ) {
+ qemu_irq_lower(s->irq);
+ }
+ }
break;
case R_HASH_SRC:
data &= ahc->src_mask;
@@ -388,6 +396,10 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
case R_CRYPT_CMD:
qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not implemented\n",
__func__);
+ s->regs[R_STATUS] |= CRYPT_IRQ;
+ if (data & CRYPT_IRQ_EN) {
+ qemu_irq_raise(s->irq);
+ }
break;
default:
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 22/28] hw/arm/aspeed_ast27x0: Add HACE support for AST2700
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (20 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 23/28] test/functional/aspeed: Introduce new function to fetch assets Jamin Lin via
` (6 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
The HACE controller between AST2600 and AST2700 are almost identical.
The HACE controller registers base address starts at 0x1207_0000 and
its alarm interrupt is connected to GICINT4.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
---
hw/arm/aspeed_ast27x0.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 926b4c3e76..dc535c92c9 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -68,6 +68,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_SDHCI] = 0x14080000,
[ASPEED_DEV_TIMER1] = 0x12C10000,
[ASPEED_DEV_INTCIO] = 0x14C18000,
+ [ASPEED_DEV_HACE] = 0x12070000,
};
#define AST2700_MAX_IRQ 256
@@ -480,6 +481,9 @@ static void aspeed_soc_ast2700_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
object_initialize_child(obj, "timerctrl", &s->timerctrl, typename);
+
+ snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
+ object_initialize_child(obj, "hace", &s->hace, typename);
}
/*
@@ -849,6 +853,17 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
}
+ /* HACE */
+ object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->hace), 0,
+ sc->memmap[ASPEED_DEV_HACE]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
+ aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
+
create_unimplemented_device("ast2700.dpmcu", 0x11000000, 0x40000);
create_unimplemented_device("ast2700.iomem0", 0x12000000, 0x01000000);
create_unimplemented_device("ast2700.iomem1", 0x14000000, 0x01000000);
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 23/28] test/functional/aspeed: Introduce new function to fetch assets
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (21 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 22/28] hw/arm/aspeed_ast27x0: Add HACE support for AST2700 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 6:30 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 24/28] tests/functional/aspeed: Introduce start_ast2700_test API and update hwmon path Jamin Lin via
` (5 subsequent siblings)
28 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
This method simplifies the process of fetching and extracting assets from the
Aspeed GitHub repository.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
tests/functional/test_aarch64_aspeed.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py
index 9595498ace..f3d7c8331a 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/test_aarch64_aspeed.py
@@ -27,14 +27,15 @@ def do_test_aarch64_aspeed_sdk_start(self, image):
wait_for_console_pattern(self, '## Loading kernel from FIT Image')
wait_for_console_pattern(self, 'Starting kernel ...')
- ASSET_SDK_V903_AST2700 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.03/ast2700-default-obmc.tar.gz',
- '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77')
+ def extra_aspeed_archive(self, version, file, checksum):
+ url = 'https://github.com/AspeedTech-BMC/openbmc/releases/download'
+ self.archive_extract(Asset(f'{url}/{version}/{file}', f'{checksum}'))
def test_aarch64_ast2700_evb_sdk_v09_03(self):
self.set_machine('ast2700-evb')
- self.archive_extract(self.ASSET_SDK_V903_AST2700)
+ self.extra_aspeed_archive('v09.03', 'ast2700-default-obmc.tar.gz',
+ '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77')
num_cpu = 4
uboot_size = os.path.getsize(self.scratch_file('ast2700-default',
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 24/28] tests/functional/aspeed: Introduce start_ast2700_test API and update hwmon path
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (22 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 23/28] test/functional/aspeed: Introduce new function to fetch assets Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 25/28] tests/functional/aspeed: Update test ASPEED SDK v09.05 Jamin Lin via
` (4 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Added a new method `start_ast2700_test` to the `AST2x00MachineSDK` class and
this method centralizes the logic for starting the AST2700 test, making it
reusable for different test cases.
Modified the hwmon path to use a wildcard to handle different SDK versions:
"cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input".
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
tests/functional/test_aarch64_aspeed.py | 35 +++++++++++++------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py
index f3d7c8331a..aa817afa4e 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/test_aarch64_aspeed.py
@@ -31,34 +31,29 @@ def extra_aspeed_archive(self, version, file, checksum):
url = 'https://github.com/AspeedTech-BMC/openbmc/releases/download'
self.archive_extract(Asset(f'{url}/{version}/{file}', f'{checksum}'))
- def test_aarch64_ast2700_evb_sdk_v09_03(self):
- self.set_machine('ast2700-evb')
-
- self.extra_aspeed_archive('v09.03', 'ast2700-default-obmc.tar.gz',
- '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77')
-
+ def start_ast2700_test(self, name):
num_cpu = 4
- uboot_size = os.path.getsize(self.scratch_file('ast2700-default',
+ uboot_size = os.path.getsize(self.scratch_file(name,
'u-boot-nodtb.bin'))
uboot_dtb_load_addr = hex(0x400000000 + uboot_size)
load_images_list = [
{
'addr': '0x400000000',
- 'file': self.scratch_file('ast2700-default',
+ 'file': self.scratch_file(name,
'u-boot-nodtb.bin')
},
{
'addr': str(uboot_dtb_load_addr),
- 'file': self.scratch_file('ast2700-default', 'u-boot.dtb')
+ 'file': self.scratch_file(name, 'u-boot.dtb')
},
{
'addr': '0x430000000',
- 'file': self.scratch_file('ast2700-default', 'bl31.bin')
+ 'file': self.scratch_file(name, 'bl31.bin')
},
{
'addr': '0x430080000',
- 'file': self.scratch_file('ast2700-default', 'optee',
+ 'file': self.scratch_file(name, 'optee',
'tee-raw.bin')
}
]
@@ -77,23 +72,29 @@ def test_aarch64_ast2700_evb_sdk_v09_03(self):
self.vm.add_args('-device',
'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
self.do_test_aarch64_aspeed_sdk_start(
- self.scratch_file('ast2700-default', 'image-bmc'))
+ self.scratch_file(name, 'image-bmc'))
- wait_for_console_pattern(self, 'ast2700-default login:')
+ wait_for_console_pattern(self, f'{name} login:')
exec_command_and_wait_for_pattern(self, 'root', 'Password:')
- exec_command_and_wait_for_pattern(self,
- '0penBmc', 'root@ast2700-default:~#')
+ exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d');
exec_command_and_wait_for_pattern(self,
- 'cat /sys/class/hwmon/hwmon20/temp1_input', '0')
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
- 'cat /sys/class/hwmon/hwmon20/temp1_input', '18000')
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
+
+ def test_aarch64_ast2700_evb_sdk_v09_03(self):
+ self.set_machine('ast2700-evb')
+
+ self.extra_aspeed_archive('v09.03', 'ast2700-default-obmc.tar.gz',
+ '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77')
+ self.start_ast2700_test('ast2700-default')
if __name__ == '__main__':
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 25/28] tests/functional/aspeed: Update test ASPEED SDK v09.05
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (23 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 24/28] tests/functional/aspeed: Introduce start_ast2700_test API and update hwmon path Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 26/28] tests/functional/aspeed: Renamed test case and machine for AST2700 A0 Jamin Lin via
` (3 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
tests/functional/test_aarch64_aspeed.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py
index aa817afa4e..788dd29a6d 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/test_aarch64_aspeed.py
@@ -89,11 +89,11 @@ def start_ast2700_test(self, name):
exec_command_and_wait_for_pattern(self,
'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
- def test_aarch64_ast2700_evb_sdk_v09_03(self):
+ def test_aarch64_ast2700_evb_sdk_v09_05(self):
self.set_machine('ast2700-evb')
- self.extra_aspeed_archive('v09.03', 'ast2700-default-obmc.tar.gz',
- '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77')
+ self.extra_aspeed_archive('v09.05', 'ast2700-default-obmc.tar.gz',
+ 'cfbbd1cce72f2a3b73b9080c41eecdadebb7077fba4f7806d72ac99f3e84b74a')
self.start_ast2700_test('ast2700-default')
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 26/28] tests/functional/aspeed: Renamed test case and machine for AST2700 A0
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (24 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 25/28] tests/functional/aspeed: Update test ASPEED SDK v09.05 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 27/28] tests/functional/aspeed: Add test case for AST2700 A1 Jamin Lin via
` (2 subsequent siblings)
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
tests/functional/test_aarch64_aspeed.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py
index 788dd29a6d..ad2774be15 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/test_aarch64_aspeed.py
@@ -89,12 +89,12 @@ def start_ast2700_test(self, name):
exec_command_and_wait_for_pattern(self,
'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
- def test_aarch64_ast2700_evb_sdk_v09_05(self):
- self.set_machine('ast2700-evb')
+ def test_aarch64_ast2700a0_evb_sdk_v09_05(self):
+ self.set_machine('ast2700a0-evb')
- self.extra_aspeed_archive('v09.05', 'ast2700-default-obmc.tar.gz',
+ self.extra_aspeed_archive('v09.05', 'ast2700-a0-default-obmc.tar.gz',
'cfbbd1cce72f2a3b73b9080c41eecdadebb7077fba4f7806d72ac99f3e84b74a')
- self.start_ast2700_test('ast2700-default')
+ self.start_ast2700_test('ast2700-a0-default')
if __name__ == '__main__':
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 27/28] tests/functional/aspeed: Add test case for AST2700 A1
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (25 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 26/28] tests/functional/aspeed: Renamed test case and machine for AST2700 A0 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 28/28] docs/specs: add aspeed-intc Jamin Lin via
2025-02-18 9:25 ` [PATCH v3 00/28] Support AST2700 A1 Cédric Le Goater
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
tests/functional/test_aarch64_aspeed.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py
index ad2774be15..2afc50265a 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/test_aarch64_aspeed.py
@@ -96,6 +96,13 @@ def test_aarch64_ast2700a0_evb_sdk_v09_05(self):
'cfbbd1cce72f2a3b73b9080c41eecdadebb7077fba4f7806d72ac99f3e84b74a')
self.start_ast2700_test('ast2700-a0-default')
+ def test_aarch64_ast2700a1_evb_sdk_v09_05(self):
+ self.set_machine('ast2700a1-evb')
+
+ self.extra_aspeed_archive('v09.05', 'ast2700-default-obmc.tar.gz',
+ 'c1f4496aec06743c812a6e9a1a18d032f34d62f3ddb6956e924fef62aa2046a5')
+ self.start_ast2700_test('ast2700-default')
+
if __name__ == '__main__':
QemuSystemTest.main()
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* [PATCH v3 28/28] docs/specs: add aspeed-intc
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (26 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 27/28] tests/functional/aspeed: Add test case for AST2700 A1 Jamin Lin via
@ 2025-02-13 3:35 ` Jamin Lin via
2025-02-18 9:25 ` [PATCH v3 00/28] Support AST2700 A1 Cédric Le Goater
28 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin via @ 2025-02-13 3:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: jamin_lin, troy_lee
Add AST2700 INTC design guidance and its block diagram.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
docs/specs/aspeed-intc.rst | 136 +++++++++++++++++++++++++++++++++++++
docs/specs/index.rst | 1 +
2 files changed, 137 insertions(+)
create mode 100644 docs/specs/aspeed-intc.rst
diff --git a/docs/specs/aspeed-intc.rst b/docs/specs/aspeed-intc.rst
new file mode 100644
index 0000000000..9cefd7f37f
--- /dev/null
+++ b/docs/specs/aspeed-intc.rst
@@ -0,0 +1,136 @@
+===========================
+ASPEED Interrupt Controller
+===========================
+
+AST2700
+-------
+There are a total of 480 interrupt sources in AST2700. Due to the limitation of
+interrupt numbers of processors, the interrupts are merged every 32 sources for
+interrupt numbers greater than 127.
+
+There are two levels of interrupt controllers, INTC (CPU Die) and INTCIO
+(I/O Die).
+
+Interrupt Mapping
+-----------------
+- INTC: Handles interrupt sources 0 - 127 and integrates signals from INTCIO.
+- INTCIO: Handles interrupt sources 128 - 319 independently.
+
+QEMU Support
+------------
+Currently, only GIC 192 to 201 are supported, and their source interrupts are
+from INTCIO and connected to INTC at input pin 0 and output pins 0 to 9 for
+GIC 192-201.
+
+Design for GICINT 196
+---------------------
+The orgate has interrupt sources ranging from 0 to 31, with its output pin
+connected to INTCIO "T0 GICINT_196". The output pin is then connected to INTC
+"GIC_192_201" at bit 4, and its bit 4 output pin is connected to GIC 196.
+
+INTC GIC_192_201 Output Pin Mapping
+-----------------------------------
+The design of INTC GIC_192_201 have 10 output pins, mapped as following:
+
+==== ====
+Bit GIC
+==== ====
+0 192
+1 193
+2 194
+3 195
+4 196
+5 197
+6 198
+7 199
+8 200
+9 201
+==== ====
+
+AST2700 A0
+----------
+It has only one INTC controller, and currently, only GIC 128-136 is supported.
+To support both AST2700 A1 and AST2700 A0, there are 10 OR gates in the INTC,
+with gates 1 to 9 supporting GIC 128-136.
+
+Design for GICINT 132
+---------------------
+The orgate has interrupt sources ranging from 0 to 31, with its output pin
+connected to INTC. The output pin is then connected to GIC 132.
+
+Block Diagram of GICINT 196 for AST2700 A1 and GICINT 132 for AST2700 A0
+------------------------------------------------------------------------
+
+.. code-block::
+
+ |-------------------------------------------------------------------------------------------------------|
+ | AST2700 A1 Design |
+ | To GICINT196 |
+ | |
+ | ETH1 |-----------| |--------------------------| |--------------| |
+ | -------->|0 | | INTCIO | | orgates[0] | |
+ | ETH2 | 4| orgates[0]------>|inpin[0]-------->outpin[0]|------->| 0 | |
+ | -------->|1 5| orgates[1]------>|inpin[1]-------->outpin[1]|------->| 1 | |
+ | ETH3 | 6| orgates[2]------>|inpin[2]-------->outpin[2]|------->| 2 | |
+ | -------->|2 19| orgates[3]------>|inpin[3]-------->outpin[3]|------->| 3 OR[0:9] |-----| |
+ | UART0 | 20|-->orgates[4]------>|inpin[4]-------->outpin[4]|------->| 4 | | |
+ | -------->|7 21| orgates[5]------>|inpin[5]-------->outpin[5]|------->| 5 | | |
+ | UART1 | 22| orgates[6]------>|inpin[6]-------->outpin[6]|------->| 6 | | |
+ | -------->|8 23| orgates[7]------>|inpin[7]-------->outpin[7]|------->| 7 | | |
+ | UART2 | 24| orgates[8]------>|inpin[8]-------->outpin[8]|------->| 8 | | |
+ | -------->|9 25| orgates[9]------>|inpin[9]-------->outpin[9]|------->| 9 | | |
+ | UART3 | 26| |--------------------------| |--------------| | |
+ | ---------|10 27| | |
+ | UART5 | 28| | |
+ | -------->|11 29| | |
+ | UART6 | | | |
+ | -------->|12 30| |-----------------------------------------------------------------------| |
+ | UART7 | 31| | |
+ | -------->|13 | | |
+ | UART8 | OR[0:31] | | |------------------------------| |----------| |
+ | -------->|14 | | | INTC | | GIC | |
+ | UART9 | | | |inpin[0:0]--------->outpin[0] |---------->|192 | |
+ | -------->|15 | | |inpin[0:1]--------->outpin[1] |---------->|193 | |
+ | UART10 | | | |inpin[0:2]--------->outpin[2] |---------->|194 | |
+ | -------->|16 | | |inpin[0:3]--------->outpin[3] |---------->|195 | |
+ | UART11 | | |--------------> |inpin[0:4]--------->outpin[4] |---------->|196 | |
+ | -------->|17 | |inpin[0:5]--------->outpin[5] |---------->|197 | |
+ | UART12 | | |inpin[0:6]--------->outpin[6] |---------->|198 | |
+ | -------->|18 | |inpin[0:7]--------->outpin[7] |---------->|199 | |
+ | |-----------| |inpin[0:8]--------->outpin[8] |---------->|200 | |
+ | |inpin[0:9]--------->outpin[9] |---------->|201 | |
+ |-------------------------------------------------------------------------------------------------------|
+ |-------------------------------------------------------------------------------------------------------|
+ | ETH1 |-----------| orgates[1]------->|inpin[1]----------->outpin[10]|---------->|128 | |
+ | -------->|0 | orgates[2]------->|inpin[2]----------->outpin[11]|---------->|129 | |
+ | ETH2 | 4| orgates[3]------->|inpin[3]----------->outpin[12]|---------->|130 | |
+ | -------->|1 5| orgates[4]------->|inpin[4]----------->outpin[13]|---------->|131 | |
+ | ETH3 | 6|---->orgates[5]------->|inpin[5]----------->outpin[14]|---------->|132 | |
+ | -------->|2 19| orgates[6]------->|inpin[6]----------->outpin[15]|---------->|133 | |
+ | UART0 | 20| orgates[7]------->|inpin[7]----------->outpin[16]|---------->|134 | |
+ | -------->|7 21| orgates[8]------->|inpin[8]----------->outpin[17]|---------->|135 | |
+ | UART1 | 22| orgates[9]------->|inpin[9]----------->outpin[18]|---------->|136 | |
+ | -------->|8 23| |------------------------------| |----------| |
+ | UART2 | 24| |
+ | -------->|9 25| AST2700 A0 Design |
+ | UART3 | 26| |
+ | -------->|10 27| |
+ | UART5 | 28| |
+ | -------->|11 29| GICINT132 |
+ | UART6 | | |
+ | -------->|12 30| |
+ | UART7 | 31| |
+ | -------->|13 | |
+ | UART8 | OR[0:31] | |
+ | -------->|14 | |
+ | UART9 | | |
+ | -------->|15 | |
+ | UART10 | | |
+ | -------->|16 | |
+ | UART11 | | |
+ | -------->|17 | |
+ | UART12 | | |
+ | -------->|18 | |
+ | |-----------| |
+ | |
+ |-------------------------------------------------------------------------------------------------------|
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index d7675cebc2..f19d73c9f6 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -38,3 +38,4 @@ guest hardware that is specific to QEMU.
rocker
riscv-iommu
riscv-aia
+ aspeed-intc
--
2.34.1
^ permalink raw reply related [flat|nested] 70+ messages in thread
* Re: [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size
2025-02-13 3:35 ` [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size Jamin Lin via
@ 2025-02-18 5:33 ` Cédric Le Goater
2025-02-20 5:45 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:33 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
Hello Jamin,
On 2/13/25 04:35, Jamin Lin wrote:
> According to the AST2700 datasheet, the INTC(CPU DIE) controller has 16KB
> (0x4000) of register space, and the INTCIO (I/O DIE) controller has 1KB (0x400)
> of register space.
>
> Introduced a new class attribute "mem_size" to set different memory sizes for
> the INTC models in AST2700.
>
> Introduced a new class attribute "reg_size" to set different register sizes for
> the INTC models in AST2700.
Shouldn't that be multiple patches ?
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/intc/aspeed_intc.c | 17 +++++++++++++----
> include/hw/intc/aspeed_intc.h | 4 ++++
> 2 files changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 126b711b94..316885a27a 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -117,10 +117,11 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
> {
> AspeedINTCState *s = ASPEED_INTC(opaque);
> + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> uint32_t addr = offset >> 2;
> uint32_t value = 0;
>
> - if (addr >= ASPEED_INTC_NR_REGS) {
Side note, ASPEED_INTC_NR_REGS is defined as
#define ASPEED_INTC_NR_REGS (0x2000 >> 2)
and the register array as:
uint32_t regs[ASPEED_INTC_NR_REGS];
The number of regs looks pretty big for me. Are the registers covering
the whole MMIO aperture ?
> + if (offset >= aic->reg_size) {
This is dead code since the MMIO aperture has the same size. You could
remove the check.
> qemu_log_mask(LOG_GUEST_ERROR,
> "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
> __func__, offset);
> @@ -143,7 +144,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> uint32_t change;
> uint32_t irq;
>
> - if (addr >= ASPEED_INTC_NR_REGS) {
> + if (offset >= aic->reg_size) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
> __func__, offset);
> @@ -302,10 +303,16 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> int i;
>
> + memory_region_init(&s->iomem_container, OBJECT(s),
> + TYPE_ASPEED_INTC ".container", aic->mem_size);
> +
> + sysbus_init_mmio(sbd, &s->iomem_container);
Why introduce a container ? Do you plan to have multiple sub-regions ?
Thanks,
C.
> +
> memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_intc_ops, s,
> - TYPE_ASPEED_INTC ".regs", ASPEED_INTC_NR_REGS << 2);
> + TYPE_ASPEED_INTC ".regs", aic->reg_size);
> +
> + memory_region_add_subregion(&s->iomem_container, 0x0, &s->iomem);
>
> - sysbus_init_mmio(sbd, &s->iomem);
> qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
>
> for (i = 0; i < aic->num_ints; i++) {
> @@ -344,6 +351,8 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
> dc->desc = "ASPEED 2700 INTC Controller";
> aic->num_lines = 32;
> aic->num_ints = 9;
> + aic->mem_size = 0x4000;
> + aic->reg_size = 0x2000;
> }
>
> static const TypeInfo aspeed_2700_intc_info = {
> diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
> index 18cb43476c..ecaeb15aea 100644
> --- a/include/hw/intc/aspeed_intc.h
> +++ b/include/hw/intc/aspeed_intc.h
> @@ -25,6 +25,8 @@ struct AspeedINTCState {
>
> /*< public >*/
> MemoryRegion iomem;
> + MemoryRegion iomem_container;
> +
> uint32_t regs[ASPEED_INTC_NR_REGS];
> OrIRQState orgates[ASPEED_INTC_NR_INTS];
> qemu_irq output_pins[ASPEED_INTC_NR_INTS];
> @@ -39,6 +41,8 @@ struct AspeedINTCClass {
>
> uint32_t num_lines;
> uint32_t num_ints;
> + uint64_t mem_size;
> + uint64_t reg_size;
> };
>
> #endif /* ASPEED_INTC_H */
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 02/28] hw/intc/aspeed: Introduce helper functions for enable and status registers
2025-02-13 3:35 ` [PATCH v3 02/28] hw/intc/aspeed: Introduce helper functions for enable and status registers Jamin Lin via
@ 2025-02-18 5:36 ` Cédric Le Goater
2025-02-20 3:24 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:36 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> The behavior of the enable and status registers is almost identical between
> INTC(CPU Die) and INTCIO(IO Die). To reduce duplicated code, adds
> "aspeed_intc_enable_handler" functions to handle enable register write
> behavior and "aspeed_intc_status_handler" functions to handle status
> register write behavior.
It's good practice to add "No functional change".
Looks good to me.
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/intc/aspeed_intc.c | 190 ++++++++++++++++++++++++------------------
> 1 file changed, 108 insertions(+), 82 deletions(-)
>
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 316885a27a..8f9fa97acc 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -114,6 +114,112 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> }
> }
>
> +static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
> + uint64_t data)
> +{
> + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + uint32_t addr = offset >> 2;
> + uint32_t old_enable;
> + uint32_t change;
> + uint32_t irq;
> +
> + irq = (offset & 0x0f00) >> 8;
> +
> + if (irq >= aic->num_ints) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> + __func__, irq);
> + return;
> + }
> +
> + /*
> + * The enable registers are used to enable source interrupts.
> + * They also handle masking and unmasking of source interrupts
> + * during the execution of the source ISR.
> + */
> +
> + /* disable all source interrupt */
> + if (!data && !s->enable[irq]) {
> + s->regs[addr] = data;
> + return;
> + }
> +
> + old_enable = s->enable[irq];
> + s->enable[irq] |= data;
> +
> + /* enable new source interrupt */
> + if (old_enable != s->enable[irq]) {
> + trace_aspeed_intc_enable(s->enable[irq]);
> + s->regs[addr] = data;
> + return;
> + }
> +
> + /* mask and unmask source interrupt */
> + change = s->regs[addr] ^ data;
> + if (change & data) {
> + s->mask[irq] &= ~change;
> + trace_aspeed_intc_unmask(change, s->mask[irq]);
> + } else {
> + s->mask[irq] |= change;
> + trace_aspeed_intc_mask(change, s->mask[irq]);
> + }
> +
> + s->regs[addr] = data;
> +}
> +
> +static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
> + uint64_t data)
> +{
> + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + uint32_t addr = offset >> 2;
> + uint32_t irq;
> +
> + if (!data) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n", __func__);
> + return;
> + }
> +
> + irq = (offset & 0x0f00) >> 8;
> +
> + if (irq >= aic->num_ints) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> + __func__, irq);
> + return;
> + }
> +
> + /* clear status */
> + s->regs[addr] &= ~data;
> +
> + /*
> + * These status registers are used for notify sources ISR are executed.
> + * If one source ISR is executed, it will clear one bit.
> + * If it clear all bits, it means to initialize this register status
> + * rather than sources ISR are executed.
> + */
> + if (data == 0xffffffff) {
> + return;
> + }
> +
> + /* All source ISR execution are done */
> + if (!s->regs[addr]) {
> + trace_aspeed_intc_all_isr_done(irq);
> + if (s->pending[irq]) {
> + /*
> + * handle pending source interrupt
> + * notify firmware which source interrupt are pending
> + * by setting status register
> + */
> + s->regs[addr] = s->pending[irq];
> + s->pending[irq] = 0;
> + trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
> + aspeed_intc_update(s, irq, 1);
> + } else {
> + /* clear irq */
> + trace_aspeed_intc_clear_irq(irq, 0);
> + aspeed_intc_update(s, irq, 0);
> + }
> + }
> +}
> +
> static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
> {
> AspeedINTCState *s = ASPEED_INTC(opaque);
> @@ -140,9 +246,6 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> AspeedINTCState *s = ASPEED_INTC(opaque);
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> uint32_t addr = offset >> 2;
> - uint32_t old_enable;
> - uint32_t change;
> - uint32_t irq;
>
> if (offset >= aic->reg_size) {
> qemu_log_mask(LOG_GUEST_ERROR,
> @@ -163,45 +266,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> case R_GICINT134_EN:
> case R_GICINT135_EN:
> case R_GICINT136_EN:
> - irq = (offset & 0x0f00) >> 8;
> -
> - if (irq >= aic->num_ints) {
> - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> - __func__, irq);
> - return;
> - }
> -
> - /*
> - * These registers are used for enable sources interrupt and
> - * mask and unmask source interrupt while executing source ISR.
> - */
> -
> - /* disable all source interrupt */
> - if (!data && !s->enable[irq]) {
> - s->regs[addr] = data;
> - return;
> - }
> -
> - old_enable = s->enable[irq];
> - s->enable[irq] |= data;
> -
> - /* enable new source interrupt */
> - if (old_enable != s->enable[irq]) {
> - trace_aspeed_intc_enable(s->enable[irq]);
> - s->regs[addr] = data;
> - return;
> - }
> -
> - /* mask and unmask source interrupt */
> - change = s->regs[addr] ^ data;
> - if (change & data) {
> - s->mask[irq] &= ~change;
> - trace_aspeed_intc_unmask(change, s->mask[irq]);
> - } else {
> - s->mask[irq] |= change;
> - trace_aspeed_intc_mask(change, s->mask[irq]);
> - }
> - s->regs[addr] = data;
> + aspeed_intc_enable_handler(s, offset, data);
> break;
> case R_GICINT128_STATUS:
> case R_GICINT129_STATUS:
> @@ -212,46 +277,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> case R_GICINT134_STATUS:
> case R_GICINT135_STATUS:
> case R_GICINT136_STATUS:
> - irq = (offset & 0x0f00) >> 8;
> -
> - if (irq >= aic->num_ints) {
> - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> - __func__, irq);
> - return;
> - }
> -
> - /* clear status */
> - s->regs[addr] &= ~data;
> -
> - /*
> - * These status registers are used for notify sources ISR are executed.
> - * If one source ISR is executed, it will clear one bit.
> - * If it clear all bits, it means to initialize this register status
> - * rather than sources ISR are executed.
> - */
> - if (data == 0xffffffff) {
> - return;
> - }
> -
> - /* All source ISR execution are done */
> - if (!s->regs[addr]) {
> - trace_aspeed_intc_all_isr_done(irq);
> - if (s->pending[irq]) {
> - /*
> - * handle pending source interrupt
> - * notify firmware which source interrupt are pending
> - * by setting status register
> - */
> - s->regs[addr] = s->pending[irq];
> - s->pending[irq] = 0;
> - trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
> - aspeed_intc_update(s, irq, 1);
> - } else {
> - /* clear irq */
> - trace_aspeed_intc_clear_irq(irq, 0);
> - aspeed_intc_update(s, irq, 0);
> - }
> - }
> + aspeed_intc_status_handler(s, offset, data);
> break;
> default:
> s->regs[addr] = data;
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 03/28] hw/intc/aspeed: Add object type name to trace events for better debugging
2025-02-13 3:35 ` [PATCH v3 03/28] hw/intc/aspeed: Add object type name to trace events for better debugging Jamin Lin via
@ 2025-02-18 5:43 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:43 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Currently, these trace events only refer to INTC. To simplify the INTC model,
> both INTC(CPU Die) and INTCIO(IO Die) will share the same helper functions.
>
> However, it is difficult to recognize whether these trace events are comes from
> INTC or INTCIO. To make these trace events more readable, adds object type name
> to the INTC trace events.
> Update trace events to include the "name" field for better identification.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/intc/aspeed_intc.c | 32 +++++++++++++++++++-------------
> hw/intc/trace-events | 24 ++++++++++++------------
> 2 files changed, 31 insertions(+), 25 deletions(-)
>
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 8f9fa97acc..91d8edb261 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -39,6 +39,7 @@ REG32(GICINT136_STATUS, 0x1804)
> static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
> {
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
>
> if (irq >= aic->num_ints) {
> qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> @@ -46,7 +47,7 @@ static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
> return;
> }
>
> - trace_aspeed_intc_update_irq(irq, level);
> + trace_aspeed_intc_update_irq(name, irq, level);
> qemu_set_irq(s->output_pins[irq], level);
> }
>
> @@ -60,6 +61,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> {
> AspeedINTCState *s = (AspeedINTCState *)opaque;
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
> uint32_t status_addr = GICINT_STATUS_BASE + ((0x100 * irq) >> 2);
> uint32_t select = 0;
> uint32_t enable;
> @@ -71,7 +73,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> return;
> }
>
> - trace_aspeed_intc_set_irq(irq, level);
> + trace_aspeed_intc_set_irq(name, irq, level);
> enable = s->enable[irq];
>
> if (!level) {
> @@ -90,7 +92,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> return;
> }
>
> - trace_aspeed_intc_select(select);
> + trace_aspeed_intc_select(name, select);
>
> if (s->mask[irq] || s->regs[status_addr]) {
> /*
> @@ -102,14 +104,14 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> * save source interrupt to pending variable.
> */
> s->pending[irq] |= select;
> - trace_aspeed_intc_pending_irq(irq, s->pending[irq]);
> + trace_aspeed_intc_pending_irq(name, irq, s->pending[irq]);
> } else {
> /*
> * notify firmware which source interrupt are coming
> * by setting status register
> */
> s->regs[status_addr] = select;
> - trace_aspeed_intc_trigger_irq(irq, s->regs[status_addr]);
> + trace_aspeed_intc_trigger_irq(name, irq, s->regs[status_addr]);
> aspeed_intc_update(s, irq, 1);
> }
> }
> @@ -118,6 +120,7 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
> uint64_t data)
> {
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
> uint32_t addr = offset >> 2;
> uint32_t old_enable;
> uint32_t change;
> @@ -148,7 +151,7 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
>
> /* enable new source interrupt */
> if (old_enable != s->enable[irq]) {
> - trace_aspeed_intc_enable(s->enable[irq]);
> + trace_aspeed_intc_enable(name, s->enable[irq]);
> s->regs[addr] = data;
> return;
> }
> @@ -157,10 +160,10 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
> change = s->regs[addr] ^ data;
> if (change & data) {
> s->mask[irq] &= ~change;
> - trace_aspeed_intc_unmask(change, s->mask[irq]);
> + trace_aspeed_intc_unmask(name, change, s->mask[irq]);
> } else {
> s->mask[irq] |= change;
> - trace_aspeed_intc_mask(change, s->mask[irq]);
> + trace_aspeed_intc_mask(name, change, s->mask[irq]);
> }
>
> s->regs[addr] = data;
> @@ -170,6 +173,7 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
> uint64_t data)
> {
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
> uint32_t addr = offset >> 2;
> uint32_t irq;
>
> @@ -201,7 +205,7 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
>
> /* All source ISR execution are done */
> if (!s->regs[addr]) {
> - trace_aspeed_intc_all_isr_done(irq);
> + trace_aspeed_intc_all_isr_done(name, irq);
> if (s->pending[irq]) {
> /*
> * handle pending source interrupt
> @@ -210,11 +214,11 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
> */
> s->regs[addr] = s->pending[irq];
> s->pending[irq] = 0;
> - trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
> + trace_aspeed_intc_trigger_irq(name, irq, s->regs[addr]);
> aspeed_intc_update(s, irq, 1);
> } else {
> /* clear irq */
> - trace_aspeed_intc_clear_irq(irq, 0);
> + trace_aspeed_intc_clear_irq(name, irq, 0);
> aspeed_intc_update(s, irq, 0);
> }
> }
> @@ -224,6 +228,7 @@ static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
> {
> AspeedINTCState *s = ASPEED_INTC(opaque);
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
> uint32_t addr = offset >> 2;
> uint32_t value = 0;
>
> @@ -235,7 +240,7 @@ static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
> }
>
> value = s->regs[addr];
> - trace_aspeed_intc_read(offset, size, value);
> + trace_aspeed_intc_read(name, offset, size, value);
>
> return value;
> }
> @@ -245,6 +250,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> {
> AspeedINTCState *s = ASPEED_INTC(opaque);
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
> uint32_t addr = offset >> 2;
>
> if (offset >= aic->reg_size) {
> @@ -254,7 +260,7 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> return;
> }
>
> - trace_aspeed_intc_write(offset, size, data);
> + trace_aspeed_intc_write(name, offset, size, data);
>
> switch (addr) {
> case R_GICINT128_EN:
> diff --git a/hw/intc/trace-events b/hw/intc/trace-events
> index 3dcf147198..e9ca34755e 100644
> --- a/hw/intc/trace-events
> +++ b/hw/intc/trace-events
> @@ -80,18 +80,18 @@ aspeed_vic_update_irq(int flags) "Raising IRQ: %d"
> aspeed_vic_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
> aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
> # aspeed_intc.c
> -aspeed_intc_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
> -aspeed_intc_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
> -aspeed_intc_set_irq(int irq, int level) "Set IRQ %d: %d"
> -aspeed_intc_clear_irq(int irq, int level) "Clear IRQ %d: %d"
> -aspeed_intc_update_irq(int irq, int level) "Update IRQ: %d: %d"
> -aspeed_intc_pending_irq(int irq, uint32_t value) "Pending IRQ: %d: 0x%x"
> -aspeed_intc_trigger_irq(int irq, uint32_t value) "Trigger IRQ: %d: 0x%x"
> -aspeed_intc_all_isr_done(int irq) "All source ISR execution are done: %d"
> -aspeed_intc_enable(uint32_t value) "Enable: 0x%x"
> -aspeed_intc_select(uint32_t value) "Select: 0x%x"
> -aspeed_intc_mask(uint32_t change, uint32_t value) "Mask: 0x%x: 0x%x"
> -aspeed_intc_unmask(uint32_t change, uint32_t value) "UnMask: 0x%x: 0x%x"
> +aspeed_intc_read(const char *s, uint64_t offset, unsigned size, uint32_t value) "%s: From 0x%" PRIx64 " of size %u: 0x%" PRIx32
> +aspeed_intc_write(const char *s, uint64_t offset, unsigned size, uint32_t data) "%s: To 0x%" PRIx64 " of size %u: 0x%" PRIx32
> +aspeed_intc_set_irq(const char *s, int irq, int level) "%s: Set IRQ %d: %d"
> +aspeed_intc_clear_irq(const char *s, int irq, int level) "%s: Clear IRQ %d: %d"
> +aspeed_intc_update_irq(const char *s, int irq, int level) "%s: Update IRQ: %d: %d"
> +aspeed_intc_pending_irq(const char *s, int irq, uint32_t value) "%s: Pending IRQ: %d: 0x%x"
> +aspeed_intc_trigger_irq(const char *s, int irq, uint32_t value) "%s: Trigger IRQ: %d: 0x%x"
> +aspeed_intc_all_isr_done(const char *s, int irq) "%s: All source ISR execution are done: %d"
> +aspeed_intc_enable(const char *s, uint32_t value) "%s: Enable: 0x%x"
> +aspeed_intc_select(const char *s, uint32_t value) "%s: Select: 0x%x"
> +aspeed_intc_mask(const char *s, uint32_t change, uint32_t value) "%s: Mask: 0x%x: 0x%x"
> +aspeed_intc_unmask(const char *s, uint32_t change, uint32_t value) "%s: UnMask: 0x%x: 0x%x"
>
> # arm_gic.c
> gic_enable_irq(int irq) "irq %d enabled"
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
2025-02-13 3:35 ` [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0 Jamin Lin via
@ 2025-02-18 5:47 ` Cédric Le Goater
2025-02-21 2:23 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:47 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Currently, AST2700 SoC only supports A0. To support AST2700 A1, rename its IRQ
> table and machine name.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/arm/aspeed.c | 8 ++++----
> hw/arm/aspeed_ast27x0.c | 8 ++++----
> 2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index d9418e2b9f..6ddfdbdeba 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -1654,12 +1654,12 @@ static void ast2700_evb_i2c_init(AspeedMachineState *bmc)
> TYPE_TMP105, 0x4d);
> }
>
> -static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc, void *data)
> +static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, void *data)
> {
> MachineClass *mc = MACHINE_CLASS(oc);
> AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
>
> - mc->desc = "Aspeed AST2700 EVB (Cortex-A35)";
> + mc->desc = "Aspeed AST2700 A0 EVB (Cortex-A35)";
> amc->soc_name = "ast2700-a0";
> amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
> amc->hw_strap2 = AST2700_EVB_HW_STRAP2;
> @@ -1795,9 +1795,9 @@ static const TypeInfo aspeed_machine_types[] = {
> .class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
> #ifdef TARGET_AARCH64
> }, {
> - .name = MACHINE_TYPE_NAME("ast2700-evb"),
> + .name = MACHINE_TYPE_NAME("ast2700a0-evb"),
machine "ast2700-evb" has now disappeared from QEMU. You need to add
an alias with "mc->alias" to restore the initial machine name, or
follow the deprecation process :
https://qemu.readthedocs.io/en/v9.2.0/about/deprecated.html
Thanks,
C.
> .parent = TYPE_ASPEED_MACHINE,
> - .class_init = aspeed_machine_ast2700_evb_class_init,
> + .class_init = aspeed_machine_ast2700a0_evb_class_init,
> #endif
> }, {
> .name = TYPE_ASPEED_MACHINE,
> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
> index 2d0c99f159..6e3375f5d3 100644
> --- a/hw/arm/aspeed_ast27x0.c
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -72,7 +72,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
> #define AST2700_MAX_IRQ 256
>
> /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
> -static const int aspeed_soc_ast2700_irqmap[] = {
> +static const int aspeed_soc_ast2700a0_irqmap[] = {
> [ASPEED_DEV_UART0] = 132,
> [ASPEED_DEV_UART1] = 132,
> [ASPEED_DEV_UART2] = 132,
> @@ -740,7 +740,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
> create_unimplemented_device("ast2700.io", 0x0, 0x4000000);
> }
>
> -static void aspeed_soc_ast2700_class_init(ObjectClass *oc, void *data)
> +static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void *data)
> {
> static const char * const valid_cpu_types[] = {
> ARM_CPU_TYPE_NAME("cortex-a35"),
> @@ -763,7 +763,7 @@ static void aspeed_soc_ast2700_class_init(ObjectClass *oc, void *data)
> sc->uarts_num = 13;
> sc->num_cpus = 4;
> sc->uarts_base = ASPEED_DEV_UART0;
> - sc->irqmap = aspeed_soc_ast2700_irqmap;
> + sc->irqmap = aspeed_soc_ast2700a0_irqmap;
> sc->memmap = aspeed_soc_ast2700_memmap;
> sc->get_irq = aspeed_soc_ast2700_get_irq;
> }
> @@ -778,7 +778,7 @@ static const TypeInfo aspeed_soc_ast27x0_types[] = {
> .name = "ast2700-a0",
> .parent = TYPE_ASPEED27X0_SOC,
> .instance_init = aspeed_soc_ast2700_init,
> - .class_init = aspeed_soc_ast2700_class_init,
> + .class_init = aspeed_soc_ast2700a0_class_init,
> },
> };
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 05/28] hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number
2025-02-13 3:35 ` [PATCH v3 05/28] hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number Jamin Lin via
@ 2025-02-18 5:48 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:48 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> To improve readability, sort the IRQ table by IRQ number.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/arm/aspeed_ast27x0.c | 50 ++++++++++++++++++++---------------------
> 1 file changed, 25 insertions(+), 25 deletions(-)
>
> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
> index 6e3375f5d3..4862b215c1 100644
> --- a/hw/arm/aspeed_ast27x0.c
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -73,27 +73,13 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
>
> /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
> static const int aspeed_soc_ast2700a0_irqmap[] = {
> - [ASPEED_DEV_UART0] = 132,
> - [ASPEED_DEV_UART1] = 132,
> - [ASPEED_DEV_UART2] = 132,
> - [ASPEED_DEV_UART3] = 132,
> - [ASPEED_DEV_UART4] = 8,
> - [ASPEED_DEV_UART5] = 132,
> - [ASPEED_DEV_UART6] = 132,
> - [ASPEED_DEV_UART7] = 132,
> - [ASPEED_DEV_UART8] = 132,
> - [ASPEED_DEV_UART9] = 132,
> - [ASPEED_DEV_UART10] = 132,
> - [ASPEED_DEV_UART11] = 132,
> - [ASPEED_DEV_UART12] = 132,
> - [ASPEED_DEV_FMC] = 131,
> [ASPEED_DEV_SDMC] = 0,
> - [ASPEED_DEV_SCU] = 12,
> - [ASPEED_DEV_ADC] = 130,
> + [ASPEED_DEV_HACE] = 4,
> [ASPEED_DEV_XDMA] = 5,
> - [ASPEED_DEV_EMMC] = 15,
> - [ASPEED_DEV_GPIO] = 130,
> + [ASPEED_DEV_UART4] = 8,
> + [ASPEED_DEV_SCU] = 12,
> [ASPEED_DEV_RTC] = 13,
> + [ASPEED_DEV_EMMC] = 15,
> [ASPEED_DEV_TIMER1] = 16,
> [ASPEED_DEV_TIMER2] = 17,
> [ASPEED_DEV_TIMER3] = 18,
> @@ -102,19 +88,33 @@ static const int aspeed_soc_ast2700a0_irqmap[] = {
> [ASPEED_DEV_TIMER6] = 21,
> [ASPEED_DEV_TIMER7] = 22,
> [ASPEED_DEV_TIMER8] = 23,
> - [ASPEED_DEV_WDT] = 131,
> - [ASPEED_DEV_PWM] = 131,
> + [ASPEED_DEV_DP] = 28,
> [ASPEED_DEV_LPC] = 128,
> [ASPEED_DEV_IBT] = 128,
> + [ASPEED_DEV_KCS] = 128,
> + [ASPEED_DEV_ADC] = 130,
> + [ASPEED_DEV_GPIO] = 130,
> [ASPEED_DEV_I2C] = 130,
> - [ASPEED_DEV_PECI] = 133,
> + [ASPEED_DEV_FMC] = 131,
> + [ASPEED_DEV_WDT] = 131,
> + [ASPEED_DEV_PWM] = 131,
> + [ASPEED_DEV_I3C] = 131,
> + [ASPEED_DEV_UART0] = 132,
> + [ASPEED_DEV_UART1] = 132,
> + [ASPEED_DEV_UART2] = 132,
> + [ASPEED_DEV_UART3] = 132,
> + [ASPEED_DEV_UART5] = 132,
> + [ASPEED_DEV_UART6] = 132,
> + [ASPEED_DEV_UART7] = 132,
> + [ASPEED_DEV_UART8] = 132,
> + [ASPEED_DEV_UART9] = 132,
> + [ASPEED_DEV_UART10] = 132,
> + [ASPEED_DEV_UART11] = 132,
> + [ASPEED_DEV_UART12] = 132,
> [ASPEED_DEV_ETH1] = 132,
> [ASPEED_DEV_ETH2] = 132,
> [ASPEED_DEV_ETH3] = 132,
> - [ASPEED_DEV_HACE] = 4,
> - [ASPEED_DEV_KCS] = 128,
> - [ASPEED_DEV_DP] = 28,
> - [ASPEED_DEV_I3C] = 131,
> + [ASPEED_DEV_PECI] = 133,
> [ASPEED_DEV_SDHCI] = 133,
> };
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 06/28] hw/intc/aspeed: Support different memory region ops
2025-02-13 3:35 ` [PATCH v3 06/28] hw/intc/aspeed: Support different memory region ops Jamin Lin via
@ 2025-02-18 5:48 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:48 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> The previous implementation set the "aspeed_intc_ops" struct, containing read
> and write callbacks, to be used when I/O is performed on the INTC region.
> Both "aspeed_intc_read" and "aspeed_intc_write" callback functions were used
> for INTC (CPU Die).
>
> To support the INTCIO (IO Die) model, introduces a new "reg_ops" class
> attribute. This allows setting different memory region operations to support
> different INTC models.
>
> Will introduce "aspeed_intcio_read" and "aspeed_intcio_write" callback
> functions are used for INTCIO.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/intc/aspeed_intc.c | 5 ++++-
> include/hw/intc/aspeed_intc.h | 1 +
> 2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 91d8edb261..cc2426fbac 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -340,7 +340,7 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
>
> sysbus_init_mmio(sbd, &s->iomem_container);
>
> - memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_intc_ops, s,
> + memory_region_init_io(&s->iomem, OBJECT(s), aic->reg_ops, s,
> TYPE_ASPEED_INTC ".regs", aic->reg_size);
>
> memory_region_add_subregion(&s->iomem_container, 0x0, &s->iomem);
> @@ -358,11 +358,14 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
> static void aspeed_intc_class_init(ObjectClass *klass, void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
>
> dc->desc = "ASPEED INTC Controller";
> dc->realize = aspeed_intc_realize;
> device_class_set_legacy_reset(dc, aspeed_intc_reset);
> dc->vmsd = NULL;
> +
> + aic->reg_ops = &aspeed_intc_ops;
> }
>
> static const TypeInfo aspeed_intc_info = {
> diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
> index ecaeb15aea..749d7c55be 100644
> --- a/include/hw/intc/aspeed_intc.h
> +++ b/include/hw/intc/aspeed_intc.h
> @@ -43,6 +43,7 @@ struct AspeedINTCClass {
> uint32_t num_ints;
> uint64_t mem_size;
> uint64_t reg_size;
> + const MemoryRegionOps *reg_ops;
> };
>
> #endif /* ASPEED_INTC_H */
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 07/28] hw/intc/aspeed: Rename num_ints to num_inpins for clarity
2025-02-13 3:35 ` [PATCH v3 07/28] hw/intc/aspeed: Rename num_ints to num_inpins for clarity Jamin Lin via
@ 2025-02-18 5:49 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:49 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> To support AST2700 A1, some registers of the INTC(CPU Die) support one input
> pin to multiple output pins. Renamed "num_ints" to "num_inpins" in the INTC
> controller code for better clarity and consistency in naming conventions.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/arm/aspeed_ast27x0.c | 2 +-
> hw/intc/aspeed_intc.c | 31 +++++++++++++++++--------------
> include/hw/intc/aspeed_intc.h | 11 ++++++-----
> 3 files changed, 24 insertions(+), 20 deletions(-)
>
> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
> index 4862b215c1..18e14a7914 100644
> --- a/hw/arm/aspeed_ast27x0.c
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -520,7 +520,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
> sc->memmap[ASPEED_DEV_INTC]);
>
> /* GICINT orgates -> INTC -> GIC */
> - for (i = 0; i < ic->num_ints; i++) {
> + for (i = 0; i < ic->num_inpins; i++) {
> qdev_connect_gpio_out(DEVICE(&a->intc.orgates[i]), 0,
> qdev_get_gpio_in(DEVICE(&a->intc), i));
> sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc), i,
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index cc2426fbac..95b40e1935 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -41,8 +41,9 @@ static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> const char *name = object_get_typename(OBJECT(s));
>
> - if (irq >= aic->num_ints) {
> - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> + if (irq >= aic->num_inpins) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Invalid input pin index: %d\n",
> __func__, irq);
> return;
> }
> @@ -54,7 +55,7 @@ static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
> /*
> * The address of GICINT128 to GICINT136 are from 0x1000 to 0x1804.
> * Utilize "address & 0x0f00" to get the irq and irq output pin index
> - * The value of irq should be 0 to num_ints.
> + * The value of irq should be 0 to num_inpins.
> * The irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on.
> */
> static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> @@ -67,8 +68,8 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> uint32_t enable;
> int i;
>
> - if (irq >= aic->num_ints) {
> - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> + if (irq >= aic->num_inpins) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n",
> __func__, irq);
> return;
> }
> @@ -128,8 +129,9 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
>
> irq = (offset & 0x0f00) >> 8;
>
> - if (irq >= aic->num_ints) {
> - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> + if (irq >= aic->num_inpins) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Invalid input pin index: %d\n",
> __func__, irq);
> return;
> }
> @@ -184,8 +186,9 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
>
> irq = (offset & 0x0f00) >> 8;
>
> - if (irq >= aic->num_ints) {
> - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
> + if (irq >= aic->num_inpins) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Invalid input pin index: %d\n",
> __func__, irq);
> return;
> }
> @@ -309,8 +312,8 @@ static void aspeed_intc_instance_init(Object *obj)
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> int i;
>
> - assert(aic->num_ints <= ASPEED_INTC_NR_INTS);
> - for (i = 0; i < aic->num_ints; i++) {
> + assert(aic->num_inpins <= ASPEED_INTC_MAX_INPINS);
> + for (i = 0; i < aic->num_inpins; i++) {
> object_initialize_child(obj, "intc-orgates[*]", &s->orgates[i],
> TYPE_OR_IRQ);
> object_property_set_int(OBJECT(&s->orgates[i]), "num-lines",
> @@ -345,9 +348,9 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
>
> memory_region_add_subregion(&s->iomem_container, 0x0, &s->iomem);
>
> - qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
> + qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_inpins);
>
> - for (i = 0; i < aic->num_ints; i++) {
> + for (i = 0; i < aic->num_inpins; i++) {
> if (!qdev_realize(DEVICE(&s->orgates[i]), NULL, errp)) {
> return;
> }
> @@ -385,7 +388,7 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
>
> dc->desc = "ASPEED 2700 INTC Controller";
> aic->num_lines = 32;
> - aic->num_ints = 9;
> + aic->num_inpins = 9;
> aic->mem_size = 0x4000;
> aic->reg_size = 0x2000;
> }
> diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
> index 749d7c55be..5f0429c7f9 100644
> --- a/include/hw/intc/aspeed_intc.h
> +++ b/include/hw/intc/aspeed_intc.h
> @@ -18,6 +18,7 @@ OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
>
> #define ASPEED_INTC_NR_REGS (0x2000 >> 2)
> #define ASPEED_INTC_NR_INTS 9
> +#define ASPEED_INTC_MAX_INPINS 9
>
> struct AspeedINTCState {
> /*< private >*/
> @@ -28,19 +29,19 @@ struct AspeedINTCState {
> MemoryRegion iomem_container;
>
> uint32_t regs[ASPEED_INTC_NR_REGS];
> - OrIRQState orgates[ASPEED_INTC_NR_INTS];
> + OrIRQState orgates[ASPEED_INTC_MAX_INPINS];
> qemu_irq output_pins[ASPEED_INTC_NR_INTS];
>
> - uint32_t enable[ASPEED_INTC_NR_INTS];
> - uint32_t mask[ASPEED_INTC_NR_INTS];
> - uint32_t pending[ASPEED_INTC_NR_INTS];
> + uint32_t enable[ASPEED_INTC_MAX_INPINS];
> + uint32_t mask[ASPEED_INTC_MAX_INPINS];
> + uint32_t pending[ASPEED_INTC_MAX_INPINS];
> };
>
> struct AspeedINTCClass {
> SysBusDeviceClass parent_class;
>
> uint32_t num_lines;
> - uint32_t num_ints;
> + uint32_t num_inpins;
> uint64_t mem_size;
> uint64_t reg_size;
> const MemoryRegionOps *reg_ops;
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output pins in INTC
2025-02-13 3:35 ` [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output pins in INTC Jamin Lin via
@ 2025-02-18 5:53 ` Cédric Le Goater
2025-02-21 1:31 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 5:53 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Added support for multiple output pins in the INTC controller to
> accommodate the AST2700 A1.
>
> Introduced "num_outpins" to represent the number of output pins. Updated the
> IRQ handling logic to initialize and connect output pins separately from input
> pins. Modified the "aspeed_soc_ast2700_realize" function to connect source
> orgates to INTC and INTC to GIC128 - GIC136. Updated the "aspeed_intc_realize"
> function to initialize output pins.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
could you please add to the .git/config file :
[diff]
orderFile = /path/to/qemu/scripts/git.orderfile
This will put .h files before the .c files in the patch.
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/arm/aspeed_ast27x0.c | 6 +++++-
> hw/intc/aspeed_intc.c | 4 ++++
> include/hw/intc/aspeed_intc.h | 5 +++--
> 3 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
> index 18e14a7914..775e953afd 100644
> --- a/hw/arm/aspeed_ast27x0.c
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -519,10 +519,14 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
> aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc), 0,
> sc->memmap[ASPEED_DEV_INTC]);
>
> - /* GICINT orgates -> INTC -> GIC */
> + /* source orgates -> INTC */
> for (i = 0; i < ic->num_inpins; i++) {
> qdev_connect_gpio_out(DEVICE(&a->intc.orgates[i]), 0,
> qdev_get_gpio_in(DEVICE(&a->intc), i));
> + }
> +
> + /* INTC -> GIC128 - GIC136 */
> + for (i = 0; i < ic->num_outpins; i++) {
> sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc), i,
> qdev_get_gpio_in(DEVICE(&a->gic),
> aspeed_soc_ast2700_gic_intcmap[i].irq));
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 95b40e1935..32c4a3bb44 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -354,6 +354,9 @@ static void aspeed_intc_realize(DeviceState *dev, Error **errp)
> if (!qdev_realize(DEVICE(&s->orgates[i]), NULL, errp)) {
> return;
> }
> + }
> +
> + for (i = 0; i < aic->num_outpins; i++) {
> sysbus_init_irq(sbd, &s->output_pins[i]);
> }
> }
> @@ -389,6 +392,7 @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
> dc->desc = "ASPEED 2700 INTC Controller";
> aic->num_lines = 32;
> aic->num_inpins = 9;
> + aic->num_outpins = 9;
> aic->mem_size = 0x4000;
> aic->reg_size = 0x2000;
> }
> diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
> index 5f0429c7f9..0bf96a81bb 100644
> --- a/include/hw/intc/aspeed_intc.h
> +++ b/include/hw/intc/aspeed_intc.h
> @@ -17,8 +17,8 @@
> OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
>
> #define ASPEED_INTC_NR_REGS (0x2000 >> 2)
> -#define ASPEED_INTC_NR_INTS 9
> #define ASPEED_INTC_MAX_INPINS 9
> +#define ASPEED_INTC_MAX_OUTPINS 9
>
> struct AspeedINTCState {
> /*< private >*/
> @@ -30,7 +30,7 @@ struct AspeedINTCState {
>
> uint32_t regs[ASPEED_INTC_NR_REGS];
> OrIRQState orgates[ASPEED_INTC_MAX_INPINS];
> - qemu_irq output_pins[ASPEED_INTC_NR_INTS];
> + qemu_irq output_pins[ASPEED_INTC_MAX_OUTPINS];
>
> uint32_t enable[ASPEED_INTC_MAX_INPINS];
> uint32_t mask[ASPEED_INTC_MAX_INPINS];
> @@ -42,6 +42,7 @@ struct AspeedINTCClass {
>
> uint32_t num_lines;
> uint32_t num_inpins;
> + uint32_t num_outpins;
> uint64_t mem_size;
> uint64_t reg_size;
> const MemoryRegionOps *reg_ops;
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 09/28] hw/intc/aspeed: Refactor INTC to support separate input and output pin indices
2025-02-13 3:35 ` [PATCH v3 09/28] hw/intc/aspeed: Refactor INTC to support separate input and output pin indices Jamin Lin via
@ 2025-02-18 6:20 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 6:20 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Refactors the INTC to distinguish between input and output pin indices,
> improving interrupt handling clarity and accuracy.
>
> Updated the functions to handle both input and output pin indices.
> Added detailed logging for input and output pin indices in trace events.
>
> These changes ensure that the INTC controller can handle multiple input and
> output pins, improving support for the AST2700 A1.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/intc/aspeed_intc.c | 97 +++++++++++++++++++++++++++----------------
> hw/intc/trace-events | 12 +++---
> 2 files changed, 67 insertions(+), 42 deletions(-)
>
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 32c4a3bb44..4e8f1e291e 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -36,20 +36,32 @@ REG32(GICINT136_STATUS, 0x1804)
>
> #define GICINT_STATUS_BASE R_GICINT128_STATUS
>
> -static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
> +/*
> + * Update the state of an interrupt controller pin by setting
> + * the specified output pin to the given level.
> + * The input pin index should be between 0 and the number of input pins.
> + * The output pin index should be between 0 and the number of output pins.
> + */
> +static void aspeed_intc_update(AspeedINTCState *s, int inpin_idx,
> + int outpin_idx, int level)
> {
> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> const char *name = object_get_typename(OBJECT(s));
>
> - if (irq >= aic->num_inpins) {
> - qemu_log_mask(LOG_GUEST_ERROR,
> - "%s: Invalid input pin index: %d\n",
> - __func__, irq);
> + if (inpin_idx >= aic->num_inpins) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n",
> + __func__, inpin_idx);
> return;
> }
>
> - trace_aspeed_intc_update_irq(name, irq, level);
> - qemu_set_irq(s->output_pins[irq], level);
> + if (outpin_idx >= aic->num_outpins) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid output pin index: %d\n",
> + __func__, outpin_idx);
> + return;
> + }
> +
> + trace_aspeed_intc_update_irq(name, inpin_idx, outpin_idx, level);
> + qemu_set_irq(s->output_pins[outpin_idx], level);
> }
>
> /*
> @@ -67,6 +79,11 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> uint32_t select = 0;
> uint32_t enable;
> int i;
> + int inpin_idx;
> + int outpin_idx;
> +
> + inpin_idx = irq;
> + outpin_idx = irq;
>
> if (irq >= aic->num_inpins) {
> qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid input pin index: %d\n",
> @@ -74,15 +91,15 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> return;
> }
>
> - trace_aspeed_intc_set_irq(name, irq, level);
> - enable = s->enable[irq];
> + trace_aspeed_intc_set_irq(name, inpin_idx, level);
> + enable = s->enable[inpin_idx];
>
> if (!level) {
> return;
> }
>
> for (i = 0; i < aic->num_lines; i++) {
> - if (s->orgates[irq].levels[i]) {
> + if (s->orgates[inpin_idx].levels[i]) {
> if (enable & BIT(i)) {
> select |= BIT(i);
> }
> @@ -95,7 +112,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
>
> trace_aspeed_intc_select(name, select);
>
> - if (s->mask[irq] || s->regs[status_addr]) {
> + if (s->mask[inpin_idx] || s->regs[status_addr]) {
> /*
> * a. mask is not 0 means in ISR mode
> * sources interrupt routine are executing.
> @@ -104,16 +121,17 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> *
> * save source interrupt to pending variable.
> */
> - s->pending[irq] |= select;
> - trace_aspeed_intc_pending_irq(name, irq, s->pending[irq]);
> + s->pending[inpin_idx] |= select;
> + trace_aspeed_intc_pending_irq(name, inpin_idx, s->pending[inpin_idx]);
> } else {
> /*
> * notify firmware which source interrupt are coming
> * by setting status register
> */
> s->regs[status_addr] = select;
> - trace_aspeed_intc_trigger_irq(name, irq, s->regs[status_addr]);
> - aspeed_intc_update(s, irq, 1);
> + trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx,
> + s->regs[status_addr]);
> + aspeed_intc_update(s, inpin_idx, outpin_idx, 1);
> }
> }
>
> @@ -126,13 +144,15 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
> uint32_t old_enable;
> uint32_t change;
> uint32_t irq;
> + int inpin_idx;
>
> irq = (offset & 0x0f00) >> 8;
> + inpin_idx = irq;
>
> - if (irq >= aic->num_inpins) {
> + if (inpin_idx >= aic->num_inpins) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "%s: Invalid input pin index: %d\n",
> - __func__, irq);
> + __func__, inpin_idx);
> return;
> }
>
> @@ -143,17 +163,17 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
> */
>
> /* disable all source interrupt */
> - if (!data && !s->enable[irq]) {
> + if (!data && !s->enable[inpin_idx]) {
> s->regs[addr] = data;
> return;
> }
>
> - old_enable = s->enable[irq];
> - s->enable[irq] |= data;
> + old_enable = s->enable[inpin_idx];
> + s->enable[inpin_idx] |= data;
>
> /* enable new source interrupt */
> - if (old_enable != s->enable[irq]) {
> - trace_aspeed_intc_enable(name, s->enable[irq]);
> + if (old_enable != s->enable[inpin_idx]) {
> + trace_aspeed_intc_enable(name, s->enable[inpin_idx]);
> s->regs[addr] = data;
> return;
> }
> @@ -161,11 +181,11 @@ static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
> /* mask and unmask source interrupt */
> change = s->regs[addr] ^ data;
> if (change & data) {
> - s->mask[irq] &= ~change;
> - trace_aspeed_intc_unmask(name, change, s->mask[irq]);
> + s->mask[inpin_idx] &= ~change;
> + trace_aspeed_intc_unmask(name, change, s->mask[inpin_idx]);
> } else {
> - s->mask[irq] |= change;
> - trace_aspeed_intc_mask(name, change, s->mask[irq]);
> + s->mask[inpin_idx] |= change;
> + trace_aspeed_intc_mask(name, change, s->mask[inpin_idx]);
> }
>
> s->regs[addr] = data;
> @@ -178,6 +198,8 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
> const char *name = object_get_typename(OBJECT(s));
> uint32_t addr = offset >> 2;
> uint32_t irq;
> + int inpin_idx;
> + int outpin_idx;
>
> if (!data) {
> qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n", __func__);
> @@ -185,11 +207,13 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
> }
>
> irq = (offset & 0x0f00) >> 8;
> + inpin_idx = irq;
> + outpin_idx = irq;
>
> - if (irq >= aic->num_inpins) {
> + if (inpin_idx >= aic->num_inpins) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "%s: Invalid input pin index: %d\n",
> - __func__, irq);
> + __func__, inpin_idx);
> return;
> }
>
> @@ -208,21 +232,22 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
>
> /* All source ISR execution are done */
> if (!s->regs[addr]) {
> - trace_aspeed_intc_all_isr_done(name, irq);
> - if (s->pending[irq]) {
> + trace_aspeed_intc_all_isr_done(name, inpin_idx);
> + if (s->pending[inpin_idx]) {
> /*
> * handle pending source interrupt
> * notify firmware which source interrupt are pending
> * by setting status register
> */
> - s->regs[addr] = s->pending[irq];
> - s->pending[irq] = 0;
> - trace_aspeed_intc_trigger_irq(name, irq, s->regs[addr]);
> - aspeed_intc_update(s, irq, 1);
> + s->regs[addr] = s->pending[inpin_idx];
> + s->pending[inpin_idx] = 0;
> + trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx,
> + s->regs[addr]);
> + aspeed_intc_update(s, inpin_idx, outpin_idx, 1);
> } else {
> /* clear irq */
> - trace_aspeed_intc_clear_irq(name, irq, 0);
> - aspeed_intc_update(s, irq, 0);
> + trace_aspeed_intc_clear_irq(name, inpin_idx, outpin_idx, 0);
> + aspeed_intc_update(s, inpin_idx, outpin_idx, 0);
> }
> }
> }
> diff --git a/hw/intc/trace-events b/hw/intc/trace-events
> index e9ca34755e..e97eea820b 100644
> --- a/hw/intc/trace-events
> +++ b/hw/intc/trace-events
> @@ -82,12 +82,12 @@ aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64
> # aspeed_intc.c
> aspeed_intc_read(const char *s, uint64_t offset, unsigned size, uint32_t value) "%s: From 0x%" PRIx64 " of size %u: 0x%" PRIx32
> aspeed_intc_write(const char *s, uint64_t offset, unsigned size, uint32_t data) "%s: To 0x%" PRIx64 " of size %u: 0x%" PRIx32
> -aspeed_intc_set_irq(const char *s, int irq, int level) "%s: Set IRQ %d: %d"
> -aspeed_intc_clear_irq(const char *s, int irq, int level) "%s: Clear IRQ %d: %d"
> -aspeed_intc_update_irq(const char *s, int irq, int level) "%s: Update IRQ: %d: %d"
> -aspeed_intc_pending_irq(const char *s, int irq, uint32_t value) "%s: Pending IRQ: %d: 0x%x"
> -aspeed_intc_trigger_irq(const char *s, int irq, uint32_t value) "%s: Trigger IRQ: %d: 0x%x"
> -aspeed_intc_all_isr_done(const char *s, int irq) "%s: All source ISR execution are done: %d"
> +aspeed_intc_set_irq(const char *s, int inpin_idx, int level) "%s: Set IRQ %d: %d"
> +aspeed_intc_clear_irq(const char *s, int inpin_idx, int outpin_idx, int level) "%s: Clear IRQ %d-%d: %d"
> +aspeed_intc_update_irq(const char *s, int inpin_idx, int outpin_idx, int level) "%s: Update IRQ: %d-%d: %d"
> +aspeed_intc_pending_irq(const char *s, int inpin_idx, uint32_t value) "%s: Pending IRQ: %d: 0x%x"
> +aspeed_intc_trigger_irq(const char *s, int inpin_idx, int outpin_idx, uint32_t value) "%s: Trigger IRQ: %d-%d: 0x%x"
> +aspeed_intc_all_isr_done(const char *s, int inpin_idx) "%s: All source ISR execution are done: %d"
> aspeed_intc_enable(const char *s, uint32_t value) "%s: Enable: 0x%x"
> aspeed_intc_select(const char *s, uint32_t value) "%s: Select: 0x%x"
> aspeed_intc_mask(const char *s, uint32_t change, uint32_t value) "%s: Mask: 0x%x: 0x%x"
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 19/28] hw/misc/aspeed_hace: Fix coding style
2025-02-13 3:35 ` [PATCH v3 19/28] hw/misc/aspeed_hace: Fix coding style Jamin Lin via
@ 2025-02-18 6:21 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 6:21 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Fix coding style issues from checkpatch.pl.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/misc/aspeed_hace.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index e3f7df2e86..18b85081c7 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -75,9 +75,12 @@ static const struct {
> { HASH_ALGO_SHA1, QCRYPTO_HASH_ALGO_SHA1 },
> { HASH_ALGO_SHA224, QCRYPTO_HASH_ALGO_SHA224 },
> { HASH_ALGO_SHA256, QCRYPTO_HASH_ALGO_SHA256 },
> - { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA512, QCRYPTO_HASH_ALGO_SHA512 },
> - { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA384, QCRYPTO_HASH_ALGO_SHA384 },
> - { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA256, QCRYPTO_HASH_ALGO_SHA256 },
> + { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA512,
> + QCRYPTO_HASH_ALGO_SHA512 },
> + { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA384,
> + QCRYPTO_HASH_ALGO_SHA384 },
> + { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA256,
> + QCRYPTO_HASH_ALGO_SHA256 },
> };
>
> static int hash_algo_lookup(uint32_t reg)
> @@ -201,7 +204,8 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
> haddr = address_space_map(&s->dram_as, addr, &plen, false,
> MEMTXATTRS_UNSPECIFIED);
> if (haddr == NULL) {
> - qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: qcrypto failed\n", __func__);
> return;
> }
> iov[i].iov_base = haddr;
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
2025-02-13 3:35 ` [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test Jamin Lin via
@ 2025-02-18 6:26 ` Cédric Le Goater
2025-02-21 5:43 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 6:26 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Currently, it does not support the CRYPT command. Instead, it only sends an
> interrupt to notify the firmware that the crypt command has completed.
> It is a temporary workaround to resolve the boot issue in the Crypto Manager
> Self Test.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Please add an AspeedHACEClass class attribute (bool) to handle
this workaround and a comment in the code mentioning the issue.
Thanks,
C.
> ---
> hw/misc/aspeed_hace.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 86422cb3be..4d0999e7e9 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -59,6 +59,7 @@
> /* Other cmd bits */
> #define HASH_IRQ_EN BIT(9)
> #define HASH_SG_EN BIT(18)
> +#define CRYPT_IRQ_EN BIT(12)
> /* Scatter-gather data list */
> #define SG_LIST_LEN_SIZE 4
> #define SG_LIST_LEN_MASK 0x0FFFFFFF
> @@ -343,6 +344,13 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
> qemu_irq_lower(s->irq);
> }
> }
> + if (data & CRYPT_IRQ) {
> + data &= ~CRYPT_IRQ;
> +
> + if (s->regs[addr] & CRYPT_IRQ) {
> + qemu_irq_lower(s->irq);
> + }
> + }
> break;
> case R_HASH_SRC:
> data &= ahc->src_mask;
> @@ -388,6 +396,10 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
> case R_CRYPT_CMD:
> qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not implemented\n",
> __func__);
> + s->regs[R_STATUS] |= CRYPT_IRQ;
> + if (data & CRYPT_IRQ_EN) {
> + qemu_irq_raise(s->irq);
> + }
> break;
> default:
> break;
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 23/28] test/functional/aspeed: Introduce new function to fetch assets
2025-02-13 3:35 ` [PATCH v3 23/28] test/functional/aspeed: Introduce new function to fetch assets Jamin Lin via
@ 2025-02-18 6:30 ` Cédric Le Goater
2025-02-21 1:35 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 6:30 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> This method simplifies the process of fetching and extracting assets from the
> Aspeed GitHub repository.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> tests/functional/test_aarch64_aspeed.py | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py
> index 9595498ace..f3d7c8331a 100755
> --- a/tests/functional/test_aarch64_aspeed.py
> +++ b/tests/functional/test_aarch64_aspeed.py
> @@ -27,14 +27,15 @@ def do_test_aarch64_aspeed_sdk_start(self, image):
> wait_for_console_pattern(self, '## Loading kernel from FIT Image')
> wait_for_console_pattern(self, 'Starting kernel ...')
>
> - ASSET_SDK_V903_AST2700 = Asset(
> - 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.03/ast2700-default-obmc.tar.gz',
> - '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77')
We need to keep the ASSET_SDK_V903_AST2700 definition for pre-caching the
assets. See :
https://qemu.readthedocs.io/en/v9.2.0/devel/testing/functional.html#asset-handling
Thanks,
C.
> + def extra_aspeed_archive(self, version, file, checksum):
> + url = 'https://github.com/AspeedTech-BMC/openbmc/releases/download'
> + self.archive_extract(Asset(f'{url}/{version}/{file}', f'{checksum}'))
>
> def test_aarch64_ast2700_evb_sdk_v09_03(self):
> self.set_machine('ast2700-evb')
>
> - self.archive_extract(self.ASSET_SDK_V903_AST2700)
> + self.extra_aspeed_archive('v09.03', 'ast2700-default-obmc.tar.gz',
> + '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77')
>
> num_cpu = 4
> uboot_size = os.path.getsize(self.scratch_file('ast2700-default',
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 14/28] hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon Revisions
2025-02-13 3:35 ` [PATCH v3 14/28] hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon Revisions Jamin Lin via
@ 2025-02-18 6:35 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 6:35 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Added new definitions for AST2700_A1_SILICON_REV and AST2750_A1_SILICON_REV to
> identify the A1 silicon revisions.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/misc/aspeed_scu.c | 2 ++
> include/hw/misc/aspeed_scu.h | 2 ++
> 2 files changed, 4 insertions(+)
>
> diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> index bac1441b06..2d9fe78926 100644
> --- a/hw/misc/aspeed_scu.c
> +++ b/hw/misc/aspeed_scu.c
> @@ -559,6 +559,8 @@ static uint32_t aspeed_silicon_revs[] = {
> AST2700_A0_SILICON_REV,
> AST2720_A0_SILICON_REV,
> AST2750_A0_SILICON_REV,
> + AST2700_A1_SILICON_REV,
> + AST2750_A1_SILICON_REV,
> };
>
> bool is_supported_silicon_rev(uint32_t silicon_rev)
> diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
> index 356be95e45..684b48b722 100644
> --- a/include/hw/misc/aspeed_scu.h
> +++ b/include/hw/misc/aspeed_scu.h
> @@ -54,6 +54,8 @@ struct AspeedSCUState {
> #define AST2700_A0_SILICON_REV 0x06000103U
> #define AST2720_A0_SILICON_REV 0x06000203U
> #define AST2750_A0_SILICON_REV 0x06000003U
> +#define AST2700_A1_SILICON_REV 0x06010103U
> +#define AST2750_A1_SILICON_REV 0x06010003U
>
> #define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04)
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700
2025-02-13 3:35 ` [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700 Jamin Lin via
@ 2025-02-18 6:47 ` Cédric Le Goater
2025-02-26 6:38 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 6:47 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> According to the design of the AST2600, it has a Silicon Revision ID Register,
> specifically SCU004 and SCU014, to set the Revision ID for the AST2600.
> For the AST2600 A3, SCU004 is set to 0x05030303 and SCU014 is set to 0x05030303.
> In the "aspeed_ast2600_scu_reset" function, the hardcoded value
> "AST2600_A3_SILICON_REV" is set in SCU004, and "s->silicon_rev" is set in
> SCU014. The value of "s->silicon_rev" is set by the SOC layer via the
> "silicon-rev" property.
>
> However, the design of the AST2700 is different. There are two SCU controllers:
> SCU0 (CPU Die) and SCU1 (IO Die). In the AST2700, the firmware reads the
> SCU Silicon Revision ID register (SCU0_000) and the SCUIO Silicon Revision ID
> register (SCU1_000) and combines them into a 64-bit value.
> The combined value of SCU0_000[23:16] and SCU1_000[23:16] represents the silicon
> revision. For example, the AST2700-A1 revision is "0x0601010306010103", where
> SCU0_000 should be 06010103 and SCU1_000 should be 06010103.
Are both these values supposed to be identical ? if not, we should
plan for changes at machine/SoC level too.
>
> Reference:
> https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2023.10/arch/arm/mach-aspeed/ast2700/cpu-info.c
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/misc/aspeed_scu.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> index 2d9fe78926..b45a36a555 100644
> --- a/hw/misc/aspeed_scu.c
> +++ b/hw/misc/aspeed_scu.c
> @@ -911,7 +911,6 @@ static const MemoryRegionOps aspeed_ast2700_scu_ops = {
> };
>
> static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS] = {
> - [AST2700_SILICON_REV] = AST2700_A0_SILICON_REV,
> [AST2700_HW_STRAP1] = 0x00000800,
> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> @@ -940,6 +939,7 @@ static void aspeed_ast2700_scu_reset(DeviceState *dev)
> AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
>
> memcpy(s->regs, asc->resets, asc->nr_regs * 4);
> + s->regs[AST2700_SILICON_REV] = s->silicon_rev;
>
> }
>
> static void aspeed_2700_scu_class_init(ObjectClass *klass, void *data)
> @@ -1032,7 +1032,6 @@ static const MemoryRegionOps aspeed_ast2700_scuio_ops = {
> };
>
> static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
> - [AST2700_SILICON_REV] = 0x06000003,
> [AST2700_HW_STRAP1] = 0x00000504,
why isn't AST2700_HW_STRAP1 assigned with s->hw_strap1 property ?
The above changes could be merged as a fix.
Thanks,
C.
> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
2025-02-13 3:35 ` [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support " Jamin Lin via
@ 2025-02-18 6:49 ` Cédric Le Goater
2025-02-21 1:37 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 6:49 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> The memory map for AST2700 A1 remains compatible with AST2700 A0. However, the
> IRQ mapping has been updated for AST2700 A1, with GIC interrupts now ranging
> from 192 to 201. Add a new IRQ map table for AST2700 A1.
> Add "aspeed_soc_ast2700a1_class_init" to initialize the AST2700 A1 SoC.
> Introduce "aspeed_machine_ast2700a1_evb_class_init" to initialize the
> AST2700 A1 EVB.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/arm/aspeed.c | 13 +++++++
> hw/arm/aspeed_ast27x0.c | 80 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 93 insertions(+)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 6ddfdbdeba..c0539e5950 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -1672,6 +1672,15 @@ static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, void *data)
> mc->default_ram_size = 1 * GiB;
> aspeed_machine_class_init_cpus_defaults(mc);
> }
> +
> +static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, void *data)
> +{
> + MachineClass *mc = MACHINE_CLASS(oc);
> + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
> +
> + mc->desc = "Aspeed AST2700 A1 EVB (Cortex-A35)";
> + amc->soc_name = "ast2700-a1";
> +}
> #endif
>
> static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
> @@ -1798,6 +1807,10 @@ static const TypeInfo aspeed_machine_types[] = {
> .name = MACHINE_TYPE_NAME("ast2700a0-evb"),
> .parent = TYPE_ASPEED_MACHINE,
> .class_init = aspeed_machine_ast2700a0_evb_class_init,
> + }, {
> + .name = MACHINE_TYPE_NAME("ast2700a1-evb"),
> + .parent = MACHINE_TYPE_NAME("ast2700a0-evb"),
Shouldn't the parent be TYPE_ASPEED_MACHINE instead ?
> + .class_init = aspeed_machine_ast2700a1_evb_class_init,
> #endif
> }, {
> .name = TYPE_ASPEED_MACHINE,
> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
> index 0ccec774de..926b4c3e76 100644
> --- a/hw/arm/aspeed_ast27x0.c
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -119,6 +119,52 @@ static const int aspeed_soc_ast2700a0_irqmap[] = {
> [ASPEED_DEV_SDHCI] = 133,
> };
>
> +static const int aspeed_soc_ast2700a1_irqmap[] = {
> + [ASPEED_DEV_SDMC] = 0,
> + [ASPEED_DEV_HACE] = 4,
> + [ASPEED_DEV_XDMA] = 5,
> + [ASPEED_DEV_UART4] = 8,
> + [ASPEED_DEV_SCU] = 12,
> + [ASPEED_DEV_RTC] = 13,
> + [ASPEED_DEV_EMMC] = 15,
> + [ASPEED_DEV_TIMER1] = 16,
> + [ASPEED_DEV_TIMER2] = 17,
> + [ASPEED_DEV_TIMER3] = 18,
> + [ASPEED_DEV_TIMER4] = 19,
> + [ASPEED_DEV_TIMER5] = 20,
> + [ASPEED_DEV_TIMER6] = 21,
> + [ASPEED_DEV_TIMER7] = 22,
> + [ASPEED_DEV_TIMER8] = 23,
> + [ASPEED_DEV_DP] = 28,
> + [ASPEED_DEV_LPC] = 192,
> + [ASPEED_DEV_IBT] = 192,
> + [ASPEED_DEV_KCS] = 192,
> + [ASPEED_DEV_I2C] = 194,
> + [ASPEED_DEV_ADC] = 194,
> + [ASPEED_DEV_GPIO] = 194,
> + [ASPEED_DEV_FMC] = 195,
> + [ASPEED_DEV_WDT] = 195,
> + [ASPEED_DEV_PWM] = 195,
> + [ASPEED_DEV_I3C] = 195,
> + [ASPEED_DEV_UART0] = 196,
> + [ASPEED_DEV_UART1] = 196,
> + [ASPEED_DEV_UART2] = 196,
> + [ASPEED_DEV_UART3] = 196,
> + [ASPEED_DEV_UART5] = 196,
> + [ASPEED_DEV_UART6] = 196,
> + [ASPEED_DEV_UART7] = 196,
> + [ASPEED_DEV_UART8] = 196,
> + [ASPEED_DEV_UART9] = 196,
> + [ASPEED_DEV_UART10] = 196,
> + [ASPEED_DEV_UART11] = 196,
> + [ASPEED_DEV_UART12] = 196,
> + [ASPEED_DEV_ETH1] = 196,
> + [ASPEED_DEV_ETH2] = 196,
> + [ASPEED_DEV_ETH3] = 196,
> + [ASPEED_DEV_PECI] = 197,
> + [ASPEED_DEV_SDHCI] = 197,
> +};
> +
> /* GICINT 128 */
> /* GICINT 192 */
> static const int ast2700_gic128_gic192_intcmap[] = {
> @@ -838,6 +884,34 @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void *data)
> sc->get_irq = aspeed_soc_ast2700_get_irq;
> }
>
> +static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, void *data)
> +{
> + static const char * const valid_cpu_types[] = {
> + ARM_CPU_TYPE_NAME("cortex-a35"),
> + NULL
> + };
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
> +
> + /* Reason: The Aspeed SoC can only be instantiated from a board */
> + dc->user_creatable = false;
> + dc->realize = aspeed_soc_ast2700_realize;
> +
> + sc->name = "ast2700-a1";
> + sc->valid_cpu_types = valid_cpu_types;
> + sc->silicon_rev = AST2700_A1_SILICON_REV;
> + sc->sram_size = 0x20000;
> + sc->spis_num = 3;
> + sc->wdts_num = 8;
> + sc->macs_num = 3;
> + sc->uarts_num = 13;
> + sc->num_cpus = 4;
> + sc->uarts_base = ASPEED_DEV_UART0;
> + sc->irqmap = aspeed_soc_ast2700a1_irqmap;
> + sc->memmap = aspeed_soc_ast2700_memmap;
> + sc->get_irq = aspeed_soc_ast2700_get_irq;
> +}
> +
> static const TypeInfo aspeed_soc_ast27x0_types[] = {
> {
> .name = TYPE_ASPEED27X0_SOC,
> @@ -850,6 +924,12 @@ static const TypeInfo aspeed_soc_ast27x0_types[] = {
> .instance_init = aspeed_soc_ast2700_init,
> .class_init = aspeed_soc_ast2700a0_class_init,
> },
> + {
> + .name = "ast2700-a1",
> + .parent = TYPE_ASPEED27X0_SOC,
> + .instance_init = aspeed_soc_ast2700_init,
> + .class_init = aspeed_soc_ast2700a1_class_init,
> + },
> };
>
> DEFINE_TYPES(aspeed_soc_ast27x0_types)
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
2025-02-13 3:35 ` [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700 INTCIO Controller Jamin Lin via
@ 2025-02-18 9:15 ` Cédric Le Goater
2025-02-20 5:57 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 9:15 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> Introduce a new ast2700 INTCIO class to support AST2700 INTCIO.
> Added new register definitions for INTCIO, including enable and status
> registers for IRQs GICINT192 through GICINT197.
> Created a dedicated IRQ array for INTCIO, supporting six input pins and six
> output pins, aligning with the newly defined registers.
> Implemented "aspeed_intcio_read" and "aspeed_intcio_write" to handle
> INTCIO-specific register access.
>
> To GICINT196 |
>
> ETH1 |-----------| |--------------------------|
> -------->|0 | | INTCIO |
> ETH2 | 4| orgates[0]------>|inpin[0]-------->outpin[0]|
> -------->|1 5| orgates[1]------>|inpin[1]-------->outpin[1]|
> ETH3 | 6| orgates[2]------>|inpin[2]-------->outpin[2]|
> -------->|2 19| orgates[3]------>|inpin[3]-------->outpin[3]|
> UART0 | 20|-->orgates[4]------>|inpin[4]-------->outpin[4]|
> -------->|7 21| orgates[5]------>|inpin[5]-------->outpin[5]|
> UART1 | 22| |--------------------------|
> -------->|8 23|
> UART2 | 24|
> -------->|9 25|
> UART3 | 26|
> ---------|10 27|
> UART5 | 28|
> -------->|11 29|
> UART6 | |
> -------->|12 30|
> UART7 | 31|
> -------->|13 |
> UART8 | OR[0:31] |
> -------->|14 |
> UART9 | |
> -------->|15 |
> UART10 | |
> -------->|16 |
> UART11 | |
> -------->|17 |
> UART12 | |
> -------->|18 |
> |-----------|
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/intc/aspeed_intc.c | 121 ++++++++++++++++++++++++++++++++++
> include/hw/intc/aspeed_intc.h | 1 +
> 2 files changed, 122 insertions(+)
>
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 1a9e2bf8ce..a3bf935789 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -36,6 +36,20 @@ REG32(GICINT136_STATUS, 0x1804)
> REG32(GICINT192_201_EN, 0x1B00)
> REG32(GICINT192_201_STATUS, 0x1B04)
>
> +/* INTCIO Registers */
> +REG32(GICINT192_EN, 0x100)
> +REG32(GICINT192_STATUS, 0x104)
> +REG32(GICINT193_EN, 0x110)
> +REG32(GICINT193_STATUS, 0x114)
> +REG32(GICINT194_EN, 0x120)
> +REG32(GICINT194_STATUS, 0x124)
> +REG32(GICINT195_EN, 0x130)
> +REG32(GICINT195_STATUS, 0x134)
> +REG32(GICINT196_EN, 0x140)
> +REG32(GICINT196_STATUS, 0x144)
> +REG32(GICINT197_EN, 0x150)
> +REG32(GICINT197_STATUS, 0x154)
> +
> static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
> {0, 0, 10, R_GICINT192_201_EN, R_GICINT192_201_STATUS},
> {1, 10, 1, R_GICINT128_EN, R_GICINT128_STATUS},
> @@ -49,6 +63,15 @@ static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
> {9, 18, 1, R_GICINT136_EN, R_GICINT136_STATUS},
> };
>
> +static AspeedINTCIRQ aspeed_2700_intcio_irqs[ASPEED_INTC_MAX_INPINS] = {
> + {0, 0, 1, R_GICINT192_EN, R_GICINT192_STATUS},
> + {1, 1, 1, R_GICINT193_EN, R_GICINT193_STATUS},
> + {2, 2, 1, R_GICINT194_EN, R_GICINT194_STATUS},
> + {3, 3, 1, R_GICINT195_EN, R_GICINT195_STATUS},
> + {4, 4, 1, R_GICINT196_EN, R_GICINT196_STATUS},
> + {5, 5, 1, R_GICINT197_EN, R_GICINT197_STATUS},
> +};
> +
I would move the array definition just before routine
aspeed_2700_intcio_class_init().
> static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic,
> uint32_t addr)
> {
> @@ -463,6 +486,71 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> return;
> }
>
> +static uint64_t aspeed_intcio_read(void *opaque, hwaddr offset,
> + unsigned int size)
> +{
> + AspeedINTCState *s = ASPEED_INTC(opaque);
> + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
> + uint32_t addr = offset >> 2;
s/addr/reg/ ? I find that "reg" makes more sense.
> + uint32_t value = 0;
> +
> + if (offset >= aic->reg_size) {
as said in patch 1, this is dead code bc the MMIO aperture has the same
size. You could remove the check.
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
> + __func__, offset);
> + return 0;
> + }
> +
> + value = s->regs[addr];
> + trace_aspeed_intc_read(name, offset, size, value);
> +
> + return value;
> +}
> +
> +static void aspeed_intcio_write(void *opaque, hwaddr offset, uint64_t data,
> + unsigned size)
> +{
> + AspeedINTCState *s = ASPEED_INTC(opaque);
> + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> + const char *name = object_get_typename(OBJECT(s));
> + uint32_t addr = offset >> 2;
> +
> + if (offset >= aic->reg_size) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
> + __func__, offset);
> + return;
> + }
> +
> + trace_aspeed_intc_write(name, offset, size, data);
> +
> + switch (addr) {
> + case R_GICINT192_EN:
> + case R_GICINT193_EN:
> + case R_GICINT194_EN:
> + case R_GICINT195_EN:
> + case R_GICINT196_EN:
> + case R_GICINT197_EN:
> + aspeed_intc_enable_handler(s, offset, data);
> + break;
> + case R_GICINT192_STATUS:
> + case R_GICINT193_STATUS:
> + case R_GICINT194_STATUS:
> + case R_GICINT195_STATUS:
> + case R_GICINT196_STATUS:
> + case R_GICINT197_STATUS:
> + aspeed_intc_status_handler(s, offset, data);
> + break;
> + default:
> + s->regs[addr] = data;
> + break;
> + }
> +
> + return;
> +}
> +
> +
> static const MemoryRegionOps aspeed_intc_ops = {
> .read = aspeed_intc_read,
> .write = aspeed_intc_write,
> @@ -473,6 +561,16 @@ static const MemoryRegionOps aspeed_intc_ops = {
> }
> };
>
> +static const MemoryRegionOps aspeed_intcio_ops = {
> + .read = aspeed_intcio_read,
> + .write = aspeed_intcio_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> + .valid = {
> + .min_access_size = 4,
> + .max_access_size = 4,
> + }
> +};
> +
> static void aspeed_intc_instance_init(Object *obj)
> {
> AspeedINTCState *s = ASPEED_INTC(obj);
> @@ -572,10 +670,33 @@ static const TypeInfo aspeed_2700_intc_info = {
> .class_init = aspeed_2700_intc_class_init,
> };
>
> +static void aspeed_2700_intcio_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
> +
> + dc->desc = "ASPEED 2700 INTC IO Controller";
> + aic->num_lines = 32;
> + aic->num_inpins = 6;
> + aic->num_outpins = 6;
> + aic->mem_size = 0x400;
> + aic->reg_size = 0x3d8;
> + aic->reg_ops = &aspeed_intcio_ops;
> + aic->irq_table = aspeed_2700_intcio_irqs;
> + aic->irq_table_count = ARRAY_SIZE(aspeed_2700_intcio_irqs);
> +}
> +
> +static const TypeInfo aspeed_2700_intcio_info = {
> + .name = TYPE_ASPEED_2700_INTCIO,
> + .parent = TYPE_ASPEED_INTC,
> + .class_init = aspeed_2700_intcio_class_init,
> +};
> +
> static void aspeed_intc_register_types(void)
> {
> type_register_static(&aspeed_intc_info);
> type_register_static(&aspeed_2700_intc_info);
> + type_register_static(&aspeed_2700_intcio_info);
> }
>
> type_init(aspeed_intc_register_types);
> diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
> index 57146db2ce..e8ead15491 100644
> --- a/include/hw/intc/aspeed_intc.h
> +++ b/include/hw/intc/aspeed_intc.h
> @@ -14,6 +14,7 @@
>
> #define TYPE_ASPEED_INTC "aspeed.intc"
> #define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700"
> +#define TYPE_ASPEED_2700_INTCIO TYPE_ASPEED_INTC "io" "-ast2700"
You could use "io-ast2700". Minor.
Thanks,
C.
> OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
>
> #define ASPEED_INTC_NR_REGS (0x2000 >> 2)
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 11/28] hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication
2025-02-13 3:35 ` [PATCH v3 11/28] hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication Jamin Lin via
@ 2025-02-18 9:17 ` Cédric Le Goater
2025-02-20 3:14 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 9:17 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
On 2/13/25 04:35, Jamin Lin wrote:
> The behavior of the INTC set IRQ is almost identical between INTC and INTCIO.
> To reduce duplicated code, introduce the "aspeed_intc_set_irq_handler" function
> to handle both INTC and INTCIO IRQ behavior.
It's good practice to add "No functional change".
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/intc/aspeed_intc.c | 62 ++++++++++++++++++++++++-------------------
> 1 file changed, 34 insertions(+), 28 deletions(-)
>
> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
> index 59c1069294..fd4f75805a 100644
> --- a/hw/intc/aspeed_intc.c
> +++ b/hw/intc/aspeed_intc.c
> @@ -92,11 +92,40 @@ static void aspeed_intc_update(AspeedINTCState *s, int inpin_idx,
> qemu_set_irq(s->output_pins[outpin_idx], level);
> }
>
> +static void aspeed_intc_set_irq_handler(AspeedINTCState *s,
> + const AspeedINTCIRQ *intc_irq,
> + uint32_t select)
> +{
> + const char *name = object_get_typename(OBJECT(s));
> +
> + 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.
> + * b. status register value is not 0 means previous
> + * source interrupt does not be executed, yet.
> + *
> + * save source interrupt to pending variable.
> + */
> + s->pending[intc_irq->inpin_idx] |= 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[intc_irq->status_addr] = 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);
> + }
> +}
> +
> /*
> - * The address of GICINT128 to GICINT136 are from 0x1000 to 0x1804.
> - * Utilize "address & 0x0f00" to get the irq and irq output pin index
> - * The value of irq should be 0 to num_inpins.
> - * The irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on.
> + * GICINT128 to GICINT136 map 1:1 to input and output IRQs 0 to 8.
> + * The value of input IRQ should be between 0 and the number of inputs.
> */
> static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> {
> @@ -135,30 +164,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> }
>
> trace_aspeed_intc_select(name, select);
> -
> - 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.
> - * b. status register value is not 0 means previous
> - * source interrupt does not be executed, yet.
> - *
> - * save source interrupt to pending variable.
> - */
> - s->pending[intc_irq->inpin_idx] |= 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[intc_irq->status_addr] = 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);
> - }
> + aspeed_intc_set_irq_handler(s, intc_irq, select);
> }
>
> static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 00/28] Support AST2700 A1
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
` (27 preceding siblings ...)
2025-02-13 3:35 ` [PATCH v3 28/28] docs/specs: add aspeed-intc Jamin Lin via
@ 2025-02-18 9:25 ` Cédric Le Goater
2025-02-20 5:11 ` Jamin Lin
28 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-18 9:25 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: troy_lee
Hello Jamin,
On 2/13/25 04:35, Jamin Lin wrote:
> v1:
> 1. Refactor INTC model to support both INTC0 and INTC1.
> 2. Support AST2700 A1.
> 3. Create ast2700a0-evb machine.
>
> v2:
> To streamline the review process, split the following patch series into
> three parts.
> https://patchwork.kernel.org/project/qemu-devel/cover/20250121070424.2465942-1-jamin_lin@aspeedtech.com/
> This patch series focuses on cleaning up the INTC model to
> facilitate future support for the INTC_IO model.
>
> v3:
> 1. Update and add functional test for AST2700
> 2. Add AST2700 INTC design guidance and its block diagram.
> 3. Retaining the INTC naming and introducing a new INTCIO model to support the AST2700 A1.
> 4. Create ast2700a1-evb machine and rename ast2700a0-evb machine
> 5. Fix silicon revision issue and support AST2700 A1.
>
> With the patch applied, QEMU now supports two machines for running AST2700 SoCs:
> ast2700a0-evb: Designed for AST2700 A0
> ast2700a1-evb: Designed for AST2700 A1
>
> Test information
> 1. QEMU version: https://github.com/qemu/qemu/commit/ffaf7f0376f8040ce9068d71ae9ae8722505c42e
> 2. ASPEED SDK v09.05 pre-built image
> https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
> ast2700-default-obmc.tar.gz (AST2700 A1)
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-default-obmc.tar.gz
> ast2700-a0-default-obmc.tar.gz (AST2700 A0)
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-a0-default-obmc.tar.gz
The part adding new functional tests needs a rework. See comment.
> Known Issue:
> The HACE crypto and hash engine is enable by default since AST2700 A1.
> However, aspeed_hace.c(HACE model) currently does not support the CRYPTO command.
> To boot AST2700 A1, I have created a Patch 21 which temporarily resolves the
> issue by sending an interrupt to notify the firmware that the cryptographic
> command has completed. It is a temporary workaround to resolve the boot issue
> in the Crypto Manager SelfTest.
>
> As a result, you will encounter the following kernel warning due to the
> Crypto Manager test failure. If you don't want to see these kernel warning,
> please add the following settings in your kernel config.
>
> ```
> CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
> ```
Would it be possible to send the hace changes in its own series ?
>
> Jamin Lin (28):
> hw/intc/aspeed: Support setting different memory and register size
> hw/intc/aspeed: Introduce helper functions for enable and status
> registers
> hw/intc/aspeed: Add object type name to trace events for better
> debugging
> hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
> hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number
> hw/intc/aspeed: Support different memory region ops
> hw/intc/aspeed: Rename num_ints to num_inpins for clarity
> hw/intc/aspeed: Add support for multiple output pins in INTC
> hw/intc/aspeed: Refactor INTC to support separate input and output pin
> indices
> hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq
> index and register address
> hw/intc/aspeed: Introduce IRQ handler function to reduce code
> duplication
> hw/intc/aspeed: Add Support for Multi-Output IRQ Handling
> hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
> hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon
> Revisions
> hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer
> for AST2700
> hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping
> hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for
> AST2700 A1
> hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
> hw/misc/aspeed_hace: Fix coding style
> hw/misc/aspeed_hace: Add AST2700 support
> hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
> hw/arm/aspeed_ast27x0: Add HACE support for AST2700
> test/functional/aspeed: Introduce new function to fetch assets
> tests/functional/aspeed: Introduce start_ast2700_test API and update
> hwmon path
> tests/functional/aspeed: Update test ASPEED SDK v09.05
> tests/functional/aspeed: Renamed test case and machine for AST2700 A0
> tests/functional/aspeed: Add test case for AST2700 A1
> docs/specs: add aspeed-intc
>
> docs/specs/aspeed-intc.rst | 136 ++++++
> docs/specs/index.rst | 1 +
> hw/arm/aspeed.c | 21 +-
> hw/arm/aspeed_ast27x0.c | 291 +++++++++---
> hw/intc/aspeed_intc.c | 593 +++++++++++++++++++-----
> hw/intc/trace-events | 25 +-
> hw/misc/aspeed_hace.c | 44 +-
> hw/misc/aspeed_scu.c | 5 +-
> include/hw/arm/aspeed_soc.h | 3 +-
> include/hw/intc/aspeed_intc.h | 32 +-
> include/hw/misc/aspeed_hace.h | 1 +
> include/hw/misc/aspeed_scu.h | 2 +
> tests/functional/test_aarch64_aspeed.py | 47 +-
> 13 files changed, 963 insertions(+), 238 deletions(-)
> create mode 100644 docs/specs/aspeed-intc.rst
>
Patch 1-9 and the hace changes could be merged quickly.
I need some help on patch 10,12,16,17.
Andrew,
Would you have time please ?
Thanks,
C.
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 11/28] hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication
2025-02-18 9:17 ` Cédric Le Goater
@ 2025-02-20 3:14 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-20 3:14 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
>
> It's good practice to add "No functional change".
>
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
>
> Thanks,
>
> C.
>
Thanks for your review and suggestion.
I will add "No functional change" in commit log.
Jamin
>
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/intc/aspeed_intc.c | 62 ++++++++++++++++++++++++-------------------
> > 1 file changed, 34 insertions(+), 28 deletions(-)
> >
> > diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index
> > 59c1069294..fd4f75805a 100644
> > --- a/hw/intc/aspeed_intc.c
> > +++ b/hw/intc/aspeed_intc.c
> > @@ -92,11 +92,40 @@ static void aspeed_intc_update(AspeedINTCState *s,
> int inpin_idx,
> > qemu_set_irq(s->output_pins[outpin_idx], level);
> > }
> >
> > +static void aspeed_intc_set_irq_handler(AspeedINTCState *s,
> > + const AspeedINTCIRQ
> *intc_irq,
> > + uint32_t select) {
> > + const char *name = object_get_typename(OBJECT(s));
> > +
> > + 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.
> > + * b. status register value is not 0 means previous
> > + * source interrupt does not be executed, yet.
> > + *
> > + * save source interrupt to pending variable.
> > + */
> > + s->pending[intc_irq->inpin_idx] |= 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[intc_irq->status_addr] = 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);
> > + }
> > +}
> > +
> > /*
> > - * The address of GICINT128 to GICINT136 are from 0x1000 to 0x1804.
> > - * Utilize "address & 0x0f00" to get the irq and irq output pin index
> > - * The value of irq should be 0 to num_inpins.
> > - * The irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on.
> > + * GICINT128 to GICINT136 map 1:1 to input and output IRQs 0 to 8.
> > + * The value of input IRQ should be between 0 and the number of inputs.
> > */
> > static void aspeed_intc_set_irq(void *opaque, int irq, int level)
> > {
> > @@ -135,30 +164,7 @@ static void aspeed_intc_set_irq(void *opaque, int
> irq, int level)
> > }
> >
> > trace_aspeed_intc_select(name, select);
> > -
> > - 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.
> > - * b. status register value is not 0 means previous
> > - * source interrupt does not be executed, yet.
> > - *
> > - * save source interrupt to pending variable.
> > - */
> > - s->pending[intc_irq->inpin_idx] |= 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[intc_irq->status_addr] = 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);
> > - }
> > + aspeed_intc_set_irq_handler(s, intc_irq, select);
> > }
> >
> > static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr
> > offset,
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 02/28] hw/intc/aspeed: Introduce helper functions for enable and status registers
2025-02-18 5:36 ` Cédric Le Goater
@ 2025-02-20 3:24 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-20 3:24 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
>
> It's good practice to add "No functional change".
>
Thanks for review and suggestion
Will add "No functional change" in commit log.
Jamin
>
> Looks good to me.
>
>
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
>
> Thanks,
>
> C.
>
>
>
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/intc/aspeed_intc.c | 190 ++++++++++++++++++++++++------------------
> > 1 file changed, 108 insertions(+), 82 deletions(-)
> >
> > diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index
> > 316885a27a..8f9fa97acc 100644
> > --- a/hw/intc/aspeed_intc.c
> > +++ b/hw/intc/aspeed_intc.c
> > @@ -114,6 +114,112 @@ static void aspeed_intc_set_irq(void *opaque, int
> irq, int level)
> > }
> > }
> >
> > +static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset,
> > + uint64_t data) {
> > + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> > + uint32_t addr = offset >> 2;
> > + uint32_t old_enable;
> > + uint32_t change;
> > + uint32_t irq;
> > +
> > + irq = (offset & 0x0f00) >> 8;
> > +
> > + if (irq >= aic->num_ints) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt
> number: %d\n",
> > + __func__, irq);
> > + return;
> > + }
> > +
> > + /*
> > + * The enable registers are used to enable source interrupts.
> > + * They also handle masking and unmasking of source interrupts
> > + * during the execution of the source ISR.
> > + */
> > +
> > + /* disable all source interrupt */
> > + if (!data && !s->enable[irq]) {
> > + s->regs[addr] = data;
> > + return;
> > + }
> > +
> > + old_enable = s->enable[irq];
> > + s->enable[irq] |= data;
> > +
> > + /* enable new source interrupt */
> > + if (old_enable != s->enable[irq]) {
> > + trace_aspeed_intc_enable(s->enable[irq]);
> > + s->regs[addr] = data;
> > + return;
> > + }
> > +
> > + /* mask and unmask source interrupt */
> > + change = s->regs[addr] ^ data;
> > + if (change & data) {
> > + s->mask[irq] &= ~change;
> > + trace_aspeed_intc_unmask(change, s->mask[irq]);
> > + } else {
> > + s->mask[irq] |= change;
> > + trace_aspeed_intc_mask(change, s->mask[irq]);
> > + }
> > +
> > + s->regs[addr] = data;
> > +}
> > +
> > +static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset,
> > + uint64_t data) {
> > + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> > + uint32_t addr = offset >> 2;
> > + uint32_t irq;
> > +
> > + if (!data) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid data 0\n",
> __func__);
> > + return;
> > + }
> > +
> > + irq = (offset & 0x0f00) >> 8;
> > +
> > + if (irq >= aic->num_ints) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt
> number: %d\n",
> > + __func__, irq);
> > + return;
> > + }
> > +
> > + /* clear status */
> > + s->regs[addr] &= ~data;
> > +
> > + /*
> > + * These status registers are used for notify sources ISR are executed.
> > + * If one source ISR is executed, it will clear one bit.
> > + * If it clear all bits, it means to initialize this register status
> > + * rather than sources ISR are executed.
> > + */
> > + if (data == 0xffffffff) {
> > + return;
> > + }
> > +
> > + /* All source ISR execution are done */
> > + if (!s->regs[addr]) {
> > + trace_aspeed_intc_all_isr_done(irq);
> > + if (s->pending[irq]) {
> > + /*
> > + * handle pending source interrupt
> > + * notify firmware which source interrupt are pending
> > + * by setting status register
> > + */
> > + s->regs[addr] = s->pending[irq];
> > + s->pending[irq] = 0;
> > + trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
> > + aspeed_intc_update(s, irq, 1);
> > + } else {
> > + /* clear irq */
> > + trace_aspeed_intc_clear_irq(irq, 0);
> > + aspeed_intc_update(s, irq, 0);
> > + }
> > + }
> > +}
> > +
> > static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned
> int size)
> > {
> > AspeedINTCState *s = ASPEED_INTC(opaque); @@ -140,9 +246,6
> @@
> > static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> > AspeedINTCState *s = ASPEED_INTC(opaque);
> > AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> > uint32_t addr = offset >> 2;
> > - uint32_t old_enable;
> > - uint32_t change;
> > - uint32_t irq;
> >
> > if (offset >= aic->reg_size) {
> > qemu_log_mask(LOG_GUEST_ERROR, @@ -163,45 +266,7 @@
> static
> > void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> > case R_GICINT134_EN:
> > case R_GICINT135_EN:
> > case R_GICINT136_EN:
> > - irq = (offset & 0x0f00) >> 8;
> > -
> > - if (irq >= aic->num_ints) {
> > - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt
> number: %d\n",
> > - __func__, irq);
> > - return;
> > - }
> > -
> > - /*
> > - * These registers are used for enable sources interrupt and
> > - * mask and unmask source interrupt while executing source ISR.
> > - */
> > -
> > - /* disable all source interrupt */
> > - if (!data && !s->enable[irq]) {
> > - s->regs[addr] = data;
> > - return;
> > - }
> > -
> > - old_enable = s->enable[irq];
> > - s->enable[irq] |= data;
> > -
> > - /* enable new source interrupt */
> > - if (old_enable != s->enable[irq]) {
> > - trace_aspeed_intc_enable(s->enable[irq]);
> > - s->regs[addr] = data;
> > - return;
> > - }
> > -
> > - /* mask and unmask source interrupt */
> > - change = s->regs[addr] ^ data;
> > - if (change & data) {
> > - s->mask[irq] &= ~change;
> > - trace_aspeed_intc_unmask(change, s->mask[irq]);
> > - } else {
> > - s->mask[irq] |= change;
> > - trace_aspeed_intc_mask(change, s->mask[irq]);
> > - }
> > - s->regs[addr] = data;
> > + aspeed_intc_enable_handler(s, offset, data);
> > break;
> > case R_GICINT128_STATUS:
> > case R_GICINT129_STATUS:
> > @@ -212,46 +277,7 @@ static void aspeed_intc_write(void *opaque,
> hwaddr offset, uint64_t data,
> > case R_GICINT134_STATUS:
> > case R_GICINT135_STATUS:
> > case R_GICINT136_STATUS:
> > - irq = (offset & 0x0f00) >> 8;
> > -
> > - if (irq >= aic->num_ints) {
> > - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt
> number: %d\n",
> > - __func__, irq);
> > - return;
> > - }
> > -
> > - /* clear status */
> > - s->regs[addr] &= ~data;
> > -
> > - /*
> > - * These status registers are used for notify sources ISR are
> executed.
> > - * If one source ISR is executed, it will clear one bit.
> > - * If it clear all bits, it means to initialize this register status
> > - * rather than sources ISR are executed.
> > - */
> > - if (data == 0xffffffff) {
> > - return;
> > - }
> > -
> > - /* All source ISR execution are done */
> > - if (!s->regs[addr]) {
> > - trace_aspeed_intc_all_isr_done(irq);
> > - if (s->pending[irq]) {
> > - /*
> > - * handle pending source interrupt
> > - * notify firmware which source interrupt are pending
> > - * by setting status register
> > - */
> > - s->regs[addr] = s->pending[irq];
> > - s->pending[irq] = 0;
> > - trace_aspeed_intc_trigger_irq(irq, s->regs[addr]);
> > - aspeed_intc_update(s, irq, 1);
> > - } else {
> > - /* clear irq */
> > - trace_aspeed_intc_clear_irq(irq, 0);
> > - aspeed_intc_update(s, irq, 0);
> > - }
> > - }
> > + aspeed_intc_status_handler(s, offset, data);
> > break;
> > default:
> > s->regs[addr] = data;
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 00/28] Support AST2700 A1
2025-02-18 9:25 ` [PATCH v3 00/28] Support AST2700 A1 Cédric Le Goater
@ 2025-02-20 5:11 ` Jamin Lin
2025-02-21 17:24 ` Cédric Le Goater
0 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin @ 2025-02-20 5:11 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 00/28] Support AST2700 A1
>
> Hello Jamin,
>
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > v1:
> > 1. Refactor INTC model to support both INTC0 and INTC1.
> > 2. Support AST2700 A1.
> > 3. Create ast2700a0-evb machine.
> >
> > v2:
> > To streamline the review process, split the following patch series into
> > three parts.
> >
> https://patchwork.kernel.org/project/qemu-devel/cover/20250121070424.246
> 5942-1-jamin_lin@aspeedtech.com/
> > This patch series focuses on cleaning up the INTC model to
> > facilitate future support for the INTC_IO model.
> >
> > v3:
> > 1. Update and add functional test for AST2700
> > 2. Add AST2700 INTC design guidance and its block diagram.
> > 3. Retaining the INTC naming and introducing a new INTCIO model to
> support the AST2700 A1.
> > 4. Create ast2700a1-evb machine and rename ast2700a0-evb machine
> > 5. Fix silicon revision issue and support AST2700 A1.
> >
> > With the patch applied, QEMU now supports two machines for running
> AST2700 SoCs:
> > ast2700a0-evb: Designed for AST2700 A0
> > ast2700a1-evb: Designed for AST2700 A1
> >
> > Test information
> > 1. QEMU version:
> >
> https://github.com/qemu/qemu/commit/ffaf7f0376f8040ce9068d71ae9ae872
> 25
> > 05c42e
> > 2. ASPEED SDK v09.05 pre-built image
> > https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
> > ast2700-default-obmc.tar.gz (AST2700 A1)
> >
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast
> 2700-default-obmc.tar.gz
> > ast2700-a0-default-obmc.tar.gz (AST2700 A0)
> >
> >
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast
> > 2700-a0-default-obmc.tar.gz
>
> The part adding new functional tests needs a rework. See comment.
>
> > Known Issue:
> > The HACE crypto and hash engine is enable by default since AST2700 A1.
> > However, aspeed_hace.c(HACE model) currently does not support the
> CRYPTO command.
> > To boot AST2700 A1, I have created a Patch 21 which temporarily
> > resolves the issue by sending an interrupt to notify the firmware that
> > the cryptographic command has completed. It is a temporary workaround
> > to resolve the boot issue in the Crypto Manager SelfTest.
> >
> > As a result, you will encounter the following kernel warning due to
> > the Crypto Manager test failure. If you don't want to see these kernel
> > warning, please add the following settings in your kernel config.
> >
> > ```
> > CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
> > ```
>
> Would it be possible to send the hace changes in its own series ?
>
>
Currently, the HACE HW engine and crypto self-tests are enabled by default in
SDK v09.05 FW. To boot QEMU for AST2700 A1 with the SDK v09.05 pre-built image,
a CRYPTO workaround patch is required.
The AST2700 A1 patch series includes functional tests. To make the functional tests
pass for AST2700 A1, I have included the HACE patch in the same patch series.
There are two ways to split this patch series:
Solution A:
1. Create series 1 to support AST2700 A1.
2. Create series 2 to support HACE.
3. Create series 3 to support AST2700 A1 functional tests.
Series 3 should depend on series 1 and 2.
Solution B:
1. Place a pre-built image called "ast2700-a1-qemu-disable-self-test" in the SDK v09.05 Github repository.
https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
2. Create one patch series to support AST2700 A1 with its functional tests.
3. Create series 2 to support HACE.
Could you tell me which solution you prefer or could you please give me any suggestion?
Thanks-Jamin
> >
> > Jamin Lin (28):
> > hw/intc/aspeed: Support setting different memory and register size
> > hw/intc/aspeed: Introduce helper functions for enable and status
> > registers
> > hw/intc/aspeed: Add object type name to trace events for better
> > debugging
> > hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
> > hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number
> > hw/intc/aspeed: Support different memory region ops
> > hw/intc/aspeed: Rename num_ints to num_inpins for clarity
> > hw/intc/aspeed: Add support for multiple output pins in INTC
> > hw/intc/aspeed: Refactor INTC to support separate input and output pin
> > indices
> > hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq
> > index and register address
> > hw/intc/aspeed: Introduce IRQ handler function to reduce code
> > duplication
> > hw/intc/aspeed: Add Support for Multi-Output IRQ Handling
> > hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
> > hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon
> > Revisions
> > hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer
> > for AST2700
> > hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping
> > hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for
> > AST2700 A1
> > hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
> > hw/misc/aspeed_hace: Fix coding style
> > hw/misc/aspeed_hace: Add AST2700 support
> > hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
> > hw/arm/aspeed_ast27x0: Add HACE support for AST2700
> > test/functional/aspeed: Introduce new function to fetch assets
> > tests/functional/aspeed: Introduce start_ast2700_test API and update
> > hwmon path
> > tests/functional/aspeed: Update test ASPEED SDK v09.05
> > tests/functional/aspeed: Renamed test case and machine for AST2700
> A0
> > tests/functional/aspeed: Add test case for AST2700 A1
> > docs/specs: add aspeed-intc
> >
> > docs/specs/aspeed-intc.rst | 136 ++++++
> > docs/specs/index.rst | 1 +
> > hw/arm/aspeed.c | 21 +-
> > hw/arm/aspeed_ast27x0.c | 291 +++++++++---
> > hw/intc/aspeed_intc.c | 593
> +++++++++++++++++++-----
> > hw/intc/trace-events | 25 +-
> > hw/misc/aspeed_hace.c | 44 +-
> > hw/misc/aspeed_scu.c | 5 +-
> > include/hw/arm/aspeed_soc.h | 3 +-
> > include/hw/intc/aspeed_intc.h | 32 +-
> > include/hw/misc/aspeed_hace.h | 1 +
> > include/hw/misc/aspeed_scu.h | 2 +
> > tests/functional/test_aarch64_aspeed.py | 47 +-
> > 13 files changed, 963 insertions(+), 238 deletions(-)
> > create mode 100644 docs/specs/aspeed-intc.rst
> >
>
> Patch 1-9 and the hace changes could be merged quickly.
>
>
> I need some help on patch 10,12,16,17.
>
> Andrew,
>
> Would you have time please ?
>
> Thanks,
>
> C.
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size
2025-02-18 5:33 ` Cédric Le Goater
@ 2025-02-20 5:45 ` Jamin Lin
2025-02-21 15:15 ` Cédric Le Goater
0 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin @ 2025-02-20 5:45 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 01/28] hw/intc/aspeed: Support setting different
> memory and register size
>
> Hello Jamin,
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > According to the AST2700 datasheet, the INTC(CPU DIE) controller has
> > 16KB
> > (0x4000) of register space, and the INTCIO (I/O DIE) controller has
> > 1KB (0x400) of register space.
> >
> > Introduced a new class attribute "mem_size" to set different memory
> > sizes for the INTC models in AST2700.
> >
> > Introduced a new class attribute "reg_size" to set different register
> > sizes for the INTC models in AST2700.
>
> Shouldn't that be multiple patches ?
>
I will add one patch for reg_size and another for mem_size.
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/intc/aspeed_intc.c | 17 +++++++++++++----
> > include/hw/intc/aspeed_intc.h | 4 ++++
> > 2 files changed, 17 insertions(+), 4 deletions(-)
> >
> > diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index
> > 126b711b94..316885a27a 100644
> > --- a/hw/intc/aspeed_intc.c
> > +++ b/hw/intc/aspeed_intc.c
> > @@ -117,10 +117,11 @@ static void aspeed_intc_set_irq(void *opaque, int
> irq, int level)
> > static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned
> int size)
> > {
> > AspeedINTCState *s = ASPEED_INTC(opaque);
> > + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> > uint32_t addr = offset >> 2;
> > uint32_t value = 0;
> >
> > - if (addr >= ASPEED_INTC_NR_REGS) {
>
> Side note, ASPEED_INTC_NR_REGS is defined as
>
> #define ASPEED_INTC_NR_REGS (0x2000 >> 2)
>
> and the register array as:
>
> uint32_t regs[ASPEED_INTC_NR_REGS];
>
> The number of regs looks pretty big for me. Are the registers covering the
> whole MMIO aperture ?
>
According to the datasheet, the entire register address space size of INTC (CPU DIE) is 16KB
(0x12100000-0x12103FFF). Therefore, I set the memory size to 0x4000.
Currently, we need to use the "GICINT192-201 raw status and clear" register INTC1B04.
Thus, an array size of 0x2000 is sufficient.
However, we are going to increase the size to 0x3000 to support the co-processors SSP and TSP
In the another patch series.
We also need to include the following register definitions:
/* SSP INTC Registers */
REG32(SSPINT128_EN, 0x2000)
REG32(SSPINT128_STATUS, 0x2004)
REG32(SSPINT129_EN, 0x2100)
REG32(SSPINT129_STATUS, 0x2104)
REG32(SSPINT130_EN, 0x2200)
REG32(SSPINT130_STATUS, 0x2204)
REG32(SSPINT131_EN, 0x2300)
REG32(SSPINT131_STATUS, 0x2304)
REG32(SSPINT132_EN, 0x2400)
REG32(SSPINT132_STATUS, 0x2404)
REG32(SSPINT133_EN, 0x2500)
REG32(SSPINT133_STATUS, 0x2504)
REG32(SSPINT134_EN, 0x2600)
REG32(SSPINT134_STATUS, 0x2604)
REG32(SSPINT135_EN, 0x2700)
REG32(SSPINT135_STATUS, 0x2704)
REG32(SSPINT136_EN, 0x2800)
REG32(SSPINT136_STATUS, 0x2804)
REG32(SSPINT137_EN, 0x2900)
REG32(SSPINT137_STATUS, 0x2904)
REG32(SSPINT138_EN, 0x2A00)
REG32(SSPINT138_STATUS, 0x2A04)
REG32(SSPINT160_169_EN, 0x2B00)
REG32(SSPINT160_169_STATUS, 0x2B04)
>
> > + if (offset >= aic->reg_size) {
>
> This is dead code since the MMIO aperture has the same size. You could
> remove the check.
Will remove.
>
> > qemu_log_mask(LOG_GUEST_ERROR,
> > "%s: Out-of-bounds read at offset 0x%"
> HWADDR_PRIx "\n",
> > __func__, offset); @@ -143,7 +144,7 @@
> static
> > void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> > uint32_t change;
> > uint32_t irq;
> >
> > - if (addr >= ASPEED_INTC_NR_REGS) {
> > + if (offset >= aic->reg_size) {
> > qemu_log_mask(LOG_GUEST_ERROR,
> > "%s: Out-of-bounds write at offset 0x%"
> HWADDR_PRIx "\n",
> > __func__, offset); @@ -302,10 +303,16 @@
> > static void aspeed_intc_realize(DeviceState *dev, Error **errp)
> > AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> > int i;
> >
> > + memory_region_init(&s->iomem_container, OBJECT(s),
> > + TYPE_ASPEED_INTC ".container", aic->mem_size);
> > +
> > + sysbus_init_mmio(sbd, &s->iomem_container);
>
> Why introduce a container ? Do you plan to have multiple sub-regions ?
>
I created a container to save the entire register address space of INTC and its sub-region to place the
actual used register address space.
0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
0000000012100000-0000000012101fff (prio 0, i/o): aspeed.intc.regs
0000000014c18000-0000000014c183ff (prio 0, i/o): aspeed.intc.container
0000000014c18000-0000000014c183d7 (prio 0, i/o): aspeed.intc.regs
If I misunderstood this design, I will change it to have two memory regions for INTC and INTCIO, respectively.
If need, I will change to the following memory regions. --> it removes containers.
0000000012100000-0000000012101fff (prio 0, i/o): aspeed.intc.regs
0000000014c18000-0000000014c183d7 (prio 0, i/o): aspeed.intc.regs
Do you expect the above memory regions for INTC?
Thanks for your review and suggestion.
Jamin
>
> Thanks,
>
> C.
>
>
>
> > +
> > memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_intc_ops,
> s,
> > - TYPE_ASPEED_INTC ".regs",
> ASPEED_INTC_NR_REGS << 2);
> > + TYPE_ASPEED_INTC ".regs", aic->reg_size);
> > +
> > + memory_region_add_subregion(&s->iomem_container, 0x0,
> &s->iomem);
> >
> > - sysbus_init_mmio(sbd, &s->iomem);
> > qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
> >
> > for (i = 0; i < aic->num_ints; i++) { @@ -344,6 +351,8 @@ static
> > void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
> > dc->desc = "ASPEED 2700 INTC Controller";
> > aic->num_lines = 32;
> > aic->num_ints = 9;
> > + aic->mem_size = 0x4000;
> > + aic->reg_size = 0x2000;
> > }
> >
> > static const TypeInfo aspeed_2700_intc_info = { diff --git
> > a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h index
> > 18cb43476c..ecaeb15aea 100644
> > --- a/include/hw/intc/aspeed_intc.h
> > +++ b/include/hw/intc/aspeed_intc.h
> > @@ -25,6 +25,8 @@ struct AspeedINTCState {
> >
> > /*< public >*/
> > MemoryRegion iomem;
> > + MemoryRegion iomem_container;
> > +
> > uint32_t regs[ASPEED_INTC_NR_REGS];
> > OrIRQState orgates[ASPEED_INTC_NR_INTS];
> > qemu_irq output_pins[ASPEED_INTC_NR_INTS]; @@ -39,6 +41,8 @@
> > struct AspeedINTCClass {
> >
> > uint32_t num_lines;
> > uint32_t num_ints;
> > + uint64_t mem_size;
> > + uint64_t reg_size;
> > };
> >
> > #endif /* ASPEED_INTC_H */
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
2025-02-18 9:15 ` Cédric Le Goater
@ 2025-02-20 5:57 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-20 5:57 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700
> INTCIO Controller
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > Introduce a new ast2700 INTCIO class to support AST2700 INTCIO.
> > Added new register definitions for INTCIO, including enable and status
> > registers for IRQs GICINT192 through GICINT197.
> > Created a dedicated IRQ array for INTCIO, supporting six input pins
> > and six output pins, aligning with the newly defined registers.
> > Implemented "aspeed_intcio_read" and "aspeed_intcio_write" to handle
> > INTCIO-specific register access.
> >
> > To GICINT196
> |
> >
> > ETH1 |-----------|
> |--------------------------|
> > -------->|0 | | INTCIO
> |
> > ETH2 | 4|
> orgates[0]------>|inpin[0]-------->outpin[0]|
> > -------->|1 5|
> orgates[1]------>|inpin[1]-------->outpin[1]|
> > ETH3 | 6|
> orgates[2]------>|inpin[2]-------->outpin[2]|
> > -------->|2 19|
> orgates[3]------>|inpin[3]-------->outpin[3]|
> > UART0 |
> 20|-->orgates[4]------>|inpin[4]-------->outpin[4]|
> > -------->|7 21|
> orgates[5]------>|inpin[5]-------->outpin[5]|
> > UART1 | 22|
> |--------------------------|
> > -------->|8 23|
> > UART2 | 24|
> > -------->|9 25|
> > UART3 | 26|
> > ---------|10 27|
> > UART5 | 28|
> > -------->|11 29|
> > UART6 | |
> > -------->|12 30|
> > UART7 | 31|
> > -------->|13 |
> > UART8 | OR[0:31] |
> > -------->|14 |
> > UART9 | |
> > -------->|15 |
> > UART10 | |
> > -------->|16 |
> > UART11 | |
> > -------->|17 |
> > UART12 | |
> > -------->|18 |
> > |-----------|
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/intc/aspeed_intc.c | 121
> ++++++++++++++++++++++++++++++++++
> > include/hw/intc/aspeed_intc.h | 1 +
> > 2 files changed, 122 insertions(+)
> >
> > diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index
> > 1a9e2bf8ce..a3bf935789 100644
> > --- a/hw/intc/aspeed_intc.c
> > +++ b/hw/intc/aspeed_intc.c
> > @@ -36,6 +36,20 @@ REG32(GICINT136_STATUS, 0x1804)
> > REG32(GICINT192_201_EN, 0x1B00)
> > REG32(GICINT192_201_STATUS, 0x1B04)
> >
> > +/* INTCIO Registers */
> > +REG32(GICINT192_EN, 0x100)
> > +REG32(GICINT192_STATUS, 0x104)
> > +REG32(GICINT193_EN, 0x110)
> > +REG32(GICINT193_STATUS, 0x114)
> > +REG32(GICINT194_EN, 0x120)
> > +REG32(GICINT194_STATUS, 0x124)
> > +REG32(GICINT195_EN, 0x130)
> > +REG32(GICINT195_STATUS, 0x134)
> > +REG32(GICINT196_EN, 0x140)
> > +REG32(GICINT196_STATUS, 0x144)
> > +REG32(GICINT197_EN, 0x150)
> > +REG32(GICINT197_STATUS, 0x154)
> > +
> > static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS]
> = {
> > {0, 0, 10, R_GICINT192_201_EN, R_GICINT192_201_STATUS},
> > {1, 10, 1, R_GICINT128_EN, R_GICINT128_STATUS}, @@ -49,6 +63,15
> > @@ static AspeedINTCIRQ
> aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
> > {9, 18, 1, R_GICINT136_EN, R_GICINT136_STATUS},
> > };
> >
> > +static AspeedINTCIRQ aspeed_2700_intcio_irqs[ASPEED_INTC_MAX_INPINS]
> = {
> > + {0, 0, 1, R_GICINT192_EN, R_GICINT192_STATUS},
> > + {1, 1, 1, R_GICINT193_EN, R_GICINT193_STATUS},
> > + {2, 2, 1, R_GICINT194_EN, R_GICINT194_STATUS},
> > + {3, 3, 1, R_GICINT195_EN, R_GICINT195_STATUS},
> > + {4, 4, 1, R_GICINT196_EN, R_GICINT196_STATUS},
> > + {5, 5, 1, R_GICINT197_EN, R_GICINT197_STATUS}, };
> > +
>
> I would move the array definition just before routine
> aspeed_2700_intcio_class_init().
>
Will update it
> > static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic,
> > uint32_t addr)
> > {
> > @@ -463,6 +486,71 @@ static void aspeed_intc_write(void *opaque,
> hwaddr offset, uint64_t data,
> > return;
> > }
> >
> > +static uint64_t aspeed_intcio_read(void *opaque, hwaddr offset,
> > + unsigned int size) {
> > + AspeedINTCState *s = ASPEED_INTC(opaque);
> > + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> > + const char *name = object_get_typename(OBJECT(s));
> > + uint32_t addr = offset >> 2;
>
> s/addr/reg/ ? I find that "reg" makes more sense.
>
Will update to reg
> > + uint32_t value = 0;
> > +
> > + if (offset >= aic->reg_size) {
>
> as said in patch 1, this is dead code bc the MMIO aperture has the same size.
> You could remove the check.
>
Will remove it
>
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "%s: Out-of-bounds read at offset 0x%"
> HWADDR_PRIx "\n",
> > + __func__, offset);
> > + return 0;
> > + }
> > +
> > + value = s->regs[addr];
> > + trace_aspeed_intc_read(name, offset, size, value);
> > +
> > + return value;
> > +}
> > +
> > +static void aspeed_intcio_write(void *opaque, hwaddr offset, uint64_t data,
> > + unsigned size) {
> > + AspeedINTCState *s = ASPEED_INTC(opaque);
> > + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> > + const char *name = object_get_typename(OBJECT(s));
> > + uint32_t addr = offset >> 2;
> > +
> > + if (offset >= aic->reg_size) {
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "%s: Out-of-bounds write at offset 0x%"
> HWADDR_PRIx "\n",
> > + __func__, offset);
> > + return;
> > + }
> > +
> > + trace_aspeed_intc_write(name, offset, size, data);
> > +
> > + switch (addr) {
> > + case R_GICINT192_EN:
> > + case R_GICINT193_EN:
> > + case R_GICINT194_EN:
> > + case R_GICINT195_EN:
> > + case R_GICINT196_EN:
> > + case R_GICINT197_EN:
> > + aspeed_intc_enable_handler(s, offset, data);
> > + break;
> > + case R_GICINT192_STATUS:
> > + case R_GICINT193_STATUS:
> > + case R_GICINT194_STATUS:
> > + case R_GICINT195_STATUS:
> > + case R_GICINT196_STATUS:
> > + case R_GICINT197_STATUS:
> > + aspeed_intc_status_handler(s, offset, data);
> > + break;
> > + default:
> > + s->regs[addr] = data;
> > + break;
> > + }
> > +
> > + return;
> > +}
> > +
> > +
> > static const MemoryRegionOps aspeed_intc_ops = {
> > .read = aspeed_intc_read,
> > .write = aspeed_intc_write,
> > @@ -473,6 +561,16 @@ static const MemoryRegionOps aspeed_intc_ops = {
> > }
> > };
> >
> > +static const MemoryRegionOps aspeed_intcio_ops = {
> > + .read = aspeed_intcio_read,
> > + .write = aspeed_intcio_write,
> > + .endianness = DEVICE_LITTLE_ENDIAN,
> > + .valid = {
> > + .min_access_size = 4,
> > + .max_access_size = 4,
> > + }
> > +};
> > +
> > static void aspeed_intc_instance_init(Object *obj)
> > {
> > AspeedINTCState *s = ASPEED_INTC(obj); @@ -572,10 +670,33 @@
> > static const TypeInfo aspeed_2700_intc_info = {
> > .class_init = aspeed_2700_intc_class_init,
> > };
> >
> > +static void aspeed_2700_intcio_class_init(ObjectClass *klass, void
> > +*data) {
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
> > +
> > + dc->desc = "ASPEED 2700 INTC IO Controller";
> > + aic->num_lines = 32;
> > + aic->num_inpins = 6;
> > + aic->num_outpins = 6;
> > + aic->mem_size = 0x400;
> > + aic->reg_size = 0x3d8;
> > + aic->reg_ops = &aspeed_intcio_ops;
> > + aic->irq_table = aspeed_2700_intcio_irqs;
> > + aic->irq_table_count = ARRAY_SIZE(aspeed_2700_intcio_irqs);
> > +}
> > +
> > +static const TypeInfo aspeed_2700_intcio_info = {
> > + .name = TYPE_ASPEED_2700_INTCIO,
> > + .parent = TYPE_ASPEED_INTC,
> > + .class_init = aspeed_2700_intcio_class_init, };
> > +
> > static void aspeed_intc_register_types(void)
> > {
> > type_register_static(&aspeed_intc_info);
> > type_register_static(&aspeed_2700_intc_info);
> > + type_register_static(&aspeed_2700_intcio_info);
> > }
> >
> > type_init(aspeed_intc_register_types);
> > diff --git a/include/hw/intc/aspeed_intc.h
> > b/include/hw/intc/aspeed_intc.h index 57146db2ce..e8ead15491 100644
> > --- a/include/hw/intc/aspeed_intc.h
> > +++ b/include/hw/intc/aspeed_intc.h
> > @@ -14,6 +14,7 @@
> >
> > #define TYPE_ASPEED_INTC "aspeed.intc"
> > #define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700"
> > +#define TYPE_ASPEED_2700_INTCIO TYPE_ASPEED_INTC "io" "-ast2700"
>
> You could use "io-ast2700". Minor.
>
Will update to "io-ast2700"
Thanks for your review and suggestion.
Jamin
> Thanks,
>
> C.
>
>
> > OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass,
> ASPEED_INTC)
> >
> > #define ASPEED_INTC_NR_REGS (0x2000 >> 2)
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output pins in INTC
2025-02-18 5:53 ` Cédric Le Goater
@ 2025-02-21 1:31 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-21 1:31 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output
> pins in INTC
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > Added support for multiple output pins in the INTC controller to
> > accommodate the AST2700 A1.
> >
> > Introduced "num_outpins" to represent the number of output pins.
> > Updated the IRQ handling logic to initialize and connect output pins
> > separately from input pins. Modified the "aspeed_soc_ast2700_realize"
> > function to connect source orgates to INTC and INTC to GIC128 - GIC136.
> Updated the "aspeed_intc_realize"
> > function to initialize output pins.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>
> could you please add to the .git/config file :
>
Thank you for letting me know this information and for your suggestion.
I will add it to my local Git configuration.
Jamin
> [diff]
> orderFile = /path/to/qemu/scripts/git.orderfile
>
> This will put .h files before the .c files in the patch.
>
>
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
>
> Thanks,
>
> C.
>
>
> > ---
> > hw/arm/aspeed_ast27x0.c | 6 +++++-
> > hw/intc/aspeed_intc.c | 4 ++++
> > include/hw/intc/aspeed_intc.h | 5 +++--
> > 3 files changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> > 18e14a7914..775e953afd 100644
> > --- a/hw/arm/aspeed_ast27x0.c
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -519,10 +519,14 @@ static void
> aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
> > aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc), 0,
> > sc->memmap[ASPEED_DEV_INTC]);
> >
> > - /* GICINT orgates -> INTC -> GIC */
> > + /* source orgates -> INTC */
> > for (i = 0; i < ic->num_inpins; i++) {
> > qdev_connect_gpio_out(DEVICE(&a->intc.orgates[i]), 0,
> >
> qdev_get_gpio_in(DEVICE(&a->intc),
> > i));
> > + }
> > +
> > + /* INTC -> GIC128 - GIC136 */
> > + for (i = 0; i < ic->num_outpins; i++) {
> > sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc), i,
> > qdev_get_gpio_in(DEVICE(&a->gic),
> >
> > aspeed_soc_ast2700_gic_intcmap[i].irq));
> > diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index
> > 95b40e1935..32c4a3bb44 100644
> > --- a/hw/intc/aspeed_intc.c
> > +++ b/hw/intc/aspeed_intc.c
> > @@ -354,6 +354,9 @@ static void aspeed_intc_realize(DeviceState *dev,
> Error **errp)
> > if (!qdev_realize(DEVICE(&s->orgates[i]), NULL, errp)) {
> > return;
> > }
> > + }
> > +
> > + for (i = 0; i < aic->num_outpins; i++) {
> > sysbus_init_irq(sbd, &s->output_pins[i]);
> > }
> > }
> > @@ -389,6 +392,7 @@ static void aspeed_2700_intc_class_init(ObjectClass
> *klass, void *data)
> > dc->desc = "ASPEED 2700 INTC Controller";
> > aic->num_lines = 32;
> > aic->num_inpins = 9;
> > + aic->num_outpins = 9;
> > aic->mem_size = 0x4000;
> > aic->reg_size = 0x2000;
> > }
> > diff --git a/include/hw/intc/aspeed_intc.h
> > b/include/hw/intc/aspeed_intc.h index 5f0429c7f9..0bf96a81bb 100644
> > --- a/include/hw/intc/aspeed_intc.h
> > +++ b/include/hw/intc/aspeed_intc.h
> > @@ -17,8 +17,8 @@
> > OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass,
> ASPEED_INTC)
> >
> > #define ASPEED_INTC_NR_REGS (0x2000 >> 2) -#define
> > ASPEED_INTC_NR_INTS 9
> > #define ASPEED_INTC_MAX_INPINS 9
> > +#define ASPEED_INTC_MAX_OUTPINS 9
> >
> > struct AspeedINTCState {
> > /*< private >*/
> > @@ -30,7 +30,7 @@ struct AspeedINTCState {
> >
> > uint32_t regs[ASPEED_INTC_NR_REGS];
> > OrIRQState orgates[ASPEED_INTC_MAX_INPINS];
> > - qemu_irq output_pins[ASPEED_INTC_NR_INTS];
> > + qemu_irq output_pins[ASPEED_INTC_MAX_OUTPINS];
> >
> > uint32_t enable[ASPEED_INTC_MAX_INPINS];
> > uint32_t mask[ASPEED_INTC_MAX_INPINS]; @@ -42,6 +42,7 @@
> struct
> > AspeedINTCClass {
> >
> > uint32_t num_lines;
> > uint32_t num_inpins;
> > + uint32_t num_outpins;
> > uint64_t mem_size;
> > uint64_t reg_size;
> > const MemoryRegionOps *reg_ops;
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 23/28] test/functional/aspeed: Introduce new function to fetch assets
2025-02-18 6:30 ` Cédric Le Goater
@ 2025-02-21 1:35 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-21 1:35 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > This method simplifies the process of fetching and extracting assets
> > from the Aspeed GitHub repository.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > tests/functional/test_aarch64_aspeed.py | 9 +++++----
> > 1 file changed, 5 insertions(+), 4 deletions(-)
> >
> > diff --git a/tests/functional/test_aarch64_aspeed.py
> > b/tests/functional/test_aarch64_aspeed.py
> > index 9595498ace..f3d7c8331a 100755
> > --- a/tests/functional/test_aarch64_aspeed.py
> > +++ b/tests/functional/test_aarch64_aspeed.py
> > @@ -27,14 +27,15 @@ def do_test_aarch64_aspeed_sdk_start(self, image):
> > wait_for_console_pattern(self, '## Loading kernel from FIT
> Image')
> > wait_for_console_pattern(self, 'Starting kernel ...')
> >
> > - ASSET_SDK_V903_AST2700 = Asset(
> > -
> 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.03/ast
> 2700-default-obmc.tar.gz',
> > -
> '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77'
> )
>
>
> We need to keep the ASSET_SDK_V903_AST2700 definition for pre-caching the
> assets. See :
>
> https://qemu.readthedocs.io/en/v9.2.0/devel/testing/functional.html#asset-ha
> ndling
>
Will rework functional test.
Thanks for your review and suggestion.
Jamin
>
> Thanks,
>
> C.
>
>
> > + def extra_aspeed_archive(self, version, file, checksum):
> > + url =
> 'https://github.com/AspeedTech-BMC/openbmc/releases/download'
> > + self.archive_extract(Asset(f'{url}/{version}/{file}',
> > + f'{checksum}'))
> >
> > def test_aarch64_ast2700_evb_sdk_v09_03(self):
> > self.set_machine('ast2700-evb')
> >
> > - self.archive_extract(self.ASSET_SDK_V903_AST2700)
> > + self.extra_aspeed_archive('v09.03', 'ast2700-default-obmc.tar.gz',
> > +
> > +
> '91225f50d255e2905ba8d8e0c80b71b9d157c3609770c7a740cd786370d85a77'
> )
> >
> > num_cpu = 4
> > uboot_size =
> > os.path.getsize(self.scratch_file('ast2700-default',
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
2025-02-18 6:49 ` Cédric Le Goater
@ 2025-02-21 1:37 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-21 1:37 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support
> for AST2700 A1
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > The memory map for AST2700 A1 remains compatible with AST2700 A0.
> > However, the IRQ mapping has been updated for AST2700 A1, with GIC
> > interrupts now ranging from 192 to 201. Add a new IRQ map table for
> AST2700 A1.
> > Add "aspeed_soc_ast2700a1_class_init" to initialize the AST2700 A1 SoC.
> > Introduce "aspeed_machine_ast2700a1_evb_class_init" to initialize the
> > AST2700 A1 EVB.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/arm/aspeed.c | 13 +++++++
> > hw/arm/aspeed_ast27x0.c | 80
> +++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 93 insertions(+)
> >
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index
> > 6ddfdbdeba..c0539e5950 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -1672,6 +1672,15 @@ static void
> aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, void *data)
> > mc->default_ram_size = 1 * GiB;
> > aspeed_machine_class_init_cpus_defaults(mc);
> > }
> > +
> > +static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc,
> > +void *data) {
> > + MachineClass *mc = MACHINE_CLASS(oc);
> > + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
> > +
> > + mc->desc = "Aspeed AST2700 A1 EVB (Cortex-A35)";
> > + amc->soc_name = "ast2700-a1";
> > +}
> > #endif
> >
> > static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass
> > *oc, @@ -1798,6 +1807,10 @@ static const TypeInfo
> aspeed_machine_types[] = {
> > .name = MACHINE_TYPE_NAME("ast2700a0-evb"),
> > .parent = TYPE_ASPEED_MACHINE,
> > .class_init = aspeed_machine_ast2700a0_evb_class_init,
> > + }, {
> > + .name = MACHINE_TYPE_NAME("ast2700a1-evb"),
> > + .parent = MACHINE_TYPE_NAME("ast2700a0-evb"),
>
> Shouldn't the parent be TYPE_ASPEED_MACHINE instead ?
>
Will update it.
Thanks for your review.
Jamin
> > + .class_init = aspeed_machine_ast2700a1_evb_class_init,
> > #endif
> > }, {
> > .name = TYPE_ASPEED_MACHINE,
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> > 0ccec774de..926b4c3e76 100644
> > --- a/hw/arm/aspeed_ast27x0.c
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -119,6 +119,52 @@ static const int aspeed_soc_ast2700a0_irqmap[] = {
> > [ASPEED_DEV_SDHCI] = 133,
> > };
> >
> > +static const int aspeed_soc_ast2700a1_irqmap[] = {
> > + [ASPEED_DEV_SDMC] = 0,
> > + [ASPEED_DEV_HACE] = 4,
> > + [ASPEED_DEV_XDMA] = 5,
> > + [ASPEED_DEV_UART4] = 8,
> > + [ASPEED_DEV_SCU] = 12,
> > + [ASPEED_DEV_RTC] = 13,
> > + [ASPEED_DEV_EMMC] = 15,
> > + [ASPEED_DEV_TIMER1] = 16,
> > + [ASPEED_DEV_TIMER2] = 17,
> > + [ASPEED_DEV_TIMER3] = 18,
> > + [ASPEED_DEV_TIMER4] = 19,
> > + [ASPEED_DEV_TIMER5] = 20,
> > + [ASPEED_DEV_TIMER6] = 21,
> > + [ASPEED_DEV_TIMER7] = 22,
> > + [ASPEED_DEV_TIMER8] = 23,
> > + [ASPEED_DEV_DP] = 28,
> > + [ASPEED_DEV_LPC] = 192,
> > + [ASPEED_DEV_IBT] = 192,
> > + [ASPEED_DEV_KCS] = 192,
> > + [ASPEED_DEV_I2C] = 194,
> > + [ASPEED_DEV_ADC] = 194,
> > + [ASPEED_DEV_GPIO] = 194,
> > + [ASPEED_DEV_FMC] = 195,
> > + [ASPEED_DEV_WDT] = 195,
> > + [ASPEED_DEV_PWM] = 195,
> > + [ASPEED_DEV_I3C] = 195,
> > + [ASPEED_DEV_UART0] = 196,
> > + [ASPEED_DEV_UART1] = 196,
> > + [ASPEED_DEV_UART2] = 196,
> > + [ASPEED_DEV_UART3] = 196,
> > + [ASPEED_DEV_UART5] = 196,
> > + [ASPEED_DEV_UART6] = 196,
> > + [ASPEED_DEV_UART7] = 196,
> > + [ASPEED_DEV_UART8] = 196,
> > + [ASPEED_DEV_UART9] = 196,
> > + [ASPEED_DEV_UART10] = 196,
> > + [ASPEED_DEV_UART11] = 196,
> > + [ASPEED_DEV_UART12] = 196,
> > + [ASPEED_DEV_ETH1] = 196,
> > + [ASPEED_DEV_ETH2] = 196,
> > + [ASPEED_DEV_ETH3] = 196,
> > + [ASPEED_DEV_PECI] = 197,
> > + [ASPEED_DEV_SDHCI] = 197,
> > +};
> > +
> > /* GICINT 128 */
> > /* GICINT 192 */
> > static const int ast2700_gic128_gic192_intcmap[] = { @@ -838,6
> > +884,34 @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc,
> void *data)
> > sc->get_irq = aspeed_soc_ast2700_get_irq;
> > }
> >
> > +static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, void
> > +*data) {
> > + static const char * const valid_cpu_types[] = {
> > + ARM_CPU_TYPE_NAME("cortex-a35"),
> > + NULL
> > + };
> > + DeviceClass *dc = DEVICE_CLASS(oc);
> > + AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
> > +
> > + /* Reason: The Aspeed SoC can only be instantiated from a board */
> > + dc->user_creatable = false;
> > + dc->realize = aspeed_soc_ast2700_realize;
> > +
> > + sc->name = "ast2700-a1";
> > + sc->valid_cpu_types = valid_cpu_types;
> > + sc->silicon_rev = AST2700_A1_SILICON_REV;
> > + sc->sram_size = 0x20000;
> > + sc->spis_num = 3;
> > + sc->wdts_num = 8;
> > + sc->macs_num = 3;
> > + sc->uarts_num = 13;
> > + sc->num_cpus = 4;
> > + sc->uarts_base = ASPEED_DEV_UART0;
> > + sc->irqmap = aspeed_soc_ast2700a1_irqmap;
> > + sc->memmap = aspeed_soc_ast2700_memmap;
> > + sc->get_irq = aspeed_soc_ast2700_get_irq;
> > +}
> > +
> > static const TypeInfo aspeed_soc_ast27x0_types[] = {
> > {
> > .name = TYPE_ASPEED27X0_SOC,
> > @@ -850,6 +924,12 @@ static const TypeInfo aspeed_soc_ast27x0_types[] =
> {
> > .instance_init = aspeed_soc_ast2700_init,
> > .class_init = aspeed_soc_ast2700a0_class_init,
> > },
> > + {
> > + .name = "ast2700-a1",
> > + .parent = TYPE_ASPEED27X0_SOC,
> > + .instance_init = aspeed_soc_ast2700_init,
> > + .class_init = aspeed_soc_ast2700a1_class_init,
> > + },
> > };
> >
> > DEFINE_TYPES(aspeed_soc_ast27x0_types)
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
2025-02-18 5:47 ` Cédric Le Goater
@ 2025-02-21 2:23 ` Jamin Lin
2025-02-21 14:04 ` Cédric Le Goater
0 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin @ 2025-02-21 2:23 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Cc: Troy Lee <troy_lee@aspeedtech.com>
> Subject: Re: [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine
> name for AST2700 A0
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > Currently, AST2700 SoC only supports A0. To support AST2700 A1, rename
> > its IRQ table and machine name.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/arm/aspeed.c | 8 ++++----
> > hw/arm/aspeed_ast27x0.c | 8 ++++----
> > 2 files changed, 8 insertions(+), 8 deletions(-)
> >
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index
> > d9418e2b9f..6ddfdbdeba 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -1654,12 +1654,12 @@ static void
> ast2700_evb_i2c_init(AspeedMachineState *bmc)
> > TYPE_TMP105, 0x4d);
> > }
> >
> > -static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc,
> > void *data)
> > +static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc,
> > +void *data)
> > {
> > MachineClass *mc = MACHINE_CLASS(oc);
> > AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
> >
> > - mc->desc = "Aspeed AST2700 EVB (Cortex-A35)";
> > + mc->desc = "Aspeed AST2700 A0 EVB (Cortex-A35)";
> > amc->soc_name = "ast2700-a0";
> > amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
> > amc->hw_strap2 = AST2700_EVB_HW_STRAP2; @@ -1795,9 +1795,9
> @@
> > static const TypeInfo aspeed_machine_types[] = {
> > .class_init =
> aspeed_minibmc_machine_ast1030_evb_class_init,
> > #ifdef TARGET_AARCH64
> > }, {
> > - .name = MACHINE_TYPE_NAME("ast2700-evb"),
> > + .name = MACHINE_TYPE_NAME("ast2700a0-evb"),
>
> machine "ast2700-evb" has now disappeared from QEMU. You need to add an
> alias with "mc->alias" to restore the initial machine name, or follow the
Will add
> deprecation process :
>
> https://qemu.readthedocs.io/en/v9.2.0/about/deprecated.html
>
Thanks for letting me know about the machine deprecation rules.
I understand why you suggest aliasing the initial machine "ast2700-evb" to "ast2700a0-evb."
To follow the machine deprecation rule, the initial machine "ast2700-evb" is aliased to "ast2700a0-evb."
In the future, we will alias "ast2700-evb" to new SoCs, such as "ast2700a1-evb."
Does this progress meet your expectations?
Thanks-Jamin
> Thanks,
>
> C.
>
>
>
> > .parent = TYPE_ASPEED_MACHINE,
> > - .class_init = aspeed_machine_ast2700_evb_class_init,
> > + .class_init = aspeed_machine_ast2700a0_evb_class_init,
> > #endif
> > }, {
> > .name = TYPE_ASPEED_MACHINE,
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> > 2d0c99f159..6e3375f5d3 100644
> > --- a/hw/arm/aspeed_ast27x0.c
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -72,7 +72,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] =
> {
> > #define AST2700_MAX_IRQ 256
> >
> > /* Shared Peripheral Interrupt values below are offset by -32 from
> > datasheet */ -static const int aspeed_soc_ast2700_irqmap[] = {
> > +static const int aspeed_soc_ast2700a0_irqmap[] = {
> > [ASPEED_DEV_UART0] = 132,
> > [ASPEED_DEV_UART1] = 132,
> > [ASPEED_DEV_UART2] = 132,
> > @@ -740,7 +740,7 @@ static void aspeed_soc_ast2700_realize(DeviceState
> *dev, Error **errp)
> > create_unimplemented_device("ast2700.io", 0x0, 0x4000000);
> > }
> >
> > -static void aspeed_soc_ast2700_class_init(ObjectClass *oc, void
> > *data)
> > +static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void
> > +*data)
> > {
> > static const char * const valid_cpu_types[] = {
> > ARM_CPU_TYPE_NAME("cortex-a35"), @@ -763,7 +763,7 @@
> static
> > void aspeed_soc_ast2700_class_init(ObjectClass *oc, void *data)
> > sc->uarts_num = 13;
> > sc->num_cpus = 4;
> > sc->uarts_base = ASPEED_DEV_UART0;
> > - sc->irqmap = aspeed_soc_ast2700_irqmap;
> > + sc->irqmap = aspeed_soc_ast2700a0_irqmap;
> > sc->memmap = aspeed_soc_ast2700_memmap;
> > sc->get_irq = aspeed_soc_ast2700_get_irq;
> > }
> > @@ -778,7 +778,7 @@ static const TypeInfo aspeed_soc_ast27x0_types[] = {
> > .name = "ast2700-a0",
> > .parent = TYPE_ASPEED27X0_SOC,
> > .instance_init = aspeed_soc_ast2700_init,
> > - .class_init = aspeed_soc_ast2700_class_init,
> > + .class_init = aspeed_soc_ast2700a0_class_init,
> > },
> > };
> >
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
2025-02-18 6:26 ` Cédric Le Goater
@ 2025-02-21 5:43 ` Jamin Lin
2025-02-21 6:55 ` Jamin Lin
2025-02-21 13:53 ` Cédric Le Goater
0 siblings, 2 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-21 5:43 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the
> Crypto Manager Self Test
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > Currently, it does not support the CRYPT command. Instead, it only
> > sends an interrupt to notify the firmware that the crypt command has
> completed.
> > It is a temporary workaround to resolve the boot issue in the Crypto
> > Manager Self Test.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>
> Please add an AspeedHACEClass class attribute (bool) to handle this
> workaround and a comment in the code mentioning the issue.
>
Thanks for review and suggestion.
I will add the use_crypt_workaround attribute to the AspeedHACEClass and introduce the use-crypt-workaround property.
Do you have any concerns, or do you have a preferred naming convention?
Thanks-Jamin
>
> Thanks,
>
> C.
>
>
>
> > ---
> > hw/misc/aspeed_hace.c | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 86422cb3be..4d0999e7e9 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -59,6 +59,7 @@
> > /* Other cmd bits */
> > #define HASH_IRQ_EN BIT(9)
> > #define HASH_SG_EN BIT(18)
> > +#define CRYPT_IRQ_EN BIT(12)
> > /* Scatter-gather data list */
> > #define SG_LIST_LEN_SIZE 4
> > #define SG_LIST_LEN_MASK 0x0FFFFFFF
> > @@ -343,6 +344,13 @@ static void aspeed_hace_write(void *opaque,
> hwaddr addr, uint64_t data,
> > qemu_irq_lower(s->irq);
> > }
> > }
> > + if (data & CRYPT_IRQ) {
> > + data &= ~CRYPT_IRQ;
> > +
> > + if (s->regs[addr] & CRYPT_IRQ) {
> > + qemu_irq_lower(s->irq);
> > + }
> > + }
> > break;
> > case R_HASH_SRC:
> > data &= ahc->src_mask;
> > @@ -388,6 +396,10 @@ static void aspeed_hace_write(void *opaque,
> hwaddr addr, uint64_t data,
> > case R_CRYPT_CMD:
> > qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not
> implemented\n",
> > __func__);
> > + s->regs[R_STATUS] |= CRYPT_IRQ;
> > + if (data & CRYPT_IRQ_EN) {
> > + qemu_irq_raise(s->irq);
> > + }
> > break;
> > default:
> > break;
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
2025-02-21 5:43 ` Jamin Lin
@ 2025-02-21 6:55 ` Jamin Lin
2025-02-21 13:53 ` Cédric Le Goater
1 sibling, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-21 6:55 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
>
> Hi Cedric,
>
> > Subject: Re: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in
> > the Crypto Manager Self Test
> >
> > On 2/13/25 04:35, Jamin Lin wrote:
> > > Currently, it does not support the CRYPT command. Instead, it only
> > > sends an interrupt to notify the firmware that the crypt command has
> > completed.
> > > It is a temporary workaround to resolve the boot issue in the Crypto
> > > Manager Self Test.
> > >
> > > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> >
> > Please add an AspeedHACEClass class attribute (bool) to handle this
> > workaround and a comment in the code mentioning the issue.
> >
> Thanks for review and suggestion.
> I will add the use_crypt_workaround attribute to the AspeedHACEClass and
> introduce the use-crypt-workaround property.
> Do you have any concerns, or do you have a preferred naming convention?
Update my comments.
I do not need to create a property. I can set use_crypt_workaround to true in aspeed_ast2700_hace_class_init
Thanks-Jamin
> Thanks-Jamin
>
> >
> > Thanks,
> >
> > C.
> >
> >
> >
> > > ---
> > > hw/misc/aspeed_hace.c | 12 ++++++++++++
> > > 1 file changed, 12 insertions(+)
> > >
> > > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > > 86422cb3be..4d0999e7e9 100644
> > > --- a/hw/misc/aspeed_hace.c
> > > +++ b/hw/misc/aspeed_hace.c
> > > @@ -59,6 +59,7 @@
> > > /* Other cmd bits */
> > > #define HASH_IRQ_EN BIT(9)
> > > #define HASH_SG_EN BIT(18)
> > > +#define CRYPT_IRQ_EN BIT(12)
> > > /* Scatter-gather data list */
> > > #define SG_LIST_LEN_SIZE 4
> > > #define SG_LIST_LEN_MASK 0x0FFFFFFF
> > > @@ -343,6 +344,13 @@ static void aspeed_hace_write(void *opaque,
> > hwaddr addr, uint64_t data,
> > > qemu_irq_lower(s->irq);
> > > }
> > > }
> > > + if (data & CRYPT_IRQ) {
> > > + data &= ~CRYPT_IRQ;
> > > +
> > > + if (s->regs[addr] & CRYPT_IRQ) {
> > > + qemu_irq_lower(s->irq);
> > > + }
> > > + }
> > > break;
> > > case R_HASH_SRC:
> > > data &= ahc->src_mask;
> > > @@ -388,6 +396,10 @@ static void aspeed_hace_write(void *opaque,
> > hwaddr addr, uint64_t data,
> > > case R_CRYPT_CMD:
> > > qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not
> > implemented\n",
> > > __func__);
> > > + s->regs[R_STATUS] |= CRYPT_IRQ;
> > > + if (data & CRYPT_IRQ_EN) {
> > > + qemu_irq_raise(s->irq);
> > > + }
> > > break;
> > > default:
> > > break;
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
2025-02-21 5:43 ` Jamin Lin
2025-02-21 6:55 ` Jamin Lin
@ 2025-02-21 13:53 ` Cédric Le Goater
2025-02-24 5:10 ` Jamin Lin
1 sibling, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-21 13:53 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
On 2/21/25 06:43, Jamin Lin wrote:
> Hi Cedric,
>
>> Subject: Re: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the
>> Crypto Manager Self Test
>>
>> On 2/13/25 04:35, Jamin Lin wrote:
>>> Currently, it does not support the CRYPT command. Instead, it only
>>> sends an interrupt to notify the firmware that the crypt command has
>> completed.
>>> It is a temporary workaround to resolve the boot issue in the Crypto
>>> Manager Self Test.
>>>
>>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>>
>> Please add an AspeedHACEClass class attribute (bool) to handle this
>> workaround and a comment in the code mentioning the issue.
>>
> Thanks for review and suggestion.
> I will add the use_crypt_workaround attribute to the AspeedHACEClass and introduce the use-crypt-workaround property.
> Do you have any concerns, or do you have a preferred naming convention?
May be 'raise_crypt_interrupt_workaround' to reflect what is being done ?
Thanks,
C.
> Thanks-Jamin
>
>>
>> Thanks,
>>
>> C.
>>
>>
>>
>>> ---
>>> hw/misc/aspeed_hace.c | 12 ++++++++++++
>>> 1 file changed, 12 insertions(+)
>>>
>>> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
>>> 86422cb3be..4d0999e7e9 100644
>>> --- a/hw/misc/aspeed_hace.c
>>> +++ b/hw/misc/aspeed_hace.c
>>> @@ -59,6 +59,7 @@
>>> /* Other cmd bits */
>>> #define HASH_IRQ_EN BIT(9)
>>> #define HASH_SG_EN BIT(18)
>>> +#define CRYPT_IRQ_EN BIT(12)
>>> /* Scatter-gather data list */
>>> #define SG_LIST_LEN_SIZE 4
>>> #define SG_LIST_LEN_MASK 0x0FFFFFFF
>>> @@ -343,6 +344,13 @@ static void aspeed_hace_write(void *opaque,
>> hwaddr addr, uint64_t data,
>>> qemu_irq_lower(s->irq);
>>> }
>>> }
>>> + if (data & CRYPT_IRQ) {
>>> + data &= ~CRYPT_IRQ;
>>> +
>>> + if (s->regs[addr] & CRYPT_IRQ) {
>>> + qemu_irq_lower(s->irq);
>>> + }
>>> + }
>>> break;
>>> case R_HASH_SRC:
>>> data &= ahc->src_mask;
>>> @@ -388,6 +396,10 @@ static void aspeed_hace_write(void *opaque,
>> hwaddr addr, uint64_t data,
>>> case R_CRYPT_CMD:
>>> qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not
>> implemented\n",
>>> __func__);
>>> + s->regs[R_STATUS] |= CRYPT_IRQ;
>>> + if (data & CRYPT_IRQ_EN) {
>>> + qemu_irq_raise(s->irq);
>>> + }
>>> break;
>>> default:
>>> break;
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
2025-02-21 2:23 ` Jamin Lin
@ 2025-02-21 14:04 ` Cédric Le Goater
0 siblings, 0 replies; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-21 14:04 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
On 2/21/25 03:23, Jamin Lin wrote:
> Hi Cedric,
>
>> Cc: Troy Lee <troy_lee@aspeedtech.com>
>> Subject: Re: [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine
>> name for AST2700 A0
>>
>> On 2/13/25 04:35, Jamin Lin wrote:
>>> Currently, AST2700 SoC only supports A0. To support AST2700 A1, rename
>>> its IRQ table and machine name.
>>>
>>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>>> ---
>>> hw/arm/aspeed.c | 8 ++++----
>>> hw/arm/aspeed_ast27x0.c | 8 ++++----
>>> 2 files changed, 8 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index
>>> d9418e2b9f..6ddfdbdeba 100644
>>> --- a/hw/arm/aspeed.c
>>> +++ b/hw/arm/aspeed.c
>>> @@ -1654,12 +1654,12 @@ static void
>> ast2700_evb_i2c_init(AspeedMachineState *bmc)
>>> TYPE_TMP105, 0x4d);
>>> }
>>>
>>> -static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc,
>>> void *data)
>>> +static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc,
>>> +void *data)
>>> {
>>> MachineClass *mc = MACHINE_CLASS(oc);
>>> AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
>>>
>>> - mc->desc = "Aspeed AST2700 EVB (Cortex-A35)";
>>> + mc->desc = "Aspeed AST2700 A0 EVB (Cortex-A35)";
>>> amc->soc_name = "ast2700-a0";
>>> amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
>>> amc->hw_strap2 = AST2700_EVB_HW_STRAP2; @@ -1795,9 +1795,9
>> @@
>>> static const TypeInfo aspeed_machine_types[] = {
>>> .class_init =
>> aspeed_minibmc_machine_ast1030_evb_class_init,
>>> #ifdef TARGET_AARCH64
>>> }, {
>>> - .name = MACHINE_TYPE_NAME("ast2700-evb"),
>>> + .name = MACHINE_TYPE_NAME("ast2700a0-evb"),
>>
>> machine "ast2700-evb" has now disappeared from QEMU. You need to add an
>> alias with "mc->alias" to restore the initial machine name, or follow the
>
>
> Will add
>
>> deprecation process :
>>
>> https://qemu.readthedocs.io/en/v9.2.0/about/deprecated.html
>>
> Thanks for letting me know about the machine deprecation rules.
> I understand why you suggest aliasing the initial machine "ast2700-evb" to "ast2700a0-evb."
yes. This to maintain compatibility for the user.
Also, this change is breaking the tests. Please run 'make check'
> To follow the machine deprecation rule, the initial machine "ast2700-evb" is aliased to "ast2700a0-evb."
You don't need the alias to deprecate a machine. You need the alias
to maintain compatibility when renaming a machine.
To deprecate, you should update docs/about/deprecated.rst.
> In the future, we will alias "ast2700-evb" to new SoCs, such as "ast2700a1-evb."
Yes we could do that.
Or we could keep the ast2700a0-evb and ast2700a1-evb machines,
change the alias to point to ast2700a1-evb first and later on
deprecate ast2700a0-evb.
Thanks,
C.
> Does this progress meet your expectations?
>
> Thanks-Jamin
>
>> Thanks,
>>
>> C.
>>
>>
>>
>>> .parent = TYPE_ASPEED_MACHINE,
>>> - .class_init = aspeed_machine_ast2700_evb_class_init,
>>> + .class_init = aspeed_machine_ast2700a0_evb_class_init,
>>> #endif
>>> }, {
>>> .name = TYPE_ASPEED_MACHINE,
>>> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
>>> 2d0c99f159..6e3375f5d3 100644
>>> --- a/hw/arm/aspeed_ast27x0.c
>>> +++ b/hw/arm/aspeed_ast27x0.c
>>> @@ -72,7 +72,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] =
>> {
>>> #define AST2700_MAX_IRQ 256
>>>
>>> /* Shared Peripheral Interrupt values below are offset by -32 from
>>> datasheet */ -static const int aspeed_soc_ast2700_irqmap[] = {
>>> +static const int aspeed_soc_ast2700a0_irqmap[] = {
>>> [ASPEED_DEV_UART0] = 132,
>>> [ASPEED_DEV_UART1] = 132,
>>> [ASPEED_DEV_UART2] = 132,
>>> @@ -740,7 +740,7 @@ static void aspeed_soc_ast2700_realize(DeviceState
>> *dev, Error **errp)
>>> create_unimplemented_device("ast2700.io", 0x0, 0x4000000);
>>> }
>>>
>>> -static void aspeed_soc_ast2700_class_init(ObjectClass *oc, void
>>> *data)
>>> +static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void
>>> +*data)
>>> {
>>> static const char * const valid_cpu_types[] = {
>>> ARM_CPU_TYPE_NAME("cortex-a35"), @@ -763,7 +763,7 @@
>> static
>>> void aspeed_soc_ast2700_class_init(ObjectClass *oc, void *data)
>>> sc->uarts_num = 13;
>>> sc->num_cpus = 4;
>>> sc->uarts_base = ASPEED_DEV_UART0;
>>> - sc->irqmap = aspeed_soc_ast2700_irqmap;
>>> + sc->irqmap = aspeed_soc_ast2700a0_irqmap;
>>> sc->memmap = aspeed_soc_ast2700_memmap;
>>> sc->get_irq = aspeed_soc_ast2700_get_irq;
>>> }
>>> @@ -778,7 +778,7 @@ static const TypeInfo aspeed_soc_ast27x0_types[] = {
>>> .name = "ast2700-a0",
>>> .parent = TYPE_ASPEED27X0_SOC,
>>> .instance_init = aspeed_soc_ast2700_init,
>>> - .class_init = aspeed_soc_ast2700_class_init,
>>> + .class_init = aspeed_soc_ast2700a0_class_init,
>>> },
>>> };
>>>
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size
2025-02-20 5:45 ` Jamin Lin
@ 2025-02-21 15:15 ` Cédric Le Goater
2025-02-26 3:40 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-21 15:15 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
On 2/20/25 06:45, Jamin Lin wrote:
> Hi Cedric,
>
>> Subject: Re: [PATCH v3 01/28] hw/intc/aspeed: Support setting different
>> memory and register size
>>
>> Hello Jamin,
>>
>> On 2/13/25 04:35, Jamin Lin wrote:
>>> According to the AST2700 datasheet, the INTC(CPU DIE) controller has
>>> 16KB
>>> (0x4000) of register space, and the INTCIO (I/O DIE) controller has
>>> 1KB (0x400) of register space.
>>>
>>> Introduced a new class attribute "mem_size" to set different memory
>>> sizes for the INTC models in AST2700.
>>>
>>> Introduced a new class attribute "reg_size" to set different register
>>> sizes for the INTC models in AST2700.
>>
>> Shouldn't that be multiple patches ?
>>
>
> I will add one patch for reg_size and another for mem_size.
>
>>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>>> ---
>>> hw/intc/aspeed_intc.c | 17 +++++++++++++----
>>> include/hw/intc/aspeed_intc.h | 4 ++++
>>> 2 files changed, 17 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index
>>> 126b711b94..316885a27a 100644
>>> --- a/hw/intc/aspeed_intc.c
>>> +++ b/hw/intc/aspeed_intc.c
>>> @@ -117,10 +117,11 @@ static void aspeed_intc_set_irq(void *opaque, int
>> irq, int level)
>>> static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned
>> int size)
>>> {
>>> AspeedINTCState *s = ASPEED_INTC(opaque);
>>> + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
>>> uint32_t addr = offset >> 2;
>>> uint32_t value = 0;
>>>
>>> - if (addr >= ASPEED_INTC_NR_REGS) {
>>
>> Side note, ASPEED_INTC_NR_REGS is defined as
>>
>> #define ASPEED_INTC_NR_REGS (0x2000 >> 2)
>>
>> and the register array as:
>>
>> uint32_t regs[ASPEED_INTC_NR_REGS];
>>
>> The number of regs looks pretty big for me. Are the registers covering the
>> whole MMIO aperture ?
>>
> According to the datasheet, the entire register address space size of INTC (CPU DIE) is 16KB
> (0x12100000-0x12103FFF). Therefore, I set the memory size to 0x4000.
> Currently, we need to use the "GICINT192-201 raw status and clear" register INTC1B04.
> Thus, an array size of 0x2000 is sufficient.
yes but we are only using these regs :
REG32(GICINT128_EN, 0x1000)
REG32(GICINT128_STATUS, 0x1004)
REG32(GICINT129_EN, 0x1100)
REG32(GICINT129_STATUS, 0x1104)
REG32(GICINT130_EN, 0x1200)
REG32(GICINT130_STATUS, 0x1204)
REG32(GICINT131_EN, 0x1300)
REG32(GICINT131_STATUS, 0x1304)
REG32(GICINT132_EN, 0x1400)
REG32(GICINT132_STATUS, 0x1404)
REG32(GICINT133_EN, 0x1500)
REG32(GICINT133_STATUS, 0x1504)
REG32(GICINT134_EN, 0x1600)
REG32(GICINT134_STATUS, 0x1604)
REG32(GICINT135_EN, 0x1700)
REG32(GICINT135_STATUS, 0x1704)
REG32(GICINT136_EN, 0x1800)
REG32(GICINT136_STATUS, 0x1804)
REG32(GICINT192_201_EN, 0x1B00)
REG32(GICINT192_201_STATUS, 0x1B04)
so the first 0x1000 are unused.
>
> However, we are going to increase the size to 0x3000 to support the co-processors SSP and TSP
> In the another patch series.
> We also need to include the following register definitions:
>
> /* SSP INTC Registers */
> REG32(SSPINT128_EN, 0x2000)
> REG32(SSPINT128_STATUS, 0x2004)
> REG32(SSPINT129_EN, 0x2100)
> REG32(SSPINT129_STATUS, 0x2104)
> REG32(SSPINT130_EN, 0x2200)
> REG32(SSPINT130_STATUS, 0x2204)
> REG32(SSPINT131_EN, 0x2300)
> REG32(SSPINT131_STATUS, 0x2304)
> REG32(SSPINT132_EN, 0x2400)
> REG32(SSPINT132_STATUS, 0x2404)
> REG32(SSPINT133_EN, 0x2500)
> REG32(SSPINT133_STATUS, 0x2504)
> REG32(SSPINT134_EN, 0x2600)
> REG32(SSPINT134_STATUS, 0x2604)
> REG32(SSPINT135_EN, 0x2700)
> REG32(SSPINT135_STATUS, 0x2704)
> REG32(SSPINT136_EN, 0x2800)
> REG32(SSPINT136_STATUS, 0x2804)
> REG32(SSPINT137_EN, 0x2900)
> REG32(SSPINT137_STATUS, 0x2904)
> REG32(SSPINT138_EN, 0x2A00)
> REG32(SSPINT138_STATUS, 0x2A04)
> REG32(SSPINT160_169_EN, 0x2B00)
> REG32(SSPINT160_169_STATUS, 0x2B04)
>
>>
>>> + if (offset >= aic->reg_size) {
>>
>> This is dead code since the MMIO aperture has the same size. You could
>> remove the check.
>
> Will remove.
>>
>>> qemu_log_mask(LOG_GUEST_ERROR,
>>> "%s: Out-of-bounds read at offset 0x%"
>> HWADDR_PRIx "\n",
>>> __func__, offset); @@ -143,7 +144,7 @@
>> static
>>> void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
>>> uint32_t change;
>>> uint32_t irq;
>>>
>>> - if (addr >= ASPEED_INTC_NR_REGS) {
>>> + if (offset >= aic->reg_size) {
>>> qemu_log_mask(LOG_GUEST_ERROR,
>>> "%s: Out-of-bounds write at offset 0x%"
>> HWADDR_PRIx "\n",
>>> __func__, offset); @@ -302,10 +303,16 @@
>>> static void aspeed_intc_realize(DeviceState *dev, Error **errp)
>>> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
>>> int i;
>>>
>>> + memory_region_init(&s->iomem_container, OBJECT(s),
>>> + TYPE_ASPEED_INTC ".container", aic->mem_size);
>>> +
>>> + sysbus_init_mmio(sbd, &s->iomem_container);
>>
>> Why introduce a container ? Do you plan to have multiple sub-regions ?
>>
> I created a container to save the entire register address space of INTC and its sub-region to place the
> actual used register address space.
> 0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
> 0000000012100000-0000000012101fff (prio 0, i/o): aspeed.intc.regs
> 0000000014c18000-0000000014c183ff (prio 0, i/o): aspeed.intc.container
> 0000000014c18000-0000000014c183d7 (prio 0, i/o): aspeed.intc.regs
>
> If I misunderstood this design, I will change it to have two memory regions for INTC and INTCIO, respectively.
> If need, I will change to the following memory regions. --> it removes containers.
> 0000000012100000-0000000012101fff (prio 0, i/o): aspeed.intc.regs
> 0000000014c18000-0000000014c183d7 (prio 0, i/o): aspeed.intc.regs
I don't think the region container is useful in that case since there is
only a single region per model.
However, we could "optimize" a bit the MMIO apertures to avoid mapping
huge unused gaps and only map the useful set of registers :
INTC Registers [ 0x1000 - 0x1B04 ]
SSP INTC Registers [ 0x2000 - 0x2B04 ]
INTCIO Registers [ 0x0100 - 0x0154 ]
Each set would be associated with a subregion which would be mapped at
the right offset in the region container.
This is just a suggestion.
Thanks,
C.
> Do you expect the above memory regions for INTC?
>
> Thanks for your review and suggestion.
> Jamin
>>
>> Thanks,
>>
>> C.
>>
>>
>>
>>> +
>>> memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_intc_ops,
>> s,
>>> - TYPE_ASPEED_INTC ".regs",
>> ASPEED_INTC_NR_REGS << 2);
>>> + TYPE_ASPEED_INTC ".regs", aic->reg_size);
>>> +
>>> + memory_region_add_subregion(&s->iomem_container, 0x0,
>> &s->iomem);
>>>
>>> - sysbus_init_mmio(sbd, &s->iomem);
>>> qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
>>>
>>> for (i = 0; i < aic->num_ints; i++) { @@ -344,6 +351,8 @@ static
>>> void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
>>> dc->desc = "ASPEED 2700 INTC Controller";
>>> aic->num_lines = 32;
>>> aic->num_ints = 9;
>>> + aic->mem_size = 0x4000;
>>> + aic->reg_size = 0x2000;
>>> }
>>>
>>> static const TypeInfo aspeed_2700_intc_info = { diff --git
>>> a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h index
>>> 18cb43476c..ecaeb15aea 100644
>>> --- a/include/hw/intc/aspeed_intc.h
>>> +++ b/include/hw/intc/aspeed_intc.h
>>> @@ -25,6 +25,8 @@ struct AspeedINTCState {
>>>
>>> /*< public >*/
>>> MemoryRegion iomem;
>>> + MemoryRegion iomem_container;
>>> +
>>> uint32_t regs[ASPEED_INTC_NR_REGS];
>>> OrIRQState orgates[ASPEED_INTC_NR_INTS];
>>> qemu_irq output_pins[ASPEED_INTC_NR_INTS]; @@ -39,6 +41,8 @@
>>> struct AspeedINTCClass {
>>>
>>> uint32_t num_lines;
>>> uint32_t num_ints;
>>> + uint64_t mem_size;
>>> + uint64_t reg_size;
>>> };
>>>
>>> #endif /* ASPEED_INTC_H */
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 00/28] Support AST2700 A1
2025-02-20 5:11 ` Jamin Lin
@ 2025-02-21 17:24 ` Cédric Le Goater
2025-02-25 8:02 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-21 17:24 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
On 2/20/25 06:11, Jamin Lin wrote:
> Hi Cedric,
>
>> Subject: Re: [PATCH v3 00/28] Support AST2700 A1
>>
>> Hello Jamin,
>>
>>
>> On 2/13/25 04:35, Jamin Lin wrote:
>>> v1:
>>> 1. Refactor INTC model to support both INTC0 and INTC1.
>>> 2. Support AST2700 A1.
>>> 3. Create ast2700a0-evb machine.
>>>
>>> v2:
>>> To streamline the review process, split the following patch series into
>>> three parts.
>>>
>> https://patchwork.kernel.org/project/qemu-devel/cover/20250121070424.246
>> 5942-1-jamin_lin@aspeedtech.com/
>>> This patch series focuses on cleaning up the INTC model to
>>> facilitate future support for the INTC_IO model.
>>>
>>> v3:
>>> 1. Update and add functional test for AST2700
>>> 2. Add AST2700 INTC design guidance and its block diagram.
>>> 3. Retaining the INTC naming and introducing a new INTCIO model to
>> support the AST2700 A1.
>>> 4. Create ast2700a1-evb machine and rename ast2700a0-evb machine
>>> 5. Fix silicon revision issue and support AST2700 A1.
>>>
>>> With the patch applied, QEMU now supports two machines for running
>> AST2700 SoCs:
>>> ast2700a0-evb: Designed for AST2700 A0
>>> ast2700a1-evb: Designed for AST2700 A1
>>>
>>> Test information
>>> 1. QEMU version:
>>>
>> https://github.com/qemu/qemu/commit/ffaf7f0376f8040ce9068d71ae9ae872
>> 25
>>> 05c42e
>>> 2. ASPEED SDK v09.05 pre-built image
>>> https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
>>> ast2700-default-obmc.tar.gz (AST2700 A1)
>>>
>> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast
>> 2700-default-obmc.tar.gz
>>> ast2700-a0-default-obmc.tar.gz (AST2700 A0)
>>>
>>>
>> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast
>>> 2700-a0-default-obmc.tar.gz
>>
>> The part adding new functional tests needs a rework. See comment.
>>
>>> Known Issue:
>>> The HACE crypto and hash engine is enable by default since AST2700 A1.
>>> However, aspeed_hace.c(HACE model) currently does not support the
>> CRYPTO command.
>>> To boot AST2700 A1, I have created a Patch 21 which temporarily
>>> resolves the issue by sending an interrupt to notify the firmware that
>>> the cryptographic command has completed. It is a temporary workaround
>>> to resolve the boot issue in the Crypto Manager SelfTest.
>>>
>>> As a result, you will encounter the following kernel warning due to
>>> the Crypto Manager test failure. If you don't want to see these kernel
>>> warning, please add the following settings in your kernel config.
>>>
>>> ```
>>> CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
>>> ```
>>
>> Would it be possible to send the hace changes in its own series ?
>>
>>
> Currently, the HACE HW engine and crypto self-tests are enabled by default in
> SDK v09.05 FW. To boot QEMU for AST2700 A1 with the SDK v09.05 pre-built image,
> a CRYPTO workaround patch is required.
can we upstream the HACE changes before having full AST2700 A1 support ?
Thanks,
C.
>
> The AST2700 A1 patch series includes functional tests. To make the functional tests
> pass for AST2700 A1, I have included the HACE patch in the same patch series.
>
> There are two ways to split this patch series:
>
> Solution A:
>
> 1. Create series 1 to support AST2700 A1.
> 2. Create series 2 to support HACE.
> 3. Create series 3 to support AST2700 A1 functional tests.
>
> Series 3 should depend on series 1 and 2.
>
> Solution B:
>
> 1. Place a pre-built image called "ast2700-a1-qemu-disable-self-test" in the SDK v09.05 Github repository.
> https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
> 2. Create one patch series to support AST2700 A1 with its functional tests.
> 3. Create series 2 to support HACE.
>
> Could you tell me which solution you prefer or could you please give me any suggestion?
>
> Thanks-Jamin
>
>>>
>>> Jamin Lin (28):
>>> hw/intc/aspeed: Support setting different memory and register size
>>> hw/intc/aspeed: Introduce helper functions for enable and status
>>> registers
>>> hw/intc/aspeed: Add object type name to trace events for better
>>> debugging
>>> hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0
>>> hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number
>>> hw/intc/aspeed: Support different memory region ops
>>> hw/intc/aspeed: Rename num_ints to num_inpins for clarity
>>> hw/intc/aspeed: Add support for multiple output pins in INTC
>>> hw/intc/aspeed: Refactor INTC to support separate input and output pin
>>> indices
>>> hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq
>>> index and register address
>>> hw/intc/aspeed: Introduce IRQ handler function to reduce code
>>> duplication
>>> hw/intc/aspeed: Add Support for Multi-Output IRQ Handling
>>> hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
>>> hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon
>>> Revisions
>>> hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer
>>> for AST2700
>>> hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping
>>> hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for
>>> AST2700 A1
>>> hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
>>> hw/misc/aspeed_hace: Fix coding style
>>> hw/misc/aspeed_hace: Add AST2700 support
>>> hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
>>> hw/arm/aspeed_ast27x0: Add HACE support for AST2700
>>> test/functional/aspeed: Introduce new function to fetch assets
>>> tests/functional/aspeed: Introduce start_ast2700_test API and update
>>> hwmon path
>>> tests/functional/aspeed: Update test ASPEED SDK v09.05
>>> tests/functional/aspeed: Renamed test case and machine for AST2700
>> A0
>>> tests/functional/aspeed: Add test case for AST2700 A1
>>> docs/specs: add aspeed-intc
>>>
>>> docs/specs/aspeed-intc.rst | 136 ++++++
>>> docs/specs/index.rst | 1 +
>>> hw/arm/aspeed.c | 21 +-
>>> hw/arm/aspeed_ast27x0.c | 291 +++++++++---
>>> hw/intc/aspeed_intc.c | 593
>> +++++++++++++++++++-----
>>> hw/intc/trace-events | 25 +-
>>> hw/misc/aspeed_hace.c | 44 +-
>>> hw/misc/aspeed_scu.c | 5 +-
>>> include/hw/arm/aspeed_soc.h | 3 +-
>>> include/hw/intc/aspeed_intc.h | 32 +-
>>> include/hw/misc/aspeed_hace.h | 1 +
>>> include/hw/misc/aspeed_scu.h | 2 +
>>> tests/functional/test_aarch64_aspeed.py | 47 +-
>>> 13 files changed, 963 insertions(+), 238 deletions(-)
>>> create mode 100644 docs/specs/aspeed-intc.rst
>>>
>>
>> Patch 1-9 and the hace changes could be merged quickly.
>>
>>
>> I need some help on patch 10,12,16,17.
>>
>> Andrew,
>>
>> Would you have time please ?
>>
>> Thanks,
>>
>> C.
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
2025-02-21 13:53 ` Cédric Le Goater
@ 2025-02-24 5:10 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-24 5:10 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the
> Crypto Manager Self Test
>
> On 2/21/25 06:43, Jamin Lin wrote:
> > Hi Cedric,
> >
> >> Subject: Re: [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in
> >> the Crypto Manager Self Test
> >>
> >> On 2/13/25 04:35, Jamin Lin wrote:
> >>> Currently, it does not support the CRYPT command. Instead, it only
> >>> sends an interrupt to notify the firmware that the crypt command has
> >> completed.
> >>> It is a temporary workaround to resolve the boot issue in the Crypto
> >>> Manager Self Test.
> >>>
> >>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> >>
> >> Please add an AspeedHACEClass class attribute (bool) to handle this
> >> workaround and a comment in the code mentioning the issue.
> >>
> > Thanks for review and suggestion.
> > I will add the use_crypt_workaround attribute to the AspeedHACEClass and
> introduce the use-crypt-workaround property.
> > Do you have any concerns, or do you have a preferred naming convention?
>
> May be 'raise_crypt_interrupt_workaround' to reflect what is being done ?
>
Thanks for your suggestion.
Will add it.
Jamin
> Thanks,
>
> C.
>
>
>
> > Thanks-Jamin
> >
> >>
> >> Thanks,
> >>
> >> C.
> >>
> >>
> >>
> >>> ---
> >>> hw/misc/aspeed_hace.c | 12 ++++++++++++
> >>> 1 file changed, 12 insertions(+)
> >>>
> >>> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> >>> 86422cb3be..4d0999e7e9 100644
> >>> --- a/hw/misc/aspeed_hace.c
> >>> +++ b/hw/misc/aspeed_hace.c
> >>> @@ -59,6 +59,7 @@
> >>> /* Other cmd bits */
> >>> #define HASH_IRQ_EN BIT(9)
> >>> #define HASH_SG_EN BIT(18)
> >>> +#define CRYPT_IRQ_EN BIT(12)
> >>> /* Scatter-gather data list */
> >>> #define SG_LIST_LEN_SIZE 4
> >>> #define SG_LIST_LEN_MASK 0x0FFFFFFF
> >>> @@ -343,6 +344,13 @@ static void aspeed_hace_write(void *opaque,
> >> hwaddr addr, uint64_t data,
> >>> qemu_irq_lower(s->irq);
> >>> }
> >>> }
> >>> + if (data & CRYPT_IRQ) {
> >>> + data &= ~CRYPT_IRQ;
> >>> +
> >>> + if (s->regs[addr] & CRYPT_IRQ) {
> >>> + qemu_irq_lower(s->irq);
> >>> + }
> >>> + }
> >>> break;
> >>> case R_HASH_SRC:
> >>> data &= ahc->src_mask;
> >>> @@ -388,6 +396,10 @@ static void aspeed_hace_write(void *opaque,
> >> hwaddr addr, uint64_t data,
> >>> case R_CRYPT_CMD:
> >>> qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not
> >> implemented\n",
> >>> __func__);
> >>> + s->regs[R_STATUS] |= CRYPT_IRQ;
> >>> + if (data & CRYPT_IRQ_EN) {
> >>> + qemu_irq_raise(s->irq);
> >>> + }
> >>> break;
> >>> default:
> >>> break;
> >
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 00/28] Support AST2700 A1
2025-02-21 17:24 ` Cédric Le Goater
@ 2025-02-25 8:02 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-02-25 8:02 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Cc: Troy Lee <troy_lee@aspeedtech.com>
> Subject: Re: [PATCH v3 00/28] Support AST2700 A1
>
> On 2/20/25 06:11, Jamin Lin wrote:
> > Hi Cedric,
> >
> >> Subject: Re: [PATCH v3 00/28] Support AST2700 A1
> >>
> >> Hello Jamin,
> >>
> >>
> >> On 2/13/25 04:35, Jamin Lin wrote:
> >>> v1:
> >>> 1. Refactor INTC model to support both INTC0 and INTC1.
> >>> 2. Support AST2700 A1.
> >>> 3. Create ast2700a0-evb machine.
> >>>
> >>> v2:
> >>> To streamline the review process, split the following patch series into
> >>> three parts.
> >>>
> >> https://patchwork.kernel.org/project/qemu-devel/cover/20250121070424.
> >> 246
> >> 5942-1-jamin_lin@aspeedtech.com/
> >>> This patch series focuses on cleaning up the INTC model to
> >>> facilitate future support for the INTC_IO model.
> >>>
> >>> v3:
> >>> 1. Update and add functional test for AST2700
> >>> 2. Add AST2700 INTC design guidance and its block diagram.
> >>> 3. Retaining the INTC naming and introducing a new INTCIO model
> >>> to
> >> support the AST2700 A1.
> >>> 4. Create ast2700a1-evb machine and rename ast2700a0-evb
> machine
> >>> 5. Fix silicon revision issue and support AST2700 A1.
> >>>
> >>> With the patch applied, QEMU now supports two machines for running
> >> AST2700 SoCs:
> >>> ast2700a0-evb: Designed for AST2700 A0
> >>> ast2700a1-evb: Designed for AST2700 A1
> >>>
> >>> Test information
> >>> 1. QEMU version:
> >>>
> >>
> https://github.com/qemu/qemu/commit/ffaf7f0376f8040ce9068d71ae9ae872
> >> 25
> >>> 05c42e
> >>> 2. ASPEED SDK v09.05 pre-built image
> >>> https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
> >>> ast2700-default-obmc.tar.gz (AST2700 A1)
> >>>
> >>
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/as
> >> t
> >> 2700-default-obmc.tar.gz
> >>> ast2700-a0-default-obmc.tar.gz (AST2700 A0)
> >>>
> >>>
> >>
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/as
> >> t
> >>> 2700-a0-default-obmc.tar.gz
> >>
> >> The part adding new functional tests needs a rework. See comment.
> >>
> >>> Known Issue:
> >>> The HACE crypto and hash engine is enable by default since AST2700 A1.
> >>> However, aspeed_hace.c(HACE model) currently does not support the
> >> CRYPTO command.
> >>> To boot AST2700 A1, I have created a Patch 21 which temporarily
> >>> resolves the issue by sending an interrupt to notify the firmware
> >>> that the cryptographic command has completed. It is a temporary
> >>> workaround to resolve the boot issue in the Crypto Manager SelfTest.
> >>>
> >>> As a result, you will encounter the following kernel warning due to
> >>> the Crypto Manager test failure. If you don't want to see these
> >>> kernel warning, please add the following settings in your kernel config.
> >>>
> >>> ```
> >>> CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
> >>> ```
> >>
> >> Would it be possible to send the hace changes in its own series ?
> >>
> >>
> > Currently, the HACE HW engine and crypto self-tests are enabled by
> > default in SDK v09.05 FW. To boot QEMU for AST2700 A1 with the SDK
> > v09.05 pre-built image, a CRYPTO workaround patch is required.
>
> can we upstream the HACE changes before having full AST2700 A1 support ?
>
I send HACE patch here, https://patchwork.kernel.org/project/qemu-devel/cover/20250225075622.305515-1-jamin_lin@aspeedtech.com/
Thanks-Jamin
> Thanks,
>
> C.
>
>
>
>
> >
> > The AST2700 A1 patch series includes functional tests. To make the
> > functional tests pass for AST2700 A1, I have included the HACE patch in the
> same patch series.
> >
> > There are two ways to split this patch series:
> >
> > Solution A:
> >
> > 1. Create series 1 to support AST2700 A1.
> > 2. Create series 2 to support HACE.
> > 3. Create series 3 to support AST2700 A1 functional tests.
> >
> > Series 3 should depend on series 1 and 2.
> >
> > Solution B:
> >
> > 1. Place a pre-built image called "ast2700-a1-qemu-disable-self-test" in the
> SDK v09.05 Github repository.
> > https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.05
> > 2. Create one patch series to support AST2700 A1 with its functional tests.
> > 3. Create series 2 to support HACE.
> >
> > Could you tell me which solution you prefer or could you please give me any
> suggestion?
> >
> > Thanks-Jamin
> >
> >>>
> >>> Jamin Lin (28):
> >>> hw/intc/aspeed: Support setting different memory and register size
> >>> hw/intc/aspeed: Introduce helper functions for enable and status
> >>> registers
> >>> hw/intc/aspeed: Add object type name to trace events for better
> >>> debugging
> >>> hw/arm/aspeed: Rename IRQ table and machine name for AST2700
> A0
> >>> hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number
> >>> hw/intc/aspeed: Support different memory region ops
> >>> hw/intc/aspeed: Rename num_ints to num_inpins for clarity
> >>> hw/intc/aspeed: Add support for multiple output pins in INTC
> >>> hw/intc/aspeed: Refactor INTC to support separate input and output
> pin
> >>> indices
> >>> hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq
> >>> index and register address
> >>> hw/intc/aspeed: Introduce IRQ handler function to reduce code
> >>> duplication
> >>> hw/intc/aspeed: Add Support for Multi-Output IRQ Handling
> >>> hw/intc/aspeed: Add Support for AST2700 INTCIO Controller
> >>> hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon
> >>> Revisions
> >>> hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC
> layer
> >>> for AST2700
> >>> hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt
> Mapping
> >>> hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for
> >>> AST2700 A1
> >>> hw/arm/aspeed: Add SoC and Machine Support for AST2700 A1
> >>> hw/misc/aspeed_hace: Fix coding style
> >>> hw/misc/aspeed_hace: Add AST2700 support
> >>> hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test
> >>> hw/arm/aspeed_ast27x0: Add HACE support for AST2700
> >>> test/functional/aspeed: Introduce new function to fetch assets
> >>> tests/functional/aspeed: Introduce start_ast2700_test API and update
> >>> hwmon path
> >>> tests/functional/aspeed: Update test ASPEED SDK v09.05
> >>> tests/functional/aspeed: Renamed test case and machine for
> >>> AST2700
> >> A0
> >>> tests/functional/aspeed: Add test case for AST2700 A1
> >>> docs/specs: add aspeed-intc
> >>>
> >>> docs/specs/aspeed-intc.rst | 136 ++++++
> >>> docs/specs/index.rst | 1 +
> >>> hw/arm/aspeed.c | 21 +-
> >>> hw/arm/aspeed_ast27x0.c | 291 +++++++++---
> >>> hw/intc/aspeed_intc.c | 593
> >> +++++++++++++++++++-----
> >>> hw/intc/trace-events | 25 +-
> >>> hw/misc/aspeed_hace.c | 44 +-
> >>> hw/misc/aspeed_scu.c | 5 +-
> >>> include/hw/arm/aspeed_soc.h | 3 +-
> >>> include/hw/intc/aspeed_intc.h | 32 +-
> >>> include/hw/misc/aspeed_hace.h | 1 +
> >>> include/hw/misc/aspeed_scu.h | 2 +
> >>> tests/functional/test_aarch64_aspeed.py | 47 +-
> >>> 13 files changed, 963 insertions(+), 238 deletions(-)
> >>> create mode 100644 docs/specs/aspeed-intc.rst
> >>>
> >>
> >> Patch 1-9 and the hace changes could be merged quickly.
> >>
> >>
> >> I need some help on patch 10,12,16,17.
> >>
> >> Andrew,
> >>
> >> Would you have time please ?
> >>
> >> Thanks,
> >>
> >> C.
> >
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size
2025-02-21 15:15 ` Cédric Le Goater
@ 2025-02-26 3:40 ` Jamin Lin
2025-02-27 9:57 ` Cédric Le Goater
0 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin @ 2025-02-26 3:40 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> >> and the register array as:
> >>
> >> uint32_t regs[ASPEED_INTC_NR_REGS];
> >>
> >> The number of regs looks pretty big for me. Are the registers
> >> covering the whole MMIO aperture ?
> >>
> > According to the datasheet, the entire register address space size of
> > INTC (CPU DIE) is 16KB (0x12100000-0x12103FFF). Therefore, I set the
> memory size to 0x4000.
> > Currently, we need to use the "GICINT192-201 raw status and clear" register
> INTC1B04.
> > Thus, an array size of 0x2000 is sufficient.
>
> yes but we are only using these regs :
>
> REG32(GICINT128_EN, 0x1000)
> REG32(GICINT128_STATUS, 0x1004)
> REG32(GICINT129_EN, 0x1100)
> REG32(GICINT129_STATUS, 0x1104)
> REG32(GICINT130_EN, 0x1200)
> REG32(GICINT130_STATUS, 0x1204)
> REG32(GICINT131_EN, 0x1300)
> REG32(GICINT131_STATUS, 0x1304)
> REG32(GICINT132_EN, 0x1400)
> REG32(GICINT132_STATUS, 0x1404)
> REG32(GICINT133_EN, 0x1500)
> REG32(GICINT133_STATUS, 0x1504)
> REG32(GICINT134_EN, 0x1600)
> REG32(GICINT134_STATUS, 0x1604)
> REG32(GICINT135_EN, 0x1700)
> REG32(GICINT135_STATUS, 0x1704)
> REG32(GICINT136_EN, 0x1800)
> REG32(GICINT136_STATUS, 0x1804)
> REG32(GICINT192_201_EN, 0x1B00)
> REG32(GICINT192_201_STATUS, 0x1B04)
>
> so the first 0x1000 are unused.
>
>
> >
> > However, we are going to increase the size to 0x3000 to support the
> > co-processors SSP and TSP In the another patch series.
> > We also need to include the following register definitions:
> >
> > /* SSP INTC Registers */
> > REG32(SSPINT128_EN, 0x2000)
> > REG32(SSPINT128_STATUS, 0x2004)
> > REG32(SSPINT129_EN, 0x2100)
> > REG32(SSPINT129_STATUS, 0x2104)
> > REG32(SSPINT130_EN, 0x2200)
> > REG32(SSPINT130_STATUS, 0x2204)
> > REG32(SSPINT131_EN, 0x2300)
> > REG32(SSPINT131_STATUS, 0x2304)
> > REG32(SSPINT132_EN, 0x2400)
> > REG32(SSPINT132_STATUS, 0x2404)
> > REG32(SSPINT133_EN, 0x2500)
> > REG32(SSPINT133_STATUS, 0x2504)
> > REG32(SSPINT134_EN, 0x2600)
> > REG32(SSPINT134_STATUS, 0x2604)
> > REG32(SSPINT135_EN, 0x2700)
> > REG32(SSPINT135_STATUS, 0x2704)
> > REG32(SSPINT136_EN, 0x2800)
> > REG32(SSPINT136_STATUS, 0x2804)
> > REG32(SSPINT137_EN, 0x2900)
> > REG32(SSPINT137_STATUS, 0x2904)
> > REG32(SSPINT138_EN, 0x2A00)
> > REG32(SSPINT138_STATUS, 0x2A04)
> > REG32(SSPINT160_169_EN, 0x2B00)
> > REG32(SSPINT160_169_STATUS, 0x2B04)
> >
> >>
> >>> + if (offset >= aic->reg_size) {
> >>
> >> This is dead code since the MMIO aperture has the same size. You
> >> could remove the check.
> >
> > Will remove.
> >>
> >>> qemu_log_mask(LOG_GUEST_ERROR,
> >>> "%s: Out-of-bounds read at offset 0x%"
> >> HWADDR_PRIx "\n",
> >>> __func__, offset); @@ -143,7 +144,7 @@
> >> static
> >>> void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> >>> uint32_t change;
> >>> uint32_t irq;
> >>>
> >>> - if (addr >= ASPEED_INTC_NR_REGS) {
> >>> + if (offset >= aic->reg_size) {
> >>> qemu_log_mask(LOG_GUEST_ERROR,
> >>> "%s: Out-of-bounds write at offset 0x%"
> >> HWADDR_PRIx "\n",
> >>> __func__, offset); @@ -302,10 +303,16
> @@
> >>> static void aspeed_intc_realize(DeviceState *dev, Error **errp)
> >>> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> >>> int i;
> >>>
> >>> + memory_region_init(&s->iomem_container, OBJECT(s),
> >>> + TYPE_ASPEED_INTC ".container", aic->mem_size);
> >>> +
> >>> + sysbus_init_mmio(sbd, &s->iomem_container);
> >>
> >> Why introduce a container ? Do you plan to have multiple sub-regions ?
> >>
> > I created a container to save the entire register address space of
> > INTC and its sub-region to place the actual used register address space.
> > 0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
> > 0000000012100000-0000000012101fff (prio 0, i/o):
> > aspeed.intc.regs 0000000014c18000-0000000014c183ff (prio 0, i/o):
> aspeed.intc.container
> > 0000000014c18000-0000000014c183d7 (prio 0, i/o):
> > aspeed.intc.regs
> >
> > If I misunderstood this design, I will change it to have two memory regions
> for INTC and INTCIO, respectively.
> > If need, I will change to the following memory regions. --> it removes
> containers.
> > 0000000012100000-0000000012101fff (prio 0, i/o):
> aspeed.intc.regs
> > 0000000014c18000-0000000014c183d7 (prio 0, i/o):
> > aspeed.intc.regs
>
> I don't think the region container is useful in that case since there is only a
> single region per model.
>
> However, we could "optimize" a bit the MMIO apertures to avoid mapping
> huge unused gaps and only map the useful set of registers :
>
> INTC Registers [ 0x1000 - 0x1B04 ]
> SSP INTC Registers [ 0x2000 - 0x2B04 ]
> INTCIO Registers [ 0x0100 - 0x0154 ]
>
> Each set would be associated with a subregion which would be mapped at the
> right offset in the region container.
>
> This is just a suggestion.
>
I followed your suggestion to reduce the size of the register array. Here's what I've done:
0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
0000000012101000-0000000012101b07 (prio 0, i/o): aspeed.intc.regs
A solution:
1. I created an INTC Register sub-region mapped at offset 0x1000 with a size of 0xb08.
This change adjusted the following register offsets to their original values minus 0x1000:
REG32(GICINT128_EN, 0x000)
REG32(GICINT128_STATUS, 0x004)
REG32(GICINT129_EN, 0x100)
REG32(GICINT129_STATUS, 0x104)
REG32(GICINT130_EN, 0x200)
REG32(GICINT130_STATUS, 0x204)
REG32(GICINT131_EN, 0x300)
REG32(GICINT131_STATUS, 0x304)
REG32(GICINT132_EN, 0x400)
REG32(GICINT132_STATUS, 0x404)
REG32(GICINT133_EN, 0x500)
REG32(GICINT133_STATUS, 0x504)
REG32(GICINT134_EN, 0x600)
REG32(GICINT134_STATUS, 0x604)
REG32(GICINT135_EN, 0x700)
REG32(GICINT135_STATUS, 0x704)
REG32(GICINT136_EN, 0x800)
REG32(GICINT136_STATUS, 0x804)
REG32(GICINT192_201_EN, 0xB00)
REG32(GICINT192_201_STATUS, 0xB04)
2. To support multiple sub-regions, such as for SSP, I created a new sub-region mapped at offset 0x2000.
This adjustment changed the register offsets to their original values minus 0x2000:
/* SSP INTC Registers */
> REG32(SSPINT128_EN, 0x000)
> REG32(SSPINT128_STATUS, 0x004)
> REG32(SSPINT129_EN, 0x100)
> REG32(SSPINT129_STATUS, 0x104)
> REG32(SSPINT130_EN, 0x200)
> REG32(SSPINT130_STATUS, 0x204)
> REG32(SSPINT131_EN, 0x300)
> REG32(SSPINT131_STATUS, 0x304)
> REG32(SSPINT132_EN, 0x400)
> REG32(SSPINT132_STATUS, 0x404)
> REG32(SSPINT133_EN, 0x500)
> REG32(SSPINT133_STATUS, 0x504)
> REG32(SSPINT134_EN, 0x600)
> REG32(SSPINT134_STATUS, 0x604)
> REG32(SSPINT135_EN, 0x700)
> REG32(SSPINT135_STATUS, 0x704)
> REG32(SSPINT136_EN, 0x800)
> REG32(SSPINT136_STATUS, 0x804)
> REG32(SSPINT137_EN, 0x900)
> REG32(SSPINT137_STATUS, 0x904)
> REG32(SSPINT138_EN, 0xA00)
> REG32(SSPINT138_STATUS, 0xA04)
> REG32(SSPINT160_169_EN, 0xB00)
> REG32(SSPINT160_169_STATUS, 0xB04)
Regarding handling identical offsets like SSPINT128_EN and GICINT128_EN, which both use offset 0x00,
they currently share the same aspeed_intc_ops and IRQ handler functions like aspeed_intc_status_handler.
How can I check whether the offset belongs to the SSP or INTC region?
Can I create new aspeed_intc_ssp_write and aspeed_intc_ssp_read callback functions specifically for
reading and writing to the SSP region, and then add new parameters to the IRQ handler to distinguish
between the SSP and INTC regions?
B solution:
There is another solution where we don't consider multiple sub-regions and only support a single sub-region.
Since the SSP runs on a co-processor, we've created a new SSP class:
static void aspeed_intc_register_types(void)
{
type_register_static(&aspeed_intc_info);
type_register_static(&aspeed_2700_intc_info);
type_register_static(&aspeed_2700_intcio_info);
+ type_register_static(&aspeed_2700_ssp_intc_info);
+ type_register_static(&aspeed_2700_ssp_intcio_info);
}
In this solution, we don’t need to make many changes because the SSP has its own AspeedINTCState register array.
As a result, most functions can be reused to support SSP.
The SSP uses the same callback function as the INTC:
static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
unsigned size)
{
switch (addr) {
case R_GICINT128_EN:
case R_GICINT129_EN:
case R_GICINT130_EN:
case R_GICINT131_EN:
case R_GICINT132_EN:
case R_GICINT133_EN:
case R_GICINT134_EN:
case R_GICINT135_EN:
case R_GICINT136_EN:
case R_GICINT192_201_EN:
+ case R_SSPINT128_STATUS:
+ case R_SSPINT129_STATUS:
+ case R_SSPINT130_STATUS:
Since both GICINT128_EN and SSPINT128_EN share the same offset of 0, I will modify the code to handle INT128 for both.
Could you please give me any suggestion?
Thanks-Jamin
>
> Thanks,
>
> C.
>
>
>
> > Do you expect the above memory regions for INTC?
> >
> > Thanks for your review and suggestion.
> > Jamin
> >>
> >> Thanks,
> >>
> >> C.
> >>
> >>
> >>
> >>> +
> >>> memory_region_init_io(&s->iomem, OBJECT(s),
> &aspeed_intc_ops,
> >> s,
> >>> - TYPE_ASPEED_INTC ".regs",
> >> ASPEED_INTC_NR_REGS << 2);
> >>> + TYPE_ASPEED_INTC ".regs",
> aic->reg_size);
> >>> +
> >>> + memory_region_add_subregion(&s->iomem_container, 0x0,
> >> &s->iomem);
> >>>
> >>> - sysbus_init_mmio(sbd, &s->iomem);
> >>> qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
> >>>
> >>> for (i = 0; i < aic->num_ints; i++) { @@ -344,6 +351,8 @@
> >>> static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
> >>> dc->desc = "ASPEED 2700 INTC Controller";
> >>> aic->num_lines = 32;
> >>> aic->num_ints = 9;
> >>> + aic->mem_size = 0x4000;
> >>> + aic->reg_size = 0x2000;
> >>> }
> >>>
> >>> static const TypeInfo aspeed_2700_intc_info = { diff --git
> >>> a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
> >>> index 18cb43476c..ecaeb15aea 100644
> >>> --- a/include/hw/intc/aspeed_intc.h
> >>> +++ b/include/hw/intc/aspeed_intc.h
> >>> @@ -25,6 +25,8 @@ struct AspeedINTCState {
> >>>
> >>> /*< public >*/
> >>> MemoryRegion iomem;
> >>> + MemoryRegion iomem_container;
> >>> +
> >>> uint32_t regs[ASPEED_INTC_NR_REGS];
> >>> OrIRQState orgates[ASPEED_INTC_NR_INTS];
> >>> qemu_irq output_pins[ASPEED_INTC_NR_INTS]; @@ -39,6 +41,8
> @@
> >>> struct AspeedINTCClass {
> >>>
> >>> uint32_t num_lines;
> >>> uint32_t num_ints;
> >>> + uint64_t mem_size;
> >>> + uint64_t reg_size;
> >>> };
> >>>
> >>> #endif /* ASPEED_INTC_H */
> >
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700
2025-02-18 6:47 ` Cédric Le Goater
@ 2025-02-26 6:38 ` Jamin Lin
2025-02-27 9:33 ` Cédric Le Goater
0 siblings, 1 reply; 70+ messages in thread
From: Jamin Lin @ 2025-02-26 6:38 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
>
> On 2/13/25 04:35, Jamin Lin wrote:
> > According to the design of the AST2600, it has a Silicon Revision ID
> > Register, specifically SCU004 and SCU014, to set the Revision ID for the
> AST2600.
> > For the AST2600 A3, SCU004 is set to 0x05030303 and SCU014 is set to
> 0x05030303.
> > In the "aspeed_ast2600_scu_reset" function, the hardcoded value
> > "AST2600_A3_SILICON_REV" is set in SCU004, and "s->silicon_rev" is set
> > in SCU014. The value of "s->silicon_rev" is set by the SOC layer via
> > the "silicon-rev" property.
> >
> > However, the design of the AST2700 is different. There are two SCU
> controllers:
> > SCU0 (CPU Die) and SCU1 (IO Die). In the AST2700, the firmware reads
> > the SCU Silicon Revision ID register (SCU0_000) and the SCUIO Silicon
> > Revision ID register (SCU1_000) and combines them into a 64-bit value.
> > The combined value of SCU0_000[23:16] and SCU1_000[23:16] represents
> > the silicon revision. For example, the AST2700-A1 revision is
> > "0x0601010306010103", where
> > SCU0_000 should be 06010103 and SCU1_000 should be 06010103.
>
> Are both these values supposed to be identical ? if not, we should plan for
> changes at machine/SoC level too.
>
Currently, these values are supposed to be identical. Therefore, we can reuse the current design of the
silicon_rev in the machine/SoC layer for AST2700.
> > static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS]
> = {
> > - [AST2700_SILICON_REV] = AST2700_A0_SILICON_REV,
> > [AST2700_HW_STRAP1] = 0x00000800,
> > [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> > [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> > @@ -940,6 +939,7 @@ static void aspeed_ast2700_scu_reset(DeviceState
> *dev)
> > AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
> >
> > memcpy(s->regs, asc->resets, asc->nr_regs * 4);
> > + s->regs[AST2700_SILICON_REV] = s->silicon_rev;
> >
> > }
> >
> > static void aspeed_2700_scu_class_init(ObjectClass *klass, void
> > *data) @@ -1032,7 +1032,6 @@ static const MemoryRegionOps
> aspeed_ast2700_scuio_ops = {
> > };
> >
> > static const uint32_t
> ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
> > - [AST2700_SILICON_REV] = 0x06000003,
> > [AST2700_HW_STRAP1] = 0x00000504,
>
> why isn't AST2700_HW_STRAP1 assigned with s->hw_strap1 property ?
>
This is a bug. The design of the HW_STRAP register has changed in the AST2700.
There is one hw_strap1 register in the SCU (CPU DIE) and another hw_strap1 register in the SCUIO (IO DIE).
The values of these two hw_strap1 registers should not be the same.
To fix this issue, I made the following changes. Do you have any suggestions?
Additionally, would it be possible to submit a separate patch for the SCU silicon_rev and SCU hw_strap fix?
The patch series for supporting AST2700 A1 is quite large.
Thanks-Jamin
1. I dumped the real values of both registers on the EVB
root@ast2700-a0-default:~# md 14c02010 1 ----> SCUIO hw_strap1
14c02010: 00000500
root@ast2700-a0-default:~# md 12c02010 1 --> SCU hw_strap1
12c02010: 00000800
The value AST2700_EVB_HW_STRAP1 0x00000800 is used for the SCU hw_strap1.
The value AST2700_EVB_HW_STRAP2 0x00000500 is used for the SCUIO hw_strap1
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -181,8 +181,8 @@ struct AspeedMachineState {
#ifdef TARGET_AARCH64
/* AST2700 evb hardware value */
-#define AST2700_EVB_HW_STRAP1 0x000000C0
-#define AST2700_EVB_HW_STRAP2 0x00000003
+#define AST2700_EVB_HW_STRAP1 0x00000800
+#define AST2700_EVB_HW_STRAP2 0x00000500
#endif
2. Change to set hw_strap2 in the SCUIO model. Note this will modify the hw_strap1 register of the SCUIO.
+++ b/hw/arm/aspeed_ast27x0.c
@@ -410,14 +410,14 @@ static void aspeed_soc_ast2700_init(Object *obj)
sc->silicon_rev);
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
"hw-strap1");
- object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
- "hw-strap2");
object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
"hw-prot-key");
object_initialize_child(obj, "scuio", &s->scuio, TYPE_ASPEED_2700_SCUIO);
qdev_prop_set_uint32(DEVICE(&s->scuio), "silicon-rev",
sc->silicon_rev);
+ object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scuio),
+ "hw-strap2");
3. I introduced a new aspeed_ast2700_scuio_reset function for the SCUIO model and
set the value of the hw_strap2 property to the HW_STRAP1 register of the SCUIO model.
s->regs[AST2700_HW_STRAP1] = s->hw_strap2;
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 259b142850..23ab7526f5 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -912,7 +912,6 @@ static const MemoryRegionOps aspeed_ast2700_scu_ops = {
};
static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS] = {
- [AST2700_HW_STRAP1] = 0x00000800,
[AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
[AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
[AST2700_HW_STRAP1_SEC1] = 0x000000FF,
@@ -942,6 +941,7 @@ static void aspeed_ast2700_scu_reset(DeviceState *dev)
memcpy(s->regs, asc->resets, asc->nr_regs * 4);
s->regs[AST2700_SILICON_REV] = s->silicon_rev;
+ s->regs[AST2700_HW_STRAP1] = s->hw_strap1;
}
static void aspeed_2700_scu_class_init(ObjectClass *klass, void *data)
@@ -1034,7 +1034,6 @@ static const MemoryRegionOps aspeed_ast2700_scuio_ops = {
};
static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
- [AST2700_HW_STRAP1] = 0x00000504,
[AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
[AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
[AST2700_HW_STRAP1_SEC1] = 0x000000FF,
@@ -1057,13 +1056,23 @@ static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
[AST2700_SCUIO_CLK_DUTY_MEAS_RST] = 0x0c9100d2,
};
+static void aspeed_ast2700_scuio_reset(DeviceState *dev)
+{
+ AspeedSCUState *s = ASPEED_SCU(dev);
+ AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
+
+ memcpy(s->regs, asc->resets, asc->nr_regs * 4);
+ s->regs[AST2700_SILICON_REV] = s->silicon_rev;
+ s->regs[AST2700_HW_STRAP1] = s->hw_strap2;
+}
+
static void aspeed_2700_scuio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
dc->desc = "ASPEED 2700 System Control Unit I/O";
- device_class_set_legacy_reset(dc, aspeed_ast2700_scu_reset);
+ device_class_set_legacy_reset(dc, aspeed_ast2700_scuio_reset);
asc->resets = ast2700_a0_resets_io;
asc->calc_hpll = aspeed_2600_scu_calc_hpll;
asc->get_apb = aspeed_2700_scuio_get_apb_freq;
> The above changes could be merged as a fix.
>
> Thanks,
>
> C.
>
>
> > [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> > [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
^ permalink raw reply related [flat|nested] 70+ messages in thread
* Re: [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700
2025-02-26 6:38 ` Jamin Lin
@ 2025-02-27 9:33 ` Cédric Le Goater
2025-03-03 2:51 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-27 9:33 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hello Jamin,
On 2/26/25 07:38, Jamin Lin wrote:
> Hi Cedric,
>
>>
>> On 2/13/25 04:35, Jamin Lin wrote:
>>> According to the design of the AST2600, it has a Silicon Revision ID
>>> Register, specifically SCU004 and SCU014, to set the Revision ID for the
>> AST2600.
>>> For the AST2600 A3, SCU004 is set to 0x05030303 and SCU014 is set to
>> 0x05030303.
>>> In the "aspeed_ast2600_scu_reset" function, the hardcoded value
>>> "AST2600_A3_SILICON_REV" is set in SCU004, and "s->silicon_rev" is set
>>> in SCU014. The value of "s->silicon_rev" is set by the SOC layer via
>>> the "silicon-rev" property.
>>>
>>> However, the design of the AST2700 is different. There are two SCU
>> controllers:
>>> SCU0 (CPU Die) and SCU1 (IO Die). In the AST2700, the firmware reads
>>> the SCU Silicon Revision ID register (SCU0_000) and the SCUIO Silicon
>>> Revision ID register (SCU1_000) and combines them into a 64-bit value.
>>> The combined value of SCU0_000[23:16] and SCU1_000[23:16] represents
>>> the silicon revision. For example, the AST2700-A1 revision is
>>> "0x0601010306010103", where
>>> SCU0_000 should be 06010103 and SCU1_000 should be 06010103.
>>
>> Are both these values supposed to be identical ? if not, we should plan for
>> changes at machine/SoC level too.
>>
>
> Currently, these values are supposed to be identical. Therefore, we can reuse the current design of the
> silicon_rev in the machine/SoC layer for AST2700.
>
>>> static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS]
>> = {
>>> - [AST2700_SILICON_REV] = AST2700_A0_SILICON_REV,
>>> [AST2700_HW_STRAP1] = 0x00000800,
>>> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
>>> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
>>> @@ -940,6 +939,7 @@ static void aspeed_ast2700_scu_reset(DeviceState
>> *dev)
>>> AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
>>>
>>> memcpy(s->regs, asc->resets, asc->nr_regs * 4);
>>> + s->regs[AST2700_SILICON_REV] = s->silicon_rev;
>>>
>>> }
>>>
>>> static void aspeed_2700_scu_class_init(ObjectClass *klass, void
>>> *data) @@ -1032,7 +1032,6 @@ static const MemoryRegionOps
>> aspeed_ast2700_scuio_ops = {
>>> };
>>>
>>> static const uint32_t
>> ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
>>> - [AST2700_SILICON_REV] = 0x06000003,
>>> [AST2700_HW_STRAP1] = 0x00000504,
>>
>> why isn't AST2700_HW_STRAP1 assigned with s->hw_strap1 property ?
>>
>
> This is a bug. The design of the HW_STRAP register has changed in the AST2700.
> There is one hw_strap1 register in the SCU (CPU DIE) and another hw_strap1 register in the SCUIO (IO DIE).
> The values of these two hw_strap1 registers should not be the same.
>
> To fix this issue, I made the following changes. Do you have any suggestions?
All Aspeed SoC models currently define "hw-strap1" and "hw-strap2"
properties as aliases on the same properties of the SCU model :
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
"hw-strap1");
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
"hw-strap2");
For the AST2700 SoC, you could change the "hw-strap2" alias to point
to the SCUIO model :
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
"hw-strap1");
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scuio),
"hw-strap1");
> Additionally, would it be possible to submit a separate patch for the SCU silicon_rev and SCU hw_strap fix?
yes we should please.
> The patch series for supporting AST2700 A1 is quite large.
yes. That's why I asked you to split it :)
> Thanks-Jamin
>
> 1. I dumped the real values of both registers on the EVB
>
> root@ast2700-a0-default:~# md 14c02010 1 ----> SCUIO hw_strap1
> 14c02010: 00000500
> root@ast2700-a0-default:~# md 12c02010 1 --> SCU hw_strap1
> 12c02010: 00000800
>
> The value AST2700_EVB_HW_STRAP1 0x00000800 is used for the SCU hw_strap1.
> The value AST2700_EVB_HW_STRAP2 0x00000500 is used for the SCUIO hw_strap1
>
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -181,8 +181,8 @@ struct AspeedMachineState {
>
> #ifdef TARGET_AARCH64
> /* AST2700 evb hardware value */
> -#define AST2700_EVB_HW_STRAP1 0x000000C0
> -#define AST2700_EVB_HW_STRAP2 0x00000003
> +#define AST2700_EVB_HW_STRAP1 0x00000800
> +#define AST2700_EVB_HW_STRAP2 0x00000500
> #endif
>
> 2. Change to set hw_strap2 in the SCUIO model. Note this will modify the hw_strap1 register of the SCUIO.
>
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -410,14 +410,14 @@ static void aspeed_soc_ast2700_init(Object *obj)
> sc->silicon_rev);
> object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
> "hw-strap1");
> - object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
> - "hw-strap2");
> object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
> "hw-prot-key");
>
> object_initialize_child(obj, "scuio", &s->scuio, TYPE_ASPEED_2700_SCUIO);
> qdev_prop_set_uint32(DEVICE(&s->scuio), "silicon-rev",
> sc->silicon_rev);
> + object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scuio),
> + "hw-strap2");
Why use "hw-strap2" and not "hw-strap1" ?
Please add comments in the AST2700 SoC and AST2700 SCU models so that the
information does not get lost.
> 3. I introduced a new aspeed_ast2700_scuio_reset function for the SCUIO model and
> set the value of the hw_strap2 property to the HW_STRAP1 register of the SCUIO model.
>
> s->regs[AST2700_HW_STRAP1] = s->hw_strap2;
That's weird. I would use s->hw_strap1.
Thanks,
C.
> diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> index 259b142850..23ab7526f5 100644
> --- a/hw/misc/aspeed_scu.c
> +++ b/hw/misc/aspeed_scu.c
> @@ -912,7 +912,6 @@ static const MemoryRegionOps aspeed_ast2700_scu_ops = {
> };
>
> static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS] = {
> - [AST2700_HW_STRAP1] = 0x00000800,
> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> [AST2700_HW_STRAP1_SEC1] = 0x000000FF,
> @@ -942,6 +941,7 @@ static void aspeed_ast2700_scu_reset(DeviceState *dev)
>
> memcpy(s->regs, asc->resets, asc->nr_regs * 4);
> s->regs[AST2700_SILICON_REV] = s->silicon_rev;
> + s->regs[AST2700_HW_STRAP1] = s->hw_strap1;
> }
>
> static void aspeed_2700_scu_class_init(ObjectClass *klass, void *data)
> @@ -1034,7 +1034,6 @@ static const MemoryRegionOps aspeed_ast2700_scuio_ops = {
> };
>
> static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
> - [AST2700_HW_STRAP1] = 0x00000504,
> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> [AST2700_HW_STRAP1_SEC1] = 0x000000FF,
> @@ -1057,13 +1056,23 @@ static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
> [AST2700_SCUIO_CLK_DUTY_MEAS_RST] = 0x0c9100d2,
> };
>
> +static void aspeed_ast2700_scuio_reset(DeviceState *dev)
> +{
> + AspeedSCUState *s = ASPEED_SCU(dev);
> + AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
> +
> + memcpy(s->regs, asc->resets, asc->nr_regs * 4);
> + s->regs[AST2700_SILICON_REV] = s->silicon_rev;
> + s->regs[AST2700_HW_STRAP1] = s->hw_strap2;
> +}
> +
> static void aspeed_2700_scuio_class_init(ObjectClass *klass, void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
>
> dc->desc = "ASPEED 2700 System Control Unit I/O";
> - device_class_set_legacy_reset(dc, aspeed_ast2700_scu_reset);
> + device_class_set_legacy_reset(dc, aspeed_ast2700_scuio_reset);
> asc->resets = ast2700_a0_resets_io;
> asc->calc_hpll = aspeed_2600_scu_calc_hpll;
> asc->get_apb = aspeed_2700_scuio_get_apb_freq;
>
>
>> The above changes could be merged as a fix.
>>
>> Thanks,
>>
>> C.
>>
>>
>>> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
>>> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size
2025-02-26 3:40 ` Jamin Lin
@ 2025-02-27 9:57 ` Cédric Le Goater
2025-03-03 2:52 ` Jamin Lin
0 siblings, 1 reply; 70+ messages in thread
From: Cédric Le Goater @ 2025-02-27 9:57 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
On 2/26/25 04:40, Jamin Lin wrote:
> Hi Cedric,
>
>>>> and the register array as:
>>>>
>>>> uint32_t regs[ASPEED_INTC_NR_REGS];
>>>>
>>>> The number of regs looks pretty big for me. Are the registers
>>>> covering the whole MMIO aperture ?
>>>>
>>> According to the datasheet, the entire register address space size of
>>> INTC (CPU DIE) is 16KB (0x12100000-0x12103FFF). Therefore, I set the
>> memory size to 0x4000.
>>> Currently, we need to use the "GICINT192-201 raw status and clear" register
>> INTC1B04.
>>> Thus, an array size of 0x2000 is sufficient.
>>
>> yes but we are only using these regs :
>>
>> REG32(GICINT128_EN, 0x1000)
>> REG32(GICINT128_STATUS, 0x1004)
>> REG32(GICINT129_EN, 0x1100)
>> REG32(GICINT129_STATUS, 0x1104)
>> REG32(GICINT130_EN, 0x1200)
>> REG32(GICINT130_STATUS, 0x1204)
>> REG32(GICINT131_EN, 0x1300)
>> REG32(GICINT131_STATUS, 0x1304)
>> REG32(GICINT132_EN, 0x1400)
>> REG32(GICINT132_STATUS, 0x1404)
>> REG32(GICINT133_EN, 0x1500)
>> REG32(GICINT133_STATUS, 0x1504)
>> REG32(GICINT134_EN, 0x1600)
>> REG32(GICINT134_STATUS, 0x1604)
>> REG32(GICINT135_EN, 0x1700)
>> REG32(GICINT135_STATUS, 0x1704)
>> REG32(GICINT136_EN, 0x1800)
>> REG32(GICINT136_STATUS, 0x1804)
>> REG32(GICINT192_201_EN, 0x1B00)
>> REG32(GICINT192_201_STATUS, 0x1B04)
>>
>> so the first 0x1000 are unused.
>>
>>
>>>
>>> However, we are going to increase the size to 0x3000 to support the
>>> co-processors SSP and TSP In the another patch series.
>>> We also need to include the following register definitions:
>>>
>>> /* SSP INTC Registers */
>>> REG32(SSPINT128_EN, 0x2000)
>>> REG32(SSPINT128_STATUS, 0x2004)
>>> REG32(SSPINT129_EN, 0x2100)
>>> REG32(SSPINT129_STATUS, 0x2104)
>>> REG32(SSPINT130_EN, 0x2200)
>>> REG32(SSPINT130_STATUS, 0x2204)
>>> REG32(SSPINT131_EN, 0x2300)
>>> REG32(SSPINT131_STATUS, 0x2304)
>>> REG32(SSPINT132_EN, 0x2400)
>>> REG32(SSPINT132_STATUS, 0x2404)
>>> REG32(SSPINT133_EN, 0x2500)
>>> REG32(SSPINT133_STATUS, 0x2504)
>>> REG32(SSPINT134_EN, 0x2600)
>>> REG32(SSPINT134_STATUS, 0x2604)
>>> REG32(SSPINT135_EN, 0x2700)
>>> REG32(SSPINT135_STATUS, 0x2704)
>>> REG32(SSPINT136_EN, 0x2800)
>>> REG32(SSPINT136_STATUS, 0x2804)
>>> REG32(SSPINT137_EN, 0x2900)
>>> REG32(SSPINT137_STATUS, 0x2904)
>>> REG32(SSPINT138_EN, 0x2A00)
>>> REG32(SSPINT138_STATUS, 0x2A04)
>>> REG32(SSPINT160_169_EN, 0x2B00)
>>> REG32(SSPINT160_169_STATUS, 0x2B04)
>>>
>>>>
>>>>> + if (offset >= aic->reg_size) {
>>>>
>>>> This is dead code since the MMIO aperture has the same size. You
>>>> could remove the check.
>>>
>>> Will remove.
>>>>
>>>>> qemu_log_mask(LOG_GUEST_ERROR,
>>>>> "%s: Out-of-bounds read at offset 0x%"
>>>> HWADDR_PRIx "\n",
>>>>> __func__, offset); @@ -143,7 +144,7 @@
>>>> static
>>>>> void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
>>>>> uint32_t change;
>>>>> uint32_t irq;
>>>>>
>>>>> - if (addr >= ASPEED_INTC_NR_REGS) {
>>>>> + if (offset >= aic->reg_size) {
>>>>> qemu_log_mask(LOG_GUEST_ERROR,
>>>>> "%s: Out-of-bounds write at offset 0x%"
>>>> HWADDR_PRIx "\n",
>>>>> __func__, offset); @@ -302,10 +303,16
>> @@
>>>>> static void aspeed_intc_realize(DeviceState *dev, Error **errp)
>>>>> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
>>>>> int i;
>>>>>
>>>>> + memory_region_init(&s->iomem_container, OBJECT(s),
>>>>> + TYPE_ASPEED_INTC ".container", aic->mem_size);
>>>>> +
>>>>> + sysbus_init_mmio(sbd, &s->iomem_container);
>>>>
>>>> Why introduce a container ? Do you plan to have multiple sub-regions ?
>>>>
>>> I created a container to save the entire register address space of
>>> INTC and its sub-region to place the actual used register address space.
>>> 0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
>>> 0000000012100000-0000000012101fff (prio 0, i/o):
>>> aspeed.intc.regs 0000000014c18000-0000000014c183ff (prio 0, i/o):
>> aspeed.intc.container
>>> 0000000014c18000-0000000014c183d7 (prio 0, i/o):
>>> aspeed.intc.regs
>>>
>>> If I misunderstood this design, I will change it to have two memory regions
>> for INTC and INTCIO, respectively.
>>> If need, I will change to the following memory regions. --> it removes
>> containers.
>>> 0000000012100000-0000000012101fff (prio 0, i/o):
>> aspeed.intc.regs
>>> 0000000014c18000-0000000014c183d7 (prio 0, i/o):
>>> aspeed.intc.regs
>>
>> I don't think the region container is useful in that case since there is only a
>> single region per model.
>>
>> However, we could "optimize" a bit the MMIO apertures to avoid mapping
>> huge unused gaps and only map the useful set of registers :
>>
>> INTC Registers [ 0x1000 - 0x1B04 ]
>> SSP INTC Registers [ 0x2000 - 0x2B04 ]
>> INTCIO Registers [ 0x0100 - 0x0154 ]
>>
>> Each set would be associated with a subregion which would be mapped at the
>> right offset in the region container.
>>
>> This is just a suggestion.
>>
>
> I followed your suggestion to reduce the size of the register array. Here's what I've done:
>
> 0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
> 0000000012101000-0000000012101b07 (prio 0, i/o): aspeed.intc.regs
>
> A solution:
> 1. I created an INTC Register sub-region mapped at offset 0x1000 with a size of 0xb08.
> This change adjusted the following register offsets to their original values minus 0x1000:
>
> REG32(GICINT128_EN, 0x000)
> REG32(GICINT128_STATUS, 0x004)
> REG32(GICINT129_EN, 0x100)
> REG32(GICINT129_STATUS, 0x104)
> REG32(GICINT130_EN, 0x200)
> REG32(GICINT130_STATUS, 0x204)
> REG32(GICINT131_EN, 0x300)
> REG32(GICINT131_STATUS, 0x304)
> REG32(GICINT132_EN, 0x400)
> REG32(GICINT132_STATUS, 0x404)
> REG32(GICINT133_EN, 0x500)
> REG32(GICINT133_STATUS, 0x504)
> REG32(GICINT134_EN, 0x600)
> REG32(GICINT134_STATUS, 0x604)
> REG32(GICINT135_EN, 0x700)
> REG32(GICINT135_STATUS, 0x704)
> REG32(GICINT136_EN, 0x800)
> REG32(GICINT136_STATUS, 0x804)
> REG32(GICINT192_201_EN, 0xB00)
> REG32(GICINT192_201_STATUS, 0xB04)
>
> 2. To support multiple sub-regions, such as for SSP, I created a new sub-region mapped at offset 0x2000.
> This adjustment changed the register offsets to their original values minus 0x2000:
>
> /* SSP INTC Registers */
>> REG32(SSPINT128_EN, 0x000)
>> REG32(SSPINT128_STATUS, 0x004)
>> REG32(SSPINT129_EN, 0x100)
>> REG32(SSPINT129_STATUS, 0x104)
>> REG32(SSPINT130_EN, 0x200)
>> REG32(SSPINT130_STATUS, 0x204)
>> REG32(SSPINT131_EN, 0x300)
>> REG32(SSPINT131_STATUS, 0x304)
>> REG32(SSPINT132_EN, 0x400)
>> REG32(SSPINT132_STATUS, 0x404)
>> REG32(SSPINT133_EN, 0x500)
>> REG32(SSPINT133_STATUS, 0x504)
>> REG32(SSPINT134_EN, 0x600)
>> REG32(SSPINT134_STATUS, 0x604)
>> REG32(SSPINT135_EN, 0x700)
>> REG32(SSPINT135_STATUS, 0x704)
>> REG32(SSPINT136_EN, 0x800)
>> REG32(SSPINT136_STATUS, 0x804)
>> REG32(SSPINT137_EN, 0x900)
>> REG32(SSPINT137_STATUS, 0x904)
>> REG32(SSPINT138_EN, 0xA00)
>> REG32(SSPINT138_STATUS, 0xA04)
>> REG32(SSPINT160_169_EN, 0xB00)
>> REG32(SSPINT160_169_STATUS, 0xB04)
>
> Regarding handling identical offsets like SSPINT128_EN and GICINT128_EN, which both use offset 0x00,
> they currently share the same aspeed_intc_ops and IRQ handler functions like aspeed_intc_status_handler.
You need a MemoryRegionOps per region.
> How can I check whether the offset belongs to the SSP or INTC region?
> Can I create new aspeed_intc_ssp_write and aspeed_intc_ssp_read callback functions specifically for
> reading and writing to the SSP region, and then add new parameters to the IRQ handler to distinguish
> between the SSP and INTC regions?
I haven't looked at that part yet.
>
> B solution:
>
> There is another solution where we don't consider multiple sub-regions and only support a single sub-region.
> Since the SSP runs on a co-processor, we've created a new SSP class:
> static void aspeed_intc_register_types(void)
> {
> type_register_static(&aspeed_intc_info);
> type_register_static(&aspeed_2700_intc_info);
> type_register_static(&aspeed_2700_intcio_info);
> + type_register_static(&aspeed_2700_ssp_intc_info);
> + type_register_static(&aspeed_2700_ssp_intcio_info);
> }
>
> In this solution, we don’t need to make many changes because the SSP has its own AspeedINTCState register array.
> As a result, most functions can be reused to support SSP.
> The SSP uses the same callback function as the INTC:
>
> static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> unsigned size)
> {
> switch (addr) {
> case R_GICINT128_EN:
> case R_GICINT129_EN:
> case R_GICINT130_EN:
> case R_GICINT131_EN:
> case R_GICINT132_EN:
> case R_GICINT133_EN:
> case R_GICINT134_EN:
> case R_GICINT135_EN:
> case R_GICINT136_EN:
> case R_GICINT192_201_EN:
> + case R_SSPINT128_STATUS:
> + case R_SSPINT129_STATUS:
> + case R_SSPINT130_STATUS:
>
> Since both GICINT128_EN and SSPINT128_EN share the same offset of 0, I will modify the code to handle INT128 for both.
>
> Could you please give me any suggestion?
Please send a series.
As a reminder, soft-freeze is in less than 2 weeks. Please try to organize
the current series so that the more obvious ones can be merged easily.
Thanks,
C.
>
> Thanks-Jamin
>
>>
>> Thanks,
>>
>> C.
>>
>>
>>
>>> Do you expect the above memory regions for INTC?
>>>
>>> Thanks for your review and suggestion.
>>> Jamin
>>>>
>>>> Thanks,
>>>>
>>>> C.
>>>>
>>>>
>>>>
>>>>> +
>>>>> memory_region_init_io(&s->iomem, OBJECT(s),
>> &aspeed_intc_ops,
>>>> s,
>>>>> - TYPE_ASPEED_INTC ".regs",
>>>> ASPEED_INTC_NR_REGS << 2);
>>>>> + TYPE_ASPEED_INTC ".regs",
>> aic->reg_size);
>>>>> +
>>>>> + memory_region_add_subregion(&s->iomem_container, 0x0,
>>>> &s->iomem);
>>>>>
>>>>> - sysbus_init_mmio(sbd, &s->iomem);
>>>>> qdev_init_gpio_in(dev, aspeed_intc_set_irq, aic->num_ints);
>>>>>
>>>>> for (i = 0; i < aic->num_ints; i++) { @@ -344,6 +351,8 @@
>>>>> static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
>>>>> dc->desc = "ASPEED 2700 INTC Controller";
>>>>> aic->num_lines = 32;
>>>>> aic->num_ints = 9;
>>>>> + aic->mem_size = 0x4000;
>>>>> + aic->reg_size = 0x2000;
>>>>> }
>>>>>
>>>>> static const TypeInfo aspeed_2700_intc_info = { diff --git
>>>>> a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
>>>>> index 18cb43476c..ecaeb15aea 100644
>>>>> --- a/include/hw/intc/aspeed_intc.h
>>>>> +++ b/include/hw/intc/aspeed_intc.h
>>>>> @@ -25,6 +25,8 @@ struct AspeedINTCState {
>>>>>
>>>>> /*< public >*/
>>>>> MemoryRegion iomem;
>>>>> + MemoryRegion iomem_container;
>>>>> +
>>>>> uint32_t regs[ASPEED_INTC_NR_REGS];
>>>>> OrIRQState orgates[ASPEED_INTC_NR_INTS];
>>>>> qemu_irq output_pins[ASPEED_INTC_NR_INTS]; @@ -39,6 +41,8
>> @@
>>>>> struct AspeedINTCClass {
>>>>>
>>>>> uint32_t num_lines;
>>>>> uint32_t num_ints;
>>>>> + uint64_t mem_size;
>>>>> + uint64_t reg_size;
>>>>> };
>>>>>
>>>>> #endif /* ASPEED_INTC_H */
>>>
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700
2025-02-27 9:33 ` Cédric Le Goater
@ 2025-03-03 2:51 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-03-03 2:51 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Subject: Re: [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot
> be set in the SOC layer for AST2700
>
> Hello Jamin,
>
> On 2/26/25 07:38, Jamin Lin wrote:
> > Hi Cedric,
> >
> >>
> >> On 2/13/25 04:35, Jamin Lin wrote:
> >>> According to the design of the AST2600, it has a Silicon Revision ID
> >>> Register, specifically SCU004 and SCU014, to set the Revision ID for
> >>> the
> >> AST2600.
> >>> For the AST2600 A3, SCU004 is set to 0x05030303 and SCU014 is set to
> >> 0x05030303.
> >>> In the "aspeed_ast2600_scu_reset" function, the hardcoded value
> >>> "AST2600_A3_SILICON_REV" is set in SCU004, and "s->silicon_rev" is
> >>> set in SCU014. The value of "s->silicon_rev" is set by the SOC layer
> >>> via the "silicon-rev" property.
> >>>
> >>> However, the design of the AST2700 is different. There are two SCU
> >> controllers:
> >>> SCU0 (CPU Die) and SCU1 (IO Die). In the AST2700, the firmware reads
> >>> the SCU Silicon Revision ID register (SCU0_000) and the SCUIO
> >>> Silicon Revision ID register (SCU1_000) and combines them into a 64-bit
> value.
> >>> The combined value of SCU0_000[23:16] and SCU1_000[23:16] represents
> >>> the silicon revision. For example, the AST2700-A1 revision is
> >>> "0x0601010306010103", where
> >>> SCU0_000 should be 06010103 and SCU1_000 should be 06010103.
> >>
> >> Are both these values supposed to be identical ? if not, we should
> >> plan for changes at machine/SoC level too.
> >>
> >
> > Currently, these values are supposed to be identical. Therefore, we
> > can reuse the current design of the silicon_rev in the machine/SoC layer for
> AST2700.
> >
> >>> static const uint32_t
> >>> ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS]
> >> = {
> >>> - [AST2700_SILICON_REV] = AST2700_A0_SILICON_REV,
> >>> [AST2700_HW_STRAP1] = 0x00000800,
> >>> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> >>> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> >>> @@ -940,6 +939,7 @@ static void aspeed_ast2700_scu_reset(DeviceState
> >> *dev)
> >>> AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
> >>>
> >>> memcpy(s->regs, asc->resets, asc->nr_regs * 4);
> >>> + s->regs[AST2700_SILICON_REV] = s->silicon_rev;
> >>>
> >>> }
> >>>
> >>> static void aspeed_2700_scu_class_init(ObjectClass *klass, void
> >>> *data) @@ -1032,7 +1032,6 @@ static const MemoryRegionOps
> >> aspeed_ast2700_scuio_ops = {
> >>> };
> >>>
> >>> static const uint32_t
> >> ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
> >>> - [AST2700_SILICON_REV] = 0x06000003,
> >>> [AST2700_HW_STRAP1] = 0x00000504,
> >>
> >> why isn't AST2700_HW_STRAP1 assigned with s->hw_strap1 property ?
> >>
> >
> > This is a bug. The design of the HW_STRAP register has changed in the
> AST2700.
> > There is one hw_strap1 register in the SCU (CPU DIE) and another hw_strap1
> register in the SCUIO (IO DIE).
> > The values of these two hw_strap1 registers should not be the same.
> >
> > To fix this issue, I made the following changes. Do you have any suggestions?
>
> All Aspeed SoC models currently define "hw-strap1" and "hw-strap2"
> properties as aliases on the same properties of the SCU model :
>
> object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
> "hw-strap1");
> object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
> "hw-strap2");
>
> For the AST2700 SoC, you could change the "hw-strap2" alias to point to the
> SCUIO model :
>
> object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
> "hw-strap1");
> object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scuio),
> "hw-strap1");
>
Will fix it.
> > Additionally, would it be possible to submit a separate patch for the SCU
> silicon_rev and SCU hw_strap fix?
>
> yes we should please.
>
> > The patch series for supporting AST2700 A1 is quite large.
>
> yes. That's why I asked you to split it :)
>
> > Thanks-Jamin
> >
> > 1. I dumped the real values of both registers on the EVB
> >
> > root@ast2700-a0-default:~# md 14c02010 1 ----> SCUIO hw_strap1
> > 14c02010: 00000500
> > root@ast2700-a0-default:~# md 12c02010 1 --> SCU hw_strap1
> > 12c02010: 00000800
> >
> > The value AST2700_EVB_HW_STRAP1 0x00000800 is used for the SCU
> hw_strap1.
> > The value AST2700_EVB_HW_STRAP2 0x00000500 is used for the SCUIO
> > hw_strap1
> >
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -181,8 +181,8 @@ struct AspeedMachineState {
> >
> > #ifdef TARGET_AARCH64
> > /* AST2700 evb hardware value */
> > -#define AST2700_EVB_HW_STRAP1 0x000000C0 -#define
> > AST2700_EVB_HW_STRAP2 0x00000003
> > +#define AST2700_EVB_HW_STRAP1 0x00000800 #define
> > +AST2700_EVB_HW_STRAP2 0x00000500
> > #endif
> >
> > 2. Change to set hw_strap2 in the SCUIO model. Note this will modify the
> hw_strap1 register of the SCUIO.
> >
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -410,14 +410,14 @@ static void aspeed_soc_ast2700_init(Object *obj)
> > sc->silicon_rev);
> > object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
> > "hw-strap1");
> > - object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
> > - "hw-strap2");
> > object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
> > "hw-prot-key");
> >
> > object_initialize_child(obj, "scuio", &s->scuio,
> TYPE_ASPEED_2700_SCUIO);
> > qdev_prop_set_uint32(DEVICE(&s->scuio), "silicon-rev",
> > sc->silicon_rev);
> > + object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scuio),
> > + "hw-strap2");
>
> Why use "hw-strap2" and not "hw-strap1" ?
>
> Please add comments in the AST2700 SoC and AST2700 SCU models so that the
> information does not get lost.
>
Will add
> > 3. I introduced a new aspeed_ast2700_scuio_reset function for the
> > SCUIO model and set the value of the hw_strap2 property to the HW_STRAP1
> register of the SCUIO model.
> >
> > s->regs[AST2700_HW_STRAP1] = s->hw_strap2;
>
> That's weird. I would use s->hw_strap1.
>
Will fix
Thanks for suggestion and review.
Jamin
> Thanks,
>
> C.
>
>
> > diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index
> > 259b142850..23ab7526f5 100644
> > --- a/hw/misc/aspeed_scu.c
> > +++ b/hw/misc/aspeed_scu.c
> > @@ -912,7 +912,6 @@ static const MemoryRegionOps
> aspeed_ast2700_scu_ops = {
> > };
> >
> > static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS]
> = {
> > - [AST2700_HW_STRAP1] = 0x00000800,
> > [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> > [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> > [AST2700_HW_STRAP1_SEC1] = 0x000000FF,
> > @@ -942,6 +941,7 @@ static void aspeed_ast2700_scu_reset(DeviceState
> > *dev)
> >
> > memcpy(s->regs, asc->resets, asc->nr_regs * 4);
> > s->regs[AST2700_SILICON_REV] = s->silicon_rev;
> > + s->regs[AST2700_HW_STRAP1] = s->hw_strap1;
> > }
> >
> > static void aspeed_2700_scu_class_init(ObjectClass *klass, void
> > *data) @@ -1034,7 +1034,6 @@ static const MemoryRegionOps
> aspeed_ast2700_scuio_ops = {
> > };
> >
> > static const uint32_t
> ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
> > - [AST2700_HW_STRAP1] = 0x00000504,
> > [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> > [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> > [AST2700_HW_STRAP1_SEC1] = 0x000000FF,
> > @@ -1057,13 +1056,23 @@ static const uint32_t
> ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = {
> > [AST2700_SCUIO_CLK_DUTY_MEAS_RST] = 0x0c9100d2,
> > };
> >
> > +static void aspeed_ast2700_scuio_reset(DeviceState *dev) {
> > + AspeedSCUState *s = ASPEED_SCU(dev);
> > + AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
> > +
> > + memcpy(s->regs, asc->resets, asc->nr_regs * 4);
> > + s->regs[AST2700_SILICON_REV] = s->silicon_rev;
> > + s->regs[AST2700_HW_STRAP1] = s->hw_strap2; }
> > +
> > static void aspeed_2700_scuio_class_init(ObjectClass *klass, void *data)
> > {
> > DeviceClass *dc = DEVICE_CLASS(klass);
> > AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
> >
> > dc->desc = "ASPEED 2700 System Control Unit I/O";
> > - device_class_set_legacy_reset(dc, aspeed_ast2700_scu_reset);
> > + device_class_set_legacy_reset(dc, aspeed_ast2700_scuio_reset);
> > asc->resets = ast2700_a0_resets_io;
> > asc->calc_hpll = aspeed_2600_scu_calc_hpll;
> > asc->get_apb = aspeed_2700_scuio_get_apb_freq;
> >
> >
> >> The above changes could be merged as a fix.
> >>
> >> Thanks,
> >>
> >> C.
> >>
> >>
> >>> [AST2700_HW_STRAP1_CLR] = 0xFFF0FFF0,
> >>> [AST2700_HW_STRAP1_LOCK] = 0x00000FFF,
> >
^ permalink raw reply [flat|nested] 70+ messages in thread
* RE: [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size
2025-02-27 9:57 ` Cédric Le Goater
@ 2025-03-03 2:52 ` Jamin Lin
0 siblings, 0 replies; 70+ messages in thread
From: Jamin Lin @ 2025-03-03 2:52 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Andrew Jeffery, Joel Stanley, open list:All patches CC here,
open list:ASPEED BMCs
Cc: Troy Lee
Hi Cedric,
> Cc: Troy Lee <troy_lee@aspeedtech.com>
> Subject: Re: [PATCH v3 01/28] hw/intc/aspeed: Support setting different
> memory and register size
>
> On 2/26/25 04:40, Jamin Lin wrote:
> > Hi Cedric,
> >
> >>>> and the register array as:
> >>>>
> >>>> uint32_t regs[ASPEED_INTC_NR_REGS];
> >>>>
> >>>> The number of regs looks pretty big for me. Are the registers
> >>>> covering the whole MMIO aperture ?
> >>>>
> >>> According to the datasheet, the entire register address space size
> >>> of INTC (CPU DIE) is 16KB (0x12100000-0x12103FFF). Therefore, I set
> >>> the
> >> memory size to 0x4000.
> >>> Currently, we need to use the "GICINT192-201 raw status and clear"
> >>> register
> >> INTC1B04.
> >>> Thus, an array size of 0x2000 is sufficient.
> >>
> >> yes but we are only using these regs :
> >>
> >> REG32(GICINT128_EN, 0x1000)
> >> REG32(GICINT128_STATUS, 0x1004)
> >> REG32(GICINT129_EN, 0x1100)
> >> REG32(GICINT129_STATUS, 0x1104)
> >> REG32(GICINT130_EN, 0x1200)
> >> REG32(GICINT130_STATUS, 0x1204)
> >> REG32(GICINT131_EN, 0x1300)
> >> REG32(GICINT131_STATUS, 0x1304)
> >> REG32(GICINT132_EN, 0x1400)
> >> REG32(GICINT132_STATUS, 0x1404)
> >> REG32(GICINT133_EN, 0x1500)
> >> REG32(GICINT133_STATUS, 0x1504)
> >> REG32(GICINT134_EN, 0x1600)
> >> REG32(GICINT134_STATUS, 0x1604)
> >> REG32(GICINT135_EN, 0x1700)
> >> REG32(GICINT135_STATUS, 0x1704)
> >> REG32(GICINT136_EN, 0x1800)
> >> REG32(GICINT136_STATUS, 0x1804)
> >> REG32(GICINT192_201_EN, 0x1B00)
> >> REG32(GICINT192_201_STATUS, 0x1B04)
> >>
> >> so the first 0x1000 are unused.
> >>
> >>
> >>>
> >>> However, we are going to increase the size to 0x3000 to support the
> >>> co-processors SSP and TSP In the another patch series.
> >>> We also need to include the following register definitions:
> >>>
> >>> /* SSP INTC Registers */
> >>> REG32(SSPINT128_EN, 0x2000)
> >>> REG32(SSPINT128_STATUS, 0x2004)
> >>> REG32(SSPINT129_EN, 0x2100)
> >>> REG32(SSPINT129_STATUS, 0x2104)
> >>> REG32(SSPINT130_EN, 0x2200)
> >>> REG32(SSPINT130_STATUS, 0x2204)
> >>> REG32(SSPINT131_EN, 0x2300)
> >>> REG32(SSPINT131_STATUS, 0x2304)
> >>> REG32(SSPINT132_EN, 0x2400)
> >>> REG32(SSPINT132_STATUS, 0x2404)
> >>> REG32(SSPINT133_EN, 0x2500)
> >>> REG32(SSPINT133_STATUS, 0x2504)
> >>> REG32(SSPINT134_EN, 0x2600)
> >>> REG32(SSPINT134_STATUS, 0x2604)
> >>> REG32(SSPINT135_EN, 0x2700)
> >>> REG32(SSPINT135_STATUS, 0x2704)
> >>> REG32(SSPINT136_EN, 0x2800)
> >>> REG32(SSPINT136_STATUS, 0x2804)
> >>> REG32(SSPINT137_EN, 0x2900)
> >>> REG32(SSPINT137_STATUS, 0x2904)
> >>> REG32(SSPINT138_EN, 0x2A00)
> >>> REG32(SSPINT138_STATUS, 0x2A04)
> >>> REG32(SSPINT160_169_EN, 0x2B00)
> >>> REG32(SSPINT160_169_STATUS, 0x2B04)
> >>>
> >>>>
> >>>>> + if (offset >= aic->reg_size) {
> >>>>
> >>>> This is dead code since the MMIO aperture has the same size. You
> >>>> could remove the check.
> >>>
> >>> Will remove.
> >>>>
> >>>>> qemu_log_mask(LOG_GUEST_ERROR,
> >>>>> "%s: Out-of-bounds read at offset 0x%"
> >>>> HWADDR_PRIx "\n",
> >>>>> __func__, offset); @@ -143,7 +144,7
> @@
> >>>> static
> >>>>> void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> >>>>> uint32_t change;
> >>>>> uint32_t irq;
> >>>>>
> >>>>> - if (addr >= ASPEED_INTC_NR_REGS) {
> >>>>> + if (offset >= aic->reg_size) {
> >>>>> qemu_log_mask(LOG_GUEST_ERROR,
> >>>>> "%s: Out-of-bounds write at offset 0x%"
> >>>> HWADDR_PRIx "\n",
> >>>>> __func__, offset); @@ -302,10 +303,16
> >> @@
> >>>>> static void aspeed_intc_realize(DeviceState *dev, Error **errp)
> >>>>> AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
> >>>>> int i;
> >>>>>
> >>>>> + memory_region_init(&s->iomem_container, OBJECT(s),
> >>>>> + TYPE_ASPEED_INTC ".container", aic->mem_size);
> >>>>> +
> >>>>> + sysbus_init_mmio(sbd, &s->iomem_container);
> >>>>
> >>>> Why introduce a container ? Do you plan to have multiple sub-regions ?
> >>>>
> >>> I created a container to save the entire register address space of
> >>> INTC and its sub-region to place the actual used register address space.
> >>> 0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
> >>> 0000000012100000-0000000012101fff (prio 0, i/o):
> >>> aspeed.intc.regs 0000000014c18000-0000000014c183ff (prio 0, i/o):
> >> aspeed.intc.container
> >>> 0000000014c18000-0000000014c183d7 (prio 0, i/o):
> >>> aspeed.intc.regs
> >>>
> >>> If I misunderstood this design, I will change it to have two memory
> >>> regions
> >> for INTC and INTCIO, respectively.
> >>> If need, I will change to the following memory regions. --> it
> >>> removes
> >> containers.
> >>> 0000000012100000-0000000012101fff (prio 0, i/o):
> >> aspeed.intc.regs
> >>> 0000000014c18000-0000000014c183d7 (prio 0, i/o):
> >>> aspeed.intc.regs
> >>
> >> I don't think the region container is useful in that case since there
> >> is only a single region per model.
> >>
> >> However, we could "optimize" a bit the MMIO apertures to avoid
> >> mapping huge unused gaps and only map the useful set of registers :
> >>
> >> INTC Registers [ 0x1000 - 0x1B04 ]
> >> SSP INTC Registers [ 0x2000 - 0x2B04 ]
> >> INTCIO Registers [ 0x0100 - 0x0154 ]
> >>
> >> Each set would be associated with a subregion which would be mapped
> >> at the right offset in the region container.
> >>
> >> This is just a suggestion.
> >>
> >
> > I followed your suggestion to reduce the size of the register array. Here's
> what I've done:
> >
> > 0000000012100000-0000000012103fff (prio 0, i/o): aspeed.intc.container
> > 0000000012101000-0000000012101b07 (prio 0, i/o):
> > aspeed.intc.regs
> >
> > A solution:
> > 1. I created an INTC Register sub-region mapped at offset 0x1000 with a size
> of 0xb08.
> > This change adjusted the following register offsets to their original values
> minus 0x1000:
> >
> > REG32(GICINT128_EN, 0x000)
> > REG32(GICINT128_STATUS, 0x004)
> > REG32(GICINT129_EN, 0x100)
> > REG32(GICINT129_STATUS, 0x104)
> > REG32(GICINT130_EN, 0x200)
> > REG32(GICINT130_STATUS, 0x204)
> > REG32(GICINT131_EN, 0x300)
> > REG32(GICINT131_STATUS, 0x304)
> > REG32(GICINT132_EN, 0x400)
> > REG32(GICINT132_STATUS, 0x404)
> > REG32(GICINT133_EN, 0x500)
> > REG32(GICINT133_STATUS, 0x504)
> > REG32(GICINT134_EN, 0x600)
> > REG32(GICINT134_STATUS, 0x604)
> > REG32(GICINT135_EN, 0x700)
> > REG32(GICINT135_STATUS, 0x704)
> > REG32(GICINT136_EN, 0x800)
> > REG32(GICINT136_STATUS, 0x804)
> > REG32(GICINT192_201_EN, 0xB00)
> > REG32(GICINT192_201_STATUS, 0xB04)
> >
> > 2. To support multiple sub-regions, such as for SSP, I created a new
> sub-region mapped at offset 0x2000.
> > This adjustment changed the register offsets to their original values minus
> 0x2000:
> >
> > /* SSP INTC Registers */
> >> REG32(SSPINT128_EN, 0x000)
> >> REG32(SSPINT128_STATUS, 0x004)
> >> REG32(SSPINT129_EN, 0x100)
> >> REG32(SSPINT129_STATUS, 0x104)
> >> REG32(SSPINT130_EN, 0x200)
> >> REG32(SSPINT130_STATUS, 0x204)
> >> REG32(SSPINT131_EN, 0x300)
> >> REG32(SSPINT131_STATUS, 0x304)
> >> REG32(SSPINT132_EN, 0x400)
> >> REG32(SSPINT132_STATUS, 0x404)
> >> REG32(SSPINT133_EN, 0x500)
> >> REG32(SSPINT133_STATUS, 0x504)
> >> REG32(SSPINT134_EN, 0x600)
> >> REG32(SSPINT134_STATUS, 0x604)
> >> REG32(SSPINT135_EN, 0x700)
> >> REG32(SSPINT135_STATUS, 0x704)
> >> REG32(SSPINT136_EN, 0x800)
> >> REG32(SSPINT136_STATUS, 0x804)
> >> REG32(SSPINT137_EN, 0x900)
> >> REG32(SSPINT137_STATUS, 0x904)
> >> REG32(SSPINT138_EN, 0xA00)
> >> REG32(SSPINT138_STATUS, 0xA04)
> >> REG32(SSPINT160_169_EN, 0xB00)
> >> REG32(SSPINT160_169_STATUS, 0xB04)
> >
> > Regarding handling identical offsets like SSPINT128_EN and
> > GICINT128_EN, which both use offset 0x00, they currently share the same
> aspeed_intc_ops and IRQ handler functions like aspeed_intc_status_handler.
>
> You need a MemoryRegionOps per region.
>
Got it. Thanks for your suggestion.
> > How can I check whether the offset belongs to the SSP or INTC region?
> > Can I create new aspeed_intc_ssp_write and aspeed_intc_ssp_read
> > callback functions specifically for reading and writing to the SSP
> > region, and then add new parameters to the IRQ handler to distinguish
> between the SSP and INTC regions?
>
> I haven't looked at that part yet.
>
> >
> > B solution:
> >
> > There is another solution where we don't consider multiple sub-regions and
> only support a single sub-region.
> > Since the SSP runs on a co-processor, we've created a new SSP class:
> > static void aspeed_intc_register_types(void) {
> > type_register_static(&aspeed_intc_info);
> > type_register_static(&aspeed_2700_intc_info);
> > type_register_static(&aspeed_2700_intcio_info);
> > + type_register_static(&aspeed_2700_ssp_intc_info);
> > + type_register_static(&aspeed_2700_ssp_intcio_info);
> > }
> >
> > In this solution, we don’t need to make many changes because the SSP has
> its own AspeedINTCState register array.
> > As a result, most functions can be reused to support SSP.
> > The SSP uses the same callback function as the INTC:
> >
> > static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
> > unsigned size) {
> > switch (addr) {
> > case R_GICINT128_EN:
> > case R_GICINT129_EN:
> > case R_GICINT130_EN:
> > case R_GICINT131_EN:
> > case R_GICINT132_EN:
> > case R_GICINT133_EN:
> > case R_GICINT134_EN:
> > case R_GICINT135_EN:
> > case R_GICINT136_EN:
> > case R_GICINT192_201_EN:
> > + case R_SSPINT128_STATUS:
> > + case R_SSPINT129_STATUS:
> > + case R_SSPINT130_STATUS:
> >
> > Since both GICINT128_EN and SSPINT128_EN share the same offset of 0, I
> will modify the code to handle INT128 for both.
> >
> > Could you please give me any suggestion?
>
> Please send a series.
>
> As a reminder, soft-freeze is in less than 2 weeks. Please try to organize the
> current series so that the more obvious ones can be merged easily.
>
Got it.
I will send patch as soon as possible.
Jamin
>
> Thanks,
>
> C.
>
>
> >
> > Thanks-Jamin
> >
> >>
> >> Thanks,
> >>
> >> C.
> >>
> >>
> >>
> >>> Do you expect the above memory regions for INTC?
> >>>
> >>> Thanks for your review and suggestion.
> >>> Jamin
> >>>>
> >>>> Thanks,
> >>>>
> >>>> C.
> >>>>
> >>>>
> >>>>
> >>>>> +
> >>>>> memory_region_init_io(&s->iomem, OBJECT(s),
> >> &aspeed_intc_ops,
> >>>> s,
> >>>>> - TYPE_ASPEED_INTC ".regs",
> >>>> ASPEED_INTC_NR_REGS << 2);
> >>>>> + TYPE_ASPEED_INTC ".regs",
> >> aic->reg_size);
> >>>>> +
> >>>>> + memory_region_add_subregion(&s->iomem_container, 0x0,
> >>>> &s->iomem);
> >>>>>
> >>>>> - sysbus_init_mmio(sbd, &s->iomem);
> >>>>> qdev_init_gpio_in(dev, aspeed_intc_set_irq,
> >>>>> aic->num_ints);
> >>>>>
> >>>>> for (i = 0; i < aic->num_ints; i++) { @@ -344,6 +351,8 @@
> >>>>> static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
> >>>>> dc->desc = "ASPEED 2700 INTC Controller";
> >>>>> aic->num_lines = 32;
> >>>>> aic->num_ints = 9;
> >>>>> + aic->mem_size = 0x4000;
> >>>>> + aic->reg_size = 0x2000;
> >>>>> }
> >>>>>
> >>>>> static const TypeInfo aspeed_2700_intc_info = { diff --git
> >>>>> a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
> >>>>> index 18cb43476c..ecaeb15aea 100644
> >>>>> --- a/include/hw/intc/aspeed_intc.h
> >>>>> +++ b/include/hw/intc/aspeed_intc.h
> >>>>> @@ -25,6 +25,8 @@ struct AspeedINTCState {
> >>>>>
> >>>>> /*< public >*/
> >>>>> MemoryRegion iomem;
> >>>>> + MemoryRegion iomem_container;
> >>>>> +
> >>>>> uint32_t regs[ASPEED_INTC_NR_REGS];
> >>>>> OrIRQState orgates[ASPEED_INTC_NR_INTS];
> >>>>> qemu_irq output_pins[ASPEED_INTC_NR_INTS]; @@ -39,6
> +41,8
> >> @@
> >>>>> struct AspeedINTCClass {
> >>>>>
> >>>>> uint32_t num_lines;
> >>>>> uint32_t num_ints;
> >>>>> + uint64_t mem_size;
> >>>>> + uint64_t reg_size;
> >>>>> };
> >>>>>
> >>>>> #endif /* ASPEED_INTC_H */
> >>>
> >
^ permalink raw reply [flat|nested] 70+ messages in thread
end of thread, other threads:[~2025-03-03 2:52 UTC | newest]
Thread overview: 70+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-13 3:35 [PATCH v3 00/28] Support AST2700 A1 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 01/28] hw/intc/aspeed: Support setting different memory and register size Jamin Lin via
2025-02-18 5:33 ` Cédric Le Goater
2025-02-20 5:45 ` Jamin Lin
2025-02-21 15:15 ` Cédric Le Goater
2025-02-26 3:40 ` Jamin Lin
2025-02-27 9:57 ` Cédric Le Goater
2025-03-03 2:52 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 02/28] hw/intc/aspeed: Introduce helper functions for enable and status registers Jamin Lin via
2025-02-18 5:36 ` Cédric Le Goater
2025-02-20 3:24 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 03/28] hw/intc/aspeed: Add object type name to trace events for better debugging Jamin Lin via
2025-02-18 5:43 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 04/28] hw/arm/aspeed: Rename IRQ table and machine name for AST2700 A0 Jamin Lin via
2025-02-18 5:47 ` Cédric Le Goater
2025-02-21 2:23 ` Jamin Lin
2025-02-21 14:04 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 05/28] hw/arm/aspeed_ast27x0: Sort the IRQ table by IRQ number Jamin Lin via
2025-02-18 5:48 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 06/28] hw/intc/aspeed: Support different memory region ops Jamin Lin via
2025-02-18 5:48 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 07/28] hw/intc/aspeed: Rename num_ints to num_inpins for clarity Jamin Lin via
2025-02-18 5:49 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 08/28] hw/intc/aspeed: Add support for multiple output pins in INTC Jamin Lin via
2025-02-18 5:53 ` Cédric Le Goater
2025-02-21 1:31 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 09/28] hw/intc/aspeed: Refactor INTC to support separate input and output pin indices Jamin Lin via
2025-02-18 6:20 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 10/28] hw/intc/aspeed: Introduce AspeedINTCIRQ structure to save the irq index and register address Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 11/28] hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication Jamin Lin via
2025-02-18 9:17 ` Cédric Le Goater
2025-02-20 3:14 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 12/28] hw/intc/aspeed: Add Support for Multi-Output IRQ Handling Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 13/28] hw/intc/aspeed: Add Support for AST2700 INTCIO Controller Jamin Lin via
2025-02-18 9:15 ` Cédric Le Goater
2025-02-20 5:57 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 14/28] hw/misc/aspeed_scu: Add Support for AST2700/AST2750 A1 Silicon Revisions Jamin Lin via
2025-02-18 6:35 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 15/28] hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2700 Jamin Lin via
2025-02-18 6:47 ` Cédric Le Goater
2025-02-26 6:38 ` Jamin Lin
2025-02-27 9:33 ` Cédric Le Goater
2025-03-03 2:51 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 16/28] hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 17/28] hw/arm/aspeed_ast27x0: Support two levels of INTC controllers for AST2700 A1 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 18/28] hw/arm/aspeed: Add SoC and Machine Support " Jamin Lin via
2025-02-18 6:49 ` Cédric Le Goater
2025-02-21 1:37 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 19/28] hw/misc/aspeed_hace: Fix coding style Jamin Lin via
2025-02-18 6:21 ` Cédric Le Goater
2025-02-13 3:35 ` [PATCH v3 20/28] hw/misc/aspeed_hace: Add AST2700 support Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 21/28] hw/misc/aspeed_hace: Fix boot issue in the Crypto Manager Self Test Jamin Lin via
2025-02-18 6:26 ` Cédric Le Goater
2025-02-21 5:43 ` Jamin Lin
2025-02-21 6:55 ` Jamin Lin
2025-02-21 13:53 ` Cédric Le Goater
2025-02-24 5:10 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 22/28] hw/arm/aspeed_ast27x0: Add HACE support for AST2700 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 23/28] test/functional/aspeed: Introduce new function to fetch assets Jamin Lin via
2025-02-18 6:30 ` Cédric Le Goater
2025-02-21 1:35 ` Jamin Lin
2025-02-13 3:35 ` [PATCH v3 24/28] tests/functional/aspeed: Introduce start_ast2700_test API and update hwmon path Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 25/28] tests/functional/aspeed: Update test ASPEED SDK v09.05 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 26/28] tests/functional/aspeed: Renamed test case and machine for AST2700 A0 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 27/28] tests/functional/aspeed: Add test case for AST2700 A1 Jamin Lin via
2025-02-13 3:35 ` [PATCH v3 28/28] docs/specs: add aspeed-intc Jamin Lin via
2025-02-18 9:25 ` [PATCH v3 00/28] Support AST2700 A1 Cédric Le Goater
2025-02-20 5:11 ` Jamin Lin
2025-02-21 17:24 ` Cédric Le Goater
2025-02-25 8:02 ` Jamin Lin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).