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.
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)