diff options
Diffstat (limited to 'hw/misc')
| -rw-r--r-- | hw/misc/aspeed_hace.c | 55 | ||||
| -rw-r--r-- | hw/misc/aspeed_scu.c | 10 |
2 files changed, 57 insertions, 8 deletions
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index e3f7df2e86..32a5dbded3 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 @@ -75,9 +76,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 +205,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; @@ -339,6 +344,15 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data, qemu_irq_lower(s->irq); } } + if (ahc->raise_crypt_interrupt_workaround) { + 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; @@ -384,6 +398,12 @@ 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__); + if (ahc->raise_crypt_interrupt_workaround) { + s->regs[R_STATUS] |= CRYPT_IRQ; + if (data & CRYPT_IRQ_EN) { + qemu_irq_raise(s->irq); + } + } break; default: break; @@ -548,12 +568,39 @@ 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; + + /* + * 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. + */ + ahc->raise_crypt_interrupt_workaround = true; +} + +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/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index bac1441b06..76cfd91671 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -157,6 +157,7 @@ #define AST2700_SCU_FREQ_CNTR TO_REG(0x3b0) #define AST2700_SCU_CPU_SCRATCH_0 TO_REG(0x780) #define AST2700_SCU_CPU_SCRATCH_1 TO_REG(0x784) +#define AST2700_SCU_VGA_SCRATCH_0 TO_REG(0x900) #define AST2700_SCUIO_CLK_STOP_CTL_1 TO_REG(0x240) #define AST2700_SCUIO_CLK_STOP_CLR_1 TO_REG(0x244) @@ -559,6 +560,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) @@ -909,8 +912,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, [AST2700_HW_STRAP1_SEC1] = 0x000000FF, @@ -930,6 +931,7 @@ static const uint32_t ast2700_a0_resets[ASPEED_AST2700_SCU_NR_REGS] = { [AST2700_SCU_FREQ_CNTR] = 0x000375eb, [AST2700_SCU_CPU_SCRATCH_0] = 0x00000000, [AST2700_SCU_CPU_SCRATCH_1] = 0x00000004, + [AST2700_SCU_VGA_SCRATCH_0] = 0x00000040, }; static void aspeed_ast2700_scu_reset(DeviceState *dev) @@ -938,6 +940,8 @@ 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; + s->regs[AST2700_HW_STRAP1] = s->hw_strap1; } static void aspeed_2700_scu_class_init(ObjectClass *klass, void *data) @@ -1030,8 +1034,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, [AST2700_HW_STRAP1_SEC1] = 0x000000FF, |