aspeed queue:
* New AST1030 SoC and eval board * Accumulative mode support for HACE controller * GPIO fix and unit test * Clock modeling adjustments for the AST2600 * Dummy eMMC Boot Controller model * Change of AST2500 EVB and AST2600 EVB flash model (for quad IO) -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmJwwq8ACgkQUaNDx8/7 7KF0IhAApbCCcg06PR66pmaDBFY2RWmU0XShDoCEeHyT5huQFcAJWNoqVAJ52E8L ZCPEeORQthxMwmtw7JLIGCFhDx4P4YzfNZRPANRosKs7BR0GequVgHp7c6fXhD/3 A3w42hfuNR4Hrbsil/yhN2vxFAYXudA+NPez2ibex3UyVc/ZUu71nCqZTxh3wZdN XQTuqxWerA5RRBRtVn8n/aBp+3mo5enD4dx44KWMZxKxJaFJfZQHVZttGHU9azF+ fXJ1lmrJZ7eHmWjCEvgnHXwl0nWiMwkLZ9/MKOAPkdjUG1JciGRxbJki0bGuS7Jr NzOyO0f++ZtOsuLGA03WiwR1oo3GmG7lBFqBcdzMwN2EMvDvVvJUp3v8IdV/L10P OJ10rBi6FDJuKGHJGIQywlFSYYjPb+DgNEWId2rugVVm4dR02Cn69amuL40OO9by /C7hO9gSvRTqSSdjFcdkbI2h+kx0354F2/gR2LFLBh1KUHulTJ4ErthrKBiuNPC8 tsELzYVnxWVT+nc30Nmidg3uCW3/5zBlaj0qlL4aiFjKR5na6Wpz+oE/aNiNdyT3 IBI+J5zvbtn/prNTWLW1TCuGdwj357LfYfkfkH8eqZWfX5vGq+5hVTc/m8EW5Cx8 yV8JrbjX8uDI379skdl4imtedbKZhPLd7csM/zrorsJhBBwSoLA= =+hIh -----END PGP SIGNATURE----- Merge tag 'pull-aspeed-20220503' of https://github.com/legoater/qemu into staging aspeed queue: * New AST1030 SoC and eval board * Accumulative mode support for HACE controller * GPIO fix and unit test * Clock modeling adjustments for the AST2600 * Dummy eMMC Boot Controller model * Change of AST2500 EVB and AST2600 EVB flash model (for quad IO) # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmJwwq8ACgkQUaNDx8/7 # 7KF0IhAApbCCcg06PR66pmaDBFY2RWmU0XShDoCEeHyT5huQFcAJWNoqVAJ52E8L # ZCPEeORQthxMwmtw7JLIGCFhDx4P4YzfNZRPANRosKs7BR0GequVgHp7c6fXhD/3 # A3w42hfuNR4Hrbsil/yhN2vxFAYXudA+NPez2ibex3UyVc/ZUu71nCqZTxh3wZdN # XQTuqxWerA5RRBRtVn8n/aBp+3mo5enD4dx44KWMZxKxJaFJfZQHVZttGHU9azF+ # fXJ1lmrJZ7eHmWjCEvgnHXwl0nWiMwkLZ9/MKOAPkdjUG1JciGRxbJki0bGuS7Jr # NzOyO0f++ZtOsuLGA03WiwR1oo3GmG7lBFqBcdzMwN2EMvDvVvJUp3v8IdV/L10P # OJ10rBi6FDJuKGHJGIQywlFSYYjPb+DgNEWId2rugVVm4dR02Cn69amuL40OO9by # /C7hO9gSvRTqSSdjFcdkbI2h+kx0354F2/gR2LFLBh1KUHulTJ4ErthrKBiuNPC8 # tsELzYVnxWVT+nc30Nmidg3uCW3/5zBlaj0qlL4aiFjKR5na6Wpz+oE/aNiNdyT3 # IBI+J5zvbtn/prNTWLW1TCuGdwj357LfYfkfkH8eqZWfX5vGq+5hVTc/m8EW5Cx8 # yV8JrbjX8uDI379skdl4imtedbKZhPLd7csM/zrorsJhBBwSoLA= # =+hIh # -----END PGP SIGNATURE----- # gpg: Signature made Mon 02 May 2022 10:50:39 PM PDT # gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1 # gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1 * tag 'pull-aspeed-20220503' of https://github.com/legoater/qemu: aspeed/hace: Support AST1030 HACE hw/gpio/aspeed_gpio: Fix QOM pin property tests/qtest: Add test for Aspeed HACE accumulative mode aspeed/hace: Support AST2600 HACE aspeed/hace: Support HMAC Key Buffer register. hw/arm/aspeed: fix AST2500/AST2600 EVB fmc model test/avocado/machine_aspeed.py: Add ast1030 test case aspeed: Add an AST1030 eval board aspeed/soc : Add AST1030 support aspeed/scu: Add AST1030 support aspeed/timer: Add AST1030 support aspeed/wdt: Add AST1030 support aspeed/wdt: Fix ast2500/ast2600 default reload value aspeed/smc: Add AST1030 support aspeed/adc: Add AST1030 support aspeed: Add eMMC Boot Controller stub aspeed: sbc: Correct default reset values hw: aspeed_scu: Introduce clkin_25Mhz attribute hw: aspeed_scu: Add AST2600 apb_freq and hpll calculation function Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
5f14cfe187
@ -389,6 +389,15 @@ static void aspeed_2600_adc_class_init(ObjectClass *klass, void *data)
|
||||
aac->nr_engines = 2;
|
||||
}
|
||||
|
||||
static void aspeed_1030_adc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedADCClass *aac = ASPEED_ADC_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 1030 ADC Controller";
|
||||
aac->nr_engines = 2;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_adc_info = {
|
||||
.name = TYPE_ASPEED_ADC,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
@ -415,6 +424,12 @@ static const TypeInfo aspeed_2600_adc_info = {
|
||||
.class_init = aspeed_2600_adc_class_init,
|
||||
};
|
||||
|
||||
static const TypeInfo aspeed_1030_adc_info = {
|
||||
.name = TYPE_ASPEED_1030_ADC,
|
||||
.parent = TYPE_ASPEED_ADC,
|
||||
.class_init = aspeed_1030_adc_class_init, /* No change since AST2600 */
|
||||
};
|
||||
|
||||
static void aspeed_adc_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_adc_engine_info);
|
||||
@ -422,6 +437,7 @@ static void aspeed_adc_register_types(void)
|
||||
type_register_static(&aspeed_2400_adc_info);
|
||||
type_register_static(&aspeed_2500_adc_info);
|
||||
type_register_static(&aspeed_2600_adc_info);
|
||||
type_register_static(&aspeed_1030_adc_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_adc_register_types);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "hw/loader.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/units.h"
|
||||
#include "hw/qdev-clock.h"
|
||||
|
||||
static struct arm_boot_info aspeed_board_binfo = {
|
||||
.board_id = -1, /* device-tree-only board */
|
||||
@ -1092,7 +1093,7 @@ static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
|
||||
mc->desc = "Aspeed AST2500 EVB (ARM1176)";
|
||||
amc->soc_name = "ast2500-a1";
|
||||
amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
|
||||
amc->fmc_model = "w25q256";
|
||||
amc->fmc_model = "mx25l25635e";
|
||||
amc->spi_model = "mx25l25635e";
|
||||
amc->num_cs = 1;
|
||||
amc->i2c_init = ast2500_evb_i2c_init;
|
||||
@ -1161,7 +1162,7 @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
|
||||
amc->soc_name = "ast2600-a3";
|
||||
amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
|
||||
amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
|
||||
amc->fmc_model = "w25q512jv";
|
||||
amc->fmc_model = "mx66u51235f";
|
||||
amc->spi_model = "mx66u51235f";
|
||||
amc->num_cs = 1;
|
||||
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON |
|
||||
@ -1292,6 +1293,67 @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
|
||||
aspeed_soc_num_cpus(amc->soc_name);
|
||||
}
|
||||
|
||||
#define AST1030_INTERNAL_FLASH_SIZE (1024 * 1024)
|
||||
/* Main SYSCLK frequency in Hz (200MHz) */
|
||||
#define SYSCLK_FRQ 200000000ULL
|
||||
|
||||
static void aspeed_minibmc_machine_init(MachineState *machine)
|
||||
{
|
||||
AspeedMachineState *bmc = ASPEED_MACHINE(machine);
|
||||
AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
|
||||
Clock *sysclk;
|
||||
|
||||
sysclk = clock_new(OBJECT(machine), "SYSCLK");
|
||||
clock_set_hz(sysclk, SYSCLK_FRQ);
|
||||
|
||||
object_initialize_child(OBJECT(machine), "soc", &bmc->soc, amc->soc_name);
|
||||
qdev_connect_clock_in(DEVICE(&bmc->soc), "sysclk", sysclk);
|
||||
|
||||
qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
|
||||
amc->uart_default);
|
||||
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
|
||||
|
||||
aspeed_board_init_flashes(&bmc->soc.fmc,
|
||||
bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
|
||||
amc->num_cs,
|
||||
0);
|
||||
|
||||
aspeed_board_init_flashes(&bmc->soc.spi[0],
|
||||
bmc->spi_model ? bmc->spi_model : amc->spi_model,
|
||||
amc->num_cs, amc->num_cs);
|
||||
|
||||
aspeed_board_init_flashes(&bmc->soc.spi[1],
|
||||
bmc->spi_model ? bmc->spi_model : amc->spi_model,
|
||||
amc->num_cs, (amc->num_cs * 2));
|
||||
|
||||
if (amc->i2c_init) {
|
||||
amc->i2c_init(bmc);
|
||||
}
|
||||
|
||||
armv7m_load_kernel(ARM_CPU(first_cpu),
|
||||
machine->kernel_filename,
|
||||
AST1030_INTERNAL_FLASH_SIZE);
|
||||
}
|
||||
|
||||
static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
|
||||
void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
|
||||
|
||||
mc->desc = "Aspeed AST1030 MiniBMC (Cortex-M4)";
|
||||
amc->soc_name = "ast1030-a1";
|
||||
amc->hw_strap1 = 0;
|
||||
amc->hw_strap2 = 0;
|
||||
mc->init = aspeed_minibmc_machine_init;
|
||||
mc->default_ram_size = 0;
|
||||
mc->default_cpus = mc->min_cpus = mc->max_cpus = 1;
|
||||
amc->fmc_model = "sst25vf032b";
|
||||
amc->spi_model = "sst25vf032b";
|
||||
amc->num_cs = 2;
|
||||
amc->macs_mask = 0;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_machine_types[] = {
|
||||
{
|
||||
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
|
||||
@ -1349,6 +1411,10 @@ static const TypeInfo aspeed_machine_types[] = {
|
||||
.name = MACHINE_TYPE_NAME("bletchley-bmc"),
|
||||
.parent = TYPE_ASPEED_MACHINE,
|
||||
.class_init = aspeed_machine_bletchley_class_init,
|
||||
}, {
|
||||
.name = MACHINE_TYPE_NAME("ast1030-evb"),
|
||||
.parent = TYPE_ASPEED_MACHINE,
|
||||
.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
|
||||
}, {
|
||||
.name = TYPE_ASPEED_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
|
299
hw/arm/aspeed_ast10x0.c
Normal file
299
hw/arm/aspeed_ast10x0.c
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* ASPEED Ast10x0 SoC
|
||||
*
|
||||
* Copyright (C) 2022 ASPEED Technology Inc.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*
|
||||
* Implementation extracted from the AST2600 and adapted for Ast10x0.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/qdev-clock.h"
|
||||
#include "hw/misc/unimp.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/arm/aspeed_soc.h"
|
||||
|
||||
#define ASPEED_SOC_IOMEM_SIZE 0x00200000
|
||||
|
||||
static const hwaddr aspeed_soc_ast1030_memmap[] = {
|
||||
[ASPEED_DEV_SRAM] = 0x00000000,
|
||||
[ASPEED_DEV_SBC] = 0x79000000,
|
||||
[ASPEED_DEV_IOMEM] = 0x7E600000,
|
||||
[ASPEED_DEV_PWM] = 0x7E610000,
|
||||
[ASPEED_DEV_FMC] = 0x7E620000,
|
||||
[ASPEED_DEV_SPI1] = 0x7E630000,
|
||||
[ASPEED_DEV_SPI2] = 0x7E640000,
|
||||
[ASPEED_DEV_SCU] = 0x7E6E2000,
|
||||
[ASPEED_DEV_ADC] = 0x7E6E9000,
|
||||
[ASPEED_DEV_SBC] = 0x7E6F2000,
|
||||
[ASPEED_DEV_GPIO] = 0x7E780000,
|
||||
[ASPEED_DEV_TIMER1] = 0x7E782000,
|
||||
[ASPEED_DEV_UART5] = 0x7E784000,
|
||||
[ASPEED_DEV_WDT] = 0x7E785000,
|
||||
[ASPEED_DEV_LPC] = 0x7E789000,
|
||||
[ASPEED_DEV_I2C] = 0x7E7B0000,
|
||||
};
|
||||
|
||||
static const int aspeed_soc_ast1030_irqmap[] = {
|
||||
[ASPEED_DEV_UART5] = 8,
|
||||
[ASPEED_DEV_GPIO] = 11,
|
||||
[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_WDT] = 24,
|
||||
[ASPEED_DEV_LPC] = 35,
|
||||
[ASPEED_DEV_FMC] = 39,
|
||||
[ASPEED_DEV_PWM] = 44,
|
||||
[ASPEED_DEV_ADC] = 46,
|
||||
[ASPEED_DEV_SPI1] = 65,
|
||||
[ASPEED_DEV_SPI2] = 66,
|
||||
[ASPEED_DEV_I2C] = 110, /* 110 ~ 123 */
|
||||
[ASPEED_DEV_KCS] = 138, /* 138 -> 142 */
|
||||
};
|
||||
|
||||
static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
|
||||
{
|
||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||
|
||||
return qdev_get_gpio_in(DEVICE(&s->armv7m), sc->irqmap[ctrl]);
|
||||
}
|
||||
|
||||
static void aspeed_soc_ast1030_init(Object *obj)
|
||||
{
|
||||
AspeedSoCState *s = ASPEED_SOC(obj);
|
||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||
char socname[8];
|
||||
char typename[64];
|
||||
int i;
|
||||
|
||||
if (sscanf(sc->name, "%7s", socname) != 1) {
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
object_initialize_child(obj, "armv7m", &s->armv7m, TYPE_ARMV7M);
|
||||
|
||||
s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname);
|
||||
object_initialize_child(obj, "scu", &s->scu, typename);
|
||||
qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 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");
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
|
||||
object_initialize_child(obj, "timerctrl", &s->timerctrl, typename);
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname);
|
||||
object_initialize_child(obj, "adc", &s->adc, typename);
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
|
||||
object_initialize_child(obj, "fmc", &s->fmc, typename);
|
||||
|
||||
for (i = 0; i < sc->spis_num; i++) {
|
||||
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
|
||||
object_initialize_child(obj, "spi[*]", &s->spi[i], typename);
|
||||
}
|
||||
|
||||
object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
|
||||
|
||||
object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
|
||||
|
||||
for (i = 0; i < sc->wdts_num; i++) {
|
||||
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
|
||||
object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename);
|
||||
}
|
||||
}
|
||||
|
||||
static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
|
||||
{
|
||||
AspeedSoCState *s = ASPEED_SOC(dev_soc);
|
||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||
MemoryRegion *system_memory = get_system_memory();
|
||||
DeviceState *armv7m;
|
||||
Error *err = NULL;
|
||||
int i;
|
||||
|
||||
if (!clock_has_source(s->sysclk)) {
|
||||
error_setg(errp, "sysclk clock must be wired up by the board code");
|
||||
return;
|
||||
}
|
||||
|
||||
/* General I/O memory space to catch all unimplemented device */
|
||||
create_unimplemented_device("aspeed.sbc",
|
||||
sc->memmap[ASPEED_DEV_SBC],
|
||||
0x40000);
|
||||
create_unimplemented_device("aspeed.io",
|
||||
sc->memmap[ASPEED_DEV_IOMEM],
|
||||
ASPEED_SOC_IOMEM_SIZE);
|
||||
|
||||
/* AST1030 CPU Core */
|
||||
armv7m = DEVICE(&s->armv7m);
|
||||
qdev_prop_set_uint32(armv7m, "num-irq", 256);
|
||||
qdev_prop_set_string(armv7m, "cpu-type", sc->cpu_type);
|
||||
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
|
||||
object_property_set_link(OBJECT(&s->armv7m), "memory",
|
||||
OBJECT(system_memory), &error_abort);
|
||||
sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), &error_abort);
|
||||
|
||||
/* Internal SRAM */
|
||||
memory_region_init_ram(&s->sram, NULL, "aspeed.sram", sc->sram_size, &err);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
memory_region_add_subregion(system_memory,
|
||||
sc->memmap[ASPEED_DEV_SRAM],
|
||||
&s->sram);
|
||||
|
||||
/* SCU */
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
|
||||
|
||||
/* LPC */
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
|
||||
|
||||
/* Connect the LPC IRQ to the GIC. It is otherwise unused. */
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
|
||||
|
||||
/*
|
||||
* On the AST1030 LPC subdevice IRQs are connected straight to the GIC.
|
||||
*/
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1,
|
||||
qdev_get_gpio_in(DEVICE(&s->armv7m),
|
||||
sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_1));
|
||||
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2,
|
||||
qdev_get_gpio_in(DEVICE(&s->armv7m),
|
||||
sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_2));
|
||||
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3,
|
||||
qdev_get_gpio_in(DEVICE(&s->armv7m),
|
||||
sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_3));
|
||||
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4,
|
||||
qdev_get_gpio_in(DEVICE(&s->armv7m),
|
||||
sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4));
|
||||
|
||||
/* UART5 - attach an 8250 to the IO space as our UART */
|
||||
serial_mm_init(get_system_memory(), sc->memmap[ASPEED_DEV_UART5], 2,
|
||||
aspeed_soc_get_irq(s, ASPEED_DEV_UART5),
|
||||
38400, serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
||||
|
||||
/* Timer */
|
||||
object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu),
|
||||
&error_abort);
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0,
|
||||
sc->memmap[ASPEED_DEV_TIMER1]);
|
||||
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
|
||||
qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
|
||||
}
|
||||
|
||||
/* ADC */
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
|
||||
|
||||
/* FMC, The number of CS is set at the board level */
|
||||
object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(&s->sram),
|
||||
&error_abort);
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
|
||||
ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
|
||||
|
||||
/* SPI */
|
||||
for (i = 0; i < sc->spis_num; i++) {
|
||||
object_property_set_link(OBJECT(&s->spi[i]), "dram",
|
||||
OBJECT(&s->sram), &error_abort);
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
|
||||
sc->memmap[ASPEED_DEV_SPI1 + i]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
|
||||
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
|
||||
}
|
||||
|
||||
/* Secure Boot Controller */
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sbc), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sbc), 0, sc->memmap[ASPEED_DEV_SBC]);
|
||||
|
||||
/* Watch dog */
|
||||
for (i = 0; i < sc->wdts_num; i++) {
|
||||
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
|
||||
|
||||
object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu),
|
||||
&error_abort);
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
|
||||
sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSoCClass *sc = ASPEED_SOC_CLASS(dc);
|
||||
|
||||
dc->realize = aspeed_soc_ast1030_realize;
|
||||
|
||||
sc->name = "ast1030-a1";
|
||||
sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
|
||||
sc->silicon_rev = AST1030_A1_SILICON_REV;
|
||||
sc->sram_size = 0xc0000;
|
||||
sc->spis_num = 2;
|
||||
sc->ehcis_num = 0;
|
||||
sc->wdts_num = 4;
|
||||
sc->macs_num = 1;
|
||||
sc->irqmap = aspeed_soc_ast1030_irqmap;
|
||||
sc->memmap = aspeed_soc_ast1030_memmap;
|
||||
sc->num_cpus = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_soc_ast1030_type_info = {
|
||||
.name = "ast1030-a1",
|
||||
.parent = TYPE_ASPEED_SOC,
|
||||
.instance_size = sizeof(AspeedSoCState),
|
||||
.instance_init = aspeed_soc_ast1030_init,
|
||||
.class_init = aspeed_soc_ast1030_class_init,
|
||||
.class_size = sizeof(AspeedSoCClass),
|
||||
};
|
||||
|
||||
static void aspeed_soc_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_soc_ast1030_type_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_soc_register_types)
|
@ -48,6 +48,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
|
||||
[ASPEED_DEV_ADC] = 0x1E6E9000,
|
||||
[ASPEED_DEV_DP] = 0x1E6EB000,
|
||||
[ASPEED_DEV_SBC] = 0x1E6F2000,
|
||||
[ASPEED_DEV_EMMC_BC] = 0x1E6f5000,
|
||||
[ASPEED_DEV_VIDEO] = 0x1E700000,
|
||||
[ASPEED_DEV_SDHCI] = 0x1E740000,
|
||||
[ASPEED_DEV_EMMC] = 0x1E750000,
|
||||
@ -257,6 +258,11 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
|
||||
create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO],
|
||||
0x1000);
|
||||
|
||||
/* eMMC Boot Controller stub */
|
||||
create_unimplemented_device("aspeed.emmc-boot-controller",
|
||||
sc->memmap[ASPEED_DEV_EMMC_BC],
|
||||
0x1000);
|
||||
|
||||
/* CPU */
|
||||
for (i = 0; i < sc->num_cpus; i++) {
|
||||
if (sc->num_cpus > 1) {
|
||||
|
@ -47,7 +47,11 @@ arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-ver
|
||||
arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c'))
|
||||
arm_ss.add(when: 'CONFIG_FSL_IMX31', if_true: files('fsl-imx31.c', 'kzm.c'))
|
||||
arm_ss.add(when: 'CONFIG_FSL_IMX6', if_true: files('fsl-imx6.c'))
|
||||
arm_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_soc.c', 'aspeed.c', 'aspeed_ast2600.c'))
|
||||
arm_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
|
||||
'aspeed_soc.c',
|
||||
'aspeed.c',
|
||||
'aspeed_ast2600.c',
|
||||
'aspeed_ast10x0.c'))
|
||||
arm_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2.c'))
|
||||
arm_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2-tz.c'))
|
||||
arm_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-soc.c'))
|
||||
|
@ -312,7 +312,7 @@ static void aspeed_gpio_set_pin_level(AspeedGPIOState *s, uint32_t set_idx,
|
||||
if (level) {
|
||||
value |= pin_mask;
|
||||
} else {
|
||||
value &= !pin_mask;
|
||||
value &= ~pin_mask;
|
||||
}
|
||||
|
||||
aspeed_gpio_update(s, &s->sets[set_idx], value);
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#define R_HASH_SRC (0x20 / 4)
|
||||
#define R_HASH_DEST (0x24 / 4)
|
||||
#define R_HASH_KEY_BUFF (0x28 / 4)
|
||||
#define R_HASH_SRC_LEN (0x2c / 4)
|
||||
|
||||
#define R_HASH_CMD (0x30 / 4)
|
||||
@ -64,7 +65,6 @@
|
||||
#define SG_LIST_ADDR_SIZE 4
|
||||
#define SG_LIST_ADDR_MASK 0x7FFFFFFF
|
||||
#define SG_LIST_ENTRY_SIZE (SG_LIST_LEN_SIZE + SG_LIST_ADDR_SIZE)
|
||||
#define ASPEED_HACE_MAX_SG 256 /* max number of entries */
|
||||
|
||||
static const struct {
|
||||
uint32_t mask;
|
||||
@ -94,11 +94,104 @@ static int hash_algo_lookup(uint32_t reg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode)
|
||||
/**
|
||||
* Check whether the request contains padding message.
|
||||
*
|
||||
* @param s aspeed hace state object
|
||||
* @param iov iov of current request
|
||||
* @param req_len length of the current request
|
||||
* @param total_msg_len length of all acc_mode requests(excluding padding msg)
|
||||
* @param pad_offset start offset of padding message
|
||||
*/
|
||||
static bool has_padding(AspeedHACEState *s, struct iovec *iov,
|
||||
hwaddr req_len, uint32_t *total_msg_len,
|
||||
uint32_t *pad_offset)
|
||||
{
|
||||
*total_msg_len = (uint32_t)(ldq_be_p(iov->iov_base + req_len - 8) / 8);
|
||||
/*
|
||||
* SG_LIST_LEN_LAST asserted in the request length doesn't mean it is the
|
||||
* last request. The last request should contain padding message.
|
||||
* We check whether message contains padding by
|
||||
* 1. Get total message length. If the current message contains
|
||||
* padding, the last 8 bytes are total message length.
|
||||
* 2. Check whether the total message length is valid.
|
||||
* If it is valid, the value should less than or equal to
|
||||
* total_req_len.
|
||||
* 3. Current request len - padding_size to get padding offset.
|
||||
* The padding message's first byte should be 0x80
|
||||
*/
|
||||
if (*total_msg_len <= s->total_req_len) {
|
||||
uint32_t padding_size = s->total_req_len - *total_msg_len;
|
||||
uint8_t *padding = iov->iov_base;
|
||||
*pad_offset = req_len - padding_size;
|
||||
if (padding[*pad_offset] == 0x80) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id,
|
||||
uint32_t *pad_offset)
|
||||
{
|
||||
int i, iov_count;
|
||||
if (*pad_offset != 0) {
|
||||
s->iov_cache[s->iov_count].iov_base = iov[id].iov_base;
|
||||
s->iov_cache[s->iov_count].iov_len = *pad_offset;
|
||||
++s->iov_count;
|
||||
}
|
||||
for (i = 0; i < s->iov_count; i++) {
|
||||
iov[i].iov_base = s->iov_cache[i].iov_base;
|
||||
iov[i].iov_len = s->iov_cache[i].iov_len;
|
||||
}
|
||||
iov_count = s->iov_count;
|
||||
s->iov_count = 0;
|
||||
s->total_req_len = 0;
|
||||
return iov_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate iov for accumulative mode.
|
||||
*
|
||||
* @param s aspeed hace state object
|
||||
* @param iov iov of the current request
|
||||
* @param id index of the current iov
|
||||
* @param req_len length of the current request
|
||||
*
|
||||
* @return count of iov
|
||||
*/
|
||||
static int gen_acc_mode_iov(AspeedHACEState *s, struct iovec *iov, int id,
|
||||
hwaddr *req_len)
|
||||
{
|
||||
uint32_t pad_offset;
|
||||
uint32_t total_msg_len;
|
||||
s->total_req_len += *req_len;
|
||||
|
||||
if (has_padding(s, &iov[id], *req_len, &total_msg_len, &pad_offset)) {
|
||||
if (s->iov_count) {
|
||||
return reconstruct_iov(s, iov, id, &pad_offset);
|
||||
}
|
||||
|
||||
*req_len -= s->total_req_len - total_msg_len;
|
||||
s->total_req_len = 0;
|
||||
iov[id].iov_len = *req_len;
|
||||
} else {
|
||||
s->iov_cache[s->iov_count].iov_base = iov->iov_base;
|
||||
s->iov_cache[s->iov_count].iov_len = *req_len;
|
||||
++s->iov_count;
|
||||
}
|
||||
|
||||
return id + 1;
|
||||
}
|
||||
|
||||
static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
|
||||
bool acc_mode)
|
||||
{
|
||||
struct iovec iov[ASPEED_HACE_MAX_SG];
|
||||
g_autofree uint8_t *digest_buf;
|
||||
size_t digest_len = 0;
|
||||
int niov = 0;
|
||||
int i;
|
||||
|
||||
if (sg_mode) {
|
||||
@ -123,10 +216,16 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode)
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
addr &= SG_LIST_ADDR_MASK;
|
||||
|
||||
iov[i].iov_len = len & SG_LIST_LEN_MASK;
|
||||
plen = iov[i].iov_len;
|
||||
plen = len & SG_LIST_LEN_MASK;
|
||||
iov[i].iov_base = address_space_map(&s->dram_as, addr, &plen, false,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
|
||||
if (acc_mode) {
|
||||
niov = gen_acc_mode_iov(s, iov, i, &plen);
|
||||
|
||||
} else {
|
||||
iov[i].iov_len = plen;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hwaddr len = s->regs[R_HASH_SRC_LEN];
|
||||
@ -136,6 +235,25 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode)
|
||||
&len, false,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
i = 1;
|
||||
|
||||
if (s->iov_count) {
|
||||
/*
|
||||
* In aspeed sdk kernel driver, sg_mode is disabled in hash_final().
|
||||
* Thus if we received a request with sg_mode disabled, it is
|
||||
* required to check whether cache is empty. If no, we should
|
||||
* combine cached iov and the current iov.
|
||||
*/
|
||||
uint32_t total_msg_len;
|
||||
uint32_t pad_offset;
|
||||
s->total_req_len += len;
|
||||
if (has_padding(s, iov, len, &total_msg_len, &pad_offset)) {
|
||||
niov = reconstruct_iov(s, iov, 0, &pad_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (niov) {
|
||||
i = niov;
|
||||
}
|
||||
|
||||
if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf, &digest_len, NULL) < 0) {
|
||||
@ -210,6 +328,9 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
case R_HASH_DEST:
|
||||
data &= ahc->dest_mask;
|
||||
break;
|
||||
case R_HASH_KEY_BUFF:
|
||||
data &= ahc->key_mask;
|
||||
break;
|
||||
case R_HASH_SRC_LEN:
|
||||
data &= 0x0FFFFFFF;
|
||||
break;
|
||||
@ -234,7 +355,8 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
__func__, data & ahc->hash_mask);
|
||||
break;
|
||||
}
|
||||
do_hash_operation(s, algo, data & HASH_SG_EN);
|
||||
do_hash_operation(s, algo, data & HASH_SG_EN,
|
||||
((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM));
|
||||
|
||||
if (data & HASH_IRQ_EN) {
|
||||
qemu_irq_raise(s->irq);
|
||||
@ -267,6 +389,8 @@ static void aspeed_hace_reset(DeviceState *dev)
|
||||
struct AspeedHACEState *s = ASPEED_HACE(dev);
|
||||
|
||||
memset(s->regs, 0, sizeof(s->regs));
|
||||
s->iov_count = 0;
|
||||
s->total_req_len = 0;
|
||||
}
|
||||
|
||||
static void aspeed_hace_realize(DeviceState *dev, Error **errp)
|
||||
@ -302,6 +426,8 @@ static const VMStateDescription vmstate_aspeed_hace = {
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, AspeedHACEState, ASPEED_HACE_NR_REGS),
|
||||
VMSTATE_UINT32(total_req_len, AspeedHACEState),
|
||||
VMSTATE_UINT32(iov_count, AspeedHACEState),
|
||||
VMSTATE_END_OF_LIST(),
|
||||
}
|
||||
};
|
||||
@ -333,6 +459,7 @@ static void aspeed_ast2400_hace_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
ahc->src_mask = 0x0FFFFFFF;
|
||||
ahc->dest_mask = 0x0FFFFFF8;
|
||||
ahc->key_mask = 0x0FFFFFC0;
|
||||
ahc->hash_mask = 0x000003ff; /* No SG or SHA512 modes */
|
||||
}
|
||||
|
||||
@ -351,6 +478,7 @@ static void aspeed_ast2500_hace_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
ahc->src_mask = 0x3fffffff;
|
||||
ahc->dest_mask = 0x3ffffff8;
|
||||
ahc->key_mask = 0x3FFFFFC0;
|
||||
ahc->hash_mask = 0x000003ff; /* No SG or SHA512 modes */
|
||||
}
|
||||
|
||||
@ -369,6 +497,7 @@ static void aspeed_ast2600_hace_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
ahc->src_mask = 0x7FFFFFFF;
|
||||
ahc->dest_mask = 0x7FFFFFF8;
|
||||
ahc->key_mask = 0x7FFFFFF8;
|
||||
ahc->hash_mask = 0x00147FFF;
|
||||
}
|
||||
|
||||
@ -378,11 +507,31 @@ static const TypeInfo aspeed_ast2600_hace_info = {
|
||||
.class_init = aspeed_ast2600_hace_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_ast1030_hace_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass);
|
||||
|
||||
dc->desc = "AST1030 Hash and Crypto Engine";
|
||||
|
||||
ahc->src_mask = 0x7FFFFFFF;
|
||||
ahc->dest_mask = 0x7FFFFFF8;
|
||||
ahc->key_mask = 0x7FFFFFF8;
|
||||
ahc->hash_mask = 0x00147FFF;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_ast1030_hace_info = {
|
||||
.name = TYPE_ASPEED_AST1030_HACE,
|
||||
.parent = TYPE_ASPEED_HACE,
|
||||
.class_init = aspeed_ast1030_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_hace_info);
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#define R_PROT (0x000 / 4)
|
||||
#define R_STATUS (0x014 / 4)
|
||||
#define R_QSR (0x040 / 4)
|
||||
|
||||
static uint64_t aspeed_sbc_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
{
|
||||
@ -50,6 +51,7 @@ static void aspeed_sbc_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
|
||||
switch (addr) {
|
||||
case R_STATUS:
|
||||
case R_QSR:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: write to read only register 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr << 2);
|
||||
@ -77,8 +79,9 @@ static void aspeed_sbc_reset(DeviceState *dev)
|
||||
|
||||
memset(s->regs, 0, sizeof(s->regs));
|
||||
|
||||
/* Set secure boot enabled, and boot from emmc/spi */
|
||||
s->regs[R_STATUS] = 1 << 6 | 1 << 5;
|
||||
/* Set secure boot enabled with RSA4096_SHA256 and enable eMMC ABR */
|
||||
s->regs[R_STATUS] = 0x000044C6;
|
||||
s->regs[R_QSR] = 0x07C07C89;
|
||||
}
|
||||
|
||||
static void aspeed_sbc_realize(DeviceState *dev, Error **errp)
|
||||
|
@ -213,6 +213,11 @@ static uint32_t aspeed_scu_get_random(void)
|
||||
}
|
||||
|
||||
uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s)
|
||||
{
|
||||
return ASPEED_SCU_GET_CLASS(s)->get_apb(s);
|
||||
}
|
||||
|
||||
static uint32_t aspeed_2400_scu_get_apb_freq(AspeedSCUState *s)
|
||||
{
|
||||
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
|
||||
uint32_t hpll = asc->calc_hpll(s, s->regs[HPLL_PARAM]);
|
||||
@ -221,6 +226,24 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s)
|
||||
/ asc->apb_divider;
|
||||
}
|
||||
|
||||
static uint32_t aspeed_2600_scu_get_apb_freq(AspeedSCUState *s)
|
||||
{
|
||||
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
|
||||
uint32_t hpll = asc->calc_hpll(s, s->regs[AST2600_HPLL_PARAM]);
|
||||
|
||||
return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[AST2600_CLK_SEL]) + 1)
|
||||
/ asc->apb_divider;
|
||||
}
|
||||
|
||||
static uint32_t aspeed_1030_scu_get_apb_freq(AspeedSCUState *s)
|
||||
{
|
||||
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
|
||||
uint32_t hpll = asc->calc_hpll(s, s->regs[AST2600_HPLL_PARAM]);
|
||||
|
||||
return hpll / (SCU_AST1030_CLK_GET_PCLK_DIV(s->regs[AST2600_CLK_SEL4]) + 1)
|
||||
/ asc->apb_divider;
|
||||
}
|
||||
|
||||
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
@ -357,7 +380,8 @@ static const MemoryRegionOps aspeed_ast2500_scu_ops = {
|
||||
|
||||
static uint32_t aspeed_scu_get_clkin(AspeedSCUState *s)
|
||||
{
|
||||
if (s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN) {
|
||||
if (s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN ||
|
||||
ASPEED_SCU_GET_CLASS(s)->clkin_25Mhz) {
|
||||
return 25000000;
|
||||
} else if (s->hw_strap1 & SCU_HW_STRAP_CLK_48M_IN) {
|
||||
return 48000000;
|
||||
@ -426,6 +450,26 @@ static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
|
||||
return clkin * multiplier;
|
||||
}
|
||||
|
||||
static uint32_t aspeed_2600_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
|
||||
{
|
||||
uint32_t multiplier = 1;
|
||||
uint32_t clkin = aspeed_scu_get_clkin(s);
|
||||
|
||||
if (hpll_reg & SCU_AST2600_H_PLL_OFF) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(hpll_reg & SCU_AST2600_H_PLL_BYPASS_EN)) {
|
||||
uint32_t p = (hpll_reg >> 19) & 0xf;
|
||||
uint32_t n = (hpll_reg >> 13) & 0x3f;
|
||||
uint32_t m = hpll_reg & 0x1fff;
|
||||
|
||||
multiplier = ((m + 1) / (n + 1)) / (p + 1);
|
||||
}
|
||||
|
||||
return clkin * multiplier;
|
||||
}
|
||||
|
||||
static void aspeed_scu_reset(DeviceState *dev)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(dev);
|
||||
@ -447,6 +491,8 @@ static uint32_t aspeed_silicon_revs[] = {
|
||||
AST2600_A1_SILICON_REV,
|
||||
AST2600_A2_SILICON_REV,
|
||||
AST2600_A3_SILICON_REV,
|
||||
AST1030_A0_SILICON_REV,
|
||||
AST1030_A1_SILICON_REV,
|
||||
};
|
||||
|
||||
bool is_supported_silicon_rev(uint32_t silicon_rev)
|
||||
@ -525,8 +571,10 @@ static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
|
||||
dc->desc = "ASPEED 2400 System Control Unit";
|
||||
asc->resets = ast2400_a0_resets;
|
||||
asc->calc_hpll = aspeed_2400_scu_calc_hpll;
|
||||
asc->get_apb = aspeed_2400_scu_get_apb_freq;
|
||||
asc->apb_divider = 2;
|
||||
asc->nr_regs = ASPEED_SCU_NR_REGS;
|
||||
asc->clkin_25Mhz = false;
|
||||
asc->ops = &aspeed_ast2400_scu_ops;
|
||||
}
|
||||
|
||||
@ -545,8 +593,10 @@ static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
|
||||
dc->desc = "ASPEED 2500 System Control Unit";
|
||||
asc->resets = ast2500_a1_resets;
|
||||
asc->calc_hpll = aspeed_2500_scu_calc_hpll;
|
||||
asc->get_apb = aspeed_2400_scu_get_apb_freq;
|
||||
asc->apb_divider = 4;
|
||||
asc->nr_regs = ASPEED_SCU_NR_REGS;
|
||||
asc->clkin_25Mhz = false;
|
||||
asc->ops = &aspeed_ast2500_scu_ops;
|
||||
}
|
||||
|
||||
@ -716,9 +766,11 @@ static void aspeed_2600_scu_class_init(ObjectClass *klass, void *data)
|
||||
dc->desc = "ASPEED 2600 System Control Unit";
|
||||
dc->reset = aspeed_ast2600_scu_reset;
|
||||
asc->resets = ast2600_a3_resets;
|
||||
asc->calc_hpll = aspeed_2500_scu_calc_hpll; /* No change since AST2500 */
|
||||
asc->calc_hpll = aspeed_2600_scu_calc_hpll;
|
||||
asc->get_apb = aspeed_2600_scu_get_apb_freq;
|
||||
asc->apb_divider = 4;
|
||||
asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;
|
||||
asc->clkin_25Mhz = true;
|
||||
asc->ops = &aspeed_ast2600_scu_ops;
|
||||
}
|
||||
|
||||
@ -729,12 +781,64 @@ static const TypeInfo aspeed_2600_scu_info = {
|
||||
.class_init = aspeed_2600_scu_class_init,
|
||||
};
|
||||
|
||||
static const uint32_t ast1030_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
|
||||
[AST2600_SYS_RST_CTRL] = 0xFFC3FED8,
|
||||
[AST2600_SYS_RST_CTRL2] = 0x09FFFFFC,
|
||||
[AST2600_CLK_STOP_CTRL] = 0xFFFF7F8A,
|
||||
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
|
||||
[AST2600_DEBUG_CTRL2] = 0x00000000,
|
||||
[AST2600_HPLL_PARAM] = 0x10004077,
|
||||
[AST2600_HPLL_EXT] = 0x00000031,
|
||||
[AST2600_CLK_SEL4] = 0x43F90900,
|
||||
[AST2600_CLK_SEL5] = 0x40000000,
|
||||
[AST2600_CHIP_ID0] = 0xDEADBEEF,
|
||||
[AST2600_CHIP_ID1] = 0x0BADCAFE,
|
||||
};
|
||||
|
||||
static void aspeed_ast1030_scu_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[AST2600_SILICON_REV] = AST1030_A1_SILICON_REV;
|
||||
s->regs[AST2600_SILICON_REV2] = s->silicon_rev;
|
||||
s->regs[AST2600_HW_STRAP1] = s->hw_strap1;
|
||||
s->regs[AST2600_HW_STRAP2] = s->hw_strap2;
|
||||
s->regs[PROT_KEY] = s->hw_prot_key;
|
||||
}
|
||||
|
||||
static void aspeed_1030_scu_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 1030 System Control Unit";
|
||||
dc->reset = aspeed_ast1030_scu_reset;
|
||||
asc->resets = ast1030_a1_resets;
|
||||
asc->calc_hpll = aspeed_2600_scu_calc_hpll;
|
||||
asc->get_apb = aspeed_1030_scu_get_apb_freq;
|
||||
asc->apb_divider = 2;
|
||||
asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;
|
||||
asc->clkin_25Mhz = true;
|
||||
asc->ops = &aspeed_ast2600_scu_ops;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_1030_scu_info = {
|
||||
.name = TYPE_ASPEED_1030_SCU,
|
||||
.parent = TYPE_ASPEED_SCU,
|
||||
.instance_size = sizeof(AspeedSCUState),
|
||||
.class_init = aspeed_1030_scu_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_scu_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_scu_info);
|
||||
type_register_static(&aspeed_2400_scu_info);
|
||||
type_register_static(&aspeed_2500_scu_info);
|
||||
type_register_static(&aspeed_2600_scu_info);
|
||||
type_register_static(&aspeed_1030_scu_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_scu_register_types);
|
||||
|
@ -1696,6 +1696,160 @@ static const TypeInfo aspeed_2600_spi2_info = {
|
||||
.class_init = aspeed_2600_spi2_class_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* The FMC Segment Registers of the AST1030 have a 512KB unit.
|
||||
* Only bits [27:19] are used for decoding.
|
||||
*/
|
||||
#define AST1030_SEG_ADDR_MASK 0x0ff80000
|
||||
|
||||
static uint32_t aspeed_1030_smc_segment_to_reg(const AspeedSMCState *s,
|
||||
const AspeedSegments *seg)
|
||||
{
|
||||
uint32_t reg = 0;
|
||||
|
||||
/* Disabled segments have a nil register */
|
||||
if (!seg->size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
reg |= (seg->addr & AST1030_SEG_ADDR_MASK) >> 16; /* start offset */
|
||||
reg |= (seg->addr + seg->size - 1) & AST1030_SEG_ADDR_MASK; /* end offset */
|
||||
return reg;
|
||||
}
|
||||
|
||||
static void aspeed_1030_smc_reg_to_segment(const AspeedSMCState *s,
|
||||
uint32_t reg, AspeedSegments *seg)
|
||||
{
|
||||
uint32_t start_offset = (reg << 16) & AST1030_SEG_ADDR_MASK;
|
||||
uint32_t end_offset = reg & AST1030_SEG_ADDR_MASK;
|
||||
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
|
||||
|
||||
if (reg) {
|
||||
seg->addr = asc->flash_window_base + start_offset;
|
||||
seg->size = end_offset + (512 * KiB) - start_offset;
|
||||
} else {
|
||||
seg->addr = asc->flash_window_base;
|
||||
seg->size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32_t aspeed_1030_fmc_resets[ASPEED_SMC_R_MAX] = {
|
||||
[R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
|
||||
CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
|
||||
};
|
||||
|
||||
static const AspeedSegments aspeed_1030_fmc_segments[] = {
|
||||
{ 0x0, 128 * MiB }, /* start address is readonly */
|
||||
{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
|
||||
{ 0x0, 0 }, /* disabled */
|
||||
};
|
||||
|
||||
static void aspeed_1030_fmc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
|
||||
|
||||
dc->desc = "Aspeed 1030 FMC Controller";
|
||||
asc->r_conf = R_CONF;
|
||||
asc->r_ce_ctrl = R_CE_CTRL;
|
||||
asc->r_ctrl0 = R_CTRL0;
|
||||
asc->r_timings = R_TIMINGS;
|
||||
asc->nregs_timings = 2;
|
||||
asc->conf_enable_w0 = CONF_ENABLE_W0;
|
||||
asc->cs_num_max = 2;
|
||||
asc->segments = aspeed_1030_fmc_segments;
|
||||
asc->segment_addr_mask = 0x0ff80ff8;
|
||||
asc->resets = aspeed_1030_fmc_resets;
|
||||
asc->flash_window_base = 0x80000000;
|
||||
asc->flash_window_size = 0x10000000;
|
||||
asc->features = ASPEED_SMC_FEATURE_DMA;
|
||||
asc->dma_flash_mask = 0x0FFFFFFC;
|
||||
asc->dma_dram_mask = 0x000BFFFC;
|
||||
asc->nregs = ASPEED_SMC_R_MAX;
|
||||
asc->segment_to_reg = aspeed_1030_smc_segment_to_reg;
|
||||
asc->reg_to_segment = aspeed_1030_smc_reg_to_segment;
|
||||
asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_1030_fmc_info = {
|
||||
.name = "aspeed.fmc-ast1030",
|
||||
.parent = TYPE_ASPEED_SMC,
|
||||
.class_init = aspeed_1030_fmc_class_init,
|
||||
};
|
||||
|
||||
static const AspeedSegments aspeed_1030_spi1_segments[] = {
|
||||
{ 0x0, 128 * MiB }, /* start address is readonly */
|
||||
{ 0x0, 0 }, /* disabled */
|
||||
};
|
||||
|
||||
static void aspeed_1030_spi1_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
|
||||
|
||||
dc->desc = "Aspeed 1030 SPI1 Controller";
|
||||
asc->r_conf = R_CONF;
|
||||
asc->r_ce_ctrl = R_CE_CTRL;
|
||||
asc->r_ctrl0 = R_CTRL0;
|
||||
asc->r_timings = R_TIMINGS;
|
||||
asc->nregs_timings = 2;
|
||||
asc->conf_enable_w0 = CONF_ENABLE_W0;
|
||||
asc->cs_num_max = 2;
|
||||
asc->segments = aspeed_1030_spi1_segments;
|
||||
asc->segment_addr_mask = 0x0ff00ff0;
|
||||
asc->flash_window_base = 0x90000000;
|
||||
asc->flash_window_size = 0x10000000;
|
||||
asc->features = ASPEED_SMC_FEATURE_DMA;
|
||||
asc->dma_flash_mask = 0x0FFFFFFC;
|
||||
asc->dma_dram_mask = 0x000BFFFC;
|
||||
asc->nregs = ASPEED_SMC_R_MAX;
|
||||
asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
|
||||
asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
|
||||
asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_1030_spi1_info = {
|
||||
.name = "aspeed.spi1-ast1030",
|
||||
.parent = TYPE_ASPEED_SMC,
|
||||
.class_init = aspeed_1030_spi1_class_init,
|
||||
};
|
||||
static const AspeedSegments aspeed_1030_spi2_segments[] = {
|
||||
{ 0x0, 128 * MiB }, /* start address is readonly */
|
||||
{ 0x0, 0 }, /* disabled */
|
||||
};
|
||||
|
||||
static void aspeed_1030_spi2_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
|
||||
|
||||
dc->desc = "Aspeed 1030 SPI2 Controller";
|
||||
asc->r_conf = R_CONF;
|
||||
asc->r_ce_ctrl = R_CE_CTRL;
|
||||
asc->r_ctrl0 = R_CTRL0;
|
||||
asc->r_timings = R_TIMINGS;
|
||||
asc->nregs_timings = 2;
|
||||
asc->conf_enable_w0 = CONF_ENABLE_W0;
|
||||
asc->cs_num_max = 2;
|
||||
asc->segments = aspeed_1030_spi2_segments;
|
||||
asc->segment_addr_mask = 0x0ff00ff0;
|
||||
asc->flash_window_base = 0xb0000000;
|
||||
asc->flash_window_size = 0x10000000;
|
||||
asc->features = ASPEED_SMC_FEATURE_DMA;
|
||||
asc->dma_flash_mask = 0x0FFFFFFC;
|
||||
asc->dma_dram_mask = 0x000BFFFC;
|
||||
asc->nregs = ASPEED_SMC_R_MAX;
|
||||
asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
|
||||
asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
|
||||
asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_1030_spi2_info = {
|
||||
.name = "aspeed.spi2-ast1030",
|
||||
.parent = TYPE_ASPEED_SMC,
|
||||
.class_init = aspeed_1030_spi2_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_smc_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_smc_flash_info);
|
||||
@ -1709,6 +1863,9 @@ static void aspeed_smc_register_types(void)
|
||||
type_register_static(&aspeed_2600_fmc_info);
|
||||
type_register_static(&aspeed_2600_spi1_info);
|
||||
type_register_static(&aspeed_2600_spi2_info);
|
||||
type_register_static(&aspeed_1030_fmc_info);
|
||||
type_register_static(&aspeed_1030_spi1_info);
|
||||
type_register_static(&aspeed_1030_spi2_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_smc_register_types)
|
||||
|
@ -745,12 +745,29 @@ static const TypeInfo aspeed_2600_timer_info = {
|
||||
.class_init = aspeed_2600_timer_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_1030_timer_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedTimerClass *awc = ASPEED_TIMER_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 1030 Timer";
|
||||
awc->read = aspeed_2600_timer_read;
|
||||
awc->write = aspeed_2600_timer_write;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_1030_timer_info = {
|
||||
.name = TYPE_ASPEED_1030_TIMER,
|
||||
.parent = TYPE_ASPEED_TIMER,
|
||||
.class_init = aspeed_1030_timer_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_timer_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_timer_info);
|
||||
type_register_static(&aspeed_2400_timer_info);
|
||||
type_register_static(&aspeed_2500_timer_info);
|
||||
type_register_static(&aspeed_2600_timer_info);
|
||||
type_register_static(&aspeed_1030_timer_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_timer_register_types)
|
||||
|
@ -232,8 +232,8 @@ static void aspeed_wdt_reset(DeviceState *dev)
|
||||
AspeedWDTState *s = ASPEED_WDT(dev);
|
||||
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
|
||||
|
||||
s->regs[WDT_STATUS] = 0x3EF1480;
|
||||
s->regs[WDT_RELOAD_VALUE] = 0x03EF1480;
|
||||
s->regs[WDT_STATUS] = awc->default_status;
|
||||
s->regs[WDT_RELOAD_VALUE] = awc->default_reload_value;
|
||||
s->regs[WDT_RESTART] = 0;
|
||||
s->regs[WDT_CTRL] = awc->sanitize_ctrl(0);
|
||||
s->regs[WDT_RESET_WIDTH] = 0xFF;
|
||||
@ -319,6 +319,8 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
|
||||
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
|
||||
awc->wdt_reload = aspeed_wdt_reload;
|
||||
awc->sanitize_ctrl = aspeed_2400_sanitize_ctrl;
|
||||
awc->default_status = 0x03EF1480;
|
||||
awc->default_reload_value = 0x03EF1480;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2400_wdt_info = {
|
||||
@ -355,6 +357,8 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
|
||||
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
|
||||
awc->wdt_reload = aspeed_wdt_reload_1mhz;
|
||||
awc->sanitize_ctrl = aspeed_2500_sanitize_ctrl;
|
||||
awc->default_status = 0x014FB180;
|
||||
awc->default_reload_value = 0x014FB180;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2500_wdt_info = {
|
||||
@ -376,6 +380,8 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
|
||||
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
|
||||
awc->wdt_reload = aspeed_wdt_reload_1mhz;
|
||||
awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
|
||||
awc->default_status = 0x014FB180;
|
||||
awc->default_reload_value = 0x014FB180;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2600_wdt_info = {
|
||||
@ -385,6 +391,29 @@ static const TypeInfo aspeed_2600_wdt_info = {
|
||||
.class_init = aspeed_2600_wdt_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_1030_wdt_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 1030 Watchdog Controller";
|
||||
awc->offset = 0x80;
|
||||
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
|
||||
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
|
||||
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
|
||||
awc->wdt_reload = aspeed_wdt_reload_1mhz;
|
||||
awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
|
||||
awc->default_status = 0x014FB180;
|
||||
awc->default_reload_value = 0x014FB180;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_1030_wdt_info = {
|
||||
.name = TYPE_ASPEED_1030_WDT,
|
||||
.parent = TYPE_ASPEED_WDT,
|
||||
.instance_size = sizeof(AspeedWDTState),
|
||||
.class_init = aspeed_1030_wdt_class_init,
|
||||
};
|
||||
|
||||
static void wdt_aspeed_register_types(void)
|
||||
{
|
||||
watchdog_add_model(&model);
|
||||
@ -392,6 +421,7 @@ static void wdt_aspeed_register_types(void)
|
||||
type_register_static(&aspeed_2400_wdt_info);
|
||||
type_register_static(&aspeed_2500_wdt_info);
|
||||
type_register_static(&aspeed_2600_wdt_info);
|
||||
type_register_static(&aspeed_1030_wdt_info);
|
||||
}
|
||||
|
||||
type_init(wdt_aspeed_register_types)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define TYPE_ASPEED_2400_ADC TYPE_ASPEED_ADC "-ast2400"
|
||||
#define TYPE_ASPEED_2500_ADC TYPE_ASPEED_ADC "-ast2500"
|
||||
#define TYPE_ASPEED_2600_ADC TYPE_ASPEED_ADC "-ast2600"
|
||||
#define TYPE_ASPEED_1030_ADC TYPE_ASPEED_ADC "-ast1030"
|
||||
OBJECT_DECLARE_TYPE(AspeedADCState, AspeedADCClass, ASPEED_ADC)
|
||||
|
||||
#define TYPE_ASPEED_ADC_ENGINE "aspeed.adc.engine"
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define ASPEED_SOC_H
|
||||
|
||||
#include "hw/cpu/a15mpcore.h"
|
||||
#include "hw/arm/armv7m.h"
|
||||
#include "hw/intc/aspeed_vic.h"
|
||||
#include "hw/misc/aspeed_scu.h"
|
||||
#include "hw/adc/aspeed_adc.h"
|
||||
@ -47,6 +48,7 @@ struct AspeedSoCState {
|
||||
/*< public >*/
|
||||
ARMCPU cpu[ASPEED_CPUS_NUM];
|
||||
A15MPPrivState a7mpcore;
|
||||
ARMv7MState armv7m;
|
||||
MemoryRegion *dram_mr;
|
||||
MemoryRegion sram;
|
||||
AspeedVICState vic;
|
||||
@ -72,6 +74,7 @@ struct AspeedSoCState {
|
||||
AspeedSDHCIState emmc;
|
||||
AspeedLPCState lpc;
|
||||
uint32_t uart_default;
|
||||
Clock *sysclk;
|
||||
};
|
||||
|
||||
#define TYPE_ASPEED_SOC "aspeed-soc"
|
||||
@ -112,6 +115,7 @@ enum {
|
||||
ASPEED_DEV_SCU,
|
||||
ASPEED_DEV_ADC,
|
||||
ASPEED_DEV_SBC,
|
||||
ASPEED_DEV_EMMC_BC,
|
||||
ASPEED_DEV_VIDEO,
|
||||
ASPEED_DEV_SRAM,
|
||||
ASPEED_DEV_SDHCI,
|
||||
|
@ -15,9 +15,12 @@
|
||||
#define TYPE_ASPEED_AST2400_HACE TYPE_ASPEED_HACE "-ast2400"
|
||||
#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"
|
||||
|
||||
OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE)
|
||||
|
||||
#define ASPEED_HACE_NR_REGS (0x64 >> 2)
|
||||
#define ASPEED_HACE_MAX_SG 256 /* max number of entries */
|
||||
|
||||
struct AspeedHACEState {
|
||||
SysBusDevice parent;
|
||||
@ -25,7 +28,10 @@ struct AspeedHACEState {
|
||||
MemoryRegion iomem;
|
||||
qemu_irq irq;
|
||||
|
||||
struct iovec iov_cache[ASPEED_HACE_MAX_SG];
|
||||
uint32_t regs[ASPEED_HACE_NR_REGS];
|
||||
uint32_t total_req_len;
|
||||
uint32_t iov_count;
|
||||
|
||||
MemoryRegion *dram_mr;
|
||||
AddressSpace dram_as;
|
||||
@ -37,6 +43,7 @@ struct AspeedHACEClass {
|
||||
|
||||
uint32_t src_mask;
|
||||
uint32_t dest_mask;
|
||||
uint32_t key_mask;
|
||||
uint32_t hash_mask;
|
||||
};
|
||||
|
||||
|
@ -19,6 +19,7 @@ OBJECT_DECLARE_TYPE(AspeedSCUState, AspeedSCUClass, ASPEED_SCU)
|
||||
#define TYPE_ASPEED_2400_SCU TYPE_ASPEED_SCU "-ast2400"
|
||||
#define TYPE_ASPEED_2500_SCU TYPE_ASPEED_SCU "-ast2500"
|
||||
#define TYPE_ASPEED_2600_SCU TYPE_ASPEED_SCU "-ast2600"
|
||||
#define TYPE_ASPEED_1030_SCU TYPE_ASPEED_SCU "-ast1030"
|
||||
|
||||
#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
|
||||
#define ASPEED_AST2600_SCU_NR_REGS (0xE20 >> 2)
|
||||
@ -45,6 +46,8 @@ struct AspeedSCUState {
|
||||
#define AST2600_A1_SILICON_REV 0x05010303U
|
||||
#define AST2600_A2_SILICON_REV 0x05020303U
|
||||
#define AST2600_A3_SILICON_REV 0x05030303U
|
||||
#define AST1030_A0_SILICON_REV 0x80000000U
|
||||
#define AST1030_A1_SILICON_REV 0x80010000U
|
||||
|
||||
#define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04)
|
||||
|
||||
@ -56,8 +59,10 @@ struct AspeedSCUClass {
|
||||
|
||||
const uint32_t *resets;
|
||||
uint32_t (*calc_hpll)(AspeedSCUState *s, uint32_t hpll_reg);
|
||||
uint32_t (*get_apb)(AspeedSCUState *s);
|
||||
uint32_t apb_divider;
|
||||
uint32_t nr_regs;
|
||||
bool clkin_25Mhz;
|
||||
const MemoryRegionOps *ops;
|
||||
};
|
||||
|
||||
@ -316,4 +321,44 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
|
||||
SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
|
||||
SCU_AST2500_HW_STRAP_RESERVED1)
|
||||
|
||||
/*
|
||||
* SCU200 H-PLL Parameter Register (for Aspeed AST2600 SOC)
|
||||
*
|
||||
* 28:26 H-PLL Parameters
|
||||
* 25 Enable H-PLL reset
|
||||
* 24 Enable H-PLL bypass mode
|
||||
* 23 Turn off H-PLL
|
||||
* 22:19 H-PLL Post Divider (P)
|
||||
* 18:13 H-PLL Numerator (M)
|
||||
* 12:0 H-PLL Denumerator (N)
|
||||
*
|
||||
* (Output frequency) = CLKIN(25MHz) * [(M+1) / (N+1)] / (P+1)
|
||||
*
|
||||
* The default frequency is 1200Mhz when CLKIN = 25MHz
|
||||
*/
|
||||
#define SCU_AST2600_H_PLL_BYPASS_EN (0x1 << 24)
|
||||
#define SCU_AST2600_H_PLL_OFF (0x1 << 23)
|
||||
|
||||
/*
|
||||
* SCU310 Clock Selection Register Set 4 (for Aspeed AST1030 SOC)
|
||||
*
|
||||
* 31 I3C Clock Source selection
|
||||
* 30:28 I3C clock divider selection
|
||||
* 26:24 MAC AHB clock divider selection
|
||||
* 22:20 RGMII 125MHz clock divider ration
|
||||
* 19:16 RGMII 50MHz clock divider ration
|
||||
* 15 LHCLK clock generation/output enable control
|
||||
* 14:12 LHCLK divider selection
|
||||
* 11:8 APB Bus PCLK divider selection
|
||||
* 7 Select PECI clock source
|
||||
* 6 Select UART debug port clock source
|
||||
* 5 Select UART6 clock source
|
||||
* 4 Select UART5 clock source
|
||||
* 3 Select UART4 clock source
|
||||
* 2 Select UART3 clock source
|
||||
* 1 Select UART2 clock source
|
||||
* 0 Select UART1 clock source
|
||||
*/
|
||||
#define SCU_AST1030_CLK_GET_PCLK_DIV(x) (((x) >> 8) & 0xf)
|
||||
|
||||
#endif /* ASPEED_SCU_H */
|
||||
|
@ -31,6 +31,7 @@ OBJECT_DECLARE_TYPE(AspeedTimerCtrlState, AspeedTimerClass, ASPEED_TIMER)
|
||||
#define TYPE_ASPEED_2400_TIMER TYPE_ASPEED_TIMER "-ast2400"
|
||||
#define TYPE_ASPEED_2500_TIMER TYPE_ASPEED_TIMER "-ast2500"
|
||||
#define TYPE_ASPEED_2600_TIMER TYPE_ASPEED_TIMER "-ast2600"
|
||||
#define TYPE_ASPEED_1030_TIMER TYPE_ASPEED_TIMER "-ast1030"
|
||||
|
||||
#define ASPEED_TIMER_NR_TIMERS 8
|
||||
|
||||
|
@ -19,6 +19,7 @@ OBJECT_DECLARE_TYPE(AspeedWDTState, AspeedWDTClass, ASPEED_WDT)
|
||||
#define TYPE_ASPEED_2400_WDT TYPE_ASPEED_WDT "-ast2400"
|
||||
#define TYPE_ASPEED_2500_WDT TYPE_ASPEED_WDT "-ast2500"
|
||||
#define TYPE_ASPEED_2600_WDT TYPE_ASPEED_WDT "-ast2600"
|
||||
#define TYPE_ASPEED_1030_WDT TYPE_ASPEED_WDT "-ast1030"
|
||||
|
||||
#define ASPEED_WDT_REGS_MAX (0x20 / 4)
|
||||
|
||||
@ -45,6 +46,8 @@ struct AspeedWDTClass {
|
||||
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
|
||||
void (*wdt_reload)(AspeedWDTState *s);
|
||||
uint64_t (*sanitize_ctrl)(uint64_t data);
|
||||
uint32_t default_status;
|
||||
uint32_t default_reload_value;
|
||||
};
|
||||
|
||||
#endif /* WDT_ASPEED_H */
|
||||
|
36
tests/avocado/machine_aspeed.py
Normal file
36
tests/avocado/machine_aspeed.py
Normal file
@ -0,0 +1,36 @@
|
||||
# Functional test that boots the ASPEED SoCs with firmware
|
||||
#
|
||||
# Copyright (C) 2022 ASPEED Technology Inc
|
||||
#
|
||||
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||
# later. See the COPYING file in the top-level directory.
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
from avocado.utils import archive
|
||||
|
||||
|
||||
class AST1030Machine(QemuSystemTest):
|
||||
"""Boots the zephyr os and checks that the console is operational"""
|
||||
|
||||
timeout = 10
|
||||
|
||||
def test_ast1030_zephyros(self):
|
||||
"""
|
||||
:avocado: tags=arch:arm
|
||||
:avocado: tags=machine:ast1030-evb
|
||||
"""
|
||||
tar_url = ('https://github.com/AspeedTech-BMC'
|
||||
'/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip')
|
||||
tar_hash = '4c6a8ce3a8ba76ef1a65dae419ae3409343c4b20'
|
||||
tar_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(tar_path, self.workdir)
|
||||
kernel_file = self.workdir + "/ast1030-evb-demo/zephyr.elf"
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_file,
|
||||
'-nographic')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, "Booting Zephyr OS")
|
||||
exec_command_and_wait_for_pattern(self, "help",
|
||||
"Available commands")
|
87
tests/qtest/aspeed_gpio-test.c
Normal file
87
tests/qtest/aspeed_gpio-test.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* QTest testcase for the Aspeed GPIO Controller.
|
||||
*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "libqtest-single.h"
|
||||
|
||||
static bool qom_get_bool(QTestState *s, const char *path, const char *property)
|
||||
{
|
||||
QDict *r;
|
||||
bool b;
|
||||
|
||||
r = qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': "
|
||||
"{ 'path': %s, 'property': %s } }", path, property);
|
||||
b = qdict_get_bool(r, "return");
|
||||
qobject_unref(r);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static void qom_set_bool(QTestState *s, const char *path, const char *property,
|
||||
bool value)
|
||||
{
|
||||
QDict *r;
|
||||
|
||||
r = qtest_qmp(s, "{ 'execute': 'qom-set', 'arguments': "
|
||||
"{ 'path': %s, 'property': %s, 'value': %i } }",
|
||||
path, property, value);
|
||||
qobject_unref(r);
|
||||
}
|
||||
|
||||
static void test_set_colocated_pins(const void *data)
|
||||
{
|
||||
QTestState *s = (QTestState *)data;
|
||||
|
||||
/*
|
||||
* gpioV4-7 occupy bits within a single 32-bit value, so we want to make
|
||||
* sure that modifying one doesn't affect the other.
|
||||
*/
|
||||
qom_set_bool(s, "/machine/soc/gpio", "gpioV4", true);
|
||||
qom_set_bool(s, "/machine/soc/gpio", "gpioV5", false);
|
||||
qom_set_bool(s, "/machine/soc/gpio", "gpioV6", true);
|
||||
qom_set_bool(s, "/machine/soc/gpio", "gpioV7", false);
|
||||
g_assert(qom_get_bool(s, "/machine/soc/gpio", "gpioV4"));
|
||||
g_assert(!qom_get_bool(s, "/machine/soc/gpio", "gpioV5"));
|
||||
g_assert(qom_get_bool(s, "/machine/soc/gpio", "gpioV6"));
|
||||
g_assert(!qom_get_bool(s, "/machine/soc/gpio", "gpioV7"));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QTestState *s;
|
||||
int r;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
s = qtest_init("-machine ast2600-evb");
|
||||
qtest_add_data_func("/ast2600/gpio/set_colocated_pins", s,
|
||||
test_set_colocated_pins);
|
||||
r = g_test_run();
|
||||
qtest_quit(s);
|
||||
|
||||
return r;
|
||||
}
|
@ -20,6 +20,7 @@
|
||||
#define HACE_ALGO_SHA512 (BIT(5) | BIT(6))
|
||||
#define HACE_ALGO_SHA384 (BIT(5) | BIT(6) | BIT(10))
|
||||
#define HACE_SG_EN BIT(18)
|
||||
#define HACE_ACCUM_EN BIT(8)
|
||||
|
||||
#define HACE_STS 0x1c
|
||||
#define HACE_RSA_ISR BIT(13)
|
||||
@ -95,6 +96,57 @@ static const uint8_t test_result_sg_sha256[] = {
|
||||
0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
|
||||
0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
|
||||
|
||||
/*
|
||||
* The accumulative mode requires firmware to provide internal initial state
|
||||
* and message padding (including length L at the end of padding).
|
||||
*
|
||||
* This test vector is a ascii text "abc" with padding message.
|
||||
*
|
||||
* Expected results were generated using command line utitiles:
|
||||
*
|
||||
* echo -n -e 'abc' | dd of=/tmp/test
|
||||
* for hash in sha512sum sha256sum; do $hash /tmp/test; done
|
||||
*/
|
||||
static const uint8_t test_vector_accum_512[] = {
|
||||
0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
|
||||
|
||||
static const uint8_t test_vector_accum_256[] = {
|
||||
0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
|
||||
|
||||
static const uint8_t test_result_accum_sha512[] = {
|
||||
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
|
||||
0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
|
||||
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
|
||||
0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
|
||||
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
|
||||
0xa5, 0x4c, 0xa4, 0x9f};
|
||||
|
||||
static const uint8_t test_result_accum_sha256[] = {
|
||||
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
|
||||
0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
|
||||
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
|
||||
|
||||
static void write_regs(QTestState *s, uint32_t base, uint32_t src,
|
||||
uint32_t length, uint32_t out, uint32_t method)
|
||||
@ -307,6 +359,88 @@ static void test_sha512_sg(const char *machine, const uint32_t base,
|
||||
qtest_quit(s);
|
||||
}
|
||||
|
||||
static void test_sha256_accum(const char *machine, const uint32_t base,
|
||||
const uint32_t src_addr)
|
||||
{
|
||||
QTestState *s = qtest_init(machine);
|
||||
|
||||
const uint32_t buffer_addr = src_addr + 0x1000000;
|
||||
const uint32_t digest_addr = src_addr + 0x4000000;
|
||||
uint8_t digest[32] = {0};
|
||||
struct AspeedSgList array[] = {
|
||||
{ cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
|
||||
cpu_to_le32(buffer_addr) },
|
||||
};
|
||||
|
||||
/* Check engine is idle, no busy or irq bits set */
|
||||
g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
|
||||
|
||||
/* Write test vector into memory */
|
||||
qtest_memwrite(s, buffer_addr, test_vector_accum_256,
|
||||
sizeof(test_vector_accum_256));
|
||||
qtest_memwrite(s, src_addr, array, sizeof(array));
|
||||
|
||||
write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
|
||||
digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
|
||||
|
||||
/* Check hash IRQ status is asserted */
|
||||
g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
|
||||
|
||||
/* Clear IRQ status and check status is deasserted */
|
||||
qtest_writel(s, base + HACE_STS, 0x00000200);
|
||||
g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
|
||||
|
||||
/* Read computed digest from memory */
|
||||
qtest_memread(s, digest_addr, digest, sizeof(digest));
|
||||
|
||||
/* Check result of computation */
|
||||
g_assert_cmpmem(digest, sizeof(digest),
|
||||
test_result_accum_sha256, sizeof(digest));
|
||||
|
||||
qtest_quit(s);
|
||||
}
|
||||
|
||||
static void test_sha512_accum(const char *machine, const uint32_t base,
|
||||
const uint32_t src_addr)
|
||||
{
|
||||
QTestState *s = qtest_init(machine);
|
||||
|
||||
const uint32_t buffer_addr = src_addr + 0x1000000;
|
||||
const uint32_t digest_addr = src_addr + 0x4000000;
|
||||
uint8_t digest[64] = {0};
|
||||
struct AspeedSgList array[] = {
|
||||
{ cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
|
||||
cpu_to_le32(buffer_addr) },
|
||||
};
|
||||
|
||||
/* Check engine is idle, no busy or irq bits set */
|
||||
g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
|
||||
|
||||
/* Write test vector into memory */
|
||||
qtest_memwrite(s, buffer_addr, test_vector_accum_512,
|
||||
sizeof(test_vector_accum_512));
|
||||
qtest_memwrite(s, src_addr, array, sizeof(array));
|
||||
|
||||
write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
|
||||
digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
|
||||
|
||||
/* Check hash IRQ status is asserted */
|
||||
g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
|
||||
|
||||
/* Clear IRQ status and check status is deasserted */
|
||||
qtest_writel(s, base + HACE_STS, 0x00000200);
|
||||
g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
|
||||
|
||||
/* Read computed digest from memory */
|
||||
qtest_memread(s, digest_addr, digest, sizeof(digest));
|
||||
|
||||
/* Check result of computation */
|
||||
g_assert_cmpmem(digest, sizeof(digest),
|
||||
test_result_accum_sha512, sizeof(digest));
|
||||
|
||||
qtest_quit(s);
|
||||
}
|
||||
|
||||
struct masks {
|
||||
uint32_t src;
|
||||
uint32_t dest;
|
||||
@ -395,6 +529,16 @@ static void test_sha512_sg_ast2600(void)
|
||||
test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
|
||||
}
|
||||
|
||||
static void test_sha256_accum_ast2600(void)
|
||||
{
|
||||
test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
|
||||
}
|
||||
|
||||
static void test_sha512_accum_ast2600(void)
|
||||
{
|
||||
test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
|
||||
}
|
||||
|
||||
static void test_addresses_ast2600(void)
|
||||
{
|
||||
test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
|
||||
@ -454,6 +598,9 @@ int main(int argc, char **argv)
|
||||
qtest_add_func("ast2600/hace/sha512_sg", test_sha512_sg_ast2600);
|
||||
qtest_add_func("ast2600/hace/sha256_sg", test_sha256_sg_ast2600);
|
||||
|
||||
qtest_add_func("ast2600/hace/sha512_accum", test_sha512_accum_ast2600);
|
||||
qtest_add_func("ast2600/hace/sha256_accum", test_sha256_accum_ast2600);
|
||||
|
||||
qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);
|
||||
qtest_add_func("ast2500/hace/sha512", test_sha512_ast2500);
|
||||
qtest_add_func("ast2500/hace/sha256", test_sha256_ast2500);
|
||||
|
@ -189,7 +189,8 @@ qtests_npcm7xx = \
|
||||
(slirp.found() ? ['npcm7xx_emc-test'] : [])
|
||||
qtests_aspeed = \
|
||||
['aspeed_hace-test',
|
||||
'aspeed_smc-test']
|
||||
'aspeed_smc-test',
|
||||
'aspeed_gpio-test']
|
||||
qtests_arm = \
|
||||
(config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
|
||||
|
Loading…
Reference in New Issue
Block a user