mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-aspeed-20240617' of https://github.com/legoater/qemu into staging
aspeed queue: * Add AST2700 support # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmZvtLUACgkQUaNDx8/7 # 7KH8Ew/+K7OJYUsRhuLByLjaQ8kCsVdxMCFLtpCL9t6AgrMUXaI6WkkynPMKITQQ # AHocO76TsWRMp962obnjvXgVRCrtvOI2W5jvgp1Gr554tW7YQClLiGhuf1FeORS9 # ZQhWryoC8vK8ymC7dAS5cyuiddWFUGC04P9lb9oXr88n6goZ1xRfKwM+RttgfCAm # 79SsK7g3TS8QOWH1kQwIQZyJKzwrw7bTM3Ijv9NmVKa050zWquMRZQeY18fgO6Ae # p/pGpkf4Bc5iv+kIXoI4UN7Cx74aZoKInQ+DA71gtCWh/s09j9PkvOAfKWYAozD+ # VSaLvw4rvhRxgbs1SjoiMb5dDjJhngfzLhJX/P2FD1LCHRk+/uxk3fDDp2AqvQ6z # IuWPb8FgWHqeiigcXkTW1JgUS85quIbjWBxreIrQiq+zR50EQy49elMRhzJlKsqZ # 3/ulk7xf+5M1+wS4bo7r8LPk5K8mFw9b4cxfnx0feZCjrl4ZfeWyDtaKzCAU0MJq # KfpHo9R98imjVmcRWUouTaFow33OXheLdPFO8PofVnT38a4KIWlkin3zFMdTOAk+ # f8kWMPlXlRpKBYsjvP2aCpoY6CY8bHskdBH7xysM2W1FfKTw3dwZRpt4dgVPxqYj # KZXiKxzwnC2gGi/wn+EdhZwYy1nNSZYGK8s+jxBXi2UBrwv4PpA= # =TnR8 # -----END PGP SIGNATURE----- # gpg: Signature made Sun 16 Jun 2024 08:59:49 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-20240617' of https://github.com/legoater/qemu: MAINTAINERS: Add reviewers for ASPEED BMCs docs:aspeed: Add AST2700 Evaluation board test/avocado/machine_aspeed.py: Add AST2700 test case aspeed/soc: fix incorrect dram size for AST2700 aspeed: Add an AST2700 eval board aspeed/soc: Add AST2700 support aspeed/intc: Add AST2700 support aspeed/scu: Add AST2700 support aspeed/smc: Add AST2700 support aspeed/smc: support different memory region ops for SMC flash region aspeed/smc: support 64 bits dma dram address aspeed/smc: support dma start length and 1 byte length unit aspeed/smc: correct device description aspeed/sdmc: Add AST2700 support aspeed/sdmc: fix coding style aspeed/sdmc: remove redundant macros aspeed/sli: Add AST2700 support aspeed/wdt: Add AST2700 support aspeed/smc: Reintroduce "dram-base" property for AST2700 Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
@@ -1158,6 +1158,9 @@ F: docs/system/arm/emcraft-sf2.rst
|
||||
ASPEED BMCs
|
||||
M: Cédric Le Goater <clg@kaod.org>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Steven Lee <steven_lee@aspeedtech.com>
|
||||
R: Troy Lee <leetroy@gmail.com>
|
||||
R: Jamin Lin <jamin_lin@aspeedtech.com>
|
||||
R: Andrew Jeffery <andrew@codeconstruct.com.au>
|
||||
R: Joel Stanley <joel@jms.id.au>
|
||||
L: qemu-arm@nongnu.org
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``)
|
||||
==================================================================
|
||||
Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``, ``ast2700-evb``)
|
||||
===================================================================================
|
||||
|
||||
The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
|
||||
Aspeed evaluation boards. They are based on different releases of the
|
||||
Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
|
||||
AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
|
||||
with dual cores ARM Cortex-A7 CPUs (1.2GHz).
|
||||
AST2500 with an ARM1176JZS CPU (800MHz), the AST2600
|
||||
with dual cores ARM Cortex-A7 CPUs (1.2GHz) and more recently the AST2700
|
||||
with quad cores ARM Cortex-A35 64 bits CPUs (1.6GHz)
|
||||
|
||||
The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
|
||||
etc.
|
||||
@@ -38,6 +39,10 @@ AST2600 SoC based machines :
|
||||
- ``qcom-dc-scm-v1-bmc`` Qualcomm DC-SCM V1 BMC
|
||||
- ``qcom-firework-bmc`` Qualcomm Firework BMC
|
||||
|
||||
AST2700 SoC based machines :
|
||||
|
||||
- ``ast2700-evb`` Aspeed AST2700 Evaluation board (Cortex-A35)
|
||||
|
||||
Supported devices
|
||||
-----------------
|
||||
|
||||
@@ -66,6 +71,7 @@ Supported devices
|
||||
* eMMC Boot Controller (dummy)
|
||||
* PECI Controller (minimal)
|
||||
* I3C Controller
|
||||
* Internal Bridge Controller (SLI dummy)
|
||||
|
||||
|
||||
Missing devices
|
||||
@@ -95,6 +101,10 @@ or directly from the OpenBMC GitHub release repository :
|
||||
|
||||
https://github.com/openbmc/openbmc/releases
|
||||
|
||||
or directly from the ASPEED Forked OpenBMC GitHub release repository :
|
||||
|
||||
https://github.com/AspeedTech-BMC/openbmc/releases
|
||||
|
||||
To boot a kernel directly from a Linux build tree:
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -164,6 +174,27 @@ under Linux), use :
|
||||
|
||||
-M ast2500-evb,bmc-console=uart3
|
||||
|
||||
|
||||
Boot the AST2700 machine from the flash image, use an MTD drive :
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
IMGDIR=ast2700-default
|
||||
UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
|
||||
|
||||
$ qemu-system-aarch64 -M ast2700-evb \
|
||||
-device loader,force-raw=on,addr=0x400000000,file=${IMGDIR}/u-boot-nodtb.bin \
|
||||
-device loader,force-raw=on,addr=$((0x400000000 + ${UBOOT_SIZE})),file=${IMGDIR}/u-boot.dtb \
|
||||
-device loader,force-raw=on,addr=0x430000000,file=${IMGDIR}/bl31.bin \
|
||||
-device loader,force-raw=on,addr=0x430080000,file=${IMGDIR}/optee/tee-raw.bin \
|
||||
-device loader,cpu-num=0,addr=0x430000000 \
|
||||
-device loader,cpu-num=1,addr=0x430000000 \
|
||||
-device loader,cpu-num=2,addr=0x430000000 \
|
||||
-device loader,cpu-num=3,addr=0x430000000 \
|
||||
-smp 4 \
|
||||
-drive file=${IMGDIR}/image-bmc,format=raw,if=mtd \
|
||||
-nographic
|
||||
|
||||
Aspeed minibmc family boards (``ast1030-evb``)
|
||||
==================================================================
|
||||
|
||||
|
||||
@@ -178,6 +178,12 @@ struct AspeedMachineState {
|
||||
#define AST2600_EVB_HW_STRAP1 0x000000C0
|
||||
#define AST2600_EVB_HW_STRAP2 0x00000003
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
/* AST2700 evb hardware value */
|
||||
#define AST2700_EVB_HW_STRAP1 0x000000C0
|
||||
#define AST2700_EVB_HW_STRAP2 0x00000003
|
||||
#endif
|
||||
|
||||
/* Tacoma hardware value */
|
||||
#define TACOMA_BMC_HW_STRAP1 0x00000000
|
||||
#define TACOMA_BMC_HW_STRAP2 0x00000040
|
||||
@@ -1588,6 +1594,26 @@ static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
|
||||
aspeed_machine_class_init_cpus_defaults(mc);
|
||||
}
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
static void aspeed_machine_ast2700_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)";
|
||||
amc->soc_name = "ast2700-a0";
|
||||
amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
|
||||
amc->hw_strap2 = AST2700_EVB_HW_STRAP2;
|
||||
amc->fmc_model = "w25q01jvq";
|
||||
amc->spi_model = "w25q512jv";
|
||||
amc->num_cs = 2;
|
||||
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON;
|
||||
amc->uart_default = ASPEED_DEV_UART12;
|
||||
mc->default_ram_size = 1 * GiB;
|
||||
aspeed_machine_class_init_cpus_defaults(mc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
|
||||
void *data)
|
||||
{
|
||||
@@ -1711,6 +1737,12 @@ static const TypeInfo aspeed_machine_types[] = {
|
||||
.name = MACHINE_TYPE_NAME("ast1030-evb"),
|
||||
.parent = TYPE_ASPEED_MACHINE,
|
||||
.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
|
||||
#ifdef TARGET_AARCH64
|
||||
}, {
|
||||
.name = MACHINE_TYPE_NAME("ast2700-evb"),
|
||||
.parent = TYPE_ASPEED_MACHINE,
|
||||
.class_init = aspeed_machine_ast2700_evb_class_init,
|
||||
#endif
|
||||
}, {
|
||||
.name = TYPE_ASPEED_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,6 +49,7 @@ arm_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
|
||||
'aspeed_ast10x0.c',
|
||||
'aspeed_eeprom.c',
|
||||
'fby35.c'))
|
||||
arm_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files('aspeed_ast27x0.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'))
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* ASPEED INTC Controller
|
||||
*
|
||||
* Copyright (C) 2024 ASPEED Technology Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/intc/aspeed_intc.h"
|
||||
#include "hw/irq.h"
|
||||
#include "qemu/log.h"
|
||||
#include "trace.h"
|
||||
#include "hw/registerfields.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
/* INTC Registers */
|
||||
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)
|
||||
|
||||
#define GICINT_STATUS_BASE R_GICINT128_STATUS
|
||||
|
||||
static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
|
||||
{
|
||||
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
|
||||
|
||||
if (irq >= aic->num_ints) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
|
||||
__func__, irq);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_intc_update_irq(irq, level);
|
||||
qemu_set_irq(s->output_pins[irq], 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 irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on.
|
||||
*/
|
||||
static void aspeed_intc_set_irq(void *opaque, int irq, int level)
|
||||
{
|
||||
AspeedINTCState *s = (AspeedINTCState *)opaque;
|
||||
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
|
||||
uint32_t status_addr = GICINT_STATUS_BASE + ((0x100 * irq) >> 2);
|
||||
uint32_t select = 0;
|
||||
uint32_t enable;
|
||||
int i;
|
||||
|
||||
if (irq >= aic->num_ints) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
|
||||
__func__, irq);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_intc_set_irq(irq, level);
|
||||
enable = s->enable[irq];
|
||||
|
||||
if (!level) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < aic->num_lines; i++) {
|
||||
if (s->orgates[irq].levels[i]) {
|
||||
if (enable & BIT(i)) {
|
||||
select |= BIT(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!select) {
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_intc_select(select);
|
||||
|
||||
if (s->mask[irq] || s->regs[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[irq] |= select;
|
||||
trace_aspeed_intc_pending_irq(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]);
|
||||
aspeed_intc_update(s, irq, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int size)
|
||||
{
|
||||
AspeedINTCState *s = ASPEED_INTC(opaque);
|
||||
uint32_t addr = offset >> 2;
|
||||
uint32_t value = 0;
|
||||
|
||||
if (addr >= ASPEED_INTC_NR_REGS) {
|
||||
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(offset, size, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
|
||||
unsigned size)
|
||||
{
|
||||
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 (addr >= ASPEED_INTC_NR_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_intc_write(offset, size, data);
|
||||
|
||||
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:
|
||||
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;
|
||||
break;
|
||||
case R_GICINT128_STATUS:
|
||||
case R_GICINT129_STATUS:
|
||||
case R_GICINT130_STATUS:
|
||||
case R_GICINT131_STATUS:
|
||||
case R_GICINT132_STATUS:
|
||||
case R_GICINT133_STATUS:
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s->regs[addr] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps aspeed_intc_ops = {
|
||||
.read = aspeed_intc_read,
|
||||
.write = aspeed_intc_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);
|
||||
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++) {
|
||||
object_initialize_child(obj, "intc-orgates[*]", &s->orgates[i],
|
||||
TYPE_OR_IRQ);
|
||||
object_property_set_int(OBJECT(&s->orgates[i]), "num-lines",
|
||||
aic->num_lines, &error_abort);
|
||||
}
|
||||
}
|
||||
|
||||
static void aspeed_intc_reset(DeviceState *dev)
|
||||
{
|
||||
AspeedINTCState *s = ASPEED_INTC(dev);
|
||||
|
||||
memset(s->regs, 0, sizeof(s->regs));
|
||||
memset(s->enable, 0, sizeof(s->enable));
|
||||
memset(s->mask, 0, sizeof(s->mask));
|
||||
memset(s->pending, 0, sizeof(s->pending));
|
||||
}
|
||||
|
||||
static void aspeed_intc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
AspeedINTCState *s = ASPEED_INTC(dev);
|
||||
AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s);
|
||||
int i;
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_intc_ops, s,
|
||||
TYPE_ASPEED_INTC ".regs", ASPEED_INTC_NR_REGS << 2);
|
||||
|
||||
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++) {
|
||||
if (!qdev_realize(DEVICE(&s->orgates[i]), NULL, errp)) {
|
||||
return;
|
||||
}
|
||||
sysbus_init_irq(sbd, &s->output_pins[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void aspeed_intc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED INTC Controller";
|
||||
dc->realize = aspeed_intc_realize;
|
||||
dc->reset = aspeed_intc_reset;
|
||||
dc->vmsd = NULL;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_intc_info = {
|
||||
.name = TYPE_ASPEED_INTC,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_init = aspeed_intc_instance_init,
|
||||
.instance_size = sizeof(AspeedINTCState),
|
||||
.class_init = aspeed_intc_class_init,
|
||||
.class_size = sizeof(AspeedINTCClass),
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2700 INTC Controller";
|
||||
aic->num_lines = 32;
|
||||
aic->num_ints = 9;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2700_intc_info = {
|
||||
.name = TYPE_ASPEED_2700_INTC,
|
||||
.parent = TYPE_ASPEED_INTC,
|
||||
.class_init = aspeed_2700_intc_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_intc_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_intc_info);
|
||||
type_register_static(&aspeed_2700_intc_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_intc_register_types);
|
||||
@@ -14,6 +14,7 @@ system_ss.add(when: 'CONFIG_ARM_GICV3_TCG', if_true: files(
|
||||
))
|
||||
system_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
|
||||
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_vic.c'))
|
||||
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_intc.c'))
|
||||
system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
|
||||
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_gic.c', 'exynos4210_combiner.c'))
|
||||
system_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c'))
|
||||
|
||||
@@ -79,6 +79,19 @@ aspeed_vic_update_fiq(int flags) "Raising FIQ: %d"
|
||||
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"
|
||||
|
||||
# arm_gic.c
|
||||
gic_enable_irq(int irq) "irq %d enabled"
|
||||
|
||||
+305
-1
@@ -134,6 +134,48 @@
|
||||
|
||||
#define AST2600_CLK TO_REG(0x40)
|
||||
|
||||
#define AST2700_SILICON_REV TO_REG(0x00)
|
||||
#define AST2700_HW_STRAP1 TO_REG(0x10)
|
||||
#define AST2700_HW_STRAP1_CLR TO_REG(0x14)
|
||||
#define AST2700_HW_STRAP1_LOCK TO_REG(0x20)
|
||||
#define AST2700_HW_STRAP1_SEC1 TO_REG(0x24)
|
||||
#define AST2700_HW_STRAP1_SEC2 TO_REG(0x28)
|
||||
#define AST2700_HW_STRAP1_SEC3 TO_REG(0x2C)
|
||||
|
||||
#define AST2700_SCU_CLK_SEL_1 TO_REG(0x280)
|
||||
#define AST2700_SCU_HPLL_PARAM TO_REG(0x300)
|
||||
#define AST2700_SCU_HPLL_EXT_PARAM TO_REG(0x304)
|
||||
#define AST2700_SCU_DPLL_PARAM TO_REG(0x308)
|
||||
#define AST2700_SCU_DPLL_EXT_PARAM TO_REG(0x30c)
|
||||
#define AST2700_SCU_MPLL_PARAM TO_REG(0x310)
|
||||
#define AST2700_SCU_MPLL_EXT_PARAM TO_REG(0x314)
|
||||
#define AST2700_SCU_D1CLK_PARAM TO_REG(0x320)
|
||||
#define AST2700_SCU_D2CLK_PARAM TO_REG(0x330)
|
||||
#define AST2700_SCU_CRT1CLK_PARAM TO_REG(0x340)
|
||||
#define AST2700_SCU_CRT2CLK_PARAM TO_REG(0x350)
|
||||
#define AST2700_SCU_MPHYCLK_PARAM TO_REG(0x360)
|
||||
#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_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)
|
||||
#define AST2700_SCUIO_CLK_STOP_CLR_2 TO_REG(0x264)
|
||||
#define AST2700_SCUIO_CLK_SEL_1 TO_REG(0x280)
|
||||
#define AST2700_SCUIO_CLK_SEL_2 TO_REG(0x284)
|
||||
#define AST2700_SCUIO_HPLL_PARAM TO_REG(0x300)
|
||||
#define AST2700_SCUIO_HPLL_EXT_PARAM TO_REG(0x304)
|
||||
#define AST2700_SCUIO_APLL_PARAM TO_REG(0x310)
|
||||
#define AST2700_SCUIO_APLL_EXT_PARAM TO_REG(0x314)
|
||||
#define AST2700_SCUIO_DPLL_PARAM TO_REG(0x320)
|
||||
#define AST2700_SCUIO_DPLL_EXT_PARAM TO_REG(0x324)
|
||||
#define AST2700_SCUIO_DPLL_PARAM_READ TO_REG(0x328)
|
||||
#define AST2700_SCUIO_DPLL_EXT_PARAM_READ TO_REG(0x32c)
|
||||
#define AST2700_SCUIO_UARTCLK_GEN TO_REG(0x330)
|
||||
#define AST2700_SCUIO_HUARTCLK_GEN TO_REG(0x334)
|
||||
#define AST2700_SCUIO_CLK_DUTY_MEAS_RST TO_REG(0x388)
|
||||
|
||||
#define SCU_IO_REGION_SIZE 0x1000
|
||||
|
||||
static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
|
||||
@@ -244,6 +286,25 @@ static uint32_t aspeed_1030_scu_get_apb_freq(AspeedSCUState *s)
|
||||
/ asc->apb_divider;
|
||||
}
|
||||
|
||||
static uint32_t aspeed_2700_scu_get_apb_freq(AspeedSCUState *s)
|
||||
{
|
||||
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
|
||||
uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCU_HPLL_PARAM]);
|
||||
|
||||
return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[AST2700_SCU_CLK_SEL_1]) + 1)
|
||||
/ asc->apb_divider;
|
||||
}
|
||||
|
||||
static uint32_t aspeed_2700_scuio_get_apb_freq(AspeedSCUState *s)
|
||||
{
|
||||
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
|
||||
uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCUIO_HPLL_PARAM]);
|
||||
|
||||
return hpll /
|
||||
(SCUIO_AST2700_CLK_GET_PCLK_DIV(s->regs[AST2700_SCUIO_CLK_SEL_1]) + 1)
|
||||
/ asc->apb_divider;
|
||||
}
|
||||
|
||||
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
@@ -258,7 +319,8 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
|
||||
|
||||
switch (reg) {
|
||||
case RNG_DATA:
|
||||
/* On hardware, RNG_DATA works regardless of
|
||||
/*
|
||||
* On hardware, RNG_DATA works regardless of
|
||||
* the state of the enable bit in RNG_CTRL
|
||||
*/
|
||||
s->regs[RNG_DATA] = aspeed_scu_get_random();
|
||||
@@ -494,6 +556,9 @@ static uint32_t aspeed_silicon_revs[] = {
|
||||
AST2600_A3_SILICON_REV,
|
||||
AST1030_A0_SILICON_REV,
|
||||
AST1030_A1_SILICON_REV,
|
||||
AST2700_A0_SILICON_REV,
|
||||
AST2720_A0_SILICON_REV,
|
||||
AST2750_A0_SILICON_REV,
|
||||
};
|
||||
|
||||
bool is_supported_silicon_rev(uint32_t silicon_rev)
|
||||
@@ -783,6 +848,243 @@ static const TypeInfo aspeed_2600_scu_info = {
|
||||
.class_init = aspeed_2600_scu_class_init,
|
||||
};
|
||||
|
||||
static uint64_t aspeed_ast2700_scu_read(void *opaque, hwaddr offset,
|
||||
unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
|
||||
if (reg >= ASPEED_AST2700_SCU_NR_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, 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];
|
||||
}
|
||||
|
||||
static void aspeed_ast2700_scu_write(void *opaque, hwaddr offset,
|
||||
uint64_t data64, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
/* Truncate here so bitwise operations below behave as expected */
|
||||
uint32_t data = data64;
|
||||
|
||||
if (reg >= ASPEED_AST2700_SCU_NR_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_ast2700_scu_write(offset, size, data);
|
||||
|
||||
switch (reg) {
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Unhandled write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps aspeed_ast2700_scu_ops = {
|
||||
.read = aspeed_ast2700_scu_read,
|
||||
.write = aspeed_ast2700_scu_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid.min_access_size = 1,
|
||||
.valid.max_access_size = 8,
|
||||
.valid.unaligned = false,
|
||||
};
|
||||
|
||||
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,
|
||||
[AST2700_HW_STRAP1_SEC2] = 0x00000000,
|
||||
[AST2700_HW_STRAP1_SEC3] = 0x1000408F,
|
||||
[AST2700_SCU_HPLL_PARAM] = 0x0000009f,
|
||||
[AST2700_SCU_HPLL_EXT_PARAM] = 0x8000004f,
|
||||
[AST2700_SCU_DPLL_PARAM] = 0x0080009f,
|
||||
[AST2700_SCU_DPLL_EXT_PARAM] = 0x8000004f,
|
||||
[AST2700_SCU_MPLL_PARAM] = 0x00000040,
|
||||
[AST2700_SCU_MPLL_EXT_PARAM] = 0x80000000,
|
||||
[AST2700_SCU_D1CLK_PARAM] = 0x00050002,
|
||||
[AST2700_SCU_D2CLK_PARAM] = 0x00050002,
|
||||
[AST2700_SCU_CRT1CLK_PARAM] = 0x00050002,
|
||||
[AST2700_SCU_CRT2CLK_PARAM] = 0x00050002,
|
||||
[AST2700_SCU_MPHYCLK_PARAM] = 0x0000004c,
|
||||
[AST2700_SCU_FREQ_CNTR] = 0x000375eb,
|
||||
[AST2700_SCU_CPU_SCRATCH_0] = 0x00000000,
|
||||
[AST2700_SCU_CPU_SCRATCH_1] = 0x00000004,
|
||||
};
|
||||
|
||||
static void aspeed_ast2700_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);
|
||||
}
|
||||
|
||||
static void aspeed_2700_scu_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2700 System Control Unit";
|
||||
dc->reset = aspeed_ast2700_scu_reset;
|
||||
asc->resets = ast2700_a0_resets;
|
||||
asc->calc_hpll = aspeed_2600_scu_calc_hpll;
|
||||
asc->get_apb = aspeed_2700_scu_get_apb_freq;
|
||||
asc->apb_divider = 4;
|
||||
asc->nr_regs = ASPEED_AST2700_SCU_NR_REGS;
|
||||
asc->clkin_25Mhz = true;
|
||||
asc->ops = &aspeed_ast2700_scu_ops;
|
||||
}
|
||||
|
||||
static uint64_t aspeed_ast2700_scuio_read(void *opaque, hwaddr offset,
|
||||
unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
if (reg >= ASPEED_AST2700_SCU_NR_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, 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_scuio_read(offset, size, s->regs[reg]);
|
||||
return s->regs[reg];
|
||||
}
|
||||
|
||||
static void aspeed_ast2700_scuio_write(void *opaque, hwaddr offset,
|
||||
uint64_t data64, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
/* Truncate here so bitwise operations below behave as expected */
|
||||
uint32_t data = data64;
|
||||
bool updated = false;
|
||||
|
||||
if (reg >= ASPEED_AST2700_SCU_NR_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_ast2700_scuio_write(offset, size, data);
|
||||
|
||||
switch (reg) {
|
||||
case AST2700_SCUIO_CLK_STOP_CTL_1:
|
||||
case AST2700_SCUIO_CLK_STOP_CTL_2:
|
||||
s->regs[reg] |= data;
|
||||
updated = true;
|
||||
break;
|
||||
case AST2700_SCUIO_CLK_STOP_CLR_1:
|
||||
case AST2700_SCUIO_CLK_STOP_CLR_2:
|
||||
s->regs[reg - 1] ^= data;
|
||||
updated = true;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Unhandled write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps aspeed_ast2700_scuio_ops = {
|
||||
.read = aspeed_ast2700_scuio_read,
|
||||
.write = aspeed_ast2700_scuio_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid.min_access_size = 1,
|
||||
.valid.max_access_size = 8,
|
||||
.valid.unaligned = false,
|
||||
};
|
||||
|
||||
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,
|
||||
[AST2700_HW_STRAP1_SEC2] = 0x00000000,
|
||||
[AST2700_HW_STRAP1_SEC3] = 0x1000408F,
|
||||
[AST2700_SCUIO_CLK_STOP_CTL_1] = 0xffff8400,
|
||||
[AST2700_SCUIO_CLK_STOP_CTL_2] = 0x00005f30,
|
||||
[AST2700_SCUIO_CLK_SEL_1] = 0x86900000,
|
||||
[AST2700_SCUIO_CLK_SEL_2] = 0x00400000,
|
||||
[AST2700_SCUIO_HPLL_PARAM] = 0x10000027,
|
||||
[AST2700_SCUIO_HPLL_EXT_PARAM] = 0x80000014,
|
||||
[AST2700_SCUIO_APLL_PARAM] = 0x1000001f,
|
||||
[AST2700_SCUIO_APLL_EXT_PARAM] = 0x8000000f,
|
||||
[AST2700_SCUIO_DPLL_PARAM] = 0x106e42ce,
|
||||
[AST2700_SCUIO_DPLL_EXT_PARAM] = 0x80000167,
|
||||
[AST2700_SCUIO_DPLL_PARAM_READ] = 0x106e42ce,
|
||||
[AST2700_SCUIO_DPLL_EXT_PARAM_READ] = 0x80000167,
|
||||
[AST2700_SCUIO_UARTCLK_GEN] = 0x00014506,
|
||||
[AST2700_SCUIO_HUARTCLK_GEN] = 0x000145c0,
|
||||
[AST2700_SCUIO_CLK_DUTY_MEAS_RST] = 0x0c9100d2,
|
||||
};
|
||||
|
||||
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";
|
||||
dc->reset = aspeed_ast2700_scu_reset;
|
||||
asc->resets = ast2700_a0_resets_io;
|
||||
asc->calc_hpll = aspeed_2600_scu_calc_hpll;
|
||||
asc->get_apb = aspeed_2700_scuio_get_apb_freq;
|
||||
asc->apb_divider = 2;
|
||||
asc->nr_regs = ASPEED_AST2700_SCU_NR_REGS;
|
||||
asc->clkin_25Mhz = true;
|
||||
asc->ops = &aspeed_ast2700_scuio_ops;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2700_scu_info = {
|
||||
.name = TYPE_ASPEED_2700_SCU,
|
||||
.parent = TYPE_ASPEED_SCU,
|
||||
.instance_size = sizeof(AspeedSCUState),
|
||||
.class_init = aspeed_2700_scu_class_init,
|
||||
};
|
||||
|
||||
static const TypeInfo aspeed_2700_scuio_info = {
|
||||
.name = TYPE_ASPEED_2700_SCUIO,
|
||||
.parent = TYPE_ASPEED_SCU,
|
||||
.instance_size = sizeof(AspeedSCUState),
|
||||
.class_init = aspeed_2700_scuio_class_init,
|
||||
};
|
||||
|
||||
static const uint32_t ast1030_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
|
||||
[AST2600_SYS_RST_CTRL] = 0xFFC3FED8,
|
||||
[AST2600_SYS_RST_CTRL2] = 0x09FFFFFC,
|
||||
@@ -841,6 +1143,8 @@ static void aspeed_scu_register_types(void)
|
||||
type_register_static(&aspeed_2500_scu_info);
|
||||
type_register_static(&aspeed_2600_scu_info);
|
||||
type_register_static(&aspeed_1030_scu_info);
|
||||
type_register_static(&aspeed_2700_scu_info);
|
||||
type_register_static(&aspeed_2700_scuio_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_scu_register_types);
|
||||
|
||||
+198
-22
@@ -27,6 +27,7 @@
|
||||
#define PROT_SOFTLOCKED 0x00
|
||||
|
||||
#define PROT_KEY_UNLOCK 0xFC600309
|
||||
#define PROT_2700_KEY_UNLOCK 0x1688A8A8
|
||||
#define PROT_KEY_HARDLOCK 0xDEADDEAD /* AST2600 */
|
||||
|
||||
/* Configuration Register */
|
||||
@@ -54,6 +55,46 @@
|
||||
#define R_DRAM_TIME (0x8c / 4)
|
||||
#define R_ECC_ERR_INJECT (0xb4 / 4)
|
||||
|
||||
/* AST2700 Register */
|
||||
#define R_2700_PROT (0x00 / 4)
|
||||
#define R_INT_STATUS (0x04 / 4)
|
||||
#define R_INT_CLEAR (0x08 / 4)
|
||||
#define R_INT_MASK (0x0c / 4)
|
||||
#define R_MAIN_CONF (0x10 / 4)
|
||||
#define R_MAIN_CONTROL (0x14 / 4)
|
||||
#define R_MAIN_STATUS (0x18 / 4)
|
||||
#define R_ERR_STATUS (0x1c / 4)
|
||||
#define R_ECC_FAIL_STATUS (0x78 / 4)
|
||||
#define R_ECC_FAIL_ADDR (0x7c / 4)
|
||||
#define R_ECC_TESTING_CONTROL (0x80 / 4)
|
||||
#define R_PROT_REGION_LOCK_STATUS (0x94 / 4)
|
||||
#define R_TEST_FAIL_ADDR (0xd4 / 4)
|
||||
#define R_TEST_FAIL_D0 (0xd8 / 4)
|
||||
#define R_TEST_FAIL_D1 (0xdc / 4)
|
||||
#define R_TEST_FAIL_D2 (0xe0 / 4)
|
||||
#define R_TEST_FAIL_D3 (0xe4 / 4)
|
||||
#define R_DBG_STATUS (0xf4 / 4)
|
||||
#define R_PHY_INTERFACE_STATUS (0xf8 / 4)
|
||||
#define R_GRAPHIC_MEM_BASE_ADDR (0x10c / 4)
|
||||
#define R_PORT0_INTERFACE_MONITOR0 (0x240 / 4)
|
||||
#define R_PORT0_INTERFACE_MONITOR1 (0x244 / 4)
|
||||
#define R_PORT0_INTERFACE_MONITOR2 (0x248 / 4)
|
||||
#define R_PORT1_INTERFACE_MONITOR0 (0x2c0 / 4)
|
||||
#define R_PORT1_INTERFACE_MONITOR1 (0x2c4 / 4)
|
||||
#define R_PORT1_INTERFACE_MONITOR2 (0x2c8 / 4)
|
||||
#define R_PORT2_INTERFACE_MONITOR0 (0x340 / 4)
|
||||
#define R_PORT2_INTERFACE_MONITOR1 (0x344 / 4)
|
||||
#define R_PORT2_INTERFACE_MONITOR2 (0x348 / 4)
|
||||
#define R_PORT3_INTERFACE_MONITOR0 (0x3c0 / 4)
|
||||
#define R_PORT3_INTERFACE_MONITOR1 (0x3c4 / 4)
|
||||
#define R_PORT3_INTERFACE_MONITOR2 (0x3c8 / 4)
|
||||
#define R_PORT4_INTERFACE_MONITOR0 (0x440 / 4)
|
||||
#define R_PORT4_INTERFACE_MONITOR1 (0x444 / 4)
|
||||
#define R_PORT4_INTERFACE_MONITOR2 (0x448 / 4)
|
||||
#define R_PORT5_INTERFACE_MONITOR0 (0x4c0 / 4)
|
||||
#define R_PORT5_INTERFACE_MONITOR1 (0x4c4 / 4)
|
||||
#define R_PORT5_INTERFACE_MONITOR2 (0x4c8 / 4)
|
||||
|
||||
/*
|
||||
* Configuration register Ox4 (for Aspeed AST2400 SOC)
|
||||
*
|
||||
@@ -76,10 +117,6 @@
|
||||
#define ASPEED_SDMC_VGA_32MB 0x2
|
||||
#define ASPEED_SDMC_VGA_64MB 0x3
|
||||
#define ASPEED_SDMC_DRAM_SIZE(x) (x & 0x3)
|
||||
#define ASPEED_SDMC_DRAM_64MB 0x0
|
||||
#define ASPEED_SDMC_DRAM_128MB 0x1
|
||||
#define ASPEED_SDMC_DRAM_256MB 0x2
|
||||
#define ASPEED_SDMC_DRAM_512MB 0x3
|
||||
|
||||
#define ASPEED_SDMC_READONLY_MASK \
|
||||
(ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT | \
|
||||
@@ -100,22 +137,24 @@
|
||||
#define ASPEED_SDMC_CACHE_ENABLE (1 << 10) /* differs from AST2400 */
|
||||
#define ASPEED_SDMC_DRAM_TYPE (1 << 4) /* differs from AST2400 */
|
||||
|
||||
/* DRAM size definitions differs */
|
||||
#define ASPEED_SDMC_AST2500_128MB 0x0
|
||||
#define ASPEED_SDMC_AST2500_256MB 0x1
|
||||
#define ASPEED_SDMC_AST2500_512MB 0x2
|
||||
#define ASPEED_SDMC_AST2500_1024MB 0x3
|
||||
|
||||
#define ASPEED_SDMC_AST2600_256MB 0x0
|
||||
#define ASPEED_SDMC_AST2600_512MB 0x1
|
||||
#define ASPEED_SDMC_AST2600_1024MB 0x2
|
||||
#define ASPEED_SDMC_AST2600_2048MB 0x3
|
||||
|
||||
#define ASPEED_SDMC_AST2500_READONLY_MASK \
|
||||
(ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE | \
|
||||
ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT | \
|
||||
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
|
||||
|
||||
/*
|
||||
* Main Configuration register Ox10 (for Aspeed AST2700 SOC and higher)
|
||||
*
|
||||
*/
|
||||
#define ASPEED_SDMC_AST2700_RESERVED 0xFFFF2082 /* 31:16, 13, 7, 1 */
|
||||
#define ASPEED_SDMC_AST2700_DATA_SCRAMBLE (1 << 8)
|
||||
#define ASPEED_SDMC_AST2700_ECC_ENABLE (1 << 6)
|
||||
#define ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE (1 << 5)
|
||||
#define ASPEED_SDMC_AST2700_DRAM_SIZE(x) ((x & 0x7) << 2)
|
||||
|
||||
#define ASPEED_SDMC_AST2700_READONLY_MASK \
|
||||
(ASPEED_SDMC_AST2700_RESERVED)
|
||||
|
||||
static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
AspeedSDMCState *s = ASPEED_SDMC(opaque);
|
||||
@@ -231,7 +270,7 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
|
||||
AspeedSDMCState *s = ASPEED_SDMC(dev);
|
||||
AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
|
||||
|
||||
assert(asc->max_ram_size < 4 * GiB); /* 32-bit address bus */
|
||||
assert(asc->max_ram_size < 4 * GiB || asc->is_bus64bit);
|
||||
s->max_ram_size = asc->max_ram_size;
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sdmc_ops, s,
|
||||
@@ -241,8 +280,8 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
static const VMStateDescription vmstate_aspeed_sdmc = {
|
||||
.name = "aspeed.sdmc",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, AspeedSDMCState, ASPEED_SDMC_NR_REGS),
|
||||
VMSTATE_END_OF_LIST()
|
||||
@@ -251,6 +290,7 @@ static const VMStateDescription vmstate_aspeed_sdmc = {
|
||||
|
||||
static Property aspeed_sdmc_properties[] = {
|
||||
DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
|
||||
DEFINE_PROP_BOOL("unlocked", AspeedSDMCState, unlocked, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -311,7 +351,8 @@ static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg,
|
||||
uint32_t data)
|
||||
{
|
||||
if (reg == R_PROT) {
|
||||
s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
|
||||
s->regs[reg] =
|
||||
(data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -369,7 +410,8 @@ static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg,
|
||||
uint32_t data)
|
||||
{
|
||||
if (reg == R_PROT) {
|
||||
s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
|
||||
s->regs[reg] =
|
||||
(data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -449,8 +491,9 @@ static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
|
||||
}
|
||||
|
||||
if (s->regs[R_PROT] == PROT_HARDLOCKED) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system reset!\n",
|
||||
__func__);
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: SDMC is locked until system reset!\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -512,12 +555,145 @@ static const TypeInfo aspeed_2600_sdmc_info = {
|
||||
.class_init = aspeed_2600_sdmc_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_2700_sdmc_reset(DeviceState *dev)
|
||||
{
|
||||
AspeedSDMCState *s = ASPEED_SDMC(dev);
|
||||
AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
|
||||
|
||||
memset(s->regs, 0, sizeof(s->regs));
|
||||
|
||||
/* Set ram size bit and defaults values */
|
||||
s->regs[R_MAIN_CONF] = asc->compute_conf(s, 0);
|
||||
|
||||
if (s->unlocked) {
|
||||
s->regs[R_2700_PROT] = PROT_UNLOCKED;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t aspeed_2700_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
|
||||
{
|
||||
uint32_t fixed_conf = ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE |
|
||||
ASPEED_SDMC_AST2700_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
|
||||
|
||||
/* Make sure readonly bits are kept */
|
||||
data &= ~ASPEED_SDMC_AST2700_READONLY_MASK;
|
||||
|
||||
return data | fixed_conf;
|
||||
}
|
||||
|
||||
static void aspeed_2700_sdmc_write(AspeedSDMCState *s, uint32_t reg,
|
||||
uint32_t data)
|
||||
{
|
||||
/* Unprotected registers */
|
||||
switch (reg) {
|
||||
case R_INT_STATUS:
|
||||
case R_INT_CLEAR:
|
||||
case R_INT_MASK:
|
||||
case R_MAIN_STATUS:
|
||||
case R_ERR_STATUS:
|
||||
case R_ECC_FAIL_STATUS:
|
||||
case R_ECC_FAIL_ADDR:
|
||||
case R_PROT_REGION_LOCK_STATUS:
|
||||
case R_TEST_FAIL_ADDR:
|
||||
case R_TEST_FAIL_D0:
|
||||
case R_TEST_FAIL_D1:
|
||||
case R_TEST_FAIL_D2:
|
||||
case R_TEST_FAIL_D3:
|
||||
case R_DBG_STATUS:
|
||||
case R_PHY_INTERFACE_STATUS:
|
||||
case R_GRAPHIC_MEM_BASE_ADDR:
|
||||
case R_PORT0_INTERFACE_MONITOR0:
|
||||
case R_PORT0_INTERFACE_MONITOR1:
|
||||
case R_PORT0_INTERFACE_MONITOR2:
|
||||
case R_PORT1_INTERFACE_MONITOR0:
|
||||
case R_PORT1_INTERFACE_MONITOR1:
|
||||
case R_PORT1_INTERFACE_MONITOR2:
|
||||
case R_PORT2_INTERFACE_MONITOR0:
|
||||
case R_PORT2_INTERFACE_MONITOR1:
|
||||
case R_PORT2_INTERFACE_MONITOR2:
|
||||
case R_PORT3_INTERFACE_MONITOR0:
|
||||
case R_PORT3_INTERFACE_MONITOR1:
|
||||
case R_PORT3_INTERFACE_MONITOR2:
|
||||
case R_PORT4_INTERFACE_MONITOR0:
|
||||
case R_PORT4_INTERFACE_MONITOR1:
|
||||
case R_PORT4_INTERFACE_MONITOR2:
|
||||
case R_PORT5_INTERFACE_MONITOR0:
|
||||
case R_PORT5_INTERFACE_MONITOR1:
|
||||
case R_PORT5_INTERFACE_MONITOR2:
|
||||
s->regs[reg] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->regs[R_2700_PROT] == PROT_HARDLOCKED) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: SDMC is locked until system reset!\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reg != R_2700_PROT && s->regs[R_2700_PROT] == PROT_SOFTLOCKED) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: SDMC is locked! (write to MCR%02x blocked)\n",
|
||||
__func__, reg * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (reg) {
|
||||
case R_2700_PROT:
|
||||
if (data == PROT_2700_KEY_UNLOCK) {
|
||||
data = PROT_UNLOCKED;
|
||||
} else if (data == PROT_KEY_HARDLOCK) {
|
||||
data = PROT_HARDLOCKED;
|
||||
} else {
|
||||
data = PROT_SOFTLOCKED;
|
||||
}
|
||||
break;
|
||||
case R_MAIN_CONF:
|
||||
data = aspeed_2700_sdmc_compute_conf(s, data);
|
||||
break;
|
||||
case R_MAIN_STATUS:
|
||||
/* Will never return 'busy'. */
|
||||
data &= ~PHY_BUSY_STATE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static const uint64_t
|
||||
aspeed_2700_ram_sizes[] = { 256 * MiB, 512 * MiB, 1024 * MiB,
|
||||
2048 * MiB, 4096 * MiB, 8192 * MiB, 0};
|
||||
|
||||
static void aspeed_2700_sdmc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2700 SDRAM Memory Controller";
|
||||
dc->reset = aspeed_2700_sdmc_reset;
|
||||
|
||||
asc->is_bus64bit = true;
|
||||
asc->max_ram_size = 8 * GiB;
|
||||
asc->compute_conf = aspeed_2700_sdmc_compute_conf;
|
||||
asc->write = aspeed_2700_sdmc_write;
|
||||
asc->valid_ram_sizes = aspeed_2700_ram_sizes;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2700_sdmc_info = {
|
||||
.name = TYPE_ASPEED_2700_SDMC,
|
||||
.parent = TYPE_ASPEED_SDMC,
|
||||
.class_init = aspeed_2700_sdmc_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_sdmc_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_sdmc_info);
|
||||
type_register_static(&aspeed_2400_sdmc_info);
|
||||
type_register_static(&aspeed_2500_sdmc_info);
|
||||
type_register_static(&aspeed_2600_sdmc_info);
|
||||
type_register_static(&aspeed_2700_sdmc_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_sdmc_register_types);
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* ASPEED SLI Controller
|
||||
*
|
||||
* Copyright (C) 2024 ASPEED Technology Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/misc/aspeed_sli.h"
|
||||
#include "qapi/error.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define SLI_REGION_SIZE 0x500
|
||||
#define TO_REG(addr) ((addr) >> 2)
|
||||
|
||||
static uint64_t aspeed_sli_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
{
|
||||
AspeedSLIState *s = ASPEED_SLI(opaque);
|
||||
int reg = TO_REG(addr);
|
||||
|
||||
if (reg >= ARRAY_SIZE(s->regs)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
trace_aspeed_sli_read(addr, size, s->regs[reg]);
|
||||
return s->regs[reg];
|
||||
}
|
||||
|
||||
static void aspeed_sli_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
unsigned int size)
|
||||
{
|
||||
AspeedSLIState *s = ASPEED_SLI(opaque);
|
||||
int reg = TO_REG(addr);
|
||||
|
||||
if (reg >= ARRAY_SIZE(s->regs)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_sli_write(addr, size, data);
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static uint64_t aspeed_sliio_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
{
|
||||
AspeedSLIState *s = ASPEED_SLI(opaque);
|
||||
int reg = TO_REG(addr);
|
||||
|
||||
if (reg >= ARRAY_SIZE(s->regs)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
trace_aspeed_sliio_read(addr, size, s->regs[reg]);
|
||||
return s->regs[reg];
|
||||
}
|
||||
|
||||
static void aspeed_sliio_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
unsigned int size)
|
||||
{
|
||||
AspeedSLIState *s = ASPEED_SLI(opaque);
|
||||
int reg = TO_REG(addr);
|
||||
|
||||
if (reg >= ARRAY_SIZE(s->regs)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_sliio_write(addr, size, data);
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps aspeed_sli_ops = {
|
||||
.read = aspeed_sli_read,
|
||||
.write = aspeed_sli_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
};
|
||||
|
||||
static const MemoryRegionOps aspeed_sliio_ops = {
|
||||
.read = aspeed_sliio_read,
|
||||
.write = aspeed_sliio_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
};
|
||||
|
||||
static void aspeed_sli_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
AspeedSLIState *s = ASPEED_SLI(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sli_ops, s,
|
||||
TYPE_ASPEED_SLI, SLI_REGION_SIZE);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
static void aspeed_sliio_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
AspeedSLIState *s = ASPEED_SLI(dev);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sliio_ops, s,
|
||||
TYPE_ASPEED_SLI, SLI_REGION_SIZE);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
static void aspeed_sli_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->desc = "Aspeed SLI Controller";
|
||||
dc->realize = aspeed_sli_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_sli_info = {
|
||||
.name = TYPE_ASPEED_SLI,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(AspeedSLIState),
|
||||
.class_init = aspeed_sli_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void aspeed_2700_sli_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->desc = "AST2700 SLI Controller";
|
||||
}
|
||||
|
||||
static void aspeed_2700_sliio_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->desc = "AST2700 I/O SLI Controller";
|
||||
dc->realize = aspeed_sliio_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2700_sli_info = {
|
||||
.name = TYPE_ASPEED_2700_SLI,
|
||||
.parent = TYPE_ASPEED_SLI,
|
||||
.class_init = aspeed_2700_sli_class_init,
|
||||
};
|
||||
|
||||
static const TypeInfo aspeed_2700_sliio_info = {
|
||||
.name = TYPE_ASPEED_2700_SLIIO,
|
||||
.parent = TYPE_ASPEED_SLI,
|
||||
.class_init = aspeed_2700_sliio_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_sli_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_sli_info);
|
||||
type_register_static(&aspeed_2700_sli_info);
|
||||
type_register_static(&aspeed_2700_sliio_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_sli_register_types);
|
||||
+2
-1
@@ -136,7 +136,8 @@ system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
|
||||
'aspeed_sbc.c',
|
||||
'aspeed_sdmc.c',
|
||||
'aspeed_xdma.c',
|
||||
'aspeed_peci.c'))
|
||||
'aspeed_peci.c',
|
||||
'aspeed_sli.c'))
|
||||
|
||||
system_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
|
||||
system_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_rng.c'))
|
||||
|
||||
@@ -93,6 +93,10 @@ slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED 0x%04x"
|
||||
# aspeed_scu.c
|
||||
aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_scu_read(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_ast2700_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_ast2700_scu_read(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_ast2700_scuio_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_ast2700_scuio_read(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
|
||||
# mps2-scc.c
|
||||
mps2_scc_read(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
||||
@@ -351,3 +355,10 @@ djmemc_write(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRI
|
||||
# iosb.c
|
||||
iosb_read(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u"
|
||||
iosb_write(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u"
|
||||
|
||||
# aspeed_sli.c
|
||||
aspeed_sli_write(uint64_t offset, unsigned int size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_sli_read(uint64_t offset, unsigned int size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_sliio_write(uint64_t offset, unsigned int size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
aspeed_sliio_read(uint64_t offset, unsigned int size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
|
||||
|
||||
+327
-20
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -6,7 +6,7 @@ aspeed_smc_do_snoop(int cs, int index, int dummies, int data) "CS%d index:0x%x d
|
||||
aspeed_smc_flash_write(int cs, uint64_t addr, uint32_t size, uint64_t data, int mode) "CS%d @0x%" PRIx64 " size %u: 0x%" PRIx64" mode:%d"
|
||||
aspeed_smc_read(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64
|
||||
aspeed_smc_dma_checksum(uint32_t addr, uint32_t data) "0x%08x: 0x%08x"
|
||||
aspeed_smc_dma_rw(const char *dir, uint32_t flash_addr, uint32_t dram_addr, uint32_t size) "%s flash:@0x%08x dram:@0x%08x size:0x%08x"
|
||||
aspeed_smc_dma_rw(const char *dir, uint32_t flash_addr, uint64_t dram_addr, uint32_t size) "%s flash:@0x%08x dram:@0x%" PRIx64 " size:0x%08x"
|
||||
aspeed_smc_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64
|
||||
aspeed_smc_flash_select(int cs, const char *prefix) "CS%d %sselect"
|
||||
|
||||
|
||||
@@ -422,12 +422,36 @@ static const TypeInfo aspeed_1030_wdt_info = {
|
||||
.class_init = aspeed_1030_wdt_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_2700_wdt_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2700 Watchdog Controller";
|
||||
awc->iosize = 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_2700_wdt_info = {
|
||||
.name = TYPE_ASPEED_2700_WDT,
|
||||
.parent = TYPE_ASPEED_WDT,
|
||||
.instance_size = sizeof(AspeedWDTState),
|
||||
.class_init = aspeed_2700_wdt_class_init,
|
||||
};
|
||||
|
||||
static void wdt_aspeed_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_wdt_info);
|
||||
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_2700_wdt_info);
|
||||
type_register_static(&aspeed_1030_wdt_info);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "hw/cpu/a15mpcore.h"
|
||||
#include "hw/arm/armv7m.h"
|
||||
#include "hw/intc/aspeed_vic.h"
|
||||
#include "hw/intc/aspeed_intc.h"
|
||||
#include "hw/misc/aspeed_scu.h"
|
||||
#include "hw/adc/aspeed_adc.h"
|
||||
#include "hw/misc/aspeed_sdmc.h"
|
||||
@@ -26,6 +27,7 @@
|
||||
#include "hw/ssi/aspeed_smc.h"
|
||||
#include "hw/misc/aspeed_hace.h"
|
||||
#include "hw/misc/aspeed_sbc.h"
|
||||
#include "hw/misc/aspeed_sli.h"
|
||||
#include "hw/watchdog/wdt_aspeed.h"
|
||||
#include "hw/net/ftgmac100.h"
|
||||
#include "target/arm/cpu.h"
|
||||
@@ -38,11 +40,12 @@
|
||||
#include "hw/misc/aspeed_peci.h"
|
||||
#include "hw/fsi/aspeed_apb2opb.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/intc/arm_gicv3.h"
|
||||
|
||||
#define ASPEED_SPIS_NUM 2
|
||||
#define ASPEED_EHCIS_NUM 2
|
||||
#define ASPEED_WDTS_NUM 4
|
||||
#define ASPEED_CPUS_NUM 2
|
||||
#define ASPEED_WDTS_NUM 8
|
||||
#define ASPEED_CPUS_NUM 4
|
||||
#define ASPEED_MACS_NUM 4
|
||||
#define ASPEED_UARTS_NUM 13
|
||||
#define ASPEED_JTAG_NUM 2
|
||||
@@ -56,11 +59,13 @@ struct AspeedSoCState {
|
||||
MemoryRegion sram;
|
||||
MemoryRegion spi_boot_container;
|
||||
MemoryRegion spi_boot;
|
||||
AddressSpace dram_as;
|
||||
AspeedRtcState rtc;
|
||||
AspeedTimerCtrlState timerctrl;
|
||||
AspeedI2CState i2c;
|
||||
AspeedI3CState i3c;
|
||||
AspeedSCUState scu;
|
||||
AspeedSCUState scuio;
|
||||
AspeedHACEState hace;
|
||||
AspeedXDMAState xdma;
|
||||
AspeedADCState adc;
|
||||
@@ -68,6 +73,8 @@ struct AspeedSoCState {
|
||||
AspeedSMCState spi[ASPEED_SPIS_NUM];
|
||||
EHCISysBusState ehci[ASPEED_EHCIS_NUM];
|
||||
AspeedSBCState sbc;
|
||||
AspeedSLIState sli;
|
||||
AspeedSLIState sliio;
|
||||
MemoryRegion secsram;
|
||||
UnimplementedDeviceState sbc_unimplemented;
|
||||
AspeedSDMCState sdmc;
|
||||
@@ -117,6 +124,18 @@ struct Aspeed2600SoCState {
|
||||
#define TYPE_ASPEED2600_SOC "aspeed2600-soc"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(Aspeed2600SoCState, ASPEED2600_SOC)
|
||||
|
||||
struct Aspeed27x0SoCState {
|
||||
AspeedSoCState parent;
|
||||
|
||||
ARMCPU cpu[ASPEED_CPUS_NUM];
|
||||
AspeedINTCState intc;
|
||||
GICv3State gic;
|
||||
MemoryRegion dram_empty;
|
||||
};
|
||||
|
||||
#define TYPE_ASPEED27X0_SOC "aspeed27x0-soc"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0SoCState, ASPEED27X0_SOC)
|
||||
|
||||
struct Aspeed10x0SoCState {
|
||||
AspeedSoCState parent;
|
||||
|
||||
@@ -168,11 +187,13 @@ enum {
|
||||
ASPEED_DEV_UART13,
|
||||
ASPEED_DEV_VUART,
|
||||
ASPEED_DEV_FMC,
|
||||
ASPEED_DEV_SPI0,
|
||||
ASPEED_DEV_SPI1,
|
||||
ASPEED_DEV_SPI2,
|
||||
ASPEED_DEV_EHCI1,
|
||||
ASPEED_DEV_EHCI2,
|
||||
ASPEED_DEV_VIC,
|
||||
ASPEED_DEV_INTC,
|
||||
ASPEED_DEV_SDMC,
|
||||
ASPEED_DEV_SCU,
|
||||
ASPEED_DEV_ADC,
|
||||
@@ -222,6 +243,11 @@ enum {
|
||||
ASPEED_DEV_JTAG1,
|
||||
ASPEED_DEV_FSI1,
|
||||
ASPEED_DEV_FSI2,
|
||||
ASPEED_DEV_SCUIO,
|
||||
ASPEED_DEV_SLI,
|
||||
ASPEED_DEV_SLIIO,
|
||||
ASPEED_GIC_DIST,
|
||||
ASPEED_GIC_REDIST,
|
||||
};
|
||||
|
||||
qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* ASPEED INTC Controller
|
||||
*
|
||||
* Copyright (C) 2024 ASPEED Technology Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef ASPEED_INTC_H
|
||||
#define ASPEED_INTC_H
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
#include "qom/object.h"
|
||||
#include "hw/or-irq.h"
|
||||
|
||||
#define TYPE_ASPEED_INTC "aspeed.intc"
|
||||
#define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700"
|
||||
OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
|
||||
|
||||
#define ASPEED_INTC_NR_REGS (0x2000 >> 2)
|
||||
#define ASPEED_INTC_NR_INTS 9
|
||||
|
||||
struct AspeedINTCState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
MemoryRegion iomem;
|
||||
uint32_t regs[ASPEED_INTC_NR_REGS];
|
||||
OrIRQState orgates[ASPEED_INTC_NR_INTS];
|
||||
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];
|
||||
};
|
||||
|
||||
struct AspeedINTCClass {
|
||||
SysBusDeviceClass parent_class;
|
||||
|
||||
uint32_t num_lines;
|
||||
uint32_t num_ints;
|
||||
};
|
||||
|
||||
#endif /* ASPEED_INTC_H */
|
||||
@@ -19,10 +19,13 @@ 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_2700_SCU TYPE_ASPEED_SCU "-ast2700"
|
||||
#define TYPE_ASPEED_2700_SCUIO TYPE_ASPEED_SCU "io" "-ast2700"
|
||||
#define TYPE_ASPEED_1030_SCU TYPE_ASPEED_SCU "-ast1030"
|
||||
|
||||
#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
|
||||
#define ASPEED_AST2600_SCU_NR_REGS (0xE20 >> 2)
|
||||
#define ASPEED_AST2700_SCU_NR_REGS (0xE20 >> 2)
|
||||
|
||||
struct AspeedSCUState {
|
||||
/*< private >*/
|
||||
@@ -31,7 +34,7 @@ struct AspeedSCUState {
|
||||
/*< public >*/
|
||||
MemoryRegion iomem;
|
||||
|
||||
uint32_t regs[ASPEED_AST2600_SCU_NR_REGS];
|
||||
uint32_t regs[ASPEED_AST2700_SCU_NR_REGS];
|
||||
uint32_t silicon_rev;
|
||||
uint32_t hw_strap1;
|
||||
uint32_t hw_strap2;
|
||||
@@ -48,6 +51,9 @@ struct AspeedSCUState {
|
||||
#define AST2600_A3_SILICON_REV 0x05030303U
|
||||
#define AST1030_A0_SILICON_REV 0x80000000U
|
||||
#define AST1030_A1_SILICON_REV 0x80010000U
|
||||
#define AST2700_A0_SILICON_REV 0x06000103U
|
||||
#define AST2720_A0_SILICON_REV 0x06000203U
|
||||
#define AST2750_A0_SILICON_REV 0x06000003U
|
||||
|
||||
#define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04)
|
||||
|
||||
@@ -87,7 +93,8 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
|
||||
* 1. 2012/12/29 Ryan Chen Create
|
||||
*/
|
||||
|
||||
/* SCU08 Clock Selection Register
|
||||
/*
|
||||
* SCU08 Clock Selection Register
|
||||
*
|
||||
* 31 Enable Video Engine clock dynamic slow down
|
||||
* 30:28 Video Engine clock slow down setting
|
||||
@@ -109,7 +116,8 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
|
||||
*/
|
||||
#define SCU_CLK_GET_PCLK_DIV(x) (((x) >> 23) & 0x7)
|
||||
|
||||
/* SCU24 H-PLL Parameter Register (for Aspeed AST2400 SOC)
|
||||
/*
|
||||
* SCU24 H-PLL Parameter Register (for Aspeed AST2400 SOC)
|
||||
*
|
||||
* 18 H-PLL parameter selection
|
||||
* 0: Select H-PLL by strapping resistors
|
||||
@@ -127,7 +135,8 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
|
||||
#define SCU_AST2400_H_PLL_BYPASS_EN (0x1 << 17)
|
||||
#define SCU_AST2400_H_PLL_OFF (0x1 << 16)
|
||||
|
||||
/* SCU24 H-PLL Parameter Register (for Aspeed AST2500 SOC)
|
||||
/*
|
||||
* SCU24 H-PLL Parameter Register (for Aspeed AST2500 SOC)
|
||||
*
|
||||
* 21 Enable H-PLL reset
|
||||
* 20 Enable H-PLL bypass mode
|
||||
@@ -144,7 +153,8 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
|
||||
#define SCU_H_PLL_BYPASS_EN (0x1 << 20)
|
||||
#define SCU_H_PLL_OFF (0x1 << 19)
|
||||
|
||||
/* SCU70 Hardware Strapping Register definition (for Aspeed AST2400 SOC)
|
||||
/*
|
||||
* SCU70 Hardware Strapping Register definition (for Aspeed AST2400 SOC)
|
||||
*
|
||||
* 31:29 Software defined strapping registers
|
||||
* 28:27 DRAM size setting (for VGA driver use)
|
||||
@@ -361,4 +371,31 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
|
||||
*/
|
||||
#define SCU_AST1030_CLK_GET_PCLK_DIV(x) (((x) >> 8) & 0xf)
|
||||
|
||||
/*
|
||||
* SCU280 Clock Selection 1 Register (for Aspeed AST2700 SCUIO)
|
||||
*
|
||||
* 31:29 MHCLK_DIV
|
||||
* 28 Reserved
|
||||
* 27:25 RGMIICLK_DIV
|
||||
* 24 Reserved
|
||||
* 23:21 RMIICLK_DIV
|
||||
* 20:18 PCLK_DIV
|
||||
* 17:14 SDCLK_DIV
|
||||
* 13 SDCLK_SEL
|
||||
* 12 UART13CLK_SEL
|
||||
* 11 UART12CLK_SEL
|
||||
* 10 UART11CLK_SEL
|
||||
* 9 UART10CLK_SEL
|
||||
* 8 UART9CLK_SEL
|
||||
* 7 UART8CLK_SEL
|
||||
* 6 UART7CLK_SEL
|
||||
* 5 UART6CLK_SEL
|
||||
* 4 UARTDBCLK_SEL
|
||||
* 3 UART4CLK_SEL
|
||||
* 2 UART3CLK_SEL
|
||||
* 1 UART2CLK_SEL
|
||||
* 0 UART1CLK_SEL
|
||||
*/
|
||||
#define SCUIO_AST2700_CLK_GET_PCLK_DIV(x) (((x) >> 18) & 0x7)
|
||||
|
||||
#endif /* ASPEED_SCU_H */
|
||||
|
||||
@@ -17,6 +17,7 @@ OBJECT_DECLARE_TYPE(AspeedSDMCState, AspeedSDMCClass, ASPEED_SDMC)
|
||||
#define TYPE_ASPEED_2400_SDMC TYPE_ASPEED_SDMC "-ast2400"
|
||||
#define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC "-ast2500"
|
||||
#define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC "-ast2600"
|
||||
#define TYPE_ASPEED_2700_SDMC TYPE_ASPEED_SDMC "-ast2700"
|
||||
|
||||
/*
|
||||
* SDMC has 174 documented registers. In addition the u-boot device tree
|
||||
@@ -29,7 +30,7 @@ OBJECT_DECLARE_TYPE(AspeedSDMCState, AspeedSDMCClass, ASPEED_SDMC)
|
||||
* time, and the other is in the DDR-PHY IP which is used during DDR-PHY
|
||||
* training.
|
||||
*/
|
||||
#define ASPEED_SDMC_NR_REGS (0x500 >> 2)
|
||||
#define ASPEED_SDMC_NR_REGS (0x1000 >> 2)
|
||||
|
||||
struct AspeedSDMCState {
|
||||
/*< private >*/
|
||||
@@ -41,6 +42,7 @@ struct AspeedSDMCState {
|
||||
uint32_t regs[ASPEED_SDMC_NR_REGS];
|
||||
uint64_t ram_size;
|
||||
uint64_t max_ram_size;
|
||||
bool unlocked;
|
||||
};
|
||||
|
||||
|
||||
@@ -51,6 +53,7 @@ struct AspeedSDMCClass {
|
||||
const uint64_t *valid_ram_sizes;
|
||||
uint32_t (*compute_conf)(AspeedSDMCState *s, uint32_t data);
|
||||
void (*write)(AspeedSDMCState *s, uint32_t reg, uint32_t data);
|
||||
bool is_bus64bit;
|
||||
};
|
||||
|
||||
#endif /* ASPEED_SDMC_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user