target-arm queue:
* Update copyright dates to 2022 * hw/armv7m: Fix broken VMStateDescription * hw/char/exynos4210_uart: Fix crash on trying to load VM state * rtc: Move RTC function prototypes to their own header * xlnx-versal-virt: Support PMC SLCR * xlnx-versal-virt: Support OSPI flash memory controller * scripts: Explain the difference between linux-headers and standard-headers * target/arm: Log CPU index in 'Taking exception' log * arm_gicv3_its: Various bugfixes and cleanups * arm_gicv3_its: Implement the missing MOVI and MOVALL commands * ast2600: Fix address mapping of second SPI controller * target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmH0C+AZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3gG4D/9biXPVdkOd7lIslRX0ihRg AZkZrMNk6VF/MW6xJNVWWd+44cyjLopFqF5dS+Vjebt7pEtZvxY0K5mYmzClk6lg 2U89gWuLEDJDKNVfKAmsmj24Os4xRj4sJPq/Mee8lsBdOAwEQ3C36p0RnWGBcTJN 9VfzRMSGvdjQFJjGAaro078zrA1Q11msA4BbLht+YGTE1aeyryyfF/qGSRlrlTn8 +r0ZWBD4ttz8IsqSLtnpQvT6EbL79w0jBywVauVzCOGQGpti3HdHJNYR7cKgTMja Hffx6f6iv/O4SAUUGS0WMWdfW/MEVxOFxJ7Zc2twGqDMuVWlFiLT0X1MZuHi0FpG CjbhTsvJIrKom1Ib+LPkWscrlHHEf0cvME0WokErLOJDXvbqKj04oOkpQmqUIv0+ 5j7o4mlQFuLXIyzcrBZxmwT/Ekg8KZA8aUR0ddUd0vBmGMdO2En/c4Qr/x4H2gXH HL/18oPRaSV6mP08mxcda+hJ9m5MC+7l0+KKoDfaPM9d4hl5StI0zTlH+5ffbK+m UWthMnrrZw2ZU8AzGPZxOAW5K5S3XOso5Z9credkRGuSDriaGuNY0s5gSvNawZGe ioIrUl50t+5/o2+tba7FA2ePiGeC9/zS671zHG9Rdpe86JpJXCzWO7OYiVulV3Yu dmQYrhgnUqNjh3SAiXUFVA== =m7N5 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220128' into staging target-arm queue: * Update copyright dates to 2022 * hw/armv7m: Fix broken VMStateDescription * hw/char/exynos4210_uart: Fix crash on trying to load VM state * rtc: Move RTC function prototypes to their own header * xlnx-versal-virt: Support PMC SLCR * xlnx-versal-virt: Support OSPI flash memory controller * scripts: Explain the difference between linux-headers and standard-headers * target/arm: Log CPU index in 'Taking exception' log * arm_gicv3_its: Various bugfixes and cleanups * arm_gicv3_its: Implement the missing MOVI and MOVALL commands * ast2600: Fix address mapping of second SPI controller * target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp # gpg: Signature made Fri 28 Jan 2022 15:29:36 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20220128: (32 commits) target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp hw/arm: ast2600: Fix address mapping of second SPI controller hw/intc/arm_gicv3_its: Implement MOVI hw/intc/arm_gicv3_its: Implement MOVALL hw/intc/arm_gicv3_its: Check table bounds against correct limit hw/intc/arm_gicv3_its: Make GITS_BASER<n> RAZ/WI for unimplemented registers hw/intc/arm_gicv3_its: Provide read accessor for translation_ops hw/intc/arm_gicv3: Set GICR_CTLR.CES if LPIs are supported hw/intc/arm_gicv3_redist: Remove unnecessary zero checks hw/intc/arm_gicv3_its: Sort ITS command list into numeric order hw/intc/arm_gicv3: Honour GICD_CTLR.EnableGrp1NS for LPIs hw/intc/arm_gicv3_its: Don't clear GITS_CWRITER on writes to GITS_CBASER hw/intc/arm_gicv3_its: Don't clear GITS_CREADR when GITS_CTLR.ENABLED is set hw/intc/arm_gicv3: Initialise dma_as in GIC, not ITS hw/intc/arm_gicv3_its: Add tracepoints target/arm: Log CPU index in 'Taking exception' log scripts: Explain the difference between linux-headers and standard-headers MAINTAINERS: Remove myself (for raspi). MAINTAINERS: Add an entry for Xilinx Versal OSPI hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
95a6af2a00
@ -818,7 +818,6 @@ F: docs/system/arm/palm.rst
|
||||
|
||||
Raspberry Pi
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Andrew Baumann <Andrew.Baumann@microsoft.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
@ -958,6 +957,12 @@ F: hw/display/dpcd.c
|
||||
F: include/hw/display/dpcd.h
|
||||
F: docs/system/arm/xlnx-versal-virt.rst
|
||||
|
||||
Xilinx Versal OSPI
|
||||
M: Francisco Iglesias <francisco.iglesias@xilinx.com>
|
||||
S: Maintained
|
||||
F: hw/ssi/xlnx-versal-ospi.c
|
||||
F: include/hw/ssi/xlnx-versal-ospi.h
|
||||
|
||||
ARM ACPI Subsystem
|
||||
M: Shannon Zhao <shannon.zhaosl@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
|
@ -98,7 +98,7 @@ default_role = 'any'
|
||||
|
||||
# General information about the project.
|
||||
project = u'QEMU'
|
||||
copyright = u'2021, The QEMU Project Developers'
|
||||
copyright = u'2022, The QEMU Project Developers'
|
||||
author = u'The QEMU Project Developers'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
|
@ -520,8 +520,8 @@ static const VMStateDescription vmstate_armv7m = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_CLOCK(refclk, SysTickState),
|
||||
VMSTATE_CLOCK(cpuclk, SysTickState),
|
||||
VMSTATE_CLOCK(refclk, ARMv7MState),
|
||||
VMSTATE_CLOCK(cpuclk, ARMv7MState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
|
||||
[ASPEED_DEV_PWM] = 0x1E610000,
|
||||
[ASPEED_DEV_FMC] = 0x1E620000,
|
||||
[ASPEED_DEV_SPI1] = 0x1E630000,
|
||||
[ASPEED_DEV_SPI2] = 0x1E641000,
|
||||
[ASPEED_DEV_SPI2] = 0x1E631000,
|
||||
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
|
||||
[ASPEED_DEV_EHCI2] = 0x1E6A3000,
|
||||
[ASPEED_DEV_MII1] = 0x1E650000,
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/hw.h"
|
||||
@ -35,6 +34,7 @@
|
||||
#include "sysemu/qtest.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "qemu/range.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/error.h"
|
||||
@ -27,6 +26,7 @@
|
||||
#include "chardev/char-fe.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qom/object.h"
|
||||
|
@ -28,7 +28,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
@ -41,6 +40,7 @@
|
||||
#include "chardev/char-fe.h"
|
||||
#include "chardev/char-serial.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "hw/ssi/ssi.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
@ -25,6 +25,8 @@
|
||||
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
|
||||
|
||||
#define XLNX_VERSAL_NUM_OSPI_FLASH 4
|
||||
|
||||
struct VersalVirt {
|
||||
MachineState parent_obj;
|
||||
|
||||
@ -365,7 +367,7 @@ static void fdt_add_bbram_node(VersalVirt *s)
|
||||
qemu_fdt_add_subnode(s->fdt, name);
|
||||
|
||||
qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
|
||||
GIC_FDT_IRQ_TYPE_SPI, VERSAL_BBRAM_APB_IRQ_0,
|
||||
GIC_FDT_IRQ_TYPE_SPI, VERSAL_PMC_APB_IRQ,
|
||||
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
|
||||
qemu_fdt_setprop(s->fdt, name, "interrupt-names",
|
||||
interrupt_names, sizeof(interrupt_names));
|
||||
@ -691,6 +693,27 @@ static void versal_virt_init(MachineState *machine)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
|
||||
BusState *spi_bus;
|
||||
DeviceState *flash_dev;
|
||||
qemu_irq cs_line;
|
||||
DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
|
||||
|
||||
spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
|
||||
|
||||
flash_dev = qdev_new("mt35xu01g");
|
||||
if (dinfo) {
|
||||
qdev_prop_set_drive_err(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
|
||||
i + 1, cs_line);
|
||||
}
|
||||
}
|
||||
|
||||
static void versal_virt_machine_instance_init(Object *obj)
|
||||
|
@ -21,10 +21,15 @@
|
||||
#include "kvm_arm.h"
|
||||
#include "hw/misc/unimp.h"
|
||||
#include "hw/arm/xlnx-versal.h"
|
||||
#include "qemu/log.h"
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
|
||||
#define GEM_REVISION 0x40070106
|
||||
|
||||
#define VERSAL_NUM_PMC_APB_IRQS 3
|
||||
#define NUM_OSPI_IRQ_LINES 3
|
||||
|
||||
static void versal_create_apu_cpus(Versal *s)
|
||||
{
|
||||
int i;
|
||||
@ -260,6 +265,26 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
|
||||
}
|
||||
}
|
||||
|
||||
static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
|
||||
{
|
||||
DeviceState *orgate;
|
||||
|
||||
/*
|
||||
* The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
|
||||
* models:
|
||||
* - RTC
|
||||
* - BBRAM
|
||||
* - PMC SLCR
|
||||
*/
|
||||
object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
|
||||
&s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
|
||||
orgate = DEVICE(&s->pmc.apb_irq_orgate);
|
||||
object_property_set_int(OBJECT(orgate),
|
||||
"num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal);
|
||||
qdev_realize(orgate, NULL, &error_fatal);
|
||||
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
|
||||
}
|
||||
|
||||
static void versal_create_rtc(Versal *s, qemu_irq *pic)
|
||||
{
|
||||
SysBusDevice *sbd;
|
||||
@ -277,7 +302,8 @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
|
||||
* TODO: Connect the ALARM and SECONDS interrupts once our RTC model
|
||||
* supports them.
|
||||
*/
|
||||
sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
|
||||
sysbus_connect_irq(sbd, 1,
|
||||
qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0));
|
||||
}
|
||||
|
||||
static void versal_create_xrams(Versal *s, qemu_irq *pic)
|
||||
@ -328,7 +354,8 @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
|
||||
sysbus_realize(sbd, &error_fatal);
|
||||
memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
|
||||
sysbus_mmio_get_region(sbd, 0));
|
||||
sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
|
||||
sysbus_connect_irq(sbd, 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
|
||||
}
|
||||
|
||||
static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
|
||||
@ -369,6 +396,114 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
|
||||
}
|
||||
|
||||
static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
|
||||
{
|
||||
SysBusDevice *sbd;
|
||||
|
||||
object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
|
||||
TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
|
||||
|
||||
sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
|
||||
sysbus_realize(sbd, &error_fatal);
|
||||
|
||||
memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
|
||||
sysbus_mmio_get_region(sbd, 0));
|
||||
|
||||
sysbus_connect_irq(sbd, 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
|
||||
}
|
||||
|
||||
static void versal_create_ospi(Versal *s, qemu_irq *pic)
|
||||
{
|
||||
SysBusDevice *sbd;
|
||||
MemoryRegion *mr_dac;
|
||||
qemu_irq ospi_mux_sel;
|
||||
DeviceState *orgate;
|
||||
|
||||
memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
|
||||
"versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);
|
||||
|
||||
object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
|
||||
TYPE_XILINX_VERSAL_OSPI);
|
||||
|
||||
mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
|
||||
memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);
|
||||
|
||||
/* Create the OSPI destination DMA */
|
||||
object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
|
||||
&s->pmc.iou.ospi.dma_dst,
|
||||
TYPE_XLNX_CSU_DMA);
|
||||
|
||||
object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
|
||||
"dma", OBJECT(get_system_memory()),
|
||||
&error_abort);
|
||||
|
||||
sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
|
||||
sysbus_realize(sbd, &error_fatal);
|
||||
|
||||
memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
|
||||
sysbus_mmio_get_region(sbd, 0));
|
||||
|
||||
/* Create the OSPI source DMA */
|
||||
object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
|
||||
&s->pmc.iou.ospi.dma_src,
|
||||
TYPE_XLNX_CSU_DMA);
|
||||
|
||||
object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
|
||||
false, &error_abort);
|
||||
|
||||
object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
|
||||
"dma", OBJECT(mr_dac), &error_abort);
|
||||
|
||||
object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
|
||||
"stream-connected-dma",
|
||||
OBJECT(&s->pmc.iou.ospi.dma_dst),
|
||||
&error_abort);
|
||||
|
||||
sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
|
||||
sysbus_realize(sbd, &error_fatal);
|
||||
|
||||
memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
|
||||
sysbus_mmio_get_region(sbd, 0));
|
||||
|
||||
/* Realize the OSPI */
|
||||
object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src",
|
||||
OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort);
|
||||
|
||||
sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi);
|
||||
sysbus_realize(sbd, &error_fatal);
|
||||
|
||||
memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
|
||||
sysbus_mmio_get_region(sbd, 0));
|
||||
|
||||
memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
|
||||
&s->pmc.iou.ospi.linear_mr);
|
||||
|
||||
/* ospi_mux_sel */
|
||||
ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi),
|
||||
"ospi-mux-sel", 0);
|
||||
qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0,
|
||||
ospi_mux_sel);
|
||||
|
||||
/* OSPI irq */
|
||||
object_initialize_child(OBJECT(s), "ospi-irq-orgate",
|
||||
&s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ);
|
||||
object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate),
|
||||
"num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);
|
||||
|
||||
orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate);
|
||||
qdev_realize(orgate, NULL, &error_fatal);
|
||||
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0,
|
||||
qdev_get_gpio_in(orgate, 0));
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0,
|
||||
qdev_get_gpio_in(orgate, 1));
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0,
|
||||
qdev_get_gpio_in(orgate, 2));
|
||||
|
||||
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
|
||||
}
|
||||
|
||||
/* This takes the board allocated linear DDR memory and creates aliases
|
||||
* for each split DDR range/aperture on the Versal address map.
|
||||
*/
|
||||
@ -425,8 +560,31 @@ static void versal_unimp_area(Versal *s, const char *name,
|
||||
memory_region_add_subregion(mr, base, mr_dev);
|
||||
}
|
||||
|
||||
static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"Selecting between enabling SD mode or eMMC mode on "
|
||||
"controller %d is not yet implemented\n", n);
|
||||
}
|
||||
|
||||
static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"Selecting between enabling the QSPI or OSPI linear address "
|
||||
"region is not yet implemented\n");
|
||||
}
|
||||
|
||||
static void versal_unimp_irq_parity_imr(void *opaque, int n, int level)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"PMC SLCR parity interrupt behaviour "
|
||||
"is not yet implemented\n");
|
||||
}
|
||||
|
||||
static void versal_unimp(Versal *s)
|
||||
{
|
||||
qemu_irq gpio_in;
|
||||
|
||||
versal_unimp_area(s, "psm", &s->mr_ps,
|
||||
MM_PSM_START, MM_PSM_END - MM_PSM_START);
|
||||
versal_unimp_area(s, "crl", &s->mr_ps,
|
||||
@ -441,6 +599,31 @@ static void versal_unimp(Versal *s)
|
||||
MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
|
||||
versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
|
||||
MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);
|
||||
|
||||
qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel,
|
||||
"sd-emmc-sel-dummy", 2);
|
||||
qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel,
|
||||
"qspi-ospi-mux-sel-dummy", 1);
|
||||
qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr,
|
||||
"irq-parity-imr-dummy", 1);
|
||||
|
||||
gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0);
|
||||
qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0,
|
||||
gpio_in);
|
||||
|
||||
gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1);
|
||||
qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1,
|
||||
gpio_in);
|
||||
|
||||
gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0);
|
||||
qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
|
||||
"qspi-ospi-mux-sel", 0,
|
||||
gpio_in);
|
||||
|
||||
gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0);
|
||||
qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
|
||||
SYSBUS_DEVICE_GPIO_IRQ, 0,
|
||||
gpio_in);
|
||||
}
|
||||
|
||||
static void versal_realize(DeviceState *dev, Error **errp)
|
||||
@ -455,10 +638,13 @@ static void versal_realize(DeviceState *dev, Error **errp)
|
||||
versal_create_gems(s, pic);
|
||||
versal_create_admas(s, pic);
|
||||
versal_create_sds(s, pic);
|
||||
versal_create_pmc_apb_irq_orgate(s, pic);
|
||||
versal_create_rtc(s, pic);
|
||||
versal_create_xrams(s, pic);
|
||||
versal_create_bbram(s, pic);
|
||||
versal_create_efuse(s, pic);
|
||||
versal_create_pmc_iou_slcr(s, pic);
|
||||
versal_create_ospi(s, pic);
|
||||
versal_map_ddr(s);
|
||||
versal_unimp(s);
|
||||
|
||||
|
@ -255,6 +255,8 @@ static const FlashPartInfo known_devices[] = {
|
||||
{ INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
|
||||
{ INFO("n25q512ax3", 0x20ba20, 0x1000, 64 << 10, 1024, ER_4K) },
|
||||
{ INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
|
||||
{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
|
||||
ER_4K | ER_32K, 2) },
|
||||
{ INFO_STACKED("n25q00", 0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
|
||||
{ INFO_STACKED("n25q00a", 0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
|
||||
{ INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
|
||||
|
@ -628,7 +628,6 @@ static const VMStateDescription vmstate_exynos4210_uart_fifo = {
|
||||
.name = "exynos4210.uart.fifo",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.post_load = exynos4210_uart_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(sp, Exynos4210UartFIFO),
|
||||
VMSTATE_UINT32(rp, Exynos4210UartFIFO),
|
||||
@ -641,6 +640,7 @@ static const VMStateDescription vmstate_exynos4210_uart = {
|
||||
.name = "exynos4210.uart",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.post_load = exynos4210_uart_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_STRUCT(rx, Exynos4210UartState, 1,
|
||||
vmstate_exynos4210_uart_fifo, Exynos4210UartFIFO),
|
||||
|
@ -472,6 +472,20 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, uint64_t val)
|
||||
return val & R_ADDR_MSB_ADDR_MSB_MASK;
|
||||
}
|
||||
|
||||
static MemTxResult xlnx_csu_dma_class_read(XlnxCSUDMA *s, hwaddr addr,
|
||||
uint32_t len)
|
||||
{
|
||||
RegisterInfo *reg = &s->regs_info[R_SIZE];
|
||||
uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
|
||||
|
||||
s->regs[R_ADDR] = addr;
|
||||
s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
|
||||
|
||||
register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
|
||||
|
||||
return (s->regs[R_SIZE] == 0) ? MEMTX_OK : MEMTX_ERROR;
|
||||
}
|
||||
|
||||
static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
|
||||
#define DMACH_REGINFO(NAME, snd) \
|
||||
(const RegisterAccessInfo []) { \
|
||||
@ -696,6 +710,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
|
||||
XlnxCSUDMAClass *xcdc = XLNX_CSU_DMA_CLASS(klass);
|
||||
|
||||
dc->reset = xlnx_csu_dma_reset;
|
||||
dc->realize = xlnx_csu_dma_realize;
|
||||
@ -704,6 +719,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
ssc->push = xlnx_csu_dma_stream_push;
|
||||
ssc->can_push = xlnx_csu_dma_stream_can_push;
|
||||
|
||||
xcdc->read = xlnx_csu_dma_class_read;
|
||||
}
|
||||
|
||||
static void xlnx_csu_dma_init(Object *obj)
|
||||
|
@ -166,6 +166,7 @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
|
||||
}
|
||||
|
||||
if ((cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) && cs->gic->lpi_enable &&
|
||||
(cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) &&
|
||||
(cs->hpplpi.prio != 0xff)) {
|
||||
if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio)) {
|
||||
cs->hppi.irq = cs->hpplpi.irq;
|
||||
|
@ -357,6 +357,11 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->lpi_enable) {
|
||||
address_space_init(&s->dma_as, s->dma,
|
||||
"gicv3-its-sysmem");
|
||||
}
|
||||
|
||||
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
@ -424,6 +429,10 @@ static void arm_gicv3_common_reset(DeviceState *dev)
|
||||
|
||||
cs->level = 0;
|
||||
cs->gicr_ctlr = 0;
|
||||
if (s->lpi_enable) {
|
||||
/* Our implementation supports clearing GICR_CTLR.EnableLPIs */
|
||||
cs->gicr_ctlr |= GICR_CTLR_CES;
|
||||
}
|
||||
cs->gicr_statusr[GICV3_S] = 0;
|
||||
cs->gicr_statusr[GICV3_NS] = 0;
|
||||
cs->gicr_waker = GICR_WAKER_ProcessorSleep | GICR_WAKER_ChildrenAsleep;
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "trace.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/intc/arm_gicv3_its_common.h"
|
||||
#include "gicv3_internal.h"
|
||||
@ -255,10 +256,10 @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
|
||||
|
||||
eventid = (value & EVENTID_MASK);
|
||||
|
||||
if (devid >= s->dt.num_ids) {
|
||||
if (devid >= s->dt.num_entries) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: devid %d>=%d",
|
||||
__func__, devid, s->dt.num_ids);
|
||||
__func__, devid, s->dt.num_entries);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
@ -299,7 +300,7 @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
if (icid >= s->ct.num_ids) {
|
||||
if (icid >= s->ct.num_entries) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
|
||||
__func__, icid);
|
||||
@ -383,10 +384,10 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
|
||||
|
||||
icid = value & ICID_MASK;
|
||||
|
||||
if (devid >= s->dt.num_ids) {
|
||||
if (devid >= s->dt.num_entries) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: devid %d>=%d",
|
||||
__func__, devid, s->dt.num_ids);
|
||||
__func__, devid, s->dt.num_entries);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
@ -399,7 +400,7 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
|
||||
num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
|
||||
num_intids = 1ULL << (GICD_TYPER_IDBITS + 1);
|
||||
|
||||
if ((icid >= s->ct.num_ids)
|
||||
if ((icid >= s->ct.num_entries)
|
||||
|| !dte_valid || (eventid >= num_eventids) ||
|
||||
(((pIntid < GICV3_LPI_INTID_START) || (pIntid >= num_intids)) &&
|
||||
(pIntid != INTID_SPURIOUS))) {
|
||||
@ -484,7 +485,7 @@ static ItsCmdResult process_mapc(GICv3ITSState *s, uint32_t offset)
|
||||
|
||||
valid = (value & CMD_FIELD_VALID_MASK);
|
||||
|
||||
if ((icid >= s->ct.num_ids) || (rdbase >= s->gicv3->num_cpu)) {
|
||||
if ((icid >= s->ct.num_entries) || (rdbase >= s->gicv3->num_cpu)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"ITS MAPC: invalid collection table attributes "
|
||||
"icid %d rdbase %" PRIu64 "\n", icid, rdbase);
|
||||
@ -565,7 +566,7 @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value,
|
||||
|
||||
valid = (value & CMD_FIELD_VALID_MASK);
|
||||
|
||||
if ((devid >= s->dt.num_ids) ||
|
||||
if ((devid >= s->dt.num_entries) ||
|
||||
(size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"ITS MAPD: invalid device table attributes "
|
||||
@ -581,6 +582,201 @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value,
|
||||
return update_dte(s, devid, valid, size, itt_addr) ? CMD_CONTINUE : CMD_STALL;
|
||||
}
|
||||
|
||||
static ItsCmdResult process_movall(GICv3ITSState *s, uint64_t value,
|
||||
uint32_t offset)
|
||||
{
|
||||
AddressSpace *as = &s->gicv3->dma_as;
|
||||
MemTxResult res = MEMTX_OK;
|
||||
uint64_t rd1, rd2;
|
||||
|
||||
/* No fields in dwords 0 or 1 */
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
value = address_space_ldq_le(as, s->cq.base_addr + offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
|
||||
rd1 = FIELD_EX64(value, MOVALL_2, RDBASE1);
|
||||
if (rd1 >= s->gicv3->num_cpu) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: RDBASE1 %" PRId64
|
||||
" out of range (must be less than %d)\n",
|
||||
__func__, rd1, s->gicv3->num_cpu);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
value = address_space_ldq_le(as, s->cq.base_addr + offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
|
||||
rd2 = FIELD_EX64(value, MOVALL_3, RDBASE2);
|
||||
if (rd2 >= s->gicv3->num_cpu) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: RDBASE2 %" PRId64
|
||||
" out of range (must be less than %d)\n",
|
||||
__func__, rd2, s->gicv3->num_cpu);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
if (rd1 == rd2) {
|
||||
/* Move to same target must succeed as a no-op */
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
/* Move all pending LPIs from redistributor 1 to redistributor 2 */
|
||||
gicv3_redist_movall_lpis(&s->gicv3->cpu[rd1], &s->gicv3->cpu[rd2]);
|
||||
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
static ItsCmdResult process_movi(GICv3ITSState *s, uint64_t value,
|
||||
uint32_t offset)
|
||||
{
|
||||
AddressSpace *as = &s->gicv3->dma_as;
|
||||
MemTxResult res = MEMTX_OK;
|
||||
uint32_t devid, eventid, intid;
|
||||
uint16_t old_icid, new_icid;
|
||||
uint64_t old_cte, new_cte;
|
||||
uint64_t old_rdbase, new_rdbase;
|
||||
uint64_t dte;
|
||||
bool dte_valid, ite_valid, cte_valid;
|
||||
uint64_t num_eventids;
|
||||
IteEntry ite = {};
|
||||
|
||||
devid = FIELD_EX64(value, MOVI_0, DEVICEID);
|
||||
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
value = address_space_ldq_le(as, s->cq.base_addr + offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
eventid = FIELD_EX64(value, MOVI_1, EVENTID);
|
||||
|
||||
offset += NUM_BYTES_IN_DW;
|
||||
value = address_space_ldq_le(as, s->cq.base_addr + offset,
|
||||
MEMTXATTRS_UNSPECIFIED, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
new_icid = FIELD_EX64(value, MOVI_2, ICID);
|
||||
|
||||
if (devid >= s->dt.num_entries) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: devid %d>=%d",
|
||||
__func__, devid, s->dt.num_entries);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
dte = get_dte(s, devid, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
|
||||
dte_valid = FIELD_EX64(dte, DTE, VALID);
|
||||
if (!dte_valid) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: "
|
||||
"invalid dte: %"PRIx64" for %d\n",
|
||||
__func__, dte, devid);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
|
||||
if (eventid >= num_eventids) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: eventid %d >= %"
|
||||
PRId64 "\n",
|
||||
__func__, eventid, num_eventids);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
ite_valid = get_ite(s, eventid, dte, &old_icid, &intid, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
|
||||
if (!ite_valid) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: invalid ITE\n",
|
||||
__func__);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
if (old_icid >= s->ct.num_entries) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
|
||||
__func__, old_icid);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
if (new_icid >= s->ct.num_entries) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: ICID 0x%x\n",
|
||||
__func__, new_icid);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
cte_valid = get_cte(s, old_icid, &old_cte, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
if (!cte_valid) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: "
|
||||
"invalid cte: %"PRIx64"\n",
|
||||
__func__, old_cte);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
cte_valid = get_cte(s, new_icid, &new_cte, &res);
|
||||
if (res != MEMTX_OK) {
|
||||
return CMD_STALL;
|
||||
}
|
||||
if (!cte_valid) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid command attributes: "
|
||||
"invalid cte: %"PRIx64"\n",
|
||||
__func__, new_cte);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
old_rdbase = FIELD_EX64(old_cte, CTE, RDBASE);
|
||||
if (old_rdbase >= s->gicv3->num_cpu) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: CTE has invalid rdbase 0x%"PRIx64"\n",
|
||||
__func__, old_rdbase);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
new_rdbase = FIELD_EX64(new_cte, CTE, RDBASE);
|
||||
if (new_rdbase >= s->gicv3->num_cpu) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: CTE has invalid rdbase 0x%"PRIx64"\n",
|
||||
__func__, new_rdbase);
|
||||
return CMD_CONTINUE;
|
||||
}
|
||||
|
||||
if (old_rdbase != new_rdbase) {
|
||||
/* Move the LPI from the old redistributor to the new one */
|
||||
gicv3_redist_mov_lpi(&s->gicv3->cpu[old_rdbase],
|
||||
&s->gicv3->cpu[new_rdbase],
|
||||
intid);
|
||||
}
|
||||
|
||||
/* Update the ICID field in the interrupt translation table entry */
|
||||
ite.itel = FIELD_DP64(ite.itel, ITE_L, VALID, 1);
|
||||
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTTYPE, ITE_INTTYPE_PHYSICAL);
|
||||
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, intid);
|
||||
ite.itel = FIELD_DP64(ite.itel, ITE_L, DOORBELL, INTID_SPURIOUS);
|
||||
ite.iteh = FIELD_DP32(ite.iteh, ITE_H, ICID, new_icid);
|
||||
return update_ite(s, eventid, dte, ite) ? CMD_CONTINUE : CMD_STALL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Current implementation blocks until all
|
||||
* commands are processed
|
||||
@ -634,6 +830,8 @@ static void process_cmdq(GICv3ITSState *s)
|
||||
|
||||
cmd = (data & CMD_MASK);
|
||||
|
||||
trace_gicv3_its_process_command(rd_offset, cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case GITS_CMD_INT:
|
||||
result = process_its_cmd(s, data, cq_offset, INTERRUPT);
|
||||
@ -676,6 +874,12 @@ static void process_cmdq(GICv3ITSState *s)
|
||||
gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
|
||||
}
|
||||
break;
|
||||
case GITS_CMD_MOVI:
|
||||
result = process_movi(s, data, cq_offset);
|
||||
break;
|
||||
case GITS_CMD_MOVALL:
|
||||
result = process_movall(s, data, cq_offset);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -788,7 +992,7 @@ static void extract_table_params(GICv3ITSState *s)
|
||||
L1TABLE_ENTRY_SIZE) *
|
||||
(page_sz / td->entry_sz));
|
||||
}
|
||||
td->num_ids = 1ULL << idbits;
|
||||
td->num_entries = MIN(td->num_entries, 1ULL << idbits);
|
||||
}
|
||||
}
|
||||
|
||||
@ -810,6 +1014,18 @@ static void extract_cmdq_params(GICv3ITSState *s)
|
||||
}
|
||||
}
|
||||
|
||||
static MemTxResult gicv3_its_translation_read(void *opaque, hwaddr offset,
|
||||
uint64_t *data, unsigned size,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
/*
|
||||
* GITS_TRANSLATER is write-only, and all other addresses
|
||||
* in the interrupt translation space frame are RES0.
|
||||
*/
|
||||
*data = 0;
|
||||
return MEMTX_OK;
|
||||
}
|
||||
|
||||
static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
|
||||
uint64_t data, unsigned size,
|
||||
MemTxAttrs attrs)
|
||||
@ -818,6 +1034,8 @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
|
||||
bool result = true;
|
||||
uint32_t devid = 0;
|
||||
|
||||
trace_gicv3_its_translation_write(offset, data, size, attrs.requester_id);
|
||||
|
||||
switch (offset) {
|
||||
case GITS_TRANSLATER:
|
||||
if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
|
||||
@ -848,7 +1066,6 @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
|
||||
s->ctlr |= R_GITS_CTLR_ENABLED_MASK;
|
||||
extract_table_params(s);
|
||||
extract_cmdq_params(s);
|
||||
s->creadr = 0;
|
||||
process_cmdq(s);
|
||||
} else {
|
||||
s->ctlr &= ~R_GITS_CTLR_ENABLED_MASK;
|
||||
@ -862,7 +1079,6 @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
|
||||
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
|
||||
s->cbaser = deposit64(s->cbaser, 0, 32, value);
|
||||
s->creadr = 0;
|
||||
s->cwriter = s->creadr;
|
||||
}
|
||||
break;
|
||||
case GITS_CBASER + 4:
|
||||
@ -873,7 +1089,6 @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
|
||||
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
|
||||
s->cbaser = deposit64(s->cbaser, 32, 32, value);
|
||||
s->creadr = 0;
|
||||
s->cwriter = s->creadr;
|
||||
}
|
||||
break;
|
||||
case GITS_CWRITER:
|
||||
@ -915,6 +1130,10 @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
|
||||
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
|
||||
index = (offset - GITS_BASER) / 8;
|
||||
|
||||
if (s->baser[index] == 0) {
|
||||
/* Unimplemented GITS_BASERn: RAZ/WI */
|
||||
break;
|
||||
}
|
||||
if (offset & 7) {
|
||||
value <<= 32;
|
||||
value &= ~GITS_BASER_RO_MASK;
|
||||
@ -1011,6 +1230,10 @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
|
||||
*/
|
||||
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
|
||||
index = (offset - GITS_BASER) / 8;
|
||||
if (s->baser[index] == 0) {
|
||||
/* Unimplemented GITS_BASERn: RAZ/WI */
|
||||
break;
|
||||
}
|
||||
s->baser[index] &= GITS_BASER_RO_MASK;
|
||||
s->baser[index] |= (value & ~GITS_BASER_RO_MASK);
|
||||
}
|
||||
@ -1023,7 +1246,6 @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
|
||||
if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
|
||||
s->cbaser = value;
|
||||
s->creadr = 0;
|
||||
s->cwriter = s->creadr;
|
||||
}
|
||||
break;
|
||||
case GITS_CWRITER:
|
||||
@ -1107,6 +1329,7 @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid guest read at offset " TARGET_FMT_plx
|
||||
"size %u\n", __func__, offset, size);
|
||||
trace_gicv3_its_badread(offset, size);
|
||||
/*
|
||||
* The spec requires that reserved registers are RAZ/WI;
|
||||
* so use false returns from leaf functions as a way to
|
||||
@ -1114,6 +1337,8 @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
|
||||
* the caller, or we'll cause a spurious guest data abort.
|
||||
*/
|
||||
*data = 0;
|
||||
} else {
|
||||
trace_gicv3_its_read(offset, *data, size);
|
||||
}
|
||||
return MEMTX_OK;
|
||||
}
|
||||
@ -1140,12 +1365,15 @@ static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data,
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: invalid guest write at offset " TARGET_FMT_plx
|
||||
"size %u\n", __func__, offset, size);
|
||||
trace_gicv3_its_badwrite(offset, data, size);
|
||||
/*
|
||||
* The spec requires that reserved registers are RAZ/WI;
|
||||
* so use false returns from leaf functions as a way to
|
||||
* trigger the guest-error logging but don't return it to
|
||||
* the caller, or we'll cause a spurious guest data abort.
|
||||
*/
|
||||
} else {
|
||||
trace_gicv3_its_write(offset, data, size);
|
||||
}
|
||||
return MEMTX_OK;
|
||||
}
|
||||
@ -1161,6 +1389,7 @@ static const MemoryRegionOps gicv3_its_control_ops = {
|
||||
};
|
||||
|
||||
static const MemoryRegionOps gicv3_its_translation_ops = {
|
||||
.read_with_attrs = gicv3_its_translation_read,
|
||||
.write_with_attrs = gicv3_its_translation_write,
|
||||
.valid.min_access_size = 2,
|
||||
.valid.max_access_size = 4,
|
||||
@ -1183,9 +1412,6 @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
|
||||
|
||||
address_space_init(&s->gicv3->dma_as, s->gicv3->dma,
|
||||
"gicv3-its-sysmem");
|
||||
|
||||
/* set the ITS default features supported */
|
||||
s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, 1);
|
||||
s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE,
|
||||
|
@ -591,8 +591,7 @@ void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
|
||||
idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
|
||||
GICD_TYPER_IDBITS);
|
||||
|
||||
if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
|
||||
!cs->gicr_pendbaser) {
|
||||
if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -673,9 +672,8 @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
|
||||
idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
|
||||
GICD_TYPER_IDBITS);
|
||||
|
||||
if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
|
||||
!cs->gicr_pendbaser || (irq > (1ULL << (idbits + 1)) - 1) ||
|
||||
irq < GICV3_LPI_INTID_START) {
|
||||
if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
|
||||
(irq > (1ULL << (idbits + 1)) - 1) || irq < GICV3_LPI_INTID_START) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -683,6 +681,113 @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
|
||||
gicv3_redist_lpi_pending(cs, irq, level);
|
||||
}
|
||||
|
||||
void gicv3_redist_mov_lpi(GICv3CPUState *src, GICv3CPUState *dest, int irq)
|
||||
{
|
||||
/*
|
||||
* Move the specified LPI's pending state from the source redistributor
|
||||
* to the destination.
|
||||
*
|
||||
* If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
|
||||
* we choose to NOP. If LPIs are disabled on source there's nothing
|
||||
* to be transferred anyway.
|
||||
*/
|
||||
AddressSpace *as = &src->gic->dma_as;
|
||||
uint64_t idbits;
|
||||
uint32_t pendt_size;
|
||||
uint64_t src_baddr;
|
||||
uint8_t src_pend;
|
||||
|
||||
if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
|
||||
!(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
|
||||
GICD_TYPER_IDBITS);
|
||||
idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
|
||||
idbits);
|
||||
|
||||
pendt_size = 1ULL << (idbits + 1);
|
||||
if ((irq / 8) >= pendt_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
|
||||
|
||||
address_space_read(as, src_baddr + (irq / 8),
|
||||
MEMTXATTRS_UNSPECIFIED, &src_pend, sizeof(src_pend));
|
||||
if (!extract32(src_pend, irq % 8, 1)) {
|
||||
/* Not pending on source, nothing to do */
|
||||
return;
|
||||
}
|
||||
src_pend &= ~(1 << (irq % 8));
|
||||
address_space_write(as, src_baddr + (irq / 8),
|
||||
MEMTXATTRS_UNSPECIFIED, &src_pend, sizeof(src_pend));
|
||||
if (irq == src->hpplpi.irq) {
|
||||
/*
|
||||
* We just made this LPI not-pending so only need to update
|
||||
* if it was previously the highest priority pending LPI
|
||||
*/
|
||||
gicv3_redist_update_lpi(src);
|
||||
}
|
||||
/* Mark it pending on the destination */
|
||||
gicv3_redist_lpi_pending(dest, irq, 1);
|
||||
}
|
||||
|
||||
void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest)
|
||||
{
|
||||
/*
|
||||
* We must move all pending LPIs from the source redistributor
|
||||
* to the destination. That is, for every pending LPI X on
|
||||
* src, we must set it not-pending on src and pending on dest.
|
||||
* LPIs that are already pending on dest are not cleared.
|
||||
*
|
||||
* If LPIs are disabled on dest this is CONSTRAINED UNPREDICTABLE:
|
||||
* we choose to NOP. If LPIs are disabled on source there's nothing
|
||||
* to be transferred anyway.
|
||||
*/
|
||||
AddressSpace *as = &src->gic->dma_as;
|
||||
uint64_t idbits;
|
||||
uint32_t pendt_size;
|
||||
uint64_t src_baddr, dest_baddr;
|
||||
int i;
|
||||
|
||||
if (!(src->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) ||
|
||||
!(dest->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
idbits = MIN(FIELD_EX64(src->gicr_propbaser, GICR_PROPBASER, IDBITS),
|
||||
GICD_TYPER_IDBITS);
|
||||
idbits = MIN(FIELD_EX64(dest->gicr_propbaser, GICR_PROPBASER, IDBITS),
|
||||
idbits);
|
||||
|
||||
pendt_size = 1ULL << (idbits + 1);
|
||||
src_baddr = src->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
|
||||
dest_baddr = dest->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
|
||||
|
||||
for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
|
||||
uint8_t src_pend, dest_pend;
|
||||
|
||||
address_space_read(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
|
||||
&src_pend, sizeof(src_pend));
|
||||
if (!src_pend) {
|
||||
continue;
|
||||
}
|
||||
address_space_read(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
|
||||
&dest_pend, sizeof(dest_pend));
|
||||
dest_pend |= src_pend;
|
||||
src_pend = 0;
|
||||
address_space_write(as, src_baddr + i, MEMTXATTRS_UNSPECIFIED,
|
||||
&src_pend, sizeof(src_pend));
|
||||
address_space_write(as, dest_baddr + i, MEMTXATTRS_UNSPECIFIED,
|
||||
&dest_pend, sizeof(dest_pend));
|
||||
}
|
||||
|
||||
gicv3_redist_update_lpi(src);
|
||||
gicv3_redist_update_lpi(dest);
|
||||
}
|
||||
|
||||
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
|
||||
{
|
||||
/* Update redistributor state for a change in an external PPI input line */
|
||||
|
@ -110,6 +110,7 @@
|
||||
#define GICR_NSACR (GICR_SGI_OFFSET + 0x0E00)
|
||||
|
||||
#define GICR_CTLR_ENABLE_LPIS (1U << 0)
|
||||
#define GICR_CTLR_CES (1U << 1)
|
||||
#define GICR_CTLR_RWP (1U << 3)
|
||||
#define GICR_CTLR_DPG0 (1U << 24)
|
||||
#define GICR_CTLR_DPG1NS (1U << 25)
|
||||
@ -314,16 +315,18 @@ FIELD(GITS_TYPER, CIL, 36, 1)
|
||||
#define CMD_MASK 0xff
|
||||
|
||||
/* ITS Commands */
|
||||
#define GITS_CMD_CLEAR 0x04
|
||||
#define GITS_CMD_DISCARD 0x0F
|
||||
#define GITS_CMD_MOVI 0x01
|
||||
#define GITS_CMD_INT 0x03
|
||||
#define GITS_CMD_MAPC 0x09
|
||||
#define GITS_CMD_CLEAR 0x04
|
||||
#define GITS_CMD_SYNC 0x05
|
||||
#define GITS_CMD_MAPD 0x08
|
||||
#define GITS_CMD_MAPI 0x0B
|
||||
#define GITS_CMD_MAPC 0x09
|
||||
#define GITS_CMD_MAPTI 0x0A
|
||||
#define GITS_CMD_MAPI 0x0B
|
||||
#define GITS_CMD_INV 0x0C
|
||||
#define GITS_CMD_INVALL 0x0D
|
||||
#define GITS_CMD_SYNC 0x05
|
||||
#define GITS_CMD_MOVALL 0x0E
|
||||
#define GITS_CMD_DISCARD 0x0F
|
||||
|
||||
/* MAPC command fields */
|
||||
#define ICID_LENGTH 16
|
||||
@ -354,6 +357,15 @@ FIELD(MAPC, RDBASE, 16, 32)
|
||||
#define L2_TABLE_VALID_MASK CMD_FIELD_VALID_MASK
|
||||
#define TABLE_ENTRY_VALID_MASK (1ULL << 0)
|
||||
|
||||
/* MOVALL command fields */
|
||||
FIELD(MOVALL_2, RDBASE1, 16, 36)
|
||||
FIELD(MOVALL_3, RDBASE2, 16, 36)
|
||||
|
||||
/* MOVI command fields */
|
||||
FIELD(MOVI_0, DEVICEID, 32, 32)
|
||||
FIELD(MOVI_1, EVENTID, 0, 32)
|
||||
FIELD(MOVI_2, ICID, 0, 16)
|
||||
|
||||
/*
|
||||
* 12 bytes Interrupt translation Table Entry size
|
||||
* as per Table 5.3 in GICv3 spec
|
||||
@ -496,6 +508,27 @@ void gicv3_redist_update_lpi(GICv3CPUState *cs);
|
||||
* an incoming migration has loaded new state.
|
||||
*/
|
||||
void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
|
||||
/**
|
||||
* gicv3_redist_mov_lpi:
|
||||
* @src: source redistributor
|
||||
* @dest: destination redistributor
|
||||
* @irq: LPI to update
|
||||
*
|
||||
* Move the pending state of the specified LPI from @src to @dest,
|
||||
* as required by the ITS MOVI command.
|
||||
*/
|
||||
void gicv3_redist_mov_lpi(GICv3CPUState *src, GICv3CPUState *dest, int irq);
|
||||
/**
|
||||
* gicv3_redist_movall_lpis:
|
||||
* @src: source redistributor
|
||||
* @dest: destination redistributor
|
||||
*
|
||||
* Scan the LPI pending table for @src, and for each pending LPI there
|
||||
* mark it as not-pending for @src and pending for @dest, as required
|
||||
* by the ITS MOVALL command.
|
||||
*/
|
||||
void gicv3_redist_movall_lpis(GICv3CPUState *src, GICv3CPUState *dest);
|
||||
|
||||
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
|
||||
void gicv3_init_cpuif(GICv3State *s);
|
||||
|
||||
|
@ -169,6 +169,14 @@ gicv3_redist_badwrite(uint32_t cpu, uint64_t offset, uint64_t data, unsigned siz
|
||||
gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor 0x%x interrupt %d level changed to %d"
|
||||
gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending SGI %d"
|
||||
|
||||
# arm_gicv3_its.c
|
||||
gicv3_its_read(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
||||
gicv3_its_badread(uint64_t offset, unsigned size) "GICv3 ITS read: offset 0x%" PRIx64 " size %u: error"
|
||||
gicv3_its_write(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
||||
gicv3_its_badwrite(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u: error"
|
||||
gicv3_its_translation_write(uint64_t offset, uint64_t data, unsigned size, uint32_t requester_id) "GICv3 ITS TRANSLATER write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u requester_id 0x%x"
|
||||
gicv3_its_process_command(uint32_t rd_offset, uint8_t cmd) "GICv3 ITS: processing command at offset 0x%x: 0x%x"
|
||||
|
||||
# armv7m_nvic.c
|
||||
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
|
||||
nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d is_s_banked %d vectpending_prio %d exception_prio %d"
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/irq.h"
|
||||
@ -30,6 +29,7 @@
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-properties-system.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "trace.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/ppc/mac.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "migration/vmstate.h"
|
||||
@ -34,6 +33,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/log.h"
|
||||
|
@ -29,7 +29,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/ppc/mac.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "migration/vmstate.h"
|
||||
@ -41,6 +40,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/log.h"
|
||||
|
@ -84,7 +84,10 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
|
||||
))
|
||||
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-xramc.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
|
||||
'xlnx-versal-xramc.c',
|
||||
'xlnx-versal-pmc-iou-slcr.c',
|
||||
))
|
||||
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: files('stm32f4xx_exti.c'))
|
||||
|
1446
hw/misc/xlnx-versal-pmc-iou-slcr.c
Normal file
1446
hw/misc/xlnx-versal-pmc-iou-slcr.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -26,9 +26,9 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "hw/ppc/spapr.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qapi/error.h"
|
||||
|
@ -23,9 +23,9 @@
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/rtc/allwinner-rtc.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* RTC registers */
|
||||
|
@ -7,11 +7,11 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/rtc/aspeed_rtc.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/rtc.h"
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
|
@ -11,12 +11,12 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/bcd.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
#include "sysemu/rtc.h"
|
||||
|
||||
/* Size of NVRAM including both the user-accessible area and the
|
||||
* secondary register area.
|
||||
|
@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/module.h"
|
||||
#include "hw/sysbus.h"
|
||||
@ -39,6 +38,7 @@
|
||||
|
||||
#include "hw/arm/exynos4210.h"
|
||||
#include "qom/object.h"
|
||||
#include "sysemu/rtc.h"
|
||||
|
||||
#define DEBUG_RTC 0
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/rtc/goldfish_rtc.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "hw/irq.h"
|
||||
@ -29,6 +28,7 @@
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
|
@ -8,13 +8,13 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/bcd.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
#include "qom/object.h"
|
||||
#include "sysemu/rtc.h"
|
||||
|
||||
#define TYPE_M41T80 "m41t80"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(M41t80State, M41T80)
|
||||
|
@ -24,12 +24,12 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/rtc/m48t59.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "qapi/error.h"
|
||||
|
@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/bcd.h"
|
||||
@ -36,6 +35,7 @@
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "hw/rtc/mc146818rtc.h"
|
||||
#include "hw/rtc/mc146818rtc_regs.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/rtc/pl031.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "hw/irq.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "hw/sysbus.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/module.h"
|
||||
|
@ -20,13 +20,13 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
#include "hw/irq.h"
|
||||
#include "migration/qemu-file-types.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "qemu/bcd.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
|
@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/register.h"
|
||||
#include "qemu/bitops.h"
|
||||
@ -34,6 +33,7 @@
|
||||
#include "hw/irq.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "trace.h"
|
||||
#include "hw/rtc/xlnx-zynqmp-rtc.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
@ -9,7 +9,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qapi/error.h"
|
||||
#include "hw/s390x/tod.h"
|
||||
#include "qemu/timer.h"
|
||||
@ -17,6 +16,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "cpu.h"
|
||||
#include "tcg/tcg_s390x.h"
|
||||
#include "sysemu/rtc.h"
|
||||
|
||||
static void qemu_s390_tod_get(const S390TODState *td, S390TOD *tod,
|
||||
Error **errp)
|
||||
|
@ -19,11 +19,11 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/pci/msix.h"
|
||||
#include "qemu/iov.h"
|
||||
|
@ -7,5 +7,6 @@ softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
|
||||
|
1853
hw/ssi/xlnx-versal-ospi.c
Normal file
1853
hw/ssi/xlnx-versal-ospi.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,9 @@
|
||||
#include "hw/misc/xlnx-versal-xramc.h"
|
||||
#include "hw/nvram/xlnx-bbram.h"
|
||||
#include "hw/nvram/xlnx-versal-efuse.h"
|
||||
#include "hw/ssi/xlnx-versal-ospi.h"
|
||||
#include "hw/dma/xlnx_csu_dma.h"
|
||||
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
|
||||
|
||||
#define TYPE_XLNX_VERSAL "xlnx-versal"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
|
||||
@ -78,6 +81,15 @@ struct Versal {
|
||||
struct {
|
||||
struct {
|
||||
SDHCIState sd[XLNX_VERSAL_NR_SDS];
|
||||
XlnxVersalPmcIouSlcr slcr;
|
||||
|
||||
struct {
|
||||
XlnxVersalOspi ospi;
|
||||
XlnxCSUDMA dma_src;
|
||||
XlnxCSUDMA dma_dst;
|
||||
MemoryRegion linear_mr;
|
||||
qemu_or_irq irq_orgate;
|
||||
} ospi;
|
||||
} iou;
|
||||
|
||||
XlnxZynqMPRTC rtc;
|
||||
@ -85,6 +97,8 @@ struct Versal {
|
||||
XlnxEFuse efuse;
|
||||
XlnxVersalEFuseCtrl efuse_ctrl;
|
||||
XlnxVersalEFuseCache efuse_cache;
|
||||
|
||||
qemu_or_irq apb_irq_orgate;
|
||||
} pmc;
|
||||
|
||||
struct {
|
||||
@ -111,8 +125,8 @@ struct Versal {
|
||||
#define VERSAL_GEM1_WAKE_IRQ_0 59
|
||||
#define VERSAL_ADMA_IRQ_0 60
|
||||
#define VERSAL_XRAM_IRQ_0 79
|
||||
#define VERSAL_BBRAM_APB_IRQ_0 121
|
||||
#define VERSAL_RTC_APB_ERR_IRQ 121
|
||||
#define VERSAL_PMC_APB_IRQ 121
|
||||
#define VERSAL_OSPI_IRQ 124
|
||||
#define VERSAL_SD0_IRQ_0 126
|
||||
#define VERSAL_EFUSE_IRQ 139
|
||||
#define VERSAL_RTC_ALARM_IRQ 142
|
||||
@ -178,6 +192,18 @@ struct Versal {
|
||||
#define MM_FPD_FPD_APU 0xfd5c0000
|
||||
#define MM_FPD_FPD_APU_SIZE 0x100
|
||||
|
||||
#define MM_PMC_PMC_IOU_SLCR 0xf1060000
|
||||
#define MM_PMC_PMC_IOU_SLCR_SIZE 0x10000
|
||||
|
||||
#define MM_PMC_OSPI 0xf1010000
|
||||
#define MM_PMC_OSPI_SIZE 0x10000
|
||||
|
||||
#define MM_PMC_OSPI_DAC 0xc0000000
|
||||
#define MM_PMC_OSPI_DAC_SIZE 0x20000000
|
||||
|
||||
#define MM_PMC_OSPI_DMA_DST 0xf1011800
|
||||
#define MM_PMC_OSPI_DMA_SRC 0xf1011000
|
||||
|
||||
#define MM_PMC_SD0 0xf1040000U
|
||||
#define MM_PMC_SD0_SIZE 0x10000
|
||||
#define MM_PMC_BBRAM_CTRL 0xf11f0000
|
||||
|
@ -21,6 +21,11 @@
|
||||
#ifndef XLNX_CSU_DMA_H
|
||||
#define XLNX_CSU_DMA_H
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/register.h"
|
||||
#include "hw/ptimer.h"
|
||||
#include "hw/stream.h"
|
||||
|
||||
#define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
|
||||
|
||||
#define XLNX_CSU_DMA_R_MAX (0x2c / 4)
|
||||
@ -46,7 +51,22 @@ typedef struct XlnxCSUDMA {
|
||||
RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
|
||||
} XlnxCSUDMA;
|
||||
|
||||
#define XLNX_CSU_DMA(obj) \
|
||||
OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA)
|
||||
OBJECT_DECLARE_TYPE(XlnxCSUDMA, XlnxCSUDMAClass, XLNX_CSU_DMA)
|
||||
|
||||
struct XlnxCSUDMAClass {
|
||||
SysBusDeviceClass parent_class;
|
||||
|
||||
/*
|
||||
* read: Start a read transfer on a Xilinx CSU DMA engine
|
||||
*
|
||||
* @s: the Xilinx CSU DMA engine to start the transfer on
|
||||
* @addr: the address to read
|
||||
* @len: the number of bytes to read at 'addr'
|
||||
*
|
||||
* @return a MemTxResult indicating whether the operation succeeded ('len'
|
||||
* bytes were read) or failed.
|
||||
*/
|
||||
MemTxResult (*read)(XlnxCSUDMA *s, hwaddr addr, uint32_t len);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -47,7 +47,6 @@ typedef struct {
|
||||
uint16_t entry_sz;
|
||||
uint32_t page_sz;
|
||||
uint32_t num_entries;
|
||||
uint32_t num_ids;
|
||||
uint64_t base_addr;
|
||||
} TableDesc;
|
||||
|
||||
|
78
include/hw/misc/xlnx-versal-pmc-iou-slcr.h
Normal file
78
include/hw/misc/xlnx-versal-pmc-iou-slcr.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Header file for the Xilinx Versal's PMC IOU SLCR
|
||||
*
|
||||
* Copyright (C) 2021 Xilinx Inc
|
||||
* Written by Edgar E. Iglesias <edgar.iglesias@xilinx.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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a model of Xilinx Versal's PMC I/O Peripheral Control and Status
|
||||
* module documented in Versal's Technical Reference manual [1] and the Versal
|
||||
* ACAP Register reference [2].
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* [1] Versal ACAP Technical Reference Manual,
|
||||
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
||||
*
|
||||
* [2] Versal ACAP Register Reference,
|
||||
* https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___pmc_iop_slcr.html
|
||||
*
|
||||
* QEMU interface:
|
||||
* + sysbus MMIO region 0: MemoryRegion for the device's registers
|
||||
* + sysbus IRQ 0: PMC (AXI and APB) parity error interrupt detected by the PMC
|
||||
* I/O peripherals.
|
||||
* + sysbus IRQ 1: Device interrupt.
|
||||
* + Named GPIO output "sd-emmc-sel[0]": Enables 0: SD mode or 1: eMMC mode on
|
||||
* SD/eMMC controller 0.
|
||||
* + Named GPIO output "sd-emmc-sel[1]": Enables 0: SD mode or 1: eMMC mode on
|
||||
* SD/eMMC controller 1.
|
||||
* + Named GPIO output "qspi-ospi-mux-sel": Selects 0: QSPI linear region or 1:
|
||||
* OSPI linear region.
|
||||
* + Named GPIO output "ospi-mux-sel": Selects 0: OSPI Indirect access mode or
|
||||
* 1: OSPI direct access mode.
|
||||
*/
|
||||
|
||||
#ifndef XILINX_VERSAL_PMC_IOU_SLCR_H
|
||||
#define XILINX_VERSAL_PMC_IOU_SLCR_H
|
||||
|
||||
#include "hw/register.h"
|
||||
|
||||
#define TYPE_XILINX_VERSAL_PMC_IOU_SLCR "xlnx.versal-pmc-iou-slcr"
|
||||
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalPmcIouSlcr, XILINX_VERSAL_PMC_IOU_SLCR)
|
||||
|
||||
#define XILINX_VERSAL_PMC_IOU_SLCR_R_MAX (0x828 / 4 + 1)
|
||||
|
||||
struct XlnxVersalPmcIouSlcr {
|
||||
SysBusDevice parent_obj;
|
||||
MemoryRegion iomem;
|
||||
qemu_irq irq_parity_imr;
|
||||
qemu_irq irq_imr;
|
||||
qemu_irq sd_emmc_sel[2];
|
||||
qemu_irq qspi_ospi_mux_sel;
|
||||
qemu_irq ospi_mux_sel;
|
||||
|
||||
uint32_t regs[XILINX_VERSAL_PMC_IOU_SLCR_R_MAX];
|
||||
RegisterInfo regs_info[XILINX_VERSAL_PMC_IOU_SLCR_R_MAX];
|
||||
};
|
||||
|
||||
#endif /* XILINX_VERSAL_PMC_IOU_SLCR_H */
|
111
include/hw/ssi/xlnx-versal-ospi.h
Normal file
111
include/hw/ssi/xlnx-versal-ospi.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Header file for the Xilinx Versal's OSPI controller
|
||||
*
|
||||
* Copyright (C) 2021 Xilinx Inc
|
||||
* Written by Francisco Iglesias <francisco.iglesias@xilinx.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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a model of Xilinx Versal's Octal SPI flash memory controller
|
||||
* documented in Versal's Technical Reference manual [1] and the Versal ACAP
|
||||
* Register reference [2].
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* [1] Versal ACAP Technical Reference Manual,
|
||||
* https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
|
||||
*
|
||||
* [2] Versal ACAP Register Reference,
|
||||
* https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___ospi.html
|
||||
*
|
||||
*
|
||||
* QEMU interface:
|
||||
* + sysbus MMIO region 0: MemoryRegion for the device's registers
|
||||
* + sysbus MMIO region 1: MemoryRegion for flash memory linear address space
|
||||
* (data transfer).
|
||||
* + sysbus IRQ 0: Device interrupt.
|
||||
* + Named GPIO input "ospi-mux-sel": 0: enables indirect access mode
|
||||
* and 1: enables direct access mode.
|
||||
* + Property "dac-with-indac": Allow both direct accesses and indirect
|
||||
* accesses simultaneously.
|
||||
* + Property "indac-write-disabled": Disable indirect access writes.
|
||||
*/
|
||||
|
||||
#ifndef XILINX_VERSAL_OSPI_H
|
||||
#define XILINX_VERSAL_OSPI_H
|
||||
|
||||
#include "hw/register.h"
|
||||
#include "hw/ssi/ssi.h"
|
||||
#include "qemu/fifo8.h"
|
||||
#include "hw/dma/xlnx_csu_dma.h"
|
||||
|
||||
#define TYPE_XILINX_VERSAL_OSPI "xlnx.versal-ospi"
|
||||
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalOspi, XILINX_VERSAL_OSPI)
|
||||
|
||||
#define XILINX_VERSAL_OSPI_R_MAX (0xfc / 4 + 1)
|
||||
|
||||
/*
|
||||
* Indirect operations
|
||||
*/
|
||||
typedef struct IndOp {
|
||||
uint32_t flash_addr;
|
||||
uint32_t num_bytes;
|
||||
uint32_t done_bytes;
|
||||
bool completed;
|
||||
} IndOp;
|
||||
|
||||
struct XlnxVersalOspi {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
MemoryRegion iomem;
|
||||
MemoryRegion iomem_dac;
|
||||
|
||||
uint8_t num_cs;
|
||||
qemu_irq *cs_lines;
|
||||
|
||||
SSIBus *spi;
|
||||
|
||||
Fifo8 rx_fifo;
|
||||
Fifo8 tx_fifo;
|
||||
|
||||
Fifo8 rx_sram;
|
||||
Fifo8 tx_sram;
|
||||
|
||||
qemu_irq irq;
|
||||
|
||||
XlnxCSUDMA *dma_src;
|
||||
bool ind_write_disabled;
|
||||
bool dac_with_indac;
|
||||
bool dac_enable;
|
||||
bool src_dma_inprog;
|
||||
|
||||
IndOp rd_ind_op[2];
|
||||
IndOp wr_ind_op[2];
|
||||
|
||||
uint32_t regs[XILINX_VERSAL_OSPI_R_MAX];
|
||||
RegisterInfo regs_info[XILINX_VERSAL_OSPI_R_MAX];
|
||||
|
||||
/* Maximum inferred membank size is 512 bytes */
|
||||
uint8_t stig_membank[512];
|
||||
};
|
||||
|
||||
#endif /* XILINX_VERSAL_OSPI_H */
|
@ -13,7 +13,7 @@
|
||||
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
|
||||
|
||||
/* Copyright string for -version arguments, About dialogs, etc */
|
||||
#define QEMU_COPYRIGHT "Copyright (c) 2003-2021 " \
|
||||
#define QEMU_COPYRIGHT "Copyright (c) 2003-2022 " \
|
||||
"Fabrice Bellard and the QEMU Project developers"
|
||||
|
||||
/* Bug reporting information for --help arguments, About dialogs, etc */
|
||||
@ -26,9 +26,6 @@
|
||||
int qemu_main(int argc, char **argv, char **envp);
|
||||
#endif
|
||||
|
||||
void qemu_get_timedate(struct tm *tm, int offset);
|
||||
int qemu_timedate_diff(struct tm *tm);
|
||||
|
||||
void *qemu_oom_check(void *ptr);
|
||||
|
||||
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
|
||||
|
58
include/sysemu/rtc.h
Normal file
58
include/sysemu/rtc.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* RTC configuration and clock read
|
||||
*
|
||||
* Copyright (c) 2003-2021 QEMU contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SYSEMU_RTC_H
|
||||
#define SYSEMU_RTC_H
|
||||
|
||||
/**
|
||||
* qemu_get_timedate: Get the current RTC time
|
||||
* @tm: struct tm to fill in with RTC time
|
||||
* @offset: offset in seconds to adjust the RTC time by before
|
||||
* converting to struct tm format.
|
||||
*
|
||||
* This function fills in @tm with the current RTC time, as adjusted
|
||||
* by @offset (for example, if @offset is 3600 then the returned time/date
|
||||
* will be one hour further ahead than the current RTC time).
|
||||
*
|
||||
* The usual use is by RTC device models, which should call this function
|
||||
* to find the time/date value that they should return to the guest
|
||||
* when it reads the RTC registers.
|
||||
*
|
||||
* The behaviour of the clock whose value this function returns will
|
||||
* depend on the -rtc command line option passed by the user.
|
||||
*/
|
||||
void qemu_get_timedate(struct tm *tm, int offset);
|
||||
|
||||
/**
|
||||
* qemu_timedate_diff: Return difference between a struct tm and the RTC
|
||||
* @tm: struct tm containing the date/time to compare against
|
||||
*
|
||||
* Returns the difference in seconds between the RTC clock time
|
||||
* and the date/time specified in @tm. For example, if @tm specifies
|
||||
* a timestamp one hour further ahead than the current RTC time
|
||||
* then this function will return 3600.
|
||||
*/
|
||||
int qemu_timedate_diff(struct tm *tm);
|
||||
|
||||
#endif
|
@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "clients.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
@ -33,6 +32,7 @@
|
||||
#include "qapi/visitor.h"
|
||||
#include "net/filter.h"
|
||||
#include "qom/object.h"
|
||||
#include "sysemu/rtc.h"
|
||||
|
||||
typedef struct DumpState {
|
||||
int64_t start_ts;
|
||||
|
@ -9,6 +9,22 @@
|
||||
#
|
||||
# This work is licensed under the terms of the GNU GPL version 2.
|
||||
# See the COPYING file in the top-level directory.
|
||||
#
|
||||
# The script will copy the headers into two target folders:
|
||||
#
|
||||
# - linux-headers/ for files that are required for compiling for a
|
||||
# Linux host. Generally we have these so we can use kernel structs
|
||||
# and defines that are more recent than the headers that might be
|
||||
# installed on the host system. Usually this script can do simple
|
||||
# file copies for these headers.
|
||||
#
|
||||
# - include/standard-headers/ for files that are used for guest
|
||||
# device emulation and are required on all hosts. For instance, we
|
||||
# get our definitions of the virtio structures from the Linux
|
||||
# kernel headers, but we need those definitions regardless of which
|
||||
# host OS we are building for. This script has to be careful to
|
||||
# sanitize the headers to remove any use of Linux-specifics such as
|
||||
# types like "__u64". This work is done in the cp_portable function.
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
linux="$1"
|
||||
|
@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
@ -33,6 +32,7 @@
|
||||
#include "qom/object.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/rtc.h"
|
||||
|
||||
static enum {
|
||||
RTC_BASE_UTC,
|
||||
|
@ -9317,8 +9317,10 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||
return target_el;
|
||||
}
|
||||
|
||||
void arm_log_exception(int idx)
|
||||
void arm_log_exception(CPUState *cs)
|
||||
{
|
||||
int idx = cs->exception_index;
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_INT)) {
|
||||
const char *exc = NULL;
|
||||
static const char * const excnames[] = {
|
||||
@ -9352,7 +9354,8 @@ void arm_log_exception(int idx)
|
||||
if (!exc) {
|
||||
exc = "unknown";
|
||||
}
|
||||
qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
|
||||
qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s] on CPU %d\n",
|
||||
idx, exc, cs->cpu_index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9655,7 +9658,7 @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
|
||||
* separately here.
|
||||
*
|
||||
* The vector table entry used is always the 0x14 Hyp mode entry point,
|
||||
* unless this is an UNDEF/HVC/abort taken from Hyp to Hyp.
|
||||
* unless this is an UNDEF/SVC/HVC/abort taken from Hyp to Hyp.
|
||||
* The offset applied to the preferred return address is always zero
|
||||
* (see DDI0487C.a section G1.12.3).
|
||||
* PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values.
|
||||
@ -9669,7 +9672,7 @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
|
||||
addr = 0x04;
|
||||
break;
|
||||
case EXCP_SWI:
|
||||
addr = 0x14;
|
||||
addr = 0x08;
|
||||
break;
|
||||
case EXCP_BKPT:
|
||||
/* Fall through to prefetch abort. */
|
||||
@ -10185,7 +10188,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
|
||||
|
||||
assert(!arm_feature(env, ARM_FEATURE_M));
|
||||
|
||||
arm_log_exception(cs->exception_index);
|
||||
arm_log_exception(cs);
|
||||
qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
|
||||
new_el);
|
||||
if (qemu_loglevel_mask(CPU_LOG_INT)
|
||||
|
@ -1130,7 +1130,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
|
||||
__attribute__((nonnull));
|
||||
|
||||
void arm_log_exception(int idx);
|
||||
void arm_log_exception(CPUState *cs);
|
||||
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
|
@ -2206,7 +2206,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
|
||||
uint32_t lr;
|
||||
bool ignore_stackfaults;
|
||||
|
||||
arm_log_exception(cs->exception_index);
|
||||
arm_log_exception(cs);
|
||||
|
||||
/*
|
||||
* For exceptions we just mark as pending on the NVIC, and let that
|
||||
|
Loading…
Reference in New Issue
Block a user