diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index 5eb6680da9..7d9fade68d 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -50,8 +50,10 @@ struct Ast2700FCState { #define AST2700FC_BMC_RAM_SIZE (2 * GiB) -#define AST2700FC_HW_STRAP1 0x000000C0 -#define AST2700FC_HW_STRAP2 0x00000003 +/* SCU HW Strap1 */ +#define AST2700FC_HW_STRAP1 0x00000800 +/* SCUIO HW Strap1 */ +#define AST2700FC_HW_STRAP2 0x00000700 #define AST2700FC_FMC_MODEL "w25q01jvq" #define AST2700FC_SPI_MODEL "w25q512jv" diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index b3c4eb1915..68a8ab26f7 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -22,11 +22,14 @@ static const hwaddr aspeed_soc_ast27x0ssp_memmap[] = { [ASPEED_DEV_SDRAM] = 0x00000000, [ASPEED_DEV_SRAM0] = 0x70000000, [ASPEED_DEV_INTC] = 0x72100000, + [ASPEED_DEV_PRIC0] = 0x72140000, [ASPEED_DEV_SCU] = 0x72C02000, [ASPEED_DEV_TIMER1] = 0x72C10000, [ASPEED_DEV_UART4] = 0x72C1A000, [ASPEED_DEV_IPC0] = 0x72C1C000, + [ASPEED_DEV_PRIC1] = 0x74100000, [ASPEED_DEV_SCUIO] = 0x74C02000, + [ASPEED_DEV_OTP] = 0x74C07000, [ASPEED_DEV_INTCIO] = 0x74C18000, [ASPEED_DEV_UART0] = 0x74C33000, [ASPEED_DEV_UART1] = 0x74C33100, @@ -141,6 +144,12 @@ static void aspeed_soc_ast27x0ssp_init(Object *obj) TYPE_UNIMPLEMENTED_DEVICE); object_initialize_child(obj, "scuio", &a->scuio, TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "pric0", &a->pric[0], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "pric1", &a->pric[1], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "otp", &a->otp, + TYPE_UNIMPLEMENTED_DEVICE); } static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) @@ -255,6 +264,15 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->scuio), "aspeed.scuio", sc->memmap[ASPEED_DEV_SCUIO], 0x1000); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->pric[0]), + "aspeed.pric0", + sc->memmap[ASPEED_DEV_PRIC0], 0x1000); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->pric[1]), + "aspeed.pric1", + sc->memmap[ASPEED_DEV_PRIC1], 0x1000); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->otp), + "aspeed.otp", + sc->memmap[ASPEED_DEV_OTP], 0x800); } static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass, diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index 6098d1aae3..b8a4f7c91d 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -22,11 +22,14 @@ static const hwaddr aspeed_soc_ast27x0tsp_memmap[] = { [ASPEED_DEV_SDRAM] = 0x00000000, [ASPEED_DEV_SRAM0] = 0x70000000, [ASPEED_DEV_INTC] = 0x72100000, + [ASPEED_DEV_PRIC0] = 0x72140000, [ASPEED_DEV_SCU] = 0x72C02000, [ASPEED_DEV_TIMER1] = 0x72C10000, [ASPEED_DEV_UART4] = 0x72C1A000, [ASPEED_DEV_IPC0] = 0x72C1C000, + [ASPEED_DEV_PRIC1] = 0x74100000, [ASPEED_DEV_SCUIO] = 0x74C02000, + [ASPEED_DEV_OTP] = 0x74C07000, [ASPEED_DEV_INTCIO] = 0x74C18000, [ASPEED_DEV_UART0] = 0x74C33000, [ASPEED_DEV_UART1] = 0x74C33100, @@ -141,6 +144,12 @@ static void aspeed_soc_ast27x0tsp_init(Object *obj) TYPE_UNIMPLEMENTED_DEVICE); object_initialize_child(obj, "scuio", &a->scuio, TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "pric0", &a->pric[0], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "pric1", &a->pric[1], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "otp", &a->otp, + TYPE_UNIMPLEMENTED_DEVICE); } static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) @@ -255,6 +264,15 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->scuio), "aspeed.scuio", sc->memmap[ASPEED_DEV_SCUIO], 0x1000); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->pric[0]), + "aspeed.pric0", + sc->memmap[ASPEED_DEV_PRIC0], 0x1000); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->pric[1]), + "aspeed.pric1", + sc->memmap[ASPEED_DEV_PRIC1], 0x1000); + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->otp), + "aspeed.otp", + sc->memmap[ASPEED_DEV_OTP], 0x800); } static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass, diff --git a/hw/gpio/pca9552.c b/hw/gpio/pca9552.c index 472d8ad957..b13ac9fd9c 100644 --- a/hw/gpio/pca9552.c +++ b/hw/gpio/pca9552.c @@ -311,8 +311,8 @@ static void pca955x_get_led(Object *obj, Visitor *v, const char *name, error_setg(errp, "%s: error reading %s", __func__, name); return; } - if (led < 0 || led > k->pin_count) { - error_setg(errp, "%s invalid led %s", __func__, name); + if (led < 0 || led >= k->pin_count) { + error_setg(errp, "%s: invalid led %s", __func__, name); return; } /* @@ -352,8 +352,8 @@ static void pca955x_set_led(Object *obj, Visitor *v, const char *name, error_setg(errp, "%s: error reading %s", __func__, name); return; } - if (led < 0 || led > k->pin_count) { - error_setg(errp, "%s invalid led %s", __func__, name); + if (led < 0 || led >= k->pin_count) { + error_setg(errp, "%s: invalid led %s", __func__, name); return; } diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index 5a36fff520..ab80c239bc 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -107,6 +107,27 @@ static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic, g_assert_not_reached(); } +static uint32_t aspeed_intc_orgate_levels(AspeedINTCState *s, int inpin_idx) +{ + AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s); + uint32_t levels = 0; + int i; + + for (i = 0; i < aic->num_lines && i < 32; i++) { + if (s->orgates[inpin_idx].levels[i]) { + levels |= BIT(i); + } + } + + return levels; +} + +static void aspeed_intc_drop_stale_pending(AspeedINTCState *s, int inpin_idx) +{ + s->pending[inpin_idx] &= aspeed_intc_orgate_levels(s, inpin_idx) & + s->enable[inpin_idx]; +} + /* * Update the state of an interrupt controller pin by setting * the specified output pin to the given level. @@ -231,6 +252,8 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level) trace_aspeed_intc_set_irq(name, inpin_idx, level); enable = s->enable[inpin_idx]; + aspeed_intc_drop_stale_pending(s, inpin_idx); + if (!level) { return; } @@ -343,6 +366,7 @@ static void aspeed_intc_status_handler(AspeedINTCState *s, hwaddr offset, /* All source ISR execution are done */ if (!s->regs[reg]) { trace_aspeed_intc_all_isr_done(name, inpin_idx); + aspeed_intc_drop_stale_pending(s, inpin_idx); if (s->pending[inpin_idx]) { /* * handle pending source interrupt @@ -402,6 +426,7 @@ static void aspeed_intc_status_handler_multi_outpins(AspeedINTCState *s, /* All source ISR executions are done from a specific bit */ if (data & BIT(i)) { trace_aspeed_intc_all_isr_done_bit(name, inpin_idx, i); + aspeed_intc_drop_stale_pending(s, inpin_idx); if (s->pending[inpin_idx] & BIT(i)) { /* * Handle pending source interrupt. diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index fe731a28bd..5dbf81c0ce 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -160,6 +160,11 @@ #define AST2700_SCU_CPU_SCRATCH_1 TO_REG(0x784) #define AST2700_SCU_VGA_SCRATCH_0 TO_REG(0x900) +#define AST2700_SCUIO_RNG_CTRL TO_REG(0xF0) +#define AST2700_SCUIO_RNG_CTRL_MASK 0x2F +#define AST2700_SCUIO_RNG_CTRL_DIS BIT(0) +#define AST2700_SCUIO_RNG_CTRL_VLD BIT(31) +#define AST2700_SCUIO_RNG_DATA TO_REG(0xF4) #define AST2700_SCUIO_CLK_STOP_CTL_1 TO_REG(0x240) #define AST2700_SCUIO_CLK_STOP_CLR_1 TO_REG(0x244) #define AST2700_SCUIO_CLK_STOP_CTL_2 TO_REG(0x260) @@ -849,13 +854,6 @@ static uint64_t aspeed_ast2700_scu_read(void *opaque, hwaddr offset, return 0; } - switch (reg) { - default: - qemu_log_mask(LOG_GUEST_ERROR, - "%s: Unhandled read at offset 0x%" HWADDR_PRIx "\n", - __func__, offset); - } - trace_aspeed_ast2700_scu_read(offset, size, s->regs[reg]); return s->regs[reg]; } @@ -962,10 +960,11 @@ static uint64_t aspeed_ast2700_scuio_read(void *opaque, hwaddr offset, } switch (reg) { - default: - qemu_log_mask(LOG_GUEST_ERROR, - "%s: Unhandled read at offset 0x%" HWADDR_PRIx "\n", - __func__, offset); + case AST2700_SCUIO_RNG_DATA: + if (!(s->regs[AST2700_SCUIO_RNG_CTRL] & AST2700_SCUIO_RNG_CTRL_DIS)) { + s->regs[AST2700_SCUIO_RNG_DATA] = aspeed_scu_get_random(); + } + break; } trace_aspeed_ast2700_scuio_read(offset, size, s->regs[reg]); @@ -991,6 +990,18 @@ static void aspeed_ast2700_scuio_write(void *opaque, hwaddr offset, trace_aspeed_ast2700_scuio_write(offset, size, data); switch (reg) { + case AST2700_SCUIO_RNG_CTRL: + data &= AST2700_SCUIO_RNG_CTRL_MASK; + if (data & AST2700_SCUIO_RNG_CTRL_DIS) { + data &= ~AST2700_SCUIO_RNG_CTRL_VLD; + s->regs[AST2700_SCUIO_RNG_DATA] = 0; + } else { + s->regs[AST2700_SCUIO_RNG_DATA] = aspeed_scu_get_random(); + data |= AST2700_SCUIO_RNG_CTRL_VLD; + } + s->regs[reg] = data; + updated = true; + break; case AST2700_SCUIO_CLK_STOP_CTL_1: case AST2700_SCUIO_CLK_STOP_CTL_2: s->regs[reg] |= data; diff --git a/include/hw/arm/aspeed_coprocessor.h b/include/hw/arm/aspeed_coprocessor.h index 4a50f688ec..ac58a5f424 100644 --- a/include/hw/arm/aspeed_coprocessor.h +++ b/include/hw/arm/aspeed_coprocessor.h @@ -48,6 +48,8 @@ struct Aspeed27x0CoprocessorState { AspeedINTCState intc[2]; UnimplementedDeviceState ipc[2]; UnimplementedDeviceState scuio; + UnimplementedDeviceState pric[2]; + UnimplementedDeviceState otp; ARMv7MState armv7m; }; diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 3aac144cd4..41dc04e293 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -295,6 +295,9 @@ enum { ASPEED_DEV_IOEXP1_INTCIO, ASPEED_DEV_IOEXP0_I3C, ASPEED_DEV_IOEXP1_I3C, + ASPEED_DEV_PRIC0, + ASPEED_DEV_PRIC1, + ASPEED_DEV_OTP, }; const char *aspeed_soc_cpu_type(const char * const *valid_cpu_types);